From 185c68f53c4aca458c605375746d8a03967b37f3 Mon Sep 17 00:00:00 2001 From: Christian Eichenberger Date: Wed, 26 Jun 2024 21:43:21 +0200 Subject: [PATCH 001/197] Set ttl for js/css to 1y instead, fix location expression. (#159) Signed-off-by: chenkins --- docker/nginx-angular.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/nginx-angular.conf b/docker/nginx-angular.conf index 7d4dcb8d..550689c8 100644 --- a/docker/nginx-angular.conf +++ b/docker/nginx-angular.conf @@ -6,7 +6,7 @@ server { error_page 500 502 503 504 /50x.html; - location ~* \.(?:.css|.js)$ { + location ~* \.(js|jpg|png|css)$ { expires 1y; } From ea6a9ebdd66807b48f2a89df3cf9328d05374a58 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 27 Jun 2024 08:30:46 +0200 Subject: [PATCH 002/197] bug fixed (#160) --- src/app/streckengrafik/services/sg-6-track.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/streckengrafik/services/sg-6-track.service.ts b/src/app/streckengrafik/services/sg-6-track.service.ts index 9c5decad..fe3500ca 100644 --- a/src/app/streckengrafik/services/sg-6-track.service.ts +++ b/src/app/streckengrafik/services/sg-6-track.service.ts @@ -274,7 +274,7 @@ export class Sg6TrackService implements OnDestroy { for (let distCellIdx = 0; distCellIdx < nDistanceCells; distCellIdx++) { // unroll frequency to get the trains - generated out of the "template" train for ( - let freqLoop = 0; + let freqLoop = -this.maxFrequency; freqLoop <= this.maxFrequency; freqLoop = freqLoop + d.trainrun.frequency ) { From 1ad4d318e8d451351167d990744b1775a952a5bd Mon Sep 17 00:00:00 2001 From: Lukas Grossar Date: Thu, 27 Jun 2024 13:52:38 +0200 Subject: [PATCH 003/197] ci: fix duplicate trigger when pushing to a PR (#163) --- .github/workflows/continuous-integration.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index d45da47a..93dd55b6 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -1,5 +1,11 @@ name: Continuous Integration -on: [push, pull_request] +on: + push: + branches: + - main + pull_request: + branches: + - main concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} From cd4fbaf75ce21ae853e8545d3ffdfc9c088f7cb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 15:03:35 +0200 Subject: [PATCH 004/197] Bump braces from 3.0.2 to 3.0.3 (#164) Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3. - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: braces dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index aa82b7b0..1ad311f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6296,11 +6296,11 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -9806,9 +9806,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -10077,6 +10077,19 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", From cc4c56b25aa2d978ebd70fbf34dc129f36b776b2 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 2 Jul 2024 21:54:34 +0200 Subject: [PATCH 005/197] feat: introduce standalone mode (#162) * feat: introduce standalone mode Co-authored-by: adrian_egli Co-authored-by: Simon Ser * feat: register as a custom element Co-authored-by: Louis Greiner * fix: easy return * small fix - the use of ng-container embeded in the sbb-icon-sidebare doesn't work correctly. This fix resolves the issue. --------- Co-authored-by: Louis Greiner Co-authored-by: adrian_egli --- angular.json | 11 +++++ package-lock.json | 17 ++++++++ package.json | 3 ++ src/app/app.component.html | 14 ++++-- src/app/app.component.ts | 16 ++++++- src/app/app.module.ts | 21 ++++++--- .../netzgrafik-application.component.html | 6 +-- .../netzgrafik-application.component.scss | 4 -- .../netzgrafik-application.component.ts | 17 +++++++- src/app/services/auth/auth.service.ts | 43 ++++++++++--------- src/app/services/data/undo.service.ts | 4 ++ .../services/data/version-control.service.ts | 13 +++++- .../column-layout.component.html | 1 + .../column-layout/column-layout.component.ts | 8 ++++ .../editor-menu/editor-menu.component.html | 4 +- .../view/editor-menu/editor-menu.component.ts | 3 ++ src/environments/environment.model.ts | 6 ++- src/environments/environment.standalone.ts | 8 ++++ src/environments/environment.ts | 2 + 19 files changed, 156 insertions(+), 45 deletions(-) create mode 100644 src/environments/environment.standalone.ts diff --git a/angular.json b/angular.json index d548e192..8f82450c 100644 --- a/angular.json +++ b/angular.json @@ -107,6 +107,14 @@ }, "es5": { "tsConfig": "tsconfig.app.es5.json" + }, + "standalone": { + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.standalone.ts" + } + ] } }, "defaultConfiguration": "" @@ -125,6 +133,9 @@ }, "es5": { "buildTarget": "netzgrafik-frontend:build:es5" + }, + "standalone": { + "buildTarget": "netzgrafik-frontend:build:standalone" } } }, diff --git a/package-lock.json b/package-lock.json index 1ad311f3..d9a0a60c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@angular/common": "^17.0.5", "@angular/compiler": "^17.0.5", "@angular/core": "^17.0.5", + "@angular/elements": "^17.1.0", "@angular/forms": "^17.0.5", "@angular/localize": "^17.0.5", "@angular/platform-browser": "^17.0.5", @@ -792,6 +793,22 @@ "zone.js": "~0.14.0" } }, + "node_modules/@angular/elements": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@angular/elements/-/elements-17.1.0.tgz", + "integrity": "sha512-cpS+f1kVVL92SIt9JRDH4eqPLMLc/7fUWYcZlGVXaPi0hq8FNRjgnNwq+zQ26fQD7Y+VjSj9hag1BdPQPCKzIQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0" + }, + "peerDependencies": { + "@angular/core": "17.1.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, "node_modules/@angular/forms": { "version": "17.1.0", "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-17.1.0.tgz", diff --git a/package.json b/package.json index bc1d4b7f..293b5a06 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,11 @@ "ng": "ng", "start": "ng serve", "start:local": "ng serve --configuration=local", + "start:standalone": "ng serve --configuration=standalone", "e2e:browserstack": "ng e2e -c browserstack", "e2e:puppeteer": "ng e2e -c puppeteer", "build": "ng run netzgrafik-frontend:ngsscbuild", + "build:standalone": "ng build --configuration=standalone", "test": "ng test -c ci", "lint": "ng lint", "e2e": "ng e2e", @@ -24,6 +26,7 @@ "@angular/common": "^17.0.5", "@angular/compiler": "^17.0.5", "@angular/core": "^17.0.5", + "@angular/elements": "^17.1.0", "@angular/forms": "^17.0.5", "@angular/localize": "^17.0.5", "@angular/platform-browser": "^17.0.5", diff --git a/src/app/app.component.html b/src/app/app.component.html index c284f833..aa309187 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -30,9 +30,17 @@ - + + + - - + + + + + + + + diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 8b3c6e00..85a11c4d 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -11,6 +11,8 @@ import {ProjectDto} from "./api/generated"; styleUrls: ["./app.component.scss"], }) export class AppComponent { + readonly disableBackend = environment.disableBackend; + version = packageJson.version; environmentLabel = environment.label; authenticated: Promise; @@ -18,18 +20,28 @@ export class AppComponent { projectInMenu: Observable; get userName() { + if (this.disableBackend) { + return undefined; + } return this.authService.claims?.name; } get email() { + if (this.disableBackend) { + return undefined; + } return this.authService.claims?.email; } constructor(private authService: AuthService) { - this.authenticated = authService.initialized; + if (!this.disableBackend) { + this.authenticated = authService.initialized; + } } logout() { - this.authService.logOut(); + if (!this.disableBackend) { + this.authService.logOut(); + } } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 4a3478b9..9ef3795b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,6 +1,7 @@ -import {NgModule} from "@angular/core"; +import {NgModule, Injector, ApplicationRef, DoBootstrap} from "@angular/core"; import {NgxEditorModule} from "ngx-editor"; import {BrowserModule} from "@angular/platform-browser"; +import {createCustomElement} from "@angular/elements"; import {HTTP_INTERCEPTORS, HttpClientModule} from "@angular/common/http"; import {OAuthModule} from "angular-oauth2-oidc"; import {FormsModule, ReactiveFormsModule} from "@angular/forms"; @@ -203,7 +204,7 @@ import {ActionMenuComponent} from "./view/action-menu/action-menu/action-menu.co // and you send a request to these, the access token is appended. // Documentation: // https://manfredsteyer.github.io/angular-oauth2-oidc/docs/additional-documentation/working-with-httpinterceptors.html - allowedUrls: [environment.backendUrl], + allowedUrls: environment.backendUrl ? [environment.backendUrl] : [], sendAccessToken: true, }, }), @@ -230,10 +231,20 @@ import {ActionMenuComponent} from "./view/action-menu/action-menu/action-menu.co SbbBreadcrumbModule, SbbAutocompleteModule, ], - bootstrap: [AppComponent], + bootstrap: environment.customElement ? [] : [AppComponent], providers: [ - {provide: BASE_PATH, useValue: environment.backendUrl}, + ... environment.backendUrl ? [{provide: BASE_PATH, useValue: environment.backendUrl}] : [], {provide: HTTP_INTERCEPTORS, useClass: HttpErrorInterceptor, multi: true}, ], }) -export class AppModule {} + +export class AppModule implements DoBootstrap { + constructor(private injector: Injector) {} + + ngDoBootstrap() { + if (environment.customElement) { + const element = createCustomElement(AppComponent, {injector: this.injector}); + customElements.define("sbb-root", element); + } + } +} diff --git a/src/app/netzgrafik-application/netzgrafik-application.component.html b/src/app/netzgrafik-application/netzgrafik-application.component.html index 9b3204a9..faadd9b3 100644 --- a/src/app/netzgrafik-application/netzgrafik-application.component.html +++ b/src/app/netzgrafik-application/netzgrafik-application.component.html @@ -1,7 +1,7 @@ - - + + - (); constructor( @@ -48,13 +52,24 @@ export class NetzgrafikApplicationComponent { .subscribe((params) => { uiInteractionService.setEditorMode(EditorMode.NetzgrafikEditing); uiInteractionService.showNetzgrafik(); - versionControlService.load(params.getVariantId(), true); + try { + versionControlService.load(params.getVariantId(), true); + } catch (e) { + versionControlService.loadNetzgrafikDTO(NetzgrafikDefault.getDefaultNetzgrafik()); + } uiInteractionService.setViewboxProperties( EditorView.svgName, uiInteractionService.getDefaultViewProperties()); }); } + getSidebarContainerStyle(): string { + if (this.disableBackend) { + return "top: 53px;"; + } + return "top: 85px;"; + } + getVariantIsWritable(): boolean { if (this.versionControlService.variant === null) { return true; diff --git a/src/app/services/auth/auth.service.ts b/src/app/services/auth/auth.service.ts index 854e73b4..246f8119 100644 --- a/src/app/services/auth/auth.service.ts +++ b/src/app/services/auth/auth.service.ts @@ -30,27 +30,28 @@ export class AuthService { private router: Router, location: Location, ) { - this.oauthService.configure(environment.authConfig); - this.oauthService.setupAutomaticSilentRefresh(); - // If the user should not be forcefully logged in (e.g. if you have pages, which can be - // accessed anonymously), change loadDiscoveryDocumentAndLogin to - // loadDiscoveryDocumentAndTryLogin and have a login functionality in the - // template of the component injecting the AuthService which calls the login() method. - this.initialized = this.oauthService - .loadDiscoveryDocumentAndLogin({state: location.path()}) - // If the user is not logged in, he will be forwarded to the identity provider - // and this promise will not resolve. After being redirected from the identity - // provider, the login promise will return true. - .then((v) => (v ? true : new Promise(() => {}))); - // Redirect the user to the url configured with state above or in a separate login call. - this.oauthService.events - .pipe(first((e) => e.type === "token_received")) - .subscribe(() => { - const state = decodeURIComponent(this.oauthService.state || ""); - if (state && state !== "/") { - this.router.navigate([state]); - } - }); + if (environment.disableBackend) return; + this.oauthService.configure(environment.authConfig); + this.oauthService.setupAutomaticSilentRefresh(); + // If the user should not be forcefully logged in (e.g. if you have pages, which can be + // accessed anonymously), change loadDiscoveryDocumentAndLogin to + // loadDiscoveryDocumentAndTryLogin and have a login functionality in the + // template of the component injecting the AuthService which calls the login() method. + this.initialized = this.oauthService + .loadDiscoveryDocumentAndLogin({state: location.path()}) + // If the user is not logged in, he will be forwarded to the identity provider + // and this promise will not resolve. After being redirected from the identity + // provider, the login promise will return true. + .then((v) => (v ? true : new Promise(() => {}))); + // Redirect the user to the url configured with state above or in a separate login call. + this.oauthService.events + .pipe(first((e) => e.type === "token_received")) + .subscribe(() => { + const state = decodeURIComponent(this.oauthService.state || ""); + if (state && state !== "/") { + this.router.navigate([state]); + } + }); } logOut() { diff --git a/src/app/services/data/undo.service.ts b/src/app/services/data/undo.service.ts index 492d4a56..2afce25f 100644 --- a/src/app/services/data/undo.service.ts +++ b/src/app/services/data/undo.service.ts @@ -128,4 +128,8 @@ export class UndoService implements OnDestroy { } this.currentVariantId = variantId; } + + public getCurrentVariantId():number{ + return this.currentVariantId; + } } diff --git a/src/app/services/data/version-control.service.ts b/src/app/services/data/version-control.service.ts index 8c266712..49323fcf 100644 --- a/src/app/services/data/version-control.service.ts +++ b/src/app/services/data/version-control.service.ts @@ -1,4 +1,4 @@ -import {Injectable, OnDestroy} from "@angular/core"; +import {HostListener, Injectable, OnDestroy} from "@angular/core"; import { VariantControllerBackendService, VariantDto, @@ -13,6 +13,7 @@ import {AutoSaveService} from "./auto-save.service"; import {LogService} from "../../logger/log.service"; import {VersionId} from "../../view/variant/variant-view/variant-history/model"; import {UndoService} from "./undo.service"; +import {environment} from "../../../environments/environment"; @Injectable({ providedIn: "root", @@ -34,7 +35,8 @@ export class VersionControlService implements OnDestroy { private readonly undoService: UndoService, private readonly logService: LogService, ) { - autoSaveService.autosaveTrigger$ + if (!environment.disableBackend) { + autoSaveService.autosaveTrigger$ .pipe( takeUntil(this.destroyed), filter(() => this.variant.isWritable), @@ -43,6 +45,7 @@ export class VersionControlService implements OnDestroy { logService.debug("auto saving changes"); this.createSnapshot(); }); + } } get variant(): VariantDto { @@ -69,6 +72,12 @@ export class VersionControlService implements OnDestroy { }); } + loadNetzgrafikDTO(netzgrafik: NetzgrafikDto) { + this.dataService.loadNetzgrafikDto(netzgrafik); + this.autoSaveService.reset(); + this.undoService.reset(this.undoService.getCurrentVariantId() + 1); + } + reload(loadModel = false): void { this.load(this.variant.id, loadModel); } diff --git a/src/app/view/column-layout/column-layout.component.html b/src/app/view/column-layout/column-layout.component.html index 2aae592b..3eee9f16 100644 --- a/src/app/view/column-layout/column-layout.component.html +++ b/src/app/view/column-layout/column-layout.component.html @@ -2,6 +2,7 @@ id="cd-layout-content" [ngClass]="['mode-' + mode]" [class.new-view]="newView" + [attr.style]="getLayoutContentStyle()" >
- + - + Stammdaten importieren Hilfe: CSV - Datei Date: Mon, 15 Jul 2024 15:05:06 +0200 Subject: [PATCH 014/197] bug fixed (#178) --- .../data-views/trainrunsection.previewline.view.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/app/view/editor-main-view/data-views/trainrunsection.previewline.view.ts b/src/app/view/editor-main-view/data-views/trainrunsection.previewline.view.ts index 529d584b..4eaab377 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsection.previewline.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsection.previewline.view.ts @@ -253,6 +253,9 @@ export class TrainrunSectionPreviewLineView { false, ); } + if (this.existingTrainrunSection !== null){ + D3Utils.removeGrayout(this.existingTrainrunSection); + } if (this.startNode !== null) { D3Utils.unhighlightNode(this.startNode); } From b99227f3e5e31fa30046a582c13bbf490b9b28bd Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 18 Jul 2024 10:03:44 +0200 Subject: [PATCH 015/197] 64 bug dark mode should be applyed to the whole netzgrafik editor content (#179) * initial dark/light mode fix commit * initial dark/light mode fix commit * initial dark/light mode fix commit * bug fixed (npm run test failed) * bug fixed (npm run test failed) * bug fixed (npm run test failed) * bug fixed (npm run test failed) * bug fixed (npm run test failed) * bug fixed (npm run test failed) * bug fixed (npm run test failed) * bug fixed (npm run test failed) * bug fixed (npm run test failed) * bug fixed (npm run test failed) * bug fixed (npm run test failed) * bug fixed (npm run test failed) * bug fixed (npm run test failed) : https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/pull/179#issuecomment-2232906983 * bug fixed - https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/pull/179#issuecomment-2233134898 * bug fixed - https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/pull/179#issuecomment-2233134898 * bug fixed - https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/pull/179#issuecomment-2233229471 * removed, no longer used * cleaned * cleaned * cleaned * fine tuning / coloring * fine tuning / coloring * fine tuning / coloring * fine tuning / coloring * removed console.log(localStoredInfo); --- src/app/app.component.ts | 6 +- .../netzgrafik-application.component.scss | 3 - .../perlenkette-node.component.html | 23 +-- .../perlenkette-node.component.scss | 10 +- .../perlenkette-section.component.html | 12 +- .../perlenkette-section.component.scss | 13 +- .../perlenkette/perlenkette.component.html | 4 +- .../perlenkette/perlenkette.component.scss | 20 +-- .../data/netzgrafikColoring.service.ts | 147 ++++++++---------- src/app/services/ui/ui.interaction.service.ts | 54 ++++++- .../view/card-grid/card/card.component.scss | 4 +- .../column-layout.component.scss | 10 +- .../htmlEditor/html-editor.component.scss | 10 +- .../htmlEditor/html-editor.component.ts | 10 +- .../note-dialog/note-dialog.component.scss | 8 +- ...trainrun-and-section-dialog.component.scss | 8 +- .../trainrun-tab/trainrun-tab.component.scss | 36 ++++- .../trainrun-section-tab.component.scss | 65 ++++---- .../editor-edit-tools-view.component.scss | 12 +- .../label-drop-list.component.scss | 6 +- .../editor-filter-view.component.html | 7 +- .../editor-filter-view.component.scss | 27 ---- .../filterable-label-filter.component.scss | 15 +- .../editor-menu/editor-menu.component.html | 2 +- .../editor-menu/editor-menu.component.scss | 124 +++++++-------- .../editor-properties-view.component.html | 14 +- .../editor-properties-view.component.ts | 9 ++ .../knoten-auslastung-view.component.scss | 10 +- .../knoten-auslastung-view.component.ts | 12 +- src/app/view/rastering/definitions.scss | 2 +- src/app/view/themes/theme-default-ux-dark.ts | 22 +-- src/app/view/themes/theme-fach-dark.ts | 26 ++-- src/app/view/themes/theme-gray-dark.ts | 18 +-- src/app/view/themes/theme-gray.ts | 2 +- src/app/view/themes/theme.spec.ts | 18 +-- .../variants-view.component.html | 2 +- src/index.html | 2 +- 37 files changed, 417 insertions(+), 356 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index b6e4ba48..8e4b8477 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -38,7 +38,10 @@ export class AppComponent { return this.authService.claims?.email; } - constructor(private authService: AuthService, private dataService: DataService, private trainrunService: TrainrunService, private trainrunSectionService: TrainrunSectionService) { + constructor(private authService: AuthService, + private dataService: DataService, + private trainrunService: TrainrunService, + private trainrunSectionService: TrainrunSectionService) { if (!this.disableBackend) { this.authenticated = authService.initialized; } @@ -54,6 +57,7 @@ export class AppComponent { get netzgrafikDto() { return this.dataService.getNetzgrafikDto(); } + set netzgrafikDto(netzgrafikDto: NetzgrafikDto) { this.dataService.loadNetzgrafikDto(netzgrafikDto); } diff --git a/src/app/netzgrafik-application/netzgrafik-application.component.scss b/src/app/netzgrafik-application/netzgrafik-application.component.scss index a4768aa8..aecb8008 100644 --- a/src/app/netzgrafik-application/netzgrafik-application.component.scss +++ b/src/app/netzgrafik-application/netzgrafik-application.component.scss @@ -1,12 +1,9 @@ ::ng-deep a.SideBarMainIcon { - background: whitesmoke; } ::ng-deep a.SideBarMainIcon:hover { - background: white; } a.SideBarMainIcon.sbb-active { pointer-events: all; - background: whitesmoke; } diff --git a/src/app/perlenkette/perlenkette-node/perlenkette-node.component.html b/src/app/perlenkette/perlenkette-node/perlenkette-node.component.html index d15f4c0e..ad5d5eaa 100644 --- a/src/app/perlenkette/perlenkette-node/perlenkette-node.component.html +++ b/src/app/perlenkette/perlenkette-node/perlenkette-node.component.html @@ -22,8 +22,8 @@ width="94px" height="28px" /> - {{ perlenketteNode.shortName }} - + {{ perlenketteNode.shortName }} + {{ perlenketteNode.connectionTime }} @@ -156,8 +156,8 @@ 20 + transformIndex(connectionIndex, connectionGrpKey) * surplus " dominant-baseline="text-after-edge" - class="edge_text station start" - style="fill: white; stroke-width: 6px; stroke: white" + class="edge_text station start layer0" + style=" stroke-width: 6px;" (click)="selectConnection(connection)" [ngClass]="[ getTextNameOrTimeClassTag(connection, connectionGrpKey, 0) @@ -188,9 +188,9 @@ " text-anchor="end" dominant-baseline="text-after-edge" - class="edge_text station end" + class="edge_text station end layer0" (click)="selectConnection(connection)" - style="fill: white; stroke-width: 6px; stroke: white" + style=" stroke-width: 6px;" [ngClass]="[ getTextNameOrTimeClassTag(connection, connectionGrpKey, 1) ]" @@ -220,9 +220,9 @@ 20 + transformIndex(connectionIndex, connectionGrpKey) * surplus " dominant-baseline="text-after-edge" - class="edge_text end station" + class="edge_text end station layer0" (click)="selectConnection(connection)" - style="fill: white; stroke-width: 6px; stroke: white" + style=" stroke-width: 6px;" [ngClass]="[ getTextTerminalStationlassTag(connection, connectionGrpKey, 0) ]" @@ -251,9 +251,9 @@ " text-anchor="start" dominant-baseline="text-after-edge" - class="edge_text start station" + class="edge_text start station layer0" (click)="selectConnection(connection)" - style="fill: white; stroke-width: 6px; stroke: white" + style=" stroke-width: 6px;" [ngClass]="[ getTextTerminalStationlassTag(connection, connectionGrpKey, 1) ]" @@ -326,13 +326,14 @@ - + {{ perlenketteNode.shortName }} {{ perlenketteNode.connectionTime }} diff --git a/src/app/perlenkette/perlenkette-node/perlenkette-node.component.scss b/src/app/perlenkette/perlenkette-node/perlenkette-node.component.scss index 933d6b4e..80fb9d4f 100644 --- a/src/app/perlenkette/perlenkette-node/perlenkette-node.component.scss +++ b/src/app/perlenkette/perlenkette-node/perlenkette-node.component.scss @@ -19,12 +19,12 @@ .main_rect { stroke: $COLOR_Default; - fill: white; + fill: var(--NODE_DOCKABLE); stroke-width: 1px; } .title_rect { - fill: var(--UI_DIALOG_NODE_COLOR_BACKGROUND); + fill: var(--NODE_COLOR_BACKGROUND); } .main_rect.no_stop_has_connections { @@ -38,7 +38,7 @@ } .non_stop_toogle { - fill: white; + fill: var(--NODE_DOCKABLE); } .non_stop_toogle.nonstop { @@ -67,6 +67,10 @@ text.edge_text.middle { text-anchor: middle; } +text.edge_text.station.layer0 { + stroke: var(--NODE_DOCKABLE) +} + path.SepConnectionLine { stroke: $COLOR_Default; stroke-width: 0.5px; diff --git a/src/app/perlenkette/perlenkette-section/perlenkette-section.component.html b/src/app/perlenkette/perlenkette-section/perlenkette-section.component.html index f3bf165e..aa27d2bd 100644 --- a/src/app/perlenkette/perlenkette-section/perlenkette-section.component.html +++ b/src/app/perlenkette/perlenkette-section/perlenkette-section.component.html @@ -107,14 +107,14 @@ y="1" width="12" height="22" - style="fill: white; cursor: pointer" + style="cursor: pointer; fill: var(--sbb-header-lean-background-color);" (click)="switchSectionViewToogleLock($event, 'leftDepartureTime')" > @@ -130,14 +130,14 @@ y="1" width="12" height="22" - style="fill: white; cursor: pointer" + style="cursor: pointer; fill: var(--sbb-header-lean-background-color);" (click)="switchSectionViewToogleLock($event, 'travelTime')" > @@ -151,14 +151,14 @@ y="1" width="12" height="22" - style="fill: white; cursor: pointer" + style="cursor: pointer; fill: var(--sbb-header-lean-background-color);" (click)="switchSectionViewToogleLock($event, 'rightDepatureTime')" > diff --git a/src/app/perlenkette/perlenkette-section/perlenkette-section.component.scss b/src/app/perlenkette/perlenkette-section/perlenkette-section.component.scss index d0dddfd7..71cc10ed 100644 --- a/src/app/perlenkette/perlenkette-section/perlenkette-section.component.scss +++ b/src/app/perlenkette/perlenkette-section/perlenkette-section.component.scss @@ -58,8 +58,8 @@ svg text.edge_text { grid-gap: 0; grid-auto-rows: 12px; grid-auto-columns: 32px; - border: 1px solid black; - background: white; + border: 1px solid var(--sbb-header-lean-border-bottom-color); + background: var(--sbb-header-lean-background-color); } .nodeBorderContainerTopLeft { @@ -130,27 +130,27 @@ svg text.edge_text { .TravelTimeLock { grid-column: 2; grid-row: 7 / span 3; - background: whitesmoke; + background: var(--COLOR_GRAYEDOUT); } .TravelTimeLock.Center { grid-column: 4; grid-row: 7 / span 3; - background: whitesmoke; + background: var(--COLOR_GRAYEDOUT); margin: 1px; } .NodeLeftLock { grid-column: 4; grid-row: 2 / span 3; - background: whitesmoke; + background: var(--COLOR_GRAYEDOUT); margin: 1px; } .NodeRightLock { grid-column: 4; grid-row: 13 / span 3; - background: whitesmoke; + background: var(--COLOR_GRAYEDOUT); margin: 1px; } } @@ -164,7 +164,6 @@ svg text.edge_text { } .PerlenketteFill5 { - fill: white; } .Rotation90 { diff --git a/src/app/perlenkette/perlenkette.component.html b/src/app/perlenkette/perlenkette.component.html index f04d9960..5731a3d0 100644 --- a/src/app/perlenkette/perlenkette.component.html +++ b/src/app/perlenkette/perlenkette.component.html @@ -3,10 +3,10 @@
- + - +
diff --git a/src/app/perlenkette/perlenkette.component.scss b/src/app/perlenkette/perlenkette.component.scss index c7aa0a7f..3bb498ce 100644 --- a/src/app/perlenkette/perlenkette.component.scss +++ b/src/app/perlenkette/perlenkette.component.scss @@ -49,7 +49,6 @@ button.SimpleButton { position: relative; left: 5px; top: 5px; - background: none; border: none; color: black; float: right; @@ -61,26 +60,22 @@ button.SimpleButton.ZoomEqual { } button.SimpleButton:hover { - background: none; font-weight: bold; transform: scale(1.25); } button.SimpleButton:active { - background: whitesmoke; } button.SimpleButton:disabled { opacity: 0.5; transform: scale(1); - background: white; } span.station { cursor: pointer; font-size: 22px; - background: none; - border: 5px solid white; + border: 5px solid var(--sbb-color-background); font-weight: lighter; user-select: none; } @@ -89,7 +84,6 @@ span.arrow { cursor: default; pointer-events: none; font-size: 22px; - background: none; user-select: none; } @@ -97,23 +91,20 @@ span.trainname { cursor: default; pointer-events: none; font-size: 22px; - background: none; - border: 5px solid white; + border: 5px solid var(--sbb-color-background); user-select: none; } span.smallstation { cursor: pointer; font-size: 12px; - background: none; - border: 3px solid white; + border: 3px solid var(--sbb-color-background); white-space: pre-wrap; font-weight: lighter; user-select: none; } span.smallstation:active { - background: whitesmoke; } span.smallstation.closest { @@ -135,3 +126,8 @@ span.smallstation:hover { color: var(--COLOR_Edit); stroke: var(--COLOR_Edit); } + +.ToggleAllEyesButton:hover { + stroke: var(--COLOR_Edit); + stroke-width: .5px; +} diff --git a/src/app/services/data/netzgrafikColoring.service.ts b/src/app/services/data/netzgrafikColoring.service.ts index f649643f..a874ddcb 100644 --- a/src/app/services/data/netzgrafikColoring.service.ts +++ b/src/app/services/data/netzgrafikColoring.service.ts @@ -35,20 +35,20 @@ export class NetzgrafikColoringService { ) { [ "path.edge_line.layer_3.Freq_30." + - StaticDomTags.TAG_UI_DIALOG + - " { stroke: whitesmoke; }", + StaticDomTags.TAG_UI_DIALOG + + " { stroke: var(--sbb-header-lean-background-color); }", "path.edge_line.layer_2.Freq_20." + - StaticDomTags.TAG_UI_DIALOG + - " { stroke: whitesmoke; }", + StaticDomTags.TAG_UI_DIALOG + + " { stroke: var(--sbb-header-lean-background-color); }", "path.edge_line.layer_1.Freq_15." + - StaticDomTags.TAG_UI_DIALOG + - " { stroke: whitesmoke; }", + StaticDomTags.TAG_UI_DIALOG + + " { stroke: var(--sbb-header-lean-background-color); }", "path.edge_line.layer_3.Freq_15." + - StaticDomTags.TAG_UI_DIALOG + - " { stroke: whitesmoke; }", + StaticDomTags.TAG_UI_DIALOG + + " { stroke: var(--sbb-header-lean-background-color); }", "path.edge_line.layer_3.Freq_15." + - StaticDomTags.TAG_UI_DIALOG + - " { stroke: whitesmoke; }", + StaticDomTags.TAG_UI_DIALOG + + " { stroke: var(--sbb-header-lean-background-color); }", ].forEach((rule) => { sheet.insertRule(rule, sheet.cssRules.length); if (verbose) { @@ -87,16 +87,8 @@ export class NetzgrafikColoringService { { tag: "", color: - StaticDomTags.TAG_UI_DIALOG + - "_" + - StaticDomTags.PREFIX_COLOR_VARIABLE + - "_" + - colorRef + - "_" + - StaticDomTags.TAG_FOCUS.toUpperCase(), + "NODE_TEXT_FOCUS", backgroundColor: - StaticDomTags.TAG_UI_DIALOG + - "_" + StaticDomTags.PREFIX_COLOR_VARIABLE + "_" + colorRef + @@ -106,16 +98,8 @@ export class NetzgrafikColoringService { { tag: StaticDomTags.TAG_SELECTED, color: - StaticDomTags.TAG_UI_DIALOG + - "_" + - StaticDomTags.PREFIX_COLOR_VARIABLE + - "_" + - colorRef + - "_" + - StaticDomTags.TAG_MUTED.toUpperCase(), + "sbb-color-white", backgroundColor: - StaticDomTags.TAG_UI_DIALOG + - "_" + StaticDomTags.PREFIX_COLOR_VARIABLE + "_" + colorRef + @@ -304,6 +288,11 @@ export class NetzgrafikColoringService { setDarkMode(darkMode) { this.isDarkMode = darkMode; this.generateColors(); + + document.documentElement.style.setProperty( + "--Button_TrainrunDialog_opacity", + this.isDarkMode ? "0.6" : "0.9", + ); } generateColors() { @@ -312,80 +301,80 @@ export class NetzgrafikColoringService { document.documentElement.style.setProperty( "--" + - StaticDomTags.PREFIX_COLOR_VARIABLE + - "_" + - netzgrafikColor.getColorRef(), + StaticDomTags.PREFIX_COLOR_VARIABLE + + "_" + + netzgrafikColor.getColorRef(), colors.color, ); document.documentElement.style.setProperty( "--" + - StaticDomTags.PREFIX_COLOR_VARIABLE + - "_" + - netzgrafikColor.getColorRef() + - "_" + - StaticDomTags.TAG_FOCUS.toUpperCase(), + StaticDomTags.PREFIX_COLOR_VARIABLE + + "_" + + netzgrafikColor.getColorRef() + + "_" + + StaticDomTags.TAG_FOCUS.toUpperCase(), colors.colorFocus, ); document.documentElement.style.setProperty( "--" + - StaticDomTags.PREFIX_COLOR_VARIABLE + - "_" + - netzgrafikColor.getColorRef() + - "_" + - StaticDomTags.TAG_MUTED.toUpperCase(), + StaticDomTags.PREFIX_COLOR_VARIABLE + + "_" + + netzgrafikColor.getColorRef() + + "_" + + StaticDomTags.TAG_MUTED.toUpperCase(), colors.colorMuted, ); document.documentElement.style.setProperty( "--" + - StaticDomTags.PREFIX_COLOR_VARIABLE + - "_" + - netzgrafikColor.getColorRef() + - "_" + - StaticDomTags.TAG_RELATED.toUpperCase(), + StaticDomTags.PREFIX_COLOR_VARIABLE + + "_" + + netzgrafikColor.getColorRef() + + "_" + + StaticDomTags.TAG_RELATED.toUpperCase(), colors.colorRelated, ); const uiColors = netzgrafikColor.getColors(false); document.documentElement.style.setProperty( "--" + - StaticDomTags.TAG_UI_DIALOG + - "_" + - StaticDomTags.PREFIX_COLOR_VARIABLE + - "_" + - netzgrafikColor.getColorRef(), + StaticDomTags.TAG_UI_DIALOG + + "_" + + StaticDomTags.PREFIX_COLOR_VARIABLE + + "_" + + netzgrafikColor.getColorRef(), uiColors.color, ); document.documentElement.style.setProperty( "--" + - StaticDomTags.TAG_UI_DIALOG + - "_" + - StaticDomTags.PREFIX_COLOR_VARIABLE + - "_" + - netzgrafikColor.getColorRef() + - "_" + - StaticDomTags.TAG_FOCUS.toUpperCase(), + StaticDomTags.TAG_UI_DIALOG + + "_" + + StaticDomTags.PREFIX_COLOR_VARIABLE + + "_" + + netzgrafikColor.getColorRef() + + "_" + + StaticDomTags.TAG_FOCUS.toUpperCase(), uiColors.colorFocus, ); document.documentElement.style.setProperty( "--" + - StaticDomTags.TAG_UI_DIALOG + - "_" + - StaticDomTags.PREFIX_COLOR_VARIABLE + - "_" + - netzgrafikColor.getColorRef() + - "_" + - StaticDomTags.TAG_MUTED.toUpperCase(), + StaticDomTags.TAG_UI_DIALOG + + "_" + + StaticDomTags.PREFIX_COLOR_VARIABLE + + "_" + + netzgrafikColor.getColorRef() + + "_" + + StaticDomTags.TAG_MUTED.toUpperCase(), uiColors.colorMuted, ); document.documentElement.style.setProperty( "--" + - StaticDomTags.TAG_UI_DIALOG + - "_" + - StaticDomTags.PREFIX_COLOR_VARIABLE + - "_" + - netzgrafikColor.getColorRef() + - "_" + - StaticDomTags.TAG_RELATED.toUpperCase(), + StaticDomTags.TAG_UI_DIALOG + + "_" + + StaticDomTags.PREFIX_COLOR_VARIABLE + + "_" + + netzgrafikColor.getColorRef() + + "_" + + StaticDomTags.TAG_RELATED.toUpperCase(), uiColors.colorRelated, ); }); @@ -547,8 +536,8 @@ export class NetzgrafikColoringService { colorRef, "fill", StaticDomTags.EDGE_LINE_STOPS_DOM_REF + - "." + - StaticDomTags.EDGE_LINE_STOPS_FILL, + "." + + StaticDomTags.EDGE_LINE_STOPS_FILL, verbose, ); NetzgrafikColoringService.generateColors( @@ -577,8 +566,8 @@ export class NetzgrafikColoringService { colorRef, "fill", StaticDomTags.EDGE_LINE_STOP_ICON_CLASS_DOM_REF + - "." + - StaticDomTags.TAG_FILL, + "." + + StaticDomTags.TAG_FILL, verbose, ); NetzgrafikColoringService.generateColors( @@ -597,21 +586,21 @@ export class NetzgrafikColoringService { ); // TODO - Knotenauslastung refactoring will impact this part - NetzgrafikColoringService.generateUIColors( + NetzgrafikColoringService.generateColors( sheetKnotenauslastung, colorRef, "stroke", StaticDomTags.KNOTENAUSLASTUNG_DATA_GROUP_PATH, verbose, ); - NetzgrafikColoringService.generateUIColors( + NetzgrafikColoringService.generateColors( sheetKnotenauslastung, colorRef, "fill", StaticDomTags.KNOTENAUSLASTUNG_DATA_GROUP_PATH, verbose, ); - NetzgrafikColoringService.generateUIColors( + NetzgrafikColoringService.generateColors( sheetKnotenauslastung, colorRef, "fill", diff --git a/src/app/services/ui/ui.interaction.service.ts b/src/app/services/ui/ui.interaction.service.ts index 2174c6c2..b09bbae7 100644 --- a/src/app/services/ui/ui.interaction.service.ts +++ b/src/app/services/ui/ui.interaction.service.ts @@ -135,6 +135,16 @@ export class UiInteractionService implements OnDestroy { private loadPerlenketteService: LoadPerlenketteService, ) { this.activeTheme = null; + this.loadActiveTheme(); + + // listen for browser setting update + window + .matchMedia("(prefers-color-scheme: dark)") + .addEventListener("change", event => { + this.activeTheme = null; + this.loadActiveTheme(); + }); + this.activeStreckengrafikRenderingType = null; this.activeTravelTimeCreationEstimatorType = null; @@ -207,10 +217,33 @@ export class UiInteractionService implements OnDestroy { this.windowViewboxPropertiesMap[key] = Object.assign({}, viewboxProperties); } + isLocalStoredColorTheme() { + const serializedState = localStorage.getItem("UiInteractionService"); + if ( + serializedState === null || + serializedState === undefined || + serializedState === "undefined" + ) { + return false; + } + return true; + } + + resetLocalStoredColorData() { + localStorage.removeItem("UiInteractionService"); + this.activeTheme = null; + this.loadActiveTheme(); + } + loadActiveTheme() { this.loadUserSettingFromLocalStorage(); if (this.activeTheme === null) { - this.activeTheme = new ThemeFach(); + // detect at initialization + if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) { + this.setActiveTheme(new ThemeFachDark(), false); + } else { + this.setActiveTheme(new ThemeFach(), false); + } this.netzgrafikColoringService.setDarkMode(this.activeTheme.isDark); } if (this.activeStreckengrafikRenderingType === null) { @@ -399,7 +432,7 @@ export class UiInteractionService implements OnDestroy { return this.editorMode; } - disableMultiSelectedNodesCorridor(){ + disableMultiSelectedNodesCorridor() { this.isMultiSelectedNodesCorridor = false; } @@ -407,14 +440,24 @@ export class UiInteractionService implements OnDestroy { this.isMultiSelectedNodesCorridor = true; } - isMultiSelectedNodesCorridorEnabled(){ + isMultiSelectedNodesCorridorEnabled() { return this.isMultiSelectedNodesCorridor; } - private setActiveTheme(theme: ThemeBase) { + private setActiveTheme(theme: ThemeBase, updateLocalStorage = true) { this.activeTheme = theme; this.netzgrafikColoringService.setDarkMode(this.activeTheme.isDark); - this.saveUserSettingToLocalStorage(); + if (updateLocalStorage) { + this.saveUserSettingToLocalStorage(); + } + this.updateLightDark(); + } + + updateLightDark() { + const el = document.getElementById("NetzgrafikRootHtml"); + if (el) { + el.className = "sbb-lean" + (this.getActiveTheme().isDark ? " sbb-dark" : " sbb-light"); + } } private loadUserSettingFromLocalStorage() { @@ -428,7 +471,6 @@ export class UiInteractionService implements OnDestroy { return; } const localStoredInfo = JSON.parse(serializedState); - console.log(localStoredInfo); const activeTheme = localStoredInfo.activeTheme; this.createTheme( activeTheme.themeRegistration, diff --git a/src/app/view/card-grid/card/card.component.scss b/src/app/view/card-grid/card/card.component.scss index 8d2dc59b..4995d29e 100644 --- a/src/app/view/card-grid/card/card.component.scss +++ b/src/app/view/card-grid/card/card.component.scss @@ -2,7 +2,7 @@ .card { border-radius: 4px; - background: sbb.$sbbColorCloud; + background: var(--sbb-header-lean-border-bottom-color); padding: 24px; min-width: 320px; min-height: 128px; @@ -24,5 +24,5 @@ display: flex; align-items: center; justify-content: center; - background: sbb.$sbbColorMilk; + background: var(--sbb-menu-item-background-color-hover); } diff --git a/src/app/view/column-layout/column-layout.component.scss b/src/app/view/column-layout/column-layout.component.scss index 6afa6739..313a6c94 100644 --- a/src/app/view/column-layout/column-layout.component.scss +++ b/src/app/view/column-layout/column-layout.component.scss @@ -45,10 +45,8 @@ $close-size: $close-padding * 2 + $defaultIconSize; position: relative; // absolute positioned children should be relative to column width: column-width(1); @include transitionLong(width, opacity, margin-left); - background-color: white; &#cd-layout-main { - background: transparent; } } @@ -68,8 +66,10 @@ $close-size: $close-padding * 2 + $defaultIconSize; top: $interComponentSpacingSmall; border-radius: 50%; // assure scrollbar is only hidden by actual (half-)circle + transform: scale(0.95); + z-index: 3; - background-color: white; + background: var(--sbb-color-background); fill: $colorBlack20; padding: $close-padding; margin-left: -(calc($close-size/2)); @@ -128,10 +128,12 @@ $close-size: $close-padding * 2 + $defaultIconSize; box-sizing: border-box; position: absolute; top: $interComponentSpacingSmall; + background: var(--sbb-color-background); border-radius: 50%; // assure scrollbar is only hidden by actual (half-)circle + transform: scale(0.95); + z-index: 3; - background-color: white; fill: $colorBlack20; padding: $close-padding; margin-right: -(calc($close-size/2)); diff --git a/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.scss b/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.scss index e06b1526..e6334015 100644 --- a/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.scss +++ b/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.scss @@ -9,7 +9,7 @@ border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom: 1px solid rgba(0, 0, 0, 0.2); - background: whitesmoke; + background: var(--sbb-header-lean-background-color); } .NgxEditor { @@ -33,6 +33,8 @@ max-height: 150px; min-height: 150px; overflow-y: auto; + background: var(--sbb-header-lean-background-color); + color: var(--NODE_TEXT_FOCUS); } } @@ -42,9 +44,9 @@ display: inline-flex; flex-wrap: wrap; margin: 1px; - background: whitesmoke; - border-right: 1px solid rgba(0, 0, 0, 0.2); - border-bottom: 1px solid rgba(0, 0, 0, 0.2); + background: var(--sbb-header-lean-background-color); + border-right: 1px solid var(--sbb-header-lean-border-bottom-color); + border-bottom: 1px solid var(--sbb-header-lean-border-bottom-color); } ::ng-deep button.ngx-html-editor-color { diff --git a/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.ts b/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.ts index 4bb5aefd..2f4527f0 100644 --- a/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.ts +++ b/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.ts @@ -107,11 +107,15 @@ export class HtmlEditorComponent implements OnInit, OnDestroy { getColorStyle(color: HtmlEditorColor): string { if (color === undefined) { if (this.textBasedActiveColor.length > 0) { - return "background: #e8f0fe;"; + return "background: var(--sbb-header-lean-background-color);" + + "color: var(--NODE_TEXT_FOCUS); " + + "transform: translate(2px, 2px);"; } - return ""; + return "background: var(--sbb-header-lean-background-color); " + + "transform: translate(2px, 2px);" + + "opacity: 0.25"; } - return "background: " + color.colorCode + ";"; + return "background: " + color.colorCode + "; color: var(--NODE_TEXT_FOCUS);"; } setClassedTag(color: HtmlEditorColor): string { diff --git a/src/app/view/dialogs/note-dialog/note-dialog.component.scss b/src/app/view/dialogs/note-dialog/note-dialog.component.scss index 0fd56492..ee31f30a 100644 --- a/src/app/view/dialogs/note-dialog/note-dialog.component.scss +++ b/src/app/view/dialogs/note-dialog/note-dialog.component.scss @@ -8,15 +8,15 @@ ::ng-deep .MainNoteTabViewDialog { position: relative; padding-top: 4px; // optical alignment - border: 1px solid #000000; + border: 1px solid var(--sbb-menu-item-label); min-height: 460px; max-height: 460px; - background-color: white; + background-color: var(--sbb-header-lean-background-color); &:before, &:after { border: 16px solid transparent; - border-top-color: #000000; + border-top-color: var(--sbb-menu-item-label); content: ""; position: absolute; top: 100%; @@ -27,7 +27,7 @@ &:after { margin-top: -0.75px; - border-top-color: #ffffff; + border-top-color: var(--sbb-header-lean-background-color); } .NoteTabGrupe { diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-and-section-dialog.component.scss b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-and-section-dialog.component.scss index 1836c723..cf74286e 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-and-section-dialog.component.scss +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-and-section-dialog.component.scss @@ -8,15 +8,15 @@ ::ng-deep .MainTrainrunTabViewDialog { position: relative; padding-top: 4px; // optical alignment - border: 1px solid #000000; + border: 1px solid var(--sbb-menu-item-label); min-height: 385px; max-height: 385px; - background-color: white; + background-color: var(--sbb-header-lean-background-color); &:before, &:after { border: 16px solid transparent; - border-top-color: #000000; + border-top-color: var(--sbb-menu-item-label); content: ""; position: absolute; top: 100%; @@ -27,7 +27,7 @@ &:after { margin-top: -0.75px; - border-top-color: #ffffff; + border-top-color: var(--sbb-header-lean-background-color); } .TrainrunTabGrupe { diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.scss b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.scss index 6b93ca59..261cbdf0 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.scss +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.scss @@ -1,6 +1,14 @@ @import "../../../rastering/definitions"; @import "../../../../../variables"; +::ng-deep .sbb-tab-body-wrapper { + background: var(--sbb-header-lean-background-color); +} + +::ng-deep div.sbb-tab-label { + background: var(--sbb-header-lean-background-color); +} + ::ng-deep .sbb-trainrun-chip-group { display: flex; } @@ -20,10 +28,24 @@ border-radius: 16px; background-color: $COLOR_BACKGROUND; + + opacity: var(--Button_TrainrunDialog_opacity); + + &.FilterableLabel { + opacity: 1.0; + } + + &.EditorToolButton { + opacity: 1.0; + border: none; + } + &.selected { color: $COLOR_Focus; background-color: white; border-color: $COLOR_Focus; + + opacity: 1.0; } } @@ -48,27 +70,31 @@ } ::ng-deep button.Frequency { - color: black; - background-color: whitesmoke; + color: var(--NODE_TEXT_FOCUS); + background-color: var(--NODE_COLOR_BACKGROUND); border-color: transparent; + opacity: 1.0; } ::ng-deep button.Frequency.selected { color: white; background-color: $COLOR_Default; border-color: transparent; + opacity: 1.0; } ::ng-deep button.TimeCategory { - color: black; - background-color: whitesmoke; + color: var(--NODE_TEXT_FOCUS); + background-color: var(--NODE_COLOR_BACKGROUND); border-color: transparent; + opacity: 1.0; } ::ng-deep button.TimeCategory.selected { color: white; background-color: $COLOR_Default; border-color: transparent; + opacity: 1.0; } ::ng-deep div.EditTrainrunDialogTabContent { @@ -87,3 +113,5 @@ padding: 0px; min-height: 270px; } + + diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.scss b/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.scss index 82e01e59..886d9e45 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.scss +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.scss @@ -5,10 +5,10 @@ width: 40px; min-width: 40px; max-width: 40px; - border: white; + border: var(--sbb-header-lean-background-color); border-style: solid; border-width: thin; - border-bottom: darkgrey; + border-bottom: var(--sbb-menu-item-label); border-bottom-style: solid; border-bottom-width: thin; transform: translate(-4px, -18px); @@ -18,10 +18,10 @@ width: 70px; min-width: 70px; max-width: 70px; - border: white; + border: var(--sbb-header-lean-background-color); border-style: solid; border-width: thin; - border-bottom: darkgrey; + border-bottom: var(--sbb-menu-item-label); border-bottom-style: solid; border-bottom-width: thin; transform: translate(4px, -18px); @@ -43,11 +43,11 @@ max-width: 110px; padding: 1px; height: 40px; - border: 0.1px solid white; + border: 0.1px solid var(--sbb-background-color); } ::ng-deep .EditTrainrunSectionDialogHeaderCenter.IsActive { - border: 0.1px solid black; + border: 0.1px solid var(--sbb-menu-item-label); } ::ng-deep .EditTrainrunSectionDialogHeaderRight { @@ -61,9 +61,8 @@ } ::ng-deep input.NumberOfStopsInputElement { - background-color: white; - border: 0.1px solid lightgrey; - color: black; + background-color: var(--sbb-background-color); + border: 0.1px solid var(--sbb-menu-item-label); border-radius: 0px; width: 40px; height: 28px; @@ -75,11 +74,11 @@ input.NumberOfStopsInputElement.show { } input.NumberOfStopsInputElement:focus { - border: 0.1px solid white; + border: 0.1px solid var(--sbb-background-color); } input.NumberOfStopsInputElement.IsActive { - border: 0.1px solid white; + border: 0.1px solid var(--sbb-background-color); } ::ng-deep .mainGridLayout { @@ -104,7 +103,7 @@ input.NumberOfStopsInputElement.IsActive { } ::ng-deep div.NodeLeftArrival { - border: 1px solid black; + border: 1px solid var(--sbb-menu-item-label); } ::ng-deep .NodeLeftArrivalMinus { @@ -128,7 +127,7 @@ input.NumberOfStopsInputElement.IsActive { } ::ng-deep div.NodeLeftDeparture { - border: 1px solid black; + border: 1px solid var(--sbb-menu-item-label); } ::ng-deep .NodeLeftDepartureMinus { @@ -149,7 +148,7 @@ input.NumberOfStopsInputElement.IsActive { ::ng-deep .NodeLefttLock { grid-column: 2/3; grid-row: 2; - background: white; + background: var(--sbb-header-lean-background-color); } ::ng-deep .NodeRightArrival { @@ -158,7 +157,7 @@ input.NumberOfStopsInputElement.IsActive { } ::ng-deep div.NodeRightArrival { - border: 1px solid black; + border: 1px solid var(--sbb-menu-item-label); } ::ng-deep .NodeRightArrivalMinus { @@ -179,7 +178,7 @@ input.NumberOfStopsInputElement.IsActive { ::ng-deep .NodeRightLock { grid-column: 14/15; grid-row: 2; - background: white; + background: var(--sbb-header-lean-background-color); } ::ng-deep .NodeRightDeparture { @@ -188,7 +187,7 @@ input.NumberOfStopsInputElement.IsActive { } ::ng-deep div.NodeRightDeparture { - border: 1px solid black; + border: 1px solid var(--sbb-menu-item-label); } ::ng-deep .NodeRightDepartureMinus { @@ -212,7 +211,7 @@ input.NumberOfStopsInputElement.IsActive { } ::ng-deep div.TravelTime { - border: 1px solid black; + border: 1px solid var(--sbb-menu-item-label); } ::ng-deep .TravelTimeMinus { @@ -233,7 +232,7 @@ input.NumberOfStopsInputElement.IsActive { ::ng-deep .TravelTimeLock { grid-column: 11; grid-row: 2; - background: white; + background: var(--sbb-header-lean-background-color); } ::ng-deep .TravelFreqLeft { @@ -254,7 +253,7 @@ input.NumberOfStopsInputElement.IsActive { padding: 6px; width: 64px; height: 32px; - border: 0px solid white; + border: 0px solid var(--sbb-background-color); text-align: center; margin: 2px; min-height: 30px; @@ -268,7 +267,7 @@ input.NumberOfStopsInputElement.IsActive { padding: 6px; width: 63px; height: 30px; - border: 0px solid white; + border: 0px solid var(--sbb-background-color); text-align: center; margin: 1px; } @@ -281,7 +280,7 @@ input.NumberOfStopsInputElement.IsActive { padding: 6px; width: 63px; height: 30px; - border: 0px solid white; + border: 0px solid var(--sbb-background-color); text-align: center; margin: 1px; background: $COLOR_Edit; @@ -300,13 +299,13 @@ input.NumberOfStopsInputElement.IsActive { padding-left: 1px; padding-top: 1px; margin: 3px; - background-color: white; + background-color: var(--sbb-background-color); outline: none; cursor: pointer; } ::ng-deep .ButtonPlus:hover { - background-color: whitesmoke; + background-color: $COLOR_MUTED_SILVER; } ::ng-deep .ButtonMinus { @@ -317,13 +316,13 @@ input.NumberOfStopsInputElement.IsActive { padding-right: 1px; padding-top: 1px; margin: 3px; - background-color: white; + background-color: var(--sbb-background-color); outline: none; cursor: pointer; } ::ng-deep .ButtonMinus:hover { - background-color: whitesmoke; + background-color: $COLOR_MUTED_SILVER; } ::ng-deep .ButtonTravelTimeLock { @@ -355,13 +354,13 @@ input.NumberOfStopsInputElement.IsActive { padding-left: 1px; padding-top: 1px; margin: 1px; - background-color: white; + background-color: var(--sbb-background-color); outline: none; cursor: pointer; } ::ng-deep input.NumberOfStopsInputButtonPlusMinus:hover { - background-color: whitesmoke; + background-color: $COLOR_MUTED_SILVER; } ::ng-deep path.edgeLineTitle { @@ -374,26 +373,26 @@ input.NumberOfStopsInputElement.IsActive { } ::ng-deep svg.InputNumberOfStopsButtonPlusMinus:hover { - background-color: whitesmoke; + background-color: $COLOR_MUTED_SILVER; } ::ng-deep button.FunctionButton { - background-color: white; + background-color: var(--sbb-background-color); border-style: hidden; padding: 2px 0px 0px 0; margin: 0; } ::ng-deep button.FunctionButton:hover { - background-color: whitesmoke; + background-color: $COLOR_MUTED_SILVER; } ::ng-deep button.FunctionButton:active { - background-color: lightgray; + background-color: var(--sbb-menu-item-label); } ::ng-deep - div.sbb-dialog-content.sbb-scrollbar.EditTrainrunSectionDialogTabContent { +div.sbb-dialog-content.sbb-scrollbar.EditTrainrunSectionDialogTabContent { border-style: none; min-height: 250px; max-height: 250px; diff --git a/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.scss b/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.scss index 887781c6..57a084b2 100644 --- a/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.scss +++ b/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.scss @@ -40,7 +40,7 @@ width: 373px; min-width: 373px; max-width: 373px; - background: whitesmoke; + background: var(--sbb-header-lean-border-bottom-color); border-radius: 4px; overflow: hidden; float: left; @@ -57,21 +57,25 @@ margin: 5px 0px 5px 0px; } +::ng-deep .sbb-icon.LabelAddGroupButton:hover { + background-color: $COLOR_MUTED_SILVER; +} + ::ng-deep button.filterable-label-grp-delete-add-button-button { border: none; fill: white; min-height: 44px; max-width: 44px; - background: white; + background: var(--sbb-expansion-panel-background-color-open); border-radius: 4px; } ::ng-deep button.filterable-label-grp-delete-add-button-button:hover { fill: whitesmoke; - background: whitesmoke; + background: var(--sbb-expansion-panel-background-color); } ::ng-deep .TrainrunDialog.EditorToolButton.disabled { - background: whitesmoke; + background: var(--sbb-expansion-panel-background-color); color: lightgray; } diff --git a/src/app/view/editor-edit-tools-view-component/label-drop-list/label-drop-list.component.scss b/src/app/view/editor-edit-tools-view-component/label-drop-list/label-drop-list.component.scss index 099941f3..51fb1ea1 100644 --- a/src/app/view/editor-edit-tools-view-component/label-drop-list/label-drop-list.component.scss +++ b/src/app/view/editor-edit-tools-view-component/label-drop-list/label-drop-list.component.scss @@ -25,7 +25,7 @@ width: 80%; min-width: 80%; max-width: 80%; - background: whitesmoke; + background: var(--sbb-header-lean-border-bottom-color); border-radius: 4px; overflow: hidden; float: left; @@ -59,13 +59,13 @@ fill: white; min-height: 44px; max-width: 44px; - background: white; + background: var(--sbb-header-lean-background-color); border-radius: 4px; } .button.filterable-label-grp-delete-add-button-button:hover { fill: whitesmoke; - background: whitesmoke; + background: var(--sbb-expansion-panel-background-color); } .cdk-drag-placeholder { diff --git a/src/app/view/editor-filter-view/editor-filter-view.component.html b/src/app/view/editor-filter-view/editor-filter-view.component.html index 2b633f49..e3de21d2 100644 --- a/src/app/view/editor-filter-view/editor-filter-view.component.html +++ b/src/app/view/editor-filter-view/editor-filter-view.component.html @@ -225,6 +225,7 @@

Filter

height="13px" width="13px" aria-hidden="false" + style="transform: translate(-4px, 2px);" > @@ -235,6 +236,7 @@

Filter

height="13px" width="13px" aria-hidden="false" + style="transform: translate(-4px, 2px);" > @@ -260,6 +262,8 @@

Filter

height="13px" width="13px" aria-hidden="false" + style="transform: translate(-4px, 2px);" + > @@ -274,6 +278,7 @@

Filter

height="13px" width="13px" aria-hidden="false" + style="transform: translate(-4px, 2px);" > @@ -287,7 +292,7 @@

Filter

>
diff --git a/src/app/view/editor-filter-view/editor-filter-view.component.scss b/src/app/view/editor-filter-view/editor-filter-view.component.scss index 97a55ebf..7926573f 100644 --- a/src/app/view/editor-filter-view/editor-filter-view.component.scss +++ b/src/app/view/editor-filter-view/editor-filter-view.component.scss @@ -3,18 +3,12 @@ @import "../dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component"; ::ng-deep .TrainrunDialog.EditorToolButton { - background: $COLOR_Default; - border: $COLOR_Default; - color: white; max-width: none; min-height: 38px; margin-bottom: 16px; } ::ng-deep .TrainrunDialog.EditorToolButton:active { - background: lightgrey; - color: $COLOR_Default; - border: lightgrey; } ::ng-deep .SummaryTitle { @@ -27,29 +21,21 @@ border-radius: 10px; border: 1px; height: 32px; - color: black; text-align: center; text-decoration: none; display: inline-block; cursor: pointer; - background-color: white; - border-color: darkgrey; border-style: solid; font-family: "SBBWeb Light", "Helvetica Neue", Helvetica, Arial, sans-serif; } ::ng-deep button.NetzgrafikButton:hover { - background-color: whitesmoke; } ::ng-deep button.NetzgrafikButton:active { - background-color: lightgray; } ::ng-deep button.NetzgrafikButton:disabled { - background-color: white; - color: lightgray; - border-color: whitesmoke; } ::ng-deep .sbb-expansion-panel-body h4:first-child { @@ -98,33 +84,20 @@ cursor: pointer; border: 1px solid transparent; border-radius: 16px; - background-color: whitesmoke; &.selected { - color: white; - background-color: $COLOR_Default; - border-color: white; } &.add_button { - background: whitesmoke; - color: black; - border: white; } &.function { - background: white; - color: black; - border: white; min-width: 40px; max-width: 40px; } } ::ng-deep .FilterSettting:active { - background: $COLOR_Default; - color: white; - border: lightgrey; } .sbb-filtersetting-chip-group { diff --git a/src/app/view/editor-filter-view/filterable-label-filter/filterable-label-filter.component.scss b/src/app/view/editor-filter-view/filterable-label-filter/filterable-label-filter.component.scss index a96b9854..b2121243 100644 --- a/src/app/view/editor-filter-view/filterable-label-filter/filterable-label-filter.component.scss +++ b/src/app/view/editor-filter-view/filterable-label-filter/filterable-label-filter.component.scss @@ -4,7 +4,7 @@ ::ng-deep button.TrainrunDialog.FilterableLabel { background-color: $COLOR_Default; - color: whitesmoke; + color: white; border: whitesmoke; max-width: none; min-height: 38px; @@ -16,18 +16,19 @@ } ::ng-deep button.TrainrunDialog.FilterableLabel.selected { - background-color: whitesmoke; - color: $COLOR_Focus; - border: whitesmoke; + background-color: var(--NODE_COLOR_BACKGROUND); + color: var(--NODE_TEXT_FOCUS); + border: 1px solid var(--NODE_COLOR_BACKGROUND); } + ::ng-deep button.TrainrunDialog.FilterableLabel.LogicalOperator { - background-color: white; + background-color: var(--sbb-expansion-panel-background-color-open); color: $COLOR_Default; margin: 4px; } ::ng-deep button.TrainrunDialog.FilterableLabel.LogicalOperator:active { - background-color: whitesmoke; + background-color: var(--COLOR_GRAYEDOUT); color: $COLOR_Default; } @@ -48,7 +49,7 @@ width: 330px; min-width: 330px; max-width: 330px; - background: white; + background: var(--sbb-expansion-panel-background-color-open); border-radius: 4px; overflow: hidden; float: right; diff --git a/src/app/view/editor-menu/editor-menu.component.html b/src/app/view/editor-menu/editor-menu.component.html index d01a54ac..64666f83 100644 --- a/src/app/view/editor-menu/editor-menu.component.html +++ b/src/app/view/editor-menu/editor-menu.component.html @@ -217,7 +217,7 @@ > diff --git a/src/app/view/editor-menu/editor-menu.component.scss b/src/app/view/editor-menu/editor-menu.component.scss index cf42cb4c..b6931a9a 100644 --- a/src/app/view/editor-menu/editor-menu.component.scss +++ b/src/app/view/editor-menu/editor-menu.component.scss @@ -34,7 +34,6 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; height: 100%; padding: 0 8px 0 8px; margin: 0; - background-color: white; outline: none; border: none; border-left: $BORDER_SIZE solid $COLOR_MUTED_SILVER; @@ -97,17 +96,16 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; font-size: 25px; padding: 8px 0 0 0; margin: 0; - background-color: white; outline: none; border: none; } .ButtonSave:hover { - background-color: whitesmoke; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .ButtonSave:active { - background-color: lightgray; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-default); } .ButtonLoad > input { @@ -123,17 +121,16 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; font-size: 25px; padding: 8px 0 0 0; margin: 0; - background-color: white; outline: none; border: none; } .ButtonLoad:hover { - background-color: whitesmoke; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .ButtonLoad:active { - background-color: lightgray; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-default); } .ButtonFilter { @@ -145,7 +142,6 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; font-size: 25px; padding: 8px 0 0 0; margin: 0; - background-color: white; outline: none; border-top-style: none; border-right: $BORDER_SIZE solid $COLOR_MUTED_SILVER; @@ -155,11 +151,11 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; } .ButtonFilter:hover { - background-color: whitesmoke; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .ButtonFilter:active { - background-color: lightgray; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-default); } .ButtonFilter.ButtonFilterActive { @@ -167,12 +163,12 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; } .ButtonFilter.ButtonFilterActive:hover { - background-color: whitesmoke; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); color: $COLOR_FILTER_ACTIVE; } .ButtonFilter.ButtonFilterActive:active { - background-color: lightgray; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-default); color: $COLOR_FILTER_ACTIVE; } @@ -185,18 +181,17 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; font-size: 25px; padding: 0 0 0 0; margin: 0; - background-color: white; outline: none; border: none; cursor: pointer; } .ButtonZoomIn:hover { - background-color: whitesmoke; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .ButtonZoomIn:active { - background-color: lightgray; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-default); } .ButtonZoomOut { @@ -208,18 +203,17 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; font-size: 25px; padding: 0 0 0 0; margin: 0; - background-color: white; outline: none; border: none; cursor: pointer; } .ButtonZoomOut:hover { - background-color: whitesmoke; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .ButtonZoomOut:active { - background-color: lightgray; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-default); } .ZoomValue { @@ -227,7 +221,6 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; height: $INSIDE_OBJECT_HEIGHT; padding: 16px 6px 6px 0px; margin: 0; - background-color: white; outline: none; border: none; text-align: center; @@ -241,7 +234,6 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; max-width: $EDITOR_MENU_BUTTON_SIZE; padding: 8px 0 0 0; margin: 0; - background-color: white; outline: none; border: none; border-left: $BORDER_SIZE; @@ -251,29 +243,27 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; } .ButtonTopologieEditor.NetzgrafikEditing { - background-color: white; } .ButtonTopologieEditor.NetzgrafikEditing:active { - background-color: lightgray; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-default); } .ButtonTopologieEditor.NetzgrafikEditing:hover { - background-color: whitesmoke; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .ButtonTopologieEditor.TopologyEditing { - background-color: white; color: $COLOR_TOPO_EDITOR_ACTIVE; } .ButtonTopologieEditor.TopologyEditing:active { - background-color: lightgray; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-default); color: $COLOR_TOPO_EDITOR_ACTIVE; } .ButtonTopologieEditor.TopologyEditing:hover { - background-color: whitesmoke; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); color: $COLOR_TOPO_EDITOR_ACTIVE; } @@ -284,7 +274,6 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; max-width: $EDITOR_MENU_BUTTON_SIZE; padding: 8px 0 0 0; margin: 0; - background-color: white; outline: none; border: none; border-left: $BORDER_SIZE; @@ -294,29 +283,26 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; } .ButtonNoteEditor.NetzgrafikEditing { - background-color: white; } .ButtonNoteEditor.NetzgrafikEditing:active { - background-color: lightgray; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-default); } .ButtonNoteEditor.NetzgrafikEditing:hover { - background-color: whitesmoke; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .ButtonNoteEditor.NoteEditing { - background-color: white; color: $COLOR_TOPO_EDITOR_ACTIVE; } .ButtonNoteEditor.NoteEditing:active { - background-color: lightgray; color: $COLOR_TOPO_EDITOR_ACTIVE; } .ButtonNoteEditor.NoteEditing:hover { - background-color: whitesmoke; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); color: $COLOR_TOPO_EDITOR_ACTIVE; } @@ -335,7 +321,6 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; max-width: $EDITOR_MENU_BUTTON_SIZE; padding: 8px 0 0 0; margin: 0; - background-color: white; outline: none; border: none; border-left: $BORDER_SIZE; @@ -348,42 +333,38 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; } .ButtonStreckengrafikEditor.NetzgrafikEditing { - background-color: white; } .ButtonStreckengrafikEditor.NetzgrafikEditing:active { - background-color: lightgray; + background-color: var(--sbb-primary-alternative-button-background-color-default); } .ButtonStreckengrafikEditor.NetzgrafikEditing:hover { - background-color: whitesmoke; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .ButtonStreckengrafikEditor.StreckengrafikEditing { - background-color: white; color: $COLOR_TOPO_EDITOR_ACTIVE; } .ButtonStreckengrafikEditor.StreckengrafikEditing:active { - background-color: lightgray; color: $COLOR_TOPO_EDITOR_ACTIVE; } .ButtonStreckengrafikEditor.StreckengrafikEditing:hover { - background-color: whitesmoke; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); color: $COLOR_TOPO_EDITOR_ACTIVE; } .NodeContextMenu { - background: white; } .NodeContextMenu:hover { - background: whitesmoke; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .NodeContextMenu:active { - background: lightgray; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-default); } .ButtonMultiNodeMoving { @@ -393,7 +374,6 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; max-width: $EDITOR_MENU_BUTTON_SIZE; padding: 8px 0 0 0; margin: 0; - background-color: white; outline: none; border: none; border-left: $BORDER_SIZE; @@ -403,36 +383,38 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; } .ButtonMultiNodeMoving.NetzgrafikEditing { - background-color: white; } .ButtonMultiNodeMoving.NetzgrafikEditing:active { - background-color: lightgray; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-default); } .ButtonMultiNodeMoving.NetzgrafikEditing:hover { - background-color: whitesmoke; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .ButtonMultiNodeMoving.MultiNodeMoving { - background-color: white; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-default); color: $COLOR_TOPO_EDITOR_ACTIVE; } .ButtonMultiNodeMoving.MultiNodeMoving:active { - background-color: lightgray; color: $COLOR_TOPO_EDITOR_ACTIVE; } .ButtonMultiNodeMoving.MultiNodeMoving:hover { - background-color: whitesmoke; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); color: $COLOR_TOPO_EDITOR_ACTIVE; } +path.ButtonMultiNodeMoving { + fill: currentColor; +} + path.ButtonMultiNodeMoving.disabled { - fill: #a9a9a9; } + .ButtonAnalytics { width: $EDITOR_MENU_BUTTON_SIZE; height: $INSIDE_OBJECT_HEIGHT; @@ -440,7 +422,6 @@ path.ButtonMultiNodeMoving.disabled { max-width: $EDITOR_MENU_BUTTON_SIZE; padding: 8px 0 0 0; margin: 0; - background-color: white; outline: none; border: none; border-left: $BORDER_SIZE; @@ -450,66 +431,63 @@ path.ButtonMultiNodeMoving.disabled { } .ButtonAnalytics { - background-color: white; } .ButtonAnalytics:active { - background-color: lightgray; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-default); } .ButtonAnalytics:hover { - background-color: whitesmoke; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .ButtonAnalytics.ButtonAnalyticsActive { - background-color: white; color: $COLOR_TOPO_EDITOR_ACTIVE; } .ButtonAnalytics.ButtonAnalyticsActive:active { - background-color: lightgray; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-default); color: $COLOR_TOPO_EDITOR_ACTIVE; } .ButtonAnalytics.ButtonAnalyticsActive:hover { - background-color: whitesmoke; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); color: $COLOR_TOPO_EDITOR_ACTIVE; } .isStreckengrafikEditing { - color: darkgray; } .ButtonTopologieEditor.NetzgrafikEditing.isStreckengrafikEditing:hover { - background: white; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .ButtonTopologieEditor.TopologyEditing.isStreckengrafikEditing:hover { - background: white; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .ButtonNoteEditor.NetzgrafikEditing.isStreckengrafikEditing:hover { - background: white; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .ButtonMultiNodeMoving.NetzgrafikEditing.isStreckengrafikEditing:hover { - background: white; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .ButtonAnalytics.isStreckengrafikEditing:hover { - background: white; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .ButtonNoteEditor.NoteEditing.isStreckengrafikEditing:hover { - background: white; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .isNotStreckengrafikAllowed { - color: darkgray; + fill-opacity: 0.35; } .ButtonStreckengrafikEditor.NetzgrafikEditing.isNotStreckengrafikAllowed:hover { - background: white; + border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); } .sbb-icon { @@ -519,3 +497,15 @@ path.ButtonMultiNodeMoving.disabled { button:disabled { cursor: default; } + +button { + background: var(--sbb-header-lean-background-color); +} + +div.LabelNetzgrafik{ + background: var(--sbb-header-lean-background-color); +} + +div.NodeZoomValue{ + background: var(--sbb-header-lean-background-color); +} diff --git a/src/app/view/editor-properties-view-component/editor-properties-view.component.html b/src/app/view/editor-properties-view-component/editor-properties-view.component.html index 547b01d1..0cc74904 100644 --- a/src/app/view/editor-properties-view-component/editor-properties-view.component.html +++ b/src/app/view/editor-properties-view-component/editor-properties-view.component.html @@ -20,7 +20,6 @@

Einstellungen


Hintergrundfarbe -
Einstellungen

+ + + diff --git a/src/app/view/editor-properties-view-component/editor-properties-view.component.ts b/src/app/view/editor-properties-view-component/editor-properties-view.component.ts index e7e10003..5736cea1 100644 --- a/src/app/view/editor-properties-view-component/editor-properties-view.component.ts +++ b/src/app/view/editor-properties-view-component/editor-properties-view.component.ts @@ -201,6 +201,15 @@ export class EditorPropertiesViewComponent { ); } + isLocalStoredColorTheme() { + return this.uiInteractionService.isLocalStoredColorTheme(); + } + + resetLocalStoredColorData() { + this.uiInteractionService.resetLocalStoredColorData(); + this.activeColorTheme = this.uiInteractionService.getActiveTheme(); + } + private getHexColor(colorStr): string { const a = document.createElement("div"); a.style.color = colorStr; diff --git a/src/app/view/knoten-auslastung-view/knoten-auslastung-view.component.scss b/src/app/view/knoten-auslastung-view/knoten-auslastung-view.component.scss index bbd17c63..f0282e43 100644 --- a/src/app/view/knoten-auslastung-view/knoten-auslastung-view.component.scss +++ b/src/app/view/knoten-auslastung-view/knoten-auslastung-view.component.scss @@ -2,7 +2,8 @@ ::ng-deep path.KnotenAuslastungResourceGroup { stroke: none; - fill: whitesmoke; + fill: var(--sbb-header-lean-border-bottom-color); + opacity: 0.25; } ::ng-deep path.KnotenAuslastungDataGroup { @@ -17,14 +18,15 @@ ::ng-deep text.KnotenAuslastungNbrTrackGroup { font-size: 12px; font-weight: bold; - fill: gray; + fill: var(--NODE_TEXT_FOCUS); } ::ng-deep text.KnotenAuslastungTimeGroup { font-size: 12px; - fill: lightgray; + fill: var(--NODE_TEXT_FOCUS); } ::ng-deep path.KnotenAuslastungResourceGroup.capacityLimitReached { - fill: #fff7eb; + fill: var(--sbb-header-lean-border-bottom-color); + opacity: 0.5; } diff --git a/src/app/view/knoten-auslastung-view/knoten-auslastung-view.component.ts b/src/app/view/knoten-auslastung-view/knoten-auslastung-view.component.ts index 735b2b68..f0b23a5a 100644 --- a/src/app/view/knoten-auslastung-view/knoten-auslastung-view.component.ts +++ b/src/app/view/knoten-auslastung-view/knoten-auslastung-view.component.ts @@ -66,7 +66,7 @@ export class KnotenAuslastungViewComponent implements AfterViewInit, OnDestroy { trainrunSection.getFrequencyLinePatternRef(), ) + StaticDomTags.makeClassTag( - StaticDomTags.TAG_UI_DIALOG + "_" + StaticDomTags.TAG_COLOR_REF, + StaticDomTags.TAG_COLOR_REF, trainrunSection.getTrainrun().getCategoryColorRef(), ); @@ -77,14 +77,12 @@ export class KnotenAuslastungViewComponent implements AfterViewInit, OnDestroy { classAttribute += " " + StaticDomTags.TAG_SELECTED; } if ( - !KnotenAuslastungViewComponent.isMuted( + KnotenAuslastungViewComponent.isMuted( trainrunSection, selectedTrainrun, connectedTrainIds, ) ) { - classAttribute += " " + StaticDomTags.TAG_FOCUS; - } else { classAttribute += " " + StaticDomTags.TAG_MUTED; } return classAttribute; @@ -296,9 +294,9 @@ export class KnotenAuslastungViewComponent implements AfterViewInit, OnDestroy { "" + Math.round( (100 * d) / - this.resourceService - .getResource(selectedNode.getResourceId()) - .getCapacity(), + this.resourceService + .getResource(selectedNode.getResourceId()) + .getCapacity(), ) + "%", ); diff --git a/src/app/view/rastering/definitions.scss b/src/app/view/rastering/definitions.scss index 067499d3..7d56373c 100644 --- a/src/app/view/rastering/definitions.scss +++ b/src/app/view/rastering/definitions.scss @@ -28,7 +28,7 @@ $COLOR_Warning: var(--COLOR_Warning); $COLOR_BACKGROUND: var(--COLOR_BACKGROUND); $COLOR_STRECKENGRAPHIK_BACKGROUND: var(--COLOR_STRECKENGRAPHIK_BACKGROUND); -$COLOR_MUTED_SILVER: var(--COLOR_MUTED_SILVER); +$COLOR_MUTED_SILVER: var(--sbb-header-lean-border-bottom-color); $COLOR_Warning_BACKGROUND: var(--COLOR_Warning_BACKGROUND); diff --git a/src/app/view/themes/theme-default-ux-dark.ts b/src/app/view/themes/theme-default-ux-dark.ts index 7539c423..144c0236 100644 --- a/src/app/view/themes/theme-default-ux-dark.ts +++ b/src/app/view/themes/theme-default-ux-dark.ts @@ -5,8 +5,8 @@ import {StaticDomTags} from "../editor-main-view/data-views/static.dom.tags"; export class ThemeDefaultUxDark extends ThemeBase { constructor( - backgroundColor = "whitesmoke", - backgroundStreckengraphikColor = "white", + backgroundColor = "var(--sbb-header-lean-background-color)", + backgroundStreckengraphikColor = "var(--sbb-header-lean-background-color)", ) { super( ThemeRegistration.ThemeDefaultUxDark, @@ -34,42 +34,42 @@ export class ThemeDefaultUxDark extends ThemeBase { "CONNECTION_COLOR_WARNING: #959595", StaticDomTags.PREFIX_COLOR_VARIABLE + "_NORMAL: #767676", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_NORMAL_FOCUS: #DCDCDC", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_NORMAL_FOCUS: #9c9a9a", StaticDomTags.PREFIX_COLOR_VARIABLE + "_NORMAL_MUTED: #000000", StaticDomTags.PREFIX_COLOR_VARIABLE + "_NORMAL_RELATED: #767676", StaticDomTags.PREFIX_COLOR_VARIABLE + "_EC: #B38BBD", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_EC_FOCUS: #E1D2E5", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_EC_FOCUS: #b782c4", StaticDomTags.PREFIX_COLOR_VARIABLE + "_EC_MUTED: #715878", StaticDomTags.PREFIX_COLOR_VARIABLE + "_EC_RELATED: #B38BBD", StaticDomTags.PREFIX_COLOR_VARIABLE + "_IC: #B38BBD", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_IC_FOCUS: #E1D2E5", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_IC_FOCUS: #b782c4", StaticDomTags.PREFIX_COLOR_VARIABLE + "_IC_MUTED: #715878", StaticDomTags.PREFIX_COLOR_VARIABLE + "_IC_RELATED: #B38BBD", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_IR: #DAA4C4", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_IR_FOCUS: #F0DBE8", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_IR: #cb83ae", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_IR_FOCUS: #db88ba", StaticDomTags.PREFIX_COLOR_VARIABLE + "_IR_MUTED: #7e5e71", StaticDomTags.PREFIX_COLOR_VARIABLE + "_IR_RELATED: #DAA4C4", StaticDomTags.PREFIX_COLOR_VARIABLE + "_RE: #9193BA", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_RE_FOCUS: #D4D5E4", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_RE_FOCUS: #999bcf", StaticDomTags.PREFIX_COLOR_VARIABLE + "_RE_MUTED: #2D327D", StaticDomTags.PREFIX_COLOR_VARIABLE + "_RE_RELATED: #9193BA", StaticDomTags.PREFIX_COLOR_VARIABLE + "_S: #79B8E1", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_S_FOCUS: #CBE3F3", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_S_FOCUS: #69b2e0", StaticDomTags.PREFIX_COLOR_VARIABLE + "_S_MUTED: #143A85", StaticDomTags.PREFIX_COLOR_VARIABLE + "_S_RELATED: #79B8E1", StaticDomTags.PREFIX_COLOR_VARIABLE + "_GEX: #a7a2a2", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_GEX_FOCUS: #DCDCDC", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_GEX_FOCUS: #a19a9a", StaticDomTags.PREFIX_COLOR_VARIABLE + "_GEX_MUTED: #444444", StaticDomTags.PREFIX_COLOR_VARIABLE + "_GEX_RELATED: #DCDCDC", StaticDomTags.PREFIX_COLOR_VARIABLE + "_G: #a7a2a2", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_G_FOCUS: #DCDCDC", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_G_FOCUS: #a19a9a", StaticDomTags.PREFIX_COLOR_VARIABLE + "_G_MUTED: #444444", StaticDomTags.PREFIX_COLOR_VARIABLE + "_G_RELATED: #DCDCDC", diff --git a/src/app/view/themes/theme-fach-dark.ts b/src/app/view/themes/theme-fach-dark.ts index 3a9f35ba..f5f99c0c 100644 --- a/src/app/view/themes/theme-fach-dark.ts +++ b/src/app/view/themes/theme-fach-dark.ts @@ -5,8 +5,8 @@ import {StaticDomTags} from "../editor-main-view/data-views/static.dom.tags"; export class ThemeFachDark extends ThemeBase { constructor( - backgroundColor = "whitesmoke", - backgroundStreckengraphikColor = "white", + backgroundColor = "var(--sbb-header-lean-background-color)", + backgroundStreckengraphikColor = "var(--sbb-header-lean-background-color)", ) { super( ThemeRegistration.ThemeFachDark, @@ -32,42 +32,42 @@ export class ThemeFachDark extends ThemeBase { "CONNECTION_COLOR_WARNING: #959595", StaticDomTags.PREFIX_COLOR_VARIABLE + "_NORMAL: #767676", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_NORMAL_FOCUS: #DCDCDC", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_NORMAL_FOCUS: #9c9a9a", StaticDomTags.PREFIX_COLOR_VARIABLE + "_NORMAL_MUTED: #000000", StaticDomTags.PREFIX_COLOR_VARIABLE + "_NORMAL_RELATED: #767676", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_EC: #f09f9f", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_EC_FOCUS: #ffdfdc", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_EC: #f06f6f", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_EC_FOCUS: #ff3b3b", StaticDomTags.PREFIX_COLOR_VARIABLE + "_EC_MUTED: #724040", StaticDomTags.PREFIX_COLOR_VARIABLE + "_EC_RELATED: #ef6950", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_IC: #f09f9f", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_IC_FOCUS: #ffdfdc", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_IC: #f06f6f", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_IC_FOCUS: #ff3b3b", StaticDomTags.PREFIX_COLOR_VARIABLE + "_IC_MUTED: #724040", StaticDomTags.PREFIX_COLOR_VARIABLE + "_IC_RELATED: #ef6950", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_IR: #f09f9f", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_IR_FOCUS: #ffdfdc", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_IR: #f06f6f", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_IR_FOCUS: #ff3b3b", StaticDomTags.PREFIX_COLOR_VARIABLE + "_IR_MUTED: #724040", StaticDomTags.PREFIX_COLOR_VARIABLE + "_IR_RELATED: #ef6950", StaticDomTags.PREFIX_COLOR_VARIABLE + "_RE: #71d573", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_RE_FOCUS: #c4e5c4", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_RE_FOCUS: #4fb351", StaticDomTags.PREFIX_COLOR_VARIABLE + "_RE_MUTED: #2e582f", StaticDomTags.PREFIX_COLOR_VARIABLE + "_RE_RELATED: #9ed267", StaticDomTags.PREFIX_COLOR_VARIABLE + "_S: #9d9d9d", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_S_FOCUS: #e4e4e4", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_S_FOCUS: #666363", StaticDomTags.PREFIX_COLOR_VARIABLE + "_S_MUTED: #3a3a3a", StaticDomTags.PREFIX_COLOR_VARIABLE + "_S_RELATED: #797979", StaticDomTags.PREFIX_COLOR_VARIABLE + "_GEX: #b197cb", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_GEX_FOCUS: #e9dae8", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_GEX_FOCUS: #b186db", StaticDomTags.PREFIX_COLOR_VARIABLE + "_GEX_MUTED: #473c51", StaticDomTags.PREFIX_COLOR_VARIABLE + "_GEX_RELATED: #b197cb", StaticDomTags.PREFIX_COLOR_VARIABLE + "_G: #6888c9", - StaticDomTags.PREFIX_COLOR_VARIABLE + "_G_FOCUS: #a6c3cd", + StaticDomTags.PREFIX_COLOR_VARIABLE + "_G_FOCUS: #4d79d1", StaticDomTags.PREFIX_COLOR_VARIABLE + "_G_MUTED: #384869", StaticDomTags.PREFIX_COLOR_VARIABLE + "_G_RELATED: #6888c9", diff --git a/src/app/view/themes/theme-gray-dark.ts b/src/app/view/themes/theme-gray-dark.ts index cbd3d1fa..d8134c7a 100644 --- a/src/app/view/themes/theme-gray-dark.ts +++ b/src/app/view/themes/theme-gray-dark.ts @@ -6,8 +6,8 @@ import {StaticDomTags} from "../editor-main-view/data-views/static.dom.tags"; export class ThemeGrayDark extends ThemeBase { constructor( - backgroundColor = "whitesmoke", - backgroundStreckengraphikColor = "white", + backgroundColor = "var(--sbb-header-lean-background-color)", + backgroundStreckengraphikColor = "var(--sbb-header-lean-background-color)", ) { super( ThemeRegistration.ThemeGrayDark, @@ -21,7 +21,7 @@ export class ThemeGrayDark extends ThemeBase { static getThemeGrayDarkColors(): string[] { const normal = 40; - const focus = 100; + const focus = 0; const muted = 0; const related = 20; @@ -42,7 +42,7 @@ export class ThemeGrayDark extends ThemeBase { d3.scaleLinear().domain([0, 100]).range(["#666666", "#FFFFFF"])(normal), StaticDomTags.PREFIX_COLOR_VARIABLE + "_NORMAL_FOCUS: " + - d3.scaleLinear().domain([0, 100]).range(["#dddddd", "#FFFFFF"])(focus), + d3.scaleLinear().domain([0, 100]).range(["#666666", "#FFFFFF"])(focus), StaticDomTags.PREFIX_COLOR_VARIABLE + "_NORMAL_MUTED: " + d3.scaleLinear().domain([0, 100]).range(["#333333", "#FFFFFF"])(muted), @@ -57,7 +57,7 @@ export class ThemeGrayDark extends ThemeBase { d3.scaleLinear().domain([0, 100]).range(["#cccccc", "#FFFFFF"])(normal), StaticDomTags.PREFIX_COLOR_VARIABLE + "_EC_FOCUS: " + - d3.scaleLinear().domain([0, 100]).range(["#dddddd", "#FFFFFF"])(focus), + d3.scaleLinear().domain([0, 100]).range(["#cccccc", "#FFFFFF"])(focus), StaticDomTags.PREFIX_COLOR_VARIABLE + "_EC_MUTED: " + d3.scaleLinear().domain([0, 100]).range(["#333333", "#FFFFFF"])(muted), @@ -72,7 +72,7 @@ export class ThemeGrayDark extends ThemeBase { d3.scaleLinear().domain([0, 100]).range(["#cccccc", "#FFFFFF"])(normal), StaticDomTags.PREFIX_COLOR_VARIABLE + "_IC_FOCUS: " + - d3.scaleLinear().domain([0, 100]).range(["#dddddd", "#FFFFFF"])(focus), + d3.scaleLinear().domain([0, 100]).range(["#cccccc", "#FFFFFF"])(focus), StaticDomTags.PREFIX_COLOR_VARIABLE + "_IC_MUTED: " + d3.scaleLinear().domain([0, 100]).range(["#333333", "#FFFFFF"])(muted), @@ -87,7 +87,7 @@ export class ThemeGrayDark extends ThemeBase { d3.scaleLinear().domain([0, 100]).range(["#cccccc", "#FFFFFF"])(normal), StaticDomTags.PREFIX_COLOR_VARIABLE + "_IR_FOCUS: " + - d3.scaleLinear().domain([0, 100]).range(["#dddddd", "#FFFFFF"])(focus), + d3.scaleLinear().domain([0, 100]).range(["#cccccc", "#FFFFFF"])(focus), StaticDomTags.PREFIX_COLOR_VARIABLE + "_IR_MUTED: " + d3.scaleLinear().domain([0, 100]).range(["#333333", "#FFFFFF"])(muted), @@ -132,7 +132,7 @@ export class ThemeGrayDark extends ThemeBase { d3.scaleLinear().domain([0, 100]).range(["#888888", "#FFFFFF"])(normal), StaticDomTags.PREFIX_COLOR_VARIABLE + "_GEX_FOCUS: " + - d3.scaleLinear().domain([0, 100]).range(["#999999", "#FFFFFF"])(focus), + d3.scaleLinear().domain([0, 100]).range(["#888888", "#FFFFFF"])(focus), StaticDomTags.PREFIX_COLOR_VARIABLE + "_GEX_MUTED: " + d3.scaleLinear().domain([0, 100]).range(["#333333", "#FFFFFF"])(muted), @@ -147,7 +147,7 @@ export class ThemeGrayDark extends ThemeBase { d3.scaleLinear().domain([0, 100]).range(["#666666", "#FFFFFF"])(normal), StaticDomTags.PREFIX_COLOR_VARIABLE + "_G_FOCUS: " + - d3.scaleLinear().domain([0, 100]).range(["#777777", "#FFFFFF"])(focus), + d3.scaleLinear().domain([0, 100]).range(["#666666", "#FFFFFF"])(focus), StaticDomTags.PREFIX_COLOR_VARIABLE + "_G_MUTED:" + d3.scaleLinear().domain([0, 100]).range(["#333333", "#FFFFFF"])(muted), diff --git a/src/app/view/themes/theme-gray.ts b/src/app/view/themes/theme-gray.ts index 8e716c2e..e5a54f35 100644 --- a/src/app/view/themes/theme-gray.ts +++ b/src/app/view/themes/theme-gray.ts @@ -20,7 +20,7 @@ export class ThemeGray extends ThemeBase { static getThemeGrayColors(): string[] { const normal = 30; - const focus = 100; + const focus = 20; const muted = 0; const related = 30; diff --git a/src/app/view/themes/theme.spec.ts b/src/app/view/themes/theme.spec.ts index 42d2b28e..a58d0791 100644 --- a/src/app/view/themes/theme.spec.ts +++ b/src/app/view/themes/theme.spec.ts @@ -172,10 +172,10 @@ describe("Theme Tests", () => { const t1 = new ThemeDefaultUxDark(); const t2 = new ThemeDefaultUxDark("red"); const t3 = new ThemeDefaultUxDark("yellow", "blue"); - expect(t1.backgroundColor).toBe("whitesmoke"); - expect(t1.backgroundStreckengraphikColor).toBe("white"); + expect(t1.backgroundColor).toBe("var(--sbb-header-lean-background-color)"); + expect(t1.backgroundStreckengraphikColor).toBe("var(--sbb-header-lean-background-color)"); expect(t2.backgroundColor).toBe("red"); - expect(t2.backgroundStreckengraphikColor).toBe("white"); + expect(t2.backgroundStreckengraphikColor).toBe("var(--sbb-header-lean-background-color)"); expect(t3.backgroundColor).toBe("yellow"); expect(t3.backgroundStreckengraphikColor).toBe("blue"); }); @@ -196,10 +196,10 @@ describe("Theme Tests", () => { const t1 = new ThemeFachDark(); const t2 = new ThemeFachDark("red"); const t3 = new ThemeFachDark("yellow", "blue"); - expect(t1.backgroundColor).toBe("whitesmoke"); - expect(t1.backgroundStreckengraphikColor).toBe("white"); + expect(t1.backgroundColor).toBe("var(--sbb-header-lean-background-color)"); + expect(t1.backgroundStreckengraphikColor).toBe("var(--sbb-header-lean-background-color)"); expect(t2.backgroundColor).toBe("red"); - expect(t2.backgroundStreckengraphikColor).toBe("white"); + expect(t2.backgroundStreckengraphikColor).toBe("var(--sbb-header-lean-background-color)"); expect(t3.backgroundColor).toBe("yellow"); expect(t3.backgroundStreckengraphikColor).toBe("blue"); }); @@ -232,10 +232,10 @@ describe("Theme Tests", () => { const t1 = new ThemeGrayDark(); const t2 = new ThemeGrayDark("red"); const t3 = new ThemeGrayDark("yellow", "blue"); - expect(t1.backgroundColor).toBe("whitesmoke"); - expect(t1.backgroundStreckengraphikColor).toBe("white"); + expect(t1.backgroundColor).toBe("var(--sbb-header-lean-background-color)"); + expect(t1.backgroundStreckengraphikColor).toBe("var(--sbb-header-lean-background-color)"); expect(t2.backgroundColor).toBe("red"); - expect(t2.backgroundStreckengraphikColor).toBe("white"); + expect(t2.backgroundStreckengraphikColor).toBe("var(--sbb-header-lean-background-color)"); expect(t3.backgroundColor).toBe("yellow"); expect(t3.backgroundStreckengraphikColor).toBe("blue"); }); diff --git a/src/app/view/variant/variants-view/variants-view.component.html b/src/app/view/variant/variants-view/variants-view.component.html index f2f55686..e3d73fb0 100644 --- a/src/app/view/variant/variants-view/variants-view.component.html +++ b/src/app/view/variant/variants-view/variants-view.component.html @@ -53,7 +53,7 @@

diff --git a/src/index.html b/src/index.html index e37eb075..d5d69fdc 100644 --- a/src/index.html +++ b/src/index.html @@ -1,5 +1,5 @@ - + Netzgrafik-Editor From 70a1b480442db738ca8655484174e4f2d94786c2 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 18 Jul 2024 10:39:40 +0200 Subject: [PATCH 016/197] hot fixed - imports missing - cause issue in the "package bundle" (#182) --- .../perlenkette/perlenkette-node/perlenkette-node.component.scss | 1 + .../perlenkette-section/perlenkette-section.component.scss | 1 + 2 files changed, 2 insertions(+) diff --git a/src/app/perlenkette/perlenkette-node/perlenkette-node.component.scss b/src/app/perlenkette/perlenkette-node/perlenkette-node.component.scss index 80fb9d4f..67ccbf10 100644 --- a/src/app/perlenkette/perlenkette-node/perlenkette-node.component.scss +++ b/src/app/perlenkette/perlenkette-node/perlenkette-node.component.scss @@ -1,4 +1,5 @@ @import "./../../view/rastering/definitions"; +@import "./../../view/editor-main-view/data-views/nodes.view"; .node-container { position: relative; diff --git a/src/app/perlenkette/perlenkette-section/perlenkette-section.component.scss b/src/app/perlenkette/perlenkette-section/perlenkette-section.component.scss index 71cc10ed..bceefbf4 100644 --- a/src/app/perlenkette/perlenkette-section/perlenkette-section.component.scss +++ b/src/app/perlenkette/perlenkette-section/perlenkette-section.component.scss @@ -1,4 +1,5 @@ @import "./../../view/rastering/definitions"; +@import "./../../view/editor-main-view/data-views/trainrunsections.view"; .sectionEditingContainer { margin-left: 45px; From b5e8e33f80df74e98221d2f173c1cbe47b7f32a5 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 18 Jul 2024 17:29:45 +0200 Subject: [PATCH 017/197] hot fixed - imports missing - cause issue in the "package bundle" (#184) --- .../htmlEditor/html-editor.component.html | 2 +- .../htmlEditor/html-editor.component.scss | 8 ++- .../htmlEditor/html-editor.component.ts | 24 ++++---- src/app/view/themes/theme-fach-dark.ts | 14 ++--- src/app/view/themes/theme-fach.ts | 56 +++++++++---------- 5 files changed, 53 insertions(+), 51 deletions(-) diff --git a/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.html b/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.html index 4ec876a5..40d679bc 100644 --- a/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.html +++ b/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.html @@ -3,7 +3,7 @@
diff --git a/src/app/view/project/project-dialog/project-form/project-form.component.spec.ts b/src/app/view/project/project-dialog/project-form/project-form.component.spec.ts index 64cd5ba8..c0f09566 100644 --- a/src/app/view/project/project-dialog/project-form/project-form.component.spec.ts +++ b/src/app/view/project/project-dialog/project-form/project-form.component.spec.ts @@ -3,8 +3,10 @@ import {ComponentFixture, TestBed} from "@angular/core/testing"; import { ProjectFormComponent, ProjectFormComponentModel, + userIdsAsEmailValidator, } from "./project-form.component"; import {FormModel} from "../../../../utils/form-model"; +import {UntypedFormControl} from "@angular/forms"; describe("ProjectFormComponent", () => { let component: ProjectFormComponent; @@ -32,4 +34,99 @@ describe("ProjectFormComponent", () => { it("should create", () => { expect(component).toBeTruthy(); }); + + it("validEMailExamples test", () => { + const validEMailExamples = [ + "franz@nix.com", + "adrian@example.com", + "muster.hans@example.test.zurich", + "name.vorname.vorname2@mail.domain.ch", + "fun@data.cloud", + "adrian@ai.org", + "1234@x.org", + "x@1234.org", + "1234@1234.org", + "123a4@1234.org", + "123a4@1234abc123zsd.a123sb.org", + "u123456", + "ue123456", + "e123456", + "u000000" + ]; + + validEMailExamples.forEach((e) => { + const test = new UntypedFormControl(); + test.setValue([e]); + expect(userIdsAsEmailValidator(test)).toBeNull(); + }); + }); + + it("invalidEMailExamples test", () => { + const invalidEMailExamples = [ + "u12345z", + "U123456", + "name.vorname.vorname2#mail.domain.ch", + "a", + "u", + "ue", + "e"]; + invalidEMailExamples.forEach((e) => { + const test = new UntypedFormControl(); + test.setValue([e]); + expect(userIdsAsEmailValidator(test).invalidUserIdAsEmails).toBe(e); + }); + }); + + it("validEMailExamples batch - test", () => { + const validEMailExamples = [ + "adrian@example.com", + "name.vorname.vorname2@mail.domain.ch", + "fun@data.cloud", + "adrian@ai.org", + "1234@x.org", + "x@1234.org", + "1234@1234.org", + "123a4@1234.org", + "Franz@nix.com", + "Adrian@ai.org", + "aDrian@ai.org", + "ADRIAN@AI.ORG", + "adrian@AI.ORG", + "adrian@ai.ORG", + "adrian@AI.org", + "adrian@AI.orG"]; + + const test = new UntypedFormControl(); + test.setValue(validEMailExamples); + expect(userIdsAsEmailValidator(test)).toBeNull(); + }); + + it("invalidEMailExamples batch - test", () => { + const invalidEMailExamples = [ + "u123456", + "name.vorname.vorname2#mail.domain.ch", + ""]; + const test = new UntypedFormControl(); + test.setValue(invalidEMailExamples); + expect(userIdsAsEmailValidator(test).invalidUserIdAsEmails.length).toBe(38); + }); + + it("mixedValInvalidExamples - batch - test", () => { + const mixedValInvalidExamples = [ + "adrian@example.com", + "name.vorname.vorname2@mail.domain.ch", + "fun@data.cloud", + "adrian@ai.org", + "u123456", + "1234@x.org", + "x@1234.org", + "a2#b.ch", + "1234@1234.org", + "123a4@1234.org", + ""]; + const test = new UntypedFormControl(); + test.setValue(mixedValInvalidExamples); + console.log(userIdsAsEmailValidator(test).invalidUserIdAsEmails); + expect(userIdsAsEmailValidator(test).invalidUserIdAsEmails.length).toBe(9); + }); }); diff --git a/src/app/view/project/project-dialog/project-form/project-form.component.ts b/src/app/view/project/project-dialog/project-form/project-form.component.ts index 1c1867b1..efb23e2c 100644 --- a/src/app/view/project/project-dialog/project-form/project-form.component.ts +++ b/src/app/view/project/project-dialog/project-form/project-form.component.ts @@ -15,8 +15,8 @@ export class ProjectFormComponent implements OnInit { ngOnInit(): void { this.model.registerValidator("name", Validators.required); - this.model.registerValidator("writeUsers", userIdsValidator); - this.model.registerValidator("readUsers", userIdsValidator); + this.model.registerValidator("writeUsers", userIdsAsEmailValidator); + this.model.registerValidator("readUsers", userIdsAsEmailValidator); } onLabelsFocusoutWrite() { @@ -31,7 +31,7 @@ export class ProjectFormComponent implements OnInit { document.getElementById("userWriteInput").dispatchEvent(keyboardEvent); } - onLabelsFocusoutReade() { + onLabelsFocusoutRead() { const keyboardEvent = new KeyboardEvent("keydown", { code: "Enter", key: "Enter", @@ -44,17 +44,25 @@ export class ProjectFormComponent implements OnInit { } } -const userIdsValidator = (control: UntypedFormControl) => { +export const userIdsAsEmailValidator = (control: UntypedFormControl) => { if (!control) { return null; } const userIds: string[] = control.value; - const invalidIds = userIds.filter((id) => !id.match(/^(u|ue|e)\d+$/)); - if (invalidIds.length === 0) { + // email adresse validator: regex to match emails using the expression + const invalidEmailPattern = userIds.filter((id) => { + const retVal = + id.match(/^([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)|(u|ue|e)\d+$/); + if (retVal === null) { + return true; + } + return retVal[0] !== id; + }); + + if (invalidEmailPattern.length === 0) { return null; } - - return {invalidUserIds: invalidIds.join(", ")}; + return {invalidUserIdAsEmails: invalidEmailPattern.join(", ")}; }; export interface ProjectFormComponentModel { diff --git a/src/app/view/variant/variant-view/variant-history/version-entry-layout/version-entry-layout.component.html b/src/app/view/variant/variant-view/variant-history/version-entry-layout/version-entry-layout.component.html index e3439645..a4855a43 100644 --- a/src/app/view/variant/variant-view/variant-history/version-entry-layout/version-entry-layout.component.html +++ b/src/app/view/variant/variant-view/variant-history/version-entry-layout/version-entry-layout.component.html @@ -9,7 +9,6 @@ {{ title }}
- {{ userId }}
From e3a87989ea28a04a4a0bb9cee825825bb1b97d7b Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 31 Jul 2024 15:43:09 +0200 Subject: [PATCH 024/197] fix: align theme color picker with buttons (#198) Fix the issue described in: https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/pull/173#issuecomment-2250557562 Use the vertical-align CSS property instead of manually hardcoding pixel offsets and margins. --- .../editor-properties-view.component.html | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/app/view/editor-properties-view-component/editor-properties-view.component.html b/src/app/view/editor-properties-view-component/editor-properties-view.component.html index 0cc74904..38bf7a64 100644 --- a/src/app/view/editor-properties-view-component/editor-properties-view.component.html +++ b/src/app/view/editor-properties-view-component/editor-properties-view.component.html @@ -25,15 +25,14 @@

Einstellungen

type="color" sbbInput name="Hintergrundfarbe" - style="width: 242px; min-height: 37px" + style="width: 242px; min-height: 37px; vertical-align: middle;" [(ngModel)]="activeBackgroundColor" (change)="colorPicked($event)" />  

  @@ -37,7 +47,7 @@ - + diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 8e4b8477..bc28114a 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -17,10 +17,10 @@ import {Operation} from "./models/operation.model"; }) export class AppComponent { readonly disableBackend = environment.disableBackend; - - version = packageJson.version; - environmentLabel = environment.label; - authenticated: Promise; + readonly version = packageJson.version; + readonly locale = localStorage.getItem("locale"); + readonly environmentLabel = environment.label; + readonly authenticated: Promise; projectInMenu: Observable; @@ -53,6 +53,11 @@ export class AppComponent { } } + changeLocale(locale: string) { + localStorage.setItem("locale", locale); + location.reload(); + } + @Input() get netzgrafikDto() { return this.dataService.getNetzgrafikDto(); diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 9ef3795b..a75586bd 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,4 +1,4 @@ -import {NgModule, Injector, ApplicationRef, DoBootstrap} from "@angular/core"; +import {NgModule, Injector, DoBootstrap} from "@angular/core"; import {NgxEditorModule} from "ngx-editor"; import {BrowserModule} from "@angular/platform-browser"; import {createCustomElement} from "@angular/elements"; @@ -101,6 +101,7 @@ import {TrainRunSectionStopsComponentComponent} from "./streckengrafik/component import {PathGridComponent} from "./streckengrafik/components/grid/path-grid/path-grid.component"; import {TrainRunNodeComponent} from "./streckengrafik/components/train-run-node/trainrun-node.component"; import {ActionMenuComponent} from "./view/action-menu/action-menu/action-menu.component"; +import {I18nModule} from "./core/i18n/i18n.module"; @NgModule({ declarations: [ @@ -230,6 +231,7 @@ import {ActionMenuComponent} from "./view/action-menu/action-menu/action-menu.co SbbTooltipModule, SbbBreadcrumbModule, SbbAutocompleteModule, + I18nModule, ], bootstrap: environment.customElement ? [] : [AppComponent], providers: [ diff --git a/src/app/core/i18n/i18n.module.ts b/src/app/core/i18n/i18n.module.ts new file mode 100644 index 00000000..e19914ff --- /dev/null +++ b/src/app/core/i18n/i18n.module.ts @@ -0,0 +1,25 @@ +import {NgModule, APP_INITIALIZER, LOCALE_ID} from "@angular/core"; +import {CommonModule} from "@angular/common"; +import {TranslatePipe} from "./translate.pipe"; +import {I18n} from "./i18n.service"; + +@NgModule({ + declarations: [TranslatePipe], // Declare the pipe + imports: [CommonModule], + providers: [ + I18n, + { // Load locale data at app start-up + provide: APP_INITIALIZER, + useFactory: (i18n: I18n) => () => i18n.setLocale(), + deps: [I18n], + multi: true, + }, + { // Set the runtime locale for the app + provide: LOCALE_ID, + useFactory: (i18n: I18n) => i18n.locale, + deps: [I18n], + } + ], + exports: [TranslatePipe] // Export the pipe +}) +export class I18nModule { } diff --git a/src/app/core/i18n/i18n.service.ts b/src/app/core/i18n/i18n.service.ts new file mode 100644 index 00000000..7fdf6394 --- /dev/null +++ b/src/app/core/i18n/i18n.service.ts @@ -0,0 +1,89 @@ +import {Injectable} from "@angular/core"; +import {registerLocaleData} from "@angular/common"; +import {loadTranslations} from "@angular/localize"; + +@Injectable({ + providedIn: "root", + }) + export class I18n { + locale = "en"; + readonly allowedLocales = ["en", "fr", "de", "it"]; + translations: any = {}; + + async setLocale() { + const userLocale = localStorage.getItem("locale"); + + // If the user has a preferred language stored in LocalStorage, use it. + if (userLocale && this.allowedLocales.includes(userLocale)) { + this.locale = userLocale; + } else { + localStorage.setItem("locale", this.locale); + } + + // Use webpack magic string to only include required locale data + const localeModule = await import( + /* webpackInclude: /(en|de|fr|it)\.mjs$/ */ + `/node_modules/@angular/common/locales/${this.locale}.mjs` + ); + registerLocaleData(localeModule.default); + + // Load translation file initially + await this.loadTranslations(); + } + + async loadTranslations() { + const localeTranslationsModule = await import( + `src/assets/i18n/${this.locale}.json` + ); + + // Ensure translations are flattened if necessary + this.translations = this.flattenTranslations(localeTranslationsModule.default); + + // Load translations for the current locale at runtime + loadTranslations(this.translations); + } + + // Helper function to flatten nested translations + // nested JSON : + // { + // "app": { + // "login": "Login", + // "models": {...} + // } + // } + // flattened JSON : + // { + // "app.login": "Login", + // "app.models...": ..., + // "app.models...": ... + // } + private flattenTranslations(translations: any): any { + const flattenedTranslations = {}; + + function flatten(obj, prefix = "") { + for (const key in obj) { + if (typeof obj[key] === "string") { + flattenedTranslations[prefix + key] = obj[key]; + } else if (typeof obj[key] === "object") { + flatten(obj[key], prefix + key + "."); + } + } + } + + flatten(translations); + return flattenedTranslations; + } + + // Used for the pipe and allowing parameters + translate(key: string, params?: any): string { + let translation = this.translations[key] || key; + + if (params) { + Object.keys(params).forEach(param => { + translation = translation.replace(`{$${param}}`, params[param]); + }); + } + + return translation; + } + } diff --git a/src/app/core/i18n/translate.pipe.ts b/src/app/core/i18n/translate.pipe.ts new file mode 100644 index 00000000..bb38f238 --- /dev/null +++ b/src/app/core/i18n/translate.pipe.ts @@ -0,0 +1,14 @@ +import {Pipe, PipeTransform} from "@angular/core"; +import {I18n} from "./i18n.service"; + +@Pipe({ + name: "translate", + pure: false +}) +export class TranslatePipe implements PipeTransform { + constructor(private i18n: I18n) {} + + transform(key: string, params?: any): string { + return this.i18n.translate(key, params); + } +} diff --git a/src/app/logger/log-notification-toast.component.html b/src/app/logger/log-notification-toast.component.html index a8748f0b..c4688299 100644 --- a/src/app/logger/log-notification-toast.component.html +++ b/src/app/logger/log-notification-toast.component.html @@ -2,7 +2,7 @@ - Title + Title diff --git a/src/app/models/node.model.ts b/src/app/models/node.model.ts index fd9906a1..c8c0f6ca 100644 --- a/src/app/models/node.model.ts +++ b/src/app/models/node.model.ts @@ -61,8 +61,8 @@ export class Node { labelIds, }: NodeDto = { id: Node.incrementId(), - betriebspunktName: "NEW", - fullName: "Neuer Knoten", + betriebspunktName: $localize`:@@app.models.node.shortNameDefault:NEW`, + fullName: $localize`:@@app.models.node.full-name-default:New node`, positionX: 0, positionY: 0, ports: [], diff --git a/src/app/models/note.model.ts b/src/app/models/note.model.ts index 6eec8540..4c3828c7 100644 --- a/src/app/models/note.model.ts +++ b/src/app/models/note.model.ts @@ -6,8 +6,8 @@ export class Note { public static DEFAULT_NOTE_HEIGHT = 64; public static DEFAULT_NOTE_POSITION_X = 0; public static DEFAULT_NOTE_POSITION_Y = 0; - public static DEFAULT_NOTE_TITLE = "Kommentar Titel"; - public static DEFAULT_NOTE_TEXT = "Kommentar Text"; + public static DEFAULT_NOTE_TITLE = $localize`:@@app.models.note.title-default:Note title`; + public static DEFAULT_NOTE_TEXT = $localize`:@@app.models.note.text-default:Note text`; public static DEFAULT_NOTE_BACKGROUND_COLOR = "#ffffff"; public static DEFAULT_NOTE_TEXT_COLOR = "#000000"; diff --git a/src/app/netzgrafik-application/netzgrafik-application.component.html b/src/app/netzgrafik-application/netzgrafik-application.component.html index faadd9b3..6ac8fef8 100644 --- a/src/app/netzgrafik-application/netzgrafik-application.component.html +++ b/src/app/netzgrafik-application/netzgrafik-application.component.html @@ -3,7 +3,7 @@ @@ -19,7 +19,7 @@ @@ -41,7 +41,7 @@ @@ -49,7 +49,7 @@ diff --git a/src/app/perlenkette/perlenkette-node/perlenkette-node.component.ts b/src/app/perlenkette/perlenkette-node/perlenkette-node.component.ts index ac483cc4..8616ae1d 100644 --- a/src/app/perlenkette/perlenkette-node/perlenkette-node.component.ts +++ b/src/app/perlenkette/perlenkette-node/perlenkette-node.component.ts @@ -52,12 +52,12 @@ export class PerlenketteNodeComponent implements OnInit { mockConnection.connectionWarning && amountOfWarningConnections++, ); if (amountOfWarningConnections === 0) { - return "Kein fehlerhafter Anschluss"; + return $localize`:@@app.perlenkette.perlenkette-node.0-warning-connection:No incorrect connection`; } if (amountOfWarningConnections === 1) { - return "1 fehlerhafter Anschluss"; + return $localize`:@@app.perlenkette.perlenkette-node.1-warning-connection:1 incorrect connection`; } - return amountOfWarningConnections + " fehlerhafte Anschlüsse"; + return $localize`:@@app.perlenkette.perlenkette-node.n-warning-connections:${amountOfWarningConnections}:number: incorrect connections`; } getFittingConnections(): string { @@ -67,12 +67,12 @@ export class PerlenketteNodeComponent implements OnInit { !mockConnection.connectionWarning && amountOfFittingConnections++, ); if (amountOfFittingConnections === 0) { - return "Kein passender Anschluss"; + return $localize`:@@app.perlenkette.perlenkette-node.0-fitting-connection:No fitting connection`; } if (amountOfFittingConnections === 1) { - return "1 passender Anschluss"; + return $localize`:@@app.perlenkette.perlenkette-node.1-fitting-connection:1 fitting connection`; } - return amountOfFittingConnections + " passende Anschlüsse"; + return $localize`:@@app.perlenkette.perlenkette-node.n-fitting-connections:${amountOfFittingConnections}:number: fitting connections`; } expandConnections() { diff --git a/src/app/perlenkette/perlenkette.component.html b/src/app/perlenkette/perlenkette.component.html index 5731a3d0..c9f44b63 100644 --- a/src/app/perlenkette/perlenkette.component.html +++ b/src/app/perlenkette/perlenkette.component.html @@ -3,10 +3,10 @@
- + - +
diff --git a/src/app/services/data/node.service.ts b/src/app/services/data/node.service.ts index 9d476db2..1ca7436f 100644 --- a/src/app/services/data/node.service.ts +++ b/src/app/services/data/node.service.ts @@ -577,9 +577,8 @@ export class NodeService implements OnDestroy { } if (isForwardPathLocked && isBackwardPathLocked) { - const warningTitle = "Durchfahrt geändert"; - const warningDescription = - "Zeiten können nicht angepasst werden, beidseitger Lock gefunden"; + const warningTitle = $localize`:@@app.services.data.node.transit-modified.title:Transition changed`; + const warningDescription = $localize`:@@app.services.data.node.transit-modified.description:Times cannot be adjusted, lock found on both sides`; this.trainrunSectionService.setWarningOnNode( trainrunSections.trainrunSection1.getId(), node.getId(), diff --git a/src/app/services/data/note.service.ts b/src/app/services/data/note.service.ts index 4ae57072..e0099c18 100644 --- a/src/app/services/data/note.service.ts +++ b/src/app/services/data/note.service.ts @@ -56,7 +56,7 @@ export class NoteService { }); } - addNote(position: Vec2D, title = "Titel", text = "Text"): Note { + addNote(position: Vec2D, title = $localize`:@@app.models.note.default-title:Note title`, text = $localize`:@@app.models.note.default-text:Note text`): Note { const newNote = new Note(); newNote.setPosition(position.getX(), position.getY()); newNote.setTitle(title); diff --git a/src/app/services/data/trainrunsection.service.ts b/src/app/services/data/trainrunsection.service.ts index 50971e9c..26fe77ed 100644 --- a/src/app/services/data/trainrunsection.service.ts +++ b/src/app/services/data/trainrunsection.service.ts @@ -1123,24 +1123,12 @@ export class TrainrunSectionService implements OnDestroy { origTravelTime || travelTimeIssue ) { - const description = - "Zwischenhalteumwandlung führte bei der Vergabe der Zeiten zu inkonsistenzen!"; - trainrunSection1.setTargetArrivalWarning( - "Zwischenhalteumwandlung", - description, - ); - trainrunSection1.setTargetDepartureWarning( - "Zwischenhalteumwandlung", - description, - ); - trainrunSection2.setSourceArrivalWarning( - "Zwischenhalteumwandlung", - description, - ); - trainrunSection2.setSourceDepartureWarning( - "Zwischenhalteumwandlung", - description, - ); + const title = $localize`:@@app.services.data.trainrunsection.intermediate-stop-replacement.title:Intermediate stop replacement`; + const description = $localize`:@@app.services.data.trainrunsection.intermediate-stop-replacement.description:Intermediate stop replacement led to inconsistencies in the allocation of times!`; + trainrunSection1.setTargetArrivalWarning(title, description); + trainrunSection1.setTargetDepartureWarning(title, description); + trainrunSection2.setSourceArrivalWarning(title, description); + trainrunSection2.setSourceDepartureWarning(title, description); } const transitionNew1 = node1.getTransition(trainrunSection1.getId()); diff --git a/src/app/services/ui/filter.service.ts b/src/app/services/ui/filter.service.ts index 2e9bda05..4d0d132e 100644 --- a/src/app/services/ui/filter.service.ts +++ b/src/app/services/ui/filter.service.ts @@ -129,7 +129,7 @@ export class FilterService implements OnDestroy { const fs = this.activeFilterSetting.copy(); this.filterSettingStore.filterSettings.push(fs); this.activateFilterSetting(fs.getId()); - this.setActiveFilterSettingName("Neuer Filter", fs.getId()); + this.setActiveFilterSettingName($localize`:@@app.services.ui.newFilter:New filter`, fs.getId()); this.filterSettingUpdated(); return fs; } diff --git a/src/app/services/util/connection.validator.ts b/src/app/services/util/connection.validator.ts index fda99447..c4d9adf2 100644 --- a/src/app/services/util/connection.validator.ts +++ b/src/app/services/util/connection.validator.ts @@ -29,8 +29,8 @@ export class ConnectionValidator { if (nonStopConnectionError) { connection.setWarning( - "Anschluss auf Durchfahrt gezeichnet!", - "Anschluss auf Durchfahrt gezeichnet!", + $localize`:@@app.services.util.connection-validator.connection-marked-for-transit.title:Connection marked for transition!`, + $localize`:@@app.services.util.connection-validator.connection-marked-for-transit.description:Connection marked for transition!` ); } else { connection.resetWarning(); diff --git a/src/app/services/util/trainrun.iterator.ts b/src/app/services/util/trainrun.iterator.ts index 045dd1e1..bafebaa6 100644 --- a/src/app/services/util/trainrun.iterator.ts +++ b/src/app/services/util/trainrun.iterator.ts @@ -58,7 +58,7 @@ export class TrainrunIterator { this.pointerElement = new TrainrunSectionNodePair(undefined, undefined); // log the issue this.logService.error( - "Iterator has detected an infinity loop. The iteration terminated early!", + $localize`:@@app.services.util.trainrun-iteration.error.infinity-loop:Iterator has detected an infinity loop. The iteration terminated early!`, new Error().stack, ); return this.currentElement; diff --git a/src/app/services/util/trainrunsection.validator.ts b/src/app/services/util/trainrunsection.validator.ts index 8c453339..bc533598 100644 --- a/src/app/services/util/trainrunsection.validator.ts +++ b/src/app/services/util/trainrunsection.validator.ts @@ -12,8 +12,8 @@ export class TrainrunsectionValidator { if (Math.abs(calculatedTargetArrivalTime - trainrunSection.getTargetArrival()) > 1 / 60) { trainrunSection.setTargetArrivalWarning( - "Target Arrival Warning", - "Target arrival time cannot be reached", + $localize`:@@app.services.util.trainrunsection-validator.target-arrival-not-reacheable.title:Target Arrival Warning`, + $localize`:@@app.services.util.trainrunsection-validator.target-arrival-not-reacheable.description:Target arrival time cannot be reached`, ); } else { trainrunSection.resetTargetArrivalWarning(); @@ -25,8 +25,8 @@ export class TrainrunsectionValidator { if (Math.abs(calculatedSourceArrivalTime - trainrunSection.getSourceArrival()) > 1 / 60) { trainrunSection.setSourceArrivalWarning( - "Source Arrival Warning", - "Target arrival time cannot be reached", + $localize`:@@app.services.util.trainrunsection-validator.source-arrival-not-reacheable.title:Source Arrival Warning`, + $localize`:@@app.services.util.trainrunsection-validator.source-arrival-not-reacheable.description:Source arrival time cannot be reached`, ); } else { trainrunSection.resetSourceArrivalWarning(); @@ -36,8 +36,8 @@ export class TrainrunsectionValidator { static validateTravelTime(trainrunSection: TrainrunSection) { if (trainrunSection.getTravelTime() < 1) { trainrunSection.setTravelTimeWarning( - "Travel Time Warning", - "Travel time must be greater-equal than 1", + $localize`:@@app.services.util.trainrunsection-validator.travel-time-less-than-1.title:Travel Time less than 1`, + $localize`:@@app.services.util.trainrunsection-validator.travel-time-less-than-1.description:Travel time must be greater than or equal to 1`, ); } else { trainrunSection.resetTravelTimeWarning(); diff --git a/src/app/services/util/transition.validator.ts b/src/app/services/util/transition.validator.ts index 7f5fb703..cd74aff1 100644 --- a/src/app/services/util/transition.validator.ts +++ b/src/app/services/util/transition.validator.ts @@ -36,42 +36,42 @@ export class TransitionValidator { trainrunSections.trainrunSection1.getSourceNodeId() === node.getId() ) { trainrunSections.trainrunSection1.setSourceArrivalWarning( - "Source Arrival Warning", - "Time cannot be reached", + $localize`:@@app.services.util.transition-validator.source-arrival-not-reacheable.title:Source Arrival Warning`, + $localize`:@@app.services.util.transition-validator.source-arrival-not-reacheable.description:Source arrival time cannot be reached`, ); trainrunSections.trainrunSection1.setSourceDepartureWarning( - "Source Departure Warning", - "Time cannot be reached", + $localize`:@@app.services.util.transition-validator.source-departure-not-reacheable.title:Source Departure Warning`, + $localize`:@@app.services.util.transition-validator.source-departure-not-reacheable.description:Source departure time cannot be reached`, ); } else { trainrunSections.trainrunSection1.setTargetArrivalWarning( - "Target Arrival Warning", - "Time cannot be reached", + $localize`:@@app.services.util.transition-validator.target-arrival-not-reacheable.title:Target Arrival Warning`, + $localize`:@@app.services.util.transition-validator.target-arrival-not-reacheable.description:Target arrival time cannot be reached`, ); trainrunSections.trainrunSection1.setTargetDepartureWarning( - "Target Departure Warning", - "Time cannot be reached", + $localize`:@@app.services.util.transition-validator.target-departure-not-reacheable.title:Target Departure Warning`, + $localize`:@@app.services.util.transition-validator.target-departure-not-reacheable.description:Target departure time cannot be reached`, ); } if ( trainrunSections.trainrunSection2.getSourceNodeId() === node.getId() ) { trainrunSections.trainrunSection2.setSourceArrivalWarning( - "Source Arrival Warning", - "Time cannot be reached", + $localize`:@@app.services.util.transition-validator.source-arrival-not-reacheable.title:Source Arrival Warning`, + $localize`:@@app.services.util.transition-validator.source-arrival-not-reacheable.description:Source arrival time cannot be reached`, ); trainrunSections.trainrunSection2.setSourceDepartureWarning( - "Source Departure Warning", - "Time cannot be reached", + $localize`:@@app.services.util.transition-validator.source-departure-not-reacheable.title:Source Departure Warning`, + $localize`:@@app.services.util.transition-validator.source-departure-not-reacheable.description:Source departure time cannot be reached`, ); } else { trainrunSections.trainrunSection2.setTargetArrivalWarning( - "Target Arrival Warning", - "Time cannot be reached", + $localize`:@@app.services.util.transition-validator.target-arrival-not-reacheable.title:Target Arrival Warning`, + $localize`:@@app.services.util.transition-validator.target-arrival-not-reacheable.description:Target arrival time cannot be reached`, ); trainrunSections.trainrunSection2.setTargetDepartureWarning( - "Target Departure Warning", - "Time cannot be reached", + $localize`:@@app.services.util.transition-validator.target-departure-not-reacheable.title:Target Departure Warning`, + $localize`:@@app.services.util.transition-validator.target-departure-not-reacheable.description:Target departure time cannot be reached`, ); } } else { diff --git a/src/app/streckengrafik/components/streckengrafik.component.html b/src/app/streckengrafik/components/streckengrafik.component.html index 0cce5300..d98d5646 100644 --- a/src/app/streckengrafik/components/streckengrafik.component.html +++ b/src/app/streckengrafik/components/streckengrafik.component.html @@ -8,7 +8,7 @@
@@ -25,7 +25,7 @@ @@ -151,37 +151,37 @@
diff --git a/src/app/streckengrafik/components/streckengrafik.component.ts b/src/app/streckengrafik/components/streckengrafik.component.ts index 05e52a8b..2cf4e930 100644 --- a/src/app/streckengrafik/components/streckengrafik.component.ts +++ b/src/app/streckengrafik/components/streckengrafik.component.ts @@ -149,36 +149,36 @@ export class StreckengrafikComponent return this.streckengrafikDisplayElementService.isRailTrackSliderVisible(); } - getRailTrackliderButtonText(): string { + getRailTrackSliderButtonText(): string { if (!this.streckengrafikDisplayElementService.isRailTrackSliderVisible()) { - return "\u{2610} Streckengleis"; + return `\u{2610} ${$localize`:@@app.streckengrafik.components.rail-track-slider:Rail track slider`}`; } - return "\u{2611} Streckengleis"; + return `\u{2611} ${$localize`:@@app.streckengrafik.components.rail-track-slider:Rail track slider`}`; } getHeadwayBandButtonText(): string { if (!this.streckengrafikDisplayElementService.isHeadwayBandVisible()) { - return "\u{2610} Zugfolgezeiten"; + return `\u{2610} ${$localize`:@@app.streckengrafik.components.headway-band:Headway band`}`; } - return "\u{2611} Zugfolgezeiten"; + return `\u{2611} ${$localize`:@@app.streckengrafik.components.headway-band:Headway band`}`; } getTimeButtonText(): string { if ( this.streckengrafikDisplayElementService.isFilterStreckengrafikTimeNotFocusNorEnabled() ) { - return "\u{2610} Zeit"; + return `\u{2610} ${$localize`:@@app.streckengrafik.components.time:Time`}`; } - return "\u{2611} Zeit"; + return `\u{2611} ${$localize`:@@app.streckengrafik.components.time:Time`}`; } getNameButtonText(): string { if ( this.streckengrafikDisplayElementService.isFilterStreckengrafikNameNotFocusNorEnabled() ) { - return "\u{2610} Name"; + return `\u{2610} ${$localize`:@@app.streckengrafik.components.name:Name`}`; } - return "\u{2611} Name"; + return `\u{2611} ${$localize`:@@app.streckengrafik.components.name:Name`}`; } getZoomButtonClassTag(tag: string, zoomFactor: number): string { diff --git a/src/app/utils/navigation-parameters.ts b/src/app/utils/navigation-parameters.ts index d7e51173..994d3445 100644 --- a/src/app/utils/navigation-parameters.ts +++ b/src/app/utils/navigation-parameters.ts @@ -11,7 +11,7 @@ export class NavigationParameters { getProjectId(): number { const id = this.tryGetProjectId(); if (!id) { - throw new Error("No project ID available"); + throw new Error($localize`:@@app.utils.navigation-parameters.no-project-id:No project ID available`); } return id; } @@ -24,7 +24,7 @@ export class NavigationParameters { getVariantId(): number { const id = this.tryGetVariantId(); if (!id) { - throw new Error("No variant ID available"); + throw new Error($localize`:@@app.utils.navigation-parameters.no-variant-id:No variant ID available`); } return id; } @@ -37,7 +37,7 @@ export class NavigationParameters { getVersionId(): number { const id = this.tryGetVersionId(); if (!id) { - throw new Error("No variant ID available"); + throw new Error($localize`:@@app.utils.navigation-parameters.no-version-id:No version ID available`); } return id; } diff --git a/src/app/view/card-grid/card/card.component.html b/src/app/view/card-grid/card/card.component.html index 5eefe084..b785e62c 100644 --- a/src/app/view/card-grid/card/card.component.html +++ b/src/app/view/card-grid/card/card.component.html @@ -8,7 +8,7 @@
{{ subtitle }}
-
öffnen + {{ 'app.view.card-grid.card.open' | translate }}
- Filterbare Labels für {{ dialogTitel }} bearbeiten + + {{ 'app.view.dialogs.filterable-labels-dialog.filterable-label-dialog-component.edit-filterable-labels' | translate:{ 'element': this.dialogTitle} }} +
- +
diff --git a/src/app/view/dialogs/filterable-labels-dialog/filterable-labels-form/filterable-label-form.component.ts b/src/app/view/dialogs/filterable-labels-dialog/filterable-labels-form/filterable-label-form.component.ts index b30679fa..cd405ae4 100644 --- a/src/app/view/dialogs/filterable-labels-dialog/filterable-labels-form/filterable-label-form.component.ts +++ b/src/app/view/dialogs/filterable-labels-dialog/filterable-labels-form/filterable-label-form.component.ts @@ -31,7 +31,7 @@ export class FilterableLabelFormComponent implements OnInit { export interface FilterableLabelsFormComponentModel { name: string; - dialogTitel: string; + dialogTitle: string; saveLabelCallback; deleteLabelCallback; transferLabelCallback; diff --git a/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.html b/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.html index 40d679bc..1a497738 100644 --- a/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.html +++ b/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.html @@ -4,9 +4,9 @@
@@ -16,8 +16,8 @@ setClassedTag(color) }}" (click)="onColor(color)" - title="{{ getColorTitle(color) }}" - style="{{ getColorStyle(color) }}" + [title]="getColorTitle(color)" + [style]="getColorStyle(color)" [ngClass]="{'NgxEditor__Color--Active': setActiveColor(color)}" > {{ getColorButtonText(color) }} @@ -29,11 +29,11 @@ cdkFocusInitial [editor]="editor" [formControl]="model.getControl('noteText')" - [placeholder]="'Kommentar hier eingeben...'" + [placeholder]="'app.view.dialogs.note-dialog.html-editor.editor-placeholder' | translate" (focusout)="onUpdate()" (keydown)="onKeydown($event)" > Pflichtfeld{{ 'app.view.dialogs.note-dialog.html-editor.mandatory-field' | translate }}
diff --git a/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.ts b/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.ts index 2223648f..7059c0bb 100644 --- a/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.ts +++ b/src/app/view/dialogs/note-dialog/htmlEditor/html-editor.component.ts @@ -19,45 +19,45 @@ export class HtmlEditorComponent implements OnInit, OnDestroy { toolbar: Toolbar = [["bold", "italic"], ["bullet_list"], ["link"]]; colorPresets: HtmlEditorColor[] = [ new HtmlEditorColor( - "Verwende die Frabe des Frabschemas für EC", + $localize`:@@app.view.dialogs.note-dialog.html-editor.color-presets.ec.title:Use color of the color scheme for EC`, "EC", "var(--" + StaticDomTags.PREFIX_COLOR_VARIABLE + "_EC_" + StaticDomTags.TAG_FOCUS.toUpperCase() + ")", ), new HtmlEditorColor( - "Verwende die Frabe des Frabschemas für IC", + $localize`:@@app.view.dialogs.note-dialog.html-editor.color-presets.ic.title:Use color of the color scheme for IC`, "IC", "var(--" + StaticDomTags.PREFIX_COLOR_VARIABLE + "_IC_" + StaticDomTags.TAG_FOCUS.toUpperCase() + ")", ), new HtmlEditorColor( - "Verwende die Frabe des Frabschemas für IR", + $localize`:@@app.view.dialogs.note-dialog.html-editor.color-presets.ir.title:Use color of the color scheme for IR`, "IR", "var(--" + StaticDomTags.PREFIX_COLOR_VARIABLE + "_IR_" + StaticDomTags.TAG_FOCUS.toUpperCase() + ")", ), new HtmlEditorColor( - "Verwende die Frabe des Frabschemas für RE", + $localize`:@@app.view.dialogs.note-dialog.html-editor.color-presets.re.title:Use color of the color scheme for RE`, "RE", "var(--" + StaticDomTags.PREFIX_COLOR_VARIABLE + "_RE_" + StaticDomTags.TAG_FOCUS.toUpperCase() + ")", ), new HtmlEditorColor( - "Verwende die Frabe des Frabschemas für S", + $localize`:@@app.view.dialogs.note-dialog.html-editor.color-presets.s.title:Use color of the color scheme for S`, "S", "var(--" + StaticDomTags.PREFIX_COLOR_VARIABLE + "_S_" + StaticDomTags.TAG_FOCUS.toUpperCase() + ")", ), new HtmlEditorColor( - "Verwende die Frabe des Frabschemas für GEX", + $localize`:@@app.view.dialogs.note-dialog.html-editor.color-presets.gex.title:Use color of the color scheme for GEX`, "GEX", "var(--" + StaticDomTags.PREFIX_COLOR_VARIABLE + "_GEX_" + StaticDomTags.TAG_FOCUS.toUpperCase() + ")", ), new HtmlEditorColor( - "Verwende die Frabe des Frabschemas für G", + $localize`:@@app.view.dialogs.note-dialog.html-editor.color-presets.g.title:Use color of the color scheme for G`, "G", "var(--" + StaticDomTags.PREFIX_COLOR_VARIABLE + "_G_" + StaticDomTags.TAG_FOCUS.toUpperCase() + ")", ), - new HtmlEditorColor("grün", "", "green"), - new HtmlEditorColor("blau", "", "blue"), - new HtmlEditorColor("rosa", "", "magenta"), - new HtmlEditorColor("rot", "", "red"), - new HtmlEditorColor("Warnung", "!", "var(--COLOR_Warning)"), + new HtmlEditorColor($localize`:@@app.view.dialogs.note-dialog.html-editor.color-presets.green.title:green`, "", "green"), + new HtmlEditorColor($localize`:@@app.view.dialogs.note-dialog.html-editor.color-presets.blue.title:blue`, "", "blue"), + new HtmlEditorColor($localize`:@@app.view.dialogs.note-dialog.html-editor.color-presets.magenta.title:magenta`, "", "magenta"), + new HtmlEditorColor($localize`:@@app.view.dialogs.note-dialog.html-editor.color-presets.red.title:red`, "", "red"), + new HtmlEditorColor($localize`:@@app.view.dialogs.note-dialog.html-editor.color-presets.warning.title:warning color`, "!", "var(--COLOR_Warning)"), ]; updateSubscription: Subscription; diff --git a/src/app/view/dialogs/note-dialog/note-dialog.component.html b/src/app/view/dialogs/note-dialog/note-dialog.component.html index 931e8ba8..b28b4e05 100644 --- a/src/app/view/dialogs/note-dialog/note-dialog.component.html +++ b/src/app/view/dialogs/note-dialog/note-dialog.component.html @@ -9,19 +9,18 @@
- + - + - +
- +
@@ -11,7 +11,7 @@ class="FunctionButton" tabindex="-1" mode="icon" - title="Kommentar löschen" + [title]="'app.view.dialogs.note-dialog.delete-note' | translate" (click)="onDeleteNote()" > (); - formmodel: FormModel; + formModel: FormModel; private destroyed = new Subject(); private deleteNoteCallback = null; private saveNoteCallback = null; ngOnInit(): void { - this.formmodel = new FormModel( + this.formModel = new FormModel( this.noteDialogParameter.noteFormComponentModel ?? { id: 0, noteTitle: "", @@ -62,11 +62,11 @@ export class NoteEditElementComponent implements OnInit, OnDestroy { } private updateNote() { - this.formmodel.tryGetValid(); - const newNoteTitle: string = this.formmodel.getControl("noteTitle").value; - const newNoteText: string = this.formmodel.getControl("noteText").value; - const newNoteHeight: string = this.formmodel.getControl("noteHeight").value; - const newNoteWidth: string = this.formmodel.getControl("noteWidth").value; + this.formModel.tryGetValid(); + const newNoteTitle: string = this.formModel.getControl("noteTitle").value; + const newNoteText: string = this.formModel.getControl("noteText").value; + const newNoteHeight: string = this.formModel.getControl("noteHeight").value; + const newNoteWidth: string = this.formModel.getControl("noteWidth").value; this.saveNoteCallback( this.noteDialogParameter.noteFormComponentModel.id, newNoteTitle, diff --git a/src/app/view/dialogs/note-dialog/note-filter-tab/note-filter-tab.component.html b/src/app/view/dialogs/note-dialog/note-filter-tab/note-filter-tab.component.html index 445febee..6bc4046c 100644 --- a/src/app/view/dialogs/note-dialog/note-filter-tab/note-filter-tab.component.html +++ b/src/app/view/dialogs/note-dialog/note-filter-tab/note-filter-tab.component.html @@ -1,7 +1,6 @@
- + @@ -14,7 +13,7 @@ diff --git a/src/app/view/dialogs/note-dialog/note-form/note-form.component.html b/src/app/view/dialogs/note-dialog/note-form/note-form.component.html index 26999fdb..3f0f1446 100644 --- a/src/app/view/dialogs/note-dialog/note-form/note-form.component.html +++ b/src/app/view/dialogs/note-dialog/note-form/note-form.component.html @@ -1,4 +1,4 @@ - + diff --git a/src/app/view/dialogs/stammdaten-dialog/stammdaten-dialog.component.html b/src/app/view/dialogs/stammdaten-dialog/stammdaten-dialog.component.html index afc7a914..7389ceac 100644 --- a/src/app/view/dialogs/stammdaten-dialog/stammdaten-dialog.component.html +++ b/src/app/view/dialogs/stammdaten-dialog/stammdaten-dialog.component.html @@ -1,18 +1,18 @@
- Stammdaten + {{ 'app.view.dialogs.stammdaten-dialog.base-data' | translate }}
- + - + - + - + - + - + - + - + - + - + - + - +
Betriebspunkt{{ 'app.view.dialogs.stammdaten-dialog.operationalPoint' | translate }} {{ element.betriebspunkt }} Haltezeit IPV{{ 'app.view.dialogs.stammdaten-dialog.ipv-stop-time' | translate }}
{{ element["HaltezeitIPV"].haltezeit }} @@ -21,7 +21,7 @@
Haltezeit A{{ 'app.view.dialogs.stammdaten-dialog.a-stop-time' | translate }}
{{ element["HaltezeitA"].haltezeit }} @@ -30,7 +30,7 @@
Haltezeit B{{ 'app.view.dialogs.stammdaten-dialog.b-stop-time' | translate }}
{{ element["HaltezeitB"].haltezeit }} @@ -39,7 +39,7 @@
Haltezeit C{{ 'app.view.dialogs.stammdaten-dialog.c-stop-time' | translate }}
{{ element["HaltezeitC"].haltezeit }} @@ -48,7 +48,7 @@
Haltezeit D{{ 'app.view.dialogs.stammdaten-dialog.d-stop-time' | translate }}
{{ element["HaltezeitD"].haltezeit }} @@ -57,7 +57,7 @@
ZAZ{{ 'app.view.dialogs.stammdaten-dialog.zaz' | translate }}
{{ element.zaz }} @@ -66,7 +66,7 @@
Connection Time{{ 'app.view.dialogs.stammdaten-dialog.connection-time' | translate }}
{{ element.connection_time }} @@ -75,7 +75,7 @@
Region{{ 'app.view.dialogs.stammdaten-dialog.region' | translate }}
{{ element.region }} @@ -84,7 +84,7 @@
Kategorie{{ 'app.view.dialogs.stammdaten-dialog.category' | translate }}
{{ element.kategorie }} @@ -93,7 +93,7 @@
Filterbare Labels{{ 'app.view.dialogs.stammdaten-dialog.filterable-labels' | translate }}
{{ element.filterableLabels }} @@ -102,7 +102,7 @@
Position{{ 'app.view.dialogs.stammdaten-dialog.position' | translate }}
{{ element.pos.getX() }}
@@ -118,7 +118,7 @@
diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-and-section-dialog.component.html b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-and-section-dialog.component.html index 2dce8809..4fa3ffdd 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-and-section-dialog.component.html +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-and-section-dialog.component.html @@ -34,7 +34,8 @@ [trainrunDialogParameter]="data" > - + diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-filter-tab/trainrun-filter-tab.component.html b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-filter-tab/trainrun-filter-tab.component.html index 8bfa3661..72c26cf7 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-filter-tab/trainrun-filter-tab.component.html +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-filter-tab/trainrun-filter-tab.component.html @@ -1,7 +1,6 @@
- + @@ -14,7 +13,7 @@ @@ -44,7 +43,7 @@ class="FunctionButton" tabindex="-1" (click)="onDeleteTrainrun()" - title="Zuglauf löschen" + [title]="'app.view.dialogs.trainrun-and-section-dialog.trainrun-tab.trainrunDelete' | translate" > diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-filter-tab/trainrun-filter-tab.component.ts b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-filter-tab/trainrun-filter-tab.component.ts index c2ddbadc..d4420711 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-filter-tab/trainrun-filter-tab.component.ts +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-filter-tab/trainrun-filter-tab.component.ts @@ -97,8 +97,8 @@ export class TrainrunFilterTabComponent implements OnInit, OnDestroy { } onDeleteTrainrun() { - const dialogTitle = "Löschen"; - const dialogContent = "Soll der gesamte Zuglauf definitiv gelöscht werden?"; + const dialogTitle = $localize`:@@app.view.dialogs.trainrun-and-section-dialog.trainrun-tab.delete:Delete`; + const dialogContent = $localize`:@@app.view.dialogs.trainrun-and-section-dialog.trainrun-tab.deleteConfirmationQuestion:Should the entire train route be definitively deleted?`; const confirmationDialogParamter = new ConfirmationDialogParameter( dialogTitle, dialogContent, diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.html b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.html index 18d48ebd..6e878063 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.html +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.html @@ -1,5 +1,5 @@
- + - Kategorie + {{ 'app.view.dialogs.trainrun-and-section-dialog.trainrun-tab.category' | translate }}
- Verkehrt + {{ 'app.view.dialogs.trainrun-and-section-dialog.trainrun-tab.verkehrt' | translate }}
@@ -72,7 +72,7 @@ class="FunctionButton" tabindex="-1" (click)="onDeleteTrainrun()" - title="Zuglauf löschen" + [title]="'app.view.dialogs.trainrun-and-section-dialog.trainrun-tab.trainrunDelete' | translate" > diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.ts b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.ts index 0d5a38d5..0b5181d8 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.ts +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.ts @@ -161,8 +161,8 @@ export class TrainrunTabComponent implements OnDestroy { } onDeleteTrainrun() { - const dialogTitle = "Löschen"; - const dialogContent = "Soll der gesamte Zuglauf definitiv gelöscht werden?"; + const dialogTitle = $localize`:@@app.view.dialogs.trainrun-and-section-dialog.trainrun-tab.delete:Delete`; + const dialogContent = $localize`:@@app.view.dialogs.trainrun-and-section-dialog.trainrun-tab.deleteConfirmationQuestion:Should the entire train route be definitively deleted?`; const confirmationDialogParamter = new ConfirmationDialogParameter( dialogTitle, dialogContent, diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.html b/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.html index 289478df..d51c1118 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.html +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.html @@ -473,7 +473,7 @@ *ngIf="trainrunSectionTimesService.getShowWarningTwoLocks() === true" disabled > - {{ warningTwoLocks }} + {{ 'app.view.dialogs.trainrun-and-section-dialog.trainrun-section-tab.warningTwoLocks' | translate }} - Alle nicht sichtbare Elemente löschen + {{ 'app.view.editor-edit-tools-view-component.delete-all-non-visible-elements' | translate }}

- Sichtbare Elemente + {{ 'app.view.editor-edit-tools-view-component.visible-elements' | translate }}
- Alle sichtbare Züge löschen + {{ 'app.view.editor-edit-tools-view-component.delete-all-visible-trainruns' | translate }}
- Alle sichtbare Kommentare löschen + {{ 'app.view.editor-edit-tools-view-component.delete-all-visible-notes' | translate }}
- Alle sichtbare Elemente löschen + {{ 'app.view.editor-edit-tools-view-component.delete-all-visible-elements' | translate }} - Netzgrafik - Zusammenführen + {{ 'app.view.editor-edit-tools-view-component.merge-netzgrafik-title' | translate }}
- Züge als Kopie einfügen + {{ 'app.view.editor-edit-tools-view-component.add-netzgrafik-as-copy' | translate }} Bearbeiten
- Züge durch Zusammenführen einfügen + {{ 'app.view.editor-edit-tools-view-component.merge-netzgrafik' | translate }}     Keine Labels vorhanden.    {{ 'app.view.editor-edit-tools-view-component.label-drop-list.no-labels-available' | translate }}
@@ -68,7 +68,7 @@
- Takt + {{ 'app.view.editor-filter-view.frequency' | translate }}
- Verkehrt + {{ 'app.view.editor-filter-view.time-category' | translate }}
- Filterbare Labels: Züge + {{ 'app.view.editor-filter-view.filterable-labels-trainruns' | translate }} - + @@ -81,10 +81,10 @@

Filter

- Filterbare Labels: Knoten + {{ 'app.view.editor-filter-view.filterable-labels-nodes' | translate }} - + @@ -96,10 +96,10 @@

Filter

- Filterbare Labels: Kommentare + {{ 'app.view.editor-filter-view.filterable-labels-notes' | translate }} - + @@ -110,15 +110,15 @@

Filter

- Anzeigen + {{ 'app.view.editor-filter-view.display' | translate }} - + - Zeiten + {{ 'app.view.editor-filter-view.times' | translate }}
- + Filter Abfahrt- und Ankuftszeiten anzeigen + >{{ 'app.view.editor-filter-view.display-arrival-departure-times' | translate }} - Abfahrt- und Ankuftszeiten für Durchfahrten anzeigen + {{ 'app.view.editor-filter-view.display-arrival-departure-times-for-connections' | translate }} Fahrzeiten anzeigen + >{{ 'app.view.editor-filter-view.display-travel-times' | translate }} Zugname anzeigen + >{{ 'app.view.editor-filter-view.display-trainrun-name' | translate }}

- Anschlüsse + {{ 'app.view.editor-filter-view.connections' | translate }}
Anschlüsse anzeigen + >{{ 'app.view.editor-filter-view.display-connections' | translate }}

- Knoten + {{ 'app.view.editor-filter-view.nodes' | translate }}
Knoten ohne (angezeigte) Züge anzeigen + >{{ 'app.view.editor-filter-view.display-nodes-without-visible-trainruns' | translate }} Knoten mit nur durchfahrenden Züge anzeigen + >{{ 'app.view.editor-filter-view.display-nodes-with-only-stopping-trainruns' | translate }}

- Kommentare + {{ 'app.view.editor-filter-view.notes' | translate }}
Kommentare anzeigen + >{{ 'app.view.editor-filter-view.display-notes' | translate }}
@@ -189,16 +189,16 @@

Filter

sbb-secondary-button class="sbb-mt-m" [disabled]="isDisplayFilteringActive()" - title="Anzeigefilter zurücksetzen" + [title]="'app.view.editor-filter-view.reset-display-filter' | translate" (click)="onResetDisplayFilter()" > - Anzeigefilter zurücksetzen + {{ 'app.view.editor-filter-view.reset-display-filter' | translate }}
- Gespeicherte Filter + {{ 'app.view.editor-filter-view.saved-filters' | translate }}
Filter mode="ghost" [title]="getFilterSettingTooltip(filterSetting)" > - {{ makeFilterSettingButtonLabel(filterSetting) }} + {{ makeFilterSettingButtonLabel(filterSetting) | translate }}
diff --git a/src/app/view/editor-filter-view/editor-filter-view.component.ts b/src/app/view/editor-filter-view/editor-filter-view.component.ts index 2d5d8ef3..b8485f2e 100644 --- a/src/app/view/editor-filter-view/editor-filter-view.component.ts +++ b/src/app/view/editor-filter-view/editor-filter-view.component.ts @@ -152,9 +152,9 @@ export class EditorFilterViewComponent implements OnInit, OnDestroy { getFilterSettingTooltip(filterSetting: FilterSetting): string { if (!this.filterService.isFilterSettingEnabled(filterSetting.getId())) { - return filterSetting.name + " laden"; + return $localize`:@@app.view.editor-filter-view.load-filter:Load ${filterSetting.name}`; } - return filterSetting.name + " neu laden"; + return $localize`:@@app.view.editor-filter-view.reload-filter:Reload ${filterSetting.name}`; } isTrainrunFilteringActive(): boolean { @@ -300,18 +300,18 @@ export class EditorFilterViewComponent implements OnInit, OnDestroy { getCategoryTooltip(trainrunCategory: TrainrunCategory): string { if (!this.filterService.isFilterTrainrunCategoryEnabled(trainrunCategory)) { - return trainrunCategory.name + " einblenden"; + return $localize`:@@app.view.editor-filter-view.show-trainrun-category:Show ${trainrunCategory.name}:trainrunCategory:`; } - return trainrunCategory.name + " ausblenden"; + return $localize`:@@app.view.editor-filter-view.hide-trainrun-category:Hide ${trainrunCategory.name}:trainrunCategory:`; } getTimeCategoryTooltip(trainrunTimeCategory: TrainrunTimeCategory): string { /* if (!this.filterService.isFilterTrainrunCategoryEnabled(trainrunTimeCategory)) { - return trainrunTimeCategory.name + ' einblenden'; + return $localize`:@@app.view.editor-filter-view.show-trainrun-time-category:Show ${trainrunTimeCategory.name}:trainrunTimeCategory:`; } */ - return trainrunTimeCategory.name + " ausblenden"; + return $localize`:@@app.view.editor-filter-view.hide-trainrun-time-category:Hide ${trainrunTimeCategory.name}:trainrunTimeCategory:`; } makeCategoryButtonLabel(trainrunCategory: TrainrunCategory): string { @@ -380,9 +380,9 @@ export class EditorFilterViewComponent implements OnInit, OnDestroy { if ( !this.filterService.isFilterTrainrunFrequencyEnabled(trainrunFrequency) ) { - return trainrunFrequency.name + " einblenden"; + return trainrunFrequency.name + " " + $localize`:@@app.view.editor-filter-view.show-trainrun-frequency:Show ${trainrunFrequency.name}:trainrunFrequency:`; } - return trainrunFrequency.name + " ausblenden"; + return trainrunFrequency.name + " " + $localize`:@@app.view.editor-filter-view.hide-trainrun-frequency:Hide ${trainrunFrequency.name}:trainrunFrequency:`; } makeFrequencyButtonLabel(trainrunFrequency: TrainrunFrequency): string { diff --git a/src/app/view/editor-filter-view/filterable-label-filter/filterable-label-filter.component.html b/src/app/view/editor-filter-view/filterable-label-filter/filterable-label-filter.component.html index 8858cce6..a8045272 100644 --- a/src/app/view/editor-filter-view/filterable-label-filter/filterable-label-filter.component.html +++ b/src/app/view/editor-filter-view/filterable-label-filter/filterable-label-filter.component.html @@ -1,5 +1,5 @@
- Keine Labels vorhanden. + {{ 'app.view.editor-filter-view.filterable-label-filter.no-labels-available' | translate }}
@@ -11,7 +11,7 @@ class="TrainrunDialog FilterableLabel LogicalOperator" (click)="enableLogicalFilterOperatorAnd(nodeLabelGrp)" > - Oder + {{ 'app.view.editor-filter-view.filterable-label-filter.or' | translate }} @@ -19,7 +19,7 @@ class="TrainrunDialog FilterableLabel LogicalOperator" (click)="enableLogicalFilterOperatorOr(nodeLabelGrp)" > - Und + {{ 'app.view.editor-filter-view.filterable-label-filter.and' | translate }}
@@ -46,9 +46,9 @@ sbb-secondary-button class="sbb-mt-m" [disabled]="isFilteringLabels()" - title="Alles anzeigen" + [title]="'app.view.editor-filter-view.filterable-label-filter.show-all' | translate" (click)="OnResetFilterableLabels()" > - Filter zurücksetzen + {{ 'app.view.editor-filter-view.filterable-label-filter.reset-filter' | translate }}
diff --git a/src/app/view/editor-filter-view/filterable-label-filter/filterable-label-filter.component.ts b/src/app/view/editor-filter-view/filterable-label-filter/filterable-label-filter.component.ts index 21202f66..859175ac 100644 --- a/src/app/view/editor-filter-view/filterable-label-filter/filterable-label-filter.component.ts +++ b/src/app/view/editor-filter-view/filterable-label-filter/filterable-label-filter.component.ts @@ -165,9 +165,9 @@ export class FilterableLabelFilterComponent implements OnInit, OnDestroy { (filterLabel) => filterLabel === labelObject.getId(), ) !== undefined ) { - return labelObject.getLabel() + ": einblenden"; + return labelObject.getLabel() + ": " + $localize`:@@app.view.editor-filter-view.filterable-label-filter.show:show`; } - return labelObject.getLabel() + ": ausblenden"; + return labelObject.getLabel() + ": " + $localize`:@@app.view.editor-filter-view.filterable-label-filter.hide:hide`; } isFilteringLabels(): boolean { diff --git a/src/app/view/editor-menu/editor-menu.component.html b/src/app/view/editor-menu/editor-menu.component.html index 64666f83..dfed58c5 100644 --- a/src/app/view/editor-menu/editor-menu.component.html +++ b/src/app/view/editor-menu/editor-menu.component.html @@ -7,16 +7,16 @@
- Speichere Änderungen + {{ 'app.view.editor-menu.save-changes' | translate }} - Änderungen gespeichert + {{ 'app.view.editor-menu.changes-saved' | translate }} - Lese-Modus + {{ 'app.view.editor-menu.read-mode' | translate }}
@@ -34,7 +34,7 @@ mode="icon" class="ButtonFilter" (click)="onFilter()" - title="Filter ein-/ausblenden" + [title]="'app.view.editor-menu.show-hide-filter' | translate" > - @@ -125,7 +125,7 @@ mode="ghost" class="ButtonZoomIn" (click)="onZoomIn()" - title="Hereinzoomen" + [title]="'app.view.editor-menu.zoom-in' | translate" > + @@ -144,7 +144,7 @@ " [disabled]="isStreckengrafikEditing() || isAnalytics()" (click)="onTopologieEditor()" - title="Topologie Editor deaktiviert" + [title]="'app.view.editor-menu.topology-editor-disabled' | translate" > Einstellungen +

{{ 'app.view.editor-properties-view-component.settings' | translate }}

- Farbschema - Theme + {{ 'app.view.editor-properties-view-component.color-scheme' | translate }} + {{ 'app.view.editor-properties-view-component.theme' | translate }}
Einstellungen
- Hintergrundfarbe + {{ 'app.view.editor-properties-view-component.background-color' | translate }} @@ -34,7 +34,7 @@

Einstellungen

sbb-secondary-button style="vertical-align: middle;" [disabled]="isBackgroundColorWhite()" - title="Hintergrundfarbe auf 'weiss' setzten" + [title]="'app.view.editor-properties-view-component.set-color-to-white' | translate" (click)="setBackgroundColorToWhite()" > Einstellungen sbb-secondary-button [disabled]="isDefaultBackgroundColorActive()" style="vertical-align: middle;" - title="Hintergrundfarbe auf Standard zurücksetzen" + [title]="'app.view.editor-properties-view-component.reset-background-color-to-default' | translate" (click)="onResetBackgroundColor()" >
- Hintergrundfarbe (dunkel) + {{ 'app.view.editor-properties-view-component.background-color-black' | translate }}
Einstellungen
diff --git a/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.ts b/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.ts index 26228a61..e00bb395 100644 --- a/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.ts +++ b/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.ts @@ -174,16 +174,9 @@ export class EditorNodeDetailViewComponent implements OnInit, OnDestroy { onDeleteNode() { const node = this.nodeService.getSelectedNode(); - const dialogTitle = "Löschen"; - const dialogContent = - "Soll der Knoten " + - node.getBetriebspunktName() + - " (" + - node.getFullName() + - ") definitiv gelöscht werden?"; const confirmationDialogParamter = new ConfirmationDialogParameter( - dialogTitle, - dialogContent, + $localize`:@@app.view.editor-side-view.editor-node-detail-view.delete:Delete`, + $localize`:@@app.view.editor-side-view.editor-node-detail-view.deleteNodeDialog:Should the node ${node.getBetriebspunktName()}:operationalPointShortName: (${node.getFullName()}:operationalPointName:) be definitely deleted?` ); this.uiInteractionService .showConfirmationDiagramDialog(confirmationDialogParamter) diff --git a/src/app/view/editor-tools-view-component/editor-tools-view.component.html b/src/app/view/editor-tools-view-component/editor-tools-view.component.html index ca641ce8..2b9fd681 100644 --- a/src/app/view/editor-tools-view-component/editor-tools-view.component.html +++ b/src/app/view/editor-tools-view-component/editor-tools-view.component.html @@ -1,49 +1,49 @@ -

Weitere Funktionen

+

{{ 'app.view.editor-side-view.editor-tools-view-component.more-functions' | translate }}

- Exportieren + {{ 'app.view.editor-side-view.editor-tools-view-component.export' | translate }} - Exportieren als SVG + {{ 'app.view.editor-side-view.editor-tools-view-component.export-as-svg' | translate }}
- Exportieren als PNG + {{ 'app.view.editor-side-view.editor-tools-view-component.export-as-png' | translate }}
- Drucken + {{ 'app.view.editor-side-view.editor-tools-view-component.print' | translate }}
- Netzgrafik + {{ 'app.view.editor-side-view.editor-tools-view-component.netzgrafik' | translate }} - Netzgrafik als JSON exportieren + {{ 'app.view.editor-side-view.editor-tools-view-component.export-netzgrafik-as-json' | translate }}
- Zuglauf als .csv exportieren + {{ 'app.view.editor-side-view.editor-tools-view-component.export-trainruns-as-csv' | translate }} In Exel : Daten -> Aus Text/CSV -> Filename ... importieren.{{ 'app.view.editor-side-view.editor-tools-view-component.export-trainruns-as-csv-excel' | translate }}
- Stammdaten + {{ 'app.view.editor-side-view.editor-tools-view-component.base-data' | translate }} - Stammdaten importieren + {{ 'app.view.editor-side-view.editor-tools-view-component.import-base-data' | translate }} Hilfe: CSV - Datei{{ 'app.view.editor-side-view.editor-tools-view-component.help-csv-data' | translate }} Weitere Funktionen
- Stammdaten exportieren + {{ 'app.view.editor-side-view.editor-tools-view-component.export-base-data' | translate }}
diff --git a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts index 97988596..a4f42f91 100644 --- a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts +++ b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts @@ -90,7 +90,7 @@ export class EditorToolsViewComponent { onSave() { const data: NetzgrafikDto = this.dataService.getNetzgrafikDto(); const blob = new Blob([JSON.stringify(data)], {type: "application/json"}); - downloadBlob(blob, "netzgrafik.json"); + downloadBlob(blob, $localize`:@@app.view.editor-side-view.editor-tools-view-component.netzgrafikFile:netzgrafik` + ".json"); } onExportNetzgrafikSVG() { @@ -109,7 +109,7 @@ export class EditorToolsViewComponent { const a = document.createElement("a"); document.body.appendChild(a); a.href = uri; - a.download = "netzgrafik.svg"; + a.download = $localize`:@@app.view.editor-side-view.editor-tools-view-component.netzgrafikFile:netzgrafik` + ".svg"; a.click(); URL.revokeObjectURL(a.href); a.remove(); @@ -135,7 +135,7 @@ export class EditorToolsViewComponent { const containerInfo = this.getContainertoExport(); svg.saveSvgAsPng( containerInfo.documentToExport, - "netzgrafik.png", + $localize`:@@app.view.editor-side-view.editor-tools-view-component.netzgrafikFile:netzgrafik` + ".png", containerInfo.exportParameter, ); //containerInfo.documentToExport.setAttribute('style', containerInfo.documentSavedStyle); @@ -162,13 +162,13 @@ export class EditorToolsViewComponent { } onExportStammdaten() { - const filename = "stammdaten.csv"; + const filename = $localize`:@@app.view.editor-side-view.editor-tools-view-component.baseDataFile:baseData` + ".csv"; const csvData = this.convertToStammdatenCSV(); this.onExport(filename, csvData); } onExportZuglauf() { - const filename = "zuglauf.csv"; + const filename = $localize`:@@app.view.editor-side-view.editor-tools-view-component.trainrunFile:trainrun` + ".csv"; const csvData = this.convertToZuglaufCSV(); this.onExport(filename, csvData); } @@ -198,21 +198,19 @@ export class EditorToolsViewComponent { const comma = ","; const headers: string[] = []; - headers.push("BP"); - headers.push("Bahnhof"); - headers.push("Kategorie"); - headers.push("Region"); - headers.push("Fahrgastwechselzeit_IPV"); - headers.push("Fahrgastwechselzeit_A"); - headers.push("Fahrgastwechselzeit_B"); - headers.push("Fahrgastwechselzeit_C"); - headers.push("Fahrgastwechselzeit_D"); - headers.push("ZAZ"); - headers.push("Umsteigezeit"); - headers.push("Labels"); - headers.push("X"); - headers.push("Y"); - headers.push("Erstellen"); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.bp:BP`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.station:Station`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.category:category`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.passengerConnectionTimeA:Passenger_connection_time_A`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.passengerConnectionTimeB:Passenger_connection_time_B`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.passengerConnectionTimeC:Passenger_connection_time_C`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.passengerConnectionTimeD:Passenger_connection_time_D`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.ZAZ:ZAZ`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.transferTime:Transfer_time`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.labels:Labels`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.X:X`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.Y:Y`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.create:Create`); const contentData: string[] = []; contentData.push(headers.join(separator)); @@ -381,22 +379,22 @@ export class EditorToolsViewComponent { const comma = ","; const contentData: string[] = []; const headers: string[] = []; - headers.push("Zugkategorie"); - headers.push("Zugname"); - headers.push("Startbahnhof"); - headers.push("Zielbahnhof"); - headers.push("Verkehrsperiode"); - headers.push("Takt"); - headers.push("Abfahrtsminute am Start Knoten)"); - headers.push("Fahrzeit Start-Ziel"); - headers.push("Ankuntsminute am Ziel Knoten)"); - headers.push("Wendezeit Zielbahnhof"); - headers.push("Abfahrtsminute am Ziel Knoten"); - headers.push("Fahrzeit Ziel-Start"); - headers.push("Ankuntsminute am Start Knoten"); - headers.push("Wendezeit Startbahnhof"); - headers.push("Umlaufzeit"); - headers.push("Labels"); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.trainCategory:Train category`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.trainName:Train name`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.startStation:Start station`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.destinationStation:Destination station`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.trafficPeriod:Traffic period`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.frequence:Frequence`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.departureMinuteAtStart:Minute of departure at start node`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.travelTimeStartDestination:Travel time start-destination`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.arrivalMinuteAtDestination:Arrival minute at destination node`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.turnaroundTimeDestination:Turnaround time at destination station`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.departureMinuteDeparture:Departure minute at destination node`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.travelTimeDestinationStart:Travel time destination-start`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.arrivalMinuteAtStart:Arrival minute at start node`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.turnaroundTimeStart:Turnaround time at start station`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.turnaroundTime:Turnaround time`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.labels:Labels`); contentData.push(headers.join(separator)); this.trainrunService diff --git a/src/app/view/error-view/error-view.component.html b/src/app/view/error-view/error-view.component.html index fa15a935..e70c6eb9 100644 --- a/src/app/view/error-view/error-view.component.html +++ b/src/app/view/error-view/error-view.component.html @@ -1,4 +1,4 @@ -

Fehler

+

{{ 'app.view.error-view.error' | translate}}

{{ error | async }}

diff --git a/src/app/view/navigation-bar/navigation-bar.component.spec.ts b/src/app/view/navigation-bar/navigation-bar.component.spec.ts index ed4eab09..4bc818c2 100644 --- a/src/app/view/navigation-bar/navigation-bar.component.spec.ts +++ b/src/app/view/navigation-bar/navigation-bar.component.spec.ts @@ -9,6 +9,7 @@ import {NavigationEnd, Router, RouterEvent} from "@angular/router"; import {NavigationService} from "../../services/ui/navigation.service"; import {NEVER} from "rxjs"; import {map} from "rxjs/operators"; +import {I18nModule} from "../../core/i18n/i18n.module"; describe("NavigationBarComponent", () => { let component: NavigationBarComponent; @@ -25,6 +26,7 @@ describe("NavigationBarComponent", () => { await TestBed.configureTestingModule({ declarations: [NavigationBarComponent], + imports: [I18nModule], providers: [ {provide: Router, useValue: router}, {provide: NavigationService, useValue: {}}, diff --git a/src/app/view/navigation-bar/navigation-bar.component.ts b/src/app/view/navigation-bar/navigation-bar.component.ts index 92d44422..743d036d 100644 --- a/src/app/view/navigation-bar/navigation-bar.component.ts +++ b/src/app/view/navigation-bar/navigation-bar.component.ts @@ -23,7 +23,7 @@ export class NavigationBarComponent implements OnInit { { name: this.projectsBackendService .getProject(params[0].asNumber()) - .pipe(map((project) => `Projekt «${project.name}»`)), + .pipe(map((project) => $localize`:@@app.view.navigation-bar.project-name:Project «${project.name}:name:»`)), route: this.navigationService.getRouteToVariants( params[0].asNumber(), ), @@ -39,8 +39,8 @@ export class NavigationBarComponent implements OnInit { .pipe( map((project) => project.isArchived === false - ? `Projekt «${project.name}»` - : `Projekt «${project.name}» (archiviert)`, + ? $localize`:@@app.view.navigation-bar.project-name:Project «${project.name}:name:»` + : $localize`:@@app.view.navigation-bar.project-name-archived:Project «${project.name}:name:» (archived)`, ), ), route: this.navigationService.getRouteToVariants( @@ -53,8 +53,8 @@ export class NavigationBarComponent implements OnInit { .pipe( map((variant) => variant.isArchived === false - ? `Variante «${variant.latestVersion.name}»` - : `Variante «${variant.latestVersion.name}» (archiviert)`, + ? $localize`:@@app.view.navigation-bar.variant-name:Variant «${variant.latestVersion.name}:name:»` + : $localize`:@@app.view.navigation-bar.variant-name-archived:Variant «${variant.latestVersion.name}:name:» (archived)`, ), ), route: this.navigationService.getRouteToEditor( diff --git a/src/app/view/project/project-dialog/project-dialog.component.html b/src/app/view/project/project-dialog/project-dialog.component.html index 63952acd..5c7d95ca 100644 --- a/src/app/view/project/project-dialog/project-dialog.component.html +++ b/src/app/view/project/project-dialog/project-dialog.component.html @@ -1,9 +1,9 @@
- Projekt erstellen - Projekt bearbeiten + {{ 'app.view.project.project-dialog.create-project' | translate }} + {{ 'app.view.project.project-dialog.edit-project' | translate }}
- +
- +
diff --git a/src/app/view/project/project-dialog/project-dialog.component.spec.ts b/src/app/view/project/project-dialog/project-dialog.component.spec.ts index 7b34cf88..c9f2a22b 100644 --- a/src/app/view/project/project-dialog/project-dialog.component.spec.ts +++ b/src/app/view/project/project-dialog/project-dialog.component.spec.ts @@ -2,6 +2,7 @@ import {ComponentFixture, TestBed} from "@angular/core/testing"; import {ProjectDialogComponent} from "./project-dialog.component"; import {SBB_DIALOG_DATA, SbbDialogRef} from "@sbb-esta/angular/dialog"; +import {I18nModule} from "../../../core/i18n/i18n.module"; describe("ProjectDialogComponent", () => { let component: ProjectDialogComponent; @@ -10,6 +11,7 @@ describe("ProjectDialogComponent", () => { beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ProjectDialogComponent], + imports:[I18nModule], providers: [ {provide: SbbDialogRef, useValue: {}}, {provide: SBB_DIALOG_DATA, useValue: {}}, diff --git a/src/app/view/project/project-dialog/project-dialog.component.ts b/src/app/view/project/project-dialog/project-dialog.component.ts index 5c2a6a03..5b54ac22 100644 --- a/src/app/view/project/project-dialog/project-dialog.component.ts +++ b/src/app/view/project/project-dialog/project-dialog.component.ts @@ -15,7 +15,7 @@ import {filter} from "rxjs/operators"; styleUrls: ["./project-dialog.component.scss"], }) export class ProjectDialogComponent { - readonly formmodel: FormModel; + readonly formModel: FormModel; readonly isNewProject: boolean; constructor( @@ -25,7 +25,7 @@ export class ProjectDialogComponent { >, @Inject(SBB_DIALOG_DATA) data?: ProjectFormComponentModel, ) { - this.formmodel = new FormModel( + this.formModel = new FormModel( data ?? { name: "", description: "", @@ -48,10 +48,10 @@ export class ProjectDialogComponent { } onCreateClicked(): void { - const formdata = this.formmodel.tryGetValid(); + const formData = this.formModel.tryGetValid(); - if (formdata) { - this.dialogRef.close(formdata); + if (formData) { + this.dialogRef.close(formData); } } diff --git a/src/app/view/project/project-dialog/project-form/project-form.component.html b/src/app/view/project/project-dialog/project-form/project-form.component.html index 72b92ec5..f37f23ed 100644 --- a/src/app/view/project/project-dialog/project-form/project-form.component.html +++ b/src/app/view/project/project-dialog/project-form/project-form.component.html @@ -1,38 +1,38 @@
- + Pflichtfeld{{ 'app.view.project.project-dialog.project-form.mandatory-field' | translate }} - + - + - Benutzer müssen mit ihrer E-Mail angegeben werden. Eingabe pro E-Mail jeweils mit 'Enter' bestätigen. + {{ 'app.view.project.project-dialog.project-form.tooltip' | translate }} - Benutzer mit Schreibzugriff + {{ 'app.view.project.project-dialog.project-form.user-with-write-access' | translate }} - Ungültige Werte (keine E-Mail Adresse): + {{ 'app.view.project.project-dialog.project-form.invalid-values' | translate }}: {{ model.getControl("writeUsers").errors?.invalidUserIdAsEmails }} - Benutzer mit Lesezugriff + {{ 'app.view.project.project-dialog.project-form.user-with-read-access' | translate }} - Ungültige Werte (keine E-Mail Adresse): + {{ 'app.view.project.project-dialog.project-form.invalid-values' | translate }}: {{ model.getControl("readUsers").errors?.invalidUserIdAsEmails }} diff --git a/src/app/view/project/project-dialog/project-form/project-form.component.spec.ts b/src/app/view/project/project-dialog/project-form/project-form.component.spec.ts index c0f09566..8e4f5802 100644 --- a/src/app/view/project/project-dialog/project-form/project-form.component.spec.ts +++ b/src/app/view/project/project-dialog/project-form/project-form.component.spec.ts @@ -6,6 +6,7 @@ import { userIdsAsEmailValidator, } from "./project-form.component"; import {FormModel} from "../../../../utils/form-model"; +import {I18nModule} from "../../../../core/i18n/i18n.module"; import {UntypedFormControl} from "@angular/forms"; describe("ProjectFormComponent", () => { @@ -15,6 +16,7 @@ describe("ProjectFormComponent", () => { beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ProjectFormComponent], + imports: [I18nModule], }).compileComponents(); }); diff --git a/src/app/view/project/projects-view/projects-view.component.html b/src/app/view/project/projects-view/projects-view.component.html index 37271645..2074345e 100644 --- a/src/app/view/project/projects-view/projects-view.component.html +++ b/src/app/view/project/projects-view/projects-view.component.html @@ -1,5 +1,5 @@ -

Projekte

+

{{ 'app.view.project.projects-view.projects' | translate }}

Projekte class="search" type="text" sbbInput - placeholder="Projekt suchen" + [placeholder]="'app.view.project.projects-view.search-project' | translate" />
Archiv anzeigen{{ 'app.view.project.projects-view.show-archive' | translate }}
@@ -24,7 +24,7 @@

Projekte

> diff --git a/src/app/view/project/projects-view/projects-view.component.spec.ts b/src/app/view/project/projects-view/projects-view.component.spec.ts index d1abce98..bdcf5484 100644 --- a/src/app/view/project/projects-view/projects-view.component.spec.ts +++ b/src/app/view/project/projects-view/projects-view.component.spec.ts @@ -6,6 +6,7 @@ import {ProjectsViewService} from "./projects-view.service"; import {SbbDialogModule} from "@sbb-esta/angular/dialog"; import {ProjectControllerBackendService} from "../../../api/generated"; import {NavigationService} from "../../../services/ui/navigation.service"; +import {I18nModule} from "../../../core/i18n/i18n.module"; describe("ProjectsViewComponent", () => { let component: ProjectsViewComponent; @@ -20,7 +21,7 @@ describe("ProjectsViewComponent", () => { await TestBed.configureTestingModule({ declarations: [ProjectsViewComponent], - imports: [SbbDialogModule], + imports: [SbbDialogModule, I18nModule], providers: [ {provide: ProjectsViewService, useValue: projectViewService}, { diff --git a/src/app/view/project/projects-view/projects-view.component.ts b/src/app/view/project/projects-view/projects-view.component.ts index 5dcc08fd..0627a909 100644 --- a/src/app/view/project/projects-view/projects-view.component.ts +++ b/src/app/view/project/projects-view/projects-view.component.ts @@ -103,8 +103,8 @@ export class ProjectsViewComponent implements OnDestroy { this.uiInteractionService .showConfirmationDiagramDialog( new ConfirmationDialogParameter( - "Projekt archivieren", - "Möchten Sie das Projekt jetzt archivieren?", + $localize`:@@app.view.project.projects-view.archive-project.title:Archive project`, + $localize`:@@app.view.project.projects-view.archive-project.content:Would you like to archive the project now?`, ), ) .pipe( @@ -124,8 +124,8 @@ export class ProjectsViewComponent implements OnDestroy { this.uiInteractionService .showConfirmationDiagramDialog( new ConfirmationDialogParameter( - "Archivierung rückgängig machen", - "Möchten Sie die Archivierung des Projekts rückgängig machen?", + $localize`:@@app.view.project.projects-view.undo-archiving-project.title:Undo archiving`, + $localize`:@@app.view.project.projects-view.undo-archiving-project.content:Would you like to undo the archiving the project now?`, ), ) .pipe( @@ -147,7 +147,7 @@ export class ProjectsViewComponent implements OnDestroy { if (project.isArchived) { return of([ { - name: "Archivierung rückgängig machen", + name: $localize`:@@app.view.project.projects-view.undo-archiving:Undo archiving`, icon: "arrow-circle-eye-small", action: () => this.onUnarchiveProjectClicked(project), }, @@ -155,12 +155,12 @@ export class ProjectsViewComponent implements OnDestroy { } return of([ { - name: "Bearbeiten", + name: $localize`:@@app.view.project.projects-view.edit:Edit`, icon: "pen-small", action: () => this.onEditProjectClicked(project), }, { - name: "Archivieren", + name: $localize`:@@app.view.project.projects-view.archive:Archive`, icon: "archive-box-small", action: () => this.onArchiveProjectClicked(project), }, diff --git a/src/app/view/slots-view/slot/slot.component.spec.ts b/src/app/view/slots-view/slot/slot.component.spec.ts index 279ac63a..152bd265 100644 --- a/src/app/view/slots-view/slot/slot.component.spec.ts +++ b/src/app/view/slots-view/slot/slot.component.spec.ts @@ -1,6 +1,7 @@ import {ComponentFixture, TestBed} from "@angular/core/testing"; import {SlotComponent} from "./slot.component"; import {SbbMenu} from "@sbb-esta/angular/menu"; +import {I18nModule} from "../../../core/i18n/i18n.module"; describe("SlotComponent", () => { let component: SlotComponent; @@ -9,6 +10,7 @@ describe("SlotComponent", () => { beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [SlotComponent], + imports:[I18nModule], }).compileComponents(); }); diff --git a/src/app/view/variant/variant-dialog/variant-dialog.component.html b/src/app/view/variant/variant-dialog/variant-dialog.component.html index e22e92df..386e8425 100644 --- a/src/app/view/variant/variant-dialog/variant-dialog.component.html +++ b/src/app/view/variant/variant-dialog/variant-dialog.component.html @@ -1,13 +1,13 @@
- Variante erstellen - Variante bearbeiten + {{ 'app.view.variant.variant-dialog.create-variant' | translate }} + {{ 'app.view.variant.variant-dialog.edit-variant' | translate }}
- +
- +
diff --git a/src/app/view/variant/variant-dialog/variant-dialog.component.spec.ts b/src/app/view/variant/variant-dialog/variant-dialog.component.spec.ts index 458ec7cd..001a515d 100644 --- a/src/app/view/variant/variant-dialog/variant-dialog.component.spec.ts +++ b/src/app/view/variant/variant-dialog/variant-dialog.component.spec.ts @@ -1,6 +1,7 @@ import {ComponentFixture, TestBed} from "@angular/core/testing"; import {VariantDialogComponent} from "./variant-dialog.component"; import {SBB_DIALOG_DATA, SbbDialogRef} from "@sbb-esta/angular/dialog"; +import {I18nModule} from "../../../core/i18n/i18n.module"; describe("VariantDialogComponent", () => { let component: VariantDialogComponent; @@ -9,6 +10,7 @@ describe("VariantDialogComponent", () => { beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [VariantDialogComponent], + imports:[I18nModule], providers: [ {provide: SbbDialogRef, useValue: {}}, {provide: SBB_DIALOG_DATA, useValue: {}}, diff --git a/src/app/view/variant/variant-dialog/variant-dialog.component.ts b/src/app/view/variant/variant-dialog/variant-dialog.component.ts index 8df58f75..c780c973 100644 --- a/src/app/view/variant/variant-dialog/variant-dialog.component.ts +++ b/src/app/view/variant/variant-dialog/variant-dialog.component.ts @@ -15,7 +15,7 @@ import {filter} from "rxjs/operators"; styleUrls: ["./variant-dialog.component.scss"], }) export class VariantDialogComponent { - readonly formmodel: FormModel; + readonly formModel: FormModel; readonly isNewVariant: boolean; constructor( @@ -25,7 +25,7 @@ export class VariantDialogComponent { >, @Inject(SBB_DIALOG_DATA) data?: VariantFormComponentModel, ) { - this.formmodel = new FormModel( + this.formModel = new FormModel( data ?? {name: ""}, ); this.isNewVariant = !!!data; @@ -42,7 +42,7 @@ export class VariantDialogComponent { } onCreateClicked(): void { - const formdata = this.formmodel.tryGetValid(); + const formdata = this.formModel.tryGetValid(); if (formdata) { this.dialogRef.close(formdata); diff --git a/src/app/view/variant/variant-dialog/variant-form/variant-form.component.html b/src/app/view/variant/variant-dialog/variant-form/variant-form.component.html index 20208470..f3a42d18 100644 --- a/src/app/view/variant/variant-dialog/variant-form/variant-form.component.html +++ b/src/app/view/variant/variant-dialog/variant-form/variant-form.component.html @@ -1,13 +1,13 @@
- + Pflichtfeld{{ 'app.view.variant.variant-dialog.variant-form.mandatory-field' | translate }}
diff --git a/src/app/view/variant/variant-dialog/variant-form/variant-form.component.spec.ts b/src/app/view/variant/variant-dialog/variant-form/variant-form.component.spec.ts index 01a505fb..b30fb431 100644 --- a/src/app/view/variant/variant-dialog/variant-form/variant-form.component.spec.ts +++ b/src/app/view/variant/variant-dialog/variant-form/variant-form.component.spec.ts @@ -4,6 +4,7 @@ import { VariantFormComponentModel, } from "./variant-form.component"; import {FormModel} from "../../../../utils/form-model"; +import {I18nModule} from "../../../../core/i18n/i18n.module"; describe("VariantFormComponent", () => { let component: VariantFormComponent; @@ -11,6 +12,7 @@ describe("VariantFormComponent", () => { beforeEach(async () => { await TestBed.configureTestingModule({ + imports:[I18nModule], declarations: [VariantFormComponent], }).compileComponents(); }); diff --git a/src/app/view/variant/variant-view/variant-history/preview-button/preview-button.component.spec.ts b/src/app/view/variant/variant-view/variant-history/preview-button/preview-button.component.spec.ts index 3dd1b1af..19d4dc3b 100644 --- a/src/app/view/variant/variant-view/variant-history/preview-button/preview-button.component.spec.ts +++ b/src/app/view/variant/variant-view/variant-history/preview-button/preview-button.component.spec.ts @@ -1,6 +1,7 @@ import {ComponentFixture, TestBed} from "@angular/core/testing"; import {PreviewButtonComponent} from "./preview-button.component"; +import {I18nModule} from "../../../../../core/i18n/i18n.module"; describe("PreviewButtonComponent", () => { let component: PreviewButtonComponent; @@ -9,6 +10,7 @@ describe("PreviewButtonComponent", () => { beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [PreviewButtonComponent], + imports:[I18nModule], }).compileComponents(); }); diff --git a/src/app/view/variant/variant-view/variant-history/publish-entry/publish-entry.component.html b/src/app/view/variant/variant-view/variant-history/publish-entry/publish-entry.component.html index d9613a45..b0b9ce00 100644 --- a/src/app/view/variant/variant-view/variant-history/publish-entry/publish-entry.component.html +++ b/src/app/view/variant/variant-view/variant-history/publish-entry/publish-entry.component.html @@ -8,20 +8,16 @@
diff --git a/src/app/view/variant/variant-view/variant-history/publish-entry/publish-entry.component.ts b/src/app/view/variant/variant-view/variant-history/publish-entry/publish-entry.component.ts index ca1b7390..e3a32872 100644 --- a/src/app/view/variant/variant-view/variant-history/publish-entry/publish-entry.component.ts +++ b/src/app/view/variant/variant-view/variant-history/publish-entry/publish-entry.component.ts @@ -19,7 +19,7 @@ export class PublishEntryComponent { get actions(): HistoryEntryAction[] { return [ { - name: "Änderungen Verwerfen", + name: $localize`:@@app.view.variant.variant-view.variant-history.publish-entry.discard-changes:Discard changes`, icon: "trash-small", onClick: () => this.dropChangedClicked.next(), }, diff --git a/src/app/view/variant/variant-view/variant-history/released-entry/released-entry.component.ts b/src/app/view/variant/variant-view/variant-history/released-entry/released-entry.component.ts index 074ee74d..fa83f663 100644 --- a/src/app/view/variant/variant-view/variant-history/released-entry/released-entry.component.ts +++ b/src/app/view/variant/variant-view/variant-history/released-entry/released-entry.component.ts @@ -21,7 +21,7 @@ export class ReleasedEntryComponent { get actions(): HistoryEntryAction[] { const download = { - name: "Download", + name: $localize`:@@app.view.variant.variant-view.variant-history.released-entry.download:Download`, icon: "download-small", onClick: () => this.download.next({ @@ -37,12 +37,12 @@ export class ReleasedEntryComponent { if (this.model.conflict) { return [ { - name: "Änderungen Verwerfen", + name: $localize`:@@app.view.variant.variant-view.variant-history.released-entry.discard-changes:Discard changes`, icon: "trash-small", onClick: () => this.dropChanges.emit(), }, { - name: "Konflikt ignorieren", + name: $localize`:@@app.view.variant.variant-view.variant-history.released-entry.ignore-conflict:Ignore conflict`, icon: "tick-small", onClick: () => this.ignoreConflict.emit(), }, @@ -52,12 +52,12 @@ export class ReleasedEntryComponent { return [ { - name: "Wiederherstellen", + name: $localize`:@@app.view.variant.variant-view.variant-history.released-entry.restore:Restore`, icon: "arrows-circle-small", onClick: () => this.restore.next(this.model.id), }, { - name: "Als neue Variante", + name: $localize`:@@app.view.variant.variant-view.variant-history.released-entry.as-new-variant:As new variant`, icon: "circle-plus-small", onClick: () => this.saveAsNewVariant.emit(this.model.id), }, @@ -78,10 +78,10 @@ export class ReleasedEntryComponent { getMessage(): string | undefined { if (this.model.conflict) { - return "Version bereits vorhanden"; + return $localize`:@@app.view.variant.variant-view.variant-history.released-entry.version-already-available:Version already available`; } if (this.model.lastAdded) { - return "Erfolgreich publiziert"; + return $localize`:@@app.view.variant.variant-view.variant-history.released-entry.successfully-published:Successfully published`; } return undefined; diff --git a/src/app/view/variant/variant-view/variant-history/snapshot-entry/snapshot-entry.component.ts b/src/app/view/variant/variant-view/variant-history/snapshot-entry/snapshot-entry.component.ts index a131f13d..b51023a8 100644 --- a/src/app/view/variant/variant-view/variant-history/snapshot-entry/snapshot-entry.component.ts +++ b/src/app/view/variant/variant-view/variant-history/snapshot-entry/snapshot-entry.component.ts @@ -18,7 +18,7 @@ export class SnapshotEntryComponent { get actions(): HistoryEntryAction[] { const download = { - name: "Download", + name: $localize`:@@app.view.variant.variant-view.variant-history.snapshot-entry.download:Download`, icon: "download-small", onClick: () => this.download.emit({ @@ -33,12 +33,12 @@ export class SnapshotEntryComponent { return [ { - name: "Wiederherstellen", + name: $localize`:@@app.view.variant.variant-view.variant-history.snapshot-entry.restore:Restore`, icon: "arrows-circle-small", onClick: () => this.restore.next(this.model.id), }, { - name: "Als neue Variante", + name: $localize`:@@app.view.variant.variant-view.variant-history.snapshot-entry.as-new-variant:As new variant`, icon: "circle-plus-small", onClick: () => this.saveAsNewVariant.emit(this.model.id), }, @@ -56,14 +56,14 @@ export class SnapshotEntryComponent { getMessage(): string | undefined { if (this.model.lastAdded) { - return "Erfolgreich gespeichert"; + return $localize`:@@app.view.variant.variant-view.variant-history.snapshot-entry.successfully-published:Successfully published`; } return undefined; } getTitle(): string { - return `Änderung ${this.model.snapshotVersion}`; + return $localize`:@@app.view.variant.variant-view.variant-history.snapshot-entry.change-snapshot-version:Change ${this.model.snapshotVersion}:snapshotVersion:`; } } diff --git a/src/app/view/variant/variant-view/variant-history/variant-history.component.ts b/src/app/view/variant/variant-view/variant-history/variant-history.component.ts index b98293ec..681a134c 100644 --- a/src/app/view/variant/variant-view/variant-history/variant-history.component.ts +++ b/src/app/view/variant/variant-view/variant-history/variant-history.component.ts @@ -72,8 +72,8 @@ export class VariantHistoryComponent implements OnChanges, OnDestroy { this.uiInteractionService .showConfirmationDiagramDialog( new ConfirmationDialogParameter( - "Neue Version publizieren", - "Möchten Sie Ihre persönlichen Änderungen als neue Version publizieren?", + $localize`:@@app.view.variant.variant-view.variant-history.new-version-published.title:New version published`, + $localize`:@@app.view.variant.variant-view.variant-history.new-version-published.content:Would you like to publish your personal changes as a new version?`, ), ) .pipe(takeUntil(this.destroyed)) @@ -88,8 +88,8 @@ export class VariantHistoryComponent implements OnChanges, OnDestroy { this.uiInteractionService .showConfirmationDiagramDialog( new ConfirmationDialogParameter( - "Änderungen verwerfen", - "Möchten Sie Ihre persönlichen Änderungen unwiderruflich verwerfen?", + $localize`:@@app.view.variant.variant-view.variant-history.discard-changes.title:Discard changes`, + $localize`:@@app.view.variant.variant-view.variant-history.discard-changes.content:Would you like to irrevocably discard your personal changes?`, ), ) .pipe(takeUntil(this.destroyed)) @@ -112,8 +112,8 @@ export class VariantHistoryComponent implements OnChanges, OnDestroy { this.uiInteractionService .showConfirmationDiagramDialog( new ConfirmationDialogParameter( - "Version wiederherstellen", - "Möchten Sie den Stand dieser Version wiederherstellen?", + $localize`:@@app.view.variant.variant-view.variant-history.restore-version.title:Restore version`, + $localize`:@@app.view.variant.variant-view.variant-history.restore-version.content:Would you like to restore the status of this version?`, ), ) .pipe(takeUntil(this.destroyed)) @@ -128,8 +128,8 @@ export class VariantHistoryComponent implements OnChanges, OnDestroy { this.uiInteractionService .showConfirmationDiagramDialog( new ConfirmationDialogParameter( - "Konflikt ignorieren", - "Möchten Sie, dass der aktuelle Stand auf der höchsten publizierten Version aufbaut?", + $localize`:@@app.view.variant.variant-view.variant-history.ignore-conflict.title:Ignore conflict`, + $localize`:@@app.view.variant.variant-view.variant-history.ignore-conflict.content:Would you like the current version to be based on the highest published version?`, ), ) .pipe(takeUntil(this.destroyed)) diff --git a/src/app/view/variant/variant-view/variant-view.component.html b/src/app/view/variant/variant-view/variant-view.component.html index b8c9cc11..475355e1 100644 --- a/src/app/view/variant/variant-view/variant-view.component.html +++ b/src/app/view/variant/variant-view/variant-view.component.html @@ -1,7 +1,7 @@

{{ (versionControlService.variant$ | async)?.latestVersion?.name }} - (archiviert) + {{ 'app.view.variant.variant-view.archived' | translate }}
@@ -10,21 +10,21 @@

sbb-menu-item mode="icon" (click)="onOpenVariantDialog()" - title="Variante bearbeiten" + [title]="'app.view.variant.variant-view.edit-variant' | translate" *ngIf="versionControlService.variant.isWritable" > - Variante bearbeiten + {{ 'app.view.variant.variant-view.edit-variant' | translate }}

@@ -32,7 +32,7 @@

- Versionen + {{ 'app.view.variant.variant-view.versions' | translate }}

{{ proj.name }} - (archiviert) + {{ ' ' + 'app.view.variant.variants-view.archived' | translate }}

- +
Archiv anzeigen{{ 'app.view.variant.variants-view.show-archive' | translate }}
@@ -44,7 +44,7 @@

- +
diff --git a/src/app/view/variant/variants-view/variants-view.component.spec.ts b/src/app/view/variant/variants-view/variants-view.component.spec.ts index cf88e8ce..f0e96dfc 100644 --- a/src/app/view/variant/variants-view/variants-view.component.spec.ts +++ b/src/app/view/variant/variants-view/variants-view.component.spec.ts @@ -12,6 +12,7 @@ import {of} from "rxjs"; import {ActivatedRoute} from "@angular/router"; import {NavigationService} from "../../../services/ui/navigation.service"; import {VersionControlService} from "../../../services/data/version-control.service"; +import {I18nModule} from "../../../core/i18n/i18n.module"; describe("VariantsViewComponent", () => { let component: VariantsViewComponent; @@ -55,7 +56,7 @@ describe("VariantsViewComponent", () => { await TestBed.configureTestingModule({ declarations: [VariantsViewComponent], - imports: [SbbDialogModule], + imports: [SbbDialogModule, I18nModule], providers: [ {provide: ActivatedRoute, useValue: activatedRoute}, {provide: NavigationService, useValue: {}}, diff --git a/src/app/view/variant/variants-view/variants-view.component.ts b/src/app/view/variant/variants-view/variants-view.component.ts index d0be8172..a744f1c5 100644 --- a/src/app/view/variant/variants-view/variants-view.component.ts +++ b/src/app/view/variant/variants-view/variants-view.component.ts @@ -79,12 +79,12 @@ export class VariantsViewComponent implements OnDestroy { if (project.isWritable) { return [ { - name: "Projekt bearbeiten", + name: $localize`:@@app.view.variant.variants-view.edit-project:Edit project`, icon: "pen-small", action: () => this.onEditProjectClicked(), }, { - name: "Projekt archivieren", + name: $localize`:@@app.view.variant.variants-view.archive-project:Archive project`, icon: "archive-box-small", action: () => this.onArchiveProjectClicked(), }, @@ -92,12 +92,12 @@ export class VariantsViewComponent implements OnDestroy { } else if (project.isDeletable && project.isArchived) { return [ { - name: "Archivierung rückgängig machen", + name: $localize`:@@app.view.variant.variants-view.undo-archiving:Undo archiving`, icon: "arrow-circle-eye-small", action: () => this.onUnarchiveProjectClicked(), }, { - name: "Projekt löschen", + name: $localize`:@@app.view.variant.variants-view.delete-project:Delete project`, icon: "trash-small", action: () => this.onDeleteProjectClicked(), }, @@ -169,7 +169,7 @@ export class VariantsViewComponent implements OnDestroy { if (variant.isArchived) { return of([ { - name: "Archivierung rückgängig machen", + name: $localize`:@@app.view.variant.variants-view.undo-archiving:Undo archiving`, icon: "arrow-circle-eye-small", action: () => this.onUnarchiveVariantClicked(variant), }, @@ -177,7 +177,7 @@ export class VariantsViewComponent implements OnDestroy { } return of([ { - name: "Archivieren", + name: $localize`:@@app.view.variant.variants-view.archive:Archive`, icon: "archive-box-small", action: () => this.onArchiveVariantClicked(variant), }, @@ -188,8 +188,8 @@ export class VariantsViewComponent implements OnDestroy { this.uiInteractionService .showConfirmationDiagramDialog( new ConfirmationDialogParameter( - "Variante archivieren", - "Möchten Sie die Variante jetzt archivieren?", + $localize`:@@app.view.variant.variants-view.archive-variant.title:Archive variant`, + $localize`:@@app.view.variant.variants-view.archive-variant.content:Would you like to archive the variant now?`, ), ) .pipe( @@ -211,8 +211,8 @@ export class VariantsViewComponent implements OnDestroy { this.uiInteractionService .showConfirmationDiagramDialog( new ConfirmationDialogParameter( - "Archivierung rückgängig machen", - "Möchten Sie die Archivierung der Variante rückgängig machen?", + $localize`:@@app.view.variant.variants-view.undo-archiving-variant.title:Undo archiving`, + $localize`:@@app.view.variant.variants-view.undo-archiving-variant.content:Would you like to undo the archiving of the variant?`, ), ) .pipe( @@ -257,8 +257,8 @@ export class VariantsViewComponent implements OnDestroy { this.uiInteractionService .showConfirmationDiagramDialog( new ConfirmationDialogParameter( - "Projekt archivieren", - "Möchten Sie das Projekt jetzt archivieren?", + $localize`:@@app.view.variant.variants-view.archive-project.title:Archive project`, + $localize`:@@app.view.variant.variants-view.archive-project.content:Would you like to archive the project now?`, ), ) .pipe( @@ -274,8 +274,8 @@ export class VariantsViewComponent implements OnDestroy { this.uiInteractionService .showConfirmationDiagramDialog( new ConfirmationDialogParameter( - "Archivierung rückgängig machen", - "Möchten Sie die Archivierung des Projekts rückgängig machen?", + $localize`:@@app.view.variant.variants-view.undo-archiving-project.title:Archive variant`, + $localize`:@@app.view.variant.variants-view.undo-archiving-project.content:Would you like to undo the archiving of the project?`, ), ) .pipe( @@ -291,9 +291,8 @@ export class VariantsViewComponent implements OnDestroy { this.uiInteractionService .showConfirmationDiagramDialog( new ConfirmationDialogParameter( - "Projekt löschen", - "Möchten Sie das Projekt und alle enthaltenen Varianten endgültig löschen? " + - "Diese Aktion kann nicht rückgängig gemacht werden.", + $localize`:@@app.view.variant.variants-view.delete-project.title:Delete projekt`, + $localize`:@@app.view.variant.variants-view.delete-project.content:Do you want to permanently delete the project and all the variants it contains? This action cannot be undone.`, ), ) .pipe( @@ -305,7 +304,7 @@ export class VariantsViewComponent implements OnDestroy { } getTitleCurrentVersion(variant: VariantSummaryDto): string { - const archivedSuffix = variant.isArchived ? " (archiviert)" : ""; + const archivedSuffix = variant.isArchived ? " " + $localize`:@@app.view.variant.variants-view.archived:(archived)` : ""; if (variant.latestSnapshotVersion) { return variant.latestSnapshotVersion.name + "*" + archivedSuffix; @@ -315,7 +314,7 @@ export class VariantsViewComponent implements OnDestroy { return variant.latestReleaseVersion.name + archivedSuffix; } - throw new Error("Unexpected data: No snapshot and no released version."); + throw new Error($localize`:@@app.view.variant.variants-view.error-unexpected-data:Unexpected data: No snapshot and no released version.`); } getChangedAtCurrentVersion(variant: VariantSummaryDto): Date { @@ -327,7 +326,7 @@ export class VariantsViewComponent implements OnDestroy { return new Date(variant.latestReleaseVersion.createdAt); } - throw new Error("Unexpected data: No snapshot and no released version."); + throw new Error($localize`:@@app.view.variant.variants-view.error-unexpected-data:Unexpected data: No snapshot and no released version.`); } private updateProject(project: ProjectDto): void { diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json new file mode 100644 index 00000000..13b9af3c --- /dev/null +++ b/src/assets/i18n/de.json @@ -0,0 +1,640 @@ +{ + "app-routing": { + "module": { + "path": { + "404": "Die gesuchte Seite wurde nicht gefunden.", + "401": "Sie sind nicht autorisiert, bitte laden Sie die Seite neu.", + "403": "Sie sind nicht berechtigt diese Aktion durchzuführen.", + "409": "Es gab einen Konflikt bei der Ausführung Ihrer Aktion, bitte versuchen Sie es erneut.", + "error": "Es ist ein Fehler aufgetreten." + } + } + }, + "app": { + "version": "Version {$version}", + "user-guide": "Benutzeranleitung", + "user-manual": "Benutzerhandbuch", + "logout": "Logout", + "login": "Sie werden angemeldet...", + "logger": { + "title": "Titel" + }, + "models": { + "node": { + "shortNameDefault": "NEW", + "full-name-default": "Neuer Knoten" + }, + "note": { + "title-default": "Notiztitel", + "text-default": "Notiztext", + "default-title": "Notiztitel", + "default-text": "Notiztext" + } + }, + "netzgrafik-application": { + "variants": "Varianten", + "filter": "Filter", + "analytics": "Analytics", + "edit": "Bearbeiten", + "more-functions": "Weitere Funktionen", + "settings": "Einstellungen" + }, + "perlenkette": { + "perlenkette-node": { + "0-warning-connection": "Kein fehlerhafter Anschluss", + "1-warning-connection": "1 fehlerhafter Anschluss", + "n-warning-connections": "{$number} fehlerhafte Anschlüsse", + "0-fitting-connection": "Kein passender Anschluss", + "1-fitting-connection": "1 passender Anschluss", + "n-fitting-connections": "{$number} passende Anschlüsse" + }, + "show-only-closed-locks": "Zeige nur geschlossene Schlösser", + "show-all-locks": "Zeige alle Schlösser" + }, + "services": { + "data": { + "node": { + "transit-modified": { + "title": "Durchfahrt geändert", + "description": "Zeiten können nicht angepasst werden, beidseitger Lock gefunden" + } + }, + "trainrunsection": { + "intermediate-stop-replacement": { + "title": "Zwischenhalteumwandlung", + "description": "Zwischenhalteumwandlung führte bei der Vergabe der Zeiten zu inkonsistenzen!" + } + } + }, + "ui": { + "newFilter": "Neuer Filter" + }, + "util": { + "connection-validator": { + "connection-marked-for-transit": { + "title": "Anschluss auf Durchfahrt gezeichnet!", + "description": "Anschluss auf Durchfahrt gezeichnet!" + } + }, + "trainrun-iteration": { + "error": { + "infinity-loop": "Iterator hat eine Unendlichkeitsschleife entdeckt. Die Iteration wurde vorzeitig abgebrochen!" + } + }, + "trainrunsection-validator": { + "target-arrival-not-reacheable": { + "title": "Ziel Ankunft Warnung", + "description": "Zielankunftszeit kann nicht erreicht werden" + }, + "source-arrival-not-reacheable": { + "title": "Quelle Ankunft Warnung", + "description": "Quellankunftszeit kann nicht erreicht werden" + }, + "travel-time-less-than-1": { + "title": "Reisezeit weniger als 1", + "description": "Die Reisezeit muss größer oder gleich 1 sein." + } + }, + "transition-validator": { + "source-arrival-not-reacheable": { + "title": "Quelle Ankunft Warnung", + "description": "Quellankunftszeit kann nicht erreicht werden" + }, + "source-departure-not-reacheable": { + "title": "Quelle Abfahrt Warnung", + "description": "Quellabfahrtszeit kann nicht erreicht werden" + }, + "target-arrival-not-reacheable": { + "title": "Ziel Ankunft Warnung", + "description": "Zielankunftszeit kann nicht erreicht werden" + }, + "target-departure-not-reacheable": { + "title": "Ziel Abfahrt Warnung", + "description": "Zielabfahrtszeit kann nicht erreicht werden" + } + } + } + }, + "streckengrafik": { + "components": { + "reset": "Zurücksetzen", + "close-all-path-nodes": "Schliesse alle Gleisbeleger", + "open-all-path-nodes": "Öffne alle Gleisbeleger", + "show-advanced-display-functions": "Erweiterte Darstellungsfunktionen einblenden", + "show-or-hide-time-for-non-selected-trainruns": "Zeit ein-/ausblenden für nicht selektierte Züge", + "show-or-hide": "{$component} ein-/ausblenden", + "show-or-hide-name-for-non-selected-trainruns": "Zugnamen ein-/ausblenden für nicht selektierte Züge", + "hide-advanced-display-functions": "Erweiterte Darstellungsfunktionen ausblenden", + "rail-track-slider": "Streckengleis", + "headway-band": "Zugfolgezeiten", + "time": "Zeit", + "name": "Name" + } + }, + "utils": { + "navigation-parameters": { + "no-project-id": "Keine Projekt-ID vorhanden", + "no-variant-id": "Keine Variante-ID vorhanden", + "no-version-id": "Keine Version-ID vorhanden" + } + }, + "view": { + "card-grid": { + "card": { + "open": "Öffnen" + } + }, + "dialogs": { + "confirmation-dialog": { + "confirmation-default": "Ja", + "abort-default": "Nein" + }, + "filterable-labels-dialog": { + "filterable-label-dialog-component": { + "edit-filterable-labels": "Filterbare Labels für {$element} bearbeiten", + "transfer-to-all-visible": "auf alle sichtbaren übertragen", + "delete-from-all-visible": "aus allen sichtbaren löschen", + "transfer": { + "title": "Übernehmen", + "content": "Soll das Label {$label} auf alle sichtbaren {$element} übertragen werden?" + }, + "delete": { + "title": "Löschen", + "content": "Soll das Label {$label} definitiv aus allen sichtbaren {$element} gelöscht werden?" + } + }, + "filterable-labels-form": { + "mandatory-field": "Pflichtfeld" + } + }, + "note-dialog": { + "html-editor": { + "reset-color": "Farbe zurücksetzen", + "editor-placeholder": "Kommentar hier eingeben...", + "mandatory-field": "Pflichtfeld", + "color-presets": { + "ec": { + "title": "Verwende die Frabe des Frabschemas für EC" + }, + "ic": { + "title": "Verwende die Frabe des Frabschemas für IC" + }, + "ir": { + "title": "Verwende die Frabe des Frabschemas für IR" + }, + "re": { + "title": "Verwende die Frabe des Frabschemas für RE" + }, + "s": { + "title": "Verwende die Frabe des Frabschemas für S" + }, + "gex": { + "title": "Verwende die Frabe des Frabschemas für GEX" + }, + "g": { + "title": "Verwende die Frabe des Frabschemas für G" + }, + "green": { + "title": "green" + }, + "blue": { + "title": "blue" + }, + "magenta": { + "title": "magenta" + }, + "red": { + "title": "red" + }, + "warning": { + "title": "Warnfarbe" + } + } + }, + "note-tab": "Kommentar", + "filterable-labels-tab": "Filterbare Labels", + "delete-note": "Kommentar löschen", + "note-filter-tab": { + "labels": "Labels", + "label-placeholder": "Neues Label..." + }, + "note-form": { + "title": "Title", + "name": "Name" + } + }, + "stammdaten-dialog": { + "base-data": "Stammdaten", + "operationalPoint": "Betriebspunkt", + "ipv-stop-time": "Haltezeit IPV", + "a-stop-time": "Haltezeit A", + "b-stop-time": "Haltezeit B", + "c-stop-time": "Haltezeit C", + "d-stop-time": "Haltezeit D", + "zaz": "ZAZ", + "connection-time": "Anschlusszeit", + "region": "Region", + "category": "Kategorie", + "filterable-labels": "Filterbare Labels", + "position": "Position", + "close": "Schliessen" + }, + "trainrun-and-section-dialog" : { + "filterableLabels": "Filterbare Labels", + "trainrun-filter-tab": { + "labels": "Labels", + "newLabels" : "Neues Label...", + "trainrunDuplicate": "Zuglauf duplizieren", + "trainrunDelete": "Zuglauf löschen", + "delete": "Löschen", + "deleteConfirmationQuestion": "Soll der gesamte Zuglauf definitiv gelöscht werden?" + }, + "trainrun-tab": { + "tabName": "Name", + "category": "Kategorie", + "frequency": "Takt", + "verkehrt": "verkehrt", + "trainrunDuplicate": "Zuglauf duplizieren", + "trainrunDelete": "Zuglauf löschen", + "delete": "Löschen", + "deleteConfirmationQuestion": "Soll der gesamte Zuglauf definitiv gelöscht werden?" + }, + "trainrun-section-tab": { + "warningTwoLocks": "Warnung: Zu viele Zeiten sind gelockt!", + "propagateTimesToLeft": "Zeiten nach links propagieren", + "propagateTimesToRight": "Zeiten nach rechts propagieren" + } + } + }, + "editor-edit-tools-view-component": { + "edit": "Bearbeiten", + "filterable-labels": "Filterbare labels", + "trainruns": "Zugfahrten", + "nodes": "Knoten", + "notes": "Kommentare", + "delete-netzgrafik-title": "Netzgrafik - Löschen", + "non-visible-elements": "Nicht sichtbare Elemente", + "delete-all-non-visible-elements-tooltip": "Alle nicht sichtbare Elemente, wie Knoten, Zugfahrten und Kommentare löschen", + "delete-all-non-visible-elements": "Alle nicht sichtbare Elemente löschen", + "visible-elements": "Sichtbare Elemente", + "delete-all-visible-trainruns-tooltip": "Alle sichtbare Zugfahrten löschen", + "delete-all-visible-trainruns": "Alle sichtbare Zugfahrten löschen", + "delete-all-visible-notes-tooltip": "Alle sichtbare Kommentare löschen", + "delete-all-visible-notes": "Alle sichtbare Kommentare löschen", + "delete-all-visible-elements-tooltip": "Alle sichtbare Elemente, wie Knoten, Zugfahrten und Kommentare löschen", + "delete-all-visible-elements": "Alle sichtbare Elemente löschen", + "merge-netzgrafik-title": "Netzgrafik - Zusammenführen", + "add-netzgrafik-as-copy-tooltip": "Netzgrafik als Kopie hinzufügen (Zugfahrtenn, Knoten, Kommentare)", + "add-netzgrafik-as-copy": "Netzgrafik als Kopie hinzufügen", + "merge-netzgrafik-tooltip": "Netzgrafik durch Zusammenführen mergen (Zugfahrtenn, Knoten, Kommentare)", + "merge-netzgrafik": "Netzgrafik durch Zusammenführen mergen", + "delete": "Löschen", + "on-clear-delete-all-non-visible-elements": "Sollen alle nicht sichtbare Elemente aus der Netzgrafik definitiv gelöscht werden?", + "on-clear-delete-all-visible-elements": "Sollen alle sichtbare Elemente aus der Netzgrafik definitiv gelöscht werden?", + "on-clear-delete-all-visible-trainruns": "Sollen alle sichtbare Zugfahrten aus der Netzgrafik definitiv gelöscht werden?", + "on-clear-delete-all-visible-notes": "Sollen alle sichtbare Kommentare aus der Netzgrafik definitiv gelöscht werden?", + "label-drop-list": { + "no-labels-available": "Keine Labels vorhanden", + "delete-group": "Gruppe löschen", + "add-new-group": "Neue Gruppe hinzufügen", + "trainruns": "Zugfahrten", + "notes": "Kommentare", + "nodes": "Knoten" + } + }, + "editor-filter-view": { + "filter": "Filter", + "general": "Allgemein", + "category": "Kategorie", + "frequency": "Takt", + "time-category": "Verkehrt", + "display-all-trainruns": "Alle Zugfahrten anzeigen", + "reset-trainrun-filter": "Zugfilter zurücksetzen", + "filterable-labels-trainruns": "Filterbare Labels: Zugfahrten", + "filterable-labels-nodes": "Filterbare Labels: Knoten", + "filterable-labels-notes": "Filterbare Labels: Kommentare", + "display": "Anzeigen", + "times": "Zeiten", + "decimal-displayed": "Anzahl Nachkommastellenanzeigen", + "display-arrival-departure-times": "Abfahrt- und Ankuftszeiten anzeigen", + "display-arrival-departure-times-for-connections": "Abfahrt- und Ankuftszeiten für Durchfahrten anzeigen", + "display-travel-times": "Fahrzeiten anzeigen", + "display-trainrun-name": "Zugname anzeigen", + "connections": "Anschlüsse", + "display-connections": "Anschlüsse anzeigen", + "nodes": "Knoten", + "display-nodes-without-visible-trainruns": "Knoten ohne (angezeigte) Zugfahrten anzeigen", + "display-nodes-with-only-stopping-trainruns": "Knoten mit nur durchfahrenden Zugfahrten anzeigen", + "notes": "Kommentare", + "display-notes": "Kommentare anzeigen", + "reset-display-filter": "Anzeigefilter zurücksetzen", + "saved-filters": "Gespeicherte Filter", + "save-filters": "Filter speichern und als Filtereinstellungen hinzufügen", + "reset-all-display-filters": "Alle Anzeigefilter zurücksetzen", + "load-filter": "{$filter} laden", + "reload-filter": "{$filter} neu laden", + "show-trainrun-category": "{$trainrunCategory} einblenden", + "hide-trainrun-category": "{$trainrunCategory} ausblenden", + "show-trainrun-time-category": "{$trainrunTimeCategory} einblenden", + "hide-trainrun-time-category": "{$trainrunTimeCategory} ausblenden", + "show-trainrun-frequency": "{$trainrunFrequency} einblenden", + "hide-trainrun-frequency": "{$trainrunFrequency} ausblenden", + "filterable-label-filter": { + "no-labels-available": "Keine Labels vorhanden", + "or": "Oder", + "and": "Und", + "show-all": "Alles anzeigen", + "reset-filter": "Filter zurücksetzen", + "show": "einblenden", + "hode": "ausblenden" + } + }, + "editor-menu": { + "save-changes": "Speichere Änderungen", + "changes-saved": "Änderungen gespeichert", + "read-mode": "Lese-Modus", + "show-hide-filter": "Filter ein-/ausblenden", + "zoom-out": "Herauszoomer", + "zoom-in": "Hereinzoomen", + "topology-editor-disabled": "Topologie Editor deaktiviert", + "topology-editor-enabled": "Topologie Editor aktiviert", + "multiple-selection-tool-disabled": "Mehrfachauswahlstool ist deaktiviert", + "multiple-selection-tool-enabled": "Mehrfachauswahlstool ist aktiviert", + "note-editor-disabled": "Notiz Editor deaktiviert", + "note-editor-enabled": "Notiz Editor aktiviert", + "analytics-disabled": "Analytics deaktiviert", + "analytics-enabled": "Analytics aktiviert", + "displayGraphicTimetable": "Streckengrafik anzeigen", + "closeGraphicTimetable": "Streckengrafik schliessen", + "errorGraphicTimetable": "Streckengrafik kann nicht angezeigt werden, da keine Zugfahrt oder keine Knoten ausgewählt wurden." + }, + "editor-properties-view-component": { + "settings": "Einstellungen", + "color-scheme": "Farbschema", + "theme": "Theme", + "background-color": "Hintergrundfarbe", + "set-color-to-white": "Hintergrundfarbe auf 'weiss' setzten", + "reset-background-color-to-default": "Hintergrundfarbe auf Standard zurücksetzen", + "background-color-black": "Hintergrundfarbe (dunkel)", + "editor": "Editor", + "travel-time-presetting-default": "Fahrzeitvoreinstellungs (Heuristik)", + "graphicTimetable": "Streckengrafik", + "axis-scaling-distance": "Achsenskalierung (Distanz)", + "standardColorTheme": "Standard Farbschema", + "specialColorTheme": "Spezielles Farbschema", + "grayscaleColorTheme": "Graustufen Farbschema", + "optimizedPrintColorTheme": "Optimiertes Farbschema zum Drucken/Exportieren", + "standardDarkColorTheme": "Standard Farbschema (dunkel)", + "specialDarkColorTheme": "Spezielles Farbschema (dunkel)", + "grayscaleDarkColorTheme": "Graustufen Farbschema (dunkel)", + "timeScaledDistance": "fahrzeitskaliert", + "timeScaledDistanceTooltip": "Die Streckengrafikabschnitte werden fahrzeitskaliert dargestellt, d.h. es wird angenommen, dass der ausgewählte Zug mit konstanter Geschwindigkeit verkehrt.", + "uniformDistance": "gleichmässig", + "uniformDistanceTooltip": "Die Streckengrafikabschnitte werden gleichmässig skaliert dargestellt.", + "fixed": "Konstant 1min.", + "fixedTooltip": "Übernimmt die Fahrzeit mit konstant 1min (Default).", + "retrieveFromEdge": "Abschnittsfahrzeit", + "retrieveFromEdgeTooltip": "Übernimmt die max. Fahrzeit auf dem selben Abschnitt aller Züge gleicher Kategorie, sonst max. Fahrzeit aller Züge, sonst 1 Min." + }, + "editor-side-view": { + "editor-node-detail-view": { + "base-data": "Stammdaten", + "operational-point": "Betriebspunkt", + "name": "Name", + "connection-time": "Anschlusszeit", + "occupancy": "Auslastung", + "capacity": "Kapazität", + "filterable-labels": "Filterbare Labels", + "labels": "Labels", + "new-label-placeholder": "Neues Label...", + "stopping-times": "Haltezeiten", + "stopping-time-per-product": "Haltezeit pro Produkt", + "no-stop": "Kein Halt", + "ipv": "IPV", + "a": "A", + "b": "B", + "c": "C", + "d": "D", + "links": "Links", + "platform-information": "Perron Informationen", + "platform-length": "Perron-Länge", + "delete-node": "Knoten löschen", + "delete": "Löschen", + "deleteNodeDialog": "Soll der Knoten {$operationalPointShortName} ({$operationalPointName}) definitiv gelöscht werden?" + }, + "editor-tools-view-component": { + "more-functions": "Weitere Funktionen", + "export": "Exportieren", + "export-netzgrafik-as-svg": "Exportieren Netzgrafik als SVG", + "export-as-svg": "Exportieren als SVG", + "export-netzgrafik-as-png": "Exportieren Netzgrafik als PNG", + "export-as-png": "Exportieren als PNG", + "print-netzgrafik": "Netzgrafik drucken", + "print": "Drucken", + "netzgrafik": "Netzgrafik", + "export-netzgrafik": "Netzgrafik exportieren", + "export-netzgrafik-as-json": "Netzgrafik als JSON exportieren", + "import-netzgrafik": "Netzgrafik importieren", + "import-netzgrafik-as-json": "Netzgrafik aus JSON importieren", + "export-trainruns": "Zugfahrten exportieren", + "export-trainruns-as-csv": "Netzgrafik aus JSON importieren", + "export-trainruns-as-csv-excel": "In Excel: Daten -> Aus Text/CSV -> Filename ... importieren", + "base-data": "Stammdaten", + "import-base-data": "Stammdaten importieren", + "help-csv-data": "Hilfe: CSV - Datei", + "export-base-data": "Stammdaten exportieren", + "bp": "BP", + "station": "Bahnhof", + "category": "Kategorie", + "region": "Region", + "passengerConnectionTimeIPV": "Fahrgastwechselzeit_IPV", + "passengerConnectionTimeA": "Fahrgastwechselzeit_A", + "passengerConnectionTimeB": "Fahrgastwechselzeit_B", + "passengerConnectionTimeC": "Fahrgastwechselzeit_C", + "passengerConnectionTimeD": "Fahrgastwechselzeit_D", + "ZAZ": "ZAZ", + "transferTime": "Umsteigezeit", + "labels": "Labels", + "X": "X", + "Y": "Y", + "create": "Erstellen", + "yes": "JA", + "netzgrafikFile": "netzgrafik", + "baseDataFile": "stammdaten", + "trainrunFile": "zuglauf", + "trainCategory": "Zugkategorie", + "trainName": "Zugname", + "startStation": "Startbahnhof", + "destinationStation": "Zielbahnhof", + "trafficPeriod": "Verkehrsperiode", + "frequence": "Takt", + "departureMinuteAtStart": "Abfahrtsminute am Start Knoten", + "travelTimeStartDestination": "Fahrzeit Start-Ziel", + "arrivalMinuteAtDestination": "Ankuntsminute am Ziel Knoten", + "turnaroundTimeDestination": "Wendezeit Zielbahnhof", + "departureMinuteDeparture": "Abfahrtsminute am Ziel Knoten", + "travelTimeDestinationStart": "Fahrzeit Ziel-Start", + "arrivalMinuteAtStart": "Ankuntsminute am Start Knoten", + "turnaroundTimeStart": "Wendezeit Startbahnhof", + "turnaroundTime": "Umlaufzeit", + "trainrunTimeCategory": "Verkehrt" + } + }, + "error-view": { + "error": "Fehler" + }, + "navigation-bar": { + "project-name": "Projekt «{$name}»", + "project-name-archived": "Projekt «{$name}» (archiviert)", + "variant-name": "Variante «{$name}»", + "variant-name-archived": "Variante «{$name}» (archiviert)" + }, + "project": { + "project-dialog": { + "create-project": "Projekt erstellen", + "edit-project": "Projekt bearbeiten", + "create": "Erstellen", + "save": "Speichern", + "cancel": "Abbrechen", + "project-form": { + "name": "Name", + "mandatory": "Pflichtfeld", + "summary": "Zusammenfassung", + "description": "Beschreibung", + "tooltip": "Benutzer müssen mit ihrer E-Mail angegeben werden. Eingabe pro E-Mail jeweils mit 'Enter' bestätigen.", + "user-with-write-access": "Benutzer mit Schreibzugriff", + "new-user-placeholder": "Neuer Benutzer...", + "invalid-values": "Ungültige Werte (keine E-Mail Adresse)", + "user-with-read-access": "Benutzer mit Lesezugriff" + } + }, + "projects-view": { + "projects": "Projekte", + "search-project": "Projekt suchen", + "show-archive": "Archiv anzeigen", + "archived": "(archiviert)", + "archive-project": { + "title": "Projekt archivieren", + "content": "Möchten Sie das Projekt jetzt archivieren?" + }, + "undo-archiving-project": { + "title": "Archivierung rückgängig machen", + "content": "Möchten Sie die Archivierung des Projekts rückgängig machen?" + }, + "undo-archiving": "Archivierung rückgängig machen", + "edit": "Bearbeiten", + "archive": "Archivieren" + } + }, + "variant": { + "variant-dialog": { + "create-variant": "Variante erstellen", + "edit-variant": "Variante bearbeiten", + "save": "Speichern", + "cancel": "Abbrechen", + "variant-form": { + "name": "Name", + "mandatory": "Pflichtfeld" + } + }, + "variant-view": { + "variant-history": { + "publish-entry": { + "comment": "Kommentar", + "publish": "Publizieren", + "local-changes": "Lokale Änderungen müssen zuerst gespeichert werden", + "discard-changes": "Änderungen Verwerfen" + }, + "released-entry": { + "download": "Herunterladen", + "discard-changes": "Änderungen Verwerfen", + "ignore-conflict": "Konflikt ignorieren", + "restore": "Wiederherstellen", + "as-new-variant": "Als neue Variante", + "version-already-available": "Version bereits vorhanden", + "successfully-published": "Erfolgreich publiziert" + }, + "snapshot-entry": { + "download": "Herunterladen", + "restore": "Wiederherstellen", + "as-new-variant": "Als neue Variante", + "successfully-published": "Erfolgreich publiziert", + "change-snapshot-version": "Änderung {$snapshotVersion}" + }, + "new-version-published": { + "title": "Neue Version publizieren", + "content": "Möchten Sie Ihre persönlichen Änderungen als neue Version publizieren?" + }, + "discard-changes": { + "title": "Änderungen verwerfen", + "content": "Möchten Sie Ihre persönlichen Änderungen unwiderruflich verwerfen?" + }, + "restore-version": { + "title": "Version wiederherstellen", + "content": "Möchten Sie den Stand dieser Version wiederherstellen?" + }, + "ignore-conflict": { + "title": "Konflikt ignorieren", + "content": "Möchten Sie, dass der aktuelle Stand auf der höchsten publizierten Version aufbaut?" + } + }, + "archived": "(archiviert)", + "edit-variant": "Variante bearbeiten", + "delete-variant": { + "_value": "Variante löschen", + "title": "Variante löschen", + "content": "Möchten Sie die Variante und alle enthaltenen Versionen endgültig löschen? Diese Aktion kann nicht rückgängig gemacht werden." + }, + "versions": "Versionen" + }, + "variants-view": { + "archived": "(archiviert)", + "variants": "Varianten", + "search-variants": "Varianten suchen", + "show-archive": "Archiv anzeigen", + "project-description": "Projekt Beschreibung", + "edit-project": "Projekt bearbeiten", + "archive-project": { + "_value": "Projekt archivieren", + "title": "Projekt archivieren", + "content": "Möchten Sie das Projekt jetzt archivieren?" + }, + "undo-archiving": "Archivierung rückgängig machen", + "delete-project": { + "_value": "Projekt löschen", + "title": "Projekt löschen", + "content": "Möchten Sie das Projekt und alle enthaltenen Varianten endgültig löschen? Diese Aktion kann nicht rückgängig gemacht werden." + }, + "archive": "Archivieren", + "archive-variant": { + "title": "Variante archivieren", + "content": "Möchten Sie die Variante jetzt archivieren?" + }, + "undo-archiving-variant": { + "title": "Archivierung rückgängig machen", + "content": "Möchten Sie die Archivierung der Variante rückgängig machen?" + }, + "undo-archiving-project": { + "title": "Archivierung rückgängig machen", + "content": "Möchten Sie die Archivierung des Projekts rückgängig machen?" + }, + "error-unexpected-data": "Unerwartete Daten: Kein Snapshot und keine freigegebene Version." + } + } + } + }, + "sbbBreadcrumbExpand": "Gesamten Pfad anzeigen", + "sbbDialogCloseDialog": "Dialog schließen", + "sbbFileSelectorUploadFile": "Datei hochladen", + "sbbFileSelectorRemoveFile": "Datei löschen", + "sbbHeaderMenuBack": "Zurück", + "sbbHeaderOpenMenu": "Menü öffnen", + "sbbHeaderCloseMenu": "Menü schliessen", + "sbbSidebarCollapse": "Zusammenklappen", + "sbbSidebarExpand": "Erweitern", + "sbbSidebarCloseSidebar": "Sidebar schließen", + "sbbSidebarOpenSidebar": "Sidebar öffnen", + "sbbTextareaCounterText": "{$number} verbleibende Zeichen", + "sbbUsermenuLogin": "Login", + "sbbUsermenuOpenPanel": "Eingeloggt als {$name}. Klicken Sie auf oder drücken Sie die Eingabetaste, um das Benutzermenü zu öffnen." +} diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json new file mode 100644 index 00000000..602be7bc --- /dev/null +++ b/src/assets/i18n/en.json @@ -0,0 +1,640 @@ +{ + "app-routing": { + "module": { + "path": { + "404": "The page you were looking for was not found.", + "401": "You are not authorized, please reload the page.", + "403": "You are not authorized to perform this action.", + "409": "There was a conflict while executing your action, please try again.", + "error": "An error has occurred." + } + } + }, + "app": { + "version": "Version {$version}", + "user-guide": "User guide", + "user-manual": "User manual", + "logout": "Logout", + "login": "You are getting logged in...", + "logger": { + "title": "Title" + }, + "models": { + "node": { + "shortNameDefault": "NEW", + "full-name-default": "New node" + }, + "note": { + "title-default": "Note title", + "text-default": "Note text", + "default-title": "Note title", + "default-text": "Note text" + } + }, + "netzgrafik-application": { + "variants": "Variants", + "filter": "Filter", + "analytics": "Analytics", + "edit": "Edit", + "more-functions": "More functions", + "settings": "Settings" + }, + "perlenkette": { + "perlenkette-node": { + "0-warning-connection": "No incorrect connection", + "1-warning-connection": "1 incorrect connection", + "n-warning-connections": "{$number} incorrect connections", + "0-fitting-connection": "No fitting connection", + "1-fitting-connection": "1 fitting connection", + "n-fitting-connections": "{$number} fitting connections" + }, + "show-only-closed-locks": "Show only closed locks", + "show-all-locks": "Show all locks" + }, + "services": { + "data": { + "node": { + "transit-modified": { + "title": "Transition changed", + "description": "Times cannot be adjusted, lock found on both sides" + } + }, + "trainrunsection": { + "intermediate-stop-replacement": { + "title": "Intermediate stop replacement", + "description": "Intermediate stop replacement led to inconsistencies in the allocation of times!" + } + } + }, + "ui": { + "newFilter": "New filer" + }, + "util": { + "connection-validator": { + "connection-marked-for-transit": { + "title": "Connection marked for transition!", + "description": "Connection marked for transition!" + } + }, + "trainrun-iteration": { + "error": { + "infinity-loop": "Iterator has detected an infinity loop. The iteration terminated early!" + } + }, + "trainrunsection-validator": { + "target-arrival-not-reacheable": { + "title": "Target Arrival Warning", + "description": "Target arrival time cannot be reached" + }, + "source-arrival-not-reacheable": { + "title": "Source Arrival Warning", + "description": "Source arrival time cannot be reached" + }, + "travel-time-less-than-1": { + "title": "Travel Time less than 1", + "description": "Travel time must be greater than or equal to 1" + } + }, + "transition-validator": { + "source-arrival-not-reacheable": { + "title": "Source Arrival Warning", + "description": "Source arrival time cannot be reached" + }, + "source-departure-not-reacheable": { + "title": "Source Departure Warning", + "description": "Source departure time cannot be reached" + }, + "target-arrival-not-reacheable": { + "title": "Target Arrival Warning", + "description": "Target arrival time cannot be reached" + }, + "target-departure-not-reacheable": { + "title": "Target Departure Warning", + "description": "Target departure time cannot be reached" + } + } + } + }, + "streckengrafik": { + "components": { + "reset": "Reset", + "close-all-path-nodes": "Close all path nodes", + "open-all-path-nodes": "Open all path nodes", + "show-advanced-display-functions": "Show advanced display functions", + "show-or-hide-time-for-non-selected-trainruns": "Show/hide time for non-selected trainruns", + "show-or-hide": "Enable/disable {$component}", + "show-or-hide-name-for-non-selected-trainruns": "Show/hide trainrun names for unselected trainruns", + "hide-advanced-display-functions": "Hide advanced display functions", + "mainTracks": "Main tracks", + "headway-band": "Headway band", + "time": "Time", + "name": "Name" + } + }, + "utils": { + "navigation-parameters": { + "no-project-id": "No project ID available", + "no-variant-id": "No variant ID available", + "no-version-id": "No version ID available" + } + }, + "view": { + "card-grid": { + "card": { + "open": "Open" + } + }, + "dialogs": { + "confirmation-dialog": { + "confirmation-default": "Yes", + "abort-default": "No" + }, + "filterable-labels-dialog": { + "filterable-label-dialog-component": { + "edit-filterable-labels": "Edit filterable labels for {$element}", + "transfer-to-all-visible": "transfer to all visible", + "delete-from-all-visible": "delete from all visible", + "transfer": { + "title": "Transfer", + "content": "Should the label {$label} be applied on all visible {$element}?" + }, + "delete": { + "title": "Delete", + "content": "Should the label {$label} be definitely delete on all visible {$element}?" + } + }, + "filterable-labels-form": { + "mandatory-field": "Mandatory field" + } + }, + "note-dialog": { + "html-editor": { + "reset-color": "Reset color", + "editor-placeholder": "Enter comment here...", + "mandatory-field": "Mandatory field", + "color-presets": { + "ec": { + "title": "Use color of the color scheme for EC" + }, + "ic": { + "title": "Use color of the color scheme for IC" + }, + "ir": { + "title": "Use color of the color scheme for IR" + }, + "re": { + "title": "Use color of the color scheme for RE" + }, + "s": { + "title": "Use color of the color scheme for S" + }, + "gex": { + "title": "Use color of the color scheme for GEX" + }, + "g": { + "title": "Use color of the color scheme for G" + }, + "green": { + "title": "green" + }, + "blue": { + "title": "blue" + }, + "magenta": { + "title": "magenta" + }, + "red": { + "title": "red" + }, + "warning": { + "title": "warning color" + } + } + }, + "note-tab": "Note", + "filterable-labels-tab": "Filterable labels", + "delete-note": "Delete note", + "note-filter-tab": { + "labels": "Labels", + "label-placeholder": "New label..." + }, + "note-form": { + "title": "Title", + "name": "Name" + } + }, + "stammdaten-dialog": { + "base-data": "Base data", + "operationalPoint": "Operational point", + "ipv-stop-time": "IPV stop time", + "a-stop-time": "A stop time", + "b-stop-time": "B stop time", + "c-stop-time": "C stop time", + "d-stop-time": "D stop time", + "zaz": "ZAZ", + "connection-time": "Connection time", + "region": "Region", + "category": "Category", + "filterable-labels": "Filterable labels", + "position": "Position", + "close": "Close" + }, + "trainrun-and-section-dialog": { + "filterableLabels": "Filterable Labels", + "trainrun-filter-tab": { + "labels": "Labels", + "newLabels" : "New label...", + "trainrunDuplicate": "Duplicate trainrun", + "trainrunDelete": "Delete trainrun", + "delete": "Delete", + "deleteConfirmationQuestion": "Should the entire train route be definitively deleted?" + }, + "trainrun-tab": { + "tabName": "Name", + "category": "Category", + "frequency": "Frequency", + "verkehrt": "Operates", + "trainrunDuplicate": "Duplicate trainrun", + "trainrunDelete": "Delete trainrun", + "delete": "Delete", + "deleteConfirmationQuestion": "Should the entire train route be definitively deleted?" + }, + "trainrun-section-tab": { + "warningTwoLocks": "Warning: Too many times are locked!", + "propagateTimesToLeft": "Propagate times to the left", + "propagateTimesToRight": "Propagate times to the right" + } + } + }, + "editor-edit-tools-view-component": { + "edit": "Edit", + "filterable-labels": "Filterable labels", + "trainruns": "Trainruns", + "nodes": "Nodes", + "notes": "Notes", + "delete-netzgrafik-title": "Netzgrafik - Delete", + "non-visible-elements": "Non visible elements", + "delete-all-non-visible-elements-tooltip": "Delete all non-visible elements, such as nodes, trainruns and notes", + "delete-all-non-visible-elements": "Delete all non-visible elements", + "visible-elements": "Visible elements", + "delete-all-visible-trainruns-tooltip": "Delete all visible trainruns", + "delete-all-visible-trainruns": "Delete all visible trainruns", + "delete-all-visible-notes-tooltip": "Delete all visible notes", + "delete-all-visible-notes": "Delete all visible notes", + "delete-all-visible-elements-tooltip": "Delete all visible elements, such as nodes, trainruns and notes", + "delete-all-visible-elements": "Delete all visible elements", + "merge-netzgrafik-title": "Netzgrafik - Merge", + "add-netzgrafik-as-copy-tooltip": "Add netzgrafik as a copy (trainruns, nodes, notes)", + "add-netzgrafik-as-copy": "Add netzgrafik as a copy", + "merge-netzgrafik-tooltip": "Merge netzgrafik (trainruns, nodes, notes)", + "merge-netzgrafik": "Merge netzgrafik", + "delete": "Delete", + "on-clear-delete-all-non-visible-elements": "Should all non-visible elements be permanently deleted from the netzgrafik?", + "on-clear-delete-all-visible-elements": "Should all visible elements be permanently deleted from the netzgrafik?", + "on-clear-delete-all-visible-trainruns": "Should all visible trainruns be permanently deleted from the netzgrafik?", + "on-clear-delete-all-visible-notes": "Should all visible notes be permanently deleted from the netzgrafik?", + "label-drop-list": { + "no-labels-available": "No labels available", + "delete-group": "Delete group", + "add-new-group": "Add new group", + "trainruns": "Trainruns", + "notes": "Notes", + "nodes": "Nodes" + } + }, + "editor-filter-view": { + "filter": "Filter", + "general": "General", + "category": "Category", + "frequency": "Frequence", + "time-category": "Time category", + "display-all-trainruns": "Display all trainruns", + "reset-trainrun-filter": "Reset trainrun filter", + "filterable-labels-trainruns": "Filterable labels: Trainruns", + "filterable-labels-nodes": "Filterable labels: Nodes", + "filterable-labels-notes": "Filterable labels: Notes", + "display": "Display", + "times": "Times", + "decimal-displayed": "Number of decimal place displayed", + "display-arrival-departure-times": "Display departure and arrival times", + "display-arrival-departure-times-for-connections": "Display departure and arrival times for connections", + "display-travel-times": "Display travel times", + "display-trainrun-name": "Display trainrun name", + "connections": "Connections", + "display-connections": "Display connections", + "nodes": "Nodes", + "display-nodes-without-visible-trainruns": "Display nodes without (visible) trainruns", + "display-nodes-with-only-stopping-trainruns": "Display nodes with only stopping trainruns", + "notes": "Notes", + "display-notes": "Display notes", + "reset-display-filter": "Reset display filter", + "saved-filters": "Saved filters", + "save-filters": "Save filters and add them as filter settings", + "reset-all-display-filters": "Reset all display filters", + "load-filter": "Load {$filter}", + "reload-filter": "Reload {$filter}", + "show-trainrun-category": "Show {$trainrunCategory}", + "hide-trainrun-category": "Hide {$trainrunCategory}", + "show-trainrun-time-category": "Show {$trainrunTimeCategory}", + "hide-trainrun-time-category": "Hide {$trainrunTimeCategory}", + "show-trainrun-frequency": "Show {$trainrunFrequency}", + "hide-trainrun-frequency": "Hide {$trainrunFrequency}", + "filterable-label-filter": { + "no-labels-available": "No labels available", + "or": "Or", + "and": "And", + "show-all": "Show all", + "reset-filter": "Reset filter", + "show": "show", + "hide": "hide" + } + }, + "editor-menu": { + "save-changes": "Save changes", + "changes-saved": "Changes saved", + "read-mode": "Read mode", + "show-hide-filter": "Show/Hide filter", + "zoom-out": "Zoom out", + "zoom-in": "Zoom in", + "topology-editor-disabled": "Topology editor disabled", + "topology-editor-enabled": "Topology editor enabled", + "multiple-selection-tool-disabled": "Multiple selection tool is disabled", + "multiple-selection-tool-enabled": "Multiple selection tool is enabled", + "note-editor-disabled": "Note editor disabled", + "note-editor-enabled": "Note editor enabled", + "analytics-disabled": "Analytics disabled", + "analytics-enabled": "Analytics enabled", + "displayGraphicTimetable": "Display graphic timetable", + "closeGraphicTimetable": "Close graphic timetable", + "errorGraphicTimetable": "Graphic timetable cannot be displayed because no trainrun or no nodes have been selected." + }, + "editor-properties-view-component": { + "settings": "Settings", + "color-scheme": "Color scheme", + "theme": "Theme", + "background-color": "Background color", + "set-color-to-white": "Set color to 'white'", + "reset-background-color-to-default": "Reset background color to default", + "background-color-black": "Background color (black)", + "editor": "Editor", + "travel-time-presetting-default": "Travel time presetting (heuristics)", + "graphicTimetable": "Graphic timetable", + "axis-scaling-distance": "Axis scaling (distance)", + "standardColorTheme": "Standard color theme", + "specialColorTheme": "Special color theme", + "grayscaleColorTheme": "Grayscale color theme", + "optimizedPrintColorTheme": "Optimized color theme for printing/exporting", + "standardDarkColorTheme": "Standard color theme (dark)", + "specialDarkColorTheme": "Special color theme (dark)", + "grayscaleDarkColorTheme": "Grayscale color theme (dark)", + "timeScaledDistance": "Travel time scaled", + "timeScaledDistanceTooltip": "The route graphic sections are displayed with travel time scaling, i.e. it is assumed that the selected train travels at a constant speed.", + "uniformDistance": "Uniform", + "uniformDistanceTooltip": "The route graphic sections are uniformly displayed.", + "fixed": "Constant 1min", + "fixedTooltip": "Adopts the travel time with a constant 1min (default).", + "retrieveFromEdge": "Section travel time", + "retrieveFromEdgeTooltip": "Takes over the max. travel time on the same section of all trains of the same category, otherwise max. travel time of all trains, otherwise 1 min." + }, + "editor-side-view": { + "editor-node-detail-view": { + "base-data": "Base data", + "operational-point": "Operational point", + "name": "Name", + "connection-time": "Connection time", + "occupancy": "Occupancy", + "capacity": "Capacity", + "filterable-labels": "Filterable labels", + "labels": "Labels", + "new-label-placeholder": "New label...", + "stopping-times": "Stopping times", + "stopping-time-per-product": "Stopping time per product", + "no-stop": "No stop", + "ipv": "IPV", + "a": "A", + "b": "B", + "c": "C", + "d": "D", + "links": "Links", + "platform-information": "Platform information", + "platform-length": "Platform length", + "delete-node": "Delete node", + "delete": "Delete", + "deleteNodeDialog": "Should the node {$operationalPointShortName} ({$operationalPointName}) be definitely deleted?" + }, + "editor-tools-view-component": { + "more-functions": "More functions", + "export": "Export", + "export-netzgrafik-as-svg": "Export netzgrafik as SVG", + "export-as-svg": "Export as SVG", + "export-netzgrafik-as-png": "Export netzgrafik as PNG", + "export-as-png": "Export as PNG", + "print-netzgrafik": "Print netzgrafik", + "print": "Print", + "netzgrafik": "Netzgrafik", + "export-netzgrafik": "Export netzgrafik", + "export-netzgrafik-as-json": "Export netzgrafik as JSON", + "import-netzgrafik": "Import netzgrafik", + "import-netzgrafik-as-json": "Import netzgrafik as JSON", + "export-trainruns": "Export trainruns", + "export-trainruns-as-csv": "Export trainruns as CSV", + "export-trainruns-as-csv-excel": "In Excel: Data -> From Text/CSV -> Import ... filename", + "base-data": "Base data", + "import-base-data": "Import base data", + "help-csv-data": "Help: CSV - Data", + "export-base-data": "Export base data", + "bp": "BP", + "station": "Station", + "category": "Category", + "region": "Region", + "passengerConnectionTimeIPV": "Passenger_connection_time_IPV", + "passengerConnectionTimeA": "Passenger_connection_time_A", + "passengerConnectionTimeB": "Passenger_connection_time_B", + "passengerConnectionTimeC": "Passenger_connection_time_C", + "passengerConnectionTimeD": "Passenger_connection_time_D", + "ZAZ": "ZAZ", + "transferTime": "Transfer_time", + "labels": "Labels", + "X": "X", + "Y": "Y", + "create": "Create", + "yes": "YES", + "netzgrafikFile": "networkGraphic", + "baseDataFile": "baseData", + "trainrunFile": "trainrun", + "trainCategory": "Train category", + "trainName": "Train name", + "startStation": "Start station", + "destinationStation": "Destination station", + "trafficPeriod": "Traffic period", + "frequence": "Frequence", + "departureMinuteAtStart": "Minute of departure at start node", + "travelTimeStartDestination": "Travel time start-destination", + "arrivalMinuteAtDestination": "Arrival minute at destination node", + "turnaroundTimeDestination": "Turnaround time at destination station", + "departureMinuteDeparture": "Departure minute at destination node", + "travelTimeDestinationStart": "Travel time destination-start", + "arrivalMinuteAtStart": "Arrival minute at start node", + "turnaroundTimeStart": "Turnaround time at start station", + "turnaroundTime": "Turnaround time", + "trainrunTimeCategory": "Trainrun time category" + } + }, + "error-view": { + "error": "Error" + }, + "navigation-bar": { + "project-name": "Project «{$name}»", + "project-name-archived": "Project «{$name}» (archived)", + "variant-name": "Variant «{$name}»", + "variant-name-archived": "Variant «{$name}» (archived)" + }, + "project": { + "project-dialog": { + "create-project": "Create project", + "edit-project": "Edit project", + "create": "Create", + "save": "Save", + "cancel": "Cancel", + "project-form": { + "name": "Name", + "mandatory-field": "Mandatory field", + "summary": "Summary", + "description": "Description", + "tooltip": "Users must be entered with their e-mail address. Confirm the entry for each e-mail with 'Enter'.", + "user-with-write-access": "User with write access", + "new-user-placeholder": "New user...", + "invalid-values": "Invalid values (no e-mail address)", + "user-with-read-access": "User with read access" + } + }, + "projects-view": { + "projects": "Projects", + "search-project": "Search project", + "show-archive": "Show archive", + "archived": "(archived)", + "archive-project": { + "title": "Archive project", + "content": "Would you like to archive the project now?" + }, + "undo-archiving-project": { + "title": "Undo archiving", + "content": "Would you like to undo the archiving the project now?" + }, + "undo-archiving": "Undo archiving", + "edit": "Edit", + "archive": "Archive" + } + }, + "variant": { + "variant-dialog": { + "create-variant": "Create variant", + "edit-variant": "Edit variant", + "save": "Save", + "cancel": "Cancel", + "variant-form": { + "name": "Name", + "mandatory-field": "Mandatory field" + } + }, + "variant-view": { + "variant-history": { + "publish-entry": { + "comment": "Comment", + "publish": "Publish", + "local-changes": "Local changes must be saved first", + "discard-changes": "Discard changes" + }, + "released-entry": { + "download": "Download", + "discard-changes": "Discard changes", + "ignore-conflict": "Ignore conflict", + "restore": "Restore", + "as-new-variant": "As new variant", + "version-already-available": "Version already available", + "successfully-published": "Successfully published" + }, + "snapshot-entry": { + "download": "Download", + "restore": "Restore", + "as-new-variant": "As new variant", + "successfully-published": "Successfully published", + "change-snapshot-version": "Change {$snapshotVersion}" + }, + "new-version-published": { + "title": "New version published", + "content": "Would you like to publish your personal changes as a new version?" + }, + "discard-changes": { + "title": "Discard changes", + "content": "Would you like to irrevocably discard your personal changes?" + }, + "restore-version": { + "title": "Restore version", + "content": "Would you like to restore the status of this version?" + }, + "ignore-conflict": { + "title": "Ignore conflict", + "content": "Would you like the current version to be based on the highest published version?" + } + }, + "archived": "(archived)", + "edit-variant": "Edit variant", + "delete-variant": { + "_value": "Delete variant", + "title": "Delete variant", + "content": "Do you want to permanently delete the variant and all versions it contains? This action cannot be undone." + }, + "versions": "Versions" + }, + "variants-view": { + "archived": "(archived)", + "variants": "Variants", + "search-variants": "Search variants", + "show-archive": "Show archive", + "project-description": "Project description", + "edit-project": "Edit project", + "archive-project": { + "_value": "Archive project", + "title": "Archive project", + "content": "Would you like to archive the project now?" + }, + "undo-archiving": "Undo archiving", + "delete-project": { + "_value": "Delete project", + "title": "Delete projekt", + "content": "Do you want to permanently delete the project and all the variants it contains? This action cannot be undone." + }, + "archive": "Archive", + "archive-variant": { + "title": "Archive variant", + "content": "Would you like to archive the variant now?" + }, + "undo-archiving-variant": { + "title": "Undo archiving", + "content": "Would you like to undo the archiving of the variant?" + }, + "undo-archiving-project": { + "title": "Archive variant", + "content": "Would you like to undo the archiving of the project?" + }, + "error-unexpected-data": "Unexpected data: No snapshot and no released version." + } + } + } + }, + "sbbBreadcrumbExpand": "Show entire path", + "sbbDialogCloseDialog": "Close dialog", + "sbbFileSelectorUploadFile": "Upload file", + "sbbFileSelectorRemoveFile": "Remove file", + "sbbHeaderMenuBack": "Back", + "sbbHeaderOpenMenu": "Open Menu", + "sbbHeaderCloseMenu": "Close Menu", + "sbbSidebarCollapse": "Collapse", + "sbbSidebarExpand": "Expand", + "sbbSidebarCloseSidebar": "Close Sidebar", + "sbbSidebarOpenSidebar": "Open Sidebar", + "sbbTextareaCounterText": "{$number} characters remaining", + "sbbUsermenuLogin": "Login", + "sbbUsermenuOpenPanel": "Logged in as {$name}. Click or press enter to open user menu." +} diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json new file mode 100644 index 00000000..602be7bc --- /dev/null +++ b/src/assets/i18n/fr.json @@ -0,0 +1,640 @@ +{ + "app-routing": { + "module": { + "path": { + "404": "The page you were looking for was not found.", + "401": "You are not authorized, please reload the page.", + "403": "You are not authorized to perform this action.", + "409": "There was a conflict while executing your action, please try again.", + "error": "An error has occurred." + } + } + }, + "app": { + "version": "Version {$version}", + "user-guide": "User guide", + "user-manual": "User manual", + "logout": "Logout", + "login": "You are getting logged in...", + "logger": { + "title": "Title" + }, + "models": { + "node": { + "shortNameDefault": "NEW", + "full-name-default": "New node" + }, + "note": { + "title-default": "Note title", + "text-default": "Note text", + "default-title": "Note title", + "default-text": "Note text" + } + }, + "netzgrafik-application": { + "variants": "Variants", + "filter": "Filter", + "analytics": "Analytics", + "edit": "Edit", + "more-functions": "More functions", + "settings": "Settings" + }, + "perlenkette": { + "perlenkette-node": { + "0-warning-connection": "No incorrect connection", + "1-warning-connection": "1 incorrect connection", + "n-warning-connections": "{$number} incorrect connections", + "0-fitting-connection": "No fitting connection", + "1-fitting-connection": "1 fitting connection", + "n-fitting-connections": "{$number} fitting connections" + }, + "show-only-closed-locks": "Show only closed locks", + "show-all-locks": "Show all locks" + }, + "services": { + "data": { + "node": { + "transit-modified": { + "title": "Transition changed", + "description": "Times cannot be adjusted, lock found on both sides" + } + }, + "trainrunsection": { + "intermediate-stop-replacement": { + "title": "Intermediate stop replacement", + "description": "Intermediate stop replacement led to inconsistencies in the allocation of times!" + } + } + }, + "ui": { + "newFilter": "New filer" + }, + "util": { + "connection-validator": { + "connection-marked-for-transit": { + "title": "Connection marked for transition!", + "description": "Connection marked for transition!" + } + }, + "trainrun-iteration": { + "error": { + "infinity-loop": "Iterator has detected an infinity loop. The iteration terminated early!" + } + }, + "trainrunsection-validator": { + "target-arrival-not-reacheable": { + "title": "Target Arrival Warning", + "description": "Target arrival time cannot be reached" + }, + "source-arrival-not-reacheable": { + "title": "Source Arrival Warning", + "description": "Source arrival time cannot be reached" + }, + "travel-time-less-than-1": { + "title": "Travel Time less than 1", + "description": "Travel time must be greater than or equal to 1" + } + }, + "transition-validator": { + "source-arrival-not-reacheable": { + "title": "Source Arrival Warning", + "description": "Source arrival time cannot be reached" + }, + "source-departure-not-reacheable": { + "title": "Source Departure Warning", + "description": "Source departure time cannot be reached" + }, + "target-arrival-not-reacheable": { + "title": "Target Arrival Warning", + "description": "Target arrival time cannot be reached" + }, + "target-departure-not-reacheable": { + "title": "Target Departure Warning", + "description": "Target departure time cannot be reached" + } + } + } + }, + "streckengrafik": { + "components": { + "reset": "Reset", + "close-all-path-nodes": "Close all path nodes", + "open-all-path-nodes": "Open all path nodes", + "show-advanced-display-functions": "Show advanced display functions", + "show-or-hide-time-for-non-selected-trainruns": "Show/hide time for non-selected trainruns", + "show-or-hide": "Enable/disable {$component}", + "show-or-hide-name-for-non-selected-trainruns": "Show/hide trainrun names for unselected trainruns", + "hide-advanced-display-functions": "Hide advanced display functions", + "mainTracks": "Main tracks", + "headway-band": "Headway band", + "time": "Time", + "name": "Name" + } + }, + "utils": { + "navigation-parameters": { + "no-project-id": "No project ID available", + "no-variant-id": "No variant ID available", + "no-version-id": "No version ID available" + } + }, + "view": { + "card-grid": { + "card": { + "open": "Open" + } + }, + "dialogs": { + "confirmation-dialog": { + "confirmation-default": "Yes", + "abort-default": "No" + }, + "filterable-labels-dialog": { + "filterable-label-dialog-component": { + "edit-filterable-labels": "Edit filterable labels for {$element}", + "transfer-to-all-visible": "transfer to all visible", + "delete-from-all-visible": "delete from all visible", + "transfer": { + "title": "Transfer", + "content": "Should the label {$label} be applied on all visible {$element}?" + }, + "delete": { + "title": "Delete", + "content": "Should the label {$label} be definitely delete on all visible {$element}?" + } + }, + "filterable-labels-form": { + "mandatory-field": "Mandatory field" + } + }, + "note-dialog": { + "html-editor": { + "reset-color": "Reset color", + "editor-placeholder": "Enter comment here...", + "mandatory-field": "Mandatory field", + "color-presets": { + "ec": { + "title": "Use color of the color scheme for EC" + }, + "ic": { + "title": "Use color of the color scheme for IC" + }, + "ir": { + "title": "Use color of the color scheme for IR" + }, + "re": { + "title": "Use color of the color scheme for RE" + }, + "s": { + "title": "Use color of the color scheme for S" + }, + "gex": { + "title": "Use color of the color scheme for GEX" + }, + "g": { + "title": "Use color of the color scheme for G" + }, + "green": { + "title": "green" + }, + "blue": { + "title": "blue" + }, + "magenta": { + "title": "magenta" + }, + "red": { + "title": "red" + }, + "warning": { + "title": "warning color" + } + } + }, + "note-tab": "Note", + "filterable-labels-tab": "Filterable labels", + "delete-note": "Delete note", + "note-filter-tab": { + "labels": "Labels", + "label-placeholder": "New label..." + }, + "note-form": { + "title": "Title", + "name": "Name" + } + }, + "stammdaten-dialog": { + "base-data": "Base data", + "operationalPoint": "Operational point", + "ipv-stop-time": "IPV stop time", + "a-stop-time": "A stop time", + "b-stop-time": "B stop time", + "c-stop-time": "C stop time", + "d-stop-time": "D stop time", + "zaz": "ZAZ", + "connection-time": "Connection time", + "region": "Region", + "category": "Category", + "filterable-labels": "Filterable labels", + "position": "Position", + "close": "Close" + }, + "trainrun-and-section-dialog": { + "filterableLabels": "Filterable Labels", + "trainrun-filter-tab": { + "labels": "Labels", + "newLabels" : "New label...", + "trainrunDuplicate": "Duplicate trainrun", + "trainrunDelete": "Delete trainrun", + "delete": "Delete", + "deleteConfirmationQuestion": "Should the entire train route be definitively deleted?" + }, + "trainrun-tab": { + "tabName": "Name", + "category": "Category", + "frequency": "Frequency", + "verkehrt": "Operates", + "trainrunDuplicate": "Duplicate trainrun", + "trainrunDelete": "Delete trainrun", + "delete": "Delete", + "deleteConfirmationQuestion": "Should the entire train route be definitively deleted?" + }, + "trainrun-section-tab": { + "warningTwoLocks": "Warning: Too many times are locked!", + "propagateTimesToLeft": "Propagate times to the left", + "propagateTimesToRight": "Propagate times to the right" + } + } + }, + "editor-edit-tools-view-component": { + "edit": "Edit", + "filterable-labels": "Filterable labels", + "trainruns": "Trainruns", + "nodes": "Nodes", + "notes": "Notes", + "delete-netzgrafik-title": "Netzgrafik - Delete", + "non-visible-elements": "Non visible elements", + "delete-all-non-visible-elements-tooltip": "Delete all non-visible elements, such as nodes, trainruns and notes", + "delete-all-non-visible-elements": "Delete all non-visible elements", + "visible-elements": "Visible elements", + "delete-all-visible-trainruns-tooltip": "Delete all visible trainruns", + "delete-all-visible-trainruns": "Delete all visible trainruns", + "delete-all-visible-notes-tooltip": "Delete all visible notes", + "delete-all-visible-notes": "Delete all visible notes", + "delete-all-visible-elements-tooltip": "Delete all visible elements, such as nodes, trainruns and notes", + "delete-all-visible-elements": "Delete all visible elements", + "merge-netzgrafik-title": "Netzgrafik - Merge", + "add-netzgrafik-as-copy-tooltip": "Add netzgrafik as a copy (trainruns, nodes, notes)", + "add-netzgrafik-as-copy": "Add netzgrafik as a copy", + "merge-netzgrafik-tooltip": "Merge netzgrafik (trainruns, nodes, notes)", + "merge-netzgrafik": "Merge netzgrafik", + "delete": "Delete", + "on-clear-delete-all-non-visible-elements": "Should all non-visible elements be permanently deleted from the netzgrafik?", + "on-clear-delete-all-visible-elements": "Should all visible elements be permanently deleted from the netzgrafik?", + "on-clear-delete-all-visible-trainruns": "Should all visible trainruns be permanently deleted from the netzgrafik?", + "on-clear-delete-all-visible-notes": "Should all visible notes be permanently deleted from the netzgrafik?", + "label-drop-list": { + "no-labels-available": "No labels available", + "delete-group": "Delete group", + "add-new-group": "Add new group", + "trainruns": "Trainruns", + "notes": "Notes", + "nodes": "Nodes" + } + }, + "editor-filter-view": { + "filter": "Filter", + "general": "General", + "category": "Category", + "frequency": "Frequence", + "time-category": "Time category", + "display-all-trainruns": "Display all trainruns", + "reset-trainrun-filter": "Reset trainrun filter", + "filterable-labels-trainruns": "Filterable labels: Trainruns", + "filterable-labels-nodes": "Filterable labels: Nodes", + "filterable-labels-notes": "Filterable labels: Notes", + "display": "Display", + "times": "Times", + "decimal-displayed": "Number of decimal place displayed", + "display-arrival-departure-times": "Display departure and arrival times", + "display-arrival-departure-times-for-connections": "Display departure and arrival times for connections", + "display-travel-times": "Display travel times", + "display-trainrun-name": "Display trainrun name", + "connections": "Connections", + "display-connections": "Display connections", + "nodes": "Nodes", + "display-nodes-without-visible-trainruns": "Display nodes without (visible) trainruns", + "display-nodes-with-only-stopping-trainruns": "Display nodes with only stopping trainruns", + "notes": "Notes", + "display-notes": "Display notes", + "reset-display-filter": "Reset display filter", + "saved-filters": "Saved filters", + "save-filters": "Save filters and add them as filter settings", + "reset-all-display-filters": "Reset all display filters", + "load-filter": "Load {$filter}", + "reload-filter": "Reload {$filter}", + "show-trainrun-category": "Show {$trainrunCategory}", + "hide-trainrun-category": "Hide {$trainrunCategory}", + "show-trainrun-time-category": "Show {$trainrunTimeCategory}", + "hide-trainrun-time-category": "Hide {$trainrunTimeCategory}", + "show-trainrun-frequency": "Show {$trainrunFrequency}", + "hide-trainrun-frequency": "Hide {$trainrunFrequency}", + "filterable-label-filter": { + "no-labels-available": "No labels available", + "or": "Or", + "and": "And", + "show-all": "Show all", + "reset-filter": "Reset filter", + "show": "show", + "hide": "hide" + } + }, + "editor-menu": { + "save-changes": "Save changes", + "changes-saved": "Changes saved", + "read-mode": "Read mode", + "show-hide-filter": "Show/Hide filter", + "zoom-out": "Zoom out", + "zoom-in": "Zoom in", + "topology-editor-disabled": "Topology editor disabled", + "topology-editor-enabled": "Topology editor enabled", + "multiple-selection-tool-disabled": "Multiple selection tool is disabled", + "multiple-selection-tool-enabled": "Multiple selection tool is enabled", + "note-editor-disabled": "Note editor disabled", + "note-editor-enabled": "Note editor enabled", + "analytics-disabled": "Analytics disabled", + "analytics-enabled": "Analytics enabled", + "displayGraphicTimetable": "Display graphic timetable", + "closeGraphicTimetable": "Close graphic timetable", + "errorGraphicTimetable": "Graphic timetable cannot be displayed because no trainrun or no nodes have been selected." + }, + "editor-properties-view-component": { + "settings": "Settings", + "color-scheme": "Color scheme", + "theme": "Theme", + "background-color": "Background color", + "set-color-to-white": "Set color to 'white'", + "reset-background-color-to-default": "Reset background color to default", + "background-color-black": "Background color (black)", + "editor": "Editor", + "travel-time-presetting-default": "Travel time presetting (heuristics)", + "graphicTimetable": "Graphic timetable", + "axis-scaling-distance": "Axis scaling (distance)", + "standardColorTheme": "Standard color theme", + "specialColorTheme": "Special color theme", + "grayscaleColorTheme": "Grayscale color theme", + "optimizedPrintColorTheme": "Optimized color theme for printing/exporting", + "standardDarkColorTheme": "Standard color theme (dark)", + "specialDarkColorTheme": "Special color theme (dark)", + "grayscaleDarkColorTheme": "Grayscale color theme (dark)", + "timeScaledDistance": "Travel time scaled", + "timeScaledDistanceTooltip": "The route graphic sections are displayed with travel time scaling, i.e. it is assumed that the selected train travels at a constant speed.", + "uniformDistance": "Uniform", + "uniformDistanceTooltip": "The route graphic sections are uniformly displayed.", + "fixed": "Constant 1min", + "fixedTooltip": "Adopts the travel time with a constant 1min (default).", + "retrieveFromEdge": "Section travel time", + "retrieveFromEdgeTooltip": "Takes over the max. travel time on the same section of all trains of the same category, otherwise max. travel time of all trains, otherwise 1 min." + }, + "editor-side-view": { + "editor-node-detail-view": { + "base-data": "Base data", + "operational-point": "Operational point", + "name": "Name", + "connection-time": "Connection time", + "occupancy": "Occupancy", + "capacity": "Capacity", + "filterable-labels": "Filterable labels", + "labels": "Labels", + "new-label-placeholder": "New label...", + "stopping-times": "Stopping times", + "stopping-time-per-product": "Stopping time per product", + "no-stop": "No stop", + "ipv": "IPV", + "a": "A", + "b": "B", + "c": "C", + "d": "D", + "links": "Links", + "platform-information": "Platform information", + "platform-length": "Platform length", + "delete-node": "Delete node", + "delete": "Delete", + "deleteNodeDialog": "Should the node {$operationalPointShortName} ({$operationalPointName}) be definitely deleted?" + }, + "editor-tools-view-component": { + "more-functions": "More functions", + "export": "Export", + "export-netzgrafik-as-svg": "Export netzgrafik as SVG", + "export-as-svg": "Export as SVG", + "export-netzgrafik-as-png": "Export netzgrafik as PNG", + "export-as-png": "Export as PNG", + "print-netzgrafik": "Print netzgrafik", + "print": "Print", + "netzgrafik": "Netzgrafik", + "export-netzgrafik": "Export netzgrafik", + "export-netzgrafik-as-json": "Export netzgrafik as JSON", + "import-netzgrafik": "Import netzgrafik", + "import-netzgrafik-as-json": "Import netzgrafik as JSON", + "export-trainruns": "Export trainruns", + "export-trainruns-as-csv": "Export trainruns as CSV", + "export-trainruns-as-csv-excel": "In Excel: Data -> From Text/CSV -> Import ... filename", + "base-data": "Base data", + "import-base-data": "Import base data", + "help-csv-data": "Help: CSV - Data", + "export-base-data": "Export base data", + "bp": "BP", + "station": "Station", + "category": "Category", + "region": "Region", + "passengerConnectionTimeIPV": "Passenger_connection_time_IPV", + "passengerConnectionTimeA": "Passenger_connection_time_A", + "passengerConnectionTimeB": "Passenger_connection_time_B", + "passengerConnectionTimeC": "Passenger_connection_time_C", + "passengerConnectionTimeD": "Passenger_connection_time_D", + "ZAZ": "ZAZ", + "transferTime": "Transfer_time", + "labels": "Labels", + "X": "X", + "Y": "Y", + "create": "Create", + "yes": "YES", + "netzgrafikFile": "networkGraphic", + "baseDataFile": "baseData", + "trainrunFile": "trainrun", + "trainCategory": "Train category", + "trainName": "Train name", + "startStation": "Start station", + "destinationStation": "Destination station", + "trafficPeriod": "Traffic period", + "frequence": "Frequence", + "departureMinuteAtStart": "Minute of departure at start node", + "travelTimeStartDestination": "Travel time start-destination", + "arrivalMinuteAtDestination": "Arrival minute at destination node", + "turnaroundTimeDestination": "Turnaround time at destination station", + "departureMinuteDeparture": "Departure minute at destination node", + "travelTimeDestinationStart": "Travel time destination-start", + "arrivalMinuteAtStart": "Arrival minute at start node", + "turnaroundTimeStart": "Turnaround time at start station", + "turnaroundTime": "Turnaround time", + "trainrunTimeCategory": "Trainrun time category" + } + }, + "error-view": { + "error": "Error" + }, + "navigation-bar": { + "project-name": "Project «{$name}»", + "project-name-archived": "Project «{$name}» (archived)", + "variant-name": "Variant «{$name}»", + "variant-name-archived": "Variant «{$name}» (archived)" + }, + "project": { + "project-dialog": { + "create-project": "Create project", + "edit-project": "Edit project", + "create": "Create", + "save": "Save", + "cancel": "Cancel", + "project-form": { + "name": "Name", + "mandatory-field": "Mandatory field", + "summary": "Summary", + "description": "Description", + "tooltip": "Users must be entered with their e-mail address. Confirm the entry for each e-mail with 'Enter'.", + "user-with-write-access": "User with write access", + "new-user-placeholder": "New user...", + "invalid-values": "Invalid values (no e-mail address)", + "user-with-read-access": "User with read access" + } + }, + "projects-view": { + "projects": "Projects", + "search-project": "Search project", + "show-archive": "Show archive", + "archived": "(archived)", + "archive-project": { + "title": "Archive project", + "content": "Would you like to archive the project now?" + }, + "undo-archiving-project": { + "title": "Undo archiving", + "content": "Would you like to undo the archiving the project now?" + }, + "undo-archiving": "Undo archiving", + "edit": "Edit", + "archive": "Archive" + } + }, + "variant": { + "variant-dialog": { + "create-variant": "Create variant", + "edit-variant": "Edit variant", + "save": "Save", + "cancel": "Cancel", + "variant-form": { + "name": "Name", + "mandatory-field": "Mandatory field" + } + }, + "variant-view": { + "variant-history": { + "publish-entry": { + "comment": "Comment", + "publish": "Publish", + "local-changes": "Local changes must be saved first", + "discard-changes": "Discard changes" + }, + "released-entry": { + "download": "Download", + "discard-changes": "Discard changes", + "ignore-conflict": "Ignore conflict", + "restore": "Restore", + "as-new-variant": "As new variant", + "version-already-available": "Version already available", + "successfully-published": "Successfully published" + }, + "snapshot-entry": { + "download": "Download", + "restore": "Restore", + "as-new-variant": "As new variant", + "successfully-published": "Successfully published", + "change-snapshot-version": "Change {$snapshotVersion}" + }, + "new-version-published": { + "title": "New version published", + "content": "Would you like to publish your personal changes as a new version?" + }, + "discard-changes": { + "title": "Discard changes", + "content": "Would you like to irrevocably discard your personal changes?" + }, + "restore-version": { + "title": "Restore version", + "content": "Would you like to restore the status of this version?" + }, + "ignore-conflict": { + "title": "Ignore conflict", + "content": "Would you like the current version to be based on the highest published version?" + } + }, + "archived": "(archived)", + "edit-variant": "Edit variant", + "delete-variant": { + "_value": "Delete variant", + "title": "Delete variant", + "content": "Do you want to permanently delete the variant and all versions it contains? This action cannot be undone." + }, + "versions": "Versions" + }, + "variants-view": { + "archived": "(archived)", + "variants": "Variants", + "search-variants": "Search variants", + "show-archive": "Show archive", + "project-description": "Project description", + "edit-project": "Edit project", + "archive-project": { + "_value": "Archive project", + "title": "Archive project", + "content": "Would you like to archive the project now?" + }, + "undo-archiving": "Undo archiving", + "delete-project": { + "_value": "Delete project", + "title": "Delete projekt", + "content": "Do you want to permanently delete the project and all the variants it contains? This action cannot be undone." + }, + "archive": "Archive", + "archive-variant": { + "title": "Archive variant", + "content": "Would you like to archive the variant now?" + }, + "undo-archiving-variant": { + "title": "Undo archiving", + "content": "Would you like to undo the archiving of the variant?" + }, + "undo-archiving-project": { + "title": "Archive variant", + "content": "Would you like to undo the archiving of the project?" + }, + "error-unexpected-data": "Unexpected data: No snapshot and no released version." + } + } + } + }, + "sbbBreadcrumbExpand": "Show entire path", + "sbbDialogCloseDialog": "Close dialog", + "sbbFileSelectorUploadFile": "Upload file", + "sbbFileSelectorRemoveFile": "Remove file", + "sbbHeaderMenuBack": "Back", + "sbbHeaderOpenMenu": "Open Menu", + "sbbHeaderCloseMenu": "Close Menu", + "sbbSidebarCollapse": "Collapse", + "sbbSidebarExpand": "Expand", + "sbbSidebarCloseSidebar": "Close Sidebar", + "sbbSidebarOpenSidebar": "Open Sidebar", + "sbbTextareaCounterText": "{$number} characters remaining", + "sbbUsermenuLogin": "Login", + "sbbUsermenuOpenPanel": "Logged in as {$name}. Click or press enter to open user menu." +} diff --git a/src/assets/i18n/it.json b/src/assets/i18n/it.json new file mode 100644 index 00000000..602be7bc --- /dev/null +++ b/src/assets/i18n/it.json @@ -0,0 +1,640 @@ +{ + "app-routing": { + "module": { + "path": { + "404": "The page you were looking for was not found.", + "401": "You are not authorized, please reload the page.", + "403": "You are not authorized to perform this action.", + "409": "There was a conflict while executing your action, please try again.", + "error": "An error has occurred." + } + } + }, + "app": { + "version": "Version {$version}", + "user-guide": "User guide", + "user-manual": "User manual", + "logout": "Logout", + "login": "You are getting logged in...", + "logger": { + "title": "Title" + }, + "models": { + "node": { + "shortNameDefault": "NEW", + "full-name-default": "New node" + }, + "note": { + "title-default": "Note title", + "text-default": "Note text", + "default-title": "Note title", + "default-text": "Note text" + } + }, + "netzgrafik-application": { + "variants": "Variants", + "filter": "Filter", + "analytics": "Analytics", + "edit": "Edit", + "more-functions": "More functions", + "settings": "Settings" + }, + "perlenkette": { + "perlenkette-node": { + "0-warning-connection": "No incorrect connection", + "1-warning-connection": "1 incorrect connection", + "n-warning-connections": "{$number} incorrect connections", + "0-fitting-connection": "No fitting connection", + "1-fitting-connection": "1 fitting connection", + "n-fitting-connections": "{$number} fitting connections" + }, + "show-only-closed-locks": "Show only closed locks", + "show-all-locks": "Show all locks" + }, + "services": { + "data": { + "node": { + "transit-modified": { + "title": "Transition changed", + "description": "Times cannot be adjusted, lock found on both sides" + } + }, + "trainrunsection": { + "intermediate-stop-replacement": { + "title": "Intermediate stop replacement", + "description": "Intermediate stop replacement led to inconsistencies in the allocation of times!" + } + } + }, + "ui": { + "newFilter": "New filer" + }, + "util": { + "connection-validator": { + "connection-marked-for-transit": { + "title": "Connection marked for transition!", + "description": "Connection marked for transition!" + } + }, + "trainrun-iteration": { + "error": { + "infinity-loop": "Iterator has detected an infinity loop. The iteration terminated early!" + } + }, + "trainrunsection-validator": { + "target-arrival-not-reacheable": { + "title": "Target Arrival Warning", + "description": "Target arrival time cannot be reached" + }, + "source-arrival-not-reacheable": { + "title": "Source Arrival Warning", + "description": "Source arrival time cannot be reached" + }, + "travel-time-less-than-1": { + "title": "Travel Time less than 1", + "description": "Travel time must be greater than or equal to 1" + } + }, + "transition-validator": { + "source-arrival-not-reacheable": { + "title": "Source Arrival Warning", + "description": "Source arrival time cannot be reached" + }, + "source-departure-not-reacheable": { + "title": "Source Departure Warning", + "description": "Source departure time cannot be reached" + }, + "target-arrival-not-reacheable": { + "title": "Target Arrival Warning", + "description": "Target arrival time cannot be reached" + }, + "target-departure-not-reacheable": { + "title": "Target Departure Warning", + "description": "Target departure time cannot be reached" + } + } + } + }, + "streckengrafik": { + "components": { + "reset": "Reset", + "close-all-path-nodes": "Close all path nodes", + "open-all-path-nodes": "Open all path nodes", + "show-advanced-display-functions": "Show advanced display functions", + "show-or-hide-time-for-non-selected-trainruns": "Show/hide time for non-selected trainruns", + "show-or-hide": "Enable/disable {$component}", + "show-or-hide-name-for-non-selected-trainruns": "Show/hide trainrun names for unselected trainruns", + "hide-advanced-display-functions": "Hide advanced display functions", + "mainTracks": "Main tracks", + "headway-band": "Headway band", + "time": "Time", + "name": "Name" + } + }, + "utils": { + "navigation-parameters": { + "no-project-id": "No project ID available", + "no-variant-id": "No variant ID available", + "no-version-id": "No version ID available" + } + }, + "view": { + "card-grid": { + "card": { + "open": "Open" + } + }, + "dialogs": { + "confirmation-dialog": { + "confirmation-default": "Yes", + "abort-default": "No" + }, + "filterable-labels-dialog": { + "filterable-label-dialog-component": { + "edit-filterable-labels": "Edit filterable labels for {$element}", + "transfer-to-all-visible": "transfer to all visible", + "delete-from-all-visible": "delete from all visible", + "transfer": { + "title": "Transfer", + "content": "Should the label {$label} be applied on all visible {$element}?" + }, + "delete": { + "title": "Delete", + "content": "Should the label {$label} be definitely delete on all visible {$element}?" + } + }, + "filterable-labels-form": { + "mandatory-field": "Mandatory field" + } + }, + "note-dialog": { + "html-editor": { + "reset-color": "Reset color", + "editor-placeholder": "Enter comment here...", + "mandatory-field": "Mandatory field", + "color-presets": { + "ec": { + "title": "Use color of the color scheme for EC" + }, + "ic": { + "title": "Use color of the color scheme for IC" + }, + "ir": { + "title": "Use color of the color scheme for IR" + }, + "re": { + "title": "Use color of the color scheme for RE" + }, + "s": { + "title": "Use color of the color scheme for S" + }, + "gex": { + "title": "Use color of the color scheme for GEX" + }, + "g": { + "title": "Use color of the color scheme for G" + }, + "green": { + "title": "green" + }, + "blue": { + "title": "blue" + }, + "magenta": { + "title": "magenta" + }, + "red": { + "title": "red" + }, + "warning": { + "title": "warning color" + } + } + }, + "note-tab": "Note", + "filterable-labels-tab": "Filterable labels", + "delete-note": "Delete note", + "note-filter-tab": { + "labels": "Labels", + "label-placeholder": "New label..." + }, + "note-form": { + "title": "Title", + "name": "Name" + } + }, + "stammdaten-dialog": { + "base-data": "Base data", + "operationalPoint": "Operational point", + "ipv-stop-time": "IPV stop time", + "a-stop-time": "A stop time", + "b-stop-time": "B stop time", + "c-stop-time": "C stop time", + "d-stop-time": "D stop time", + "zaz": "ZAZ", + "connection-time": "Connection time", + "region": "Region", + "category": "Category", + "filterable-labels": "Filterable labels", + "position": "Position", + "close": "Close" + }, + "trainrun-and-section-dialog": { + "filterableLabels": "Filterable Labels", + "trainrun-filter-tab": { + "labels": "Labels", + "newLabels" : "New label...", + "trainrunDuplicate": "Duplicate trainrun", + "trainrunDelete": "Delete trainrun", + "delete": "Delete", + "deleteConfirmationQuestion": "Should the entire train route be definitively deleted?" + }, + "trainrun-tab": { + "tabName": "Name", + "category": "Category", + "frequency": "Frequency", + "verkehrt": "Operates", + "trainrunDuplicate": "Duplicate trainrun", + "trainrunDelete": "Delete trainrun", + "delete": "Delete", + "deleteConfirmationQuestion": "Should the entire train route be definitively deleted?" + }, + "trainrun-section-tab": { + "warningTwoLocks": "Warning: Too many times are locked!", + "propagateTimesToLeft": "Propagate times to the left", + "propagateTimesToRight": "Propagate times to the right" + } + } + }, + "editor-edit-tools-view-component": { + "edit": "Edit", + "filterable-labels": "Filterable labels", + "trainruns": "Trainruns", + "nodes": "Nodes", + "notes": "Notes", + "delete-netzgrafik-title": "Netzgrafik - Delete", + "non-visible-elements": "Non visible elements", + "delete-all-non-visible-elements-tooltip": "Delete all non-visible elements, such as nodes, trainruns and notes", + "delete-all-non-visible-elements": "Delete all non-visible elements", + "visible-elements": "Visible elements", + "delete-all-visible-trainruns-tooltip": "Delete all visible trainruns", + "delete-all-visible-trainruns": "Delete all visible trainruns", + "delete-all-visible-notes-tooltip": "Delete all visible notes", + "delete-all-visible-notes": "Delete all visible notes", + "delete-all-visible-elements-tooltip": "Delete all visible elements, such as nodes, trainruns and notes", + "delete-all-visible-elements": "Delete all visible elements", + "merge-netzgrafik-title": "Netzgrafik - Merge", + "add-netzgrafik-as-copy-tooltip": "Add netzgrafik as a copy (trainruns, nodes, notes)", + "add-netzgrafik-as-copy": "Add netzgrafik as a copy", + "merge-netzgrafik-tooltip": "Merge netzgrafik (trainruns, nodes, notes)", + "merge-netzgrafik": "Merge netzgrafik", + "delete": "Delete", + "on-clear-delete-all-non-visible-elements": "Should all non-visible elements be permanently deleted from the netzgrafik?", + "on-clear-delete-all-visible-elements": "Should all visible elements be permanently deleted from the netzgrafik?", + "on-clear-delete-all-visible-trainruns": "Should all visible trainruns be permanently deleted from the netzgrafik?", + "on-clear-delete-all-visible-notes": "Should all visible notes be permanently deleted from the netzgrafik?", + "label-drop-list": { + "no-labels-available": "No labels available", + "delete-group": "Delete group", + "add-new-group": "Add new group", + "trainruns": "Trainruns", + "notes": "Notes", + "nodes": "Nodes" + } + }, + "editor-filter-view": { + "filter": "Filter", + "general": "General", + "category": "Category", + "frequency": "Frequence", + "time-category": "Time category", + "display-all-trainruns": "Display all trainruns", + "reset-trainrun-filter": "Reset trainrun filter", + "filterable-labels-trainruns": "Filterable labels: Trainruns", + "filterable-labels-nodes": "Filterable labels: Nodes", + "filterable-labels-notes": "Filterable labels: Notes", + "display": "Display", + "times": "Times", + "decimal-displayed": "Number of decimal place displayed", + "display-arrival-departure-times": "Display departure and arrival times", + "display-arrival-departure-times-for-connections": "Display departure and arrival times for connections", + "display-travel-times": "Display travel times", + "display-trainrun-name": "Display trainrun name", + "connections": "Connections", + "display-connections": "Display connections", + "nodes": "Nodes", + "display-nodes-without-visible-trainruns": "Display nodes without (visible) trainruns", + "display-nodes-with-only-stopping-trainruns": "Display nodes with only stopping trainruns", + "notes": "Notes", + "display-notes": "Display notes", + "reset-display-filter": "Reset display filter", + "saved-filters": "Saved filters", + "save-filters": "Save filters and add them as filter settings", + "reset-all-display-filters": "Reset all display filters", + "load-filter": "Load {$filter}", + "reload-filter": "Reload {$filter}", + "show-trainrun-category": "Show {$trainrunCategory}", + "hide-trainrun-category": "Hide {$trainrunCategory}", + "show-trainrun-time-category": "Show {$trainrunTimeCategory}", + "hide-trainrun-time-category": "Hide {$trainrunTimeCategory}", + "show-trainrun-frequency": "Show {$trainrunFrequency}", + "hide-trainrun-frequency": "Hide {$trainrunFrequency}", + "filterable-label-filter": { + "no-labels-available": "No labels available", + "or": "Or", + "and": "And", + "show-all": "Show all", + "reset-filter": "Reset filter", + "show": "show", + "hide": "hide" + } + }, + "editor-menu": { + "save-changes": "Save changes", + "changes-saved": "Changes saved", + "read-mode": "Read mode", + "show-hide-filter": "Show/Hide filter", + "zoom-out": "Zoom out", + "zoom-in": "Zoom in", + "topology-editor-disabled": "Topology editor disabled", + "topology-editor-enabled": "Topology editor enabled", + "multiple-selection-tool-disabled": "Multiple selection tool is disabled", + "multiple-selection-tool-enabled": "Multiple selection tool is enabled", + "note-editor-disabled": "Note editor disabled", + "note-editor-enabled": "Note editor enabled", + "analytics-disabled": "Analytics disabled", + "analytics-enabled": "Analytics enabled", + "displayGraphicTimetable": "Display graphic timetable", + "closeGraphicTimetable": "Close graphic timetable", + "errorGraphicTimetable": "Graphic timetable cannot be displayed because no trainrun or no nodes have been selected." + }, + "editor-properties-view-component": { + "settings": "Settings", + "color-scheme": "Color scheme", + "theme": "Theme", + "background-color": "Background color", + "set-color-to-white": "Set color to 'white'", + "reset-background-color-to-default": "Reset background color to default", + "background-color-black": "Background color (black)", + "editor": "Editor", + "travel-time-presetting-default": "Travel time presetting (heuristics)", + "graphicTimetable": "Graphic timetable", + "axis-scaling-distance": "Axis scaling (distance)", + "standardColorTheme": "Standard color theme", + "specialColorTheme": "Special color theme", + "grayscaleColorTheme": "Grayscale color theme", + "optimizedPrintColorTheme": "Optimized color theme for printing/exporting", + "standardDarkColorTheme": "Standard color theme (dark)", + "specialDarkColorTheme": "Special color theme (dark)", + "grayscaleDarkColorTheme": "Grayscale color theme (dark)", + "timeScaledDistance": "Travel time scaled", + "timeScaledDistanceTooltip": "The route graphic sections are displayed with travel time scaling, i.e. it is assumed that the selected train travels at a constant speed.", + "uniformDistance": "Uniform", + "uniformDistanceTooltip": "The route graphic sections are uniformly displayed.", + "fixed": "Constant 1min", + "fixedTooltip": "Adopts the travel time with a constant 1min (default).", + "retrieveFromEdge": "Section travel time", + "retrieveFromEdgeTooltip": "Takes over the max. travel time on the same section of all trains of the same category, otherwise max. travel time of all trains, otherwise 1 min." + }, + "editor-side-view": { + "editor-node-detail-view": { + "base-data": "Base data", + "operational-point": "Operational point", + "name": "Name", + "connection-time": "Connection time", + "occupancy": "Occupancy", + "capacity": "Capacity", + "filterable-labels": "Filterable labels", + "labels": "Labels", + "new-label-placeholder": "New label...", + "stopping-times": "Stopping times", + "stopping-time-per-product": "Stopping time per product", + "no-stop": "No stop", + "ipv": "IPV", + "a": "A", + "b": "B", + "c": "C", + "d": "D", + "links": "Links", + "platform-information": "Platform information", + "platform-length": "Platform length", + "delete-node": "Delete node", + "delete": "Delete", + "deleteNodeDialog": "Should the node {$operationalPointShortName} ({$operationalPointName}) be definitely deleted?" + }, + "editor-tools-view-component": { + "more-functions": "More functions", + "export": "Export", + "export-netzgrafik-as-svg": "Export netzgrafik as SVG", + "export-as-svg": "Export as SVG", + "export-netzgrafik-as-png": "Export netzgrafik as PNG", + "export-as-png": "Export as PNG", + "print-netzgrafik": "Print netzgrafik", + "print": "Print", + "netzgrafik": "Netzgrafik", + "export-netzgrafik": "Export netzgrafik", + "export-netzgrafik-as-json": "Export netzgrafik as JSON", + "import-netzgrafik": "Import netzgrafik", + "import-netzgrafik-as-json": "Import netzgrafik as JSON", + "export-trainruns": "Export trainruns", + "export-trainruns-as-csv": "Export trainruns as CSV", + "export-trainruns-as-csv-excel": "In Excel: Data -> From Text/CSV -> Import ... filename", + "base-data": "Base data", + "import-base-data": "Import base data", + "help-csv-data": "Help: CSV - Data", + "export-base-data": "Export base data", + "bp": "BP", + "station": "Station", + "category": "Category", + "region": "Region", + "passengerConnectionTimeIPV": "Passenger_connection_time_IPV", + "passengerConnectionTimeA": "Passenger_connection_time_A", + "passengerConnectionTimeB": "Passenger_connection_time_B", + "passengerConnectionTimeC": "Passenger_connection_time_C", + "passengerConnectionTimeD": "Passenger_connection_time_D", + "ZAZ": "ZAZ", + "transferTime": "Transfer_time", + "labels": "Labels", + "X": "X", + "Y": "Y", + "create": "Create", + "yes": "YES", + "netzgrafikFile": "networkGraphic", + "baseDataFile": "baseData", + "trainrunFile": "trainrun", + "trainCategory": "Train category", + "trainName": "Train name", + "startStation": "Start station", + "destinationStation": "Destination station", + "trafficPeriod": "Traffic period", + "frequence": "Frequence", + "departureMinuteAtStart": "Minute of departure at start node", + "travelTimeStartDestination": "Travel time start-destination", + "arrivalMinuteAtDestination": "Arrival minute at destination node", + "turnaroundTimeDestination": "Turnaround time at destination station", + "departureMinuteDeparture": "Departure minute at destination node", + "travelTimeDestinationStart": "Travel time destination-start", + "arrivalMinuteAtStart": "Arrival minute at start node", + "turnaroundTimeStart": "Turnaround time at start station", + "turnaroundTime": "Turnaround time", + "trainrunTimeCategory": "Trainrun time category" + } + }, + "error-view": { + "error": "Error" + }, + "navigation-bar": { + "project-name": "Project «{$name}»", + "project-name-archived": "Project «{$name}» (archived)", + "variant-name": "Variant «{$name}»", + "variant-name-archived": "Variant «{$name}» (archived)" + }, + "project": { + "project-dialog": { + "create-project": "Create project", + "edit-project": "Edit project", + "create": "Create", + "save": "Save", + "cancel": "Cancel", + "project-form": { + "name": "Name", + "mandatory-field": "Mandatory field", + "summary": "Summary", + "description": "Description", + "tooltip": "Users must be entered with their e-mail address. Confirm the entry for each e-mail with 'Enter'.", + "user-with-write-access": "User with write access", + "new-user-placeholder": "New user...", + "invalid-values": "Invalid values (no e-mail address)", + "user-with-read-access": "User with read access" + } + }, + "projects-view": { + "projects": "Projects", + "search-project": "Search project", + "show-archive": "Show archive", + "archived": "(archived)", + "archive-project": { + "title": "Archive project", + "content": "Would you like to archive the project now?" + }, + "undo-archiving-project": { + "title": "Undo archiving", + "content": "Would you like to undo the archiving the project now?" + }, + "undo-archiving": "Undo archiving", + "edit": "Edit", + "archive": "Archive" + } + }, + "variant": { + "variant-dialog": { + "create-variant": "Create variant", + "edit-variant": "Edit variant", + "save": "Save", + "cancel": "Cancel", + "variant-form": { + "name": "Name", + "mandatory-field": "Mandatory field" + } + }, + "variant-view": { + "variant-history": { + "publish-entry": { + "comment": "Comment", + "publish": "Publish", + "local-changes": "Local changes must be saved first", + "discard-changes": "Discard changes" + }, + "released-entry": { + "download": "Download", + "discard-changes": "Discard changes", + "ignore-conflict": "Ignore conflict", + "restore": "Restore", + "as-new-variant": "As new variant", + "version-already-available": "Version already available", + "successfully-published": "Successfully published" + }, + "snapshot-entry": { + "download": "Download", + "restore": "Restore", + "as-new-variant": "As new variant", + "successfully-published": "Successfully published", + "change-snapshot-version": "Change {$snapshotVersion}" + }, + "new-version-published": { + "title": "New version published", + "content": "Would you like to publish your personal changes as a new version?" + }, + "discard-changes": { + "title": "Discard changes", + "content": "Would you like to irrevocably discard your personal changes?" + }, + "restore-version": { + "title": "Restore version", + "content": "Would you like to restore the status of this version?" + }, + "ignore-conflict": { + "title": "Ignore conflict", + "content": "Would you like the current version to be based on the highest published version?" + } + }, + "archived": "(archived)", + "edit-variant": "Edit variant", + "delete-variant": { + "_value": "Delete variant", + "title": "Delete variant", + "content": "Do you want to permanently delete the variant and all versions it contains? This action cannot be undone." + }, + "versions": "Versions" + }, + "variants-view": { + "archived": "(archived)", + "variants": "Variants", + "search-variants": "Search variants", + "show-archive": "Show archive", + "project-description": "Project description", + "edit-project": "Edit project", + "archive-project": { + "_value": "Archive project", + "title": "Archive project", + "content": "Would you like to archive the project now?" + }, + "undo-archiving": "Undo archiving", + "delete-project": { + "_value": "Delete project", + "title": "Delete projekt", + "content": "Do you want to permanently delete the project and all the variants it contains? This action cannot be undone." + }, + "archive": "Archive", + "archive-variant": { + "title": "Archive variant", + "content": "Would you like to archive the variant now?" + }, + "undo-archiving-variant": { + "title": "Undo archiving", + "content": "Would you like to undo the archiving of the variant?" + }, + "undo-archiving-project": { + "title": "Archive variant", + "content": "Would you like to undo the archiving of the project?" + }, + "error-unexpected-data": "Unexpected data: No snapshot and no released version." + } + } + } + }, + "sbbBreadcrumbExpand": "Show entire path", + "sbbDialogCloseDialog": "Close dialog", + "sbbFileSelectorUploadFile": "Upload file", + "sbbFileSelectorRemoveFile": "Remove file", + "sbbHeaderMenuBack": "Back", + "sbbHeaderOpenMenu": "Open Menu", + "sbbHeaderCloseMenu": "Close Menu", + "sbbSidebarCollapse": "Collapse", + "sbbSidebarExpand": "Expand", + "sbbSidebarCloseSidebar": "Close Sidebar", + "sbbSidebarOpenSidebar": "Open Sidebar", + "sbbTextareaCounterText": "{$number} characters remaining", + "sbbUsermenuLogin": "Login", + "sbbUsermenuOpenPanel": "Logged in as {$name}. Click or press enter to open user menu." +} diff --git a/src/i18n/messages.de-CH.xlf b/src/i18n/messages.de-CH.xlf deleted file mode 100644 index 5142e472..00000000 --- a/src/i18n/messages.de-CH.xlf +++ /dev/null @@ -1,149 +0,0 @@ - - - - - - Einträge Einträge - - node_modules/@sbb-esta/angular-public/lib/tabs/tabs/tabs.component.d.ts - 26 - - Aria label for amount of entries displayed in badge pill - - Kalender öffnenKalender öffnen - - node_modules/@sbb-esta/angular-public/lib/datepicker/datepicker-toggle/datepicker-toggle.component.d.ts - 4 - - Open calendar - - Zum letzten Monat wechselnZum letzten Monat wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 10 - - Button label to switch to the previous month - - Zum nächsten Monat wechselnZum nächsten Monat wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 28 - - Button label to switch to the next month - - Zum letzten Jahr wechselnZum letzten Jahr wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 42 - - Button label to switch to the previous year - - Zum nächsten Jahr wechselnZum nächsten Jahr wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 60 - - Button label to switch to the next year - - Vorherige SeiteVorherige Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/pagination/pagination.component.d.ts - 6 - - - Nächste SeiteNächste Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/pagination/pagination.component.d.ts - 37 - - - Vorherige SeiteVorherige Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/navigation/navigation.component.d.ts - 6 - - - Nächste SeiteNächste Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/navigation/navigation.component.d.ts - 22 - - - Weniger anzeigenWeniger anzeigen - - node_modules/@sbb-esta/angular-public/lib/textexpand/textexpand/textexpand.component.d.ts - 14 - - Button label for showing less - - Mehr anzeigenMehr anzeigen - - node_modules/@sbb-esta/angular-public/lib/textexpand/textexpand/textexpand.component.d.ts - 20 - - Button label for showing more - - Resultate verfügbar Resultate verfügbar - - node_modules/@sbb-esta/angular-public/lib/tag/tag/tag.component.d.ts - 7 - - - node_modules/@sbb-esta/angular-public/lib/tag/tag/tag.component.d.ts - 41 - - Aria label for amount of results displayed in badge pill - - AlleAlle - - node_modules/@sbb-esta/angular-public/lib/tag/tags/tags.component.d.ts - 4 - - Label for 'All' tag - - Datei hochladenDatei hochladen - - node_modules/@sbb-esta/angular-public/lib/file-selector/file-selector/file-selector.component.d.ts - 17 - - Button label to select files for upload - - Datei entfernenDatei entfernen - - node_modules/@sbb-esta/angular-public/lib/file-selector/file-selector/file-selector.component.d.ts - 48 - - Hidden button label to remove a file from the selection list - - - Login - - Login - - - node_modules/@sbb-esta/angular-public/lib/usermenu/usermenu/usermenu.component.d.ts - 54 - - Button label for login - - Hinweismeldung schliessenHinweismeldung schliessen - - node_modules/@sbb-esta/angular-public/lib/ghettobox/ghettobox/ghettobox.component.d.ts - 44 - - Hidden button label to close the ghettobox - - This is the template from ESTA Cloud for building Angular applications. - Dies ist das Template von ESTA Cloud für das erstellen von Angular Applications. - - src/app/app.component.html6 - This app uses the Angular Component Library from ESTA (@sbb-esta/angular-public). See documentation on how to use it. - Diese Applikation benutzt die Angular Component Library von ESTA (@sbb-esta/angular-public). Siehe Dokumentation, wie sie zu verwenden ist. - - src/app/app.component.html - 8 - - - - - diff --git a/src/i18n/messages.en-CH.xlf b/src/i18n/messages.en-CH.xlf deleted file mode 100644 index fb8068c0..00000000 --- a/src/i18n/messages.en-CH.xlf +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - Einträge Einträge - - node_modules/@sbb-esta/angular-public/lib/tabs/tabs/tabs.component.d.ts - 26 - - Aria label for amount of entries displayed in badge pill - - Kalender öffnenKalender öffnen - - node_modules/@sbb-esta/angular-public/lib/datepicker/datepicker-toggle/datepicker-toggle.component.d.ts - 4 - - Open calendar - - Zum letzten Monat wechselnZum letzten Monat wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 10 - - Button label to switch to the previous month - - Zum nächsten Monat wechselnZum nächsten Monat wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 28 - - Button label to switch to the next month - - Zum letzten Jahr wechselnZum letzten Jahr wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 42 - - Button label to switch to the previous year - - Zum nächsten Jahr wechselnZum nächsten Jahr wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 60 - - Button label to switch to the next year - - Vorherige SeiteVorherige Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/pagination/pagination.component.d.ts - 6 - - - Nächste SeiteNächste Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/pagination/pagination.component.d.ts - 37 - - - Vorherige SeiteVorherige Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/navigation/navigation.component.d.ts - 6 - - - Nächste SeiteNächste Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/navigation/navigation.component.d.ts - 22 - - - Weniger anzeigenWeniger anzeigen - - node_modules/@sbb-esta/angular-public/lib/textexpand/textexpand/textexpand.component.d.ts - 14 - - Button label for showing less - - Mehr anzeigenMehr anzeigen - - node_modules/@sbb-esta/angular-public/lib/textexpand/textexpand/textexpand.component.d.ts - 20 - - Button label for showing more - - Resultate verfügbar Resultate verfügbar - - node_modules/@sbb-esta/angular-public/lib/tag/tag/tag.component.d.ts - 7 - - - node_modules/@sbb-esta/angular-public/lib/tag/tag/tag.component.d.ts - 41 - - Aria label for amount of results displayed in badge pill - - AlleAlle - - node_modules/@sbb-esta/angular-public/lib/tag/tags/tags.component.d.ts - 4 - - Label for 'All' tag - - Datei hochladenDatei hochladen - - node_modules/@sbb-esta/angular-public/lib/file-selector/file-selector/file-selector.component.d.ts - 17 - - Button label to select files for upload - - Datei entfernenDatei entfernen - - node_modules/@sbb-esta/angular-public/lib/file-selector/file-selector/file-selector.component.d.ts - 48 - - Hidden button label to remove a file from the selection list - - - Login - - Login - - - node_modules/@sbb-esta/angular-public/lib/usermenu/usermenu/usermenu.component.d.ts - 54 - - Button label for login - - Hinweismeldung schliessenHinweismeldung schliessen - - node_modules/@sbb-esta/angular-public/lib/ghettobox/ghettobox/ghettobox.component.d.ts - 44 - - Hidden button label to close the ghettobox - - This is the template from ESTA Cloud for building Angular applications.This is the template from ESTA Cloud for building Angular applications. - - src/app/app.component.html6 - This app uses the Angular Component Library from ESTA (@sbb-esta/angular-public). See documentation on how to use it.This app uses the Angular Component Library from ESTA (@sbb-esta/angular-public). See documentation on how to use it. - - src/app/app.component.html - 8 - - - - - diff --git a/src/i18n/messages.fr-CH.xlf b/src/i18n/messages.fr-CH.xlf deleted file mode 100644 index 9c1fb17f..00000000 --- a/src/i18n/messages.fr-CH.xlf +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - Einträge Einträge - - node_modules/@sbb-esta/angular-public/lib/tabs/tabs/tabs.component.d.ts - 26 - - Aria label for amount of entries displayed in badge pill - - Kalender öffnenKalender öffnen - - node_modules/@sbb-esta/angular-public/lib/datepicker/datepicker-toggle/datepicker-toggle.component.d.ts - 4 - - Open calendar - - Zum letzten Monat wechselnZum letzten Monat wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 10 - - Button label to switch to the previous month - - Zum nächsten Monat wechselnZum nächsten Monat wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 28 - - Button label to switch to the next month - - Zum letzten Jahr wechselnZum letzten Jahr wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 42 - - Button label to switch to the previous year - - Zum nächsten Jahr wechselnZum nächsten Jahr wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 60 - - Button label to switch to the next year - - Vorherige SeiteVorherige Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/pagination/pagination.component.d.ts - 6 - - - Nächste SeiteNächste Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/pagination/pagination.component.d.ts - 37 - - - Vorherige SeiteVorherige Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/navigation/navigation.component.d.ts - 6 - - - Nächste SeiteNächste Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/navigation/navigation.component.d.ts - 22 - - - Weniger anzeigenWeniger anzeigen - - node_modules/@sbb-esta/angular-public/lib/textexpand/textexpand/textexpand.component.d.ts - 14 - - Button label for showing less - - Mehr anzeigenMehr anzeigen - - node_modules/@sbb-esta/angular-public/lib/textexpand/textexpand/textexpand.component.d.ts - 20 - - Button label for showing more - - Resultate verfügbar Resultate verfügbar - - node_modules/@sbb-esta/angular-public/lib/tag/tag/tag.component.d.ts - 7 - - - node_modules/@sbb-esta/angular-public/lib/tag/tag/tag.component.d.ts - 41 - - Aria label for amount of results displayed in badge pill - - AlleAlle - - node_modules/@sbb-esta/angular-public/lib/tag/tags/tags.component.d.ts - 4 - - Label for 'All' tag - - Datei hochladenDatei hochladen - - node_modules/@sbb-esta/angular-public/lib/file-selector/file-selector/file-selector.component.d.ts - 17 - - Button label to select files for upload - - Datei entfernenDatei entfernen - - node_modules/@sbb-esta/angular-public/lib/file-selector/file-selector/file-selector.component.d.ts - 48 - - Hidden button label to remove a file from the selection list - - - Login - - Login - - - node_modules/@sbb-esta/angular-public/lib/usermenu/usermenu/usermenu.component.d.ts - 54 - - Button label for login - - Hinweismeldung schliessenHinweismeldung schliessen - - node_modules/@sbb-esta/angular-public/lib/ghettobox/ghettobox/ghettobox.component.d.ts - 44 - - Hidden button label to close the ghettobox - - This is the template from ESTA Cloud for building Angular applications.This is the template from ESTA Cloud for building Angular applications. - - src/app/app.component.html6 - This app uses the Angular Component Library from ESTA (@sbb-esta/angular-public). See documentation on how to use it.This app uses the Angular Component Library from ESTA (@sbb-esta/angular-public). See documentation on how to use it. - - src/app/app.component.html - 8 - - - - - diff --git a/src/i18n/messages.it-CH.xlf b/src/i18n/messages.it-CH.xlf deleted file mode 100644 index 254f4e9b..00000000 --- a/src/i18n/messages.it-CH.xlf +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - Einträge Einträge - - node_modules/@sbb-esta/angular-public/lib/tabs/tabs/tabs.component.d.ts - 26 - - Aria label for amount of entries displayed in badge pill - - Kalender öffnenKalender öffnen - - node_modules/@sbb-esta/angular-public/lib/datepicker/datepicker-toggle/datepicker-toggle.component.d.ts - 4 - - Open calendar - - Zum letzten Monat wechselnZum letzten Monat wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 10 - - Button label to switch to the previous month - - Zum nächsten Monat wechselnZum nächsten Monat wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 28 - - Button label to switch to the next month - - Zum letzten Jahr wechselnZum letzten Jahr wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 42 - - Button label to switch to the previous year - - Zum nächsten Jahr wechselnZum nächsten Jahr wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 60 - - Button label to switch to the next year - - Vorherige SeiteVorherige Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/pagination/pagination.component.d.ts - 6 - - - Nächste SeiteNächste Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/pagination/pagination.component.d.ts - 37 - - - Vorherige SeiteVorherige Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/navigation/navigation.component.d.ts - 6 - - - Nächste SeiteNächste Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/navigation/navigation.component.d.ts - 22 - - - Weniger anzeigenWeniger anzeigen - - node_modules/@sbb-esta/angular-public/lib/textexpand/textexpand/textexpand.component.d.ts - 14 - - Button label for showing less - - Mehr anzeigenMehr anzeigen - - node_modules/@sbb-esta/angular-public/lib/textexpand/textexpand/textexpand.component.d.ts - 20 - - Button label for showing more - - Resultate verfügbar Resultate verfügbar - - node_modules/@sbb-esta/angular-public/lib/tag/tag/tag.component.d.ts - 7 - - - node_modules/@sbb-esta/angular-public/lib/tag/tag/tag.component.d.ts - 41 - - Aria label for amount of results displayed in badge pill - - AlleAlle - - node_modules/@sbb-esta/angular-public/lib/tag/tags/tags.component.d.ts - 4 - - Label for 'All' tag - - Datei hochladenDatei hochladen - - node_modules/@sbb-esta/angular-public/lib/file-selector/file-selector/file-selector.component.d.ts - 17 - - Button label to select files for upload - - Datei entfernenDatei entfernen - - node_modules/@sbb-esta/angular-public/lib/file-selector/file-selector/file-selector.component.d.ts - 48 - - Hidden button label to remove a file from the selection list - - - Login - - Login - - - node_modules/@sbb-esta/angular-public/lib/usermenu/usermenu/usermenu.component.d.ts - 54 - - Button label for login - - Hinweismeldung schliessenHinweismeldung schliessen - - node_modules/@sbb-esta/angular-public/lib/ghettobox/ghettobox/ghettobox.component.d.ts - 44 - - Hidden button label to close the ghettobox - - This is the template from ESTA Cloud for building Angular applications.This is the template from ESTA Cloud for building Angular applications. - - src/app/app.component.html6 - This app uses the Angular Component Library from ESTA (@sbb-esta/angular-public). See documentation on how to use it.This app uses the Angular Component Library from ESTA (@sbb-esta/angular-public). See documentation on how to use it. - - src/app/app.component.html - 8 - - - - - diff --git a/src/i18n/messages.xlf b/src/i18n/messages.xlf deleted file mode 100644 index fbdcfc1e..00000000 --- a/src/i18n/messages.xlf +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - Einträge - - node_modules/@sbb-esta/angular-public/lib/tabs/tabs/tabs.component.d.ts - 26 - - Aria label for amount of entries displayed in badge pill - - - Kalender öffnen - - node_modules/@sbb-esta/angular-public/lib/datepicker/datepicker-toggle/datepicker-toggle.component.d.ts - 4 - - Open calendar - - - Zum letzten Monat wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 10 - - Button label to switch to the previous month - - - Zum nächsten Monat wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 28 - - Button label to switch to the next month - - - Zum letzten Jahr wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 42 - - Button label to switch to the previous year - - - Zum nächsten Jahr wechseln - - node_modules/@sbb-esta/angular-public/lib/datepicker/calendar/calendar.component.d.ts - 60 - - Button label to switch to the next year - - - Vorherige Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/pagination/pagination.component.d.ts - 6 - - - - Nächste Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/pagination/pagination.component.d.ts - 37 - - - - Vorherige Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/navigation/navigation.component.d.ts - 6 - - - - Nächste Seite - - node_modules/@sbb-esta/angular-public/lib/pagination/navigation/navigation.component.d.ts - 22 - - - - Weniger anzeigen - - node_modules/@sbb-esta/angular-public/lib/textexpand/textexpand/textexpand.component.d.ts - 14 - - Button label for showing less - - - Mehr anzeigen - - node_modules/@sbb-esta/angular-public/lib/textexpand/textexpand/textexpand.component.d.ts - 20 - - Button label for showing more - - - Resultate verfügbar - - node_modules/@sbb-esta/angular-public/lib/tag/tag/tag.component.d.ts - 7 - - - node_modules/@sbb-esta/angular-public/lib/tag/tag/tag.component.d.ts - 41 - - Aria label for amount of results displayed in badge pill - - - Alle - - node_modules/@sbb-esta/angular-public/lib/tag/tags/tags.component.d.ts - 4 - - Label for 'All' tag - - - Datei hochladen - - node_modules/@sbb-esta/angular-public/lib/file-selector/file-selector/file-selector.component.d.ts - 17 - - Button label to select files for upload - - - Datei entfernen - - node_modules/@sbb-esta/angular-public/lib/file-selector/file-selector/file-selector.component.d.ts - 48 - - Hidden button label to remove a file from the selection list - - - - Login - - - node_modules/@sbb-esta/angular-public/lib/usermenu/usermenu/usermenu.component.d.ts - 54 - - Button label for login - - - Hinweismeldung schliessen - - node_modules/@sbb-esta/angular-public/lib/ghettobox/ghettobox/ghettobox.component.d.ts - 44 - - Hidden button label to close the ghettobox - - - This is the template from ESTA Cloud for building Angular applications. - - src/app/app.component.html - 6 - - - - This app uses the Angular Component Library from ESTA (@sbb-esta/angular-public). See documentation on how to use it. - - src/app/app.component.html - 8 - - - - - From 8f5f2fbb3b462cf8e9f5280aeff0d83cbf916b9c Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Wed, 31 Jul 2024 17:29:08 +0200 Subject: [PATCH 027/197] Preparation Version 2.7.0 (Release) (#203) * 2.6.0 -> 2.6.1 * 2.7.0 release preparation --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3f6dda03..d191ce4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.6.0", + "version": "2.7.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.6.0", + "version": "2.7.0", "dependencies": { "@angular/animations": "^17.0.5", "@angular/cdk": "^17.0.1", diff --git a/package.json b/package.json index b3cb9e0e..1b17ab1d 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.6.0", + "version": "2.7.0", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From c2aea8ff09770103b4ba9e186c9b716a3d48510f Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 2 Aug 2024 22:10:09 +0200 Subject: [PATCH 028/197] refactor: simplify formatDisplayText() (#206) Use a loop instead of repeating the replace() calls. --- src/app/models/trainrunsection.model.ts | 45 +++++++------------------ 1 file changed, 12 insertions(+), 33 deletions(-) diff --git a/src/app/models/trainrunsection.model.ts b/src/app/models/trainrunsection.model.ts index a062dc53..0460aee7 100644 --- a/src/app/models/trainrunsection.model.ts +++ b/src/app/models/trainrunsection.model.ts @@ -178,46 +178,25 @@ export class TrainrunSection { if (!time?.timeFormatter?.stylePattern) { return undefined; } - const stylePattern = time.timeFormatter.stylePattern; - let formattedText = ""; - const consecutiveTimePatternHHMMSS = "{{consecutiveTime}}.format(HH:mm:ss)"; - const consecutiveTimePatternHHMM = "{{consecutiveTime}}.format(HH:mm)"; - const consecutiveTimePattern = "{{consecutiveTime}}"; - const timePatternHHMMSS = "{{time}}.format(HH:mm:ss)"; - const timePatternHHMM = "{{time}}.format(HH:mm)"; - const timePattern = "{{time}}"; const consecutiveTimeDate = new Date(null); consecutiveTimeDate.setSeconds((time.consecutiveTime + offset) * 60); const timeDate = new Date(null); timeDate.setSeconds(((time.time + offset + 24 * 60) % 60) * 60); - formattedText = stylePattern; - formattedText = formattedText.replace( - consecutiveTimePatternHHMMSS, - formatDate(consecutiveTimeDate.toISOString(), "HH:mm:ss", "en-US", "UTC"), - ); - formattedText = formattedText.replace( - consecutiveTimePatternHHMM, - formatDate(consecutiveTimeDate.toISOString(), "HH:mm", "en-US", "UTC"), - ); - formattedText = formattedText.replace( - consecutiveTimePattern, - "" + time.consecutiveTime, - ); + const patterns = { + "{{consecutiveTime}}.format(HH:mm:ss)": formatDate(consecutiveTimeDate.toISOString(), "HH:mm:ss", "en-US", "UTC"), + "{{consecutiveTime}}.format(HH:mm)": formatDate(consecutiveTimeDate.toISOString(), "HH:mm", "en-US", "UTC"), + "{{consecutiveTime}}": "" + time.consecutiveTime, + "{{time}}.format(HH:mm:ss)": formatDate(timeDate.toISOString(), "HH:mm:ss", "en-US", "UTC"), + "{{time}}.format(HH:mm)": formatDate(timeDate.toISOString(), "HH:mm", "en-US", "UTC"), + "{{time}}": "" + ((time.time + offset + 24 * 60) % 60), + }; - formattedText = formattedText.replace( - timePatternHHMMSS, - formatDate(timeDate.toISOString(), "HH:mm:ss", "en-US", "UTC"), - ); - formattedText = formattedText.replace( - timePatternHHMM, - formatDate(timeDate.toISOString(), "HH:mm", "en-US", "UTC"), - ); - formattedText = formattedText.replace( - timePattern, - "" + ((time.time + offset + 24 * 60) % 60), - ); + let formattedText = time.timeFormatter.stylePattern; + for (const pattern in patterns) { + formattedText = formattedText.replace(pattern, patterns[pattern]); + } return formattedText; } From 9caa47df57ebe0bffb84168bfee4d82e85255029 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 11:57:37 +0200 Subject: [PATCH 029/197] chore(main): release 2.6.2 (#204) * chore(main): release 2.6.2 * Update package.json Manually edited version number (preparation automatic release building) * Update package-lock.json Manually edited version number (preparation automatic release building) * Manually edited version number (preparation automatic release building) * Text formatted --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Adrian Egli --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb9a5a82..df063ecf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 2.7.1 Manually edited version number (preparation automatic release building) + + +### Bug Fixes + +* align theme color picker with buttons ([#198](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/198)) ([e3a8798](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/e3a87989ea28a04a4a0bb9cee825825bb1b97d7b)) + ## [2.6.0](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/v2.5.0...v2.6.0) (2024-07-22) diff --git a/package-lock.json b/package-lock.json index d191ce4e..318e47f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.7.0", + "version": "2.7.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.7.0", + "version": "2.7.1", "dependencies": { "@angular/animations": "^17.0.5", "@angular/cdk": "^17.0.1", diff --git a/package.json b/package.json index 1b17ab1d..f2233e0d 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.7.0", + "version": "2.7.1", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From ced024451cb329946b22172e7caecece2b9afddd Mon Sep 17 00:00:00 2001 From: Louis Greiner <57864277+louisgreiner@users.noreply.github.com> Date: Mon, 5 Aug 2024 16:36:25 +0200 Subject: [PATCH 030/197] Missing translations (#209) * perlenkette-section * sbb components * browser color theme --- .../perlenkette-section.component.html | 4 ++-- .../editor-properties-view.component.html | 4 ++-- src/assets/i18n/de.json | 10 ++++++++-- src/assets/i18n/en.json | 10 ++++++++-- src/assets/i18n/fr.json | 10 ++++++++-- src/assets/i18n/it.json | 10 ++++++++-- 6 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/app/perlenkette/perlenkette-section/perlenkette-section.component.html b/src/app/perlenkette/perlenkette-section/perlenkette-section.component.html index aa27d2bd..c4b36fb6 100644 --- a/src/app/perlenkette/perlenkette-section/perlenkette-section.component.html +++ b/src/app/perlenkette/perlenkette-section/perlenkette-section.component.html @@ -581,7 +581,7 @@ tabindex="-1" mode="icon" (click)="onPropagateTimeLeft($event)" - title="Zeiten nach oben propagieren" + [title]="'app.perlenkette.perlenkette-section.propagate-times-upwards' | translate" >
{{ 'app.view.editor-properties-view-component.settings' diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index 13b9af3c..5a88788a 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -48,6 +48,10 @@ "1-fitting-connection": "1 passender Anschluss", "n-fitting-connections": "{$number} passende Anschlüsse" }, + "perlenkette-section": { + "propagate-times-upwards": "Zeiten nach oben propagieren", + "propagate-times-downwards": "Zeiten nach unten propagieren" + }, "show-only-closed-locks": "Zeige nur geschlossene Schlösser", "show-all-locks": "Zeige alle Schlösser" }, @@ -377,6 +381,8 @@ "reset-background-color-to-default": "Hintergrundfarbe auf Standard zurücksetzen", "background-color-black": "Hintergrundfarbe (dunkel)", "editor": "Editor", + "useDefaultBrowserColorTheme": "Verwenden Sie das Standard-Browser-Farbtheme.", + "defaultBrowserColorTheme": "Standard-Browser-Farbtheme", "travel-time-presetting-default": "Fahrzeitvoreinstellungs (Heuristik)", "graphicTimetable": "Streckengrafik", "axis-scaling-distance": "Achsenskalierung (Distanz)", @@ -634,7 +640,7 @@ "sbbSidebarExpand": "Erweitern", "sbbSidebarCloseSidebar": "Sidebar schließen", "sbbSidebarOpenSidebar": "Sidebar öffnen", - "sbbTextareaCounterText": "{$number} verbleibende Zeichen", + "sbbTextareaCounterText": "{$PH} verbleibende Zeichen", "sbbUsermenuLogin": "Login", - "sbbUsermenuOpenPanel": "Eingeloggt als {$name}. Klicken Sie auf oder drücken Sie die Eingabetaste, um das Benutzermenü zu öffnen." + "sbbUsermenuOpenPanel": "Eingeloggt als {$PH}. Klicken Sie auf oder drücken Sie die Eingabetaste, um das Benutzermenü zu öffnen." } diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 602be7bc..8066d137 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -48,6 +48,10 @@ "1-fitting-connection": "1 fitting connection", "n-fitting-connections": "{$number} fitting connections" }, + "perlenkette-section": { + "propagate-times-upwards": "Propagate times upwards", + "propagate-times-downwards": "Propagate times downwards" + }, "show-only-closed-locks": "Show only closed locks", "show-all-locks": "Show all locks" }, @@ -377,6 +381,8 @@ "reset-background-color-to-default": "Reset background color to default", "background-color-black": "Background color (black)", "editor": "Editor", + "useDefaultBrowserColorTheme": "Use the default browser color theme.", + "defaultBrowserColorTheme": "Default browser color theme", "travel-time-presetting-default": "Travel time presetting (heuristics)", "graphicTimetable": "Graphic timetable", "axis-scaling-distance": "Axis scaling (distance)", @@ -634,7 +640,7 @@ "sbbSidebarExpand": "Expand", "sbbSidebarCloseSidebar": "Close Sidebar", "sbbSidebarOpenSidebar": "Open Sidebar", - "sbbTextareaCounterText": "{$number} characters remaining", + "sbbTextareaCounterText": "{$PH} characters remaining", "sbbUsermenuLogin": "Login", - "sbbUsermenuOpenPanel": "Logged in as {$name}. Click or press enter to open user menu." + "sbbUsermenuOpenPanel": "Logged in as {$PH}. Click or press enter to open user menu." } diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index 602be7bc..8066d137 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -48,6 +48,10 @@ "1-fitting-connection": "1 fitting connection", "n-fitting-connections": "{$number} fitting connections" }, + "perlenkette-section": { + "propagate-times-upwards": "Propagate times upwards", + "propagate-times-downwards": "Propagate times downwards" + }, "show-only-closed-locks": "Show only closed locks", "show-all-locks": "Show all locks" }, @@ -377,6 +381,8 @@ "reset-background-color-to-default": "Reset background color to default", "background-color-black": "Background color (black)", "editor": "Editor", + "useDefaultBrowserColorTheme": "Use the default browser color theme.", + "defaultBrowserColorTheme": "Default browser color theme", "travel-time-presetting-default": "Travel time presetting (heuristics)", "graphicTimetable": "Graphic timetable", "axis-scaling-distance": "Axis scaling (distance)", @@ -634,7 +640,7 @@ "sbbSidebarExpand": "Expand", "sbbSidebarCloseSidebar": "Close Sidebar", "sbbSidebarOpenSidebar": "Open Sidebar", - "sbbTextareaCounterText": "{$number} characters remaining", + "sbbTextareaCounterText": "{$PH} characters remaining", "sbbUsermenuLogin": "Login", - "sbbUsermenuOpenPanel": "Logged in as {$name}. Click or press enter to open user menu." + "sbbUsermenuOpenPanel": "Logged in as {$PH}. Click or press enter to open user menu." } diff --git a/src/assets/i18n/it.json b/src/assets/i18n/it.json index 602be7bc..8066d137 100644 --- a/src/assets/i18n/it.json +++ b/src/assets/i18n/it.json @@ -48,6 +48,10 @@ "1-fitting-connection": "1 fitting connection", "n-fitting-connections": "{$number} fitting connections" }, + "perlenkette-section": { + "propagate-times-upwards": "Propagate times upwards", + "propagate-times-downwards": "Propagate times downwards" + }, "show-only-closed-locks": "Show only closed locks", "show-all-locks": "Show all locks" }, @@ -377,6 +381,8 @@ "reset-background-color-to-default": "Reset background color to default", "background-color-black": "Background color (black)", "editor": "Editor", + "useDefaultBrowserColorTheme": "Use the default browser color theme.", + "defaultBrowserColorTheme": "Default browser color theme", "travel-time-presetting-default": "Travel time presetting (heuristics)", "graphicTimetable": "Graphic timetable", "axis-scaling-distance": "Axis scaling (distance)", @@ -634,7 +640,7 @@ "sbbSidebarExpand": "Expand", "sbbSidebarCloseSidebar": "Close Sidebar", "sbbSidebarOpenSidebar": "Open Sidebar", - "sbbTextareaCounterText": "{$number} characters remaining", + "sbbTextareaCounterText": "{$PH} characters remaining", "sbbUsermenuLogin": "Login", - "sbbUsermenuOpenPanel": "Logged in as {$name}. Click or press enter to open user menu." + "sbbUsermenuOpenPanel": "Logged in as {$PH}. Click or press enter to open user menu." } From 6a7b37dc04b4bc0ed1a3679c07b2fef4a6e54b68 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Mon, 5 Aug 2024 16:44:34 +0200 Subject: [PATCH 031/197] Menu extended with language (selector) (#208) * Menu extended with language (selector) Sidebar language (local) removed * //not supported: anguler/elements * //not supported: anguler/elements * select instead buttons (language selector) * select using the allLocale List * code simplified * code changes clean up * code changes clean up * code changes clean up * code changes clean up * code changes clean up * code changes clean up * nickel * removed - as suggested --- src/app/app.component.html | 19 ++++++++++++++++--- src/app/app.component.scss | 5 +++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/app/app.component.html b/src/app/app.component.html index 29914ac3..9bf4a822 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -11,9 +11,9 @@ {{ 'app.user-manual' | translate }} 🇬🇧 English 🇩🇪 Deutsch @@ -34,6 +34,19 @@ + + 🇬🇧 English + 🇩🇪 Deutsch + + + +

- + {{ 'app.view.editor-side-view.editor-node-detail-view.links' | translate }}
  • diff --git a/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.ts b/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.ts index e00bb395..f78bf9ef 100644 --- a/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.ts +++ b/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.ts @@ -22,6 +22,7 @@ import {LabelService} from "../../../services/data/label.serivce"; import {LabelGroupService} from "../../../services/data/labelgroup.service"; import {SbbChipEvent, SbbChipInputEvent} from "@sbb-esta/angular/chips"; import {COMMA, ENTER} from "@angular/cdk/keycodes"; +import {environment} from "../../../../environments/environment"; interface NodeProperties { nodeId: number; @@ -57,6 +58,8 @@ export class EditorNodeDetailViewComponent implements OnInit, OnDestroy { readonly separatorKeysCodes = [ENTER, COMMA]; nodeLabelsAutoCompleteOptions: string[] = []; + readonly disableBackend = environment.disableBackend; + private destroyed = new Subject(); constructor( From af9f9d7cda86d3dd1d3ad3117f53da4a576d2f0b Mon Sep 17 00:00:00 2001 From: Christian Eichenberger Date: Tue, 6 Aug 2024 11:05:54 +0200 Subject: [PATCH 033/197] Add Manifest Driven release-please. (#214) Signed-off-by: chenkins --- .github/workflows/release-please.yml | 2 -- .release-please-manifest.json | 3 +++ CI.md | 19 +++++++++++++++++++ README.md | 5 +++++ release-please-config.json | 14 ++++++++++++++ 5 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 .release-please-manifest.json create mode 100644 CI.md create mode 100644 release-please-config.json diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 8a7ee217..80731c29 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -15,5 +15,3 @@ jobs: steps: - uses: google-github-actions/release-please-action@v4 id: release - with: - release-type: node diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 00000000..e18ee077 --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "0.0.0" +} diff --git a/CI.md b/CI.md new file mode 100644 index 00000000..2fd67ad0 --- /dev/null +++ b/CI.md @@ -0,0 +1,19 @@ +# Continuous Integration + +This repository uses [release-please](https://github.com/googleapis/release-please) for CHANGELOG generation, the creation of GitHub releases, and version bumps +for your projects. + +It maintains [Release PRs](https://github.com/googleapis/release-please?tab=readme-ov-file#whats-a-release-pr). + +We use [Manifest Driven release-please](https://github.com/googleapis/release-please/blob/main/docs/manifest-releaser.md). +It uses source-controlled files containing + +* releaser specific configuration ([release-please-config.json](release-please-config.json)) +* package version tracking ([.release-please-manifest.json](.release-please-manifest.json)). + +See [release-please CLI documentation](https://github.com/googleapis/release-please/blob/main/docs/cli.md) for more details. + +### FAQ + +* [How do I change the version number?](https://github.com/googleapis/release-please?tab=readme-ov-file#how-do-i-change-the-version-number) + diff --git a/README.md b/README.md index 91d31bba..607aa70e 100644 --- a/README.md +++ b/README.md @@ -263,3 +263,8 @@ Many thanks to all contributors for their engagement and contribution, without w would not have been possible. Thank you for your current and future contribution! [CREDITS.md](CREDITS.md) + +## Continuous Integration + +This repository uses [release-please](https://github.com/googleapis/release-please) for CHANGELOG generation, the creation of GitHub releases, and version bumps for your projects. +See [CI.md](CONTRIBUTING.md) for details. diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 00000000..1603c0b4 --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,14 @@ +{ + "packages": { + ".": { + "changelog-path": "CHANGELOG.md", + "release-type": "node", + "bump-minor-pre-major": false, + "bump-patch-for-minor-pre-major": false, + "draft": false, + "prerelease": false, + "release-as": "2.7.2" + } + }, + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json" +} From 51736578b508132975702e54f8d23741941fe3af Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 11:11:02 +0200 Subject: [PATCH 034/197] chore(main): release netzgrafik-frontend 2.7.2 (#215) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 23 +++++++++++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index e18ee077..fcb5b308 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.0.0" + ".": "2.7.2" } diff --git a/CHANGELOG.md b/CHANGELOG.md index df063ecf..d3503796 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,28 @@ # Changelog +## 2.7.2 (2024-08-06) + + +### Features + +* add AppComponent inputs/outputs ([#166](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/166)) ([9d2c6ee](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/9d2c6eee74f94912b68ec8b3375dc53e21a5ecdc)) +* introduce standalone mode ([#162](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/162)) ([cc4c56b](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/cc4c56b25aa2d978ebd70fbf34dc129f36b776b2)) +* **pr-template:** add pull request template ([89b4d61](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/89b4d61954382c45ffd20ac54137d1faf2f0c5f9)) +* publish package on NPM ([#172](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/172)) ([1692d55](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/1692d5561f8e1fd8b00a60b673b7567d81d83aef)) + + +### Bug Fixes + +* align theme color picker with buttons ([#198](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/198)) ([e3a8798](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/e3a87989ea28a04a4a0bb9cee825825bb1b97d7b)) +* enable output hashing by default ([#174](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/174)) ([8ac67b8](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/8ac67b807db1e0fc418d4bacddabfabcb80620f4)) +* issue I. + typo ([#72](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/72)) ([deb7cd1](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/deb7cd1514a320ca14d53bdd26cdbdeff6005c79)) +* use light theme for sbb-esta ([#176](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/176)) ([89aaae0](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/89aaae004170b59649b0856f14de1d31e86a6e18)) + + +### Miscellaneous Chores + +* release 2.5.0 ([00e6836](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/00e68365b1401d0af211cf6f9cd3184ed61fa102)) + ## 2.7.1 Manually edited version number (preparation automatic release building) diff --git a/package-lock.json b/package-lock.json index 318e47f1..fedb550c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.7.1", + "version": "2.7.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.7.1", + "version": "2.7.2", "dependencies": { "@angular/animations": "^17.0.5", "@angular/cdk": "^17.0.1", diff --git a/package.json b/package.json index f2233e0d..88d8b071 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.7.1", + "version": "2.7.2", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From 930441c7b83210e521cad04d7a3d71b9fe921bc7 Mon Sep 17 00:00:00 2001 From: Louis Greiner <57864277+louisgreiner@users.noreply.github.com> Date: Tue, 6 Aug 2024 13:16:57 +0200 Subject: [PATCH 035/197] refacto trainrun filter service for label uniqueness (#212) * refacto trainrun filter service for label uniqueness * fix error if trainrun is deleted * refactor node filter label uniqueness * fix bug for note label initialization + refactor label uniqueness * remove console log for test --- src/app/services/data/node.service.ts | 16 +++---- src/app/services/data/note.service.ts | 16 +++---- src/app/services/data/trainrun.service.ts | 16 +++---- .../note-filter-tab.component.ts | 34 ++++++++++++++- .../trainrun-filter-tab.component.ts | 42 ++++++++++++------- .../editor-node-detail-view.component.ts | 39 +++++++++++------ 6 files changed, 111 insertions(+), 52 deletions(-) diff --git a/src/app/services/data/node.service.ts b/src/app/services/data/node.service.ts index 1ca7436f..3c2a7177 100644 --- a/src/app/services/data/node.service.ts +++ b/src/app/services/data/node.service.ts @@ -982,17 +982,17 @@ export class NodeService implements OnDestroy { changeLabels(nodeId: number, labels: string[]) { const node = this.getNodeFromId(nodeId); - const labelIds: number[] = []; - labels.forEach((label) => { - labelIds.push( - this.labelService.getOrCreateLabel(label, LabelRef.Node).getId(), - ); - }); - const deletetLabelIds = this.labelService.clearLabel( + + // ensure uniqueness of input labels + const uniqueLabels = Array.from(new Set(labels)); + const labelIds = uniqueLabels.map(label => + this.labelService.getOrCreateLabel(label, LabelRef.Node).getId() + ); + const deletedLabelIds = this.labelService.clearLabel( this.findClearedLabel(node, labelIds), this.makeLabelIDCounterMap(this.getNodes()), ); - this.filterService.clearDeletetFilterNodeLabels(deletetLabelIds); + this.filterService.clearDeletetFilterNodeLabels(deletedLabelIds); node.setLabelIds(labelIds); this.nodesUpdated(); } diff --git a/src/app/services/data/note.service.ts b/src/app/services/data/note.service.ts index e0099c18..786020d8 100644 --- a/src/app/services/data/note.service.ts +++ b/src/app/services/data/note.service.ts @@ -188,17 +188,17 @@ export class NoteService { setLabels(noteId: number, labels: string[]) { const note = this.getNoteFromId(noteId); - const labelIds: number[] = []; - labels.forEach((label) => { - labelIds.push( - this.labelService.getOrCreateLabel(label, LabelRef.Note).getId(), - ); - }); - const deletetLabelIds = this.labelService.clearLabel( + + // ensure uniqueness of input labels + const uniqueLabels = Array.from(new Set(labels)); + const labelIds = uniqueLabels.map(label => + this.labelService.getOrCreateLabel(label, LabelRef.Note).getId() + ); + const deletedLabelIds = this.labelService.clearLabel( this.findClearedLabel(note, labelIds), this.makeLabelIDCounterMap(this.getNotes()), ); - this.filterService.clearDeletetFilterNoteLabels(deletetLabelIds); + this.filterService.clearDeletetFilterNoteLabels(deletedLabelIds); note.setLabelIds(labelIds); this.notesUpdated(); } diff --git a/src/app/services/data/trainrun.service.ts b/src/app/services/data/trainrun.service.ts index 4c104674..03253b07 100644 --- a/src/app/services/data/trainrun.service.ts +++ b/src/app/services/data/trainrun.service.ts @@ -529,17 +529,17 @@ export class TrainrunService { setLabels(trainrunId: number, labels: string[]) { const trainrun = this.getTrainrunFromId(trainrunId); - const labelIds: number[] = []; - labels.forEach((label) => { - labelIds.push( - this.labelService.getOrCreateLabel(label, LabelRef.Trainrun).getId(), - ); - }); - const deletetLabelIds = this.labelService.clearLabel( + + // ensure uniqueness of input labels + const uniqueLabels = Array.from(new Set(labels)); + const labelIds = uniqueLabels.map(label => + this.labelService.getOrCreateLabel(label, LabelRef.Trainrun).getId() + ); + const deletedLabelIds = this.labelService.clearLabel( this.findClearedLabel(trainrun, labelIds), this.makeLabelIDCounterMap(this.getTrainruns()), ); - this.filterService.clearDeletetFilterTrainrunLabels(deletetLabelIds); + this.filterService.clearDeletetFilterTrainrunLabels(deletedLabelIds); trainrun.setLabelIds(labelIds); this.trainrunsUpdated(); } diff --git a/src/app/view/dialogs/note-dialog/note-filter-tab/note-filter-tab.component.ts b/src/app/view/dialogs/note-dialog/note-filter-tab/note-filter-tab.component.ts index 8a0017b3..def2ce54 100644 --- a/src/app/view/dialogs/note-dialog/note-filter-tab/note-filter-tab.component.ts +++ b/src/app/view/dialogs/note-dialog/note-filter-tab/note-filter-tab.component.ts @@ -30,9 +30,11 @@ export class NoteFilterTabComponent implements OnInit, OnDestroy { public note: Note; public noteLabels: string[]; + private initialNoteLabels: string[]; noteLabelsAutoCompleteOptions: string[] = []; readonly separatorKeysCodes = [ENTER, COMMA]; private destroyed = new Subject(); + private isLabelBeingEdited = false; constructor( public dataService: DataService, @@ -47,6 +49,11 @@ export class NoteFilterTabComponent implements OnInit, OnDestroy { this.noteService.notes.pipe(takeUntil(this.destroyed)).subscribe(() => { this.updateNoteLabelsAutoCompleteOptions(); }); + this.noteService.notes + .pipe(takeUntil(this.destroyed)) + .subscribe(() => { + this.initializeWithCurrentNote(); + }); this.updateNoteLabelsAutoCompleteOptions(); } @@ -64,7 +71,9 @@ export class NoteFilterTabComponent implements OnInit, OnDestroy { this.noteLabels = this.noteLabels.filter( (labels) => labels !== valueDelete, ); - this.noteService.setLabels(this.note.getId(), this.noteLabels); + this.isLabelBeingEdited = true; + this.checkAndSetLabels(); + this.isLabelBeingEdited = false; } add(chipInputEvent: SbbChipInputEvent): void { @@ -73,11 +82,15 @@ export class NoteFilterTabComponent implements OnInit, OnDestroy { return; } this.noteLabels.push(value); - this.noteService.setLabels(this.note.getId(), this.noteLabels); + this.isLabelBeingEdited = true; + this.checkAndSetLabels(); + this.isLabelBeingEdited = false; chipInputEvent.chipInput!.clear(); } onLabelsFocusout() { + if (this.isLabelBeingEdited) return; + const keyboardEvent = new KeyboardEvent("keydown", { code: "Enter", key: "Enter", @@ -87,6 +100,7 @@ export class NoteFilterTabComponent implements OnInit, OnDestroy { bubbles: true, }); document.getElementById("noteLabelsInput").dispatchEvent(keyboardEvent); + this.checkAndSetLabels(); } onDeleteNote(): void { @@ -104,16 +118,32 @@ export class NoteFilterTabComponent implements OnInit, OnDestroy { } private initializeWithCurrentNote() { + if (this.note === null) return; this.note = this.noteService.getNoteFromId( this.noteDialogParameter.noteFormComponentModel.id, ); this.noteLabels = this.labelService.getTextLabelsFromIds( this.note.getLabelIds(), ); + this.initialNoteLabels = [...this.noteLabels]; // initialize labels } private updateNoteLabelsAutoCompleteOptions() { this.noteLabelsAutoCompleteOptions = this.getAutoCompleteLabels(); this.cd.detectChanges(); } + + // set labels only if any of it has changed + private checkAndSetLabels() { + if ( + this.noteLabels.length !== this.initialNoteLabels.length || + !this.noteLabels.every((label, index) => label === this.initialNoteLabels[index]) + ) { + this.noteService.setLabels( + this.note.getId(), + this.noteLabels + ); + this.initialNoteLabels = [...this.noteLabels]; + } + } } diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-filter-tab/trainrun-filter-tab.component.ts b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-filter-tab/trainrun-filter-tab.component.ts index d4420711..2c33b994 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-filter-tab/trainrun-filter-tab.component.ts +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-filter-tab/trainrun-filter-tab.component.ts @@ -30,9 +30,11 @@ export class TrainrunFilterTabComponent implements OnInit, OnDestroy { public selectedTrainrun: Trainrun; public trainrunLabels: string[]; + private initialTrainrunLabels: string[]; trainrunLabelsAutoCompleteOptions: string[] = []; readonly separatorKeysCodes = [ENTER, COMMA]; private destroyed = new Subject(); + private isLabelBeingEdited = false; constructor( public dataService: DataService, @@ -76,10 +78,9 @@ export class TrainrunFilterTabComponent implements OnInit, OnDestroy { this.trainrunLabels = this.trainrunLabels.filter( (labels) => labels !== valueDelete, ); - this.trainrunService.setLabels( - this.selectedTrainrun.getId(), - this.trainrunLabels, - ); + this.isLabelBeingEdited = true; + this.checkAndSetLabels(); + this.isLabelBeingEdited = false; } add(inputEvent: SbbChipInputEvent): void { @@ -87,12 +88,10 @@ export class TrainrunFilterTabComponent implements OnInit, OnDestroy { if (!value) { return; } - console.log("add", value); this.trainrunLabels.push(value); - this.trainrunService.setLabels( - this.selectedTrainrun.getId(), - this.trainrunLabels, - ); + this.isLabelBeingEdited = true; + this.checkAndSetLabels(); + this.isLabelBeingEdited = false; inputEvent.chipInput!.clear(); } @@ -121,6 +120,8 @@ export class TrainrunFilterTabComponent implements OnInit, OnDestroy { } onLabelsFocusout() { + if (this.isLabelBeingEdited) return; + const keyboardEvent = new KeyboardEvent("keydown", { code: "Enter", key: "Enter", @@ -130,10 +131,7 @@ export class TrainrunFilterTabComponent implements OnInit, OnDestroy { bubbles: true, }); document.getElementById("trainrunLabelsInput").dispatchEvent(keyboardEvent); - this.trainrunService.setLabels( - this.selectedTrainrun.getId(), - this.trainrunLabels, - ); + this.checkAndSetLabels(); } getAutoCompleteLabels(): string[] { @@ -145,13 +143,29 @@ export class TrainrunFilterTabComponent implements OnInit, OnDestroy { private initializeWithCurrentSelectedTrainrun() { this.selectedTrainrun = this.trainrunService.getSelectedTrainrun(); + if (this.selectedTrainrun === null) return; this.trainrunLabels = this.labelService.getTextLabelsFromIds( this.selectedTrainrun.getLabelIds(), ); + this.initialTrainrunLabels = [...this.trainrunLabels]; // initialize labels } private updateTrainrunLabelsAutoCompleteOptions() { this.trainrunLabelsAutoCompleteOptions = this.getAutoCompleteLabels(); this.cd.detectChanges(); } -} + + // set labels only if any of it has changed + private checkAndSetLabels() { + if ( + this.trainrunLabels.length !== this.initialTrainrunLabels.length || + !this.trainrunLabels.every((label, index) => label === this.initialTrainrunLabels[index]) + ) { + this.trainrunService.setLabels( + this.selectedTrainrun.getId(), + this.trainrunLabels + ); + this.initialTrainrunLabels = [...this.trainrunLabels]; + } + } +} \ No newline at end of file diff --git a/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.ts b/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.ts index e00bb395..2482921d 100644 --- a/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.ts +++ b/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.ts @@ -54,10 +54,13 @@ export class EditorNodeDetailViewComponent implements OnInit, OnDestroy { labels: [], }; + private initialNodeLabels: string[]; + readonly separatorKeysCodes = [ENTER, COMMA]; nodeLabelsAutoCompleteOptions: string[] = []; private destroyed = new Subject(); + private isLabelBeingEdited = false; constructor( private uiInteractionService: UiInteractionService, @@ -117,10 +120,9 @@ export class EditorNodeDetailViewComponent implements OnInit, OnDestroy { return; } this.nodeProperties.labels.push(value); - this.nodeService.changeLabels( - this.nodeProperties.nodeId, - this.nodeProperties.labels, - ); + this.isLabelBeingEdited = true; + this.checkAndSetLabels(); + this.isLabelBeingEdited = false; chipInputEvent.chipInput!.clear(); } @@ -133,13 +135,14 @@ export class EditorNodeDetailViewComponent implements OnInit, OnDestroy { this.nodeProperties.labels = this.nodeProperties.labels.filter( (labels) => labels !== valueDelete, ); - this.nodeService.changeLabels( - this.nodeProperties.nodeId, - this.nodeProperties.labels, - ); + this.isLabelBeingEdited = true; + this.checkAndSetLabels(); + this.isLabelBeingEdited = false; } onLabelsFocusout() { + if (this.isLabelBeingEdited) return; + const keyboardEvent = new KeyboardEvent("keydown", { code: "Enter", key: "Enter", @@ -149,10 +152,7 @@ export class EditorNodeDetailViewComponent implements OnInit, OnDestroy { bubbles: true, }); document.getElementById("nodeLabelsInput").dispatchEvent(keyboardEvent); - this.nodeService.changeLabels( - this.nodeProperties.nodeId, - this.nodeProperties.labels, - ); + this.checkAndSetLabels(); } onCapacityChanged() { @@ -261,6 +261,21 @@ export class EditorNodeDetailViewComponent implements OnInit, OnDestroy { selectedNode.getLabelIds(), ), }; + this.initialNodeLabels = [...this.nodeProperties.labels]; // initialize labels + } + } + + // set labels only if any of it has changed + private checkAndSetLabels() { + if ( + this.nodeProperties.labels.length !== this.initialNodeLabels.length || + !this.nodeProperties.labels.every((label, index) => label === this.initialNodeLabels[index]) + ) { + this.nodeService.changeLabels( + this.nodeProperties.nodeId, + this.nodeProperties.labels + ); + this.initialNodeLabels = [...this.nodeProperties.labels]; } } } From df335ef9aede8c47064655f3dbcc5723c2a89f1a Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 6 Aug 2024 15:08:49 +0200 Subject: [PATCH 036/197] fix: disable notes in filter sidebar in standalone mode (#211) * fix: disable notes in filter sidebar in standalone mode Notes are disabled in standalone mode. * If the backend is turned off, the notes - labels will no longer be displayed in the filter. To keep everything consistent, these labels will also be deactivated in the filter and hidden in the note-edit dialog. --------- Co-authored-by: adrian_egli --- .../note-dialog/note-dialog.component.html | 5 ++++- .../note-dialog/note-dialog.component.ts | 3 +++ .../editor-edit-tools-view.component.html | 2 +- .../editor-edit-tools-view.component.ts | 3 +++ .../editor-filter-view.component.html | 18 ++++++++++-------- .../editor-filter-view.component.ts | 3 +++ 6 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/app/view/dialogs/note-dialog/note-dialog.component.html b/src/app/view/dialogs/note-dialog/note-dialog.component.html index b28b4e05..f7356fa9 100644 --- a/src/app/view/dialogs/note-dialog/note-dialog.component.html +++ b/src/app/view/dialogs/note-dialog/note-dialog.component.html @@ -20,7 +20,10 @@ (noteDeleted)="closeDialog()" > - + (); private deleteNoteCallback = null; private saveNoteCallback = null; diff --git a/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.html b/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.html index 1952d101..baaf2efc 100644 --- a/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.html +++ b/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.html @@ -20,7 +20,7 @@

    {{ 'app.view.editor-edit-tools-view-component.edit' | t > - + {{ 'app.view.editor-edit-tools-view-component.notes' | translate }} (); + readonly disableBackend = environment.disableBackend; + constructor( private dataService: DataService, private nodeService: NodeService, diff --git a/src/app/view/editor-filter-view/editor-filter-view.component.html b/src/app/view/editor-filter-view/editor-filter-view.component.html index 90f4540e..fbf38e94 100644 --- a/src/app/view/editor-filter-view/editor-filter-view.component.html +++ b/src/app/view/editor-filter-view/editor-filter-view.component.html @@ -93,7 +93,7 @@

    {{ 'app.view.editor-filter-view.filter' | translate }}< > - + {{ 'app.view.editor-filter-view.filterable-labels-notes' | translate }} @@ -177,13 +177,15 @@

    {{ 'app.view.editor-filter-view.filter' | translate }}<

-
- {{ 'app.view.editor-filter-view.notes' | translate }} -
- {{ 'app.view.editor-filter-view.display-notes' | translate }} - -
+ +
+ {{ 'app.view.editor-filter-view.notes' | translate }} +
+ {{ 'app.view.editor-filter-view.display-notes' | translate }} + +
+
{{ 'app.view.editor-edit-tools-view-component.delete-all-visible-elements' | translate }} - + {{ 'app.view.editor-edit-tools-view-component.merge-netzgrafik-title' | translate }} diff --git a/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.ts b/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.ts index e1f2bbea..e640a999 100644 --- a/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.ts +++ b/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.ts @@ -16,6 +16,7 @@ import {LabelService} from "../../services/data/label.serivce"; import {LabelGroupService} from "../../services/data/labelgroup.service"; import {LabelGroup} from "../../models/labelGroup.model"; import {environment} from "../../../environments/environment"; +import {VersionControlService} from "../../services/data/version-control.service"; @Component({ selector: "sbb-editor-edit-tools-view-component", @@ -46,6 +47,7 @@ export class EditorEditToolsViewComponent implements OnDestroy { private logger: LogService, public filterService: FilterService, private uiInteractionService: UiInteractionService, + private versionControlService : VersionControlService ) { this.nodeLabelGroups = this.labelGroupService.getLabelGroupsFromLabelRef( LabelRef.Node, @@ -76,6 +78,10 @@ export class EditorEditToolsViewComponent implements OnDestroy { this.destroyed.complete(); } + getVariantIsWritable() { + return this.versionControlService.getVariantIsWritable(); + } + onClearAllFiltered() { const confirmationDialogParamter = new ConfirmationDialogParameter( $localize`:@@app.view.editor-edit-tools-view-component.delete:Delete`, diff --git a/src/app/view/editor-filter-view/editor-filter-view.component.html b/src/app/view/editor-filter-view/editor-filter-view.component.html index fbf38e94..5bb95bd0 100644 --- a/src/app/view/editor-filter-view/editor-filter-view.component.html +++ b/src/app/view/editor-filter-view/editor-filter-view.component.html @@ -198,107 +198,109 @@

{{ 'app.view.editor-filter-view.filter' | translate }}< - - - {{ 'app.view.editor-filter-view.saved-filters' | translate }} - -
- - - + + + + {{ 'app.view.editor-filter-view.saved-filters' | translate }} + +
+ + + - + + + + + + - - - - + + +
- -
- - -
-
+
+
+
diff --git a/src/app/view/editor-filter-view/editor-filter-view.component.ts b/src/app/view/editor-filter-view/editor-filter-view.component.ts index f71c1014..12cf52b1 100644 --- a/src/app/view/editor-filter-view/editor-filter-view.component.ts +++ b/src/app/view/editor-filter-view/editor-filter-view.component.ts @@ -13,6 +13,7 @@ import {FilterSetting} from "../../models/filterSettings.model"; import {takeUntil} from "rxjs/operators"; import {StaticDomTags} from "../editor-main-view/data-views/static.dom.tags"; import {environment} from "../../../environments/environment"; +import {VersionControlService} from "../../services/data/version-control.service"; @Component({ selector: "sbb-editor-filter-view", @@ -45,6 +46,7 @@ export class EditorFilterViewComponent implements OnInit, OnDestroy { public dataService: DataService, public uiInteractionService: UiInteractionService, public filterService: FilterService, + public versionControlService : VersionControlService, ) { this.activeFilterName = undefined; this.activeEditFilterSettingId = undefined; diff --git a/src/app/view/editor-main-view/data-views/d3.utils.spec.ts b/src/app/view/editor-main-view/data-views/d3.utils.spec.ts index 8305516d..35bf64b1 100644 --- a/src/app/view/editor-main-view/data-views/d3.utils.spec.ts +++ b/src/app/view/editor-main-view/data-views/d3.utils.spec.ts @@ -167,7 +167,8 @@ describe("3d.Utils.tests", () => { copyService, logService, viewportCullSerivce, - levelOfDetailService + levelOfDetailService, + undefined ); controller.bindViewToServices(); editorView = controller.editorView; diff --git a/src/app/view/editor-main-view/data-views/data.view.spec.ts b/src/app/view/editor-main-view/data-views/data.view.spec.ts index 4137a1e7..79ae5eaf 100644 --- a/src/app/view/editor-main-view/data-views/data.view.spec.ts +++ b/src/app/view/editor-main-view/data-views/data.view.spec.ts @@ -172,7 +172,8 @@ describe("Editor-DataView", () => { copyService, logService, viewportCullSerivce, - levelOfDetailService + levelOfDetailService, + undefined ); controller.bindViewToServices(); diff --git a/src/app/view/editor-main-view/data-views/editor.keyEvents.ts b/src/app/view/editor-main-view/data-views/editor.keyEvents.ts index f5ad4b65..0629dd36 100644 --- a/src/app/view/editor-main-view/data-views/editor.keyEvents.ts +++ b/src/app/view/editor-main-view/data-views/editor.keyEvents.ts @@ -193,16 +193,26 @@ export class EditorKeyEvents { } private onInsertAllVisibleElementsFromCopyCache(): boolean { + if ( !this.trainrunSectionPreviewLineView.getVariantIsWritable() ) { + return true; + } this.copyService.insertCopiedNetzgrafik(); return false; } private onRevertLastChange(): boolean { + if ( !this.trainrunSectionPreviewLineView.getVariantIsWritable() ) { + return true; + } this.undoService.undo(); return true; } private onDuplicate(): boolean { + if ( !this.trainrunSectionPreviewLineView.getVariantIsWritable() ) { + return true; + } + if (this.doDuplicateTrainrun()) { return true; } @@ -490,6 +500,10 @@ export class EditorKeyEvents { } private onKeyPressedInsert(): boolean { + if ( !this.trainrunSectionPreviewLineView.getVariantIsWritable() ) { + return true; + } + if (this.onDuplicate()) { return true; } @@ -573,6 +587,9 @@ export class EditorKeyEvents { } private onKeyPressedDelete(): boolean { + if ( !this.trainrunSectionPreviewLineView.getVariantIsWritable() ) { + return true; + } const selectedTrainrunSectionId = this.getSelectedTrainSectionId(); const connections = this.nodeSerivce.getAllSelectedConnections(); diff --git a/src/app/view/editor-main-view/data-views/editor.view.ts b/src/app/view/editor-main-view/data-views/editor.view.ts index 659cfb5c..12d2e7c3 100644 --- a/src/app/view/editor-main-view/data-views/editor.view.ts +++ b/src/app/view/editor-main-view/data-views/editor.view.ts @@ -33,6 +33,7 @@ import {CopyService} from "../../../services/data/copy.service"; import {StreckengrafikDrawingContext} from "../../../streckengrafik/model/util/streckengrafik.drawing.context"; import {LevelOfDetail, LevelOfDetailService} from "../../../services/ui/level.of.detail.service"; import {ViewportCullService} from "../../../services/ui/viewport.cull.service"; +import {VersionControlService} from "../../../services/data/version-control.service"; export class EditorView implements SVGMouseControllerObserver { static svgName = "graphContainer"; @@ -128,7 +129,8 @@ export class EditorView implements SVGMouseControllerObserver { private copyService: CopyService, private logService: LogService, private viewportCullService: ViewportCullService, - private levelOfDetailService: LevelOfDetailService + private levelOfDetailService: LevelOfDetailService, + private versionControlService : VersionControlService ) { this.controller = controller; this.svgMouseController = new SVGMouseController(EditorView.svgName, this); @@ -139,6 +141,7 @@ export class EditorView implements SVGMouseControllerObserver { this.trainrunSectionPreviewLineView = new TrainrunSectionPreviewLineView( nodeService, filterService, + versionControlService ); this.multiSelectRenderer = new MultiSelectRenderer(); this.notesView = new NotesView(this); diff --git a/src/app/view/editor-main-view/data-views/nodes.view.scss b/src/app/view/editor-main-view/data-views/nodes.view.scss index 7be45f8e..0dab3138 100644 --- a/src/app/view/editor-main-view/data-views/nodes.view.scss +++ b/src/app/view/editor-main-view/data-views/nodes.view.scss @@ -55,6 +55,14 @@ font-size: $BP_LABEL_FONT_SIZE; } +::ng-deep text.node_text.readonly { + cursor: default; +} + +::ng-deep rect.node_hover_drag_root_background.readonly { + cursor: default; +} + ::ng-deep text.node_text.hover { fill: $COLOR_Edit; } diff --git a/src/app/view/editor-main-view/data-views/nodes.view.spec.ts b/src/app/view/editor-main-view/data-views/nodes.view.spec.ts index 8675ad75..664456bb 100644 --- a/src/app/view/editor-main-view/data-views/nodes.view.spec.ts +++ b/src/app/view/editor-main-view/data-views/nodes.view.spec.ts @@ -167,6 +167,7 @@ describe("Nodes-View", () => { logService, viewportCullSerivce, levelOfDetailService, + undefined ); controller.bindViewToServices(); editorView = controller.editorView; diff --git a/src/app/view/editor-main-view/data-views/nodes.view.ts b/src/app/view/editor-main-view/data-views/nodes.view.ts index fbfea1f6..1f43766b 100644 --- a/src/app/view/editor-main-view/data-views/nodes.view.ts +++ b/src/app/view/editor-main-view/data-views/nodes.view.ts @@ -324,9 +324,10 @@ export class NodesView { } private makeHoverDragBackground(groupEnter: any) { - - groupEnter - .append(StaticDomTags.NODE_HOVER_DRAG_AREA_BACKGROUND_SVG) + const added= + groupEnter + .append(StaticDomTags.NODE_HOVER_DRAG_AREA_BACKGROUND_SVG); + added .attr("class", StaticDomTags.NODE_HOVER_DRAG_AREA_BACKGROUND_CLASS) .classed(StaticDomTags.TAG_SELECTED, (n: NodeViewObject) => n.node.selected(), @@ -340,7 +341,17 @@ export class NodesView { "y", (n: NodeViewObject) => n.node.getNodeHeight() - NODE_TEXT_AREA_HEIGHT, ) - .call(this.draggable) + .classed( + StaticDomTags.NODE_READONLY, + !this.editorView.trainrunSectionPreviewLineView.getVariantIsWritable() + ); + + if ( this.editorView.trainrunSectionPreviewLineView.getVariantIsWritable() ){ + added + .call(this.draggable); + } + + added .on("mouseover", (n: NodeViewObject, i, a) => this.onNodeMouseoverDragButton(n.node, a[i]), ) @@ -352,7 +363,9 @@ export class NodesView { } private makeHoverDragRoot(groupEnter: any) { - + if ( !this.editorView.trainrunSectionPreviewLineView.getVariantIsWritable() ){ + return; + } groupEnter .append(StaticDomTags.NODE_HOVER_DRAG_AREA_SVG) .attr("class", StaticDomTags.NODE_HOVER_DRAG_AREA_CLASS) @@ -561,9 +574,9 @@ export class NodesView { } private makeLabelText(groupEnter: any) { - - groupEnter - .append(StaticDomTags.NODE_LABELAREA_TEXT_SVG) + const added = groupEnter + .append(StaticDomTags.NODE_LABELAREA_TEXT_SVG); + added .attr("class", StaticDomTags.NODE_LABELAREA_TEXT_CLASS) .attr(StaticDomTags.NODE_ID, (n: NodeViewObject) => n.node.getId()) .attr("x", NODE_TEXT_LEFT_SPACING) @@ -576,6 +589,16 @@ export class NodesView { StaticDomTags.NODE_HAS_CONNECTIONS, (n: NodeViewObject) => n.node.getConnections().length > 0, ) + .classed( + StaticDomTags.NODE_READONLY, + !this.editorView.trainrunSectionPreviewLineView.getVariantIsWritable() + ); + + if ( !this.editorView.trainrunSectionPreviewLineView.getVariantIsWritable() ){ + return; + } + + added .call(this.draggable) .on("mouseover", (n: NodeViewObject, i, a) => this.onNodeLabelAreaMouseover(n.node, a[i]), diff --git a/src/app/view/editor-main-view/data-views/notes.view.spec.ts b/src/app/view/editor-main-view/data-views/notes.view.spec.ts index 281e3f30..882e579e 100644 --- a/src/app/view/editor-main-view/data-views/notes.view.spec.ts +++ b/src/app/view/editor-main-view/data-views/notes.view.spec.ts @@ -166,7 +166,8 @@ describe("Notes-View", () => { copyService, logService, viewportCullSerivce, - levelOfDetailService + levelOfDetailService, + undefined ); controller.bindViewToServices(); editorView = controller.editorView; diff --git a/src/app/view/editor-main-view/data-views/notes.view.ts b/src/app/view/editor-main-view/data-views/notes.view.ts index 0cc47553..4e0dd6d5 100644 --- a/src/app/view/editor-main-view/data-views/notes.view.ts +++ b/src/app/view/editor-main-view/data-views/notes.view.ts @@ -227,9 +227,9 @@ export class NotesView { } private makeNoteHoverRoot(groupEnter: any) { - - groupEnter - .append(StaticDomTags.NOTE_HOVER_ROOT_SVG) + const added = groupEnter + .append(StaticDomTags.NOTE_HOVER_ROOT_SVG); + added .attr("class", StaticDomTags.NOTE_HOVER_ROOT_CLASS) .attr(StaticDomTags.NOTE_ID, (n: NoteViewObject) => n.note.getId()) .attr( @@ -241,7 +241,13 @@ export class NotesView { (n: NoteViewObject) => NotesView.extractTextBasedHeight(n.note) + 48, ) .attr("x", -24) - .attr("y", -24) + .attr("y", -24); + + if ( !this.editorView.trainrunSectionPreviewLineView.getVariantIsWritable() ){ + return; + } + + added .call(this.draggable) .on("mouseout", (n: NoteViewObject) => this.onNoteMouseout(n.note, null)) .on("mouseover", (n: NoteViewObject, i, a) => @@ -377,8 +383,10 @@ export class NotesView { private makeNoteDragAreaBackground(groupEnter: any) { - groupEnter - .append(StaticDomTags.NOTE_HOVER_DRAG_AREA_BACKGROUND_SVG) + const added = groupEnter + .append(StaticDomTags.NOTE_HOVER_DRAG_AREA_BACKGROUND_SVG); + + added .attr("class", StaticDomTags.NOTE_HOVER_DRAG_AREA_BACKGROUND_CLASS) .classed(StaticDomTags.TAG_SELECTED, (n: NoteViewObject) => n.note.selected(), @@ -388,7 +396,13 @@ export class NotesView { .attr("width", 28) .attr("height", 28) .attr("x", 0) - .attr("y", 0) + .attr("y", 0); + + if ( !this.editorView.trainrunSectionPreviewLineView.getVariantIsWritable() ){ + return; + } + + added .on("mouseout", (n: NoteViewObject) => this.onNoteMouseoutDragButton(n.note, null), ) @@ -399,7 +413,9 @@ export class NotesView { } private makeNoteDragArea(groupEnter: any) { - + if ( !this.editorView.trainrunSectionPreviewLineView.getVariantIsWritable() ){ + return; + } groupEnter .append(StaticDomTags.NOTE_HOVER_DRAG_AREA_SVG) .attr("class", StaticDomTags.NOTE_HOVER_DRAG_AREA_CLASS) @@ -427,6 +443,11 @@ export class NotesView { } onNoteMousedown(note: Note) { + if ( !this.editorView.trainrunSectionPreviewLineView.getVariantIsWritable() ){ + d3.event.stopPropagation(); + return; + } + if (this.editorView.editorMode === EditorMode.MultiNodeMoving) { const multiSelected = this.editorView.isNoteSelected(note.getId()); if (multiSelected) { @@ -439,6 +460,11 @@ export class NotesView { } onNoteMouseup(note: Note, domObj: any) { + if ( !this.editorView.trainrunSectionPreviewLineView.getVariantIsWritable() ){ + d3.event.stopPropagation(); + return; + } + const rect: DOMRect = d3.select(domObj).node().getBoundingClientRect(); const clickPosition = new Vec2D( rect.x + rect.width / 2, diff --git a/src/app/view/editor-main-view/data-views/static.dom.tags.ts b/src/app/view/editor-main-view/data-views/static.dom.tags.ts index 35ea7546..c3e19c57 100644 --- a/src/app/view/editor-main-view/data-views/static.dom.tags.ts +++ b/src/app/view/editor-main-view/data-views/static.dom.tags.ts @@ -77,6 +77,7 @@ export class StaticDomTags { static NODE_TAG_REQ_FOR_DRAGGING = "req_for_dragging"; static NODE_TAG_JUNCTION_ONLY = "junction_only"; static NODE_HAS_CONNECTIONS = "has_connections"; + static NODE_READONLY = "readonly"; static NODE_HOVER_ROOT_SVG = "rect"; static NODE_HOVER_ROOT_CLASS = "node_hover_root"; diff --git a/src/app/view/editor-main-view/data-views/trainrunsection.previewline.view.ts b/src/app/view/editor-main-view/data-views/trainrunsection.previewline.view.ts index 4eaab377..d51f7353 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsection.previewline.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsection.previewline.view.ts @@ -8,6 +8,7 @@ import {Transition} from "../../../models/transition.model"; import {SimpleTrainrunSectionRouter} from "../../../services/util/trainrunsection.routing"; import {NodeService} from "../../../services/data/node.service"; import {FilterService} from "../../../services/ui/filter.service"; +import {VersionControlService} from "../../../services/data/version-control.service"; export enum PreviewLineMode { NotDragging, @@ -55,6 +56,7 @@ export class TrainrunSectionPreviewLineView { constructor( private nodeService: NodeService, private filterService: FilterService, + private versionControlService : VersionControlService ) {} static setGroup(nodeGroup: d3.Selector) { @@ -69,6 +71,13 @@ export class TrainrunSectionPreviewLineView { .attr("class", StaticDomTags.PREVIEW_CONNECTION_LINE_ROOT_CLASS); } + getVariantIsWritable() : boolean { + if ( !this.versionControlService?.getVariantIsWritable()){ + return false; + } + return true; + } + getMode(): PreviewLineMode { return this.mode; } @@ -93,6 +102,9 @@ export class TrainrunSectionPreviewLineView { dragIntermediateStopInfo: DragIntermediateStopInfo, startPosition: Vec2D, ) { + if ( !this.versionControlService?.getVariantIsWritable()){ + return; + } this.mode = PreviewLineMode.DragIntermediateStop; this.dragIntermediateStopInfo = dragIntermediateStopInfo; this.startIntermediatePos = startPosition; @@ -105,6 +117,9 @@ export class TrainrunSectionPreviewLineView { dragTransition: DragTransitionInfo, startPosition: Vec2D, ) { + if ( !this.versionControlService?.getVariantIsWritable()){ + return; + } this.filterService.switchOffTemporaryEmptyAndNonStopFiltering(); this.mode = PreviewLineMode.DragTransition; this.dragTransitionInfo = dragTransition; @@ -143,6 +158,9 @@ export class TrainrunSectionPreviewLineView { } startPreviewLine(nodeId: number) { + if ( !this.versionControlService?.getVariantIsWritable()){ + return; + } this.mode = PreviewLineMode.DragNewTrainrunSection; const mousePosition = d3.mouse( d3.select(StaticDomTags.PREVIEW_LINE_ROOT_DOM_REF).node(), @@ -153,6 +171,9 @@ export class TrainrunSectionPreviewLineView { } startPreviewLineAtPosition(startNode: Node, startPosition: Vec2D) { + if ( !this.versionControlService?.getVariantIsWritable()){ + return; + } this.mode = PreviewLineMode.DragExistingTrainrunSection; this.startNode = startNode; this.startPos = startPosition; diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts index 7f6cd843..5c4befa2 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts @@ -171,7 +171,8 @@ describe("TrainrunSection-View", () => { copyService, logService, viewportCullSerivce, - levelOfDetailService + levelOfDetailService, + undefined ); controller.bindViewToServices(); diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 99d9ddeb..0232ec33 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -1221,7 +1221,9 @@ export class TrainrunSectionsView { connectedTrainIds: any, atSource: boolean, ) { - + if (!this.editorView.trainrunSectionPreviewLineView.getVariantIsWritable()){ + return; + } groupEnter .append(StaticDomTags.EDGE_LINE_PIN_SVG) .attr("class", StaticDomTags.EDGE_LINE_PIN_CLASS) diff --git a/src/app/view/editor-main-view/data-views/transitions.view.spec.ts b/src/app/view/editor-main-view/data-views/transitions.view.spec.ts index 302cfd11..9a168d30 100644 --- a/src/app/view/editor-main-view/data-views/transitions.view.spec.ts +++ b/src/app/view/editor-main-view/data-views/transitions.view.spec.ts @@ -167,7 +167,8 @@ describe("Transitions-View", () => { copyService, logService, viewportCullSerivce, - levelOfDetailService + levelOfDetailService, + undefined ); controller.bindViewToServices(); diff --git a/src/app/view/editor-main-view/data-views/transitions.view.ts b/src/app/view/editor-main-view/data-views/transitions.view.ts index 8a6f166a..4788acc6 100644 --- a/src/app/view/editor-main-view/data-views/transitions.view.ts +++ b/src/app/view/editor-main-view/data-views/transitions.view.ts @@ -151,6 +151,9 @@ export class TransitionsView { selectedTrainrun: Trainrun, connectedTrainIds: any, ) { + if (!this.editorView.trainrunSectionPreviewLineView.getVariantIsWritable()){ + return; + } grpEnter .append(StaticDomTags.TRANSITION_BUTTON_SVG) .attr( diff --git a/src/app/view/editor-main-view/editor-main-view.component.ts b/src/app/view/editor-main-view/editor-main-view.component.ts index 365192af..1e3caa73 100644 --- a/src/app/view/editor-main-view/editor-main-view.component.ts +++ b/src/app/view/editor-main-view/editor-main-view.component.ts @@ -91,7 +91,8 @@ export class EditorMainViewComponent implements AfterViewInit, OnDestroy { copyService, logService, viewportCullSerivce, - levelOfDetailService + levelOfDetailService, + versionControlService ); this.uiInteractionService.zoomInObservable .pipe(takeUntil(this.destroyed)) diff --git a/src/app/view/editor-menu/editor-menu.component.html b/src/app/view/editor-menu/editor-menu.component.html index dfed58c5..7ca57c1b 100644 --- a/src/app/view/editor-menu/editor-menu.component.html +++ b/src/app/view/editor-menu/editor-menu.component.html @@ -142,7 +142,8 @@ [class.isStreckengrafikEditing]=" isStreckengrafikEditing() || isAnalytics() " - [disabled]="isStreckengrafikEditing() || isAnalytics()" + [class.readonly]="isStreckengrafikEditing() || isAnalytics() || !getVariantIsWritable()" + [disabled]="isStreckengrafikEditing() || isAnalytics() || !getVariantIsWritable()" (click)="onTopologieEditor()" [title]="'app.view.editor-menu.topology-editor-disabled' | translate" > @@ -242,7 +243,8 @@ [class.isStreckengrafikEditing]=" isStreckengrafikEditing() || isAnalytics() " - [disabled]="isStreckengrafikEditing() || isAnalytics()" + [class.readonly]="!getVariantIsWritable()" + [disabled]="isStreckengrafikEditing() || isAnalytics() || !getVariantIsWritable()" (click)="onNoteEditor()" [title]="'app.view.editor-menu.note-editor-disabled' | translate" > diff --git a/src/app/view/editor-menu/editor-menu.component.scss b/src/app/view/editor-menu/editor-menu.component.scss index a7d5436e..646e5197 100644 --- a/src/app/view/editor-menu/editor-menu.component.scss +++ b/src/app/view/editor-menu/editor-menu.component.scss @@ -87,52 +87,6 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; } } -.ButtonSave { - width: $EDITOR_MENU_BUTTON_SIZE; - height: $INSIDE_OBJECT_HEIGHT; - min-width: $EDITOR_MENU_BUTTON_SIZE; - max-width: $EDITOR_MENU_BUTTON_SIZE; - text-align: center; - font-size: 25px; - padding: 8px 0 0 0; - margin: 0; - outline: none; - border: none; -} - -.ButtonSave:hover { - border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); -} - -.ButtonSave:active { - border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-default); -} - -.ButtonLoad > input { - display: none; -} - -.ButtonLoad { - width: $EDITOR_MENU_BUTTON_SIZE; - height: $INSIDE_OBJECT_HEIGHT; - min-width: $EDITOR_MENU_BUTTON_SIZE; - max-width: $EDITOR_MENU_BUTTON_SIZE; - text-align: center; - font-size: 25px; - padding: 8px 0 0 0; - margin: 0; - outline: none; - border: none; -} - -.ButtonLoad:hover { - border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-hover); -} - -.ButtonLoad:active { - border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-default); -} - .ButtonFilter { width: $EDITOR_MENU_BUTTON_SIZE; height: $INSIDE_OBJECT_HEIGHT; @@ -254,6 +208,7 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; } .ButtonTopologieEditor.TopologyEditing { + border-bottom: 3px solid $COLOR_TOPO_EDITOR_ACTIVE; color: $COLOR_TOPO_EDITOR_ACTIVE; } @@ -294,6 +249,7 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; } .ButtonNoteEditor.NoteEditing { + border-bottom: 3px solid $COLOR_TOPO_EDITOR_ACTIVE; color: $COLOR_TOPO_EDITOR_ACTIVE; } @@ -344,6 +300,7 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; } .ButtonStreckengrafikEditor.StreckengrafikEditing { + border-bottom: 3px solid $COLOR_TOPO_EDITOR_ACTIVE; color: $COLOR_TOPO_EDITOR_ACTIVE; } @@ -394,7 +351,7 @@ $COLOR_TOPO_EDITOR_ACTIVE: #eb0000; } .ButtonMultiNodeMoving.MultiNodeMoving { - border-bottom: 3px solid var(--sbb-primary-alternative-button-background-color-default); + border-bottom: 3px solid $COLOR_TOPO_EDITOR_ACTIVE; color: $COLOR_TOPO_EDITOR_ACTIVE; } @@ -411,10 +368,6 @@ path.ButtonMultiNodeMoving { fill: currentColor; } -path.ButtonMultiNodeMoving.disabled { -} - - .ButtonAnalytics { width: $EDITOR_MENU_BUTTON_SIZE; height: $INSIDE_OBJECT_HEIGHT; @@ -442,6 +395,7 @@ path.ButtonMultiNodeMoving.disabled { } .ButtonAnalytics.ButtonAnalyticsActive { + border-bottom: 3px solid $COLOR_TOPO_EDITOR_ACTIVE; color: $COLOR_TOPO_EDITOR_ACTIVE; } @@ -510,3 +464,54 @@ div.LabelNetzgrafik{ div.NodeZoomValue{ background: var(--sbb-header-lean-background-color); } + +button.ButtonTopologieEditor.readonly { + fill-opacity: 0.35; +} + +button.ButtonNoteEditor.readonly { + fill-opacity: 0.35; +} + +button.ButtonTopologieEditor.readonly:hover { + border-bottom: 0 solid var(--sbb-header-lean-background-color); +} + +button.ButtonNoteEditor.readonly:hover { + border-bottom: 0 solid var(--sbb-header-lean-background-color); +} + +.ButtonTopologieEditor.NetzgrafikEditing.isStreckengrafikEditing.readonly { + border-bottom: 0 solid var(--sbb-header-lean-background-color); +} + +.ButtonStreckengrafikEditor.NetzgrafikEditing.isNotStreckengrafikAllowed:hover { + border-bottom: 0 solid var(--sbb-header-lean-background-color); +} + +.ButtonMultiNodeMoving.NetzgrafikEditing.isStreckengrafikEditing { + fill-opacity: 0.35; + border-bottom: 0 solid var(--sbb-header-lean-background-color); +} + +.ButtonNoteEditor.NetzgrafikEditing.isStreckengrafikEditing { + fill-opacity: 0.35; + border-bottom: 0 solid var(--sbb-header-lean-background-color); +} + +.ButtonMultiNodeMoving.NetzgrafikEditing.isStreckengrafikEditing:hover { + border-bottom: 0 solid var(--sbb-header-lean-background-color); +} + +.ButtonNoteEditor.NetzgrafikEditing.isStreckengrafikEditing:hover { + border-bottom: 0 solid var(--sbb-header-lean-background-color); +} + +.ButtonAnalytics.isStreckengrafikEditing { + fill-opacity: 0.35; + border-bottom: 0 solid var(--sbb-header-lean-background-color); +} + +.ButtonAnalytics.isStreckengrafikEditing:hover { + border-bottom: 0 solid var(--sbb-header-lean-background-color); +} diff --git a/src/app/view/editor-menu/editor-menu.component.ts b/src/app/view/editor-menu/editor-menu.component.ts index 497ac174..c5532ebe 100644 --- a/src/app/view/editor-menu/editor-menu.component.ts +++ b/src/app/view/editor-menu/editor-menu.component.ts @@ -100,6 +100,10 @@ export class EditorMenuComponent implements OnInit, OnDestroy { this.destroyed.complete(); } + getVariantIsWritable() : boolean { + return this.versionControlService.getVariantIsWritable(); + } + onZoomIn() { if ( this.uiInteractionService.getEditorMode() === diff --git a/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.html b/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.html index 3cc0681f..d90ce735 100644 --- a/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.html +++ b/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.html @@ -6,21 +6,30 @@

{{ 'app.view.editor-side-view.editor-node-detail-view.base-data' | translate }} - + - + - +
- + {{ 'app.view.editor-side-view.editor-node-detail-view.filterable-labels' | translate }} - + - +
{{ 'app.view.editor-side-view.editor-node-detail-view.ipv' | translate }} @@ -300,12 +317,14 @@

- + + + diff --git a/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.scss b/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.scss index 2e851d09..95497863 100644 --- a/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.scss +++ b/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.scss @@ -61,3 +61,13 @@ } } } + +sbb-form-field.readonly { + pointer-events: none; + cursor: default; +} + +table.NodeDataTable.readonly { + pointer-events: none; + cursor: default; +} diff --git a/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.ts b/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.ts index ea68518e..1ac22d36 100644 --- a/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.ts +++ b/src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.ts @@ -23,6 +23,7 @@ import {LabelGroupService} from "../../../services/data/labelgroup.service"; import {SbbChipEvent, SbbChipInputEvent} from "@sbb-esta/angular/chips"; import {COMMA, ENTER} from "@angular/cdk/keycodes"; import {environment} from "../../../../environments/environment"; +import {VersionControlService} from "../../../services/data/version-control.service"; interface NodeProperties { nodeId: number; @@ -71,6 +72,7 @@ export class EditorNodeDetailViewComponent implements OnInit, OnDestroy { private nodeService: NodeService, private labelService: LabelService, private labelGroupService: LabelGroupService, + public versionControlService : VersionControlService, private cd: ChangeDetectorRef, ) {} diff --git a/src/app/view/editor-tools-view-component/editor-tools-view.component.html b/src/app/view/editor-tools-view-component/editor-tools-view.component.html index 2b9fd681..fde30347 100644 --- a/src/app/view/editor-tools-view-component/editor-tools-view.component.html +++ b/src/app/view/editor-tools-view-component/editor-tools-view.component.html @@ -40,22 +40,25 @@

{{ 'app.view.editor-side-view.editor-tools-view-compone {{ 'app.view.editor-side-view.editor-tools-view-component.export-netzgrafik-as-json' | translate }} -
- - - {{ 'app.view.editor-side-view.editor-tools-view-component.import-netzgrafik-as-json' | translate }} + +
+ + + {{ 'app.view.editor-side-view.editor-tools-view-component.import-netzgrafik-as-json' | translate }} +
+
- {{ 'app.view.editor-side-view.editor-tools-view-component.import-base-data' | translate }} - {{ 'app.view.editor-side-view.editor-tools-view-component.help-csv-data' | translate }} - -
+ + + {{ 'app.view.editor-side-view.editor-tools-view-component.import-base-data' | translate }} + {{ 'app.view.editor-side-view.editor-tools-view-component.help-csv-data' | translate }} + +
+
diff --git a/src/app/view/variant/variants-view/variants-view.component.ts b/src/app/view/variant/variants-view/variants-view.component.ts index a744f1c5..9218b15a 100644 --- a/src/app/view/variant/variants-view/variants-view.component.ts +++ b/src/app/view/variant/variants-view/variants-view.component.ts @@ -166,6 +166,10 @@ export class VariantsViewComponent implements OnDestroy { } getVariantDataActions(variant: VariantSummaryDto): Observable { + if (this.project.isArchived) { + return undefined; + } + if (variant.isArchived) { return of([ { diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index d0d4de3e..0831f58c 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -272,7 +272,7 @@ }, "editor-edit-tools-view-component": { "edit": "Bearbeiten", - "filterable-labels": "Filterbare labels", + "filterable-labels": "Filterbare Labels", "trainruns": "Zugfahrten", "nodes": "Knoten", "notes": "Kommentare", @@ -443,7 +443,7 @@ "import-netzgrafik": "Netzgrafik importieren", "import-netzgrafik-as-json": "Netzgrafik aus JSON importieren", "export-trainruns": "Zugfahrten exportieren", - "export-trainruns-as-csv": "Netzgrafik aus JSON importieren", + "export-trainruns-as-csv": "Zugfahrten als CSV exportieren", "export-trainruns-as-csv-excel": "In Excel: Daten -> Aus Text/CSV -> Filename ... importieren", "base-data": "Stammdaten", "import-base-data": "Stammdaten importieren", @@ -590,7 +590,6 @@ "archived": "(archiviert)", "edit-variant": "Variante bearbeiten", "delete-variant": { - "_value": "Variante löschen", "title": "Variante löschen", "content": "Möchten Sie die Variante und alle enthaltenen Versionen endgültig löschen? Diese Aktion kann nicht rückgängig gemacht werden." }, @@ -604,13 +603,11 @@ "project-description": "Projekt Beschreibung", "edit-project": "Projekt bearbeiten", "archive-project": { - "_value": "Projekt archivieren", "title": "Projekt archivieren", "content": "Möchten Sie das Projekt jetzt archivieren?" }, "undo-archiving": "Archivierung rückgängig machen", "delete-project": { - "_value": "Projekt löschen", "title": "Projekt löschen", "content": "Möchten Sie das Projekt und alle enthaltenen Varianten endgültig löschen? Diese Aktion kann nicht rückgängig gemacht werden." }, diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 98ac66ce..04cbf5dc 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -590,7 +590,6 @@ "archived": "(archived)", "edit-variant": "Edit variant", "delete-variant": { - "_value": "Delete variant", "title": "Delete variant", "content": "Do you want to permanently delete the variant and all versions it contains? This action cannot be undone." }, @@ -604,13 +603,11 @@ "project-description": "Project description", "edit-project": "Edit project", "archive-project": { - "_value": "Archive project", "title": "Archive project", "content": "Would you like to archive the project now?" }, "undo-archiving": "Undo archiving", "delete-project": { - "_value": "Delete project", "title": "Delete projekt", "content": "Do you want to permanently delete the project and all the variants it contains? This action cannot be undone." }, diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index 98ac66ce..04cbf5dc 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -590,7 +590,6 @@ "archived": "(archived)", "edit-variant": "Edit variant", "delete-variant": { - "_value": "Delete variant", "title": "Delete variant", "content": "Do you want to permanently delete the variant and all versions it contains? This action cannot be undone." }, @@ -604,13 +603,11 @@ "project-description": "Project description", "edit-project": "Edit project", "archive-project": { - "_value": "Archive project", "title": "Archive project", "content": "Would you like to archive the project now?" }, "undo-archiving": "Undo archiving", "delete-project": { - "_value": "Delete project", "title": "Delete projekt", "content": "Do you want to permanently delete the project and all the variants it contains? This action cannot be undone." }, diff --git a/src/assets/i18n/it.json b/src/assets/i18n/it.json index 98ac66ce..04cbf5dc 100644 --- a/src/assets/i18n/it.json +++ b/src/assets/i18n/it.json @@ -590,7 +590,6 @@ "archived": "(archived)", "edit-variant": "Edit variant", "delete-variant": { - "_value": "Delete variant", "title": "Delete variant", "content": "Do you want to permanently delete the variant and all versions it contains? This action cannot be undone." }, @@ -604,13 +603,11 @@ "project-description": "Project description", "edit-project": "Edit project", "archive-project": { - "_value": "Archive project", "title": "Archive project", "content": "Would you like to archive the project now?" }, "undo-archiving": "Undo archiving", "delete-project": { - "_value": "Delete project", "title": "Delete projekt", "content": "Do you want to permanently delete the project and all the variants it contains? This action cannot be undone." }, From e46e68490eab4dd16e8f116d034419e5378c1612 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 14:02:44 +0200 Subject: [PATCH 085/197] chore(main): release netzgrafik-frontend 2.7.13 (#275) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 58017253..8bc18390 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.7.12" + ".": "2.7.13" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c756438..fe8beee6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.7.13](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.7.12...netzgrafik-frontend-v2.7.13) (2024-08-29) + + +### Bug Fixes + +* Bug archived read only mode variants are editable even tho not persisted ([#257](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/257)) ([9472a89](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/9472a89c445e3473877e7fe80add5f5e3cc37863)) + ## [2.7.12](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.7.11...netzgrafik-frontend-v2.7.12) (2024-08-29) diff --git a/package-lock.json b/package-lock.json index 18b8b7b5..b3f5bdcc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.7.12", + "version": "2.7.13", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.7.12", + "version": "2.7.13", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index d64c602b..254425e9 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.7.12", + "version": "2.7.13", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From 57cf61519c81fb93890ab22fac857d9f00ead350 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 29 Aug 2024 23:48:34 +0200 Subject: [PATCH 086/197] Demo file added --- src/app/sample-netzgrafik/Demo_Netzgrafik_Fernverkehr_2024.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/app/sample-netzgrafik/Demo_Netzgrafik_Fernverkehr_2024.json diff --git a/src/app/sample-netzgrafik/Demo_Netzgrafik_Fernverkehr_2024.json b/src/app/sample-netzgrafik/Demo_Netzgrafik_Fernverkehr_2024.json new file mode 100644 index 00000000..2d657582 --- /dev/null +++ b/src/app/sample-netzgrafik/Demo_Netzgrafik_Fernverkehr_2024.json @@ -0,0 +1 @@ +{"nodes":[{"id":128,"betriebspunktName":"Lausanne","fullName":"Lausanne","positionX":-3072,"positionY":544,"ports":[{"id":1207,"trainrunSectionId":596,"positionIndex":0,"positionAlignment":2},{"id":1187,"trainrunSectionId":586,"positionIndex":1,"positionAlignment":2},{"id":1382,"trainrunSectionId":683,"positionIndex":0,"positionAlignment":3},{"id":1380,"trainrunSectionId":682,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":345,"port1Id":1187,"port2Id":1380,"isNonStopTransit":false},{"id":347,"port1Id":1207,"port2Id":1382,"isNonStopTransit":false}],"connections":[],"resourceId":152,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":129,"betriebspunktName":"Bern","fullName":"Bern","positionX":-2144,"positionY":128,"ports":[{"id":1328,"trainrunSectionId":656,"positionIndex":0,"positionAlignment":1},{"id":1311,"trainrunSectionId":648,"positionIndex":1,"positionAlignment":1},{"id":1313,"trainrunSectionId":649,"positionIndex":2,"positionAlignment":1},{"id":1339,"trainrunSectionId":662,"positionIndex":3,"positionAlignment":1},{"id":1205,"trainrunSectionId":595,"positionIndex":0,"positionAlignment":2},{"id":1109,"trainrunSectionId":547,"positionIndex":1,"positionAlignment":2},{"id":1440,"trainrunSectionId":712,"positionIndex":0,"positionAlignment":3},{"id":1329,"trainrunSectionId":657,"positionIndex":1,"positionAlignment":3},{"id":1436,"trainrunSectionId":710,"positionIndex":2,"positionAlignment":3},{"id":1434,"trainrunSectionId":709,"positionIndex":3,"positionAlignment":3},{"id":1432,"trainrunSectionId":708,"positionIndex":4,"positionAlignment":3},{"id":1430,"trainrunSectionId":707,"positionIndex":5,"positionAlignment":3},{"id":1428,"trainrunSectionId":706,"positionIndex":6,"positionAlignment":3}],"transitions":[{"id":315,"port1Id":1328,"port2Id":1329,"isNonStopTransit":false},{"id":376,"port1Id":1109,"port2Id":1430,"isNonStopTransit":false},{"id":378,"port1Id":1339,"port2Id":1432,"isNonStopTransit":false},{"id":380,"port1Id":1313,"port2Id":1434,"isNonStopTransit":false},{"id":382,"port1Id":1311,"port2Id":1436,"isNonStopTransit":false},{"id":386,"port1Id":1205,"port2Id":1440,"isNonStopTransit":false}],"connections":[],"resourceId":153,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":130,"betriebspunktName":"Biel","fullName":"Biel","positionX":-2528,"positionY":-32,"ports":[{"id":1183,"trainrunSectionId":584,"positionIndex":0,"positionAlignment":2},{"id":1418,"trainrunSectionId":701,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":366,"port1Id":1183,"port2Id":1418,"isNonStopTransit":false}],"connections":[],"resourceId":154,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":131,"betriebspunktName":"Interlaken ","fullName":"Interlaken Ost","positionX":-1088,"positionY":928,"ports":[{"id":1318,"trainrunSectionId":651,"positionIndex":0,"positionAlignment":2},{"id":1344,"trainrunSectionId":664,"positionIndex":1,"positionAlignment":2}],"transitions":[],"connections":[],"resourceId":155,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":132,"betriebspunktName":"Visp","fullName":"Visp","positionX":-2144,"positionY":1440,"ports":[{"id":1323,"trainrunSectionId":654,"positionIndex":0,"positionAlignment":0},{"id":1322,"trainrunSectionId":653,"positionIndex":1,"positionAlignment":0}],"transitions":[],"connections":[],"resourceId":156,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":133,"betriebspunktName":"Olten","fullName":"Olten","positionX":64,"positionY":96,"ports":[{"id":1047,"trainrunSectionId":516,"positionIndex":0,"positionAlignment":0},{"id":1331,"trainrunSectionId":658,"positionIndex":1,"positionAlignment":0},{"id":1308,"trainrunSectionId":646,"positionIndex":2,"positionAlignment":0},{"id":1371,"trainrunSectionId":678,"positionIndex":3,"positionAlignment":0},{"id":1131,"trainrunSectionId":558,"positionIndex":4,"positionAlignment":0},{"id":1117,"trainrunSectionId":551,"positionIndex":5,"positionAlignment":0},{"id":1046,"trainrunSectionId":515,"positionIndex":0,"positionAlignment":1},{"id":1370,"trainrunSectionId":677,"positionIndex":1,"positionAlignment":1},{"id":1130,"trainrunSectionId":557,"positionIndex":2,"positionAlignment":1},{"id":1116,"trainrunSectionId":550,"positionIndex":3,"positionAlignment":1},{"id":1181,"trainrunSectionId":583,"positionIndex":0,"positionAlignment":2},{"id":1203,"trainrunSectionId":594,"positionIndex":1,"positionAlignment":2},{"id":1394,"trainrunSectionId":689,"positionIndex":2,"positionAlignment":2},{"id":1309,"trainrunSectionId":647,"positionIndex":3,"positionAlignment":2},{"id":1225,"trainrunSectionId":605,"positionIndex":4,"positionAlignment":2},{"id":1241,"trainrunSectionId":613,"positionIndex":5,"positionAlignment":2},{"id":1165,"trainrunSectionId":575,"positionIndex":6,"positionAlignment":2},{"id":1202,"trainrunSectionId":593,"positionIndex":0,"positionAlignment":3},{"id":1180,"trainrunSectionId":582,"positionIndex":1,"positionAlignment":3},{"id":1224,"trainrunSectionId":604,"positionIndex":2,"positionAlignment":3},{"id":1240,"trainrunSectionId":612,"positionIndex":3,"positionAlignment":3},{"id":1164,"trainrunSectionId":574,"positionIndex":4,"positionAlignment":3}],"transitions":[{"id":210,"port1Id":1047,"port2Id":1046,"isNonStopTransit":false},{"id":236,"port1Id":1117,"port2Id":1116,"isNonStopTransit":false},{"id":242,"port1Id":1131,"port2Id":1130,"isNonStopTransit":false},{"id":253,"port1Id":1165,"port2Id":1164,"isNonStopTransit":false},{"id":259,"port1Id":1181,"port2Id":1180,"isNonStopTransit":false},{"id":264,"port1Id":1203,"port2Id":1202,"isNonStopTransit":true},{"id":270,"port1Id":1225,"port2Id":1224,"isNonStopTransit":true},{"id":276,"port1Id":1241,"port2Id":1240,"isNonStopTransit":true},{"id":308,"port1Id":1308,"port2Id":1309,"isNonStopTransit":false},{"id":340,"port1Id":1371,"port2Id":1370,"isNonStopTransit":false},{"id":353,"port1Id":1331,"port2Id":1394,"isNonStopTransit":false}],"connections":[],"resourceId":157,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":134,"betriebspunktName":"Basel","fullName":"Basel","positionX":64,"positionY":-1888,"ports":[{"id":1054,"trainrunSectionId":519,"positionIndex":0,"positionAlignment":1},{"id":1416,"trainrunSectionId":700,"positionIndex":1,"positionAlignment":1},{"id":1277,"trainrunSectionId":631,"positionIndex":2,"positionAlignment":1},{"id":1338,"trainrunSectionId":661,"positionIndex":3,"positionAlignment":1},{"id":1301,"trainrunSectionId":643,"positionIndex":4,"positionAlignment":1},{"id":1378,"trainrunSectionId":681,"positionIndex":5,"positionAlignment":1},{"id":1138,"trainrunSectionId":561,"positionIndex":6,"positionAlignment":1},{"id":1124,"trainrunSectionId":554,"positionIndex":7,"positionAlignment":1},{"id":1267,"trainrunSectionId":626,"positionIndex":0,"positionAlignment":3}],"transitions":[],"connections":[],"resourceId":158,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":135,"betriebspunktName":"Zürich","fullName":"Zürich","positionX":2656,"positionY":32,"ports":[{"id":1255,"trainrunSectionId":620,"positionIndex":0,"positionAlignment":0},{"id":1254,"trainrunSectionId":619,"positionIndex":1,"positionAlignment":0},{"id":1360,"trainrunSectionId":672,"positionIndex":0,"positionAlignment":1},{"id":1149,"trainrunSectionId":567,"positionIndex":1,"positionAlignment":1},{"id":1153,"trainrunSectionId":569,"positionIndex":2,"positionAlignment":1},{"id":1358,"trainrunSectionId":671,"positionIndex":3,"positionAlignment":1},{"id":1356,"trainrunSectionId":670,"positionIndex":4,"positionAlignment":1},{"id":1354,"trainrunSectionId":669,"positionIndex":5,"positionAlignment":1},{"id":1195,"trainrunSectionId":590,"positionIndex":0,"positionAlignment":2},{"id":1401,"trainrunSectionId":693,"positionIndex":1,"positionAlignment":2},{"id":1292,"trainrunSectionId":638,"positionIndex":2,"positionAlignment":2},{"id":1173,"trainrunSectionId":579,"positionIndex":3,"positionAlignment":2},{"id":1217,"trainrunSectionId":601,"positionIndex":4,"positionAlignment":2},{"id":1233,"trainrunSectionId":609,"positionIndex":5,"positionAlignment":2},{"id":1157,"trainrunSectionId":571,"positionIndex":6,"positionAlignment":2},{"id":1276,"trainrunSectionId":630,"positionIndex":7,"positionAlignment":2},{"id":1300,"trainrunSectionId":642,"positionIndex":8,"positionAlignment":2},{"id":1191,"trainrunSectionId":588,"positionIndex":0,"positionAlignment":3},{"id":1172,"trainrunSectionId":578,"positionIndex":1,"positionAlignment":3},{"id":1213,"trainrunSectionId":599,"positionIndex":2,"positionAlignment":3},{"id":1229,"trainrunSectionId":607,"positionIndex":3,"positionAlignment":3},{"id":1139,"trainrunSectionId":562,"positionIndex":4,"positionAlignment":3},{"id":1245,"trainrunSectionId":615,"positionIndex":5,"positionAlignment":3}],"transitions":[{"id":250,"port1Id":1153,"port2Id":1157,"isNonStopTransit":false},{"id":256,"port1Id":1173,"port2Id":1172,"isNonStopTransit":false},{"id":261,"port1Id":1195,"port2Id":1191,"isNonStopTransit":false},{"id":267,"port1Id":1217,"port2Id":1213,"isNonStopTransit":false},{"id":273,"port1Id":1233,"port2Id":1229,"isNonStopTransit":false},{"id":329,"port1Id":1354,"port2Id":1245,"isNonStopTransit":false},{"id":357,"port1Id":1149,"port2Id":1401,"isNonStopTransit":false}],"connections":[],"resourceId":159,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":136,"betriebspunktName":"Bellinz.","fullName":"Bellinzona","positionX":2592,"positionY":3232,"ports":[{"id":1059,"trainrunSectionId":522,"positionIndex":0,"positionAlignment":0},{"id":1035,"trainrunSectionId":510,"positionIndex":1,"positionAlignment":0},{"id":1071,"trainrunSectionId":528,"positionIndex":2,"positionAlignment":0},{"id":1083,"trainrunSectionId":534,"positionIndex":3,"positionAlignment":0},{"id":1058,"trainrunSectionId":521,"positionIndex":0,"positionAlignment":1},{"id":1034,"trainrunSectionId":509,"positionIndex":1,"positionAlignment":1},{"id":1070,"trainrunSectionId":527,"positionIndex":0,"positionAlignment":2},{"id":1082,"trainrunSectionId":533,"positionIndex":1,"positionAlignment":2}],"transitions":[{"id":206,"port1Id":1035,"port2Id":1034,"isNonStopTransit":false},{"id":216,"port1Id":1059,"port2Id":1058,"isNonStopTransit":false},{"id":221,"port1Id":1071,"port2Id":1070,"isNonStopTransit":false},{"id":226,"port1Id":1083,"port2Id":1082,"isNonStopTransit":false}],"connections":[],"resourceId":160,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":137,"betriebspunktName":"St. Gallen","fullName":"Sankt Gallen","positionX":4640,"positionY":96,"ports":[{"id":1145,"trainrunSectionId":565,"positionIndex":0,"positionAlignment":1},{"id":1212,"trainrunSectionId":598,"positionIndex":0,"positionAlignment":2},{"id":1167,"trainrunSectionId":576,"positionIndex":1,"positionAlignment":2},{"id":1144,"trainrunSectionId":564,"positionIndex":2,"positionAlignment":2},{"id":1419,"trainrunSectionId":702,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":248,"port1Id":1145,"port2Id":1144,"isNonStopTransit":false},{"id":367,"port1Id":1167,"port2Id":1419,"isNonStopTransit":false}],"connections":[],"resourceId":161,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":138,"betriebspunktName":"Schaffh.","fullName":"Schaffhausen","positionX":2624,"positionY":-1120,"ports":[{"id":1256,"trainrunSectionId":620,"positionIndex":0,"positionAlignment":1},{"id":1251,"trainrunSectionId":618,"positionIndex":1,"positionAlignment":1}],"transitions":[],"connections":[],"resourceId":162,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":139,"betriebspunktName":"Konstanz","fullName":"Konstanz","positionX":4256,"positionY":-416,"ports":[{"id":1250,"trainrunSectionId":617,"positionIndex":0,"positionAlignment":1}],"transitions":[],"connections":[],"resourceId":163,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":140,"betriebspunktName":"Sargans","fullName":"Sargans","positionX":4640,"positionY":1184,"ports":[{"id":1146,"trainrunSectionId":565,"positionIndex":0,"positionAlignment":0},{"id":1151,"trainrunSectionId":568,"positionIndex":0,"positionAlignment":1},{"id":1147,"trainrunSectionId":566,"positionIndex":1,"positionAlignment":1},{"id":1155,"trainrunSectionId":570,"positionIndex":2,"positionAlignment":1},{"id":1362,"trainrunSectionId":673,"positionIndex":0,"positionAlignment":2},{"id":1364,"trainrunSectionId":674,"positionIndex":1,"positionAlignment":2}],"transitions":[{"id":249,"port1Id":1146,"port2Id":1147,"isNonStopTransit":false},{"id":334,"port1Id":1151,"port2Id":1362,"isNonStopTransit":false},{"id":336,"port1Id":1155,"port2Id":1364,"isNonStopTransit":false}],"connections":[],"resourceId":164,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":141,"betriebspunktName":"Sursee","fullName":"Sursee","positionX":64,"positionY":1184,"ports":[{"id":1043,"trainrunSectionId":514,"positionIndex":0,"positionAlignment":0},{"id":1105,"trainrunSectionId":545,"positionIndex":1,"positionAlignment":0},{"id":1367,"trainrunSectionId":676,"positionIndex":2,"positionAlignment":0},{"id":1127,"trainrunSectionId":556,"positionIndex":3,"positionAlignment":0},{"id":1113,"trainrunSectionId":549,"positionIndex":4,"positionAlignment":0},{"id":1042,"trainrunSectionId":513,"positionIndex":0,"positionAlignment":1},{"id":1104,"trainrunSectionId":544,"positionIndex":1,"positionAlignment":1},{"id":1366,"trainrunSectionId":675,"positionIndex":2,"positionAlignment":1},{"id":1126,"trainrunSectionId":555,"positionIndex":3,"positionAlignment":1},{"id":1112,"trainrunSectionId":548,"positionIndex":4,"positionAlignment":1}],"transitions":[{"id":208,"port1Id":1043,"port2Id":1042,"isNonStopTransit":true},{"id":232,"port1Id":1105,"port2Id":1104,"isNonStopTransit":false},{"id":234,"port1Id":1113,"port2Id":1112,"isNonStopTransit":false},{"id":240,"port1Id":1127,"port2Id":1126,"isNonStopTransit":true},{"id":338,"port1Id":1367,"port2Id":1366,"isNonStopTransit":true}],"connections":[],"resourceId":165,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":142,"betriebspunktName":"Luzern","fullName":"Luzern","positionX":64,"positionY":1728,"ports":[{"id":1041,"trainrunSectionId":513,"positionIndex":0,"positionAlignment":0},{"id":1103,"trainrunSectionId":544,"positionIndex":1,"positionAlignment":0},{"id":1365,"trainrunSectionId":675,"positionIndex":2,"positionAlignment":0},{"id":1125,"trainrunSectionId":555,"positionIndex":3,"positionAlignment":0},{"id":1111,"trainrunSectionId":548,"positionIndex":4,"positionAlignment":0},{"id":1352,"trainrunSectionId":668,"positionIndex":0,"positionAlignment":3},{"id":1350,"trainrunSectionId":667,"positionIndex":1,"positionAlignment":3},{"id":1099,"trainrunSectionId":542,"positionIndex":2,"positionAlignment":3},{"id":1095,"trainrunSectionId":540,"positionIndex":3,"positionAlignment":3}],"transitions":[{"id":327,"port1Id":1041,"port2Id":1352,"isNonStopTransit":false},{"id":337,"port1Id":1365,"port2Id":1350,"isNonStopTransit":false}],"connections":[],"resourceId":166,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":143,"betriebspunktName":"Zofingen","fullName":"Zofingen","positionX":64,"positionY":736,"ports":[{"id":1045,"trainrunSectionId":515,"positionIndex":0,"positionAlignment":0},{"id":1369,"trainrunSectionId":677,"positionIndex":1,"positionAlignment":0},{"id":1129,"trainrunSectionId":557,"positionIndex":2,"positionAlignment":0},{"id":1115,"trainrunSectionId":550,"positionIndex":3,"positionAlignment":0},{"id":1044,"trainrunSectionId":514,"positionIndex":0,"positionAlignment":1},{"id":1106,"trainrunSectionId":545,"positionIndex":1,"positionAlignment":1},{"id":1368,"trainrunSectionId":676,"positionIndex":2,"positionAlignment":1},{"id":1128,"trainrunSectionId":556,"positionIndex":3,"positionAlignment":1},{"id":1114,"trainrunSectionId":549,"positionIndex":4,"positionAlignment":1},{"id":1107,"trainrunSectionId":546,"positionIndex":0,"positionAlignment":2}],"transitions":[{"id":209,"port1Id":1045,"port2Id":1044,"isNonStopTransit":true},{"id":233,"port1Id":1107,"port2Id":1106,"isNonStopTransit":false},{"id":235,"port1Id":1115,"port2Id":1114,"isNonStopTransit":false},{"id":241,"port1Id":1129,"port2Id":1128,"isNonStopTransit":true},{"id":339,"port1Id":1369,"port2Id":1368,"isNonStopTransit":false}],"connections":[],"resourceId":167,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":144,"betriebspunktName":"Gelterk.","fullName":"Gelterkinden","positionX":64,"positionY":-448,"ports":[{"id":1049,"trainrunSectionId":517,"positionIndex":0,"positionAlignment":0},{"id":1411,"trainrunSectionId":698,"positionIndex":1,"positionAlignment":0},{"id":1282,"trainrunSectionId":633,"positionIndex":2,"positionAlignment":0},{"id":1333,"trainrunSectionId":659,"positionIndex":3,"positionAlignment":0},{"id":1306,"trainrunSectionId":645,"positionIndex":4,"positionAlignment":0},{"id":1373,"trainrunSectionId":679,"positionIndex":5,"positionAlignment":0},{"id":1133,"trainrunSectionId":559,"positionIndex":6,"positionAlignment":0},{"id":1119,"trainrunSectionId":552,"positionIndex":7,"positionAlignment":0},{"id":1048,"trainrunSectionId":516,"positionIndex":0,"positionAlignment":1},{"id":1332,"trainrunSectionId":658,"positionIndex":1,"positionAlignment":1},{"id":1307,"trainrunSectionId":646,"positionIndex":2,"positionAlignment":1},{"id":1372,"trainrunSectionId":678,"positionIndex":3,"positionAlignment":1},{"id":1132,"trainrunSectionId":558,"positionIndex":4,"positionAlignment":1},{"id":1118,"trainrunSectionId":551,"positionIndex":5,"positionAlignment":1},{"id":1410,"trainrunSectionId":697,"positionIndex":0,"positionAlignment":3},{"id":1283,"trainrunSectionId":634,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":211,"port1Id":1049,"port2Id":1048,"isNonStopTransit":true},{"id":237,"port1Id":1119,"port2Id":1118,"isNonStopTransit":false},{"id":243,"port1Id":1133,"port2Id":1132,"isNonStopTransit":true},{"id":297,"port1Id":1282,"port2Id":1283,"isNonStopTransit":true},{"id":307,"port1Id":1306,"port2Id":1307,"isNonStopTransit":true},{"id":316,"port1Id":1333,"port2Id":1332,"isNonStopTransit":true},{"id":341,"port1Id":1373,"port2Id":1372,"isNonStopTransit":true},{"id":362,"port1Id":1411,"port2Id":1410,"isNonStopTransit":true}],"connections":[],"resourceId":168,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":145,"betriebspunktName":"Sissach","fullName":"Sissach","positionX":64,"positionY":-928,"ports":[{"id":1051,"trainrunSectionId":518,"positionIndex":0,"positionAlignment":0},{"id":1413,"trainrunSectionId":699,"positionIndex":1,"positionAlignment":0},{"id":1280,"trainrunSectionId":632,"positionIndex":2,"positionAlignment":0},{"id":1335,"trainrunSectionId":660,"positionIndex":3,"positionAlignment":0},{"id":1304,"trainrunSectionId":644,"positionIndex":4,"positionAlignment":0},{"id":1375,"trainrunSectionId":680,"positionIndex":5,"positionAlignment":0},{"id":1135,"trainrunSectionId":560,"positionIndex":6,"positionAlignment":0},{"id":1121,"trainrunSectionId":553,"positionIndex":7,"positionAlignment":0},{"id":1050,"trainrunSectionId":517,"positionIndex":0,"positionAlignment":1},{"id":1412,"trainrunSectionId":698,"positionIndex":1,"positionAlignment":1},{"id":1281,"trainrunSectionId":633,"positionIndex":2,"positionAlignment":1},{"id":1334,"trainrunSectionId":659,"positionIndex":3,"positionAlignment":1},{"id":1305,"trainrunSectionId":645,"positionIndex":4,"positionAlignment":1},{"id":1374,"trainrunSectionId":679,"positionIndex":5,"positionAlignment":1},{"id":1134,"trainrunSectionId":559,"positionIndex":6,"positionAlignment":1},{"id":1120,"trainrunSectionId":552,"positionIndex":7,"positionAlignment":1}],"transitions":[{"id":212,"port1Id":1051,"port2Id":1050,"isNonStopTransit":true},{"id":238,"port1Id":1121,"port2Id":1120,"isNonStopTransit":false},{"id":244,"port1Id":1135,"port2Id":1134,"isNonStopTransit":true},{"id":296,"port1Id":1280,"port2Id":1281,"isNonStopTransit":true},{"id":306,"port1Id":1304,"port2Id":1305,"isNonStopTransit":true},{"id":317,"port1Id":1335,"port2Id":1334,"isNonStopTransit":true},{"id":342,"port1Id":1375,"port2Id":1374,"isNonStopTransit":true},{"id":363,"port1Id":1413,"port2Id":1412,"isNonStopTransit":true}],"connections":[],"resourceId":169,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":146,"betriebspunktName":"Liestal","fullName":"Liestal","positionX":64,"positionY":-1408,"ports":[{"id":1053,"trainrunSectionId":519,"positionIndex":0,"positionAlignment":0},{"id":1415,"trainrunSectionId":700,"positionIndex":1,"positionAlignment":0},{"id":1278,"trainrunSectionId":631,"positionIndex":2,"positionAlignment":0},{"id":1337,"trainrunSectionId":661,"positionIndex":3,"positionAlignment":0},{"id":1302,"trainrunSectionId":643,"positionIndex":4,"positionAlignment":0},{"id":1377,"trainrunSectionId":681,"positionIndex":5,"positionAlignment":0},{"id":1137,"trainrunSectionId":561,"positionIndex":6,"positionAlignment":0},{"id":1123,"trainrunSectionId":554,"positionIndex":7,"positionAlignment":0},{"id":1052,"trainrunSectionId":518,"positionIndex":0,"positionAlignment":1},{"id":1414,"trainrunSectionId":699,"positionIndex":1,"positionAlignment":1},{"id":1279,"trainrunSectionId":632,"positionIndex":2,"positionAlignment":1},{"id":1336,"trainrunSectionId":660,"positionIndex":3,"positionAlignment":1},{"id":1303,"trainrunSectionId":644,"positionIndex":4,"positionAlignment":1},{"id":1376,"trainrunSectionId":680,"positionIndex":5,"positionAlignment":1},{"id":1136,"trainrunSectionId":560,"positionIndex":6,"positionAlignment":1},{"id":1122,"trainrunSectionId":553,"positionIndex":7,"positionAlignment":1}],"transitions":[{"id":213,"port1Id":1053,"port2Id":1052,"isNonStopTransit":true},{"id":239,"port1Id":1123,"port2Id":1122,"isNonStopTransit":false},{"id":245,"port1Id":1137,"port2Id":1136,"isNonStopTransit":true},{"id":295,"port1Id":1278,"port2Id":1279,"isNonStopTransit":true},{"id":305,"port1Id":1302,"port2Id":1303,"isNonStopTransit":true},{"id":318,"port1Id":1337,"port2Id":1336,"isNonStopTransit":true},{"id":343,"port1Id":1377,"port2Id":1376,"isNonStopTransit":true},{"id":364,"port1Id":1415,"port2Id":1414,"isNonStopTransit":true}],"connections":[],"resourceId":170,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":147,"betriebspunktName":"Aarau","fullName":"Aarau","positionX":960,"positionY":32,"ports":[{"id":1409,"trainrunSectionId":697,"positionIndex":0,"positionAlignment":2},{"id":1284,"trainrunSectionId":634,"positionIndex":1,"positionAlignment":2},{"id":1201,"trainrunSectionId":593,"positionIndex":2,"positionAlignment":2},{"id":1179,"trainrunSectionId":582,"positionIndex":3,"positionAlignment":2},{"id":1223,"trainrunSectionId":604,"positionIndex":4,"positionAlignment":2},{"id":1239,"trainrunSectionId":612,"positionIndex":5,"positionAlignment":2},{"id":1163,"trainrunSectionId":574,"positionIndex":6,"positionAlignment":2},{"id":1200,"trainrunSectionId":592,"positionIndex":0,"positionAlignment":3},{"id":1408,"trainrunSectionId":696,"positionIndex":1,"positionAlignment":3},{"id":1285,"trainrunSectionId":635,"positionIndex":2,"positionAlignment":3},{"id":1178,"trainrunSectionId":581,"positionIndex":3,"positionAlignment":3},{"id":1222,"trainrunSectionId":603,"positionIndex":4,"positionAlignment":3},{"id":1238,"trainrunSectionId":611,"positionIndex":5,"positionAlignment":3},{"id":1162,"trainrunSectionId":573,"positionIndex":6,"positionAlignment":3},{"id":1293,"trainrunSectionId":639,"positionIndex":7,"positionAlignment":3}],"transitions":[{"id":252,"port1Id":1163,"port2Id":1162,"isNonStopTransit":true},{"id":258,"port1Id":1179,"port2Id":1178,"isNonStopTransit":false},{"id":263,"port1Id":1201,"port2Id":1200,"isNonStopTransit":true},{"id":269,"port1Id":1223,"port2Id":1222,"isNonStopTransit":true},{"id":275,"port1Id":1239,"port2Id":1238,"isNonStopTransit":true},{"id":298,"port1Id":1284,"port2Id":1285,"isNonStopTransit":true},{"id":361,"port1Id":1409,"port2Id":1408,"isNonStopTransit":true}],"connections":[],"resourceId":171,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":148,"betriebspunktName":"Lenzburg","fullName":"Lenzburg","positionX":1344,"positionY":32,"ports":[{"id":1199,"trainrunSectionId":592,"positionIndex":0,"positionAlignment":2},{"id":1407,"trainrunSectionId":696,"positionIndex":1,"positionAlignment":2},{"id":1286,"trainrunSectionId":635,"positionIndex":2,"positionAlignment":2},{"id":1177,"trainrunSectionId":581,"positionIndex":3,"positionAlignment":2},{"id":1221,"trainrunSectionId":603,"positionIndex":4,"positionAlignment":2},{"id":1237,"trainrunSectionId":611,"positionIndex":5,"positionAlignment":2},{"id":1161,"trainrunSectionId":573,"positionIndex":6,"positionAlignment":2},{"id":1294,"trainrunSectionId":639,"positionIndex":7,"positionAlignment":2},{"id":1258,"trainrunSectionId":621,"positionIndex":0,"positionAlignment":3},{"id":1406,"trainrunSectionId":695,"positionIndex":1,"positionAlignment":3},{"id":1287,"trainrunSectionId":636,"positionIndex":2,"positionAlignment":3},{"id":1260,"trainrunSectionId":622,"positionIndex":3,"positionAlignment":3},{"id":1262,"trainrunSectionId":623,"positionIndex":4,"positionAlignment":3},{"id":1264,"trainrunSectionId":624,"positionIndex":5,"positionAlignment":3},{"id":1266,"trainrunSectionId":625,"positionIndex":6,"positionAlignment":3},{"id":1295,"trainrunSectionId":640,"positionIndex":7,"positionAlignment":3}],"transitions":[{"id":282,"port1Id":1199,"port2Id":1258,"isNonStopTransit":true},{"id":284,"port1Id":1177,"port2Id":1260,"isNonStopTransit":true},{"id":286,"port1Id":1221,"port2Id":1262,"isNonStopTransit":true},{"id":288,"port1Id":1237,"port2Id":1264,"isNonStopTransit":true},{"id":290,"port1Id":1161,"port2Id":1266,"isNonStopTransit":true},{"id":299,"port1Id":1286,"port2Id":1287,"isNonStopTransit":true},{"id":302,"port1Id":1294,"port2Id":1295,"isNonStopTransit":false},{"id":360,"port1Id":1407,"port2Id":1406,"isNonStopTransit":true}],"connections":[],"resourceId":172,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":149,"betriebspunktName":"Baden","fullName":"Baden","positionX":2240,"positionY":32,"ports":[{"id":1197,"trainrunSectionId":591,"positionIndex":0,"positionAlignment":2},{"id":1403,"trainrunSectionId":694,"positionIndex":1,"positionAlignment":2},{"id":1290,"trainrunSectionId":637,"positionIndex":2,"positionAlignment":2},{"id":1175,"trainrunSectionId":580,"positionIndex":3,"positionAlignment":2},{"id":1219,"trainrunSectionId":602,"positionIndex":4,"positionAlignment":2},{"id":1235,"trainrunSectionId":610,"positionIndex":5,"positionAlignment":2},{"id":1159,"trainrunSectionId":572,"positionIndex":6,"positionAlignment":2},{"id":1274,"trainrunSectionId":629,"positionIndex":7,"positionAlignment":2},{"id":1298,"trainrunSectionId":641,"positionIndex":8,"positionAlignment":2},{"id":1196,"trainrunSectionId":590,"positionIndex":0,"positionAlignment":3},{"id":1402,"trainrunSectionId":693,"positionIndex":1,"positionAlignment":3},{"id":1291,"trainrunSectionId":638,"positionIndex":2,"positionAlignment":3},{"id":1174,"trainrunSectionId":579,"positionIndex":3,"positionAlignment":3},{"id":1218,"trainrunSectionId":601,"positionIndex":4,"positionAlignment":3},{"id":1234,"trainrunSectionId":609,"positionIndex":5,"positionAlignment":3},{"id":1158,"trainrunSectionId":571,"positionIndex":6,"positionAlignment":3},{"id":1275,"trainrunSectionId":630,"positionIndex":7,"positionAlignment":3},{"id":1299,"trainrunSectionId":642,"positionIndex":8,"positionAlignment":3}],"transitions":[{"id":251,"port1Id":1159,"port2Id":1158,"isNonStopTransit":true},{"id":257,"port1Id":1175,"port2Id":1174,"isNonStopTransit":true},{"id":262,"port1Id":1197,"port2Id":1196,"isNonStopTransit":true},{"id":268,"port1Id":1219,"port2Id":1218,"isNonStopTransit":true},{"id":274,"port1Id":1235,"port2Id":1234,"isNonStopTransit":true},{"id":294,"port1Id":1274,"port2Id":1275,"isNonStopTransit":false},{"id":301,"port1Id":1290,"port2Id":1291,"isNonStopTransit":true},{"id":304,"port1Id":1298,"port2Id":1299,"isNonStopTransit":true},{"id":358,"port1Id":1403,"port2Id":1402,"isNonStopTransit":true}],"connections":[],"resourceId":173,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":150,"betriebspunktName":"Zürich ✈","fullName":"Zürich Flughafen","positionX":3296,"positionY":32,"ports":[{"id":1192,"trainrunSectionId":588,"positionIndex":0,"positionAlignment":2},{"id":1171,"trainrunSectionId":578,"positionIndex":1,"positionAlignment":2},{"id":1214,"trainrunSectionId":599,"positionIndex":2,"positionAlignment":2},{"id":1230,"trainrunSectionId":607,"positionIndex":3,"positionAlignment":2},{"id":1140,"trainrunSectionId":562,"positionIndex":4,"positionAlignment":2},{"id":1246,"trainrunSectionId":615,"positionIndex":5,"positionAlignment":2},{"id":1193,"trainrunSectionId":589,"positionIndex":0,"positionAlignment":3},{"id":1170,"trainrunSectionId":577,"positionIndex":1,"positionAlignment":3},{"id":1215,"trainrunSectionId":600,"positionIndex":2,"positionAlignment":3},{"id":1231,"trainrunSectionId":608,"positionIndex":3,"positionAlignment":3},{"id":1141,"trainrunSectionId":563,"positionIndex":4,"positionAlignment":3},{"id":1247,"trainrunSectionId":616,"positionIndex":5,"positionAlignment":3}],"transitions":[{"id":246,"port1Id":1140,"port2Id":1141,"isNonStopTransit":false},{"id":255,"port1Id":1171,"port2Id":1170,"isNonStopTransit":false},{"id":260,"port1Id":1192,"port2Id":1193,"isNonStopTransit":false},{"id":266,"port1Id":1214,"port2Id":1215,"isNonStopTransit":false},{"id":272,"port1Id":1230,"port2Id":1231,"isNonStopTransit":false},{"id":278,"port1Id":1246,"port2Id":1247,"isNonStopTransit":false}],"connections":[],"resourceId":174,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":151,"betriebspunktName":"Wintert.","fullName":"Winterthur","positionX":3872,"positionY":32,"ports":[{"id":1249,"trainrunSectionId":617,"positionIndex":0,"positionAlignment":0},{"id":1194,"trainrunSectionId":589,"positionIndex":0,"positionAlignment":2},{"id":1169,"trainrunSectionId":577,"positionIndex":1,"positionAlignment":2},{"id":1216,"trainrunSectionId":600,"positionIndex":2,"positionAlignment":2},{"id":1232,"trainrunSectionId":608,"positionIndex":3,"positionAlignment":2},{"id":1142,"trainrunSectionId":563,"positionIndex":4,"positionAlignment":2},{"id":1248,"trainrunSectionId":616,"positionIndex":5,"positionAlignment":2},{"id":1227,"trainrunSectionId":606,"positionIndex":0,"positionAlignment":3},{"id":1243,"trainrunSectionId":614,"positionIndex":1,"positionAlignment":3},{"id":1211,"trainrunSectionId":598,"positionIndex":2,"positionAlignment":3},{"id":1168,"trainrunSectionId":576,"positionIndex":3,"positionAlignment":3},{"id":1143,"trainrunSectionId":564,"positionIndex":4,"positionAlignment":3}],"transitions":[{"id":247,"port1Id":1142,"port2Id":1143,"isNonStopTransit":false},{"id":254,"port1Id":1169,"port2Id":1168,"isNonStopTransit":false},{"id":265,"port1Id":1194,"port2Id":1211,"isNonStopTransit":false},{"id":271,"port1Id":1216,"port2Id":1227,"isNonStopTransit":false},{"id":277,"port1Id":1232,"port2Id":1243,"isNonStopTransit":false},{"id":279,"port1Id":1249,"port2Id":1248,"isNonStopTransit":false}],"connections":[],"resourceId":175,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":152,"betriebspunktName":"Chur","fullName":"Chur","positionX":4640,"positionY":1888,"ports":[{"id":1152,"trainrunSectionId":568,"positionIndex":0,"positionAlignment":0},{"id":1148,"trainrunSectionId":566,"positionIndex":1,"positionAlignment":0},{"id":1156,"trainrunSectionId":570,"positionIndex":2,"positionAlignment":0}],"transitions":[],"connections":[],"resourceId":176,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":153,"betriebspunktName":"Zug","fullName":"Zug","positionX":2656,"positionY":1312,"ports":[{"id":1067,"trainrunSectionId":526,"positionIndex":0,"positionAlignment":0},{"id":1093,"trainrunSectionId":539,"positionIndex":1,"positionAlignment":0},{"id":1101,"trainrunSectionId":543,"positionIndex":2,"positionAlignment":0},{"id":1097,"trainrunSectionId":541,"positionIndex":3,"positionAlignment":0},{"id":1066,"trainrunSectionId":525,"positionIndex":0,"positionAlignment":1},{"id":1092,"trainrunSectionId":538,"positionIndex":1,"positionAlignment":1},{"id":1348,"trainrunSectionId":666,"positionIndex":0,"positionAlignment":2},{"id":1346,"trainrunSectionId":665,"positionIndex":1,"positionAlignment":2}],"transitions":[{"id":220,"port1Id":1067,"port2Id":1066,"isNonStopTransit":false},{"id":231,"port1Id":1093,"port2Id":1092,"isNonStopTransit":false},{"id":322,"port1Id":1097,"port2Id":1346,"isNonStopTransit":false},{"id":324,"port1Id":1101,"port2Id":1348,"isNonStopTransit":false}],"connections":[],"resourceId":177,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":154,"betriebspunktName":"Arth-G.","fullName":"Arth-Goldau","positionX":2656,"positionY":1792,"ports":[{"id":1065,"trainrunSectionId":525,"positionIndex":0,"positionAlignment":0},{"id":1091,"trainrunSectionId":538,"positionIndex":1,"positionAlignment":0},{"id":1064,"trainrunSectionId":524,"positionIndex":0,"positionAlignment":1},{"id":1038,"trainrunSectionId":511,"positionIndex":1,"positionAlignment":1},{"id":1078,"trainrunSectionId":531,"positionIndex":2,"positionAlignment":1},{"id":1090,"trainrunSectionId":537,"positionIndex":3,"positionAlignment":1},{"id":1039,"trainrunSectionId":512,"positionIndex":0,"positionAlignment":2},{"id":1079,"trainrunSectionId":532,"positionIndex":1,"positionAlignment":2}],"transitions":[{"id":207,"port1Id":1038,"port2Id":1039,"isNonStopTransit":false},{"id":219,"port1Id":1065,"port2Id":1064,"isNonStopTransit":false},{"id":225,"port1Id":1078,"port2Id":1079,"isNonStopTransit":false},{"id":230,"port1Id":1091,"port2Id":1090,"isNonStopTransit":false}],"connections":[],"resourceId":178,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":155,"betriebspunktName":"Altdorf","fullName":"Altdorf","positionX":2656,"positionY":2176,"ports":[{"id":1063,"trainrunSectionId":524,"positionIndex":0,"positionAlignment":0},{"id":1037,"trainrunSectionId":511,"positionIndex":1,"positionAlignment":0},{"id":1077,"trainrunSectionId":531,"positionIndex":2,"positionAlignment":0},{"id":1089,"trainrunSectionId":537,"positionIndex":3,"positionAlignment":0},{"id":1062,"trainrunSectionId":523,"positionIndex":0,"positionAlignment":1},{"id":1055,"trainrunSectionId":520,"positionIndex":1,"positionAlignment":1},{"id":1076,"trainrunSectionId":530,"positionIndex":0,"positionAlignment":2},{"id":1088,"trainrunSectionId":536,"positionIndex":1,"positionAlignment":2}],"transitions":[{"id":214,"port1Id":1037,"port2Id":1055,"isNonStopTransit":true},{"id":218,"port1Id":1063,"port2Id":1062,"isNonStopTransit":false},{"id":224,"port1Id":1077,"port2Id":1076,"isNonStopTransit":false},{"id":229,"port1Id":1089,"port2Id":1088,"isNonStopTransit":false}],"connections":[],"resourceId":179,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":156,"betriebspunktName":"Lugano","fullName":"Lugano","positionX":2592,"positionY":3712,"ports":[{"id":1057,"trainrunSectionId":521,"positionIndex":0,"positionAlignment":0},{"id":1033,"trainrunSectionId":509,"positionIndex":1,"positionAlignment":0}],"transitions":[],"connections":[],"resourceId":180,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":157,"betriebspunktName":"Locarno","fullName":"Locarno","positionX":2208,"positionY":3232,"ports":[{"id":1069,"trainrunSectionId":527,"positionIndex":0,"positionAlignment":3},{"id":1081,"trainrunSectionId":533,"positionIndex":1,"positionAlignment":3}],"transitions":[],"connections":[],"resourceId":181,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":158,"betriebspunktName":"Biasca","fullName":"Biasca","positionX":2592,"positionY":2688,"ports":[{"id":1073,"trainrunSectionId":529,"positionIndex":0,"positionAlignment":0},{"id":1085,"trainrunSectionId":535,"positionIndex":1,"positionAlignment":0},{"id":1061,"trainrunSectionId":523,"positionIndex":2,"positionAlignment":0},{"id":1056,"trainrunSectionId":520,"positionIndex":3,"positionAlignment":0},{"id":1060,"trainrunSectionId":522,"positionIndex":0,"positionAlignment":1},{"id":1036,"trainrunSectionId":510,"positionIndex":1,"positionAlignment":1},{"id":1072,"trainrunSectionId":528,"positionIndex":2,"positionAlignment":1},{"id":1084,"trainrunSectionId":534,"positionIndex":3,"positionAlignment":1}],"transitions":[{"id":215,"port1Id":1056,"port2Id":1036,"isNonStopTransit":true},{"id":217,"port1Id":1061,"port2Id":1060,"isNonStopTransit":true},{"id":222,"port1Id":1073,"port2Id":1072,"isNonStopTransit":false},{"id":227,"port1Id":1085,"port2Id":1084,"isNonStopTransit":false}],"connections":[],"resourceId":182,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":159,"betriebspunktName":"Göschn.","fullName":"Göschenen","positionX":2272,"positionY":2240,"ports":[{"id":1074,"trainrunSectionId":529,"positionIndex":0,"positionAlignment":1},{"id":1086,"trainrunSectionId":535,"positionIndex":1,"positionAlignment":1},{"id":1075,"trainrunSectionId":530,"positionIndex":0,"positionAlignment":3},{"id":1087,"trainrunSectionId":536,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":223,"port1Id":1074,"port2Id":1075,"isNonStopTransit":false},{"id":228,"port1Id":1086,"port2Id":1087,"isNonStopTransit":false}],"connections":[],"resourceId":183,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":160,"betriebspunktName":"Genf","fullName":"Genf","positionX":-3936,"positionY":608,"ports":[{"id":1209,"trainrunSectionId":597,"positionIndex":0,"positionAlignment":2},{"id":1185,"trainrunSectionId":585,"positionIndex":1,"positionAlignment":2},{"id":1189,"trainrunSectionId":587,"positionIndex":2,"positionAlignment":2},{"id":1424,"trainrunSectionId":704,"positionIndex":0,"positionAlignment":3},{"id":1426,"trainrunSectionId":705,"positionIndex":1,"positionAlignment":3},{"id":1422,"trainrunSectionId":703,"positionIndex":2,"positionAlignment":3}],"transitions":[{"id":369,"port1Id":1189,"port2Id":1422,"isNonStopTransit":false},{"id":371,"port1Id":1209,"port2Id":1424,"isNonStopTransit":false},{"id":373,"port1Id":1185,"port2Id":1426,"isNonStopTransit":false}],"connections":[],"resourceId":184,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":161,"betriebspunktName":"Genf ✈","fullName":"Aiport","positionX":-4352,"positionY":608,"ports":[{"id":1210,"trainrunSectionId":597,"positionIndex":0,"positionAlignment":3},{"id":1186,"trainrunSectionId":585,"positionIndex":1,"positionAlignment":3},{"id":1190,"trainrunSectionId":587,"positionIndex":2,"positionAlignment":3}],"transitions":[],"connections":[],"resourceId":185,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":162,"betriebspunktName":"Romansh.","fullName":"Romanshorn","positionX":4640,"positionY":-192,"ports":[{"id":1228,"trainrunSectionId":606,"positionIndex":0,"positionAlignment":2},{"id":1244,"trainrunSectionId":614,"positionIndex":1,"positionAlignment":2}],"transitions":[],"connections":[],"resourceId":186,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":163,"betriebspunktName":"Bülach","fullName":"Bülach","positionX":2784,"positionY":-544,"ports":[{"id":1252,"trainrunSectionId":618,"positionIndex":0,"positionAlignment":0},{"id":1253,"trainrunSectionId":619,"positionIndex":0,"positionAlignment":1}],"transitions":[{"id":280,"port1Id":1252,"port2Id":1253,"isNonStopTransit":false}],"connections":[],"resourceId":187,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":164,"betriebspunktName":"Reihnf.","fullName":"Reihnfelden","positionX":1056,"positionY":-960,"ports":[{"id":1268,"trainrunSectionId":626,"positionIndex":0,"positionAlignment":2},{"id":1269,"trainrunSectionId":627,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":291,"port1Id":1268,"port2Id":1269,"isNonStopTransit":false}],"connections":[],"resourceId":188,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":165,"betriebspunktName":"Frick","fullName":"Frick","positionX":1792,"positionY":-672,"ports":[{"id":1271,"trainrunSectionId":628,"positionIndex":0,"positionAlignment":1},{"id":1270,"trainrunSectionId":627,"positionIndex":0,"positionAlignment":2}],"transitions":[{"id":292,"port1Id":1271,"port2Id":1270,"isNonStopTransit":false}],"connections":[],"resourceId":189,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":166,"betriebspunktName":"Brugg","fullName":"Brugg","positionX":1792,"positionY":32,"ports":[{"id":1272,"trainrunSectionId":628,"positionIndex":0,"positionAlignment":0},{"id":1257,"trainrunSectionId":621,"positionIndex":0,"positionAlignment":2},{"id":1405,"trainrunSectionId":695,"positionIndex":1,"positionAlignment":2},{"id":1288,"trainrunSectionId":636,"positionIndex":2,"positionAlignment":2},{"id":1259,"trainrunSectionId":622,"positionIndex":3,"positionAlignment":2},{"id":1261,"trainrunSectionId":623,"positionIndex":4,"positionAlignment":2},{"id":1263,"trainrunSectionId":624,"positionIndex":5,"positionAlignment":2},{"id":1265,"trainrunSectionId":625,"positionIndex":6,"positionAlignment":2},{"id":1296,"trainrunSectionId":640,"positionIndex":7,"positionAlignment":2},{"id":1198,"trainrunSectionId":591,"positionIndex":0,"positionAlignment":3},{"id":1404,"trainrunSectionId":694,"positionIndex":1,"positionAlignment":3},{"id":1289,"trainrunSectionId":637,"positionIndex":2,"positionAlignment":3},{"id":1176,"trainrunSectionId":580,"positionIndex":3,"positionAlignment":3},{"id":1220,"trainrunSectionId":602,"positionIndex":4,"positionAlignment":3},{"id":1236,"trainrunSectionId":610,"positionIndex":5,"positionAlignment":3},{"id":1160,"trainrunSectionId":572,"positionIndex":6,"positionAlignment":3},{"id":1273,"trainrunSectionId":629,"positionIndex":7,"positionAlignment":3},{"id":1297,"trainrunSectionId":641,"positionIndex":8,"positionAlignment":3}],"transitions":[{"id":281,"port1Id":1257,"port2Id":1198,"isNonStopTransit":true},{"id":283,"port1Id":1259,"port2Id":1176,"isNonStopTransit":true},{"id":285,"port1Id":1261,"port2Id":1220,"isNonStopTransit":true},{"id":287,"port1Id":1263,"port2Id":1236,"isNonStopTransit":false},{"id":289,"port1Id":1265,"port2Id":1160,"isNonStopTransit":true},{"id":293,"port1Id":1272,"port2Id":1273,"isNonStopTransit":false},{"id":300,"port1Id":1288,"port2Id":1289,"isNonStopTransit":true},{"id":303,"port1Id":1296,"port2Id":1297,"isNonStopTransit":true},{"id":359,"port1Id":1405,"port2Id":1404,"isNonStopTransit":true}],"connections":[],"resourceId":190,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":167,"betriebspunktName":"Thun","fullName":"Thun","positionX":-2144,"positionY":640,"ports":[{"id":1327,"trainrunSectionId":656,"positionIndex":0,"positionAlignment":0},{"id":1312,"trainrunSectionId":648,"positionIndex":1,"positionAlignment":0},{"id":1314,"trainrunSectionId":649,"positionIndex":2,"positionAlignment":0},{"id":1340,"trainrunSectionId":662,"positionIndex":3,"positionAlignment":0},{"id":1326,"trainrunSectionId":655,"positionIndex":0,"positionAlignment":1},{"id":1315,"trainrunSectionId":650,"positionIndex":1,"positionAlignment":1},{"id":1319,"trainrunSectionId":652,"positionIndex":2,"positionAlignment":1},{"id":1341,"trainrunSectionId":663,"positionIndex":3,"positionAlignment":1}],"transitions":[{"id":309,"port1Id":1312,"port2Id":1315,"isNonStopTransit":false},{"id":311,"port1Id":1314,"port2Id":1319,"isNonStopTransit":false},{"id":314,"port1Id":1327,"port2Id":1326,"isNonStopTransit":false},{"id":319,"port1Id":1340,"port2Id":1341,"isNonStopTransit":false}],"connections":[],"resourceId":191,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":168,"betriebspunktName":"Spiez","fullName":"Spiez","positionX":-2144,"positionY":928,"ports":[{"id":1325,"trainrunSectionId":655,"positionIndex":0,"positionAlignment":0},{"id":1316,"trainrunSectionId":650,"positionIndex":1,"positionAlignment":0},{"id":1320,"trainrunSectionId":652,"positionIndex":2,"positionAlignment":0},{"id":1342,"trainrunSectionId":663,"positionIndex":3,"positionAlignment":0},{"id":1324,"trainrunSectionId":654,"positionIndex":0,"positionAlignment":1},{"id":1321,"trainrunSectionId":653,"positionIndex":1,"positionAlignment":1},{"id":1317,"trainrunSectionId":651,"positionIndex":0,"positionAlignment":3},{"id":1343,"trainrunSectionId":664,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":310,"port1Id":1316,"port2Id":1317,"isNonStopTransit":false},{"id":312,"port1Id":1320,"port2Id":1321,"isNonStopTransit":false},{"id":313,"port1Id":1325,"port2Id":1324,"isNonStopTransit":false},{"id":320,"port1Id":1342,"port2Id":1343,"isNonStopTransit":false}],"connections":[],"resourceId":192,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":169,"betriebspunktName":"Rothkr.","fullName":"Rothkreuz","positionX":1856,"positionY":1728,"ports":[{"id":1351,"trainrunSectionId":668,"positionIndex":0,"positionAlignment":2},{"id":1349,"trainrunSectionId":667,"positionIndex":1,"positionAlignment":2},{"id":1100,"trainrunSectionId":542,"positionIndex":2,"positionAlignment":2},{"id":1096,"trainrunSectionId":540,"positionIndex":3,"positionAlignment":2},{"id":1347,"trainrunSectionId":666,"positionIndex":0,"positionAlignment":3},{"id":1345,"trainrunSectionId":665,"positionIndex":1,"positionAlignment":3},{"id":1040,"trainrunSectionId":512,"positionIndex":2,"positionAlignment":3},{"id":1080,"trainrunSectionId":532,"positionIndex":3,"positionAlignment":3}],"transitions":[{"id":321,"port1Id":1096,"port2Id":1345,"isNonStopTransit":false},{"id":323,"port1Id":1100,"port2Id":1347,"isNonStopTransit":true},{"id":325,"port1Id":1349,"port2Id":1080,"isNonStopTransit":true},{"id":326,"port1Id":1351,"port2Id":1040,"isNonStopTransit":true}],"connections":[],"resourceId":193,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":170,"betriebspunktName":"Thalwil","fullName":"Thalwil","positionX":2656,"positionY":736,"ports":[{"id":1359,"trainrunSectionId":672,"positionIndex":0,"positionAlignment":0},{"id":1150,"trainrunSectionId":567,"positionIndex":1,"positionAlignment":0},{"id":1154,"trainrunSectionId":569,"positionIndex":2,"positionAlignment":0},{"id":1357,"trainrunSectionId":671,"positionIndex":3,"positionAlignment":0},{"id":1355,"trainrunSectionId":670,"positionIndex":4,"positionAlignment":0},{"id":1353,"trainrunSectionId":669,"positionIndex":5,"positionAlignment":0},{"id":1068,"trainrunSectionId":526,"positionIndex":0,"positionAlignment":1},{"id":1094,"trainrunSectionId":539,"positionIndex":1,"positionAlignment":1},{"id":1102,"trainrunSectionId":543,"positionIndex":2,"positionAlignment":1},{"id":1098,"trainrunSectionId":541,"positionIndex":3,"positionAlignment":1},{"id":1361,"trainrunSectionId":673,"positionIndex":0,"positionAlignment":3},{"id":1363,"trainrunSectionId":674,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":328,"port1Id":1353,"port2Id":1098,"isNonStopTransit":false},{"id":330,"port1Id":1355,"port2Id":1102,"isNonStopTransit":true},{"id":331,"port1Id":1357,"port2Id":1094,"isNonStopTransit":true},{"id":332,"port1Id":1359,"port2Id":1068,"isNonStopTransit":true},{"id":333,"port1Id":1150,"port2Id":1361,"isNonStopTransit":true},{"id":335,"port1Id":1154,"port2Id":1363,"isNonStopTransit":false}],"connections":[],"resourceId":194,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":171,"betriebspunktName":"Fribourg","fullName":"Fribourg","positionX":-2560,"positionY":288,"ports":[{"id":1381,"trainrunSectionId":683,"positionIndex":0,"positionAlignment":2},{"id":1379,"trainrunSectionId":682,"positionIndex":1,"positionAlignment":2},{"id":1206,"trainrunSectionId":595,"positionIndex":0,"positionAlignment":3},{"id":1110,"trainrunSectionId":547,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":344,"port1Id":1379,"port2Id":1110,"isNonStopTransit":false},{"id":346,"port1Id":1381,"port2Id":1206,"isNonStopTransit":false}],"connections":[],"resourceId":195,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":172,"betriebspunktName":"RTR","fullName":"Rothrist","positionX":-608,"positionY":128,"ports":[{"id":1395,"trainrunSectionId":690,"positionIndex":0,"positionAlignment":2},{"id":1438,"trainrunSectionId":711,"positionIndex":1,"positionAlignment":2},{"id":1391,"trainrunSectionId":688,"positionIndex":2,"positionAlignment":2},{"id":1389,"trainrunSectionId":687,"positionIndex":3,"positionAlignment":2},{"id":1387,"trainrunSectionId":686,"positionIndex":4,"positionAlignment":2},{"id":1383,"trainrunSectionId":684,"positionIndex":5,"positionAlignment":2},{"id":1385,"trainrunSectionId":685,"positionIndex":6,"positionAlignment":2},{"id":1204,"trainrunSectionId":594,"positionIndex":0,"positionAlignment":3},{"id":1393,"trainrunSectionId":689,"positionIndex":1,"positionAlignment":3},{"id":1310,"trainrunSectionId":647,"positionIndex":2,"positionAlignment":3},{"id":1226,"trainrunSectionId":605,"positionIndex":3,"positionAlignment":3},{"id":1242,"trainrunSectionId":613,"positionIndex":4,"positionAlignment":3},{"id":1166,"trainrunSectionId":575,"positionIndex":5,"positionAlignment":3},{"id":1108,"trainrunSectionId":546,"positionIndex":6,"positionAlignment":3}],"transitions":[{"id":348,"port1Id":1108,"port2Id":1383,"isNonStopTransit":true},{"id":349,"port1Id":1385,"port2Id":1166,"isNonStopTransit":true},{"id":350,"port1Id":1387,"port2Id":1242,"isNonStopTransit":true},{"id":351,"port1Id":1389,"port2Id":1226,"isNonStopTransit":true},{"id":352,"port1Id":1391,"port2Id":1310,"isNonStopTransit":true},{"id":354,"port1Id":1395,"port2Id":1204,"isNonStopTransit":true},{"id":384,"port1Id":1438,"port2Id":1393,"isNonStopTransit":true}],"connections":[],"resourceId":196,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":173,"betriebspunktName":"Burgdorf","fullName":"Burgdorf","positionX":-1344,"positionY":352,"ports":[{"id":1397,"trainrunSectionId":691,"positionIndex":0,"positionAlignment":2},{"id":1400,"trainrunSectionId":692,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":356,"port1Id":1397,"port2Id":1400,"isNonStopTransit":false}],"connections":[],"resourceId":197,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":174,"betriebspunktName":"Langent.","fullName":"Langenthal","positionX":-992,"positionY":352,"ports":[{"id":1399,"trainrunSectionId":692,"positionIndex":0,"positionAlignment":2},{"id":1386,"trainrunSectionId":685,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":355,"port1Id":1399,"port2Id":1386,"isNonStopTransit":false}],"connections":[],"resourceId":198,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":175,"betriebspunktName":"Solothurn","fullName":"Solothurn","positionX":-1696,"positionY":-32,"ports":[{"id":1417,"trainrunSectionId":701,"positionIndex":0,"positionAlignment":2},{"id":1182,"trainrunSectionId":583,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":365,"port1Id":1417,"port2Id":1182,"isNonStopTransit":false}],"connections":[],"resourceId":199,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":176,"betriebspunktName":"Rohrsch.","fullName":"Rohrschach","positionX":5376,"positionY":96,"ports":[{"id":1420,"trainrunSectionId":702,"positionIndex":0,"positionAlignment":2}],"transitions":[],"connections":[],"resourceId":200,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":177,"betriebspunktName":"Morges","fullName":"Morges","positionX":-3520,"positionY":544,"ports":[{"id":1423,"trainrunSectionId":704,"positionIndex":0,"positionAlignment":2},{"id":1425,"trainrunSectionId":705,"positionIndex":1,"positionAlignment":2},{"id":1421,"trainrunSectionId":703,"positionIndex":2,"positionAlignment":2},{"id":1184,"trainrunSectionId":584,"positionIndex":0,"positionAlignment":3},{"id":1208,"trainrunSectionId":596,"positionIndex":1,"positionAlignment":3},{"id":1188,"trainrunSectionId":586,"positionIndex":2,"positionAlignment":3}],"transitions":[{"id":368,"port1Id":1421,"port2Id":1188,"isNonStopTransit":false},{"id":370,"port1Id":1423,"port2Id":1208,"isNonStopTransit":true},{"id":372,"port1Id":1425,"port2Id":1184,"isNonStopTransit":false}],"connections":[],"resourceId":201,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":178,"betriebspunktName":"BNWD","fullName":"Bern Wankdorf","positionX":-1696,"positionY":128,"ports":[{"id":1439,"trainrunSectionId":712,"positionIndex":0,"positionAlignment":2},{"id":1330,"trainrunSectionId":657,"positionIndex":1,"positionAlignment":2},{"id":1435,"trainrunSectionId":710,"positionIndex":2,"positionAlignment":2},{"id":1433,"trainrunSectionId":709,"positionIndex":3,"positionAlignment":2},{"id":1431,"trainrunSectionId":708,"positionIndex":4,"positionAlignment":2},{"id":1429,"trainrunSectionId":707,"positionIndex":5,"positionAlignment":2},{"id":1427,"trainrunSectionId":706,"positionIndex":6,"positionAlignment":2},{"id":1396,"trainrunSectionId":690,"positionIndex":0,"positionAlignment":3},{"id":1437,"trainrunSectionId":711,"positionIndex":1,"positionAlignment":3},{"id":1392,"trainrunSectionId":688,"positionIndex":2,"positionAlignment":3},{"id":1390,"trainrunSectionId":687,"positionIndex":3,"positionAlignment":3},{"id":1388,"trainrunSectionId":686,"positionIndex":4,"positionAlignment":3},{"id":1384,"trainrunSectionId":684,"positionIndex":5,"positionAlignment":3},{"id":1398,"trainrunSectionId":691,"positionIndex":6,"positionAlignment":3}],"transitions":[{"id":374,"port1Id":1427,"port2Id":1398,"isNonStopTransit":true},{"id":375,"port1Id":1429,"port2Id":1384,"isNonStopTransit":true},{"id":377,"port1Id":1431,"port2Id":1388,"isNonStopTransit":true},{"id":379,"port1Id":1433,"port2Id":1390,"isNonStopTransit":true},{"id":381,"port1Id":1435,"port2Id":1392,"isNonStopTransit":true},{"id":383,"port1Id":1330,"port2Id":1437,"isNonStopTransit":true},{"id":385,"port1Id":1439,"port2Id":1396,"isNonStopTransit":true}],"connections":[],"resourceId":202,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]}],"trainrunSections":[{"id":509,"sourceNodeId":156,"sourcePortId":1033,"targetNodeId":136,"targetPortId":1034,"travelTime":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":182},"sourceArrival":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":178},"targetDeparture":{"lock":false,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":164},"targetArrival":{"lock":false,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":196},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2640,"y":3710},{"x":2640,"y":3646},{"x":2640,"y":3390},{"x":2640,"y":3326}],"textPositions":{"0":{"x":2652,"y":3692},"1":{"x":2628,"y":3664},"2":{"x":2628,"y":3344},"3":{"x":2652,"y":3372},"4":{"x":2628,"y":3518},"5":{"x":2628,"y":3518},"6":{"x":2652,"y":3518}}},"warnings":null},{"id":510,"sourceNodeId":136,"sourcePortId":1035,"targetNodeId":158,"targetPortId":1036,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":198},"sourceArrival":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":162},"targetDeparture":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":156},"targetArrival":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":204},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2640,"y":3230},{"x":2640,"y":3166},{"x":2640,"y":2818},{"x":2640,"y":2754}],"textPositions":{"0":{"x":2652,"y":3212},"1":{"x":2628,"y":3184},"2":{"x":2628,"y":2772},"3":{"x":2652,"y":2800},"4":{"x":2628,"y":2992},"5":{"x":2628,"y":2992},"6":{"x":2652,"y":2992}}},"warnings":null},{"id":511,"sourceNodeId":155,"sourcePortId":1037,"targetNodeId":154,"targetPortId":1038,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":232},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":128},"targetDeparture":{"lock":true,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":109},"targetArrival":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":251},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":2174},{"x":2704,"y":2110},{"x":2704,"y":1950},{"x":2704,"y":1886}],"textPositions":{"0":{"x":2716,"y":2156},"1":{"x":2692,"y":2128},"2":{"x":2692,"y":1904},"3":{"x":2716,"y":1932},"4":{"x":2692,"y":2030},"5":{"x":2692,"y":2030},"6":{"x":2716,"y":2030}}},"warnings":null},{"id":512,"sourceNodeId":154,"sourcePortId":1039,"targetNodeId":169,"targetPortId":1040,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":255},"sourceArrival":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":105},"targetDeparture":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":87},"targetArrival":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":273},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":1808},{"x":2590,"y":1808},{"x":2018,"y":1808},{"x":1954,"y":1808}],"textPositions":{"0":{"x":2636,"y":1796},"1":{"x":2608,"y":1820},"2":{"x":1972,"y":1820},"3":{"x":2000,"y":1796},"4":{"x":2304,"y":1796},"5":{"x":2304,"y":1796},"6":{"x":2304,"y":1820}}},"warnings":null},{"id":513,"sourceNodeId":142,"sourcePortId":1041,"targetNodeId":141,"targetPortId":1042,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":295},"sourceArrival":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":1726},{"x":80,"y":1662},{"x":80,"y":1314},{"x":80,"y":1250}],"textPositions":{"0":{"x":92,"y":1708},"1":{"x":68,"y":1680},"2":{"x":68,"y":1268},"3":{"x":92,"y":1296},"4":{"x":68,"y":1488},"5":{"x":68,"y":1488},"6":{"x":92,"y":1488}}},"warnings":null},{"id":514,"sourceNodeId":141,"sourcePortId":1043,"targetNodeId":143,"targetPortId":1044,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"sourceArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetDeparture":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":37},"targetArrival":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":323},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":1182},{"x":80,"y":1118},{"x":80,"y":866},{"x":80,"y":802}],"textPositions":{"0":{"x":92,"y":1164},"1":{"x":68,"y":1136},"2":{"x":68,"y":820},"3":{"x":92,"y":848},"4":{"x":68,"y":992},"5":{"x":68,"y":992},"6":{"x":92,"y":992}}},"warnings":null},{"id":515,"sourceNodeId":143,"sourcePortId":1045,"targetNodeId":133,"targetPortId":1046,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":323},"sourceArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":37},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":30},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":734},{"x":80,"y":670},{"x":80,"y":414},{"x":80,"y":350}],"textPositions":{"0":{"x":92,"y":716},"1":{"x":68,"y":688},"2":{"x":68,"y":368},"3":{"x":92,"y":396},"4":{"x":68,"y":542},"5":{"x":68,"y":542},"6":{"x":92,"y":542}}},"warnings":null},{"id":516,"sourceNodeId":133,"sourcePortId":1047,"targetNodeId":144,"targetPortId":1048,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":332},"sourceArrival":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":28},"targetDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"targetArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":342},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":94},{"x":80,"y":30},{"x":80,"y":-290},{"x":80,"y":-354}],"textPositions":{"0":{"x":92,"y":76},"1":{"x":68,"y":48},"2":{"x":68,"y":-336},"3":{"x":92,"y":-308},"4":{"x":68,"y":-130},"5":{"x":68,"y":-130},"6":{"x":92,"y":-130}}},"warnings":null},{"id":517,"sourceNodeId":144,"sourcePortId":1049,"targetNodeId":145,"targetPortId":1050,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":342},"sourceArrival":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":-450},{"x":80,"y":-514},{"x":80,"y":-798},{"x":80,"y":-862}],"textPositions":{"0":{"x":92,"y":-468},"1":{"x":68,"y":-496},"2":{"x":68,"y":-844},"3":{"x":92,"y":-816},"4":{"x":68,"y":-656},"5":{"x":68,"y":-656},"6":{"x":92,"y":-656}}},"warnings":null},{"id":518,"sourceNodeId":145,"sourcePortId":1051,"targetNodeId":146,"targetPortId":1052,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":8},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":352},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":-930},{"x":80,"y":-994},{"x":80,"y":-1278},{"x":80,"y":-1342}],"textPositions":{"0":{"x":92,"y":-948},"1":{"x":68,"y":-976},"2":{"x":68,"y":-1324},"3":{"x":92,"y":-1296},"4":{"x":68,"y":-1136},"5":{"x":68,"y":-1136},"6":{"x":92,"y":-1136}}},"warnings":null},{"id":519,"sourceNodeId":146,"sourcePortId":1053,"targetNodeId":134,"targetPortId":1054,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":352},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":8},"targetDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":3},"targetArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":357},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":-1410},{"x":80,"y":-1474},{"x":80,"y":-1758},{"x":80,"y":-1822}],"textPositions":{"0":{"x":92,"y":-1428},"1":{"x":68,"y":-1456},"2":{"x":68,"y":-1804},"3":{"x":92,"y":-1776},"4":{"x":68,"y":-1616},"5":{"x":68,"y":-1616},"6":{"x":92,"y":-1616}}},"warnings":null},{"id":520,"sourceNodeId":155,"sourcePortId":1055,"targetNodeId":158,"targetPortId":1056,"travelTime":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":128},"sourceArrival":{"lock":true,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":232},"targetDeparture":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":204},"targetArrival":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":156},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":2270},{"x":2704,"y":2334},{"x":2704,"y":2622},{"x":2704,"y":2686}],"textPositions":{"0":{"x":2692,"y":2288},"1":{"x":2716,"y":2316},"2":{"x":2716,"y":2668},"3":{"x":2692,"y":2640},"4":{"x":2692,"y":2478},"5":{"x":2692,"y":2478},"6":{"x":2716,"y":2478}}},"warnings":null},{"id":521,"sourceNodeId":156,"sourcePortId":1057,"targetNodeId":136,"targetPortId":1058,"travelTime":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":2},"sourceArrival":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":118},"targetDeparture":{"lock":false,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":104},"targetArrival":{"lock":false,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":16},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2608,"y":3710},{"x":2608,"y":3646},{"x":2608,"y":3390},{"x":2608,"y":3326}],"textPositions":{"0":{"x":2620,"y":3692},"1":{"x":2596,"y":3664},"2":{"x":2596,"y":3344},"3":{"x":2620,"y":3372},"4":{"x":2596,"y":3518},"5":{"x":2596,"y":3518},"6":{"x":2620,"y":3518}}},"warnings":null},{"id":522,"sourceNodeId":136,"sourcePortId":1059,"targetNodeId":158,"targetPortId":1060,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"sourceArrival":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":102},"targetDeparture":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":96},"targetArrival":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":24},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2608,"y":3230},{"x":2608,"y":3166},{"x":2608,"y":2818},{"x":2608,"y":2754}],"textPositions":{"0":{"x":2620,"y":3212},"1":{"x":2596,"y":3184},"2":{"x":2596,"y":2772},"3":{"x":2620,"y":2800},"4":{"x":2596,"y":2992},"5":{"x":2596,"y":2992},"6":{"x":2620,"y":2992}}},"warnings":null},{"id":523,"sourceNodeId":158,"sourcePortId":1061,"targetNodeId":155,"targetPortId":1062,"travelTime":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":24},"sourceArrival":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":96},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":2686},{"x":2672,"y":2622},{"x":2672,"y":2334},{"x":2672,"y":2270}],"textPositions":{"0":{"x":2684,"y":2668},"1":{"x":2660,"y":2640},"2":{"x":2660,"y":2288},"3":{"x":2684,"y":2316},"4":{"x":2660,"y":2478},"5":{"x":2660,"y":2478},"6":{"x":2684,"y":2478}}},"warnings":null},{"id":524,"sourceNodeId":155,"sourcePortId":1063,"targetNodeId":154,"targetPortId":1064,"travelTime":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetDeparture":{"lock":true,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":49},"targetArrival":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":71},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":2174},{"x":2672,"y":2110},{"x":2672,"y":1950},{"x":2672,"y":1886}],"textPositions":{"0":{"x":2684,"y":2156},"1":{"x":2660,"y":2128},"2":{"x":2660,"y":1904},"3":{"x":2684,"y":1932},"4":{"x":2660,"y":2030},"5":{"x":2660,"y":2030},"6":{"x":2684,"y":2030}}},"warnings":null},{"id":525,"sourceNodeId":154,"sourcePortId":1065,"targetNodeId":153,"targetPortId":1066,"travelTime":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":75},"sourceArrival":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":45},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":30},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":1790},{"x":2672,"y":1726},{"x":2672,"y":1470},{"x":2672,"y":1406}],"textPositions":{"0":{"x":2684,"y":1772},"1":{"x":2660,"y":1744},"2":{"x":2660,"y":1424},"3":{"x":2684,"y":1452},"4":{"x":2660,"y":1598},"5":{"x":2660,"y":1598},"6":{"x":2684,"y":1598}}},"warnings":null},{"id":526,"sourceNodeId":153,"sourcePortId":1067,"targetNodeId":170,"targetPortId":1068,"travelTime":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":91},"sourceArrival":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":29},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":107},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":1310},{"x":2672,"y":1246},{"x":2672,"y":894},{"x":2672,"y":830}],"textPositions":{"0":{"x":2684,"y":1292},"1":{"x":2660,"y":1264},"2":{"x":2660,"y":848},"3":{"x":2684,"y":876},"4":{"x":2660,"y":1070},"5":{"x":2660,"y":1070},"6":{"x":2684,"y":1070}}},"warnings":null},{"id":527,"sourceNodeId":157,"sourcePortId":1069,"targetNodeId":136,"targetPortId":1070,"travelTime":{"lock":true,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":273},"sourceArrival":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":327},"targetDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":304},"targetArrival":{"lock":true,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":296},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2306,"y":3248},{"x":2370,"y":3248},{"x":2526,"y":3248},{"x":2590,"y":3248}],"textPositions":{"0":{"x":2324,"y":3260},"1":{"x":2352,"y":3236},"2":{"x":2572,"y":3236},"3":{"x":2544,"y":3260},"4":{"x":2448,"y":3236},"5":{"x":2448,"y":3236},"6":{"x":2448,"y":3260}}},"warnings":null},{"id":528,"sourceNodeId":136,"sourcePortId":1071,"targetNodeId":158,"targetPortId":1072,"travelTime":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":300},"sourceArrival":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":300},"targetDeparture":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":285},"targetArrival":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":315},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":3230},{"x":2672,"y":3166},{"x":2672,"y":2818},{"x":2672,"y":2754}],"textPositions":{"0":{"x":2684,"y":3212},"1":{"x":2660,"y":3184},"2":{"x":2660,"y":2772},"3":{"x":2684,"y":2800},"4":{"x":2660,"y":2992},"5":{"x":2660,"y":2992},"6":{"x":2684,"y":2992}}},"warnings":null},{"id":529,"sourceNodeId":158,"sourcePortId":1073,"targetNodeId":159,"targetPortId":1074,"travelTime":{"lock":true,"time":53,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":316},"sourceArrival":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":284},"targetDeparture":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":231},"targetArrival":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":369},"numberOfStops":5,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2608,"y":2686},{"x":2608,"y":2622},{"x":2288,"y":2398},{"x":2288,"y":2334}],"textPositions":{"0":{"x":2620,"y":2668},"1":{"x":2596,"y":2640},"2":{"x":2276,"y":2352},"3":{"x":2300,"y":2380},"4":{"x":2460,"y":2510},"5":{"x":2460,"y":2510},"6":{"x":2436,"y":2510}}},"warnings":null},{"id":530,"sourceNodeId":159,"sourcePortId":1075,"targetNodeId":155,"targetPortId":1076,"travelTime":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":370},"sourceArrival":{"lock":true,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":230},"targetDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":198},"targetArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":402},"numberOfStops":1,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2370,"y":2256},{"x":2434,"y":2256},{"x":2590,"y":2192},{"x":2654,"y":2192}],"textPositions":{"0":{"x":2388,"y":2268},"1":{"x":2416,"y":2244},"2":{"x":2636,"y":2180},"3":{"x":2608,"y":2204},"4":{"x":2512,"y":2212},"5":{"x":2512,"y":2212},"6":{"x":2512,"y":2236}}},"warnings":null},{"id":531,"sourceNodeId":155,"sourcePortId":1077,"targetNodeId":154,"targetPortId":1078,"travelTime":{"lock":true,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":403},"sourceArrival":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":197},"targetDeparture":{"lock":true,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":174},"targetArrival":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":426},"numberOfStops":3,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2736,"y":2174},{"x":2736,"y":2110},{"x":2736,"y":1950},{"x":2736,"y":1886}],"textPositions":{"0":{"x":2748,"y":2156},"1":{"x":2724,"y":2128},"2":{"x":2724,"y":1904},"3":{"x":2748,"y":1932},"4":{"x":2724,"y":2030},"5":{"x":2724,"y":2030},"6":{"x":2748,"y":2030}}},"warnings":null},{"id":532,"sourceNodeId":154,"sourcePortId":1079,"targetNodeId":169,"targetPortId":1080,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":435},"sourceArrival":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":165},"targetDeparture":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":147},"targetArrival":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":453},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":1840},{"x":2590,"y":1840},{"x":2018,"y":1840},{"x":1954,"y":1840}],"textPositions":{"0":{"x":2636,"y":1828},"1":{"x":2608,"y":1852},"2":{"x":1972,"y":1852},"3":{"x":2000,"y":1828},"4":{"x":2304,"y":1828},"5":{"x":2304,"y":1828},"6":{"x":2304,"y":1852}}},"warnings":null},{"id":533,"sourceNodeId":157,"sourcePortId":1081,"targetNodeId":136,"targetPortId":1082,"travelTime":{"lock":true,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":153},"sourceArrival":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":207},"targetDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":184},"targetArrival":{"lock":true,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":176},"numberOfStops":3,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2306,"y":3280},{"x":2370,"y":3280},{"x":2526,"y":3280},{"x":2590,"y":3280}],"textPositions":{"0":{"x":2324,"y":3292},"1":{"x":2352,"y":3268},"2":{"x":2572,"y":3268},"3":{"x":2544,"y":3292},"4":{"x":2448,"y":3268},"5":{"x":2448,"y":3268},"6":{"x":2448,"y":3292}}},"warnings":null},{"id":534,"sourceNodeId":136,"sourcePortId":1083,"targetNodeId":158,"targetPortId":1084,"travelTime":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":180},"sourceArrival":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":180},"targetDeparture":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":165},"targetArrival":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":195},"numberOfStops":1,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":3230},{"x":2704,"y":3166},{"x":2704,"y":2818},{"x":2704,"y":2754}],"textPositions":{"0":{"x":2716,"y":3212},"1":{"x":2692,"y":3184},"2":{"x":2692,"y":2772},"3":{"x":2716,"y":2800},"4":{"x":2692,"y":2992},"5":{"x":2692,"y":2992},"6":{"x":2716,"y":2992}}},"warnings":null},{"id":535,"sourceNodeId":158,"sourcePortId":1085,"targetNodeId":159,"targetPortId":1086,"travelTime":{"lock":true,"time":53,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":196},"sourceArrival":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":164},"targetDeparture":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":111},"targetArrival":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":249},"numberOfStops":5,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2640,"y":2686},{"x":2640,"y":2622},{"x":2320,"y":2398},{"x":2320,"y":2334}],"textPositions":{"0":{"x":2652,"y":2668},"1":{"x":2628,"y":2640},"2":{"x":2308,"y":2352},"3":{"x":2332,"y":2380},"4":{"x":2492,"y":2510},"5":{"x":2492,"y":2510},"6":{"x":2468,"y":2510}}},"warnings":null},{"id":536,"sourceNodeId":159,"sourcePortId":1087,"targetNodeId":155,"targetPortId":1088,"travelTime":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":250},"sourceArrival":{"lock":true,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":110},"targetDeparture":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":78},"targetArrival":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":282},"numberOfStops":1,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2370,"y":2288},{"x":2434,"y":2288},{"x":2590,"y":2224},{"x":2654,"y":2224}],"textPositions":{"0":{"x":2388,"y":2300},"1":{"x":2416,"y":2276},"2":{"x":2636,"y":2212},"3":{"x":2608,"y":2236},"4":{"x":2512,"y":2244},"5":{"x":2512,"y":2244},"6":{"x":2512,"y":2268}}},"warnings":null},{"id":537,"sourceNodeId":155,"sourcePortId":1089,"targetNodeId":154,"targetPortId":1090,"travelTime":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":283},"sourceArrival":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":77},"targetDeparture":{"lock":true,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":54},"targetArrival":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":306},"numberOfStops":3,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2768,"y":2174},{"x":2768,"y":2110},{"x":2768,"y":1950},{"x":2768,"y":1886}],"textPositions":{"0":{"x":2780,"y":2156},"1":{"x":2756,"y":2128},"2":{"x":2756,"y":1904},"3":{"x":2780,"y":1932},"4":{"x":2756,"y":2030},"5":{"x":2756,"y":2030},"6":{"x":2780,"y":2030}}},"warnings":null},{"id":538,"sourceNodeId":154,"sourcePortId":1091,"targetNodeId":153,"targetPortId":1092,"travelTime":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":315},"sourceArrival":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":45},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":30},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"numberOfStops":0,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":1790},{"x":2704,"y":1726},{"x":2704,"y":1470},{"x":2704,"y":1406}],"textPositions":{"0":{"x":2716,"y":1772},"1":{"x":2692,"y":1744},"2":{"x":2692,"y":1424},"3":{"x":2716,"y":1452},"4":{"x":2692,"y":1598},"5":{"x":2692,"y":1598},"6":{"x":2716,"y":1598}}},"warnings":null},{"id":539,"sourceNodeId":153,"sourcePortId":1093,"targetNodeId":170,"targetPortId":1094,"travelTime":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":331},"sourceArrival":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":29},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"numberOfStops":0,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":1310},{"x":2704,"y":1246},{"x":2704,"y":894},{"x":2704,"y":830}],"textPositions":{"0":{"x":2716,"y":1292},"1":{"x":2692,"y":1264},"2":{"x":2692,"y":848},"3":{"x":2716,"y":876},"4":{"x":2692,"y":1070},"5":{"x":2692,"y":1070},"6":{"x":2716,"y":1070}}},"warnings":null},{"id":540,"sourceNodeId":142,"sourcePortId":1095,"targetNodeId":169,"targetPortId":1096,"travelTime":{"lock":false,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"sourceArrival":{"lock":true,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":265},"targetDeparture":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":253},"targetArrival":{"lock":true,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":47},"numberOfStops":0,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":226,"y":1840},{"x":290,"y":1840},{"x":1790,"y":1840},{"x":1854,"y":1840}],"textPositions":{"0":{"x":244,"y":1852},"1":{"x":272,"y":1828},"2":{"x":1836,"y":1828},"3":{"x":1808,"y":1852},"4":{"x":1040,"y":1828},"5":{"x":1040,"y":1828},"6":{"x":1040,"y":1852}}},"warnings":null},{"id":541,"sourceNodeId":153,"sourcePortId":1097,"targetNodeId":170,"targetPortId":1098,"travelTime":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":58},"sourceArrival":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":242},"targetDeparture":{"lock":true,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":227},"targetArrival":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":73},"numberOfStops":1,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2768,"y":1310},{"x":2768,"y":1246},{"x":2768,"y":894},{"x":2768,"y":830}],"textPositions":{"0":{"x":2780,"y":1292},"1":{"x":2756,"y":1264},"2":{"x":2756,"y":848},"3":{"x":2780,"y":876},"4":{"x":2756,"y":1070},"5":{"x":2756,"y":1070},"6":{"x":2780,"y":1070}}},"warnings":null},{"id":542,"sourceNodeId":142,"sourcePortId":1099,"targetNodeId":169,"targetPortId":1100,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":9},"sourceArrival":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":51},"targetDeparture":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":42},"targetArrival":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"numberOfStops":0,"trainrunId":80,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":226,"y":1808},{"x":290,"y":1808},{"x":1790,"y":1808},{"x":1854,"y":1808}],"textPositions":{"0":{"x":244,"y":1820},"1":{"x":272,"y":1796},"2":{"x":1836,"y":1796},"3":{"x":1808,"y":1820},"4":{"x":1040,"y":1796},"5":{"x":1040,"y":1796},"6":{"x":1040,"y":1820}}},"warnings":null},{"id":543,"sourceNodeId":153,"sourcePortId":1101,"targetNodeId":170,"targetPortId":1102,"travelTime":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":29},"sourceArrival":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":31},"targetDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":17},"targetArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":43},"numberOfStops":0,"trainrunId":80,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2736,"y":1310},{"x":2736,"y":1246},{"x":2736,"y":894},{"x":2736,"y":830}],"textPositions":{"0":{"x":2748,"y":1292},"1":{"x":2724,"y":1264},"2":{"x":2724,"y":848},"3":{"x":2748,"y":876},"4":{"x":2724,"y":1070},"5":{"x":2724,"y":1070},"6":{"x":2748,"y":1070}}},"warnings":null},{"id":544,"sourceNodeId":142,"sourcePortId":1103,"targetNodeId":141,"targetPortId":1104,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":299},"sourceArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":241},"targetDeparture":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":222},"targetArrival":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":318},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":1726},{"x":112,"y":1662},{"x":112,"y":1314},{"x":112,"y":1250}],"textPositions":{"0":{"x":124,"y":1708},"1":{"x":100,"y":1680},"2":{"x":100,"y":1268},"3":{"x":124,"y":1296},"4":{"x":100,"y":1488},"5":{"x":100,"y":1488},"6":{"x":124,"y":1488}}},"warnings":null},{"id":545,"sourceNodeId":141,"sourcePortId":1105,"targetNodeId":143,"targetPortId":1106,"travelTime":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":319},"sourceArrival":{"lock":true,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":221},"targetDeparture":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":209},"targetArrival":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":331},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":1182},{"x":112,"y":1118},{"x":112,"y":866},{"x":112,"y":802}],"textPositions":{"0":{"x":124,"y":1164},"1":{"x":100,"y":1136},"2":{"x":100,"y":820},"3":{"x":124,"y":848},"4":{"x":100,"y":992},"5":{"x":100,"y":992},"6":{"x":124,"y":992}}},"warnings":null},{"id":546,"sourceNodeId":143,"sourcePortId":1107,"targetNodeId":172,"targetPortId":1108,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":332},"sourceArrival":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":208},"targetDeparture":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":202},"targetArrival":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":338},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":752},{"x":-2,"y":752},{"x":-446,"y":336},{"x":-510,"y":336}],"textPositions":{"0":{"x":44,"y":740},"1":{"x":16,"y":764},"2":{"x":-492,"y":348},"3":{"x":-464,"y":324},"4":{"x":-224,"y":532},"5":{"x":-224,"y":532},"6":{"x":-224,"y":556}}},"warnings":null},{"id":547,"sourceNodeId":129,"sourcePortId":1109,"targetNodeId":171,"targetPortId":1110,"travelTime":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":364},"sourceArrival":{"lock":true,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":176},"targetDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":154},"targetArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":386},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2146,"y":176},{"x":-2210,"y":176},{"x":-2398,"y":336},{"x":-2462,"y":336}],"textPositions":{"0":{"x":-2164,"y":164},"1":{"x":-2192,"y":188},"2":{"x":-2444,"y":348},"3":{"x":-2416,"y":324},"4":{"x":-2304,"y":244},"5":{"x":-2304,"y":244},"6":{"x":-2304,"y":268}}},"warnings":null},{"id":548,"sourceNodeId":142,"sourcePortId":1111,"targetNodeId":141,"targetPortId":1112,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"sourceArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetDeparture":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":72},"targetArrival":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":108},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":1726},{"x":208,"y":1662},{"x":208,"y":1314},{"x":208,"y":1250}],"textPositions":{"0":{"x":220,"y":1708},"1":{"x":196,"y":1680},"2":{"x":196,"y":1268},"3":{"x":220,"y":1296},"4":{"x":196,"y":1488},"5":{"x":196,"y":1488},"6":{"x":220,"y":1488}}},"warnings":null},{"id":549,"sourceNodeId":141,"sourcePortId":1113,"targetNodeId":143,"targetPortId":1114,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":109},"sourceArrival":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":71},"targetDeparture":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":58},"targetArrival":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":122},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":1182},{"x":208,"y":1118},{"x":208,"y":866},{"x":208,"y":802}],"textPositions":{"0":{"x":220,"y":1164},"1":{"x":196,"y":1136},"2":{"x":196,"y":820},"3":{"x":220,"y":848},"4":{"x":196,"y":992},"5":{"x":196,"y":992},"6":{"x":220,"y":992}}},"warnings":null},{"id":550,"sourceNodeId":143,"sourcePortId":1115,"targetNodeId":133,"targetPortId":1116,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":124},"sourceArrival":{"lock":true,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":56},"targetDeparture":{"lock":true,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":49},"targetArrival":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":131},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":734},{"x":176,"y":670},{"x":176,"y":414},{"x":176,"y":350}],"textPositions":{"0":{"x":188,"y":716},"1":{"x":164,"y":688},"2":{"x":164,"y":368},"3":{"x":188,"y":396},"4":{"x":164,"y":542},"5":{"x":164,"y":542},"6":{"x":188,"y":542}}},"warnings":null},{"id":551,"sourceNodeId":133,"sourcePortId":1117,"targetNodeId":144,"targetPortId":1118,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":132},"sourceArrival":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":48},"targetDeparture":{"lock":true,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":38},"targetArrival":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":142},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":240,"y":94},{"x":240,"y":30},{"x":240,"y":-290},{"x":240,"y":-354}],"textPositions":{"0":{"x":252,"y":76},"1":{"x":228,"y":48},"2":{"x":228,"y":-336},"3":{"x":252,"y":-308},"4":{"x":228,"y":-130},"5":{"x":228,"y":-130},"6":{"x":252,"y":-130}}},"warnings":null},{"id":552,"sourceNodeId":144,"sourcePortId":1119,"targetNodeId":145,"targetPortId":1120,"travelTime":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":143},"sourceArrival":{"lock":true,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":37},"targetDeparture":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":33},"targetArrival":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":147},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":304,"y":-450},{"x":304,"y":-514},{"x":304,"y":-798},{"x":304,"y":-862}],"textPositions":{"0":{"x":316,"y":-468},"1":{"x":292,"y":-496},"2":{"x":292,"y":-844},"3":{"x":316,"y":-816},"4":{"x":292,"y":-656},"5":{"x":292,"y":-656},"6":{"x":316,"y":-656}}},"warnings":null},{"id":553,"sourceNodeId":145,"sourcePortId":1121,"targetNodeId":146,"targetPortId":1122,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":148},"sourceArrival":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":32},"targetDeparture":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":27},"targetArrival":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":153},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":304,"y":-930},{"x":304,"y":-994},{"x":304,"y":-1278},{"x":304,"y":-1342}],"textPositions":{"0":{"x":316,"y":-948},"1":{"x":292,"y":-976},"2":{"x":292,"y":-1324},"3":{"x":316,"y":-1296},"4":{"x":292,"y":-1136},"5":{"x":292,"y":-1136},"6":{"x":316,"y":-1136}}},"warnings":null},{"id":554,"sourceNodeId":146,"sourcePortId":1123,"targetNodeId":134,"targetPortId":1124,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":154},"sourceArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":26},"targetDeparture":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":16},"targetArrival":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":164},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":304,"y":-1410},{"x":304,"y":-1474},{"x":304,"y":-1758},{"x":304,"y":-1822}],"textPositions":{"0":{"x":316,"y":-1428},"1":{"x":292,"y":-1456},"2":{"x":292,"y":-1804},"3":{"x":316,"y":-1776},"4":{"x":292,"y":-1616},"5":{"x":292,"y":-1616},"6":{"x":316,"y":-1616}}},"warnings":null},{"id":555,"sourceNodeId":142,"sourcePortId":1125,"targetNodeId":141,"targetPortId":1126,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":115},"sourceArrival":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":1726},{"x":176,"y":1662},{"x":176,"y":1314},{"x":176,"y":1250}],"textPositions":{"0":{"x":188,"y":1708},"1":{"x":164,"y":1680},"2":{"x":164,"y":1268},"3":{"x":188,"y":1296},"4":{"x":164,"y":1488},"5":{"x":164,"y":1488},"6":{"x":188,"y":1488}}},"warnings":null},{"id":556,"sourceNodeId":141,"sourcePortId":1127,"targetNodeId":143,"targetPortId":1128,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"sourceArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":38},"targetArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":142},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":1182},{"x":176,"y":1118},{"x":176,"y":866},{"x":176,"y":802}],"textPositions":{"0":{"x":188,"y":1164},"1":{"x":164,"y":1136},"2":{"x":164,"y":820},"3":{"x":188,"y":848},"4":{"x":164,"y":992},"5":{"x":164,"y":992},"6":{"x":188,"y":992}}},"warnings":null},{"id":557,"sourceNodeId":143,"sourcePortId":1129,"targetNodeId":133,"targetPortId":1130,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":142},"sourceArrival":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":38},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":30},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":150},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":734},{"x":144,"y":670},{"x":144,"y":414},{"x":144,"y":350}],"textPositions":{"0":{"x":156,"y":716},"1":{"x":132,"y":688},"2":{"x":132,"y":368},"3":{"x":156,"y":396},"4":{"x":132,"y":542},"5":{"x":132,"y":542},"6":{"x":156,"y":542}}},"warnings":null},{"id":558,"sourceNodeId":133,"sourcePortId":1131,"targetNodeId":144,"targetPortId":1132,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":152},"sourceArrival":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":28},"targetDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"targetArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":162},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":94},{"x":208,"y":30},{"x":208,"y":-290},{"x":208,"y":-354}],"textPositions":{"0":{"x":220,"y":76},"1":{"x":196,"y":48},"2":{"x":196,"y":-336},"3":{"x":220,"y":-308},"4":{"x":196,"y":-130},"5":{"x":196,"y":-130},"6":{"x":220,"y":-130}}},"warnings":null},{"id":559,"sourceNodeId":144,"sourcePortId":1133,"targetNodeId":145,"targetPortId":1134,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":162},"sourceArrival":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":167},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":272,"y":-450},{"x":272,"y":-514},{"x":272,"y":-798},{"x":272,"y":-862}],"textPositions":{"0":{"x":284,"y":-468},"1":{"x":260,"y":-496},"2":{"x":260,"y":-844},"3":{"x":284,"y":-816},"4":{"x":260,"y":-656},"5":{"x":260,"y":-656},"6":{"x":284,"y":-656}}},"warnings":null},{"id":560,"sourceNodeId":145,"sourcePortId":1135,"targetNodeId":146,"targetPortId":1136,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":167},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":8},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":172},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":272,"y":-930},{"x":272,"y":-994},{"x":272,"y":-1278},{"x":272,"y":-1342}],"textPositions":{"0":{"x":284,"y":-948},"1":{"x":260,"y":-976},"2":{"x":260,"y":-1324},"3":{"x":284,"y":-1296},"4":{"x":260,"y":-1136},"5":{"x":260,"y":-1136},"6":{"x":284,"y":-1136}}},"warnings":null},{"id":561,"sourceNodeId":146,"sourcePortId":1137,"targetNodeId":134,"targetPortId":1138,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":172},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":8},"targetDeparture":{"lock":false,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":3},"targetArrival":{"lock":false,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":177},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":272,"y":-1410},{"x":272,"y":-1474},{"x":272,"y":-1758},{"x":272,"y":-1822}],"textPositions":{"0":{"x":284,"y":-1428},"1":{"x":260,"y":-1456},"2":{"x":260,"y":-1804},"3":{"x":284,"y":-1776},"4":{"x":260,"y":-1616},"5":{"x":260,"y":-1616},"6":{"x":284,"y":-1616}}},"warnings":null},{"id":562,"sourceNodeId":135,"sourcePortId":1139,"targetNodeId":150,"targetPortId":1140,"travelTime":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":9},"sourceArrival":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":291},"targetDeparture":{"lock":true,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":279},"targetArrival":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":21},"numberOfStops":1,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":176},{"x":2914,"y":176},{"x":3230,"y":176},{"x":3294,"y":176}],"textPositions":{"0":{"x":2868,"y":188},"1":{"x":2896,"y":164},"2":{"x":3276,"y":164},"3":{"x":3248,"y":188},"4":{"x":3072,"y":164},"5":{"x":3072,"y":164},"6":{"x":3072,"y":188}}},"warnings":null},{"id":563,"sourceNodeId":150,"sourcePortId":1141,"targetNodeId":151,"targetPortId":1142,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":23},"sourceArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":277},"targetDeparture":{"lock":true,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":264},"targetArrival":{"lock":true,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":36},"numberOfStops":0,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3394,"y":176},{"x":3458,"y":176},{"x":3806,"y":176},{"x":3870,"y":176}],"textPositions":{"0":{"x":3412,"y":188},"1":{"x":3440,"y":164},"2":{"x":3852,"y":164},"3":{"x":3824,"y":188},"4":{"x":3632,"y":164},"5":{"x":3632,"y":164},"6":{"x":3632,"y":188}}},"warnings":null},{"id":564,"sourceNodeId":151,"sourcePortId":1143,"targetNodeId":137,"targetPortId":1144,"travelTime":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":38},"sourceArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":262},"targetDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":218},"targetArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":82},"numberOfStops":4,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3970,"y":176},{"x":4034,"y":176},{"x":4574,"y":176},{"x":4638,"y":176}],"textPositions":{"0":{"x":3988,"y":188},"1":{"x":4016,"y":164},"2":{"x":4620,"y":164},"3":{"x":4592,"y":188},"4":{"x":4304,"y":164},"5":{"x":4304,"y":164},"6":{"x":4304,"y":188}}},"warnings":null},{"id":565,"sourceNodeId":137,"sourcePortId":1145,"targetNodeId":140,"targetPortId":1146,"travelTime":{"lock":true,"time":61,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":84},"sourceArrival":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":216},"targetDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":155},"targetArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":145},"numberOfStops":5,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4656,"y":222},{"x":4656,"y":286},{"x":4656,"y":1118},{"x":4656,"y":1182}],"textPositions":{"0":{"x":4644,"y":240},"1":{"x":4668,"y":268},"2":{"x":4668,"y":1164},"3":{"x":4644,"y":1136},"4":{"x":4644,"y":702},"5":{"x":4644,"y":702},"6":{"x":4668,"y":702}}},"warnings":null},{"id":566,"sourceNodeId":140,"sourcePortId":1147,"targetNodeId":152,"targetPortId":1148,"travelTime":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":146},"sourceArrival":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":154},"targetDeparture":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":132},"targetArrival":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":168},"numberOfStops":2,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4688,"y":1278},{"x":4688,"y":1342},{"x":4688,"y":1822},{"x":4688,"y":1886}],"textPositions":{"0":{"x":4676,"y":1296},"1":{"x":4700,"y":1324},"2":{"x":4700,"y":1868},"3":{"x":4676,"y":1840},"4":{"x":4676,"y":1582},"5":{"x":4676,"y":1582},"6":{"x":4700,"y":1582}}},"warnings":null},{"id":567,"sourceNodeId":135,"sourcePortId":1149,"targetNodeId":170,"targetPortId":1150,"travelTime":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":67},"sourceArrival":{"lock":true,"time":53,"warning":null,"timeFormatter":null,"consecutiveTime":293},"targetDeparture":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":285},"targetArrival":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":75},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":350},{"x":2704,"y":414},{"x":2704,"y":670},{"x":2704,"y":734}],"textPositions":{"0":{"x":2692,"y":368},"1":{"x":2716,"y":396},"2":{"x":2716,"y":716},"3":{"x":2692,"y":688},"4":{"x":2692,"y":542},"5":{"x":2692,"y":542},"6":{"x":2716,"y":542}}},"warnings":null},{"id":568,"sourceNodeId":140,"sourcePortId":1151,"targetNodeId":152,"targetPortId":1152,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":123},"sourceArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":237},"targetDeparture":{"lock":true,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":218},"targetArrival":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":142},"numberOfStops":1,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4656,"y":1278},{"x":4656,"y":1342},{"x":4656,"y":1822},{"x":4656,"y":1886}],"textPositions":{"0":{"x":4644,"y":1296},"1":{"x":4668,"y":1324},"2":{"x":4668,"y":1868},"3":{"x":4644,"y":1840},"4":{"x":4644,"y":1582},"5":{"x":4644,"y":1582},"6":{"x":4668,"y":1582}}},"warnings":null},{"id":569,"sourceNodeId":135,"sourcePortId":1153,"targetNodeId":170,"targetPortId":1154,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":132},"sourceArrival":{"lock":false,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":288},"targetDeparture":{"lock":true,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":280},"targetArrival":{"lock":true,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":140},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2736,"y":350},{"x":2736,"y":414},{"x":2736,"y":670},{"x":2736,"y":734}],"textPositions":{"0":{"x":2724,"y":368},"1":{"x":2748,"y":396},"2":{"x":2748,"y":716},"3":{"x":2724,"y":688},"4":{"x":2724,"y":542},"5":{"x":2724,"y":542},"6":{"x":2748,"y":542}}},"warnings":null},{"id":570,"sourceNodeId":140,"sourcePortId":1155,"targetNodeId":152,"targetPortId":1156,"travelTime":{"lock":true,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":203},"sourceArrival":{"lock":true,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":217},"targetDeparture":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":197},"targetArrival":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":223},"numberOfStops":1,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4720,"y":1278},{"x":4720,"y":1342},{"x":4720,"y":1822},{"x":4720,"y":1886}],"textPositions":{"0":{"x":4708,"y":1296},"1":{"x":4732,"y":1324},"2":{"x":4732,"y":1868},"3":{"x":4708,"y":1840},"4":{"x":4708,"y":1582},"5":{"x":4708,"y":1582},"6":{"x":4732,"y":1582}}},"warnings":null},{"id":571,"sourceNodeId":135,"sourcePortId":1157,"targetNodeId":149,"targetPortId":1158,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":294},"sourceArrival":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":126},"targetDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":119},"targetArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":301},"numberOfStops":1,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":240},{"x":2590,"y":240},{"x":2402,"y":240},{"x":2338,"y":240}],"textPositions":{"0":{"x":2636,"y":228},"1":{"x":2608,"y":252},"2":{"x":2356,"y":252},"3":{"x":2384,"y":228},"4":{"x":2496,"y":228},"5":{"x":2496,"y":228},"6":{"x":2496,"y":252}}},"warnings":null},{"id":572,"sourceNodeId":149,"sourcePortId":1159,"targetNodeId":166,"targetPortId":1160,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":301},"sourceArrival":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":119},"targetDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":240},{"x":2174,"y":240},{"x":1954,"y":240},{"x":1890,"y":240}],"textPositions":{"0":{"x":2220,"y":228},"1":{"x":2192,"y":252},"2":{"x":1908,"y":252},"3":{"x":1936,"y":228},"4":{"x":2064,"y":228},"5":{"x":2064,"y":228},"6":{"x":2064,"y":252}}},"warnings":null},{"id":573,"sourceNodeId":148,"sourcePortId":1161,"targetNodeId":147,"targetPortId":1162,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":315},"sourceArrival":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":105},"targetDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":98},"targetArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":322},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":240},{"x":1278,"y":240},{"x":1122,"y":240},{"x":1058,"y":240}],"textPositions":{"0":{"x":1324,"y":228},"1":{"x":1296,"y":252},"2":{"x":1076,"y":252},"3":{"x":1104,"y":228},"4":{"x":1200,"y":228},"5":{"x":1200,"y":228},"6":{"x":1200,"y":252}}},"warnings":null},{"id":574,"sourceNodeId":147,"sourcePortId":1163,"targetNodeId":133,"targetPortId":1164,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":322},"sourceArrival":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":98},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":240},{"x":894,"y":240},{"x":322,"y":240},{"x":258,"y":240}],"textPositions":{"0":{"x":940,"y":228},"1":{"x":912,"y":252},"2":{"x":276,"y":252},"3":{"x":304,"y":228},"4":{"x":608,"y":228},"5":{"x":608,"y":228},"6":{"x":608,"y":252}}},"warnings":null},{"id":575,"sourceNodeId":133,"sourcePortId":1165,"targetNodeId":172,"targetPortId":1166,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":336},"sourceArrival":{"lock":true,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":84},"targetDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":77},"targetArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":343},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":304},{"x":-2,"y":304},{"x":-446,"y":304},{"x":-510,"y":304}],"textPositions":{"0":{"x":44,"y":292},"1":{"x":16,"y":316},"2":{"x":-492,"y":316},"3":{"x":-464,"y":292},"4":{"x":-224,"y":292},"5":{"x":-224,"y":292},"6":{"x":-224,"y":316}}},"warnings":null},{"id":576,"sourceNodeId":137,"sourcePortId":1167,"targetNodeId":151,"targetPortId":1168,"travelTime":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":298},"sourceArrival":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":242},"targetDeparture":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":209},"targetArrival":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":331},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4638,"y":144},{"x":4574,"y":144},{"x":4034,"y":144},{"x":3970,"y":144}],"textPositions":{"0":{"x":4620,"y":132},"1":{"x":4592,"y":156},"2":{"x":3988,"y":156},"3":{"x":4016,"y":132},"4":{"x":4304,"y":132},"5":{"x":4304,"y":132},"6":{"x":4304,"y":156}}},"warnings":null},{"id":577,"sourceNodeId":151,"sourcePortId":1169,"targetNodeId":150,"targetPortId":1170,"travelTime":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":333},"sourceArrival":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":207},"targetDeparture":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":193},"targetArrival":{"lock":true,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3870,"y":80},{"x":3806,"y":80},{"x":3458,"y":80},{"x":3394,"y":80}],"textPositions":{"0":{"x":3852,"y":68},"1":{"x":3824,"y":92},"2":{"x":3412,"y":92},"3":{"x":3440,"y":68},"4":{"x":3632,"y":68},"5":{"x":3632,"y":68},"6":{"x":3632,"y":92}}},"warnings":null},{"id":578,"sourceNodeId":150,"sourcePortId":1171,"targetNodeId":135,"targetPortId":1172,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":348},"sourceArrival":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":192},"targetDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":183},"targetArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":357},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3294,"y":80},{"x":3230,"y":80},{"x":2914,"y":80},{"x":2850,"y":80}],"textPositions":{"0":{"x":3276,"y":68},"1":{"x":3248,"y":92},"2":{"x":2868,"y":92},"3":{"x":2896,"y":68},"4":{"x":3072,"y":68},"5":{"x":3072,"y":68},"6":{"x":3072,"y":92}}},"warnings":null},{"id":579,"sourceNodeId":135,"sourcePortId":1173,"targetNodeId":149,"targetPortId":1174,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":364},"sourceArrival":{"lock":true,"time":56,"warning":{"title":"Source Arrival Warning","description":"Source arrival time cannot be reached"},"timeFormatter":null,"consecutiveTime":176},"targetDeparture":{"lock":false,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":170},"targetArrival":{"lock":false,"time":10,"warning":{"title":"Target Arrival Warning","description":"Target arrival time cannot be reached"},"timeFormatter":null,"consecutiveTime":370},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":144},{"x":2590,"y":144},{"x":2402,"y":144},{"x":2338,"y":144}],"textPositions":{"0":{"x":2636,"y":132},"1":{"x":2608,"y":156},"2":{"x":2356,"y":156},"3":{"x":2384,"y":132},"4":{"x":2496,"y":132},"5":{"x":2496,"y":132},"6":{"x":2496,"y":156}}},"warnings":null},{"id":580,"sourceNodeId":149,"sourcePortId":1175,"targetNodeId":166,"targetPortId":1176,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":370},"sourceArrival":{"lock":false,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":170},"targetDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":377},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":144},{"x":2174,"y":144},{"x":1954,"y":144},{"x":1890,"y":144}],"textPositions":{"0":{"x":2220,"y":132},"1":{"x":2192,"y":156},"2":{"x":1908,"y":156},"3":{"x":1936,"y":132},"4":{"x":2064,"y":132},"5":{"x":2064,"y":132},"6":{"x":2064,"y":156}}},"warnings":null},{"id":581,"sourceNodeId":148,"sourcePortId":1177,"targetNodeId":147,"targetPortId":1178,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":384},"sourceArrival":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":156},"targetDeparture":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":151},"targetArrival":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":389},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":144},{"x":1278,"y":144},{"x":1122,"y":144},{"x":1058,"y":144}],"textPositions":{"0":{"x":1324,"y":132},"1":{"x":1296,"y":156},"2":{"x":1076,"y":156},"3":{"x":1104,"y":132},"4":{"x":1200,"y":132},"5":{"x":1200,"y":132},"6":{"x":1200,"y":156}}},"warnings":null},{"id":582,"sourceNodeId":147,"sourcePortId":1179,"targetNodeId":133,"targetPortId":1180,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":391},"sourceArrival":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":149},"targetDeparture":{"lock":true,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":140},"targetArrival":{"lock":true,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":400},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":144},{"x":894,"y":144},{"x":322,"y":144},{"x":258,"y":144}],"textPositions":{"0":{"x":940,"y":132},"1":{"x":912,"y":156},"2":{"x":276,"y":156},"3":{"x":304,"y":132},"4":{"x":608,"y":132},"5":{"x":608,"y":132},"6":{"x":608,"y":156}}},"warnings":null},{"id":583,"sourceNodeId":133,"sourcePortId":1181,"targetNodeId":175,"targetPortId":1182,"travelTime":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":402},"sourceArrival":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":138},"targetDeparture":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":121},"targetArrival":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":419},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":112},{"x":-2,"y":112},{"x":-1534,"y":-16},{"x":-1598,"y":-16}],"textPositions":{"0":{"x":44,"y":100},"1":{"x":16,"y":124},"2":{"x":-1580,"y":-4},"3":{"x":-1552,"y":-28},"4":{"x":-768,"y":36},"5":{"x":-768,"y":36},"6":{"x":-768,"y":60}}},"warnings":null},{"id":584,"sourceNodeId":130,"sourcePortId":1183,"targetNodeId":177,"targetPortId":1184,"travelTime":{"lock":false,"time":61,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":437},"sourceArrival":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":103},"targetDeparture":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":42},"targetArrival":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":498},"numberOfStops":2,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2530,"y":-16},{"x":-2594,"y":-16},{"x":-3358,"y":560},{"x":-3422,"y":560}],"textPositions":{"0":{"x":-2548,"y":-28},"1":{"x":-2576,"y":-4},"2":{"x":-3404,"y":572},"3":{"x":-3376,"y":548},"4":{"x":-2976,"y":260},"5":{"x":-2976,"y":260},"6":{"x":-2976,"y":284}}},"warnings":null},{"id":585,"sourceNodeId":160,"sourcePortId":1185,"targetNodeId":161,"targetPortId":1186,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":528},"sourceArrival":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":12},"targetDeparture":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":4},"targetArrival":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":536},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3938,"y":656},{"x":-4002,"y":656},{"x":-4190,"y":656},{"x":-4254,"y":656}],"textPositions":{"0":{"x":-3956,"y":644},"1":{"x":-3984,"y":668},"2":{"x":-4236,"y":668},"3":{"x":-4208,"y":644},"4":{"x":-4096,"y":644},"5":{"x":-4096,"y":644},"6":{"x":-4096,"y":668}}},"warnings":null},{"id":586,"sourceNodeId":128,"sourcePortId":1187,"targetNodeId":177,"targetPortId":1188,"travelTime":{"lock":false,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":439},"sourceArrival":{"lock":true,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":101},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":450},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3074,"y":592},{"x":-3138,"y":592},{"x":-3358,"y":624},{"x":-3422,"y":624}],"textPositions":{"0":{"x":-3092,"y":580},"1":{"x":-3120,"y":604},"2":{"x":-3404,"y":636},"3":{"x":-3376,"y":612},"4":{"x":-3248,"y":596},"5":{"x":-3248,"y":596},"6":{"x":-3248,"y":620}}},"warnings":null},{"id":587,"sourceNodeId":160,"sourcePortId":1189,"targetNodeId":161,"targetPortId":1190,"travelTime":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":484},"sourceArrival":{"lock":true,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":56},"targetDeparture":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":48},"targetArrival":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":492},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3938,"y":688},{"x":-4002,"y":688},{"x":-4190,"y":688},{"x":-4254,"y":688}],"textPositions":{"0":{"x":-3956,"y":676},"1":{"x":-3984,"y":700},"2":{"x":-4236,"y":700},"3":{"x":-4208,"y":676},"4":{"x":-4096,"y":676},"5":{"x":-4096,"y":676},"6":{"x":-4096,"y":700}}},"warnings":null},{"id":588,"sourceNodeId":135,"sourcePortId":1191,"targetNodeId":150,"targetPortId":1192,"travelTime":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":219},"sourceArrival":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":321},"targetDeparture":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":309},"targetArrival":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":231},"numberOfStops":1,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":48},{"x":2914,"y":48},{"x":3230,"y":48},{"x":3294,"y":48}],"textPositions":{"0":{"x":2868,"y":60},"1":{"x":2896,"y":36},"2":{"x":3276,"y":36},"3":{"x":3248,"y":60},"4":{"x":3072,"y":36},"5":{"x":3072,"y":36},"6":{"x":3072,"y":60}}},"warnings":null},{"id":589,"sourceNodeId":150,"sourcePortId":1193,"targetNodeId":151,"targetPortId":1194,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":53,"warning":null,"timeFormatter":null,"consecutiveTime":233},"sourceArrival":{"lock":false,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":307},"targetDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":294},"targetArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":246},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3394,"y":48},{"x":3458,"y":48},{"x":3806,"y":48},{"x":3870,"y":48}],"textPositions":{"0":{"x":3412,"y":60},"1":{"x":3440,"y":36},"2":{"x":3852,"y":36},"3":{"x":3824,"y":60},"4":{"x":3632,"y":36},"5":{"x":3632,"y":36},"6":{"x":3632,"y":60}}},"warnings":null},{"id":590,"sourceNodeId":135,"sourcePortId":1195,"targetNodeId":149,"targetPortId":1196,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":346},"sourceArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":194},"targetDeparture":{"lock":false,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":189},"targetArrival":{"lock":false,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":351},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":48},{"x":2590,"y":48},{"x":2402,"y":48},{"x":2338,"y":48}],"textPositions":{"0":{"x":2636,"y":36},"1":{"x":2608,"y":60},"2":{"x":2356,"y":60},"3":{"x":2384,"y":36},"4":{"x":2496,"y":36},"5":{"x":2496,"y":36},"6":{"x":2496,"y":60}}},"warnings":null},{"id":591,"sourceNodeId":149,"sourcePortId":1197,"targetNodeId":166,"targetPortId":1198,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":351},"sourceArrival":{"lock":false,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":189},"targetDeparture":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":184},"targetArrival":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":356},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":48},{"x":2174,"y":48},{"x":1954,"y":48},{"x":1890,"y":48}],"textPositions":{"0":{"x":2220,"y":36},"1":{"x":2192,"y":60},"2":{"x":1908,"y":60},"3":{"x":1936,"y":36},"4":{"x":2064,"y":36},"5":{"x":2064,"y":36},"6":{"x":2064,"y":60}}},"warnings":null},{"id":592,"sourceNodeId":148,"sourcePortId":1199,"targetNodeId":147,"targetPortId":1200,"travelTime":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":361},"sourceArrival":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":179},"targetDeparture":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":175},"targetArrival":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":365},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":48},{"x":1278,"y":48},{"x":1122,"y":48},{"x":1058,"y":48}],"textPositions":{"0":{"x":1324,"y":36},"1":{"x":1296,"y":60},"2":{"x":1076,"y":60},"3":{"x":1104,"y":36},"4":{"x":1200,"y":36},"5":{"x":1200,"y":36},"6":{"x":1200,"y":60}}},"warnings":null},{"id":593,"sourceNodeId":147,"sourcePortId":1201,"targetNodeId":133,"targetPortId":1202,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":365},"sourceArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":175},"targetDeparture":{"lock":false,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":170},"targetArrival":{"lock":false,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":370},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":112},{"x":894,"y":112},{"x":322,"y":112},{"x":258,"y":112}],"textPositions":{"0":{"x":940,"y":100},"1":{"x":912,"y":124},"2":{"x":276,"y":124},"3":{"x":304,"y":100},"4":{"x":608,"y":100},"5":{"x":608,"y":100},"6":{"x":608,"y":124}}},"warnings":null},{"id":594,"sourceNodeId":133,"sourcePortId":1203,"targetNodeId":172,"targetPortId":1204,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":370},"sourceArrival":{"lock":false,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":170},"targetDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":377},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":144},{"x":-2,"y":144},{"x":-446,"y":144},{"x":-510,"y":144}],"textPositions":{"0":{"x":44,"y":132},"1":{"x":16,"y":156},"2":{"x":-492,"y":156},"3":{"x":-464,"y":132},"4":{"x":-224,"y":132},"5":{"x":-224,"y":132},"6":{"x":-224,"y":156}}},"warnings":null},{"id":595,"sourceNodeId":129,"sourcePortId":1205,"targetNodeId":171,"targetPortId":1206,"travelTime":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":390},"sourceArrival":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":150},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":128},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":412},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2146,"y":144},{"x":-2210,"y":144},{"x":-2398,"y":304},{"x":-2462,"y":304}],"textPositions":{"0":{"x":-2164,"y":132},"1":{"x":-2192,"y":156},"2":{"x":-2444,"y":316},"3":{"x":-2416,"y":292},"4":{"x":-2304,"y":212},"5":{"x":-2304,"y":212},"6":{"x":-2304,"y":236}}},"warnings":null},{"id":596,"sourceNodeId":128,"sourcePortId":1207,"targetNodeId":177,"targetPortId":1208,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":463},"sourceArrival":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":77},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":472},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3074,"y":560},{"x":-3138,"y":560},{"x":-3358,"y":592},{"x":-3422,"y":592}],"textPositions":{"0":{"x":-3092,"y":548},"1":{"x":-3120,"y":572},"2":{"x":-3404,"y":604},"3":{"x":-3376,"y":580},"4":{"x":-3248,"y":564},"5":{"x":-3248,"y":564},"6":{"x":-3248,"y":588}}},"warnings":null},{"id":597,"sourceNodeId":160,"sourcePortId":1209,"targetNodeId":161,"targetPortId":1210,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":501},"sourceArrival":{"lock":true,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":39},"targetDeparture":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":32},"targetArrival":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":508},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3938,"y":624},{"x":-4002,"y":624},{"x":-4190,"y":624},{"x":-4254,"y":624}],"textPositions":{"0":{"x":-3956,"y":612},"1":{"x":-3984,"y":636},"2":{"x":-4236,"y":636},"3":{"x":-4208,"y":612},"4":{"x":-4096,"y":612},"5":{"x":-4096,"y":612},"6":{"x":-4096,"y":636}}},"warnings":null},{"id":598,"sourceNodeId":151,"sourcePortId":1211,"targetNodeId":137,"targetPortId":1212,"travelTime":{"lock":false,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":248},"sourceArrival":{"lock":true,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":292},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":248},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":292},"numberOfStops":4,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3970,"y":112},{"x":4034,"y":112},{"x":4574,"y":112},{"x":4638,"y":112}],"textPositions":{"0":{"x":3988,"y":124},"1":{"x":4016,"y":100},"2":{"x":4620,"y":100},"3":{"x":4592,"y":124},"4":{"x":4304,"y":100},"5":{"x":4304,"y":100},"6":{"x":4304,"y":124}}},"warnings":null},{"id":599,"sourceNodeId":135,"sourcePortId":1213,"targetNodeId":150,"targetPortId":1214,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":125},"sourceArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":295},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":286},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":112},{"x":2914,"y":112},{"x":3230,"y":112},{"x":3294,"y":112}],"textPositions":{"0":{"x":2868,"y":124},"1":{"x":2896,"y":100},"2":{"x":3276,"y":100},"3":{"x":3248,"y":124},"4":{"x":3072,"y":100},"5":{"x":3072,"y":100},"6":{"x":3072,"y":124}}},"warnings":null},{"id":600,"sourceNodeId":150,"sourcePortId":1215,"targetNodeId":151,"targetPortId":1216,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":136},"sourceArrival":{"lock":false,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":284},"targetDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":271},"targetArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":149},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3394,"y":112},{"x":3458,"y":112},{"x":3806,"y":112},{"x":3870,"y":112}],"textPositions":{"0":{"x":3412,"y":124},"1":{"x":3440,"y":100},"2":{"x":3852,"y":100},"3":{"x":3824,"y":124},"4":{"x":3632,"y":100},"5":{"x":3632,"y":100},"6":{"x":3632,"y":124}}},"warnings":null},{"id":601,"sourceNodeId":135,"sourcePortId":1217,"targetNodeId":149,"targetPortId":1218,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":302},"sourceArrival":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":118},"targetDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":176},{"x":2590,"y":176},{"x":2402,"y":176},{"x":2338,"y":176}],"textPositions":{"0":{"x":2636,"y":164},"1":{"x":2608,"y":188},"2":{"x":2356,"y":188},"3":{"x":2384,"y":164},"4":{"x":2496,"y":164},"5":{"x":2496,"y":164},"6":{"x":2496,"y":188}}},"warnings":null},{"id":602,"sourceNodeId":149,"sourcePortId":1219,"targetNodeId":166,"targetPortId":1220,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":176},{"x":2174,"y":176},{"x":1954,"y":176},{"x":1890,"y":176}],"textPositions":{"0":{"x":2220,"y":164},"1":{"x":2192,"y":188},"2":{"x":1908,"y":188},"3":{"x":1936,"y":164},"4":{"x":2064,"y":164},"5":{"x":2064,"y":164},"6":{"x":2064,"y":188}}},"warnings":null},{"id":603,"sourceNodeId":148,"sourcePortId":1221,"targetNodeId":147,"targetPortId":1222,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":320},"sourceArrival":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":100},"targetDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":95},"targetArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":325},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":176},{"x":1278,"y":176},{"x":1122,"y":176},{"x":1058,"y":176}],"textPositions":{"0":{"x":1324,"y":164},"1":{"x":1296,"y":188},"2":{"x":1076,"y":188},"3":{"x":1104,"y":164},"4":{"x":1200,"y":164},"5":{"x":1200,"y":164},"6":{"x":1200,"y":188}}},"warnings":null},{"id":604,"sourceNodeId":147,"sourcePortId":1223,"targetNodeId":133,"targetPortId":1224,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":325},"sourceArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":95},"targetDeparture":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetArrival":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":176},{"x":894,"y":176},{"x":322,"y":176},{"x":258,"y":176}],"textPositions":{"0":{"x":940,"y":164},"1":{"x":912,"y":188},"2":{"x":276,"y":188},"3":{"x":304,"y":164},"4":{"x":608,"y":164},"5":{"x":608,"y":164},"6":{"x":608,"y":188}}},"warnings":null},{"id":605,"sourceNodeId":133,"sourcePortId":1225,"targetNodeId":172,"targetPortId":1226,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"sourceArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":83},"targetArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":337},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":240},{"x":-2,"y":240},{"x":-446,"y":240},{"x":-510,"y":240}],"textPositions":{"0":{"x":44,"y":228},"1":{"x":16,"y":252},"2":{"x":-492,"y":252},"3":{"x":-464,"y":228},"4":{"x":-224,"y":228},"5":{"x":-224,"y":228},"6":{"x":-224,"y":252}}},"warnings":null},{"id":606,"sourceNodeId":151,"sourcePortId":1227,"targetNodeId":162,"targetPortId":1228,"travelTime":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":151},"sourceArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":269},"targetDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":218},"targetArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":202},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3970,"y":48},{"x":4034,"y":48},{"x":4574,"y":-176},{"x":4638,"y":-176}],"textPositions":{"0":{"x":3988,"y":60},"1":{"x":4016,"y":36},"2":{"x":4620,"y":-188},"3":{"x":4592,"y":-164},"4":{"x":4304,"y":-76},"5":{"x":4304,"y":-76},"6":{"x":4304,"y":-52}}},"warnings":null},{"id":607,"sourceNodeId":135,"sourcePortId":1229,"targetNodeId":150,"targetPortId":1230,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":125},"sourceArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":295},"targetDeparture":{"lock":true,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":286},"targetArrival":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":144},{"x":2914,"y":144},{"x":3230,"y":144},{"x":3294,"y":144}],"textPositions":{"0":{"x":2868,"y":156},"1":{"x":2896,"y":132},"2":{"x":3276,"y":132},"3":{"x":3248,"y":156},"4":{"x":3072,"y":132},"5":{"x":3072,"y":132},"6":{"x":3072,"y":156}}},"warnings":null},{"id":608,"sourceNodeId":150,"sourcePortId":1231,"targetNodeId":151,"targetPortId":1232,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":136},"sourceArrival":{"lock":false,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":284},"targetDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":271},"targetArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":149},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3394,"y":144},{"x":3458,"y":144},{"x":3806,"y":144},{"x":3870,"y":144}],"textPositions":{"0":{"x":3412,"y":156},"1":{"x":3440,"y":132},"2":{"x":3852,"y":132},"3":{"x":3824,"y":156},"4":{"x":3632,"y":132},"5":{"x":3632,"y":132},"6":{"x":3632,"y":156}}},"warnings":null},{"id":609,"sourceNodeId":135,"sourcePortId":1233,"targetNodeId":149,"targetPortId":1234,"travelTime":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":302},"sourceArrival":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":118},"targetDeparture":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":103},"targetArrival":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":317},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":208},{"x":2590,"y":208},{"x":2402,"y":208},{"x":2338,"y":208}],"textPositions":{"0":{"x":2636,"y":196},"1":{"x":2608,"y":220},"2":{"x":2356,"y":220},"3":{"x":2384,"y":196},"4":{"x":2496,"y":196},"5":{"x":2496,"y":196},"6":{"x":2496,"y":220}}},"warnings":null},{"id":610,"sourceNodeId":149,"sourcePortId":1235,"targetNodeId":166,"targetPortId":1236,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":317},"sourceArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":103},"targetDeparture":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":97},"targetArrival":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":323},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":208},{"x":2174,"y":208},{"x":1954,"y":208},{"x":1890,"y":208}],"textPositions":{"0":{"x":2220,"y":196},"1":{"x":2192,"y":220},"2":{"x":1908,"y":220},"3":{"x":1936,"y":196},"4":{"x":2064,"y":196},"5":{"x":2064,"y":196},"6":{"x":2064,"y":220}}},"warnings":null},{"id":611,"sourceNodeId":148,"sourcePortId":1237,"targetNodeId":147,"targetPortId":1238,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"sourceArrival":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":85},"targetArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":335},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":208},{"x":1278,"y":208},{"x":1122,"y":208},{"x":1058,"y":208}],"textPositions":{"0":{"x":1324,"y":196},"1":{"x":1296,"y":220},"2":{"x":1076,"y":220},"3":{"x":1104,"y":196},"4":{"x":1200,"y":196},"5":{"x":1200,"y":196},"6":{"x":1200,"y":220}}},"warnings":null},{"id":612,"sourceNodeId":147,"sourcePortId":1239,"targetNodeId":133,"targetPortId":1240,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":335},"sourceArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":85},"targetDeparture":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":80},"targetArrival":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":340},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":208},{"x":894,"y":208},{"x":322,"y":208},{"x":258,"y":208}],"textPositions":{"0":{"x":940,"y":196},"1":{"x":912,"y":220},"2":{"x":276,"y":220},"3":{"x":304,"y":196},"4":{"x":608,"y":196},"5":{"x":608,"y":196},"6":{"x":608,"y":220}}},"warnings":null},{"id":613,"sourceNodeId":133,"sourcePortId":1241,"targetNodeId":172,"targetPortId":1242,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":340},"sourceArrival":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":80},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":73},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":272},{"x":-2,"y":272},{"x":-446,"y":272},{"x":-510,"y":272}],"textPositions":{"0":{"x":44,"y":260},"1":{"x":16,"y":284},"2":{"x":-492,"y":284},"3":{"x":-464,"y":260},"4":{"x":-224,"y":260},"5":{"x":-224,"y":260},"6":{"x":-224,"y":284}}},"warnings":null},{"id":614,"sourceNodeId":151,"sourcePortId":1243,"targetNodeId":162,"targetPortId":1244,"travelTime":{"lock":true,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":151},"sourceArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":269},"targetDeparture":{"lock":false,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":228},"targetArrival":{"lock":false,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":192},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3970,"y":80},{"x":4034,"y":80},{"x":4574,"y":-144},{"x":4638,"y":-144}],"textPositions":{"0":{"x":3988,"y":92},"1":{"x":4016,"y":68},"2":{"x":4620,"y":-156},"3":{"x":4592,"y":-132},"4":{"x":4304,"y":-44},"5":{"x":4304,"y":-44},"6":{"x":4304,"y":-20}}},"warnings":null},{"id":615,"sourceNodeId":135,"sourcePortId":1245,"targetNodeId":150,"targetPortId":1246,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":95},"sourceArrival":{"lock":true,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":205},"targetDeparture":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":196},"targetArrival":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":104},"numberOfStops":0,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":208},{"x":2914,"y":208},{"x":3230,"y":208},{"x":3294,"y":208}],"textPositions":{"0":{"x":2868,"y":220},"1":{"x":2896,"y":196},"2":{"x":3276,"y":196},"3":{"x":3248,"y":220},"4":{"x":3072,"y":196},"5":{"x":3072,"y":196},"6":{"x":3072,"y":220}}},"warnings":null},{"id":616,"sourceNodeId":150,"sourcePortId":1247,"targetNodeId":151,"targetPortId":1248,"travelTime":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"sourceArrival":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":194},"targetDeparture":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":181},"targetArrival":{"lock":true,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":119},"numberOfStops":0,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3394,"y":208},{"x":3458,"y":208},{"x":3806,"y":208},{"x":3870,"y":208}],"textPositions":{"0":{"x":3412,"y":220},"1":{"x":3440,"y":196},"2":{"x":3852,"y":196},"3":{"x":3824,"y":220},"4":{"x":3632,"y":196},"5":{"x":3632,"y":196},"6":{"x":3632,"y":220}}},"warnings":null},{"id":617,"sourceNodeId":151,"sourcePortId":1249,"targetNodeId":139,"targetPortId":1250,"travelTime":{"lock":false,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":121},"sourceArrival":{"lock":true,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":179},"targetDeparture":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":130},"targetArrival":{"lock":true,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":170},"numberOfStops":2,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3888,"y":30},{"x":3888,"y":-34},{"x":4272,"y":-286},{"x":4272,"y":-350}],"textPositions":{"0":{"x":3900,"y":12},"1":{"x":3876,"y":-16},"2":{"x":4260,"y":-332},"3":{"x":4284,"y":-304},"4":{"x":4068,"y":-160},"5":{"x":4068,"y":-160},"6":{"x":4092,"y":-160}}},"warnings":null},{"id":618,"sourceNodeId":138,"sourcePortId":1251,"targetNodeId":163,"targetPortId":1252,"travelTime":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":0},"sourceArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"targetDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":59},"targetArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":1},"numberOfStops":0,"trainrunId":91,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":-1054},{"x":2672,"y":-990},{"x":2800,"y":-610},{"x":2800,"y":-546}],"textPositions":{"0":{"x":2660,"y":-1036},"1":{"x":2684,"y":-1008},"2":{"x":2812,"y":-564},"3":{"x":2788,"y":-592},"4":{"x":2748,"y":-800},"5":{"x":2748,"y":-800},"6":{"x":2724,"y":-800}}},"warnings":null},{"id":619,"sourceNodeId":163,"sourcePortId":1253,"targetNodeId":135,"targetPortId":1254,"travelTime":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":3},"sourceArrival":{"lock":false,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":57},"targetDeparture":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":56},"targetArrival":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":4},"numberOfStops":0,"trainrunId":91,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2800,"y":-478},{"x":2800,"y":-414},{"x":2704,"y":-34},{"x":2704,"y":30}],"textPositions":{"0":{"x":2788,"y":-460},"1":{"x":2812,"y":-432},"2":{"x":2716,"y":12},"3":{"x":2692,"y":-16},"4":{"x":2740,"y":-224},"5":{"x":2740,"y":-224},"6":{"x":2764,"y":-224}}},"warnings":null},{"id":620,"sourceNodeId":135,"sourcePortId":1255,"targetNodeId":138,"targetPortId":1256,"travelTime":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":120},"sourceArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"targetDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":59},"targetArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":121},"numberOfStops":0,"trainrunId":92,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":30},{"x":2672,"y":-34},{"x":2640,"y":-990},{"x":2640,"y":-1054}],"textPositions":{"0":{"x":2684,"y":12},"1":{"x":2660,"y":-16},"2":{"x":2628,"y":-1036},"3":{"x":2652,"y":-1008},"4":{"x":2668,"y":-512},"5":{"x":2668,"y":-512},"6":{"x":2644,"y":-512}}},"warnings":null},{"id":621,"sourceNodeId":166,"sourcePortId":1257,"targetNodeId":148,"targetPortId":1258,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":356},"sourceArrival":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":184},"targetDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":179},"targetArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":361},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":48},{"x":1726,"y":48},{"x":1506,"y":48},{"x":1442,"y":48}],"textPositions":{"0":{"x":1772,"y":36},"1":{"x":1744,"y":60},"2":{"x":1460,"y":60},"3":{"x":1488,"y":36},"4":{"x":1616,"y":36},"5":{"x":1616,"y":36},"6":{"x":1616,"y":60}}},"warnings":null},{"id":622,"sourceNodeId":166,"sourcePortId":1259,"targetNodeId":148,"targetPortId":1260,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":377},"sourceArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetDeparture":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":156},"targetArrival":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":384},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":144},{"x":1726,"y":144},{"x":1506,"y":144},{"x":1442,"y":144}],"textPositions":{"0":{"x":1772,"y":132},"1":{"x":1744,"y":156},"2":{"x":1460,"y":156},"3":{"x":1488,"y":132},"4":{"x":1616,"y":132},"5":{"x":1616,"y":132},"6":{"x":1616,"y":156}}},"warnings":null},{"id":623,"sourceNodeId":166,"sourcePortId":1261,"targetNodeId":148,"targetPortId":1262,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"sourceArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"targetDeparture":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":100},"targetArrival":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":320},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":176},{"x":1726,"y":176},{"x":1506,"y":176},{"x":1442,"y":176}],"textPositions":{"0":{"x":1772,"y":164},"1":{"x":1744,"y":188},"2":{"x":1460,"y":188},"3":{"x":1488,"y":164},"4":{"x":1616,"y":164},"5":{"x":1616,"y":164},"6":{"x":1616,"y":188}}},"warnings":null},{"id":624,"sourceNodeId":166,"sourcePortId":1263,"targetNodeId":148,"targetPortId":1264,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":325},"sourceArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":95},"targetDeparture":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetArrival":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":208},{"x":1726,"y":208},{"x":1506,"y":208},{"x":1442,"y":208}],"textPositions":{"0":{"x":1772,"y":196},"1":{"x":1744,"y":220},"2":{"x":1460,"y":220},"3":{"x":1488,"y":196},"4":{"x":1616,"y":196},"5":{"x":1616,"y":196},"6":{"x":1616,"y":220}}},"warnings":null},{"id":625,"sourceNodeId":166,"sourcePortId":1265,"targetNodeId":148,"targetPortId":1266,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetDeparture":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":105},"targetArrival":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":315},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":240},{"x":1726,"y":240},{"x":1506,"y":240},{"x":1442,"y":240}],"textPositions":{"0":{"x":1772,"y":228},"1":{"x":1744,"y":252},"2":{"x":1460,"y":252},"3":{"x":1488,"y":228},"4":{"x":1616,"y":228},"5":{"x":1616,"y":228},"6":{"x":1616,"y":252}}},"warnings":null},{"id":626,"sourceNodeId":134,"sourcePortId":1267,"targetNodeId":164,"targetPortId":1268,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":11},"sourceArrival":{"lock":false,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":169},"targetDeparture":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":156},"targetArrival":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":24},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":322,"y":-1872},{"x":386,"y":-1872},{"x":990,"y":-944},{"x":1054,"y":-944}],"textPositions":{"0":{"x":340,"y":-1860},"1":{"x":368,"y":-1884},"2":{"x":1036,"y":-956},"3":{"x":1008,"y":-932},"4":{"x":688,"y":-1420},"5":{"x":688,"y":-1420},"6":{"x":688,"y":-1396}}},"warnings":null},{"id":627,"sourceNodeId":164,"sourcePortId":1269,"targetNodeId":165,"targetPortId":1270,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":25},"sourceArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":155},"targetDeparture":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":146},"targetArrival":{"lock":false,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":34},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1154,"y":-944},{"x":1218,"y":-944},{"x":1726,"y":-656},{"x":1790,"y":-656}],"textPositions":{"0":{"x":1172,"y":-932},"1":{"x":1200,"y":-956},"2":{"x":1772,"y":-668},"3":{"x":1744,"y":-644},"4":{"x":1472,"y":-812},"5":{"x":1472,"y":-812},"6":{"x":1472,"y":-788}}},"warnings":null},{"id":628,"sourceNodeId":165,"sourcePortId":1271,"targetNodeId":166,"targetPortId":1272,"travelTime":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"sourceArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":145},"targetDeparture":{"lock":false,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":123},"targetArrival":{"lock":false,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":57},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1808,"y":-606},{"x":1808,"y":-542},{"x":1808,"y":-34},{"x":1808,"y":30}],"textPositions":{"0":{"x":1796,"y":-588},"1":{"x":1820,"y":-560},"2":{"x":1820,"y":12},"3":{"x":1796,"y":-16},"4":{"x":1796,"y":-288},"5":{"x":1796,"y":-288},"6":{"x":1820,"y":-288}}},"warnings":null},{"id":629,"sourceNodeId":166,"sourcePortId":1273,"targetNodeId":149,"targetPortId":1274,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"sourceArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":120},"targetDeparture":{"lock":false,"time":53,"warning":null,"timeFormatter":null,"consecutiveTime":113},"targetArrival":{"lock":false,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":67},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1890,"y":272},{"x":1954,"y":272},{"x":2174,"y":272},{"x":2238,"y":272}],"textPositions":{"0":{"x":1908,"y":284},"1":{"x":1936,"y":260},"2":{"x":2220,"y":260},"3":{"x":2192,"y":284},"4":{"x":2064,"y":260},"5":{"x":2064,"y":260},"6":{"x":2064,"y":284}}},"warnings":null},{"id":630,"sourceNodeId":149,"sourcePortId":1275,"targetNodeId":135,"targetPortId":1276,"travelTime":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetDeparture":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":96},"targetArrival":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":84},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2338,"y":272},{"x":2402,"y":272},{"x":2590,"y":272},{"x":2654,"y":272}],"textPositions":{"0":{"x":2356,"y":284},"1":{"x":2384,"y":260},"2":{"x":2636,"y":260},"3":{"x":2608,"y":284},"4":{"x":2496,"y":260},"5":{"x":2496,"y":260},"6":{"x":2496,"y":284}}},"warnings":null},{"id":631,"sourceNodeId":134,"sourcePortId":1277,"targetNodeId":146,"targetPortId":1278,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":6},"sourceArrival":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":174},"targetDeparture":{"lock":false,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":169},"targetArrival":{"lock":false,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":11},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":-1822},{"x":144,"y":-1758},{"x":144,"y":-1474},{"x":144,"y":-1410}],"textPositions":{"0":{"x":132,"y":-1804},"1":{"x":156,"y":-1776},"2":{"x":156,"y":-1428},"3":{"x":132,"y":-1456},"4":{"x":132,"y":-1616},"5":{"x":132,"y":-1616},"6":{"x":156,"y":-1616}}},"warnings":null},{"id":632,"sourceNodeId":146,"sourcePortId":1279,"targetNodeId":145,"targetPortId":1280,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":11},"sourceArrival":{"lock":false,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":169},"targetDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":17},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":-1342},{"x":144,"y":-1278},{"x":144,"y":-994},{"x":144,"y":-930}],"textPositions":{"0":{"x":132,"y":-1324},"1":{"x":156,"y":-1296},"2":{"x":156,"y":-948},"3":{"x":132,"y":-976},"4":{"x":132,"y":-1136},"5":{"x":132,"y":-1136},"6":{"x":156,"y":-1136}}},"warnings":null},{"id":633,"sourceNodeId":145,"sourcePortId":1281,"targetNodeId":144,"targetPortId":1282,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":17},"sourceArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetDeparture":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":157},"targetArrival":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":23},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":-862},{"x":144,"y":-798},{"x":144,"y":-514},{"x":144,"y":-450}],"textPositions":{"0":{"x":132,"y":-844},"1":{"x":156,"y":-816},"2":{"x":156,"y":-468},"3":{"x":132,"y":-496},"4":{"x":132,"y":-656},"5":{"x":132,"y":-656},"6":{"x":156,"y":-656}}},"warnings":null},{"id":634,"sourceNodeId":144,"sourcePortId":1283,"targetNodeId":147,"targetPortId":1284,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":23},"sourceArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":157},"targetDeparture":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":147},"targetArrival":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":33},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":322,"y":-400},{"x":386,"y":-400},{"x":894,"y":80},{"x":958,"y":80}],"textPositions":{"0":{"x":340,"y":-388},"1":{"x":368,"y":-412},"2":{"x":940,"y":68},"3":{"x":912,"y":92},"4":{"x":640,"y":-172},"5":{"x":640,"y":-172},"6":{"x":640,"y":-148}}},"warnings":null},{"id":635,"sourceNodeId":147,"sourcePortId":1285,"targetNodeId":148,"targetPortId":1286,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":33},"sourceArrival":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":147},"targetDeparture":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":140},"targetArrival":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":40},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1058,"y":112},{"x":1122,"y":112},{"x":1278,"y":112},{"x":1342,"y":112}],"textPositions":{"0":{"x":1076,"y":124},"1":{"x":1104,"y":100},"2":{"x":1324,"y":100},"3":{"x":1296,"y":124},"4":{"x":1200,"y":100},"5":{"x":1200,"y":100},"6":{"x":1200,"y":124}}},"warnings":null},{"id":636,"sourceNodeId":148,"sourcePortId":1287,"targetNodeId":166,"targetPortId":1288,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":40},"sourceArrival":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":140},"targetDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"targetArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1442,"y":112},{"x":1506,"y":112},{"x":1726,"y":112},{"x":1790,"y":112}],"textPositions":{"0":{"x":1460,"y":124},"1":{"x":1488,"y":100},"2":{"x":1772,"y":100},"3":{"x":1744,"y":124},"4":{"x":1616,"y":100},"5":{"x":1616,"y":100},"6":{"x":1616,"y":124}}},"warnings":null},{"id":637,"sourceNodeId":166,"sourcePortId":1289,"targetNodeId":149,"targetPortId":1290,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"sourceArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":128},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1890,"y":112},{"x":1954,"y":112},{"x":2174,"y":112},{"x":2238,"y":112}],"textPositions":{"0":{"x":1908,"y":124},"1":{"x":1936,"y":100},"2":{"x":2220,"y":100},"3":{"x":2192,"y":124},"4":{"x":2064,"y":100},"5":{"x":2064,"y":100},"6":{"x":2064,"y":124}}},"warnings":null},{"id":638,"sourceNodeId":149,"sourcePortId":1291,"targetNodeId":135,"targetPortId":1292,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":128},"targetDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":120},"targetArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2338,"y":112},{"x":2402,"y":112},{"x":2590,"y":112},{"x":2654,"y":112}],"textPositions":{"0":{"x":2356,"y":124},"1":{"x":2384,"y":100},"2":{"x":2636,"y":100},"3":{"x":2608,"y":124},"4":{"x":2496,"y":100},"5":{"x":2496,"y":100},"6":{"x":2496,"y":124}}},"warnings":null},{"id":639,"sourceNodeId":147,"sourcePortId":1293,"targetNodeId":148,"targetPortId":1294,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":54},"sourceArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":126},"targetDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":120},"targetArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"numberOfStops":0,"trainrunId":97,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1058,"y":272},{"x":1122,"y":272},{"x":1278,"y":272},{"x":1342,"y":272}],"textPositions":{"0":{"x":1076,"y":284},"1":{"x":1104,"y":260},"2":{"x":1324,"y":260},"3":{"x":1296,"y":284},"4":{"x":1200,"y":260},"5":{"x":1200,"y":260},"6":{"x":1200,"y":284}}},"warnings":null},{"id":640,"sourceNodeId":148,"sourcePortId":1295,"targetNodeId":166,"targetPortId":1296,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":62},"sourceArrival":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":118},"targetDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"numberOfStops":0,"trainrunId":97,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1442,"y":272},{"x":1506,"y":272},{"x":1726,"y":272},{"x":1790,"y":272}],"textPositions":{"0":{"x":1460,"y":284},"1":{"x":1488,"y":260},"2":{"x":1772,"y":260},"3":{"x":1744,"y":284},"4":{"x":1616,"y":260},"5":{"x":1616,"y":260},"6":{"x":1616,"y":284}}},"warnings":null},{"id":641,"sourceNodeId":166,"sourcePortId":1297,"targetNodeId":149,"targetPortId":1298,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetDeparture":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":105},"targetArrival":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":75},"numberOfStops":0,"trainrunId":97,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1890,"y":304},{"x":1954,"y":304},{"x":2174,"y":304},{"x":2238,"y":304}],"textPositions":{"0":{"x":1908,"y":316},"1":{"x":1936,"y":292},"2":{"x":2220,"y":292},"3":{"x":2192,"y":316},"4":{"x":2064,"y":292},"5":{"x":2064,"y":292},"6":{"x":2064,"y":316}}},"warnings":null},{"id":642,"sourceNodeId":149,"sourcePortId":1299,"targetNodeId":135,"targetPortId":1300,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":75},"sourceArrival":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":105},"targetDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":98},"targetArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":82},"numberOfStops":0,"trainrunId":97,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2338,"y":304},{"x":2402,"y":304},{"x":2590,"y":304},{"x":2654,"y":304}],"textPositions":{"0":{"x":2356,"y":316},"1":{"x":2384,"y":292},"2":{"x":2636,"y":292},"3":{"x":2608,"y":316},"4":{"x":2496,"y":292},"5":{"x":2496,"y":292},"6":{"x":2496,"y":316}}},"warnings":null},{"id":643,"sourceNodeId":134,"sourcePortId":1301,"targetNodeId":146,"targetPortId":1302,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":28},"sourceArrival":{"lock":false,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":272},"targetDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":265},"targetArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":-1822},{"x":208,"y":-1758},{"x":208,"y":-1474},{"x":208,"y":-1410}],"textPositions":{"0":{"x":196,"y":-1804},"1":{"x":220,"y":-1776},"2":{"x":220,"y":-1428},"3":{"x":196,"y":-1456},"4":{"x":196,"y":-1616},"5":{"x":196,"y":-1616},"6":{"x":220,"y":-1616}}},"warnings":null},{"id":644,"sourceNodeId":146,"sourcePortId":1303,"targetNodeId":145,"targetPortId":1304,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"sourceArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":265},"targetDeparture":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":259},"targetArrival":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":-1342},{"x":208,"y":-1278},{"x":208,"y":-994},{"x":208,"y":-930}],"textPositions":{"0":{"x":196,"y":-1324},"1":{"x":220,"y":-1296},"2":{"x":220,"y":-948},"3":{"x":196,"y":-976},"4":{"x":196,"y":-1136},"5":{"x":196,"y":-1136},"6":{"x":220,"y":-1136}}},"warnings":null},{"id":645,"sourceNodeId":145,"sourcePortId":1305,"targetNodeId":144,"targetPortId":1306,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"sourceArrival":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":259},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":253},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":47},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":-862},{"x":208,"y":-798},{"x":208,"y":-514},{"x":208,"y":-450}],"textPositions":{"0":{"x":196,"y":-844},"1":{"x":220,"y":-816},"2":{"x":220,"y":-468},"3":{"x":196,"y":-496},"4":{"x":196,"y":-656},"5":{"x":196,"y":-656},"6":{"x":220,"y":-656}}},"warnings":null},{"id":646,"sourceNodeId":144,"sourcePortId":1307,"targetNodeId":133,"targetPortId":1308,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":47},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":253},"targetDeparture":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":245},"targetArrival":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":55},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":-354},{"x":144,"y":-290},{"x":144,"y":30},{"x":144,"y":94}],"textPositions":{"0":{"x":132,"y":-336},"1":{"x":156,"y":-308},"2":{"x":156,"y":76},"3":{"x":132,"y":48},"4":{"x":132,"y":-130},"5":{"x":132,"y":-130},"6":{"x":156,"y":-130}}},"warnings":null},{"id":647,"sourceNodeId":133,"sourcePortId":1309,"targetNodeId":172,"targetPortId":1310,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":58},"sourceArrival":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":242},"targetDeparture":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":235},"targetArrival":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":208},{"x":-2,"y":208},{"x":-446,"y":208},{"x":-510,"y":208}],"textPositions":{"0":{"x":44,"y":196},"1":{"x":16,"y":220},"2":{"x":-492,"y":220},"3":{"x":-464,"y":196},"4":{"x":-224,"y":196},"5":{"x":-224,"y":196},"6":{"x":-224,"y":220}}},"warnings":null},{"id":648,"sourceNodeId":129,"sourcePortId":1311,"targetNodeId":167,"targetPortId":1312,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":94},"sourceArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":206},"targetDeparture":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":188},"targetArrival":{"lock":true,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2096,"y":382},{"x":-2096,"y":446},{"x":-2096,"y":574},{"x":-2096,"y":638}],"textPositions":{"0":{"x":-2108,"y":400},"1":{"x":-2084,"y":428},"2":{"x":-2084,"y":620},"3":{"x":-2108,"y":592},"4":{"x":-2108,"y":510},"5":{"x":-2108,"y":510},"6":{"x":-2084,"y":510}}},"warnings":null},{"id":649,"sourceNodeId":129,"sourcePortId":1313,"targetNodeId":167,"targetPortId":1314,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":359},"sourceArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":61},"targetDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":43},"targetArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":377},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2064,"y":382},{"x":-2064,"y":446},{"x":-2064,"y":574},{"x":-2064,"y":638}],"textPositions":{"0":{"x":-2076,"y":400},"1":{"x":-2052,"y":428},"2":{"x":-2052,"y":620},"3":{"x":-2076,"y":592},"4":{"x":-2076,"y":510},"5":{"x":-2076,"y":510},"6":{"x":-2052,"y":510}}},"warnings":null},{"id":650,"sourceNodeId":167,"sourcePortId":1315,"targetNodeId":168,"targetPortId":1316,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":114},"sourceArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":186},"targetDeparture":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":178},"targetArrival":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":122},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2096,"y":706},{"x":-2096,"y":770},{"x":-2096,"y":862},{"x":-2096,"y":926}],"textPositions":{"0":{"x":-2108,"y":724},"1":{"x":-2084,"y":752},"2":{"x":-2084,"y":908},"3":{"x":-2108,"y":880},"4":{"x":-2108,"y":816},"5":{"x":-2108,"y":816},"6":{"x":-2084,"y":816}}},"warnings":null},{"id":651,"sourceNodeId":168,"sourcePortId":1317,"targetNodeId":131,"targetPortId":1318,"travelTime":{"lock":true,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":124},"sourceArrival":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":176},"targetDeparture":{"lock":false,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":152},"targetArrival":{"lock":false,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":148},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2014,"y":944},{"x":-1950,"y":944},{"x":-1154,"y":944},{"x":-1090,"y":944}],"textPositions":{"0":{"x":-1996,"y":956},"1":{"x":-1968,"y":932},"2":{"x":-1108,"y":932},"3":{"x":-1136,"y":956},"4":{"x":-1552,"y":932},"5":{"x":-1552,"y":932},"6":{"x":-1552,"y":956}}},"warnings":null},{"id":652,"sourceNodeId":167,"sourcePortId":1319,"targetNodeId":168,"targetPortId":1320,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":379},"sourceArrival":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"targetDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":31},"targetArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":389},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2064,"y":706},{"x":-2064,"y":770},{"x":-2064,"y":862},{"x":-2064,"y":926}],"textPositions":{"0":{"x":-2076,"y":724},"1":{"x":-2052,"y":752},"2":{"x":-2052,"y":908},"3":{"x":-2076,"y":880},"4":{"x":-2076,"y":816},"5":{"x":-2076,"y":816},"6":{"x":-2052,"y":816}}},"warnings":null},{"id":653,"sourceNodeId":168,"sourcePortId":1321,"targetNodeId":132,"targetPortId":1322,"travelTime":{"lock":true,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":391},"sourceArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":29},"targetDeparture":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":4},"targetArrival":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":416},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2096,"y":1022},{"x":-2096,"y":1086},{"x":-2096,"y":1374},{"x":-2096,"y":1438}],"textPositions":{"0":{"x":-2108,"y":1040},"1":{"x":-2084,"y":1068},"2":{"x":-2084,"y":1420},"3":{"x":-2108,"y":1392},"4":{"x":-2108,"y":1230},"5":{"x":-2108,"y":1230},"6":{"x":-2084,"y":1230}}},"warnings":null},{"id":654,"sourceNodeId":132,"sourcePortId":1323,"targetNodeId":168,"targetPortId":1324,"travelTime":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":149},"sourceArrival":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":151},"targetDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":125},"targetArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":175},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2128,"y":1438},{"x":-2128,"y":1374},{"x":-2128,"y":1086},{"x":-2128,"y":1022}],"textPositions":{"0":{"x":-2116,"y":1420},"1":{"x":-2140,"y":1392},"2":{"x":-2140,"y":1040},"3":{"x":-2116,"y":1068},"4":{"x":-2140,"y":1230},"5":{"x":-2140,"y":1230},"6":{"x":-2116,"y":1230}}},"warnings":null},{"id":655,"sourceNodeId":168,"sourcePortId":1325,"targetNodeId":167,"targetPortId":1326,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":178},"sourceArrival":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":122},"targetDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":114},"targetArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":186},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2128,"y":926},{"x":-2128,"y":862},{"x":-2128,"y":770},{"x":-2128,"y":706}],"textPositions":{"0":{"x":-2116,"y":908},"1":{"x":-2140,"y":880},"2":{"x":-2140,"y":724},"3":{"x":-2116,"y":752},"4":{"x":-2140,"y":816},"5":{"x":-2140,"y":816},"6":{"x":-2116,"y":816}}},"warnings":null},{"id":656,"sourceNodeId":167,"sourcePortId":1327,"targetNodeId":129,"targetPortId":1328,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":188},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":94},"targetArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":206},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2128,"y":638},{"x":-2128,"y":574},{"x":-2128,"y":446},{"x":-2128,"y":382}],"textPositions":{"0":{"x":-2116,"y":620},"1":{"x":-2140,"y":592},"2":{"x":-2140,"y":400},"3":{"x":-2116,"y":428},"4":{"x":-2140,"y":510},"5":{"x":-2140,"y":510},"6":{"x":-2116,"y":510}}},"warnings":null},{"id":657,"sourceNodeId":129,"sourcePortId":1329,"targetNodeId":178,"targetPortId":1330,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":214},"sourceArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":86},"targetDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":83},"targetArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":217},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2014,"y":176},{"x":-1950,"y":176},{"x":-1762,"y":176},{"x":-1698,"y":176}],"textPositions":{"0":{"x":-1996,"y":188},"1":{"x":-1968,"y":164},"2":{"x":-1716,"y":164},"3":{"x":-1744,"y":188},"4":{"x":-1856,"y":164},"5":{"x":-1856,"y":164},"6":{"x":-1856,"y":188}}},"warnings":null},{"id":658,"sourceNodeId":133,"sourcePortId":1331,"targetNodeId":144,"targetPortId":1332,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":245},"sourceArrival":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":55},"targetDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":47},"targetArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":253},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":94},{"x":112,"y":30},{"x":112,"y":-290},{"x":112,"y":-354}],"textPositions":{"0":{"x":124,"y":76},"1":{"x":100,"y":48},"2":{"x":100,"y":-336},"3":{"x":124,"y":-308},"4":{"x":100,"y":-130},"5":{"x":100,"y":-130},"6":{"x":124,"y":-130}}},"warnings":null},{"id":659,"sourceNodeId":144,"sourcePortId":1333,"targetNodeId":145,"targetPortId":1334,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":253},"sourceArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":47},"targetDeparture":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"targetArrival":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":259},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":-450},{"x":176,"y":-514},{"x":176,"y":-798},{"x":176,"y":-862}],"textPositions":{"0":{"x":188,"y":-468},"1":{"x":164,"y":-496},"2":{"x":164,"y":-844},"3":{"x":188,"y":-816},"4":{"x":164,"y":-656},"5":{"x":164,"y":-656},"6":{"x":188,"y":-656}}},"warnings":null},{"id":660,"sourceNodeId":145,"sourcePortId":1335,"targetNodeId":146,"targetPortId":1336,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":259},"sourceArrival":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"targetDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"targetArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":265},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":-930},{"x":176,"y":-994},{"x":176,"y":-1278},{"x":176,"y":-1342}],"textPositions":{"0":{"x":188,"y":-948},"1":{"x":164,"y":-976},"2":{"x":164,"y":-1324},"3":{"x":188,"y":-1296},"4":{"x":164,"y":-1136},"5":{"x":164,"y":-1136},"6":{"x":188,"y":-1136}}},"warnings":null},{"id":661,"sourceNodeId":146,"sourcePortId":1337,"targetNodeId":134,"targetPortId":1338,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":265},"sourceArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"targetDeparture":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":28},"targetArrival":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":272},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":-1410},{"x":176,"y":-1474},{"x":176,"y":-1758},{"x":176,"y":-1822}],"textPositions":{"0":{"x":188,"y":-1428},"1":{"x":164,"y":-1456},"2":{"x":164,"y":-1804},"3":{"x":188,"y":-1776},"4":{"x":164,"y":-1616},"5":{"x":164,"y":-1616},"6":{"x":188,"y":-1616}}},"warnings":null},{"id":662,"sourceNodeId":129,"sourcePortId":1339,"targetNodeId":167,"targetPortId":1340,"travelTime":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":368},"sourceArrival":{"lock":true,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"targetDeparture":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":33},"targetArrival":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":387},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2032,"y":382},{"x":-2032,"y":446},{"x":-2032,"y":574},{"x":-2032,"y":638}],"textPositions":{"0":{"x":-2044,"y":400},"1":{"x":-2020,"y":428},"2":{"x":-2020,"y":620},"3":{"x":-2044,"y":592},"4":{"x":-2044,"y":510},"5":{"x":-2044,"y":510},"6":{"x":-2020,"y":510}}},"warnings":null},{"id":663,"sourceNodeId":167,"sourcePortId":1341,"targetNodeId":168,"targetPortId":1342,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":388},"sourceArrival":{"lock":false,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":32},"targetDeparture":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":22},"targetArrival":{"lock":true,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":398},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2032,"y":706},{"x":-2032,"y":770},{"x":-2032,"y":862},{"x":-2032,"y":926}],"textPositions":{"0":{"x":-2044,"y":724},"1":{"x":-2020,"y":752},"2":{"x":-2020,"y":908},"3":{"x":-2044,"y":880},"4":{"x":-2044,"y":816},"5":{"x":-2044,"y":816},"6":{"x":-2020,"y":816}}},"warnings":null},{"id":664,"sourceNodeId":168,"sourcePortId":1343,"targetNodeId":131,"targetPortId":1344,"travelTime":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":399},"sourceArrival":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":21},"targetDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":0},"targetArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":420},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2014,"y":976},{"x":-1950,"y":976},{"x":-1154,"y":976},{"x":-1090,"y":976}],"textPositions":{"0":{"x":-1996,"y":988},"1":{"x":-1968,"y":964},"2":{"x":-1108,"y":964},"3":{"x":-1136,"y":988},"4":{"x":-1552,"y":964},"5":{"x":-1552,"y":964},"6":{"x":-1552,"y":988}}},"warnings":null},{"id":665,"sourceNodeId":169,"sourcePortId":1345,"targetNodeId":153,"targetPortId":1346,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":48},"sourceArrival":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":252},"targetDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":243},"targetArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":57},"numberOfStops":0,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1954,"y":1776},{"x":2018,"y":1776},{"x":2590,"y":1360},{"x":2654,"y":1360}],"textPositions":{"0":{"x":1972,"y":1788},"1":{"x":2000,"y":1764},"2":{"x":2636,"y":1348},"3":{"x":2608,"y":1372},"4":{"x":2304,"y":1556},"5":{"x":2304,"y":1556},"6":{"x":2304,"y":1580}}},"warnings":null},{"id":666,"sourceNodeId":169,"sourcePortId":1347,"targetNodeId":153,"targetPortId":1348,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"sourceArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":42},"targetDeparture":{"lock":false,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":32},"targetArrival":{"lock":false,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":28},"numberOfStops":0,"trainrunId":80,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1954,"y":1744},{"x":2018,"y":1744},{"x":2590,"y":1328},{"x":2654,"y":1328}],"textPositions":{"0":{"x":1972,"y":1756},"1":{"x":2000,"y":1732},"2":{"x":2636,"y":1316},"3":{"x":2608,"y":1340},"4":{"x":2304,"y":1524},"5":{"x":2304,"y":1524},"6":{"x":2304,"y":1548}}},"warnings":null},{"id":667,"sourceNodeId":169,"sourcePortId":1349,"targetNodeId":142,"targetPortId":1350,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":453},"sourceArrival":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":147},"targetDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":138},"targetArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":462},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1854,"y":1776},{"x":1790,"y":1776},{"x":290,"y":1776},{"x":226,"y":1776}],"textPositions":{"0":{"x":1836,"y":1764},"1":{"x":1808,"y":1788},"2":{"x":244,"y":1788},"3":{"x":272,"y":1764},"4":{"x":1040,"y":1764},"5":{"x":1040,"y":1764},"6":{"x":1040,"y":1788}}},"warnings":null},{"id":668,"sourceNodeId":169,"sourcePortId":1351,"targetNodeId":142,"targetPortId":1352,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":273},"sourceArrival":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":87},"targetDeparture":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":78},"targetArrival":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":282},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1854,"y":1744},{"x":1790,"y":1744},{"x":290,"y":1744},{"x":226,"y":1744}],"textPositions":{"0":{"x":1836,"y":1732},"1":{"x":1808,"y":1756},"2":{"x":244,"y":1756},"3":{"x":272,"y":1732},"4":{"x":1040,"y":1732},"5":{"x":1040,"y":1732},"6":{"x":1040,"y":1756}}},"warnings":null},{"id":669,"sourceNodeId":170,"sourcePortId":1353,"targetNodeId":135,"targetPortId":1354,"travelTime":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":74},"sourceArrival":{"lock":true,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":226},"targetDeparture":{"lock":true,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":215},"targetArrival":{"lock":true,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":85},"numberOfStops":0,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2832,"y":734},{"x":2832,"y":670},{"x":2832,"y":414},{"x":2832,"y":350}],"textPositions":{"0":{"x":2844,"y":716},"1":{"x":2820,"y":688},"2":{"x":2820,"y":368},"3":{"x":2844,"y":396},"4":{"x":2820,"y":542},"5":{"x":2820,"y":542},"6":{"x":2844,"y":542}}},"warnings":null},{"id":670,"sourceNodeId":170,"sourcePortId":1355,"targetNodeId":135,"targetPortId":1356,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":43},"sourceArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":17},"targetDeparture":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":10},"targetArrival":{"lock":true,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":50},"numberOfStops":0,"trainrunId":80,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2800,"y":734},{"x":2800,"y":670},{"x":2800,"y":414},{"x":2800,"y":350}],"textPositions":{"0":{"x":2812,"y":716},"1":{"x":2788,"y":688},"2":{"x":2788,"y":368},"3":{"x":2812,"y":396},"4":{"x":2788,"y":542},"5":{"x":2788,"y":542},"6":{"x":2812,"y":542}}},"warnings":null},{"id":671,"sourceNodeId":170,"sourcePortId":1357,"targetNodeId":135,"targetPortId":1358,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetDeparture":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":5},"targetArrival":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":355},"numberOfStops":0,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2768,"y":734},{"x":2768,"y":670},{"x":2768,"y":414},{"x":2768,"y":350}],"textPositions":{"0":{"x":2780,"y":716},"1":{"x":2756,"y":688},"2":{"x":2756,"y":368},"3":{"x":2780,"y":396},"4":{"x":2756,"y":542},"5":{"x":2756,"y":542},"6":{"x":2780,"y":542}}},"warnings":null},{"id":672,"sourceNodeId":170,"sourcePortId":1359,"targetNodeId":135,"targetPortId":1360,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":107},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetDeparture":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":5},"targetArrival":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":115},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":734},{"x":2672,"y":670},{"x":2672,"y":414},{"x":2672,"y":350}],"textPositions":{"0":{"x":2684,"y":716},"1":{"x":2660,"y":688},"2":{"x":2660,"y":368},"3":{"x":2684,"y":396},"4":{"x":2660,"y":542},"5":{"x":2660,"y":542},"6":{"x":2684,"y":542}}},"warnings":null},{"id":673,"sourceNodeId":170,"sourcePortId":1361,"targetNodeId":140,"targetPortId":1362,"travelTime":{"lock":true,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":75},"sourceArrival":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":285},"targetDeparture":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":238},"targetArrival":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":122},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":752},{"x":2914,"y":752},{"x":4574,"y":1200},{"x":4638,"y":1200}],"textPositions":{"0":{"x":2868,"y":764},"1":{"x":2896,"y":740},"2":{"x":4620,"y":1188},"3":{"x":4592,"y":1212},"4":{"x":3744,"y":964},"5":{"x":3744,"y":964},"6":{"x":3744,"y":988}}},"warnings":null},{"id":674,"sourceNodeId":170,"sourcePortId":1363,"targetNodeId":140,"targetPortId":1364,"travelTime":{"lock":false,"time":61,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":141},"sourceArrival":{"lock":true,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":279},"targetDeparture":{"lock":true,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":218},"targetArrival":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":202},"numberOfStops":5,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":784},{"x":2914,"y":784},{"x":4574,"y":1232},{"x":4638,"y":1232}],"textPositions":{"0":{"x":2868,"y":796},"1":{"x":2896,"y":772},"2":{"x":4620,"y":1220},"3":{"x":4592,"y":1244},"4":{"x":3744,"y":996},"5":{"x":3744,"y":996},"6":{"x":3744,"y":1020}}},"warnings":null},{"id":675,"sourceNodeId":142,"sourcePortId":1365,"targetNodeId":141,"targetPortId":1366,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":475},"sourceArrival":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":125},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":494},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":1726},{"x":144,"y":1662},{"x":144,"y":1314},{"x":144,"y":1250}],"textPositions":{"0":{"x":156,"y":1708},"1":{"x":132,"y":1680},"2":{"x":132,"y":1268},"3":{"x":156,"y":1296},"4":{"x":132,"y":1488},"5":{"x":132,"y":1488},"6":{"x":156,"y":1488}}},"warnings":null},{"id":676,"sourceNodeId":141,"sourcePortId":1367,"targetNodeId":143,"targetPortId":1368,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":494},"sourceArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"targetDeparture":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":99},"targetArrival":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":501},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":1182},{"x":144,"y":1118},{"x":144,"y":866},{"x":144,"y":802}],"textPositions":{"0":{"x":156,"y":1164},"1":{"x":132,"y":1136},"2":{"x":132,"y":820},"3":{"x":156,"y":848},"4":{"x":132,"y":992},"5":{"x":132,"y":992},"6":{"x":156,"y":992}}},"warnings":null},{"id":677,"sourceNodeId":143,"sourcePortId":1369,"targetNodeId":133,"targetPortId":1370,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":503},"sourceArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":97},"targetDeparture":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetArrival":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":510},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":734},{"x":112,"y":670},{"x":112,"y":414},{"x":112,"y":350}],"textPositions":{"0":{"x":124,"y":716},"1":{"x":100,"y":688},"2":{"x":100,"y":368},"3":{"x":124,"y":396},"4":{"x":100,"y":542},"5":{"x":100,"y":542},"6":{"x":124,"y":542}}},"warnings":null},{"id":678,"sourceNodeId":133,"sourcePortId":1371,"targetNodeId":144,"targetPortId":1372,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":512},"sourceArrival":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":88},"targetDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":78},"targetArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":522},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":94},{"x":176,"y":30},{"x":176,"y":-290},{"x":176,"y":-354}],"textPositions":{"0":{"x":188,"y":76},"1":{"x":164,"y":48},"2":{"x":164,"y":-336},"3":{"x":188,"y":-308},"4":{"x":164,"y":-130},"5":{"x":164,"y":-130},"6":{"x":188,"y":-130}}},"warnings":null},{"id":679,"sourceNodeId":144,"sourcePortId":1373,"targetNodeId":145,"targetPortId":1374,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":522},"sourceArrival":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":78},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":73},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":527},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":240,"y":-450},{"x":240,"y":-514},{"x":240,"y":-798},{"x":240,"y":-862}],"textPositions":{"0":{"x":252,"y":-468},"1":{"x":228,"y":-496},"2":{"x":228,"y":-844},"3":{"x":252,"y":-816},"4":{"x":228,"y":-656},"5":{"x":228,"y":-656},"6":{"x":252,"y":-656}}},"warnings":null},{"id":680,"sourceNodeId":145,"sourcePortId":1375,"targetNodeId":146,"targetPortId":1376,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":527},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":73},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":532},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":240,"y":-930},{"x":240,"y":-994},{"x":240,"y":-1278},{"x":240,"y":-1342}],"textPositions":{"0":{"x":252,"y":-948},"1":{"x":228,"y":-976},"2":{"x":228,"y":-1324},"3":{"x":252,"y":-1296},"4":{"x":228,"y":-1136},"5":{"x":228,"y":-1136},"6":{"x":252,"y":-1136}}},"warnings":null},{"id":681,"sourceNodeId":146,"sourcePortId":1377,"targetNodeId":134,"targetPortId":1378,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":532},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":63},"targetArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":537},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":240,"y":-1410},{"x":240,"y":-1474},{"x":240,"y":-1758},{"x":240,"y":-1822}],"textPositions":{"0":{"x":252,"y":-1428},"1":{"x":228,"y":-1456},"2":{"x":228,"y":-1804},"3":{"x":252,"y":-1776},"4":{"x":228,"y":-1616},"5":{"x":228,"y":-1616},"6":{"x":252,"y":-1616}}},"warnings":null},{"id":682,"sourceNodeId":171,"sourcePortId":1379,"targetNodeId":128,"targetPortId":1380,"travelTime":{"lock":false,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":387},"sourceArrival":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":153},"targetDeparture":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":104},"targetArrival":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":436},"numberOfStops":2,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2562,"y":336},{"x":-2626,"y":336},{"x":-2910,"y":592},{"x":-2974,"y":592}],"textPositions":{"0":{"x":-2580,"y":324},"1":{"x":-2608,"y":348},"2":{"x":-2956,"y":604},"3":{"x":-2928,"y":580},"4":{"x":-2768,"y":452},"5":{"x":-2768,"y":452},"6":{"x":-2768,"y":476}}},"warnings":null},{"id":683,"sourceNodeId":171,"sourcePortId":1381,"targetNodeId":128,"targetPortId":1382,"travelTime":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":414},"sourceArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":126},"targetDeparture":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":82},"targetArrival":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":458},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2562,"y":304},{"x":-2626,"y":304},{"x":-2910,"y":560},{"x":-2974,"y":560}],"textPositions":{"0":{"x":-2580,"y":292},"1":{"x":-2608,"y":316},"2":{"x":-2956,"y":572},"3":{"x":-2928,"y":548},"4":{"x":-2768,"y":420},"5":{"x":-2768,"y":420},"6":{"x":-2768,"y":444}}},"warnings":null},{"id":684,"sourceNodeId":172,"sourcePortId":1383,"targetNodeId":178,"targetPortId":1384,"travelTime":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":339},"sourceArrival":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":201},"targetDeparture":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":184},"targetArrival":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":356},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":304},{"x":-674,"y":304},{"x":-1534,"y":304},{"x":-1598,"y":304}],"textPositions":{"0":{"x":-628,"y":292},"1":{"x":-656,"y":316},"2":{"x":-1580,"y":316},"3":{"x":-1552,"y":292},"4":{"x":-1104,"y":292},"5":{"x":-1104,"y":292},"6":{"x":-1104,"y":316}}},"warnings":null},{"id":685,"sourceNodeId":172,"sourcePortId":1385,"targetNodeId":174,"targetPortId":1386,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":343},"sourceArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":77},"targetDeparture":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":69},"targetArrival":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":351},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":336},{"x":-674,"y":336},{"x":-830,"y":368},{"x":-894,"y":368}],"textPositions":{"0":{"x":-628,"y":324},"1":{"x":-656,"y":348},"2":{"x":-876,"y":380},"3":{"x":-848,"y":356},"4":{"x":-752,"y":340},"5":{"x":-752,"y":340},"6":{"x":-752,"y":364}}},"warnings":null},{"id":686,"sourceNodeId":172,"sourcePortId":1387,"targetNodeId":178,"targetPortId":1388,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":73},"targetDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"targetArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":355},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":272},{"x":-674,"y":272},{"x":-1534,"y":272},{"x":-1598,"y":272}],"textPositions":{"0":{"x":-628,"y":260},"1":{"x":-656,"y":284},"2":{"x":-1580,"y":284},"3":{"x":-1552,"y":260},"4":{"x":-1104,"y":260},"5":{"x":-1104,"y":260},"6":{"x":-1104,"y":284}}},"warnings":null},{"id":687,"sourceNodeId":172,"sourcePortId":1389,"targetNodeId":178,"targetPortId":1390,"travelTime":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":342},"sourceArrival":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":78},"targetDeparture":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":66},"targetArrival":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":354},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":240},{"x":-674,"y":240},{"x":-1534,"y":240},{"x":-1598,"y":240}],"textPositions":{"0":{"x":-628,"y":228},"1":{"x":-656,"y":252},"2":{"x":-1580,"y":252},"3":{"x":-1552,"y":228},"4":{"x":-1104,"y":228},"5":{"x":-1104,"y":228},"6":{"x":-1104,"y":252}}},"warnings":null},{"id":688,"sourceNodeId":172,"sourcePortId":1391,"targetNodeId":178,"targetPortId":1392,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"sourceArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":235},"targetDeparture":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":217},"targetArrival":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":83},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":208},{"x":-674,"y":208},{"x":-1534,"y":208},{"x":-1598,"y":208}],"textPositions":{"0":{"x":-628,"y":196},"1":{"x":-656,"y":220},"2":{"x":-1580,"y":220},"3":{"x":-1552,"y":196},"4":{"x":-1104,"y":196},"5":{"x":-1104,"y":196},"6":{"x":-1104,"y":220}}},"warnings":null},{"id":689,"sourceNodeId":172,"sourcePortId":1393,"targetNodeId":133,"targetPortId":1394,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":234},"sourceArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":66},"targetDeparture":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":58},"targetArrival":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":242},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-510,"y":176},{"x":-446,"y":176},{"x":-2,"y":176},{"x":62,"y":176}],"textPositions":{"0":{"x":-492,"y":188},"1":{"x":-464,"y":164},"2":{"x":44,"y":164},"3":{"x":16,"y":188},"4":{"x":-224,"y":164},"5":{"x":-224,"y":164},"6":{"x":-224,"y":188}}},"warnings":null},{"id":690,"sourceNodeId":172,"sourcePortId":1395,"targetNodeId":178,"targetPortId":1396,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":377},"sourceArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetDeparture":{"lock":false,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":154},"targetArrival":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":386},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":144},{"x":-674,"y":144},{"x":-1534,"y":144},{"x":-1598,"y":144}],"textPositions":{"0":{"x":-628,"y":132},"1":{"x":-656,"y":156},"2":{"x":-1580,"y":156},"3":{"x":-1552,"y":132},"4":{"x":-1104,"y":132},"5":{"x":-1104,"y":132},"6":{"x":-1104,"y":156}}},"warnings":null},{"id":691,"sourceNodeId":173,"sourcePortId":1397,"targetNodeId":178,"targetPortId":1398,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":371},"sourceArrival":{"lock":true,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":49},"targetDeparture":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":39},"targetArrival":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":381},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1346,"y":368},{"x":-1410,"y":368},{"x":-1534,"y":336},{"x":-1598,"y":336}],"textPositions":{"0":{"x":-1364,"y":356},"1":{"x":-1392,"y":380},"2":{"x":-1580,"y":348},"3":{"x":-1552,"y":324},"4":{"x":-1472,"y":340},"5":{"x":-1472,"y":340},"6":{"x":-1472,"y":364}}},"warnings":null},{"id":692,"sourceNodeId":174,"sourcePortId":1399,"targetNodeId":173,"targetPortId":1400,"travelTime":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":352},"sourceArrival":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetDeparture":{"lock":false,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":51},"targetArrival":{"lock":false,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":369},"numberOfStops":1,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-994,"y":368},{"x":-1058,"y":368},{"x":-1182,"y":368},{"x":-1246,"y":368}],"textPositions":{"0":{"x":-1012,"y":356},"1":{"x":-1040,"y":380},"2":{"x":-1228,"y":380},"3":{"x":-1200,"y":356},"4":{"x":-1120,"y":356},"5":{"x":-1120,"y":356},"6":{"x":-1120,"y":380}}},"warnings":null},{"id":693,"sourceNodeId":135,"sourcePortId":1401,"targetNodeId":149,"targetPortId":1402,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":300},"sourceArrival":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"targetDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"targetArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":80},{"x":2590,"y":80},{"x":2402,"y":80},{"x":2338,"y":80}],"textPositions":{"0":{"x":2636,"y":68},"1":{"x":2608,"y":92},"2":{"x":2356,"y":92},"3":{"x":2384,"y":68},"4":{"x":2496,"y":68},"5":{"x":2496,"y":68},"6":{"x":2496,"y":92}}},"warnings":null},{"id":694,"sourceNodeId":149,"sourcePortId":1403,"targetNodeId":166,"targetPortId":1404,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":80},{"x":2174,"y":80},{"x":1954,"y":80},{"x":1890,"y":80}],"textPositions":{"0":{"x":2220,"y":68},"1":{"x":2192,"y":92},"2":{"x":1908,"y":92},"3":{"x":1936,"y":68},"4":{"x":2064,"y":68},"5":{"x":2064,"y":68},"6":{"x":2064,"y":92}}},"warnings":null},{"id":695,"sourceNodeId":166,"sourcePortId":1405,"targetNodeId":148,"targetPortId":1406,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"sourceArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetDeparture":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":40},"targetArrival":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":320},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":80},{"x":1726,"y":80},{"x":1506,"y":80},{"x":1442,"y":80}],"textPositions":{"0":{"x":1772,"y":68},"1":{"x":1744,"y":92},"2":{"x":1460,"y":92},"3":{"x":1488,"y":68},"4":{"x":1616,"y":68},"5":{"x":1616,"y":68},"6":{"x":1616,"y":92}}},"warnings":null},{"id":696,"sourceNodeId":148,"sourcePortId":1407,"targetNodeId":147,"targetPortId":1408,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":320},"sourceArrival":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":40},"targetDeparture":{"lock":false,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":34},"targetArrival":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":326},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":80},{"x":1278,"y":80},{"x":1122,"y":80},{"x":1058,"y":80}],"textPositions":{"0":{"x":1324,"y":68},"1":{"x":1296,"y":92},"2":{"x":1076,"y":92},"3":{"x":1104,"y":68},"4":{"x":1200,"y":68},"5":{"x":1200,"y":68},"6":{"x":1200,"y":92}}},"warnings":null},{"id":697,"sourceNodeId":147,"sourcePortId":1409,"targetNodeId":144,"targetPortId":1410,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":326},"sourceArrival":{"lock":false,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":34},"targetDeparture":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":27},"targetArrival":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":333},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":48},{"x":894,"y":48},{"x":386,"y":-432},{"x":322,"y":-432}],"textPositions":{"0":{"x":940,"y":36},"1":{"x":912,"y":60},"2":{"x":340,"y":-420},"3":{"x":368,"y":-444},"4":{"x":640,"y":-204},"5":{"x":640,"y":-204},"6":{"x":640,"y":-180}}},"warnings":null},{"id":698,"sourceNodeId":144,"sourcePortId":1411,"targetNodeId":145,"targetPortId":1412,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":333},"sourceArrival":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":27},"targetDeparture":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":21},"targetArrival":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":339},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":-450},{"x":112,"y":-514},{"x":112,"y":-798},{"x":112,"y":-862}],"textPositions":{"0":{"x":124,"y":-468},"1":{"x":100,"y":-496},"2":{"x":100,"y":-844},"3":{"x":124,"y":-816},"4":{"x":100,"y":-656},"5":{"x":100,"y":-656},"6":{"x":124,"y":-656}}},"warnings":null},{"id":699,"sourceNodeId":145,"sourcePortId":1413,"targetNodeId":146,"targetPortId":1414,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":339},"sourceArrival":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":21},"targetDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":14},"targetArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":346},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":-930},{"x":112,"y":-994},{"x":112,"y":-1278},{"x":112,"y":-1342}],"textPositions":{"0":{"x":124,"y":-948},"1":{"x":100,"y":-976},"2":{"x":100,"y":-1324},"3":{"x":124,"y":-1296},"4":{"x":100,"y":-1136},"5":{"x":100,"y":-1136},"6":{"x":124,"y":-1136}}},"warnings":null},{"id":700,"sourceNodeId":146,"sourcePortId":1415,"targetNodeId":134,"targetPortId":1416,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":346},"sourceArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":14},"targetDeparture":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":6},"targetArrival":{"lock":true,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":354},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":-1410},{"x":112,"y":-1474},{"x":112,"y":-1758},{"x":112,"y":-1822}],"textPositions":{"0":{"x":124,"y":-1428},"1":{"x":100,"y":-1456},"2":{"x":100,"y":-1804},"3":{"x":124,"y":-1776},"4":{"x":100,"y":-1616},"5":{"x":100,"y":-1616},"6":{"x":124,"y":-1616}}},"warnings":null},{"id":701,"sourceNodeId":175,"sourcePortId":1417,"targetNodeId":130,"targetPortId":1418,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":421},"sourceArrival":{"lock":true,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":119},"targetDeparture":{"lock":true,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"targetArrival":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":434},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":-16},{"x":-1762,"y":-16},{"x":-2366,"y":-16},{"x":-2430,"y":-16}],"textPositions":{"0":{"x":-1716,"y":-28},"1":{"x":-1744,"y":-4},"2":{"x":-2412,"y":-4},"3":{"x":-2384,"y":-28},"4":{"x":-2064,"y":-28},"5":{"x":-2064,"y":-28},"6":{"x":-2064,"y":-4}}},"warnings":null},{"id":702,"sourceNodeId":137,"sourcePortId":1419,"targetNodeId":176,"targetPortId":1420,"travelTime":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":245},"sourceArrival":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":295},"targetDeparture":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":279},"targetArrival":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":261},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4738,"y":112},{"x":4802,"y":112},{"x":5310,"y":112},{"x":5374,"y":112}],"textPositions":{"0":{"x":4756,"y":124},"1":{"x":4784,"y":100},"2":{"x":5356,"y":100},"3":{"x":5328,"y":124},"4":{"x":5056,"y":100},"5":{"x":5056,"y":100},"6":{"x":5056,"y":124}}},"warnings":null},{"id":703,"sourceNodeId":177,"sourcePortId":1421,"targetNodeId":160,"targetPortId":1422,"travelTime":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":451},"sourceArrival":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":89},"targetDeparture":{"lock":true,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":59},"targetArrival":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":481},"numberOfStops":1,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3522,"y":624},{"x":-3586,"y":624},{"x":-3774,"y":688},{"x":-3838,"y":688}],"textPositions":{"0":{"x":-3540,"y":612},"1":{"x":-3568,"y":636},"2":{"x":-3820,"y":700},"3":{"x":-3792,"y":676},"4":{"x":-3680,"y":644},"5":{"x":-3680,"y":644},"6":{"x":-3680,"y":668}}},"warnings":null},{"id":704,"sourceNodeId":177,"sourcePortId":1423,"targetNodeId":160,"targetPortId":1424,"travelTime":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":472},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetDeparture":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":42},"targetArrival":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":498},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3522,"y":560},{"x":-3586,"y":560},{"x":-3774,"y":624},{"x":-3838,"y":624}],"textPositions":{"0":{"x":-3540,"y":548},"1":{"x":-3568,"y":572},"2":{"x":-3820,"y":636},"3":{"x":-3792,"y":612},"4":{"x":-3680,"y":580},"5":{"x":-3680,"y":580},"6":{"x":-3680,"y":604}}},"warnings":null},{"id":705,"sourceNodeId":177,"sourcePortId":1425,"targetNodeId":160,"targetPortId":1426,"travelTime":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":499},"sourceArrival":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"targetDeparture":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":15},"targetArrival":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":525},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3522,"y":592},{"x":-3586,"y":592},{"x":-3774,"y":656},{"x":-3838,"y":656}],"textPositions":{"0":{"x":-3540,"y":580},"1":{"x":-3568,"y":604},"2":{"x":-3820,"y":668},"3":{"x":-3792,"y":644},"4":{"x":-3680,"y":612},"5":{"x":-3680,"y":612},"6":{"x":-3680,"y":636}}},"warnings":null},{"id":706,"sourceNodeId":178,"sourcePortId":1427,"targetNodeId":129,"targetPortId":1428,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":381},"sourceArrival":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":39},"targetDeparture":{"lock":true,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":36},"targetArrival":{"lock":true,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":384},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":336},{"x":-1762,"y":336},{"x":-1950,"y":336},{"x":-2014,"y":336}],"textPositions":{"0":{"x":-1716,"y":324},"1":{"x":-1744,"y":348},"2":{"x":-1996,"y":348},"3":{"x":-1968,"y":324},"4":{"x":-1856,"y":324},"5":{"x":-1856,"y":324},"6":{"x":-1856,"y":348}}},"warnings":null},{"id":707,"sourceNodeId":178,"sourcePortId":1429,"targetNodeId":129,"targetPortId":1430,"travelTime":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":356},"sourceArrival":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":184},"targetDeparture":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":180},"targetArrival":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":360},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":304},{"x":-1762,"y":304},{"x":-1950,"y":304},{"x":-2014,"y":304}],"textPositions":{"0":{"x":-1716,"y":292},"1":{"x":-1744,"y":316},"2":{"x":-1996,"y":316},"3":{"x":-1968,"y":292},"4":{"x":-1856,"y":292},"5":{"x":-1856,"y":292},"6":{"x":-1856,"y":316}}},"warnings":null},{"id":708,"sourceNodeId":178,"sourcePortId":1431,"targetNodeId":129,"targetPortId":1432,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":355},"sourceArrival":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"targetDeparture":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":62},"targetArrival":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":358},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":272},{"x":-1762,"y":272},{"x":-1950,"y":272},{"x":-2014,"y":272}],"textPositions":{"0":{"x":-1716,"y":260},"1":{"x":-1744,"y":284},"2":{"x":-1996,"y":284},"3":{"x":-1968,"y":260},"4":{"x":-1856,"y":260},"5":{"x":-1856,"y":260},"6":{"x":-1856,"y":284}}},"warnings":null},{"id":709,"sourceNodeId":178,"sourcePortId":1433,"targetNodeId":129,"targetPortId":1434,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":354},"sourceArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":66},"targetDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":63},"targetArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":357},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":240},{"x":-1762,"y":240},{"x":-1950,"y":240},{"x":-2014,"y":240}],"textPositions":{"0":{"x":-1716,"y":228},"1":{"x":-1744,"y":252},"2":{"x":-1996,"y":252},"3":{"x":-1968,"y":228},"4":{"x":-1856,"y":228},"5":{"x":-1856,"y":228},"6":{"x":-1856,"y":252}}},"warnings":null},{"id":710,"sourceNodeId":178,"sourcePortId":1435,"targetNodeId":129,"targetPortId":1436,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":83},"sourceArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":217},"targetDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":214},"targetArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":86},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":208},{"x":-1762,"y":208},{"x":-1950,"y":208},{"x":-2014,"y":208}],"textPositions":{"0":{"x":-1716,"y":196},"1":{"x":-1744,"y":220},"2":{"x":-1996,"y":220},"3":{"x":-1968,"y":196},"4":{"x":-1856,"y":196},"5":{"x":-1856,"y":196},"6":{"x":-1856,"y":220}}},"warnings":null},{"id":711,"sourceNodeId":178,"sourcePortId":1437,"targetNodeId":172,"targetPortId":1438,"travelTime":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":217},"sourceArrival":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":83},"targetDeparture":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":66},"targetArrival":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":234},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1598,"y":176},{"x":-1534,"y":176},{"x":-674,"y":176},{"x":-610,"y":176}],"textPositions":{"0":{"x":-1580,"y":188},"1":{"x":-1552,"y":164},"2":{"x":-628,"y":164},"3":{"x":-656,"y":188},"4":{"x":-1104,"y":164},"5":{"x":-1104,"y":164},"6":{"x":-1104,"y":188}}},"warnings":null},{"id":712,"sourceNodeId":178,"sourcePortId":1439,"targetNodeId":129,"targetPortId":1440,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":386},"sourceArrival":{"lock":false,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":154},"targetDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":151},"targetArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":389},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":144},{"x":-1762,"y":144},{"x":-1950,"y":144},{"x":-2014,"y":144}],"textPositions":{"0":{"x":-1716,"y":132},"1":{"x":-1744,"y":156},"2":{"x":-1996,"y":156},"3":{"x":-1968,"y":132},"4":{"x":-1856,"y":132},"5":{"x":-1856,"y":132},"6":{"x":-1856,"y":156}}},"warnings":null}],"trainruns":[{"id":75,"name":"21","categoryId":1,"frequencyId":4,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":76,"name":"2","categoryId":1,"frequencyId":4,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":77,"name":"26","categoryId":2,"frequencyId":5,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":78,"name":"46","categoryId":2,"frequencyId":4,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":79,"name":"75","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":80,"name":"70","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":81,"name":"15","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":82,"name":"27","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":83,"name":"26","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":84,"name":"13","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":85,"name":"3","categoryId":1,"frequencyId":4,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":86,"name":"35","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":87,"name":"5","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":88,"name":"1","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":89,"name":"8","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":90,"name":"81","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":91,"name":"48","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[1,9,5]},{"id":92,"name":"","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[1,9,5]},{"id":93,"name":"36","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":94,"name":"3","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":95,"name":"61","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":96,"name":"6","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":97,"name":"37","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]}],"resources":[{"id":88,"capacity":2},{"id":89,"capacity":2},{"id":90,"capacity":2},{"id":91,"capacity":2},{"id":92,"capacity":2},{"id":93,"capacity":2},{"id":94,"capacity":2},{"id":95,"capacity":2},{"id":96,"capacity":2},{"id":97,"capacity":2},{"id":98,"capacity":2},{"id":99,"capacity":2},{"id":100,"capacity":2},{"id":101,"capacity":2},{"id":102,"capacity":2},{"id":103,"capacity":2},{"id":104,"capacity":2},{"id":105,"capacity":2},{"id":106,"capacity":2},{"id":107,"capacity":2},{"id":108,"capacity":2},{"id":109,"capacity":2},{"id":110,"capacity":2},{"id":111,"capacity":2},{"id":112,"capacity":2},{"id":113,"capacity":2},{"id":114,"capacity":2},{"id":115,"capacity":2},{"id":116,"capacity":2},{"id":117,"capacity":2},{"id":118,"capacity":2},{"id":119,"capacity":2},{"id":120,"capacity":2},{"id":121,"capacity":2},{"id":122,"capacity":2},{"id":123,"capacity":2},{"id":124,"capacity":2},{"id":125,"capacity":2},{"id":126,"capacity":2},{"id":127,"capacity":2},{"id":128,"capacity":2},{"id":129,"capacity":2},{"id":130,"capacity":2},{"id":131,"capacity":2},{"id":132,"capacity":2},{"id":133,"capacity":2},{"id":134,"capacity":2},{"id":135,"capacity":2},{"id":136,"capacity":2},{"id":137,"capacity":2},{"id":138,"capacity":2},{"id":139,"capacity":2},{"id":140,"capacity":2},{"id":141,"capacity":2},{"id":142,"capacity":2},{"id":143,"capacity":2},{"id":144,"capacity":2},{"id":145,"capacity":2},{"id":146,"capacity":2},{"id":147,"capacity":2},{"id":148,"capacity":2},{"id":149,"capacity":2},{"id":150,"capacity":2},{"id":151,"capacity":2},{"id":152,"capacity":2},{"id":153,"capacity":2},{"id":154,"capacity":2},{"id":155,"capacity":2},{"id":156,"capacity":2},{"id":157,"capacity":2},{"id":158,"capacity":2},{"id":159,"capacity":2},{"id":160,"capacity":2},{"id":161,"capacity":2},{"id":162,"capacity":2},{"id":163,"capacity":2},{"id":164,"capacity":2},{"id":165,"capacity":2},{"id":166,"capacity":2},{"id":167,"capacity":2},{"id":168,"capacity":2},{"id":169,"capacity":2},{"id":170,"capacity":2},{"id":171,"capacity":2},{"id":172,"capacity":2},{"id":173,"capacity":2},{"id":174,"capacity":2},{"id":175,"capacity":2},{"id":176,"capacity":2},{"id":177,"capacity":2},{"id":178,"capacity":2},{"id":179,"capacity":2},{"id":180,"capacity":2},{"id":181,"capacity":2},{"id":182,"capacity":2},{"id":183,"capacity":2},{"id":184,"capacity":2},{"id":185,"capacity":2},{"id":186,"capacity":2},{"id":187,"capacity":2},{"id":188,"capacity":2},{"id":189,"capacity":2},{"id":190,"capacity":2},{"id":191,"capacity":2},{"id":192,"capacity":2},{"id":193,"capacity":2},{"id":194,"capacity":2},{"id":195,"capacity":2},{"id":196,"capacity":2},{"id":197,"capacity":2},{"id":198,"capacity":2},{"id":199,"capacity":2},{"id":200,"capacity":2},{"id":201,"capacity":2},{"id":202,"capacity":2}],"metadata":{"netzgrafikColors":[],"trainrunCategories":[{"id":0,"name":"International","order":0,"colorRef":"EC","shortName":"EC","fachCategory":"HaltezeitIPV","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":1,"name":"InterCity","order":1,"colorRef":"IC","shortName":"IC","fachCategory":"HaltezeitA","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":2,"name":"InterRegio","order":2,"colorRef":"IR","shortName":"IR","fachCategory":"HaltezeitB","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":3,"name":"RegioExpress","order":3,"colorRef":"RE","shortName":"RE","fachCategory":"HaltezeitC","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":4,"name":"RegioUndSBahnverkehr","order":4,"colorRef":"S","shortName":"S","fachCategory":"HaltezeitD","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":5,"name":"GüterExpress","order":5,"colorRef":"GEX","shortName":"GEX","fachCategory":"HaltezeitUncategorized","sectionHeadway":3,"nodeHeadwayStop":3,"nodeHeadwayNonStop":3,"minimalTurnaroundTime":4},{"id":6,"name":"Güterverkehr","order":6,"colorRef":"G","shortName":"G","fachCategory":"HaltezeitUncategorized","sectionHeadway":3,"nodeHeadwayStop":3,"nodeHeadwayNonStop":3,"minimalTurnaroundTime":4}],"trainrunFrequencies":[{"id":0,"name":"verkehrt viertelstündlich","order":0,"offset":0,"frequency":15,"shortName":"15","linePatternRef":"15"},{"id":1,"name":"verkehrt im 20 Minuten Takt","order":0,"offset":0,"frequency":20,"shortName":"20","linePatternRef":"20"},{"id":2,"name":"verkehrt halbstündlich","order":0,"offset":0,"frequency":30,"shortName":"30","linePatternRef":"30"},{"id":3,"name":"verkehrt stündlich","order":0,"offset":0,"frequency":60,"shortName":"60","linePatternRef":"60"},{"id":4,"name":"verkehrt zweistündlich (gerade)","order":0,"offset":0,"frequency":120,"shortName":"120","linePatternRef":"120"},{"id":5,"name":"verkehrt zweistündlich (ungerade)","order":0,"offset":60,"frequency":120,"shortName":"120+","linePatternRef":"120"}],"trainrunTimeCategories":[{"id":0,"name":"verkehrt uneingeschränkt","order":0,"weekday":[1,2,3,4,5,6,7],"shortName":"7/24","linePatternRef":"7/24","dayTimeInterval":[]},{"id":1,"name":"verkehrt zur Hauptverkehrszeit","order":0,"weekday":[1,2,3,4,5,6,7],"shortName":"HVZ","linePatternRef":"HVZ","dayTimeInterval":[{"to":420,"from":360},{"to":1140,"from":960}]},{"id":2,"name":"verkehrt zeitweise","order":0,"weekday":[],"shortName":"zeitweise","linePatternRef":"ZEITWEISE","dayTimeInterval":[]}]},"freeFloatingTexts":[],"labels":[{"id":4,"label":"OK","labelGroupId":1,"labelRef":"Trainrun"},{"id":5,"label":"Zeiten falsch","labelGroupId":3,"labelRef":"Trainrun"}],"labelGroups":[{"id":1,"name":"Standard","labelRef":"Trainrun"},{"id":2,"name":"Standard","labelRef":"Node"},{"id":3,"name":"Standard","labelRef":"Trainrun"}],"filterData":{"filterSettings":[{"id":5,"name":"Neuer Filter","description":"","filterNodeLabels":[],"filterNoteLabels":[],"filterTrainrunLabels":[],"filterArrivalDepartureTime":true,"filterTravelTime":true,"filterTrainrunName":true,"filterConnections":true,"filterShowNonStopTime":true,"filterTrainrunCategory":[{"id":0,"name":"International","order":0,"colorRef":"EC","shortName":"EC","fachCategory":"HaltezeitIPV","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":1,"name":"InterCity","order":1,"colorRef":"IC","shortName":"IC","fachCategory":"HaltezeitA","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":2,"name":"InterRegio","order":2,"colorRef":"IR","shortName":"IR","fachCategory":"HaltezeitB","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":3,"name":"RegioExpress","order":3,"colorRef":"RE","shortName":"RE","fachCategory":"HaltezeitC","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":4,"name":"RegioUndSBahnverkehr","order":4,"colorRef":"S","shortName":"S","fachCategory":"HaltezeitD","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":5,"name":"GüterExpress","order":5,"colorRef":"GEX","shortName":"GEX","fachCategory":"HaltezeitUncategorized","sectionHeadway":3,"nodeHeadwayStop":3,"nodeHeadwayNonStop":3,"minimalTurnaroundTime":4},{"id":6,"name":"Güterverkehr","order":6,"colorRef":"G","shortName":"G","fachCategory":"HaltezeitUncategorized","sectionHeadway":3,"nodeHeadwayStop":3,"nodeHeadwayNonStop":3,"minimalTurnaroundTime":4}],"filterTrainrunFrequency":[{"id":0,"name":"verkehrt viertelstündlich","order":0,"offset":0,"frequency":15,"shortName":"15","linePatternRef":"15"},{"id":1,"name":"verkehrt im 20 Minuten Takt","order":0,"offset":0,"frequency":20,"shortName":"20","linePatternRef":"20"},{"id":2,"name":"verkehrt halbstündlich","order":0,"offset":0,"frequency":30,"shortName":"30","linePatternRef":"30"},{"id":3,"name":"verkehrt stündlich","order":0,"offset":0,"frequency":60,"shortName":"60","linePatternRef":"60"},{"id":4,"name":"verkehrt zweistündlich (gerade)","order":0,"offset":0,"frequency":120,"shortName":"120","linePatternRef":"120"},{"id":5,"name":"verkehrt zweistündlich (ungerade)","order":0,"offset":60,"frequency":120,"shortName":"120+","linePatternRef":"120"}],"filterTrainrunTimeCategory":[{"id":0,"name":"verkehrt uneingeschränkt","order":0,"weekday":[1,2,3,4,5,6,7],"shortName":"7/24","linePatternRef":"7/24","dayTimeInterval":[]},{"id":1,"name":"verkehrt zur Hauptverkehrszeit","order":0,"weekday":[1,2,3,4,5,6,7],"shortName":"HVZ","linePatternRef":"HVZ","dayTimeInterval":[{"to":420,"from":360},{"to":1140,"from":960}]},{"id":2,"name":"verkehrt zeitweise","order":0,"weekday":[],"shortName":"zeitweise","linePatternRef":"ZEITWEISE","dayTimeInterval":[]}],"filterAllEmptyNodes":false,"filterAllNonStopNodes":false,"filterNotes":false,"timeDisplayPrecision":1,"isTemporaryDisableFilteringOfItemsInView":false,"temporaryEmptyAndNonStopFilteringSwitchedOff":false}]}} \ No newline at end of file From f504f0d40a4269fb4ab5a47ce6797e43c1564d32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serge=20Crois=C3=A9?= Date: Mon, 16 Sep 2024 13:35:26 +0200 Subject: [PATCH 087/197] fix: doc: DATA_MODEL_JSON.md, spelling (#276) - ... labels ... - Array of integer --- documentation/DATA_MODEL_JSON.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/documentation/DATA_MODEL_JSON.md b/documentation/DATA_MODEL_JSON.md index 32128f80..22d3bbb8 100644 --- a/documentation/DATA_MODEL_JSON.md +++ b/documentation/DATA_MODEL_JSON.md @@ -32,7 +32,7 @@ understandable representation of data, which facilitates manual editing. - **metadata**: Stores metadata information such as colors, train categories, etc. - **freeFloatingTexts**: Contains any freely placed texts in the Netzgrafik, notes. - **labels**: Represents labels associated with nodes or trainruns. -- **labelGroups**: Groups labels together for easier management and to classify the labels into trainrun labels, node labels and note labes,. +- **labelGroups**: Groups labels together for easier management and to classify the labels into trainrun labels, node labels and note labels,. - **filterData**: Contains data related to filtering the Netzgrafik. This is the basic data structure to represent the various elements in a JSON description. You can populate each element with the specific data relevant to your scenario. @@ -110,7 +110,7 @@ See also [DATA_MODEL.md : business orientated description](https://github.com/Sc - **trainrunCategoryHaltezeiten** : The stop time if the trainrun of product [A, B, C, D or IPV] have to do per default : trainrunCategoryHaltezeiten - **symmetryAxis** : Deprecated : null - **warnings**: If the business logic needs to notify the user about issues, a warning can be used in JSON format : Warning -- **labelIds**: Filterable labels assigned to the node are stored in this array of label identifiers : Arrey of numeric +- **labelIds**: Filterable labels assigned to the node are stored in this array of label identifiers : Array of numeric
@@ -355,7 +355,7 @@ More details about TimeLock - **categoryId**: Reference to the [trainrunCategories](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/main/documentation/DATA_MODEL_JSON.md#metadata) : numeric - **frequencyId**: Reference to the [trainrunFrequencies](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/main/documentation/DATA_MODEL_JSON.md#metadata) : numeric - **trainrunTimeCategoryId**: Reference to the [trainrunTimeCategories](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/main/documentation/DATA_MODEL_JSON.md#metadata) : numeric -- **labelIds**: Filterable labels assigned to the node are stored in this array of label identifiers : Arrey of integer +- **labelIds**: Filterable labels assigned to the node are stored in this array of label identifiers : Array of integer @@ -621,5 +621,5 @@ Define the dayTimeIntervalElement - **text**: The text (description) of the node : string - **backgroundColor**: HTML color as HEX for the background: string - **textColor**: HTML color as HEX for the text: string -- **labelIds**: Filterable labels assigned to the node are stored in this array of label identifiers : Arrey of integer +- **labelIds**: Filterable labels assigned to the node are stored in this array of label identifiers : Array of integer From 853b80fa30b4e2119a919787f2b22bd4f4ac2600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serge=20Crois=C3=A9?= Date: Mon, 16 Sep 2024 13:42:07 +0200 Subject: [PATCH 088/197] fix: doc: Graphic_Timetable.md, spelling, grammar (#277) - along - an early phase - the diagram ... reveals ... - separately - minimum --- documentation/Graphic_Timetable.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/documentation/Graphic_Timetable.md b/documentation/Graphic_Timetable.md index 8ba299d7..efb80810 100644 --- a/documentation/Graphic_Timetable.md +++ b/documentation/Graphic_Timetable.md @@ -6,15 +6,14 @@ The graphic timetable (Streckengraphik) is a ***distance-time diagram***. This d representation which shows the relationship between the distance travelled and the time taken. The diagram shows the course of train journeys along a route corridor. -In the distance-time diagram, the horizontal axis (x-axis) represents the distance traveled a long +In the distance-time diagram, the horizontal axis (x-axis) represents the distance traveled along the corridor of interest, and the vertical axis (y-axis) represents time. The units on the time axis are given in minutes. Due to the unspecified distance in the previously designed Netzgrafik, the exact distance cannot be determined. To ensure readability, there are two different scaling heuristics: -- **Equal distances between the sections**: Each section has the same width, i.e. it has the same - number - of pixels. It is important to understand that the speed can only be compared within a section +- **Equal distances between the sections**: Each section has the same width, i.e., it has the same + number of pixels. It is important to understand that the speed can only be compared within a section based on the angles. Comparing two sections based on the angle is not very meaningful as the actual distance travelled can be very different. Therefore, the comparison cannot be made due to the lack of information. @@ -77,7 +76,7 @@ there must be future expand the node's capacity to run the concept smoothly. This information can help in efficient train planning and ensures that there is adequate infrastructure to accommodate trains during their scheduled stops. It enables better utilization of resources and facilitates smooth and reliable train processes. Further can this information help to -continue working on a variant or reject in a early phase. +continue working on a variant or reject in an early phase. When a train ends or starts at a node, track occupancy is more complicated. The track occupancy must take the turnaround into account. A simple turnaround is possible if the minimum dwell time for the @@ -98,9 +97,9 @@ Example #### Minimum number of tracks on sections The distance-time diagram provides a graphical overview of the entire corridor of interest and -reveal points of intersection or overlap between different train runs. These intersection points -indicate potential conflicts or temporal overlaps between trains. The temporal overlaps takes also -into account of the headway time which can be defined for each trainrun category seperatly. +reveals points of intersection or overlap between different train runs. These intersection points +indicate potential conflicts or temporal overlaps between trains. The temporal overlaps take also +into account the headway time which can be defined for each trainrun category separately. By analyzing these conflicting regions in the distance-time diagram, it is possible to estimate the minimum number of tracks needed to ensure smooth train operations. These projections can give @@ -117,6 +116,6 @@ working on the variant or reject it. Example -![minum number of tracks on sections](./images/Overview_Streckengrafik_Screenshot_003.png) +![minimum number of tracks on sections](./images/Overview_Streckengrafik_Screenshot_003.png)
From b8159b4e177a762e5cdb229c488a6c208dc72d29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:45:25 +0200 Subject: [PATCH 089/197] Bump webpack and @angular-devkit/build-angular (#283) Bumps [webpack](https://github.com/webpack/webpack) to 5.94.0 and updates ancestor dependency [@angular-devkit/build-angular](https://github.com/angular/angular-cli). These dependencies need to be updated together. Updates `webpack` from 5.90.3 to 5.94.0 - [Release notes](https://github.com/webpack/webpack/releases) - [Commits](https://github.com/webpack/webpack/compare/v5.90.3...v5.94.0) Updates `@angular-devkit/build-angular` from 17.3.8 to 17.3.9 - [Release notes](https://github.com/angular/angular-cli/releases) - [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md) - [Commits](https://github.com/angular/angular-cli/compare/17.3.8...17.3.9) --- updated-dependencies: - dependency-name: webpack dependency-type: indirect - dependency-name: "@angular-devkit/build-angular" dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 120 ++++++++++++++++++++++++---------------------- package.json | 2 +- 2 files changed, 63 insertions(+), 59 deletions(-) diff --git a/package-lock.json b/package-lock.json index b3f5bdcc..ce3c79e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ }, "devDependencies": { "@angular-devkit/architect": "^0.1700.10", - "@angular-devkit/build-angular": "^17.3.8", + "@angular-devkit/build-angular": "^17.3.9", "@angular-eslint/builder": "17.1.1", "@angular-eslint/eslint-plugin": "17.1.1", "@angular-eslint/eslint-plugin-template": "17.1.1", @@ -109,15 +109,15 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "17.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-17.3.8.tgz", - "integrity": "sha512-ixsdXggWaFRP7Jvxd0AMukImnePuGflT9Yy7NJ9/y0cL/k//S/3RnkQv5i411KzN+7D4RIbNkRGGTYeqH24zlg==", + "version": "17.3.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-17.3.9.tgz", + "integrity": "sha512-EuAPSC4c2DSJLlL4ieviKLx1faTyY+ymWycq6KFwoxu1FgWly/dqBeWyXccYinLhPVZmoh6+A/5S4YWXlOGSnA==", "dev": true, "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1703.8", - "@angular-devkit/build-webpack": "0.1703.8", - "@angular-devkit/core": "17.3.8", + "@angular-devkit/architect": "0.1703.9", + "@angular-devkit/build-webpack": "0.1703.9", + "@angular-devkit/core": "17.3.9", "@babel/core": "7.24.0", "@babel/generator": "7.23.6", "@babel/helper-annotate-as-pure": "7.22.5", @@ -128,7 +128,7 @@ "@babel/preset-env": "7.24.0", "@babel/runtime": "7.24.0", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "17.3.8", + "@ngtools/webpack": "17.3.9", "@vitejs/plugin-basic-ssl": "1.1.0", "ansi-colors": "4.1.3", "autoprefixer": "10.4.18", @@ -172,7 +172,7 @@ "undici": "6.11.1", "vite": "5.1.7", "watchpack": "2.4.0", - "webpack": "5.90.3", + "webpack": "5.94.0", "webpack-dev-middleware": "6.1.2", "webpack-dev-server": "4.15.1", "webpack-merge": "5.10.0", @@ -238,12 +238,12 @@ } }, "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/architect": { - "version": "0.1703.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1703.8.tgz", - "integrity": "sha512-lKxwG4/QABXZvJpqeSIn/kAwnY6MM9HdHZUV+o5o3UiTi+vO8rZApG4CCaITH3Bxebm7Nam7Xbk8RuukC5rq6g==", + "version": "0.1703.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1703.9.tgz", + "integrity": "sha512-kEPfTOVnzrJxPGTvaXy8653HU9Fucxttx9gVfQR1yafs+yIEGx3fKGKe89YPmaEay32bIm7ZUpxDF1FO14nkdQ==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.3.8", + "@angular-devkit/core": "17.3.9", "rxjs": "7.8.1" }, "engines": { @@ -253,9 +253,9 @@ } }, "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { - "version": "17.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.8.tgz", - "integrity": "sha512-Q8q0voCGudbdCgJ7lXdnyaxKHbNQBARH68zPQV72WT8NWy+Gw/tys870i6L58NWbBaCJEUcIj/kb6KoakSRu+Q==", + "version": "17.3.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.9.tgz", + "integrity": "sha512-/iKyn5YT7NW5ylrg9yufUydS8byExeQ2HHIwFC4Ebwb/JYYCz+k4tBf2LdP+zXpemDpLznXTQGWia0/yJjG8Vg==", "dev": true, "dependencies": { "ajv": "8.12.0", @@ -295,12 +295,12 @@ "dev": true }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1703.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1703.8.tgz", - "integrity": "sha512-9u6fl8VVOxcLOEMzrUeaybSvi9hSLSRucHnybneYrabsgreDo32tuy/4G8p6YAHQjpWEj9jvF9Um13ertdni5Q==", + "version": "0.1703.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1703.9.tgz", + "integrity": "sha512-3b0LND39Nc+DwCQ0N7Tbsd7RAFWTeIc4VDwk/7RO8EMYTP5Kfgr/TK66nwTBypHsjmD69IMKHZZaZuiDfGfx2A==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1703.8", + "@angular-devkit/architect": "0.1703.9", "rxjs": "7.8.1" }, "engines": { @@ -314,12 +314,12 @@ } }, "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/architect": { - "version": "0.1703.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1703.8.tgz", - "integrity": "sha512-lKxwG4/QABXZvJpqeSIn/kAwnY6MM9HdHZUV+o5o3UiTi+vO8rZApG4CCaITH3Bxebm7Nam7Xbk8RuukC5rq6g==", + "version": "0.1703.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1703.9.tgz", + "integrity": "sha512-kEPfTOVnzrJxPGTvaXy8653HU9Fucxttx9gVfQR1yafs+yIEGx3fKGKe89YPmaEay32bIm7ZUpxDF1FO14nkdQ==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.3.8", + "@angular-devkit/core": "17.3.9", "rxjs": "7.8.1" }, "engines": { @@ -329,9 +329,9 @@ } }, "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/core": { - "version": "17.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.8.tgz", - "integrity": "sha512-Q8q0voCGudbdCgJ7lXdnyaxKHbNQBARH68zPQV72WT8NWy+Gw/tys870i6L58NWbBaCJEUcIj/kb6KoakSRu+Q==", + "version": "17.3.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.9.tgz", + "integrity": "sha512-/iKyn5YT7NW5ylrg9yufUydS8byExeQ2HHIwFC4Ebwb/JYYCz+k4tBf2LdP+zXpemDpLznXTQGWia0/yJjG8Vg==", "dev": true, "dependencies": { "ajv": "8.12.0", @@ -3568,9 +3568,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "17.3.8", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-17.3.8.tgz", - "integrity": "sha512-CjSVVa/9fzMpEDQP01SC4colKCbZwj7vUq0H2bivp8jVsmd21x9Fu0gDBH0Y9NdfAIm4eGZvmiZKMII3vIOaYQ==", + "version": "17.3.9", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-17.3.9.tgz", + "integrity": "sha512-2+NvEQuYKRWdZaJbRJWEnR48tpW0uYbhwfHBHLDI9Kazb3mb0oAwYBVXdq+TtDLBypXnMsFpCewjRHTvkVx4/A==", "dev": true, "engines": { "node": "^18.13.0 || >=20.9.0", @@ -5067,21 +5067,13 @@ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.0.tgz", "integrity": "sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -6073,10 +6065,10 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", "dev": true, "peerDependencies": { "acorn": "^8" @@ -12115,9 +12107,9 @@ "dev": true }, "node_modules/launch-editor": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.1.tgz", - "integrity": "sha512-elBx2l/tp9z99X5H/qev8uyDywVh0VXAwEbjk8kJhnc5grOFkGh7aW6q55me9xnYbss261XtnUrysZ+XvGbhQA==", + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.2.tgz", + "integrity": "sha512-eF5slEUZXmi6WvFzI3dYcv+hA24/iKnROf24HztcURJpSz9RBmBgz5cNCVOeguouf1llrwy6Yctl4C4HM+xI8g==", "dev": true, "dependencies": { "picocolors": "^1.0.0", @@ -17763,26 +17755,25 @@ "dev": true }, "node_modules/webpack": { - "version": "5.90.3", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", - "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dev": true, "dependencies": { - "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", + "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", @@ -17790,7 +17781,7 @@ "schema-utils": "^3.2.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.0", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { @@ -18040,6 +18031,19 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/webpack/node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", diff --git a/package.json b/package.json index 254425e9..710e4ccc 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ }, "devDependencies": { "@angular-devkit/architect": "^0.1700.10", - "@angular-devkit/build-angular": "^17.3.8", + "@angular-devkit/build-angular": "^17.3.9", "@angular-eslint/builder": "17.1.1", "@angular-eslint/eslint-plugin": "17.1.1", "@angular-eslint/eslint-plugin-template": "17.1.1", From 3773b31874f07ee9939bd0f72f6462e0f7358189 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:46:30 +0200 Subject: [PATCH 090/197] chore(main): release netzgrafik-frontend 2.7.14 (#286) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8bc18390..d2300db9 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.7.13" + ".": "2.7.14" } diff --git a/CHANGELOG.md b/CHANGELOG.md index fe8beee6..bb3db265 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [2.7.14](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.7.13...netzgrafik-frontend-v2.7.14) (2024-09-16) + + +### Bug Fixes + +* doc: DATA_MODEL_JSON.md, spelling ([#276](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/276)) ([f504f0d](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/f504f0d40a4269fb4ab5a47ce6797e43c1564d32)) +* doc: Graphic_Timetable.md, spelling, grammar ([#277](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/277)) ([853b80f](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/853b80fa30b4e2119a919787f2b22bd4f4ac2600)) + ## [2.7.13](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.7.12...netzgrafik-frontend-v2.7.13) (2024-08-29) diff --git a/package-lock.json b/package-lock.json index ce3c79e7..1087dfcd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.7.13", + "version": "2.7.14", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.7.13", + "version": "2.7.14", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index 710e4ccc..7dd1236f 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.7.13", + "version": "2.7.14", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From d587e6e64835aea3964597229b98cbb38ff0f25a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Henriot?= <142150521+shenriotpro@users.noreply.github.com> Date: Tue, 17 Sep 2024 11:27:37 +0200 Subject: [PATCH 091/197] add the interface for origin-destination CSV (#280) --- documentation/ORIGIN_DESTINATION_MATRIX.md | 13 +++++ src/app/services/data/node.service.ts | 8 +++ .../editor-tools-view.component.html | 10 ++++ .../editor-tools-view.component.ts | 55 +++++++++++++++---- src/assets/i18n/de.json | 10 +++- src/assets/i18n/en.json | 10 +++- src/assets/i18n/fr.json | 10 +++- src/assets/i18n/it.json | 10 +++- 8 files changed, 112 insertions(+), 14 deletions(-) create mode 100644 documentation/ORIGIN_DESTINATION_MATRIX.md diff --git a/documentation/ORIGIN_DESTINATION_MATRIX.md b/documentation/ORIGIN_DESTINATION_MATRIX.md new file mode 100644 index 00000000..fdd7a4f2 --- /dev/null +++ b/documentation/ORIGIN_DESTINATION_MATRIX.md @@ -0,0 +1,13 @@ +## Origin Destination Matrix + +The Origin Destination Matrix shows the optimized travel time (total cost) between each pair of nodes. + +The optimized travel time includes a fixed penalty for each connection, but the Origin Destination Matrix also shows the corresponding effective travel time and number of connections. + +### Filtering + +If some nodes are selected, then the Origin Destination Matrix will only show results between these nodes (but other nodes may be used to compute paths). + +The Origin Destination Matrix will only show results between visible nodes (but other nodes may be used to compute paths). + +The Origin Destination Matrix will only use visible trainruns to compute paths. diff --git a/src/app/services/data/node.service.ts b/src/app/services/data/node.service.ts index c71838b7..e705bfb1 100644 --- a/src/app/services/data/node.service.ts +++ b/src/app/services/data/node.service.ts @@ -1231,6 +1231,14 @@ export class NodeService implements OnDestroy { return Object.assign({}, this.nodesStore).nodes; } + getVisibleNodes(): Node[] { + return this.getNodes().filter((n) => this.filterService.filterNode(n)); + } + + getSelectedNodes(): Node[] { + return this.getNodes().filter((n) => n.selected()); + } + getAllNodeLabels(): string[] { let nodeLabels = []; this.getNodes().forEach((n) => diff --git a/src/app/view/editor-tools-view-component/editor-tools-view.component.html b/src/app/view/editor-tools-view-component/editor-tools-view.component.html index fde30347..735ab888 100644 --- a/src/app/view/editor-tools-view-component/editor-tools-view.component.html +++ b/src/app/view/editor-tools-view-component/editor-tools-view.component.html @@ -71,6 +71,16 @@

{{ 'app.view.editor-side-view.editor-tools-view-compone {{ 'app.view.editor-side-view.editor-tools-view-component.export-trainruns-as-csv-excel' | translate }} + + {{ 'app.view.editor-side-view.editor-tools-view-component.base-data' | translate }} diff --git a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts index 577ed715..973f8140 100644 --- a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts +++ b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts @@ -174,6 +174,12 @@ export class EditorToolsViewComponent { this.onExport(filename, csvData); } + onExportOriginDestination() { + const filename = $localize`:@@app.view.editor-side-view.editor-tools-view-component.originDestinationFile:originDestination` + ".csv"; + const csvData = this.convertToOriginDestinationCSV(); + this.onExport(filename, csvData); + } + onExport(filename: string, csvData: string) { const blob = new Blob([csvData], { type: "text/csv", @@ -199,8 +205,18 @@ export class EditorToolsViewComponent { return this.versionControlService.getVariantIsWritable(); } - private convertToStammdatenCSV(): string { + private buildCSVString(headers: string[], rows: string[][]): string{ const separator = ";"; + + const contentData: string[] = []; + contentData.push(headers.join(separator)); + rows.forEach((row) => { + contentData.push(row.join(separator)); + }); + return contentData.join("\n"); + } + + private convertToStammdatenCSV(): string { const comma = ","; const headers: string[] = []; @@ -218,8 +234,7 @@ export class EditorToolsViewComponent { headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.Y:Y`); headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.create:Create`); - const contentData: string[] = []; - contentData.push(headers.join(separator)); + const rows: string[][] = []; this.nodeService.getNodes().forEach((nodeElement) => { const trainrunCategoryHaltezeit: TrainrunCategoryHaltezeit = nodeElement.getTrainrunCategoryHaltezeit(); @@ -288,9 +303,9 @@ export class EditorToolsViewComponent { row.push("" + nodeElement.getPositionX()); row.push("" + nodeElement.getPositionY()); row.push(erstellen); - contentData.push(row.join(separator)); + rows.push(row); }); - return contentData.join("\n"); + return this.buildCSVString(headers, rows); } private getContainertoExport() { @@ -355,9 +370,7 @@ export class EditorToolsViewComponent { } private convertToZuglaufCSV(): string { - const separator = ";"; const comma = ","; - const contentData: string[] = []; const headers: string[] = []; headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.trainCategory:Train category`); headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.trainName:Train name`); @@ -376,7 +389,7 @@ export class EditorToolsViewComponent { headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.turnaroundTime:Turnaround time`); headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.labels:Labels`); - contentData.push(headers.join(separator)); + const rows: string[][] = []; this.trainrunService .getTrainruns() .filter((trainrun) => this.filterService.filterTrainrun(trainrun)) @@ -477,8 +490,30 @@ export class EditorToolsViewComponent { .join(comma), ); - contentData.push(row.join(separator)); + rows.push(row); }); - return contentData.join("\n"); + return this.buildCSVString(headers, rows); + } + + private convertToOriginDestinationCSV(): string { + const headers: string[] = []; + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.origin:Origin`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.destination:Destination`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.travelTime:Travel time`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.connections:Connections`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.totalCost:Total cost`); + + const selectedNodes = this.nodeService.getSelectedNodes(); + const nodes = selectedNodes.length > 0 ? selectedNodes : this.nodeService.getVisibleNodes(); + + // TODO: implement the actual shortest path algorithm. + const rows = []; + nodes.forEach((origin) => { + nodes.forEach((destination) => { + const row = [origin.getFullName(), destination.getFullName(), "-1", "-1", "-1"]; + rows.push(row); + });}); + + return this.buildCSVString(headers, rows); } } diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index 0831f58c..e6982068 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -445,6 +445,8 @@ "export-trainruns": "Zugfahrten exportieren", "export-trainruns-as-csv": "Zugfahrten als CSV exportieren", "export-trainruns-as-csv-excel": "In Excel: Daten -> Aus Text/CSV -> Filename ... importieren", + "export-origin-destination": "Export origin-destination", + "export-origin-destination-as-csv": "Export origin-destination as CSV", "base-data": "Stammdaten", "import-base-data": "Stammdaten importieren", "help-csv-data": "Hilfe: CSV - Datei", @@ -468,6 +470,7 @@ "netzgrafikFile": "netzgrafik", "baseDataFile": "stammdaten", "trainrunFile": "zuglauf", + "originDestinationFile": "originDestination", "trainCategory": "Zugkategorie", "trainName": "Zugname", "startStation": "Startbahnhof", @@ -483,7 +486,12 @@ "arrivalMinuteAtStart": "Ankuntsminute am Start Knoten", "turnaroundTimeStart": "Wendezeit Startbahnhof", "turnaroundTime": "Umlaufzeit", - "trainrunTimeCategory": "Verkehrt" + "trainrunTimeCategory": "Verkehrt", + "origin": "Origin", + "destination": "Destination", + "travelTime": "Travel time", + "connections": "Connections", + "totalCost": "Total cost" } }, "error-view": { diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 04cbf5dc..f6612887 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -445,6 +445,8 @@ "export-trainruns": "Export trainruns", "export-trainruns-as-csv": "Export trainruns as CSV", "export-trainruns-as-csv-excel": "In Excel: Data -> From Text/CSV -> Import ... filename", + "export-origin-destination": "Export origin-destination", + "export-origin-destination-as-csv": "Export origin-destination as CSV", "base-data": "Base data", "import-base-data": "Import base data", "help-csv-data": "Help: CSV - Data", @@ -468,6 +470,7 @@ "netzgrafikFile": "networkGraphic", "baseDataFile": "baseData", "trainrunFile": "trainrun", + "originDestinationFile": "originDestination", "trainCategory": "Train category", "trainName": "Train name", "startStation": "Start station", @@ -483,7 +486,12 @@ "arrivalMinuteAtStart": "Arrival minute at start node", "turnaroundTimeStart": "Turnaround time at start station", "turnaroundTime": "Turnaround time", - "trainrunTimeCategory": "Trainrun time category" + "trainrunTimeCategory": "Trainrun time category", + "origin": "Origin", + "destination": "Destination", + "travelTime": "Travel time", + "connections": "Connections", + "totalCost": "Total cost" } }, "error-view": { diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index 04cbf5dc..f6612887 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -445,6 +445,8 @@ "export-trainruns": "Export trainruns", "export-trainruns-as-csv": "Export trainruns as CSV", "export-trainruns-as-csv-excel": "In Excel: Data -> From Text/CSV -> Import ... filename", + "export-origin-destination": "Export origin-destination", + "export-origin-destination-as-csv": "Export origin-destination as CSV", "base-data": "Base data", "import-base-data": "Import base data", "help-csv-data": "Help: CSV - Data", @@ -468,6 +470,7 @@ "netzgrafikFile": "networkGraphic", "baseDataFile": "baseData", "trainrunFile": "trainrun", + "originDestinationFile": "originDestination", "trainCategory": "Train category", "trainName": "Train name", "startStation": "Start station", @@ -483,7 +486,12 @@ "arrivalMinuteAtStart": "Arrival minute at start node", "turnaroundTimeStart": "Turnaround time at start station", "turnaroundTime": "Turnaround time", - "trainrunTimeCategory": "Trainrun time category" + "trainrunTimeCategory": "Trainrun time category", + "origin": "Origin", + "destination": "Destination", + "travelTime": "Travel time", + "connections": "Connections", + "totalCost": "Total cost" } }, "error-view": { diff --git a/src/assets/i18n/it.json b/src/assets/i18n/it.json index 04cbf5dc..f6612887 100644 --- a/src/assets/i18n/it.json +++ b/src/assets/i18n/it.json @@ -445,6 +445,8 @@ "export-trainruns": "Export trainruns", "export-trainruns-as-csv": "Export trainruns as CSV", "export-trainruns-as-csv-excel": "In Excel: Data -> From Text/CSV -> Import ... filename", + "export-origin-destination": "Export origin-destination", + "export-origin-destination-as-csv": "Export origin-destination as CSV", "base-data": "Base data", "import-base-data": "Import base data", "help-csv-data": "Help: CSV - Data", @@ -468,6 +470,7 @@ "netzgrafikFile": "networkGraphic", "baseDataFile": "baseData", "trainrunFile": "trainrun", + "originDestinationFile": "originDestination", "trainCategory": "Train category", "trainName": "Train name", "startStation": "Start station", @@ -483,7 +486,12 @@ "arrivalMinuteAtStart": "Arrival minute at start node", "turnaroundTimeStart": "Turnaround time at start station", "turnaroundTime": "Turnaround time", - "trainrunTimeCategory": "Trainrun time category" + "trainrunTimeCategory": "Trainrun time category", + "origin": "Origin", + "destination": "Destination", + "travelTime": "Travel time", + "connections": "Connections", + "totalCost": "Total cost" } }, "error-view": { From e786e87d42597612de65dae76cd741009de7af5a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 13:17:36 +0200 Subject: [PATCH 092/197] chore(deps): bump serve-static and express (#287) Bumps [serve-static](https://github.com/expressjs/serve-static) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together. Updates `serve-static` from 1.15.0 to 1.16.2 - [Release notes](https://github.com/expressjs/serve-static/releases) - [Changelog](https://github.com/expressjs/serve-static/blob/v1.16.2/HISTORY.md) - [Commits](https://github.com/expressjs/serve-static/compare/v1.15.0...v1.16.2) Updates `express` from 4.19.2 to 4.21.0 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/4.21.0/History.md) - [Commits](https://github.com/expressjs/express/compare/4.19.2...4.21.0) --- updated-dependencies: - dependency-name: serve-static dependency-type: indirect - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 97 ++++++++++++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 38 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1087dfcd..c635b4d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6698,9 +6698,9 @@ } }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dev": true, "dependencies": { "bytes": "3.1.2", @@ -6711,7 +6711,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -9735,37 +9735,37 @@ "dev": true }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", + "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", "dev": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -9794,14 +9794,23 @@ "ms": "2.0.0" } }, + "node_modules/express/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/express/node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dev": true, "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -12523,10 +12532,13 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-stream": { "version": "2.0.0", @@ -14143,9 +14155,9 @@ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" }, "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", "dev": true }, "node_modules/path-type": { @@ -14820,12 +14832,12 @@ } }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dev": true, "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -15584,9 +15596,9 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dev": true, "dependencies": { "debug": "2.6.9", @@ -15728,20 +15740,29 @@ "dev": true }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dev": true, "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/serve-static/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", From fcf9d8a435aed2adc65394d3846bb9ca73c39170 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 13:20:29 +0200 Subject: [PATCH 093/197] chore(deps): bump send and express (#288) Bumps [send](https://github.com/pillarjs/send) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together. Updates `send` from 0.18.0 to 0.19.0 - [Release notes](https://github.com/pillarjs/send/releases) - [Changelog](https://github.com/pillarjs/send/blob/master/HISTORY.md) - [Commits](https://github.com/pillarjs/send/compare/0.18.0...0.19.0) Updates `express` from 4.19.2 to 4.21.0 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/4.21.0/History.md) - [Commits](https://github.com/expressjs/express/compare/4.19.2...4.21.0) --- updated-dependencies: - dependency-name: send dependency-type: indirect - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> From 6b4bba6796d4fe1d2f8716392bd914bf931ec878 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 13:22:54 +0200 Subject: [PATCH 094/197] chore(deps): bump body-parser and express (#289) Bumps [body-parser](https://github.com/expressjs/body-parser) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together. Updates `body-parser` from 1.20.2 to 1.20.3 - [Release notes](https://github.com/expressjs/body-parser/releases) - [Changelog](https://github.com/expressjs/body-parser/blob/master/HISTORY.md) - [Commits](https://github.com/expressjs/body-parser/compare/1.20.2...1.20.3) Updates `express` from 4.19.2 to 4.21.0 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/4.21.0/History.md) - [Commits](https://github.com/expressjs/express/compare/4.19.2...4.21.0) --- updated-dependencies: - dependency-name: body-parser dependency-type: indirect - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> From 1f53563c5e7d4f10fdd8b5d717341f538f782b4b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 13:24:42 +0200 Subject: [PATCH 095/197] chore(deps-dev): bump express from 4.19.2 to 4.21.0 (#290) Bumps [express](https://github.com/expressjs/express) from 4.19.2 to 4.21.0. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/4.21.0/History.md) - [Commits](https://github.com/expressjs/express/compare/4.19.2...4.21.0) --- updated-dependencies: - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> From 85996b8fdaec5f1214a2b4753d8d9374c8716662 Mon Sep 17 00:00:00 2001 From: Louis Greiner <57864277+louisgreiner@users.noreply.github.com> Date: Tue, 17 Sep 2024 18:06:28 +0200 Subject: [PATCH 096/197] Add french translations (#279) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add french translations * fix: unaccurate translation paths * enable french translation button * fix typo in translation syntax * refacto: Noeud instead of Nœud * fix: typos * fix DE translations --- src/app/app.component.html | 4 +- .../editor-filter-view.component.ts | 4 +- .../variants-view/variants-view.component.ts | 4 +- src/assets/i18n/de.json | 16 +- src/assets/i18n/en.json | 2 +- src/assets/i18n/fr.json | 823 +++++++++--------- src/assets/i18n/it.json | 1 - 7 files changed, 426 insertions(+), 428 deletions(-) diff --git a/src/app/app.component.html b/src/app/app.component.html index bd76cc5c..9e422d63 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -17,7 +17,7 @@ > 🇬🇧 English 🇩🇪 Deutsch - + 🇫🇷 Français @@ -43,7 +43,7 @@ > 🇬🇧 English 🇩🇪 Deutsch - + 🇫🇷 Français
diff --git a/src/app/view/editor-filter-view/editor-filter-view.component.ts b/src/app/view/editor-filter-view/editor-filter-view.component.ts index 12cf52b1..1c00ad4f 100644 --- a/src/app/view/editor-filter-view/editor-filter-view.component.ts +++ b/src/app/view/editor-filter-view/editor-filter-view.component.ts @@ -385,9 +385,9 @@ export class EditorFilterViewComponent implements OnInit, OnDestroy { if ( !this.filterService.isFilterTrainrunFrequencyEnabled(trainrunFrequency) ) { - return trainrunFrequency.name + " " + $localize`:@@app.view.editor-filter-view.show-trainrun-frequency:Show ${trainrunFrequency.name}:trainrunFrequency:`; + return $localize`:@@app.view.editor-filter-view.show-trainrun-frequency:Show ${trainrunFrequency.name}:trainrunFrequency:`; } - return trainrunFrequency.name + " " + $localize`:@@app.view.editor-filter-view.hide-trainrun-frequency:Hide ${trainrunFrequency.name}:trainrunFrequency:`; + return $localize`:@@app.view.editor-filter-view.hide-trainrun-frequency:Hide ${trainrunFrequency.name}:trainrunFrequency:`; } makeFrequencyButtonLabel(trainrunFrequency: TrainrunFrequency): string { diff --git a/src/app/view/variant/variants-view/variants-view.component.ts b/src/app/view/variant/variants-view/variants-view.component.ts index 9218b15a..28342ea9 100644 --- a/src/app/view/variant/variants-view/variants-view.component.ts +++ b/src/app/view/variant/variants-view/variants-view.component.ts @@ -84,7 +84,7 @@ export class VariantsViewComponent implements OnDestroy { action: () => this.onEditProjectClicked(), }, { - name: $localize`:@@app.view.variant.variants-view.archive-project:Archive project`, + name: $localize`:@@app.view.variant.variants-view.archive-project.title:Archive project`, icon: "archive-box-small", action: () => this.onArchiveProjectClicked(), }, @@ -97,7 +97,7 @@ export class VariantsViewComponent implements OnDestroy { action: () => this.onUnarchiveProjectClicked(), }, { - name: $localize`:@@app.view.variant.variants-view.delete-project:Delete project`, + name: $localize`:@@app.view.variant.variants-view.delete-project.title:Delete project`, icon: "trash-small", action: () => this.onDeleteProjectClicked(), }, diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index e6982068..057c7fb3 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -82,7 +82,7 @@ }, "trainrun-iteration": { "error": { - "infinity-loop": "Iterator hat eine Unendlichkeitsschleife entdeckt. Die Iteration wurde vorzeitig abgebrochen!" + "infinity-loop": "Iterator hat eine Endlosschleife entdeckt. Die Iteration wurde vorzeitig abgebrochen!" } }, "trainrunsection-validator": { @@ -138,7 +138,7 @@ "utils": { "navigation-parameters": { "no-project-id": "Keine Projekt-ID vorhanden", - "no-variant-id": "Keine Variante-ID vorhanden", + "no-variant-id": "Keine Varianten-ID vorhanden", "no-version-id": "Keine Version-ID vorhanden" } }, @@ -288,10 +288,10 @@ "delete-all-visible-elements-tooltip": "Alle sichtbare Elemente, wie Knoten, Zugfahrten und Kommentare löschen", "delete-all-visible-elements": "Alle sichtbare Elemente löschen", "merge-netzgrafik-title": "Netzgrafik - Zusammenführen", - "add-netzgrafik-as-copy-tooltip": "Netzgrafik als Kopie hinzufügen (Zugfahrtenn, Knoten, Kommentare)", - "add-netzgrafik-as-copy": "Netzgrafik als Kopie hinzufügen", - "merge-netzgrafik-tooltip": "Netzgrafik durch Zusammenführen mergen (Zugfahrtenn, Knoten, Kommentare)", - "merge-netzgrafik": "Netzgrafik durch Zusammenführen mergen", + "add-netzgrafik-as-copy-tooltip": "Netzgrafik als Kopie einfügen (Zugfahrten, Knoten, Kommentare)", + "add-netzgrafik-as-copy": "Netzgrafik als Kopie einfügen", + "merge-netzgrafik-tooltip": "Netzgrafik zusammenführen (Zugfahrten, Knoten, Kommentare)", + "merge-netzgrafik": "Netzgrafik durch zusammenführen", "delete": "Löschen", "on-clear-delete-all-non-visible-elements": "Sollen alle nicht sichtbare Elemente aus der Netzgrafik definitiv gelöscht werden?", "on-clear-delete-all-visible-elements": "Sollen alle sichtbare Elemente aus der Netzgrafik definitiv gelöscht werden?", @@ -381,8 +381,8 @@ "reset-background-color-to-default": "Hintergrundfarbe auf Standard zurücksetzen", "background-color-black": "Hintergrundfarbe (dunkel)", "editor": "Editor", - "useDefaultBrowserColorTheme": "Verwenden Sie das Standard-Browser-Farbtheme.", - "defaultBrowserColorTheme": "Standard-Browser-Farbtheme", + "useDefaultBrowserColorTheme": "Verwenden Sie das Standard-Browser-Farbschema", + "defaultBrowserColorTheme": "Standard-Browser-Farbschema", "travel-time-presetting-default": "Fahrzeitvoreinstellungs (Heuristik)", "graphicTimetable": "Streckengrafik", "axis-scaling-distance": "Achsenskalierung (Distanz)", diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index f6612887..b508ee71 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -129,7 +129,7 @@ "show-or-hide": "Enable/disable {$component}", "show-or-hide-name-for-non-selected-trainruns": "Show/hide trainrun names for unselected trainruns", "hide-advanced-display-functions": "Hide advanced display functions", - "mainTracks": "Main tracks", + "rail-track-slider": "Rail track slider", "headway-band": "Headway band", "time": "Time", "name": "Name" diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index f6612887..94e7b8a5 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -2,653 +2,652 @@ "app-routing": { "module": { "path": { - "404": "The page you were looking for was not found.", - "401": "You are not authorized, please reload the page.", - "403": "You are not authorized to perform this action.", - "409": "There was a conflict while executing your action, please try again.", - "error": "An error has occurred." + "404": "La page recherchée n'a pas été trouvée.", + "401": "Vous n'êtes pas autorisé, veuillez recharger la page.", + "403": "Vous n'êtes pas autorisé à effectuer cette action.", + "409": "Un conflit s'est produit lors de l'exécution de votre action, veuillez réessayer.", + "error": "Une erreur s'est produite." } } }, "app": { "version": "Version {$version}", - "user-guide": "User guide", - "user-manual": "User manual", - "logout": "Logout", - "login": "You are getting logged in...", + "user-guide": "Guide de l'utilisateur", + "user-manual": "Manuel de l'utilisateur", + "logout": "Déconnexion", + "login": "Vous êtes en train de vous connecter...", "logger": { - "title": "Title" + "title": "Titre" }, "models": { "node": { "shortNameDefault": "NEW", - "full-name-default": "New node" + "full-name-default": "Nouveau noeud" }, "note": { - "title-default": "Note title", - "text-default": "Note text", - "default-title": "Note title", - "default-text": "Note text" + "title-default": "Titre de la note", + "text-default": "Texte de la note", + "default-title": "Titre de la note", + "default-text": "Texte de la note" } }, "netzgrafik-application": { - "variants": "Variants", - "filter": "Filter", - "analytics": "Analytics", - "edit": "Edit", - "more-functions": "More functions", - "settings": "Settings" + "variants": "Variantes", + "filter": "Filtre", + "analytics": "Analyse", + "edit": "Edition", + "more-functions": "Plus de fonctionnalités", + "settings": "Paramètres" }, "perlenkette": { "perlenkette-node": { - "0-warning-connection": "No incorrect connection", - "1-warning-connection": "1 incorrect connection", - "n-warning-connections": "{$number} incorrect connections", - "0-fitting-connection": "No fitting connection", - "1-fitting-connection": "1 fitting connection", - "n-fitting-connections": "{$number} fitting connections" + "0-warning-connection": "Pas de correspondance incorrecte", + "1-warning-connection": "1 correspondance incorrecte", + "n-warning-connections": "{$number} correspondances incorrectes", + "0-fitting-connection": "Pas de correspondance correcte", + "1-fitting-connection": "1 correspondance correcte", + "n-fitting-connections": "{$number} correspondances correctes" }, "perlenkette-section": { - "propagate-times-upwards": "Propagate times upwards", - "propagate-times-downwards": "Propagate times downwards" + "propagate-times-upwards": "Propager les temps vers l'avant", + "propagate-times-downwards": "Propager les temps vers l'arrière" }, - "show-only-closed-locks": "Show only closed locks", - "show-all-locks": "Show all locks" + "show-only-closed-locks": "Afficher uniquement les verrous fermés", + "show-all-locks": "Afficher tous les verrous" }, "services": { "data": { "node": { "transit-modified": { - "title": "Transition changed", - "description": "Times cannot be adjusted, lock found on both sides" + "title": "Transition modifiée", + "description": "Les temps ne peuvent pas être ajustés, le verrou se trouve des deux côtés." } }, "trainrunsection": { "intermediate-stop-replacement": { - "title": "Intermediate stop replacement", - "description": "Intermediate stop replacement led to inconsistencies in the allocation of times!" + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" } } }, "ui": { - "newFilter": "New filter" + "newFilter": "Nouveau filtre" }, "util": { "connection-validator": { "connection-marked-for-transit": { - "title": "Connection marked for transition!", - "description": "Connection marked for transition!" + "title": "Correspondance marquée par une transition", + "description": "Correspondance marquée par une transition!" } }, "trainrun-iteration": { "error": { - "infinity-loop": "Iterator has detected an infinity loop. The iteration terminated early!" + "infinity-loop": "L'itérateur a détecté une boucle infinie. L'itération s'est terminée prématurément !" } }, "trainrunsection-validator": { "target-arrival-not-reacheable": { - "title": "Target Arrival Warning", - "description": "Target arrival time cannot be reached" + "title": "Avertissement d'arrivée à la destination", + "description": "L'heure d'arrivée à la destination ne peut être atteinte" }, "source-arrival-not-reacheable": { - "title": "Source Arrival Warning", - "description": "Source arrival time cannot be reached" + "title": "Avertissement d'arrivée à l'origine", + "description": "L'heure d'arrivée à l'origine ne peut être atteinte" }, "travel-time-less-than-1": { - "title": "Travel Time less than 1", - "description": "Travel time must be greater than or equal to 1" + "title": "Temps de trajet inférieur à 1", + "description": "Le temps de trajet doit être supérieur ou égal à 1" } }, "transition-validator": { "source-arrival-not-reacheable": { - "title": "Source Arrival Warning", - "description": "Source arrival time cannot be reached" + "title": "Avertissement d'arrivée à l'origine", + "description": "L'heure d'arrivée à l'origine ne peut être atteinte" }, "source-departure-not-reacheable": { - "title": "Source Departure Warning", - "description": "Source departure time cannot be reached" + "title": "Avertissement de départ à l'origine", + "description": "L'heure de départ à l'origine ne peut être atteinte" }, "target-arrival-not-reacheable": { - "title": "Target Arrival Warning", - "description": "Target arrival time cannot be reached" + "title": "Avertissement d'arrivée à la destination", + "description": "L'heure d'arrivée à la destination ne peut être atteinte" }, "target-departure-not-reacheable": { - "title": "Target Departure Warning", - "description": "Target departure time cannot be reached" + "title": "Avertissement de départ à la destination", + "description": "L'heure de départ à la destination ne peut être atteinte" } } } }, "streckengrafik": { "components": { - "reset": "Reset", - "close-all-path-nodes": "Close all path nodes", - "open-all-path-nodes": "Open all path nodes", - "show-advanced-display-functions": "Show advanced display functions", - "show-or-hide-time-for-non-selected-trainruns": "Show/hide time for non-selected trainruns", - "show-or-hide": "Enable/disable {$component}", - "show-or-hide-name-for-non-selected-trainruns": "Show/hide trainrun names for unselected trainruns", - "hide-advanced-display-functions": "Hide advanced display functions", - "mainTracks": "Main tracks", - "headway-band": "Headway band", - "time": "Time", - "name": "Name" + "reset": "Réinitialiser", + "close-all-path-nodes": "Fermer tous les noeuds du chemin", + "open-all-path-nodes": "Ouvrir tous les noeuds du chemin", + "show-advanced-display-functions": "Afficher les fonctionnalités d'affichage avancées", + "show-or-hide-time-for-non-selected-trainruns": "Afficher/masquer le temps des lignes de train non sélectionnées", + "show-or-hide": "Activer/Désactiver {$component}", + "show-or-hide-name-for-non-selected-trainruns": "Afficher/masquer le nom des lignes de train non sélectionnées", + "hide-advanced-display-functions": "Masquer les fonctionnalités d'affichage avancées", + "headway-band": "Espacement", + "time": "Temps", + "name": "Nom" } }, "utils": { "navigation-parameters": { - "no-project-id": "No project ID available", - "no-variant-id": "No variant ID available", - "no-version-id": "No version ID available" + "no-project-id": "ID du projet indisponible", + "no-variant-id": "ID de la variante indisponible", + "no-version-id": "ID de la version indisponible" } }, "view": { "card-grid": { "card": { - "open": "Open" + "open": "Ouvrir" } }, "dialogs": { "confirmation-dialog": { - "confirmation-default": "Yes", - "abort-default": "No" + "confirmation-default": "Oui", + "abort-default": "Non" }, "filterable-labels-dialog": { "filterable-label-dialog-component": { - "edit-filterable-labels": "Edit filterable labels for {$element}", - "transfer-to-all-visible": "transfer to all visible", - "delete-from-all-visible": "delete from all visible", + "edit-filterable-labels": "Modifier les labels filtrables pour {$element}", + "transfer-to-all-visible": "transférer à tous les visibles", + "delete-from-all-visible": "supprimer de tous les visibles", "transfer": { - "title": "Transfer", - "content": "Should the label {$label} be applied on all visible {$element}?" + "title": "Transférer", + "content": "Le label {$label} doit-il être appliqué à tous les {$element} visibles ?" }, "delete": { - "title": "Delete", - "content": "Should the label {$label} be definitely delete on all visible {$element}?" + "title": "Supprimer", + "content": "Le label {$label} doit-il être définitivement supprimé sur tous les {$element} visibles ?" } }, "filterable-labels-form": { - "mandatory-field": "Mandatory field" + "mandatory-field": "Champ obligatoire" } }, "note-dialog": { "html-editor": { - "reset-color": "Reset color", - "editor-placeholder": "Enter comment here...", - "mandatory-field": "Mandatory field", + "reset-color": "Réinitialiser la couleur", + "editor-placeholder": "Entrez un commentaire ici...", + "mandatory-field": "Champ obligatoire", "color-presets": { "ec": { - "title": "Use color of the color scheme for EC" + "title": "Utiliser la couleur du schéma de couleurs de EC" }, "ic": { - "title": "Use color of the color scheme for IC" + "title": "Utiliser la couleur du schéma de couleurs de IC" }, "ir": { - "title": "Use color of the color scheme for IR" + "title": "Utiliser la couleur du schéma de couleurs de IR" }, "re": { - "title": "Use color of the color scheme for RE" + "title": "Utiliser la couleur du schéma de couleurs de RE" }, "s": { - "title": "Use color of the color scheme for S" + "title": "Utiliser la couleur du schéma de couleurs de S" }, "gex": { - "title": "Use color of the color scheme for GEX" + "title": "Utiliser la couleur du schéma de couleurs de GEX" }, "g": { - "title": "Use color of the color scheme for G" + "title": "Utiliser la couleur du schéma de couleurs de G" }, "green": { - "title": "green" + "title": "vert" }, "blue": { - "title": "blue" + "title": "bleu" }, "magenta": { "title": "magenta" }, "red": { - "title": "red" + "title": "rouge" }, "warning": { - "title": "warning color" + "title": "couleur d'avertissement" } } }, "note-tab": "Note", - "filterable-labels-tab": "Filterable labels", - "delete-note": "Delete note", + "filterable-labels-tab": "Labels filtrables", + "delete-note": "Supprimer la note", "note-filter-tab": { "labels": "Labels", - "label-placeholder": "New label..." + "label-placeholder": "Nouveau label..." }, "note-form": { - "title": "Title", - "name": "Name" + "title": "Titre", + "name": "Nom" } }, "stammdaten-dialog": { - "base-data": "Base data", - "operationalPoint": "Operational point", - "ipv-stop-time": "IPV stop time", - "a-stop-time": "A stop time", - "b-stop-time": "B stop time", - "c-stop-time": "C stop time", - "d-stop-time": "D stop time", + "base-data": "Données de base", + "operationalPoint": "Point opérationnel", + "ipv-stop-time": "Temps d'arrêt IPV", + "a-stop-time": "Temps d'arrêt A", + "b-stop-time": "Temps d'arrêt B", + "c-stop-time": "Temps d'arrêt C", + "d-stop-time": "Temps d'arrêt D", "zaz": "ZAZ", - "connection-time": "Connection time", - "region": "Region", - "category": "Category", - "filterable-labels": "Filterable labels", + "connection-time": "Temps de correspondance", + "region": "Région", + "category": "Catégorie", + "filterable-labels": "Labels filtrables", "position": "Position", - "close": "Close" + "close": "Fermer" }, "trainrun-and-section-dialog": { - "filterableLabels": "Filterable Labels", + "filterableLabels": "Labels filtrables", "trainrun-filter-tab": { "labels": "Labels", - "newLabels" : "New label...", - "trainrunDuplicate": "Duplicate trainrun", - "trainrunDelete": "Delete trainrun", - "delete": "Delete", - "deleteConfirmationQuestion": "Should the entire train route be definitively deleted?" + "newLabels" : "Nouveau label...", + "trainrunDuplicate": "Dupliquer la ligne de train", + "trainrunDelete": "Supprimer la ligne de train", + "delete": "Supprimer", + "deleteConfirmationQuestion": "Faut-il supprimer définitivement l'ensemble de la ligne de train ?" }, "trainrun-tab": { - "tabName": "Name", - "category": "Category", - "frequency": "Frequency", - "verkehrt": "Operates", - "trainrunDuplicate": "Duplicate trainrun", - "trainrunDelete": "Delete trainrun", - "delete": "Delete", - "deleteConfirmationQuestion": "Should the entire train route be definitively deleted?" + "tabName": "Nom", + "category": "Catégorie", + "frequency": "Fréquence", + "verkehrt": "Fonctionnement", + "trainrunDuplicate": "Dupliquer la ligne de train", + "trainrunDelete": "Supprimer la ligne de train", + "delete": "Supprimer", + "deleteConfirmationQuestion": "Faut-il supprimer définitivement l'ensemble de la ligne de train ?" }, "trainrun-section-tab": { - "warningTwoLocks": "Warning: Too many times are locked!", - "propagateTimesToLeft": "Propagate times to the left", - "propagateTimesToRight": "Propagate times to the right" + "warningTwoLocks": "Avertissement : Trop de temps sont bloqués !", + "propagateTimesToLeft": "Propager les temps à gauche", + "propagateTimesToRight": "Propager les temps à droite" } } }, "editor-edit-tools-view-component": { - "edit": "Edit", - "filterable-labels": "Filterable labels", - "trainruns": "Trainruns", - "nodes": "Nodes", + "edit": "Editer", + "filterable-labels": "Labels filtrables", + "trainruns": "Lignes de train", + "nodes": "Noeuds", "notes": "Notes", - "delete-netzgrafik-title": "Netzgrafik - Delete", - "non-visible-elements": "Non visible elements", - "delete-all-non-visible-elements-tooltip": "Delete all non-visible elements, such as nodes, trainruns and notes", - "delete-all-non-visible-elements": "Delete all non-visible elements", - "visible-elements": "Visible elements", - "delete-all-visible-trainruns-tooltip": "Delete all visible trainruns", - "delete-all-visible-trainruns": "Delete all visible trainruns", - "delete-all-visible-notes-tooltip": "Delete all visible notes", - "delete-all-visible-notes": "Delete all visible notes", - "delete-all-visible-elements-tooltip": "Delete all visible elements, such as nodes, trainruns and notes", - "delete-all-visible-elements": "Delete all visible elements", - "merge-netzgrafik-title": "Netzgrafik - Merge", - "add-netzgrafik-as-copy-tooltip": "Add netzgrafik as a copy (trainruns, nodes, notes)", - "add-netzgrafik-as-copy": "Add netzgrafik as a copy", - "merge-netzgrafik-tooltip": "Merge netzgrafik (trainruns, nodes, notes)", - "merge-netzgrafik": "Merge netzgrafik", - "delete": "Delete", - "on-clear-delete-all-non-visible-elements": "Should all non-visible elements be permanently deleted from the netzgrafik?", - "on-clear-delete-all-visible-elements": "Should all visible elements be permanently deleted from the netzgrafik?", - "on-clear-delete-all-visible-trainruns": "Should all visible trainruns be permanently deleted from the netzgrafik?", - "on-clear-delete-all-visible-notes": "Should all visible notes be permanently deleted from the netzgrafik?", + "delete-netzgrafik-title": "Netzgrafik - Supprimer", + "non-visible-elements": "Éléments non visibles", + "delete-all-non-visible-elements-tooltip": "Supprimer tous les éléments non visibles, tels que les noeuds, les lignes de train et les notes", + "delete-all-non-visible-elements": "Supprimer tous les éléments non visibles", + "visible-elements": "Éléments visibles", + "delete-all-visible-trainruns-tooltip": "Supprimer toutes les lignes de trains visibles", + "delete-all-visible-trainruns": "Supprimer toutes les lignes de trains visibles", + "delete-all-visible-notes-tooltip": "Supprimer toutes les notes visibles", + "delete-all-visible-notes": "Supprimer toutes les notes visibles", + "delete-all-visible-elements-tooltip": "Supprimer tous les éléments visibles, tels que les noeuds, les lignes de train et les notes", + "delete-all-visible-elements": "Supprimer tous les éléments visibles", + "merge-netzgrafik-title": "Netzgrafik - Fusionner", + "add-netzgrafik-as-copy-tooltip": "Ajouter un netzgrafik en tant que copie (lignes de train, noeuds, notes)", + "add-netzgrafik-as-copy": "Ajouter un netzgrafik en tant que copie", + "merge-netzgrafik-tooltip": "Fusionner les réticulaires (lignes de train, noeuds, notes)", + "merge-netzgrafik": "Fusionner un netzgrafik", + "delete": "Supprimer", + "on-clear-delete-all-non-visible-elements": "Tous les éléments non visibles doivent-ils être définitivement supprimés du netzgrafik ?", + "on-clear-delete-all-visible-elements": "Tous les éléments visibles doivent-ils être définitivement supprimés du netzgrafik ?", + "on-clear-delete-all-visible-trainruns": "Toutes les lignes de train visibles doivent-elles être définitivement supprimées du netzgrafik ?", + "on-clear-delete-all-visible-notes": "Toutes les notes visibles doivent-elles être définitivement supprimées du netzgrafik ?", "label-drop-list": { - "no-labels-available": "No labels available", - "delete-group": "Delete group", - "add-new-group": "Add new group", - "trainruns": "Trainruns", + "no-labels-available": "Aucun label disponible", + "delete-group": "Supprimer le groupe", + "add-new-group": "Ajouter un nouveau groupe", + "trainruns": "Lignes de train", "notes": "Notes", - "nodes": "Nodes" + "nodes": "Noeuds" } }, "editor-filter-view": { - "filter": "Filter", - "general": "General", - "category": "Category", - "frequency": "Frequence", - "time-category": "Time category", - "display-all-trainruns": "Display all trainruns", - "reset-trainrun-filter": "Reset trainrun filter", - "filterable-labels-trainruns": "Filterable labels: Trainruns", - "filterable-labels-nodes": "Filterable labels: Nodes", - "filterable-labels-notes": "Filterable labels: Notes", - "display": "Display", - "times": "Times", - "decimal-displayed": "Number of decimal place displayed", - "display-arrival-departure-times": "Display departure and arrival times", - "display-arrival-departure-times-for-connections": "Display departure and arrival times for connections", - "display-travel-times": "Display travel times", - "display-trainrun-name": "Display trainrun name", - "connections": "Connections", - "display-connections": "Display connections", - "nodes": "Nodes", - "display-nodes-without-visible-trainruns": "Display nodes without (visible) trainruns", - "display-nodes-with-only-stopping-trainruns": "Display nodes with only stopping trainruns", + "filter": "Filtre", + "general": "Général", + "category": "Catégorie", + "frequency": "Fréquence", + "time-category": "Période de fonctionnement", + "display-all-trainruns": "Afficher toutes les lignes de train", + "reset-trainrun-filter": "Réinitialiser le filtre sur les lignes de train", + "filterable-labels-trainruns": "Labels filtrables: Lignes de train", + "filterable-labels-nodes": "Labels filtrables: Noeuds", + "filterable-labels-notes": "Labels filtrables: Notes", + "display": "Afficher", + "times": "Temps", + "decimal-displayed": "Nombre de décimales affichées", + "display-arrival-departure-times": "Afficher les heures de départ et d'arrivée", + "display-arrival-departure-times-for-connections": "Afficher les heures de départ et d'arrivée des correspondances", + "display-travel-times": "Afficher les temps de parcours", + "display-trainrun-name": "Afficher le nom du train", + "connections": "Correspondances", + "display-connections": "Afficher les correspondances", + "nodes": "Noeuds", + "display-nodes-without-visible-trainruns": "Afficher les noeuds sans lignes de train (visibles)", + "display-nodes-with-only-stopping-trainruns": "Afficher les noeuds où les trains s'arrêtent", "notes": "Notes", - "display-notes": "Display notes", - "reset-display-filter": "Reset display filter", - "saved-filters": "Saved filters", - "save-filters": "Save filters and add them as filter settings", - "reset-all-display-filters": "Reset all display filters", - "load-filter": "Load {$filter}", - "reload-filter": "Reload {$filter}", - "show-trainrun-category": "Show {$trainrunCategory}", - "hide-trainrun-category": "Hide {$trainrunCategory}", - "show-trainrun-time-category": "Show {$trainrunTimeCategory}", - "hide-trainrun-time-category": "Hide {$trainrunTimeCategory}", - "show-trainrun-frequency": "Show {$trainrunFrequency}", - "hide-trainrun-frequency": "Hide {$trainrunFrequency}", + "display-notes": "Afficher les notes", + "reset-display-filter": "Réinitialiser l'affichage des filtres", + "saved-filters": "Filtres sauvegardés", + "save-filters": "Enregistrer les filtres et les ajouter en tant que paramètres de filtre", + "reset-all-display-filters": "Réinitialiser l'affichage des filtres", + "load-filter": "Charger {$filter}", + "reload-filter": "Recharger {$filter}", + "show-trainrun-category": "Afficher {$trainrunCategory}", + "hide-trainrun-category": "Masquer {$trainrunCategory}", + "show-trainrun-time-category": "Afficher {$trainrunTimeCategory}", + "hide-trainrun-time-category": "Masquer {$trainrunTimeCategory}", + "show-trainrun-frequency": "Afficher {$trainrunFrequency}", + "hide-trainrun-frequency": "Masquer {$trainrunFrequency}", "filterable-label-filter": { - "no-labels-available": "No labels available", - "or": "Or", - "and": "And", - "show-all": "Show all", - "reset-filter": "Reset filter", - "show": "show", - "hide": "hide" + "no-labels-available": "Aucun label disponible", + "or": "Ou", + "and": "Et", + "show-all": "Afficher tout", + "reset-filter": "Réinitialiser le filtre", + "show": "afficher", + "hide": "masquer" } }, "editor-menu": { - "save-changes": "Save changes", - "changes-saved": "Changes saved", - "read-mode": "Read mode", - "show-hide-filter": "Show/Hide filter", - "zoom-out": "Zoom out", - "zoom-in": "Zoom in", - "topology-editor-disabled": "Topology editor disabled", - "topology-editor-enabled": "Topology editor enabled", - "multiple-selection-tool-disabled": "Multiple selection tool is disabled", - "multiple-selection-tool-enabled": "Multiple selection tool is enabled", - "note-editor-disabled": "Note editor disabled", - "note-editor-enabled": "Note editor enabled", - "analytics-disabled": "Analytics disabled", - "analytics-enabled": "Analytics enabled", - "displayGraphicTimetable": "Display graphic timetable", - "closeGraphicTimetable": "Close graphic timetable", - "errorGraphicTimetable": "Graphic timetable cannot be displayed because no trainrun or no nodes have been selected." + "save-changes": "Enregistrer les modifications", + "changes-saved": "Modifications enregistrées", + "read-mode": "Mode lecture", + "show-hide-filter": "Filtre", + "zoom-out": "Zoom arrière", + "zoom-in": "Zoom avant", + "topology-editor-disabled": "Editeur de topologie désactivé", + "topology-editor-enabled": "Editeur de topologie activé", + "multiple-selection-tool-disabled": "Outil de sélection multiple désactivé", + "multiple-selection-tool-enabled": "Outil de sélection multiple activé", + "note-editor-disabled": "Editeur de notes désactivé", + "note-editor-enabled": "Editeur de notes activé", + "analytics-disabled": "Analyse désactivée", + "analytics-enabled": "Analyse activée", + "displayGraphicTimetable": "Afficher le graphique espace-temps", + "closeGraphicTimetable": "Fermer le graphique espace-temps", + "errorGraphicTimetable": "Le graphique espace-temps ne peut pas être affiché parce qu'aucune ligne de train ou aucun noeud n'a été sélectionné." }, "editor-properties-view-component": { - "settings": "Settings", - "color-scheme": "Color scheme", - "theme": "Theme", - "background-color": "Background color", - "set-color-to-white": "Set color to 'white'", - "reset-background-color-to-default": "Reset background color to default", - "background-color-black": "Background color (black)", - "editor": "Editor", - "useDefaultBrowserColorTheme": "Use the default browser color theme.", - "defaultBrowserColorTheme": "Default browser color theme", - "travel-time-presetting-default": "Travel time presetting (heuristics)", - "graphicTimetable": "Graphic timetable", - "axis-scaling-distance": "Axis scaling (distance)", - "standardColorTheme": "Standard color theme", - "specialColorTheme": "Special color theme", - "grayscaleColorTheme": "Grayscale color theme", - "optimizedPrintColorTheme": "Optimized color theme for printing/exporting", - "standardDarkColorTheme": "Standard color theme (dark)", - "specialDarkColorTheme": "Special color theme (dark)", - "grayscaleDarkColorTheme": "Grayscale color theme (dark)", - "timeScaledDistance": "Travel time scaled", - "timeScaledDistanceTooltip": "The route graphic sections are displayed with travel time scaling, i.e. it is assumed that the selected train travels at a constant speed.", - "uniformDistance": "Uniform", - "uniformDistanceTooltip": "The route graphic sections are uniformly displayed.", - "fixed": "Constant 1min", - "fixedTooltip": "Adopts the travel time with a constant 1min (default).", - "retrieveFromEdge": "Section travel time", - "retrieveFromEdgeTooltip": "Takes over the max. travel time on the same section of all trains of the same category, otherwise max. travel time of all trains, otherwise 1 min." + "settings": "Paramètres", + "color-scheme": "Palette de couleurs", + "theme": "Thème", + "background-color": "Couleur d'arrière-plan", + "set-color-to-white": "Définir la couleur à 'blanc'", + "reset-background-color-to-default": "Réinitialiser la couleur d'arrière-plan par défaut", + "background-color-black": "Couleur d'arrière-plan (noir)", + "editor": "Editeur", + "useDefaultBrowserColorTheme": "Utiliser le thème de couleur par défaut du navigateur", + "defaultBrowserColorTheme": "Thème de couleur par défaut du navigateur", + "travel-time-presetting-default": "Prédétermination du temps de parcours (heuristique)", + "graphicTimetable": "Graphique espace-temps", + "axis-scaling-distance": "Mise à l'échelle de l'axe (distance)", + "standardColorTheme": "Thème de couleur standard", + "specialColorTheme": "Thème de couleur spécial", + "grayscaleColorTheme": "Thème de couleurs en niveaux de gris", + "optimizedPrintColorTheme": "Thème de couleurs optimisé pour l'import/export", + "standardDarkColorTheme": "Thème de couleur standard (sombre)", + "specialDarkColorTheme": "Thème de couleur spécial (sombre)", + "grayscaleDarkColorTheme": "Thème de couleurs en niveaux de gris (sombre)", + "timeScaledDistance": "Temps de trajet mis à l'échelle", + "timeScaledDistanceTooltip": "Les sections graphiques de l'itinéraire sont affichées avec une mise à l'échelle des temps de parcours, c'est-à-dire que l'on suppose que le train sélectionné circule à une vitesse constante.", + "uniformDistance": "Uniforme", + "uniformDistanceTooltip": "Les sections graphiques de l'itinéraire sont affichées de manière uniforme.", + "fixed": "Constante 1min", + "fixedTooltip": "Adopte le temps de parcours avec une constante de 1min (par défaut).", + "retrieveFromEdge": "Temps de parcours de la section", + "retrieveFromEdgeTooltip": "Reprend le temps de parcours maximal sur le même tronçon de tous les trains de la même catégorie, sinon le temps de parcours maximal de tous les trains, sinon 1 min." }, "editor-side-view": { "editor-node-detail-view": { - "base-data": "Base data", - "operational-point": "Operational point", - "name": "Name", - "connection-time": "Connection time", - "occupancy": "Occupancy", - "capacity": "Capacity", - "filterable-labels": "Filterable labels", + "base-data": "Données de base", + "operational-point": "Point opérationnel", + "name": "Nom", + "connection-time": "Temps de correspondance", + "occupancy": "Occupation", + "capacity": "Capacité", + "filterable-labels": "Labels filtrables", "labels": "Labels", - "new-label-placeholder": "New label...", - "stopping-times": "Stopping times", - "stopping-time-per-product": "Stopping time per product", - "no-stop": "No stop", + "new-label-placeholder": "Nouveau label...", + "stopping-times": "Temps d'arrêt", + "stopping-time-per-product": "Temps d'arrêt par produit", + "no-stop": "Pas d'arrêt", "ipv": "IPV", "a": "A", "b": "B", "c": "C", "d": "D", - "links": "Links", - "platform-information": "Platform information", - "platform-length": "Platform length", - "delete-node": "Delete node", - "delete": "Delete", - "deleteNodeDialog": "Should the node {$operationalPointShortName} ({$operationalPointName}) be definitely deleted?" + "links": "Liens", + "platform-information": "Informations sur les quais", + "platform-length": "Longueur des quais", + "delete-node": "Supprimer le noeud", + "delete": "Supprimer", + "deleteNodeDialog": "Le noeud {$operationalPointShortName} ({$operationalPointName}) doit-il être définitivement supprimé ?" }, "editor-tools-view-component": { - "more-functions": "More functions", - "export": "Export", - "export-netzgrafik-as-svg": "Export netzgrafik as SVG", - "export-as-svg": "Export as SVG", - "export-netzgrafik-as-png": "Export netzgrafik as PNG", - "export-as-png": "Export as PNG", - "print-netzgrafik": "Print netzgrafik", - "print": "Print", + "more-functions": "Plus de fonctionnalités", + "export": "Exporter", + "export-netzgrafik-as-svg": "Exporter le netzgrafik au format SVG", + "export-as-svg": "Exporter au format SVG", + "export-netzgrafik-as-png": "Exporter le netzgrafik au format PNG", + "export-as-png": "Exporter au format PNG", + "print-netzgrafik": "Imprimer le netzgrafik", + "print": "Imprimer", "netzgrafik": "Netzgrafik", - "export-netzgrafik": "Export netzgrafik", - "export-netzgrafik-as-json": "Export netzgrafik as JSON", - "import-netzgrafik": "Import netzgrafik", - "import-netzgrafik-as-json": "Import netzgrafik as JSON", - "export-trainruns": "Export trainruns", - "export-trainruns-as-csv": "Export trainruns as CSV", - "export-trainruns-as-csv-excel": "In Excel: Data -> From Text/CSV -> Import ... filename", - "export-origin-destination": "Export origin-destination", - "export-origin-destination-as-csv": "Export origin-destination as CSV", - "base-data": "Base data", - "import-base-data": "Import base data", - "help-csv-data": "Help: CSV - Data", - "export-base-data": "Export base data", + "export-netzgrafik": "Exporter le netzgrafik", + "export-netzgrafik-as-json": "Exporter le netzgrafik au format JSON", + "import-netzgrafik": "Importer le netzgrafik", + "import-netzgrafik-as-json": "Importer le netzgrafik au format JSON", + "export-trainruns": "Exporter les lignes de train", + "export-trainruns-as-csv": "Exporter les lignes de train au format CSV", + "export-trainruns-as-csv-excel": "Dans Excel : Données -> txt/CSV -> Importer ... nom de fichier", + "export-origin-destination": "Exporter origine-destination", + "export-origin-destination-as-csv": "Exporter origine-destination au format CSV", + "base-data": "Données de base", + "import-base-data": "Importer les données de base", + "help-csv-data": "Aide: CSV - Données", + "export-base-data": "Exporter les données de base", "bp": "BP", - "station": "Station", - "category": "Category", - "region": "Region", - "passengerConnectionTimeIPV": "Passenger_connection_time_IPV", - "passengerConnectionTimeA": "Passenger_connection_time_A", - "passengerConnectionTimeB": "Passenger_connection_time_B", - "passengerConnectionTimeC": "Passenger_connection_time_C", - "passengerConnectionTimeD": "Passenger_connection_time_D", + "station": "Gare", + "category": "Catégorie", + "region": "Région", + "passengerConnectionTimeIPV": "Temps_correspondance_passager_IPV", + "passengerConnectionTimeA": "Temps_correspondance_passager_A", + "passengerConnectionTimeB": "Temps_correspondance_passager_B", + "passengerConnectionTimeC": "Temps_correspondance_passager_C", + "passengerConnectionTimeD": "Temps_correspondance_passager_D", "ZAZ": "ZAZ", - "transferTime": "Transfer_time", + "transferTime": "Temps_transfert", "labels": "Labels", "X": "X", "Y": "Y", - "create": "Create", - "yes": "YES", - "netzgrafikFile": "networkGraphic", + "create": "Créer", + "yes": "OUI", + "netzgrafikFile": "netzgrafik", "baseDataFile": "baseData", - "trainrunFile": "trainrun", - "originDestinationFile": "originDestination", - "trainCategory": "Train category", - "trainName": "Train name", - "startStation": "Start station", - "destinationStation": "Destination station", - "trafficPeriod": "Traffic period", - "frequence": "Frequence", - "departureMinuteAtStart": "Minute of departure at start node", - "travelTimeStartDestination": "Travel time start-destination", - "arrivalMinuteAtDestination": "Arrival minute at destination node", - "turnaroundTimeDestination": "Turnaround time at destination station", - "departureMinuteDeparture": "Departure minute at destination node", - "travelTimeDestinationStart": "Travel time destination-start", - "arrivalMinuteAtStart": "Arrival minute at start node", - "turnaroundTimeStart": "Turnaround time at start station", - "turnaroundTime": "Turnaround time", - "trainrunTimeCategory": "Trainrun time category", - "origin": "Origin", + "trainrunFile": "trains", + "originDestinationFile": "origineDestination", + "trainCategory": "Catégorie du train", + "trainName": "Nom du train", + "startStation": "Gare d'origine", + "destinationStation": "Gare de destination", + "trafficPeriod": "Période de circulation", + "frequence": "Fréquence", + "departureMinuteAtStart": "Minute de départ au noeud de départ", + "travelTimeStartDestination": "Temps de parcours origine-destination", + "arrivalMinuteAtDestination": "Minute d'arrivée au noeud de destination", + "turnaroundTimeDestination": "Durée de retournement à la gare de destination", + "departureMinuteDeparture": "Minute de départ au noeud de destination", + "travelTimeDestinationStart": "Temps de parcours destination-origine", + "arrivalMinuteAtStart": "Minute d'arrivée au noeud d'origine", + "turnaroundTimeStart": "Durée de retournement à la gare d'origine", + "turnaroundTime": "Durée de retournement", + "trainrunTimeCategory": "Catégorie temporelle d'opération", + "origin": "Origine", "destination": "Destination", - "travelTime": "Travel time", - "connections": "Connections", - "totalCost": "Total cost" + "travelTime": "Temps de parcours", + "connections": "Correspondances", + "totalCost": "Coût total" } }, "error-view": { - "error": "Error" + "error": "Erreur" }, "navigation-bar": { - "project-name": "Project «{$name}»", - "project-name-archived": "Project «{$name}» (archived)", - "variant-name": "Variant «{$name}»", - "variant-name-archived": "Variant «{$name}» (archived)" + "project-name": "Projet «{$name}»", + "project-name-archived": "Projet «{$name}» (archivé)", + "variant-name": "Variante «{$name}»", + "variant-name-archived": "Variante «{$name}» (archivée)" }, "project": { "project-dialog": { - "create-project": "Create project", - "edit-project": "Edit project", - "create": "Create", - "save": "Save", - "cancel": "Cancel", + "create-project": "Créer un projet", + "edit-project": "Editer un projet", + "create": "Créer", + "save": "Sauvegarder", + "cancel": "Annuler", "project-form": { - "name": "Name", - "mandatory-field": "Mandatory field", - "summary": "Summary", + "name": "Nom", + "mandatory-field": "Champ obligatoire", + "summary": "Résumé", "description": "Description", - "tooltip": "Users must be entered with their e-mail address. Confirm the entry for each e-mail with 'Enter'.", - "user-with-write-access": "User with write access", - "new-user-placeholder": "New user...", - "invalid-values": "Invalid values (no e-mail address)", - "user-with-read-access": "User with read access" + "tooltip": "Les utilisateurs doivent être saisis avec leur adresse électronique. Confirmez la saisie de chaque e-mail avec « Entrée ».", + "user-with-write-access": "Utilisateur avec accès en écriture", + "new-user-placeholder": "Nouvel utilisateur...", + "invalid-values": "Valeurs invalides (pas d'adresse e-mail)", + "user-with-read-access": "Utilisateur avec accès en lecture" } }, "projects-view": { - "projects": "Projects", - "search-project": "Search project", - "show-archive": "Show archive", - "archived": "(archived)", + "projects": "Projets", + "search-project": "Chercher un projet", + "show-archive": "Afficher les archives", + "archived": "(archivé)", "archive-project": { - "title": "Archive project", - "content": "Would you like to archive the project now?" + "title": "Archiver un projet", + "content": "Voulez-vous archiver le projet maintenant ?" }, "undo-archiving-project": { - "title": "Undo archiving", - "content": "Would you like to undo the archiving the project now?" + "title": "Annuler l'archivage", + "content": "Voulez-vous annuler l'archivage du projet maintenant ?" }, - "undo-archiving": "Undo archiving", - "edit": "Edit", - "archive": "Archive" + "undo-archiving": "Annuler l'archivage", + "edit": "Editer", + "archive": "Archiver" } }, "variant": { "variant-dialog": { - "create-variant": "Create variant", - "edit-variant": "Edit variant", - "save": "Save", - "cancel": "Cancel", + "create-variant": "Créer une variante", + "edit-variant": "Editer une variante", + "save": "Sauvegarder", + "cancel": "Annuler", "variant-form": { - "name": "Name", - "mandatory-field": "Mandatory field" + "name": "Nom", + "mandatory-field": "Champ obligatoire" } }, "variant-view": { "variant-history": { "publish-entry": { - "comment": "Comment", - "publish": "Publish", - "local-changes": "Local changes must be saved first", - "discard-changes": "Discard changes" + "comment": "Commentaire", + "publish": "Publier", + "local-changes": "Les modifications locales doivent d'abord être sauvegardées", + "discard-changes": "Annuler les modifications" }, "released-entry": { - "download": "Download", - "discard-changes": "Discard changes", - "ignore-conflict": "Ignore conflict", - "restore": "Restore", - "as-new-variant": "As new variant", - "version-already-available": "Version already available", - "successfully-published": "Successfully published" + "download": "Télécharger", + "discard-changes": "Annuler les modifications", + "ignore-conflict": "Ignorer les conflits", + "restore": "Restaurer", + "as-new-variant": "En tant que nouvelle variante", + "version-already-available": "Version déjà disponible", + "successfully-published": "Publication réussie" }, "version-entry-layout": { - "user-id-copied": "Copied to clipboard: {$msg}" + "user-id-copied": "Copié dans le presse-papiers : {$msg}" }, "snapshot-entry": { - "download": "Download", - "restore": "Restore", - "as-new-variant": "As new variant", - "successfully-published": "Successfully published", - "change-snapshot-version": "Change {$snapshotVersion}" + "download": "Télécharger", + "restore": "Restaurer", + "as-new-variant": "En tant que nouvelle variante", + "successfully-published": "Publication réussie", + "change-snapshot-version": "Changer {$snapshotVersion}" }, "new-version-published": { - "title": "New version published", - "content": "Would you like to publish your personal changes as a new version?" + "title": "Nouvelle version publiée", + "content": "Voulez-vous publier vos modifications personnelles dans une nouvelle version ?" }, "discard-changes": { - "title": "Discard changes", - "content": "Would you like to irrevocably discard your personal changes?" + "title": "Annuler les modifications", + "content": "Voulez-vous annuler définitivement vos modifications personnelles ?" }, "restore-version": { - "title": "Restore version", - "content": "Would you like to restore the status of this version?" + "title": "Restaurer version", + "content": "Voulez-vous restaurer cette version ?" }, "ignore-conflict": { - "title": "Ignore conflict", - "content": "Would you like the current version to be based on the highest published version?" + "title": "Ignorer les conflits", + "content": "Voulez-vous que la version actuelle soit basée sur la version publiée la plus récente ?" } }, - "archived": "(archived)", - "edit-variant": "Edit variant", + "archived": "(archivée)", + "edit-variant": "Editer la variante", "delete-variant": { - "title": "Delete variant", - "content": "Do you want to permanently delete the variant and all versions it contains? This action cannot be undone." + "title": "Supprimer la variante", + "content": "Voulez-vous supprimer définitivement la variante et toutes les versions qu'elle contient ? Cette action ne peut pas être annulée." }, "versions": "Versions" }, "variants-view": { - "archived": "(archived)", - "variants": "Variants", - "search-variants": "Search variants", - "show-archive": "Show archive", - "project-description": "Project description", - "edit-project": "Edit project", + "archived": "(archivée)", + "variants": "Variantes", + "search-variants": "Rechercher des variantes", + "show-archive": "Afficher les archives", + "project-description": "Description du projet", + "edit-project": "Editer le projet", "archive-project": { - "title": "Archive project", - "content": "Would you like to archive the project now?" + "title": "Archiver un projet", + "content": "Voulez-vous archiver le projet maintenant ?" }, - "undo-archiving": "Undo archiving", + "undo-archiving": "Annuler l'archivage", "delete-project": { - "title": "Delete projekt", - "content": "Do you want to permanently delete the project and all the variants it contains? This action cannot be undone." + "title": "Supprimer le projet", + "content": "Voulez-vous supprimer définitivement le projet et toutes les variantes qu'il contient ? Cette action ne peut pas être annulée." }, - "archive": "Archive", + "archive": "Archiver", "archive-variant": { - "title": "Archive variant", - "content": "Would you like to archive the variant now?" + "title": "Archiver la variante", + "content": "Souhaitez-vous archiver la variante maintenant ?" }, "undo-archiving-variant": { - "title": "Undo archiving", - "content": "Would you like to undo the archiving of the variant?" + "title": "Annuler l'archivage", + "content": "Souhaitez-vous annuler l'archivage de la variante ?" }, "undo-archiving-project": { - "title": "Archive variant", - "content": "Would you like to undo the archiving of the project?" + "title": "Archiver la variante", + "content": "Voulez-vous annuler l'archivage du projet ?" }, - "error-unexpected-data": "Unexpected data: No snapshot and no released version." + "error-unexpected-data": "Données inattendues : Pas de snapshot ni de version publiée." } } } }, - "sbbBreadcrumbExpand": "Show entire path", - "sbbDialogCloseDialog": "Close dialog", - "sbbFileSelectorUploadFile": "Upload file", - "sbbFileSelectorRemoveFile": "Remove file", - "sbbHeaderMenuBack": "Back", - "sbbHeaderOpenMenu": "Open Menu", - "sbbHeaderCloseMenu": "Close Menu", - "sbbSidebarCollapse": "Collapse", - "sbbSidebarExpand": "Expand", - "sbbSidebarCloseSidebar": "Close Sidebar", - "sbbSidebarOpenSidebar": "Open Sidebar", - "sbbTextareaCounterText": "{$PH} characters remaining", + "sbbBreadcrumbExpand": "Afficher l'ensemble du chemin", + "sbbDialogCloseDialog": "Fermer la boîte de dialogue", + "sbbFileSelectorUploadFile": "Télécharger le fichier", + "sbbFileSelectorRemoveFile": "Supprimer le fichier", + "sbbHeaderMenuBack": "Retour", + "sbbHeaderOpenMenu": "Ouvrir le menu", + "sbbHeaderCloseMenu": "Fermer le menu", + "sbbSidebarCollapse": "Réduire", + "sbbSidebarExpand": "Agrandir", + "sbbSidebarCloseSidebar": "Fermer la barre latérale", + "sbbSidebarOpenSidebar": "Ouvrir la barre latérale", + "sbbTextareaCounterText": "{$PH} caractères restants", "sbbUsermenuLogin": "Login", - "sbbUsermenuOpenPanel": "Logged in as {$PH}. Click or press enter to open user menu." + "sbbUsermenuOpenPanel": "Connecté en tant que {$PH}. Cliquez ou appuyez sur la touche Entrée pour ouvrir le menu utilisateur." } diff --git a/src/assets/i18n/it.json b/src/assets/i18n/it.json index f6612887..b513a4c1 100644 --- a/src/assets/i18n/it.json +++ b/src/assets/i18n/it.json @@ -129,7 +129,6 @@ "show-or-hide": "Enable/disable {$component}", "show-or-hide-name-for-non-selected-trainruns": "Show/hide trainrun names for unselected trainruns", "hide-advanced-display-functions": "Hide advanced display functions", - "mainTracks": "Main tracks", "headway-band": "Headway band", "time": "Time", "name": "Name" From b5895c93b579628eec0bc1d0e54cd8a9f6d0de71 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 19 Sep 2024 10:09:23 +0200 Subject: [PATCH 097/197] Added new demostration (JSON) --- src/app/sample-netzgrafik/Demo_LZ_netzgrafik.json | 1 + src/app/sample-netzgrafik/Demo_OL_LZ.json.json | 1 + 2 files changed, 2 insertions(+) create mode 100644 src/app/sample-netzgrafik/Demo_LZ_netzgrafik.json create mode 100644 src/app/sample-netzgrafik/Demo_OL_LZ.json.json diff --git a/src/app/sample-netzgrafik/Demo_LZ_netzgrafik.json b/src/app/sample-netzgrafik/Demo_LZ_netzgrafik.json new file mode 100644 index 00000000..033b10f7 --- /dev/null +++ b/src/app/sample-netzgrafik/Demo_LZ_netzgrafik.json @@ -0,0 +1 @@ +{"nodes":[{"id":133,"betriebspunktName":"MADI","fullName":"Madiswil ","positionX":192,"positionY":864,"ports":[{"id":597,"trainrunSectionId":281,"positionIndex":0,"positionAlignment":0},{"id":593,"trainrunSectionId":279,"positionIndex":1,"positionAlignment":0},{"id":596,"trainrunSectionId":280,"positionIndex":0,"positionAlignment":1},{"id":592,"trainrunSectionId":278,"positionIndex":1,"positionAlignment":1}],"transitions":[{"id":183,"port1Id":593,"port2Id":592,"isNonStopTransit":false},{"id":185,"port1Id":597,"port2Id":596,"isNonStopTransit":false}],"connections":[],"resourceId":162,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":134,"betriebspunktName":"WSAU","fullName":"Willisau","positionX":544,"positionY":1952,"ports":[{"id":522,"trainrunSectionId":243,"positionIndex":0,"positionAlignment":1},{"id":527,"trainrunSectionId":246,"positionIndex":1,"positionAlignment":1},{"id":524,"trainrunSectionId":244,"positionIndex":2,"positionAlignment":1},{"id":518,"trainrunSectionId":241,"positionIndex":0,"positionAlignment":2},{"id":515,"trainrunSectionId":240,"positionIndex":1,"positionAlignment":2}],"transitions":[{"id":150,"port1Id":522,"port2Id":518,"isNonStopTransit":false},{"id":151,"port1Id":527,"port2Id":515,"isNonStopTransit":false}],"connections":[],"resourceId":163,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":135,"betriebspunktName":"ZG","fullName":"Zug","positionX":1888,"positionY":1984,"ports":[{"id":507,"trainrunSectionId":236,"positionIndex":0,"positionAlignment":0},{"id":509,"trainrunSectionId":237,"positionIndex":1,"positionAlignment":0},{"id":582,"trainrunSectionId":273,"positionIndex":0,"positionAlignment":1},{"id":578,"trainrunSectionId":271,"positionIndex":1,"positionAlignment":1}],"transitions":[{"id":174,"port1Id":509,"port2Id":578,"isNonStopTransit":false},{"id":177,"port1Id":507,"port2Id":582,"isNonStopTransit":false}],"connections":[],"resourceId":164,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":136,"betriebspunktName":"BAA","fullName":"Baar","positionX":1920,"positionY":1632,"ports":[{"id":505,"trainrunSectionId":235,"positionIndex":0,"positionAlignment":0},{"id":508,"trainrunSectionId":236,"positionIndex":0,"positionAlignment":1},{"id":510,"trainrunSectionId":237,"positionIndex":1,"positionAlignment":1}],"transitions":[{"id":147,"port1Id":505,"port2Id":508,"isNonStopTransit":true}],"connections":[],"resourceId":165,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":137,"betriebspunktName":"LZ","fullName":"Luzern","positionX":1152,"positionY":2272,"ports":[{"id":542,"trainrunSectionId":253,"positionIndex":0,"positionAlignment":0},{"id":540,"trainrunSectionId":252,"positionIndex":1,"positionAlignment":0},{"id":538,"trainrunSectionId":251,"positionIndex":2,"positionAlignment":0},{"id":536,"trainrunSectionId":250,"positionIndex":3,"positionAlignment":0},{"id":532,"trainrunSectionId":248,"positionIndex":0,"positionAlignment":2},{"id":530,"trainrunSectionId":247,"positionIndex":1,"positionAlignment":2},{"id":544,"trainrunSectionId":254,"positionIndex":0,"positionAlignment":3},{"id":548,"trainrunSectionId":256,"positionIndex":1,"positionAlignment":3},{"id":550,"trainrunSectionId":257,"positionIndex":2,"positionAlignment":3},{"id":546,"trainrunSectionId":255,"positionIndex":3,"positionAlignment":3}],"transitions":[{"id":155,"port1Id":542,"port2Id":544,"isNonStopTransit":false},{"id":156,"port1Id":536,"port2Id":550,"isNonStopTransit":false}],"connections":[],"resourceId":166,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":138,"betriebspunktName":"WH","fullName":"Wolhusen","positionX":576,"positionY":2272,"ports":[{"id":521,"trainrunSectionId":243,"positionIndex":0,"positionAlignment":0},{"id":528,"trainrunSectionId":246,"positionIndex":1,"positionAlignment":0},{"id":523,"trainrunSectionId":244,"positionIndex":2,"positionAlignment":0},{"id":525,"trainrunSectionId":245,"positionIndex":0,"positionAlignment":2},{"id":520,"trainrunSectionId":242,"positionIndex":1,"positionAlignment":2},{"id":531,"trainrunSectionId":248,"positionIndex":0,"positionAlignment":3},{"id":529,"trainrunSectionId":247,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":149,"port1Id":521,"port2Id":520,"isNonStopTransit":false},{"id":152,"port1Id":523,"port2Id":529,"isNonStopTransit":false},{"id":153,"port1Id":525,"port2Id":531,"isNonStopTransit":false}],"connections":[],"resourceId":167,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":139,"betriebspunktName":"LABE","fullName":"Langnau i.E.","positionX":32,"positionY":2272,"ports":[{"id":526,"trainrunSectionId":245,"positionIndex":0,"positionAlignment":3},{"id":519,"trainrunSectionId":242,"positionIndex":1,"positionAlignment":3}],"transitions":[],"connections":[],"resourceId":168,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":140,"betriebspunktName":"RK","fullName":"Rotkreuz ","positionX":1504,"positionY":2272,"ports":[{"id":543,"trainrunSectionId":254,"positionIndex":0,"positionAlignment":2},{"id":547,"trainrunSectionId":256,"positionIndex":1,"positionAlignment":2},{"id":549,"trainrunSectionId":257,"positionIndex":2,"positionAlignment":2},{"id":545,"trainrunSectionId":255,"positionIndex":3,"positionAlignment":2},{"id":579,"trainrunSectionId":272,"positionIndex":0,"positionAlignment":3},{"id":575,"trainrunSectionId":270,"positionIndex":1,"positionAlignment":3},{"id":587,"trainrunSectionId":276,"positionIndex":2,"positionAlignment":3},{"id":583,"trainrunSectionId":274,"positionIndex":3,"positionAlignment":3}],"transitions":[{"id":172,"port1Id":549,"port2Id":575,"isNonStopTransit":false},{"id":175,"port1Id":547,"port2Id":579,"isNonStopTransit":true},{"id":178,"port1Id":545,"port2Id":583,"isNonStopTransit":false},{"id":180,"port1Id":543,"port2Id":587,"isNonStopTransit":true}],"connections":[],"resourceId":169,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":141,"betriebspunktName":"ZF","fullName":"Zofingen","positionX":992,"positionY":672,"ports":[{"id":472,"trainrunSectionId":218,"positionIndex":0,"positionAlignment":0},{"id":511,"trainrunSectionId":238,"positionIndex":1,"positionAlignment":0},{"id":473,"trainrunSectionId":219,"positionIndex":2,"positionAlignment":0},{"id":477,"trainrunSectionId":221,"positionIndex":0,"positionAlignment":1},{"id":691,"trainrunSectionId":415,"positionIndex":1,"positionAlignment":1},{"id":513,"trainrunSectionId":239,"positionIndex":2,"positionAlignment":1},{"id":534,"trainrunSectionId":249,"positionIndex":3,"positionAlignment":1},{"id":479,"trainrunSectionId":222,"positionIndex":0,"positionAlignment":2}],"transitions":[{"id":137,"port1Id":472,"port2Id":477,"isNonStopTransit":true},{"id":148,"port1Id":511,"port2Id":513,"isNonStopTransit":false},{"id":154,"port1Id":473,"port2Id":534,"isNonStopTransit":false},{"id":188,"port1Id":691,"port2Id":479,"isNonStopTransit":false}],"connections":[],"resourceId":170,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":142,"betriebspunktName":"LTH","fullName":"Langenthal","positionX":192,"positionY":352,"ports":[{"id":598,"trainrunSectionId":281,"positionIndex":0,"positionAlignment":1},{"id":594,"trainrunSectionId":279,"positionIndex":1,"positionAlignment":1},{"id":503,"trainrunSectionId":234,"positionIndex":0,"positionAlignment":2},{"id":491,"trainrunSectionId":228,"positionIndex":1,"positionAlignment":2},{"id":501,"trainrunSectionId":233,"positionIndex":0,"positionAlignment":3},{"id":499,"trainrunSectionId":232,"positionIndex":1,"positionAlignment":3},{"id":601,"trainrunSectionId":283,"positionIndex":2,"positionAlignment":3},{"id":599,"trainrunSectionId":282,"positionIndex":3,"positionAlignment":3}],"transitions":[{"id":144,"port1Id":491,"port2Id":499,"isNonStopTransit":false},{"id":146,"port1Id":503,"port2Id":501,"isNonStopTransit":false},{"id":186,"port1Id":594,"port2Id":599,"isNonStopTransit":false},{"id":187,"port1Id":598,"port2Id":601,"isNonStopTransit":false}],"connections":[],"resourceId":171,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":143,"betriebspunktName":"RTR","fullName":"Rothrist","positionX":192,"positionY":160,"ports":[{"id":497,"trainrunSectionId":231,"positionIndex":0,"positionAlignment":2},{"id":487,"trainrunSectionId":226,"positionIndex":1,"positionAlignment":2},{"id":481,"trainrunSectionId":223,"positionIndex":2,"positionAlignment":2},{"id":496,"trainrunSectionId":230,"positionIndex":0,"positionAlignment":3},{"id":486,"trainrunSectionId":225,"positionIndex":1,"positionAlignment":3},{"id":480,"trainrunSectionId":222,"positionIndex":2,"positionAlignment":3}],"transitions":[{"id":139,"port1Id":481,"port2Id":480,"isNonStopTransit":true},{"id":141,"port1Id":487,"port2Id":486,"isNonStopTransit":true},{"id":143,"port1Id":497,"port2Id":496,"isNonStopTransit":true}],"connections":[],"resourceId":172,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":144,"betriebspunktName":"BN","fullName":"Bern","positionX":-672,"positionY":160,"ports":[{"id":498,"trainrunSectionId":231,"positionIndex":0,"positionAlignment":3},{"id":488,"trainrunSectionId":226,"positionIndex":1,"positionAlignment":3},{"id":482,"trainrunSectionId":223,"positionIndex":2,"positionAlignment":3},{"id":504,"trainrunSectionId":234,"positionIndex":3,"positionAlignment":3},{"id":492,"trainrunSectionId":228,"positionIndex":4,"positionAlignment":3}],"transitions":[],"connections":[],"resourceId":173,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":145,"betriebspunktName":"ZUE","fullName":"Zuerich","positionX":1920,"positionY":160,"ports":[{"id":506,"trainrunSectionId":235,"positionIndex":0,"positionAlignment":1},{"id":493,"trainrunSectionId":229,"positionIndex":0,"positionAlignment":2},{"id":484,"trainrunSectionId":224,"positionIndex":1,"positionAlignment":2},{"id":489,"trainrunSectionId":227,"positionIndex":2,"positionAlignment":2}],"transitions":[],"connections":[],"resourceId":174,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":146,"betriebspunktName":"CHAM","fullName":"Cham","positionX":1888,"positionY":2208,"ports":[{"id":581,"trainrunSectionId":273,"positionIndex":0,"positionAlignment":0},{"id":577,"trainrunSectionId":271,"positionIndex":1,"positionAlignment":0},{"id":580,"trainrunSectionId":272,"positionIndex":0,"positionAlignment":2},{"id":576,"trainrunSectionId":270,"positionIndex":1,"positionAlignment":2}],"transitions":[{"id":173,"port1Id":577,"port2Id":576,"isNonStopTransit":false},{"id":176,"port1Id":581,"port2Id":580,"isNonStopTransit":true}],"connections":[],"resourceId":175,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":147,"betriebspunktName":"IM","fullName":"Immensee","positionX":1888,"positionY":2336,"ports":[{"id":588,"trainrunSectionId":276,"positionIndex":0,"positionAlignment":2},{"id":584,"trainrunSectionId":274,"positionIndex":1,"positionAlignment":2},{"id":589,"trainrunSectionId":277,"positionIndex":0,"positionAlignment":3},{"id":585,"trainrunSectionId":275,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":179,"port1Id":584,"port2Id":585,"isNonStopTransit":false},{"id":181,"port1Id":588,"port2Id":589,"isNonStopTransit":false}],"connections":[],"resourceId":176,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":148,"betriebspunktName":"HWIL","fullName":"Huttwil","positionX":192,"positionY":1920,"ports":[{"id":595,"trainrunSectionId":280,"positionIndex":0,"positionAlignment":0},{"id":591,"trainrunSectionId":278,"positionIndex":1,"positionAlignment":0},{"id":517,"trainrunSectionId":241,"positionIndex":0,"positionAlignment":3},{"id":516,"trainrunSectionId":240,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":182,"port1Id":591,"port2Id":516,"isNonStopTransit":false},{"id":184,"port1Id":595,"port2Id":517,"isNonStopTransit":false}],"connections":[],"resourceId":177,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":149,"betriebspunktName":"EBR","fullName":"Emmenbrücke ","positionX":1088,"positionY":1984,"ports":[{"id":571,"trainrunSectionId":268,"positionIndex":0,"positionAlignment":0},{"id":567,"trainrunSectionId":266,"positionIndex":1,"positionAlignment":0},{"id":563,"trainrunSectionId":264,"positionIndex":2,"positionAlignment":0},{"id":559,"trainrunSectionId":262,"positionIndex":3,"positionAlignment":0},{"id":541,"trainrunSectionId":253,"positionIndex":0,"positionAlignment":1},{"id":539,"trainrunSectionId":252,"positionIndex":1,"positionAlignment":1},{"id":537,"trainrunSectionId":251,"positionIndex":2,"positionAlignment":1},{"id":535,"trainrunSectionId":250,"positionIndex":3,"positionAlignment":1}],"transitions":[{"id":161,"port1Id":559,"port2Id":535,"isNonStopTransit":false},{"id":163,"port1Id":563,"port2Id":537,"isNonStopTransit":false},{"id":166,"port1Id":567,"port2Id":539,"isNonStopTransit":true},{"id":169,"port1Id":571,"port2Id":541,"isNonStopTransit":true}],"connections":[],"resourceId":178,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":150,"betriebspunktName":"GEAP","fullName":"Genf Flughafen","positionX":-864,"positionY":192,"ports":[],"transitions":[],"connections":[],"resourceId":179,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":151,"betriebspunktName":"IO","fullName":"Interlaken Ost","positionX":-800,"positionY":416,"ports":[],"transitions":[],"connections":[],"resourceId":180,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":152,"betriebspunktName":"BI","fullName":"Biel","positionX":-512,"positionY":64,"ports":[],"transitions":[],"connections":[],"resourceId":181,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":153,"betriebspunktName":"SG","fullName":"St. Gallen","positionX":2752,"positionY":256,"ports":[],"transitions":[],"connections":[],"resourceId":182,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":154,"betriebspunktName":"GD","fullName":"Goldau","positionX":2368,"positionY":2336,"ports":[{"id":603,"trainrunSectionId":284,"positionIndex":0,"positionAlignment":1},{"id":590,"trainrunSectionId":277,"positionIndex":0,"positionAlignment":2},{"id":586,"trainrunSectionId":275,"positionIndex":1,"positionAlignment":2}],"transitions":[],"connections":[],"resourceId":183,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":155,"betriebspunktName":"Milano","fullName":"Neuer Knoten","positionX":2528,"positionY":2560,"ports":[{"id":604,"trainrunSectionId":284,"positionIndex":0,"positionAlignment":0}],"transitions":[],"connections":[],"resourceId":184,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":156,"betriebspunktName":"CH","fullName":"Chur","positionX":2816,"positionY":2016,"ports":[],"transitions":[],"connections":[],"resourceId":185,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":157,"betriebspunktName":"OL","fullName":"Olten","positionX":992,"positionY":160,"ports":[{"id":471,"trainrunSectionId":218,"positionIndex":0,"positionAlignment":1},{"id":512,"trainrunSectionId":238,"positionIndex":1,"positionAlignment":1},{"id":474,"trainrunSectionId":219,"positionIndex":2,"positionAlignment":1},{"id":495,"trainrunSectionId":230,"positionIndex":0,"positionAlignment":2},{"id":485,"trainrunSectionId":225,"positionIndex":1,"positionAlignment":2},{"id":502,"trainrunSectionId":233,"positionIndex":2,"positionAlignment":2},{"id":500,"trainrunSectionId":232,"positionIndex":3,"positionAlignment":2},{"id":602,"trainrunSectionId":283,"positionIndex":4,"positionAlignment":2},{"id":600,"trainrunSectionId":282,"positionIndex":5,"positionAlignment":2},{"id":494,"trainrunSectionId":229,"positionIndex":0,"positionAlignment":3},{"id":483,"trainrunSectionId":224,"positionIndex":1,"positionAlignment":3},{"id":490,"trainrunSectionId":227,"positionIndex":2,"positionAlignment":3}],"transitions":[{"id":140,"port1Id":485,"port2Id":483,"isNonStopTransit":false},{"id":142,"port1Id":495,"port2Id":494,"isNonStopTransit":false},{"id":145,"port1Id":500,"port2Id":490,"isNonStopTransit":false}],"connections":[],"resourceId":186,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":158,"betriebspunktName":"BS","fullName":"Basel","positionX":992,"positionY":-64,"ports":[],"transitions":[],"connections":[],"resourceId":187,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":159,"betriebspunktName":"REID","fullName":"Reiden","positionX":992,"positionY":992,"ports":[{"id":478,"trainrunSectionId":221,"positionIndex":0,"positionAlignment":0},{"id":692,"trainrunSectionId":415,"positionIndex":1,"positionAlignment":0},{"id":514,"trainrunSectionId":239,"positionIndex":2,"positionAlignment":0},{"id":533,"trainrunSectionId":249,"positionIndex":3,"positionAlignment":0},{"id":551,"trainrunSectionId":258,"positionIndex":0,"positionAlignment":1},{"id":553,"trainrunSectionId":259,"positionIndex":1,"positionAlignment":1},{"id":555,"trainrunSectionId":260,"positionIndex":2,"positionAlignment":1},{"id":557,"trainrunSectionId":261,"positionIndex":3,"positionAlignment":1}],"transitions":[{"id":157,"port1Id":551,"port2Id":478,"isNonStopTransit":true},{"id":159,"port1Id":555,"port2Id":514,"isNonStopTransit":false},{"id":160,"port1Id":557,"port2Id":533,"isNonStopTransit":false},{"id":189,"port1Id":692,"port2Id":553,"isNonStopTransit":false}],"connections":[],"resourceId":188,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":160,"betriebspunktName":"SEM","fullName":"Sempach-Neuenkirch","positionX":1088,"positionY":1696,"ports":[{"id":573,"trainrunSectionId":269,"positionIndex":0,"positionAlignment":0},{"id":569,"trainrunSectionId":267,"positionIndex":1,"positionAlignment":0},{"id":565,"trainrunSectionId":265,"positionIndex":2,"positionAlignment":0},{"id":561,"trainrunSectionId":263,"positionIndex":3,"positionAlignment":0},{"id":572,"trainrunSectionId":268,"positionIndex":0,"positionAlignment":1},{"id":568,"trainrunSectionId":266,"positionIndex":1,"positionAlignment":1},{"id":564,"trainrunSectionId":264,"positionIndex":2,"positionAlignment":1},{"id":560,"trainrunSectionId":262,"positionIndex":3,"positionAlignment":1}],"transitions":[{"id":162,"port1Id":560,"port2Id":561,"isNonStopTransit":false},{"id":164,"port1Id":564,"port2Id":565,"isNonStopTransit":false},{"id":167,"port1Id":568,"port2Id":569,"isNonStopTransit":true},{"id":170,"port1Id":572,"port2Id":573,"isNonStopTransit":true}],"connections":[],"resourceId":189,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":161,"betriebspunktName":"SS","fullName":"Sursee","positionX":992,"positionY":1312,"ports":[{"id":552,"trainrunSectionId":258,"positionIndex":0,"positionAlignment":0},{"id":554,"trainrunSectionId":259,"positionIndex":1,"positionAlignment":0},{"id":556,"trainrunSectionId":260,"positionIndex":2,"positionAlignment":0},{"id":558,"trainrunSectionId":261,"positionIndex":3,"positionAlignment":0},{"id":574,"trainrunSectionId":269,"positionIndex":0,"positionAlignment":1},{"id":570,"trainrunSectionId":267,"positionIndex":1,"positionAlignment":1},{"id":566,"trainrunSectionId":265,"positionIndex":2,"positionAlignment":1},{"id":562,"trainrunSectionId":263,"positionIndex":3,"positionAlignment":1}],"transitions":[{"id":165,"port1Id":556,"port2Id":566,"isNonStopTransit":false},{"id":168,"port1Id":554,"port2Id":570,"isNonStopTransit":false},{"id":171,"port1Id":552,"port2Id":574,"isNonStopTransit":true}],"connections":[{"id":11,"port1Id":558,"port2Id":566},{"id":12,"port1Id":562,"port2Id":556},{"id":13,"port1Id":554,"port2Id":566}],"resourceId":190,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]}],"trainrunSections":[{"id":218,"sourceNodeId":157,"sourcePortId":471,"targetNodeId":141,"targetPortId":472,"travelTime":{"lock":false,"time":30,"warning":null},"sourceDeparture":{"lock":false,"time":46,"warning":null,"consecutiveTime":46},"sourceArrival":{"lock":false,"time":14,"warning":null,"consecutiveTime":314},"targetDeparture":{"lock":false,"time":44,"warning":null,"consecutiveTime":284},"targetArrival":{"lock":false,"time":16,"warning":null,"consecutiveTime":76},"numberOfStops":0,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1008,"y":382},{"x":1008,"y":446},{"x":1008,"y":606},{"x":1008,"y":670}],"textPositions":{"0":{"x":996,"y":400},"1":{"x":1020,"y":428},"2":{"x":1020,"y":652},"3":{"x":996,"y":624},"4":{"x":996,"y":526},"5":{"x":996,"y":526},"6":{"x":1020,"y":526}}},"warnings":null},{"id":219,"sourceNodeId":141,"sourcePortId":473,"targetNodeId":157,"targetPortId":474,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":40,"warning":null,"consecutiveTime":40},"sourceArrival":{"lock":false,"time":20,"warning":null,"consecutiveTime":20},"targetDeparture":{"lock":false,"time":10,"warning":null,"consecutiveTime":10},"targetArrival":{"lock":false,"time":50,"warning":null,"consecutiveTime":50},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1072,"y":670},{"x":1072,"y":606},{"x":1072,"y":446},{"x":1072,"y":382}],"textPositions":{"0":{"x":1084,"y":652},"1":{"x":1060,"y":624},"2":{"x":1060,"y":400},"3":{"x":1084,"y":428},"4":{"x":1060,"y":526},"5":{"x":1060,"y":526},"6":{"x":1084,"y":526}}},"warnings":null},{"id":221,"sourceNodeId":141,"sourcePortId":477,"targetNodeId":159,"targetPortId":478,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":16,"warning":null,"consecutiveTime":76},"sourceArrival":{"lock":false,"time":44,"warning":null,"consecutiveTime":284},"targetDeparture":{"lock":false,"time":34,"warning":null,"consecutiveTime":274},"targetArrival":{"lock":false,"time":26,"warning":null,"consecutiveTime":86},"numberOfStops":0,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1008,"y":738},{"x":1008,"y":802},{"x":1008,"y":926},{"x":1008,"y":990}],"textPositions":{"0":{"x":996,"y":756},"1":{"x":1020,"y":784},"2":{"x":1020,"y":972},"3":{"x":996,"y":944},"4":{"x":996,"y":864},"5":{"x":996,"y":864},"6":{"x":1020,"y":864}}},"warnings":null},{"id":222,"sourceNodeId":141,"sourcePortId":479,"targetNodeId":143,"targetPortId":480,"travelTime":{"lock":false,"time":6,"warning":null},"sourceDeparture":{"lock":false,"time":33,"warning":null,"consecutiveTime":153},"sourceArrival":{"lock":false,"time":27,"warning":null,"consecutiveTime":27},"targetDeparture":{"lock":false,"time":21,"warning":null,"consecutiveTime":21},"targetArrival":{"lock":false,"time":39,"warning":null,"consecutiveTime":159},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":990,"y":688},{"x":926,"y":688},{"x":354,"y":240},{"x":290,"y":240}],"textPositions":{"0":{"x":972,"y":676},"1":{"x":944,"y":700},"2":{"x":308,"y":252},"3":{"x":336,"y":228},"4":{"x":640,"y":452},"5":{"x":640,"y":452},"6":{"x":640,"y":476}}},"warnings":null},{"id":223,"sourceNodeId":143,"sourcePortId":481,"targetNodeId":144,"targetPortId":482,"travelTime":{"lock":false,"time":21,"warning":null},"sourceDeparture":{"lock":false,"time":39,"warning":null,"consecutiveTime":159},"sourceArrival":{"lock":false,"time":21,"warning":null,"consecutiveTime":21},"targetDeparture":{"lock":true,"time":0,"warning":null,"consecutiveTime":0},"targetArrival":{"lock":true,"time":0,"warning":null,"consecutiveTime":180},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":190,"y":240},{"x":126,"y":240},{"x":-510,"y":240},{"x":-574,"y":240}],"textPositions":{"0":{"x":172,"y":228},"1":{"x":144,"y":252},"2":{"x":-556,"y":252},"3":{"x":-528,"y":228},"4":{"x":-192,"y":228},"5":{"x":-192,"y":228},"6":{"x":-192,"y":252}}},"warnings":null},{"id":224,"sourceNodeId":157,"sourcePortId":483,"targetNodeId":145,"targetPortId":484,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":31,"warning":null,"consecutiveTime":91},"sourceArrival":{"lock":false,"time":29,"warning":null,"consecutiveTime":89},"targetDeparture":{"lock":false,"time":19,"warning":null,"consecutiveTime":79},"targetArrival":{"lock":false,"time":41,"warning":null,"consecutiveTime":101},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1090,"y":208},{"x":1154,"y":208},{"x":1854,"y":208},{"x":1918,"y":208}],"textPositions":{"0":{"x":1108,"y":220},"1":{"x":1136,"y":196},"2":{"x":1900,"y":196},"3":{"x":1872,"y":220},"4":{"x":1504,"y":196},"5":{"x":1504,"y":196},"6":{"x":1504,"y":220}}},"warnings":null},{"id":225,"sourceNodeId":157,"sourcePortId":485,"targetNodeId":143,"targetPortId":486,"travelTime":{"lock":false,"time":20,"warning":null},"sourceDeparture":{"lock":false,"time":31,"warning":null,"consecutiveTime":91},"sourceArrival":{"lock":false,"time":29,"warning":null,"consecutiveTime":89},"targetDeparture":{"lock":false,"time":9,"warning":null,"consecutiveTime":69},"targetArrival":{"lock":false,"time":51,"warning":null,"consecutiveTime":111},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":990,"y":208},{"x":926,"y":208},{"x":354,"y":208},{"x":290,"y":208}],"textPositions":{"0":{"x":972,"y":196},"1":{"x":944,"y":220},"2":{"x":308,"y":220},"3":{"x":336,"y":196},"4":{"x":640,"y":196},"5":{"x":640,"y":196},"6":{"x":640,"y":220}}},"warnings":null},{"id":226,"sourceNodeId":143,"sourcePortId":487,"targetNodeId":144,"targetPortId":488,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":51,"warning":null,"consecutiveTime":111},"sourceArrival":{"lock":false,"time":9,"warning":null,"consecutiveTime":69},"targetDeparture":{"lock":false,"time":59,"warning":null,"consecutiveTime":59},"targetArrival":{"lock":false,"time":1,"warning":null,"consecutiveTime":121},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":190,"y":208},{"x":126,"y":208},{"x":-510,"y":208},{"x":-574,"y":208}],"textPositions":{"0":{"x":172,"y":196},"1":{"x":144,"y":220},"2":{"x":-556,"y":220},"3":{"x":-528,"y":196},"4":{"x":-192,"y":196},"5":{"x":-192,"y":196},"6":{"x":-192,"y":220}}},"warnings":null},{"id":227,"sourceNodeId":145,"sourcePortId":489,"targetNodeId":157,"targetPortId":490,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":32,"warning":null,"consecutiveTime":152},"sourceArrival":{"lock":false,"time":28,"warning":null,"consecutiveTime":148},"targetDeparture":{"lock":false,"time":18,"warning":null,"consecutiveTime":138},"targetArrival":{"lock":false,"time":42,"warning":null,"consecutiveTime":162},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1918,"y":240},{"x":1854,"y":240},{"x":1154,"y":240},{"x":1090,"y":240}],"textPositions":{"0":{"x":1900,"y":228},"1":{"x":1872,"y":252},"2":{"x":1108,"y":252},"3":{"x":1136,"y":228},"4":{"x":1504,"y":228},"5":{"x":1504,"y":228},"6":{"x":1504,"y":252}}},"warnings":null},{"id":228,"sourceNodeId":142,"sourcePortId":491,"targetNodeId":144,"targetPortId":492,"travelTime":{"lock":false,"time":78,"warning":null},"sourceDeparture":{"lock":false,"time":56,"warning":null,"consecutiveTime":176},"sourceArrival":{"lock":false,"time":4,"warning":null,"consecutiveTime":124},"targetDeparture":{"lock":false,"time":46,"warning":null,"consecutiveTime":46},"targetArrival":{"lock":false,"time":14,"warning":null,"consecutiveTime":254},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":190,"y":400},{"x":126,"y":400},{"x":-510,"y":304},{"x":-574,"y":304}],"textPositions":{"0":{"x":172,"y":388},"1":{"x":144,"y":412},"2":{"x":-556,"y":316},"3":{"x":-528,"y":292},"4":{"x":-192,"y":340},"5":{"x":-192,"y":340},"6":{"x":-192,"y":364}}},"warnings":null},{"id":229,"sourceNodeId":145,"sourcePortId":493,"targetNodeId":157,"targetPortId":494,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":19,"warning":null,"consecutiveTime":19},"sourceArrival":{"lock":false,"time":41,"warning":null,"consecutiveTime":41},"targetDeparture":{"lock":false,"time":31,"warning":null,"consecutiveTime":31},"targetArrival":{"lock":false,"time":29,"warning":null,"consecutiveTime":29},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1918,"y":176},{"x":1854,"y":176},{"x":1154,"y":176},{"x":1090,"y":176}],"textPositions":{"0":{"x":1900,"y":164},"1":{"x":1872,"y":188},"2":{"x":1108,"y":188},"3":{"x":1136,"y":164},"4":{"x":1504,"y":164},"5":{"x":1504,"y":164},"6":{"x":1504,"y":188}}},"warnings":null},{"id":230,"sourceNodeId":157,"sourcePortId":495,"targetNodeId":143,"targetPortId":496,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":31,"warning":null,"consecutiveTime":31},"sourceArrival":{"lock":false,"time":29,"warning":null,"consecutiveTime":29},"targetDeparture":{"lock":false,"time":19,"warning":null,"consecutiveTime":19},"targetArrival":{"lock":false,"time":41,"warning":null,"consecutiveTime":41},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":990,"y":176},{"x":926,"y":176},{"x":354,"y":176},{"x":290,"y":176}],"textPositions":{"0":{"x":972,"y":164},"1":{"x":944,"y":188},"2":{"x":308,"y":188},"3":{"x":336,"y":164},"4":{"x":640,"y":164},"5":{"x":640,"y":164},"6":{"x":640,"y":188}}},"warnings":null},{"id":231,"sourceNodeId":143,"sourcePortId":497,"targetNodeId":144,"targetPortId":498,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":41,"warning":null,"consecutiveTime":41},"sourceArrival":{"lock":false,"time":19,"warning":null,"consecutiveTime":19},"targetDeparture":{"lock":false,"time":9,"warning":null,"consecutiveTime":9},"targetArrival":{"lock":false,"time":51,"warning":null,"consecutiveTime":51},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":190,"y":176},{"x":126,"y":176},{"x":-510,"y":176},{"x":-574,"y":176}],"textPositions":{"0":{"x":172,"y":164},"1":{"x":144,"y":188},"2":{"x":-556,"y":188},"3":{"x":-528,"y":164},"4":{"x":-192,"y":164},"5":{"x":-192,"y":164},"6":{"x":-192,"y":188}}},"warnings":null},{"id":232,"sourceNodeId":142,"sourcePortId":499,"targetNodeId":157,"targetPortId":500,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":6,"warning":null,"consecutiveTime":126},"sourceArrival":{"lock":false,"time":54,"warning":null,"consecutiveTime":174},"targetDeparture":{"lock":false,"time":44,"warning":null,"consecutiveTime":164},"targetArrival":{"lock":false,"time":16,"warning":null,"consecutiveTime":136},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":290,"y":400},{"x":354,"y":400},{"x":926,"y":272},{"x":990,"y":272}],"textPositions":{"0":{"x":308,"y":412},"1":{"x":336,"y":388},"2":{"x":972,"y":260},"3":{"x":944,"y":284},"4":{"x":640,"y":324},"5":{"x":640,"y":324},"6":{"x":640,"y":348}}},"warnings":null},{"id":233,"sourceNodeId":142,"sourcePortId":501,"targetNodeId":157,"targetPortId":502,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":22,"warning":null,"consecutiveTime":22},"sourceArrival":{"lock":false,"time":38,"warning":null,"consecutiveTime":38},"targetDeparture":{"lock":false,"time":28,"warning":null,"consecutiveTime":28},"targetArrival":{"lock":false,"time":32,"warning":null,"consecutiveTime":32},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":290,"y":368},{"x":354,"y":368},{"x":926,"y":240},{"x":990,"y":240}],"textPositions":{"0":{"x":308,"y":380},"1":{"x":336,"y":356},"2":{"x":972,"y":228},"3":{"x":944,"y":252},"4":{"x":640,"y":292},"5":{"x":640,"y":292},"6":{"x":640,"y":316}}},"warnings":null},{"id":234,"sourceNodeId":142,"sourcePortId":503,"targetNodeId":144,"targetPortId":504,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":40,"warning":null,"consecutiveTime":40},"sourceArrival":{"lock":false,"time":20,"warning":null,"consecutiveTime":20},"targetDeparture":{"lock":false,"time":10,"warning":null,"consecutiveTime":10},"targetArrival":{"lock":false,"time":50,"warning":null,"consecutiveTime":50},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":190,"y":368},{"x":126,"y":368},{"x":-510,"y":272},{"x":-574,"y":272}],"textPositions":{"0":{"x":172,"y":356},"1":{"x":144,"y":380},"2":{"x":-556,"y":284},"3":{"x":-528,"y":260},"4":{"x":-192,"y":308},"5":{"x":-192,"y":308},"6":{"x":-192,"y":332}}},"warnings":null},{"id":235,"sourceNodeId":136,"sourcePortId":505,"targetNodeId":145,"targetPortId":506,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":52,"warning":null,"consecutiveTime":112},"sourceArrival":{"lock":false,"time":8,"warning":null,"consecutiveTime":68},"targetDeparture":{"lock":false,"time":58,"warning":null,"consecutiveTime":58},"targetArrival":{"lock":false,"time":2,"warning":null,"consecutiveTime":122},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1936,"y":1630},{"x":1936,"y":1566},{"x":1936,"y":350},{"x":1936,"y":286}],"textPositions":{"0":{"x":1948,"y":1612},"1":{"x":1924,"y":1584},"2":{"x":1924,"y":304},"3":{"x":1948,"y":332},"4":{"x":1924,"y":958},"5":{"x":1924,"y":958},"6":{"x":1948,"y":958}}},"warnings":null},{"id":236,"sourceNodeId":135,"sourcePortId":507,"targetNodeId":136,"targetPortId":508,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":42,"warning":null,"consecutiveTime":102},"sourceArrival":{"lock":false,"time":18,"warning":null,"consecutiveTime":78},"targetDeparture":{"lock":false,"time":8,"warning":null,"consecutiveTime":68},"targetArrival":{"lock":false,"time":52,"warning":null,"consecutiveTime":112},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1904,"y":1982},{"x":1904,"y":1918},{"x":1936,"y":1762},{"x":1936,"y":1698}],"textPositions":{"0":{"x":1916,"y":1964},"1":{"x":1892,"y":1936},"2":{"x":1924,"y":1716},"3":{"x":1948,"y":1744},"4":{"x":1908,"y":1840},"5":{"x":1908,"y":1840},"6":{"x":1932,"y":1840}}},"warnings":null},{"id":237,"sourceNodeId":135,"sourcePortId":509,"targetNodeId":136,"targetPortId":510,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":23,"warning":null,"consecutiveTime":83},"sourceArrival":{"lock":false,"time":37,"warning":null,"consecutiveTime":97},"targetDeparture":{"lock":false,"time":27,"warning":null,"consecutiveTime":87},"targetArrival":{"lock":false,"time":33,"warning":null,"consecutiveTime":93},"numberOfStops":0,"trainrunId":91,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1936,"y":1982},{"x":1936,"y":1918},{"x":1968,"y":1762},{"x":1968,"y":1698}],"textPositions":{"0":{"x":1948,"y":1964},"1":{"x":1924,"y":1936},"2":{"x":1956,"y":1716},"3":{"x":1980,"y":1744},"4":{"x":1940,"y":1840},"5":{"x":1940,"y":1840},"6":{"x":1964,"y":1840}}},"warnings":null},{"id":238,"sourceNodeId":141,"sourcePortId":511,"targetNodeId":157,"targetPortId":512,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":40,"warning":null,"consecutiveTime":160},"sourceArrival":{"lock":false,"time":20,"warning":null,"consecutiveTime":20},"targetDeparture":{"lock":false,"time":10,"warning":null,"consecutiveTime":10},"targetArrival":{"lock":false,"time":50,"warning":null,"consecutiveTime":170},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1040,"y":670},{"x":1040,"y":606},{"x":1040,"y":446},{"x":1040,"y":382}],"textPositions":{"0":{"x":1052,"y":652},"1":{"x":1028,"y":624},"2":{"x":1028,"y":400},"3":{"x":1052,"y":428},"4":{"x":1028,"y":526},"5":{"x":1028,"y":526},"6":{"x":1052,"y":526}}},"warnings":null},{"id":239,"sourceNodeId":141,"sourcePortId":513,"targetNodeId":159,"targetPortId":514,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":21.5,"warning":null,"consecutiveTime":21.5},"sourceArrival":{"lock":false,"time":38.5,"warning":null,"consecutiveTime":158.5},"targetDeparture":{"lock":false,"time":28.5,"warning":null,"consecutiveTime":148.5},"targetArrival":{"lock":false,"time":31.5,"warning":null,"consecutiveTime":31.5},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1072,"y":738},{"x":1072,"y":802},{"x":1072,"y":926},{"x":1072,"y":990}],"textPositions":{"0":{"x":1060,"y":756},"1":{"x":1084,"y":784},"2":{"x":1084,"y":972},"3":{"x":1060,"y":944},"4":{"x":1060,"y":864},"5":{"x":1060,"y":864},"6":{"x":1084,"y":864}}},"warnings":null},{"id":240,"sourceNodeId":134,"sourcePortId":515,"targetNodeId":148,"targetPortId":516,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":33,"warning":null,"consecutiveTime":93},"sourceArrival":{"lock":false,"time":27,"warning":null,"consecutiveTime":87},"targetDeparture":{"lock":false,"time":17,"warning":null,"consecutiveTime":77},"targetArrival":{"lock":false,"time":43,"warning":null,"consecutiveTime":103},"numberOfStops":3,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":542,"y":2000},{"x":478,"y":2000},{"x":354,"y":1968},{"x":290,"y":1968}],"textPositions":{"0":{"x":524,"y":1988},"1":{"x":496,"y":2012},"2":{"x":308,"y":1980},"3":{"x":336,"y":1956},"4":{"x":416,"y":1972},"5":{"x":416,"y":1972},"6":{"x":416,"y":1996}}},"warnings":null},{"id":241,"sourceNodeId":148,"sourcePortId":517,"targetNodeId":134,"targetPortId":518,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":37,"warning":null,"consecutiveTime":37},"sourceArrival":{"lock":false,"time":23,"warning":null,"consecutiveTime":143},"targetDeparture":{"lock":false,"time":13,"warning":null,"consecutiveTime":133},"targetArrival":{"lock":false,"time":47,"warning":null,"consecutiveTime":47},"numberOfStops":2,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":290,"y":1936},{"x":354,"y":1936},{"x":478,"y":1968},{"x":542,"y":1968}],"textPositions":{"0":{"x":308,"y":1948},"1":{"x":336,"y":1924},"2":{"x":524,"y":1956},"3":{"x":496,"y":1980},"4":{"x":416,"y":1940},"5":{"x":416,"y":1940},"6":{"x":416,"y":1964}}},"warnings":null},{"id":242,"sourceNodeId":139,"sourcePortId":519,"targetNodeId":138,"targetPortId":520,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":51,"warning":null,"consecutiveTime":111},"sourceArrival":{"lock":false,"time":9,"warning":null,"consecutiveTime":69},"targetDeparture":{"lock":false,"time":59,"warning":null,"consecutiveTime":59},"targetArrival":{"lock":false,"time":1,"warning":null,"consecutiveTime":121},"numberOfStops":4,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":130,"y":2320},{"x":194,"y":2320},{"x":510,"y":2320},{"x":574,"y":2320}],"textPositions":{"0":{"x":148,"y":2332},"1":{"x":176,"y":2308},"2":{"x":556,"y":2308},"3":{"x":528,"y":2332},"4":{"x":352,"y":2308},"5":{"x":352,"y":2308},"6":{"x":352,"y":2332}}},"warnings":null},{"id":243,"sourceNodeId":138,"sourcePortId":521,"targetNodeId":134,"targetPortId":522,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":2,"warning":null,"consecutiveTime":122},"sourceArrival":{"lock":false,"time":58,"warning":null,"consecutiveTime":58},"targetDeparture":{"lock":false,"time":48,"warning":null,"consecutiveTime":48},"targetArrival":{"lock":false,"time":12,"warning":null,"consecutiveTime":132},"numberOfStops":1,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":592,"y":2270},{"x":592,"y":2206},{"x":560,"y":2110},{"x":560,"y":2046}],"textPositions":{"0":{"x":604,"y":2252},"1":{"x":580,"y":2224},"2":{"x":548,"y":2064},"3":{"x":572,"y":2092},"4":{"x":588,"y":2158},"5":{"x":588,"y":2158},"6":{"x":564,"y":2158}}},"warnings":null},{"id":244,"sourceNodeId":138,"sourcePortId":523,"targetNodeId":134,"targetPortId":524,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":40,"warning":null,"consecutiveTime":40},"sourceArrival":{"lock":false,"time":20,"warning":null,"consecutiveTime":20},"targetDeparture":{"lock":false,"time":10,"warning":null,"consecutiveTime":10},"targetArrival":{"lock":false,"time":50,"warning":null,"consecutiveTime":50},"numberOfStops":2,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":656,"y":2270},{"x":656,"y":2206},{"x":624,"y":2110},{"x":624,"y":2046}],"textPositions":{"0":{"x":668,"y":2252},"1":{"x":644,"y":2224},"2":{"x":612,"y":2064},"3":{"x":636,"y":2092},"4":{"x":652,"y":2158},"5":{"x":652,"y":2158},"6":{"x":628,"y":2158}}},"warnings":null},{"id":245,"sourceNodeId":138,"sourcePortId":525,"targetNodeId":139,"targetPortId":526,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":20,"warning":null,"consecutiveTime":20},"sourceArrival":{"lock":false,"time":40,"warning":null,"consecutiveTime":40},"targetDeparture":{"lock":false,"time":30,"warning":null,"consecutiveTime":30},"targetArrival":{"lock":false,"time":30,"warning":null,"consecutiveTime":30},"numberOfStops":5,"trainrunId":97,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":574,"y":2288},{"x":510,"y":2288},{"x":194,"y":2288},{"x":130,"y":2288}],"textPositions":{"0":{"x":556,"y":2276},"1":{"x":528,"y":2300},"2":{"x":148,"y":2300},"3":{"x":176,"y":2276},"4":{"x":352,"y":2276},"5":{"x":352,"y":2276},"6":{"x":352,"y":2300}}},"warnings":null},{"id":246,"sourceNodeId":134,"sourcePortId":527,"targetNodeId":138,"targetPortId":528,"travelTime":{"lock":false,"time":20,"warning":null},"sourceDeparture":{"lock":false,"time":28,"warning":null,"consecutiveTime":88},"sourceArrival":{"lock":false,"time":32,"warning":null,"consecutiveTime":92},"targetDeparture":{"lock":false,"time":12,"warning":null,"consecutiveTime":72},"targetArrival":{"lock":false,"time":48,"warning":null,"consecutiveTime":108},"numberOfStops":2,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":592,"y":2046},{"x":592,"y":2110},{"x":624,"y":2206},{"x":624,"y":2270}],"textPositions":{"0":{"x":580,"y":2064},"1":{"x":604,"y":2092},"2":{"x":636,"y":2252},"3":{"x":612,"y":2224},"4":{"x":620,"y":2158},"5":{"x":620,"y":2158},"6":{"x":596,"y":2158}}},"warnings":null},{"id":247,"sourceNodeId":138,"sourcePortId":529,"targetNodeId":137,"targetPortId":530,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":21,"warning":null,"consecutiveTime":21},"sourceArrival":{"lock":false,"time":39,"warning":null,"consecutiveTime":39},"targetDeparture":{"lock":false,"time":29,"warning":null,"consecutiveTime":29},"targetArrival":{"lock":false,"time":31,"warning":null,"consecutiveTime":31},"numberOfStops":4,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":674,"y":2320},{"x":738,"y":2320},{"x":1086,"y":2320},{"x":1150,"y":2320}],"textPositions":{"0":{"x":692,"y":2332},"1":{"x":720,"y":2308},"2":{"x":1132,"y":2308},"3":{"x":1104,"y":2332},"4":{"x":912,"y":2308},"5":{"x":912,"y":2308},"6":{"x":912,"y":2332}}},"warnings":null},{"id":248,"sourceNodeId":138,"sourcePortId":531,"targetNodeId":137,"targetPortId":532,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":41.5,"warning":null,"consecutiveTime":41.5},"sourceArrival":{"lock":false,"time":18.5,"warning":null,"consecutiveTime":18.5},"targetDeparture":{"lock":false,"time":8.5,"warning":null,"consecutiveTime":8.5},"targetArrival":{"lock":false,"time":51.5,"warning":null,"consecutiveTime":51.5},"numberOfStops":2,"trainrunId":97,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":674,"y":2288},{"x":738,"y":2288},{"x":1086,"y":2288},{"x":1150,"y":2288}],"textPositions":{"0":{"x":692,"y":2300},"1":{"x":720,"y":2276},"2":{"x":1132,"y":2276},"3":{"x":1104,"y":2300},"4":{"x":912,"y":2276},"5":{"x":912,"y":2276},"6":{"x":912,"y":2300}}},"warnings":null},{"id":249,"sourceNodeId":159,"sourcePortId":533,"targetNodeId":141,"targetPortId":534,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":29,"warning":null,"consecutiveTime":29},"sourceArrival":{"lock":false,"time":31,"warning":null,"consecutiveTime":31},"targetDeparture":{"lock":false,"time":21,"warning":null,"consecutiveTime":21},"targetArrival":{"lock":false,"time":39,"warning":null,"consecutiveTime":39},"numberOfStops":1,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1104,"y":990},{"x":1104,"y":926},{"x":1104,"y":802},{"x":1104,"y":738}],"textPositions":{"0":{"x":1116,"y":972},"1":{"x":1092,"y":944},"2":{"x":1092,"y":756},"3":{"x":1116,"y":784},"4":{"x":1092,"y":864},"5":{"x":1092,"y":864},"6":{"x":1116,"y":864}}},"warnings":null},{"id":250,"sourceNodeId":149,"sourcePortId":535,"targetNodeId":137,"targetPortId":536,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":39,"warning":null,"consecutiveTime":39},"sourceArrival":{"lock":false,"time":21,"warning":null,"consecutiveTime":141},"targetDeparture":{"lock":false,"time":11,"warning":null,"consecutiveTime":131},"targetArrival":{"lock":false,"time":49,"warning":null,"consecutiveTime":49},"numberOfStops":0,"trainrunId":91,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1200,"y":2050},{"x":1200,"y":2114},{"x":1264,"y":2206},{"x":1264,"y":2270}],"textPositions":{"0":{"x":1188,"y":2068},"1":{"x":1212,"y":2096},"2":{"x":1276,"y":2252},"3":{"x":1252,"y":2224},"4":{"x":1244,"y":2160},"5":{"x":1244,"y":2160},"6":{"x":1220,"y":2160}}},"warnings":null},{"id":251,"sourceNodeId":149,"sourcePortId":537,"targetNodeId":137,"targetPortId":538,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":7.5,"warning":null,"consecutiveTime":67.5},"sourceArrival":{"lock":false,"time":52.5,"warning":null,"consecutiveTime":112.5},"targetDeparture":{"lock":false,"time":42.5,"warning":null,"consecutiveTime":102.5},"targetArrival":{"lock":false,"time":17.5,"warning":null,"consecutiveTime":77.5},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1168,"y":2050},{"x":1168,"y":2114},{"x":1232,"y":2206},{"x":1232,"y":2270}],"textPositions":{"0":{"x":1156,"y":2068},"1":{"x":1180,"y":2096},"2":{"x":1244,"y":2252},"3":{"x":1220,"y":2224},"4":{"x":1212,"y":2160},"5":{"x":1212,"y":2160},"6":{"x":1188,"y":2160}}},"warnings":null},{"id":252,"sourceNodeId":149,"sourcePortId":539,"targetNodeId":137,"targetPortId":540,"travelTime":{"lock":false,"time":5,"warning":null},"sourceDeparture":{"lock":false,"time":56,"warning":null,"consecutiveTime":56},"sourceArrival":{"lock":false,"time":4,"warning":null,"consecutiveTime":124},"targetDeparture":{"lock":false,"time":59,"warning":null,"consecutiveTime":119},"targetArrival":{"lock":false,"time":1,"warning":null,"consecutiveTime":61},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1136,"y":2050},{"x":1136,"y":2114},{"x":1200,"y":2206},{"x":1200,"y":2270}],"textPositions":{"0":{"x":1124,"y":2068},"1":{"x":1148,"y":2096},"2":{"x":1212,"y":2252},"3":{"x":1188,"y":2224},"4":{"x":1180,"y":2160},"5":{"x":1180,"y":2160},"6":{"x":1156,"y":2160}}},"warnings":null},{"id":253,"sourceNodeId":149,"sourcePortId":541,"targetNodeId":137,"targetPortId":542,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":56,"warning":null,"consecutiveTime":116},"sourceArrival":{"lock":false,"time":4,"warning":null,"consecutiveTime":244},"targetDeparture":{"lock":false,"time":54,"warning":null,"consecutiveTime":234},"targetArrival":{"lock":false,"time":6,"warning":null,"consecutiveTime":126},"numberOfStops":0,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1104,"y":2050},{"x":1104,"y":2114},{"x":1168,"y":2206},{"x":1168,"y":2270}],"textPositions":{"0":{"x":1092,"y":2068},"1":{"x":1116,"y":2096},"2":{"x":1180,"y":2252},"3":{"x":1156,"y":2224},"4":{"x":1148,"y":2160},"5":{"x":1148,"y":2160},"6":{"x":1124,"y":2160}}},"warnings":null},{"id":254,"sourceNodeId":140,"sourcePortId":543,"targetNodeId":137,"targetPortId":544,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":42,"warning":null,"consecutiveTime":222},"sourceArrival":{"lock":false,"time":18,"warning":null,"consecutiveTime":138},"targetDeparture":{"lock":false,"time":8,"warning":null,"consecutiveTime":128},"targetArrival":{"lock":false,"time":52,"warning":null,"consecutiveTime":232},"numberOfStops":0,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1502,"y":2288},{"x":1438,"y":2288},{"x":1346,"y":2288},{"x":1282,"y":2288}],"textPositions":{"0":{"x":1484,"y":2276},"1":{"x":1456,"y":2300},"2":{"x":1300,"y":2300},"3":{"x":1328,"y":2276},"4":{"x":1392,"y":2276},"5":{"x":1392,"y":2276},"6":{"x":1392,"y":2300}}},"warnings":null},{"id":255,"sourceNodeId":140,"sourcePortId":545,"targetNodeId":137,"targetPortId":546,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":40,"warning":null,"consecutiveTime":40},"sourceArrival":{"lock":false,"time":20,"warning":null,"consecutiveTime":20},"targetDeparture":{"lock":false,"time":10,"warning":null,"consecutiveTime":10},"targetArrival":{"lock":false,"time":50,"warning":null,"consecutiveTime":50},"numberOfStops":4,"trainrunId":92,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1502,"y":2384},{"x":1438,"y":2384},{"x":1346,"y":2384},{"x":1282,"y":2384}],"textPositions":{"0":{"x":1484,"y":2372},"1":{"x":1456,"y":2396},"2":{"x":1300,"y":2396},"3":{"x":1328,"y":2372},"4":{"x":1392,"y":2372},"5":{"x":1392,"y":2372},"6":{"x":1392,"y":2396}}},"warnings":null},{"id":256,"sourceNodeId":140,"sourcePortId":547,"targetNodeId":137,"targetPortId":548,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":40,"warning":null,"consecutiveTime":100},"sourceArrival":{"lock":false,"time":20,"warning":null,"consecutiveTime":80},"targetDeparture":{"lock":false,"time":10,"warning":null,"consecutiveTime":70},"targetArrival":{"lock":false,"time":50,"warning":null,"consecutiveTime":110},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1502,"y":2320},{"x":1438,"y":2320},{"x":1346,"y":2320},{"x":1282,"y":2320}],"textPositions":{"0":{"x":1484,"y":2308},"1":{"x":1456,"y":2332},"2":{"x":1300,"y":2332},"3":{"x":1328,"y":2308},"4":{"x":1392,"y":2308},"5":{"x":1392,"y":2308},"6":{"x":1392,"y":2332}}},"warnings":null},{"id":257,"sourceNodeId":140,"sourcePortId":549,"targetNodeId":137,"targetPortId":550,"travelTime":{"lock":false,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":0,"warning":null,"consecutiveTime":120},"sourceArrival":{"lock":false,"time":0,"warning":null,"consecutiveTime":60},"targetDeparture":{"lock":false,"time":50,"warning":null,"consecutiveTime":50},"targetArrival":{"lock":false,"time":10,"warning":null,"consecutiveTime":130},"numberOfStops":4,"trainrunId":91,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1502,"y":2352},{"x":1438,"y":2352},{"x":1346,"y":2352},{"x":1282,"y":2352}],"textPositions":{"0":{"x":1484,"y":2340},"1":{"x":1456,"y":2364},"2":{"x":1300,"y":2364},"3":{"x":1328,"y":2340},"4":{"x":1392,"y":2340},"5":{"x":1392,"y":2340},"6":{"x":1392,"y":2364}}},"warnings":null},{"id":258,"sourceNodeId":159,"sourcePortId":551,"targetNodeId":161,"targetPortId":552,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":26,"warning":null,"consecutiveTime":86},"sourceArrival":{"lock":false,"time":34,"warning":null,"consecutiveTime":274},"targetDeparture":{"lock":false,"time":24,"warning":null,"consecutiveTime":264},"targetArrival":{"lock":false,"time":36,"warning":null,"consecutiveTime":96},"numberOfStops":0,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1008,"y":1058},{"x":1008,"y":1122},{"x":1008,"y":1246},{"x":1008,"y":1310}],"textPositions":{"0":{"x":996,"y":1076},"1":{"x":1020,"y":1104},"2":{"x":1020,"y":1292},"3":{"x":996,"y":1264},"4":{"x":996,"y":1184},"5":{"x":996,"y":1184},"6":{"x":1020,"y":1184}}},"warnings":null},{"id":259,"sourceNodeId":159,"sourcePortId":553,"targetNodeId":161,"targetPortId":554,"travelTime":{"lock":true,"time":7,"warning":null},"sourceDeparture":{"lock":true,"time":35,"warning":null,"consecutiveTime":35},"sourceArrival":{"lock":true,"time":25,"warning":null,"consecutiveTime":145},"targetDeparture":{"lock":true,"time":18,"warning":null,"consecutiveTime":138},"targetArrival":{"lock":true,"time":42,"warning":null,"consecutiveTime":42},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1040,"y":1058},{"x":1040,"y":1122},{"x":1040,"y":1246},{"x":1040,"y":1310}],"textPositions":{"0":{"x":1028,"y":1076},"1":{"x":1052,"y":1104},"2":{"x":1052,"y":1292},"3":{"x":1028,"y":1264},"4":{"x":1028,"y":1184},"5":{"x":1028,"y":1184},"6":{"x":1052,"y":1184}}},"warnings":null},{"id":260,"sourceNodeId":159,"sourcePortId":555,"targetNodeId":161,"targetPortId":556,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":33,"warning":null,"consecutiveTime":33},"sourceArrival":{"lock":false,"time":27,"warning":null,"consecutiveTime":147},"targetDeparture":{"lock":false,"time":17,"warning":null,"consecutiveTime":137},"targetArrival":{"lock":false,"time":43,"warning":null,"consecutiveTime":43},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1072,"y":1058},{"x":1072,"y":1122},{"x":1072,"y":1246},{"x":1072,"y":1310}],"textPositions":{"0":{"x":1060,"y":1076},"1":{"x":1084,"y":1104},"2":{"x":1084,"y":1292},"3":{"x":1060,"y":1264},"4":{"x":1060,"y":1184},"5":{"x":1060,"y":1184},"6":{"x":1084,"y":1184}}},"warnings":null},{"id":261,"sourceNodeId":159,"sourcePortId":557,"targetNodeId":161,"targetPortId":558,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":32,"warning":null,"consecutiveTime":32},"sourceArrival":{"lock":false,"time":28,"warning":null,"consecutiveTime":28},"targetDeparture":{"lock":false,"time":18,"warning":null,"consecutiveTime":18},"targetArrival":{"lock":false,"time":42,"warning":null,"consecutiveTime":42},"numberOfStops":4,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1104,"y":1058},{"x":1104,"y":1122},{"x":1104,"y":1246},{"x":1104,"y":1310}],"textPositions":{"0":{"x":1092,"y":1076},"1":{"x":1116,"y":1104},"2":{"x":1116,"y":1292},"3":{"x":1092,"y":1264},"4":{"x":1092,"y":1184},"5":{"x":1092,"y":1184},"6":{"x":1116,"y":1184}}},"warnings":null},{"id":262,"sourceNodeId":149,"sourcePortId":559,"targetNodeId":160,"targetPortId":560,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":22,"warning":null,"consecutiveTime":142},"sourceArrival":{"lock":false,"time":38,"warning":null,"consecutiveTime":38},"targetDeparture":{"lock":false,"time":28,"warning":null,"consecutiveTime":28},"targetArrival":{"lock":false,"time":32,"warning":null,"consecutiveTime":152},"numberOfStops":3,"trainrunId":91,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1200,"y":1982},{"x":1200,"y":1918},{"x":1200,"y":1826},{"x":1200,"y":1762}],"textPositions":{"0":{"x":1212,"y":1964},"1":{"x":1188,"y":1936},"2":{"x":1188,"y":1780},"3":{"x":1212,"y":1808},"4":{"x":1188,"y":1872},"5":{"x":1188,"y":1872},"6":{"x":1212,"y":1872}}},"warnings":null},{"id":263,"sourceNodeId":160,"sourcePortId":561,"targetNodeId":161,"targetPortId":562,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":33,"warning":null,"consecutiveTime":153},"sourceArrival":{"lock":false,"time":27,"warning":null,"consecutiveTime":27},"targetDeparture":{"lock":false,"time":17,"warning":null,"consecutiveTime":17},"targetArrival":{"lock":false,"time":43,"warning":null,"consecutiveTime":163},"numberOfStops":2,"trainrunId":91,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1200,"y":1694},{"x":1200,"y":1630},{"x":1104,"y":1442},{"x":1104,"y":1378}],"textPositions":{"0":{"x":1212,"y":1676},"1":{"x":1188,"y":1648},"2":{"x":1092,"y":1396},"3":{"x":1116,"y":1424},"4":{"x":1164,"y":1536},"5":{"x":1164,"y":1536},"6":{"x":1140,"y":1536}}},"warnings":null},{"id":264,"sourceNodeId":149,"sourcePortId":563,"targetNodeId":160,"targetPortId":564,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":54,"warning":null,"consecutiveTime":114},"sourceArrival":{"lock":false,"time":6,"warning":null,"consecutiveTime":66},"targetDeparture":{"lock":false,"time":56,"warning":null,"consecutiveTime":56},"targetArrival":{"lock":false,"time":4,"warning":null,"consecutiveTime":124},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1168,"y":1982},{"x":1168,"y":1918},{"x":1168,"y":1826},{"x":1168,"y":1762}],"textPositions":{"0":{"x":1180,"y":1964},"1":{"x":1156,"y":1936},"2":{"x":1156,"y":1780},"3":{"x":1180,"y":1808},"4":{"x":1156,"y":1872},"5":{"x":1156,"y":1872},"6":{"x":1180,"y":1872}}},"warnings":null},{"id":265,"sourceNodeId":160,"sourcePortId":565,"targetNodeId":161,"targetPortId":566,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":5.5,"warning":null,"consecutiveTime":125.5},"sourceArrival":{"lock":false,"time":54.5,"warning":null,"consecutiveTime":54.5},"targetDeparture":{"lock":false,"time":44.5,"warning":null,"consecutiveTime":44.5},"targetArrival":{"lock":false,"time":15.5,"warning":null,"consecutiveTime":135.5},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1168,"y":1694},{"x":1168,"y":1630},{"x":1072,"y":1442},{"x":1072,"y":1378}],"textPositions":{"0":{"x":1180,"y":1676},"1":{"x":1156,"y":1648},"2":{"x":1060,"y":1396},"3":{"x":1084,"y":1424},"4":{"x":1132,"y":1536},"5":{"x":1132,"y":1536},"6":{"x":1108,"y":1536}}},"warnings":null},{"id":266,"sourceNodeId":149,"sourcePortId":567,"targetNodeId":160,"targetPortId":568,"travelTime":{"lock":true,"time":4,"warning":null},"sourceDeparture":{"lock":false,"time":4,"warning":null,"consecutiveTime":124},"sourceArrival":{"lock":false,"time":56,"warning":null,"consecutiveTime":56},"targetDeparture":{"lock":false,"time":52,"warning":null,"consecutiveTime":52},"targetArrival":{"lock":false,"time":8,"warning":null,"consecutiveTime":128},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1136,"y":1982},{"x":1136,"y":1918},{"x":1136,"y":1826},{"x":1136,"y":1762}],"textPositions":{"0":{"x":1148,"y":1964},"1":{"x":1124,"y":1936},"2":{"x":1124,"y":1780},"3":{"x":1148,"y":1808},"4":{"x":1124,"y":1872},"5":{"x":1124,"y":1872},"6":{"x":1148,"y":1872}}},"warnings":null},{"id":267,"sourceNodeId":160,"sourcePortId":569,"targetNodeId":161,"targetPortId":570,"travelTime":{"lock":true,"time":8,"warning":null},"sourceDeparture":{"lock":false,"time":8,"warning":null,"consecutiveTime":128},"sourceArrival":{"lock":false,"time":52,"warning":null,"consecutiveTime":52},"targetDeparture":{"lock":false,"time":44,"warning":null,"consecutiveTime":44},"targetArrival":{"lock":false,"time":16,"warning":null,"consecutiveTime":136},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1136,"y":1694},{"x":1136,"y":1630},{"x":1040,"y":1442},{"x":1040,"y":1378}],"textPositions":{"0":{"x":1148,"y":1676},"1":{"x":1124,"y":1648},"2":{"x":1028,"y":1396},"3":{"x":1052,"y":1424},"4":{"x":1100,"y":1536},"5":{"x":1100,"y":1536},"6":{"x":1076,"y":1536}}},"warnings":null},{"id":268,"sourceNodeId":149,"sourcePortId":571,"targetNodeId":160,"targetPortId":572,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":4,"warning":null,"consecutiveTime":244},"sourceArrival":{"lock":false,"time":56,"warning":null,"consecutiveTime":116},"targetDeparture":{"lock":false,"time":46,"warning":null,"consecutiveTime":106},"targetArrival":{"lock":false,"time":14,"warning":null,"consecutiveTime":254},"numberOfStops":0,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1104,"y":1982},{"x":1104,"y":1918},{"x":1104,"y":1826},{"x":1104,"y":1762}],"textPositions":{"0":{"x":1116,"y":1964},"1":{"x":1092,"y":1936},"2":{"x":1092,"y":1780},"3":{"x":1116,"y":1808},"4":{"x":1092,"y":1872},"5":{"x":1092,"y":1872},"6":{"x":1116,"y":1872}}},"warnings":null},{"id":269,"sourceNodeId":160,"sourcePortId":573,"targetNodeId":161,"targetPortId":574,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":14,"warning":null,"consecutiveTime":254},"sourceArrival":{"lock":false,"time":46,"warning":null,"consecutiveTime":106},"targetDeparture":{"lock":false,"time":36,"warning":null,"consecutiveTime":96},"targetArrival":{"lock":false,"time":24,"warning":null,"consecutiveTime":264},"numberOfStops":0,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1104,"y":1694},{"x":1104,"y":1630},{"x":1008,"y":1442},{"x":1008,"y":1378}],"textPositions":{"0":{"x":1116,"y":1676},"1":{"x":1092,"y":1648},"2":{"x":996,"y":1396},"3":{"x":1020,"y":1424},"4":{"x":1068,"y":1536},"5":{"x":1068,"y":1536},"6":{"x":1044,"y":1536}}},"warnings":null},{"id":270,"sourceNodeId":140,"sourcePortId":575,"targetNodeId":146,"targetPortId":576,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":1,"warning":null,"consecutiveTime":61},"sourceArrival":{"lock":false,"time":59,"warning":null,"consecutiveTime":119},"targetDeparture":{"lock":false,"time":49,"warning":null,"consecutiveTime":109},"targetArrival":{"lock":false,"time":11,"warning":null,"consecutiveTime":71},"numberOfStops":1,"trainrunId":91,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1602,"y":2320},{"x":1666,"y":2320},{"x":1822,"y":2256},{"x":1886,"y":2256}],"textPositions":{"0":{"x":1620,"y":2332},"1":{"x":1648,"y":2308},"2":{"x":1868,"y":2244},"3":{"x":1840,"y":2268},"4":{"x":1744,"y":2276},"5":{"x":1744,"y":2276},"6":{"x":1744,"y":2300}}},"warnings":null},{"id":271,"sourceNodeId":146,"sourcePortId":577,"targetNodeId":135,"targetPortId":578,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":12,"warning":null,"consecutiveTime":72},"sourceArrival":{"lock":false,"time":48,"warning":null,"consecutiveTime":108},"targetDeparture":{"lock":false,"time":38,"warning":null,"consecutiveTime":98},"targetArrival":{"lock":false,"time":22,"warning":null,"consecutiveTime":82},"numberOfStops":3,"trainrunId":91,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1936,"y":2206},{"x":1936,"y":2142},{"x":1936,"y":2114},{"x":1936,"y":2050}],"textPositions":{"0":{"x":1948,"y":2188},"1":{"x":1924,"y":2160},"2":{"x":1924,"y":2068},"3":{"x":1948,"y":2096},"4":{"x":1924,"y":2128},"5":{"x":1924,"y":2128},"6":{"x":1948,"y":2128}}},"warnings":null},{"id":272,"sourceNodeId":140,"sourcePortId":579,"targetNodeId":146,"targetPortId":580,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":20,"warning":null,"consecutiveTime":80},"sourceArrival":{"lock":false,"time":40,"warning":null,"consecutiveTime":100},"targetDeparture":{"lock":false,"time":30,"warning":null,"consecutiveTime":90},"targetArrival":{"lock":false,"time":30,"warning":null,"consecutiveTime":90},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1602,"y":2288},{"x":1666,"y":2288},{"x":1822,"y":2224},{"x":1886,"y":2224}],"textPositions":{"0":{"x":1620,"y":2300},"1":{"x":1648,"y":2276},"2":{"x":1868,"y":2212},"3":{"x":1840,"y":2236},"4":{"x":1744,"y":2244},"5":{"x":1744,"y":2244},"6":{"x":1744,"y":2268}}},"warnings":null},{"id":273,"sourceNodeId":146,"sourcePortId":581,"targetNodeId":135,"targetPortId":582,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":30,"warning":null,"consecutiveTime":90},"sourceArrival":{"lock":false,"time":30,"warning":null,"consecutiveTime":90},"targetDeparture":{"lock":false,"time":20,"warning":null,"consecutiveTime":80},"targetArrival":{"lock":false,"time":40,"warning":null,"consecutiveTime":100},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1904,"y":2206},{"x":1904,"y":2142},{"x":1904,"y":2114},{"x":1904,"y":2050}],"textPositions":{"0":{"x":1916,"y":2188},"1":{"x":1892,"y":2160},"2":{"x":1892,"y":2068},"3":{"x":1916,"y":2096},"4":{"x":1892,"y":2128},"5":{"x":1892,"y":2128},"6":{"x":1916,"y":2128}}},"warnings":null},{"id":274,"sourceNodeId":140,"sourcePortId":583,"targetNodeId":147,"targetPortId":584,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":21,"warning":null,"consecutiveTime":21},"sourceArrival":{"lock":false,"time":39,"warning":null,"consecutiveTime":39},"targetDeparture":{"lock":false,"time":29,"warning":null,"consecutiveTime":29},"targetArrival":{"lock":false,"time":31,"warning":null,"consecutiveTime":31},"numberOfStops":0,"trainrunId":92,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1602,"y":2384},{"x":1666,"y":2384},{"x":1822,"y":2384},{"x":1886,"y":2384}],"textPositions":{"0":{"x":1620,"y":2396},"1":{"x":1648,"y":2372},"2":{"x":1868,"y":2372},"3":{"x":1840,"y":2396},"4":{"x":1744,"y":2372},"5":{"x":1744,"y":2372},"6":{"x":1744,"y":2396}}},"warnings":null},{"id":275,"sourceNodeId":147,"sourcePortId":585,"targetNodeId":154,"targetPortId":586,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":32,"warning":null,"consecutiveTime":32},"sourceArrival":{"lock":false,"time":28,"warning":null,"consecutiveTime":28},"targetDeparture":{"lock":false,"time":18,"warning":null,"consecutiveTime":18},"targetArrival":{"lock":false,"time":42,"warning":null,"consecutiveTime":42},"numberOfStops":0,"trainrunId":92,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1986,"y":2384},{"x":2050,"y":2384},{"x":2302,"y":2384},{"x":2366,"y":2384}],"textPositions":{"0":{"x":2004,"y":2396},"1":{"x":2032,"y":2372},"2":{"x":2348,"y":2372},"3":{"x":2320,"y":2396},"4":{"x":2176,"y":2372},"5":{"x":2176,"y":2372},"6":{"x":2176,"y":2396}}},"warnings":null},{"id":276,"sourceNodeId":140,"sourcePortId":587,"targetNodeId":147,"targetPortId":588,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":18,"warning":null,"consecutiveTime":138},"sourceArrival":{"lock":false,"time":42,"warning":null,"consecutiveTime":222},"targetDeparture":{"lock":false,"time":32,"warning":null,"consecutiveTime":212},"targetArrival":{"lock":false,"time":28,"warning":null,"consecutiveTime":148},"numberOfStops":0,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1602,"y":2352},{"x":1666,"y":2352},{"x":1822,"y":2352},{"x":1886,"y":2352}],"textPositions":{"0":{"x":1620,"y":2364},"1":{"x":1648,"y":2340},"2":{"x":1868,"y":2340},"3":{"x":1840,"y":2364},"4":{"x":1744,"y":2340},"5":{"x":1744,"y":2340},"6":{"x":1744,"y":2364}}},"warnings":null},{"id":277,"sourceNodeId":147,"sourcePortId":589,"targetNodeId":154,"targetPortId":590,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":30,"warning":null,"consecutiveTime":150},"sourceArrival":{"lock":false,"time":30,"warning":null,"consecutiveTime":210},"targetDeparture":{"lock":false,"time":20,"warning":null,"consecutiveTime":200},"targetArrival":{"lock":false,"time":40,"warning":null,"consecutiveTime":160},"numberOfStops":0,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1986,"y":2352},{"x":2050,"y":2352},{"x":2302,"y":2352},{"x":2366,"y":2352}],"textPositions":{"0":{"x":2004,"y":2364},"1":{"x":2032,"y":2340},"2":{"x":2348,"y":2340},"3":{"x":2320,"y":2364},"4":{"x":2176,"y":2340},"5":{"x":2176,"y":2340},"6":{"x":2176,"y":2364}}},"warnings":null},{"id":278,"sourceNodeId":148,"sourcePortId":591,"targetNodeId":133,"targetPortId":592,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":44,"warning":null,"consecutiveTime":104},"sourceArrival":{"lock":false,"time":16,"warning":null,"consecutiveTime":76},"targetDeparture":{"lock":false,"time":6,"warning":null,"consecutiveTime":66},"targetArrival":{"lock":false,"time":54,"warning":null,"consecutiveTime":114},"numberOfStops":3,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":240,"y":1918},{"x":240,"y":1854},{"x":240,"y":994},{"x":240,"y":930}],"textPositions":{"0":{"x":252,"y":1900},"1":{"x":228,"y":1872},"2":{"x":228,"y":948},"3":{"x":252,"y":976},"4":{"x":228,"y":1424},"5":{"x":228,"y":1424},"6":{"x":252,"y":1424}}},"warnings":null},{"id":279,"sourceNodeId":133,"sourcePortId":593,"targetNodeId":142,"targetPortId":594,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":55,"warning":null,"consecutiveTime":115},"sourceArrival":{"lock":false,"time":5,"warning":null,"consecutiveTime":65},"targetDeparture":{"lock":false,"time":55,"warning":null,"consecutiveTime":55},"targetArrival":{"lock":false,"time":5,"warning":null,"consecutiveTime":125},"numberOfStops":3,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":240,"y":862},{"x":240,"y":798},{"x":240,"y":574},{"x":240,"y":510}],"textPositions":{"0":{"x":252,"y":844},"1":{"x":228,"y":816},"2":{"x":228,"y":528},"3":{"x":252,"y":556},"4":{"x":228,"y":686},"5":{"x":228,"y":686},"6":{"x":252,"y":686}}},"warnings":null},{"id":280,"sourceNodeId":148,"sourcePortId":595,"targetNodeId":133,"targetPortId":596,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":24,"warning":null,"consecutiveTime":144},"sourceArrival":{"lock":false,"time":36,"warning":null,"consecutiveTime":36},"targetDeparture":{"lock":false,"time":26,"warning":null,"consecutiveTime":26},"targetArrival":{"lock":false,"time":34,"warning":null,"consecutiveTime":154},"numberOfStops":3,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":1918},{"x":208,"y":1854},{"x":208,"y":994},{"x":208,"y":930}],"textPositions":{"0":{"x":220,"y":1900},"1":{"x":196,"y":1872},"2":{"x":196,"y":948},"3":{"x":220,"y":976},"4":{"x":196,"y":1424},"5":{"x":196,"y":1424},"6":{"x":220,"y":1424}}},"warnings":null},{"id":281,"sourceNodeId":133,"sourcePortId":597,"targetNodeId":142,"targetPortId":598,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":35,"warning":null,"consecutiveTime":155},"sourceArrival":{"lock":false,"time":25,"warning":null,"consecutiveTime":25},"targetDeparture":{"lock":false,"time":15,"warning":null,"consecutiveTime":15},"targetArrival":{"lock":false,"time":45,"warning":null,"consecutiveTime":165},"numberOfStops":3,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":862},{"x":208,"y":798},{"x":208,"y":574},{"x":208,"y":510}],"textPositions":{"0":{"x":220,"y":844},"1":{"x":196,"y":816},"2":{"x":196,"y":528},"3":{"x":220,"y":556},"4":{"x":196,"y":686},"5":{"x":196,"y":686},"6":{"x":220,"y":686}}},"warnings":null},{"id":282,"sourceNodeId":142,"sourcePortId":599,"targetNodeId":157,"targetPortId":600,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":6,"warning":null,"consecutiveTime":126},"sourceArrival":{"lock":false,"time":54,"warning":null,"consecutiveTime":54},"targetDeparture":{"lock":false,"time":44,"warning":null,"consecutiveTime":44},"targetArrival":{"lock":false,"time":16,"warning":null,"consecutiveTime":136},"numberOfStops":3,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":290,"y":464},{"x":354,"y":464},{"x":926,"y":336},{"x":990,"y":336}],"textPositions":{"0":{"x":308,"y":476},"1":{"x":336,"y":452},"2":{"x":972,"y":324},"3":{"x":944,"y":348},"4":{"x":640,"y":388},"5":{"x":640,"y":388},"6":{"x":640,"y":412}}},"warnings":null},{"id":283,"sourceNodeId":142,"sourcePortId":601,"targetNodeId":157,"targetPortId":602,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":46,"warning":null,"consecutiveTime":166},"sourceArrival":{"lock":false,"time":14,"warning":null,"consecutiveTime":14},"targetDeparture":{"lock":false,"time":4,"warning":null,"consecutiveTime":4},"targetArrival":{"lock":false,"time":56,"warning":null,"consecutiveTime":176},"numberOfStops":1,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":290,"y":432},{"x":354,"y":432},{"x":926,"y":304},{"x":990,"y":304}],"textPositions":{"0":{"x":308,"y":444},"1":{"x":336,"y":420},"2":{"x":972,"y":292},"3":{"x":944,"y":316},"4":{"x":640,"y":356},"5":{"x":640,"y":356},"6":{"x":640,"y":380}}},"warnings":null},{"id":284,"sourceNodeId":154,"sourcePortId":603,"targetNodeId":155,"targetPortId":604,"travelTime":{"lock":true,"time":10,"warning":null},"sourceDeparture":{"lock":false,"time":0,"warning":null,"consecutiveTime":0},"sourceArrival":{"lock":false,"time":0,"warning":null,"consecutiveTime":60},"targetDeparture":{"lock":false,"time":50,"warning":null,"consecutiveTime":50},"targetArrival":{"lock":false,"time":10,"warning":null,"consecutiveTime":10},"numberOfStops":0,"trainrunId":98,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2384,"y":2430},{"x":2384,"y":2494},{"x":2544,"y":2494},{"x":2544,"y":2558}],"textPositions":{"0":{"x":2372,"y":2448},"1":{"x":2396,"y":2476},"2":{"x":2556,"y":2540},"3":{"x":2532,"y":2512},"4":{"x":2476,"y":2494},"5":{"x":2476,"y":2494},"6":{"x":2452,"y":2494}}},"warnings":null},{"id":415,"sourceNodeId":141,"sourcePortId":691,"targetNodeId":159,"targetPortId":692,"travelTime":{"time":5,"consecutiveTime":1,"lock":true,"warning":null,"timeFormatter":null},"sourceDeparture":{"time":29,"consecutiveTime":29,"lock":false,"warning":null,"timeFormatter":null},"sourceArrival":{"time":31,"consecutiveTime":151,"lock":false,"warning":null,"timeFormatter":null},"targetDeparture":{"time":26,"consecutiveTime":146,"lock":false,"warning":null,"timeFormatter":null},"targetArrival":{"time":34,"consecutiveTime":34,"lock":false,"warning":null,"timeFormatter":null},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1040,"y":738},{"x":1040,"y":802},{"x":1040,"y":926},{"x":1040,"y":990}],"textPositions":{"0":{"x":1028,"y":756},"1":{"x":1052,"y":784},"2":{"x":1052,"y":972},"3":{"x":1028,"y":944},"4":{"x":1028,"y":864},"5":{"x":1028,"y":864},"6":{"x":1052,"y":864}}},"warnings":null}],"trainruns":[{"id":83,"name":"1","categoryId":2,"frequencyId":2,"trainrunTimeCategoryId":0,"labelIds":[]},{"id":84,"name":"1","categoryId":0,"frequencyId":4,"trainrunTimeCategoryId":0,"labelIds":[]},{"id":85,"name":"12","categoryId":2,"frequencyId":2,"trainrunTimeCategoryId":0,"labelIds":[]},{"id":86,"name":"29","categoryId":4,"frequencyId":2,"trainrunTimeCategoryId":0,"labelIds":[]},{"id":87,"name":"15","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[]},{"id":88,"name":"8","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[]},{"id":89,"name":"12","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[]},{"id":90,"name":"1","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[]},{"id":91,"name":"1","categoryId":4,"frequencyId":0,"trainrunTimeCategoryId":0,"labelIds":[]},{"id":92,"name":"3","categoryId":4,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[]},{"id":93,"name":"","categoryId":3,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[]},{"id":94,"name":"7","categoryId":4,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[]},{"id":95,"name":"6","categoryId":4,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[]},{"id":96,"name":"77","categoryId":4,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[]},{"id":97,"name":"","categoryId":3,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[]},{"id":98,"name":"X","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[]}],"resources":[{"id":151,"capacity":2},{"id":152,"capacity":2},{"id":153,"capacity":2},{"id":154,"capacity":2},{"id":155,"capacity":2},{"id":156,"capacity":2},{"id":157,"capacity":2},{"id":158,"capacity":2},{"id":159,"capacity":2},{"id":160,"capacity":2},{"id":161,"capacity":2},{"id":162,"capacity":2},{"id":163,"capacity":2},{"id":164,"capacity":2},{"id":165,"capacity":2},{"id":166,"capacity":2},{"id":167,"capacity":2},{"id":168,"capacity":2},{"id":169,"capacity":2},{"id":170,"capacity":2},{"id":171,"capacity":2},{"id":172,"capacity":2},{"id":173,"capacity":2},{"id":174,"capacity":2},{"id":175,"capacity":2},{"id":176,"capacity":2},{"id":177,"capacity":2},{"id":178,"capacity":2},{"id":179,"capacity":2},{"id":180,"capacity":2},{"id":181,"capacity":2},{"id":182,"capacity":2},{"id":183,"capacity":2},{"id":184,"capacity":2},{"id":185,"capacity":2},{"id":186,"capacity":2},{"id":187,"capacity":2},{"id":188,"capacity":2},{"id":189,"capacity":2},{"id":190,"capacity":2}],"metadata":{"netzgrafikColors":[],"trainrunCategories":[{"id":0,"name":"International","order":0,"colorRef":"EC","shortName":"EC","fachCategory":"HaltezeitIPV","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":1,"name":"InterCity","order":1,"colorRef":"IC","shortName":"IC","fachCategory":"HaltezeitA","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":2,"name":"InterRegio","order":2,"colorRef":"IR","shortName":"IR","fachCategory":"HaltezeitB","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":3,"name":"RegioExpress","order":3,"colorRef":"RE","shortName":"RE","fachCategory":"HaltezeitC","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":4,"name":"RegioUndSBahnverkehr","order":4,"colorRef":"S","shortName":"S","fachCategory":"HaltezeitD","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":5,"name":"GüterExpress","order":5,"colorRef":"GEX","shortName":"GEX","fachCategory":"HaltezeitUncategorized","sectionHeadway":3,"nodeHeadwayStop":3,"nodeHeadwayNonStop":3,"minimalTurnaroundTime":4},{"id":6,"name":"Güterverkehr","order":6,"colorRef":"G","shortName":"G","fachCategory":"HaltezeitUncategorized","sectionHeadway":3,"nodeHeadwayStop":3,"nodeHeadwayNonStop":3,"minimalTurnaroundTime":4}],"trainrunFrequencies":[{"id":0,"name":"verkehrt viertelstündlich","order":0,"offset":0,"frequency":15,"shortName":"15","linePatternRef":"15"},{"id":1,"name":"verkehrt im 20 Minuten Takt","order":0,"offset":0,"frequency":20,"shortName":"20","linePatternRef":"20"},{"id":2,"name":"verkehrt halbstündlich","order":0,"offset":0,"frequency":30,"shortName":"30","linePatternRef":"30"},{"id":3,"name":"verkehrt stündlich","order":0,"offset":0,"frequency":60,"shortName":"60","linePatternRef":"60"},{"id":4,"name":"verkehrt zweistündlich (gerade)","order":0,"offset":0,"frequency":120,"shortName":"120","linePatternRef":"120"},{"id":5,"name":"verkehrt zweistündlich (ungerade)","order":0,"offset":60,"frequency":120,"shortName":"120+","linePatternRef":"120"}],"trainrunTimeCategories":[{"id":0,"name":"verkehrt uneingeschränkt","order":0,"weekday":[1,2,3,4,5,6,7],"shortName":"7/24","linePatternRef":"7/24","dayTimeInterval":[]},{"id":1,"name":"verkehrt zur Hauptverkehrszeit","order":0,"weekday":[1,2,3,4,5,6,7],"shortName":"HVZ","linePatternRef":"HVZ","dayTimeInterval":[{"to":420,"from":360},{"to":1140,"from":960}]},{"id":2,"name":"verkehrt zeitweise","order":0,"weekday":[],"shortName":"zeitweise","linePatternRef":"ZEITWEISE","dayTimeInterval":[]}]},"freeFloatingTexts":[],"labels":[],"labelGroups":[],"filterData":{"filterSettings":[]}} \ No newline at end of file diff --git a/src/app/sample-netzgrafik/Demo_OL_LZ.json.json b/src/app/sample-netzgrafik/Demo_OL_LZ.json.json new file mode 100644 index 00000000..95ff3d07 --- /dev/null +++ b/src/app/sample-netzgrafik/Demo_OL_LZ.json.json @@ -0,0 +1 @@ +{"nodes":[{"id":0,"betriebspunktName":"BN","fullName":"Bern","positionX":-960,"positionY":32,"ports":[{"id":118,"trainrunSectionId":101,"positionIndex":0,"positionAlignment":3},{"id":137,"trainrunSectionId":110,"positionIndex":1,"positionAlignment":3},{"id":94,"trainrunSectionId":90,"positionIndex":2,"positionAlignment":3},{"id":104,"trainrunSectionId":95,"positionIndex":3,"positionAlignment":3},{"id":86,"trainrunSectionId":86,"positionIndex":4,"positionAlignment":3},{"id":126,"trainrunSectionId":105,"positionIndex":5,"positionAlignment":3},{"id":214,"trainrunSectionId":141,"positionIndex":6,"positionAlignment":3},{"id":143,"trainrunSectionId":113,"positionIndex":7,"positionAlignment":3},{"id":147,"trainrunSectionId":115,"positionIndex":8,"positionAlignment":3},{"id":181,"trainrunSectionId":132,"positionIndex":9,"positionAlignment":3}],"transitions":[],"connections":[],"resourceId":65,"perronkanten":10,"connectionTime":5,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":0,"warnings":null,"labelIds":[41]},{"id":1,"betriebspunktName":"OL","fullName":"Olten","positionX":832,"positionY":32,"ports":[{"id":141,"trainrunSectionId":112,"positionIndex":0,"positionAlignment":0},{"id":108,"trainrunSectionId":97,"positionIndex":1,"positionAlignment":0},{"id":166,"trainrunSectionId":124,"positionIndex":2,"positionAlignment":0},{"id":174,"trainrunSectionId":128,"positionIndex":3,"positionAlignment":0},{"id":167,"trainrunSectionId":125,"positionIndex":0,"positionAlignment":1},{"id":175,"trainrunSectionId":129,"positionIndex":1,"positionAlignment":1},{"id":153,"trainrunSectionId":118,"positionIndex":2,"positionAlignment":1},{"id":161,"trainrunSectionId":122,"positionIndex":3,"positionAlignment":1},{"id":159,"trainrunSectionId":121,"positionIndex":4,"positionAlignment":1},{"id":185,"trainrunSectionId":134,"positionIndex":5,"positionAlignment":1},{"id":121,"trainrunSectionId":102,"positionIndex":0,"positionAlignment":2},{"id":140,"trainrunSectionId":111,"positionIndex":1,"positionAlignment":2},{"id":97,"trainrunSectionId":91,"positionIndex":2,"positionAlignment":2},{"id":107,"trainrunSectionId":96,"positionIndex":3,"positionAlignment":2},{"id":210,"trainrunSectionId":139,"positionIndex":4,"positionAlignment":2},{"id":129,"trainrunSectionId":106,"positionIndex":5,"positionAlignment":2},{"id":146,"trainrunSectionId":136,"positionIndex":6,"positionAlignment":2},{"id":150,"trainrunSectionId":137,"positionIndex":7,"positionAlignment":2},{"id":184,"trainrunSectionId":138,"positionIndex":8,"positionAlignment":2},{"id":122,"trainrunSectionId":103,"positionIndex":0,"positionAlignment":3},{"id":98,"trainrunSectionId":92,"positionIndex":1,"positionAlignment":3},{"id":151,"trainrunSectionId":117,"positionIndex":2,"positionAlignment":3}],"transitions":[{"id":102,"port1Id":97,"port2Id":98,"isNonStopTransit":true},{"id":104,"port1Id":108,"port2Id":107,"isNonStopTransit":false},{"id":109,"port1Id":121,"port2Id":122,"isNonStopTransit":true},{"id":114,"port1Id":141,"port2Id":140,"isNonStopTransit":false},{"id":117,"port1Id":150,"port2Id":151,"isNonStopTransit":false},{"id":121,"port1Id":166,"port2Id":167,"isNonStopTransit":false},{"id":124,"port1Id":174,"port2Id":175,"isNonStopTransit":false},{"id":128,"port1Id":185,"port2Id":184,"isNonStopTransit":true}],"connections":[],"resourceId":66,"perronkanten":10,"connectionTime":5,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[2,3]},{"id":2,"betriebspunktName":"ZUE","fullName":"Zuerich","positionX":2464,"positionY":32,"ports":[{"id":123,"trainrunSectionId":103,"positionIndex":0,"positionAlignment":2},{"id":99,"trainrunSectionId":92,"positionIndex":1,"positionAlignment":2},{"id":152,"trainrunSectionId":117,"positionIndex":2,"positionAlignment":2}],"transitions":[],"connections":[],"resourceId":67,"perronkanten":10,"connectionTime":5,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[42]},{"id":3,"betriebspunktName":"LZ","fullName":"Luzern","positionX":832,"positionY":1440,"ports":[{"id":93,"trainrunSectionId":89,"positionIndex":0,"positionAlignment":0},{"id":172,"trainrunSectionId":127,"positionIndex":1,"positionAlignment":0},{"id":180,"trainrunSectionId":131,"positionIndex":2,"positionAlignment":0},{"id":158,"trainrunSectionId":120,"positionIndex":3,"positionAlignment":0}],"transitions":[],"connections":[],"resourceId":68,"perronkanten":10,"connectionTime":5,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[40]},{"id":4,"betriebspunktName":"ZF","fullName":"Zofingen","positionX":832,"positionY":576,"ports":[{"id":168,"trainrunSectionId":125,"positionIndex":0,"positionAlignment":0},{"id":176,"trainrunSectionId":129,"positionIndex":1,"positionAlignment":0},{"id":154,"trainrunSectionId":118,"positionIndex":2,"positionAlignment":0},{"id":162,"trainrunSectionId":122,"positionIndex":3,"positionAlignment":0},{"id":160,"trainrunSectionId":121,"positionIndex":4,"positionAlignment":0},{"id":186,"trainrunSectionId":134,"positionIndex":5,"positionAlignment":0},{"id":90,"trainrunSectionId":88,"positionIndex":0,"positionAlignment":1},{"id":169,"trainrunSectionId":126,"positionIndex":1,"positionAlignment":1},{"id":177,"trainrunSectionId":130,"positionIndex":2,"positionAlignment":1},{"id":155,"trainrunSectionId":119,"positionIndex":3,"positionAlignment":1},{"id":163,"trainrunSectionId":123,"positionIndex":4,"positionAlignment":1},{"id":189,"trainrunSectionId":135,"positionIndex":5,"positionAlignment":1},{"id":89,"trainrunSectionId":87,"positionIndex":0,"positionAlignment":2}],"transitions":[{"id":99,"port1Id":90,"port2Id":89,"isNonStopTransit":false},{"id":118,"port1Id":154,"port2Id":155,"isNonStopTransit":false},{"id":120,"port1Id":162,"port2Id":163,"isNonStopTransit":false},{"id":122,"port1Id":168,"port2Id":169,"isNonStopTransit":true},{"id":125,"port1Id":176,"port2Id":177,"isNonStopTransit":false},{"id":130,"port1Id":186,"port2Id":189,"isNonStopTransit":true}],"connections":[{"id":3,"port1Id":89,"port2Id":160},{"id":4,"port1Id":163,"port2Id":89},{"id":5,"port1Id":162,"port2Id":90}],"resourceId":69,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[2,3]},{"id":6,"betriebspunktName":"SS","fullName":"Sursee","positionX":832,"positionY":1024,"ports":[{"id":91,"trainrunSectionId":88,"positionIndex":0,"positionAlignment":0},{"id":170,"trainrunSectionId":126,"positionIndex":1,"positionAlignment":0},{"id":178,"trainrunSectionId":130,"positionIndex":2,"positionAlignment":0},{"id":156,"trainrunSectionId":119,"positionIndex":3,"positionAlignment":0},{"id":164,"trainrunSectionId":123,"positionIndex":4,"positionAlignment":0},{"id":190,"trainrunSectionId":135,"positionIndex":5,"positionAlignment":0},{"id":92,"trainrunSectionId":89,"positionIndex":0,"positionAlignment":1},{"id":171,"trainrunSectionId":127,"positionIndex":1,"positionAlignment":1},{"id":179,"trainrunSectionId":131,"positionIndex":2,"positionAlignment":1},{"id":157,"trainrunSectionId":120,"positionIndex":3,"positionAlignment":1}],"transitions":[{"id":100,"port1Id":91,"port2Id":92,"isNonStopTransit":false},{"id":119,"port1Id":156,"port2Id":157,"isNonStopTransit":false},{"id":123,"port1Id":170,"port2Id":171,"isNonStopTransit":true},{"id":126,"port1Id":178,"port2Id":179,"isNonStopTransit":false}],"connections":[],"resourceId":71,"perronkanten":5,"connectionTime":6,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[40]},{"id":7,"betriebspunktName":"RTR","fullName":"Rothrist","positionX":256,"positionY":32,"ports":[{"id":119,"trainrunSectionId":101,"positionIndex":0,"positionAlignment":2},{"id":138,"trainrunSectionId":110,"positionIndex":1,"positionAlignment":2},{"id":95,"trainrunSectionId":90,"positionIndex":2,"positionAlignment":2},{"id":105,"trainrunSectionId":95,"positionIndex":3,"positionAlignment":2},{"id":87,"trainrunSectionId":86,"positionIndex":4,"positionAlignment":2},{"id":127,"trainrunSectionId":105,"positionIndex":5,"positionAlignment":2},{"id":211,"trainrunSectionId":140,"positionIndex":6,"positionAlignment":2},{"id":203,"trainrunSectionId":114,"positionIndex":7,"positionAlignment":2},{"id":205,"trainrunSectionId":116,"positionIndex":8,"positionAlignment":2},{"id":207,"trainrunSectionId":133,"positionIndex":9,"positionAlignment":2},{"id":120,"trainrunSectionId":102,"positionIndex":0,"positionAlignment":3},{"id":139,"trainrunSectionId":111,"positionIndex":1,"positionAlignment":3},{"id":96,"trainrunSectionId":91,"positionIndex":2,"positionAlignment":3},{"id":106,"trainrunSectionId":96,"positionIndex":3,"positionAlignment":3},{"id":209,"trainrunSectionId":139,"positionIndex":4,"positionAlignment":3},{"id":128,"trainrunSectionId":106,"positionIndex":5,"positionAlignment":3},{"id":204,"trainrunSectionId":136,"positionIndex":6,"positionAlignment":3},{"id":206,"trainrunSectionId":137,"positionIndex":7,"positionAlignment":3},{"id":208,"trainrunSectionId":138,"positionIndex":8,"positionAlignment":3},{"id":88,"trainrunSectionId":87,"positionIndex":9,"positionAlignment":3}],"transitions":[{"id":98,"port1Id":87,"port2Id":88,"isNonStopTransit":true},{"id":101,"port1Id":95,"port2Id":96,"isNonStopTransit":true},{"id":103,"port1Id":105,"port2Id":106,"isNonStopTransit":true},{"id":108,"port1Id":119,"port2Id":120,"isNonStopTransit":true},{"id":110,"port1Id":127,"port2Id":128,"isNonStopTransit":true},{"id":113,"port1Id":138,"port2Id":139,"isNonStopTransit":true},{"id":137,"port1Id":203,"port2Id":204,"isNonStopTransit":true},{"id":138,"port1Id":205,"port2Id":206,"isNonStopTransit":true},{"id":139,"port1Id":207,"port2Id":208,"isNonStopTransit":true},{"id":140,"port1Id":211,"port2Id":209,"isNonStopTransit":true}],"connections":[],"resourceId":72,"perronkanten":5,"connectionTime":5,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[2]},{"id":8,"betriebspunktName":"LTH","fullName":"Langenthal","positionX":-320,"positionY":224,"ports":[{"id":213,"trainrunSectionId":141,"positionIndex":0,"positionAlignment":2},{"id":144,"trainrunSectionId":113,"positionIndex":1,"positionAlignment":2},{"id":148,"trainrunSectionId":115,"positionIndex":2,"positionAlignment":2},{"id":201,"trainrunSectionId":132,"positionIndex":3,"positionAlignment":2},{"id":212,"trainrunSectionId":140,"positionIndex":0,"positionAlignment":3},{"id":145,"trainrunSectionId":114,"positionIndex":1,"positionAlignment":3},{"id":149,"trainrunSectionId":116,"positionIndex":2,"positionAlignment":3},{"id":202,"trainrunSectionId":133,"positionIndex":3,"positionAlignment":3}],"transitions":[{"id":115,"port1Id":144,"port2Id":145,"isNonStopTransit":false},{"id":116,"port1Id":148,"port2Id":149,"isNonStopTransit":false},{"id":136,"port1Id":201,"port2Id":202,"isNonStopTransit":false},{"id":141,"port1Id":213,"port2Id":212,"isNonStopTransit":false}],"connections":[],"resourceId":73,"perronkanten":5,"connectionTime":5,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[1]},{"id":106,"betriebspunktName":"BS","fullName":"Basel","positionX":832,"positionY":-352,"ports":[{"id":142,"trainrunSectionId":112,"positionIndex":0,"positionAlignment":1},{"id":109,"trainrunSectionId":97,"positionIndex":1,"positionAlignment":1},{"id":165,"trainrunSectionId":124,"positionIndex":2,"positionAlignment":1},{"id":173,"trainrunSectionId":128,"positionIndex":3,"positionAlignment":1}],"transitions":[],"connections":[],"resourceId":76,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[2]}],"trainrunSections":[{"id":86,"sourceNodeId":0,"sourcePortId":86,"targetNodeId":7,"targetPortId":87,"travelTime":{"lock":true,"time":23,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":0,"warning":null,"consecutiveTime":0},"sourceArrival":{"lock":false,"time":0,"warning":null,"consecutiveTime":180},"targetDeparture":{"lock":false,"time":37,"warning":null,"consecutiveTime":157},"targetArrival":{"lock":false,"time":23,"warning":null,"consecutiveTime":23},"numberOfStops":0,"trainrunId":11,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-862,"y":176},{"x":-798,"y":176},{"x":190,"y":176},{"x":254,"y":176}],"textPositions":{"0":{"x":-844,"y":188},"1":{"x":-816,"y":164},"2":{"x":236,"y":164},"3":{"x":208,"y":188},"4":{"x":-304,"y":164},"5":{"x":-304,"y":164},"6":{"x":-304,"y":188}}},"warnings":null},{"id":87,"sourceNodeId":7,"sourcePortId":88,"targetNodeId":4,"targetPortId":89,"travelTime":{"lock":true,"time":5,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":23,"warning":null,"consecutiveTime":23},"sourceArrival":{"lock":false,"time":37,"warning":null,"consecutiveTime":157},"targetDeparture":{"lock":false,"time":32,"warning":null,"consecutiveTime":152},"targetArrival":{"lock":false,"time":28,"warning":null,"consecutiveTime":28},"numberOfStops":0,"trainrunId":11,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":354,"y":336},{"x":418,"y":336},{"x":766,"y":592},{"x":830,"y":592}],"textPositions":{"0":{"x":372,"y":348},"1":{"x":400,"y":324},"2":{"x":812,"y":580},"3":{"x":784,"y":604},"4":{"x":592,"y":452},"5":{"x":592,"y":452},"6":{"x":592,"y":476}}},"warnings":null},{"id":88,"sourceNodeId":4,"sourcePortId":90,"targetNodeId":6,"targetPortId":91,"travelTime":{"lock":true,"time":13,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":29,"warning":null,"consecutiveTime":29},"sourceArrival":{"lock":false,"time":31,"warning":null,"consecutiveTime":151},"targetDeparture":{"lock":false,"time":18,"warning":null,"consecutiveTime":138},"targetArrival":{"lock":false,"time":42,"warning":null,"consecutiveTime":42},"numberOfStops":0,"trainrunId":11,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":848,"y":642},{"x":848,"y":706},{"x":848,"y":958},{"x":848,"y":1022}],"textPositions":{"0":{"x":836,"y":660},"1":{"x":860,"y":688},"2":{"x":860,"y":1004},"3":{"x":836,"y":976},"4":{"x":836,"y":832},"5":{"x":836,"y":832},"6":{"x":860,"y":832}}},"warnings":null},{"id":89,"sourceNodeId":6,"sourcePortId":92,"targetNodeId":3,"targetPortId":93,"travelTime":{"lock":true,"time":18,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":43,"warning":null,"consecutiveTime":43},"sourceArrival":{"lock":false,"time":17,"warning":null,"consecutiveTime":137},"targetDeparture":{"lock":false,"time":59,"warning":null,"consecutiveTime":119},"targetArrival":{"lock":false,"time":1,"warning":null,"consecutiveTime":61},"numberOfStops":0,"trainrunId":11,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":848,"y":1090},{"x":848,"y":1154},{"x":848,"y":1374},{"x":848,"y":1438}],"textPositions":{"0":{"x":836,"y":1108},"1":{"x":860,"y":1136},"2":{"x":860,"y":1420},"3":{"x":836,"y":1392},"4":{"x":836,"y":1264},"5":{"x":836,"y":1264},"6":{"x":860,"y":1264}}},"warnings":null},{"id":90,"sourceNodeId":0,"sourcePortId":94,"targetNodeId":7,"targetPortId":95,"travelTime":{"lock":true,"time":23,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":31,"warning":null,"consecutiveTime":31},"sourceArrival":{"lock":false,"time":29,"warning":null,"consecutiveTime":149},"targetDeparture":{"lock":false,"time":6,"warning":null,"consecutiveTime":126},"targetArrival":{"lock":false,"time":54,"warning":null,"consecutiveTime":54},"numberOfStops":0,"trainrunId":12,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-862,"y":112},{"x":-798,"y":112},{"x":190,"y":112},{"x":254,"y":112}],"textPositions":{"0":{"x":-844,"y":124},"1":{"x":-816,"y":100},"2":{"x":236,"y":100},"3":{"x":208,"y":124},"4":{"x":-304,"y":100},"5":{"x":-304,"y":100},"6":{"x":-304,"y":124}}},"warnings":null},{"id":91,"sourceNodeId":7,"sourcePortId":96,"targetNodeId":1,"targetPortId":97,"travelTime":{"lock":true,"time":5,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":54,"warning":null,"consecutiveTime":54},"sourceArrival":{"lock":false,"time":6,"warning":null,"consecutiveTime":126},"targetDeparture":{"lock":false,"time":1,"warning":null,"consecutiveTime":121},"targetArrival":{"lock":false,"time":59,"warning":null,"consecutiveTime":59},"numberOfStops":0,"trainrunId":12,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":354,"y":112},{"x":418,"y":112},{"x":766,"y":112},{"x":830,"y":112}],"textPositions":{"0":{"x":372,"y":124},"1":{"x":400,"y":100},"2":{"x":812,"y":100},"3":{"x":784,"y":124},"4":{"x":592,"y":100},"5":{"x":592,"y":100},"6":{"x":592,"y":124}}},"warnings":null},{"id":92,"sourceNodeId":1,"sourcePortId":98,"targetNodeId":2,"targetPortId":99,"travelTime":{"lock":true,"time":29,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":59,"warning":null,"consecutiveTime":59},"sourceArrival":{"lock":false,"time":1,"warning":null,"consecutiveTime":121},"targetDeparture":{"lock":false,"time":32,"warning":null,"consecutiveTime":92},"targetArrival":{"lock":false,"time":28,"warning":null,"consecutiveTime":88},"numberOfStops":0,"trainrunId":12,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1026,"y":80},{"x":1090,"y":80},{"x":2398,"y":80},{"x":2462,"y":80}],"textPositions":{"0":{"x":1044,"y":92},"1":{"x":1072,"y":68},"2":{"x":2444,"y":68},"3":{"x":2416,"y":92},"4":{"x":1744,"y":68},"5":{"x":1744,"y":68},"6":{"x":1744,"y":92}}},"warnings":null},{"id":95,"sourceNodeId":0,"sourcePortId":104,"targetNodeId":7,"targetPortId":105,"travelTime":{"lock":true,"time":23,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":4,"warning":null,"consecutiveTime":4},"sourceArrival":{"lock":false,"time":56,"warning":null,"consecutiveTime":176},"targetDeparture":{"lock":false,"time":33,"warning":null,"consecutiveTime":153},"targetArrival":{"lock":false,"time":27,"warning":null,"consecutiveTime":27},"numberOfStops":0,"trainrunId":14,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-862,"y":144},{"x":-798,"y":144},{"x":190,"y":144},{"x":254,"y":144}],"textPositions":{"0":{"x":-844,"y":156},"1":{"x":-816,"y":132},"2":{"x":236,"y":132},"3":{"x":208,"y":156},"4":{"x":-304,"y":132},"5":{"x":-304,"y":132},"6":{"x":-304,"y":156}}},"warnings":null},{"id":96,"sourceNodeId":7,"sourcePortId":106,"targetNodeId":1,"targetPortId":107,"travelTime":{"lock":true,"time":5,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":27,"warning":null,"consecutiveTime":27},"sourceArrival":{"lock":false,"time":33,"warning":null,"consecutiveTime":153},"targetDeparture":{"lock":false,"time":28,"warning":null,"consecutiveTime":148},"targetArrival":{"lock":false,"time":32,"warning":null,"consecutiveTime":32},"numberOfStops":0,"trainrunId":14,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":354,"y":144},{"x":418,"y":144},{"x":766,"y":144},{"x":830,"y":144}],"textPositions":{"0":{"x":372,"y":156},"1":{"x":400,"y":132},"2":{"x":812,"y":132},"3":{"x":784,"y":156},"4":{"x":592,"y":132},"5":{"x":592,"y":132},"6":{"x":592,"y":156}}},"warnings":null},{"id":97,"sourceNodeId":1,"sourcePortId":108,"targetNodeId":106,"targetPortId":109,"travelTime":{"lock":true,"time":27,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":34,"warning":null,"consecutiveTime":34},"sourceArrival":{"lock":false,"time":26,"warning":null,"consecutiveTime":146},"targetDeparture":{"lock":false,"time":59,"warning":null,"consecutiveTime":119},"targetArrival":{"lock":false,"time":1,"warning":null,"consecutiveTime":61},"numberOfStops":0,"trainrunId":14,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":880,"y":30},{"x":880,"y":-34},{"x":880,"y":-222},{"x":880,"y":-286}],"textPositions":{"0":{"x":892,"y":12},"1":{"x":868,"y":-16},"2":{"x":868,"y":-268},"3":{"x":892,"y":-240},"4":{"x":868,"y":-128},"5":{"x":868,"y":-128},"6":{"x":892,"y":-128}}},"warnings":null},{"id":101,"sourceNodeId":0,"sourcePortId":118,"targetNodeId":7,"targetPortId":119,"travelTime":{"lock":true,"time":23,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":2,"warning":null,"consecutiveTime":2},"sourceArrival":{"lock":false,"time":58,"warning":null,"consecutiveTime":58},"targetDeparture":{"lock":false,"time":35,"warning":null,"consecutiveTime":35},"targetArrival":{"lock":false,"time":25,"warning":null,"consecutiveTime":25},"numberOfStops":0,"trainrunId":16,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-862,"y":48},{"x":-798,"y":48},{"x":190,"y":48},{"x":254,"y":48}],"textPositions":{"0":{"x":-844,"y":60},"1":{"x":-816,"y":36},"2":{"x":236,"y":36},"3":{"x":208,"y":60},"4":{"x":-304,"y":36},"5":{"x":-304,"y":36},"6":{"x":-304,"y":60}}},"warnings":null},{"id":102,"sourceNodeId":7,"sourcePortId":120,"targetNodeId":1,"targetPortId":121,"travelTime":{"lock":true,"time":5,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":25,"warning":null,"consecutiveTime":25},"sourceArrival":{"lock":false,"time":35,"warning":null,"consecutiveTime":35},"targetDeparture":{"lock":false,"time":30,"warning":null,"consecutiveTime":30},"targetArrival":{"lock":false,"time":30,"warning":null,"consecutiveTime":30},"numberOfStops":0,"trainrunId":16,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":354,"y":48},{"x":418,"y":48},{"x":766,"y":48},{"x":830,"y":48}],"textPositions":{"0":{"x":372,"y":60},"1":{"x":400,"y":36},"2":{"x":812,"y":36},"3":{"x":784,"y":60},"4":{"x":592,"y":36},"5":{"x":592,"y":36},"6":{"x":592,"y":60}}},"warnings":null},{"id":103,"sourceNodeId":1,"sourcePortId":122,"targetNodeId":2,"targetPortId":123,"travelTime":{"lock":true,"time":28,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":30,"warning":null,"consecutiveTime":30},"sourceArrival":{"lock":false,"time":30,"warning":null,"consecutiveTime":30},"targetDeparture":{"lock":false,"time":2,"warning":null,"consecutiveTime":2},"targetArrival":{"lock":false,"time":58,"warning":null,"consecutiveTime":58},"numberOfStops":0,"trainrunId":16,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1026,"y":48},{"x":1090,"y":48},{"x":2398,"y":48},{"x":2462,"y":48}],"textPositions":{"0":{"x":1044,"y":60},"1":{"x":1072,"y":36},"2":{"x":2444,"y":36},"3":{"x":2416,"y":60},"4":{"x":1744,"y":36},"5":{"x":1744,"y":36},"6":{"x":1744,"y":60}}},"warnings":null},{"id":105,"sourceNodeId":0,"sourcePortId":126,"targetNodeId":7,"targetPortId":127,"travelTime":{"lock":true,"time":23,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":33,"warning":null,"consecutiveTime":33},"sourceArrival":{"lock":false,"time":27,"warning":null,"consecutiveTime":147},"targetDeparture":{"lock":false,"time":4,"warning":null,"consecutiveTime":124},"targetArrival":{"lock":false,"time":56,"warning":null,"consecutiveTime":56},"numberOfStops":0,"trainrunId":18,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-862,"y":208},{"x":-798,"y":208},{"x":190,"y":208},{"x":254,"y":208}],"textPositions":{"0":{"x":-844,"y":220},"1":{"x":-816,"y":196},"2":{"x":236,"y":196},"3":{"x":208,"y":220},"4":{"x":-304,"y":196},"5":{"x":-304,"y":196},"6":{"x":-304,"y":220}}},"warnings":null},{"id":106,"sourceNodeId":7,"sourcePortId":128,"targetNodeId":1,"targetPortId":129,"travelTime":{"lock":true,"time":5,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":56,"warning":null,"consecutiveTime":56},"sourceArrival":{"lock":false,"time":4,"warning":null,"consecutiveTime":124},"targetDeparture":{"lock":false,"time":59,"warning":null,"consecutiveTime":119},"targetArrival":{"lock":false,"time":1,"warning":null,"consecutiveTime":61},"numberOfStops":0,"trainrunId":18,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":354,"y":208},{"x":418,"y":208},{"x":766,"y":208},{"x":830,"y":208}],"textPositions":{"0":{"x":372,"y":220},"1":{"x":400,"y":196},"2":{"x":812,"y":196},"3":{"x":784,"y":220},"4":{"x":592,"y":196},"5":{"x":592,"y":196},"6":{"x":592,"y":220}}},"warnings":null},{"id":110,"sourceNodeId":0,"sourcePortId":137,"targetNodeId":7,"targetPortId":138,"travelTime":{"lock":true,"time":22,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":36,"warning":null,"consecutiveTime":36},"sourceArrival":{"lock":false,"time":24,"warning":null,"consecutiveTime":144},"targetDeparture":{"lock":false,"time":2,"warning":null,"consecutiveTime":122},"targetArrival":{"lock":false,"time":58,"warning":null,"consecutiveTime":58},"numberOfStops":0,"trainrunId":20,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-862,"y":80},{"x":-798,"y":80},{"x":190,"y":80},{"x":254,"y":80}],"textPositions":{"0":{"x":-844,"y":92},"1":{"x":-816,"y":68},"2":{"x":236,"y":68},"3":{"x":208,"y":92},"4":{"x":-304,"y":68},"5":{"x":-304,"y":68},"6":{"x":-304,"y":92}}},"warnings":null},{"id":111,"sourceNodeId":7,"sourcePortId":139,"targetNodeId":1,"targetPortId":140,"travelTime":{"lock":false,"time":5,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":58,"warning":null,"consecutiveTime":58},"sourceArrival":{"lock":false,"time":2,"warning":null,"consecutiveTime":122},"targetDeparture":{"lock":false,"time":57,"warning":null,"consecutiveTime":117},"targetArrival":{"lock":false,"time":3,"warning":null,"consecutiveTime":63},"numberOfStops":0,"trainrunId":20,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":354,"y":80},{"x":418,"y":80},{"x":766,"y":80},{"x":830,"y":80}],"textPositions":{"0":{"x":372,"y":92},"1":{"x":400,"y":68},"2":{"x":812,"y":68},"3":{"x":784,"y":92},"4":{"x":592,"y":68},"5":{"x":592,"y":68},"6":{"x":592,"y":92}}},"warnings":null},{"id":112,"sourceNodeId":1,"sourcePortId":141,"targetNodeId":106,"targetPortId":142,"travelTime":{"lock":true,"time":27,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":5,"warning":null,"consecutiveTime":65},"sourceArrival":{"lock":false,"time":55,"warning":null,"consecutiveTime":115},"targetDeparture":{"lock":true,"time":28,"warning":null,"consecutiveTime":88},"targetArrival":{"lock":true,"time":32,"warning":null,"consecutiveTime":92},"numberOfStops":0,"trainrunId":20,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":848,"y":30},{"x":848,"y":-34},{"x":848,"y":-222},{"x":848,"y":-286}],"textPositions":{"0":{"x":860,"y":12},"1":{"x":836,"y":-16},"2":{"x":836,"y":-268},"3":{"x":860,"y":-240},"4":{"x":836,"y":-128},"5":{"x":836,"y":-128},"6":{"x":860,"y":-128}}},"warnings":null},{"id":113,"sourceNodeId":0,"sourcePortId":143,"targetNodeId":8,"targetPortId":144,"travelTime":{"lock":true,"time":33,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":7,"warning":null,"consecutiveTime":7},"sourceArrival":{"lock":false,"time":53,"warning":null,"consecutiveTime":53},"targetDeparture":{"lock":false,"time":20,"warning":null,"consecutiveTime":20},"targetArrival":{"lock":false,"time":40,"warning":null,"consecutiveTime":40},"numberOfStops":0,"trainrunId":21,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-862,"y":272},{"x":-798,"y":272},{"x":-386,"y":272},{"x":-322,"y":272}],"textPositions":{"0":{"x":-844,"y":284},"1":{"x":-816,"y":260},"2":{"x":-340,"y":260},"3":{"x":-368,"y":284},"4":{"x":-592,"y":260},"5":{"x":-592,"y":260},"6":{"x":-592,"y":284}}},"warnings":null},{"id":114,"sourceNodeId":8,"sourcePortId":145,"targetNodeId":7,"targetPortId":203,"travelTime":{"lock":true,"time":4,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":42,"warning":null,"consecutiveTime":42},"sourceArrival":{"lock":false,"time":18,"warning":null,"consecutiveTime":18},"targetDeparture":{"lock":false,"time":14,"warning":null,"consecutiveTime":14},"targetArrival":{"lock":false,"time":46,"warning":null,"consecutiveTime":46},"numberOfStops":0,"trainrunId":21,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-222,"y":272},{"x":-158,"y":272},{"x":190,"y":272},{"x":254,"y":272}],"textPositions":{"0":{"x":-204,"y":284},"1":{"x":-176,"y":260},"2":{"x":236,"y":260},"3":{"x":208,"y":284},"4":{"x":16,"y":260},"5":{"x":16,"y":260},"6":{"x":16,"y":284}}},"warnings":null},{"id":115,"sourceNodeId":0,"sourcePortId":147,"targetNodeId":8,"targetPortId":148,"travelTime":{"lock":true,"time":32,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":38,"warning":null,"consecutiveTime":38},"sourceArrival":{"lock":false,"time":22,"warning":null,"consecutiveTime":262},"targetDeparture":{"lock":false,"time":50,"warning":null,"consecutiveTime":230},"targetArrival":{"lock":false,"time":10,"warning":null,"consecutiveTime":70},"numberOfStops":0,"trainrunId":22,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-862,"y":304},{"x":-798,"y":304},{"x":-386,"y":304},{"x":-322,"y":304}],"textPositions":{"0":{"x":-844,"y":316},"1":{"x":-816,"y":292},"2":{"x":-340,"y":292},"3":{"x":-368,"y":316},"4":{"x":-592,"y":292},"5":{"x":-592,"y":292},"6":{"x":-592,"y":316}}},"warnings":null},{"id":116,"sourceNodeId":8,"sourcePortId":149,"targetNodeId":7,"targetPortId":205,"travelTime":{"lock":true,"time":5,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":12,"warning":null,"consecutiveTime":72},"sourceArrival":{"lock":false,"time":48,"warning":null,"consecutiveTime":228},"targetDeparture":{"lock":false,"time":43,"warning":null,"consecutiveTime":223},"targetArrival":{"lock":false,"time":17,"warning":null,"consecutiveTime":77},"numberOfStops":0,"trainrunId":22,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-222,"y":304},{"x":-158,"y":304},{"x":190,"y":304},{"x":254,"y":304}],"textPositions":{"0":{"x":-204,"y":316},"1":{"x":-176,"y":292},"2":{"x":236,"y":292},"3":{"x":208,"y":316},"4":{"x":16,"y":292},"5":{"x":16,"y":292},"6":{"x":16,"y":316}}},"warnings":null},{"id":117,"sourceNodeId":1,"sourcePortId":151,"targetNodeId":2,"targetPortId":152,"travelTime":{"lock":true,"time":36,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":24,"warning":null,"consecutiveTime":84},"sourceArrival":{"lock":false,"time":36,"warning":null,"consecutiveTime":216},"targetDeparture":{"lock":false,"time":0,"warning":null,"consecutiveTime":180},"targetArrival":{"lock":false,"time":0,"warning":null,"consecutiveTime":120},"numberOfStops":0,"trainrunId":22,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1026,"y":112},{"x":1090,"y":112},{"x":2398,"y":112},{"x":2462,"y":112}],"textPositions":{"0":{"x":1044,"y":124},"1":{"x":1072,"y":100},"2":{"x":2444,"y":100},"3":{"x":2416,"y":124},"4":{"x":1744,"y":100},"5":{"x":1744,"y":100},"6":{"x":1744,"y":124}}},"warnings":null},{"id":118,"sourceNodeId":1,"sourcePortId":153,"targetNodeId":4,"targetPortId":154,"travelTime":{"lock":true,"time":6,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":6,"warning":null,"consecutiveTime":6},"sourceArrival":{"lock":false,"time":54,"warning":null,"consecutiveTime":54},"targetDeparture":{"lock":false,"time":48,"warning":null,"consecutiveTime":48},"targetArrival":{"lock":false,"time":12,"warning":null,"consecutiveTime":12},"numberOfStops":0,"trainrunId":23,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":912,"y":350},{"x":912,"y":414},{"x":912,"y":510},{"x":912,"y":574}],"textPositions":{"0":{"x":900,"y":368},"1":{"x":924,"y":396},"2":{"x":924,"y":556},"3":{"x":900,"y":528},"4":{"x":900,"y":462},"5":{"x":900,"y":462},"6":{"x":924,"y":462}}},"warnings":null},{"id":119,"sourceNodeId":4,"sourcePortId":155,"targetNodeId":6,"targetPortId":156,"travelTime":{"lock":true,"time":17,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":13,"warning":null,"consecutiveTime":13},"sourceArrival":{"lock":false,"time":47,"warning":null,"consecutiveTime":47},"targetDeparture":{"lock":false,"time":30,"warning":null,"consecutiveTime":30},"targetArrival":{"lock":false,"time":30,"warning":null,"consecutiveTime":30},"numberOfStops":0,"trainrunId":23,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":944,"y":642},{"x":944,"y":706},{"x":944,"y":958},{"x":944,"y":1022}],"textPositions":{"0":{"x":932,"y":660},"1":{"x":956,"y":688},"2":{"x":956,"y":1004},"3":{"x":932,"y":976},"4":{"x":932,"y":832},"5":{"x":932,"y":832},"6":{"x":956,"y":832}}},"warnings":null},{"id":120,"sourceNodeId":6,"sourcePortId":157,"targetNodeId":3,"targetPortId":158,"travelTime":{"lock":true,"time":24,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":31,"warning":null,"consecutiveTime":31},"sourceArrival":{"lock":false,"time":29,"warning":null,"consecutiveTime":29},"targetDeparture":{"lock":false,"time":5,"warning":null,"consecutiveTime":5},"targetArrival":{"lock":false,"time":55,"warning":null,"consecutiveTime":55},"numberOfStops":0,"trainrunId":23,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":944,"y":1090},{"x":944,"y":1154},{"x":944,"y":1374},{"x":944,"y":1438}],"textPositions":{"0":{"x":932,"y":1108},"1":{"x":956,"y":1136},"2":{"x":956,"y":1420},"3":{"x":932,"y":1392},"4":{"x":932,"y":1264},"5":{"x":932,"y":1264},"6":{"x":956,"y":1264}}},"warnings":null},{"id":121,"sourceNodeId":1,"sourcePortId":159,"targetNodeId":4,"targetPortId":160,"travelTime":{"lock":true,"time":9,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":12,"warning":null,"consecutiveTime":12},"sourceArrival":{"lock":false,"time":48,"warning":null,"consecutiveTime":48},"targetDeparture":{"lock":false,"time":39,"warning":null,"consecutiveTime":39},"targetArrival":{"lock":false,"time":21,"warning":null,"consecutiveTime":21},"numberOfStops":0,"trainrunId":24,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":976,"y":350},{"x":976,"y":414},{"x":976,"y":510},{"x":976,"y":574}],"textPositions":{"0":{"x":964,"y":368},"1":{"x":988,"y":396},"2":{"x":988,"y":556},"3":{"x":964,"y":528},"4":{"x":964,"y":462},"5":{"x":964,"y":462},"6":{"x":988,"y":462}}},"warnings":null},{"id":122,"sourceNodeId":1,"sourcePortId":161,"targetNodeId":4,"targetPortId":162,"travelTime":{"lock":true,"time":8,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":36,"warning":null,"consecutiveTime":36},"sourceArrival":{"lock":false,"time":24,"warning":null,"consecutiveTime":144},"targetDeparture":{"lock":false,"time":16,"warning":null,"consecutiveTime":136},"targetArrival":{"lock":false,"time":44,"warning":null,"consecutiveTime":44},"numberOfStops":0,"trainrunId":25,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":944,"y":350},{"x":944,"y":414},{"x":944,"y":510},{"x":944,"y":574}],"textPositions":{"0":{"x":932,"y":368},"1":{"x":956,"y":396},"2":{"x":956,"y":556},"3":{"x":932,"y":528},"4":{"x":932,"y":462},"5":{"x":932,"y":462},"6":{"x":956,"y":462}}},"warnings":null},{"id":123,"sourceNodeId":4,"sourcePortId":163,"targetNodeId":6,"targetPortId":164,"travelTime":{"lock":true,"time":22,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":45,"warning":null,"consecutiveTime":45},"sourceArrival":{"lock":false,"time":15,"warning":null,"consecutiveTime":135},"targetDeparture":{"lock":false,"time":53,"warning":null,"consecutiveTime":113},"targetArrival":{"lock":false,"time":7,"warning":null,"consecutiveTime":67},"numberOfStops":0,"trainrunId":25,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":976,"y":642},{"x":976,"y":706},{"x":976,"y":958},{"x":976,"y":1022}],"textPositions":{"0":{"x":964,"y":660},"1":{"x":988,"y":688},"2":{"x":988,"y":1004},"3":{"x":964,"y":976},"4":{"x":964,"y":832},"5":{"x":964,"y":832},"6":{"x":988,"y":832}}},"warnings":null},{"id":124,"sourceNodeId":106,"sourcePortId":165,"targetNodeId":1,"targetPortId":166,"travelTime":{"lock":true,"time":25,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":3,"warning":null,"consecutiveTime":3},"sourceArrival":{"lock":false,"time":57,"warning":null,"consecutiveTime":177},"targetDeparture":{"lock":false,"time":32,"warning":null,"consecutiveTime":152},"targetArrival":{"lock":false,"time":28,"warning":null,"consecutiveTime":28},"numberOfStops":0,"trainrunId":26,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":912,"y":-286},{"x":912,"y":-222},{"x":912,"y":-34},{"x":912,"y":30}],"textPositions":{"0":{"x":900,"y":-268},"1":{"x":924,"y":-240},"2":{"x":924,"y":12},"3":{"x":900,"y":-16},"4":{"x":900,"y":-128},"5":{"x":900,"y":-128},"6":{"x":924,"y":-128}}},"warnings":null},{"id":125,"sourceNodeId":1,"sourcePortId":167,"targetNodeId":4,"targetPortId":168,"travelTime":{"lock":true,"time":6,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":30,"warning":null,"consecutiveTime":30},"sourceArrival":{"lock":false,"time":30,"warning":null,"consecutiveTime":150},"targetDeparture":{"lock":false,"time":24,"warning":null,"consecutiveTime":144},"targetArrival":{"lock":false,"time":36,"warning":null,"consecutiveTime":36},"numberOfStops":0,"trainrunId":26,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":848,"y":350},{"x":848,"y":414},{"x":848,"y":510},{"x":848,"y":574}],"textPositions":{"0":{"x":836,"y":368},"1":{"x":860,"y":396},"2":{"x":860,"y":556},"3":{"x":836,"y":528},"4":{"x":836,"y":462},"5":{"x":836,"y":462},"6":{"x":860,"y":462}}},"warnings":null},{"id":126,"sourceNodeId":4,"sourcePortId":169,"targetNodeId":6,"targetPortId":170,"travelTime":{"lock":true,"time":10,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":36,"warning":null,"consecutiveTime":36},"sourceArrival":{"lock":false,"time":24,"warning":null,"consecutiveTime":144},"targetDeparture":{"lock":false,"time":14,"warning":null,"consecutiveTime":134},"targetArrival":{"lock":false,"time":46,"warning":null,"consecutiveTime":46},"numberOfStops":0,"trainrunId":26,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":880,"y":642},{"x":880,"y":706},{"x":880,"y":958},{"x":880,"y":1022}],"textPositions":{"0":{"x":868,"y":660},"1":{"x":892,"y":688},"2":{"x":892,"y":1004},"3":{"x":868,"y":976},"4":{"x":868,"y":832},"5":{"x":868,"y":832},"6":{"x":892,"y":832}}},"warnings":null},{"id":127,"sourceNodeId":6,"sourcePortId":171,"targetNodeId":3,"targetPortId":172,"travelTime":{"lock":true,"time":19,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":46,"warning":null,"consecutiveTime":46},"sourceArrival":{"lock":false,"time":14,"warning":null,"consecutiveTime":134},"targetDeparture":{"lock":false,"time":55,"warning":null,"consecutiveTime":115},"targetArrival":{"lock":false,"time":5,"warning":null,"consecutiveTime":65},"numberOfStops":0,"trainrunId":26,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":880,"y":1090},{"x":880,"y":1154},{"x":880,"y":1374},{"x":880,"y":1438}],"textPositions":{"0":{"x":868,"y":1108},"1":{"x":892,"y":1136},"2":{"x":892,"y":1420},"3":{"x":868,"y":1392},"4":{"x":868,"y":1264},"5":{"x":868,"y":1264},"6":{"x":892,"y":1264}}},"warnings":null},{"id":128,"sourceNodeId":106,"sourcePortId":173,"targetNodeId":1,"targetPortId":174,"travelTime":{"lock":true,"time":32,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":16,"warning":null,"consecutiveTime":16},"sourceArrival":{"lock":false,"time":44,"warning":null,"consecutiveTime":164},"targetDeparture":{"lock":false,"time":12,"warning":null,"consecutiveTime":132},"targetArrival":{"lock":false,"time":48,"warning":null,"consecutiveTime":48},"numberOfStops":0,"trainrunId":27,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":944,"y":-286},{"x":944,"y":-222},{"x":944,"y":-34},{"x":944,"y":30}],"textPositions":{"0":{"x":932,"y":-268},"1":{"x":956,"y":-240},"2":{"x":956,"y":12},"3":{"x":932,"y":-16},"4":{"x":932,"y":-128},"5":{"x":932,"y":-128},"6":{"x":956,"y":-128}}},"warnings":null},{"id":129,"sourceNodeId":1,"sourcePortId":175,"targetNodeId":4,"targetPortId":176,"travelTime":{"lock":true,"time":7,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":49,"warning":null,"consecutiveTime":49},"sourceArrival":{"lock":false,"time":11,"warning":null,"consecutiveTime":131},"targetDeparture":{"lock":false,"time":4,"warning":null,"consecutiveTime":124},"targetArrival":{"lock":false,"time":56,"warning":null,"consecutiveTime":56},"numberOfStops":0,"trainrunId":27,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":880,"y":350},{"x":880,"y":414},{"x":880,"y":510},{"x":880,"y":574}],"textPositions":{"0":{"x":868,"y":368},"1":{"x":892,"y":396},"2":{"x":892,"y":556},"3":{"x":868,"y":528},"4":{"x":868,"y":462},"5":{"x":868,"y":462},"6":{"x":892,"y":462}}},"warnings":null},{"id":130,"sourceNodeId":4,"sourcePortId":177,"targetNodeId":6,"targetPortId":178,"travelTime":{"lock":true,"time":12,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":58,"warning":null,"consecutiveTime":58},"sourceArrival":{"lock":false,"time":2,"warning":null,"consecutiveTime":122},"targetDeparture":{"lock":false,"time":50,"warning":null,"consecutiveTime":110},"targetArrival":{"lock":false,"time":10,"warning":null,"consecutiveTime":70},"numberOfStops":0,"trainrunId":27,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":912,"y":642},{"x":912,"y":706},{"x":912,"y":958},{"x":912,"y":1022}],"textPositions":{"0":{"x":900,"y":660},"1":{"x":924,"y":688},"2":{"x":924,"y":1004},"3":{"x":900,"y":976},"4":{"x":900,"y":832},"5":{"x":900,"y":832},"6":{"x":924,"y":832}}},"warnings":null},{"id":131,"sourceNodeId":6,"sourcePortId":179,"targetNodeId":3,"targetPortId":180,"travelTime":{"lock":true,"time":18,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":12,"warning":null,"consecutiveTime":72},"sourceArrival":{"lock":false,"time":48,"warning":null,"consecutiveTime":108},"targetDeparture":{"lock":false,"time":30,"warning":null,"consecutiveTime":90},"targetArrival":{"lock":false,"time":30,"warning":null,"consecutiveTime":90},"numberOfStops":0,"trainrunId":27,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":912,"y":1090},{"x":912,"y":1154},{"x":912,"y":1374},{"x":912,"y":1438}],"textPositions":{"0":{"x":900,"y":1108},"1":{"x":924,"y":1136},"2":{"x":924,"y":1420},"3":{"x":900,"y":1392},"4":{"x":900,"y":1264},"5":{"x":900,"y":1264},"6":{"x":924,"y":1264}}},"warnings":null},{"id":132,"sourceNodeId":0,"sourcePortId":181,"targetNodeId":8,"targetPortId":201,"travelTime":{"lock":true,"time":44,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":48,"warning":null,"consecutiveTime":48},"sourceArrival":{"lock":false,"time":12,"warning":null,"consecutiveTime":252},"targetDeparture":{"lock":false,"time":28,"warning":null,"consecutiveTime":208},"targetArrival":{"lock":false,"time":32,"warning":null,"consecutiveTime":92},"numberOfStops":0,"trainrunId":28,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-862,"y":336},{"x":-798,"y":336},{"x":-386,"y":336},{"x":-322,"y":336}],"textPositions":{"0":{"x":-844,"y":348},"1":{"x":-816,"y":324},"2":{"x":-340,"y":324},"3":{"x":-368,"y":348},"4":{"x":-592,"y":324},"5":{"x":-592,"y":324},"6":{"x":-592,"y":348}}},"warnings":null},{"id":133,"sourceNodeId":8,"sourcePortId":202,"targetNodeId":7,"targetPortId":207,"travelTime":{"lock":true,"time":6,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":44,"warning":null,"consecutiveTime":104},"sourceArrival":{"lock":false,"time":16,"warning":null,"consecutiveTime":196},"targetDeparture":{"lock":false,"time":10,"warning":null,"consecutiveTime":190},"targetArrival":{"lock":false,"time":50,"warning":null,"consecutiveTime":110},"numberOfStops":0,"trainrunId":28,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-222,"y":336},{"x":-158,"y":336},{"x":190,"y":336},{"x":254,"y":336}],"textPositions":{"0":{"x":-204,"y":348},"1":{"x":-176,"y":324},"2":{"x":236,"y":324},"3":{"x":208,"y":348},"4":{"x":16,"y":324},"5":{"x":16,"y":324},"6":{"x":16,"y":348}}},"warnings":null},{"id":134,"sourceNodeId":1,"sourcePortId":185,"targetNodeId":4,"targetPortId":186,"travelTime":{"lock":true,"time":13,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":55,"warning":null,"consecutiveTime":115},"sourceArrival":{"lock":false,"time":5,"warning":null,"consecutiveTime":185},"targetDeparture":{"lock":false,"time":52,"warning":null,"consecutiveTime":172},"targetArrival":{"lock":false,"time":8,"warning":null,"consecutiveTime":128},"numberOfStops":0,"trainrunId":28,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1008,"y":350},{"x":1008,"y":414},{"x":1008,"y":510},{"x":1008,"y":574}],"textPositions":{"0":{"x":996,"y":368},"1":{"x":1020,"y":396},"2":{"x":1020,"y":556},"3":{"x":996,"y":528},"4":{"x":996,"y":462},"5":{"x":996,"y":462},"6":{"x":1020,"y":462}}},"warnings":null},{"id":135,"sourceNodeId":4,"sourcePortId":189,"targetNodeId":6,"targetPortId":190,"travelTime":{"lock":true,"time":20,"warning":null,"consecutiveTime":10},"sourceDeparture":{"lock":false,"time":8,"warning":null,"consecutiveTime":128},"sourceArrival":{"lock":false,"time":52,"warning":null,"consecutiveTime":172},"targetDeparture":{"lock":false,"time":32,"warning":null,"consecutiveTime":152},"targetArrival":{"lock":false,"time":28,"warning":null,"consecutiveTime":148},"numberOfStops":0,"trainrunId":28,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1008,"y":642},{"x":1008,"y":706},{"x":1008,"y":958},{"x":1008,"y":1022}],"textPositions":{"0":{"x":996,"y":660},"1":{"x":1020,"y":688},"2":{"x":1020,"y":1004},"3":{"x":996,"y":976},"4":{"x":996,"y":832},"5":{"x":996,"y":832},"6":{"x":1020,"y":832}}},"warnings":null},{"id":136,"sourceNodeId":7,"sourcePortId":204,"targetNodeId":1,"targetPortId":146,"travelTime":{"lock":true,"time":4,"warning":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":46,"warning":null,"consecutiveTime":46},"sourceArrival":{"lock":false,"time":14,"warning":null,"consecutiveTime":14},"targetDeparture":{"lock":false,"time":10,"warning":null,"consecutiveTime":10},"targetArrival":{"lock":false,"time":50,"warning":null,"consecutiveTime":50},"numberOfStops":0,"trainrunId":21,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":354,"y":240},{"x":418,"y":240},{"x":766,"y":240},{"x":830,"y":240}],"textPositions":{"0":{"x":372,"y":252},"1":{"x":400,"y":228},"2":{"x":812,"y":228},"3":{"x":784,"y":252},"4":{"x":592,"y":228},"5":{"x":592,"y":228},"6":{"x":592,"y":252}}},"warnings":null},{"id":137,"sourceNodeId":7,"sourcePortId":206,"targetNodeId":1,"targetPortId":150,"travelTime":{"lock":true,"time":5,"warning":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":17,"warning":null,"consecutiveTime":77},"sourceArrival":{"lock":false,"time":43,"warning":null,"consecutiveTime":223},"targetDeparture":{"lock":false,"time":38,"warning":null,"consecutiveTime":218},"targetArrival":{"lock":false,"time":22,"warning":null,"consecutiveTime":82},"numberOfStops":0,"trainrunId":22,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":354,"y":272},{"x":418,"y":272},{"x":766,"y":272},{"x":830,"y":272}],"textPositions":{"0":{"x":372,"y":284},"1":{"x":400,"y":260},"2":{"x":812,"y":260},"3":{"x":784,"y":284},"4":{"x":592,"y":260},"5":{"x":592,"y":260},"6":{"x":592,"y":284}}},"warnings":null},{"id":138,"sourceNodeId":7,"sourcePortId":208,"targetNodeId":1,"targetPortId":184,"travelTime":{"lock":true,"time":5,"warning":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":50,"warning":null,"consecutiveTime":110},"sourceArrival":{"lock":false,"time":10,"warning":null,"consecutiveTime":190},"targetDeparture":{"lock":false,"time":5,"warning":null,"consecutiveTime":185},"targetArrival":{"lock":false,"time":55,"warning":null,"consecutiveTime":115},"numberOfStops":0,"trainrunId":28,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":354,"y":304},{"x":418,"y":304},{"x":766,"y":304},{"x":830,"y":304}],"textPositions":{"0":{"x":372,"y":316},"1":{"x":400,"y":292},"2":{"x":812,"y":292},"3":{"x":784,"y":316},"4":{"x":592,"y":292},"5":{"x":592,"y":292},"6":{"x":592,"y":316}}},"warnings":null},{"id":139,"sourceNodeId":7,"sourcePortId":209,"targetNodeId":1,"targetPortId":210,"travelTime":{"lock":true,"time":1,"warning":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":58,"warning":null,"consecutiveTime":58},"sourceArrival":{"lock":false,"time":2,"warning":null,"consecutiveTime":2},"targetDeparture":{"lock":false,"time":1,"warning":null,"consecutiveTime":1},"targetArrival":{"lock":false,"time":59,"warning":null,"consecutiveTime":59},"numberOfStops":0,"trainrunId":29,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":354,"y":176},{"x":418,"y":176},{"x":766,"y":176},{"x":830,"y":176}],"textPositions":{"0":{"x":372,"y":188},"1":{"x":400,"y":164},"2":{"x":812,"y":164},"3":{"x":784,"y":188},"4":{"x":592,"y":164},"5":{"x":592,"y":164},"6":{"x":592,"y":188}}},"warnings":null},{"id":140,"sourceNodeId":7,"sourcePortId":211,"targetNodeId":8,"targetPortId":212,"travelTime":{"lock":true,"time":1,"warning":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":2,"warning":null,"consecutiveTime":2},"sourceArrival":{"lock":false,"time":58,"warning":null,"consecutiveTime":58},"targetDeparture":{"lock":false,"time":57,"warning":null,"consecutiveTime":57},"targetArrival":{"lock":false,"time":3,"warning":null,"consecutiveTime":3},"numberOfStops":0,"trainrunId":29,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":254,"y":240},{"x":190,"y":240},{"x":-158,"y":240},{"x":-222,"y":240}],"textPositions":{"0":{"x":236,"y":228},"1":{"x":208,"y":252},"2":{"x":-204,"y":252},"3":{"x":-176,"y":228},"4":{"x":16,"y":228},"5":{"x":16,"y":228},"6":{"x":16,"y":252}}},"warnings":null},{"id":141,"sourceNodeId":8,"sourcePortId":213,"targetNodeId":0,"targetPortId":214,"travelTime":{"lock":true,"time":1,"warning":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":5,"warning":null,"consecutiveTime":5},"sourceArrival":{"lock":false,"time":55,"warning":null,"consecutiveTime":55},"targetDeparture":{"lock":false,"time":54,"warning":null,"consecutiveTime":54},"targetArrival":{"lock":false,"time":6,"warning":null,"consecutiveTime":6},"numberOfStops":0,"trainrunId":29,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-322,"y":240},{"x":-386,"y":240},{"x":-798,"y":240},{"x":-862,"y":240}],"textPositions":{"0":{"x":-340,"y":228},"1":{"x":-368,"y":252},"2":{"x":-844,"y":252},"3":{"x":-816,"y":228},"4":{"x":-592,"y":228},"5":{"x":-592,"y":228},"6":{"x":-592,"y":252}}},"warnings":null}],"trainruns":[{"id":11,"name":"15","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[26]},{"id":12,"name":"8","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[31]},{"id":14,"name":"E","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[28]},{"id":16,"name":"1","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[30]},{"id":18,"name":"16","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[27]},{"id":20,"name":"61","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[29]},{"id":21,"name":"17","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[32]},{"id":22,"name":"35","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[33]},{"id":23,"name":"","categoryId":3,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[37]},{"id":24,"name":"29a","categoryId":4,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[38]},{"id":25,"name":"29","categoryId":3,"frequencyId":2,"trainrunTimeCategoryId":0,"labelIds":[39]},{"id":26,"name":"26","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[35]},{"id":27,"name":"27","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[36]},{"id":28,"name":"X","categoryId":5,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[34]},{"id":29,"name":"X","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[]}],"resources":[{"id":65,"capacity":10},{"id":66,"capacity":8},{"id":67,"capacity":15},{"id":68,"capacity":10},{"id":69,"capacity":3},{"id":70,"capacity":2},{"id":71,"capacity":3},{"id":72,"capacity":3},{"id":73,"capacity":3},{"id":74,"capacity":2},{"id":75,"capacity":2},{"id":76,"capacity":9},{"id":77,"capacity":2}],"metadata":{"netzgrafikColors":[],"trainrunCategories":[{"id":0,"name":"International","order":0,"colorRef":"EC","shortName":"EC","fachCategory":"HaltezeitIPV","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":8},{"id":1,"name":"InterCity","order":1,"colorRef":"IC","shortName":"IC","fachCategory":"HaltezeitA","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":8},{"id":2,"name":"InterRegio","order":2,"colorRef":"IR","shortName":"IR","fachCategory":"HaltezeitB","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":8},{"id":3,"name":"RegioExpress","order":3,"colorRef":"RE","shortName":"RE","fachCategory":"HaltezeitC","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":8},{"id":4,"name":"RegioUndSBahnverkehr","order":4,"colorRef":"S","shortName":"S","fachCategory":"HaltezeitD","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":8},{"id":5,"name":"GüterExpress","order":5,"colorRef":"GEX","shortName":"GEX","fachCategory":"HaltezeitUncategorized","sectionHeadway":3,"nodeHeadwayStop":3,"nodeHeadwayNonStop":3,"minimalTurnaroundTime":8},{"id":6,"name":"Güterverkehr","order":6,"colorRef":"G","shortName":"G","fachCategory":"HaltezeitUncategorized","sectionHeadway":3,"nodeHeadwayStop":3,"nodeHeadwayNonStop":3,"minimalTurnaroundTime":8}],"trainrunFrequencies":[{"id":0,"name":"verkehrt viertelstündlich","order":0,"offset":0,"frequency":15,"shortName":"15","linePatternRef":"15"},{"id":1,"name":"verkehrt im 20 Minuten Takt","order":0,"offset":0,"frequency":20,"shortName":"20","linePatternRef":"20"},{"id":2,"name":"verkehrt halbstündlich","order":0,"offset":0,"frequency":30,"shortName":"30","linePatternRef":"30"},{"id":3,"name":"verkehrt stündlich","order":0,"offset":0,"frequency":60,"shortName":"60","linePatternRef":"60"},{"id":4,"name":"verkehrt zweistündlich (gerade)","order":0,"offset":0,"frequency":120,"shortName":"120","linePatternRef":"120"},{"id":5,"name":"verkehrt zweistündlich (ungerade)","order":0,"offset":60,"frequency":120,"shortName":"120+","linePatternRef":"120"}],"trainrunTimeCategories":[{"id":0,"name":"verkehrt uneingeschränkt","order":0,"weekday":[1,2,3,4,5,6,7],"shortName":"7/24","linePatternRef":"7/24","dayTimeInterval":[]},{"id":1,"name":"verkehrt zur Hauptverkehrszeit","order":0,"weekday":[1,2,3,4,5,6,7],"shortName":"HVZ","linePatternRef":"HVZ","dayTimeInterval":[{"to":420,"from":360},{"to":1140,"from":960}]},{"id":2,"name":"verkehrt zeitweise","order":0,"weekday":[],"shortName":"zeitweise","linePatternRef":"ZEITWEISE","dayTimeInterval":[]}]},"freeFloatingTexts":[],"labels":[{"id":1,"label":"BLS","labelGroupId":1,"labelRef":"Node"},{"id":2,"label":"SBB","labelGroupId":1,"labelRef":"Node"},{"id":3,"label":"OL-LZ","labelGroupId":1,"labelRef":"Node"},{"id":26,"label":"IR15","labelGroupId":9,"labelRef":"Trainrun"},{"id":27,"label":"IR16","labelGroupId":9,"labelRef":"Trainrun"},{"id":28,"label":"ICE","labelGroupId":9,"labelRef":"Trainrun"},{"id":29,"label":"IC61","labelGroupId":9,"labelRef":"Trainrun"},{"id":30,"label":"IC1","labelGroupId":9,"labelRef":"Trainrun"},{"id":31,"label":"IC8","labelGroupId":9,"labelRef":"Trainrun"},{"id":32,"label":"IR17","labelGroupId":9,"labelRef":"Trainrun"},{"id":33,"label":"IR35","labelGroupId":9,"labelRef":"Trainrun"},{"id":34,"label":"GEXX","labelGroupId":9,"labelRef":"Trainrun"},{"id":35,"label":"IR26","labelGroupId":9,"labelRef":"Trainrun"},{"id":36,"label":"IR27","labelGroupId":9,"labelRef":"Trainrun"},{"id":37,"label":"RE","labelGroupId":9,"labelRef":"Trainrun"},{"id":38,"label":"S29","labelGroupId":9,"labelRef":"Trainrun"},{"id":39,"label":"S29_OL_SS","labelGroupId":9,"labelRef":"Trainrun"},{"id":40,"label":"LZ","labelGroupId":1,"labelRef":"Node"},{"id":41,"label":"BN","labelGroupId":1,"labelRef":"Node"},{"id":42,"label":"ZUE","labelGroupId":1,"labelRef":"Node"}],"labelGroups":[{"id":1,"name":"Standard","labelRef":"Node"},{"id":9,"name":"Standard","labelRef":"Trainrun"}],"filterData":{"filterSettings":[]}} \ No newline at end of file From 0c8d905eed40cfb6db100c0f1d5473d913a73faa Mon Sep 17 00:00:00 2001 From: Uriel Sautron Date: Thu, 19 Sep 2024 12:20:35 +0200 Subject: [PATCH 098/197] Add label operation - edit STANDALONE.md Signed-off-by: Uriel Sautron --- documentation/STANDALONE.md | 14 +++++++++----- src/app/app.component.ts | 2 ++ src/app/models/operation.model.ts | 14 +++++++++++++- src/app/services/data/label.serivce.ts | 10 +++++++++- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/documentation/STANDALONE.md b/documentation/STANDALONE.md index 89ba2597..a979a8bc 100644 --- a/documentation/STANDALONE.md +++ b/documentation/STANDALONE.md @@ -24,7 +24,7 @@ The emission of these events doesn't impact the general behavior of the applicat ## NGE Operations -The operations related to the NGE framework are used to handle changes to Trainrun and Node entities. These operations ensure that any modifications are properly tracked and emitted, allowing for real-time updates and consistency within the application. +The operations related to the NGE framework are used to handle changes to Trainrun, Node and Label entities. These operations ensure that any modifications are properly tracked and emitted, allowing for real-time updates and consistency within the application. ### Current list of actions available in NGE @@ -63,8 +63,8 @@ The operations related to the NGE framework are used to handle changes to Trainr #### Node - create Node manually => NodeOperation(create) -- copy-paste one or more Nodes (selection + CTRL-C key then CTRL-V key) => n*(NodeOperation(create)) -- duplicate one or more Nodes (selection + CTRL-D key) => n*(NodeOperation(create)) +- copy-paste one or more Nodes (selection + CTRL-C key then CTRL-V key) => n\*(NodeOperation(create)) +- duplicate one or more Nodes (selection + CTRL-D key) => n\*(NodeOperation(create)) - modify Node name (node window, fill in the box then ENTER key / click elsewhere) => NodeOperation(update) / TODO: triggered on change (not great) - modify Node betriebspunktName (node window, fill in the box then ENTER key / click elsewhere) => NodeOperation(update) / TODO: triggered on change (not great) - modify Node connectionTime (node window, fill in the box then ENTER key / click elsewhere) => NodeOperation(update) @@ -80,13 +80,17 @@ The operations related to the NGE framework are used to handle changes to Trainr - modify Node D stoppingTime time (node window, fill in the box then ENTER key / click elsewhere) => none (disabled feature) - modify Node D stoppingTime noStop (node window, tick button) => none (disabled feature) - modify Node position (cross cursor + drag) => NodeOperation(update) -- modify Nodes positions (multi selection, cross cursor + drag) => n*(NodeOperation(update)) +- modify Nodes positions (multi selection, cross cursor + drag) => n\*(NodeOperation(update)) - (if it does not exist, create and) add Node label (node window, fill in the box then ENTER key / click elsewhere) => NodeOperation(update) - delete Node label (node window, delete label button) => NodeOperation(update) - delete Node (selection + DEL key) => NodeOperation(delete) -- delete Nodes (multi selection + DEL key) => n*(NodeOperation(delete)) +- delete Nodes (multi selection + DEL key) => n\*(NodeOperation(delete)) - delete Node (node window, Delete node button) => NodeOperation(delete) +#### Label + +- update Label (edit sidebar, Filterable labels / Trainruns, click on a label to edit it) => LabelOperation(update) + ## Future work The current design can be improved by providing more information in the event payload or making the framework more generic. New ideas and suggestions are welcome. Additionally, we will learn from the practical use of this framework and iterate on its design accordingly. diff --git a/src/app/app.component.ts b/src/app/app.component.ts index b37e3f49..a4806b5e 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -45,6 +45,7 @@ export class AppComponent { private trainrunService: TrainrunService, private trainrunSectionService: TrainrunSectionService, private nodeService: NodeService, + private labelService: LabelService, ) { if (!this.disableBackend) { this.authenticated = authService.initialized; @@ -76,5 +77,6 @@ export class AppComponent { this.trainrunService.operation, this.trainrunSectionService.operation, this.nodeService.operation, + this.labelService.operation, ); } diff --git a/src/app/models/operation.model.ts b/src/app/models/operation.model.ts index b811e4cf..b2120789 100644 --- a/src/app/models/operation.model.ts +++ b/src/app/models/operation.model.ts @@ -1,5 +1,6 @@ import {Node} from "./node.model"; import {Trainrun} from "./trainrun.model"; +import {Label} from "./label.model"; enum OperationType { create = "create", @@ -10,7 +11,8 @@ enum OperationType { enum OperationObjectType { trainrun = "trainrun", node = "node", -}; + label = "label", +} abstract class Operation { readonly type: OperationType; @@ -40,9 +42,19 @@ class NodeOperation extends Operation { } } +class LabelOperation extends Operation { + readonly label: Label; + + constructor(operationType: OperationType, label: Label) { + super(operationType, OperationObjectType.label); + this.label = label; + } +} + export { OperationType, Operation, TrainrunOperation, NodeOperation, + LabelOperation, }; diff --git a/src/app/services/data/label.serivce.ts b/src/app/services/data/label.serivce.ts index 23a20fb1..385d4cdf 100644 --- a/src/app/services/data/label.serivce.ts +++ b/src/app/services/data/label.serivce.ts @@ -1,4 +1,4 @@ -import {Injectable, OnDestroy} from "@angular/core"; +import {Injectable, OnDestroy, EventEmitter} from "@angular/core"; import {BehaviorSubject, Subject} from "rxjs"; import {LogService} from "../../logger/log.service"; import { @@ -7,6 +7,11 @@ import { } from "../../data-structures/business.data.structures"; import {Label} from "../../models/label.model"; import {LabelGroupService} from "./labelgroup.service"; +import { + LabelOperation, + Operation, + OperationType, +} from "src/app/models/operation.model"; @Injectable({ providedIn: "root", @@ -16,6 +21,8 @@ export class LabelService implements OnDestroy { readonly labels = this.labelSubject.asObservable(); private labelStore: {labels: Label[]} = {labels: []}; // store the data in memory + readonly operation = new EventEmitter(); + private destroyed = new Subject(); constructor( @@ -36,6 +43,7 @@ export class LabelService implements OnDestroy { labelObject.setLabel(newLabelValue); } this.labelUpdated(); + this.operation.emit(new LabelOperation(OperationType.update, labelObject)); } doUserDefinedLabelsOrdering(labelIds: number[]) { From 22f4f87074faa9b9a06a7b482ffb9a0d7312303d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serge=20Crois=C3=A9?= Date: Thu, 19 Sep 2024 22:37:20 +0200 Subject: [PATCH 099/197] fix: doc: STANDALONE.md grammar (#292) - Operations can be simply ignored --- documentation/STANDALONE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/STANDALONE.md b/documentation/STANDALONE.md index a979a8bc..3c87167c 100644 --- a/documentation/STANDALONE.md +++ b/documentation/STANDALONE.md @@ -20,7 +20,7 @@ The Operation class is designed to represent various operations performed on dif Emitting events about NGE changes is crucial for ensuring that all parts of the application are aware of modifications. This is especially useful when NGE is integrated into another application, as it allows for seamless updates and synchronization of state across different components. -The emission of these events doesn't impact the general behavior of the application, and if the user doesn't need these events, the Operations can be simply ignore. +The emission of these events doesn't impact the general behavior of the application, and if the user doesn't need these events, the Operations can be simply ignored. ## NGE Operations From ae64d446ca979db5b95601dbd414a3c9d6e6419f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serge=20Crois=C3=A9?= Date: Thu, 19 Sep 2024 22:37:31 +0200 Subject: [PATCH 100/197] fix: doc: Split_Combine_Trainruns.md grammar (#293) - ... must be hold pressed as long as you ... --- documentation/Split_Combine_Trainruns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/Split_Combine_Trainruns.md b/documentation/Split_Combine_Trainruns.md index 03b3aa87..28b8d006 100644 --- a/documentation/Split_Combine_Trainruns.md +++ b/documentation/Split_Combine_Trainruns.md @@ -11,7 +11,7 @@ the trainrun has to have a transition. Press **CTRL key** and click with the mou #### Combine two trainruns To combine two trainruns, you have to select one of the two trains. Then you have to navigate to the node where the trainrun ends (or starts). Now you can draw -the new transition similar to creating a connection - but you have to press **CTRL key** and it must be hold pressed as long you are drawing a new transition. +the new transition similar to creating a connection - but you have to press **CTRL key** and it must be held pressed as long as you are drawing a new transition. Once you finish drawing the new transition, both trains will be combined to one single trainrun. Please have as well a look into [Create Connections](CREATE_CONNECTIONS.md). From 6a402c87322bac3daedadf7bc359c2875f7b31c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serge=20Crois=C3=A9?= Date: Thu, 19 Sep 2024 22:37:42 +0200 Subject: [PATCH 101/197] fix: doc: USERMANUAL.md spelling grammar punctuation (#294) - consists of one or more ... - e.g., ... - For more details ... - allows you to edit ... - propagation - switches ... - vice-versa - Visible eye ... --- documentation/USERMANUAL.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/documentation/USERMANUAL.md b/documentation/USERMANUAL.md index c839e475..d9427dce 100644 --- a/documentation/USERMANUAL.md +++ b/documentation/USERMANUAL.md @@ -88,17 +88,17 @@ For more details and to create your first Netzgrafik have a look into [create a ## Nodes The nodes represent the specific locations, such as stations or stops, where a trainrun can have different actions or events associated with it. These nodes serve as key points in the trainrun's route, determining where it stops, passes through, or starts and ends ([see data model](DATA_MODEL.md)). -For mor details have a look into [create and modifiy nodes](CREATE_NODES.md). +For more details have a look into [create and modifiy nodes](CREATE_NODES.md). ## Trainruns -A trainrun consists out of one ore more trainrun sections. The trainrun section represents a specific segment or portion of a trainrun that connects two nodes. It encapsulates all the relevant information related to that particular section, including temporal details like departure and arrival times. Additionally, it also stores the journey time, which indicates the duration it takes for the train to run to move from one node to another. +A trainrun consists of one or more trainrun sections. The trainrun section represents a specific segment or portion of a trainrun that connects two nodes. It encapsulates all the relevant information related to that particular section, including temporal details like departure and arrival times. Additionally, it also stores the journey time, which indicates the duration it takes for the train to run to move from one node to another. A trainrun has references to behaviour-related abstractions such as -category (e.g. a regional train, an intercity train or a goods train), frequency (e.g. 1/4h, 1/2h or every hourand) time category (e.g. peak times or off-peak times or occasional), which define the behaviour of a trainrun ([see data model](DATA_MODEL.md)). +category (e.g., a regional train, an intercity train or a goods train), frequency (e.g., 1/4h, 1/2h or every hourand) time category (e.g., peak times or off-peak times or occasional), which define the behaviour of a trainrun ([see data model](DATA_MODEL.md)). -For mor details have a look into [create and modifiy trainrun](CREATE_TRAINRUN.md). +For more details have a look into [create and modifiy trainrun](CREATE_TRAINRUN.md). - [Split / Combine two trainruns](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/main/documentation/CREATE_TRAINRUN.md#split--combine-two-trainruns) - [Merge two indepandant Netzgrafik](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/main/documentation/CREATE_TRAINRUN.md#merge-two-indepandant-netzgrafik) @@ -109,7 +109,7 @@ For mor details have a look into [create and modifiy trainrun](CREATE_TRAINRUN.m ![Editing_Connections](./images/Editing_Connections.png) -For mor details have a look into [create and modifiy connections](CREATE_CONNECTIONS.md). +For more details have a look into [create and modifiy connections](CREATE_CONNECTIONS.md). --- @@ -117,7 +117,7 @@ For mor details have a look into [create and modifiy connections](CREATE_CONNECT ## Filters -For mor details have a look into [create and modifiy filters](CREATE_FILTERS.md). +For more details have a look into [create and modifiy filters](CREATE_FILTERS.md). --- @@ -137,7 +137,7 @@ For mor details have a look into [graphic timetable](Graphic_Timetable.md). The Perlenkette allows you to view and edit the entire trainrun from a vertical perspective. It is displayed on the right-hand side. In the upper part of the Perlenkette, the train information is displayed. -It can also be expanded to get more information. It also allows to edit the train name, category or +It can also be expanded to get more information. It also allows you to edit the train name, category or frequency. Between the title and the train route display, there is a sorted list of all the passed nodes. @@ -155,13 +155,13 @@ displaying the train's route as a vertical chain of nodes and trainrunsections. [2024-1-25_DeleteConnections-Perlenkette-Show_Connections.webm](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/assets/2674075/d272fc58-3f31-4427-aacf-cc3c50c03905) ### Change the time locks -The time can be locked so that no propagtion (automated update) will be done. Just click on the lock icon and the lock state switchs: On to off or vice-versa. +The time can be locked so that no propagation (automated update) will be done. Just click on the lock icon and the lock state switches: On to off or vice-versa. ### Toggle: show all locks / or only closed (default) In the Perlenkette view, you can click on the eye icon in the bottom left corner to display all locks. By default, only the locks that are closed are shown. This is visually visible with the disabled eye icon. When you click on the icon then the disable -eye icon switchs to the visible eye icon - or vive-versa. Visble eye means all locks are visible. +eye icon switches to the visible eye icon - or vice-versa. Visible eye means all locks are visible. --- From a401efc1f21cd175f43f1894107518e0cc25e7a3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 19 Sep 2024 22:38:34 +0200 Subject: [PATCH 102/197] chore(main): release netzgrafik-frontend 2.7.15 (#296) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 9 +++++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index d2300db9..99cadb2a 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.7.14" + ".": "2.7.15" } diff --git a/CHANGELOG.md b/CHANGELOG.md index bb3db265..f6213c77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## [2.7.15](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.7.14...netzgrafik-frontend-v2.7.15) (2024-09-19) + + +### Bug Fixes + +* doc: Split_Combine_Trainruns.md grammar ([#293](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/293)) ([ae64d44](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/ae64d446ca979db5b95601dbd414a3c9d6e6419f)) +* doc: STANDALONE.md grammar ([#292](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/292)) ([22f4f87](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/22f4f87074faa9b9a06a7b482ffb9a0d7312303d)) +* doc: USERMANUAL.md spelling grammar punctuation ([#294](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/294)) ([6a402c8](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/6a402c87322bac3daedadf7bc359c2875f7b31c1)) + ## [2.7.14](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.7.13...netzgrafik-frontend-v2.7.14) (2024-09-16) diff --git a/package-lock.json b/package-lock.json index c635b4d8..834ff28d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.7.14", + "version": "2.7.15", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.7.14", + "version": "2.7.15", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index 7dd1236f..5fba289b 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.7.14", + "version": "2.7.15", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From b76ed6ab75283b0da21d80cd211524b10f81977b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 17:41:04 +0200 Subject: [PATCH 103/197] chore(deps-dev): bump rollup from 4.20.0 to 4.22.4 (#298) Bumps [rollup](https://github.com/rollup/rollup) from 4.20.0 to 4.22.4. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.20.0...v4.22.4) --- updated-dependencies: - dependency-name: rollup dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 134 +++++++++++++++++++++++----------------------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/package-lock.json b/package-lock.json index 834ff28d..0c6aaa4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4540,9 +4540,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.20.0.tgz", - "integrity": "sha512-TSpWzflCc4VGAUJZlPpgAJE1+V60MePDQnBd7PPkpuEmOy8i87aL6tinFGKBFKuEDikYpig72QzdT3QPYIi+oA==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", + "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", "cpu": [ "arm" ], @@ -4553,9 +4553,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.20.0.tgz", - "integrity": "sha512-u00Ro/nok7oGzVuh/FMYfNoGqxU5CPWz1mxV85S2w9LxHR8OoMQBuSk+3BKVIDYgkpeOET5yXkx90OYFc+ytpQ==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", + "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", "cpu": [ "arm64" ], @@ -4566,9 +4566,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.20.0.tgz", - "integrity": "sha512-uFVfvzvsdGtlSLuL0ZlvPJvl6ZmrH4CBwLGEFPe7hUmf7htGAN+aXo43R/V6LATyxlKVC/m6UsLb7jbG+LG39Q==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", + "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", "cpu": [ "arm64" ], @@ -4579,9 +4579,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.20.0.tgz", - "integrity": "sha512-xbrMDdlev53vNXexEa6l0LffojxhqDTBeL+VUxuuIXys4x6xyvbKq5XqTXBCEUA8ty8iEJblHvFaWRJTk/icAQ==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", + "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", "cpu": [ "x64" ], @@ -4592,9 +4592,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.20.0.tgz", - "integrity": "sha512-jMYvxZwGmoHFBTbr12Xc6wOdc2xA5tF5F2q6t7Rcfab68TT0n+r7dgawD4qhPEvasDsVpQi+MgDzj2faOLsZjA==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", + "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", "cpu": [ "arm" ], @@ -4605,9 +4605,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.20.0.tgz", - "integrity": "sha512-1asSTl4HKuIHIB1GcdFHNNZhxAYEdqML/MW4QmPS4G0ivbEcBr1JKlFLKsIRqjSwOBkdItn3/ZDlyvZ/N6KPlw==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", + "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", "cpu": [ "arm" ], @@ -4618,9 +4618,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.20.0.tgz", - "integrity": "sha512-COBb8Bkx56KldOYJfMf6wKeYJrtJ9vEgBRAOkfw6Ens0tnmzPqvlpjZiLgkhg6cA3DGzCmLmmd319pmHvKWWlQ==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", + "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", "cpu": [ "arm64" ], @@ -4631,9 +4631,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.20.0.tgz", - "integrity": "sha512-+it+mBSyMslVQa8wSPvBx53fYuZK/oLTu5RJoXogjk6x7Q7sz1GNRsXWjn6SwyJm8E/oMjNVwPhmNdIjwP135Q==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", + "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", "cpu": [ "arm64" ], @@ -4644,9 +4644,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.20.0.tgz", - "integrity": "sha512-yAMvqhPfGKsAxHN8I4+jE0CpLWD8cv4z7CK7BMmhjDuz606Q2tFKkWRY8bHR9JQXYcoLfopo5TTqzxgPUjUMfw==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", + "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", "cpu": [ "ppc64" ], @@ -4657,9 +4657,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.20.0.tgz", - "integrity": "sha512-qmuxFpfmi/2SUkAw95TtNq/w/I7Gpjurx609OOOV7U4vhvUhBcftcmXwl3rqAek+ADBwSjIC4IVNLiszoj3dPA==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", + "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", "cpu": [ "riscv64" ], @@ -4670,9 +4670,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.20.0.tgz", - "integrity": "sha512-I0BtGXddHSHjV1mqTNkgUZLnS3WtsqebAXv11D5BZE/gfw5KoyXSAXVqyJximQXNvNzUo4GKlCK/dIwXlz+jlg==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", + "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", "cpu": [ "s390x" ], @@ -4683,9 +4683,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.20.0.tgz", - "integrity": "sha512-y+eoL2I3iphUg9tN9GB6ku1FA8kOfmF4oUEWhztDJ4KXJy1agk/9+pejOuZkNFhRwHAOxMsBPLbXPd6mJiCwew==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", + "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", "cpu": [ "x64" ], @@ -4696,9 +4696,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.20.0.tgz", - "integrity": "sha512-hM3nhW40kBNYUkZb/r9k2FKK+/MnKglX7UYd4ZUy5DJs8/sMsIbqWK2piZtVGE3kcXVNj3B2IrUYROJMMCikNg==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", + "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", "cpu": [ "x64" ], @@ -4709,9 +4709,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.20.0.tgz", - "integrity": "sha512-psegMvP+Ik/Bg7QRJbv8w8PAytPA7Uo8fpFjXyCRHWm6Nt42L+JtoqH8eDQ5hRP7/XW2UiIriy1Z46jf0Oa1kA==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", + "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", "cpu": [ "arm64" ], @@ -4722,9 +4722,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.20.0.tgz", - "integrity": "sha512-GabekH3w4lgAJpVxkk7hUzUf2hICSQO0a/BLFA11/RMxQT92MabKAqyubzDZmMOC/hcJNlc+rrypzNzYl4Dx7A==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", + "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", "cpu": [ "ia32" ], @@ -4735,9 +4735,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.20.0.tgz", - "integrity": "sha512-aJ1EJSuTdGnM6qbVC4B5DSmozPTqIag9fSzXRNNo+humQLG89XpPgdt16Ia56ORD7s+H8Pmyx44uczDQ0yDzpg==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", + "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", "cpu": [ "x64" ], @@ -15253,9 +15253,9 @@ } }, "node_modules/rollup": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.20.0.tgz", - "integrity": "sha512-6rbWBChcnSGzIlXeIdNIZTopKYad8ZG8ajhl78lGRLsI2rX8IkaotQhVas2Ma+GPxJav19wrSzvRvuiv0YKzWw==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", + "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -15268,22 +15268,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.20.0", - "@rollup/rollup-android-arm64": "4.20.0", - "@rollup/rollup-darwin-arm64": "4.20.0", - "@rollup/rollup-darwin-x64": "4.20.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.20.0", - "@rollup/rollup-linux-arm-musleabihf": "4.20.0", - "@rollup/rollup-linux-arm64-gnu": "4.20.0", - "@rollup/rollup-linux-arm64-musl": "4.20.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.20.0", - "@rollup/rollup-linux-riscv64-gnu": "4.20.0", - "@rollup/rollup-linux-s390x-gnu": "4.20.0", - "@rollup/rollup-linux-x64-gnu": "4.20.0", - "@rollup/rollup-linux-x64-musl": "4.20.0", - "@rollup/rollup-win32-arm64-msvc": "4.20.0", - "@rollup/rollup-win32-ia32-msvc": "4.20.0", - "@rollup/rollup-win32-x64-msvc": "4.20.0", + "@rollup/rollup-android-arm-eabi": "4.22.4", + "@rollup/rollup-android-arm64": "4.22.4", + "@rollup/rollup-darwin-arm64": "4.22.4", + "@rollup/rollup-darwin-x64": "4.22.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", + "@rollup/rollup-linux-arm-musleabihf": "4.22.4", + "@rollup/rollup-linux-arm64-gnu": "4.22.4", + "@rollup/rollup-linux-arm64-musl": "4.22.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", + "@rollup/rollup-linux-riscv64-gnu": "4.22.4", + "@rollup/rollup-linux-s390x-gnu": "4.22.4", + "@rollup/rollup-linux-x64-gnu": "4.22.4", + "@rollup/rollup-linux-x64-musl": "4.22.4", + "@rollup/rollup-win32-arm64-msvc": "4.22.4", + "@rollup/rollup-win32-ia32-msvc": "4.22.4", + "@rollup/rollup-win32-x64-msvc": "4.22.4", "fsevents": "~2.3.2" } }, From c29c93f2e48fb294484d31e7238da637620c6e43 Mon Sep 17 00:00:00 2001 From: Louis Greiner <57864277+louisgreiner@users.noreply.github.com> Date: Thu, 26 Sep 2024 17:51:55 +0200 Subject: [PATCH 104/197] fix: some translations (#299) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: fr Afficher -> Affichage * fix: fr Filtre -> Filtres * fix: fr Ligne de train -> Trajet de train * fix: fr netzgrafik -> réticulaire --- src/assets/i18n/fr.json | 90 ++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index 94e7b8a5..9bb805f9 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -33,7 +33,7 @@ }, "netzgrafik-application": { "variants": "Variantes", - "filter": "Filtre", + "filter": "Filtres", "analytics": "Analyse", "edit": "Edition", "more-functions": "Plus de fonctionnalités", @@ -125,9 +125,9 @@ "close-all-path-nodes": "Fermer tous les noeuds du chemin", "open-all-path-nodes": "Ouvrir tous les noeuds du chemin", "show-advanced-display-functions": "Afficher les fonctionnalités d'affichage avancées", - "show-or-hide-time-for-non-selected-trainruns": "Afficher/masquer le temps des lignes de train non sélectionnées", + "show-or-hide-time-for-non-selected-trainruns": "Afficher/masquer le temps des trajets de train non sélectionnés", "show-or-hide": "Activer/Désactiver {$component}", - "show-or-hide-name-for-non-selected-trainruns": "Afficher/masquer le nom des lignes de train non sélectionnées", + "show-or-hide-name-for-non-selected-trainruns": "Afficher/masquer le nom des trajets de train non sélectionnés", "hide-advanced-display-functions": "Masquer les fonctionnalités d'affichage avancées", "headway-band": "Espacement", "time": "Temps", @@ -247,20 +247,20 @@ "trainrun-filter-tab": { "labels": "Labels", "newLabels" : "Nouveau label...", - "trainrunDuplicate": "Dupliquer la ligne de train", - "trainrunDelete": "Supprimer la ligne de train", + "trainrunDuplicate": "Dupliquer le trajet de train", + "trainrunDelete": "Supprimer le trajet de train", "delete": "Supprimer", - "deleteConfirmationQuestion": "Faut-il supprimer définitivement l'ensemble de la ligne de train ?" + "deleteConfirmationQuestion": "Faut-il supprimer définitivement l'ensemble du trajet de train ?" }, "trainrun-tab": { "tabName": "Nom", "category": "Catégorie", "frequency": "Fréquence", "verkehrt": "Fonctionnement", - "trainrunDuplicate": "Dupliquer la ligne de train", - "trainrunDelete": "Supprimer la ligne de train", + "trainrunDuplicate": "Dupliquer le trajet de train", + "trainrunDelete": "Supprimer le trajet de train", "delete": "Supprimer", - "deleteConfirmationQuestion": "Faut-il supprimer définitivement l'ensemble de la ligne de train ?" + "deleteConfirmationQuestion": "Faut-il supprimer définitivement l'ensemble du trajet de train ?" }, "trainrun-section-tab": { "warningTwoLocks": "Avertissement : Trop de temps sont bloqués !", @@ -272,61 +272,61 @@ "editor-edit-tools-view-component": { "edit": "Editer", "filterable-labels": "Labels filtrables", - "trainruns": "Lignes de train", + "trainruns": "Trajets de train", "nodes": "Noeuds", "notes": "Notes", - "delete-netzgrafik-title": "Netzgrafik - Supprimer", + "delete-netzgrafik-title": "Réticulaire - Supprimer", "non-visible-elements": "Éléments non visibles", - "delete-all-non-visible-elements-tooltip": "Supprimer tous les éléments non visibles, tels que les noeuds, les lignes de train et les notes", + "delete-all-non-visible-elements-tooltip": "Supprimer tous les éléments non visibles, tels que les noeuds, les trajets de train et les notes", "delete-all-non-visible-elements": "Supprimer tous les éléments non visibles", "visible-elements": "Éléments visibles", - "delete-all-visible-trainruns-tooltip": "Supprimer toutes les lignes de trains visibles", - "delete-all-visible-trainruns": "Supprimer toutes les lignes de trains visibles", + "delete-all-visible-trainruns-tooltip": "Supprimer tous les trajets de trains visibles", + "delete-all-visible-trainruns": "Supprimer tous les trajets de trains visibles", "delete-all-visible-notes-tooltip": "Supprimer toutes les notes visibles", "delete-all-visible-notes": "Supprimer toutes les notes visibles", - "delete-all-visible-elements-tooltip": "Supprimer tous les éléments visibles, tels que les noeuds, les lignes de train et les notes", + "delete-all-visible-elements-tooltip": "Supprimer tous les éléments visibles, tels que les noeuds, les trajets de train et les notes", "delete-all-visible-elements": "Supprimer tous les éléments visibles", - "merge-netzgrafik-title": "Netzgrafik - Fusionner", - "add-netzgrafik-as-copy-tooltip": "Ajouter un netzgrafik en tant que copie (lignes de train, noeuds, notes)", - "add-netzgrafik-as-copy": "Ajouter un netzgrafik en tant que copie", - "merge-netzgrafik-tooltip": "Fusionner les réticulaires (lignes de train, noeuds, notes)", - "merge-netzgrafik": "Fusionner un netzgrafik", + "merge-netzgrafik-title": "Réticulaire - Fusionner", + "add-netzgrafik-as-copy-tooltip": "Ajouter un réticulaire en tant que copie (trajets de train, noeuds, notes)", + "add-netzgrafik-as-copy": "Ajouter un réticulaire en tant que copie", + "merge-netzgrafik-tooltip": "Fusionner les réticulaires (trajets de train, noeuds, notes)", + "merge-netzgrafik": "Fusionner un réticulaire", "delete": "Supprimer", - "on-clear-delete-all-non-visible-elements": "Tous les éléments non visibles doivent-ils être définitivement supprimés du netzgrafik ?", - "on-clear-delete-all-visible-elements": "Tous les éléments visibles doivent-ils être définitivement supprimés du netzgrafik ?", - "on-clear-delete-all-visible-trainruns": "Toutes les lignes de train visibles doivent-elles être définitivement supprimées du netzgrafik ?", - "on-clear-delete-all-visible-notes": "Toutes les notes visibles doivent-elles être définitivement supprimées du netzgrafik ?", + "on-clear-delete-all-non-visible-elements": "Tous les éléments non visibles doivent-ils être définitivement supprimés du réticulaire ?", + "on-clear-delete-all-visible-elements": "Tous les éléments visibles doivent-ils être définitivement supprimés du réticulaire ?", + "on-clear-delete-all-visible-trainruns": "Tous les trajets de train visibles doivent-ils être définitivement supprimés du réticulaire ?", + "on-clear-delete-all-visible-notes": "Toutes les notes visibles doivent-elles être définitivement supprimées du réticulaire ?", "label-drop-list": { "no-labels-available": "Aucun label disponible", "delete-group": "Supprimer le groupe", "add-new-group": "Ajouter un nouveau groupe", - "trainruns": "Lignes de train", + "trainruns": "Trajets de train", "notes": "Notes", "nodes": "Noeuds" } }, "editor-filter-view": { - "filter": "Filtre", + "filter": "Filtres", "general": "Général", "category": "Catégorie", "frequency": "Fréquence", "time-category": "Période de fonctionnement", - "display-all-trainruns": "Afficher toutes les lignes de train", - "reset-trainrun-filter": "Réinitialiser le filtre sur les lignes de train", - "filterable-labels-trainruns": "Labels filtrables: Lignes de train", + "display-all-trainruns": "Afficher tous les trajets de train", + "reset-trainrun-filter": "Réinitialiser les filtres sur les trajets de train", + "filterable-labels-trainruns": "Labels filtrables: Trajets de train", "filterable-labels-nodes": "Labels filtrables: Noeuds", "filterable-labels-notes": "Labels filtrables: Notes", - "display": "Afficher", + "display": "Affichage", "times": "Temps", "decimal-displayed": "Nombre de décimales affichées", "display-arrival-departure-times": "Afficher les heures de départ et d'arrivée", "display-arrival-departure-times-for-connections": "Afficher les heures de départ et d'arrivée des correspondances", "display-travel-times": "Afficher les temps de parcours", - "display-trainrun-name": "Afficher le nom du train", + "display-trainrun-name": "Afficher le nom du trajet de train", "connections": "Correspondances", "display-connections": "Afficher les correspondances", "nodes": "Noeuds", - "display-nodes-without-visible-trainruns": "Afficher les noeuds sans lignes de train (visibles)", + "display-nodes-without-visible-trainruns": "Afficher les noeuds sans trajets de train (visibles)", "display-nodes-with-only-stopping-trainruns": "Afficher les noeuds où les trains s'arrêtent", "notes": "Notes", "display-notes": "Afficher les notes", @@ -356,7 +356,7 @@ "save-changes": "Enregistrer les modifications", "changes-saved": "Modifications enregistrées", "read-mode": "Mode lecture", - "show-hide-filter": "Filtre", + "show-hide-filter": "Filtres", "zoom-out": "Zoom arrière", "zoom-in": "Zoom avant", "topology-editor-disabled": "Editeur de topologie désactivé", @@ -369,7 +369,7 @@ "analytics-enabled": "Analyse activée", "displayGraphicTimetable": "Afficher le graphique espace-temps", "closeGraphicTimetable": "Fermer le graphique espace-temps", - "errorGraphicTimetable": "Le graphique espace-temps ne peut pas être affiché parce qu'aucune ligne de train ou aucun noeud n'a été sélectionné." + "errorGraphicTimetable": "Le graphique espace-temps ne peut pas être affiché parce qu'aucun trajet de train ou aucun noeud n'a été sélectionné." }, "editor-properties-view-component": { "settings": "Paramètres", @@ -430,19 +430,19 @@ "editor-tools-view-component": { "more-functions": "Plus de fonctionnalités", "export": "Exporter", - "export-netzgrafik-as-svg": "Exporter le netzgrafik au format SVG", + "export-netzgrafik-as-svg": "Exporter le réticulaire au format SVG", "export-as-svg": "Exporter au format SVG", - "export-netzgrafik-as-png": "Exporter le netzgrafik au format PNG", + "export-netzgrafik-as-png": "Exporter le réticulaire au format PNG", "export-as-png": "Exporter au format PNG", - "print-netzgrafik": "Imprimer le netzgrafik", + "print-netzgrafik": "Imprimer le réticulaire", "print": "Imprimer", - "netzgrafik": "Netzgrafik", - "export-netzgrafik": "Exporter le netzgrafik", - "export-netzgrafik-as-json": "Exporter le netzgrafik au format JSON", - "import-netzgrafik": "Importer le netzgrafik", - "import-netzgrafik-as-json": "Importer le netzgrafik au format JSON", - "export-trainruns": "Exporter les lignes de train", - "export-trainruns-as-csv": "Exporter les lignes de train au format CSV", + "netzgrafik": "Réticulaire", + "export-netzgrafik": "Exporter le réticulaire", + "export-netzgrafik-as-json": "Exporter le réticulaire au format JSON", + "import-netzgrafik": "Importer le réticulaire", + "import-netzgrafik-as-json": "Importer le réticulaire au format JSON", + "export-trainruns": "Exporter les trajets de train", + "export-trainruns-as-csv": "Exporter les trajets de train au format CSV", "export-trainruns-as-csv-excel": "Dans Excel : Données -> txt/CSV -> Importer ... nom de fichier", "export-origin-destination": "Exporter origine-destination", "export-origin-destination-as-csv": "Exporter origine-destination au format CSV", @@ -466,7 +466,7 @@ "Y": "Y", "create": "Créer", "yes": "OUI", - "netzgrafikFile": "netzgrafik", + "netzgrafikFile": "reticulaire", "baseDataFile": "baseData", "trainrunFile": "trains", "originDestinationFile": "origineDestination", From cade856374c6faac19c69de3a6c64578b1c42147 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 10:31:39 +0200 Subject: [PATCH 105/197] chore(main): release netzgrafik-frontend 2.7.16 (#300) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 99cadb2a..24909727 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.7.15" + ".": "2.7.16" } diff --git a/CHANGELOG.md b/CHANGELOG.md index f6213c77..cb248857 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.7.16](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.7.15...netzgrafik-frontend-v2.7.16) (2024-09-26) + + +### Bug Fixes + +* some translations ([#299](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/299)) ([c29c93f](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/c29c93f2e48fb294484d31e7238da637620c6e43)) + ## [2.7.15](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.7.14...netzgrafik-frontend-v2.7.15) (2024-09-19) diff --git a/package-lock.json b/package-lock.json index 0c6aaa4d..72ffded3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.7.15", + "version": "2.7.16", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.7.15", + "version": "2.7.16", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index 5fba289b..0924547c 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.7.15", + "version": "2.7.16", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From 9b6d60c82ffa0dc54e3727d55b37a4227acd6de9 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 12:36:45 +0200 Subject: [PATCH 106/197] Create deploy-standalone-github.yml --- .../workflows/deploy-standalone-github.yml | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 .github/workflows/deploy-standalone-github.yml diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml new file mode 100644 index 00000000..7e04ad0f --- /dev/null +++ b/.github/workflows/deploy-standalone-github.yml @@ -0,0 +1,49 @@ +name: Deploy static content to GitHub Pages + +on: + push: + branches: ['main'] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets the GITHUB_TOKEN permissions to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow one concurrent deployment +concurrency: + group: 'pages' + cancel-in-progress: true + +jobs: + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'npm' + - name: Install dependencies + run: npm ci + - name: Build + run: npm run build:standalone + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + # Upload dist folder + path: './dist' + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 + if: ${{ github.ref == 'refs/heads/main' }} From 19da696c64df76bcd38bab6886e1e89884cb80b0 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 13:08:13 +0200 Subject: [PATCH 107/197] Create index.html --- index.html | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 index.html diff --git a/index.html b/index.html new file mode 100644 index 00000000..b6d9a9da --- /dev/null +++ b/index.html @@ -0,0 +1,14 @@ + + + + + Netzgrafik-Editor + + + + + + + + + From 02571f0bc329a29456ca7e04dca9b5356648a4a7 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 13:16:40 +0200 Subject: [PATCH 108/197] Update index.html (#303) --- index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/index.html b/index.html index b6d9a9da..e145a451 100644 --- a/index.html +++ b/index.html @@ -9,6 +9,7 @@ + From eb3ca9bf29fb5f8e5fe3d434fa696d828195d658 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 13:31:17 +0200 Subject: [PATCH 109/197] Delete index.html --- index.html | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 index.html diff --git a/index.html b/index.html deleted file mode 100644 index e145a451..00000000 --- a/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - Netzgrafik-Editor - - - - - - - - - - From c059427ed7b7606a8a9418a7a71c111b6541e74a Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 13:33:13 +0200 Subject: [PATCH 110/197] Update deploy-standalone-github.yml --- .github/workflows/deploy-standalone-github.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index 7e04ad0f..c28ff082 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -30,7 +30,7 @@ jobs: - name: Set up Node uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 18 cache: 'npm' - name: Install dependencies run: npm ci From 6a9a582bf8becc275ecc93fdc436d2e56e7eb4dc Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 14:01:38 +0200 Subject: [PATCH 111/197] Create 404.html --- 404.html | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 404.html diff --git a/404.html b/404.html new file mode 100644 index 00000000..839813f6 --- /dev/null +++ b/404.html @@ -0,0 +1,5 @@ + + +

Page Not Found

+ + From d9843e01c64408bbc45eecef2650c579dc1de7b8 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 15:04:33 +0200 Subject: [PATCH 112/197] Delete 404.html --- 404.html | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 404.html diff --git a/404.html b/404.html deleted file mode 100644 index 839813f6..00000000 --- a/404.html +++ /dev/null @@ -1,5 +0,0 @@ - - -

Page Not Found

- - From 17c1810be3e65251039377809cf439a6890fb218 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 15:09:03 +0200 Subject: [PATCH 113/197] Update deploy-standalone-github.yml --- .../workflows/deploy-standalone-github.yml | 49 +++++++++---------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index c28ff082..ee915e8b 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -20,30 +20,29 @@ concurrency: jobs: deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up Node - uses: actions/setup-node@v4 - with: - node-version: 18 - cache: 'npm' - - name: Install dependencies - run: npm ci - - name: Build - run: npm run build:standalone - - name: Setup Pages - uses: actions/configure-pages@v4 - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - # Upload dist folder - path: './dist' - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 - if: ${{ github.ref == 'refs/heads/main' }} + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Install dependencies + run: npm install + + - name: Run tests + run: npm run test:headless + + - name: Build + run: npm run build:prod + + - name: Deploy + if: success() + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: dist/angular-github-actions + enable_jekyll: true From 97b12ea5fcd91002d6e02cb49abe2dd8c177c8b7 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 15:11:00 +0200 Subject: [PATCH 114/197] Update deploy-standalone-github.yml --- .github/workflows/deploy-standalone-github.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index ee915e8b..e9d8a85c 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -31,13 +31,10 @@ jobs: node-version: 18 - name: Install dependencies - run: npm install - - - name: Run tests - run: npm run test:headless + run: npm ci - name: Build - run: npm run build:prod + run: npm run build:standalone - name: Deploy if: success() From d3ff5c67f20b88ea8b2f90cfb680b65a901d5571 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 15:18:55 +0200 Subject: [PATCH 115/197] Update deploy-standalone-github.yml --- .../workflows/deploy-standalone-github.yml | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index e9d8a85c..f8f19a22 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -20,26 +20,32 @@ concurrency: jobs: deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: 18 - - - name: Install dependencies - run: npm ci - - - name: Build - run: npm run build:standalone - - - name: Deploy - if: success() - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: dist/angular-github-actions - enable_jekyll: true + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: 18 + cache: 'npm' + - name: Install dependencies + run: npm ci + - name: Build + run: npm run build:standalone + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + # Upload dist folder + path: './dist' + - name: Info + run: ls ./dist + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 + if: ${{ github.ref == 'refs/heads/main' }} From 11863bfa9d917e44f399604196febe161bfecbe3 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 15:22:17 +0200 Subject: [PATCH 116/197] Update deploy-standalone-github.yml --- .github/workflows/deploy-standalone-github.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index f8f19a22..8de62038 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -46,6 +46,8 @@ jobs: - name: Info run: ls ./dist - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 - if: ${{ github.ref == 'refs/heads/main' }} + uses: peaceiris/actions-gh-pages@v4 + if: github.ref == 'refs/heads/main' + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./dist From e2f3e4f5fe39d50853cafed288344427ebf42b2f Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 15:24:52 +0200 Subject: [PATCH 117/197] Update deploy-standalone-github.yml From 32b382ad713156ab1a815c75c553d1b5c843112a Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 15:40:58 +0200 Subject: [PATCH 118/197] Update deploy-standalone-github.yml --- .github/workflows/deploy-standalone-github.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index 8de62038..60d38ddc 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -43,11 +43,6 @@ jobs: with: # Upload dist folder path: './dist' - - name: Info - run: ls ./dist - name: Deploy to GitHub Pages - uses: peaceiris/actions-gh-pages@v4 - if: github.ref == 'refs/heads/main' - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./dist + id: deployment + uses: actions/deploy-pages@v4 From 43e10094552a7d751d8027a55af03f41df50a9cd Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 15:47:14 +0200 Subject: [PATCH 119/197] Update deploy-standalone-github.yml --- .github/workflows/deploy-standalone-github.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index 60d38ddc..6bb393cf 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -42,7 +42,7 @@ jobs: uses: actions/upload-pages-artifact@v3 with: # Upload dist folder - path: './dist' + path: './dist/netzgrafik-frontend' - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4 From 607bd6ec70adeea65dae901b4629dc6f4ce0179a Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 15:50:07 +0200 Subject: [PATCH 120/197] Update deploy-standalone-github.yml --- .github/workflows/deploy-standalone-github.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index 6bb393cf..075bf64b 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -42,7 +42,8 @@ jobs: uses: actions/upload-pages-artifact@v3 with: # Upload dist folder - path: './dist/netzgrafik-frontend' + # path: './dist/netzgrafik-frontend' + path: './dist' - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4 From cee83367bea26230ed77ff775244de7c7717cb52 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 15:54:39 +0200 Subject: [PATCH 121/197] Update deploy-standalone-github.yml --- .../workflows/deploy-standalone-github.yml | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index 075bf64b..230953c4 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -36,14 +36,22 @@ jobs: run: npm ci - name: Build run: npm run build:standalone - - name: Setup Pages - uses: actions/configure-pages@v4 - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 + - name: Deploy + if: success() + uses: peaceiris/actions-gh-pages@v3 with: - # Upload dist folder - # path: './dist/netzgrafik-frontend' - path: './dist' - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: dist/angular-github-actions + enable_jekyll: true + + #- name: Setup Pages + # uses: actions/configure-pages@v4 + #- name: Upload artifact + # uses: actions/upload-pages-artifact@v3 + # with: + # # Upload dist folder + # # path: './dist/netzgrafik-frontend' + # path: './dist' + #- name: Deploy to GitHub Pages + # id: deployment + # uses: actions/deploy-pages@v4 From 4dd716735947e35cc3862165e0b7980073c8b6af Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 15:59:29 +0200 Subject: [PATCH 122/197] Update deploy-standalone-github.yml --- .../workflows/deploy-standalone-github.yml | 33 +++---------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index 230953c4..6888a3e9 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -25,33 +25,8 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up Node - uses: actions/setup-node@v4 + - id: build-publish + uses: bitovi/github-actions-angular-to-github-pages@v1.0.0 with: - node-version: 18 - cache: 'npm' - - name: Install dependencies - run: npm ci - - name: Build - run: npm run build:standalone - - name: Deploy - if: success() - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: dist/angular-github-actions - enable_jekyll: true - - #- name: Setup Pages - # uses: actions/configure-pages@v4 - #- name: Upload artifact - # uses: actions/upload-pages-artifact@v3 - # with: - # # Upload dist folder - # # path: './dist/netzgrafik-frontend' - # path: './dist' - #- name: Deploy to GitHub Pages - # id: deployment - # uses: actions/deploy-pages@v4 + path: dist/${{ github.event.repository.name }}/browser # default + build_command: npm run build -- --base-href=/${{ github.event.repository.name }}/ # default From 3d8039d6b6fc44ae0ff37318e883601f65451dd8 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 16:00:32 +0200 Subject: [PATCH 123/197] Update deploy-standalone-github.yml --- .github/workflows/deploy-standalone-github.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index 6888a3e9..09eeac17 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -29,4 +29,4 @@ jobs: uses: bitovi/github-actions-angular-to-github-pages@v1.0.0 with: path: dist/${{ github.event.repository.name }}/browser # default - build_command: npm run build -- --base-href=/${{ github.event.repository.name }}/ # default + build_command: npm run build:standalone -- --base-href=/${{ github.event.repository.name }}/ # default From 35914c7ae05d010d86a21a9bc6938f28c5ea7436 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 16:01:22 +0200 Subject: [PATCH 124/197] Update deploy-standalone-github.yml --- .github/workflows/deploy-standalone-github.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index 09eeac17..ba9a0118 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -29,4 +29,4 @@ jobs: uses: bitovi/github-actions-angular-to-github-pages@v1.0.0 with: path: dist/${{ github.event.repository.name }}/browser # default - build_command: npm run build:standalone -- --base-href=/${{ github.event.repository.name }}/ # default + build_command: npm run build:standalone From ab41faeab74211bc4f20a028bac68aca923e0387 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 16:06:52 +0200 Subject: [PATCH 125/197] Update deploy-standalone-github.yml --- .../workflows/deploy-standalone-github.yml | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index ba9a0118..b87ca2e1 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -25,8 +25,27 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - id: build-publish - uses: bitovi/github-actions-angular-to-github-pages@v1.0.0 - with: - path: dist/${{ github.event.repository.name }}/browser # default - build_command: npm run build:standalone + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Install dependencies + run: npm install + + - name: Run tests + run: npm run test:headless + + - name: Build + run: npm run build:prod + + - name: Deploy + if: success() + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: dist/${{ github.event.repository.name }} + enable_jekyll: false From 0ed5f3e89b0c5304595015da2f8ef5d5ac45102f Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 16:08:59 +0200 Subject: [PATCH 126/197] Update deploy-standalone-github.yml --- .github/workflows/deploy-standalone-github.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index b87ca2e1..4286d275 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -34,13 +34,10 @@ jobs: node-version: 18 - name: Install dependencies - run: npm install - - - name: Run tests - run: npm run test:headless - - - name: Build - run: npm run build:prod + run: npm ci + + - name: Build standlone + run: npm run build:standalone - name: Deploy if: success() From d74ad1610d5aebf4c09539d1816b938748416a18 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 16:14:50 +0200 Subject: [PATCH 127/197] Update deploy-standalone-github.yml --- .../workflows/deploy-standalone-github.yml | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index 4286d275..c0aaac43 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -25,24 +25,8 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: 18 - - - name: Install dependencies - run: npm ci - - - name: Build standlone - run: npm run build:standalone - - - name: Deploy - if: success() - uses: peaceiris/actions-gh-pages@v3 + - id: build-publish + uses: bitovi/github-actions-angular-to-github-pages@v1.0.0 with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: dist/${{ github.event.repository.name }} - enable_jekyll: false + path: dist/${{ github.event.repository.name }} # default + build_command: npm run build:standalone -- --base-href=/${{ github.event.repository.name }}/ # default From 62ed59cb5b3afb2626b202d5f899debea31578ce Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 16:16:56 +0200 Subject: [PATCH 128/197] Update deploy-standalone-github.yml --- .github/workflows/deploy-standalone-github.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index c0aaac43..b28cfc61 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -28,5 +28,6 @@ jobs: - id: build-publish uses: bitovi/github-actions-angular-to-github-pages@v1.0.0 with: - path: dist/${{ github.event.repository.name }} # default + # path: dist/${{ github.event.repository.name }} # default + path: dist build_command: npm run build:standalone -- --base-href=/${{ github.event.repository.name }}/ # default From 5ba727d9908e2f62a97d6f9fbe84f2b08f245879 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 16:23:38 +0200 Subject: [PATCH 129/197] Update deploy-standalone-github.yml --- .github/workflows/deploy-standalone-github.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index b28cfc61..27949c8a 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -30,4 +30,5 @@ jobs: with: # path: dist/${{ github.event.repository.name }} # default path: dist - build_command: npm run build:standalone -- --base-href=/${{ github.event.repository.name }}/ # default + # build_command: npm run build:standalone -- --base-href=/${{ github.event.repository.name }}/ # default + build_command: npm run build:standalone From 610b2e150c881964228fe3200cb876137f9a1c06 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 16:25:52 +0200 Subject: [PATCH 130/197] Update deploy-standalone-github.yml --- .github/workflows/deploy-standalone-github.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index 27949c8a..29e50bd7 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -28,7 +28,6 @@ jobs: - id: build-publish uses: bitovi/github-actions-angular-to-github-pages@v1.0.0 with: - # path: dist/${{ github.event.repository.name }} # default - path: dist + path: dist/${{ github.event.repository.name }} # default # build_command: npm run build:standalone -- --base-href=/${{ github.event.repository.name }}/ # default build_command: npm run build:standalone From 4c574725e2542daf46f615fed8096d9a8c807316 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 16:31:25 +0200 Subject: [PATCH 131/197] Update deploy-standalone-github.yml --- .github/workflows/deploy-standalone-github.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index 29e50bd7..470b000c 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -28,6 +28,7 @@ jobs: - id: build-publish uses: bitovi/github-actions-angular-to-github-pages@v1.0.0 with: - path: dist/${{ github.event.repository.name }} # default + # path: dist/${{ github.event.repository.name }} # default # build_command: npm run build:standalone -- --base-href=/${{ github.event.repository.name }}/ # default - build_command: npm run build:standalone + path: dist/netzgrafik-frontend + build_command: npm run build:standalone -- --base-href=netzgrafik-frontend From 2d1032c395400a70f98d7f72a1d72b6edba031b1 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 16:40:34 +0200 Subject: [PATCH 132/197] Github pages => demostrator https://schweizerischebundesbahnen.github.io/netzgrafik-editor-frontend/ --- .github/workflows/deploy-standalone-github.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index 470b000c..d1b31e1e 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -28,7 +28,5 @@ jobs: - id: build-publish uses: bitovi/github-actions-angular-to-github-pages@v1.0.0 with: - # path: dist/${{ github.event.repository.name }} # default - # build_command: npm run build:standalone -- --base-href=/${{ github.event.repository.name }}/ # default path: dist/netzgrafik-frontend build_command: npm run build:standalone -- --base-href=netzgrafik-frontend From 3ad67d7210ac667233841168ad0b014117086d01 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 16:51:31 +0200 Subject: [PATCH 133/197] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a0ae21a9..13f52e87 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,9 @@ Get an insight into the plan and future [ROADMAP.md](ROADMAP.md). The user manual can be found here [USERMANUAL.md](documentation/USERMANUAL.md) ## Online Demo -[nge.flatland.cloud](https://nge.flatland.cloud) +[Standalone Demo](https://schweizerischebundesbahnen.github.io/netzgrafik-editor-frontend/) ( [Sample Netzgrafik](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/main/src/app/sample-netzgrafik/Demo_Netzgrafik_Fernverkehr_2024.json) - [How to Import JSON](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/main/documentation/DATA_MODEL_JSON.md) ) + +[Extern: nge.flatland.cloud](https://nge.flatland.cloud) - powered by [Flatland Association](https://www.flatland-association.org/) ## Getting-Started From bee16d216a980bb32fdd0e6427d90c775bcd4292 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 3 Oct 2024 17:13:04 +0200 Subject: [PATCH 134/197] fix: Documentation enhanced and standalone application deployed to github pages (#304) * Update DATA_MODEL_JSON.md * Update DATA_MODEL_JSON.md * Update DATA_MODEL_JSON.md * Update DATA_MODEL_JSON.md --- documentation/DATA_MODEL_JSON.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/documentation/DATA_MODEL_JSON.md b/documentation/DATA_MODEL_JSON.md index 22d3bbb8..74464460 100644 --- a/documentation/DATA_MODEL_JSON.md +++ b/documentation/DATA_MODEL_JSON.md @@ -9,6 +9,15 @@ understandable representation of data, which facilitates manual editing. [DATA MODEL](DATA_MODEL.md) +## Export/Import +![image](https://github.com/user-attachments/assets/df46327d-5a00-4510-ab8f-563292ce81f8) + +#### Export +To export the current Netzgrafik use the `Export netzgrafik as JSON` button. + +#### Import +The exported data in JSON format can be imported again using the `Import netzgrafik as JSON` button. + ## JSON Description (basic data structure) ```json From 5ce01dd94ba712e1828f5d82109d334e3c4a4169 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Oct 2024 17:15:04 +0200 Subject: [PATCH 135/197] chore(main): release netzgrafik-frontend 2.7.17 (#305) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 24909727..edb30bfd 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.7.16" + ".": "2.7.17" } diff --git a/CHANGELOG.md b/CHANGELOG.md index cb248857..fe14a2d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.7.17](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.7.16...netzgrafik-frontend-v2.7.17) (2024-10-03) + + +### Bug Fixes + +* Documentation enhanced and standalone application deployed to github pages ([#304](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/304)) ([bee16d2](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/bee16d216a980bb32fdd0e6427d90c775bcd4292)) + ## [2.7.16](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.7.15...netzgrafik-frontend-v2.7.16) (2024-09-26) diff --git a/package-lock.json b/package-lock.json index 72ffded3..f097fc0a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.7.16", + "version": "2.7.17", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.7.16", + "version": "2.7.17", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index 0924547c..44223522 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.7.16", + "version": "2.7.17", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From be4ba8f669f38266e23dcf8c0a86333eb21b453e Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Mon, 7 Oct 2024 22:08:40 +0200 Subject: [PATCH 136/197] 306 feature request load a realistic sample plan when opening the demo for the first time GitHub pages (#308) * fix/enhanced: if the standalonedemo build is choosen the demo secanrio gets shows per default: > This is a demonstration scenario - no guarantee that the data is correct or corresponds to reality. * lint fixes * undo fix * undo fix * deploy * undo --- angular.json | 14 +++++++++++++- package.json | 2 ++ src/app/sample-netzgrafik/netzgrafik.default.ts | 5 +++++ .../netzgrafik.demo.standalone.github.ts | 10 ++++++++++ src/environments/environment.model.ts | 1 + src/environments/environment.standalone.ts | 1 + src/environments/environment.standalonedemo.ts | 8 ++++++++ src/environments/environment.ts | 1 + 8 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/app/sample-netzgrafik/netzgrafik.demo.standalone.github.ts create mode 100644 src/environments/environment.standalonedemo.ts diff --git a/angular.json b/angular.json index 81650831..8145c845 100644 --- a/angular.json +++ b/angular.json @@ -89,7 +89,16 @@ "with": "src/environments/environment.standalone.ts" } ] - } + }, + "standalonedemo": { + "outputHashing": "none", + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.standalonedemo.ts" + } + ] + }, }, "defaultConfiguration": "" }, @@ -110,6 +119,9 @@ }, "standalone": { "buildTarget": "netzgrafik-frontend:build:standalone" + }, + "standalonedemo": { + "buildTarget": "netzgrafik-frontend:build:standalonedemo" } } }, diff --git a/package.json b/package.json index 44223522..0aca15ee 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,12 @@ "start": "ng serve", "start:local": "ng serve --configuration=local", "start:standalone": "ng serve --configuration=standalone", + "start:standalonedemo": "ng serve --configuration=standalonedemo", "e2e:browserstack": "ng e2e -c browserstack", "e2e:puppeteer": "ng e2e -c puppeteer", "build": "ng run netzgrafik-frontend:ngsscbuild", "build:standalone": "ng build --configuration=standalone", + "build:standalonedemo": "ng build --configuration=standalonedemo", "test": "ng test -c ci", "lint": "ng lint", "e2e": "ng e2e", diff --git a/src/app/sample-netzgrafik/netzgrafik.default.ts b/src/app/sample-netzgrafik/netzgrafik.default.ts index 269b1404..bc6707d2 100644 --- a/src/app/sample-netzgrafik/netzgrafik.default.ts +++ b/src/app/sample-netzgrafik/netzgrafik.default.ts @@ -3,9 +3,14 @@ import { LinePatternRefs, NetzgrafikDto, } from "../data-structures/business.data.structures"; +import {environment} from "../../environments/environment"; +import {NetzgrafikDemoStandaloneGithub} from "./netzgrafik.demo.standalone.github"; export class NetzgrafikDefault { static getDefaultNetzgrafik(): NetzgrafikDto { + if (environment.standalonedemo) { + return NetzgrafikDemoStandaloneGithub.getNetzgrafikDemoStandaloneGithub(); + } return { nodes: [ { diff --git a/src/app/sample-netzgrafik/netzgrafik.demo.standalone.github.ts b/src/app/sample-netzgrafik/netzgrafik.demo.standalone.github.ts new file mode 100644 index 00000000..28abac5c --- /dev/null +++ b/src/app/sample-netzgrafik/netzgrafik.demo.standalone.github.ts @@ -0,0 +1,10 @@ +import { + NetzgrafikDto, +} from "../data-structures/business.data.structures"; + +export class NetzgrafikDemoStandaloneGithub { + static getNetzgrafikDemoStandaloneGithub(): NetzgrafikDto { + return JSON.parse('{"nodes":[{"id":128,"betriebspunktName":"Lausanne","fullName":"Lausanne","positionX":-3072,"positionY":544,"ports":[{"id":1207,"trainrunSectionId":596,"positionIndex":0,"positionAlignment":2},{"id":1187,"trainrunSectionId":586,"positionIndex":1,"positionAlignment":2},{"id":1382,"trainrunSectionId":683,"positionIndex":0,"positionAlignment":3},{"id":1380,"trainrunSectionId":682,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":345,"port1Id":1187,"port2Id":1380,"isNonStopTransit":false},{"id":347,"port1Id":1207,"port2Id":1382,"isNonStopTransit":false}],"connections":[],"resourceId":152,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":129,"betriebspunktName":"Bern","fullName":"Bern","positionX":-2144,"positionY":128,"ports":[{"id":1328,"trainrunSectionId":656,"positionIndex":0,"positionAlignment":1},{"id":1311,"trainrunSectionId":648,"positionIndex":1,"positionAlignment":1},{"id":1313,"trainrunSectionId":649,"positionIndex":2,"positionAlignment":1},{"id":1339,"trainrunSectionId":662,"positionIndex":3,"positionAlignment":1},{"id":1205,"trainrunSectionId":595,"positionIndex":0,"positionAlignment":2},{"id":1109,"trainrunSectionId":547,"positionIndex":1,"positionAlignment":2},{"id":1440,"trainrunSectionId":712,"positionIndex":0,"positionAlignment":3},{"id":1329,"trainrunSectionId":657,"positionIndex":1,"positionAlignment":3},{"id":1436,"trainrunSectionId":710,"positionIndex":2,"positionAlignment":3},{"id":1434,"trainrunSectionId":709,"positionIndex":3,"positionAlignment":3},{"id":1432,"trainrunSectionId":708,"positionIndex":4,"positionAlignment":3},{"id":1430,"trainrunSectionId":707,"positionIndex":5,"positionAlignment":3},{"id":1428,"trainrunSectionId":706,"positionIndex":6,"positionAlignment":3}],"transitions":[{"id":315,"port1Id":1328,"port2Id":1329,"isNonStopTransit":false},{"id":376,"port1Id":1109,"port2Id":1430,"isNonStopTransit":false},{"id":378,"port1Id":1339,"port2Id":1432,"isNonStopTransit":false},{"id":380,"port1Id":1313,"port2Id":1434,"isNonStopTransit":false},{"id":382,"port1Id":1311,"port2Id":1436,"isNonStopTransit":false},{"id":386,"port1Id":1205,"port2Id":1440,"isNonStopTransit":false}],"connections":[],"resourceId":153,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":130,"betriebspunktName":"Biel","fullName":"Biel","positionX":-2528,"positionY":-32,"ports":[{"id":1183,"trainrunSectionId":584,"positionIndex":0,"positionAlignment":2},{"id":1418,"trainrunSectionId":701,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":366,"port1Id":1183,"port2Id":1418,"isNonStopTransit":false}],"connections":[],"resourceId":154,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":131,"betriebspunktName":"Interlaken ","fullName":"Interlaken Ost","positionX":-1088,"positionY":928,"ports":[{"id":1318,"trainrunSectionId":651,"positionIndex":0,"positionAlignment":2},{"id":1344,"trainrunSectionId":664,"positionIndex":1,"positionAlignment":2}],"transitions":[],"connections":[],"resourceId":155,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":132,"betriebspunktName":"Visp","fullName":"Visp","positionX":-2144,"positionY":1440,"ports":[{"id":1323,"trainrunSectionId":654,"positionIndex":0,"positionAlignment":0},{"id":1322,"trainrunSectionId":653,"positionIndex":1,"positionAlignment":0}],"transitions":[],"connections":[],"resourceId":156,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":133,"betriebspunktName":"Olten","fullName":"Olten","positionX":64,"positionY":96,"ports":[{"id":1047,"trainrunSectionId":516,"positionIndex":0,"positionAlignment":0},{"id":1331,"trainrunSectionId":658,"positionIndex":1,"positionAlignment":0},{"id":1308,"trainrunSectionId":646,"positionIndex":2,"positionAlignment":0},{"id":1371,"trainrunSectionId":678,"positionIndex":3,"positionAlignment":0},{"id":1131,"trainrunSectionId":558,"positionIndex":4,"positionAlignment":0},{"id":1117,"trainrunSectionId":551,"positionIndex":5,"positionAlignment":0},{"id":1046,"trainrunSectionId":515,"positionIndex":0,"positionAlignment":1},{"id":1370,"trainrunSectionId":677,"positionIndex":1,"positionAlignment":1},{"id":1130,"trainrunSectionId":557,"positionIndex":2,"positionAlignment":1},{"id":1116,"trainrunSectionId":550,"positionIndex":3,"positionAlignment":1},{"id":1181,"trainrunSectionId":583,"positionIndex":0,"positionAlignment":2},{"id":1203,"trainrunSectionId":594,"positionIndex":1,"positionAlignment":2},{"id":1394,"trainrunSectionId":689,"positionIndex":2,"positionAlignment":2},{"id":1309,"trainrunSectionId":647,"positionIndex":3,"positionAlignment":2},{"id":1225,"trainrunSectionId":605,"positionIndex":4,"positionAlignment":2},{"id":1241,"trainrunSectionId":613,"positionIndex":5,"positionAlignment":2},{"id":1165,"trainrunSectionId":575,"positionIndex":6,"positionAlignment":2},{"id":1202,"trainrunSectionId":593,"positionIndex":0,"positionAlignment":3},{"id":1180,"trainrunSectionId":582,"positionIndex":1,"positionAlignment":3},{"id":1224,"trainrunSectionId":604,"positionIndex":2,"positionAlignment":3},{"id":1240,"trainrunSectionId":612,"positionIndex":3,"positionAlignment":3},{"id":1164,"trainrunSectionId":574,"positionIndex":4,"positionAlignment":3}],"transitions":[{"id":210,"port1Id":1047,"port2Id":1046,"isNonStopTransit":false},{"id":236,"port1Id":1117,"port2Id":1116,"isNonStopTransit":false},{"id":242,"port1Id":1131,"port2Id":1130,"isNonStopTransit":false},{"id":253,"port1Id":1165,"port2Id":1164,"isNonStopTransit":false},{"id":259,"port1Id":1181,"port2Id":1180,"isNonStopTransit":false},{"id":264,"port1Id":1203,"port2Id":1202,"isNonStopTransit":true},{"id":270,"port1Id":1225,"port2Id":1224,"isNonStopTransit":true},{"id":276,"port1Id":1241,"port2Id":1240,"isNonStopTransit":true},{"id":308,"port1Id":1308,"port2Id":1309,"isNonStopTransit":false},{"id":340,"port1Id":1371,"port2Id":1370,"isNonStopTransit":false},{"id":353,"port1Id":1331,"port2Id":1394,"isNonStopTransit":false}],"connections":[],"resourceId":157,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":134,"betriebspunktName":"Basel","fullName":"Basel","positionX":64,"positionY":-1888,"ports":[{"id":1054,"trainrunSectionId":519,"positionIndex":0,"positionAlignment":1},{"id":1416,"trainrunSectionId":700,"positionIndex":1,"positionAlignment":1},{"id":1277,"trainrunSectionId":631,"positionIndex":2,"positionAlignment":1},{"id":1338,"trainrunSectionId":661,"positionIndex":3,"positionAlignment":1},{"id":1301,"trainrunSectionId":643,"positionIndex":4,"positionAlignment":1},{"id":1378,"trainrunSectionId":681,"positionIndex":5,"positionAlignment":1},{"id":1138,"trainrunSectionId":561,"positionIndex":6,"positionAlignment":1},{"id":1124,"trainrunSectionId":554,"positionIndex":7,"positionAlignment":1},{"id":1267,"trainrunSectionId":626,"positionIndex":0,"positionAlignment":3}],"transitions":[],"connections":[],"resourceId":158,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":135,"betriebspunktName":"Zürich","fullName":"Zürich","positionX":2656,"positionY":32,"ports":[{"id":1255,"trainrunSectionId":620,"positionIndex":0,"positionAlignment":0},{"id":1254,"trainrunSectionId":619,"positionIndex":1,"positionAlignment":0},{"id":1360,"trainrunSectionId":672,"positionIndex":0,"positionAlignment":1},{"id":1149,"trainrunSectionId":567,"positionIndex":1,"positionAlignment":1},{"id":1153,"trainrunSectionId":569,"positionIndex":2,"positionAlignment":1},{"id":1358,"trainrunSectionId":671,"positionIndex":3,"positionAlignment":1},{"id":1356,"trainrunSectionId":670,"positionIndex":4,"positionAlignment":1},{"id":1354,"trainrunSectionId":669,"positionIndex":5,"positionAlignment":1},{"id":1195,"trainrunSectionId":590,"positionIndex":0,"positionAlignment":2},{"id":1401,"trainrunSectionId":693,"positionIndex":1,"positionAlignment":2},{"id":1292,"trainrunSectionId":638,"positionIndex":2,"positionAlignment":2},{"id":1173,"trainrunSectionId":579,"positionIndex":3,"positionAlignment":2},{"id":1217,"trainrunSectionId":601,"positionIndex":4,"positionAlignment":2},{"id":1233,"trainrunSectionId":609,"positionIndex":5,"positionAlignment":2},{"id":1157,"trainrunSectionId":571,"positionIndex":6,"positionAlignment":2},{"id":1276,"trainrunSectionId":630,"positionIndex":7,"positionAlignment":2},{"id":1300,"trainrunSectionId":642,"positionIndex":8,"positionAlignment":2},{"id":1191,"trainrunSectionId":588,"positionIndex":0,"positionAlignment":3},{"id":1172,"trainrunSectionId":578,"positionIndex":1,"positionAlignment":3},{"id":1213,"trainrunSectionId":599,"positionIndex":2,"positionAlignment":3},{"id":1229,"trainrunSectionId":607,"positionIndex":3,"positionAlignment":3},{"id":1139,"trainrunSectionId":562,"positionIndex":4,"positionAlignment":3},{"id":1245,"trainrunSectionId":615,"positionIndex":5,"positionAlignment":3}],"transitions":[{"id":250,"port1Id":1153,"port2Id":1157,"isNonStopTransit":false},{"id":256,"port1Id":1173,"port2Id":1172,"isNonStopTransit":false},{"id":261,"port1Id":1195,"port2Id":1191,"isNonStopTransit":false},{"id":267,"port1Id":1217,"port2Id":1213,"isNonStopTransit":false},{"id":273,"port1Id":1233,"port2Id":1229,"isNonStopTransit":false},{"id":329,"port1Id":1354,"port2Id":1245,"isNonStopTransit":false},{"id":357,"port1Id":1149,"port2Id":1401,"isNonStopTransit":false}],"connections":[],"resourceId":159,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":136,"betriebspunktName":"Bellinz.","fullName":"Bellinzona","positionX":2592,"positionY":3232,"ports":[{"id":1059,"trainrunSectionId":522,"positionIndex":0,"positionAlignment":0},{"id":1035,"trainrunSectionId":510,"positionIndex":1,"positionAlignment":0},{"id":1071,"trainrunSectionId":528,"positionIndex":2,"positionAlignment":0},{"id":1083,"trainrunSectionId":534,"positionIndex":3,"positionAlignment":0},{"id":1058,"trainrunSectionId":521,"positionIndex":0,"positionAlignment":1},{"id":1034,"trainrunSectionId":509,"positionIndex":1,"positionAlignment":1},{"id":1070,"trainrunSectionId":527,"positionIndex":0,"positionAlignment":2},{"id":1082,"trainrunSectionId":533,"positionIndex":1,"positionAlignment":2}],"transitions":[{"id":206,"port1Id":1035,"port2Id":1034,"isNonStopTransit":false},{"id":216,"port1Id":1059,"port2Id":1058,"isNonStopTransit":false},{"id":221,"port1Id":1071,"port2Id":1070,"isNonStopTransit":false},{"id":226,"port1Id":1083,"port2Id":1082,"isNonStopTransit":false}],"connections":[],"resourceId":160,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":137,"betriebspunktName":"St. Gallen","fullName":"Sankt Gallen","positionX":4640,"positionY":96,"ports":[{"id":1145,"trainrunSectionId":565,"positionIndex":0,"positionAlignment":1},{"id":1212,"trainrunSectionId":598,"positionIndex":0,"positionAlignment":2},{"id":1167,"trainrunSectionId":576,"positionIndex":1,"positionAlignment":2},{"id":1144,"trainrunSectionId":564,"positionIndex":2,"positionAlignment":2},{"id":1419,"trainrunSectionId":702,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":248,"port1Id":1145,"port2Id":1144,"isNonStopTransit":false},{"id":367,"port1Id":1167,"port2Id":1419,"isNonStopTransit":false}],"connections":[],"resourceId":161,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":138,"betriebspunktName":"Schaffh.","fullName":"Schaffhausen","positionX":2624,"positionY":-1120,"ports":[{"id":1256,"trainrunSectionId":620,"positionIndex":0,"positionAlignment":1},{"id":1251,"trainrunSectionId":618,"positionIndex":1,"positionAlignment":1}],"transitions":[],"connections":[],"resourceId":162,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":139,"betriebspunktName":"Konstanz","fullName":"Konstanz","positionX":4256,"positionY":-416,"ports":[{"id":1250,"trainrunSectionId":617,"positionIndex":0,"positionAlignment":1}],"transitions":[],"connections":[],"resourceId":163,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":140,"betriebspunktName":"Sargans","fullName":"Sargans","positionX":4640,"positionY":1184,"ports":[{"id":1146,"trainrunSectionId":565,"positionIndex":0,"positionAlignment":0},{"id":1151,"trainrunSectionId":568,"positionIndex":0,"positionAlignment":1},{"id":1147,"trainrunSectionId":566,"positionIndex":1,"positionAlignment":1},{"id":1155,"trainrunSectionId":570,"positionIndex":2,"positionAlignment":1},{"id":1362,"trainrunSectionId":673,"positionIndex":0,"positionAlignment":2},{"id":1364,"trainrunSectionId":674,"positionIndex":1,"positionAlignment":2}],"transitions":[{"id":249,"port1Id":1146,"port2Id":1147,"isNonStopTransit":false},{"id":334,"port1Id":1151,"port2Id":1362,"isNonStopTransit":false},{"id":336,"port1Id":1155,"port2Id":1364,"isNonStopTransit":false}],"connections":[],"resourceId":164,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":141,"betriebspunktName":"Sursee","fullName":"Sursee","positionX":64,"positionY":1184,"ports":[{"id":1043,"trainrunSectionId":514,"positionIndex":0,"positionAlignment":0},{"id":1105,"trainrunSectionId":545,"positionIndex":1,"positionAlignment":0},{"id":1367,"trainrunSectionId":676,"positionIndex":2,"positionAlignment":0},{"id":1127,"trainrunSectionId":556,"positionIndex":3,"positionAlignment":0},{"id":1113,"trainrunSectionId":549,"positionIndex":4,"positionAlignment":0},{"id":1042,"trainrunSectionId":513,"positionIndex":0,"positionAlignment":1},{"id":1104,"trainrunSectionId":544,"positionIndex":1,"positionAlignment":1},{"id":1366,"trainrunSectionId":675,"positionIndex":2,"positionAlignment":1},{"id":1126,"trainrunSectionId":555,"positionIndex":3,"positionAlignment":1},{"id":1112,"trainrunSectionId":548,"positionIndex":4,"positionAlignment":1}],"transitions":[{"id":208,"port1Id":1043,"port2Id":1042,"isNonStopTransit":true},{"id":232,"port1Id":1105,"port2Id":1104,"isNonStopTransit":false},{"id":234,"port1Id":1113,"port2Id":1112,"isNonStopTransit":false},{"id":240,"port1Id":1127,"port2Id":1126,"isNonStopTransit":true},{"id":338,"port1Id":1367,"port2Id":1366,"isNonStopTransit":true}],"connections":[],"resourceId":165,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":142,"betriebspunktName":"Luzern","fullName":"Luzern","positionX":64,"positionY":1728,"ports":[{"id":1041,"trainrunSectionId":513,"positionIndex":0,"positionAlignment":0},{"id":1103,"trainrunSectionId":544,"positionIndex":1,"positionAlignment":0},{"id":1365,"trainrunSectionId":675,"positionIndex":2,"positionAlignment":0},{"id":1125,"trainrunSectionId":555,"positionIndex":3,"positionAlignment":0},{"id":1111,"trainrunSectionId":548,"positionIndex":4,"positionAlignment":0},{"id":1352,"trainrunSectionId":668,"positionIndex":0,"positionAlignment":3},{"id":1350,"trainrunSectionId":667,"positionIndex":1,"positionAlignment":3},{"id":1099,"trainrunSectionId":542,"positionIndex":2,"positionAlignment":3},{"id":1095,"trainrunSectionId":540,"positionIndex":3,"positionAlignment":3}],"transitions":[{"id":327,"port1Id":1041,"port2Id":1352,"isNonStopTransit":false},{"id":337,"port1Id":1365,"port2Id":1350,"isNonStopTransit":false}],"connections":[],"resourceId":166,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":143,"betriebspunktName":"Zofingen","fullName":"Zofingen","positionX":64,"positionY":736,"ports":[{"id":1045,"trainrunSectionId":515,"positionIndex":0,"positionAlignment":0},{"id":1369,"trainrunSectionId":677,"positionIndex":1,"positionAlignment":0},{"id":1129,"trainrunSectionId":557,"positionIndex":2,"positionAlignment":0},{"id":1115,"trainrunSectionId":550,"positionIndex":3,"positionAlignment":0},{"id":1044,"trainrunSectionId":514,"positionIndex":0,"positionAlignment":1},{"id":1106,"trainrunSectionId":545,"positionIndex":1,"positionAlignment":1},{"id":1368,"trainrunSectionId":676,"positionIndex":2,"positionAlignment":1},{"id":1128,"trainrunSectionId":556,"positionIndex":3,"positionAlignment":1},{"id":1114,"trainrunSectionId":549,"positionIndex":4,"positionAlignment":1},{"id":1107,"trainrunSectionId":546,"positionIndex":0,"positionAlignment":2}],"transitions":[{"id":209,"port1Id":1045,"port2Id":1044,"isNonStopTransit":true},{"id":233,"port1Id":1107,"port2Id":1106,"isNonStopTransit":false},{"id":235,"port1Id":1115,"port2Id":1114,"isNonStopTransit":false},{"id":241,"port1Id":1129,"port2Id":1128,"isNonStopTransit":true},{"id":339,"port1Id":1369,"port2Id":1368,"isNonStopTransit":false}],"connections":[],"resourceId":167,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":144,"betriebspunktName":"Gelterk.","fullName":"Gelterkinden","positionX":64,"positionY":-448,"ports":[{"id":1049,"trainrunSectionId":517,"positionIndex":0,"positionAlignment":0},{"id":1411,"trainrunSectionId":698,"positionIndex":1,"positionAlignment":0},{"id":1282,"trainrunSectionId":633,"positionIndex":2,"positionAlignment":0},{"id":1333,"trainrunSectionId":659,"positionIndex":3,"positionAlignment":0},{"id":1306,"trainrunSectionId":645,"positionIndex":4,"positionAlignment":0},{"id":1373,"trainrunSectionId":679,"positionIndex":5,"positionAlignment":0},{"id":1133,"trainrunSectionId":559,"positionIndex":6,"positionAlignment":0},{"id":1119,"trainrunSectionId":552,"positionIndex":7,"positionAlignment":0},{"id":1048,"trainrunSectionId":516,"positionIndex":0,"positionAlignment":1},{"id":1332,"trainrunSectionId":658,"positionIndex":1,"positionAlignment":1},{"id":1307,"trainrunSectionId":646,"positionIndex":2,"positionAlignment":1},{"id":1372,"trainrunSectionId":678,"positionIndex":3,"positionAlignment":1},{"id":1132,"trainrunSectionId":558,"positionIndex":4,"positionAlignment":1},{"id":1118,"trainrunSectionId":551,"positionIndex":5,"positionAlignment":1},{"id":1410,"trainrunSectionId":697,"positionIndex":0,"positionAlignment":3},{"id":1283,"trainrunSectionId":634,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":211,"port1Id":1049,"port2Id":1048,"isNonStopTransit":true},{"id":237,"port1Id":1119,"port2Id":1118,"isNonStopTransit":false},{"id":243,"port1Id":1133,"port2Id":1132,"isNonStopTransit":true},{"id":297,"port1Id":1282,"port2Id":1283,"isNonStopTransit":true},{"id":307,"port1Id":1306,"port2Id":1307,"isNonStopTransit":true},{"id":316,"port1Id":1333,"port2Id":1332,"isNonStopTransit":true},{"id":341,"port1Id":1373,"port2Id":1372,"isNonStopTransit":true},{"id":362,"port1Id":1411,"port2Id":1410,"isNonStopTransit":true}],"connections":[],"resourceId":168,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":145,"betriebspunktName":"Sissach","fullName":"Sissach","positionX":64,"positionY":-928,"ports":[{"id":1051,"trainrunSectionId":518,"positionIndex":0,"positionAlignment":0},{"id":1413,"trainrunSectionId":699,"positionIndex":1,"positionAlignment":0},{"id":1280,"trainrunSectionId":632,"positionIndex":2,"positionAlignment":0},{"id":1335,"trainrunSectionId":660,"positionIndex":3,"positionAlignment":0},{"id":1304,"trainrunSectionId":644,"positionIndex":4,"positionAlignment":0},{"id":1375,"trainrunSectionId":680,"positionIndex":5,"positionAlignment":0},{"id":1135,"trainrunSectionId":560,"positionIndex":6,"positionAlignment":0},{"id":1121,"trainrunSectionId":553,"positionIndex":7,"positionAlignment":0},{"id":1050,"trainrunSectionId":517,"positionIndex":0,"positionAlignment":1},{"id":1412,"trainrunSectionId":698,"positionIndex":1,"positionAlignment":1},{"id":1281,"trainrunSectionId":633,"positionIndex":2,"positionAlignment":1},{"id":1334,"trainrunSectionId":659,"positionIndex":3,"positionAlignment":1},{"id":1305,"trainrunSectionId":645,"positionIndex":4,"positionAlignment":1},{"id":1374,"trainrunSectionId":679,"positionIndex":5,"positionAlignment":1},{"id":1134,"trainrunSectionId":559,"positionIndex":6,"positionAlignment":1},{"id":1120,"trainrunSectionId":552,"positionIndex":7,"positionAlignment":1}],"transitions":[{"id":212,"port1Id":1051,"port2Id":1050,"isNonStopTransit":true},{"id":238,"port1Id":1121,"port2Id":1120,"isNonStopTransit":false},{"id":244,"port1Id":1135,"port2Id":1134,"isNonStopTransit":true},{"id":296,"port1Id":1280,"port2Id":1281,"isNonStopTransit":true},{"id":306,"port1Id":1304,"port2Id":1305,"isNonStopTransit":true},{"id":317,"port1Id":1335,"port2Id":1334,"isNonStopTransit":true},{"id":342,"port1Id":1375,"port2Id":1374,"isNonStopTransit":true},{"id":363,"port1Id":1413,"port2Id":1412,"isNonStopTransit":true}],"connections":[],"resourceId":169,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":146,"betriebspunktName":"Liestal","fullName":"Liestal","positionX":64,"positionY":-1408,"ports":[{"id":1053,"trainrunSectionId":519,"positionIndex":0,"positionAlignment":0},{"id":1415,"trainrunSectionId":700,"positionIndex":1,"positionAlignment":0},{"id":1278,"trainrunSectionId":631,"positionIndex":2,"positionAlignment":0},{"id":1337,"trainrunSectionId":661,"positionIndex":3,"positionAlignment":0},{"id":1302,"trainrunSectionId":643,"positionIndex":4,"positionAlignment":0},{"id":1377,"trainrunSectionId":681,"positionIndex":5,"positionAlignment":0},{"id":1137,"trainrunSectionId":561,"positionIndex":6,"positionAlignment":0},{"id":1123,"trainrunSectionId":554,"positionIndex":7,"positionAlignment":0},{"id":1052,"trainrunSectionId":518,"positionIndex":0,"positionAlignment":1},{"id":1414,"trainrunSectionId":699,"positionIndex":1,"positionAlignment":1},{"id":1279,"trainrunSectionId":632,"positionIndex":2,"positionAlignment":1},{"id":1336,"trainrunSectionId":660,"positionIndex":3,"positionAlignment":1},{"id":1303,"trainrunSectionId":644,"positionIndex":4,"positionAlignment":1},{"id":1376,"trainrunSectionId":680,"positionIndex":5,"positionAlignment":1},{"id":1136,"trainrunSectionId":560,"positionIndex":6,"positionAlignment":1},{"id":1122,"trainrunSectionId":553,"positionIndex":7,"positionAlignment":1}],"transitions":[{"id":213,"port1Id":1053,"port2Id":1052,"isNonStopTransit":true},{"id":239,"port1Id":1123,"port2Id":1122,"isNonStopTransit":false},{"id":245,"port1Id":1137,"port2Id":1136,"isNonStopTransit":true},{"id":295,"port1Id":1278,"port2Id":1279,"isNonStopTransit":true},{"id":305,"port1Id":1302,"port2Id":1303,"isNonStopTransit":true},{"id":318,"port1Id":1337,"port2Id":1336,"isNonStopTransit":true},{"id":343,"port1Id":1377,"port2Id":1376,"isNonStopTransit":true},{"id":364,"port1Id":1415,"port2Id":1414,"isNonStopTransit":true}],"connections":[],"resourceId":170,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":147,"betriebspunktName":"Aarau","fullName":"Aarau","positionX":960,"positionY":32,"ports":[{"id":1409,"trainrunSectionId":697,"positionIndex":0,"positionAlignment":2},{"id":1284,"trainrunSectionId":634,"positionIndex":1,"positionAlignment":2},{"id":1201,"trainrunSectionId":593,"positionIndex":2,"positionAlignment":2},{"id":1179,"trainrunSectionId":582,"positionIndex":3,"positionAlignment":2},{"id":1223,"trainrunSectionId":604,"positionIndex":4,"positionAlignment":2},{"id":1239,"trainrunSectionId":612,"positionIndex":5,"positionAlignment":2},{"id":1163,"trainrunSectionId":574,"positionIndex":6,"positionAlignment":2},{"id":1200,"trainrunSectionId":592,"positionIndex":0,"positionAlignment":3},{"id":1408,"trainrunSectionId":696,"positionIndex":1,"positionAlignment":3},{"id":1285,"trainrunSectionId":635,"positionIndex":2,"positionAlignment":3},{"id":1178,"trainrunSectionId":581,"positionIndex":3,"positionAlignment":3},{"id":1222,"trainrunSectionId":603,"positionIndex":4,"positionAlignment":3},{"id":1238,"trainrunSectionId":611,"positionIndex":5,"positionAlignment":3},{"id":1162,"trainrunSectionId":573,"positionIndex":6,"positionAlignment":3},{"id":1293,"trainrunSectionId":639,"positionIndex":7,"positionAlignment":3}],"transitions":[{"id":252,"port1Id":1163,"port2Id":1162,"isNonStopTransit":true},{"id":258,"port1Id":1179,"port2Id":1178,"isNonStopTransit":false},{"id":263,"port1Id":1201,"port2Id":1200,"isNonStopTransit":true},{"id":269,"port1Id":1223,"port2Id":1222,"isNonStopTransit":true},{"id":275,"port1Id":1239,"port2Id":1238,"isNonStopTransit":true},{"id":298,"port1Id":1284,"port2Id":1285,"isNonStopTransit":true},{"id":361,"port1Id":1409,"port2Id":1408,"isNonStopTransit":true}],"connections":[],"resourceId":171,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":148,"betriebspunktName":"Lenzburg","fullName":"Lenzburg","positionX":1344,"positionY":32,"ports":[{"id":1199,"trainrunSectionId":592,"positionIndex":0,"positionAlignment":2},{"id":1407,"trainrunSectionId":696,"positionIndex":1,"positionAlignment":2},{"id":1286,"trainrunSectionId":635,"positionIndex":2,"positionAlignment":2},{"id":1177,"trainrunSectionId":581,"positionIndex":3,"positionAlignment":2},{"id":1221,"trainrunSectionId":603,"positionIndex":4,"positionAlignment":2},{"id":1237,"trainrunSectionId":611,"positionIndex":5,"positionAlignment":2},{"id":1161,"trainrunSectionId":573,"positionIndex":6,"positionAlignment":2},{"id":1294,"trainrunSectionId":639,"positionIndex":7,"positionAlignment":2},{"id":1258,"trainrunSectionId":621,"positionIndex":0,"positionAlignment":3},{"id":1406,"trainrunSectionId":695,"positionIndex":1,"positionAlignment":3},{"id":1287,"trainrunSectionId":636,"positionIndex":2,"positionAlignment":3},{"id":1260,"trainrunSectionId":622,"positionIndex":3,"positionAlignment":3},{"id":1262,"trainrunSectionId":623,"positionIndex":4,"positionAlignment":3},{"id":1264,"trainrunSectionId":624,"positionIndex":5,"positionAlignment":3},{"id":1266,"trainrunSectionId":625,"positionIndex":6,"positionAlignment":3},{"id":1295,"trainrunSectionId":640,"positionIndex":7,"positionAlignment":3}],"transitions":[{"id":282,"port1Id":1199,"port2Id":1258,"isNonStopTransit":true},{"id":284,"port1Id":1177,"port2Id":1260,"isNonStopTransit":true},{"id":286,"port1Id":1221,"port2Id":1262,"isNonStopTransit":true},{"id":288,"port1Id":1237,"port2Id":1264,"isNonStopTransit":true},{"id":290,"port1Id":1161,"port2Id":1266,"isNonStopTransit":true},{"id":299,"port1Id":1286,"port2Id":1287,"isNonStopTransit":true},{"id":302,"port1Id":1294,"port2Id":1295,"isNonStopTransit":false},{"id":360,"port1Id":1407,"port2Id":1406,"isNonStopTransit":true}],"connections":[],"resourceId":172,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":149,"betriebspunktName":"Baden","fullName":"Baden","positionX":2240,"positionY":32,"ports":[{"id":1197,"trainrunSectionId":591,"positionIndex":0,"positionAlignment":2},{"id":1403,"trainrunSectionId":694,"positionIndex":1,"positionAlignment":2},{"id":1290,"trainrunSectionId":637,"positionIndex":2,"positionAlignment":2},{"id":1175,"trainrunSectionId":580,"positionIndex":3,"positionAlignment":2},{"id":1219,"trainrunSectionId":602,"positionIndex":4,"positionAlignment":2},{"id":1235,"trainrunSectionId":610,"positionIndex":5,"positionAlignment":2},{"id":1159,"trainrunSectionId":572,"positionIndex":6,"positionAlignment":2},{"id":1274,"trainrunSectionId":629,"positionIndex":7,"positionAlignment":2},{"id":1298,"trainrunSectionId":641,"positionIndex":8,"positionAlignment":2},{"id":1196,"trainrunSectionId":590,"positionIndex":0,"positionAlignment":3},{"id":1402,"trainrunSectionId":693,"positionIndex":1,"positionAlignment":3},{"id":1291,"trainrunSectionId":638,"positionIndex":2,"positionAlignment":3},{"id":1174,"trainrunSectionId":579,"positionIndex":3,"positionAlignment":3},{"id":1218,"trainrunSectionId":601,"positionIndex":4,"positionAlignment":3},{"id":1234,"trainrunSectionId":609,"positionIndex":5,"positionAlignment":3},{"id":1158,"trainrunSectionId":571,"positionIndex":6,"positionAlignment":3},{"id":1275,"trainrunSectionId":630,"positionIndex":7,"positionAlignment":3},{"id":1299,"trainrunSectionId":642,"positionIndex":8,"positionAlignment":3}],"transitions":[{"id":251,"port1Id":1159,"port2Id":1158,"isNonStopTransit":true},{"id":257,"port1Id":1175,"port2Id":1174,"isNonStopTransit":true},{"id":262,"port1Id":1197,"port2Id":1196,"isNonStopTransit":true},{"id":268,"port1Id":1219,"port2Id":1218,"isNonStopTransit":true},{"id":274,"port1Id":1235,"port2Id":1234,"isNonStopTransit":true},{"id":294,"port1Id":1274,"port2Id":1275,"isNonStopTransit":false},{"id":301,"port1Id":1290,"port2Id":1291,"isNonStopTransit":true},{"id":304,"port1Id":1298,"port2Id":1299,"isNonStopTransit":true},{"id":358,"port1Id":1403,"port2Id":1402,"isNonStopTransit":true}],"connections":[],"resourceId":173,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":150,"betriebspunktName":"Zürich ✈","fullName":"Zürich Flughafen","positionX":3296,"positionY":32,"ports":[{"id":1192,"trainrunSectionId":588,"positionIndex":0,"positionAlignment":2},{"id":1171,"trainrunSectionId":578,"positionIndex":1,"positionAlignment":2},{"id":1214,"trainrunSectionId":599,"positionIndex":2,"positionAlignment":2},{"id":1230,"trainrunSectionId":607,"positionIndex":3,"positionAlignment":2},{"id":1140,"trainrunSectionId":562,"positionIndex":4,"positionAlignment":2},{"id":1246,"trainrunSectionId":615,"positionIndex":5,"positionAlignment":2},{"id":1193,"trainrunSectionId":589,"positionIndex":0,"positionAlignment":3},{"id":1170,"trainrunSectionId":577,"positionIndex":1,"positionAlignment":3},{"id":1215,"trainrunSectionId":600,"positionIndex":2,"positionAlignment":3},{"id":1231,"trainrunSectionId":608,"positionIndex":3,"positionAlignment":3},{"id":1141,"trainrunSectionId":563,"positionIndex":4,"positionAlignment":3},{"id":1247,"trainrunSectionId":616,"positionIndex":5,"positionAlignment":3}],"transitions":[{"id":246,"port1Id":1140,"port2Id":1141,"isNonStopTransit":false},{"id":255,"port1Id":1171,"port2Id":1170,"isNonStopTransit":false},{"id":260,"port1Id":1192,"port2Id":1193,"isNonStopTransit":false},{"id":266,"port1Id":1214,"port2Id":1215,"isNonStopTransit":false},{"id":272,"port1Id":1230,"port2Id":1231,"isNonStopTransit":false},{"id":278,"port1Id":1246,"port2Id":1247,"isNonStopTransit":false}],"connections":[],"resourceId":174,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":151,"betriebspunktName":"Wintert.","fullName":"Winterthur","positionX":3872,"positionY":32,"ports":[{"id":1249,"trainrunSectionId":617,"positionIndex":0,"positionAlignment":0},{"id":1194,"trainrunSectionId":589,"positionIndex":0,"positionAlignment":2},{"id":1169,"trainrunSectionId":577,"positionIndex":1,"positionAlignment":2},{"id":1216,"trainrunSectionId":600,"positionIndex":2,"positionAlignment":2},{"id":1232,"trainrunSectionId":608,"positionIndex":3,"positionAlignment":2},{"id":1142,"trainrunSectionId":563,"positionIndex":4,"positionAlignment":2},{"id":1248,"trainrunSectionId":616,"positionIndex":5,"positionAlignment":2},{"id":1227,"trainrunSectionId":606,"positionIndex":0,"positionAlignment":3},{"id":1243,"trainrunSectionId":614,"positionIndex":1,"positionAlignment":3},{"id":1211,"trainrunSectionId":598,"positionIndex":2,"positionAlignment":3},{"id":1168,"trainrunSectionId":576,"positionIndex":3,"positionAlignment":3},{"id":1143,"trainrunSectionId":564,"positionIndex":4,"positionAlignment":3}],"transitions":[{"id":247,"port1Id":1142,"port2Id":1143,"isNonStopTransit":false},{"id":254,"port1Id":1169,"port2Id":1168,"isNonStopTransit":false},{"id":265,"port1Id":1194,"port2Id":1211,"isNonStopTransit":false},{"id":271,"port1Id":1216,"port2Id":1227,"isNonStopTransit":false},{"id":277,"port1Id":1232,"port2Id":1243,"isNonStopTransit":false},{"id":279,"port1Id":1249,"port2Id":1248,"isNonStopTransit":false}],"connections":[],"resourceId":175,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":152,"betriebspunktName":"Chur","fullName":"Chur","positionX":4640,"positionY":1888,"ports":[{"id":1152,"trainrunSectionId":568,"positionIndex":0,"positionAlignment":0},{"id":1148,"trainrunSectionId":566,"positionIndex":1,"positionAlignment":0},{"id":1156,"trainrunSectionId":570,"positionIndex":2,"positionAlignment":0}],"transitions":[],"connections":[],"resourceId":176,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":153,"betriebspunktName":"Zug","fullName":"Zug","positionX":2656,"positionY":1312,"ports":[{"id":1067,"trainrunSectionId":526,"positionIndex":0,"positionAlignment":0},{"id":1093,"trainrunSectionId":539,"positionIndex":1,"positionAlignment":0},{"id":1101,"trainrunSectionId":543,"positionIndex":2,"positionAlignment":0},{"id":1097,"trainrunSectionId":541,"positionIndex":3,"positionAlignment":0},{"id":1066,"trainrunSectionId":525,"positionIndex":0,"positionAlignment":1},{"id":1092,"trainrunSectionId":538,"positionIndex":1,"positionAlignment":1},{"id":1348,"trainrunSectionId":666,"positionIndex":0,"positionAlignment":2},{"id":1346,"trainrunSectionId":665,"positionIndex":1,"positionAlignment":2}],"transitions":[{"id":220,"port1Id":1067,"port2Id":1066,"isNonStopTransit":false},{"id":231,"port1Id":1093,"port2Id":1092,"isNonStopTransit":false},{"id":322,"port1Id":1097,"port2Id":1346,"isNonStopTransit":false},{"id":324,"port1Id":1101,"port2Id":1348,"isNonStopTransit":false}],"connections":[],"resourceId":177,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":154,"betriebspunktName":"Arth-G.","fullName":"Arth-Goldau","positionX":2656,"positionY":1792,"ports":[{"id":1065,"trainrunSectionId":525,"positionIndex":0,"positionAlignment":0},{"id":1091,"trainrunSectionId":538,"positionIndex":1,"positionAlignment":0},{"id":1064,"trainrunSectionId":524,"positionIndex":0,"positionAlignment":1},{"id":1038,"trainrunSectionId":511,"positionIndex":1,"positionAlignment":1},{"id":1078,"trainrunSectionId":531,"positionIndex":2,"positionAlignment":1},{"id":1090,"trainrunSectionId":537,"positionIndex":3,"positionAlignment":1},{"id":1039,"trainrunSectionId":512,"positionIndex":0,"positionAlignment":2},{"id":1079,"trainrunSectionId":532,"positionIndex":1,"positionAlignment":2}],"transitions":[{"id":207,"port1Id":1038,"port2Id":1039,"isNonStopTransit":false},{"id":219,"port1Id":1065,"port2Id":1064,"isNonStopTransit":false},{"id":225,"port1Id":1078,"port2Id":1079,"isNonStopTransit":false},{"id":230,"port1Id":1091,"port2Id":1090,"isNonStopTransit":false}],"connections":[],"resourceId":178,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":155,"betriebspunktName":"Altdorf","fullName":"Altdorf","positionX":2656,"positionY":2176,"ports":[{"id":1063,"trainrunSectionId":524,"positionIndex":0,"positionAlignment":0},{"id":1037,"trainrunSectionId":511,"positionIndex":1,"positionAlignment":0},{"id":1077,"trainrunSectionId":531,"positionIndex":2,"positionAlignment":0},{"id":1089,"trainrunSectionId":537,"positionIndex":3,"positionAlignment":0},{"id":1062,"trainrunSectionId":523,"positionIndex":0,"positionAlignment":1},{"id":1055,"trainrunSectionId":520,"positionIndex":1,"positionAlignment":1},{"id":1076,"trainrunSectionId":530,"positionIndex":0,"positionAlignment":2},{"id":1088,"trainrunSectionId":536,"positionIndex":1,"positionAlignment":2}],"transitions":[{"id":214,"port1Id":1037,"port2Id":1055,"isNonStopTransit":true},{"id":218,"port1Id":1063,"port2Id":1062,"isNonStopTransit":false},{"id":224,"port1Id":1077,"port2Id":1076,"isNonStopTransit":false},{"id":229,"port1Id":1089,"port2Id":1088,"isNonStopTransit":false}],"connections":[],"resourceId":179,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":156,"betriebspunktName":"Lugano","fullName":"Lugano","positionX":2592,"positionY":3712,"ports":[{"id":1057,"trainrunSectionId":521,"positionIndex":0,"positionAlignment":0},{"id":1033,"trainrunSectionId":509,"positionIndex":1,"positionAlignment":0}],"transitions":[],"connections":[],"resourceId":180,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":157,"betriebspunktName":"Locarno","fullName":"Locarno","positionX":2208,"positionY":3232,"ports":[{"id":1069,"trainrunSectionId":527,"positionIndex":0,"positionAlignment":3},{"id":1081,"trainrunSectionId":533,"positionIndex":1,"positionAlignment":3}],"transitions":[],"connections":[],"resourceId":181,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":158,"betriebspunktName":"Biasca","fullName":"Biasca","positionX":2592,"positionY":2688,"ports":[{"id":1073,"trainrunSectionId":529,"positionIndex":0,"positionAlignment":0},{"id":1085,"trainrunSectionId":535,"positionIndex":1,"positionAlignment":0},{"id":1061,"trainrunSectionId":523,"positionIndex":2,"positionAlignment":0},{"id":1056,"trainrunSectionId":520,"positionIndex":3,"positionAlignment":0},{"id":1060,"trainrunSectionId":522,"positionIndex":0,"positionAlignment":1},{"id":1036,"trainrunSectionId":510,"positionIndex":1,"positionAlignment":1},{"id":1072,"trainrunSectionId":528,"positionIndex":2,"positionAlignment":1},{"id":1084,"trainrunSectionId":534,"positionIndex":3,"positionAlignment":1}],"transitions":[{"id":215,"port1Id":1056,"port2Id":1036,"isNonStopTransit":true},{"id":217,"port1Id":1061,"port2Id":1060,"isNonStopTransit":true},{"id":222,"port1Id":1073,"port2Id":1072,"isNonStopTransit":false},{"id":227,"port1Id":1085,"port2Id":1084,"isNonStopTransit":false}],"connections":[],"resourceId":182,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":159,"betriebspunktName":"Göschn.","fullName":"Göschenen","positionX":2272,"positionY":2240,"ports":[{"id":1074,"trainrunSectionId":529,"positionIndex":0,"positionAlignment":1},{"id":1086,"trainrunSectionId":535,"positionIndex":1,"positionAlignment":1},{"id":1075,"trainrunSectionId":530,"positionIndex":0,"positionAlignment":3},{"id":1087,"trainrunSectionId":536,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":223,"port1Id":1074,"port2Id":1075,"isNonStopTransit":false},{"id":228,"port1Id":1086,"port2Id":1087,"isNonStopTransit":false}],"connections":[],"resourceId":183,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":160,"betriebspunktName":"Genf","fullName":"Genf","positionX":-3936,"positionY":608,"ports":[{"id":1209,"trainrunSectionId":597,"positionIndex":0,"positionAlignment":2},{"id":1185,"trainrunSectionId":585,"positionIndex":1,"positionAlignment":2},{"id":1189,"trainrunSectionId":587,"positionIndex":2,"positionAlignment":2},{"id":1424,"trainrunSectionId":704,"positionIndex":0,"positionAlignment":3},{"id":1426,"trainrunSectionId":705,"positionIndex":1,"positionAlignment":3},{"id":1422,"trainrunSectionId":703,"positionIndex":2,"positionAlignment":3}],"transitions":[{"id":369,"port1Id":1189,"port2Id":1422,"isNonStopTransit":false},{"id":371,"port1Id":1209,"port2Id":1424,"isNonStopTransit":false},{"id":373,"port1Id":1185,"port2Id":1426,"isNonStopTransit":false}],"connections":[],"resourceId":184,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":161,"betriebspunktName":"Genf ✈","fullName":"Aiport","positionX":-4352,"positionY":608,"ports":[{"id":1210,"trainrunSectionId":597,"positionIndex":0,"positionAlignment":3},{"id":1186,"trainrunSectionId":585,"positionIndex":1,"positionAlignment":3},{"id":1190,"trainrunSectionId":587,"positionIndex":2,"positionAlignment":3}],"transitions":[],"connections":[],"resourceId":185,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":162,"betriebspunktName":"Romansh.","fullName":"Romanshorn","positionX":4640,"positionY":-192,"ports":[{"id":1228,"trainrunSectionId":606,"positionIndex":0,"positionAlignment":2},{"id":1244,"trainrunSectionId":614,"positionIndex":1,"positionAlignment":2}],"transitions":[],"connections":[],"resourceId":186,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":163,"betriebspunktName":"Bülach","fullName":"Bülach","positionX":2784,"positionY":-544,"ports":[{"id":1252,"trainrunSectionId":618,"positionIndex":0,"positionAlignment":0},{"id":1253,"trainrunSectionId":619,"positionIndex":0,"positionAlignment":1}],"transitions":[{"id":280,"port1Id":1252,"port2Id":1253,"isNonStopTransit":false}],"connections":[],"resourceId":187,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":164,"betriebspunktName":"Reihnf.","fullName":"Reihnfelden","positionX":1056,"positionY":-960,"ports":[{"id":1268,"trainrunSectionId":626,"positionIndex":0,"positionAlignment":2},{"id":1269,"trainrunSectionId":627,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":291,"port1Id":1268,"port2Id":1269,"isNonStopTransit":false}],"connections":[],"resourceId":188,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":165,"betriebspunktName":"Frick","fullName":"Frick","positionX":1792,"positionY":-672,"ports":[{"id":1271,"trainrunSectionId":628,"positionIndex":0,"positionAlignment":1},{"id":1270,"trainrunSectionId":627,"positionIndex":0,"positionAlignment":2}],"transitions":[{"id":292,"port1Id":1271,"port2Id":1270,"isNonStopTransit":false}],"connections":[],"resourceId":189,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":166,"betriebspunktName":"Brugg","fullName":"Brugg","positionX":1792,"positionY":32,"ports":[{"id":1272,"trainrunSectionId":628,"positionIndex":0,"positionAlignment":0},{"id":1257,"trainrunSectionId":621,"positionIndex":0,"positionAlignment":2},{"id":1405,"trainrunSectionId":695,"positionIndex":1,"positionAlignment":2},{"id":1288,"trainrunSectionId":636,"positionIndex":2,"positionAlignment":2},{"id":1259,"trainrunSectionId":622,"positionIndex":3,"positionAlignment":2},{"id":1261,"trainrunSectionId":623,"positionIndex":4,"positionAlignment":2},{"id":1263,"trainrunSectionId":624,"positionIndex":5,"positionAlignment":2},{"id":1265,"trainrunSectionId":625,"positionIndex":6,"positionAlignment":2},{"id":1296,"trainrunSectionId":640,"positionIndex":7,"positionAlignment":2},{"id":1198,"trainrunSectionId":591,"positionIndex":0,"positionAlignment":3},{"id":1404,"trainrunSectionId":694,"positionIndex":1,"positionAlignment":3},{"id":1289,"trainrunSectionId":637,"positionIndex":2,"positionAlignment":3},{"id":1176,"trainrunSectionId":580,"positionIndex":3,"positionAlignment":3},{"id":1220,"trainrunSectionId":602,"positionIndex":4,"positionAlignment":3},{"id":1236,"trainrunSectionId":610,"positionIndex":5,"positionAlignment":3},{"id":1160,"trainrunSectionId":572,"positionIndex":6,"positionAlignment":3},{"id":1273,"trainrunSectionId":629,"positionIndex":7,"positionAlignment":3},{"id":1297,"trainrunSectionId":641,"positionIndex":8,"positionAlignment":3}],"transitions":[{"id":281,"port1Id":1257,"port2Id":1198,"isNonStopTransit":true},{"id":283,"port1Id":1259,"port2Id":1176,"isNonStopTransit":true},{"id":285,"port1Id":1261,"port2Id":1220,"isNonStopTransit":true},{"id":287,"port1Id":1263,"port2Id":1236,"isNonStopTransit":false},{"id":289,"port1Id":1265,"port2Id":1160,"isNonStopTransit":true},{"id":293,"port1Id":1272,"port2Id":1273,"isNonStopTransit":false},{"id":300,"port1Id":1288,"port2Id":1289,"isNonStopTransit":true},{"id":303,"port1Id":1296,"port2Id":1297,"isNonStopTransit":true},{"id":359,"port1Id":1405,"port2Id":1404,"isNonStopTransit":true}],"connections":[],"resourceId":190,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":167,"betriebspunktName":"Thun","fullName":"Thun","positionX":-2144,"positionY":640,"ports":[{"id":1327,"trainrunSectionId":656,"positionIndex":0,"positionAlignment":0},{"id":1312,"trainrunSectionId":648,"positionIndex":1,"positionAlignment":0},{"id":1314,"trainrunSectionId":649,"positionIndex":2,"positionAlignment":0},{"id":1340,"trainrunSectionId":662,"positionIndex":3,"positionAlignment":0},{"id":1326,"trainrunSectionId":655,"positionIndex":0,"positionAlignment":1},{"id":1315,"trainrunSectionId":650,"positionIndex":1,"positionAlignment":1},{"id":1319,"trainrunSectionId":652,"positionIndex":2,"positionAlignment":1},{"id":1341,"trainrunSectionId":663,"positionIndex":3,"positionAlignment":1}],"transitions":[{"id":309,"port1Id":1312,"port2Id":1315,"isNonStopTransit":false},{"id":311,"port1Id":1314,"port2Id":1319,"isNonStopTransit":false},{"id":314,"port1Id":1327,"port2Id":1326,"isNonStopTransit":false},{"id":319,"port1Id":1340,"port2Id":1341,"isNonStopTransit":false}],"connections":[],"resourceId":191,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":168,"betriebspunktName":"Spiez","fullName":"Spiez","positionX":-2144,"positionY":928,"ports":[{"id":1325,"trainrunSectionId":655,"positionIndex":0,"positionAlignment":0},{"id":1316,"trainrunSectionId":650,"positionIndex":1,"positionAlignment":0},{"id":1320,"trainrunSectionId":652,"positionIndex":2,"positionAlignment":0},{"id":1342,"trainrunSectionId":663,"positionIndex":3,"positionAlignment":0},{"id":1324,"trainrunSectionId":654,"positionIndex":0,"positionAlignment":1},{"id":1321,"trainrunSectionId":653,"positionIndex":1,"positionAlignment":1},{"id":1317,"trainrunSectionId":651,"positionIndex":0,"positionAlignment":3},{"id":1343,"trainrunSectionId":664,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":310,"port1Id":1316,"port2Id":1317,"isNonStopTransit":false},{"id":312,"port1Id":1320,"port2Id":1321,"isNonStopTransit":false},{"id":313,"port1Id":1325,"port2Id":1324,"isNonStopTransit":false},{"id":320,"port1Id":1342,"port2Id":1343,"isNonStopTransit":false}],"connections":[],"resourceId":192,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":169,"betriebspunktName":"Rothkr.","fullName":"Rothkreuz","positionX":1856,"positionY":1728,"ports":[{"id":1351,"trainrunSectionId":668,"positionIndex":0,"positionAlignment":2},{"id":1349,"trainrunSectionId":667,"positionIndex":1,"positionAlignment":2},{"id":1100,"trainrunSectionId":542,"positionIndex":2,"positionAlignment":2},{"id":1096,"trainrunSectionId":540,"positionIndex":3,"positionAlignment":2},{"id":1347,"trainrunSectionId":666,"positionIndex":0,"positionAlignment":3},{"id":1345,"trainrunSectionId":665,"positionIndex":1,"positionAlignment":3},{"id":1040,"trainrunSectionId":512,"positionIndex":2,"positionAlignment":3},{"id":1080,"trainrunSectionId":532,"positionIndex":3,"positionAlignment":3}],"transitions":[{"id":321,"port1Id":1096,"port2Id":1345,"isNonStopTransit":false},{"id":323,"port1Id":1100,"port2Id":1347,"isNonStopTransit":true},{"id":325,"port1Id":1349,"port2Id":1080,"isNonStopTransit":true},{"id":326,"port1Id":1351,"port2Id":1040,"isNonStopTransit":true}],"connections":[],"resourceId":193,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":170,"betriebspunktName":"Thalwil","fullName":"Thalwil","positionX":2656,"positionY":736,"ports":[{"id":1359,"trainrunSectionId":672,"positionIndex":0,"positionAlignment":0},{"id":1150,"trainrunSectionId":567,"positionIndex":1,"positionAlignment":0},{"id":1154,"trainrunSectionId":569,"positionIndex":2,"positionAlignment":0},{"id":1357,"trainrunSectionId":671,"positionIndex":3,"positionAlignment":0},{"id":1355,"trainrunSectionId":670,"positionIndex":4,"positionAlignment":0},{"id":1353,"trainrunSectionId":669,"positionIndex":5,"positionAlignment":0},{"id":1068,"trainrunSectionId":526,"positionIndex":0,"positionAlignment":1},{"id":1094,"trainrunSectionId":539,"positionIndex":1,"positionAlignment":1},{"id":1102,"trainrunSectionId":543,"positionIndex":2,"positionAlignment":1},{"id":1098,"trainrunSectionId":541,"positionIndex":3,"positionAlignment":1},{"id":1361,"trainrunSectionId":673,"positionIndex":0,"positionAlignment":3},{"id":1363,"trainrunSectionId":674,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":328,"port1Id":1353,"port2Id":1098,"isNonStopTransit":false},{"id":330,"port1Id":1355,"port2Id":1102,"isNonStopTransit":true},{"id":331,"port1Id":1357,"port2Id":1094,"isNonStopTransit":true},{"id":332,"port1Id":1359,"port2Id":1068,"isNonStopTransit":true},{"id":333,"port1Id":1150,"port2Id":1361,"isNonStopTransit":true},{"id":335,"port1Id":1154,"port2Id":1363,"isNonStopTransit":false}],"connections":[],"resourceId":194,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":171,"betriebspunktName":"Fribourg","fullName":"Fribourg","positionX":-2560,"positionY":288,"ports":[{"id":1381,"trainrunSectionId":683,"positionIndex":0,"positionAlignment":2},{"id":1379,"trainrunSectionId":682,"positionIndex":1,"positionAlignment":2},{"id":1206,"trainrunSectionId":595,"positionIndex":0,"positionAlignment":3},{"id":1110,"trainrunSectionId":547,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":344,"port1Id":1379,"port2Id":1110,"isNonStopTransit":false},{"id":346,"port1Id":1381,"port2Id":1206,"isNonStopTransit":false}],"connections":[],"resourceId":195,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":172,"betriebspunktName":"RTR","fullName":"Rothrist","positionX":-608,"positionY":128,"ports":[{"id":1395,"trainrunSectionId":690,"positionIndex":0,"positionAlignment":2},{"id":1438,"trainrunSectionId":711,"positionIndex":1,"positionAlignment":2},{"id":1391,"trainrunSectionId":688,"positionIndex":2,"positionAlignment":2},{"id":1389,"trainrunSectionId":687,"positionIndex":3,"positionAlignment":2},{"id":1387,"trainrunSectionId":686,"positionIndex":4,"positionAlignment":2},{"id":1383,"trainrunSectionId":684,"positionIndex":5,"positionAlignment":2},{"id":1385,"trainrunSectionId":685,"positionIndex":6,"positionAlignment":2},{"id":1204,"trainrunSectionId":594,"positionIndex":0,"positionAlignment":3},{"id":1393,"trainrunSectionId":689,"positionIndex":1,"positionAlignment":3},{"id":1310,"trainrunSectionId":647,"positionIndex":2,"positionAlignment":3},{"id":1226,"trainrunSectionId":605,"positionIndex":3,"positionAlignment":3},{"id":1242,"trainrunSectionId":613,"positionIndex":4,"positionAlignment":3},{"id":1166,"trainrunSectionId":575,"positionIndex":5,"positionAlignment":3},{"id":1108,"trainrunSectionId":546,"positionIndex":6,"positionAlignment":3}],"transitions":[{"id":348,"port1Id":1108,"port2Id":1383,"isNonStopTransit":true},{"id":349,"port1Id":1385,"port2Id":1166,"isNonStopTransit":true},{"id":350,"port1Id":1387,"port2Id":1242,"isNonStopTransit":true},{"id":351,"port1Id":1389,"port2Id":1226,"isNonStopTransit":true},{"id":352,"port1Id":1391,"port2Id":1310,"isNonStopTransit":true},{"id":354,"port1Id":1395,"port2Id":1204,"isNonStopTransit":true},{"id":384,"port1Id":1438,"port2Id":1393,"isNonStopTransit":true}],"connections":[],"resourceId":196,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":173,"betriebspunktName":"Burgdorf","fullName":"Burgdorf","positionX":-1344,"positionY":352,"ports":[{"id":1397,"trainrunSectionId":691,"positionIndex":0,"positionAlignment":2},{"id":1400,"trainrunSectionId":692,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":356,"port1Id":1397,"port2Id":1400,"isNonStopTransit":false}],"connections":[],"resourceId":197,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":174,"betriebspunktName":"Langent.","fullName":"Langenthal","positionX":-992,"positionY":352,"ports":[{"id":1399,"trainrunSectionId":692,"positionIndex":0,"positionAlignment":2},{"id":1386,"trainrunSectionId":685,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":355,"port1Id":1399,"port2Id":1386,"isNonStopTransit":false}],"connections":[],"resourceId":198,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":175,"betriebspunktName":"Solothurn","fullName":"Solothurn","positionX":-1696,"positionY":-32,"ports":[{"id":1417,"trainrunSectionId":701,"positionIndex":0,"positionAlignment":2},{"id":1182,"trainrunSectionId":583,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":365,"port1Id":1417,"port2Id":1182,"isNonStopTransit":false}],"connections":[],"resourceId":199,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":176,"betriebspunktName":"Rohrsch.","fullName":"Rohrschach","positionX":5376,"positionY":96,"ports":[{"id":1420,"trainrunSectionId":702,"positionIndex":0,"positionAlignment":2}],"transitions":[],"connections":[],"resourceId":200,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":177,"betriebspunktName":"Morges","fullName":"Morges","positionX":-3520,"positionY":544,"ports":[{"id":1423,"trainrunSectionId":704,"positionIndex":0,"positionAlignment":2},{"id":1425,"trainrunSectionId":705,"positionIndex":1,"positionAlignment":2},{"id":1421,"trainrunSectionId":703,"positionIndex":2,"positionAlignment":2},{"id":1184,"trainrunSectionId":584,"positionIndex":0,"positionAlignment":3},{"id":1208,"trainrunSectionId":596,"positionIndex":1,"positionAlignment":3},{"id":1188,"trainrunSectionId":586,"positionIndex":2,"positionAlignment":3}],"transitions":[{"id":368,"port1Id":1421,"port2Id":1188,"isNonStopTransit":false},{"id":370,"port1Id":1423,"port2Id":1208,"isNonStopTransit":true},{"id":372,"port1Id":1425,"port2Id":1184,"isNonStopTransit":false}],"connections":[],"resourceId":201,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":178,"betriebspunktName":"BNWD","fullName":"Bern Wankdorf","positionX":-1696,"positionY":128,"ports":[{"id":1439,"trainrunSectionId":712,"positionIndex":0,"positionAlignment":2},{"id":1330,"trainrunSectionId":657,"positionIndex":1,"positionAlignment":2},{"id":1435,"trainrunSectionId":710,"positionIndex":2,"positionAlignment":2},{"id":1433,"trainrunSectionId":709,"positionIndex":3,"positionAlignment":2},{"id":1431,"trainrunSectionId":708,"positionIndex":4,"positionAlignment":2},{"id":1429,"trainrunSectionId":707,"positionIndex":5,"positionAlignment":2},{"id":1427,"trainrunSectionId":706,"positionIndex":6,"positionAlignment":2},{"id":1396,"trainrunSectionId":690,"positionIndex":0,"positionAlignment":3},{"id":1437,"trainrunSectionId":711,"positionIndex":1,"positionAlignment":3},{"id":1392,"trainrunSectionId":688,"positionIndex":2,"positionAlignment":3},{"id":1390,"trainrunSectionId":687,"positionIndex":3,"positionAlignment":3},{"id":1388,"trainrunSectionId":686,"positionIndex":4,"positionAlignment":3},{"id":1384,"trainrunSectionId":684,"positionIndex":5,"positionAlignment":3},{"id":1398,"trainrunSectionId":691,"positionIndex":6,"positionAlignment":3}],"transitions":[{"id":374,"port1Id":1427,"port2Id":1398,"isNonStopTransit":true},{"id":375,"port1Id":1429,"port2Id":1384,"isNonStopTransit":true},{"id":377,"port1Id":1431,"port2Id":1388,"isNonStopTransit":true},{"id":379,"port1Id":1433,"port2Id":1390,"isNonStopTransit":true},{"id":381,"port1Id":1435,"port2Id":1392,"isNonStopTransit":true},{"id":383,"port1Id":1330,"port2Id":1437,"isNonStopTransit":true},{"id":385,"port1Id":1439,"port2Id":1396,"isNonStopTransit":true}],"connections":[],"resourceId":202,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]}],"trainrunSections":[{"id":509,"sourceNodeId":156,"sourcePortId":1033,"targetNodeId":136,"targetPortId":1034,"travelTime":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":182},"sourceArrival":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":178},"targetDeparture":{"lock":false,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":164},"targetArrival":{"lock":false,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":196},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2640,"y":3710},{"x":2640,"y":3646},{"x":2640,"y":3390},{"x":2640,"y":3326}],"textPositions":{"0":{"x":2652,"y":3692},"1":{"x":2628,"y":3664},"2":{"x":2628,"y":3344},"3":{"x":2652,"y":3372},"4":{"x":2628,"y":3518},"5":{"x":2628,"y":3518},"6":{"x":2652,"y":3518}}},"warnings":null},{"id":510,"sourceNodeId":136,"sourcePortId":1035,"targetNodeId":158,"targetPortId":1036,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":198},"sourceArrival":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":162},"targetDeparture":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":156},"targetArrival":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":204},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2640,"y":3230},{"x":2640,"y":3166},{"x":2640,"y":2818},{"x":2640,"y":2754}],"textPositions":{"0":{"x":2652,"y":3212},"1":{"x":2628,"y":3184},"2":{"x":2628,"y":2772},"3":{"x":2652,"y":2800},"4":{"x":2628,"y":2992},"5":{"x":2628,"y":2992},"6":{"x":2652,"y":2992}}},"warnings":null},{"id":511,"sourceNodeId":155,"sourcePortId":1037,"targetNodeId":154,"targetPortId":1038,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":232},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":128},"targetDeparture":{"lock":true,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":109},"targetArrival":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":251},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":2174},{"x":2704,"y":2110},{"x":2704,"y":1950},{"x":2704,"y":1886}],"textPositions":{"0":{"x":2716,"y":2156},"1":{"x":2692,"y":2128},"2":{"x":2692,"y":1904},"3":{"x":2716,"y":1932},"4":{"x":2692,"y":2030},"5":{"x":2692,"y":2030},"6":{"x":2716,"y":2030}}},"warnings":null},{"id":512,"sourceNodeId":154,"sourcePortId":1039,"targetNodeId":169,"targetPortId":1040,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":255},"sourceArrival":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":105},"targetDeparture":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":87},"targetArrival":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":273},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":1808},{"x":2590,"y":1808},{"x":2018,"y":1808},{"x":1954,"y":1808}],"textPositions":{"0":{"x":2636,"y":1796},"1":{"x":2608,"y":1820},"2":{"x":1972,"y":1820},"3":{"x":2000,"y":1796},"4":{"x":2304,"y":1796},"5":{"x":2304,"y":1796},"6":{"x":2304,"y":1820}}},"warnings":null},{"id":513,"sourceNodeId":142,"sourcePortId":1041,"targetNodeId":141,"targetPortId":1042,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":295},"sourceArrival":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":1726},{"x":80,"y":1662},{"x":80,"y":1314},{"x":80,"y":1250}],"textPositions":{"0":{"x":92,"y":1708},"1":{"x":68,"y":1680},"2":{"x":68,"y":1268},"3":{"x":92,"y":1296},"4":{"x":68,"y":1488},"5":{"x":68,"y":1488},"6":{"x":92,"y":1488}}},"warnings":null},{"id":514,"sourceNodeId":141,"sourcePortId":1043,"targetNodeId":143,"targetPortId":1044,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"sourceArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetDeparture":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":37},"targetArrival":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":323},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":1182},{"x":80,"y":1118},{"x":80,"y":866},{"x":80,"y":802}],"textPositions":{"0":{"x":92,"y":1164},"1":{"x":68,"y":1136},"2":{"x":68,"y":820},"3":{"x":92,"y":848},"4":{"x":68,"y":992},"5":{"x":68,"y":992},"6":{"x":92,"y":992}}},"warnings":null},{"id":515,"sourceNodeId":143,"sourcePortId":1045,"targetNodeId":133,"targetPortId":1046,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":323},"sourceArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":37},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":30},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":734},{"x":80,"y":670},{"x":80,"y":414},{"x":80,"y":350}],"textPositions":{"0":{"x":92,"y":716},"1":{"x":68,"y":688},"2":{"x":68,"y":368},"3":{"x":92,"y":396},"4":{"x":68,"y":542},"5":{"x":68,"y":542},"6":{"x":92,"y":542}}},"warnings":null},{"id":516,"sourceNodeId":133,"sourcePortId":1047,"targetNodeId":144,"targetPortId":1048,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":332},"sourceArrival":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":28},"targetDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"targetArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":342},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":94},{"x":80,"y":30},{"x":80,"y":-290},{"x":80,"y":-354}],"textPositions":{"0":{"x":92,"y":76},"1":{"x":68,"y":48},"2":{"x":68,"y":-336},"3":{"x":92,"y":-308},"4":{"x":68,"y":-130},"5":{"x":68,"y":-130},"6":{"x":92,"y":-130}}},"warnings":null},{"id":517,"sourceNodeId":144,"sourcePortId":1049,"targetNodeId":145,"targetPortId":1050,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":342},"sourceArrival":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":-450},{"x":80,"y":-514},{"x":80,"y":-798},{"x":80,"y":-862}],"textPositions":{"0":{"x":92,"y":-468},"1":{"x":68,"y":-496},"2":{"x":68,"y":-844},"3":{"x":92,"y":-816},"4":{"x":68,"y":-656},"5":{"x":68,"y":-656},"6":{"x":92,"y":-656}}},"warnings":null},{"id":518,"sourceNodeId":145,"sourcePortId":1051,"targetNodeId":146,"targetPortId":1052,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":8},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":352},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":-930},{"x":80,"y":-994},{"x":80,"y":-1278},{"x":80,"y":-1342}],"textPositions":{"0":{"x":92,"y":-948},"1":{"x":68,"y":-976},"2":{"x":68,"y":-1324},"3":{"x":92,"y":-1296},"4":{"x":68,"y":-1136},"5":{"x":68,"y":-1136},"6":{"x":92,"y":-1136}}},"warnings":null},{"id":519,"sourceNodeId":146,"sourcePortId":1053,"targetNodeId":134,"targetPortId":1054,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":352},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":8},"targetDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":3},"targetArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":357},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":-1410},{"x":80,"y":-1474},{"x":80,"y":-1758},{"x":80,"y":-1822}],"textPositions":{"0":{"x":92,"y":-1428},"1":{"x":68,"y":-1456},"2":{"x":68,"y":-1804},"3":{"x":92,"y":-1776},"4":{"x":68,"y":-1616},"5":{"x":68,"y":-1616},"6":{"x":92,"y":-1616}}},"warnings":null},{"id":520,"sourceNodeId":155,"sourcePortId":1055,"targetNodeId":158,"targetPortId":1056,"travelTime":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":128},"sourceArrival":{"lock":true,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":232},"targetDeparture":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":204},"targetArrival":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":156},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":2270},{"x":2704,"y":2334},{"x":2704,"y":2622},{"x":2704,"y":2686}],"textPositions":{"0":{"x":2692,"y":2288},"1":{"x":2716,"y":2316},"2":{"x":2716,"y":2668},"3":{"x":2692,"y":2640},"4":{"x":2692,"y":2478},"5":{"x":2692,"y":2478},"6":{"x":2716,"y":2478}}},"warnings":null},{"id":521,"sourceNodeId":156,"sourcePortId":1057,"targetNodeId":136,"targetPortId":1058,"travelTime":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":2},"sourceArrival":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":118},"targetDeparture":{"lock":false,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":104},"targetArrival":{"lock":false,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":16},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2608,"y":3710},{"x":2608,"y":3646},{"x":2608,"y":3390},{"x":2608,"y":3326}],"textPositions":{"0":{"x":2620,"y":3692},"1":{"x":2596,"y":3664},"2":{"x":2596,"y":3344},"3":{"x":2620,"y":3372},"4":{"x":2596,"y":3518},"5":{"x":2596,"y":3518},"6":{"x":2620,"y":3518}}},"warnings":null},{"id":522,"sourceNodeId":136,"sourcePortId":1059,"targetNodeId":158,"targetPortId":1060,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"sourceArrival":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":102},"targetDeparture":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":96},"targetArrival":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":24},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2608,"y":3230},{"x":2608,"y":3166},{"x":2608,"y":2818},{"x":2608,"y":2754}],"textPositions":{"0":{"x":2620,"y":3212},"1":{"x":2596,"y":3184},"2":{"x":2596,"y":2772},"3":{"x":2620,"y":2800},"4":{"x":2596,"y":2992},"5":{"x":2596,"y":2992},"6":{"x":2620,"y":2992}}},"warnings":null},{"id":523,"sourceNodeId":158,"sourcePortId":1061,"targetNodeId":155,"targetPortId":1062,"travelTime":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":24},"sourceArrival":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":96},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":2686},{"x":2672,"y":2622},{"x":2672,"y":2334},{"x":2672,"y":2270}],"textPositions":{"0":{"x":2684,"y":2668},"1":{"x":2660,"y":2640},"2":{"x":2660,"y":2288},"3":{"x":2684,"y":2316},"4":{"x":2660,"y":2478},"5":{"x":2660,"y":2478},"6":{"x":2684,"y":2478}}},"warnings":null},{"id":524,"sourceNodeId":155,"sourcePortId":1063,"targetNodeId":154,"targetPortId":1064,"travelTime":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetDeparture":{"lock":true,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":49},"targetArrival":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":71},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":2174},{"x":2672,"y":2110},{"x":2672,"y":1950},{"x":2672,"y":1886}],"textPositions":{"0":{"x":2684,"y":2156},"1":{"x":2660,"y":2128},"2":{"x":2660,"y":1904},"3":{"x":2684,"y":1932},"4":{"x":2660,"y":2030},"5":{"x":2660,"y":2030},"6":{"x":2684,"y":2030}}},"warnings":null},{"id":525,"sourceNodeId":154,"sourcePortId":1065,"targetNodeId":153,"targetPortId":1066,"travelTime":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":75},"sourceArrival":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":45},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":30},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":1790},{"x":2672,"y":1726},{"x":2672,"y":1470},{"x":2672,"y":1406}],"textPositions":{"0":{"x":2684,"y":1772},"1":{"x":2660,"y":1744},"2":{"x":2660,"y":1424},"3":{"x":2684,"y":1452},"4":{"x":2660,"y":1598},"5":{"x":2660,"y":1598},"6":{"x":2684,"y":1598}}},"warnings":null},{"id":526,"sourceNodeId":153,"sourcePortId":1067,"targetNodeId":170,"targetPortId":1068,"travelTime":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":91},"sourceArrival":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":29},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":107},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":1310},{"x":2672,"y":1246},{"x":2672,"y":894},{"x":2672,"y":830}],"textPositions":{"0":{"x":2684,"y":1292},"1":{"x":2660,"y":1264},"2":{"x":2660,"y":848},"3":{"x":2684,"y":876},"4":{"x":2660,"y":1070},"5":{"x":2660,"y":1070},"6":{"x":2684,"y":1070}}},"warnings":null},{"id":527,"sourceNodeId":157,"sourcePortId":1069,"targetNodeId":136,"targetPortId":1070,"travelTime":{"lock":true,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":273},"sourceArrival":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":327},"targetDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":304},"targetArrival":{"lock":true,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":296},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2306,"y":3248},{"x":2370,"y":3248},{"x":2526,"y":3248},{"x":2590,"y":3248}],"textPositions":{"0":{"x":2324,"y":3260},"1":{"x":2352,"y":3236},"2":{"x":2572,"y":3236},"3":{"x":2544,"y":3260},"4":{"x":2448,"y":3236},"5":{"x":2448,"y":3236},"6":{"x":2448,"y":3260}}},"warnings":null},{"id":528,"sourceNodeId":136,"sourcePortId":1071,"targetNodeId":158,"targetPortId":1072,"travelTime":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":300},"sourceArrival":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":300},"targetDeparture":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":285},"targetArrival":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":315},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":3230},{"x":2672,"y":3166},{"x":2672,"y":2818},{"x":2672,"y":2754}],"textPositions":{"0":{"x":2684,"y":3212},"1":{"x":2660,"y":3184},"2":{"x":2660,"y":2772},"3":{"x":2684,"y":2800},"4":{"x":2660,"y":2992},"5":{"x":2660,"y":2992},"6":{"x":2684,"y":2992}}},"warnings":null},{"id":529,"sourceNodeId":158,"sourcePortId":1073,"targetNodeId":159,"targetPortId":1074,"travelTime":{"lock":true,"time":53,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":316},"sourceArrival":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":284},"targetDeparture":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":231},"targetArrival":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":369},"numberOfStops":5,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2608,"y":2686},{"x":2608,"y":2622},{"x":2288,"y":2398},{"x":2288,"y":2334}],"textPositions":{"0":{"x":2620,"y":2668},"1":{"x":2596,"y":2640},"2":{"x":2276,"y":2352},"3":{"x":2300,"y":2380},"4":{"x":2460,"y":2510},"5":{"x":2460,"y":2510},"6":{"x":2436,"y":2510}}},"warnings":null},{"id":530,"sourceNodeId":159,"sourcePortId":1075,"targetNodeId":155,"targetPortId":1076,"travelTime":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":370},"sourceArrival":{"lock":true,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":230},"targetDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":198},"targetArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":402},"numberOfStops":1,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2370,"y":2256},{"x":2434,"y":2256},{"x":2590,"y":2192},{"x":2654,"y":2192}],"textPositions":{"0":{"x":2388,"y":2268},"1":{"x":2416,"y":2244},"2":{"x":2636,"y":2180},"3":{"x":2608,"y":2204},"4":{"x":2512,"y":2212},"5":{"x":2512,"y":2212},"6":{"x":2512,"y":2236}}},"warnings":null},{"id":531,"sourceNodeId":155,"sourcePortId":1077,"targetNodeId":154,"targetPortId":1078,"travelTime":{"lock":true,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":403},"sourceArrival":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":197},"targetDeparture":{"lock":true,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":174},"targetArrival":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":426},"numberOfStops":3,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2736,"y":2174},{"x":2736,"y":2110},{"x":2736,"y":1950},{"x":2736,"y":1886}],"textPositions":{"0":{"x":2748,"y":2156},"1":{"x":2724,"y":2128},"2":{"x":2724,"y":1904},"3":{"x":2748,"y":1932},"4":{"x":2724,"y":2030},"5":{"x":2724,"y":2030},"6":{"x":2748,"y":2030}}},"warnings":null},{"id":532,"sourceNodeId":154,"sourcePortId":1079,"targetNodeId":169,"targetPortId":1080,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":435},"sourceArrival":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":165},"targetDeparture":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":147},"targetArrival":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":453},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":1840},{"x":2590,"y":1840},{"x":2018,"y":1840},{"x":1954,"y":1840}],"textPositions":{"0":{"x":2636,"y":1828},"1":{"x":2608,"y":1852},"2":{"x":1972,"y":1852},"3":{"x":2000,"y":1828},"4":{"x":2304,"y":1828},"5":{"x":2304,"y":1828},"6":{"x":2304,"y":1852}}},"warnings":null},{"id":533,"sourceNodeId":157,"sourcePortId":1081,"targetNodeId":136,"targetPortId":1082,"travelTime":{"lock":true,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":153},"sourceArrival":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":207},"targetDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":184},"targetArrival":{"lock":true,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":176},"numberOfStops":3,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2306,"y":3280},{"x":2370,"y":3280},{"x":2526,"y":3280},{"x":2590,"y":3280}],"textPositions":{"0":{"x":2324,"y":3292},"1":{"x":2352,"y":3268},"2":{"x":2572,"y":3268},"3":{"x":2544,"y":3292},"4":{"x":2448,"y":3268},"5":{"x":2448,"y":3268},"6":{"x":2448,"y":3292}}},"warnings":null},{"id":534,"sourceNodeId":136,"sourcePortId":1083,"targetNodeId":158,"targetPortId":1084,"travelTime":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":180},"sourceArrival":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":180},"targetDeparture":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":165},"targetArrival":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":195},"numberOfStops":1,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":3230},{"x":2704,"y":3166},{"x":2704,"y":2818},{"x":2704,"y":2754}],"textPositions":{"0":{"x":2716,"y":3212},"1":{"x":2692,"y":3184},"2":{"x":2692,"y":2772},"3":{"x":2716,"y":2800},"4":{"x":2692,"y":2992},"5":{"x":2692,"y":2992},"6":{"x":2716,"y":2992}}},"warnings":null},{"id":535,"sourceNodeId":158,"sourcePortId":1085,"targetNodeId":159,"targetPortId":1086,"travelTime":{"lock":true,"time":53,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":196},"sourceArrival":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":164},"targetDeparture":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":111},"targetArrival":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":249},"numberOfStops":5,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2640,"y":2686},{"x":2640,"y":2622},{"x":2320,"y":2398},{"x":2320,"y":2334}],"textPositions":{"0":{"x":2652,"y":2668},"1":{"x":2628,"y":2640},"2":{"x":2308,"y":2352},"3":{"x":2332,"y":2380},"4":{"x":2492,"y":2510},"5":{"x":2492,"y":2510},"6":{"x":2468,"y":2510}}},"warnings":null},{"id":536,"sourceNodeId":159,"sourcePortId":1087,"targetNodeId":155,"targetPortId":1088,"travelTime":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":250},"sourceArrival":{"lock":true,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":110},"targetDeparture":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":78},"targetArrival":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":282},"numberOfStops":1,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2370,"y":2288},{"x":2434,"y":2288},{"x":2590,"y":2224},{"x":2654,"y":2224}],"textPositions":{"0":{"x":2388,"y":2300},"1":{"x":2416,"y":2276},"2":{"x":2636,"y":2212},"3":{"x":2608,"y":2236},"4":{"x":2512,"y":2244},"5":{"x":2512,"y":2244},"6":{"x":2512,"y":2268}}},"warnings":null},{"id":537,"sourceNodeId":155,"sourcePortId":1089,"targetNodeId":154,"targetPortId":1090,"travelTime":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":283},"sourceArrival":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":77},"targetDeparture":{"lock":true,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":54},"targetArrival":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":306},"numberOfStops":3,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2768,"y":2174},{"x":2768,"y":2110},{"x":2768,"y":1950},{"x":2768,"y":1886}],"textPositions":{"0":{"x":2780,"y":2156},"1":{"x":2756,"y":2128},"2":{"x":2756,"y":1904},"3":{"x":2780,"y":1932},"4":{"x":2756,"y":2030},"5":{"x":2756,"y":2030},"6":{"x":2780,"y":2030}}},"warnings":null},{"id":538,"sourceNodeId":154,"sourcePortId":1091,"targetNodeId":153,"targetPortId":1092,"travelTime":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":315},"sourceArrival":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":45},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":30},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"numberOfStops":0,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":1790},{"x":2704,"y":1726},{"x":2704,"y":1470},{"x":2704,"y":1406}],"textPositions":{"0":{"x":2716,"y":1772},"1":{"x":2692,"y":1744},"2":{"x":2692,"y":1424},"3":{"x":2716,"y":1452},"4":{"x":2692,"y":1598},"5":{"x":2692,"y":1598},"6":{"x":2716,"y":1598}}},"warnings":null},{"id":539,"sourceNodeId":153,"sourcePortId":1093,"targetNodeId":170,"targetPortId":1094,"travelTime":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":331},"sourceArrival":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":29},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"numberOfStops":0,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":1310},{"x":2704,"y":1246},{"x":2704,"y":894},{"x":2704,"y":830}],"textPositions":{"0":{"x":2716,"y":1292},"1":{"x":2692,"y":1264},"2":{"x":2692,"y":848},"3":{"x":2716,"y":876},"4":{"x":2692,"y":1070},"5":{"x":2692,"y":1070},"6":{"x":2716,"y":1070}}},"warnings":null},{"id":540,"sourceNodeId":142,"sourcePortId":1095,"targetNodeId":169,"targetPortId":1096,"travelTime":{"lock":false,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"sourceArrival":{"lock":true,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":265},"targetDeparture":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":253},"targetArrival":{"lock":true,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":47},"numberOfStops":0,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":226,"y":1840},{"x":290,"y":1840},{"x":1790,"y":1840},{"x":1854,"y":1840}],"textPositions":{"0":{"x":244,"y":1852},"1":{"x":272,"y":1828},"2":{"x":1836,"y":1828},"3":{"x":1808,"y":1852},"4":{"x":1040,"y":1828},"5":{"x":1040,"y":1828},"6":{"x":1040,"y":1852}}},"warnings":null},{"id":541,"sourceNodeId":153,"sourcePortId":1097,"targetNodeId":170,"targetPortId":1098,"travelTime":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":58},"sourceArrival":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":242},"targetDeparture":{"lock":true,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":227},"targetArrival":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":73},"numberOfStops":1,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2768,"y":1310},{"x":2768,"y":1246},{"x":2768,"y":894},{"x":2768,"y":830}],"textPositions":{"0":{"x":2780,"y":1292},"1":{"x":2756,"y":1264},"2":{"x":2756,"y":848},"3":{"x":2780,"y":876},"4":{"x":2756,"y":1070},"5":{"x":2756,"y":1070},"6":{"x":2780,"y":1070}}},"warnings":null},{"id":542,"sourceNodeId":142,"sourcePortId":1099,"targetNodeId":169,"targetPortId":1100,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":9},"sourceArrival":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":51},"targetDeparture":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":42},"targetArrival":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"numberOfStops":0,"trainrunId":80,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":226,"y":1808},{"x":290,"y":1808},{"x":1790,"y":1808},{"x":1854,"y":1808}],"textPositions":{"0":{"x":244,"y":1820},"1":{"x":272,"y":1796},"2":{"x":1836,"y":1796},"3":{"x":1808,"y":1820},"4":{"x":1040,"y":1796},"5":{"x":1040,"y":1796},"6":{"x":1040,"y":1820}}},"warnings":null},{"id":543,"sourceNodeId":153,"sourcePortId":1101,"targetNodeId":170,"targetPortId":1102,"travelTime":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":29},"sourceArrival":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":31},"targetDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":17},"targetArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":43},"numberOfStops":0,"trainrunId":80,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2736,"y":1310},{"x":2736,"y":1246},{"x":2736,"y":894},{"x":2736,"y":830}],"textPositions":{"0":{"x":2748,"y":1292},"1":{"x":2724,"y":1264},"2":{"x":2724,"y":848},"3":{"x":2748,"y":876},"4":{"x":2724,"y":1070},"5":{"x":2724,"y":1070},"6":{"x":2748,"y":1070}}},"warnings":null},{"id":544,"sourceNodeId":142,"sourcePortId":1103,"targetNodeId":141,"targetPortId":1104,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":299},"sourceArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":241},"targetDeparture":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":222},"targetArrival":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":318},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":1726},{"x":112,"y":1662},{"x":112,"y":1314},{"x":112,"y":1250}],"textPositions":{"0":{"x":124,"y":1708},"1":{"x":100,"y":1680},"2":{"x":100,"y":1268},"3":{"x":124,"y":1296},"4":{"x":100,"y":1488},"5":{"x":100,"y":1488},"6":{"x":124,"y":1488}}},"warnings":null},{"id":545,"sourceNodeId":141,"sourcePortId":1105,"targetNodeId":143,"targetPortId":1106,"travelTime":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":319},"sourceArrival":{"lock":true,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":221},"targetDeparture":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":209},"targetArrival":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":331},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":1182},{"x":112,"y":1118},{"x":112,"y":866},{"x":112,"y":802}],"textPositions":{"0":{"x":124,"y":1164},"1":{"x":100,"y":1136},"2":{"x":100,"y":820},"3":{"x":124,"y":848},"4":{"x":100,"y":992},"5":{"x":100,"y":992},"6":{"x":124,"y":992}}},"warnings":null},{"id":546,"sourceNodeId":143,"sourcePortId":1107,"targetNodeId":172,"targetPortId":1108,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":332},"sourceArrival":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":208},"targetDeparture":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":201},"targetArrival":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":339},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":752},{"x":-2,"y":752},{"x":-446,"y":336},{"x":-510,"y":336}],"textPositions":{"0":{"x":44,"y":740},"1":{"x":16,"y":764},"2":{"x":-492,"y":348},"3":{"x":-464,"y":324},"4":{"x":-224,"y":532},"5":{"x":-224,"y":532},"6":{"x":-224,"y":556}}},"warnings":null},{"id":547,"sourceNodeId":129,"sourcePortId":1109,"targetNodeId":171,"targetPortId":1110,"travelTime":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":364},"sourceArrival":{"lock":true,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":176},"targetDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":154},"targetArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":386},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2146,"y":176},{"x":-2210,"y":176},{"x":-2398,"y":336},{"x":-2462,"y":336}],"textPositions":{"0":{"x":-2164,"y":164},"1":{"x":-2192,"y":188},"2":{"x":-2444,"y":348},"3":{"x":-2416,"y":324},"4":{"x":-2304,"y":244},"5":{"x":-2304,"y":244},"6":{"x":-2304,"y":268}}},"warnings":null},{"id":548,"sourceNodeId":142,"sourcePortId":1111,"targetNodeId":141,"targetPortId":1112,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"sourceArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetDeparture":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":72},"targetArrival":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":108},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":1726},{"x":208,"y":1662},{"x":208,"y":1314},{"x":208,"y":1250}],"textPositions":{"0":{"x":220,"y":1708},"1":{"x":196,"y":1680},"2":{"x":196,"y":1268},"3":{"x":220,"y":1296},"4":{"x":196,"y":1488},"5":{"x":196,"y":1488},"6":{"x":220,"y":1488}}},"warnings":null},{"id":549,"sourceNodeId":141,"sourcePortId":1113,"targetNodeId":143,"targetPortId":1114,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":109},"sourceArrival":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":71},"targetDeparture":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":58},"targetArrival":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":122},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":1182},{"x":208,"y":1118},{"x":208,"y":866},{"x":208,"y":802}],"textPositions":{"0":{"x":220,"y":1164},"1":{"x":196,"y":1136},"2":{"x":196,"y":820},"3":{"x":220,"y":848},"4":{"x":196,"y":992},"5":{"x":196,"y":992},"6":{"x":220,"y":992}}},"warnings":null},{"id":550,"sourceNodeId":143,"sourcePortId":1115,"targetNodeId":133,"targetPortId":1116,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":124},"sourceArrival":{"lock":true,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":56},"targetDeparture":{"lock":true,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":49},"targetArrival":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":131},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":734},{"x":176,"y":670},{"x":176,"y":414},{"x":176,"y":350}],"textPositions":{"0":{"x":188,"y":716},"1":{"x":164,"y":688},"2":{"x":164,"y":368},"3":{"x":188,"y":396},"4":{"x":164,"y":542},"5":{"x":164,"y":542},"6":{"x":188,"y":542}}},"warnings":null},{"id":551,"sourceNodeId":133,"sourcePortId":1117,"targetNodeId":144,"targetPortId":1118,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":132},"sourceArrival":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":48},"targetDeparture":{"lock":true,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":38},"targetArrival":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":142},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":240,"y":94},{"x":240,"y":30},{"x":240,"y":-290},{"x":240,"y":-354}],"textPositions":{"0":{"x":252,"y":76},"1":{"x":228,"y":48},"2":{"x":228,"y":-336},"3":{"x":252,"y":-308},"4":{"x":228,"y":-130},"5":{"x":228,"y":-130},"6":{"x":252,"y":-130}}},"warnings":null},{"id":552,"sourceNodeId":144,"sourcePortId":1119,"targetNodeId":145,"targetPortId":1120,"travelTime":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":143},"sourceArrival":{"lock":true,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":37},"targetDeparture":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":33},"targetArrival":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":147},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":304,"y":-450},{"x":304,"y":-514},{"x":304,"y":-798},{"x":304,"y":-862}],"textPositions":{"0":{"x":316,"y":-468},"1":{"x":292,"y":-496},"2":{"x":292,"y":-844},"3":{"x":316,"y":-816},"4":{"x":292,"y":-656},"5":{"x":292,"y":-656},"6":{"x":316,"y":-656}}},"warnings":null},{"id":553,"sourceNodeId":145,"sourcePortId":1121,"targetNodeId":146,"targetPortId":1122,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":148},"sourceArrival":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":32},"targetDeparture":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":27},"targetArrival":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":153},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":304,"y":-930},{"x":304,"y":-994},{"x":304,"y":-1278},{"x":304,"y":-1342}],"textPositions":{"0":{"x":316,"y":-948},"1":{"x":292,"y":-976},"2":{"x":292,"y":-1324},"3":{"x":316,"y":-1296},"4":{"x":292,"y":-1136},"5":{"x":292,"y":-1136},"6":{"x":316,"y":-1136}}},"warnings":null},{"id":554,"sourceNodeId":146,"sourcePortId":1123,"targetNodeId":134,"targetPortId":1124,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":154},"sourceArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":26},"targetDeparture":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":16},"targetArrival":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":164},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":304,"y":-1410},{"x":304,"y":-1474},{"x":304,"y":-1758},{"x":304,"y":-1822}],"textPositions":{"0":{"x":316,"y":-1428},"1":{"x":292,"y":-1456},"2":{"x":292,"y":-1804},"3":{"x":316,"y":-1776},"4":{"x":292,"y":-1616},"5":{"x":292,"y":-1616},"6":{"x":316,"y":-1616}}},"warnings":null},{"id":555,"sourceNodeId":142,"sourcePortId":1125,"targetNodeId":141,"targetPortId":1126,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":115},"sourceArrival":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":1726},{"x":176,"y":1662},{"x":176,"y":1314},{"x":176,"y":1250}],"textPositions":{"0":{"x":188,"y":1708},"1":{"x":164,"y":1680},"2":{"x":164,"y":1268},"3":{"x":188,"y":1296},"4":{"x":164,"y":1488},"5":{"x":164,"y":1488},"6":{"x":188,"y":1488}}},"warnings":null},{"id":556,"sourceNodeId":141,"sourcePortId":1127,"targetNodeId":143,"targetPortId":1128,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"sourceArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":38},"targetArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":142},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":1182},{"x":176,"y":1118},{"x":176,"y":866},{"x":176,"y":802}],"textPositions":{"0":{"x":188,"y":1164},"1":{"x":164,"y":1136},"2":{"x":164,"y":820},"3":{"x":188,"y":848},"4":{"x":164,"y":992},"5":{"x":164,"y":992},"6":{"x":188,"y":992}}},"warnings":null},{"id":557,"sourceNodeId":143,"sourcePortId":1129,"targetNodeId":133,"targetPortId":1130,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":142},"sourceArrival":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":38},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":30},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":150},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":734},{"x":144,"y":670},{"x":144,"y":414},{"x":144,"y":350}],"textPositions":{"0":{"x":156,"y":716},"1":{"x":132,"y":688},"2":{"x":132,"y":368},"3":{"x":156,"y":396},"4":{"x":132,"y":542},"5":{"x":132,"y":542},"6":{"x":156,"y":542}}},"warnings":null},{"id":558,"sourceNodeId":133,"sourcePortId":1131,"targetNodeId":144,"targetPortId":1132,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":152},"sourceArrival":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":28},"targetDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"targetArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":162},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":94},{"x":208,"y":30},{"x":208,"y":-290},{"x":208,"y":-354}],"textPositions":{"0":{"x":220,"y":76},"1":{"x":196,"y":48},"2":{"x":196,"y":-336},"3":{"x":220,"y":-308},"4":{"x":196,"y":-130},"5":{"x":196,"y":-130},"6":{"x":220,"y":-130}}},"warnings":null},{"id":559,"sourceNodeId":144,"sourcePortId":1133,"targetNodeId":145,"targetPortId":1134,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":162},"sourceArrival":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":167},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":272,"y":-450},{"x":272,"y":-514},{"x":272,"y":-798},{"x":272,"y":-862}],"textPositions":{"0":{"x":284,"y":-468},"1":{"x":260,"y":-496},"2":{"x":260,"y":-844},"3":{"x":284,"y":-816},"4":{"x":260,"y":-656},"5":{"x":260,"y":-656},"6":{"x":284,"y":-656}}},"warnings":null},{"id":560,"sourceNodeId":145,"sourcePortId":1135,"targetNodeId":146,"targetPortId":1136,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":167},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":8},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":172},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":272,"y":-930},{"x":272,"y":-994},{"x":272,"y":-1278},{"x":272,"y":-1342}],"textPositions":{"0":{"x":284,"y":-948},"1":{"x":260,"y":-976},"2":{"x":260,"y":-1324},"3":{"x":284,"y":-1296},"4":{"x":260,"y":-1136},"5":{"x":260,"y":-1136},"6":{"x":284,"y":-1136}}},"warnings":null},{"id":561,"sourceNodeId":146,"sourcePortId":1137,"targetNodeId":134,"targetPortId":1138,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":172},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":8},"targetDeparture":{"lock":false,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":3},"targetArrival":{"lock":false,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":177},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":272,"y":-1410},{"x":272,"y":-1474},{"x":272,"y":-1758},{"x":272,"y":-1822}],"textPositions":{"0":{"x":284,"y":-1428},"1":{"x":260,"y":-1456},"2":{"x":260,"y":-1804},"3":{"x":284,"y":-1776},"4":{"x":260,"y":-1616},"5":{"x":260,"y":-1616},"6":{"x":284,"y":-1616}}},"warnings":null},{"id":562,"sourceNodeId":135,"sourcePortId":1139,"targetNodeId":150,"targetPortId":1140,"travelTime":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":9},"sourceArrival":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":291},"targetDeparture":{"lock":true,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":279},"targetArrival":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":21},"numberOfStops":1,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":176},{"x":2914,"y":176},{"x":3230,"y":176},{"x":3294,"y":176}],"textPositions":{"0":{"x":2868,"y":188},"1":{"x":2896,"y":164},"2":{"x":3276,"y":164},"3":{"x":3248,"y":188},"4":{"x":3072,"y":164},"5":{"x":3072,"y":164},"6":{"x":3072,"y":188}}},"warnings":null},{"id":563,"sourceNodeId":150,"sourcePortId":1141,"targetNodeId":151,"targetPortId":1142,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":23},"sourceArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":277},"targetDeparture":{"lock":true,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":264},"targetArrival":{"lock":true,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":36},"numberOfStops":0,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3394,"y":176},{"x":3458,"y":176},{"x":3806,"y":176},{"x":3870,"y":176}],"textPositions":{"0":{"x":3412,"y":188},"1":{"x":3440,"y":164},"2":{"x":3852,"y":164},"3":{"x":3824,"y":188},"4":{"x":3632,"y":164},"5":{"x":3632,"y":164},"6":{"x":3632,"y":188}}},"warnings":null},{"id":564,"sourceNodeId":151,"sourcePortId":1143,"targetNodeId":137,"targetPortId":1144,"travelTime":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":38},"sourceArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":262},"targetDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":218},"targetArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":82},"numberOfStops":4,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3970,"y":176},{"x":4034,"y":176},{"x":4574,"y":176},{"x":4638,"y":176}],"textPositions":{"0":{"x":3988,"y":188},"1":{"x":4016,"y":164},"2":{"x":4620,"y":164},"3":{"x":4592,"y":188},"4":{"x":4304,"y":164},"5":{"x":4304,"y":164},"6":{"x":4304,"y":188}}},"warnings":null},{"id":565,"sourceNodeId":137,"sourcePortId":1145,"targetNodeId":140,"targetPortId":1146,"travelTime":{"lock":true,"time":61,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":84},"sourceArrival":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":216},"targetDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":155},"targetArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":145},"numberOfStops":5,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4656,"y":222},{"x":4656,"y":286},{"x":4656,"y":1118},{"x":4656,"y":1182}],"textPositions":{"0":{"x":4644,"y":240},"1":{"x":4668,"y":268},"2":{"x":4668,"y":1164},"3":{"x":4644,"y":1136},"4":{"x":4644,"y":702},"5":{"x":4644,"y":702},"6":{"x":4668,"y":702}}},"warnings":null},{"id":566,"sourceNodeId":140,"sourcePortId":1147,"targetNodeId":152,"targetPortId":1148,"travelTime":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":146},"sourceArrival":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":154},"targetDeparture":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":132},"targetArrival":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":168},"numberOfStops":2,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4688,"y":1278},{"x":4688,"y":1342},{"x":4688,"y":1822},{"x":4688,"y":1886}],"textPositions":{"0":{"x":4676,"y":1296},"1":{"x":4700,"y":1324},"2":{"x":4700,"y":1868},"3":{"x":4676,"y":1840},"4":{"x":4676,"y":1582},"5":{"x":4676,"y":1582},"6":{"x":4700,"y":1582}}},"warnings":null},{"id":567,"sourceNodeId":135,"sourcePortId":1149,"targetNodeId":170,"targetPortId":1150,"travelTime":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":67},"sourceArrival":{"lock":true,"time":53,"warning":null,"timeFormatter":null,"consecutiveTime":293},"targetDeparture":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":285},"targetArrival":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":75},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":350},{"x":2704,"y":414},{"x":2704,"y":670},{"x":2704,"y":734}],"textPositions":{"0":{"x":2692,"y":368},"1":{"x":2716,"y":396},"2":{"x":2716,"y":716},"3":{"x":2692,"y":688},"4":{"x":2692,"y":542},"5":{"x":2692,"y":542},"6":{"x":2716,"y":542}}},"warnings":null},{"id":568,"sourceNodeId":140,"sourcePortId":1151,"targetNodeId":152,"targetPortId":1152,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":123},"sourceArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":237},"targetDeparture":{"lock":true,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":218},"targetArrival":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":142},"numberOfStops":1,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4656,"y":1278},{"x":4656,"y":1342},{"x":4656,"y":1822},{"x":4656,"y":1886}],"textPositions":{"0":{"x":4644,"y":1296},"1":{"x":4668,"y":1324},"2":{"x":4668,"y":1868},"3":{"x":4644,"y":1840},"4":{"x":4644,"y":1582},"5":{"x":4644,"y":1582},"6":{"x":4668,"y":1582}}},"warnings":null},{"id":569,"sourceNodeId":135,"sourcePortId":1153,"targetNodeId":170,"targetPortId":1154,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":132},"sourceArrival":{"lock":false,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":288},"targetDeparture":{"lock":true,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":280},"targetArrival":{"lock":true,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":140},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2736,"y":350},{"x":2736,"y":414},{"x":2736,"y":670},{"x":2736,"y":734}],"textPositions":{"0":{"x":2724,"y":368},"1":{"x":2748,"y":396},"2":{"x":2748,"y":716},"3":{"x":2724,"y":688},"4":{"x":2724,"y":542},"5":{"x":2724,"y":542},"6":{"x":2748,"y":542}}},"warnings":null},{"id":570,"sourceNodeId":140,"sourcePortId":1155,"targetNodeId":152,"targetPortId":1156,"travelTime":{"lock":true,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":203},"sourceArrival":{"lock":true,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":217},"targetDeparture":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":197},"targetArrival":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":223},"numberOfStops":1,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4720,"y":1278},{"x":4720,"y":1342},{"x":4720,"y":1822},{"x":4720,"y":1886}],"textPositions":{"0":{"x":4708,"y":1296},"1":{"x":4732,"y":1324},"2":{"x":4732,"y":1868},"3":{"x":4708,"y":1840},"4":{"x":4708,"y":1582},"5":{"x":4708,"y":1582},"6":{"x":4732,"y":1582}}},"warnings":null},{"id":571,"sourceNodeId":135,"sourcePortId":1157,"targetNodeId":149,"targetPortId":1158,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":294},"sourceArrival":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":126},"targetDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":119},"targetArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":301},"numberOfStops":1,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":240},{"x":2590,"y":240},{"x":2402,"y":240},{"x":2338,"y":240}],"textPositions":{"0":{"x":2636,"y":228},"1":{"x":2608,"y":252},"2":{"x":2356,"y":252},"3":{"x":2384,"y":228},"4":{"x":2496,"y":228},"5":{"x":2496,"y":228},"6":{"x":2496,"y":252}}},"warnings":null},{"id":572,"sourceNodeId":149,"sourcePortId":1159,"targetNodeId":166,"targetPortId":1160,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":301},"sourceArrival":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":119},"targetDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":240},{"x":2174,"y":240},{"x":1954,"y":240},{"x":1890,"y":240}],"textPositions":{"0":{"x":2220,"y":228},"1":{"x":2192,"y":252},"2":{"x":1908,"y":252},"3":{"x":1936,"y":228},"4":{"x":2064,"y":228},"5":{"x":2064,"y":228},"6":{"x":2064,"y":252}}},"warnings":null},{"id":573,"sourceNodeId":148,"sourcePortId":1161,"targetNodeId":147,"targetPortId":1162,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":315},"sourceArrival":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":105},"targetDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":98},"targetArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":322},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":240},{"x":1278,"y":240},{"x":1122,"y":240},{"x":1058,"y":240}],"textPositions":{"0":{"x":1324,"y":228},"1":{"x":1296,"y":252},"2":{"x":1076,"y":252},"3":{"x":1104,"y":228},"4":{"x":1200,"y":228},"5":{"x":1200,"y":228},"6":{"x":1200,"y":252}}},"warnings":null},{"id":574,"sourceNodeId":147,"sourcePortId":1163,"targetNodeId":133,"targetPortId":1164,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":322},"sourceArrival":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":98},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":240},{"x":894,"y":240},{"x":322,"y":240},{"x":258,"y":240}],"textPositions":{"0":{"x":940,"y":228},"1":{"x":912,"y":252},"2":{"x":276,"y":252},"3":{"x":304,"y":228},"4":{"x":608,"y":228},"5":{"x":608,"y":228},"6":{"x":608,"y":252}}},"warnings":null},{"id":575,"sourceNodeId":133,"sourcePortId":1165,"targetNodeId":172,"targetPortId":1166,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":336},"sourceArrival":{"lock":true,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":84},"targetDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":77},"targetArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":343},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":304},{"x":-2,"y":304},{"x":-446,"y":304},{"x":-510,"y":304}],"textPositions":{"0":{"x":44,"y":292},"1":{"x":16,"y":316},"2":{"x":-492,"y":316},"3":{"x":-464,"y":292},"4":{"x":-224,"y":292},"5":{"x":-224,"y":292},"6":{"x":-224,"y":316}}},"warnings":null},{"id":576,"sourceNodeId":137,"sourcePortId":1167,"targetNodeId":151,"targetPortId":1168,"travelTime":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":298},"sourceArrival":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":242},"targetDeparture":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":209},"targetArrival":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":331},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4638,"y":144},{"x":4574,"y":144},{"x":4034,"y":144},{"x":3970,"y":144}],"textPositions":{"0":{"x":4620,"y":132},"1":{"x":4592,"y":156},"2":{"x":3988,"y":156},"3":{"x":4016,"y":132},"4":{"x":4304,"y":132},"5":{"x":4304,"y":132},"6":{"x":4304,"y":156}}},"warnings":null},{"id":577,"sourceNodeId":151,"sourcePortId":1169,"targetNodeId":150,"targetPortId":1170,"travelTime":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":333},"sourceArrival":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":207},"targetDeparture":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":193},"targetArrival":{"lock":true,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3870,"y":80},{"x":3806,"y":80},{"x":3458,"y":80},{"x":3394,"y":80}],"textPositions":{"0":{"x":3852,"y":68},"1":{"x":3824,"y":92},"2":{"x":3412,"y":92},"3":{"x":3440,"y":68},"4":{"x":3632,"y":68},"5":{"x":3632,"y":68},"6":{"x":3632,"y":92}}},"warnings":null},{"id":578,"sourceNodeId":150,"sourcePortId":1171,"targetNodeId":135,"targetPortId":1172,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":348},"sourceArrival":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":192},"targetDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":183},"targetArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":357},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3294,"y":80},{"x":3230,"y":80},{"x":2914,"y":80},{"x":2850,"y":80}],"textPositions":{"0":{"x":3276,"y":68},"1":{"x":3248,"y":92},"2":{"x":2868,"y":92},"3":{"x":2896,"y":68},"4":{"x":3072,"y":68},"5":{"x":3072,"y":68},"6":{"x":3072,"y":92}}},"warnings":null},{"id":579,"sourceNodeId":135,"sourcePortId":1173,"targetNodeId":149,"targetPortId":1174,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":364},"sourceArrival":{"lock":true,"time":56,"warning":{"title":"Quelle Ankunft Warnung","description":"Quellankunftszeit kann nicht erreicht werden"},"timeFormatter":null,"consecutiveTime":176},"targetDeparture":{"lock":false,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":170},"targetArrival":{"lock":false,"time":10,"warning":{"title":"Ziel Ankunft Warnung","description":"Zielankunftszeit kann nicht erreicht werden"},"timeFormatter":null,"consecutiveTime":370},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":144},{"x":2590,"y":144},{"x":2402,"y":144},{"x":2338,"y":144}],"textPositions":{"0":{"x":2636,"y":132},"1":{"x":2608,"y":156},"2":{"x":2356,"y":156},"3":{"x":2384,"y":132},"4":{"x":2496,"y":132},"5":{"x":2496,"y":132},"6":{"x":2496,"y":156}}},"warnings":null},{"id":580,"sourceNodeId":149,"sourcePortId":1175,"targetNodeId":166,"targetPortId":1176,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":370},"sourceArrival":{"lock":false,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":170},"targetDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":377},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":144},{"x":2174,"y":144},{"x":1954,"y":144},{"x":1890,"y":144}],"textPositions":{"0":{"x":2220,"y":132},"1":{"x":2192,"y":156},"2":{"x":1908,"y":156},"3":{"x":1936,"y":132},"4":{"x":2064,"y":132},"5":{"x":2064,"y":132},"6":{"x":2064,"y":156}}},"warnings":null},{"id":581,"sourceNodeId":148,"sourcePortId":1177,"targetNodeId":147,"targetPortId":1178,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":384},"sourceArrival":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":156},"targetDeparture":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":151},"targetArrival":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":389},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":144},{"x":1278,"y":144},{"x":1122,"y":144},{"x":1058,"y":144}],"textPositions":{"0":{"x":1324,"y":132},"1":{"x":1296,"y":156},"2":{"x":1076,"y":156},"3":{"x":1104,"y":132},"4":{"x":1200,"y":132},"5":{"x":1200,"y":132},"6":{"x":1200,"y":156}}},"warnings":null},{"id":582,"sourceNodeId":147,"sourcePortId":1179,"targetNodeId":133,"targetPortId":1180,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":391},"sourceArrival":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":149},"targetDeparture":{"lock":true,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":140},"targetArrival":{"lock":true,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":400},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":144},{"x":894,"y":144},{"x":322,"y":144},{"x":258,"y":144}],"textPositions":{"0":{"x":940,"y":132},"1":{"x":912,"y":156},"2":{"x":276,"y":156},"3":{"x":304,"y":132},"4":{"x":608,"y":132},"5":{"x":608,"y":132},"6":{"x":608,"y":156}}},"warnings":null},{"id":583,"sourceNodeId":133,"sourcePortId":1181,"targetNodeId":175,"targetPortId":1182,"travelTime":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":402},"sourceArrival":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":138},"targetDeparture":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":121},"targetArrival":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":419},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":112},{"x":-2,"y":112},{"x":-1534,"y":-16},{"x":-1598,"y":-16}],"textPositions":{"0":{"x":44,"y":100},"1":{"x":16,"y":124},"2":{"x":-1580,"y":-4},"3":{"x":-1552,"y":-28},"4":{"x":-768,"y":36},"5":{"x":-768,"y":36},"6":{"x":-768,"y":60}}},"warnings":null},{"id":584,"sourceNodeId":130,"sourcePortId":1183,"targetNodeId":177,"targetPortId":1184,"travelTime":{"lock":false,"time":61,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":437},"sourceArrival":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":103},"targetDeparture":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":42},"targetArrival":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":498},"numberOfStops":2,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2530,"y":-16},{"x":-2594,"y":-16},{"x":-3358,"y":560},{"x":-3422,"y":560}],"textPositions":{"0":{"x":-2548,"y":-28},"1":{"x":-2576,"y":-4},"2":{"x":-3404,"y":572},"3":{"x":-3376,"y":548},"4":{"x":-2976,"y":260},"5":{"x":-2976,"y":260},"6":{"x":-2976,"y":284}}},"warnings":null},{"id":585,"sourceNodeId":160,"sourcePortId":1185,"targetNodeId":161,"targetPortId":1186,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":528},"sourceArrival":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":12},"targetDeparture":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":4},"targetArrival":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":536},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3938,"y":656},{"x":-4002,"y":656},{"x":-4190,"y":656},{"x":-4254,"y":656}],"textPositions":{"0":{"x":-3956,"y":644},"1":{"x":-3984,"y":668},"2":{"x":-4236,"y":668},"3":{"x":-4208,"y":644},"4":{"x":-4096,"y":644},"5":{"x":-4096,"y":644},"6":{"x":-4096,"y":668}}},"warnings":null},{"id":586,"sourceNodeId":128,"sourcePortId":1187,"targetNodeId":177,"targetPortId":1188,"travelTime":{"lock":false,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":439},"sourceArrival":{"lock":true,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":101},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":450},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3074,"y":592},{"x":-3138,"y":592},{"x":-3358,"y":624},{"x":-3422,"y":624}],"textPositions":{"0":{"x":-3092,"y":580},"1":{"x":-3120,"y":604},"2":{"x":-3404,"y":636},"3":{"x":-3376,"y":612},"4":{"x":-3248,"y":596},"5":{"x":-3248,"y":596},"6":{"x":-3248,"y":620}}},"warnings":null},{"id":587,"sourceNodeId":160,"sourcePortId":1189,"targetNodeId":161,"targetPortId":1190,"travelTime":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":484},"sourceArrival":{"lock":true,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":56},"targetDeparture":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":48},"targetArrival":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":492},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3938,"y":688},{"x":-4002,"y":688},{"x":-4190,"y":688},{"x":-4254,"y":688}],"textPositions":{"0":{"x":-3956,"y":676},"1":{"x":-3984,"y":700},"2":{"x":-4236,"y":700},"3":{"x":-4208,"y":676},"4":{"x":-4096,"y":676},"5":{"x":-4096,"y":676},"6":{"x":-4096,"y":700}}},"warnings":null},{"id":588,"sourceNodeId":135,"sourcePortId":1191,"targetNodeId":150,"targetPortId":1192,"travelTime":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":219},"sourceArrival":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":321},"targetDeparture":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":309},"targetArrival":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":231},"numberOfStops":1,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":48},{"x":2914,"y":48},{"x":3230,"y":48},{"x":3294,"y":48}],"textPositions":{"0":{"x":2868,"y":60},"1":{"x":2896,"y":36},"2":{"x":3276,"y":36},"3":{"x":3248,"y":60},"4":{"x":3072,"y":36},"5":{"x":3072,"y":36},"6":{"x":3072,"y":60}}},"warnings":null},{"id":589,"sourceNodeId":150,"sourcePortId":1193,"targetNodeId":151,"targetPortId":1194,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":53,"warning":null,"timeFormatter":null,"consecutiveTime":233},"sourceArrival":{"lock":false,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":307},"targetDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":294},"targetArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":246},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3394,"y":48},{"x":3458,"y":48},{"x":3806,"y":48},{"x":3870,"y":48}],"textPositions":{"0":{"x":3412,"y":60},"1":{"x":3440,"y":36},"2":{"x":3852,"y":36},"3":{"x":3824,"y":60},"4":{"x":3632,"y":36},"5":{"x":3632,"y":36},"6":{"x":3632,"y":60}}},"warnings":null},{"id":590,"sourceNodeId":135,"sourcePortId":1195,"targetNodeId":149,"targetPortId":1196,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":346},"sourceArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":194},"targetDeparture":{"lock":false,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":189},"targetArrival":{"lock":false,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":351},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":48},{"x":2590,"y":48},{"x":2402,"y":48},{"x":2338,"y":48}],"textPositions":{"0":{"x":2636,"y":36},"1":{"x":2608,"y":60},"2":{"x":2356,"y":60},"3":{"x":2384,"y":36},"4":{"x":2496,"y":36},"5":{"x":2496,"y":36},"6":{"x":2496,"y":60}}},"warnings":null},{"id":591,"sourceNodeId":149,"sourcePortId":1197,"targetNodeId":166,"targetPortId":1198,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":351},"sourceArrival":{"lock":false,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":189},"targetDeparture":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":184},"targetArrival":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":356},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":48},{"x":2174,"y":48},{"x":1954,"y":48},{"x":1890,"y":48}],"textPositions":{"0":{"x":2220,"y":36},"1":{"x":2192,"y":60},"2":{"x":1908,"y":60},"3":{"x":1936,"y":36},"4":{"x":2064,"y":36},"5":{"x":2064,"y":36},"6":{"x":2064,"y":60}}},"warnings":null},{"id":592,"sourceNodeId":148,"sourcePortId":1199,"targetNodeId":147,"targetPortId":1200,"travelTime":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":361},"sourceArrival":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":179},"targetDeparture":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":175},"targetArrival":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":365},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":48},{"x":1278,"y":48},{"x":1122,"y":48},{"x":1058,"y":48}],"textPositions":{"0":{"x":1324,"y":36},"1":{"x":1296,"y":60},"2":{"x":1076,"y":60},"3":{"x":1104,"y":36},"4":{"x":1200,"y":36},"5":{"x":1200,"y":36},"6":{"x":1200,"y":60}}},"warnings":null},{"id":593,"sourceNodeId":147,"sourcePortId":1201,"targetNodeId":133,"targetPortId":1202,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":365},"sourceArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":175},"targetDeparture":{"lock":false,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":170},"targetArrival":{"lock":false,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":370},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":112},{"x":894,"y":112},{"x":322,"y":112},{"x":258,"y":112}],"textPositions":{"0":{"x":940,"y":100},"1":{"x":912,"y":124},"2":{"x":276,"y":124},"3":{"x":304,"y":100},"4":{"x":608,"y":100},"5":{"x":608,"y":100},"6":{"x":608,"y":124}}},"warnings":null},{"id":594,"sourceNodeId":133,"sourcePortId":1203,"targetNodeId":172,"targetPortId":1204,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":370},"sourceArrival":{"lock":false,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":170},"targetDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":377},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":144},{"x":-2,"y":144},{"x":-446,"y":144},{"x":-510,"y":144}],"textPositions":{"0":{"x":44,"y":132},"1":{"x":16,"y":156},"2":{"x":-492,"y":156},"3":{"x":-464,"y":132},"4":{"x":-224,"y":132},"5":{"x":-224,"y":132},"6":{"x":-224,"y":156}}},"warnings":null},{"id":595,"sourceNodeId":129,"sourcePortId":1205,"targetNodeId":171,"targetPortId":1206,"travelTime":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":390},"sourceArrival":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":150},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":128},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":412},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2146,"y":144},{"x":-2210,"y":144},{"x":-2398,"y":304},{"x":-2462,"y":304}],"textPositions":{"0":{"x":-2164,"y":132},"1":{"x":-2192,"y":156},"2":{"x":-2444,"y":316},"3":{"x":-2416,"y":292},"4":{"x":-2304,"y":212},"5":{"x":-2304,"y":212},"6":{"x":-2304,"y":236}}},"warnings":null},{"id":596,"sourceNodeId":128,"sourcePortId":1207,"targetNodeId":177,"targetPortId":1208,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":463},"sourceArrival":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":77},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":472},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3074,"y":560},{"x":-3138,"y":560},{"x":-3358,"y":592},{"x":-3422,"y":592}],"textPositions":{"0":{"x":-3092,"y":548},"1":{"x":-3120,"y":572},"2":{"x":-3404,"y":604},"3":{"x":-3376,"y":580},"4":{"x":-3248,"y":564},"5":{"x":-3248,"y":564},"6":{"x":-3248,"y":588}}},"warnings":null},{"id":597,"sourceNodeId":160,"sourcePortId":1209,"targetNodeId":161,"targetPortId":1210,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":501},"sourceArrival":{"lock":true,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":39},"targetDeparture":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":32},"targetArrival":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":508},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3938,"y":624},{"x":-4002,"y":624},{"x":-4190,"y":624},{"x":-4254,"y":624}],"textPositions":{"0":{"x":-3956,"y":612},"1":{"x":-3984,"y":636},"2":{"x":-4236,"y":636},"3":{"x":-4208,"y":612},"4":{"x":-4096,"y":612},"5":{"x":-4096,"y":612},"6":{"x":-4096,"y":636}}},"warnings":null},{"id":598,"sourceNodeId":151,"sourcePortId":1211,"targetNodeId":137,"targetPortId":1212,"travelTime":{"lock":false,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":248},"sourceArrival":{"lock":true,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":292},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":248},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":292},"numberOfStops":4,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3970,"y":112},{"x":4034,"y":112},{"x":4574,"y":112},{"x":4638,"y":112}],"textPositions":{"0":{"x":3988,"y":124},"1":{"x":4016,"y":100},"2":{"x":4620,"y":100},"3":{"x":4592,"y":124},"4":{"x":4304,"y":100},"5":{"x":4304,"y":100},"6":{"x":4304,"y":124}}},"warnings":null},{"id":599,"sourceNodeId":135,"sourcePortId":1213,"targetNodeId":150,"targetPortId":1214,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":125},"sourceArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":295},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":286},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":112},{"x":2914,"y":112},{"x":3230,"y":112},{"x":3294,"y":112}],"textPositions":{"0":{"x":2868,"y":124},"1":{"x":2896,"y":100},"2":{"x":3276,"y":100},"3":{"x":3248,"y":124},"4":{"x":3072,"y":100},"5":{"x":3072,"y":100},"6":{"x":3072,"y":124}}},"warnings":null},{"id":600,"sourceNodeId":150,"sourcePortId":1215,"targetNodeId":151,"targetPortId":1216,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":136},"sourceArrival":{"lock":false,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":284},"targetDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":271},"targetArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":149},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3394,"y":112},{"x":3458,"y":112},{"x":3806,"y":112},{"x":3870,"y":112}],"textPositions":{"0":{"x":3412,"y":124},"1":{"x":3440,"y":100},"2":{"x":3852,"y":100},"3":{"x":3824,"y":124},"4":{"x":3632,"y":100},"5":{"x":3632,"y":100},"6":{"x":3632,"y":124}}},"warnings":null},{"id":601,"sourceNodeId":135,"sourcePortId":1217,"targetNodeId":149,"targetPortId":1218,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":302},"sourceArrival":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":118},"targetDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":176},{"x":2590,"y":176},{"x":2402,"y":176},{"x":2338,"y":176}],"textPositions":{"0":{"x":2636,"y":164},"1":{"x":2608,"y":188},"2":{"x":2356,"y":188},"3":{"x":2384,"y":164},"4":{"x":2496,"y":164},"5":{"x":2496,"y":164},"6":{"x":2496,"y":188}}},"warnings":null},{"id":602,"sourceNodeId":149,"sourcePortId":1219,"targetNodeId":166,"targetPortId":1220,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":176},{"x":2174,"y":176},{"x":1954,"y":176},{"x":1890,"y":176}],"textPositions":{"0":{"x":2220,"y":164},"1":{"x":2192,"y":188},"2":{"x":1908,"y":188},"3":{"x":1936,"y":164},"4":{"x":2064,"y":164},"5":{"x":2064,"y":164},"6":{"x":2064,"y":188}}},"warnings":null},{"id":603,"sourceNodeId":148,"sourcePortId":1221,"targetNodeId":147,"targetPortId":1222,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":320},"sourceArrival":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":100},"targetDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":95},"targetArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":325},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":176},{"x":1278,"y":176},{"x":1122,"y":176},{"x":1058,"y":176}],"textPositions":{"0":{"x":1324,"y":164},"1":{"x":1296,"y":188},"2":{"x":1076,"y":188},"3":{"x":1104,"y":164},"4":{"x":1200,"y":164},"5":{"x":1200,"y":164},"6":{"x":1200,"y":188}}},"warnings":null},{"id":604,"sourceNodeId":147,"sourcePortId":1223,"targetNodeId":133,"targetPortId":1224,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":325},"sourceArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":95},"targetDeparture":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetArrival":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":176},{"x":894,"y":176},{"x":322,"y":176},{"x":258,"y":176}],"textPositions":{"0":{"x":940,"y":164},"1":{"x":912,"y":188},"2":{"x":276,"y":188},"3":{"x":304,"y":164},"4":{"x":608,"y":164},"5":{"x":608,"y":164},"6":{"x":608,"y":188}}},"warnings":null},{"id":605,"sourceNodeId":133,"sourcePortId":1225,"targetNodeId":172,"targetPortId":1226,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"sourceArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":83},"targetArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":337},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":240},{"x":-2,"y":240},{"x":-446,"y":240},{"x":-510,"y":240}],"textPositions":{"0":{"x":44,"y":228},"1":{"x":16,"y":252},"2":{"x":-492,"y":252},"3":{"x":-464,"y":228},"4":{"x":-224,"y":228},"5":{"x":-224,"y":228},"6":{"x":-224,"y":252}}},"warnings":null},{"id":606,"sourceNodeId":151,"sourcePortId":1227,"targetNodeId":162,"targetPortId":1228,"travelTime":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":151},"sourceArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":269},"targetDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":218},"targetArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":202},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3970,"y":48},{"x":4034,"y":48},{"x":4574,"y":-176},{"x":4638,"y":-176}],"textPositions":{"0":{"x":3988,"y":60},"1":{"x":4016,"y":36},"2":{"x":4620,"y":-188},"3":{"x":4592,"y":-164},"4":{"x":4304,"y":-76},"5":{"x":4304,"y":-76},"6":{"x":4304,"y":-52}}},"warnings":null},{"id":607,"sourceNodeId":135,"sourcePortId":1229,"targetNodeId":150,"targetPortId":1230,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":125},"sourceArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":295},"targetDeparture":{"lock":true,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":286},"targetArrival":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":144},{"x":2914,"y":144},{"x":3230,"y":144},{"x":3294,"y":144}],"textPositions":{"0":{"x":2868,"y":156},"1":{"x":2896,"y":132},"2":{"x":3276,"y":132},"3":{"x":3248,"y":156},"4":{"x":3072,"y":132},"5":{"x":3072,"y":132},"6":{"x":3072,"y":156}}},"warnings":null},{"id":608,"sourceNodeId":150,"sourcePortId":1231,"targetNodeId":151,"targetPortId":1232,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":136},"sourceArrival":{"lock":false,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":284},"targetDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":271},"targetArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":149},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3394,"y":144},{"x":3458,"y":144},{"x":3806,"y":144},{"x":3870,"y":144}],"textPositions":{"0":{"x":3412,"y":156},"1":{"x":3440,"y":132},"2":{"x":3852,"y":132},"3":{"x":3824,"y":156},"4":{"x":3632,"y":132},"5":{"x":3632,"y":132},"6":{"x":3632,"y":156}}},"warnings":null},{"id":609,"sourceNodeId":135,"sourcePortId":1233,"targetNodeId":149,"targetPortId":1234,"travelTime":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":302},"sourceArrival":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":118},"targetDeparture":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":103},"targetArrival":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":317},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":208},{"x":2590,"y":208},{"x":2402,"y":208},{"x":2338,"y":208}],"textPositions":{"0":{"x":2636,"y":196},"1":{"x":2608,"y":220},"2":{"x":2356,"y":220},"3":{"x":2384,"y":196},"4":{"x":2496,"y":196},"5":{"x":2496,"y":196},"6":{"x":2496,"y":220}}},"warnings":null},{"id":610,"sourceNodeId":149,"sourcePortId":1235,"targetNodeId":166,"targetPortId":1236,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":317},"sourceArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":103},"targetDeparture":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":97},"targetArrival":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":323},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":208},{"x":2174,"y":208},{"x":1954,"y":208},{"x":1890,"y":208}],"textPositions":{"0":{"x":2220,"y":196},"1":{"x":2192,"y":220},"2":{"x":1908,"y":220},"3":{"x":1936,"y":196},"4":{"x":2064,"y":196},"5":{"x":2064,"y":196},"6":{"x":2064,"y":220}}},"warnings":null},{"id":611,"sourceNodeId":148,"sourcePortId":1237,"targetNodeId":147,"targetPortId":1238,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"sourceArrival":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":85},"targetArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":335},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":208},{"x":1278,"y":208},{"x":1122,"y":208},{"x":1058,"y":208}],"textPositions":{"0":{"x":1324,"y":196},"1":{"x":1296,"y":220},"2":{"x":1076,"y":220},"3":{"x":1104,"y":196},"4":{"x":1200,"y":196},"5":{"x":1200,"y":196},"6":{"x":1200,"y":220}}},"warnings":null},{"id":612,"sourceNodeId":147,"sourcePortId":1239,"targetNodeId":133,"targetPortId":1240,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":335},"sourceArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":85},"targetDeparture":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":80},"targetArrival":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":340},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":208},{"x":894,"y":208},{"x":322,"y":208},{"x":258,"y":208}],"textPositions":{"0":{"x":940,"y":196},"1":{"x":912,"y":220},"2":{"x":276,"y":220},"3":{"x":304,"y":196},"4":{"x":608,"y":196},"5":{"x":608,"y":196},"6":{"x":608,"y":220}}},"warnings":null},{"id":613,"sourceNodeId":133,"sourcePortId":1241,"targetNodeId":172,"targetPortId":1242,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":340},"sourceArrival":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":80},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":73},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":272},{"x":-2,"y":272},{"x":-446,"y":272},{"x":-510,"y":272}],"textPositions":{"0":{"x":44,"y":260},"1":{"x":16,"y":284},"2":{"x":-492,"y":284},"3":{"x":-464,"y":260},"4":{"x":-224,"y":260},"5":{"x":-224,"y":260},"6":{"x":-224,"y":284}}},"warnings":null},{"id":614,"sourceNodeId":151,"sourcePortId":1243,"targetNodeId":162,"targetPortId":1244,"travelTime":{"lock":true,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":151},"sourceArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":269},"targetDeparture":{"lock":false,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":228},"targetArrival":{"lock":false,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":192},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3970,"y":80},{"x":4034,"y":80},{"x":4574,"y":-144},{"x":4638,"y":-144}],"textPositions":{"0":{"x":3988,"y":92},"1":{"x":4016,"y":68},"2":{"x":4620,"y":-156},"3":{"x":4592,"y":-132},"4":{"x":4304,"y":-44},"5":{"x":4304,"y":-44},"6":{"x":4304,"y":-20}}},"warnings":null},{"id":615,"sourceNodeId":135,"sourcePortId":1245,"targetNodeId":150,"targetPortId":1246,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":95},"sourceArrival":{"lock":true,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":205},"targetDeparture":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":196},"targetArrival":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":104},"numberOfStops":0,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":208},{"x":2914,"y":208},{"x":3230,"y":208},{"x":3294,"y":208}],"textPositions":{"0":{"x":2868,"y":220},"1":{"x":2896,"y":196},"2":{"x":3276,"y":196},"3":{"x":3248,"y":220},"4":{"x":3072,"y":196},"5":{"x":3072,"y":196},"6":{"x":3072,"y":220}}},"warnings":null},{"id":616,"sourceNodeId":150,"sourcePortId":1247,"targetNodeId":151,"targetPortId":1248,"travelTime":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"sourceArrival":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":194},"targetDeparture":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":181},"targetArrival":{"lock":true,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":119},"numberOfStops":0,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3394,"y":208},{"x":3458,"y":208},{"x":3806,"y":208},{"x":3870,"y":208}],"textPositions":{"0":{"x":3412,"y":220},"1":{"x":3440,"y":196},"2":{"x":3852,"y":196},"3":{"x":3824,"y":220},"4":{"x":3632,"y":196},"5":{"x":3632,"y":196},"6":{"x":3632,"y":220}}},"warnings":null},{"id":617,"sourceNodeId":151,"sourcePortId":1249,"targetNodeId":139,"targetPortId":1250,"travelTime":{"lock":false,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":121},"sourceArrival":{"lock":true,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":179},"targetDeparture":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":130},"targetArrival":{"lock":true,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":170},"numberOfStops":2,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3888,"y":30},{"x":3888,"y":-34},{"x":4272,"y":-286},{"x":4272,"y":-350}],"textPositions":{"0":{"x":3900,"y":12},"1":{"x":3876,"y":-16},"2":{"x":4260,"y":-332},"3":{"x":4284,"y":-304},"4":{"x":4068,"y":-160},"5":{"x":4068,"y":-160},"6":{"x":4092,"y":-160}}},"warnings":null},{"id":618,"sourceNodeId":138,"sourcePortId":1251,"targetNodeId":163,"targetPortId":1252,"travelTime":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":0},"sourceArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"targetDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":59},"targetArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":1},"numberOfStops":0,"trainrunId":91,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":-1054},{"x":2672,"y":-990},{"x":2800,"y":-610},{"x":2800,"y":-546}],"textPositions":{"0":{"x":2660,"y":-1036},"1":{"x":2684,"y":-1008},"2":{"x":2812,"y":-564},"3":{"x":2788,"y":-592},"4":{"x":2748,"y":-800},"5":{"x":2748,"y":-800},"6":{"x":2724,"y":-800}}},"warnings":null},{"id":619,"sourceNodeId":163,"sourcePortId":1253,"targetNodeId":135,"targetPortId":1254,"travelTime":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":3},"sourceArrival":{"lock":false,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":57},"targetDeparture":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":56},"targetArrival":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":4},"numberOfStops":0,"trainrunId":91,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2800,"y":-478},{"x":2800,"y":-414},{"x":2704,"y":-34},{"x":2704,"y":30}],"textPositions":{"0":{"x":2788,"y":-460},"1":{"x":2812,"y":-432},"2":{"x":2716,"y":12},"3":{"x":2692,"y":-16},"4":{"x":2740,"y":-224},"5":{"x":2740,"y":-224},"6":{"x":2764,"y":-224}}},"warnings":null},{"id":620,"sourceNodeId":135,"sourcePortId":1255,"targetNodeId":138,"targetPortId":1256,"travelTime":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":120},"sourceArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"targetDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":59},"targetArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":121},"numberOfStops":0,"trainrunId":92,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":30},{"x":2672,"y":-34},{"x":2640,"y":-990},{"x":2640,"y":-1054}],"textPositions":{"0":{"x":2684,"y":12},"1":{"x":2660,"y":-16},"2":{"x":2628,"y":-1036},"3":{"x":2652,"y":-1008},"4":{"x":2668,"y":-512},"5":{"x":2668,"y":-512},"6":{"x":2644,"y":-512}}},"warnings":null},{"id":621,"sourceNodeId":166,"sourcePortId":1257,"targetNodeId":148,"targetPortId":1258,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":356},"sourceArrival":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":184},"targetDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":179},"targetArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":361},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":48},{"x":1726,"y":48},{"x":1506,"y":48},{"x":1442,"y":48}],"textPositions":{"0":{"x":1772,"y":36},"1":{"x":1744,"y":60},"2":{"x":1460,"y":60},"3":{"x":1488,"y":36},"4":{"x":1616,"y":36},"5":{"x":1616,"y":36},"6":{"x":1616,"y":60}}},"warnings":null},{"id":622,"sourceNodeId":166,"sourcePortId":1259,"targetNodeId":148,"targetPortId":1260,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":377},"sourceArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetDeparture":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":156},"targetArrival":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":384},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":144},{"x":1726,"y":144},{"x":1506,"y":144},{"x":1442,"y":144}],"textPositions":{"0":{"x":1772,"y":132},"1":{"x":1744,"y":156},"2":{"x":1460,"y":156},"3":{"x":1488,"y":132},"4":{"x":1616,"y":132},"5":{"x":1616,"y":132},"6":{"x":1616,"y":156}}},"warnings":null},{"id":623,"sourceNodeId":166,"sourcePortId":1261,"targetNodeId":148,"targetPortId":1262,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"sourceArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"targetDeparture":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":100},"targetArrival":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":320},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":176},{"x":1726,"y":176},{"x":1506,"y":176},{"x":1442,"y":176}],"textPositions":{"0":{"x":1772,"y":164},"1":{"x":1744,"y":188},"2":{"x":1460,"y":188},"3":{"x":1488,"y":164},"4":{"x":1616,"y":164},"5":{"x":1616,"y":164},"6":{"x":1616,"y":188}}},"warnings":null},{"id":624,"sourceNodeId":166,"sourcePortId":1263,"targetNodeId":148,"targetPortId":1264,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":325},"sourceArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":95},"targetDeparture":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetArrival":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":208},{"x":1726,"y":208},{"x":1506,"y":208},{"x":1442,"y":208}],"textPositions":{"0":{"x":1772,"y":196},"1":{"x":1744,"y":220},"2":{"x":1460,"y":220},"3":{"x":1488,"y":196},"4":{"x":1616,"y":196},"5":{"x":1616,"y":196},"6":{"x":1616,"y":220}}},"warnings":null},{"id":625,"sourceNodeId":166,"sourcePortId":1265,"targetNodeId":148,"targetPortId":1266,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetDeparture":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":105},"targetArrival":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":315},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":240},{"x":1726,"y":240},{"x":1506,"y":240},{"x":1442,"y":240}],"textPositions":{"0":{"x":1772,"y":228},"1":{"x":1744,"y":252},"2":{"x":1460,"y":252},"3":{"x":1488,"y":228},"4":{"x":1616,"y":228},"5":{"x":1616,"y":228},"6":{"x":1616,"y":252}}},"warnings":null},{"id":626,"sourceNodeId":134,"sourcePortId":1267,"targetNodeId":164,"targetPortId":1268,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":11},"sourceArrival":{"lock":false,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":169},"targetDeparture":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":156},"targetArrival":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":24},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":322,"y":-1872},{"x":386,"y":-1872},{"x":990,"y":-944},{"x":1054,"y":-944}],"textPositions":{"0":{"x":340,"y":-1860},"1":{"x":368,"y":-1884},"2":{"x":1036,"y":-956},"3":{"x":1008,"y":-932},"4":{"x":688,"y":-1420},"5":{"x":688,"y":-1420},"6":{"x":688,"y":-1396}}},"warnings":null},{"id":627,"sourceNodeId":164,"sourcePortId":1269,"targetNodeId":165,"targetPortId":1270,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":25},"sourceArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":155},"targetDeparture":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":146},"targetArrival":{"lock":false,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":34},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1154,"y":-944},{"x":1218,"y":-944},{"x":1726,"y":-656},{"x":1790,"y":-656}],"textPositions":{"0":{"x":1172,"y":-932},"1":{"x":1200,"y":-956},"2":{"x":1772,"y":-668},"3":{"x":1744,"y":-644},"4":{"x":1472,"y":-812},"5":{"x":1472,"y":-812},"6":{"x":1472,"y":-788}}},"warnings":null},{"id":628,"sourceNodeId":165,"sourcePortId":1271,"targetNodeId":166,"targetPortId":1272,"travelTime":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"sourceArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":145},"targetDeparture":{"lock":false,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":123},"targetArrival":{"lock":false,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":57},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1808,"y":-606},{"x":1808,"y":-542},{"x":1808,"y":-34},{"x":1808,"y":30}],"textPositions":{"0":{"x":1796,"y":-588},"1":{"x":1820,"y":-560},"2":{"x":1820,"y":12},"3":{"x":1796,"y":-16},"4":{"x":1796,"y":-288},"5":{"x":1796,"y":-288},"6":{"x":1820,"y":-288}}},"warnings":null},{"id":629,"sourceNodeId":166,"sourcePortId":1273,"targetNodeId":149,"targetPortId":1274,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"sourceArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":120},"targetDeparture":{"lock":false,"time":53,"warning":null,"timeFormatter":null,"consecutiveTime":113},"targetArrival":{"lock":false,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":67},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1890,"y":272},{"x":1954,"y":272},{"x":2174,"y":272},{"x":2238,"y":272}],"textPositions":{"0":{"x":1908,"y":284},"1":{"x":1936,"y":260},"2":{"x":2220,"y":260},"3":{"x":2192,"y":284},"4":{"x":2064,"y":260},"5":{"x":2064,"y":260},"6":{"x":2064,"y":284}}},"warnings":null},{"id":630,"sourceNodeId":149,"sourcePortId":1275,"targetNodeId":135,"targetPortId":1276,"travelTime":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetDeparture":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":96},"targetArrival":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":84},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2338,"y":272},{"x":2402,"y":272},{"x":2590,"y":272},{"x":2654,"y":272}],"textPositions":{"0":{"x":2356,"y":284},"1":{"x":2384,"y":260},"2":{"x":2636,"y":260},"3":{"x":2608,"y":284},"4":{"x":2496,"y":260},"5":{"x":2496,"y":260},"6":{"x":2496,"y":284}}},"warnings":null},{"id":631,"sourceNodeId":134,"sourcePortId":1277,"targetNodeId":146,"targetPortId":1278,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":6},"sourceArrival":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":174},"targetDeparture":{"lock":false,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":169},"targetArrival":{"lock":false,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":11},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":-1822},{"x":144,"y":-1758},{"x":144,"y":-1474},{"x":144,"y":-1410}],"textPositions":{"0":{"x":132,"y":-1804},"1":{"x":156,"y":-1776},"2":{"x":156,"y":-1428},"3":{"x":132,"y":-1456},"4":{"x":132,"y":-1616},"5":{"x":132,"y":-1616},"6":{"x":156,"y":-1616}}},"warnings":null},{"id":632,"sourceNodeId":146,"sourcePortId":1279,"targetNodeId":145,"targetPortId":1280,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":11},"sourceArrival":{"lock":false,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":169},"targetDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":17},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":-1342},{"x":144,"y":-1278},{"x":144,"y":-994},{"x":144,"y":-930}],"textPositions":{"0":{"x":132,"y":-1324},"1":{"x":156,"y":-1296},"2":{"x":156,"y":-948},"3":{"x":132,"y":-976},"4":{"x":132,"y":-1136},"5":{"x":132,"y":-1136},"6":{"x":156,"y":-1136}}},"warnings":null},{"id":633,"sourceNodeId":145,"sourcePortId":1281,"targetNodeId":144,"targetPortId":1282,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":17},"sourceArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetDeparture":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":157},"targetArrival":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":23},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":-862},{"x":144,"y":-798},{"x":144,"y":-514},{"x":144,"y":-450}],"textPositions":{"0":{"x":132,"y":-844},"1":{"x":156,"y":-816},"2":{"x":156,"y":-468},"3":{"x":132,"y":-496},"4":{"x":132,"y":-656},"5":{"x":132,"y":-656},"6":{"x":156,"y":-656}}},"warnings":null},{"id":634,"sourceNodeId":144,"sourcePortId":1283,"targetNodeId":147,"targetPortId":1284,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":23},"sourceArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":157},"targetDeparture":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":147},"targetArrival":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":33},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":322,"y":-400},{"x":386,"y":-400},{"x":894,"y":80},{"x":958,"y":80}],"textPositions":{"0":{"x":340,"y":-388},"1":{"x":368,"y":-412},"2":{"x":940,"y":68},"3":{"x":912,"y":92},"4":{"x":640,"y":-172},"5":{"x":640,"y":-172},"6":{"x":640,"y":-148}}},"warnings":null},{"id":635,"sourceNodeId":147,"sourcePortId":1285,"targetNodeId":148,"targetPortId":1286,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":33},"sourceArrival":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":147},"targetDeparture":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":140},"targetArrival":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":40},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1058,"y":112},{"x":1122,"y":112},{"x":1278,"y":112},{"x":1342,"y":112}],"textPositions":{"0":{"x":1076,"y":124},"1":{"x":1104,"y":100},"2":{"x":1324,"y":100},"3":{"x":1296,"y":124},"4":{"x":1200,"y":100},"5":{"x":1200,"y":100},"6":{"x":1200,"y":124}}},"warnings":null},{"id":636,"sourceNodeId":148,"sourcePortId":1287,"targetNodeId":166,"targetPortId":1288,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":40},"sourceArrival":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":140},"targetDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"targetArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1442,"y":112},{"x":1506,"y":112},{"x":1726,"y":112},{"x":1790,"y":112}],"textPositions":{"0":{"x":1460,"y":124},"1":{"x":1488,"y":100},"2":{"x":1772,"y":100},"3":{"x":1744,"y":124},"4":{"x":1616,"y":100},"5":{"x":1616,"y":100},"6":{"x":1616,"y":124}}},"warnings":null},{"id":637,"sourceNodeId":166,"sourcePortId":1289,"targetNodeId":149,"targetPortId":1290,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"sourceArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":128},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1890,"y":112},{"x":1954,"y":112},{"x":2174,"y":112},{"x":2238,"y":112}],"textPositions":{"0":{"x":1908,"y":124},"1":{"x":1936,"y":100},"2":{"x":2220,"y":100},"3":{"x":2192,"y":124},"4":{"x":2064,"y":100},"5":{"x":2064,"y":100},"6":{"x":2064,"y":124}}},"warnings":null},{"id":638,"sourceNodeId":149,"sourcePortId":1291,"targetNodeId":135,"targetPortId":1292,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":128},"targetDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":120},"targetArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2338,"y":112},{"x":2402,"y":112},{"x":2590,"y":112},{"x":2654,"y":112}],"textPositions":{"0":{"x":2356,"y":124},"1":{"x":2384,"y":100},"2":{"x":2636,"y":100},"3":{"x":2608,"y":124},"4":{"x":2496,"y":100},"5":{"x":2496,"y":100},"6":{"x":2496,"y":124}}},"warnings":null},{"id":639,"sourceNodeId":147,"sourcePortId":1293,"targetNodeId":148,"targetPortId":1294,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":54},"sourceArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":126},"targetDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":120},"targetArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"numberOfStops":0,"trainrunId":97,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1058,"y":272},{"x":1122,"y":272},{"x":1278,"y":272},{"x":1342,"y":272}],"textPositions":{"0":{"x":1076,"y":284},"1":{"x":1104,"y":260},"2":{"x":1324,"y":260},"3":{"x":1296,"y":284},"4":{"x":1200,"y":260},"5":{"x":1200,"y":260},"6":{"x":1200,"y":284}}},"warnings":null},{"id":640,"sourceNodeId":148,"sourcePortId":1295,"targetNodeId":166,"targetPortId":1296,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":62},"sourceArrival":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":118},"targetDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"numberOfStops":0,"trainrunId":97,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1442,"y":272},{"x":1506,"y":272},{"x":1726,"y":272},{"x":1790,"y":272}],"textPositions":{"0":{"x":1460,"y":284},"1":{"x":1488,"y":260},"2":{"x":1772,"y":260},"3":{"x":1744,"y":284},"4":{"x":1616,"y":260},"5":{"x":1616,"y":260},"6":{"x":1616,"y":284}}},"warnings":null},{"id":641,"sourceNodeId":166,"sourcePortId":1297,"targetNodeId":149,"targetPortId":1298,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetDeparture":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":105},"targetArrival":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":75},"numberOfStops":0,"trainrunId":97,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1890,"y":304},{"x":1954,"y":304},{"x":2174,"y":304},{"x":2238,"y":304}],"textPositions":{"0":{"x":1908,"y":316},"1":{"x":1936,"y":292},"2":{"x":2220,"y":292},"3":{"x":2192,"y":316},"4":{"x":2064,"y":292},"5":{"x":2064,"y":292},"6":{"x":2064,"y":316}}},"warnings":null},{"id":642,"sourceNodeId":149,"sourcePortId":1299,"targetNodeId":135,"targetPortId":1300,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":75},"sourceArrival":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":105},"targetDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":98},"targetArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":82},"numberOfStops":0,"trainrunId":97,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2338,"y":304},{"x":2402,"y":304},{"x":2590,"y":304},{"x":2654,"y":304}],"textPositions":{"0":{"x":2356,"y":316},"1":{"x":2384,"y":292},"2":{"x":2636,"y":292},"3":{"x":2608,"y":316},"4":{"x":2496,"y":292},"5":{"x":2496,"y":292},"6":{"x":2496,"y":316}}},"warnings":null},{"id":643,"sourceNodeId":134,"sourcePortId":1301,"targetNodeId":146,"targetPortId":1302,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":28},"sourceArrival":{"lock":false,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":272},"targetDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":265},"targetArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":-1822},{"x":208,"y":-1758},{"x":208,"y":-1474},{"x":208,"y":-1410}],"textPositions":{"0":{"x":196,"y":-1804},"1":{"x":220,"y":-1776},"2":{"x":220,"y":-1428},"3":{"x":196,"y":-1456},"4":{"x":196,"y":-1616},"5":{"x":196,"y":-1616},"6":{"x":220,"y":-1616}}},"warnings":null},{"id":644,"sourceNodeId":146,"sourcePortId":1303,"targetNodeId":145,"targetPortId":1304,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"sourceArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":265},"targetDeparture":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":259},"targetArrival":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":-1342},{"x":208,"y":-1278},{"x":208,"y":-994},{"x":208,"y":-930}],"textPositions":{"0":{"x":196,"y":-1324},"1":{"x":220,"y":-1296},"2":{"x":220,"y":-948},"3":{"x":196,"y":-976},"4":{"x":196,"y":-1136},"5":{"x":196,"y":-1136},"6":{"x":220,"y":-1136}}},"warnings":null},{"id":645,"sourceNodeId":145,"sourcePortId":1305,"targetNodeId":144,"targetPortId":1306,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"sourceArrival":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":259},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":253},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":47},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":-862},{"x":208,"y":-798},{"x":208,"y":-514},{"x":208,"y":-450}],"textPositions":{"0":{"x":196,"y":-844},"1":{"x":220,"y":-816},"2":{"x":220,"y":-468},"3":{"x":196,"y":-496},"4":{"x":196,"y":-656},"5":{"x":196,"y":-656},"6":{"x":220,"y":-656}}},"warnings":null},{"id":646,"sourceNodeId":144,"sourcePortId":1307,"targetNodeId":133,"targetPortId":1308,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":47},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":253},"targetDeparture":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":245},"targetArrival":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":55},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":-354},{"x":144,"y":-290},{"x":144,"y":30},{"x":144,"y":94}],"textPositions":{"0":{"x":132,"y":-336},"1":{"x":156,"y":-308},"2":{"x":156,"y":76},"3":{"x":132,"y":48},"4":{"x":132,"y":-130},"5":{"x":132,"y":-130},"6":{"x":156,"y":-130}}},"warnings":null},{"id":647,"sourceNodeId":133,"sourcePortId":1309,"targetNodeId":172,"targetPortId":1310,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":58},"sourceArrival":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":242},"targetDeparture":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":235},"targetArrival":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":208},{"x":-2,"y":208},{"x":-446,"y":208},{"x":-510,"y":208}],"textPositions":{"0":{"x":44,"y":196},"1":{"x":16,"y":220},"2":{"x":-492,"y":220},"3":{"x":-464,"y":196},"4":{"x":-224,"y":196},"5":{"x":-224,"y":196},"6":{"x":-224,"y":220}}},"warnings":null},{"id":648,"sourceNodeId":129,"sourcePortId":1311,"targetNodeId":167,"targetPortId":1312,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":94},"sourceArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":206},"targetDeparture":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":188},"targetArrival":{"lock":true,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2096,"y":382},{"x":-2096,"y":446},{"x":-2096,"y":574},{"x":-2096,"y":638}],"textPositions":{"0":{"x":-2108,"y":400},"1":{"x":-2084,"y":428},"2":{"x":-2084,"y":620},"3":{"x":-2108,"y":592},"4":{"x":-2108,"y":510},"5":{"x":-2108,"y":510},"6":{"x":-2084,"y":510}}},"warnings":null},{"id":649,"sourceNodeId":129,"sourcePortId":1313,"targetNodeId":167,"targetPortId":1314,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":359},"sourceArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":61},"targetDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":43},"targetArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":377},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2064,"y":382},{"x":-2064,"y":446},{"x":-2064,"y":574},{"x":-2064,"y":638}],"textPositions":{"0":{"x":-2076,"y":400},"1":{"x":-2052,"y":428},"2":{"x":-2052,"y":620},"3":{"x":-2076,"y":592},"4":{"x":-2076,"y":510},"5":{"x":-2076,"y":510},"6":{"x":-2052,"y":510}}},"warnings":null},{"id":650,"sourceNodeId":167,"sourcePortId":1315,"targetNodeId":168,"targetPortId":1316,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":114},"sourceArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":186},"targetDeparture":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":178},"targetArrival":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":122},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2096,"y":706},{"x":-2096,"y":770},{"x":-2096,"y":862},{"x":-2096,"y":926}],"textPositions":{"0":{"x":-2108,"y":724},"1":{"x":-2084,"y":752},"2":{"x":-2084,"y":908},"3":{"x":-2108,"y":880},"4":{"x":-2108,"y":816},"5":{"x":-2108,"y":816},"6":{"x":-2084,"y":816}}},"warnings":null},{"id":651,"sourceNodeId":168,"sourcePortId":1317,"targetNodeId":131,"targetPortId":1318,"travelTime":{"lock":true,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":124},"sourceArrival":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":176},"targetDeparture":{"lock":false,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":152},"targetArrival":{"lock":false,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":148},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2014,"y":944},{"x":-1950,"y":944},{"x":-1154,"y":944},{"x":-1090,"y":944}],"textPositions":{"0":{"x":-1996,"y":956},"1":{"x":-1968,"y":932},"2":{"x":-1108,"y":932},"3":{"x":-1136,"y":956},"4":{"x":-1552,"y":932},"5":{"x":-1552,"y":932},"6":{"x":-1552,"y":956}}},"warnings":null},{"id":652,"sourceNodeId":167,"sourcePortId":1319,"targetNodeId":168,"targetPortId":1320,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":379},"sourceArrival":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"targetDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":31},"targetArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":389},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2064,"y":706},{"x":-2064,"y":770},{"x":-2064,"y":862},{"x":-2064,"y":926}],"textPositions":{"0":{"x":-2076,"y":724},"1":{"x":-2052,"y":752},"2":{"x":-2052,"y":908},"3":{"x":-2076,"y":880},"4":{"x":-2076,"y":816},"5":{"x":-2076,"y":816},"6":{"x":-2052,"y":816}}},"warnings":null},{"id":653,"sourceNodeId":168,"sourcePortId":1321,"targetNodeId":132,"targetPortId":1322,"travelTime":{"lock":true,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":391},"sourceArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":29},"targetDeparture":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":4},"targetArrival":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":416},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2096,"y":1022},{"x":-2096,"y":1086},{"x":-2096,"y":1374},{"x":-2096,"y":1438}],"textPositions":{"0":{"x":-2108,"y":1040},"1":{"x":-2084,"y":1068},"2":{"x":-2084,"y":1420},"3":{"x":-2108,"y":1392},"4":{"x":-2108,"y":1230},"5":{"x":-2108,"y":1230},"6":{"x":-2084,"y":1230}}},"warnings":null},{"id":654,"sourceNodeId":132,"sourcePortId":1323,"targetNodeId":168,"targetPortId":1324,"travelTime":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":149},"sourceArrival":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":151},"targetDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":125},"targetArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":175},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2128,"y":1438},{"x":-2128,"y":1374},{"x":-2128,"y":1086},{"x":-2128,"y":1022}],"textPositions":{"0":{"x":-2116,"y":1420},"1":{"x":-2140,"y":1392},"2":{"x":-2140,"y":1040},"3":{"x":-2116,"y":1068},"4":{"x":-2140,"y":1230},"5":{"x":-2140,"y":1230},"6":{"x":-2116,"y":1230}}},"warnings":null},{"id":655,"sourceNodeId":168,"sourcePortId":1325,"targetNodeId":167,"targetPortId":1326,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":178},"sourceArrival":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":122},"targetDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":114},"targetArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":186},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2128,"y":926},{"x":-2128,"y":862},{"x":-2128,"y":770},{"x":-2128,"y":706}],"textPositions":{"0":{"x":-2116,"y":908},"1":{"x":-2140,"y":880},"2":{"x":-2140,"y":724},"3":{"x":-2116,"y":752},"4":{"x":-2140,"y":816},"5":{"x":-2140,"y":816},"6":{"x":-2116,"y":816}}},"warnings":null},{"id":656,"sourceNodeId":167,"sourcePortId":1327,"targetNodeId":129,"targetPortId":1328,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":188},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":94},"targetArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":206},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2128,"y":638},{"x":-2128,"y":574},{"x":-2128,"y":446},{"x":-2128,"y":382}],"textPositions":{"0":{"x":-2116,"y":620},"1":{"x":-2140,"y":592},"2":{"x":-2140,"y":400},"3":{"x":-2116,"y":428},"4":{"x":-2140,"y":510},"5":{"x":-2140,"y":510},"6":{"x":-2116,"y":510}}},"warnings":null},{"id":657,"sourceNodeId":129,"sourcePortId":1329,"targetNodeId":178,"targetPortId":1330,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":214},"sourceArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":86},"targetDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":83},"targetArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":217},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2014,"y":176},{"x":-1950,"y":176},{"x":-1762,"y":176},{"x":-1698,"y":176}],"textPositions":{"0":{"x":-1996,"y":188},"1":{"x":-1968,"y":164},"2":{"x":-1716,"y":164},"3":{"x":-1744,"y":188},"4":{"x":-1856,"y":164},"5":{"x":-1856,"y":164},"6":{"x":-1856,"y":188}}},"warnings":null},{"id":658,"sourceNodeId":133,"sourcePortId":1331,"targetNodeId":144,"targetPortId":1332,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":245},"sourceArrival":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":55},"targetDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":47},"targetArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":253},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":94},{"x":112,"y":30},{"x":112,"y":-290},{"x":112,"y":-354}],"textPositions":{"0":{"x":124,"y":76},"1":{"x":100,"y":48},"2":{"x":100,"y":-336},"3":{"x":124,"y":-308},"4":{"x":100,"y":-130},"5":{"x":100,"y":-130},"6":{"x":124,"y":-130}}},"warnings":null},{"id":659,"sourceNodeId":144,"sourcePortId":1333,"targetNodeId":145,"targetPortId":1334,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":253},"sourceArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":47},"targetDeparture":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"targetArrival":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":259},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":-450},{"x":176,"y":-514},{"x":176,"y":-798},{"x":176,"y":-862}],"textPositions":{"0":{"x":188,"y":-468},"1":{"x":164,"y":-496},"2":{"x":164,"y":-844},"3":{"x":188,"y":-816},"4":{"x":164,"y":-656},"5":{"x":164,"y":-656},"6":{"x":188,"y":-656}}},"warnings":null},{"id":660,"sourceNodeId":145,"sourcePortId":1335,"targetNodeId":146,"targetPortId":1336,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":259},"sourceArrival":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"targetDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"targetArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":265},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":-930},{"x":176,"y":-994},{"x":176,"y":-1278},{"x":176,"y":-1342}],"textPositions":{"0":{"x":188,"y":-948},"1":{"x":164,"y":-976},"2":{"x":164,"y":-1324},"3":{"x":188,"y":-1296},"4":{"x":164,"y":-1136},"5":{"x":164,"y":-1136},"6":{"x":188,"y":-1136}}},"warnings":null},{"id":661,"sourceNodeId":146,"sourcePortId":1337,"targetNodeId":134,"targetPortId":1338,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":265},"sourceArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"targetDeparture":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":28},"targetArrival":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":272},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":-1410},{"x":176,"y":-1474},{"x":176,"y":-1758},{"x":176,"y":-1822}],"textPositions":{"0":{"x":188,"y":-1428},"1":{"x":164,"y":-1456},"2":{"x":164,"y":-1804},"3":{"x":188,"y":-1776},"4":{"x":164,"y":-1616},"5":{"x":164,"y":-1616},"6":{"x":188,"y":-1616}}},"warnings":null},{"id":662,"sourceNodeId":129,"sourcePortId":1339,"targetNodeId":167,"targetPortId":1340,"travelTime":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":368},"sourceArrival":{"lock":true,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"targetDeparture":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":33},"targetArrival":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":387},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2032,"y":382},{"x":-2032,"y":446},{"x":-2032,"y":574},{"x":-2032,"y":638}],"textPositions":{"0":{"x":-2044,"y":400},"1":{"x":-2020,"y":428},"2":{"x":-2020,"y":620},"3":{"x":-2044,"y":592},"4":{"x":-2044,"y":510},"5":{"x":-2044,"y":510},"6":{"x":-2020,"y":510}}},"warnings":null},{"id":663,"sourceNodeId":167,"sourcePortId":1341,"targetNodeId":168,"targetPortId":1342,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":388},"sourceArrival":{"lock":false,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":32},"targetDeparture":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":22},"targetArrival":{"lock":true,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":398},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2032,"y":706},{"x":-2032,"y":770},{"x":-2032,"y":862},{"x":-2032,"y":926}],"textPositions":{"0":{"x":-2044,"y":724},"1":{"x":-2020,"y":752},"2":{"x":-2020,"y":908},"3":{"x":-2044,"y":880},"4":{"x":-2044,"y":816},"5":{"x":-2044,"y":816},"6":{"x":-2020,"y":816}}},"warnings":null},{"id":664,"sourceNodeId":168,"sourcePortId":1343,"targetNodeId":131,"targetPortId":1344,"travelTime":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":399},"sourceArrival":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":21},"targetDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":0},"targetArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":420},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2014,"y":976},{"x":-1950,"y":976},{"x":-1154,"y":976},{"x":-1090,"y":976}],"textPositions":{"0":{"x":-1996,"y":988},"1":{"x":-1968,"y":964},"2":{"x":-1108,"y":964},"3":{"x":-1136,"y":988},"4":{"x":-1552,"y":964},"5":{"x":-1552,"y":964},"6":{"x":-1552,"y":988}}},"warnings":null},{"id":665,"sourceNodeId":169,"sourcePortId":1345,"targetNodeId":153,"targetPortId":1346,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":48},"sourceArrival":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":252},"targetDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":243},"targetArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":57},"numberOfStops":0,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1954,"y":1776},{"x":2018,"y":1776},{"x":2590,"y":1360},{"x":2654,"y":1360}],"textPositions":{"0":{"x":1972,"y":1788},"1":{"x":2000,"y":1764},"2":{"x":2636,"y":1348},"3":{"x":2608,"y":1372},"4":{"x":2304,"y":1556},"5":{"x":2304,"y":1556},"6":{"x":2304,"y":1580}}},"warnings":null},{"id":666,"sourceNodeId":169,"sourcePortId":1347,"targetNodeId":153,"targetPortId":1348,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"sourceArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":42},"targetDeparture":{"lock":false,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":32},"targetArrival":{"lock":false,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":28},"numberOfStops":0,"trainrunId":80,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1954,"y":1744},{"x":2018,"y":1744},{"x":2590,"y":1328},{"x":2654,"y":1328}],"textPositions":{"0":{"x":1972,"y":1756},"1":{"x":2000,"y":1732},"2":{"x":2636,"y":1316},"3":{"x":2608,"y":1340},"4":{"x":2304,"y":1524},"5":{"x":2304,"y":1524},"6":{"x":2304,"y":1548}}},"warnings":null},{"id":667,"sourceNodeId":169,"sourcePortId":1349,"targetNodeId":142,"targetPortId":1350,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":453},"sourceArrival":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":147},"targetDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":138},"targetArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":462},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1854,"y":1776},{"x":1790,"y":1776},{"x":290,"y":1776},{"x":226,"y":1776}],"textPositions":{"0":{"x":1836,"y":1764},"1":{"x":1808,"y":1788},"2":{"x":244,"y":1788},"3":{"x":272,"y":1764},"4":{"x":1040,"y":1764},"5":{"x":1040,"y":1764},"6":{"x":1040,"y":1788}}},"warnings":null},{"id":668,"sourceNodeId":169,"sourcePortId":1351,"targetNodeId":142,"targetPortId":1352,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":273},"sourceArrival":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":87},"targetDeparture":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":78},"targetArrival":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":282},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1854,"y":1744},{"x":1790,"y":1744},{"x":290,"y":1744},{"x":226,"y":1744}],"textPositions":{"0":{"x":1836,"y":1732},"1":{"x":1808,"y":1756},"2":{"x":244,"y":1756},"3":{"x":272,"y":1732},"4":{"x":1040,"y":1732},"5":{"x":1040,"y":1732},"6":{"x":1040,"y":1756}}},"warnings":null},{"id":669,"sourceNodeId":170,"sourcePortId":1353,"targetNodeId":135,"targetPortId":1354,"travelTime":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":74},"sourceArrival":{"lock":true,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":226},"targetDeparture":{"lock":true,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":215},"targetArrival":{"lock":true,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":85},"numberOfStops":0,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2832,"y":734},{"x":2832,"y":670},{"x":2832,"y":414},{"x":2832,"y":350}],"textPositions":{"0":{"x":2844,"y":716},"1":{"x":2820,"y":688},"2":{"x":2820,"y":368},"3":{"x":2844,"y":396},"4":{"x":2820,"y":542},"5":{"x":2820,"y":542},"6":{"x":2844,"y":542}}},"warnings":null},{"id":670,"sourceNodeId":170,"sourcePortId":1355,"targetNodeId":135,"targetPortId":1356,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":43},"sourceArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":17},"targetDeparture":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":10},"targetArrival":{"lock":true,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":50},"numberOfStops":0,"trainrunId":80,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2800,"y":734},{"x":2800,"y":670},{"x":2800,"y":414},{"x":2800,"y":350}],"textPositions":{"0":{"x":2812,"y":716},"1":{"x":2788,"y":688},"2":{"x":2788,"y":368},"3":{"x":2812,"y":396},"4":{"x":2788,"y":542},"5":{"x":2788,"y":542},"6":{"x":2812,"y":542}}},"warnings":null},{"id":671,"sourceNodeId":170,"sourcePortId":1357,"targetNodeId":135,"targetPortId":1358,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetDeparture":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":5},"targetArrival":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":355},"numberOfStops":0,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2768,"y":734},{"x":2768,"y":670},{"x":2768,"y":414},{"x":2768,"y":350}],"textPositions":{"0":{"x":2780,"y":716},"1":{"x":2756,"y":688},"2":{"x":2756,"y":368},"3":{"x":2780,"y":396},"4":{"x":2756,"y":542},"5":{"x":2756,"y":542},"6":{"x":2780,"y":542}}},"warnings":null},{"id":672,"sourceNodeId":170,"sourcePortId":1359,"targetNodeId":135,"targetPortId":1360,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":107},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetDeparture":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":5},"targetArrival":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":115},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":734},{"x":2672,"y":670},{"x":2672,"y":414},{"x":2672,"y":350}],"textPositions":{"0":{"x":2684,"y":716},"1":{"x":2660,"y":688},"2":{"x":2660,"y":368},"3":{"x":2684,"y":396},"4":{"x":2660,"y":542},"5":{"x":2660,"y":542},"6":{"x":2684,"y":542}}},"warnings":null},{"id":673,"sourceNodeId":170,"sourcePortId":1361,"targetNodeId":140,"targetPortId":1362,"travelTime":{"lock":true,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":75},"sourceArrival":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":285},"targetDeparture":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":238},"targetArrival":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":122},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":752},{"x":2914,"y":752},{"x":4574,"y":1200},{"x":4638,"y":1200}],"textPositions":{"0":{"x":2868,"y":764},"1":{"x":2896,"y":740},"2":{"x":4620,"y":1188},"3":{"x":4592,"y":1212},"4":{"x":3744,"y":964},"5":{"x":3744,"y":964},"6":{"x":3744,"y":988}}},"warnings":null},{"id":674,"sourceNodeId":170,"sourcePortId":1363,"targetNodeId":140,"targetPortId":1364,"travelTime":{"lock":false,"time":61,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":141},"sourceArrival":{"lock":true,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":279},"targetDeparture":{"lock":true,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":218},"targetArrival":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":202},"numberOfStops":5,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":784},{"x":2914,"y":784},{"x":4574,"y":1232},{"x":4638,"y":1232}],"textPositions":{"0":{"x":2868,"y":796},"1":{"x":2896,"y":772},"2":{"x":4620,"y":1220},"3":{"x":4592,"y":1244},"4":{"x":3744,"y":996},"5":{"x":3744,"y":996},"6":{"x":3744,"y":1020}}},"warnings":null},{"id":675,"sourceNodeId":142,"sourcePortId":1365,"targetNodeId":141,"targetPortId":1366,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":475},"sourceArrival":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":125},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":494},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":1726},{"x":144,"y":1662},{"x":144,"y":1314},{"x":144,"y":1250}],"textPositions":{"0":{"x":156,"y":1708},"1":{"x":132,"y":1680},"2":{"x":132,"y":1268},"3":{"x":156,"y":1296},"4":{"x":132,"y":1488},"5":{"x":132,"y":1488},"6":{"x":156,"y":1488}}},"warnings":null},{"id":676,"sourceNodeId":141,"sourcePortId":1367,"targetNodeId":143,"targetPortId":1368,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":494},"sourceArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"targetDeparture":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":99},"targetArrival":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":501},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":1182},{"x":144,"y":1118},{"x":144,"y":866},{"x":144,"y":802}],"textPositions":{"0":{"x":156,"y":1164},"1":{"x":132,"y":1136},"2":{"x":132,"y":820},"3":{"x":156,"y":848},"4":{"x":132,"y":992},"5":{"x":132,"y":992},"6":{"x":156,"y":992}}},"warnings":null},{"id":677,"sourceNodeId":143,"sourcePortId":1369,"targetNodeId":133,"targetPortId":1370,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":503},"sourceArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":97},"targetDeparture":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetArrival":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":510},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":734},{"x":112,"y":670},{"x":112,"y":414},{"x":112,"y":350}],"textPositions":{"0":{"x":124,"y":716},"1":{"x":100,"y":688},"2":{"x":100,"y":368},"3":{"x":124,"y":396},"4":{"x":100,"y":542},"5":{"x":100,"y":542},"6":{"x":124,"y":542}}},"warnings":null},{"id":678,"sourceNodeId":133,"sourcePortId":1371,"targetNodeId":144,"targetPortId":1372,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":512},"sourceArrival":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":88},"targetDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":78},"targetArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":522},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":94},{"x":176,"y":30},{"x":176,"y":-290},{"x":176,"y":-354}],"textPositions":{"0":{"x":188,"y":76},"1":{"x":164,"y":48},"2":{"x":164,"y":-336},"3":{"x":188,"y":-308},"4":{"x":164,"y":-130},"5":{"x":164,"y":-130},"6":{"x":188,"y":-130}}},"warnings":null},{"id":679,"sourceNodeId":144,"sourcePortId":1373,"targetNodeId":145,"targetPortId":1374,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":522},"sourceArrival":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":78},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":73},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":527},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":240,"y":-450},{"x":240,"y":-514},{"x":240,"y":-798},{"x":240,"y":-862}],"textPositions":{"0":{"x":252,"y":-468},"1":{"x":228,"y":-496},"2":{"x":228,"y":-844},"3":{"x":252,"y":-816},"4":{"x":228,"y":-656},"5":{"x":228,"y":-656},"6":{"x":252,"y":-656}}},"warnings":null},{"id":680,"sourceNodeId":145,"sourcePortId":1375,"targetNodeId":146,"targetPortId":1376,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":527},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":73},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":532},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":240,"y":-930},{"x":240,"y":-994},{"x":240,"y":-1278},{"x":240,"y":-1342}],"textPositions":{"0":{"x":252,"y":-948},"1":{"x":228,"y":-976},"2":{"x":228,"y":-1324},"3":{"x":252,"y":-1296},"4":{"x":228,"y":-1136},"5":{"x":228,"y":-1136},"6":{"x":252,"y":-1136}}},"warnings":null},{"id":681,"sourceNodeId":146,"sourcePortId":1377,"targetNodeId":134,"targetPortId":1378,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":532},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":63},"targetArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":537},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":240,"y":-1410},{"x":240,"y":-1474},{"x":240,"y":-1758},{"x":240,"y":-1822}],"textPositions":{"0":{"x":252,"y":-1428},"1":{"x":228,"y":-1456},"2":{"x":228,"y":-1804},"3":{"x":252,"y":-1776},"4":{"x":228,"y":-1616},"5":{"x":228,"y":-1616},"6":{"x":252,"y":-1616}}},"warnings":null},{"id":682,"sourceNodeId":171,"sourcePortId":1379,"targetNodeId":128,"targetPortId":1380,"travelTime":{"lock":false,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":387},"sourceArrival":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":153},"targetDeparture":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":104},"targetArrival":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":436},"numberOfStops":2,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2562,"y":336},{"x":-2626,"y":336},{"x":-2910,"y":592},{"x":-2974,"y":592}],"textPositions":{"0":{"x":-2580,"y":324},"1":{"x":-2608,"y":348},"2":{"x":-2956,"y":604},"3":{"x":-2928,"y":580},"4":{"x":-2768,"y":452},"5":{"x":-2768,"y":452},"6":{"x":-2768,"y":476}}},"warnings":null},{"id":683,"sourceNodeId":171,"sourcePortId":1381,"targetNodeId":128,"targetPortId":1382,"travelTime":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":414},"sourceArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":126},"targetDeparture":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":82},"targetArrival":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":458},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2562,"y":304},{"x":-2626,"y":304},{"x":-2910,"y":560},{"x":-2974,"y":560}],"textPositions":{"0":{"x":-2580,"y":292},"1":{"x":-2608,"y":316},"2":{"x":-2956,"y":572},"3":{"x":-2928,"y":548},"4":{"x":-2768,"y":420},"5":{"x":-2768,"y":420},"6":{"x":-2768,"y":444}}},"warnings":null},{"id":684,"sourceNodeId":172,"sourcePortId":1383,"targetNodeId":178,"targetPortId":1384,"travelTime":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":339},"sourceArrival":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":201},"targetDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":185},"targetArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":355},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":304},{"x":-674,"y":304},{"x":-1534,"y":304},{"x":-1598,"y":304}],"textPositions":{"0":{"x":-628,"y":292},"1":{"x":-656,"y":316},"2":{"x":-1580,"y":316},"3":{"x":-1552,"y":292},"4":{"x":-1104,"y":292},"5":{"x":-1104,"y":292},"6":{"x":-1104,"y":316}}},"warnings":null},{"id":685,"sourceNodeId":172,"sourcePortId":1385,"targetNodeId":174,"targetPortId":1386,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":343},"sourceArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":77},"targetDeparture":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":69},"targetArrival":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":351},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":336},{"x":-674,"y":336},{"x":-830,"y":368},{"x":-894,"y":368}],"textPositions":{"0":{"x":-628,"y":324},"1":{"x":-656,"y":348},"2":{"x":-876,"y":380},"3":{"x":-848,"y":356},"4":{"x":-752,"y":340},"5":{"x":-752,"y":340},"6":{"x":-752,"y":364}}},"warnings":null},{"id":686,"sourceNodeId":172,"sourcePortId":1387,"targetNodeId":178,"targetPortId":1388,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":73},"targetDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"targetArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":355},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":272},{"x":-674,"y":272},{"x":-1534,"y":272},{"x":-1598,"y":272}],"textPositions":{"0":{"x":-628,"y":260},"1":{"x":-656,"y":284},"2":{"x":-1580,"y":284},"3":{"x":-1552,"y":260},"4":{"x":-1104,"y":260},"5":{"x":-1104,"y":260},"6":{"x":-1104,"y":284}}},"warnings":null},{"id":687,"sourceNodeId":172,"sourcePortId":1389,"targetNodeId":178,"targetPortId":1390,"travelTime":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":337},"sourceArrival":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":83},"targetDeparture":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":66},"targetArrival":{"lock":true,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":354},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":240},{"x":-674,"y":240},{"x":-1534,"y":240},{"x":-1598,"y":240}],"textPositions":{"0":{"x":-628,"y":228},"1":{"x":-656,"y":252},"2":{"x":-1580,"y":252},"3":{"x":-1552,"y":228},"4":{"x":-1104,"y":228},"5":{"x":-1104,"y":228},"6":{"x":-1104,"y":252}}},"warnings":null},{"id":688,"sourceNodeId":172,"sourcePortId":1391,"targetNodeId":178,"targetPortId":1392,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"sourceArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":235},"targetDeparture":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":217},"targetArrival":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":83},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":208},{"x":-674,"y":208},{"x":-1534,"y":208},{"x":-1598,"y":208}],"textPositions":{"0":{"x":-628,"y":196},"1":{"x":-656,"y":220},"2":{"x":-1580,"y":220},"3":{"x":-1552,"y":196},"4":{"x":-1104,"y":196},"5":{"x":-1104,"y":196},"6":{"x":-1104,"y":220}}},"warnings":null},{"id":689,"sourceNodeId":172,"sourcePortId":1393,"targetNodeId":133,"targetPortId":1394,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":234},"sourceArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":66},"targetDeparture":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":58},"targetArrival":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":242},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-510,"y":176},{"x":-446,"y":176},{"x":-2,"y":176},{"x":62,"y":176}],"textPositions":{"0":{"x":-492,"y":188},"1":{"x":-464,"y":164},"2":{"x":44,"y":164},"3":{"x":16,"y":188},"4":{"x":-224,"y":164},"5":{"x":-224,"y":164},"6":{"x":-224,"y":188}}},"warnings":null},{"id":690,"sourceNodeId":172,"sourcePortId":1395,"targetNodeId":178,"targetPortId":1396,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":377},"sourceArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetDeparture":{"lock":false,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":154},"targetArrival":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":386},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":144},{"x":-674,"y":144},{"x":-1534,"y":144},{"x":-1598,"y":144}],"textPositions":{"0":{"x":-628,"y":132},"1":{"x":-656,"y":156},"2":{"x":-1580,"y":156},"3":{"x":-1552,"y":132},"4":{"x":-1104,"y":132},"5":{"x":-1104,"y":132},"6":{"x":-1104,"y":156}}},"warnings":null},{"id":691,"sourceNodeId":173,"sourcePortId":1397,"targetNodeId":178,"targetPortId":1398,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":371},"sourceArrival":{"lock":true,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":49},"targetDeparture":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":39},"targetArrival":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":381},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1346,"y":368},{"x":-1410,"y":368},{"x":-1534,"y":336},{"x":-1598,"y":336}],"textPositions":{"0":{"x":-1364,"y":356},"1":{"x":-1392,"y":380},"2":{"x":-1580,"y":348},"3":{"x":-1552,"y":324},"4":{"x":-1472,"y":340},"5":{"x":-1472,"y":340},"6":{"x":-1472,"y":364}}},"warnings":null},{"id":692,"sourceNodeId":174,"sourcePortId":1399,"targetNodeId":173,"targetPortId":1400,"travelTime":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":352},"sourceArrival":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetDeparture":{"lock":false,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":51},"targetArrival":{"lock":false,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":369},"numberOfStops":1,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-994,"y":368},{"x":-1058,"y":368},{"x":-1182,"y":368},{"x":-1246,"y":368}],"textPositions":{"0":{"x":-1012,"y":356},"1":{"x":-1040,"y":380},"2":{"x":-1228,"y":380},"3":{"x":-1200,"y":356},"4":{"x":-1120,"y":356},"5":{"x":-1120,"y":356},"6":{"x":-1120,"y":380}}},"warnings":null},{"id":693,"sourceNodeId":135,"sourcePortId":1401,"targetNodeId":149,"targetPortId":1402,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":300},"sourceArrival":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"targetDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"targetArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":80},{"x":2590,"y":80},{"x":2402,"y":80},{"x":2338,"y":80}],"textPositions":{"0":{"x":2636,"y":68},"1":{"x":2608,"y":92},"2":{"x":2356,"y":92},"3":{"x":2384,"y":68},"4":{"x":2496,"y":68},"5":{"x":2496,"y":68},"6":{"x":2496,"y":92}}},"warnings":null},{"id":694,"sourceNodeId":149,"sourcePortId":1403,"targetNodeId":166,"targetPortId":1404,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":80},{"x":2174,"y":80},{"x":1954,"y":80},{"x":1890,"y":80}],"textPositions":{"0":{"x":2220,"y":68},"1":{"x":2192,"y":92},"2":{"x":1908,"y":92},"3":{"x":1936,"y":68},"4":{"x":2064,"y":68},"5":{"x":2064,"y":68},"6":{"x":2064,"y":92}}},"warnings":null},{"id":695,"sourceNodeId":166,"sourcePortId":1405,"targetNodeId":148,"targetPortId":1406,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"sourceArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetDeparture":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":40},"targetArrival":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":320},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":80},{"x":1726,"y":80},{"x":1506,"y":80},{"x":1442,"y":80}],"textPositions":{"0":{"x":1772,"y":68},"1":{"x":1744,"y":92},"2":{"x":1460,"y":92},"3":{"x":1488,"y":68},"4":{"x":1616,"y":68},"5":{"x":1616,"y":68},"6":{"x":1616,"y":92}}},"warnings":null},{"id":696,"sourceNodeId":148,"sourcePortId":1407,"targetNodeId":147,"targetPortId":1408,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":320},"sourceArrival":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":40},"targetDeparture":{"lock":false,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":34},"targetArrival":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":326},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":80},{"x":1278,"y":80},{"x":1122,"y":80},{"x":1058,"y":80}],"textPositions":{"0":{"x":1324,"y":68},"1":{"x":1296,"y":92},"2":{"x":1076,"y":92},"3":{"x":1104,"y":68},"4":{"x":1200,"y":68},"5":{"x":1200,"y":68},"6":{"x":1200,"y":92}}},"warnings":null},{"id":697,"sourceNodeId":147,"sourcePortId":1409,"targetNodeId":144,"targetPortId":1410,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":326},"sourceArrival":{"lock":false,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":34},"targetDeparture":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":27},"targetArrival":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":333},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":48},{"x":894,"y":48},{"x":386,"y":-432},{"x":322,"y":-432}],"textPositions":{"0":{"x":940,"y":36},"1":{"x":912,"y":60},"2":{"x":340,"y":-420},"3":{"x":368,"y":-444},"4":{"x":640,"y":-204},"5":{"x":640,"y":-204},"6":{"x":640,"y":-180}}},"warnings":null},{"id":698,"sourceNodeId":144,"sourcePortId":1411,"targetNodeId":145,"targetPortId":1412,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":333},"sourceArrival":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":27},"targetDeparture":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":21},"targetArrival":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":339},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":-450},{"x":112,"y":-514},{"x":112,"y":-798},{"x":112,"y":-862}],"textPositions":{"0":{"x":124,"y":-468},"1":{"x":100,"y":-496},"2":{"x":100,"y":-844},"3":{"x":124,"y":-816},"4":{"x":100,"y":-656},"5":{"x":100,"y":-656},"6":{"x":124,"y":-656}}},"warnings":null},{"id":699,"sourceNodeId":145,"sourcePortId":1413,"targetNodeId":146,"targetPortId":1414,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":339},"sourceArrival":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":21},"targetDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":14},"targetArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":346},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":-930},{"x":112,"y":-994},{"x":112,"y":-1278},{"x":112,"y":-1342}],"textPositions":{"0":{"x":124,"y":-948},"1":{"x":100,"y":-976},"2":{"x":100,"y":-1324},"3":{"x":124,"y":-1296},"4":{"x":100,"y":-1136},"5":{"x":100,"y":-1136},"6":{"x":124,"y":-1136}}},"warnings":null},{"id":700,"sourceNodeId":146,"sourcePortId":1415,"targetNodeId":134,"targetPortId":1416,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":346},"sourceArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":14},"targetDeparture":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":6},"targetArrival":{"lock":true,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":354},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":-1410},{"x":112,"y":-1474},{"x":112,"y":-1758},{"x":112,"y":-1822}],"textPositions":{"0":{"x":124,"y":-1428},"1":{"x":100,"y":-1456},"2":{"x":100,"y":-1804},"3":{"x":124,"y":-1776},"4":{"x":100,"y":-1616},"5":{"x":100,"y":-1616},"6":{"x":124,"y":-1616}}},"warnings":null},{"id":701,"sourceNodeId":175,"sourcePortId":1417,"targetNodeId":130,"targetPortId":1418,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":421},"sourceArrival":{"lock":true,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":119},"targetDeparture":{"lock":true,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"targetArrival":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":434},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":-16},{"x":-1762,"y":-16},{"x":-2366,"y":-16},{"x":-2430,"y":-16}],"textPositions":{"0":{"x":-1716,"y":-28},"1":{"x":-1744,"y":-4},"2":{"x":-2412,"y":-4},"3":{"x":-2384,"y":-28},"4":{"x":-2064,"y":-28},"5":{"x":-2064,"y":-28},"6":{"x":-2064,"y":-4}}},"warnings":null},{"id":702,"sourceNodeId":137,"sourcePortId":1419,"targetNodeId":176,"targetPortId":1420,"travelTime":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":245},"sourceArrival":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":295},"targetDeparture":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":279},"targetArrival":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":261},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4738,"y":112},{"x":4802,"y":112},{"x":5310,"y":112},{"x":5374,"y":112}],"textPositions":{"0":{"x":4756,"y":124},"1":{"x":4784,"y":100},"2":{"x":5356,"y":100},"3":{"x":5328,"y":124},"4":{"x":5056,"y":100},"5":{"x":5056,"y":100},"6":{"x":5056,"y":124}}},"warnings":null},{"id":703,"sourceNodeId":177,"sourcePortId":1421,"targetNodeId":160,"targetPortId":1422,"travelTime":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":451},"sourceArrival":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":89},"targetDeparture":{"lock":true,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":59},"targetArrival":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":481},"numberOfStops":1,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3522,"y":624},{"x":-3586,"y":624},{"x":-3774,"y":688},{"x":-3838,"y":688}],"textPositions":{"0":{"x":-3540,"y":612},"1":{"x":-3568,"y":636},"2":{"x":-3820,"y":700},"3":{"x":-3792,"y":676},"4":{"x":-3680,"y":644},"5":{"x":-3680,"y":644},"6":{"x":-3680,"y":668}}},"warnings":null},{"id":704,"sourceNodeId":177,"sourcePortId":1423,"targetNodeId":160,"targetPortId":1424,"travelTime":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":472},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetDeparture":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":42},"targetArrival":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":498},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3522,"y":560},{"x":-3586,"y":560},{"x":-3774,"y":624},{"x":-3838,"y":624}],"textPositions":{"0":{"x":-3540,"y":548},"1":{"x":-3568,"y":572},"2":{"x":-3820,"y":636},"3":{"x":-3792,"y":612},"4":{"x":-3680,"y":580},"5":{"x":-3680,"y":580},"6":{"x":-3680,"y":604}}},"warnings":null},{"id":705,"sourceNodeId":177,"sourcePortId":1425,"targetNodeId":160,"targetPortId":1426,"travelTime":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":499},"sourceArrival":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"targetDeparture":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":15},"targetArrival":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":525},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3522,"y":592},{"x":-3586,"y":592},{"x":-3774,"y":656},{"x":-3838,"y":656}],"textPositions":{"0":{"x":-3540,"y":580},"1":{"x":-3568,"y":604},"2":{"x":-3820,"y":668},"3":{"x":-3792,"y":644},"4":{"x":-3680,"y":612},"5":{"x":-3680,"y":612},"6":{"x":-3680,"y":636}}},"warnings":null},{"id":706,"sourceNodeId":178,"sourcePortId":1427,"targetNodeId":129,"targetPortId":1428,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":381},"sourceArrival":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":39},"targetDeparture":{"lock":true,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":36},"targetArrival":{"lock":true,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":384},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":336},{"x":-1762,"y":336},{"x":-1950,"y":336},{"x":-2014,"y":336}],"textPositions":{"0":{"x":-1716,"y":324},"1":{"x":-1744,"y":348},"2":{"x":-1996,"y":348},"3":{"x":-1968,"y":324},"4":{"x":-1856,"y":324},"5":{"x":-1856,"y":324},"6":{"x":-1856,"y":348}}},"warnings":null},{"id":707,"sourceNodeId":178,"sourcePortId":1429,"targetNodeId":129,"targetPortId":1430,"travelTime":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":355},"sourceArrival":{"lock":false,"time":5,"warning":{"title":"Quelle Ankunft Warnung","description":"Quellankunftszeit kann nicht erreicht werden"},"timeFormatter":null,"consecutiveTime":185},"targetDeparture":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":180},"targetArrival":{"lock":true,"time":0,"warning":{"title":"Ziel Ankunft Warnung","description":"Zielankunftszeit kann nicht erreicht werden"},"timeFormatter":null,"consecutiveTime":360},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":304},{"x":-1762,"y":304},{"x":-1950,"y":304},{"x":-2014,"y":304}],"textPositions":{"0":{"x":-1716,"y":292},"1":{"x":-1744,"y":316},"2":{"x":-1996,"y":316},"3":{"x":-1968,"y":292},"4":{"x":-1856,"y":292},"5":{"x":-1856,"y":292},"6":{"x":-1856,"y":316}}},"warnings":null},{"id":708,"sourceNodeId":178,"sourcePortId":1431,"targetNodeId":129,"targetPortId":1432,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":355},"sourceArrival":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"targetDeparture":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":62},"targetArrival":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":358},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":272},{"x":-1762,"y":272},{"x":-1950,"y":272},{"x":-2014,"y":272}],"textPositions":{"0":{"x":-1716,"y":260},"1":{"x":-1744,"y":284},"2":{"x":-1996,"y":284},"3":{"x":-1968,"y":260},"4":{"x":-1856,"y":260},"5":{"x":-1856,"y":260},"6":{"x":-1856,"y":284}}},"warnings":null},{"id":709,"sourceNodeId":178,"sourcePortId":1433,"targetNodeId":129,"targetPortId":1434,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":354},"sourceArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":66},"targetDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":63},"targetArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":357},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":240},{"x":-1762,"y":240},{"x":-1950,"y":240},{"x":-2014,"y":240}],"textPositions":{"0":{"x":-1716,"y":228},"1":{"x":-1744,"y":252},"2":{"x":-1996,"y":252},"3":{"x":-1968,"y":228},"4":{"x":-1856,"y":228},"5":{"x":-1856,"y":228},"6":{"x":-1856,"y":252}}},"warnings":null},{"id":710,"sourceNodeId":178,"sourcePortId":1435,"targetNodeId":129,"targetPortId":1436,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":83},"sourceArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":217},"targetDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":214},"targetArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":86},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":208},{"x":-1762,"y":208},{"x":-1950,"y":208},{"x":-2014,"y":208}],"textPositions":{"0":{"x":-1716,"y":196},"1":{"x":-1744,"y":220},"2":{"x":-1996,"y":220},"3":{"x":-1968,"y":196},"4":{"x":-1856,"y":196},"5":{"x":-1856,"y":196},"6":{"x":-1856,"y":220}}},"warnings":null},{"id":711,"sourceNodeId":178,"sourcePortId":1437,"targetNodeId":172,"targetPortId":1438,"travelTime":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":217},"sourceArrival":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":83},"targetDeparture":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":66},"targetArrival":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":234},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1598,"y":176},{"x":-1534,"y":176},{"x":-674,"y":176},{"x":-610,"y":176}],"textPositions":{"0":{"x":-1580,"y":188},"1":{"x":-1552,"y":164},"2":{"x":-628,"y":164},"3":{"x":-656,"y":188},"4":{"x":-1104,"y":164},"5":{"x":-1104,"y":164},"6":{"x":-1104,"y":188}}},"warnings":null},{"id":712,"sourceNodeId":178,"sourcePortId":1439,"targetNodeId":129,"targetPortId":1440,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":386},"sourceArrival":{"lock":false,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":154},"targetDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":151},"targetArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":389},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":144},{"x":-1762,"y":144},{"x":-1950,"y":144},{"x":-2014,"y":144}],"textPositions":{"0":{"x":-1716,"y":132},"1":{"x":-1744,"y":156},"2":{"x":-1996,"y":156},"3":{"x":-1968,"y":132},"4":{"x":-1856,"y":132},"5":{"x":-1856,"y":132},"6":{"x":-1856,"y":156}}},"warnings":null}],"trainruns":[{"id":75,"name":"21","categoryId":1,"frequencyId":4,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":76,"name":"2","categoryId":1,"frequencyId":4,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":77,"name":"26","categoryId":2,"frequencyId":5,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":78,"name":"46","categoryId":2,"frequencyId":4,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":79,"name":"75","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":80,"name":"70","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":81,"name":"15","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":82,"name":"27","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":83,"name":"26","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":84,"name":"13","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":85,"name":"3","categoryId":1,"frequencyId":4,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":86,"name":"35","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":87,"name":"5","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":88,"name":"1","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":89,"name":"8","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":90,"name":"81","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":91,"name":"48","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[1,9,5]},{"id":92,"name":"","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[1,9,5]},{"id":93,"name":"36","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":94,"name":"3","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":95,"name":"61","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":96,"name":"6","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":97,"name":"37","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]}],"resources":[{"id":88,"capacity":2},{"id":89,"capacity":2},{"id":90,"capacity":2},{"id":91,"capacity":2},{"id":92,"capacity":2},{"id":93,"capacity":2},{"id":94,"capacity":2},{"id":95,"capacity":2},{"id":96,"capacity":2},{"id":97,"capacity":2},{"id":98,"capacity":2},{"id":99,"capacity":2},{"id":100,"capacity":2},{"id":101,"capacity":2},{"id":102,"capacity":2},{"id":103,"capacity":2},{"id":104,"capacity":2},{"id":105,"capacity":2},{"id":106,"capacity":2},{"id":107,"capacity":2},{"id":108,"capacity":2},{"id":109,"capacity":2},{"id":110,"capacity":2},{"id":111,"capacity":2},{"id":112,"capacity":2},{"id":113,"capacity":2},{"id":114,"capacity":2},{"id":115,"capacity":2},{"id":116,"capacity":2},{"id":117,"capacity":2},{"id":118,"capacity":2},{"id":119,"capacity":2},{"id":120,"capacity":2},{"id":121,"capacity":2},{"id":122,"capacity":2},{"id":123,"capacity":2},{"id":124,"capacity":2},{"id":125,"capacity":2},{"id":126,"capacity":2},{"id":127,"capacity":2},{"id":128,"capacity":2},{"id":129,"capacity":2},{"id":130,"capacity":2},{"id":131,"capacity":2},{"id":132,"capacity":2},{"id":133,"capacity":2},{"id":134,"capacity":2},{"id":135,"capacity":2},{"id":136,"capacity":2},{"id":137,"capacity":2},{"id":138,"capacity":2},{"id":139,"capacity":2},{"id":140,"capacity":2},{"id":141,"capacity":2},{"id":142,"capacity":2},{"id":143,"capacity":2},{"id":144,"capacity":2},{"id":145,"capacity":2},{"id":146,"capacity":2},{"id":147,"capacity":2},{"id":148,"capacity":2},{"id":149,"capacity":2},{"id":150,"capacity":2},{"id":151,"capacity":2},{"id":152,"capacity":2},{"id":153,"capacity":2},{"id":154,"capacity":2},{"id":155,"capacity":2},{"id":156,"capacity":2},{"id":157,"capacity":2},{"id":158,"capacity":2},{"id":159,"capacity":2},{"id":160,"capacity":2},{"id":161,"capacity":2},{"id":162,"capacity":2},{"id":163,"capacity":2},{"id":164,"capacity":2},{"id":165,"capacity":2},{"id":166,"capacity":2},{"id":167,"capacity":2},{"id":168,"capacity":2},{"id":169,"capacity":2},{"id":170,"capacity":2},{"id":171,"capacity":2},{"id":172,"capacity":2},{"id":173,"capacity":2},{"id":174,"capacity":2},{"id":175,"capacity":2},{"id":176,"capacity":2},{"id":177,"capacity":2},{"id":178,"capacity":2},{"id":179,"capacity":2},{"id":180,"capacity":2},{"id":181,"capacity":2},{"id":182,"capacity":2},{"id":183,"capacity":2},{"id":184,"capacity":2},{"id":185,"capacity":2},{"id":186,"capacity":2},{"id":187,"capacity":2},{"id":188,"capacity":2},{"id":189,"capacity":2},{"id":190,"capacity":2},{"id":191,"capacity":2},{"id":192,"capacity":2},{"id":193,"capacity":2},{"id":194,"capacity":2},{"id":195,"capacity":2},{"id":196,"capacity":2},{"id":197,"capacity":2},{"id":198,"capacity":2},{"id":199,"capacity":2},{"id":200,"capacity":2},{"id":201,"capacity":2},{"id":202,"capacity":2}],"metadata":{"netzgrafikColors":[],"trainrunCategories":[{"id":0,"name":"International","order":0,"colorRef":"EC","shortName":"EC","fachCategory":"HaltezeitIPV","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":1,"name":"InterCity","order":1,"colorRef":"IC","shortName":"IC","fachCategory":"HaltezeitA","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":2,"name":"InterRegio","order":2,"colorRef":"IR","shortName":"IR","fachCategory":"HaltezeitB","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":3,"name":"RegioExpress","order":3,"colorRef":"RE","shortName":"RE","fachCategory":"HaltezeitC","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":4,"name":"RegioUndSBahnverkehr","order":4,"colorRef":"S","shortName":"S","fachCategory":"HaltezeitD","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":5,"name":"GüterExpress","order":5,"colorRef":"GEX","shortName":"GEX","fachCategory":"HaltezeitUncategorized","sectionHeadway":3,"nodeHeadwayStop":3,"nodeHeadwayNonStop":3,"minimalTurnaroundTime":4},{"id":6,"name":"Güterverkehr","order":6,"colorRef":"G","shortName":"G","fachCategory":"HaltezeitUncategorized","sectionHeadway":3,"nodeHeadwayStop":3,"nodeHeadwayNonStop":3,"minimalTurnaroundTime":4}],"trainrunFrequencies":[{"id":0,"name":"verkehrt viertelstündlich","order":0,"offset":0,"frequency":15,"shortName":"15","linePatternRef":"15"},{"id":1,"name":"verkehrt im 20 Minuten Takt","order":0,"offset":0,"frequency":20,"shortName":"20","linePatternRef":"20"},{"id":2,"name":"verkehrt halbstündlich","order":0,"offset":0,"frequency":30,"shortName":"30","linePatternRef":"30"},{"id":3,"name":"verkehrt stündlich","order":0,"offset":0,"frequency":60,"shortName":"60","linePatternRef":"60"},{"id":4,"name":"verkehrt zweistündlich (gerade)","order":0,"offset":0,"frequency":120,"shortName":"120","linePatternRef":"120"},{"id":5,"name":"verkehrt zweistündlich (ungerade)","order":0,"offset":60,"frequency":120,"shortName":"120+","linePatternRef":"120"}],"trainrunTimeCategories":[{"id":0,"name":"verkehrt uneingeschränkt","order":0,"weekday":[1,2,3,4,5,6,7],"shortName":"7/24","linePatternRef":"7/24","dayTimeInterval":[]},{"id":1,"name":"verkehrt zur Hauptverkehrszeit","order":0,"weekday":[1,2,3,4,5,6,7],"shortName":"HVZ","linePatternRef":"HVZ","dayTimeInterval":[{"to":420,"from":360},{"to":1140,"from":960}]},{"id":2,"name":"verkehrt zeitweise","order":0,"weekday":[],"shortName":"zeitweise","linePatternRef":"ZEITWEISE","dayTimeInterval":[]}]},"freeFloatingTexts":[{"id":1,"x":716,"y":445,"width":192,"height":64,"title":"DEMO ","text":"

This is a demonstration scenario - no guarantee that the data is correct or corresponds to reality.

","backgroundColor":"#ffffff","textColor":"#000000","labelIds":[]}],"labels":[{"id":4,"label":"OK","labelGroupId":1,"labelRef":"Trainrun"},{"id":5,"label":"Zeiten falsch","labelGroupId":3,"labelRef":"Trainrun"}],"labelGroups":[{"id":1,"name":"Standard","labelRef":"Trainrun"},{"id":2,"name":"Standard","labelRef":"Node"},{"id":3,"name":"Standard","labelRef":"Trainrun"}],"filterData":{"filterSettings":[{"id":5,"name":"Neuer Filter","description":"","filterNodeLabels":[],"filterNoteLabels":[],"filterTrainrunLabels":[],"filterArrivalDepartureTime":true,"filterTravelTime":true,"filterTrainrunName":true,"filterConnections":true,"filterShowNonStopTime":true,"filterTrainrunCategory":[{"id":0,"name":"International","order":0,"colorRef":"EC","shortName":"EC","fachCategory":"HaltezeitIPV","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":1,"name":"InterCity","order":1,"colorRef":"IC","shortName":"IC","fachCategory":"HaltezeitA","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":2,"name":"InterRegio","order":2,"colorRef":"IR","shortName":"IR","fachCategory":"HaltezeitB","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":3,"name":"RegioExpress","order":3,"colorRef":"RE","shortName":"RE","fachCategory":"HaltezeitC","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":4,"name":"RegioUndSBahnverkehr","order":4,"colorRef":"S","shortName":"S","fachCategory":"HaltezeitD","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":5,"name":"GüterExpress","order":5,"colorRef":"GEX","shortName":"GEX","fachCategory":"HaltezeitUncategorized","sectionHeadway":3,"nodeHeadwayStop":3,"nodeHeadwayNonStop":3,"minimalTurnaroundTime":4},{"id":6,"name":"Güterverkehr","order":6,"colorRef":"G","shortName":"G","fachCategory":"HaltezeitUncategorized","sectionHeadway":3,"nodeHeadwayStop":3,"nodeHeadwayNonStop":3,"minimalTurnaroundTime":4}],"filterTrainrunFrequency":[{"id":0,"name":"verkehrt viertelstündlich","order":0,"offset":0,"frequency":15,"shortName":"15","linePatternRef":"15"},{"id":1,"name":"verkehrt im 20 Minuten Takt","order":0,"offset":0,"frequency":20,"shortName":"20","linePatternRef":"20"},{"id":2,"name":"verkehrt halbstündlich","order":0,"offset":0,"frequency":30,"shortName":"30","linePatternRef":"30"},{"id":3,"name":"verkehrt stündlich","order":0,"offset":0,"frequency":60,"shortName":"60","linePatternRef":"60"},{"id":4,"name":"verkehrt zweistündlich (gerade)","order":0,"offset":0,"frequency":120,"shortName":"120","linePatternRef":"120"},{"id":5,"name":"verkehrt zweistündlich (ungerade)","order":0,"offset":60,"frequency":120,"shortName":"120+","linePatternRef":"120"}],"filterTrainrunTimeCategory":[{"id":0,"name":"verkehrt uneingeschränkt","order":0,"weekday":[1,2,3,4,5,6,7],"shortName":"7/24","linePatternRef":"7/24","dayTimeInterval":[]},{"id":1,"name":"verkehrt zur Hauptverkehrszeit","order":0,"weekday":[1,2,3,4,5,6,7],"shortName":"HVZ","linePatternRef":"HVZ","dayTimeInterval":[{"to":420,"from":360},{"to":1140,"from":960}]},{"id":2,"name":"verkehrt zeitweise","order":0,"weekday":[],"shortName":"zeitweise","linePatternRef":"ZEITWEISE","dayTimeInterval":[]}],"filterAllEmptyNodes":false,"filterAllNonStopNodes":false,"filterNotes":false,"timeDisplayPrecision":1,"isTemporaryDisableFilteringOfItemsInView":false,"temporaryEmptyAndNonStopFilteringSwitchedOff":false}]}}' + ); + } +} diff --git a/src/environments/environment.model.ts b/src/environments/environment.model.ts index a36321ca..0ec0626d 100644 --- a/src/environments/environment.model.ts +++ b/src/environments/environment.model.ts @@ -7,4 +7,5 @@ export interface Environment { authConfig?: AuthConfig; disableBackend: boolean; customElement: boolean; + standalonedemo: boolean; } diff --git a/src/environments/environment.standalone.ts b/src/environments/environment.standalone.ts index ca2a9e39..27de6a4e 100644 --- a/src/environments/environment.standalone.ts +++ b/src/environments/environment.standalone.ts @@ -4,4 +4,5 @@ export const environment: Environment = { production: true, disableBackend: true, customElement: true, + standalonedemo: false, }; diff --git a/src/environments/environment.standalonedemo.ts b/src/environments/environment.standalonedemo.ts new file mode 100644 index 00000000..30183cc8 --- /dev/null +++ b/src/environments/environment.standalonedemo.ts @@ -0,0 +1,8 @@ +import {Environment} from "./environment.model"; + +export const environment: Environment = { + production: true, + disableBackend: true, + customElement: true, + standalonedemo: true, +}; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 44ca836f..a2001543 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -25,6 +25,7 @@ export const environment: Environment = { authConfig, disableBackend: false, customElement: false, + standalonedemo: false, }; /* From 8ae8fa38a2f3af47ec323d9a6e7dc5b1096cc667 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Mon, 7 Oct 2024 22:10:52 +0200 Subject: [PATCH 137/197] Update deploy-standalone-github.yml (#309) --- .github/workflows/deploy-standalone-github.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-standalone-github.yml b/.github/workflows/deploy-standalone-github.yml index d1b31e1e..69b3ffbe 100644 --- a/.github/workflows/deploy-standalone-github.yml +++ b/.github/workflows/deploy-standalone-github.yml @@ -29,4 +29,4 @@ jobs: uses: bitovi/github-actions-angular-to-github-pages@v1.0.0 with: path: dist/netzgrafik-frontend - build_command: npm run build:standalone -- --base-href=netzgrafik-frontend + build_command: npm run build:standalonedemo -- --base-href=netzgrafik-frontend From 294bc9a9fc09164bb4e561112dbbc2b9016d7a05 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Mon, 7 Oct 2024 22:22:09 +0200 Subject: [PATCH 138/197] Update continuous-integration.yml (#310) --- .github/workflows/continuous-integration.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 65823691..07f2eead 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -71,3 +71,20 @@ jobs: with: name: build-standalone path: dist/netzgrafik-frontend/ + + build-standalonedemo: + runs-on: ubuntu-latest + needs: lint + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'npm' + - run: npm clean-install + - run: npm run build:standalonedemo + - name: Store build artifacts + uses: actions/upload-artifact@v4 + with: + name: build-standalone-demo + path: dist/netzgrafik-frontend/ From 03d44a00401bc45bddc9a3acd967fdd1689006fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Henriot?= <142150521+shenriotpro@users.noreply.github.com> Date: Tue, 8 Oct 2024 09:50:51 +0200 Subject: [PATCH 139/197] test: improve NodeService coverage (#307) --- src/integration-testing/node.service.test.spec.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/integration-testing/node.service.test.spec.ts b/src/integration-testing/node.service.test.spec.ts index 3ed3faf4..869d865b 100644 --- a/src/integration-testing/node.service.test.spec.ts +++ b/src/integration-testing/node.service.test.spec.ts @@ -88,6 +88,8 @@ describe("NodeService Test", () => { const netzgrafik = NetzgrafikUnitTesting.getUnitTestNetzgrafik(); dataService.loadNetzgrafikDto(netzgrafik); expect(nodes.length).toBe(5); + expect(nodeService.getVisibleNodes().length).toBe(5); + expect(nodeService.getSelectedNodes().length).toBe(0); nodeService.setDataService(dataService); const node = netzgrafik.nodes.pop(); node.resourceId = null; @@ -95,6 +97,8 @@ describe("NodeService Test", () => { netzgrafik.nodes.push(node); nodeService.setNodeData(netzgrafik.nodes); expect(nodes.length).toBe(netzgrafik.nodes.length); + expect(nodeService.getVisibleNodes().length).toBe(netzgrafik.nodes.length); + expect(nodeService.getSelectedNodes().length).toBe(0); nodes.forEach((n) => { expect(n.getResourceId() !== null).toBe(true); }); @@ -215,11 +219,13 @@ describe("NodeService Test", () => { NetzgrafikUnitTesting.getUnitTestNetzgrafik(), ); expect(nodes.length).toBe(5); + expect(nodeService.getVisibleNodes().length).toBe(5); expect(trainrunSections.length).toBe(8); nodeService.deleteAllNonVisibleNodes(); expect(nodes.length).toBe(5); + expect(nodeService.getVisibleNodes().length).toBe(5); expect(trainrunSections.length).toBe(8); }); @@ -228,12 +234,15 @@ describe("NodeService Test", () => { NetzgrafikUnitTesting.getUnitTestNetzgrafik(), ); expect(nodes.length).toBe(5); + expect(nodeService.getVisibleNodes().length).toBe(5); expect(trainrunSections.length).toBe(8); filterService.setFilterNodeLabels([3]); + expect(nodeService.getVisibleNodes().length).toBe(4); nodeService.deleteAllNonVisibleNodes(); expect(nodes.length).toBe(4); + expect(nodeService.getVisibleNodes().length).toBe(4); expect(trainrunSections.length).toBe(6); }); @@ -788,6 +797,7 @@ describe("NodeService Test", () => { } n.setPosition(n.getId() * 32, n.getId() * 32); }); + expect(nodeService.getSelectedNodes().length).toBe(3); nodeService.moveSelectedNodes(-63, 132, 32, false); @@ -803,6 +813,7 @@ describe("NodeService Test", () => { nodeService.unselectAllNodes(); expect(nodeService.getSelectedNode()).toBe(null); + expect(nodeService.getSelectedNodes().length).toBe(0); }); it("select single node as selected test", () => { @@ -824,6 +835,7 @@ describe("NodeService Test", () => { nodeService.setSingleNodeAsSelected(ids[2]); expect(nodeService.getSelectedNode().getId()).toBe(ids[2]); + expect(nodeService.getSelectedNodes().length).toBe(1); nodeService.getNodes().forEach((n: Node) => { if (n.getId() === ids[2]) { @@ -837,6 +849,7 @@ describe("NodeService Test", () => { expect(n.selected()).toBe(false); expect(nodeService.isNodeSelected(n.getId())).toBe(false); }); + expect(nodeService.getSelectedNodes().length).toBe(0); }); it("unselect all nodes test", () => { @@ -861,5 +874,6 @@ describe("NodeService Test", () => { expect(n.selected()).toBe(false); expect(nodeService.isNodeSelected(n.getId())).toBe(false); }); + expect(nodeService.getSelectedNodes().length).toBe(0); }); }); From 383c99d9e2081c1587bf36aa71dcb7ee6e73c7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Henriot?= <142150521+shenriotpro@users.noreply.github.com> Date: Thu, 10 Oct 2024 15:11:18 +0200 Subject: [PATCH 140/197] feat: Implement Origin/Destination matrix (#301) --- documentation/ORIGIN_DESTINATION_MATRIX.md | 7 +- src/app/services/data/trainrun.service.ts | 22 + .../editor-tools-view.component.html | 5 +- .../editor-tools-view.component.ts | 50 +- src/app/view/util/origin-destination-graph.ts | 263 ++++ .../netzgrafik.unit.testing.od.matrix.ts | 1159 +++++++++++++++++ .../origin.destination.csv.test.spec.ts | 233 ++++ 7 files changed, 1729 insertions(+), 10 deletions(-) create mode 100644 src/app/view/util/origin-destination-graph.ts create mode 100644 src/integration-testing/netzgrafik.unit.testing.od.matrix.ts create mode 100644 src/integration-testing/origin.destination.csv.test.spec.ts diff --git a/documentation/ORIGIN_DESTINATION_MATRIX.md b/documentation/ORIGIN_DESTINATION_MATRIX.md index fdd7a4f2..a4961d2e 100644 --- a/documentation/ORIGIN_DESTINATION_MATRIX.md +++ b/documentation/ORIGIN_DESTINATION_MATRIX.md @@ -2,7 +2,7 @@ The Origin Destination Matrix shows the optimized travel time (total cost) between each pair of nodes. -The optimized travel time includes a fixed penalty for each connection, but the Origin Destination Matrix also shows the corresponding effective travel time and number of connections. +The optimized travel time includes a fixed penalty (5 minutes) for each connection, but the Origin Destination Matrix also shows the corresponding effective travel time and number of connections. ### Filtering @@ -11,3 +11,8 @@ If some nodes are selected, then the Origin Destination Matrix will only show re The Origin Destination Matrix will only show results between visible nodes (but other nodes may be used to compute paths). The Origin Destination Matrix will only use visible trainruns to compute paths. + +### Caveats + +Split trainruns are not supported at the moment: https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/285. +As a simplification, we currently consider trains run at their frequency for a fixed schedule duration (10 hours). diff --git a/src/app/services/data/trainrun.service.ts b/src/app/services/data/trainrun.service.ts index e3e702cc..dd3463be 100644 --- a/src/app/services/data/trainrun.service.ts +++ b/src/app/services/data/trainrun.service.ts @@ -289,6 +289,10 @@ export class TrainrunService { return Object.assign({}, this.trainrunsStore).trainruns; } + getVisibleTrainruns(): Trainrun[] { + return this.getTrainruns().filter((t) => this.filterService.filterTrainrun(t)); + } + getAllTrainrunLabels(): string[] { let trainrunLabels = []; this.getTrainruns().forEach((t) => @@ -769,6 +773,24 @@ export class TrainrunService { return new NonStopTrainrunIterator(this.logService, node, trainrunSection); } + // For each trainrun, get iterators from the source (trainruns may be split). + public getRootIterators(): Map { + const trainrunSections = this.trainrunSectionService.getTrainrunSections(); + const iterators = new Map(); + trainrunSections.forEach((ts) => { + const node = ts.getSourceNode(); + if (node.isEndNode(ts)) { + const it = iterators.get(ts.getTrainrunId()); + if (it === undefined) { + iterators.set(ts.getTrainrunId(), [this.getIterator(node, ts)]); + } else { + it.push(this.getIterator(node, ts)); + } + } + }); + return iterators; + } + getBothEndNodesWithTrainrunId(trainrunId: number) { const trainrunSections: TrainrunSection[] = this.trainrunSectionService.getTrainrunSections(); diff --git a/src/app/view/editor-tools-view-component/editor-tools-view.component.html b/src/app/view/editor-tools-view-component/editor-tools-view.component.html index 735ab888..04347475 100644 --- a/src/app/view/editor-tools-view-component/editor-tools-view.component.html +++ b/src/app/view/editor-tools-view-component/editor-tools-view.component.html @@ -71,8 +71,7 @@

{{ 'app.view.editor-side-view.editor-tools-view-compone {{ 'app.view.editor-side-view.editor-tools-view-component.export-trainruns-as-csv-excel' | translate }} - - + {{ 'app.view.editor-side-view.editor-tools-view-component.export-origin-destination-as-csv' | translate }} {{ 'app.view.editor-side-view.editor-tools-view-component.base-data' | translate }} diff --git a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts index 973f8140..00795a35 100644 --- a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts +++ b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts @@ -21,6 +21,8 @@ import {LabelService} from "../../services/data/label.serivce"; import {NetzgrafikColoringService} from "../../services/data/netzgrafikColoring.service"; import {ViewportCullService} from "../../services/ui/viewport.cull.service"; import {LevelOfDetailService} from "../../services/ui/level.of.detail.service"; +import {_ViewRepeaterItemContext} from "@angular/cdk/collections"; +import {buildEdges, computeNeighbors, computeShortestPaths, topoSort} from "../util/origin-destination-graph"; @Component({ selector: "sbb-editor-tools-view-component", @@ -495,7 +497,16 @@ export class EditorToolsViewComponent { return this.buildCSVString(headers, rows); } + // Split trainruns are not supported at the moment: + // https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/285 private convertToOriginDestinationCSV(): string { + // The cost to add for each connection. + // TODO: this may belong to the grafix metadata. + const connectionPenalty = 5; + // Duration of the schedule to consider (in minutes). + // TODO: ideally this would be 24 hours, but performance is a concern. + const timeLimit = 10*60; + const headers: string[] = []; headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.origin:Origin`); headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.destination:Destination`); @@ -503,16 +514,43 @@ export class EditorToolsViewComponent { headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.connections:Connections`); headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.totalCost:Total cost`); + const nodes = this.nodeService.getNodes(); const selectedNodes = this.nodeService.getSelectedNodes(); - const nodes = selectedNodes.length > 0 ? selectedNodes : this.nodeService.getVisibleNodes(); + const odNodes = selectedNodes.length > 0 ? selectedNodes : this.nodeService.getVisibleNodes(); + const trainruns = this.trainrunService.getVisibleTrainruns(); + + const edges = buildEdges(nodes, odNodes, trainruns, connectionPenalty, this.trainrunService, timeLimit); + + const neighbors = computeNeighbors(edges); + const vertices = topoSort(neighbors); + // In theory we could parallelize the pathfindings, but the overhead might be too big. + const res = new Map(); + odNodes.forEach((origin) => { + computeShortestPaths(origin.getId(), neighbors, vertices).forEach((value, key) => { + res.set([origin.getId(), key].join(","), value); + }); + }); - // TODO: implement the actual shortest path algorithm. const rows = []; - nodes.forEach((origin) => { - nodes.forEach((destination) => { - const row = [origin.getFullName(), destination.getFullName(), "-1", "-1", "-1"]; + odNodes.sort((a, b) => a.getBetriebspunktName().localeCompare(b.getBetriebspunktName())); + odNodes.forEach((origin) => { + odNodes.forEach((destination) => { + if (origin.getId() === destination.getId()) { + return; + } + const costs = res.get([origin.getId(), destination.getId()].join(",")); + if (costs === undefined) { + // Keep empty if no path is found. + rows.push([origin.getBetriebspunktName(), destination.getBetriebspunktName(), "", "", ""]); + return; + } + const [totalCost, connections] = costs; + const row = [origin.getBetriebspunktName(), destination.getBetriebspunktName(), + (totalCost-connections*connectionPenalty).toString(), + connections.toString(), totalCost.toString()]; rows.push(row); - });}); + }); + }); return this.buildCSVString(headers, rows); } diff --git a/src/app/view/util/origin-destination-graph.ts b/src/app/view/util/origin-destination-graph.ts new file mode 100644 index 00000000..1f50f08d --- /dev/null +++ b/src/app/view/util/origin-destination-graph.ts @@ -0,0 +1,263 @@ +import {Trainrun} from "src/app/models/trainrun.model"; +import {TrainrunService} from "src/app/services/data/trainrun.service"; +import {TrainrunIterator} from "src/app/services/util/trainrun.iterator"; +import {Node} from "src/app/models/node.model"; + +// A vertex indicates a "state": e.g. arriving at a node at a certain time and from a given trainrun. +export class Vertex { + constructor( + public nodeId: number, + // Indicates if we depart or arrive at the node. + public isDeparture: boolean, + // Optional fields are undefined for "convenience" vertices. + // Absolute time (duration from the start of the schedule) in minutes. + public time?: number, + // Negative trainrun ids are used for reverse directions. + public trainrunId?: number + ){} +} + +export class Edge { + constructor( + public v1: Vertex, + public v2: Vertex, + // The weight represents the cost of the edge, it is similar to a duration in minutes + // but it may include a connection penalty cost. + public weight: number + ){} +} + +export const buildEdges = (nodes: Node[], odNodes: Node[], trainruns: Trainrun[], connectionPenalty: number, trainrunService: TrainrunService, + timeLimit: number +): Edge[] => { + let edges = buildSectionEdges(trainruns, trainrunService, timeLimit); + + // TODO: organize by trainrun and sort + const verticesDepartureByNode = new Map(); + const verticesArrivalByNode = new Map(); + edges.forEach((edge) => { + const src = edge.v1; + const tgt = edge.v2; + if (src.isDeparture !== true) { + console.log("src is not a departure: ", src); + } + if (tgt.isDeparture !== false) { + console.log("tgt is not an arrival: ", tgt); + } + const departures = verticesDepartureByNode.get(src.nodeId); + if (departures === undefined) { + verticesDepartureByNode.set(src.nodeId, [src]); + } else { + departures.push(src); + } + const arrivals = verticesArrivalByNode.get(tgt.nodeId); + if (arrivals === undefined) { + verticesArrivalByNode.set(tgt.nodeId, [tgt]); + } else { + arrivals.push(tgt); + } + }); + + // Note: pushing too many elements at once does not work well. + edges = [...edges, ...buildConvenienceEdges(odNodes, verticesDepartureByNode, verticesArrivalByNode)]; + edges = [...edges, ...buildConnectionEdges(nodes, verticesDepartureByNode, verticesArrivalByNode, connectionPenalty)]; + + return edges; +}; + +// Given edges, return the neighbors (with weights) for each vertex, if any (outgoing adjacency list). +export const computeNeighbors = (edges: Edge[]): Map => { + const neighbors = new Map(); + edges.forEach((edge) => { + const v1 = JSON.stringify(edge.v1); + const v1Neighbors = neighbors.get(v1); + if (v1Neighbors === undefined) { + neighbors.set(v1, [[edge.v2, edge.weight]]); + } else { + v1Neighbors.push([edge.v2, edge.weight]); + } + }); + return neighbors; +}; + +// Given a graph (adjacency list), return the vertices in topological order. +// Note: sorting vertices by time would be enough for our use case. +export const topoSort = (graph: Map): Vertex[] => { + const res = []; + const visited = new Set(); + for (const node of graph.keys()) { + if (!visited.has(node)) { + depthFirstSearch(graph, JSON.parse(node) as Vertex, visited, res); + } + } + return res.reverse(); +}; + +// Given a graph (adjacency list), and vertices in topological order, return the shortest paths (and connections) +// from a given node to other nodes. +export const computeShortestPaths = (from: number, neighbors: Map, vertices: Vertex[]): +Map => { + const res = new Map(); + const dist = new Map(); + let started = false; + vertices.forEach((vertex) => { + const key = JSON.stringify(vertex); + if (!started) { + if (from === vertex.nodeId && vertex.isDeparture === true && vertex.time === undefined) { + started = true; + dist.set(key, [0, 0]); + } else { + return; + } + } + if (vertex.isDeparture === false && vertex.time === undefined && dist.get(key) !== undefined + && vertex.nodeId !== from) { + res.set(vertex.nodeId, dist.get(key)); + } + const neighs = neighbors.get(key); + if (neighs === undefined || dist.get(key) === undefined) { + return; + } + neighs.forEach(([neighbor, weight]) => { + const alt = dist.get(key)[0] + weight; + const neighborKey = JSON.stringify(neighbor); + if (dist.get(neighborKey) === undefined || alt < dist.get(neighborKey)[0]) { + let connection = 0; + if (vertex.trainrunId !== undefined && neighbor.trainrunId !== undefined && vertex.trainrunId !== neighbor.trainrunId) { + connection = 1; + } + dist.set(neighborKey, [alt, dist.get(key)[1] + connection]); + } + }); + }); + return res; +}; + +const buildSectionEdges = (trainruns: Trainrun[], trainrunService: TrainrunService, timeLimit: number): Edge[] => { + const edges = []; + const its = trainrunService.getRootIterators(); + trainruns.forEach((trainrun) => { + const tsIterators = its.get(trainrun.getId()); + if (tsIterators === undefined) { + console.log("Ignoring trainrun (no root found): ", trainrun.getId()); + return; + } + tsIterators.forEach((tsIterator) => { + edges.push(...buildSectionEdgesFromIterator(tsIterator, false, timeLimit)); + const ts = tsIterator.current().trainrunSection; + const nextIterator = trainrunService.getIterator(ts.getTargetNode(), ts); + edges.push(...buildSectionEdgesFromIterator(nextIterator, true, timeLimit)); + }); + }); + return edges; +}; + +const buildSectionEdgesFromIterator = (tsIterator: TrainrunIterator, reverse: boolean, timeLimit: number): Edge[] => { + const edges = []; + let nonStopV1Time = -1; + let nonStopV1Node = -1; + while (tsIterator.hasNext()) { + tsIterator.next(); + const ts = tsIterator.current().trainrunSection; + const trainrunId = reverse ? -ts.getTrainrunId() : ts.getTrainrunId(); + const v1Time = reverse ? ts.getTargetDepartureDto().consecutiveTime : ts.getSourceDepartureDto().consecutiveTime; + const v1Node = reverse ? ts.getTargetNodeId() : ts.getSourceNodeId(); + if (reverse ? ts.getSourceNode().isNonStop(ts) : ts.getTargetNode().isNonStop(ts)) { + if (nonStopV1Time === -1) { + nonStopV1Time = v1Time; + nonStopV1Node = v1Node; + } + continue; + } + let v1 = new Vertex(v1Node, true, v1Time, trainrunId); + let nonStop = false; + if (nonStopV1Time !== -1) { + v1 = new Vertex(nonStopV1Node, true, nonStopV1Time, trainrunId); + nonStopV1Time = -1; + nonStop = true; + } + const v2Time = reverse ? ts.getSourceArrivalDto().consecutiveTime : ts.getTargetArrivalDto().consecutiveTime; + const v2Node = reverse ? ts.getSourceNodeId() : ts.getTargetNodeId(); + const v2 = new Vertex(v2Node, false, v2Time, trainrunId); + + for (let i = 0; i*ts.getTrainrun().getFrequency() < timeLimit; i++) { + const newV1 = new Vertex(v1.nodeId, v1.isDeparture, v1.time+i*ts.getTrainrun().getFrequency(), v1.trainrunId); + const newV2 = new Vertex(v2.nodeId, v2.isDeparture, v2.time+i*ts.getTrainrun().getFrequency(), v2.trainrunId); + const edge = new Edge(newV1, newV2, newV2.time - newV1.time); + edges.push(edge); + } + } + return edges; +}; + +const buildConvenienceEdges = (nodes: Node[], verticesDepartureByNode: Map, + verticesArrivalByNode: Map): Edge[] => { + const edges = []; + nodes.forEach((node) => { + const v1 = new Vertex(node.getId(), true); + const v2 = new Vertex(node.getId(), false); + const edge = new Edge(v1, v2, 0); + edges.push(edge); + const departures = verticesDepartureByNode.get(node.getId()); + if (departures !== undefined) { + const srcVertex = new Vertex(node.getId(), true); + departures.forEach((departure) => { + const edge = new Edge(srcVertex, departure, 0); + edges.push(edge); + }); + } + const arrivals = verticesArrivalByNode.get(node.getId()); + if (arrivals !== undefined) { + const tgtVertex = new Vertex(node.getId(), false); + arrivals.forEach((arrival) => { + const edge = new Edge(arrival, tgtVertex, 0); + edges.push(edge); + }); + } + }); + return edges; +}; + +const buildConnectionEdges = (nodes: Node[], verticesDepartureByNode: Map, + verticesArrivalByNode: Map, connectionPenalty: number): Edge[] => { + const edges = []; + nodes.forEach((node) => { + const departures = verticesDepartureByNode.get(node.getId()); + const arrivals = verticesArrivalByNode.get(node.getId()); + if (departures !== undefined && arrivals !== undefined) { + departures.forEach((departure) => { + arrivals.forEach((arrival) => { + if (departure.trainrunId === arrival.trainrunId) { + if (departure.time < arrival.time) { + return; + } + const edge = new Edge(arrival, departure, departure.time - arrival.time); + edges.push(edge); + return; + } + if (departure.time < arrival.time + node.getConnectionTime()) { + return; + } + const edge = new Edge(arrival, departure, departure.time - arrival.time + connectionPenalty); + edges.push(edge); + }); + }); + } + }); + return edges; +}; + +const depthFirstSearch = (graph: Map, root: Vertex, visited: Set, res: Vertex[]): void => { + const key = JSON.stringify(root); + visited.add(key); + const neighbors = graph.get(key); + if (neighbors !== undefined) { + neighbors.forEach(([neighbor, weight]) => { + if (!visited.has(JSON.stringify(neighbor))) { + depthFirstSearch(graph, neighbor, visited, res); + } + }); + } + // Note that the order is important for topological sorting. + res.push(root); +}; diff --git a/src/integration-testing/netzgrafik.unit.testing.od.matrix.ts b/src/integration-testing/netzgrafik.unit.testing.od.matrix.ts new file mode 100644 index 00000000..6ed8ca06 --- /dev/null +++ b/src/integration-testing/netzgrafik.unit.testing.od.matrix.ts @@ -0,0 +1,1159 @@ +import { + HaltezeitFachCategories, + LabelRef, + LinePatternRefs, + NetzgrafikDto, +} from "../app/data-structures/business.data.structures"; +import {TrainrunSectionText} from "../app/data-structures/technical.data.structures"; + +export class NetzgrafikUnitTestingOdMatrix { + static getUnitTestNetzgrafik(): NetzgrafikDto { + return { + "nodes": [ + { + "id": 11, + "betriebspunktName": "C", + "fullName": "C", + "positionX": 1536, + "positionY": 864, + "ports": [ + { + "id": 14, + "trainrunSectionId": 7, + "positionIndex": 0, + "positionAlignment": 2 + }, + { + "id": 20, + "trainrunSectionId": 10, + "positionIndex": 1, + "positionAlignment": 2 + }, + { + "id": 15, + "trainrunSectionId": 8, + "positionIndex": 2, + "positionAlignment": 2 + }, + { + "id": 21, + "trainrunSectionId": 11, + "positionIndex": 3, + "positionAlignment": 2 + } + ], + "transitions": [ + { + "id": 4, + "port1Id": 20, + "port2Id": 21, + "isNonStopTransit": true + } + ], + "connections": [], + "resourceId": 12, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": { + "haltezeit": 3, + "no_halt": false + }, + "HaltezeitA": { + "haltezeit": 2, + "no_halt": false + }, + "HaltezeitB": { + "haltezeit": 2, + "no_halt": false + }, + "HaltezeitC": { + "haltezeit": 1, + "no_halt": false + }, + "HaltezeitD": { + "haltezeit": 1, + "no_halt": false + }, + "HaltezeitUncategorized": { + "haltezeit": 0, + "no_halt": true + } + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [] + }, + { + "id": 12, + "betriebspunktName": "A", + "fullName": "A", + "positionX": 1120, + "positionY": 672, + "ports": [ + { + "id": 17, + "trainrunSectionId": 9, + "positionIndex": 0, + "positionAlignment": 1 + }, + { + "id": 12, + "trainrunSectionId": 6, + "positionIndex": 0, + "positionAlignment": 2 + }, + { + "id": 13, + "trainrunSectionId": 7, + "positionIndex": 0, + "positionAlignment": 3 + }, + { + "id": 19, + "trainrunSectionId": 10, + "positionIndex": 1, + "positionAlignment": 3 + } + ], + "transitions": [ + { + "id": 3, + "port1Id": 12, + "port2Id": 13, + "isNonStopTransit": false + } + ], + "connections": [], + "resourceId": 13, + "perronkanten": 5, + "connectionTime": 8, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": { + "haltezeit": 3, + "no_halt": false + }, + "HaltezeitA": { + "haltezeit": 2, + "no_halt": false + }, + "HaltezeitB": { + "haltezeit": 2, + "no_halt": false + }, + "HaltezeitC": { + "haltezeit": 1, + "no_halt": false + }, + "HaltezeitD": { + "haltezeit": 1, + "no_halt": false + }, + "HaltezeitUncategorized": { + "haltezeit": 0, + "no_halt": true + } + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [] + }, + { + "id": 13, + "betriebspunktName": "D", + "fullName": "D", + "positionX": 1088, + "positionY": 1088, + "ports": [ + { + "id": 18, + "trainrunSectionId": 9, + "positionIndex": 0, + "positionAlignment": 0 + }, + { + "id": 22, + "trainrunSectionId": 11, + "positionIndex": 0, + "positionAlignment": 3 + } + ], + "transitions": [], + "connections": [], + "resourceId": 14, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": { + "haltezeit": 3, + "no_halt": false + }, + "HaltezeitA": { + "haltezeit": 2, + "no_halt": false + }, + "HaltezeitB": { + "haltezeit": 2, + "no_halt": false + }, + "HaltezeitC": { + "haltezeit": 1, + "no_halt": false + }, + "HaltezeitD": { + "haltezeit": 1, + "no_halt": false + }, + "HaltezeitUncategorized": { + "haltezeit": 0, + "no_halt": true + } + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [] + }, + { + "id": 14, + "betriebspunktName": "B", + "fullName": "B", + "positionX": 800, + "positionY": 864, + "ports": [ + { + "id": 11, + "trainrunSectionId": 6, + "positionIndex": 0, + "positionAlignment": 3 + }, + { + "id": 16, + "trainrunSectionId": 8, + "positionIndex": 1, + "positionAlignment": 3 + } + ], + "transitions": [], + "connections": [], + "resourceId": 15, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": { + "haltezeit": 3, + "no_halt": false + }, + "HaltezeitA": { + "haltezeit": 2, + "no_halt": false + }, + "HaltezeitB": { + "haltezeit": 2, + "no_halt": false + }, + "HaltezeitC": { + "haltezeit": 1, + "no_halt": false + }, + "HaltezeitD": { + "haltezeit": 1, + "no_halt": false + }, + "HaltezeitUncategorized": { + "haltezeit": 0, + "no_halt": true + } + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [] + } + ], + "trainrunSections": [ + { + "id": 6, + "sourceNodeId": 14, + "sourcePortId": 11, + "targetNodeId": 12, + "targetPortId": 12, + "travelTime": { + "time": 2, + "consecutiveTime": 1, + "lock": true, + "warning": null, + "timeFormatter": null + }, + "sourceDeparture": { + "time": 0, + "consecutiveTime": 0, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "sourceArrival": { + "time": 0, + "consecutiveTime": 60, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetDeparture": { + "time": 58, + "consecutiveTime": 58, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetArrival": { + "time": 2, + "consecutiveTime": 2, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "numberOfStops": 0, + "trainrunId": 4, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + { + "x": 898, + "y": 880 + }, + { + "x": 962, + "y": 880 + }, + { + "x": 1054, + "y": 688 + }, + { + "x": 1118, + "y": 688 + } + ], + "textPositions": { + "0": { + "x": 916, + "y": 892 + }, + "1": { + "x": 944, + "y": 868 + }, + "2": { + "x": 1100, + "y": 676 + }, + "3": { + "x": 1072, + "y": 700 + }, + "4": { + "x": 1008, + "y": 772 + }, + "5": { + "x": 1008, + "y": 772 + }, + "6": { + "x": 1008, + "y": 796 + } + } + }, + "warnings": null + }, + { + "id": 7, + "sourceNodeId": 12, + "sourcePortId": 13, + "targetNodeId": 11, + "targetPortId": 14, + "travelTime": { + "time": 4, + "consecutiveTime": 1, + "lock": true, + "warning": null, + "timeFormatter": null + }, + "sourceDeparture": { + "time": 3, + "consecutiveTime": 3, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "sourceArrival": { + "time": 57, + "consecutiveTime": 57, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetDeparture": { + "time": 53, + "consecutiveTime": 53, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetArrival": { + "time": 7, + "consecutiveTime": 7, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "numberOfStops": 0, + "trainrunId": 4, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + { + "x": 1218, + "y": 688 + }, + { + "x": 1282, + "y": 688 + }, + { + "x": 1470, + "y": 880 + }, + { + "x": 1534, + "y": 880 + } + ], + "textPositions": { + "0": { + "x": 1236, + "y": 700 + }, + "1": { + "x": 1264, + "y": 676 + }, + "2": { + "x": 1516, + "y": 868 + }, + "3": { + "x": 1488, + "y": 892 + }, + "4": { + "x": 1376, + "y": 772 + }, + "5": { + "x": 1376, + "y": 772 + }, + "6": { + "x": 1376, + "y": 796 + } + } + }, + "warnings": null + }, + { + "id": 8, + "sourceNodeId": 11, + "sourcePortId": 15, + "targetNodeId": 14, + "targetPortId": 16, + "travelTime": { + "time": 6, + "consecutiveTime": 1, + "lock": true, + "warning": null, + "timeFormatter": null + }, + "sourceDeparture": { + "time": 0, + "consecutiveTime": 60, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "sourceArrival": { + "time": 0, + "consecutiveTime": 60, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetDeparture": { + "time": 54, + "consecutiveTime": 54, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetArrival": { + "time": 6, + "consecutiveTime": 66, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "numberOfStops": 0, + "trainrunId": 5, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + { + "x": 1534, + "y": 944 + }, + { + "x": 1470, + "y": 944 + }, + { + "x": 962, + "y": 912 + }, + { + "x": 898, + "y": 912 + } + ], + "textPositions": { + "0": { + "x": 1516, + "y": 932 + }, + "1": { + "x": 1488, + "y": 956 + }, + "2": { + "x": 916, + "y": 924 + }, + "3": { + "x": 944, + "y": 900 + }, + "4": { + "x": 1216, + "y": 916 + }, + "5": { + "x": 1216, + "y": 916 + }, + "6": { + "x": 1216, + "y": 940 + } + } + }, + "warnings": null + }, + { + "id": 9, + "sourceNodeId": 12, + "sourcePortId": 17, + "targetNodeId": 13, + "targetPortId": 18, + "travelTime": { + "time": 2, + "consecutiveTime": 1, + "lock": true, + "warning": null, + "timeFormatter": null + }, + "sourceDeparture": { + "time": 8, + "consecutiveTime": 8, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "sourceArrival": { + "time": 52, + "consecutiveTime": 52, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetDeparture": { + "time": 50, + "consecutiveTime": 50, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetArrival": { + "time": 10, + "consecutiveTime": 10, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "numberOfStops": 0, + "trainrunId": 6, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + { + "x": 1136, + "y": 766 + }, + { + "x": 1136, + "y": 830 + }, + { + "x": 1104, + "y": 1022 + }, + { + "x": 1104, + "y": 1086 + } + ], + "textPositions": { + "0": { + "x": 1124, + "y": 784 + }, + "1": { + "x": 1148, + "y": 812 + }, + "2": { + "x": 1116, + "y": 1068 + }, + "3": { + "x": 1092, + "y": 1040 + }, + "4": { + "x": 1108, + "y": 926 + }, + "5": { + "x": 1108, + "y": 926 + }, + "6": { + "x": 1132, + "y": 926 + } + } + }, + "warnings": null + }, + { + "id": 10, + "sourceNodeId": 12, + "sourcePortId": 19, + "targetNodeId": 11, + "targetPortId": 20, + "travelTime": { + "time": 5, + "consecutiveTime": 1, + "lock": true, + "warning": null, + "timeFormatter": null + }, + "sourceDeparture": { + "time": 0, + "consecutiveTime": 0, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "sourceArrival": { + "time": 0, + "consecutiveTime": 60, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetDeparture": { + "time": 55, + "consecutiveTime": 55, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetArrival": { + "time": 5, + "consecutiveTime": 5, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "numberOfStops": 0, + "trainrunId": 7, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + { + "x": 1218, + "y": 720 + }, + { + "x": 1282, + "y": 720 + }, + { + "x": 1470, + "y": 912 + }, + { + "x": 1534, + "y": 912 + } + ], + "textPositions": { + "0": { + "x": 1236, + "y": 732 + }, + "1": { + "x": 1264, + "y": 708 + }, + "2": { + "x": 1516, + "y": 900 + }, + "3": { + "x": 1488, + "y": 924 + }, + "4": { + "x": 1376, + "y": 804 + }, + "5": { + "x": 1376, + "y": 804 + }, + "6": { + "x": 1376, + "y": 828 + } + } + }, + "warnings": null + }, + { + "id": 11, + "sourceNodeId": 11, + "sourcePortId": 21, + "targetNodeId": 13, + "targetPortId": 22, + "travelTime": { + "time": 4, + "consecutiveTime": 1, + "lock": true, + "warning": null, + "timeFormatter": null + }, + "sourceDeparture": { + "time": 5, + "consecutiveTime": 5, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "sourceArrival": { + "time": 55, + "consecutiveTime": 55, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetDeparture": { + "time": 51, + "consecutiveTime": 51, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetArrival": { + "time": 9, + "consecutiveTime": 9, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "numberOfStops": 0, + "trainrunId": 7, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + { + "x": 1534, + "y": 976 + }, + { + "x": 1470, + "y": 976 + }, + { + "x": 1250, + "y": 1104 + }, + { + "x": 1186, + "y": 1104 + } + ], + "textPositions": { + "0": { + "x": 1516, + "y": 964 + }, + "1": { + "x": 1488, + "y": 988 + }, + "2": { + "x": 1204, + "y": 1116 + }, + "3": { + "x": 1232, + "y": 1092 + }, + "4": { + "x": 1360, + "y": 1028 + }, + "5": { + "x": 1360, + "y": 1028 + }, + "6": { + "x": 1360, + "y": 1052 + } + } + }, + "warnings": null + } + ], + "trainruns": [ + { + "id": 4, + "name": "1", + "categoryId": 1, + "frequencyId": 3, + "trainrunTimeCategoryId": 0, + "labelIds": [] + }, + { + "id": 5, + "name": "2", + "categoryId": 3, + "frequencyId": 2, + "trainrunTimeCategoryId": 0, + "labelIds": [] + }, + { + "id": 6, + "name": "4", + "categoryId": 6, + "frequencyId": 3, + "trainrunTimeCategoryId": 0, + "labelIds": [] + }, + { + "id": 7, + "name": "3", + "categoryId": 5, + "frequencyId": 0, + "trainrunTimeCategoryId": 0, + "labelIds": [] + } + ], + "resources": [ + { + "id": 1, + "capacity": 2 + }, + { + "id": 2, + "capacity": 2 + }, + { + "id": 3, + "capacity": 2 + }, + { + "id": 4, + "capacity": 2 + }, + { + "id": 5, + "capacity": 2 + }, + { + "id": 6, + "capacity": 2 + }, + { + "id": 7, + "capacity": 2 + }, + { + "id": 8, + "capacity": 2 + }, + { + "id": 9, + "capacity": 2 + }, + { + "id": 10, + "capacity": 2 + }, + { + "id": 11, + "capacity": 2 + }, + { + "id": 12, + "capacity": 2 + }, + { + "id": 13, + "capacity": 2 + }, + { + "id": 14, + "capacity": 2 + }, + { + "id": 15, + "capacity": 2 + } + ], + "metadata": { + "trainrunCategories": [ + { + "id": 0, + "order": 0, + "shortName": "EC", + "name": "International", + "colorRef": "EC", + "fachCategory": HaltezeitFachCategories.IPV, + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 2, + "nodeHeadwayNonStop": 2, + "sectionHeadway": 2 + }, + { + "id": 1, + "order": 1, + "shortName": "IC", + "name": "InterCity", + "colorRef": "IC", + "fachCategory": HaltezeitFachCategories.A, + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 2, + "nodeHeadwayNonStop": 2, + "sectionHeadway": 2 + }, + { + "id": 2, + "order": 2, + "shortName": "IR", + "name": "InterRegio", + "colorRef": "IR", + "fachCategory": HaltezeitFachCategories.B, + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 2, + "nodeHeadwayNonStop": 2, + "sectionHeadway": 2 + }, + { + "id": 3, + "order": 3, + "shortName": "RE", + "name": "RegioExpress", + "colorRef": "RE", + "fachCategory": HaltezeitFachCategories.C, + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 2, + "nodeHeadwayNonStop": 2, + "sectionHeadway": 2 + }, + { + "id": 4, + "order": 4, + "shortName": "S", + "name": "RegioUndSBahnverkehr", + "colorRef": "S", + "fachCategory": HaltezeitFachCategories.D, + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 2, + "nodeHeadwayNonStop": 2, + "sectionHeadway": 2 + }, + { + "id": 5, + "order": 5, + "shortName": "GEX", + "name": "GüterExpress", + "colorRef": "GEX", + "fachCategory": HaltezeitFachCategories.Uncategorized, + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 3, + "nodeHeadwayNonStop": 3, + "sectionHeadway": 3 + }, + { + "id": 6, + "order": 6, + "shortName": "G", + "name": "Güterverkehr", + "colorRef": "G", + "fachCategory": HaltezeitFachCategories.Uncategorized, + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 3, + "nodeHeadwayNonStop": 3, + "sectionHeadway": 3 + } + ], + "trainrunFrequencies": [ + { + "id": 0, + "order": 0, + "frequency": 15, + "offset": 0, + "shortName": "15", + "name": "verkehrt viertelstündlich", + "linePatternRef": LinePatternRefs.Freq15 + }, + { + "id": 1, + "order": 0, + "frequency": 20, + "offset": 0, + "shortName": "20", + "name": "verkehrt im 20 Minuten Takt", + "linePatternRef": LinePatternRefs.Freq20 + }, + { + "id": 2, + "order": 0, + "frequency": 30, + "offset": 0, + "shortName": "30", + "name": "verkehrt halbstündlich", + "linePatternRef": LinePatternRefs.Freq30 + }, + { + "id": 3, + "order": 0, + "frequency": 60, + "offset": 0, + "shortName": "60", + "name": "verkehrt stündlich", + "linePatternRef": LinePatternRefs.Freq60 + }, + { + "id": 4, + "order": 0, + "frequency": 120, + "offset": 0, + "shortName": "120", + "name": "verkehrt zweistündlich (gerade)", + "linePatternRef": LinePatternRefs.Freq120 + }, + { + "id": 5, + "order": 0, + "frequency": 120, + "offset": 60, + "shortName": "120+", + "name": "verkehrt zweistündlich (ungerade)", + "linePatternRef": LinePatternRefs.Freq120 + } + ], + "trainrunTimeCategories": [ + { + "id": 0, + "order": 0, + "shortName": "7/24", + "name": "verkehrt uneingeschränkt", + "dayTimeInterval": [], + "weekday": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "linePatternRef": LinePatternRefs.TimeCat7_24 + }, + { + "id": 1, + "order": 0, + "shortName": "HVZ", + "name": "verkehrt zur Hauptverkehrszeit", + "dayTimeInterval": [ + { + "from": 360, + "to": 420 + }, + { + "from": 960, + "to": 1140 + } + ], + "weekday": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "linePatternRef": LinePatternRefs.TimeCatHVZ + }, + { + "id": 2, + "order": 0, + "shortName": "zeitweise", + "name": "verkehrt zeitweise", + "dayTimeInterval": [], + "weekday": [], + "linePatternRef": LinePatternRefs.TimeZeitweise + } + ], + "netzgrafikColors": [] + }, + "freeFloatingTexts": [], + "labels": [], + "labelGroups": [], + "filterData": { + "filterSettings": [] + } + }; + } +} diff --git a/src/integration-testing/origin.destination.csv.test.spec.ts b/src/integration-testing/origin.destination.csv.test.spec.ts new file mode 100644 index 00000000..0e7cbb9d --- /dev/null +++ b/src/integration-testing/origin.destination.csv.test.spec.ts @@ -0,0 +1,233 @@ +import {LogPublishersService} from "src/app/logger/log.publishers.service"; +import {LogService} from "src/app/logger/log.service"; +import {DataService} from "src/app/services/data/data.service"; +import {LabelService} from "src/app/services/data/label.serivce"; +import {LabelGroupService} from "src/app/services/data/labelgroup.service"; +import {NetzgrafikColoringService} from "src/app/services/data/netzgrafikColoring.service"; +import {NodeService} from "src/app/services/data/node.service"; +import {NoteService} from "src/app/services/data/note.service"; +import {ResourceService} from "src/app/services/data/resource.service"; +import {StammdatenService} from "src/app/services/data/stammdaten.service"; +import {TrainrunService} from "src/app/services/data/trainrun.service"; +import {TrainrunSectionService} from "src/app/services/data/trainrunsection.service"; +import {FilterService} from "src/app/services/ui/filter.service"; +import {buildEdges, computeNeighbors, computeShortestPaths, Edge, topoSort, Vertex} from "src/app/view/util/origin-destination-graph"; +import {NetzgrafikUnitTestingOdMatrix} from "./netzgrafik.unit.testing.od.matrix"; + +describe("Origin Destination CSV Test", () => { + let dataService: DataService = null; + let resourceService: ResourceService = null; + let nodeService: NodeService = null; + let logService: LogService = null; + let logPublishersService: LogPublishersService = null; + let trainrunService: TrainrunService = null; + let labelService: LabelService = null; + let labelGroupService: LabelGroupService = null; + let filterService: FilterService = null; + let trainrunSectionService: TrainrunSectionService = null; + let stammdatenService: StammdatenService = null; + let noteService: NoteService = null; + let netzgrafikColoringService: NetzgrafikColoringService = null; + + beforeEach(() => { + resourceService = new ResourceService(); + logPublishersService = new LogPublishersService(); + logService = new LogService(logPublishersService); + labelGroupService = new LabelGroupService(logService); + labelService = new LabelService(logService, labelGroupService); + filterService = new FilterService(labelService, labelGroupService); + trainrunService = new TrainrunService( + logService, + labelService, + filterService, + ); + trainrunSectionService = new TrainrunSectionService( + logService, + trainrunService, + filterService, + ); + nodeService = new NodeService( + logService, + resourceService, + trainrunService, + trainrunSectionService, + labelService, + filterService, + ); + stammdatenService = new StammdatenService(); + noteService = new NoteService(logService, labelService, filterService); + netzgrafikColoringService = new NetzgrafikColoringService(logService); + dataService = new DataService( + resourceService, + nodeService, + trainrunSectionService, + trainrunService, + stammdatenService, + noteService, + labelService, + labelGroupService, + filterService, + netzgrafikColoringService, + ); + }); + + it("integration test", () => { + dataService.loadNetzgrafikDto( + NetzgrafikUnitTestingOdMatrix.getUnitTestNetzgrafik(), + ); + const nodes = nodeService.getNodes(); + const trainruns = trainrunService.getTrainruns(); + const connectionPenalty = 5; + const timeLimit = 60*10; + + const edges = buildEdges(nodes, nodes, trainruns, connectionPenalty, trainrunService, timeLimit); + + const neighbors = computeNeighbors(edges); + const vertices = topoSort(neighbors); + + const res = new Map(); + nodes.forEach((origin) => { + computeShortestPaths(origin.getId(), neighbors, vertices).forEach((value, key) => { + res.set([origin.getId(), key].join(","), value); + }); + }); + + // Note: there may be some other equivalent solutions, depending on connections. + // See https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/199 + expect(res).toEqual(new Map([ + ["11,13", [22, 1]], ["11,14", [6, 0]], ["11,12", [4, 0]], ["12,13", [2, 0]], ["12,14", [2, 0]], + ["12,11", [4, 0]], ["13,14", [29, 1]], ["13,11", [22, 1]], ["13,12", [2, 0]], ["14,13", [29, 1]], + ["14,11", [6, 0]], ["14,12", [2, 0]] + ])); + }); + + it("integration test with selected nodes", () => { + dataService.loadNetzgrafikDto( + NetzgrafikUnitTestingOdMatrix.getUnitTestNetzgrafik(), + ); + nodeService.selectNode(13); + nodeService.selectNode(14); + const nodes = nodeService.getNodes(); + const odNodes = nodeService.getSelectedNodes(); + const trainruns = trainrunService.getTrainruns(); + const connectionPenalty = 5; + const timeLimit = 60*10; + + const edges = buildEdges(nodes, odNodes, trainruns, connectionPenalty, trainrunService, timeLimit); + + const neighbors = computeNeighbors(edges); + const vertices = topoSort(neighbors); + + const res = new Map(); + nodes.forEach((origin) => { + computeShortestPaths(origin.getId(), neighbors, vertices).forEach((value, key) => { + res.set([origin.getId(), key].join(","), value); + }); + }); + + // Note: there may be some other equivalent solutions, depending on connections. + // See https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/199 + expect(res).toEqual(new Map([["13,14", [29, 1]], ["14,13", [29, 1]]])); + }); + + it("simple path unit test", () => { + const v1 = new Vertex(0, true); + const v2 = new Vertex(0, true, 0, 0); + const v3 = new Vertex(1, false, 15, 0); + const v4 = new Vertex(1, false); + const e1 = new Edge(v1, v2, 0); + const e2 = new Edge(v2, v3, 15); + const e3 = new Edge(v3, v4, 0); + const edges = [e1, e2, e3]; + + const neighbors = computeNeighbors(edges); + + // v4 has no outgoing edges. + expect(neighbors).toHaveSize(3); + expect(neighbors.get(JSON.stringify(v1))).toHaveSize(1); + expect(neighbors.get(JSON.stringify(v1))).toContain([v2, 0]); + expect(neighbors.get(JSON.stringify(v2))).toHaveSize(1); + expect(neighbors.get(JSON.stringify(v2))).toContain([v3, 15]); + expect(neighbors.get(JSON.stringify(v3))).toHaveSize(1); + expect(neighbors.get(JSON.stringify(v3))).toContain([v4, 0]); + + const topoVertices = topoSort(neighbors); + + expect(topoVertices).toHaveSize(4); + edges.forEach((edge) => { + const v1Index = topoVertices.findIndex((value, index, obj) => {return value === edge.v1;}); + const v2Index = topoVertices.findIndex((value, index, obj) => {return value === edge.v2;}); + expect(v1Index).toBeLessThan(v2Index); + }); + + const distances0 = computeShortestPaths(0, neighbors, topoVertices); + + expect(distances0).toHaveSize(1); + expect(distances0.get(1)).toEqual([15, 0]); + }); + + it("connection unit test", () => { + // trainrun 0 + const v1 = new Vertex(0, true); + const v2 = new Vertex(0, true, 0, 0); + const v3 = new Vertex(1, false, 15, 0); + const v4 = new Vertex(1, true, 16, 0); + const v5 = new Vertex(2, false, 30, 0); + const v6 = new Vertex(2, false); + const e1 = new Edge(v1, v2, 0); + const e2 = new Edge(v2, v3, 15); + const e3 = new Edge(v3, v4, 1); + const e4 = new Edge(v4, v5, 14); + const e5 = new Edge(v5, v6, 0); + // trainrun 1 + const v7 = new Vertex(3, true); + const v8 = new Vertex(3, true, 0, 1); + const v9 = new Vertex(1, false, 10, 1); + const e6 = new Edge(v7, v8, 0); + const e7 = new Edge(v8, v9, 10); + // connection + const e8 = new Edge(v9, v4, 6+5); + // convenience + const v10 = new Vertex(1, false); + const e9 = new Edge(v3, v10, 0); + const e10 = new Edge(v9, v10, 0); + const v11 = new Vertex(1, true); + const e11 = new Edge(v11, v4, 0); + const edges = [e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11]; + + const neighbors = computeNeighbors(edges); + expect(neighbors).toHaveSize(9); + expect(neighbors.get(JSON.stringify(v1))).toHaveSize(1); + expect(neighbors.get(JSON.stringify(v2))).toHaveSize(1); + expect(neighbors.get(JSON.stringify(v3))).toHaveSize(2); + expect(neighbors.get(JSON.stringify(v4))).toHaveSize(1); + expect(neighbors.get(JSON.stringify(v5))).toHaveSize(1); + expect(neighbors.get(JSON.stringify(v7))).toHaveSize(1); + expect(neighbors.get(JSON.stringify(v8))).toHaveSize(1); + expect(neighbors.get(JSON.stringify(v9))).toHaveSize(2); + expect(neighbors.get(JSON.stringify(v11))).toHaveSize(1); + + const topoVertices = topoSort(neighbors); + expect(topoVertices).toHaveSize(11); + edges.forEach((edge) => { + const v1Index = topoVertices.findIndex((value, index, obj) => {return value === edge.v1;}); + const v2Index = topoVertices.findIndex((value, index, obj) => {return value === edge.v2;}); + expect(v1Index).toBeLessThan(v2Index); + }); + + const distances0 = computeShortestPaths(0, neighbors, topoVertices); + expect(distances0).toHaveSize(2); + expect(distances0.get(1)).toEqual([15, 0]); + expect(distances0.get(2)).toEqual([30, 0]); + + const distances1 = computeShortestPaths(1, neighbors, topoVertices); + expect(distances1).toHaveSize(1); + expect(distances1.get(2)).toEqual([14, 0]); + + const distances3 = computeShortestPaths(3, neighbors, topoVertices); + expect(distances3).toHaveSize(2); + expect(distances3.get(1)).toEqual([10, 0]); + // connection + expect(distances3.get(2)).toEqual([30+5, 1]); + }); +}); From d67445abbc7ff57767229a46a6a61f0f05ba41ec Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 15:25:20 +0200 Subject: [PATCH 141/197] chore(main): release netzgrafik-frontend 2.8.0 (#311) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index edb30bfd..7a564723 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.7.17" + ".": "2.8.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index fe14a2d2..31488aa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.8.0](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.7.17...netzgrafik-frontend-v2.8.0) (2024-10-10) + + +### Features + +* Implement Origin/Destination matrix ([#301](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/301)) ([383c99d](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/383c99d9e2081c1587bf36aa71dcb7ee6e73c7d9)) + ## [2.7.17](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.7.16...netzgrafik-frontend-v2.7.17) (2024-10-03) diff --git a/package-lock.json b/package-lock.json index f097fc0a..0a2e355f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.7.17", + "version": "2.8.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.7.17", + "version": "2.8.0", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index 0aca15ee..0cde10b8 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.7.17", + "version": "2.8.0", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From ce3f90d73784fabb49f29ac3625b142ceaa4134f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Henriot?= <142150521+shenriotpro@users.noreply.github.com> Date: Thu, 17 Oct 2024 21:57:41 +0200 Subject: [PATCH 142/197] feat: migrate originDestination connectionPenalty to netzgrafikDto (#314) * feat: migrate originDestination connectionPenalty to netzgrafixDto * fixup! feat: migrate originDestination connectionPenalty to netzgrafixDto --- documentation/DATA_MODEL_JSON.md | 23 ++++++++++++++++++- .../business.data.structures.ts | 10 ++++++++ .../sample-netzgrafik/netzgrafik.default.ts | 5 ++++ src/app/utils/data-migration.ts | 5 ++++ .../editor-tools-view.component.ts | 6 ++--- ...ik.unit.test.reconnec.trainrunsectionst.ts | 5 ++++ .../netzgrafik.unit.testing.od.matrix.ts | 5 ++++ .../netzgrafik.unit.testing.transition.ts | 5 ++++ .../netzgrafik.unit.testing.ts | 5 ++++ 9 files changed, 65 insertions(+), 4 deletions(-) diff --git a/documentation/DATA_MODEL_JSON.md b/documentation/DATA_MODEL_JSON.md index 74464460..e85e5c5d 100644 --- a/documentation/DATA_MODEL_JSON.md +++ b/documentation/DATA_MODEL_JSON.md @@ -378,7 +378,8 @@ More details about TimeLock "netzgrafikColors": [], "trainrunCategories": [], "trainrunFrequencies": [], - "trainrunTimeCategories": [] + "trainrunTimeCategories": [], + "analyticsSettings": {} } ``` @@ -600,6 +601,26 @@ Define the dayTimeIntervalElement ``` - **from** : interval starts at time (include), in minute : numeric - **to** : interval ends at time (include), in minute : numeric + + +
+ +analyticsSettings: Contains settings for analytics features, such as originDestination matrix. + + + +```JSON +"analyticsSettings": { + "originDestinationSettings": { + "connectionPenalty": 5 + }, +} +``` + +- **connectionPenalty**: Cost to add for each connection, in minute : numeric + + +
--- diff --git a/src/app/data-structures/business.data.structures.ts b/src/app/data-structures/business.data.structures.ts index d84f4d9b..c7e72141 100644 --- a/src/app/data-structures/business.data.structures.ts +++ b/src/app/data-structures/business.data.structures.ts @@ -252,6 +252,15 @@ export interface Haltezeit { no_halt: boolean; // no halt per default } +export interface OriginDestinationSettingsDto { + // TODO: we may want a UI to display/edit this. + connectionPenalty: number; // the cost to add for each connection, in minutes +} + +export interface AnalyticsSettingsDto { + originDestinationSettings: OriginDestinationSettingsDto; +} + /** * Groups Meta data in exported JSON / internal data structure (global properties for a project) */ @@ -260,6 +269,7 @@ export interface MetadataDto { trainrunFrequencies: TrainrunFrequency[]; trainrunTimeCategories: TrainrunTimeCategory[]; netzgrafikColors: NetzgrafikColorDto[]; + analyticsSettings: AnalyticsSettingsDto; } /** diff --git a/src/app/sample-netzgrafik/netzgrafik.default.ts b/src/app/sample-netzgrafik/netzgrafik.default.ts index bc6707d2..9c883ab7 100644 --- a/src/app/sample-netzgrafik/netzgrafik.default.ts +++ b/src/app/sample-netzgrafik/netzgrafik.default.ts @@ -205,6 +205,11 @@ export class NetzgrafikDefault { trainruns: [], resources: [], metadata: { + analyticsSettings: { + originDestinationSettings: { + connectionPenalty: 5, + } + }, trainrunCategories: [ { id: 0, diff --git a/src/app/utils/data-migration.ts b/src/app/utils/data-migration.ts index ab46188e..87a21599 100644 --- a/src/app/utils/data-migration.ts +++ b/src/app/utils/data-migration.ts @@ -80,6 +80,11 @@ export class DataMigration { NetzgrafikDefault.getDefaultNetzgrafik().metadata.netzgrafikColors; } + if (netzgrafikDto.metadata.analyticsSettings === undefined) { + netzgrafikDto.metadata.analyticsSettings = + NetzgrafikDefault.getDefaultNetzgrafik().metadata.analyticsSettings; + } + if (netzgrafikDto.freeFloatingTexts === undefined) { netzgrafikDto.freeFloatingTexts = NetzgrafikDefault.getDefaultNetzgrafik().freeFloatingTexts; diff --git a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts index 00795a35..64f41965 100644 --- a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts +++ b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts @@ -500,9 +500,6 @@ export class EditorToolsViewComponent { // Split trainruns are not supported at the moment: // https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/285 private convertToOriginDestinationCSV(): string { - // The cost to add for each connection. - // TODO: this may belong to the grafix metadata. - const connectionPenalty = 5; // Duration of the schedule to consider (in minutes). // TODO: ideally this would be 24 hours, but performance is a concern. const timeLimit = 10*60; @@ -514,6 +511,9 @@ export class EditorToolsViewComponent { headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.connections:Connections`); headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.totalCost:Total cost`); + const metadata = this.dataService.getNetzgrafikDto().metadata; + // The cost to add for each connection. + const connectionPenalty = metadata.analyticsSettings.originDestinationSettings.connectionPenalty; const nodes = this.nodeService.getNodes(); const selectedNodes = this.nodeService.getSelectedNodes(); const odNodes = selectedNodes.length > 0 ? selectedNodes : this.nodeService.getVisibleNodes(); diff --git a/src/integration-testing/netzgrafik.unit.test.reconnec.trainrunsectionst.ts b/src/integration-testing/netzgrafik.unit.test.reconnec.trainrunsectionst.ts index 457b1bac..bda20da2 100644 --- a/src/integration-testing/netzgrafik.unit.test.reconnec.trainrunsectionst.ts +++ b/src/integration-testing/netzgrafik.unit.test.reconnec.trainrunsectionst.ts @@ -696,6 +696,11 @@ export class NetzgrafikUnitTestingReconnectTrainrunSection { }, ], metadata: { + analyticsSettings: { + originDestinationSettings: { + connectionPenalty: 5, + } + }, trainrunCategories: [ { id: 0, diff --git a/src/integration-testing/netzgrafik.unit.testing.od.matrix.ts b/src/integration-testing/netzgrafik.unit.testing.od.matrix.ts index 6ed8ca06..b8a3f98c 100644 --- a/src/integration-testing/netzgrafik.unit.testing.od.matrix.ts +++ b/src/integration-testing/netzgrafik.unit.testing.od.matrix.ts @@ -950,6 +950,11 @@ export class NetzgrafikUnitTestingOdMatrix { } ], "metadata": { + "analyticsSettings": { + "originDestinationSettings": { + "connectionPenalty": 5, + } + }, "trainrunCategories": [ { "id": 0, diff --git a/src/integration-testing/netzgrafik.unit.testing.transition.ts b/src/integration-testing/netzgrafik.unit.testing.transition.ts index 43b14e33..77bf831e 100644 --- a/src/integration-testing/netzgrafik.unit.testing.transition.ts +++ b/src/integration-testing/netzgrafik.unit.testing.transition.ts @@ -1126,6 +1126,11 @@ export class NetzgrafikUnitTestingTransition { }, ], metadata: { + analyticsSettings: { + originDestinationSettings: { + connectionPenalty: 5, + } + }, trainrunCategories: [ { id: 0, diff --git a/src/integration-testing/netzgrafik.unit.testing.ts b/src/integration-testing/netzgrafik.unit.testing.ts index c1f00685..bfef3c89 100644 --- a/src/integration-testing/netzgrafik.unit.testing.ts +++ b/src/integration-testing/netzgrafik.unit.testing.ts @@ -820,6 +820,11 @@ export class NetzgrafikUnitTesting { ], resources: [], metadata: { + analyticsSettings: { + originDestinationSettings: { + connectionPenalty: 5, + } + }, trainrunCategories: [ { id: 0, From 83895a153bcbc83cbbb692f48b8df196a56a9467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Henriot?= <142150521+shenriotpro@users.noreply.github.com> Date: Mon, 21 Oct 2024 20:40:09 +0200 Subject: [PATCH 143/197] feat: optimize originDestination graph (#316) --- documentation/ORIGIN_DESTINATION_MATRIX.md | 2 +- .../editor-tools-view.component.ts | 4 +- src/app/view/util/origin-destination-graph.ts | 155 +++++++++++------- .../origin.destination.csv.test.spec.ts | 4 + 4 files changed, 105 insertions(+), 60 deletions(-) diff --git a/documentation/ORIGIN_DESTINATION_MATRIX.md b/documentation/ORIGIN_DESTINATION_MATRIX.md index a4961d2e..4c78697d 100644 --- a/documentation/ORIGIN_DESTINATION_MATRIX.md +++ b/documentation/ORIGIN_DESTINATION_MATRIX.md @@ -15,4 +15,4 @@ The Origin Destination Matrix will only use visible trainruns to compute paths. ### Caveats Split trainruns are not supported at the moment: https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/285. -As a simplification, we currently consider trains run at their frequency for a fixed schedule duration (10 hours). +As a simplification, we currently consider trains run at their frequency for a fixed schedule duration (16 hours). diff --git a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts index 64f41965..53b6d352 100644 --- a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts +++ b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts @@ -502,7 +502,9 @@ export class EditorToolsViewComponent { private convertToOriginDestinationCSV(): string { // Duration of the schedule to consider (in minutes). // TODO: ideally this would be 24 hours, but performance is a concern. - const timeLimit = 10*60; + // One idea to optimize would be to consider the minimum time window before the schedule repeats (LCM). + // Draft here: https://colab.research.google.com/drive/1Z1r2uU2pgffWxCbG_wt2zoLStZKzWleE#scrollTo=F6vOevK6znee + const timeLimit = 16*60; const headers: string[] = []; headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.origin:Origin`); diff --git a/src/app/view/util/origin-destination-graph.ts b/src/app/view/util/origin-destination-graph.ts index 1f50f08d..1420ba34 100644 --- a/src/app/view/util/origin-destination-graph.ts +++ b/src/app/view/util/origin-destination-graph.ts @@ -27,14 +27,13 @@ export class Edge { ){} } -export const buildEdges = (nodes: Node[], odNodes: Node[], trainruns: Trainrun[], connectionPenalty: number, trainrunService: TrainrunService, - timeLimit: number +export const buildEdges = (nodes: Node[], odNodes: Node[], trainruns: Trainrun[], connectionPenalty: number, + trainrunService: TrainrunService, timeLimit: number ): Edge[] => { let edges = buildSectionEdges(trainruns, trainrunService, timeLimit); - // TODO: organize by trainrun and sort - const verticesDepartureByNode = new Map(); - const verticesArrivalByNode = new Map(); + const verticesDepartureByTrainrunByNode = new Map>(); + const verticesArrivalByTrainrunByNode = new Map>(); edges.forEach((edge) => { const src = edge.v1; const tgt = edge.v2; @@ -44,23 +43,47 @@ export const buildEdges = (nodes: Node[], odNodes: Node[], trainruns: Trainrun[] if (tgt.isDeparture !== false) { console.log("tgt is not an arrival: ", tgt); } - const departures = verticesDepartureByNode.get(src.nodeId); - if (departures === undefined) { - verticesDepartureByNode.set(src.nodeId, [src]); + const departuresByTrainrun = verticesDepartureByTrainrunByNode.get(src.nodeId); + if (departuresByTrainrun === undefined) { + verticesDepartureByTrainrunByNode.set(src.nodeId, new Map([[src.trainrunId, [src]]])); } else { - departures.push(src); + const departures = departuresByTrainrun.get(src.trainrunId); + if (departures === undefined) { + departuresByTrainrun.set(src.trainrunId, [src]); + } else { + departures.push(src); + } } - const arrivals = verticesArrivalByNode.get(tgt.nodeId); - if (arrivals === undefined) { - verticesArrivalByNode.set(tgt.nodeId, [tgt]); + const arrivalsByTrainrun = verticesArrivalByTrainrunByNode.get(tgt.nodeId); + if (arrivalsByTrainrun === undefined) { + verticesArrivalByTrainrunByNode.set(tgt.nodeId, new Map([[tgt.trainrunId, [tgt]]])); } else { - arrivals.push(tgt); + const arrivals = arrivalsByTrainrun.get(tgt.trainrunId); + if (arrivals === undefined) { + arrivalsByTrainrun.set(tgt.trainrunId, [tgt]); + } else { + arrivals.push(tgt); + } } }); + + // Sorting is useful to find relevant connections later. + verticesDepartureByTrainrunByNode.forEach((verticesDepartureByTrainrun) => { + verticesDepartureByTrainrun.forEach((departures, trainrunId) => { + departures.sort((a, b) => a.time - b.time); + }); + }); + verticesArrivalByTrainrunByNode.forEach((verticesArrivalByTrainrun) => { + verticesArrivalByTrainrun.forEach((arrivals, trainrunId) => { + arrivals.sort((a, b) => a.time - b.time); + }); + }); // Note: pushing too many elements at once does not work well. - edges = [...edges, ...buildConvenienceEdges(odNodes, verticesDepartureByNode, verticesArrivalByNode)]; - edges = [...edges, ...buildConnectionEdges(nodes, verticesDepartureByNode, verticesArrivalByNode, connectionPenalty)]; + edges = [...edges, ...buildConvenienceEdges(odNodes, verticesDepartureByTrainrunByNode, verticesArrivalByTrainrunByNode)]; + edges = [...edges, + ...buildConnectionEdges(nodes, verticesDepartureByTrainrunByNode, verticesArrivalByTrainrunByNode, connectionPenalty) + ]; return edges; }; @@ -102,6 +125,7 @@ Map => { let started = false; vertices.forEach((vertex) => { const key = JSON.stringify(vertex); + // First, look for our start node. if (!started) { if (from === vertex.nodeId && vertex.isDeparture === true && vertex.time === undefined) { started = true; @@ -110,6 +134,7 @@ Map => { return; } } + // We found an end node. if (vertex.isDeparture === false && vertex.time === undefined && dist.get(key) !== undefined && vertex.nodeId !== from) { res.set(vertex.nodeId, dist.get(key)); @@ -118,12 +143,15 @@ Map => { if (neighs === undefined || dist.get(key) === undefined) { return; } + // The shortest path from the start node to this vertex is a shortest path from the start node to a neighbor + // plus the weight of the edge connecting the neighbor to this vertex. neighs.forEach(([neighbor, weight]) => { const alt = dist.get(key)[0] + weight; const neighborKey = JSON.stringify(neighbor); if (dist.get(neighborKey) === undefined || alt < dist.get(neighborKey)[0]) { let connection = 0; - if (vertex.trainrunId !== undefined && neighbor.trainrunId !== undefined && vertex.trainrunId !== neighbor.trainrunId) { + if (vertex.trainrunId !== undefined && neighbor.trainrunId !== undefined + && vertex.trainrunId !== neighbor.trainrunId) { connection = 1; } dist.set(neighborKey, [alt, dist.get(key)[1] + connection]); @@ -144,6 +172,7 @@ const buildSectionEdges = (trainruns: Trainrun[], trainrunService: TrainrunServi } tsIterators.forEach((tsIterator) => { edges.push(...buildSectionEdgesFromIterator(tsIterator, false, timeLimit)); + // Don't forget the reverse direction. const ts = tsIterator.current().trainrunSection; const nextIterator = trainrunService.getIterator(ts.getTargetNode(), ts); edges.push(...buildSectionEdgesFromIterator(nextIterator, true, timeLimit)); @@ -162,6 +191,7 @@ const buildSectionEdgesFromIterator = (tsIterator: TrainrunIterator, reverse: bo const trainrunId = reverse ? -ts.getTrainrunId() : ts.getTrainrunId(); const v1Time = reverse ? ts.getTargetDepartureDto().consecutiveTime : ts.getSourceDepartureDto().consecutiveTime; const v1Node = reverse ? ts.getTargetNodeId() : ts.getSourceNodeId(); + // If we don't stop here, we need to remember where we started. if (reverse ? ts.getSourceNode().isNonStop(ts) : ts.getTargetNode().isNonStop(ts)) { if (nonStopV1Time === -1) { nonStopV1Time = v1Time; @@ -190,58 +220,67 @@ const buildSectionEdgesFromIterator = (tsIterator: TrainrunIterator, reverse: bo return edges; }; -const buildConvenienceEdges = (nodes: Node[], verticesDepartureByNode: Map, - verticesArrivalByNode: Map): Edge[] => { +const buildConvenienceEdges = (nodes: Node[], verticesDepartureByTrainrunByNode: Map>, + verticesArrivalByTrainrunByNode: Map>): Edge[] => { const edges = []; nodes.forEach((node) => { - const v1 = new Vertex(node.getId(), true); - const v2 = new Vertex(node.getId(), false); - const edge = new Edge(v1, v2, 0); - edges.push(edge); - const departures = verticesDepartureByNode.get(node.getId()); - if (departures !== undefined) { - const srcVertex = new Vertex(node.getId(), true); - departures.forEach((departure) => { - const edge = new Edge(srcVertex, departure, 0); - edges.push(edge); - }); - } - const arrivals = verticesArrivalByNode.get(node.getId()); - if (arrivals !== undefined) { - const tgtVertex = new Vertex(node.getId(), false); - arrivals.forEach((arrival) => { - const edge = new Edge(arrival, tgtVertex, 0); - edges.push(edge); - }); + const nodeId = node.getId(); + // We add a single start and end vertex for each node, so we can compute shortest paths more easily. + const srcVertex = new Vertex(nodeId, true); + const tgtVertex = new Vertex(nodeId, false); + // Going from one node to itself is free. + const edge = new Edge(srcVertex, tgtVertex, 0); + edges.push(edge); + const departuresByTrainrun = verticesDepartureByTrainrunByNode.get(nodeId); + if (departuresByTrainrun !== undefined) { + departuresByTrainrun.forEach((departures, trainrunId) => { + departures.forEach((departure) => { + const edge = new Edge(srcVertex, departure, 0); + edges.push(edge); + }); + }); } + const arrivalsByTrainrun = verticesArrivalByTrainrunByNode.get(nodeId); + if (arrivalsByTrainrun !== undefined) { + arrivalsByTrainrun.forEach((arrivals, trainrunId) => { + arrivals.forEach((arrival) => { + const edge = new Edge(arrival, tgtVertex, 0); + edges.push(edge); + }); + }); + } }); return edges; }; -const buildConnectionEdges = (nodes: Node[], verticesDepartureByNode: Map, - verticesArrivalByNode: Map, connectionPenalty: number): Edge[] => { +const buildConnectionEdges = (nodes: Node[], verticesDepartureByTrainrunByNode: Map>, + verticesArrivalByTrainrunByNode: Map>, connectionPenalty: number): Edge[] => { const edges = []; nodes.forEach((node) => { - const departures = verticesDepartureByNode.get(node.getId()); - const arrivals = verticesArrivalByNode.get(node.getId()); - if (departures !== undefined && arrivals !== undefined) { - departures.forEach((departure) => { - arrivals.forEach((arrival) => { - if (departure.trainrunId === arrival.trainrunId) { - if (departure.time < arrival.time) { - return; - } - const edge = new Edge(arrival, departure, departure.time - arrival.time); - edges.push(edge); - return; - } - if (departure.time < arrival.time + node.getConnectionTime()) { - return; - } - const edge = new Edge(arrival, departure, departure.time - arrival.time + connectionPenalty); - edges.push(edge); - }); + const departuresByTrainrun = verticesDepartureByTrainrunByNode.get(node.getId()); + const arrivalsByTrainrun = verticesArrivalByTrainrunByNode.get(node.getId()); + if (departuresByTrainrun !== undefined && arrivalsByTrainrun !== undefined) { + arrivalsByTrainrun.forEach((arrivals, arrivalTrainrunId) => { + arrivals.forEach((arrival) => { + departuresByTrainrun.forEach((departures, departureTrainrunId) => { + let minDepartureTime = arrival.time; + if (arrivalTrainrunId !== departureTrainrunId) { + minDepartureTime += node.getConnectionTime(); + } + // For each arrival and for each trainrun available, we only want to consider the first departure. + // This could be a binary search but it does not seem to be worth it. + const departure = departures.find((departure) => {return departure.time >= minDepartureTime;}); + if (departure !== undefined) { + let cost = departure.time - arrival.time; + if (arrivalTrainrunId !== departureTrainrunId) { + cost += connectionPenalty; + } + const edge = new Edge(arrival, departure, cost); + edges.push(edge); + } + }); }); + }); } }); return edges; diff --git a/src/integration-testing/origin.destination.csv.test.spec.ts b/src/integration-testing/origin.destination.csv.test.spec.ts index 0e7cbb9d..d859c4f7 100644 --- a/src/integration-testing/origin.destination.csv.test.spec.ts +++ b/src/integration-testing/origin.destination.csv.test.spec.ts @@ -80,6 +80,7 @@ describe("Origin Destination CSV Test", () => { const connectionPenalty = 5; const timeLimit = 60*10; + const start = new Date().getTime(); const edges = buildEdges(nodes, nodes, trainruns, connectionPenalty, trainrunService, timeLimit); const neighbors = computeNeighbors(edges); @@ -91,6 +92,7 @@ describe("Origin Destination CSV Test", () => { res.set([origin.getId(), key].join(","), value); }); }); + const end = new Date().getTime(); // Note: there may be some other equivalent solutions, depending on connections. // See https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/199 @@ -99,6 +101,8 @@ describe("Origin Destination CSV Test", () => { ["12,11", [4, 0]], ["13,14", [29, 1]], ["13,11", [22, 1]], ["13,12", [2, 0]], ["14,13", [29, 1]], ["14,11", [6, 0]], ["14,12", [2, 0]] ])); + // This should be reasonably fast, likely less than 10ms. + expect(end - start).toBeLessThan(100); }); it("integration test with selected nodes", () => { From b3f7e94f02ee9d59d960760b5c15d232fd748b52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Henriot?= <142150521+shenriotpro@users.noreply.github.com> Date: Mon, 21 Oct 2024 22:09:20 +0200 Subject: [PATCH 144/197] test: improve TrainrunService coverage (#317) --- .../services/data/trainrun.service.spec.ts | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/app/services/data/trainrun.service.spec.ts b/src/app/services/data/trainrun.service.spec.ts index d531043d..e4541b6b 100644 --- a/src/app/services/data/trainrun.service.spec.ts +++ b/src/app/services/data/trainrun.service.spec.ts @@ -359,4 +359,42 @@ describe("TrainrunService", () => { expect(trainrunSections4.length).toBe(2); }); + it("getRootIterators", () => { + dataService.loadNetzgrafikDto( + NetzgrafikUnitTesting.getUnitTestNetzgrafik(), + ); + + const iterators = trainrunService.getRootIterators(); + + const iterators0 = iterators.get(0); + // trainrun 0: 0 -> 1 -> 2 + // 1 root: 0 + expect(iterators0.length).toBe(1); + expect(iterators0[0].current().trainrunSection.getSourceNodeId()).toBe(0); + + const iterators1 = iterators.get(1); + // trainrun 1: 1 -> 2 + // 1 root: 1 + expect(iterators1.length).toBe(1); + expect(iterators1[0].current().trainrunSection.getSourceNodeId()).toBe(1); + + const iterators2 = iterators.get(2); + // trainrun 2: 0 -> 1 -> 2 -> 3 + // 1 root: 0 + expect(iterators2.length).toBe(1); + expect(iterators2[0].current().trainrunSection.getSourceNodeId()).toBe(0); + + const iterators3 = iterators.get(3); + // trainrun 3: 4 -> 2 + // 1 root: 4 + expect(iterators3.length).toBe(1); + expect(iterators3[0].current().trainrunSection.getSourceNodeId()).toBe(4); + + const iterators4 = iterators.get(4); + // trainrun 4: 4 -> 2 + // 1 root: 4 + expect(iterators4.length).toBe(1); + expect(iterators4[0].current().trainrunSection.getSourceNodeId()).toBe(4); + }); + }); From 1d89ece357ce5844289ebe03c46504cf932e5235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Henriot?= <142150521+shenriotpro@users.noreply.github.com> Date: Tue, 22 Oct 2024 13:36:25 +0200 Subject: [PATCH 145/197] style: format O/D Matrix source using prettier (#318) --- src/app/view/util/origin-destination-graph.ts | 594 +++-- .../netzgrafik.unit.testing.od.matrix.ts | 2178 ++++++++--------- .../origin.destination.csv.test.spec.ts | 97 +- 3 files changed, 1501 insertions(+), 1368 deletions(-) diff --git a/src/app/view/util/origin-destination-graph.ts b/src/app/view/util/origin-destination-graph.ts index 1420ba34..29f26f52 100644 --- a/src/app/view/util/origin-destination-graph.ts +++ b/src/app/view/util/origin-destination-graph.ts @@ -5,298 +5,400 @@ import {Node} from "src/app/models/node.model"; // A vertex indicates a "state": e.g. arriving at a node at a certain time and from a given trainrun. export class Vertex { - constructor( - public nodeId: number, - // Indicates if we depart or arrive at the node. - public isDeparture: boolean, - // Optional fields are undefined for "convenience" vertices. - // Absolute time (duration from the start of the schedule) in minutes. - public time?: number, - // Negative trainrun ids are used for reverse directions. - public trainrunId?: number - ){} + constructor( + public nodeId: number, + // Indicates if we depart or arrive at the node. + public isDeparture: boolean, + // Optional fields are undefined for "convenience" vertices. + // Absolute time (duration from the start of the schedule) in minutes. + public time?: number, + // Negative trainrun ids are used for reverse directions. + public trainrunId?: number, + ) {} } export class Edge { - constructor( - public v1: Vertex, - public v2: Vertex, - // The weight represents the cost of the edge, it is similar to a duration in minutes - // but it may include a connection penalty cost. - public weight: number - ){} + constructor( + public v1: Vertex, + public v2: Vertex, + // The weight represents the cost of the edge, it is similar to a duration in minutes + // but it may include a connection penalty cost. + public weight: number, + ) {} } -export const buildEdges = (nodes: Node[], odNodes: Node[], trainruns: Trainrun[], connectionPenalty: number, - trainrunService: TrainrunService, timeLimit: number +export const buildEdges = ( + nodes: Node[], + odNodes: Node[], + trainruns: Trainrun[], + connectionPenalty: number, + trainrunService: TrainrunService, + timeLimit: number, ): Edge[] => { - let edges = buildSectionEdges(trainruns, trainrunService, timeLimit); + let edges = buildSectionEdges(trainruns, trainrunService, timeLimit); - const verticesDepartureByTrainrunByNode = new Map>(); - const verticesArrivalByTrainrunByNode = new Map>(); - edges.forEach((edge) => { - const src = edge.v1; - const tgt = edge.v2; - if (src.isDeparture !== true) { - console.log("src is not a departure: ", src); - } - if (tgt.isDeparture !== false) { - console.log("tgt is not an arrival: ", tgt); - } - const departuresByTrainrun = verticesDepartureByTrainrunByNode.get(src.nodeId); - if (departuresByTrainrun === undefined) { - verticesDepartureByTrainrunByNode.set(src.nodeId, new Map([[src.trainrunId, [src]]])); + const verticesDepartureByTrainrunByNode = new Map< + number, + Map + >(); + const verticesArrivalByTrainrunByNode = new Map< + number, + Map + >(); + edges.forEach((edge) => { + const src = edge.v1; + const tgt = edge.v2; + if (src.isDeparture !== true) { + console.log("src is not a departure: ", src); + } + if (tgt.isDeparture !== false) { + console.log("tgt is not an arrival: ", tgt); + } + const departuresByTrainrun = verticesDepartureByTrainrunByNode.get( + src.nodeId, + ); + if (departuresByTrainrun === undefined) { + verticesDepartureByTrainrunByNode.set( + src.nodeId, + new Map([[src.trainrunId, [src]]]), + ); + } else { + const departures = departuresByTrainrun.get(src.trainrunId); + if (departures === undefined) { + departuresByTrainrun.set(src.trainrunId, [src]); } else { - const departures = departuresByTrainrun.get(src.trainrunId); - if (departures === undefined) { - departuresByTrainrun.set(src.trainrunId, [src]); - } else { - departures.push(src); - } + departures.push(src); } - const arrivalsByTrainrun = verticesArrivalByTrainrunByNode.get(tgt.nodeId); - if (arrivalsByTrainrun === undefined) { - verticesArrivalByTrainrunByNode.set(tgt.nodeId, new Map([[tgt.trainrunId, [tgt]]])); + } + const arrivalsByTrainrun = verticesArrivalByTrainrunByNode.get(tgt.nodeId); + if (arrivalsByTrainrun === undefined) { + verticesArrivalByTrainrunByNode.set( + tgt.nodeId, + new Map([[tgt.trainrunId, [tgt]]]), + ); + } else { + const arrivals = arrivalsByTrainrun.get(tgt.trainrunId); + if (arrivals === undefined) { + arrivalsByTrainrun.set(tgt.trainrunId, [tgt]); } else { - const arrivals = arrivalsByTrainrun.get(tgt.trainrunId); - if (arrivals === undefined) { - arrivalsByTrainrun.set(tgt.trainrunId, [tgt]); - } else { - arrivals.push(tgt); - } + arrivals.push(tgt); } - }); + } + }); - // Sorting is useful to find relevant connections later. - verticesDepartureByTrainrunByNode.forEach((verticesDepartureByTrainrun) => { - verticesDepartureByTrainrun.forEach((departures, trainrunId) => { - departures.sort((a, b) => a.time - b.time); - }); + // Sorting is useful to find relevant connections later. + verticesDepartureByTrainrunByNode.forEach((verticesDepartureByTrainrun) => { + verticesDepartureByTrainrun.forEach((departures, trainrunId) => { + departures.sort((a, b) => a.time - b.time); }); - verticesArrivalByTrainrunByNode.forEach((verticesArrivalByTrainrun) => { - verticesArrivalByTrainrun.forEach((arrivals, trainrunId) => { - arrivals.sort((a, b) => a.time - b.time); - }); + }); + verticesArrivalByTrainrunByNode.forEach((verticesArrivalByTrainrun) => { + verticesArrivalByTrainrun.forEach((arrivals, trainrunId) => { + arrivals.sort((a, b) => a.time - b.time); }); - - // Note: pushing too many elements at once does not work well. - edges = [...edges, ...buildConvenienceEdges(odNodes, verticesDepartureByTrainrunByNode, verticesArrivalByTrainrunByNode)]; - edges = [...edges, - ...buildConnectionEdges(nodes, verticesDepartureByTrainrunByNode, verticesArrivalByTrainrunByNode, connectionPenalty) - ]; + }); - return edges; + // Note: pushing too many elements at once does not work well. + edges = [ + ...edges, + ...buildConvenienceEdges( + odNodes, + verticesDepartureByTrainrunByNode, + verticesArrivalByTrainrunByNode, + ), + ]; + edges = [ + ...edges, + ...buildConnectionEdges( + nodes, + verticesDepartureByTrainrunByNode, + verticesArrivalByTrainrunByNode, + connectionPenalty, + ), + ]; + + return edges; }; // Given edges, return the neighbors (with weights) for each vertex, if any (outgoing adjacency list). -export const computeNeighbors = (edges: Edge[]): Map => { - const neighbors = new Map(); - edges.forEach((edge) => { - const v1 = JSON.stringify(edge.v1); - const v1Neighbors = neighbors.get(v1); - if (v1Neighbors === undefined) { - neighbors.set(v1, [[edge.v2, edge.weight]]); - } else { - v1Neighbors.push([edge.v2, edge.weight]); - } - }); - return neighbors; +export const computeNeighbors = ( + edges: Edge[], +): Map => { + const neighbors = new Map(); + edges.forEach((edge) => { + const v1 = JSON.stringify(edge.v1); + const v1Neighbors = neighbors.get(v1); + if (v1Neighbors === undefined) { + neighbors.set(v1, [[edge.v2, edge.weight]]); + } else { + v1Neighbors.push([edge.v2, edge.weight]); + } + }); + return neighbors; }; // Given a graph (adjacency list), return the vertices in topological order. // Note: sorting vertices by time would be enough for our use case. export const topoSort = (graph: Map): Vertex[] => { - const res = []; - const visited = new Set(); - for (const node of graph.keys()) { - if (!visited.has(node)) { - depthFirstSearch(graph, JSON.parse(node) as Vertex, visited, res); - } + const res = []; + const visited = new Set(); + for (const node of graph.keys()) { + if (!visited.has(node)) { + depthFirstSearch(graph, JSON.parse(node) as Vertex, visited, res); } - return res.reverse(); + } + return res.reverse(); }; // Given a graph (adjacency list), and vertices in topological order, return the shortest paths (and connections) // from a given node to other nodes. -export const computeShortestPaths = (from: number, neighbors: Map, vertices: Vertex[]): -Map => { - const res = new Map(); - const dist = new Map(); - let started = false; - vertices.forEach((vertex) => { - const key = JSON.stringify(vertex); - // First, look for our start node. - if (!started) { - if (from === vertex.nodeId && vertex.isDeparture === true && vertex.time === undefined) { - started = true; - dist.set(key, [0, 0]); - } else { - return; - } - } - // We found an end node. - if (vertex.isDeparture === false && vertex.time === undefined && dist.get(key) !== undefined - && vertex.nodeId !== from) { - res.set(vertex.nodeId, dist.get(key)); - } - const neighs = neighbors.get(key); - if (neighs === undefined || dist.get(key) === undefined) { - return; +export const computeShortestPaths = ( + from: number, + neighbors: Map, + vertices: Vertex[], +): Map => { + const res = new Map(); + const dist = new Map(); + let started = false; + vertices.forEach((vertex) => { + const key = JSON.stringify(vertex); + // First, look for our start node. + if (!started) { + if ( + from === vertex.nodeId && + vertex.isDeparture === true && + vertex.time === undefined + ) { + started = true; + dist.set(key, [0, 0]); + } else { + return; + } + } + // We found an end node. + if ( + vertex.isDeparture === false && + vertex.time === undefined && + dist.get(key) !== undefined && + vertex.nodeId !== from + ) { + res.set(vertex.nodeId, dist.get(key)); + } + const neighs = neighbors.get(key); + if (neighs === undefined || dist.get(key) === undefined) { + return; + } + // The shortest path from the start node to this vertex is a shortest path from the start node to a neighbor + // plus the weight of the edge connecting the neighbor to this vertex. + neighs.forEach(([neighbor, weight]) => { + const alt = dist.get(key)[0] + weight; + const neighborKey = JSON.stringify(neighbor); + if ( + dist.get(neighborKey) === undefined || + alt < dist.get(neighborKey)[0] + ) { + let connection = 0; + if ( + vertex.trainrunId !== undefined && + neighbor.trainrunId !== undefined && + vertex.trainrunId !== neighbor.trainrunId + ) { + connection = 1; } - // The shortest path from the start node to this vertex is a shortest path from the start node to a neighbor - // plus the weight of the edge connecting the neighbor to this vertex. - neighs.forEach(([neighbor, weight]) => { - const alt = dist.get(key)[0] + weight; - const neighborKey = JSON.stringify(neighbor); - if (dist.get(neighborKey) === undefined || alt < dist.get(neighborKey)[0]) { - let connection = 0; - if (vertex.trainrunId !== undefined && neighbor.trainrunId !== undefined - && vertex.trainrunId !== neighbor.trainrunId) { - connection = 1; - } - dist.set(neighborKey, [alt, dist.get(key)[1] + connection]); - } - }); + dist.set(neighborKey, [alt, dist.get(key)[1] + connection]); + } }); - return res; + }); + return res; }; -const buildSectionEdges = (trainruns: Trainrun[], trainrunService: TrainrunService, timeLimit: number): Edge[] => { - const edges = []; - const its = trainrunService.getRootIterators(); - trainruns.forEach((trainrun) => { - const tsIterators = its.get(trainrun.getId()); - if (tsIterators === undefined) { - console.log("Ignoring trainrun (no root found): ", trainrun.getId()); - return; - } - tsIterators.forEach((tsIterator) => { - edges.push(...buildSectionEdgesFromIterator(tsIterator, false, timeLimit)); - // Don't forget the reverse direction. - const ts = tsIterator.current().trainrunSection; - const nextIterator = trainrunService.getIterator(ts.getTargetNode(), ts); - edges.push(...buildSectionEdgesFromIterator(nextIterator, true, timeLimit)); - }); +const buildSectionEdges = ( + trainruns: Trainrun[], + trainrunService: TrainrunService, + timeLimit: number, +): Edge[] => { + const edges = []; + const its = trainrunService.getRootIterators(); + trainruns.forEach((trainrun) => { + const tsIterators = its.get(trainrun.getId()); + if (tsIterators === undefined) { + console.log("Ignoring trainrun (no root found): ", trainrun.getId()); + return; + } + tsIterators.forEach((tsIterator) => { + edges.push( + ...buildSectionEdgesFromIterator(tsIterator, false, timeLimit), + ); + // Don't forget the reverse direction. + const ts = tsIterator.current().trainrunSection; + const nextIterator = trainrunService.getIterator(ts.getTargetNode(), ts); + edges.push( + ...buildSectionEdgesFromIterator(nextIterator, true, timeLimit), + ); }); - return edges; + }); + return edges; }; -const buildSectionEdgesFromIterator = (tsIterator: TrainrunIterator, reverse: boolean, timeLimit: number): Edge[] => { - const edges = []; - let nonStopV1Time = -1; - let nonStopV1Node = -1; - while (tsIterator.hasNext()) { - tsIterator.next(); - const ts = tsIterator.current().trainrunSection; - const trainrunId = reverse ? -ts.getTrainrunId() : ts.getTrainrunId(); - const v1Time = reverse ? ts.getTargetDepartureDto().consecutiveTime : ts.getSourceDepartureDto().consecutiveTime; - const v1Node = reverse ? ts.getTargetNodeId() : ts.getSourceNodeId(); - // If we don't stop here, we need to remember where we started. - if (reverse ? ts.getSourceNode().isNonStop(ts) : ts.getTargetNode().isNonStop(ts)) { - if (nonStopV1Time === -1) { - nonStopV1Time = v1Time; - nonStopV1Node = v1Node; - } - continue; - } - let v1 = new Vertex(v1Node, true, v1Time, trainrunId); - let nonStop = false; - if (nonStopV1Time !== -1) { - v1 = new Vertex(nonStopV1Node, true, nonStopV1Time, trainrunId); - nonStopV1Time = -1; - nonStop = true; +const buildSectionEdgesFromIterator = ( + tsIterator: TrainrunIterator, + reverse: boolean, + timeLimit: number, +): Edge[] => { + const edges = []; + let nonStopV1Time = -1; + let nonStopV1Node = -1; + while (tsIterator.hasNext()) { + tsIterator.next(); + const ts = tsIterator.current().trainrunSection; + const trainrunId = reverse ? -ts.getTrainrunId() : ts.getTrainrunId(); + const v1Time = reverse + ? ts.getTargetDepartureDto().consecutiveTime + : ts.getSourceDepartureDto().consecutiveTime; + const v1Node = reverse ? ts.getTargetNodeId() : ts.getSourceNodeId(); + // If we don't stop here, we need to remember where we started. + if ( + reverse + ? ts.getSourceNode().isNonStop(ts) + : ts.getTargetNode().isNonStop(ts) + ) { + if (nonStopV1Time === -1) { + nonStopV1Time = v1Time; + nonStopV1Node = v1Node; } - const v2Time = reverse ? ts.getSourceArrivalDto().consecutiveTime : ts.getTargetArrivalDto().consecutiveTime; - const v2Node = reverse ? ts.getSourceNodeId() : ts.getTargetNodeId(); - const v2 = new Vertex(v2Node, false, v2Time, trainrunId); + continue; + } + let v1 = new Vertex(v1Node, true, v1Time, trainrunId); + let nonStop = false; + if (nonStopV1Time !== -1) { + v1 = new Vertex(nonStopV1Node, true, nonStopV1Time, trainrunId); + nonStopV1Time = -1; + nonStop = true; + } + const v2Time = reverse + ? ts.getSourceArrivalDto().consecutiveTime + : ts.getTargetArrivalDto().consecutiveTime; + const v2Node = reverse ? ts.getSourceNodeId() : ts.getTargetNodeId(); + const v2 = new Vertex(v2Node, false, v2Time, trainrunId); - for (let i = 0; i*ts.getTrainrun().getFrequency() < timeLimit; i++) { - const newV1 = new Vertex(v1.nodeId, v1.isDeparture, v1.time+i*ts.getTrainrun().getFrequency(), v1.trainrunId); - const newV2 = new Vertex(v2.nodeId, v2.isDeparture, v2.time+i*ts.getTrainrun().getFrequency(), v2.trainrunId); - const edge = new Edge(newV1, newV2, newV2.time - newV1.time); - edges.push(edge); - } + for (let i = 0; i * ts.getTrainrun().getFrequency() < timeLimit; i++) { + const newV1 = new Vertex( + v1.nodeId, + v1.isDeparture, + v1.time + i * ts.getTrainrun().getFrequency(), + v1.trainrunId, + ); + const newV2 = new Vertex( + v2.nodeId, + v2.isDeparture, + v2.time + i * ts.getTrainrun().getFrequency(), + v2.trainrunId, + ); + const edge = new Edge(newV1, newV2, newV2.time - newV1.time); + edges.push(edge); } - return edges; + } + return edges; }; -const buildConvenienceEdges = (nodes: Node[], verticesDepartureByTrainrunByNode: Map>, - verticesArrivalByTrainrunByNode: Map>): Edge[] => { - const edges = []; - nodes.forEach((node) => { - const nodeId = node.getId(); - // We add a single start and end vertex for each node, so we can compute shortest paths more easily. - const srcVertex = new Vertex(nodeId, true); - const tgtVertex = new Vertex(nodeId, false); - // Going from one node to itself is free. - const edge = new Edge(srcVertex, tgtVertex, 0); - edges.push(edge); - const departuresByTrainrun = verticesDepartureByTrainrunByNode.get(nodeId); - if (departuresByTrainrun !== undefined) { - departuresByTrainrun.forEach((departures, trainrunId) => { - departures.forEach((departure) => { - const edge = new Edge(srcVertex, departure, 0); - edges.push(edge); - }); +const buildConvenienceEdges = ( + nodes: Node[], + verticesDepartureByTrainrunByNode: Map>, + verticesArrivalByTrainrunByNode: Map>, +): Edge[] => { + const edges = []; + nodes.forEach((node) => { + const nodeId = node.getId(); + // We add a single start and end vertex for each node, so we can compute shortest paths more easily. + const srcVertex = new Vertex(nodeId, true); + const tgtVertex = new Vertex(nodeId, false); + // Going from one node to itself is free. + const edge = new Edge(srcVertex, tgtVertex, 0); + edges.push(edge); + const departuresByTrainrun = verticesDepartureByTrainrunByNode.get(nodeId); + if (departuresByTrainrun !== undefined) { + departuresByTrainrun.forEach((departures, trainrunId) => { + departures.forEach((departure) => { + const edge = new Edge(srcVertex, departure, 0); + edges.push(edge); }); - } - const arrivalsByTrainrun = verticesArrivalByTrainrunByNode.get(nodeId); - if (arrivalsByTrainrun !== undefined) { - arrivalsByTrainrun.forEach((arrivals, trainrunId) => { - arrivals.forEach((arrival) => { - const edge = new Edge(arrival, tgtVertex, 0); - edges.push(edge); - }); + }); + } + const arrivalsByTrainrun = verticesArrivalByTrainrunByNode.get(nodeId); + if (arrivalsByTrainrun !== undefined) { + arrivalsByTrainrun.forEach((arrivals, trainrunId) => { + arrivals.forEach((arrival) => { + const edge = new Edge(arrival, tgtVertex, 0); + edges.push(edge); }); - } - }); - return edges; + }); + } + }); + return edges; }; -const buildConnectionEdges = (nodes: Node[], verticesDepartureByTrainrunByNode: Map>, - verticesArrivalByTrainrunByNode: Map>, connectionPenalty: number): Edge[] => { - const edges = []; - nodes.forEach((node) => { - const departuresByTrainrun = verticesDepartureByTrainrunByNode.get(node.getId()); - const arrivalsByTrainrun = verticesArrivalByTrainrunByNode.get(node.getId()); - if (departuresByTrainrun !== undefined && arrivalsByTrainrun !== undefined) { - arrivalsByTrainrun.forEach((arrivals, arrivalTrainrunId) => { - arrivals.forEach((arrival) => { - departuresByTrainrun.forEach((departures, departureTrainrunId) => { - let minDepartureTime = arrival.time; - if (arrivalTrainrunId !== departureTrainrunId) { - minDepartureTime += node.getConnectionTime(); - } - // For each arrival and for each trainrun available, we only want to consider the first departure. - // This could be a binary search but it does not seem to be worth it. - const departure = departures.find((departure) => {return departure.time >= minDepartureTime;}); - if (departure !== undefined) { - let cost = departure.time - arrival.time; - if (arrivalTrainrunId !== departureTrainrunId) { - cost += connectionPenalty; - } - const edge = new Edge(arrival, departure, cost); - edges.push(edge); - } - }); +const buildConnectionEdges = ( + nodes: Node[], + verticesDepartureByTrainrunByNode: Map>, + verticesArrivalByTrainrunByNode: Map>, + connectionPenalty: number, +): Edge[] => { + const edges = []; + nodes.forEach((node) => { + const departuresByTrainrun = verticesDepartureByTrainrunByNode.get( + node.getId(), + ); + const arrivalsByTrainrun = verticesArrivalByTrainrunByNode.get( + node.getId(), + ); + if ( + departuresByTrainrun !== undefined && + arrivalsByTrainrun !== undefined + ) { + arrivalsByTrainrun.forEach((arrivals, arrivalTrainrunId) => { + arrivals.forEach((arrival) => { + departuresByTrainrun.forEach((departures, departureTrainrunId) => { + let minDepartureTime = arrival.time; + if (arrivalTrainrunId !== departureTrainrunId) { + minDepartureTime += node.getConnectionTime(); + } + // For each arrival and for each trainrun available, we only want to consider the first departure. + // This could be a binary search but it does not seem to be worth it. + const departure = departures.find((departure) => { + return departure.time >= minDepartureTime; }); + if (departure !== undefined) { + let cost = departure.time - arrival.time; + if (arrivalTrainrunId !== departureTrainrunId) { + cost += connectionPenalty; + } + const edge = new Edge(arrival, departure, cost); + edges.push(edge); + } }); - } - }); - return edges; -}; - -const depthFirstSearch = (graph: Map, root: Vertex, visited: Set, res: Vertex[]): void => { - const key = JSON.stringify(root); - visited.add(key); - const neighbors = graph.get(key); - if (neighbors !== undefined) { - neighbors.forEach(([neighbor, weight]) => { - if (!visited.has(JSON.stringify(neighbor))) { - depthFirstSearch(graph, neighbor, visited, res); - } + }); }); } - // Note that the order is important for topological sorting. - res.push(root); + }); + return edges; +}; + +const depthFirstSearch = ( + graph: Map, + root: Vertex, + visited: Set, + res: Vertex[], +): void => { + const key = JSON.stringify(root); + visited.add(key); + const neighbors = graph.get(key); + if (neighbors !== undefined) { + neighbors.forEach(([neighbor, weight]) => { + if (!visited.has(JSON.stringify(neighbor))) { + depthFirstSearch(graph, neighbor, visited, res); + } + }); + } + // Note that the order is important for topological sorting. + res.push(root); }; diff --git a/src/integration-testing/netzgrafik.unit.testing.od.matrix.ts b/src/integration-testing/netzgrafik.unit.testing.od.matrix.ts index b8a3f98c..f46158cb 100644 --- a/src/integration-testing/netzgrafik.unit.testing.od.matrix.ts +++ b/src/integration-testing/netzgrafik.unit.testing.od.matrix.ts @@ -1,1164 +1,1146 @@ import { HaltezeitFachCategories, - LabelRef, LinePatternRefs, NetzgrafikDto, } from "../app/data-structures/business.data.structures"; -import {TrainrunSectionText} from "../app/data-structures/technical.data.structures"; export class NetzgrafikUnitTestingOdMatrix { static getUnitTestNetzgrafik(): NetzgrafikDto { return { - "nodes": [ - { - "id": 11, - "betriebspunktName": "C", - "fullName": "C", - "positionX": 1536, - "positionY": 864, - "ports": [ - { - "id": 14, - "trainrunSectionId": 7, - "positionIndex": 0, - "positionAlignment": 2 - }, - { - "id": 20, - "trainrunSectionId": 10, - "positionIndex": 1, - "positionAlignment": 2 - }, - { - "id": 15, - "trainrunSectionId": 8, - "positionIndex": 2, - "positionAlignment": 2 - }, - { - "id": 21, - "trainrunSectionId": 11, - "positionIndex": 3, - "positionAlignment": 2 - } - ], - "transitions": [ - { - "id": 4, - "port1Id": 20, - "port2Id": 21, - "isNonStopTransit": true - } - ], - "connections": [], - "resourceId": 12, - "perronkanten": 5, - "connectionTime": 3, - "trainrunCategoryHaltezeiten": { - "HaltezeitIPV": { - "haltezeit": 3, - "no_halt": false - }, - "HaltezeitA": { - "haltezeit": 2, - "no_halt": false - }, - "HaltezeitB": { - "haltezeit": 2, - "no_halt": false - }, - "HaltezeitC": { - "haltezeit": 1, - "no_halt": false - }, - "HaltezeitD": { - "haltezeit": 1, - "no_halt": false - }, - "HaltezeitUncategorized": { - "haltezeit": 0, - "no_halt": true - } - }, - "symmetryAxis": null, - "warnings": null, - "labelIds": [] + nodes: [ + { + id: 11, + betriebspunktName: "C", + fullName: "C", + positionX: 1536, + positionY: 864, + ports: [ + { + id: 14, + trainrunSectionId: 7, + positionIndex: 0, + positionAlignment: 2, + }, + { + id: 20, + trainrunSectionId: 10, + positionIndex: 1, + positionAlignment: 2, + }, + { + id: 15, + trainrunSectionId: 8, + positionIndex: 2, + positionAlignment: 2, + }, + { + id: 21, + trainrunSectionId: 11, + positionIndex: 3, + positionAlignment: 2, + }, + ], + transitions: [ + { + id: 4, + port1Id: 20, + port2Id: 21, + isNonStopTransit: true, + }, + ], + connections: [], + resourceId: 12, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitIPV: { + haltezeit: 3, + no_halt: false, + }, + HaltezeitA: { + haltezeit: 2, + no_halt: false, + }, + HaltezeitB: { + haltezeit: 2, + no_halt: false, + }, + HaltezeitC: { + haltezeit: 1, + no_halt: false, + }, + HaltezeitD: { + haltezeit: 1, + no_halt: false, + }, + HaltezeitUncategorized: { + haltezeit: 0, + no_halt: true, + }, }, - { - "id": 12, - "betriebspunktName": "A", - "fullName": "A", - "positionX": 1120, - "positionY": 672, - "ports": [ - { - "id": 17, - "trainrunSectionId": 9, - "positionIndex": 0, - "positionAlignment": 1 - }, - { - "id": 12, - "trainrunSectionId": 6, - "positionIndex": 0, - "positionAlignment": 2 - }, - { - "id": 13, - "trainrunSectionId": 7, - "positionIndex": 0, - "positionAlignment": 3 - }, - { - "id": 19, - "trainrunSectionId": 10, - "positionIndex": 1, - "positionAlignment": 3 - } - ], - "transitions": [ - { - "id": 3, - "port1Id": 12, - "port2Id": 13, - "isNonStopTransit": false - } - ], - "connections": [], - "resourceId": 13, - "perronkanten": 5, - "connectionTime": 8, - "trainrunCategoryHaltezeiten": { - "HaltezeitIPV": { - "haltezeit": 3, - "no_halt": false - }, - "HaltezeitA": { - "haltezeit": 2, - "no_halt": false - }, - "HaltezeitB": { - "haltezeit": 2, - "no_halt": false - }, - "HaltezeitC": { - "haltezeit": 1, - "no_halt": false - }, - "HaltezeitD": { - "haltezeit": 1, - "no_halt": false - }, - "HaltezeitUncategorized": { - "haltezeit": 0, - "no_halt": true - } - }, - "symmetryAxis": null, - "warnings": null, - "labelIds": [] + symmetryAxis: null, + warnings: null, + labelIds: [], + }, + { + id: 12, + betriebspunktName: "A", + fullName: "A", + positionX: 1120, + positionY: 672, + ports: [ + { + id: 17, + trainrunSectionId: 9, + positionIndex: 0, + positionAlignment: 1, + }, + { + id: 12, + trainrunSectionId: 6, + positionIndex: 0, + positionAlignment: 2, + }, + { + id: 13, + trainrunSectionId: 7, + positionIndex: 0, + positionAlignment: 3, + }, + { + id: 19, + trainrunSectionId: 10, + positionIndex: 1, + positionAlignment: 3, + }, + ], + transitions: [ + { + id: 3, + port1Id: 12, + port2Id: 13, + isNonStopTransit: false, + }, + ], + connections: [], + resourceId: 13, + perronkanten: 5, + connectionTime: 8, + trainrunCategoryHaltezeiten: { + HaltezeitIPV: { + haltezeit: 3, + no_halt: false, + }, + HaltezeitA: { + haltezeit: 2, + no_halt: false, + }, + HaltezeitB: { + haltezeit: 2, + no_halt: false, + }, + HaltezeitC: { + haltezeit: 1, + no_halt: false, + }, + HaltezeitD: { + haltezeit: 1, + no_halt: false, + }, + HaltezeitUncategorized: { + haltezeit: 0, + no_halt: true, + }, }, - { - "id": 13, - "betriebspunktName": "D", - "fullName": "D", - "positionX": 1088, - "positionY": 1088, - "ports": [ - { - "id": 18, - "trainrunSectionId": 9, - "positionIndex": 0, - "positionAlignment": 0 - }, - { - "id": 22, - "trainrunSectionId": 11, - "positionIndex": 0, - "positionAlignment": 3 - } - ], - "transitions": [], - "connections": [], - "resourceId": 14, - "perronkanten": 5, - "connectionTime": 3, - "trainrunCategoryHaltezeiten": { - "HaltezeitIPV": { - "haltezeit": 3, - "no_halt": false - }, - "HaltezeitA": { - "haltezeit": 2, - "no_halt": false - }, - "HaltezeitB": { - "haltezeit": 2, - "no_halt": false - }, - "HaltezeitC": { - "haltezeit": 1, - "no_halt": false - }, - "HaltezeitD": { - "haltezeit": 1, - "no_halt": false - }, - "HaltezeitUncategorized": { - "haltezeit": 0, - "no_halt": true - } - }, - "symmetryAxis": null, - "warnings": null, - "labelIds": [] + symmetryAxis: null, + warnings: null, + labelIds: [], + }, + { + id: 13, + betriebspunktName: "D", + fullName: "D", + positionX: 1088, + positionY: 1088, + ports: [ + { + id: 18, + trainrunSectionId: 9, + positionIndex: 0, + positionAlignment: 0, + }, + { + id: 22, + trainrunSectionId: 11, + positionIndex: 0, + positionAlignment: 3, + }, + ], + transitions: [], + connections: [], + resourceId: 14, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitIPV: { + haltezeit: 3, + no_halt: false, + }, + HaltezeitA: { + haltezeit: 2, + no_halt: false, + }, + HaltezeitB: { + haltezeit: 2, + no_halt: false, + }, + HaltezeitC: { + haltezeit: 1, + no_halt: false, + }, + HaltezeitD: { + haltezeit: 1, + no_halt: false, + }, + HaltezeitUncategorized: { + haltezeit: 0, + no_halt: true, + }, }, - { - "id": 14, - "betriebspunktName": "B", - "fullName": "B", - "positionX": 800, - "positionY": 864, - "ports": [ - { - "id": 11, - "trainrunSectionId": 6, - "positionIndex": 0, - "positionAlignment": 3 - }, - { - "id": 16, - "trainrunSectionId": 8, - "positionIndex": 1, - "positionAlignment": 3 - } - ], - "transitions": [], - "connections": [], - "resourceId": 15, - "perronkanten": 5, - "connectionTime": 3, - "trainrunCategoryHaltezeiten": { - "HaltezeitIPV": { - "haltezeit": 3, - "no_halt": false - }, - "HaltezeitA": { - "haltezeit": 2, - "no_halt": false - }, - "HaltezeitB": { - "haltezeit": 2, - "no_halt": false - }, - "HaltezeitC": { - "haltezeit": 1, - "no_halt": false - }, - "HaltezeitD": { - "haltezeit": 1, - "no_halt": false - }, - "HaltezeitUncategorized": { - "haltezeit": 0, - "no_halt": true - } - }, - "symmetryAxis": null, - "warnings": null, - "labelIds": [] - } + symmetryAxis: null, + warnings: null, + labelIds: [], + }, + { + id: 14, + betriebspunktName: "B", + fullName: "B", + positionX: 800, + positionY: 864, + ports: [ + { + id: 11, + trainrunSectionId: 6, + positionIndex: 0, + positionAlignment: 3, + }, + { + id: 16, + trainrunSectionId: 8, + positionIndex: 1, + positionAlignment: 3, + }, + ], + transitions: [], + connections: [], + resourceId: 15, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitIPV: { + haltezeit: 3, + no_halt: false, + }, + HaltezeitA: { + haltezeit: 2, + no_halt: false, + }, + HaltezeitB: { + haltezeit: 2, + no_halt: false, + }, + HaltezeitC: { + haltezeit: 1, + no_halt: false, + }, + HaltezeitD: { + haltezeit: 1, + no_halt: false, + }, + HaltezeitUncategorized: { + haltezeit: 0, + no_halt: true, + }, + }, + symmetryAxis: null, + warnings: null, + labelIds: [], + }, ], - "trainrunSections": [ - { - "id": 6, - "sourceNodeId": 14, - "sourcePortId": 11, - "targetNodeId": 12, - "targetPortId": 12, - "travelTime": { - "time": 2, - "consecutiveTime": 1, - "lock": true, - "warning": null, - "timeFormatter": null - }, - "sourceDeparture": { - "time": 0, - "consecutiveTime": 0, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "sourceArrival": { - "time": 0, - "consecutiveTime": 60, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "targetDeparture": { - "time": 58, - "consecutiveTime": 58, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "targetArrival": { - "time": 2, - "consecutiveTime": 2, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "numberOfStops": 0, - "trainrunId": 4, - "resourceId": 0, - "specificTrainrunSectionFrequencyId": null, - "path": { - "path": [ - { - "x": 898, - "y": 880 - }, - { - "x": 962, - "y": 880 - }, - { - "x": 1054, - "y": 688 - }, - { - "x": 1118, - "y": 688 - } - ], - "textPositions": { - "0": { - "x": 916, - "y": 892 - }, - "1": { - "x": 944, - "y": 868 - }, - "2": { - "x": 1100, - "y": 676 - }, - "3": { - "x": 1072, - "y": 700 - }, - "4": { - "x": 1008, - "y": 772 - }, - "5": { - "x": 1008, - "y": 772 - }, - "6": { - "x": 1008, - "y": 796 - } - } - }, - "warnings": null + trainrunSections: [ + { + id: 6, + sourceNodeId: 14, + sourcePortId: 11, + targetNodeId: 12, + targetPortId: 12, + travelTime: { + time: 2, + consecutiveTime: 1, + lock: true, + warning: null, + timeFormatter: null, }, - { - "id": 7, - "sourceNodeId": 12, - "sourcePortId": 13, - "targetNodeId": 11, - "targetPortId": 14, - "travelTime": { - "time": 4, - "consecutiveTime": 1, - "lock": true, - "warning": null, - "timeFormatter": null - }, - "sourceDeparture": { - "time": 3, - "consecutiveTime": 3, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "sourceArrival": { - "time": 57, - "consecutiveTime": 57, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "targetDeparture": { - "time": 53, - "consecutiveTime": 53, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "targetArrival": { - "time": 7, - "consecutiveTime": 7, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "numberOfStops": 0, - "trainrunId": 4, - "resourceId": 0, - "specificTrainrunSectionFrequencyId": null, - "path": { - "path": [ - { - "x": 1218, - "y": 688 - }, - { - "x": 1282, - "y": 688 - }, - { - "x": 1470, - "y": 880 - }, - { - "x": 1534, - "y": 880 - } - ], - "textPositions": { - "0": { - "x": 1236, - "y": 700 - }, - "1": { - "x": 1264, - "y": 676 - }, - "2": { - "x": 1516, - "y": 868 - }, - "3": { - "x": 1488, - "y": 892 - }, - "4": { - "x": 1376, - "y": 772 - }, - "5": { - "x": 1376, - "y": 772 - }, - "6": { - "x": 1376, - "y": 796 - } - } - }, - "warnings": null + sourceDeparture: { + time: 0, + consecutiveTime: 0, + lock: false, + warning: null, + timeFormatter: null, }, - { - "id": 8, - "sourceNodeId": 11, - "sourcePortId": 15, - "targetNodeId": 14, - "targetPortId": 16, - "travelTime": { - "time": 6, - "consecutiveTime": 1, - "lock": true, - "warning": null, - "timeFormatter": null - }, - "sourceDeparture": { - "time": 0, - "consecutiveTime": 60, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "sourceArrival": { - "time": 0, - "consecutiveTime": 60, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "targetDeparture": { - "time": 54, - "consecutiveTime": 54, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "targetArrival": { - "time": 6, - "consecutiveTime": 66, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "numberOfStops": 0, - "trainrunId": 5, - "resourceId": 0, - "specificTrainrunSectionFrequencyId": null, - "path": { - "path": [ - { - "x": 1534, - "y": 944 - }, - { - "x": 1470, - "y": 944 - }, - { - "x": 962, - "y": 912 - }, - { - "x": 898, - "y": 912 - } - ], - "textPositions": { - "0": { - "x": 1516, - "y": 932 - }, - "1": { - "x": 1488, - "y": 956 - }, - "2": { - "x": 916, - "y": 924 - }, - "3": { - "x": 944, - "y": 900 - }, - "4": { - "x": 1216, - "y": 916 - }, - "5": { - "x": 1216, - "y": 916 - }, - "6": { - "x": 1216, - "y": 940 - } - } - }, - "warnings": null + sourceArrival: { + time: 0, + consecutiveTime: 60, + lock: false, + warning: null, + timeFormatter: null, }, - { - "id": 9, - "sourceNodeId": 12, - "sourcePortId": 17, - "targetNodeId": 13, - "targetPortId": 18, - "travelTime": { - "time": 2, - "consecutiveTime": 1, - "lock": true, - "warning": null, - "timeFormatter": null - }, - "sourceDeparture": { - "time": 8, - "consecutiveTime": 8, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "sourceArrival": { - "time": 52, - "consecutiveTime": 52, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "targetDeparture": { - "time": 50, - "consecutiveTime": 50, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "targetArrival": { - "time": 10, - "consecutiveTime": 10, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "numberOfStops": 0, - "trainrunId": 6, - "resourceId": 0, - "specificTrainrunSectionFrequencyId": null, - "path": { - "path": [ - { - "x": 1136, - "y": 766 - }, - { - "x": 1136, - "y": 830 - }, - { - "x": 1104, - "y": 1022 - }, - { - "x": 1104, - "y": 1086 - } - ], - "textPositions": { - "0": { - "x": 1124, - "y": 784 - }, - "1": { - "x": 1148, - "y": 812 - }, - "2": { - "x": 1116, - "y": 1068 - }, - "3": { - "x": 1092, - "y": 1040 - }, - "4": { - "x": 1108, - "y": 926 - }, - "5": { - "x": 1108, - "y": 926 - }, - "6": { - "x": 1132, - "y": 926 - } - } - }, - "warnings": null + targetDeparture: { + time: 58, + consecutiveTime: 58, + lock: false, + warning: null, + timeFormatter: null, }, - { - "id": 10, - "sourceNodeId": 12, - "sourcePortId": 19, - "targetNodeId": 11, - "targetPortId": 20, - "travelTime": { - "time": 5, - "consecutiveTime": 1, - "lock": true, - "warning": null, - "timeFormatter": null - }, - "sourceDeparture": { - "time": 0, - "consecutiveTime": 0, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "sourceArrival": { - "time": 0, - "consecutiveTime": 60, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "targetDeparture": { - "time": 55, - "consecutiveTime": 55, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "targetArrival": { - "time": 5, - "consecutiveTime": 5, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "numberOfStops": 0, - "trainrunId": 7, - "resourceId": 0, - "specificTrainrunSectionFrequencyId": null, - "path": { - "path": [ - { - "x": 1218, - "y": 720 - }, - { - "x": 1282, - "y": 720 - }, - { - "x": 1470, - "y": 912 - }, - { - "x": 1534, - "y": 912 - } - ], - "textPositions": { - "0": { - "x": 1236, - "y": 732 - }, - "1": { - "x": 1264, - "y": 708 - }, - "2": { - "x": 1516, - "y": 900 - }, - "3": { - "x": 1488, - "y": 924 - }, - "4": { - "x": 1376, - "y": 804 - }, - "5": { - "x": 1376, - "y": 804 - }, - "6": { - "x": 1376, - "y": 828 - } - } - }, - "warnings": null + targetArrival: { + time: 2, + consecutiveTime: 2, + lock: false, + warning: null, + timeFormatter: null, }, - { - "id": 11, - "sourceNodeId": 11, - "sourcePortId": 21, - "targetNodeId": 13, - "targetPortId": 22, - "travelTime": { - "time": 4, - "consecutiveTime": 1, - "lock": true, - "warning": null, - "timeFormatter": null - }, - "sourceDeparture": { - "time": 5, - "consecutiveTime": 5, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "sourceArrival": { - "time": 55, - "consecutiveTime": 55, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "targetDeparture": { - "time": 51, - "consecutiveTime": 51, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "targetArrival": { - "time": 9, - "consecutiveTime": 9, - "lock": false, - "warning": null, - "timeFormatter": null - }, - "numberOfStops": 0, - "trainrunId": 7, - "resourceId": 0, - "specificTrainrunSectionFrequencyId": null, - "path": { - "path": [ - { - "x": 1534, - "y": 976 - }, - { - "x": 1470, - "y": 976 - }, - { - "x": 1250, - "y": 1104 - }, - { - "x": 1186, - "y": 1104 - } - ], - "textPositions": { - "0": { - "x": 1516, - "y": 964 - }, - "1": { - "x": 1488, - "y": 988 - }, - "2": { - "x": 1204, - "y": 1116 - }, - "3": { - "x": 1232, - "y": 1092 - }, - "4": { - "x": 1360, - "y": 1028 - }, - "5": { - "x": 1360, - "y": 1028 - }, - "6": { - "x": 1360, - "y": 1052 - } - } - }, - "warnings": null - } - ], - "trainruns": [ - { - "id": 4, - "name": "1", - "categoryId": 1, - "frequencyId": 3, - "trainrunTimeCategoryId": 0, - "labelIds": [] + numberOfStops: 0, + trainrunId: 4, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 898, + y: 880, + }, + { + x: 962, + y: 880, + }, + { + x: 1054, + y: 688, + }, + { + x: 1118, + y: 688, + }, + ], + textPositions: { + "0": { + x: 916, + y: 892, + }, + "1": { + x: 944, + y: 868, + }, + "2": { + x: 1100, + y: 676, + }, + "3": { + x: 1072, + y: 700, + }, + "4": { + x: 1008, + y: 772, + }, + "5": { + x: 1008, + y: 772, + }, + "6": { + x: 1008, + y: 796, + }, + }, }, - { - "id": 5, - "name": "2", - "categoryId": 3, - "frequencyId": 2, - "trainrunTimeCategoryId": 0, - "labelIds": [] + warnings: null, + }, + { + id: 7, + sourceNodeId: 12, + sourcePortId: 13, + targetNodeId: 11, + targetPortId: 14, + travelTime: { + time: 4, + consecutiveTime: 1, + lock: true, + warning: null, + timeFormatter: null, }, - { - "id": 6, - "name": "4", - "categoryId": 6, - "frequencyId": 3, - "trainrunTimeCategoryId": 0, - "labelIds": [] + sourceDeparture: { + time: 3, + consecutiveTime: 3, + lock: false, + warning: null, + timeFormatter: null, }, - { - "id": 7, - "name": "3", - "categoryId": 5, - "frequencyId": 0, - "trainrunTimeCategoryId": 0, - "labelIds": [] - } - ], - "resources": [ - { - "id": 1, - "capacity": 2 + sourceArrival: { + time: 57, + consecutiveTime: 57, + lock: false, + warning: null, + timeFormatter: null, }, - { - "id": 2, - "capacity": 2 + targetDeparture: { + time: 53, + consecutiveTime: 53, + lock: false, + warning: null, + timeFormatter: null, }, - { - "id": 3, - "capacity": 2 + targetArrival: { + time: 7, + consecutiveTime: 7, + lock: false, + warning: null, + timeFormatter: null, }, - { - "id": 4, - "capacity": 2 + numberOfStops: 0, + trainrunId: 4, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1218, + y: 688, + }, + { + x: 1282, + y: 688, + }, + { + x: 1470, + y: 880, + }, + { + x: 1534, + y: 880, + }, + ], + textPositions: { + "0": { + x: 1236, + y: 700, + }, + "1": { + x: 1264, + y: 676, + }, + "2": { + x: 1516, + y: 868, + }, + "3": { + x: 1488, + y: 892, + }, + "4": { + x: 1376, + y: 772, + }, + "5": { + x: 1376, + y: 772, + }, + "6": { + x: 1376, + y: 796, + }, + }, }, - { - "id": 5, - "capacity": 2 + warnings: null, + }, + { + id: 8, + sourceNodeId: 11, + sourcePortId: 15, + targetNodeId: 14, + targetPortId: 16, + travelTime: { + time: 6, + consecutiveTime: 1, + lock: true, + warning: null, + timeFormatter: null, }, - { - "id": 6, - "capacity": 2 + sourceDeparture: { + time: 0, + consecutiveTime: 60, + lock: false, + warning: null, + timeFormatter: null, }, - { - "id": 7, - "capacity": 2 + sourceArrival: { + time: 0, + consecutiveTime: 60, + lock: false, + warning: null, + timeFormatter: null, }, - { - "id": 8, - "capacity": 2 + targetDeparture: { + time: 54, + consecutiveTime: 54, + lock: false, + warning: null, + timeFormatter: null, }, - { - "id": 9, - "capacity": 2 + targetArrival: { + time: 6, + consecutiveTime: 66, + lock: false, + warning: null, + timeFormatter: null, }, - { - "id": 10, - "capacity": 2 + numberOfStops: 0, + trainrunId: 5, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1534, + y: 944, + }, + { + x: 1470, + y: 944, + }, + { + x: 962, + y: 912, + }, + { + x: 898, + y: 912, + }, + ], + textPositions: { + "0": { + x: 1516, + y: 932, + }, + "1": { + x: 1488, + y: 956, + }, + "2": { + x: 916, + y: 924, + }, + "3": { + x: 944, + y: 900, + }, + "4": { + x: 1216, + y: 916, + }, + "5": { + x: 1216, + y: 916, + }, + "6": { + x: 1216, + y: 940, + }, + }, }, - { - "id": 11, - "capacity": 2 + warnings: null, + }, + { + id: 9, + sourceNodeId: 12, + sourcePortId: 17, + targetNodeId: 13, + targetPortId: 18, + travelTime: { + time: 2, + consecutiveTime: 1, + lock: true, + warning: null, + timeFormatter: null, }, - { - "id": 12, - "capacity": 2 + sourceDeparture: { + time: 8, + consecutiveTime: 8, + lock: false, + warning: null, + timeFormatter: null, }, - { - "id": 13, - "capacity": 2 + sourceArrival: { + time: 52, + consecutiveTime: 52, + lock: false, + warning: null, + timeFormatter: null, }, - { - "id": 14, - "capacity": 2 + targetDeparture: { + time: 50, + consecutiveTime: 50, + lock: false, + warning: null, + timeFormatter: null, }, - { - "id": 15, - "capacity": 2 - } - ], - "metadata": { - "analyticsSettings": { - "originDestinationSettings": { - "connectionPenalty": 5, - } + targetArrival: { + time: 10, + consecutiveTime: 10, + lock: false, + warning: null, + timeFormatter: null, }, - "trainrunCategories": [ + numberOfStops: 0, + trainrunId: 6, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ { - "id": 0, - "order": 0, - "shortName": "EC", - "name": "International", - "colorRef": "EC", - "fachCategory": HaltezeitFachCategories.IPV, - "minimalTurnaroundTime": 4, - "nodeHeadwayStop": 2, - "nodeHeadwayNonStop": 2, - "sectionHeadway": 2 + x: 1136, + y: 766, }, { - "id": 1, - "order": 1, - "shortName": "IC", - "name": "InterCity", - "colorRef": "IC", - "fachCategory": HaltezeitFachCategories.A, - "minimalTurnaroundTime": 4, - "nodeHeadwayStop": 2, - "nodeHeadwayNonStop": 2, - "sectionHeadway": 2 + x: 1136, + y: 830, }, { - "id": 2, - "order": 2, - "shortName": "IR", - "name": "InterRegio", - "colorRef": "IR", - "fachCategory": HaltezeitFachCategories.B, - "minimalTurnaroundTime": 4, - "nodeHeadwayStop": 2, - "nodeHeadwayNonStop": 2, - "sectionHeadway": 2 + x: 1104, + y: 1022, }, { - "id": 3, - "order": 3, - "shortName": "RE", - "name": "RegioExpress", - "colorRef": "RE", - "fachCategory": HaltezeitFachCategories.C, - "minimalTurnaroundTime": 4, - "nodeHeadwayStop": 2, - "nodeHeadwayNonStop": 2, - "sectionHeadway": 2 + x: 1104, + y: 1086, }, - { - "id": 4, - "order": 4, - "shortName": "S", - "name": "RegioUndSBahnverkehr", - "colorRef": "S", - "fachCategory": HaltezeitFachCategories.D, - "minimalTurnaroundTime": 4, - "nodeHeadwayStop": 2, - "nodeHeadwayNonStop": 2, - "sectionHeadway": 2 + ], + textPositions: { + "0": { + x: 1124, + y: 784, }, - { - "id": 5, - "order": 5, - "shortName": "GEX", - "name": "GüterExpress", - "colorRef": "GEX", - "fachCategory": HaltezeitFachCategories.Uncategorized, - "minimalTurnaroundTime": 4, - "nodeHeadwayStop": 3, - "nodeHeadwayNonStop": 3, - "sectionHeadway": 3 + "1": { + x: 1148, + y: 812, + }, + "2": { + x: 1116, + y: 1068, + }, + "3": { + x: 1092, + y: 1040, + }, + "4": { + x: 1108, + y: 926, + }, + "5": { + x: 1108, + y: 926, + }, + "6": { + x: 1132, + y: 926, }, + }, + }, + warnings: null, + }, + { + id: 10, + sourceNodeId: 12, + sourcePortId: 19, + targetNodeId: 11, + targetPortId: 20, + travelTime: { + time: 5, + consecutiveTime: 1, + lock: true, + warning: null, + timeFormatter: null, + }, + sourceDeparture: { + time: 0, + consecutiveTime: 0, + lock: false, + warning: null, + timeFormatter: null, + }, + sourceArrival: { + time: 0, + consecutiveTime: 60, + lock: false, + warning: null, + timeFormatter: null, + }, + targetDeparture: { + time: 55, + consecutiveTime: 55, + lock: false, + warning: null, + timeFormatter: null, + }, + targetArrival: { + time: 5, + consecutiveTime: 5, + lock: false, + warning: null, + timeFormatter: null, + }, + numberOfStops: 0, + trainrunId: 7, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ { - "id": 6, - "order": 6, - "shortName": "G", - "name": "Güterverkehr", - "colorRef": "G", - "fachCategory": HaltezeitFachCategories.Uncategorized, - "minimalTurnaroundTime": 4, - "nodeHeadwayStop": 3, - "nodeHeadwayNonStop": 3, - "sectionHeadway": 3 - } - ], - "trainrunFrequencies": [ + x: 1218, + y: 720, + }, { - "id": 0, - "order": 0, - "frequency": 15, - "offset": 0, - "shortName": "15", - "name": "verkehrt viertelstündlich", - "linePatternRef": LinePatternRefs.Freq15 + x: 1282, + y: 720, }, { - "id": 1, - "order": 0, - "frequency": 20, - "offset": 0, - "shortName": "20", - "name": "verkehrt im 20 Minuten Takt", - "linePatternRef": LinePatternRefs.Freq20 + x: 1470, + y: 912, }, { - "id": 2, - "order": 0, - "frequency": 30, - "offset": 0, - "shortName": "30", - "name": "verkehrt halbstündlich", - "linePatternRef": LinePatternRefs.Freq30 + x: 1534, + y: 912, + }, + ], + textPositions: { + "0": { + x: 1236, + y: 732, + }, + "1": { + x: 1264, + y: 708, }, + "2": { + x: 1516, + y: 900, + }, + "3": { + x: 1488, + y: 924, + }, + "4": { + x: 1376, + y: 804, + }, + "5": { + x: 1376, + y: 804, + }, + "6": { + x: 1376, + y: 828, + }, + }, + }, + warnings: null, + }, + { + id: 11, + sourceNodeId: 11, + sourcePortId: 21, + targetNodeId: 13, + targetPortId: 22, + travelTime: { + time: 4, + consecutiveTime: 1, + lock: true, + warning: null, + timeFormatter: null, + }, + sourceDeparture: { + time: 5, + consecutiveTime: 5, + lock: false, + warning: null, + timeFormatter: null, + }, + sourceArrival: { + time: 55, + consecutiveTime: 55, + lock: false, + warning: null, + timeFormatter: null, + }, + targetDeparture: { + time: 51, + consecutiveTime: 51, + lock: false, + warning: null, + timeFormatter: null, + }, + targetArrival: { + time: 9, + consecutiveTime: 9, + lock: false, + warning: null, + timeFormatter: null, + }, + numberOfStops: 0, + trainrunId: 7, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ { - "id": 3, - "order": 0, - "frequency": 60, - "offset": 0, - "shortName": "60", - "name": "verkehrt stündlich", - "linePatternRef": LinePatternRefs.Freq60 + x: 1534, + y: 976, }, { - "id": 4, - "order": 0, - "frequency": 120, - "offset": 0, - "shortName": "120", - "name": "verkehrt zweistündlich (gerade)", - "linePatternRef": LinePatternRefs.Freq120 + x: 1470, + y: 976, }, { - "id": 5, - "order": 0, - "frequency": 120, - "offset": 60, - "shortName": "120+", - "name": "verkehrt zweistündlich (ungerade)", - "linePatternRef": LinePatternRefs.Freq120 - } - ], - "trainrunTimeCategories": [ + x: 1250, + y: 1104, + }, { - "id": 0, - "order": 0, - "shortName": "7/24", - "name": "verkehrt uneingeschränkt", - "dayTimeInterval": [], - "weekday": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7 - ], - "linePatternRef": LinePatternRefs.TimeCat7_24 + x: 1186, + y: 1104, + }, + ], + textPositions: { + "0": { + x: 1516, + y: 964, + }, + "1": { + x: 1488, + y: 988, + }, + "2": { + x: 1204, + y: 1116, + }, + "3": { + x: 1232, + y: 1092, + }, + "4": { + x: 1360, + y: 1028, + }, + "5": { + x: 1360, + y: 1028, + }, + "6": { + x: 1360, + y: 1052, }, + }, + }, + warnings: null, + }, + ], + trainruns: [ + { + id: 4, + name: "1", + categoryId: 1, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [], + }, + { + id: 5, + name: "2", + categoryId: 3, + frequencyId: 2, + trainrunTimeCategoryId: 0, + labelIds: [], + }, + { + id: 6, + name: "4", + categoryId: 6, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [], + }, + { + id: 7, + name: "3", + categoryId: 5, + frequencyId: 0, + trainrunTimeCategoryId: 0, + labelIds: [], + }, + ], + resources: [ + { + id: 1, + capacity: 2, + }, + { + id: 2, + capacity: 2, + }, + { + id: 3, + capacity: 2, + }, + { + id: 4, + capacity: 2, + }, + { + id: 5, + capacity: 2, + }, + { + id: 6, + capacity: 2, + }, + { + id: 7, + capacity: 2, + }, + { + id: 8, + capacity: 2, + }, + { + id: 9, + capacity: 2, + }, + { + id: 10, + capacity: 2, + }, + { + id: 11, + capacity: 2, + }, + { + id: 12, + capacity: 2, + }, + { + id: 13, + capacity: 2, + }, + { + id: 14, + capacity: 2, + }, + { + id: 15, + capacity: 2, + }, + ], + metadata: { + analyticsSettings: { + originDestinationSettings: { + connectionPenalty: 5, + }, + }, + trainrunCategories: [ + { + id: 0, + order: 0, + shortName: "EC", + name: "International", + colorRef: "EC", + fachCategory: HaltezeitFachCategories.IPV, + minimalTurnaroundTime: 4, + nodeHeadwayStop: 2, + nodeHeadwayNonStop: 2, + sectionHeadway: 2, + }, + { + id: 1, + order: 1, + shortName: "IC", + name: "InterCity", + colorRef: "IC", + fachCategory: HaltezeitFachCategories.A, + minimalTurnaroundTime: 4, + nodeHeadwayStop: 2, + nodeHeadwayNonStop: 2, + sectionHeadway: 2, + }, + { + id: 2, + order: 2, + shortName: "IR", + name: "InterRegio", + colorRef: "IR", + fachCategory: HaltezeitFachCategories.B, + minimalTurnaroundTime: 4, + nodeHeadwayStop: 2, + nodeHeadwayNonStop: 2, + sectionHeadway: 2, + }, + { + id: 3, + order: 3, + shortName: "RE", + name: "RegioExpress", + colorRef: "RE", + fachCategory: HaltezeitFachCategories.C, + minimalTurnaroundTime: 4, + nodeHeadwayStop: 2, + nodeHeadwayNonStop: 2, + sectionHeadway: 2, + }, + { + id: 4, + order: 4, + shortName: "S", + name: "RegioUndSBahnverkehr", + colorRef: "S", + fachCategory: HaltezeitFachCategories.D, + minimalTurnaroundTime: 4, + nodeHeadwayStop: 2, + nodeHeadwayNonStop: 2, + sectionHeadway: 2, + }, + { + id: 5, + order: 5, + shortName: "GEX", + name: "GüterExpress", + colorRef: "GEX", + fachCategory: HaltezeitFachCategories.Uncategorized, + minimalTurnaroundTime: 4, + nodeHeadwayStop: 3, + nodeHeadwayNonStop: 3, + sectionHeadway: 3, + }, + { + id: 6, + order: 6, + shortName: "G", + name: "Güterverkehr", + colorRef: "G", + fachCategory: HaltezeitFachCategories.Uncategorized, + minimalTurnaroundTime: 4, + nodeHeadwayStop: 3, + nodeHeadwayNonStop: 3, + sectionHeadway: 3, + }, + ], + trainrunFrequencies: [ + { + id: 0, + order: 0, + frequency: 15, + offset: 0, + shortName: "15", + name: "verkehrt viertelstündlich", + linePatternRef: LinePatternRefs.Freq15, + }, + { + id: 1, + order: 0, + frequency: 20, + offset: 0, + shortName: "20", + name: "verkehrt im 20 Minuten Takt", + linePatternRef: LinePatternRefs.Freq20, + }, + { + id: 2, + order: 0, + frequency: 30, + offset: 0, + shortName: "30", + name: "verkehrt halbstündlich", + linePatternRef: LinePatternRefs.Freq30, + }, + { + id: 3, + order: 0, + frequency: 60, + offset: 0, + shortName: "60", + name: "verkehrt stündlich", + linePatternRef: LinePatternRefs.Freq60, + }, + { + id: 4, + order: 0, + frequency: 120, + offset: 0, + shortName: "120", + name: "verkehrt zweistündlich (gerade)", + linePatternRef: LinePatternRefs.Freq120, + }, + { + id: 5, + order: 0, + frequency: 120, + offset: 60, + shortName: "120+", + name: "verkehrt zweistündlich (ungerade)", + linePatternRef: LinePatternRefs.Freq120, + }, + ], + trainrunTimeCategories: [ + { + id: 0, + order: 0, + shortName: "7/24", + name: "verkehrt uneingeschränkt", + dayTimeInterval: [], + weekday: [1, 2, 3, 4, 5, 6, 7], + linePatternRef: LinePatternRefs.TimeCat7_24, + }, + { + id: 1, + order: 0, + shortName: "HVZ", + name: "verkehrt zur Hauptverkehrszeit", + dayTimeInterval: [ { - "id": 1, - "order": 0, - "shortName": "HVZ", - "name": "verkehrt zur Hauptverkehrszeit", - "dayTimeInterval": [ - { - "from": 360, - "to": 420 - }, - { - "from": 960, - "to": 1140 - } - ], - "weekday": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7 - ], - "linePatternRef": LinePatternRefs.TimeCatHVZ + from: 360, + to: 420, }, { - "id": 2, - "order": 0, - "shortName": "zeitweise", - "name": "verkehrt zeitweise", - "dayTimeInterval": [], - "weekday": [], - "linePatternRef": LinePatternRefs.TimeZeitweise - } - ], - "netzgrafikColors": [] + from: 960, + to: 1140, + }, + ], + weekday: [1, 2, 3, 4, 5, 6, 7], + linePatternRef: LinePatternRefs.TimeCatHVZ, + }, + { + id: 2, + order: 0, + shortName: "zeitweise", + name: "verkehrt zeitweise", + dayTimeInterval: [], + weekday: [], + linePatternRef: LinePatternRefs.TimeZeitweise, + }, + ], + netzgrafikColors: [], + }, + freeFloatingTexts: [], + labels: [], + labelGroups: [], + filterData: { + filterSettings: [], }, - "freeFloatingTexts": [], - "labels": [], - "labelGroups": [], - "filterData": { - "filterSettings": [] - } - }; + }; } } diff --git a/src/integration-testing/origin.destination.csv.test.spec.ts b/src/integration-testing/origin.destination.csv.test.spec.ts index d859c4f7..b3f3d467 100644 --- a/src/integration-testing/origin.destination.csv.test.spec.ts +++ b/src/integration-testing/origin.destination.csv.test.spec.ts @@ -11,7 +11,14 @@ import {StammdatenService} from "src/app/services/data/stammdaten.service"; import {TrainrunService} from "src/app/services/data/trainrun.service"; import {TrainrunSectionService} from "src/app/services/data/trainrunsection.service"; import {FilterService} from "src/app/services/ui/filter.service"; -import {buildEdges, computeNeighbors, computeShortestPaths, Edge, topoSort, Vertex} from "src/app/view/util/origin-destination-graph"; +import { + buildEdges, + computeNeighbors, + computeShortestPaths, + Edge, + topoSort, + Vertex, +} from "src/app/view/util/origin-destination-graph"; import {NetzgrafikUnitTestingOdMatrix} from "./netzgrafik.unit.testing.od.matrix"; describe("Origin Destination CSV Test", () => { @@ -28,7 +35,7 @@ describe("Origin Destination CSV Test", () => { let stammdatenService: StammdatenService = null; let noteService: NoteService = null; let netzgrafikColoringService: NetzgrafikColoringService = null; - + beforeEach(() => { resourceService = new ResourceService(); logPublishersService = new LogPublishersService(); @@ -78,29 +85,49 @@ describe("Origin Destination CSV Test", () => { const nodes = nodeService.getNodes(); const trainruns = trainrunService.getTrainruns(); const connectionPenalty = 5; - const timeLimit = 60*10; + const timeLimit = 60 * 10; const start = new Date().getTime(); - const edges = buildEdges(nodes, nodes, trainruns, connectionPenalty, trainrunService, timeLimit); + const edges = buildEdges( + nodes, + nodes, + trainruns, + connectionPenalty, + trainrunService, + timeLimit, + ); const neighbors = computeNeighbors(edges); const vertices = topoSort(neighbors); const res = new Map(); nodes.forEach((origin) => { - computeShortestPaths(origin.getId(), neighbors, vertices).forEach((value, key) => { - res.set([origin.getId(), key].join(","), value); - }); + computeShortestPaths(origin.getId(), neighbors, vertices).forEach( + (value, key) => { + res.set([origin.getId(), key].join(","), value); + }, + ); }); const end = new Date().getTime(); // Note: there may be some other equivalent solutions, depending on connections. // See https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/199 - expect(res).toEqual(new Map([ - ["11,13", [22, 1]], ["11,14", [6, 0]], ["11,12", [4, 0]], ["12,13", [2, 0]], ["12,14", [2, 0]], - ["12,11", [4, 0]], ["13,14", [29, 1]], ["13,11", [22, 1]], ["13,12", [2, 0]], ["14,13", [29, 1]], - ["14,11", [6, 0]], ["14,12", [2, 0]] - ])); + expect(res).toEqual( + new Map([ + ["11,13", [22, 1]], + ["11,14", [6, 0]], + ["11,12", [4, 0]], + ["12,13", [2, 0]], + ["12,14", [2, 0]], + ["12,11", [4, 0]], + ["13,14", [29, 1]], + ["13,11", [22, 1]], + ["13,12", [2, 0]], + ["14,13", [29, 1]], + ["14,11", [6, 0]], + ["14,12", [2, 0]], + ]), + ); // This should be reasonably fast, likely less than 10ms. expect(end - start).toBeLessThan(100); }); @@ -115,23 +142,37 @@ describe("Origin Destination CSV Test", () => { const odNodes = nodeService.getSelectedNodes(); const trainruns = trainrunService.getTrainruns(); const connectionPenalty = 5; - const timeLimit = 60*10; + const timeLimit = 60 * 10; - const edges = buildEdges(nodes, odNodes, trainruns, connectionPenalty, trainrunService, timeLimit); + const edges = buildEdges( + nodes, + odNodes, + trainruns, + connectionPenalty, + trainrunService, + timeLimit, + ); const neighbors = computeNeighbors(edges); const vertices = topoSort(neighbors); const res = new Map(); nodes.forEach((origin) => { - computeShortestPaths(origin.getId(), neighbors, vertices).forEach((value, key) => { - res.set([origin.getId(), key].join(","), value); - }); + computeShortestPaths(origin.getId(), neighbors, vertices).forEach( + (value, key) => { + res.set([origin.getId(), key].join(","), value); + }, + ); }); // Note: there may be some other equivalent solutions, depending on connections. // See https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/199 - expect(res).toEqual(new Map([["13,14", [29, 1]], ["14,13", [29, 1]]])); + expect(res).toEqual( + new Map([ + ["13,14", [29, 1]], + ["14,13", [29, 1]], + ]), + ); }); it("simple path unit test", () => { @@ -159,8 +200,12 @@ describe("Origin Destination CSV Test", () => { expect(topoVertices).toHaveSize(4); edges.forEach((edge) => { - const v1Index = topoVertices.findIndex((value, index, obj) => {return value === edge.v1;}); - const v2Index = topoVertices.findIndex((value, index, obj) => {return value === edge.v2;}); + const v1Index = topoVertices.findIndex((value, index, obj) => { + return value === edge.v1; + }); + const v2Index = topoVertices.findIndex((value, index, obj) => { + return value === edge.v2; + }); expect(v1Index).toBeLessThan(v2Index); }); @@ -190,7 +235,7 @@ describe("Origin Destination CSV Test", () => { const e6 = new Edge(v7, v8, 0); const e7 = new Edge(v8, v9, 10); // connection - const e8 = new Edge(v9, v4, 6+5); + const e8 = new Edge(v9, v4, 6 + 5); // convenience const v10 = new Vertex(1, false); const e9 = new Edge(v3, v10, 0); @@ -214,8 +259,12 @@ describe("Origin Destination CSV Test", () => { const topoVertices = topoSort(neighbors); expect(topoVertices).toHaveSize(11); edges.forEach((edge) => { - const v1Index = topoVertices.findIndex((value, index, obj) => {return value === edge.v1;}); - const v2Index = topoVertices.findIndex((value, index, obj) => {return value === edge.v2;}); + const v1Index = topoVertices.findIndex((value, index, obj) => { + return value === edge.v1; + }); + const v2Index = topoVertices.findIndex((value, index, obj) => { + return value === edge.v2; + }); expect(v1Index).toBeLessThan(v2Index); }); @@ -232,6 +281,6 @@ describe("Origin Destination CSV Test", () => { expect(distances3).toHaveSize(2); expect(distances3.get(1)).toEqual([10, 0]); // connection - expect(distances3.get(2)).toEqual([30+5, 1]); + expect(distances3.get(2)).toEqual([30 + 5, 1]); }); }); From d170955ecc466bfa9c10071927c63199eb7a86f7 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Tue, 22 Oct 2024 15:45:30 +0200 Subject: [PATCH 146/197] Update DATA_MODEL.md --- documentation/DATA_MODEL.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/documentation/DATA_MODEL.md b/documentation/DATA_MODEL.md index e00ab568..2d46e19b 100644 --- a/documentation/DATA_MODEL.md +++ b/documentation/DATA_MODEL.md @@ -41,6 +41,9 @@ trainrun routes and schedules. ### Technically orientated description +![image](https://github.com/user-attachments/assets/21fdb029-2a59-468a-ac93-11cf702536bd) + + Thus, the data model, consisting of TrainrunSection and nodes, forms a network of edges and nodes, similar to an undirected graph. The TrainrunSections represent the connections between the nodes and enable the representation and analysis of complex relationships in the model. From 3d9644fbe94ea0a11a5403b798ea5634481166fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Henriot?= <142150521+shenriotpro@users.noreply.github.com> Date: Thu, 24 Oct 2024 08:45:01 +0200 Subject: [PATCH 147/197] fix: fix O/D Matrix for unordered trainruns (#321) --- .../services/data/trainrun.service.spec.ts | 59 +-- src/app/services/data/trainrun.service.ts | 29 +- .../editor-tools-view.component.ts | 3 +- src/app/view/util/origin-destination-graph.ts | 44 +- .../netzgrafik.unit.testing.od.matrix.ts | 392 +++++++++++++++++- .../origin.destination.csv.test.spec.ts | 9 +- 6 files changed, 466 insertions(+), 70 deletions(-) diff --git a/src/app/services/data/trainrun.service.spec.ts b/src/app/services/data/trainrun.service.spec.ts index e4541b6b..01307136 100644 --- a/src/app/services/data/trainrun.service.spec.ts +++ b/src/app/services/data/trainrun.service.spec.ts @@ -344,18 +344,26 @@ describe("TrainrunService", () => { trainrunService.splitTrainrunIntoTwoParts(n.getTransition(0)); const trainrunSections2 = - trainrunSectionService.getAllTrainrunSectionsForTrainrun(ts0.getTrainrunId()); + trainrunSectionService.getAllTrainrunSectionsForTrainrun( + ts0.getTrainrunId(), + ); expect(trainrunSections2.length).toBe(1); const trainrunSections3 = - trainrunSectionService.getAllTrainrunSectionsForTrainrun(ts1.getTrainrunId()); + trainrunSectionService.getAllTrainrunSectionsForTrainrun( + ts1.getTrainrunId(), + ); expect(trainrunSections3.length).toBe(1); - trainrunService.combineTwoTrainruns(n, + trainrunService.combineTwoTrainruns( + n, n.getPortOfTrainrunSection(0), - n.getPortOfTrainrunSection(1)); + n.getPortOfTrainrunSection(1), + ); const trainrunSections4 = - trainrunSectionService.getAllTrainrunSectionsForTrainrun(ts1.getTrainrunId()); + trainrunSectionService.getAllTrainrunSectionsForTrainrun( + ts1.getTrainrunId(), + ); expect(trainrunSections4.length).toBe(2); }); @@ -366,35 +374,34 @@ describe("TrainrunService", () => { const iterators = trainrunService.getRootIterators(); - const iterators0 = iterators.get(0); // trainrun 0: 0 -> 1 -> 2 - // 1 root: 0 - expect(iterators0.length).toBe(1); - expect(iterators0[0].current().trainrunSection.getSourceNodeId()).toBe(0); + // root: 0 + expect(iterators.get(0).current().trainrunSection.getSourceNodeId()).toBe( + 0, + ); - const iterators1 = iterators.get(1); // trainrun 1: 1 -> 2 - // 1 root: 1 - expect(iterators1.length).toBe(1); - expect(iterators1[0].current().trainrunSection.getSourceNodeId()).toBe(1); + // root: 1 + expect(iterators.get(1).current().trainrunSection.getSourceNodeId()).toBe( + 1, + ); - const iterators2 = iterators.get(2); // trainrun 2: 0 -> 1 -> 2 -> 3 - // 1 root: 0 - expect(iterators2.length).toBe(1); - expect(iterators2[0].current().trainrunSection.getSourceNodeId()).toBe(0); + // root: 0 + expect(iterators.get(2).current().trainrunSection.getSourceNodeId()).toBe( + 0, + ); - const iterators3 = iterators.get(3); // trainrun 3: 4 -> 2 - // 1 root: 4 - expect(iterators3.length).toBe(1); - expect(iterators3[0].current().trainrunSection.getSourceNodeId()).toBe(4); + // root: 4 + expect(iterators.get(3).current().trainrunSection.getSourceNodeId()).toBe( + 4, + ); - const iterators4 = iterators.get(4); // trainrun 4: 4 -> 2 - // 1 root: 4 - expect(iterators4.length).toBe(1); - expect(iterators4[0].current().trainrunSection.getSourceNodeId()).toBe(4); + // root: 4 + expect(iterators.get(4).current().trainrunSection.getSourceNodeId()).toBe( + 4, + ); }); - }); diff --git a/src/app/services/data/trainrun.service.ts b/src/app/services/data/trainrun.service.ts index dd3463be..229f75ef 100644 --- a/src/app/services/data/trainrun.service.ts +++ b/src/app/services/data/trainrun.service.ts @@ -773,18 +773,29 @@ export class TrainrunService { return new NonStopTrainrunIterator(this.logService, node, trainrunSection); } - // For each trainrun, get iterators from the source (trainruns may be split). - public getRootIterators(): Map { + // For each trainrun, get iterator from the smallest consecutiveTime. + public getRootIterators(): Map { const trainrunSections = this.trainrunSectionService.getTrainrunSections(); - const iterators = new Map(); + const iterators = new Map(); + const consecutiveTimes = new Map(); trainrunSections.forEach((ts) => { - const node = ts.getSourceNode(); + const trainrunId = ts.getTrainrunId(); + let node = ts.getSourceNode(); if (node.isEndNode(ts)) { - const it = iterators.get(ts.getTrainrunId()); - if (it === undefined) { - iterators.set(ts.getTrainrunId(), [this.getIterator(node, ts)]); - } else { - it.push(this.getIterator(node, ts)); + const it = iterators.get(trainrunId); + const consecutiveTime = ts.getSourceDepartureDto().consecutiveTime; + if (it === undefined || consecutiveTimes.get(trainrunId) > consecutiveTime) { + iterators.set(trainrunId, this.getIterator(node, ts)); + consecutiveTimes.set(trainrunId, consecutiveTime); + } + } + node = ts.getTargetNode(); + if (node.isEndNode(ts)) { + const it = iterators.get(trainrunId); + const consecutiveTime = ts.getTargetDepartureDto().consecutiveTime; + if (it === undefined || consecutiveTimes.get(trainrunId) > consecutiveTime) { + iterators.set(trainrunId, this.getIterator(node, ts)); + consecutiveTimes.set(trainrunId, consecutiveTime); } } }); diff --git a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts index 53b6d352..3d0adce2 100644 --- a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts +++ b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts @@ -497,8 +497,7 @@ export class EditorToolsViewComponent { return this.buildCSVString(headers, rows); } - // Split trainruns are not supported at the moment: - // https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/285 + // TODO: this may be incorrect for trainruns going through the same node several times. private convertToOriginDestinationCSV(): string { // Duration of the schedule to consider (in minutes). // TODO: ideally this would be 24 hours, but performance is a concern. diff --git a/src/app/view/util/origin-destination-graph.ts b/src/app/view/util/origin-destination-graph.ts index 29f26f52..9787d20d 100644 --- a/src/app/view/util/origin-destination-graph.ts +++ b/src/app/view/util/origin-destination-graph.ts @@ -220,29 +220,26 @@ const buildSectionEdges = ( const edges = []; const its = trainrunService.getRootIterators(); trainruns.forEach((trainrun) => { - const tsIterators = its.get(trainrun.getId()); - if (tsIterators === undefined) { + const tsIterator = its.get(trainrun.getId()); + if (tsIterator === undefined) { console.log("Ignoring trainrun (no root found): ", trainrun.getId()); return; } - tsIterators.forEach((tsIterator) => { - edges.push( - ...buildSectionEdgesFromIterator(tsIterator, false, timeLimit), - ); - // Don't forget the reverse direction. - const ts = tsIterator.current().trainrunSection; - const nextIterator = trainrunService.getIterator(ts.getTargetNode(), ts); - edges.push( - ...buildSectionEdgesFromIterator(nextIterator, true, timeLimit), - ); - }); + edges.push(...buildSectionEdgesFromIterator(tsIterator, false, timeLimit)); + // Don't forget the reverse direction. + const ts = tsIterator.current().trainrunSection; + const nextIterator = trainrunService.getIterator( + tsIterator.current().node, + ts, + ); + edges.push(...buildSectionEdgesFromIterator(nextIterator, true, timeLimit)); }); return edges; }; const buildSectionEdgesFromIterator = ( tsIterator: TrainrunIterator, - reverse: boolean, + reverseIterator: boolean, timeLimit: number, ): Edge[] => { const edges = []; @@ -251,14 +248,18 @@ const buildSectionEdgesFromIterator = ( while (tsIterator.hasNext()) { tsIterator.next(); const ts = tsIterator.current().trainrunSection; - const trainrunId = reverse ? -ts.getTrainrunId() : ts.getTrainrunId(); - const v1Time = reverse + const trainrunId = reverseIterator + ? -ts.getTrainrunId() + : ts.getTrainrunId(); + const reverseSection = + tsIterator.current().node.getId() !== ts.getTargetNodeId(); + const v1Time = reverseSection ? ts.getTargetDepartureDto().consecutiveTime : ts.getSourceDepartureDto().consecutiveTime; - const v1Node = reverse ? ts.getTargetNodeId() : ts.getSourceNodeId(); + const v1Node = reverseSection ? ts.getTargetNodeId() : ts.getSourceNodeId(); // If we don't stop here, we need to remember where we started. if ( - reverse + reverseSection ? ts.getSourceNode().isNonStop(ts) : ts.getTargetNode().isNonStop(ts) ) { @@ -269,16 +270,15 @@ const buildSectionEdgesFromIterator = ( continue; } let v1 = new Vertex(v1Node, true, v1Time, trainrunId); - let nonStop = false; + // If we didn't stop previously, we need to use the stored start. if (nonStopV1Time !== -1) { v1 = new Vertex(nonStopV1Node, true, nonStopV1Time, trainrunId); nonStopV1Time = -1; - nonStop = true; } - const v2Time = reverse + const v2Time = reverseSection ? ts.getSourceArrivalDto().consecutiveTime : ts.getTargetArrivalDto().consecutiveTime; - const v2Node = reverse ? ts.getSourceNodeId() : ts.getTargetNodeId(); + const v2Node = reverseSection ? ts.getSourceNodeId() : ts.getTargetNodeId(); const v2 = new Vertex(v2Node, false, v2Time, trainrunId); for (let i = 0; i * ts.getTrainrun().getFrequency() < timeLimit; i++) { diff --git a/src/integration-testing/netzgrafik.unit.testing.od.matrix.ts b/src/integration-testing/netzgrafik.unit.testing.od.matrix.ts index f46158cb..1018d0e4 100644 --- a/src/integration-testing/netzgrafik.unit.testing.od.matrix.ts +++ b/src/integration-testing/netzgrafik.unit.testing.od.matrix.ts @@ -11,7 +11,7 @@ export class NetzgrafikUnitTestingOdMatrix { { id: 11, betriebspunktName: "C", - fullName: "C", + fullName: "Neuer Knoten", positionX: 1536, positionY: 864, ports: [ @@ -85,7 +85,7 @@ export class NetzgrafikUnitTestingOdMatrix { { id: 12, betriebspunktName: "A", - fullName: "A", + fullName: "Neuer Knoten", positionX: 1120, positionY: 672, ports: [ @@ -159,7 +159,7 @@ export class NetzgrafikUnitTestingOdMatrix { { id: 13, betriebspunktName: "D", - fullName: "D", + fullName: "Neuer Knoten", positionX: 1088, positionY: 1088, ports: [ @@ -214,7 +214,7 @@ export class NetzgrafikUnitTestingOdMatrix { { id: 14, betriebspunktName: "B", - fullName: "B", + fullName: "Neuer Knoten", positionX: 800, positionY: 864, ports: [ @@ -266,6 +266,166 @@ export class NetzgrafikUnitTestingOdMatrix { warnings: null, labelIds: [], }, + { + id: 15, + betriebspunktName: "E", + fullName: "New node", + positionX: 1472, + positionY: 1248, + ports: [ + { + id: 24, + trainrunSectionId: 12, + positionIndex: 0, + positionAlignment: 3, + }, + ], + transitions: [], + connections: [], + resourceId: 16, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitIPV: { + haltezeit: 3, + no_halt: false, + }, + HaltezeitA: { + haltezeit: 2, + no_halt: false, + }, + HaltezeitB: { + haltezeit: 2, + no_halt: false, + }, + HaltezeitC: { + haltezeit: 1, + no_halt: false, + }, + HaltezeitD: { + haltezeit: 1, + no_halt: false, + }, + HaltezeitUncategorized: { + haltezeit: 0, + no_halt: true, + }, + }, + symmetryAxis: null, + warnings: null, + labelIds: [], + }, + { + id: 16, + betriebspunktName: "F", + fullName: "New node", + positionX: 1696, + positionY: 1248, + ports: [ + { + id: 23, + trainrunSectionId: 12, + positionIndex: 0, + positionAlignment: 2, + }, + { + id: 25, + trainrunSectionId: 13, + positionIndex: 0, + positionAlignment: 3, + }, + ], + transitions: [ + { + id: 5, + port1Id: 23, + port2Id: 25, + isNonStopTransit: false, + }, + ], + connections: [], + resourceId: 17, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitIPV: { + haltezeit: 3, + no_halt: false, + }, + HaltezeitA: { + haltezeit: 2, + no_halt: false, + }, + HaltezeitB: { + haltezeit: 2, + no_halt: false, + }, + HaltezeitC: { + haltezeit: 1, + no_halt: false, + }, + HaltezeitD: { + haltezeit: 1, + no_halt: false, + }, + HaltezeitUncategorized: { + haltezeit: 0, + no_halt: true, + }, + }, + symmetryAxis: null, + warnings: null, + labelIds: [], + }, + { + id: 17, + betriebspunktName: "G", + fullName: "New node", + positionX: 1920, + positionY: 1248, + ports: [ + { + id: 26, + trainrunSectionId: 13, + positionIndex: 0, + positionAlignment: 2, + }, + ], + transitions: [], + connections: [], + resourceId: 18, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitIPV: { + haltezeit: 3, + no_halt: false, + }, + HaltezeitA: { + haltezeit: 2, + no_halt: false, + }, + HaltezeitB: { + haltezeit: 2, + no_halt: false, + }, + HaltezeitC: { + haltezeit: 1, + no_halt: false, + }, + HaltezeitD: { + haltezeit: 1, + no_halt: false, + }, + HaltezeitUncategorized: { + haltezeit: 0, + no_halt: true, + }, + }, + symmetryAxis: null, + warnings: null, + labelIds: [], + }, ], trainrunSections: [ { @@ -850,6 +1010,200 @@ export class NetzgrafikUnitTestingOdMatrix { }, warnings: null, }, + { + id: 12, + sourceNodeId: 16, + sourcePortId: 23, + targetNodeId: 15, + targetPortId: 24, + travelTime: { + time: 1, + consecutiveTime: 1, + lock: true, + warning: null, + timeFormatter: null, + }, + sourceDeparture: { + time: 0, + consecutiveTime: 120, + lock: false, + warning: null, + timeFormatter: null, + }, + sourceArrival: { + time: 0, + consecutiveTime: 60, + lock: false, + warning: null, + timeFormatter: null, + }, + targetDeparture: { + time: 59, + consecutiveTime: 59, + lock: false, + warning: null, + timeFormatter: null, + }, + targetArrival: { + time: 1, + consecutiveTime: 121, + lock: false, + warning: null, + timeFormatter: null, + }, + numberOfStops: 0, + trainrunId: 8, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1694, + y: 1264, + }, + { + x: 1630, + y: 1264, + }, + { + x: 1634, + y: 1264, + }, + { + x: 1570, + y: 1264, + }, + ], + textPositions: { + "0": { + x: 1676, + y: 1252, + }, + "1": { + x: 1648, + y: 1276, + }, + "2": { + x: 1588, + y: 1276, + }, + "3": { + x: 1616, + y: 1252, + }, + "4": { + x: 1632, + y: 1252, + }, + "5": { + x: 1632, + y: 1252, + }, + "6": { + x: 1632, + y: 1276, + }, + }, + }, + warnings: null, + }, + { + id: 13, + sourceNodeId: 16, + sourcePortId: 25, + targetNodeId: 17, + targetPortId: 26, + travelTime: { + time: 1, + consecutiveTime: 1, + lock: true, + warning: null, + timeFormatter: null, + }, + sourceDeparture: { + time: 2, + consecutiveTime: 62, + lock: false, + warning: null, + timeFormatter: null, + }, + sourceArrival: { + time: 58, + consecutiveTime: 118, + lock: false, + warning: null, + timeFormatter: null, + }, + targetDeparture: { + time: 57, + consecutiveTime: 117, + lock: false, + warning: null, + timeFormatter: null, + }, + targetArrival: { + time: 3, + consecutiveTime: 63, + lock: false, + warning: null, + timeFormatter: null, + }, + numberOfStops: 0, + trainrunId: 8, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1794, + y: 1264, + }, + { + x: 1858, + y: 1264, + }, + { + x: 1854, + y: 1264, + }, + { + x: 1918, + y: 1264, + }, + ], + textPositions: { + "0": { + x: 1812, + y: 1276, + }, + "1": { + x: 1840, + y: 1252, + }, + "2": { + x: 1900, + y: 1252, + }, + "3": { + x: 1872, + y: 1276, + }, + "4": { + x: 1856, + y: 1252, + }, + "5": { + x: 1856, + y: 1252, + }, + "6": { + x: 1856, + y: 1276, + }, + }, + }, + warnings: null, + }, ], trainruns: [ { @@ -884,6 +1238,14 @@ export class NetzgrafikUnitTestingOdMatrix { trainrunTimeCategoryId: 0, labelIds: [], }, + { + id: 8, + name: "X", + categoryId: 1, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [], + }, ], resources: [ { @@ -946,13 +1308,20 @@ export class NetzgrafikUnitTestingOdMatrix { id: 15, capacity: 2, }, + { + id: 16, + capacity: 2, + }, + { + id: 17, + capacity: 2, + }, + { + id: 18, + capacity: 2, + }, ], metadata: { - analyticsSettings: { - originDestinationSettings: { - connectionPenalty: 5, - }, - }, trainrunCategories: [ { id: 0, @@ -1134,6 +1503,11 @@ export class NetzgrafikUnitTestingOdMatrix { }, ], netzgrafikColors: [], + analyticsSettings: { + originDestinationSettings: { + connectionPenalty: 5, + }, + }, }, freeFloatingTexts: [], labels: [], diff --git a/src/integration-testing/origin.destination.csv.test.spec.ts b/src/integration-testing/origin.destination.csv.test.spec.ts index b3f3d467..e02e3a71 100644 --- a/src/integration-testing/origin.destination.csv.test.spec.ts +++ b/src/integration-testing/origin.destination.csv.test.spec.ts @@ -110,7 +110,6 @@ describe("Origin Destination CSV Test", () => { }); const end = new Date().getTime(); - // Note: there may be some other equivalent solutions, depending on connections. // See https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/199 expect(res).toEqual( new Map([ @@ -126,6 +125,13 @@ describe("Origin Destination CSV Test", () => { ["14,13", [29, 1]], ["14,11", [6, 0]], ["14,12", [2, 0]], + // Making sure we traverse E <- F -> G correctly. + ["15,17", [4, 0]], + ["15,16", [1, 0]], + ["16,15", [1, 0]], + ["16,17", [1, 0]], + ["17,15", [4, 0]], + ["17,16", [1, 0]], ]), ); // This should be reasonably fast, likely less than 10ms. @@ -165,7 +171,6 @@ describe("Origin Destination CSV Test", () => { ); }); - // Note: there may be some other equivalent solutions, depending on connections. // See https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/199 expect(res).toEqual( new Map([ From 36ea0b686e3c3d51a5c297e2a1d46c7a873b531a Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 24 Oct 2024 09:55:35 +0200 Subject: [PATCH 148/197] The JSON was integrated as a string and then parsed within the code. This is not well integrated because changes to properties will not be detected by the compiler. Therefore, it was changed and the bug was fixed. (#323) --- .../netzgrafik.demo.standalone.github.ts | 26505 +++++++++++++++- 1 file changed, 26503 insertions(+), 2 deletions(-) diff --git a/src/app/sample-netzgrafik/netzgrafik.demo.standalone.github.ts b/src/app/sample-netzgrafik/netzgrafik.demo.standalone.github.ts index 28abac5c..6a09ce19 100644 --- a/src/app/sample-netzgrafik/netzgrafik.demo.standalone.github.ts +++ b/src/app/sample-netzgrafik/netzgrafik.demo.standalone.github.ts @@ -1,10 +1,26511 @@ import { + HaltezeitFachCategories, + LinePatternRefs, NetzgrafikDto, } from "../data-structures/business.data.structures"; export class NetzgrafikDemoStandaloneGithub { static getNetzgrafikDemoStandaloneGithub(): NetzgrafikDto { - return JSON.parse('{"nodes":[{"id":128,"betriebspunktName":"Lausanne","fullName":"Lausanne","positionX":-3072,"positionY":544,"ports":[{"id":1207,"trainrunSectionId":596,"positionIndex":0,"positionAlignment":2},{"id":1187,"trainrunSectionId":586,"positionIndex":1,"positionAlignment":2},{"id":1382,"trainrunSectionId":683,"positionIndex":0,"positionAlignment":3},{"id":1380,"trainrunSectionId":682,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":345,"port1Id":1187,"port2Id":1380,"isNonStopTransit":false},{"id":347,"port1Id":1207,"port2Id":1382,"isNonStopTransit":false}],"connections":[],"resourceId":152,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":129,"betriebspunktName":"Bern","fullName":"Bern","positionX":-2144,"positionY":128,"ports":[{"id":1328,"trainrunSectionId":656,"positionIndex":0,"positionAlignment":1},{"id":1311,"trainrunSectionId":648,"positionIndex":1,"positionAlignment":1},{"id":1313,"trainrunSectionId":649,"positionIndex":2,"positionAlignment":1},{"id":1339,"trainrunSectionId":662,"positionIndex":3,"positionAlignment":1},{"id":1205,"trainrunSectionId":595,"positionIndex":0,"positionAlignment":2},{"id":1109,"trainrunSectionId":547,"positionIndex":1,"positionAlignment":2},{"id":1440,"trainrunSectionId":712,"positionIndex":0,"positionAlignment":3},{"id":1329,"trainrunSectionId":657,"positionIndex":1,"positionAlignment":3},{"id":1436,"trainrunSectionId":710,"positionIndex":2,"positionAlignment":3},{"id":1434,"trainrunSectionId":709,"positionIndex":3,"positionAlignment":3},{"id":1432,"trainrunSectionId":708,"positionIndex":4,"positionAlignment":3},{"id":1430,"trainrunSectionId":707,"positionIndex":5,"positionAlignment":3},{"id":1428,"trainrunSectionId":706,"positionIndex":6,"positionAlignment":3}],"transitions":[{"id":315,"port1Id":1328,"port2Id":1329,"isNonStopTransit":false},{"id":376,"port1Id":1109,"port2Id":1430,"isNonStopTransit":false},{"id":378,"port1Id":1339,"port2Id":1432,"isNonStopTransit":false},{"id":380,"port1Id":1313,"port2Id":1434,"isNonStopTransit":false},{"id":382,"port1Id":1311,"port2Id":1436,"isNonStopTransit":false},{"id":386,"port1Id":1205,"port2Id":1440,"isNonStopTransit":false}],"connections":[],"resourceId":153,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":130,"betriebspunktName":"Biel","fullName":"Biel","positionX":-2528,"positionY":-32,"ports":[{"id":1183,"trainrunSectionId":584,"positionIndex":0,"positionAlignment":2},{"id":1418,"trainrunSectionId":701,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":366,"port1Id":1183,"port2Id":1418,"isNonStopTransit":false}],"connections":[],"resourceId":154,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":131,"betriebspunktName":"Interlaken ","fullName":"Interlaken Ost","positionX":-1088,"positionY":928,"ports":[{"id":1318,"trainrunSectionId":651,"positionIndex":0,"positionAlignment":2},{"id":1344,"trainrunSectionId":664,"positionIndex":1,"positionAlignment":2}],"transitions":[],"connections":[],"resourceId":155,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":132,"betriebspunktName":"Visp","fullName":"Visp","positionX":-2144,"positionY":1440,"ports":[{"id":1323,"trainrunSectionId":654,"positionIndex":0,"positionAlignment":0},{"id":1322,"trainrunSectionId":653,"positionIndex":1,"positionAlignment":0}],"transitions":[],"connections":[],"resourceId":156,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":133,"betriebspunktName":"Olten","fullName":"Olten","positionX":64,"positionY":96,"ports":[{"id":1047,"trainrunSectionId":516,"positionIndex":0,"positionAlignment":0},{"id":1331,"trainrunSectionId":658,"positionIndex":1,"positionAlignment":0},{"id":1308,"trainrunSectionId":646,"positionIndex":2,"positionAlignment":0},{"id":1371,"trainrunSectionId":678,"positionIndex":3,"positionAlignment":0},{"id":1131,"trainrunSectionId":558,"positionIndex":4,"positionAlignment":0},{"id":1117,"trainrunSectionId":551,"positionIndex":5,"positionAlignment":0},{"id":1046,"trainrunSectionId":515,"positionIndex":0,"positionAlignment":1},{"id":1370,"trainrunSectionId":677,"positionIndex":1,"positionAlignment":1},{"id":1130,"trainrunSectionId":557,"positionIndex":2,"positionAlignment":1},{"id":1116,"trainrunSectionId":550,"positionIndex":3,"positionAlignment":1},{"id":1181,"trainrunSectionId":583,"positionIndex":0,"positionAlignment":2},{"id":1203,"trainrunSectionId":594,"positionIndex":1,"positionAlignment":2},{"id":1394,"trainrunSectionId":689,"positionIndex":2,"positionAlignment":2},{"id":1309,"trainrunSectionId":647,"positionIndex":3,"positionAlignment":2},{"id":1225,"trainrunSectionId":605,"positionIndex":4,"positionAlignment":2},{"id":1241,"trainrunSectionId":613,"positionIndex":5,"positionAlignment":2},{"id":1165,"trainrunSectionId":575,"positionIndex":6,"positionAlignment":2},{"id":1202,"trainrunSectionId":593,"positionIndex":0,"positionAlignment":3},{"id":1180,"trainrunSectionId":582,"positionIndex":1,"positionAlignment":3},{"id":1224,"trainrunSectionId":604,"positionIndex":2,"positionAlignment":3},{"id":1240,"trainrunSectionId":612,"positionIndex":3,"positionAlignment":3},{"id":1164,"trainrunSectionId":574,"positionIndex":4,"positionAlignment":3}],"transitions":[{"id":210,"port1Id":1047,"port2Id":1046,"isNonStopTransit":false},{"id":236,"port1Id":1117,"port2Id":1116,"isNonStopTransit":false},{"id":242,"port1Id":1131,"port2Id":1130,"isNonStopTransit":false},{"id":253,"port1Id":1165,"port2Id":1164,"isNonStopTransit":false},{"id":259,"port1Id":1181,"port2Id":1180,"isNonStopTransit":false},{"id":264,"port1Id":1203,"port2Id":1202,"isNonStopTransit":true},{"id":270,"port1Id":1225,"port2Id":1224,"isNonStopTransit":true},{"id":276,"port1Id":1241,"port2Id":1240,"isNonStopTransit":true},{"id":308,"port1Id":1308,"port2Id":1309,"isNonStopTransit":false},{"id":340,"port1Id":1371,"port2Id":1370,"isNonStopTransit":false},{"id":353,"port1Id":1331,"port2Id":1394,"isNonStopTransit":false}],"connections":[],"resourceId":157,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":134,"betriebspunktName":"Basel","fullName":"Basel","positionX":64,"positionY":-1888,"ports":[{"id":1054,"trainrunSectionId":519,"positionIndex":0,"positionAlignment":1},{"id":1416,"trainrunSectionId":700,"positionIndex":1,"positionAlignment":1},{"id":1277,"trainrunSectionId":631,"positionIndex":2,"positionAlignment":1},{"id":1338,"trainrunSectionId":661,"positionIndex":3,"positionAlignment":1},{"id":1301,"trainrunSectionId":643,"positionIndex":4,"positionAlignment":1},{"id":1378,"trainrunSectionId":681,"positionIndex":5,"positionAlignment":1},{"id":1138,"trainrunSectionId":561,"positionIndex":6,"positionAlignment":1},{"id":1124,"trainrunSectionId":554,"positionIndex":7,"positionAlignment":1},{"id":1267,"trainrunSectionId":626,"positionIndex":0,"positionAlignment":3}],"transitions":[],"connections":[],"resourceId":158,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":135,"betriebspunktName":"Zürich","fullName":"Zürich","positionX":2656,"positionY":32,"ports":[{"id":1255,"trainrunSectionId":620,"positionIndex":0,"positionAlignment":0},{"id":1254,"trainrunSectionId":619,"positionIndex":1,"positionAlignment":0},{"id":1360,"trainrunSectionId":672,"positionIndex":0,"positionAlignment":1},{"id":1149,"trainrunSectionId":567,"positionIndex":1,"positionAlignment":1},{"id":1153,"trainrunSectionId":569,"positionIndex":2,"positionAlignment":1},{"id":1358,"trainrunSectionId":671,"positionIndex":3,"positionAlignment":1},{"id":1356,"trainrunSectionId":670,"positionIndex":4,"positionAlignment":1},{"id":1354,"trainrunSectionId":669,"positionIndex":5,"positionAlignment":1},{"id":1195,"trainrunSectionId":590,"positionIndex":0,"positionAlignment":2},{"id":1401,"trainrunSectionId":693,"positionIndex":1,"positionAlignment":2},{"id":1292,"trainrunSectionId":638,"positionIndex":2,"positionAlignment":2},{"id":1173,"trainrunSectionId":579,"positionIndex":3,"positionAlignment":2},{"id":1217,"trainrunSectionId":601,"positionIndex":4,"positionAlignment":2},{"id":1233,"trainrunSectionId":609,"positionIndex":5,"positionAlignment":2},{"id":1157,"trainrunSectionId":571,"positionIndex":6,"positionAlignment":2},{"id":1276,"trainrunSectionId":630,"positionIndex":7,"positionAlignment":2},{"id":1300,"trainrunSectionId":642,"positionIndex":8,"positionAlignment":2},{"id":1191,"trainrunSectionId":588,"positionIndex":0,"positionAlignment":3},{"id":1172,"trainrunSectionId":578,"positionIndex":1,"positionAlignment":3},{"id":1213,"trainrunSectionId":599,"positionIndex":2,"positionAlignment":3},{"id":1229,"trainrunSectionId":607,"positionIndex":3,"positionAlignment":3},{"id":1139,"trainrunSectionId":562,"positionIndex":4,"positionAlignment":3},{"id":1245,"trainrunSectionId":615,"positionIndex":5,"positionAlignment":3}],"transitions":[{"id":250,"port1Id":1153,"port2Id":1157,"isNonStopTransit":false},{"id":256,"port1Id":1173,"port2Id":1172,"isNonStopTransit":false},{"id":261,"port1Id":1195,"port2Id":1191,"isNonStopTransit":false},{"id":267,"port1Id":1217,"port2Id":1213,"isNonStopTransit":false},{"id":273,"port1Id":1233,"port2Id":1229,"isNonStopTransit":false},{"id":329,"port1Id":1354,"port2Id":1245,"isNonStopTransit":false},{"id":357,"port1Id":1149,"port2Id":1401,"isNonStopTransit":false}],"connections":[],"resourceId":159,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":136,"betriebspunktName":"Bellinz.","fullName":"Bellinzona","positionX":2592,"positionY":3232,"ports":[{"id":1059,"trainrunSectionId":522,"positionIndex":0,"positionAlignment":0},{"id":1035,"trainrunSectionId":510,"positionIndex":1,"positionAlignment":0},{"id":1071,"trainrunSectionId":528,"positionIndex":2,"positionAlignment":0},{"id":1083,"trainrunSectionId":534,"positionIndex":3,"positionAlignment":0},{"id":1058,"trainrunSectionId":521,"positionIndex":0,"positionAlignment":1},{"id":1034,"trainrunSectionId":509,"positionIndex":1,"positionAlignment":1},{"id":1070,"trainrunSectionId":527,"positionIndex":0,"positionAlignment":2},{"id":1082,"trainrunSectionId":533,"positionIndex":1,"positionAlignment":2}],"transitions":[{"id":206,"port1Id":1035,"port2Id":1034,"isNonStopTransit":false},{"id":216,"port1Id":1059,"port2Id":1058,"isNonStopTransit":false},{"id":221,"port1Id":1071,"port2Id":1070,"isNonStopTransit":false},{"id":226,"port1Id":1083,"port2Id":1082,"isNonStopTransit":false}],"connections":[],"resourceId":160,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":137,"betriebspunktName":"St. Gallen","fullName":"Sankt Gallen","positionX":4640,"positionY":96,"ports":[{"id":1145,"trainrunSectionId":565,"positionIndex":0,"positionAlignment":1},{"id":1212,"trainrunSectionId":598,"positionIndex":0,"positionAlignment":2},{"id":1167,"trainrunSectionId":576,"positionIndex":1,"positionAlignment":2},{"id":1144,"trainrunSectionId":564,"positionIndex":2,"positionAlignment":2},{"id":1419,"trainrunSectionId":702,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":248,"port1Id":1145,"port2Id":1144,"isNonStopTransit":false},{"id":367,"port1Id":1167,"port2Id":1419,"isNonStopTransit":false}],"connections":[],"resourceId":161,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":138,"betriebspunktName":"Schaffh.","fullName":"Schaffhausen","positionX":2624,"positionY":-1120,"ports":[{"id":1256,"trainrunSectionId":620,"positionIndex":0,"positionAlignment":1},{"id":1251,"trainrunSectionId":618,"positionIndex":1,"positionAlignment":1}],"transitions":[],"connections":[],"resourceId":162,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":139,"betriebspunktName":"Konstanz","fullName":"Konstanz","positionX":4256,"positionY":-416,"ports":[{"id":1250,"trainrunSectionId":617,"positionIndex":0,"positionAlignment":1}],"transitions":[],"connections":[],"resourceId":163,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":140,"betriebspunktName":"Sargans","fullName":"Sargans","positionX":4640,"positionY":1184,"ports":[{"id":1146,"trainrunSectionId":565,"positionIndex":0,"positionAlignment":0},{"id":1151,"trainrunSectionId":568,"positionIndex":0,"positionAlignment":1},{"id":1147,"trainrunSectionId":566,"positionIndex":1,"positionAlignment":1},{"id":1155,"trainrunSectionId":570,"positionIndex":2,"positionAlignment":1},{"id":1362,"trainrunSectionId":673,"positionIndex":0,"positionAlignment":2},{"id":1364,"trainrunSectionId":674,"positionIndex":1,"positionAlignment":2}],"transitions":[{"id":249,"port1Id":1146,"port2Id":1147,"isNonStopTransit":false},{"id":334,"port1Id":1151,"port2Id":1362,"isNonStopTransit":false},{"id":336,"port1Id":1155,"port2Id":1364,"isNonStopTransit":false}],"connections":[],"resourceId":164,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":141,"betriebspunktName":"Sursee","fullName":"Sursee","positionX":64,"positionY":1184,"ports":[{"id":1043,"trainrunSectionId":514,"positionIndex":0,"positionAlignment":0},{"id":1105,"trainrunSectionId":545,"positionIndex":1,"positionAlignment":0},{"id":1367,"trainrunSectionId":676,"positionIndex":2,"positionAlignment":0},{"id":1127,"trainrunSectionId":556,"positionIndex":3,"positionAlignment":0},{"id":1113,"trainrunSectionId":549,"positionIndex":4,"positionAlignment":0},{"id":1042,"trainrunSectionId":513,"positionIndex":0,"positionAlignment":1},{"id":1104,"trainrunSectionId":544,"positionIndex":1,"positionAlignment":1},{"id":1366,"trainrunSectionId":675,"positionIndex":2,"positionAlignment":1},{"id":1126,"trainrunSectionId":555,"positionIndex":3,"positionAlignment":1},{"id":1112,"trainrunSectionId":548,"positionIndex":4,"positionAlignment":1}],"transitions":[{"id":208,"port1Id":1043,"port2Id":1042,"isNonStopTransit":true},{"id":232,"port1Id":1105,"port2Id":1104,"isNonStopTransit":false},{"id":234,"port1Id":1113,"port2Id":1112,"isNonStopTransit":false},{"id":240,"port1Id":1127,"port2Id":1126,"isNonStopTransit":true},{"id":338,"port1Id":1367,"port2Id":1366,"isNonStopTransit":true}],"connections":[],"resourceId":165,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":142,"betriebspunktName":"Luzern","fullName":"Luzern","positionX":64,"positionY":1728,"ports":[{"id":1041,"trainrunSectionId":513,"positionIndex":0,"positionAlignment":0},{"id":1103,"trainrunSectionId":544,"positionIndex":1,"positionAlignment":0},{"id":1365,"trainrunSectionId":675,"positionIndex":2,"positionAlignment":0},{"id":1125,"trainrunSectionId":555,"positionIndex":3,"positionAlignment":0},{"id":1111,"trainrunSectionId":548,"positionIndex":4,"positionAlignment":0},{"id":1352,"trainrunSectionId":668,"positionIndex":0,"positionAlignment":3},{"id":1350,"trainrunSectionId":667,"positionIndex":1,"positionAlignment":3},{"id":1099,"trainrunSectionId":542,"positionIndex":2,"positionAlignment":3},{"id":1095,"trainrunSectionId":540,"positionIndex":3,"positionAlignment":3}],"transitions":[{"id":327,"port1Id":1041,"port2Id":1352,"isNonStopTransit":false},{"id":337,"port1Id":1365,"port2Id":1350,"isNonStopTransit":false}],"connections":[],"resourceId":166,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":143,"betriebspunktName":"Zofingen","fullName":"Zofingen","positionX":64,"positionY":736,"ports":[{"id":1045,"trainrunSectionId":515,"positionIndex":0,"positionAlignment":0},{"id":1369,"trainrunSectionId":677,"positionIndex":1,"positionAlignment":0},{"id":1129,"trainrunSectionId":557,"positionIndex":2,"positionAlignment":0},{"id":1115,"trainrunSectionId":550,"positionIndex":3,"positionAlignment":0},{"id":1044,"trainrunSectionId":514,"positionIndex":0,"positionAlignment":1},{"id":1106,"trainrunSectionId":545,"positionIndex":1,"positionAlignment":1},{"id":1368,"trainrunSectionId":676,"positionIndex":2,"positionAlignment":1},{"id":1128,"trainrunSectionId":556,"positionIndex":3,"positionAlignment":1},{"id":1114,"trainrunSectionId":549,"positionIndex":4,"positionAlignment":1},{"id":1107,"trainrunSectionId":546,"positionIndex":0,"positionAlignment":2}],"transitions":[{"id":209,"port1Id":1045,"port2Id":1044,"isNonStopTransit":true},{"id":233,"port1Id":1107,"port2Id":1106,"isNonStopTransit":false},{"id":235,"port1Id":1115,"port2Id":1114,"isNonStopTransit":false},{"id":241,"port1Id":1129,"port2Id":1128,"isNonStopTransit":true},{"id":339,"port1Id":1369,"port2Id":1368,"isNonStopTransit":false}],"connections":[],"resourceId":167,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":144,"betriebspunktName":"Gelterk.","fullName":"Gelterkinden","positionX":64,"positionY":-448,"ports":[{"id":1049,"trainrunSectionId":517,"positionIndex":0,"positionAlignment":0},{"id":1411,"trainrunSectionId":698,"positionIndex":1,"positionAlignment":0},{"id":1282,"trainrunSectionId":633,"positionIndex":2,"positionAlignment":0},{"id":1333,"trainrunSectionId":659,"positionIndex":3,"positionAlignment":0},{"id":1306,"trainrunSectionId":645,"positionIndex":4,"positionAlignment":0},{"id":1373,"trainrunSectionId":679,"positionIndex":5,"positionAlignment":0},{"id":1133,"trainrunSectionId":559,"positionIndex":6,"positionAlignment":0},{"id":1119,"trainrunSectionId":552,"positionIndex":7,"positionAlignment":0},{"id":1048,"trainrunSectionId":516,"positionIndex":0,"positionAlignment":1},{"id":1332,"trainrunSectionId":658,"positionIndex":1,"positionAlignment":1},{"id":1307,"trainrunSectionId":646,"positionIndex":2,"positionAlignment":1},{"id":1372,"trainrunSectionId":678,"positionIndex":3,"positionAlignment":1},{"id":1132,"trainrunSectionId":558,"positionIndex":4,"positionAlignment":1},{"id":1118,"trainrunSectionId":551,"positionIndex":5,"positionAlignment":1},{"id":1410,"trainrunSectionId":697,"positionIndex":0,"positionAlignment":3},{"id":1283,"trainrunSectionId":634,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":211,"port1Id":1049,"port2Id":1048,"isNonStopTransit":true},{"id":237,"port1Id":1119,"port2Id":1118,"isNonStopTransit":false},{"id":243,"port1Id":1133,"port2Id":1132,"isNonStopTransit":true},{"id":297,"port1Id":1282,"port2Id":1283,"isNonStopTransit":true},{"id":307,"port1Id":1306,"port2Id":1307,"isNonStopTransit":true},{"id":316,"port1Id":1333,"port2Id":1332,"isNonStopTransit":true},{"id":341,"port1Id":1373,"port2Id":1372,"isNonStopTransit":true},{"id":362,"port1Id":1411,"port2Id":1410,"isNonStopTransit":true}],"connections":[],"resourceId":168,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":145,"betriebspunktName":"Sissach","fullName":"Sissach","positionX":64,"positionY":-928,"ports":[{"id":1051,"trainrunSectionId":518,"positionIndex":0,"positionAlignment":0},{"id":1413,"trainrunSectionId":699,"positionIndex":1,"positionAlignment":0},{"id":1280,"trainrunSectionId":632,"positionIndex":2,"positionAlignment":0},{"id":1335,"trainrunSectionId":660,"positionIndex":3,"positionAlignment":0},{"id":1304,"trainrunSectionId":644,"positionIndex":4,"positionAlignment":0},{"id":1375,"trainrunSectionId":680,"positionIndex":5,"positionAlignment":0},{"id":1135,"trainrunSectionId":560,"positionIndex":6,"positionAlignment":0},{"id":1121,"trainrunSectionId":553,"positionIndex":7,"positionAlignment":0},{"id":1050,"trainrunSectionId":517,"positionIndex":0,"positionAlignment":1},{"id":1412,"trainrunSectionId":698,"positionIndex":1,"positionAlignment":1},{"id":1281,"trainrunSectionId":633,"positionIndex":2,"positionAlignment":1},{"id":1334,"trainrunSectionId":659,"positionIndex":3,"positionAlignment":1},{"id":1305,"trainrunSectionId":645,"positionIndex":4,"positionAlignment":1},{"id":1374,"trainrunSectionId":679,"positionIndex":5,"positionAlignment":1},{"id":1134,"trainrunSectionId":559,"positionIndex":6,"positionAlignment":1},{"id":1120,"trainrunSectionId":552,"positionIndex":7,"positionAlignment":1}],"transitions":[{"id":212,"port1Id":1051,"port2Id":1050,"isNonStopTransit":true},{"id":238,"port1Id":1121,"port2Id":1120,"isNonStopTransit":false},{"id":244,"port1Id":1135,"port2Id":1134,"isNonStopTransit":true},{"id":296,"port1Id":1280,"port2Id":1281,"isNonStopTransit":true},{"id":306,"port1Id":1304,"port2Id":1305,"isNonStopTransit":true},{"id":317,"port1Id":1335,"port2Id":1334,"isNonStopTransit":true},{"id":342,"port1Id":1375,"port2Id":1374,"isNonStopTransit":true},{"id":363,"port1Id":1413,"port2Id":1412,"isNonStopTransit":true}],"connections":[],"resourceId":169,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":146,"betriebspunktName":"Liestal","fullName":"Liestal","positionX":64,"positionY":-1408,"ports":[{"id":1053,"trainrunSectionId":519,"positionIndex":0,"positionAlignment":0},{"id":1415,"trainrunSectionId":700,"positionIndex":1,"positionAlignment":0},{"id":1278,"trainrunSectionId":631,"positionIndex":2,"positionAlignment":0},{"id":1337,"trainrunSectionId":661,"positionIndex":3,"positionAlignment":0},{"id":1302,"trainrunSectionId":643,"positionIndex":4,"positionAlignment":0},{"id":1377,"trainrunSectionId":681,"positionIndex":5,"positionAlignment":0},{"id":1137,"trainrunSectionId":561,"positionIndex":6,"positionAlignment":0},{"id":1123,"trainrunSectionId":554,"positionIndex":7,"positionAlignment":0},{"id":1052,"trainrunSectionId":518,"positionIndex":0,"positionAlignment":1},{"id":1414,"trainrunSectionId":699,"positionIndex":1,"positionAlignment":1},{"id":1279,"trainrunSectionId":632,"positionIndex":2,"positionAlignment":1},{"id":1336,"trainrunSectionId":660,"positionIndex":3,"positionAlignment":1},{"id":1303,"trainrunSectionId":644,"positionIndex":4,"positionAlignment":1},{"id":1376,"trainrunSectionId":680,"positionIndex":5,"positionAlignment":1},{"id":1136,"trainrunSectionId":560,"positionIndex":6,"positionAlignment":1},{"id":1122,"trainrunSectionId":553,"positionIndex":7,"positionAlignment":1}],"transitions":[{"id":213,"port1Id":1053,"port2Id":1052,"isNonStopTransit":true},{"id":239,"port1Id":1123,"port2Id":1122,"isNonStopTransit":false},{"id":245,"port1Id":1137,"port2Id":1136,"isNonStopTransit":true},{"id":295,"port1Id":1278,"port2Id":1279,"isNonStopTransit":true},{"id":305,"port1Id":1302,"port2Id":1303,"isNonStopTransit":true},{"id":318,"port1Id":1337,"port2Id":1336,"isNonStopTransit":true},{"id":343,"port1Id":1377,"port2Id":1376,"isNonStopTransit":true},{"id":364,"port1Id":1415,"port2Id":1414,"isNonStopTransit":true}],"connections":[],"resourceId":170,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":147,"betriebspunktName":"Aarau","fullName":"Aarau","positionX":960,"positionY":32,"ports":[{"id":1409,"trainrunSectionId":697,"positionIndex":0,"positionAlignment":2},{"id":1284,"trainrunSectionId":634,"positionIndex":1,"positionAlignment":2},{"id":1201,"trainrunSectionId":593,"positionIndex":2,"positionAlignment":2},{"id":1179,"trainrunSectionId":582,"positionIndex":3,"positionAlignment":2},{"id":1223,"trainrunSectionId":604,"positionIndex":4,"positionAlignment":2},{"id":1239,"trainrunSectionId":612,"positionIndex":5,"positionAlignment":2},{"id":1163,"trainrunSectionId":574,"positionIndex":6,"positionAlignment":2},{"id":1200,"trainrunSectionId":592,"positionIndex":0,"positionAlignment":3},{"id":1408,"trainrunSectionId":696,"positionIndex":1,"positionAlignment":3},{"id":1285,"trainrunSectionId":635,"positionIndex":2,"positionAlignment":3},{"id":1178,"trainrunSectionId":581,"positionIndex":3,"positionAlignment":3},{"id":1222,"trainrunSectionId":603,"positionIndex":4,"positionAlignment":3},{"id":1238,"trainrunSectionId":611,"positionIndex":5,"positionAlignment":3},{"id":1162,"trainrunSectionId":573,"positionIndex":6,"positionAlignment":3},{"id":1293,"trainrunSectionId":639,"positionIndex":7,"positionAlignment":3}],"transitions":[{"id":252,"port1Id":1163,"port2Id":1162,"isNonStopTransit":true},{"id":258,"port1Id":1179,"port2Id":1178,"isNonStopTransit":false},{"id":263,"port1Id":1201,"port2Id":1200,"isNonStopTransit":true},{"id":269,"port1Id":1223,"port2Id":1222,"isNonStopTransit":true},{"id":275,"port1Id":1239,"port2Id":1238,"isNonStopTransit":true},{"id":298,"port1Id":1284,"port2Id":1285,"isNonStopTransit":true},{"id":361,"port1Id":1409,"port2Id":1408,"isNonStopTransit":true}],"connections":[],"resourceId":171,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":148,"betriebspunktName":"Lenzburg","fullName":"Lenzburg","positionX":1344,"positionY":32,"ports":[{"id":1199,"trainrunSectionId":592,"positionIndex":0,"positionAlignment":2},{"id":1407,"trainrunSectionId":696,"positionIndex":1,"positionAlignment":2},{"id":1286,"trainrunSectionId":635,"positionIndex":2,"positionAlignment":2},{"id":1177,"trainrunSectionId":581,"positionIndex":3,"positionAlignment":2},{"id":1221,"trainrunSectionId":603,"positionIndex":4,"positionAlignment":2},{"id":1237,"trainrunSectionId":611,"positionIndex":5,"positionAlignment":2},{"id":1161,"trainrunSectionId":573,"positionIndex":6,"positionAlignment":2},{"id":1294,"trainrunSectionId":639,"positionIndex":7,"positionAlignment":2},{"id":1258,"trainrunSectionId":621,"positionIndex":0,"positionAlignment":3},{"id":1406,"trainrunSectionId":695,"positionIndex":1,"positionAlignment":3},{"id":1287,"trainrunSectionId":636,"positionIndex":2,"positionAlignment":3},{"id":1260,"trainrunSectionId":622,"positionIndex":3,"positionAlignment":3},{"id":1262,"trainrunSectionId":623,"positionIndex":4,"positionAlignment":3},{"id":1264,"trainrunSectionId":624,"positionIndex":5,"positionAlignment":3},{"id":1266,"trainrunSectionId":625,"positionIndex":6,"positionAlignment":3},{"id":1295,"trainrunSectionId":640,"positionIndex":7,"positionAlignment":3}],"transitions":[{"id":282,"port1Id":1199,"port2Id":1258,"isNonStopTransit":true},{"id":284,"port1Id":1177,"port2Id":1260,"isNonStopTransit":true},{"id":286,"port1Id":1221,"port2Id":1262,"isNonStopTransit":true},{"id":288,"port1Id":1237,"port2Id":1264,"isNonStopTransit":true},{"id":290,"port1Id":1161,"port2Id":1266,"isNonStopTransit":true},{"id":299,"port1Id":1286,"port2Id":1287,"isNonStopTransit":true},{"id":302,"port1Id":1294,"port2Id":1295,"isNonStopTransit":false},{"id":360,"port1Id":1407,"port2Id":1406,"isNonStopTransit":true}],"connections":[],"resourceId":172,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":149,"betriebspunktName":"Baden","fullName":"Baden","positionX":2240,"positionY":32,"ports":[{"id":1197,"trainrunSectionId":591,"positionIndex":0,"positionAlignment":2},{"id":1403,"trainrunSectionId":694,"positionIndex":1,"positionAlignment":2},{"id":1290,"trainrunSectionId":637,"positionIndex":2,"positionAlignment":2},{"id":1175,"trainrunSectionId":580,"positionIndex":3,"positionAlignment":2},{"id":1219,"trainrunSectionId":602,"positionIndex":4,"positionAlignment":2},{"id":1235,"trainrunSectionId":610,"positionIndex":5,"positionAlignment":2},{"id":1159,"trainrunSectionId":572,"positionIndex":6,"positionAlignment":2},{"id":1274,"trainrunSectionId":629,"positionIndex":7,"positionAlignment":2},{"id":1298,"trainrunSectionId":641,"positionIndex":8,"positionAlignment":2},{"id":1196,"trainrunSectionId":590,"positionIndex":0,"positionAlignment":3},{"id":1402,"trainrunSectionId":693,"positionIndex":1,"positionAlignment":3},{"id":1291,"trainrunSectionId":638,"positionIndex":2,"positionAlignment":3},{"id":1174,"trainrunSectionId":579,"positionIndex":3,"positionAlignment":3},{"id":1218,"trainrunSectionId":601,"positionIndex":4,"positionAlignment":3},{"id":1234,"trainrunSectionId":609,"positionIndex":5,"positionAlignment":3},{"id":1158,"trainrunSectionId":571,"positionIndex":6,"positionAlignment":3},{"id":1275,"trainrunSectionId":630,"positionIndex":7,"positionAlignment":3},{"id":1299,"trainrunSectionId":642,"positionIndex":8,"positionAlignment":3}],"transitions":[{"id":251,"port1Id":1159,"port2Id":1158,"isNonStopTransit":true},{"id":257,"port1Id":1175,"port2Id":1174,"isNonStopTransit":true},{"id":262,"port1Id":1197,"port2Id":1196,"isNonStopTransit":true},{"id":268,"port1Id":1219,"port2Id":1218,"isNonStopTransit":true},{"id":274,"port1Id":1235,"port2Id":1234,"isNonStopTransit":true},{"id":294,"port1Id":1274,"port2Id":1275,"isNonStopTransit":false},{"id":301,"port1Id":1290,"port2Id":1291,"isNonStopTransit":true},{"id":304,"port1Id":1298,"port2Id":1299,"isNonStopTransit":true},{"id":358,"port1Id":1403,"port2Id":1402,"isNonStopTransit":true}],"connections":[],"resourceId":173,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":150,"betriebspunktName":"Zürich ✈","fullName":"Zürich Flughafen","positionX":3296,"positionY":32,"ports":[{"id":1192,"trainrunSectionId":588,"positionIndex":0,"positionAlignment":2},{"id":1171,"trainrunSectionId":578,"positionIndex":1,"positionAlignment":2},{"id":1214,"trainrunSectionId":599,"positionIndex":2,"positionAlignment":2},{"id":1230,"trainrunSectionId":607,"positionIndex":3,"positionAlignment":2},{"id":1140,"trainrunSectionId":562,"positionIndex":4,"positionAlignment":2},{"id":1246,"trainrunSectionId":615,"positionIndex":5,"positionAlignment":2},{"id":1193,"trainrunSectionId":589,"positionIndex":0,"positionAlignment":3},{"id":1170,"trainrunSectionId":577,"positionIndex":1,"positionAlignment":3},{"id":1215,"trainrunSectionId":600,"positionIndex":2,"positionAlignment":3},{"id":1231,"trainrunSectionId":608,"positionIndex":3,"positionAlignment":3},{"id":1141,"trainrunSectionId":563,"positionIndex":4,"positionAlignment":3},{"id":1247,"trainrunSectionId":616,"positionIndex":5,"positionAlignment":3}],"transitions":[{"id":246,"port1Id":1140,"port2Id":1141,"isNonStopTransit":false},{"id":255,"port1Id":1171,"port2Id":1170,"isNonStopTransit":false},{"id":260,"port1Id":1192,"port2Id":1193,"isNonStopTransit":false},{"id":266,"port1Id":1214,"port2Id":1215,"isNonStopTransit":false},{"id":272,"port1Id":1230,"port2Id":1231,"isNonStopTransit":false},{"id":278,"port1Id":1246,"port2Id":1247,"isNonStopTransit":false}],"connections":[],"resourceId":174,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":151,"betriebspunktName":"Wintert.","fullName":"Winterthur","positionX":3872,"positionY":32,"ports":[{"id":1249,"trainrunSectionId":617,"positionIndex":0,"positionAlignment":0},{"id":1194,"trainrunSectionId":589,"positionIndex":0,"positionAlignment":2},{"id":1169,"trainrunSectionId":577,"positionIndex":1,"positionAlignment":2},{"id":1216,"trainrunSectionId":600,"positionIndex":2,"positionAlignment":2},{"id":1232,"trainrunSectionId":608,"positionIndex":3,"positionAlignment":2},{"id":1142,"trainrunSectionId":563,"positionIndex":4,"positionAlignment":2},{"id":1248,"trainrunSectionId":616,"positionIndex":5,"positionAlignment":2},{"id":1227,"trainrunSectionId":606,"positionIndex":0,"positionAlignment":3},{"id":1243,"trainrunSectionId":614,"positionIndex":1,"positionAlignment":3},{"id":1211,"trainrunSectionId":598,"positionIndex":2,"positionAlignment":3},{"id":1168,"trainrunSectionId":576,"positionIndex":3,"positionAlignment":3},{"id":1143,"trainrunSectionId":564,"positionIndex":4,"positionAlignment":3}],"transitions":[{"id":247,"port1Id":1142,"port2Id":1143,"isNonStopTransit":false},{"id":254,"port1Id":1169,"port2Id":1168,"isNonStopTransit":false},{"id":265,"port1Id":1194,"port2Id":1211,"isNonStopTransit":false},{"id":271,"port1Id":1216,"port2Id":1227,"isNonStopTransit":false},{"id":277,"port1Id":1232,"port2Id":1243,"isNonStopTransit":false},{"id":279,"port1Id":1249,"port2Id":1248,"isNonStopTransit":false}],"connections":[],"resourceId":175,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":152,"betriebspunktName":"Chur","fullName":"Chur","positionX":4640,"positionY":1888,"ports":[{"id":1152,"trainrunSectionId":568,"positionIndex":0,"positionAlignment":0},{"id":1148,"trainrunSectionId":566,"positionIndex":1,"positionAlignment":0},{"id":1156,"trainrunSectionId":570,"positionIndex":2,"positionAlignment":0}],"transitions":[],"connections":[],"resourceId":176,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":153,"betriebspunktName":"Zug","fullName":"Zug","positionX":2656,"positionY":1312,"ports":[{"id":1067,"trainrunSectionId":526,"positionIndex":0,"positionAlignment":0},{"id":1093,"trainrunSectionId":539,"positionIndex":1,"positionAlignment":0},{"id":1101,"trainrunSectionId":543,"positionIndex":2,"positionAlignment":0},{"id":1097,"trainrunSectionId":541,"positionIndex":3,"positionAlignment":0},{"id":1066,"trainrunSectionId":525,"positionIndex":0,"positionAlignment":1},{"id":1092,"trainrunSectionId":538,"positionIndex":1,"positionAlignment":1},{"id":1348,"trainrunSectionId":666,"positionIndex":0,"positionAlignment":2},{"id":1346,"trainrunSectionId":665,"positionIndex":1,"positionAlignment":2}],"transitions":[{"id":220,"port1Id":1067,"port2Id":1066,"isNonStopTransit":false},{"id":231,"port1Id":1093,"port2Id":1092,"isNonStopTransit":false},{"id":322,"port1Id":1097,"port2Id":1346,"isNonStopTransit":false},{"id":324,"port1Id":1101,"port2Id":1348,"isNonStopTransit":false}],"connections":[],"resourceId":177,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":154,"betriebspunktName":"Arth-G.","fullName":"Arth-Goldau","positionX":2656,"positionY":1792,"ports":[{"id":1065,"trainrunSectionId":525,"positionIndex":0,"positionAlignment":0},{"id":1091,"trainrunSectionId":538,"positionIndex":1,"positionAlignment":0},{"id":1064,"trainrunSectionId":524,"positionIndex":0,"positionAlignment":1},{"id":1038,"trainrunSectionId":511,"positionIndex":1,"positionAlignment":1},{"id":1078,"trainrunSectionId":531,"positionIndex":2,"positionAlignment":1},{"id":1090,"trainrunSectionId":537,"positionIndex":3,"positionAlignment":1},{"id":1039,"trainrunSectionId":512,"positionIndex":0,"positionAlignment":2},{"id":1079,"trainrunSectionId":532,"positionIndex":1,"positionAlignment":2}],"transitions":[{"id":207,"port1Id":1038,"port2Id":1039,"isNonStopTransit":false},{"id":219,"port1Id":1065,"port2Id":1064,"isNonStopTransit":false},{"id":225,"port1Id":1078,"port2Id":1079,"isNonStopTransit":false},{"id":230,"port1Id":1091,"port2Id":1090,"isNonStopTransit":false}],"connections":[],"resourceId":178,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":155,"betriebspunktName":"Altdorf","fullName":"Altdorf","positionX":2656,"positionY":2176,"ports":[{"id":1063,"trainrunSectionId":524,"positionIndex":0,"positionAlignment":0},{"id":1037,"trainrunSectionId":511,"positionIndex":1,"positionAlignment":0},{"id":1077,"trainrunSectionId":531,"positionIndex":2,"positionAlignment":0},{"id":1089,"trainrunSectionId":537,"positionIndex":3,"positionAlignment":0},{"id":1062,"trainrunSectionId":523,"positionIndex":0,"positionAlignment":1},{"id":1055,"trainrunSectionId":520,"positionIndex":1,"positionAlignment":1},{"id":1076,"trainrunSectionId":530,"positionIndex":0,"positionAlignment":2},{"id":1088,"trainrunSectionId":536,"positionIndex":1,"positionAlignment":2}],"transitions":[{"id":214,"port1Id":1037,"port2Id":1055,"isNonStopTransit":true},{"id":218,"port1Id":1063,"port2Id":1062,"isNonStopTransit":false},{"id":224,"port1Id":1077,"port2Id":1076,"isNonStopTransit":false},{"id":229,"port1Id":1089,"port2Id":1088,"isNonStopTransit":false}],"connections":[],"resourceId":179,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":156,"betriebspunktName":"Lugano","fullName":"Lugano","positionX":2592,"positionY":3712,"ports":[{"id":1057,"trainrunSectionId":521,"positionIndex":0,"positionAlignment":0},{"id":1033,"trainrunSectionId":509,"positionIndex":1,"positionAlignment":0}],"transitions":[],"connections":[],"resourceId":180,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":157,"betriebspunktName":"Locarno","fullName":"Locarno","positionX":2208,"positionY":3232,"ports":[{"id":1069,"trainrunSectionId":527,"positionIndex":0,"positionAlignment":3},{"id":1081,"trainrunSectionId":533,"positionIndex":1,"positionAlignment":3}],"transitions":[],"connections":[],"resourceId":181,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":158,"betriebspunktName":"Biasca","fullName":"Biasca","positionX":2592,"positionY":2688,"ports":[{"id":1073,"trainrunSectionId":529,"positionIndex":0,"positionAlignment":0},{"id":1085,"trainrunSectionId":535,"positionIndex":1,"positionAlignment":0},{"id":1061,"trainrunSectionId":523,"positionIndex":2,"positionAlignment":0},{"id":1056,"trainrunSectionId":520,"positionIndex":3,"positionAlignment":0},{"id":1060,"trainrunSectionId":522,"positionIndex":0,"positionAlignment":1},{"id":1036,"trainrunSectionId":510,"positionIndex":1,"positionAlignment":1},{"id":1072,"trainrunSectionId":528,"positionIndex":2,"positionAlignment":1},{"id":1084,"trainrunSectionId":534,"positionIndex":3,"positionAlignment":1}],"transitions":[{"id":215,"port1Id":1056,"port2Id":1036,"isNonStopTransit":true},{"id":217,"port1Id":1061,"port2Id":1060,"isNonStopTransit":true},{"id":222,"port1Id":1073,"port2Id":1072,"isNonStopTransit":false},{"id":227,"port1Id":1085,"port2Id":1084,"isNonStopTransit":false}],"connections":[],"resourceId":182,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":159,"betriebspunktName":"Göschn.","fullName":"Göschenen","positionX":2272,"positionY":2240,"ports":[{"id":1074,"trainrunSectionId":529,"positionIndex":0,"positionAlignment":1},{"id":1086,"trainrunSectionId":535,"positionIndex":1,"positionAlignment":1},{"id":1075,"trainrunSectionId":530,"positionIndex":0,"positionAlignment":3},{"id":1087,"trainrunSectionId":536,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":223,"port1Id":1074,"port2Id":1075,"isNonStopTransit":false},{"id":228,"port1Id":1086,"port2Id":1087,"isNonStopTransit":false}],"connections":[],"resourceId":183,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":160,"betriebspunktName":"Genf","fullName":"Genf","positionX":-3936,"positionY":608,"ports":[{"id":1209,"trainrunSectionId":597,"positionIndex":0,"positionAlignment":2},{"id":1185,"trainrunSectionId":585,"positionIndex":1,"positionAlignment":2},{"id":1189,"trainrunSectionId":587,"positionIndex":2,"positionAlignment":2},{"id":1424,"trainrunSectionId":704,"positionIndex":0,"positionAlignment":3},{"id":1426,"trainrunSectionId":705,"positionIndex":1,"positionAlignment":3},{"id":1422,"trainrunSectionId":703,"positionIndex":2,"positionAlignment":3}],"transitions":[{"id":369,"port1Id":1189,"port2Id":1422,"isNonStopTransit":false},{"id":371,"port1Id":1209,"port2Id":1424,"isNonStopTransit":false},{"id":373,"port1Id":1185,"port2Id":1426,"isNonStopTransit":false}],"connections":[],"resourceId":184,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":161,"betriebspunktName":"Genf ✈","fullName":"Aiport","positionX":-4352,"positionY":608,"ports":[{"id":1210,"trainrunSectionId":597,"positionIndex":0,"positionAlignment":3},{"id":1186,"trainrunSectionId":585,"positionIndex":1,"positionAlignment":3},{"id":1190,"trainrunSectionId":587,"positionIndex":2,"positionAlignment":3}],"transitions":[],"connections":[],"resourceId":185,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":162,"betriebspunktName":"Romansh.","fullName":"Romanshorn","positionX":4640,"positionY":-192,"ports":[{"id":1228,"trainrunSectionId":606,"positionIndex":0,"positionAlignment":2},{"id":1244,"trainrunSectionId":614,"positionIndex":1,"positionAlignment":2}],"transitions":[],"connections":[],"resourceId":186,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":163,"betriebspunktName":"Bülach","fullName":"Bülach","positionX":2784,"positionY":-544,"ports":[{"id":1252,"trainrunSectionId":618,"positionIndex":0,"positionAlignment":0},{"id":1253,"trainrunSectionId":619,"positionIndex":0,"positionAlignment":1}],"transitions":[{"id":280,"port1Id":1252,"port2Id":1253,"isNonStopTransit":false}],"connections":[],"resourceId":187,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":164,"betriebspunktName":"Reihnf.","fullName":"Reihnfelden","positionX":1056,"positionY":-960,"ports":[{"id":1268,"trainrunSectionId":626,"positionIndex":0,"positionAlignment":2},{"id":1269,"trainrunSectionId":627,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":291,"port1Id":1268,"port2Id":1269,"isNonStopTransit":false}],"connections":[],"resourceId":188,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":165,"betriebspunktName":"Frick","fullName":"Frick","positionX":1792,"positionY":-672,"ports":[{"id":1271,"trainrunSectionId":628,"positionIndex":0,"positionAlignment":1},{"id":1270,"trainrunSectionId":627,"positionIndex":0,"positionAlignment":2}],"transitions":[{"id":292,"port1Id":1271,"port2Id":1270,"isNonStopTransit":false}],"connections":[],"resourceId":189,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":166,"betriebspunktName":"Brugg","fullName":"Brugg","positionX":1792,"positionY":32,"ports":[{"id":1272,"trainrunSectionId":628,"positionIndex":0,"positionAlignment":0},{"id":1257,"trainrunSectionId":621,"positionIndex":0,"positionAlignment":2},{"id":1405,"trainrunSectionId":695,"positionIndex":1,"positionAlignment":2},{"id":1288,"trainrunSectionId":636,"positionIndex":2,"positionAlignment":2},{"id":1259,"trainrunSectionId":622,"positionIndex":3,"positionAlignment":2},{"id":1261,"trainrunSectionId":623,"positionIndex":4,"positionAlignment":2},{"id":1263,"trainrunSectionId":624,"positionIndex":5,"positionAlignment":2},{"id":1265,"trainrunSectionId":625,"positionIndex":6,"positionAlignment":2},{"id":1296,"trainrunSectionId":640,"positionIndex":7,"positionAlignment":2},{"id":1198,"trainrunSectionId":591,"positionIndex":0,"positionAlignment":3},{"id":1404,"trainrunSectionId":694,"positionIndex":1,"positionAlignment":3},{"id":1289,"trainrunSectionId":637,"positionIndex":2,"positionAlignment":3},{"id":1176,"trainrunSectionId":580,"positionIndex":3,"positionAlignment":3},{"id":1220,"trainrunSectionId":602,"positionIndex":4,"positionAlignment":3},{"id":1236,"trainrunSectionId":610,"positionIndex":5,"positionAlignment":3},{"id":1160,"trainrunSectionId":572,"positionIndex":6,"positionAlignment":3},{"id":1273,"trainrunSectionId":629,"positionIndex":7,"positionAlignment":3},{"id":1297,"trainrunSectionId":641,"positionIndex":8,"positionAlignment":3}],"transitions":[{"id":281,"port1Id":1257,"port2Id":1198,"isNonStopTransit":true},{"id":283,"port1Id":1259,"port2Id":1176,"isNonStopTransit":true},{"id":285,"port1Id":1261,"port2Id":1220,"isNonStopTransit":true},{"id":287,"port1Id":1263,"port2Id":1236,"isNonStopTransit":false},{"id":289,"port1Id":1265,"port2Id":1160,"isNonStopTransit":true},{"id":293,"port1Id":1272,"port2Id":1273,"isNonStopTransit":false},{"id":300,"port1Id":1288,"port2Id":1289,"isNonStopTransit":true},{"id":303,"port1Id":1296,"port2Id":1297,"isNonStopTransit":true},{"id":359,"port1Id":1405,"port2Id":1404,"isNonStopTransit":true}],"connections":[],"resourceId":190,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":167,"betriebspunktName":"Thun","fullName":"Thun","positionX":-2144,"positionY":640,"ports":[{"id":1327,"trainrunSectionId":656,"positionIndex":0,"positionAlignment":0},{"id":1312,"trainrunSectionId":648,"positionIndex":1,"positionAlignment":0},{"id":1314,"trainrunSectionId":649,"positionIndex":2,"positionAlignment":0},{"id":1340,"trainrunSectionId":662,"positionIndex":3,"positionAlignment":0},{"id":1326,"trainrunSectionId":655,"positionIndex":0,"positionAlignment":1},{"id":1315,"trainrunSectionId":650,"positionIndex":1,"positionAlignment":1},{"id":1319,"trainrunSectionId":652,"positionIndex":2,"positionAlignment":1},{"id":1341,"trainrunSectionId":663,"positionIndex":3,"positionAlignment":1}],"transitions":[{"id":309,"port1Id":1312,"port2Id":1315,"isNonStopTransit":false},{"id":311,"port1Id":1314,"port2Id":1319,"isNonStopTransit":false},{"id":314,"port1Id":1327,"port2Id":1326,"isNonStopTransit":false},{"id":319,"port1Id":1340,"port2Id":1341,"isNonStopTransit":false}],"connections":[],"resourceId":191,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":168,"betriebspunktName":"Spiez","fullName":"Spiez","positionX":-2144,"positionY":928,"ports":[{"id":1325,"trainrunSectionId":655,"positionIndex":0,"positionAlignment":0},{"id":1316,"trainrunSectionId":650,"positionIndex":1,"positionAlignment":0},{"id":1320,"trainrunSectionId":652,"positionIndex":2,"positionAlignment":0},{"id":1342,"trainrunSectionId":663,"positionIndex":3,"positionAlignment":0},{"id":1324,"trainrunSectionId":654,"positionIndex":0,"positionAlignment":1},{"id":1321,"trainrunSectionId":653,"positionIndex":1,"positionAlignment":1},{"id":1317,"trainrunSectionId":651,"positionIndex":0,"positionAlignment":3},{"id":1343,"trainrunSectionId":664,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":310,"port1Id":1316,"port2Id":1317,"isNonStopTransit":false},{"id":312,"port1Id":1320,"port2Id":1321,"isNonStopTransit":false},{"id":313,"port1Id":1325,"port2Id":1324,"isNonStopTransit":false},{"id":320,"port1Id":1342,"port2Id":1343,"isNonStopTransit":false}],"connections":[],"resourceId":192,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":169,"betriebspunktName":"Rothkr.","fullName":"Rothkreuz","positionX":1856,"positionY":1728,"ports":[{"id":1351,"trainrunSectionId":668,"positionIndex":0,"positionAlignment":2},{"id":1349,"trainrunSectionId":667,"positionIndex":1,"positionAlignment":2},{"id":1100,"trainrunSectionId":542,"positionIndex":2,"positionAlignment":2},{"id":1096,"trainrunSectionId":540,"positionIndex":3,"positionAlignment":2},{"id":1347,"trainrunSectionId":666,"positionIndex":0,"positionAlignment":3},{"id":1345,"trainrunSectionId":665,"positionIndex":1,"positionAlignment":3},{"id":1040,"trainrunSectionId":512,"positionIndex":2,"positionAlignment":3},{"id":1080,"trainrunSectionId":532,"positionIndex":3,"positionAlignment":3}],"transitions":[{"id":321,"port1Id":1096,"port2Id":1345,"isNonStopTransit":false},{"id":323,"port1Id":1100,"port2Id":1347,"isNonStopTransit":true},{"id":325,"port1Id":1349,"port2Id":1080,"isNonStopTransit":true},{"id":326,"port1Id":1351,"port2Id":1040,"isNonStopTransit":true}],"connections":[],"resourceId":193,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":170,"betriebspunktName":"Thalwil","fullName":"Thalwil","positionX":2656,"positionY":736,"ports":[{"id":1359,"trainrunSectionId":672,"positionIndex":0,"positionAlignment":0},{"id":1150,"trainrunSectionId":567,"positionIndex":1,"positionAlignment":0},{"id":1154,"trainrunSectionId":569,"positionIndex":2,"positionAlignment":0},{"id":1357,"trainrunSectionId":671,"positionIndex":3,"positionAlignment":0},{"id":1355,"trainrunSectionId":670,"positionIndex":4,"positionAlignment":0},{"id":1353,"trainrunSectionId":669,"positionIndex":5,"positionAlignment":0},{"id":1068,"trainrunSectionId":526,"positionIndex":0,"positionAlignment":1},{"id":1094,"trainrunSectionId":539,"positionIndex":1,"positionAlignment":1},{"id":1102,"trainrunSectionId":543,"positionIndex":2,"positionAlignment":1},{"id":1098,"trainrunSectionId":541,"positionIndex":3,"positionAlignment":1},{"id":1361,"trainrunSectionId":673,"positionIndex":0,"positionAlignment":3},{"id":1363,"trainrunSectionId":674,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":328,"port1Id":1353,"port2Id":1098,"isNonStopTransit":false},{"id":330,"port1Id":1355,"port2Id":1102,"isNonStopTransit":true},{"id":331,"port1Id":1357,"port2Id":1094,"isNonStopTransit":true},{"id":332,"port1Id":1359,"port2Id":1068,"isNonStopTransit":true},{"id":333,"port1Id":1150,"port2Id":1361,"isNonStopTransit":true},{"id":335,"port1Id":1154,"port2Id":1363,"isNonStopTransit":false}],"connections":[],"resourceId":194,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":171,"betriebspunktName":"Fribourg","fullName":"Fribourg","positionX":-2560,"positionY":288,"ports":[{"id":1381,"trainrunSectionId":683,"positionIndex":0,"positionAlignment":2},{"id":1379,"trainrunSectionId":682,"positionIndex":1,"positionAlignment":2},{"id":1206,"trainrunSectionId":595,"positionIndex":0,"positionAlignment":3},{"id":1110,"trainrunSectionId":547,"positionIndex":1,"positionAlignment":3}],"transitions":[{"id":344,"port1Id":1379,"port2Id":1110,"isNonStopTransit":false},{"id":346,"port1Id":1381,"port2Id":1206,"isNonStopTransit":false}],"connections":[],"resourceId":195,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":172,"betriebspunktName":"RTR","fullName":"Rothrist","positionX":-608,"positionY":128,"ports":[{"id":1395,"trainrunSectionId":690,"positionIndex":0,"positionAlignment":2},{"id":1438,"trainrunSectionId":711,"positionIndex":1,"positionAlignment":2},{"id":1391,"trainrunSectionId":688,"positionIndex":2,"positionAlignment":2},{"id":1389,"trainrunSectionId":687,"positionIndex":3,"positionAlignment":2},{"id":1387,"trainrunSectionId":686,"positionIndex":4,"positionAlignment":2},{"id":1383,"trainrunSectionId":684,"positionIndex":5,"positionAlignment":2},{"id":1385,"trainrunSectionId":685,"positionIndex":6,"positionAlignment":2},{"id":1204,"trainrunSectionId":594,"positionIndex":0,"positionAlignment":3},{"id":1393,"trainrunSectionId":689,"positionIndex":1,"positionAlignment":3},{"id":1310,"trainrunSectionId":647,"positionIndex":2,"positionAlignment":3},{"id":1226,"trainrunSectionId":605,"positionIndex":3,"positionAlignment":3},{"id":1242,"trainrunSectionId":613,"positionIndex":4,"positionAlignment":3},{"id":1166,"trainrunSectionId":575,"positionIndex":5,"positionAlignment":3},{"id":1108,"trainrunSectionId":546,"positionIndex":6,"positionAlignment":3}],"transitions":[{"id":348,"port1Id":1108,"port2Id":1383,"isNonStopTransit":true},{"id":349,"port1Id":1385,"port2Id":1166,"isNonStopTransit":true},{"id":350,"port1Id":1387,"port2Id":1242,"isNonStopTransit":true},{"id":351,"port1Id":1389,"port2Id":1226,"isNonStopTransit":true},{"id":352,"port1Id":1391,"port2Id":1310,"isNonStopTransit":true},{"id":354,"port1Id":1395,"port2Id":1204,"isNonStopTransit":true},{"id":384,"port1Id":1438,"port2Id":1393,"isNonStopTransit":true}],"connections":[],"resourceId":196,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":173,"betriebspunktName":"Burgdorf","fullName":"Burgdorf","positionX":-1344,"positionY":352,"ports":[{"id":1397,"trainrunSectionId":691,"positionIndex":0,"positionAlignment":2},{"id":1400,"trainrunSectionId":692,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":356,"port1Id":1397,"port2Id":1400,"isNonStopTransit":false}],"connections":[],"resourceId":197,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":174,"betriebspunktName":"Langent.","fullName":"Langenthal","positionX":-992,"positionY":352,"ports":[{"id":1399,"trainrunSectionId":692,"positionIndex":0,"positionAlignment":2},{"id":1386,"trainrunSectionId":685,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":355,"port1Id":1399,"port2Id":1386,"isNonStopTransit":false}],"connections":[],"resourceId":198,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":175,"betriebspunktName":"Solothurn","fullName":"Solothurn","positionX":-1696,"positionY":-32,"ports":[{"id":1417,"trainrunSectionId":701,"positionIndex":0,"positionAlignment":2},{"id":1182,"trainrunSectionId":583,"positionIndex":0,"positionAlignment":3}],"transitions":[{"id":365,"port1Id":1417,"port2Id":1182,"isNonStopTransit":false}],"connections":[],"resourceId":199,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":176,"betriebspunktName":"Rohrsch.","fullName":"Rohrschach","positionX":5376,"positionY":96,"ports":[{"id":1420,"trainrunSectionId":702,"positionIndex":0,"positionAlignment":2}],"transitions":[],"connections":[],"resourceId":200,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":177,"betriebspunktName":"Morges","fullName":"Morges","positionX":-3520,"positionY":544,"ports":[{"id":1423,"trainrunSectionId":704,"positionIndex":0,"positionAlignment":2},{"id":1425,"trainrunSectionId":705,"positionIndex":1,"positionAlignment":2},{"id":1421,"trainrunSectionId":703,"positionIndex":2,"positionAlignment":2},{"id":1184,"trainrunSectionId":584,"positionIndex":0,"positionAlignment":3},{"id":1208,"trainrunSectionId":596,"positionIndex":1,"positionAlignment":3},{"id":1188,"trainrunSectionId":586,"positionIndex":2,"positionAlignment":3}],"transitions":[{"id":368,"port1Id":1421,"port2Id":1188,"isNonStopTransit":false},{"id":370,"port1Id":1423,"port2Id":1208,"isNonStopTransit":true},{"id":372,"port1Id":1425,"port2Id":1184,"isNonStopTransit":false}],"connections":[],"resourceId":201,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]},{"id":178,"betriebspunktName":"BNWD","fullName":"Bern Wankdorf","positionX":-1696,"positionY":128,"ports":[{"id":1439,"trainrunSectionId":712,"positionIndex":0,"positionAlignment":2},{"id":1330,"trainrunSectionId":657,"positionIndex":1,"positionAlignment":2},{"id":1435,"trainrunSectionId":710,"positionIndex":2,"positionAlignment":2},{"id":1433,"trainrunSectionId":709,"positionIndex":3,"positionAlignment":2},{"id":1431,"trainrunSectionId":708,"positionIndex":4,"positionAlignment":2},{"id":1429,"trainrunSectionId":707,"positionIndex":5,"positionAlignment":2},{"id":1427,"trainrunSectionId":706,"positionIndex":6,"positionAlignment":2},{"id":1396,"trainrunSectionId":690,"positionIndex":0,"positionAlignment":3},{"id":1437,"trainrunSectionId":711,"positionIndex":1,"positionAlignment":3},{"id":1392,"trainrunSectionId":688,"positionIndex":2,"positionAlignment":3},{"id":1390,"trainrunSectionId":687,"positionIndex":3,"positionAlignment":3},{"id":1388,"trainrunSectionId":686,"positionIndex":4,"positionAlignment":3},{"id":1384,"trainrunSectionId":684,"positionIndex":5,"positionAlignment":3},{"id":1398,"trainrunSectionId":691,"positionIndex":6,"positionAlignment":3}],"transitions":[{"id":374,"port1Id":1427,"port2Id":1398,"isNonStopTransit":true},{"id":375,"port1Id":1429,"port2Id":1384,"isNonStopTransit":true},{"id":377,"port1Id":1431,"port2Id":1388,"isNonStopTransit":true},{"id":379,"port1Id":1433,"port2Id":1390,"isNonStopTransit":true},{"id":381,"port1Id":1435,"port2Id":1392,"isNonStopTransit":true},{"id":383,"port1Id":1330,"port2Id":1437,"isNonStopTransit":true},{"id":385,"port1Id":1439,"port2Id":1396,"isNonStopTransit":true}],"connections":[],"resourceId":202,"perronkanten":5,"connectionTime":3,"trainrunCategoryHaltezeiten":{"HaltezeitA":{"no_halt":false,"haltezeit":2},"HaltezeitB":{"no_halt":false,"haltezeit":2},"HaltezeitC":{"no_halt":false,"haltezeit":1},"HaltezeitD":{"no_halt":false,"haltezeit":1},"HaltezeitIPV":{"no_halt":false,"haltezeit":3},"HaltezeitUncategorized":{"no_halt":true,"haltezeit":0}},"symmetryAxis":null,"warnings":null,"labelIds":[]}],"trainrunSections":[{"id":509,"sourceNodeId":156,"sourcePortId":1033,"targetNodeId":136,"targetPortId":1034,"travelTime":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":182},"sourceArrival":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":178},"targetDeparture":{"lock":false,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":164},"targetArrival":{"lock":false,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":196},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2640,"y":3710},{"x":2640,"y":3646},{"x":2640,"y":3390},{"x":2640,"y":3326}],"textPositions":{"0":{"x":2652,"y":3692},"1":{"x":2628,"y":3664},"2":{"x":2628,"y":3344},"3":{"x":2652,"y":3372},"4":{"x":2628,"y":3518},"5":{"x":2628,"y":3518},"6":{"x":2652,"y":3518}}},"warnings":null},{"id":510,"sourceNodeId":136,"sourcePortId":1035,"targetNodeId":158,"targetPortId":1036,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":198},"sourceArrival":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":162},"targetDeparture":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":156},"targetArrival":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":204},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2640,"y":3230},{"x":2640,"y":3166},{"x":2640,"y":2818},{"x":2640,"y":2754}],"textPositions":{"0":{"x":2652,"y":3212},"1":{"x":2628,"y":3184},"2":{"x":2628,"y":2772},"3":{"x":2652,"y":2800},"4":{"x":2628,"y":2992},"5":{"x":2628,"y":2992},"6":{"x":2652,"y":2992}}},"warnings":null},{"id":511,"sourceNodeId":155,"sourcePortId":1037,"targetNodeId":154,"targetPortId":1038,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":232},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":128},"targetDeparture":{"lock":true,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":109},"targetArrival":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":251},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":2174},{"x":2704,"y":2110},{"x":2704,"y":1950},{"x":2704,"y":1886}],"textPositions":{"0":{"x":2716,"y":2156},"1":{"x":2692,"y":2128},"2":{"x":2692,"y":1904},"3":{"x":2716,"y":1932},"4":{"x":2692,"y":2030},"5":{"x":2692,"y":2030},"6":{"x":2716,"y":2030}}},"warnings":null},{"id":512,"sourceNodeId":154,"sourcePortId":1039,"targetNodeId":169,"targetPortId":1040,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":255},"sourceArrival":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":105},"targetDeparture":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":87},"targetArrival":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":273},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":1808},{"x":2590,"y":1808},{"x":2018,"y":1808},{"x":1954,"y":1808}],"textPositions":{"0":{"x":2636,"y":1796},"1":{"x":2608,"y":1820},"2":{"x":1972,"y":1820},"3":{"x":2000,"y":1796},"4":{"x":2304,"y":1796},"5":{"x":2304,"y":1796},"6":{"x":2304,"y":1820}}},"warnings":null},{"id":513,"sourceNodeId":142,"sourcePortId":1041,"targetNodeId":141,"targetPortId":1042,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":295},"sourceArrival":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":1726},{"x":80,"y":1662},{"x":80,"y":1314},{"x":80,"y":1250}],"textPositions":{"0":{"x":92,"y":1708},"1":{"x":68,"y":1680},"2":{"x":68,"y":1268},"3":{"x":92,"y":1296},"4":{"x":68,"y":1488},"5":{"x":68,"y":1488},"6":{"x":92,"y":1488}}},"warnings":null},{"id":514,"sourceNodeId":141,"sourcePortId":1043,"targetNodeId":143,"targetPortId":1044,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"sourceArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetDeparture":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":37},"targetArrival":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":323},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":1182},{"x":80,"y":1118},{"x":80,"y":866},{"x":80,"y":802}],"textPositions":{"0":{"x":92,"y":1164},"1":{"x":68,"y":1136},"2":{"x":68,"y":820},"3":{"x":92,"y":848},"4":{"x":68,"y":992},"5":{"x":68,"y":992},"6":{"x":92,"y":992}}},"warnings":null},{"id":515,"sourceNodeId":143,"sourcePortId":1045,"targetNodeId":133,"targetPortId":1046,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":323},"sourceArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":37},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":30},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":734},{"x":80,"y":670},{"x":80,"y":414},{"x":80,"y":350}],"textPositions":{"0":{"x":92,"y":716},"1":{"x":68,"y":688},"2":{"x":68,"y":368},"3":{"x":92,"y":396},"4":{"x":68,"y":542},"5":{"x":68,"y":542},"6":{"x":92,"y":542}}},"warnings":null},{"id":516,"sourceNodeId":133,"sourcePortId":1047,"targetNodeId":144,"targetPortId":1048,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":332},"sourceArrival":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":28},"targetDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"targetArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":342},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":94},{"x":80,"y":30},{"x":80,"y":-290},{"x":80,"y":-354}],"textPositions":{"0":{"x":92,"y":76},"1":{"x":68,"y":48},"2":{"x":68,"y":-336},"3":{"x":92,"y":-308},"4":{"x":68,"y":-130},"5":{"x":68,"y":-130},"6":{"x":92,"y":-130}}},"warnings":null},{"id":517,"sourceNodeId":144,"sourcePortId":1049,"targetNodeId":145,"targetPortId":1050,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":342},"sourceArrival":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":-450},{"x":80,"y":-514},{"x":80,"y":-798},{"x":80,"y":-862}],"textPositions":{"0":{"x":92,"y":-468},"1":{"x":68,"y":-496},"2":{"x":68,"y":-844},"3":{"x":92,"y":-816},"4":{"x":68,"y":-656},"5":{"x":68,"y":-656},"6":{"x":92,"y":-656}}},"warnings":null},{"id":518,"sourceNodeId":145,"sourcePortId":1051,"targetNodeId":146,"targetPortId":1052,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":8},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":352},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":-930},{"x":80,"y":-994},{"x":80,"y":-1278},{"x":80,"y":-1342}],"textPositions":{"0":{"x":92,"y":-948},"1":{"x":68,"y":-976},"2":{"x":68,"y":-1324},"3":{"x":92,"y":-1296},"4":{"x":68,"y":-1136},"5":{"x":68,"y":-1136},"6":{"x":92,"y":-1136}}},"warnings":null},{"id":519,"sourceNodeId":146,"sourcePortId":1053,"targetNodeId":134,"targetPortId":1054,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":352},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":8},"targetDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":3},"targetArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":357},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":80,"y":-1410},{"x":80,"y":-1474},{"x":80,"y":-1758},{"x":80,"y":-1822}],"textPositions":{"0":{"x":92,"y":-1428},"1":{"x":68,"y":-1456},"2":{"x":68,"y":-1804},"3":{"x":92,"y":-1776},"4":{"x":68,"y":-1616},"5":{"x":68,"y":-1616},"6":{"x":92,"y":-1616}}},"warnings":null},{"id":520,"sourceNodeId":155,"sourcePortId":1055,"targetNodeId":158,"targetPortId":1056,"travelTime":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":128},"sourceArrival":{"lock":true,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":232},"targetDeparture":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":204},"targetArrival":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":156},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":2270},{"x":2704,"y":2334},{"x":2704,"y":2622},{"x":2704,"y":2686}],"textPositions":{"0":{"x":2692,"y":2288},"1":{"x":2716,"y":2316},"2":{"x":2716,"y":2668},"3":{"x":2692,"y":2640},"4":{"x":2692,"y":2478},"5":{"x":2692,"y":2478},"6":{"x":2716,"y":2478}}},"warnings":null},{"id":521,"sourceNodeId":156,"sourcePortId":1057,"targetNodeId":136,"targetPortId":1058,"travelTime":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":2},"sourceArrival":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":118},"targetDeparture":{"lock":false,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":104},"targetArrival":{"lock":false,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":16},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2608,"y":3710},{"x":2608,"y":3646},{"x":2608,"y":3390},{"x":2608,"y":3326}],"textPositions":{"0":{"x":2620,"y":3692},"1":{"x":2596,"y":3664},"2":{"x":2596,"y":3344},"3":{"x":2620,"y":3372},"4":{"x":2596,"y":3518},"5":{"x":2596,"y":3518},"6":{"x":2620,"y":3518}}},"warnings":null},{"id":522,"sourceNodeId":136,"sourcePortId":1059,"targetNodeId":158,"targetPortId":1060,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"sourceArrival":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":102},"targetDeparture":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":96},"targetArrival":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":24},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2608,"y":3230},{"x":2608,"y":3166},{"x":2608,"y":2818},{"x":2608,"y":2754}],"textPositions":{"0":{"x":2620,"y":3212},"1":{"x":2596,"y":3184},"2":{"x":2596,"y":2772},"3":{"x":2620,"y":2800},"4":{"x":2596,"y":2992},"5":{"x":2596,"y":2992},"6":{"x":2620,"y":2992}}},"warnings":null},{"id":523,"sourceNodeId":158,"sourcePortId":1061,"targetNodeId":155,"targetPortId":1062,"travelTime":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":24},"sourceArrival":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":96},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":2686},{"x":2672,"y":2622},{"x":2672,"y":2334},{"x":2672,"y":2270}],"textPositions":{"0":{"x":2684,"y":2668},"1":{"x":2660,"y":2640},"2":{"x":2660,"y":2288},"3":{"x":2684,"y":2316},"4":{"x":2660,"y":2478},"5":{"x":2660,"y":2478},"6":{"x":2684,"y":2478}}},"warnings":null},{"id":524,"sourceNodeId":155,"sourcePortId":1063,"targetNodeId":154,"targetPortId":1064,"travelTime":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetDeparture":{"lock":true,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":49},"targetArrival":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":71},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":2174},{"x":2672,"y":2110},{"x":2672,"y":1950},{"x":2672,"y":1886}],"textPositions":{"0":{"x":2684,"y":2156},"1":{"x":2660,"y":2128},"2":{"x":2660,"y":1904},"3":{"x":2684,"y":1932},"4":{"x":2660,"y":2030},"5":{"x":2660,"y":2030},"6":{"x":2684,"y":2030}}},"warnings":null},{"id":525,"sourceNodeId":154,"sourcePortId":1065,"targetNodeId":153,"targetPortId":1066,"travelTime":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":75},"sourceArrival":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":45},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":30},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":1790},{"x":2672,"y":1726},{"x":2672,"y":1470},{"x":2672,"y":1406}],"textPositions":{"0":{"x":2684,"y":1772},"1":{"x":2660,"y":1744},"2":{"x":2660,"y":1424},"3":{"x":2684,"y":1452},"4":{"x":2660,"y":1598},"5":{"x":2660,"y":1598},"6":{"x":2684,"y":1598}}},"warnings":null},{"id":526,"sourceNodeId":153,"sourcePortId":1067,"targetNodeId":170,"targetPortId":1068,"travelTime":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":91},"sourceArrival":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":29},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":107},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":1310},{"x":2672,"y":1246},{"x":2672,"y":894},{"x":2672,"y":830}],"textPositions":{"0":{"x":2684,"y":1292},"1":{"x":2660,"y":1264},"2":{"x":2660,"y":848},"3":{"x":2684,"y":876},"4":{"x":2660,"y":1070},"5":{"x":2660,"y":1070},"6":{"x":2684,"y":1070}}},"warnings":null},{"id":527,"sourceNodeId":157,"sourcePortId":1069,"targetNodeId":136,"targetPortId":1070,"travelTime":{"lock":true,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":273},"sourceArrival":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":327},"targetDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":304},"targetArrival":{"lock":true,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":296},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2306,"y":3248},{"x":2370,"y":3248},{"x":2526,"y":3248},{"x":2590,"y":3248}],"textPositions":{"0":{"x":2324,"y":3260},"1":{"x":2352,"y":3236},"2":{"x":2572,"y":3236},"3":{"x":2544,"y":3260},"4":{"x":2448,"y":3236},"5":{"x":2448,"y":3236},"6":{"x":2448,"y":3260}}},"warnings":null},{"id":528,"sourceNodeId":136,"sourcePortId":1071,"targetNodeId":158,"targetPortId":1072,"travelTime":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":300},"sourceArrival":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":300},"targetDeparture":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":285},"targetArrival":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":315},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":3230},{"x":2672,"y":3166},{"x":2672,"y":2818},{"x":2672,"y":2754}],"textPositions":{"0":{"x":2684,"y":3212},"1":{"x":2660,"y":3184},"2":{"x":2660,"y":2772},"3":{"x":2684,"y":2800},"4":{"x":2660,"y":2992},"5":{"x":2660,"y":2992},"6":{"x":2684,"y":2992}}},"warnings":null},{"id":529,"sourceNodeId":158,"sourcePortId":1073,"targetNodeId":159,"targetPortId":1074,"travelTime":{"lock":true,"time":53,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":316},"sourceArrival":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":284},"targetDeparture":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":231},"targetArrival":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":369},"numberOfStops":5,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2608,"y":2686},{"x":2608,"y":2622},{"x":2288,"y":2398},{"x":2288,"y":2334}],"textPositions":{"0":{"x":2620,"y":2668},"1":{"x":2596,"y":2640},"2":{"x":2276,"y":2352},"3":{"x":2300,"y":2380},"4":{"x":2460,"y":2510},"5":{"x":2460,"y":2510},"6":{"x":2436,"y":2510}}},"warnings":null},{"id":530,"sourceNodeId":159,"sourcePortId":1075,"targetNodeId":155,"targetPortId":1076,"travelTime":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":370},"sourceArrival":{"lock":true,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":230},"targetDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":198},"targetArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":402},"numberOfStops":1,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2370,"y":2256},{"x":2434,"y":2256},{"x":2590,"y":2192},{"x":2654,"y":2192}],"textPositions":{"0":{"x":2388,"y":2268},"1":{"x":2416,"y":2244},"2":{"x":2636,"y":2180},"3":{"x":2608,"y":2204},"4":{"x":2512,"y":2212},"5":{"x":2512,"y":2212},"6":{"x":2512,"y":2236}}},"warnings":null},{"id":531,"sourceNodeId":155,"sourcePortId":1077,"targetNodeId":154,"targetPortId":1078,"travelTime":{"lock":true,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":403},"sourceArrival":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":197},"targetDeparture":{"lock":true,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":174},"targetArrival":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":426},"numberOfStops":3,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2736,"y":2174},{"x":2736,"y":2110},{"x":2736,"y":1950},{"x":2736,"y":1886}],"textPositions":{"0":{"x":2748,"y":2156},"1":{"x":2724,"y":2128},"2":{"x":2724,"y":1904},"3":{"x":2748,"y":1932},"4":{"x":2724,"y":2030},"5":{"x":2724,"y":2030},"6":{"x":2748,"y":2030}}},"warnings":null},{"id":532,"sourceNodeId":154,"sourcePortId":1079,"targetNodeId":169,"targetPortId":1080,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":435},"sourceArrival":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":165},"targetDeparture":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":147},"targetArrival":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":453},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":1840},{"x":2590,"y":1840},{"x":2018,"y":1840},{"x":1954,"y":1840}],"textPositions":{"0":{"x":2636,"y":1828},"1":{"x":2608,"y":1852},"2":{"x":1972,"y":1852},"3":{"x":2000,"y":1828},"4":{"x":2304,"y":1828},"5":{"x":2304,"y":1828},"6":{"x":2304,"y":1852}}},"warnings":null},{"id":533,"sourceNodeId":157,"sourcePortId":1081,"targetNodeId":136,"targetPortId":1082,"travelTime":{"lock":true,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":153},"sourceArrival":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":207},"targetDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":184},"targetArrival":{"lock":true,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":176},"numberOfStops":3,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2306,"y":3280},{"x":2370,"y":3280},{"x":2526,"y":3280},{"x":2590,"y":3280}],"textPositions":{"0":{"x":2324,"y":3292},"1":{"x":2352,"y":3268},"2":{"x":2572,"y":3268},"3":{"x":2544,"y":3292},"4":{"x":2448,"y":3268},"5":{"x":2448,"y":3268},"6":{"x":2448,"y":3292}}},"warnings":null},{"id":534,"sourceNodeId":136,"sourcePortId":1083,"targetNodeId":158,"targetPortId":1084,"travelTime":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":180},"sourceArrival":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":180},"targetDeparture":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":165},"targetArrival":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":195},"numberOfStops":1,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":3230},{"x":2704,"y":3166},{"x":2704,"y":2818},{"x":2704,"y":2754}],"textPositions":{"0":{"x":2716,"y":3212},"1":{"x":2692,"y":3184},"2":{"x":2692,"y":2772},"3":{"x":2716,"y":2800},"4":{"x":2692,"y":2992},"5":{"x":2692,"y":2992},"6":{"x":2716,"y":2992}}},"warnings":null},{"id":535,"sourceNodeId":158,"sourcePortId":1085,"targetNodeId":159,"targetPortId":1086,"travelTime":{"lock":true,"time":53,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":196},"sourceArrival":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":164},"targetDeparture":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":111},"targetArrival":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":249},"numberOfStops":5,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2640,"y":2686},{"x":2640,"y":2622},{"x":2320,"y":2398},{"x":2320,"y":2334}],"textPositions":{"0":{"x":2652,"y":2668},"1":{"x":2628,"y":2640},"2":{"x":2308,"y":2352},"3":{"x":2332,"y":2380},"4":{"x":2492,"y":2510},"5":{"x":2492,"y":2510},"6":{"x":2468,"y":2510}}},"warnings":null},{"id":536,"sourceNodeId":159,"sourcePortId":1087,"targetNodeId":155,"targetPortId":1088,"travelTime":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":250},"sourceArrival":{"lock":true,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":110},"targetDeparture":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":78},"targetArrival":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":282},"numberOfStops":1,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2370,"y":2288},{"x":2434,"y":2288},{"x":2590,"y":2224},{"x":2654,"y":2224}],"textPositions":{"0":{"x":2388,"y":2300},"1":{"x":2416,"y":2276},"2":{"x":2636,"y":2212},"3":{"x":2608,"y":2236},"4":{"x":2512,"y":2244},"5":{"x":2512,"y":2244},"6":{"x":2512,"y":2268}}},"warnings":null},{"id":537,"sourceNodeId":155,"sourcePortId":1089,"targetNodeId":154,"targetPortId":1090,"travelTime":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":283},"sourceArrival":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":77},"targetDeparture":{"lock":true,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":54},"targetArrival":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":306},"numberOfStops":3,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2768,"y":2174},{"x":2768,"y":2110},{"x":2768,"y":1950},{"x":2768,"y":1886}],"textPositions":{"0":{"x":2780,"y":2156},"1":{"x":2756,"y":2128},"2":{"x":2756,"y":1904},"3":{"x":2780,"y":1932},"4":{"x":2756,"y":2030},"5":{"x":2756,"y":2030},"6":{"x":2780,"y":2030}}},"warnings":null},{"id":538,"sourceNodeId":154,"sourcePortId":1091,"targetNodeId":153,"targetPortId":1092,"travelTime":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":315},"sourceArrival":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":45},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":30},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"numberOfStops":0,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":1790},{"x":2704,"y":1726},{"x":2704,"y":1470},{"x":2704,"y":1406}],"textPositions":{"0":{"x":2716,"y":1772},"1":{"x":2692,"y":1744},"2":{"x":2692,"y":1424},"3":{"x":2716,"y":1452},"4":{"x":2692,"y":1598},"5":{"x":2692,"y":1598},"6":{"x":2716,"y":1598}}},"warnings":null},{"id":539,"sourceNodeId":153,"sourcePortId":1093,"targetNodeId":170,"targetPortId":1094,"travelTime":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":331},"sourceArrival":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":29},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"numberOfStops":0,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":1310},{"x":2704,"y":1246},{"x":2704,"y":894},{"x":2704,"y":830}],"textPositions":{"0":{"x":2716,"y":1292},"1":{"x":2692,"y":1264},"2":{"x":2692,"y":848},"3":{"x":2716,"y":876},"4":{"x":2692,"y":1070},"5":{"x":2692,"y":1070},"6":{"x":2716,"y":1070}}},"warnings":null},{"id":540,"sourceNodeId":142,"sourcePortId":1095,"targetNodeId":169,"targetPortId":1096,"travelTime":{"lock":false,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"sourceArrival":{"lock":true,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":265},"targetDeparture":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":253},"targetArrival":{"lock":true,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":47},"numberOfStops":0,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":226,"y":1840},{"x":290,"y":1840},{"x":1790,"y":1840},{"x":1854,"y":1840}],"textPositions":{"0":{"x":244,"y":1852},"1":{"x":272,"y":1828},"2":{"x":1836,"y":1828},"3":{"x":1808,"y":1852},"4":{"x":1040,"y":1828},"5":{"x":1040,"y":1828},"6":{"x":1040,"y":1852}}},"warnings":null},{"id":541,"sourceNodeId":153,"sourcePortId":1097,"targetNodeId":170,"targetPortId":1098,"travelTime":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":58},"sourceArrival":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":242},"targetDeparture":{"lock":true,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":227},"targetArrival":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":73},"numberOfStops":1,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2768,"y":1310},{"x":2768,"y":1246},{"x":2768,"y":894},{"x":2768,"y":830}],"textPositions":{"0":{"x":2780,"y":1292},"1":{"x":2756,"y":1264},"2":{"x":2756,"y":848},"3":{"x":2780,"y":876},"4":{"x":2756,"y":1070},"5":{"x":2756,"y":1070},"6":{"x":2780,"y":1070}}},"warnings":null},{"id":542,"sourceNodeId":142,"sourcePortId":1099,"targetNodeId":169,"targetPortId":1100,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":9},"sourceArrival":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":51},"targetDeparture":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":42},"targetArrival":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"numberOfStops":0,"trainrunId":80,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":226,"y":1808},{"x":290,"y":1808},{"x":1790,"y":1808},{"x":1854,"y":1808}],"textPositions":{"0":{"x":244,"y":1820},"1":{"x":272,"y":1796},"2":{"x":1836,"y":1796},"3":{"x":1808,"y":1820},"4":{"x":1040,"y":1796},"5":{"x":1040,"y":1796},"6":{"x":1040,"y":1820}}},"warnings":null},{"id":543,"sourceNodeId":153,"sourcePortId":1101,"targetNodeId":170,"targetPortId":1102,"travelTime":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":29},"sourceArrival":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":31},"targetDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":17},"targetArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":43},"numberOfStops":0,"trainrunId":80,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2736,"y":1310},{"x":2736,"y":1246},{"x":2736,"y":894},{"x":2736,"y":830}],"textPositions":{"0":{"x":2748,"y":1292},"1":{"x":2724,"y":1264},"2":{"x":2724,"y":848},"3":{"x":2748,"y":876},"4":{"x":2724,"y":1070},"5":{"x":2724,"y":1070},"6":{"x":2748,"y":1070}}},"warnings":null},{"id":544,"sourceNodeId":142,"sourcePortId":1103,"targetNodeId":141,"targetPortId":1104,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":299},"sourceArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":241},"targetDeparture":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":222},"targetArrival":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":318},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":1726},{"x":112,"y":1662},{"x":112,"y":1314},{"x":112,"y":1250}],"textPositions":{"0":{"x":124,"y":1708},"1":{"x":100,"y":1680},"2":{"x":100,"y":1268},"3":{"x":124,"y":1296},"4":{"x":100,"y":1488},"5":{"x":100,"y":1488},"6":{"x":124,"y":1488}}},"warnings":null},{"id":545,"sourceNodeId":141,"sourcePortId":1105,"targetNodeId":143,"targetPortId":1106,"travelTime":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":319},"sourceArrival":{"lock":true,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":221},"targetDeparture":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":209},"targetArrival":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":331},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":1182},{"x":112,"y":1118},{"x":112,"y":866},{"x":112,"y":802}],"textPositions":{"0":{"x":124,"y":1164},"1":{"x":100,"y":1136},"2":{"x":100,"y":820},"3":{"x":124,"y":848},"4":{"x":100,"y":992},"5":{"x":100,"y":992},"6":{"x":124,"y":992}}},"warnings":null},{"id":546,"sourceNodeId":143,"sourcePortId":1107,"targetNodeId":172,"targetPortId":1108,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":332},"sourceArrival":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":208},"targetDeparture":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":201},"targetArrival":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":339},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":752},{"x":-2,"y":752},{"x":-446,"y":336},{"x":-510,"y":336}],"textPositions":{"0":{"x":44,"y":740},"1":{"x":16,"y":764},"2":{"x":-492,"y":348},"3":{"x":-464,"y":324},"4":{"x":-224,"y":532},"5":{"x":-224,"y":532},"6":{"x":-224,"y":556}}},"warnings":null},{"id":547,"sourceNodeId":129,"sourcePortId":1109,"targetNodeId":171,"targetPortId":1110,"travelTime":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":364},"sourceArrival":{"lock":true,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":176},"targetDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":154},"targetArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":386},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2146,"y":176},{"x":-2210,"y":176},{"x":-2398,"y":336},{"x":-2462,"y":336}],"textPositions":{"0":{"x":-2164,"y":164},"1":{"x":-2192,"y":188},"2":{"x":-2444,"y":348},"3":{"x":-2416,"y":324},"4":{"x":-2304,"y":244},"5":{"x":-2304,"y":244},"6":{"x":-2304,"y":268}}},"warnings":null},{"id":548,"sourceNodeId":142,"sourcePortId":1111,"targetNodeId":141,"targetPortId":1112,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"sourceArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetDeparture":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":72},"targetArrival":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":108},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":1726},{"x":208,"y":1662},{"x":208,"y":1314},{"x":208,"y":1250}],"textPositions":{"0":{"x":220,"y":1708},"1":{"x":196,"y":1680},"2":{"x":196,"y":1268},"3":{"x":220,"y":1296},"4":{"x":196,"y":1488},"5":{"x":196,"y":1488},"6":{"x":220,"y":1488}}},"warnings":null},{"id":549,"sourceNodeId":141,"sourcePortId":1113,"targetNodeId":143,"targetPortId":1114,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":109},"sourceArrival":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":71},"targetDeparture":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":58},"targetArrival":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":122},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":1182},{"x":208,"y":1118},{"x":208,"y":866},{"x":208,"y":802}],"textPositions":{"0":{"x":220,"y":1164},"1":{"x":196,"y":1136},"2":{"x":196,"y":820},"3":{"x":220,"y":848},"4":{"x":196,"y":992},"5":{"x":196,"y":992},"6":{"x":220,"y":992}}},"warnings":null},{"id":550,"sourceNodeId":143,"sourcePortId":1115,"targetNodeId":133,"targetPortId":1116,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":124},"sourceArrival":{"lock":true,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":56},"targetDeparture":{"lock":true,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":49},"targetArrival":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":131},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":734},{"x":176,"y":670},{"x":176,"y":414},{"x":176,"y":350}],"textPositions":{"0":{"x":188,"y":716},"1":{"x":164,"y":688},"2":{"x":164,"y":368},"3":{"x":188,"y":396},"4":{"x":164,"y":542},"5":{"x":164,"y":542},"6":{"x":188,"y":542}}},"warnings":null},{"id":551,"sourceNodeId":133,"sourcePortId":1117,"targetNodeId":144,"targetPortId":1118,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":132},"sourceArrival":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":48},"targetDeparture":{"lock":true,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":38},"targetArrival":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":142},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":240,"y":94},{"x":240,"y":30},{"x":240,"y":-290},{"x":240,"y":-354}],"textPositions":{"0":{"x":252,"y":76},"1":{"x":228,"y":48},"2":{"x":228,"y":-336},"3":{"x":252,"y":-308},"4":{"x":228,"y":-130},"5":{"x":228,"y":-130},"6":{"x":252,"y":-130}}},"warnings":null},{"id":552,"sourceNodeId":144,"sourcePortId":1119,"targetNodeId":145,"targetPortId":1120,"travelTime":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":143},"sourceArrival":{"lock":true,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":37},"targetDeparture":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":33},"targetArrival":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":147},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":304,"y":-450},{"x":304,"y":-514},{"x":304,"y":-798},{"x":304,"y":-862}],"textPositions":{"0":{"x":316,"y":-468},"1":{"x":292,"y":-496},"2":{"x":292,"y":-844},"3":{"x":316,"y":-816},"4":{"x":292,"y":-656},"5":{"x":292,"y":-656},"6":{"x":316,"y":-656}}},"warnings":null},{"id":553,"sourceNodeId":145,"sourcePortId":1121,"targetNodeId":146,"targetPortId":1122,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":148},"sourceArrival":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":32},"targetDeparture":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":27},"targetArrival":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":153},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":304,"y":-930},{"x":304,"y":-994},{"x":304,"y":-1278},{"x":304,"y":-1342}],"textPositions":{"0":{"x":316,"y":-948},"1":{"x":292,"y":-976},"2":{"x":292,"y":-1324},"3":{"x":316,"y":-1296},"4":{"x":292,"y":-1136},"5":{"x":292,"y":-1136},"6":{"x":316,"y":-1136}}},"warnings":null},{"id":554,"sourceNodeId":146,"sourcePortId":1123,"targetNodeId":134,"targetPortId":1124,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":154},"sourceArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":26},"targetDeparture":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":16},"targetArrival":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":164},"numberOfStops":0,"trainrunId":82,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":304,"y":-1410},{"x":304,"y":-1474},{"x":304,"y":-1758},{"x":304,"y":-1822}],"textPositions":{"0":{"x":316,"y":-1428},"1":{"x":292,"y":-1456},"2":{"x":292,"y":-1804},"3":{"x":316,"y":-1776},"4":{"x":292,"y":-1616},"5":{"x":292,"y":-1616},"6":{"x":316,"y":-1616}}},"warnings":null},{"id":555,"sourceNodeId":142,"sourcePortId":1125,"targetNodeId":141,"targetPortId":1126,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":115},"sourceArrival":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":1726},{"x":176,"y":1662},{"x":176,"y":1314},{"x":176,"y":1250}],"textPositions":{"0":{"x":188,"y":1708},"1":{"x":164,"y":1680},"2":{"x":164,"y":1268},"3":{"x":188,"y":1296},"4":{"x":164,"y":1488},"5":{"x":164,"y":1488},"6":{"x":188,"y":1488}}},"warnings":null},{"id":556,"sourceNodeId":141,"sourcePortId":1127,"targetNodeId":143,"targetPortId":1128,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"sourceArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":38},"targetArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":142},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":1182},{"x":176,"y":1118},{"x":176,"y":866},{"x":176,"y":802}],"textPositions":{"0":{"x":188,"y":1164},"1":{"x":164,"y":1136},"2":{"x":164,"y":820},"3":{"x":188,"y":848},"4":{"x":164,"y":992},"5":{"x":164,"y":992},"6":{"x":188,"y":992}}},"warnings":null},{"id":557,"sourceNodeId":143,"sourcePortId":1129,"targetNodeId":133,"targetPortId":1130,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":142},"sourceArrival":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":38},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":30},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":150},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":734},{"x":144,"y":670},{"x":144,"y":414},{"x":144,"y":350}],"textPositions":{"0":{"x":156,"y":716},"1":{"x":132,"y":688},"2":{"x":132,"y":368},"3":{"x":156,"y":396},"4":{"x":132,"y":542},"5":{"x":132,"y":542},"6":{"x":156,"y":542}}},"warnings":null},{"id":558,"sourceNodeId":133,"sourcePortId":1131,"targetNodeId":144,"targetPortId":1132,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":152},"sourceArrival":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":28},"targetDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"targetArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":162},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":94},{"x":208,"y":30},{"x":208,"y":-290},{"x":208,"y":-354}],"textPositions":{"0":{"x":220,"y":76},"1":{"x":196,"y":48},"2":{"x":196,"y":-336},"3":{"x":220,"y":-308},"4":{"x":196,"y":-130},"5":{"x":196,"y":-130},"6":{"x":220,"y":-130}}},"warnings":null},{"id":559,"sourceNodeId":144,"sourcePortId":1133,"targetNodeId":145,"targetPortId":1134,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":162},"sourceArrival":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":167},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":272,"y":-450},{"x":272,"y":-514},{"x":272,"y":-798},{"x":272,"y":-862}],"textPositions":{"0":{"x":284,"y":-468},"1":{"x":260,"y":-496},"2":{"x":260,"y":-844},"3":{"x":284,"y":-816},"4":{"x":260,"y":-656},"5":{"x":260,"y":-656},"6":{"x":284,"y":-656}}},"warnings":null},{"id":560,"sourceNodeId":145,"sourcePortId":1135,"targetNodeId":146,"targetPortId":1136,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":167},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":8},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":172},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":272,"y":-930},{"x":272,"y":-994},{"x":272,"y":-1278},{"x":272,"y":-1342}],"textPositions":{"0":{"x":284,"y":-948},"1":{"x":260,"y":-976},"2":{"x":260,"y":-1324},"3":{"x":284,"y":-1296},"4":{"x":260,"y":-1136},"5":{"x":260,"y":-1136},"6":{"x":284,"y":-1136}}},"warnings":null},{"id":561,"sourceNodeId":146,"sourcePortId":1137,"targetNodeId":134,"targetPortId":1138,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":172},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":8},"targetDeparture":{"lock":false,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":3},"targetArrival":{"lock":false,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":177},"numberOfStops":0,"trainrunId":83,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":272,"y":-1410},{"x":272,"y":-1474},{"x":272,"y":-1758},{"x":272,"y":-1822}],"textPositions":{"0":{"x":284,"y":-1428},"1":{"x":260,"y":-1456},"2":{"x":260,"y":-1804},"3":{"x":284,"y":-1776},"4":{"x":260,"y":-1616},"5":{"x":260,"y":-1616},"6":{"x":284,"y":-1616}}},"warnings":null},{"id":562,"sourceNodeId":135,"sourcePortId":1139,"targetNodeId":150,"targetPortId":1140,"travelTime":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":9},"sourceArrival":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":291},"targetDeparture":{"lock":true,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":279},"targetArrival":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":21},"numberOfStops":1,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":176},{"x":2914,"y":176},{"x":3230,"y":176},{"x":3294,"y":176}],"textPositions":{"0":{"x":2868,"y":188},"1":{"x":2896,"y":164},"2":{"x":3276,"y":164},"3":{"x":3248,"y":188},"4":{"x":3072,"y":164},"5":{"x":3072,"y":164},"6":{"x":3072,"y":188}}},"warnings":null},{"id":563,"sourceNodeId":150,"sourcePortId":1141,"targetNodeId":151,"targetPortId":1142,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":23},"sourceArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":277},"targetDeparture":{"lock":true,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":264},"targetArrival":{"lock":true,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":36},"numberOfStops":0,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3394,"y":176},{"x":3458,"y":176},{"x":3806,"y":176},{"x":3870,"y":176}],"textPositions":{"0":{"x":3412,"y":188},"1":{"x":3440,"y":164},"2":{"x":3852,"y":164},"3":{"x":3824,"y":188},"4":{"x":3632,"y":164},"5":{"x":3632,"y":164},"6":{"x":3632,"y":188}}},"warnings":null},{"id":564,"sourceNodeId":151,"sourcePortId":1143,"targetNodeId":137,"targetPortId":1144,"travelTime":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":38},"sourceArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":262},"targetDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":218},"targetArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":82},"numberOfStops":4,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3970,"y":176},{"x":4034,"y":176},{"x":4574,"y":176},{"x":4638,"y":176}],"textPositions":{"0":{"x":3988,"y":188},"1":{"x":4016,"y":164},"2":{"x":4620,"y":164},"3":{"x":4592,"y":188},"4":{"x":4304,"y":164},"5":{"x":4304,"y":164},"6":{"x":4304,"y":188}}},"warnings":null},{"id":565,"sourceNodeId":137,"sourcePortId":1145,"targetNodeId":140,"targetPortId":1146,"travelTime":{"lock":true,"time":61,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":84},"sourceArrival":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":216},"targetDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":155},"targetArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":145},"numberOfStops":5,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4656,"y":222},{"x":4656,"y":286},{"x":4656,"y":1118},{"x":4656,"y":1182}],"textPositions":{"0":{"x":4644,"y":240},"1":{"x":4668,"y":268},"2":{"x":4668,"y":1164},"3":{"x":4644,"y":1136},"4":{"x":4644,"y":702},"5":{"x":4644,"y":702},"6":{"x":4668,"y":702}}},"warnings":null},{"id":566,"sourceNodeId":140,"sourcePortId":1147,"targetNodeId":152,"targetPortId":1148,"travelTime":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":146},"sourceArrival":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":154},"targetDeparture":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":132},"targetArrival":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":168},"numberOfStops":2,"trainrunId":84,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4688,"y":1278},{"x":4688,"y":1342},{"x":4688,"y":1822},{"x":4688,"y":1886}],"textPositions":{"0":{"x":4676,"y":1296},"1":{"x":4700,"y":1324},"2":{"x":4700,"y":1868},"3":{"x":4676,"y":1840},"4":{"x":4676,"y":1582},"5":{"x":4676,"y":1582},"6":{"x":4700,"y":1582}}},"warnings":null},{"id":567,"sourceNodeId":135,"sourcePortId":1149,"targetNodeId":170,"targetPortId":1150,"travelTime":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":67},"sourceArrival":{"lock":true,"time":53,"warning":null,"timeFormatter":null,"consecutiveTime":293},"targetDeparture":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":285},"targetArrival":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":75},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2704,"y":350},{"x":2704,"y":414},{"x":2704,"y":670},{"x":2704,"y":734}],"textPositions":{"0":{"x":2692,"y":368},"1":{"x":2716,"y":396},"2":{"x":2716,"y":716},"3":{"x":2692,"y":688},"4":{"x":2692,"y":542},"5":{"x":2692,"y":542},"6":{"x":2716,"y":542}}},"warnings":null},{"id":568,"sourceNodeId":140,"sourcePortId":1151,"targetNodeId":152,"targetPortId":1152,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":123},"sourceArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":237},"targetDeparture":{"lock":true,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":218},"targetArrival":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":142},"numberOfStops":1,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4656,"y":1278},{"x":4656,"y":1342},{"x":4656,"y":1822},{"x":4656,"y":1886}],"textPositions":{"0":{"x":4644,"y":1296},"1":{"x":4668,"y":1324},"2":{"x":4668,"y":1868},"3":{"x":4644,"y":1840},"4":{"x":4644,"y":1582},"5":{"x":4644,"y":1582},"6":{"x":4668,"y":1582}}},"warnings":null},{"id":569,"sourceNodeId":135,"sourcePortId":1153,"targetNodeId":170,"targetPortId":1154,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":132},"sourceArrival":{"lock":false,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":288},"targetDeparture":{"lock":true,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":280},"targetArrival":{"lock":true,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":140},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2736,"y":350},{"x":2736,"y":414},{"x":2736,"y":670},{"x":2736,"y":734}],"textPositions":{"0":{"x":2724,"y":368},"1":{"x":2748,"y":396},"2":{"x":2748,"y":716},"3":{"x":2724,"y":688},"4":{"x":2724,"y":542},"5":{"x":2724,"y":542},"6":{"x":2748,"y":542}}},"warnings":null},{"id":570,"sourceNodeId":140,"sourcePortId":1155,"targetNodeId":152,"targetPortId":1156,"travelTime":{"lock":true,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":203},"sourceArrival":{"lock":true,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":217},"targetDeparture":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":197},"targetArrival":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":223},"numberOfStops":1,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4720,"y":1278},{"x":4720,"y":1342},{"x":4720,"y":1822},{"x":4720,"y":1886}],"textPositions":{"0":{"x":4708,"y":1296},"1":{"x":4732,"y":1324},"2":{"x":4732,"y":1868},"3":{"x":4708,"y":1840},"4":{"x":4708,"y":1582},"5":{"x":4708,"y":1582},"6":{"x":4732,"y":1582}}},"warnings":null},{"id":571,"sourceNodeId":135,"sourcePortId":1157,"targetNodeId":149,"targetPortId":1158,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":294},"sourceArrival":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":126},"targetDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":119},"targetArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":301},"numberOfStops":1,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":240},{"x":2590,"y":240},{"x":2402,"y":240},{"x":2338,"y":240}],"textPositions":{"0":{"x":2636,"y":228},"1":{"x":2608,"y":252},"2":{"x":2356,"y":252},"3":{"x":2384,"y":228},"4":{"x":2496,"y":228},"5":{"x":2496,"y":228},"6":{"x":2496,"y":252}}},"warnings":null},{"id":572,"sourceNodeId":149,"sourcePortId":1159,"targetNodeId":166,"targetPortId":1160,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":301},"sourceArrival":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":119},"targetDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":240},{"x":2174,"y":240},{"x":1954,"y":240},{"x":1890,"y":240}],"textPositions":{"0":{"x":2220,"y":228},"1":{"x":2192,"y":252},"2":{"x":1908,"y":252},"3":{"x":1936,"y":228},"4":{"x":2064,"y":228},"5":{"x":2064,"y":228},"6":{"x":2064,"y":252}}},"warnings":null},{"id":573,"sourceNodeId":148,"sourcePortId":1161,"targetNodeId":147,"targetPortId":1162,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":315},"sourceArrival":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":105},"targetDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":98},"targetArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":322},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":240},{"x":1278,"y":240},{"x":1122,"y":240},{"x":1058,"y":240}],"textPositions":{"0":{"x":1324,"y":228},"1":{"x":1296,"y":252},"2":{"x":1076,"y":252},"3":{"x":1104,"y":228},"4":{"x":1200,"y":228},"5":{"x":1200,"y":228},"6":{"x":1200,"y":252}}},"warnings":null},{"id":574,"sourceNodeId":147,"sourcePortId":1163,"targetNodeId":133,"targetPortId":1164,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":322},"sourceArrival":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":98},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":240},{"x":894,"y":240},{"x":322,"y":240},{"x":258,"y":240}],"textPositions":{"0":{"x":940,"y":228},"1":{"x":912,"y":252},"2":{"x":276,"y":252},"3":{"x":304,"y":228},"4":{"x":608,"y":228},"5":{"x":608,"y":228},"6":{"x":608,"y":252}}},"warnings":null},{"id":575,"sourceNodeId":133,"sourcePortId":1165,"targetNodeId":172,"targetPortId":1166,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":336},"sourceArrival":{"lock":true,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":84},"targetDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":77},"targetArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":343},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":304},{"x":-2,"y":304},{"x":-446,"y":304},{"x":-510,"y":304}],"textPositions":{"0":{"x":44,"y":292},"1":{"x":16,"y":316},"2":{"x":-492,"y":316},"3":{"x":-464,"y":292},"4":{"x":-224,"y":292},"5":{"x":-224,"y":292},"6":{"x":-224,"y":316}}},"warnings":null},{"id":576,"sourceNodeId":137,"sourcePortId":1167,"targetNodeId":151,"targetPortId":1168,"travelTime":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":298},"sourceArrival":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":242},"targetDeparture":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":209},"targetArrival":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":331},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4638,"y":144},{"x":4574,"y":144},{"x":4034,"y":144},{"x":3970,"y":144}],"textPositions":{"0":{"x":4620,"y":132},"1":{"x":4592,"y":156},"2":{"x":3988,"y":156},"3":{"x":4016,"y":132},"4":{"x":4304,"y":132},"5":{"x":4304,"y":132},"6":{"x":4304,"y":156}}},"warnings":null},{"id":577,"sourceNodeId":151,"sourcePortId":1169,"targetNodeId":150,"targetPortId":1170,"travelTime":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":333},"sourceArrival":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":207},"targetDeparture":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":193},"targetArrival":{"lock":true,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3870,"y":80},{"x":3806,"y":80},{"x":3458,"y":80},{"x":3394,"y":80}],"textPositions":{"0":{"x":3852,"y":68},"1":{"x":3824,"y":92},"2":{"x":3412,"y":92},"3":{"x":3440,"y":68},"4":{"x":3632,"y":68},"5":{"x":3632,"y":68},"6":{"x":3632,"y":92}}},"warnings":null},{"id":578,"sourceNodeId":150,"sourcePortId":1171,"targetNodeId":135,"targetPortId":1172,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":348},"sourceArrival":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":192},"targetDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":183},"targetArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":357},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3294,"y":80},{"x":3230,"y":80},{"x":2914,"y":80},{"x":2850,"y":80}],"textPositions":{"0":{"x":3276,"y":68},"1":{"x":3248,"y":92},"2":{"x":2868,"y":92},"3":{"x":2896,"y":68},"4":{"x":3072,"y":68},"5":{"x":3072,"y":68},"6":{"x":3072,"y":92}}},"warnings":null},{"id":579,"sourceNodeId":135,"sourcePortId":1173,"targetNodeId":149,"targetPortId":1174,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":364},"sourceArrival":{"lock":true,"time":56,"warning":{"title":"Quelle Ankunft Warnung","description":"Quellankunftszeit kann nicht erreicht werden"},"timeFormatter":null,"consecutiveTime":176},"targetDeparture":{"lock":false,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":170},"targetArrival":{"lock":false,"time":10,"warning":{"title":"Ziel Ankunft Warnung","description":"Zielankunftszeit kann nicht erreicht werden"},"timeFormatter":null,"consecutiveTime":370},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":144},{"x":2590,"y":144},{"x":2402,"y":144},{"x":2338,"y":144}],"textPositions":{"0":{"x":2636,"y":132},"1":{"x":2608,"y":156},"2":{"x":2356,"y":156},"3":{"x":2384,"y":132},"4":{"x":2496,"y":132},"5":{"x":2496,"y":132},"6":{"x":2496,"y":156}}},"warnings":null},{"id":580,"sourceNodeId":149,"sourcePortId":1175,"targetNodeId":166,"targetPortId":1176,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":370},"sourceArrival":{"lock":false,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":170},"targetDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":377},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":144},{"x":2174,"y":144},{"x":1954,"y":144},{"x":1890,"y":144}],"textPositions":{"0":{"x":2220,"y":132},"1":{"x":2192,"y":156},"2":{"x":1908,"y":156},"3":{"x":1936,"y":132},"4":{"x":2064,"y":132},"5":{"x":2064,"y":132},"6":{"x":2064,"y":156}}},"warnings":null},{"id":581,"sourceNodeId":148,"sourcePortId":1177,"targetNodeId":147,"targetPortId":1178,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":384},"sourceArrival":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":156},"targetDeparture":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":151},"targetArrival":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":389},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":144},{"x":1278,"y":144},{"x":1122,"y":144},{"x":1058,"y":144}],"textPositions":{"0":{"x":1324,"y":132},"1":{"x":1296,"y":156},"2":{"x":1076,"y":156},"3":{"x":1104,"y":132},"4":{"x":1200,"y":132},"5":{"x":1200,"y":132},"6":{"x":1200,"y":156}}},"warnings":null},{"id":582,"sourceNodeId":147,"sourcePortId":1179,"targetNodeId":133,"targetPortId":1180,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":391},"sourceArrival":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":149},"targetDeparture":{"lock":true,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":140},"targetArrival":{"lock":true,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":400},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":144},{"x":894,"y":144},{"x":322,"y":144},{"x":258,"y":144}],"textPositions":{"0":{"x":940,"y":132},"1":{"x":912,"y":156},"2":{"x":276,"y":156},"3":{"x":304,"y":132},"4":{"x":608,"y":132},"5":{"x":608,"y":132},"6":{"x":608,"y":156}}},"warnings":null},{"id":583,"sourceNodeId":133,"sourcePortId":1181,"targetNodeId":175,"targetPortId":1182,"travelTime":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":402},"sourceArrival":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":138},"targetDeparture":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":121},"targetArrival":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":419},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":112},{"x":-2,"y":112},{"x":-1534,"y":-16},{"x":-1598,"y":-16}],"textPositions":{"0":{"x":44,"y":100},"1":{"x":16,"y":124},"2":{"x":-1580,"y":-4},"3":{"x":-1552,"y":-28},"4":{"x":-768,"y":36},"5":{"x":-768,"y":36},"6":{"x":-768,"y":60}}},"warnings":null},{"id":584,"sourceNodeId":130,"sourcePortId":1183,"targetNodeId":177,"targetPortId":1184,"travelTime":{"lock":false,"time":61,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":437},"sourceArrival":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":103},"targetDeparture":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":42},"targetArrival":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":498},"numberOfStops":2,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2530,"y":-16},{"x":-2594,"y":-16},{"x":-3358,"y":560},{"x":-3422,"y":560}],"textPositions":{"0":{"x":-2548,"y":-28},"1":{"x":-2576,"y":-4},"2":{"x":-3404,"y":572},"3":{"x":-3376,"y":548},"4":{"x":-2976,"y":260},"5":{"x":-2976,"y":260},"6":{"x":-2976,"y":284}}},"warnings":null},{"id":585,"sourceNodeId":160,"sourcePortId":1185,"targetNodeId":161,"targetPortId":1186,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":528},"sourceArrival":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":12},"targetDeparture":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":4},"targetArrival":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":536},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3938,"y":656},{"x":-4002,"y":656},{"x":-4190,"y":656},{"x":-4254,"y":656}],"textPositions":{"0":{"x":-3956,"y":644},"1":{"x":-3984,"y":668},"2":{"x":-4236,"y":668},"3":{"x":-4208,"y":644},"4":{"x":-4096,"y":644},"5":{"x":-4096,"y":644},"6":{"x":-4096,"y":668}}},"warnings":null},{"id":586,"sourceNodeId":128,"sourcePortId":1187,"targetNodeId":177,"targetPortId":1188,"travelTime":{"lock":false,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":439},"sourceArrival":{"lock":true,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":101},"targetDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":450},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3074,"y":592},{"x":-3138,"y":592},{"x":-3358,"y":624},{"x":-3422,"y":624}],"textPositions":{"0":{"x":-3092,"y":580},"1":{"x":-3120,"y":604},"2":{"x":-3404,"y":636},"3":{"x":-3376,"y":612},"4":{"x":-3248,"y":596},"5":{"x":-3248,"y":596},"6":{"x":-3248,"y":620}}},"warnings":null},{"id":587,"sourceNodeId":160,"sourcePortId":1189,"targetNodeId":161,"targetPortId":1190,"travelTime":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":484},"sourceArrival":{"lock":true,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":56},"targetDeparture":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":48},"targetArrival":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":492},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3938,"y":688},{"x":-4002,"y":688},{"x":-4190,"y":688},{"x":-4254,"y":688}],"textPositions":{"0":{"x":-3956,"y":676},"1":{"x":-3984,"y":700},"2":{"x":-4236,"y":700},"3":{"x":-4208,"y":676},"4":{"x":-4096,"y":676},"5":{"x":-4096,"y":676},"6":{"x":-4096,"y":700}}},"warnings":null},{"id":588,"sourceNodeId":135,"sourcePortId":1191,"targetNodeId":150,"targetPortId":1192,"travelTime":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":219},"sourceArrival":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":321},"targetDeparture":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":309},"targetArrival":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":231},"numberOfStops":1,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":48},{"x":2914,"y":48},{"x":3230,"y":48},{"x":3294,"y":48}],"textPositions":{"0":{"x":2868,"y":60},"1":{"x":2896,"y":36},"2":{"x":3276,"y":36},"3":{"x":3248,"y":60},"4":{"x":3072,"y":36},"5":{"x":3072,"y":36},"6":{"x":3072,"y":60}}},"warnings":null},{"id":589,"sourceNodeId":150,"sourcePortId":1193,"targetNodeId":151,"targetPortId":1194,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":53,"warning":null,"timeFormatter":null,"consecutiveTime":233},"sourceArrival":{"lock":false,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":307},"targetDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":294},"targetArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":246},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3394,"y":48},{"x":3458,"y":48},{"x":3806,"y":48},{"x":3870,"y":48}],"textPositions":{"0":{"x":3412,"y":60},"1":{"x":3440,"y":36},"2":{"x":3852,"y":36},"3":{"x":3824,"y":60},"4":{"x":3632,"y":36},"5":{"x":3632,"y":36},"6":{"x":3632,"y":60}}},"warnings":null},{"id":590,"sourceNodeId":135,"sourcePortId":1195,"targetNodeId":149,"targetPortId":1196,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":346},"sourceArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":194},"targetDeparture":{"lock":false,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":189},"targetArrival":{"lock":false,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":351},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":48},{"x":2590,"y":48},{"x":2402,"y":48},{"x":2338,"y":48}],"textPositions":{"0":{"x":2636,"y":36},"1":{"x":2608,"y":60},"2":{"x":2356,"y":60},"3":{"x":2384,"y":36},"4":{"x":2496,"y":36},"5":{"x":2496,"y":36},"6":{"x":2496,"y":60}}},"warnings":null},{"id":591,"sourceNodeId":149,"sourcePortId":1197,"targetNodeId":166,"targetPortId":1198,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":351},"sourceArrival":{"lock":false,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":189},"targetDeparture":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":184},"targetArrival":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":356},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":48},{"x":2174,"y":48},{"x":1954,"y":48},{"x":1890,"y":48}],"textPositions":{"0":{"x":2220,"y":36},"1":{"x":2192,"y":60},"2":{"x":1908,"y":60},"3":{"x":1936,"y":36},"4":{"x":2064,"y":36},"5":{"x":2064,"y":36},"6":{"x":2064,"y":60}}},"warnings":null},{"id":592,"sourceNodeId":148,"sourcePortId":1199,"targetNodeId":147,"targetPortId":1200,"travelTime":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":361},"sourceArrival":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":179},"targetDeparture":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":175},"targetArrival":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":365},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":48},{"x":1278,"y":48},{"x":1122,"y":48},{"x":1058,"y":48}],"textPositions":{"0":{"x":1324,"y":36},"1":{"x":1296,"y":60},"2":{"x":1076,"y":60},"3":{"x":1104,"y":36},"4":{"x":1200,"y":36},"5":{"x":1200,"y":36},"6":{"x":1200,"y":60}}},"warnings":null},{"id":593,"sourceNodeId":147,"sourcePortId":1201,"targetNodeId":133,"targetPortId":1202,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":365},"sourceArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":175},"targetDeparture":{"lock":false,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":170},"targetArrival":{"lock":false,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":370},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":112},{"x":894,"y":112},{"x":322,"y":112},{"x":258,"y":112}],"textPositions":{"0":{"x":940,"y":100},"1":{"x":912,"y":124},"2":{"x":276,"y":124},"3":{"x":304,"y":100},"4":{"x":608,"y":100},"5":{"x":608,"y":100},"6":{"x":608,"y":124}}},"warnings":null},{"id":594,"sourceNodeId":133,"sourcePortId":1203,"targetNodeId":172,"targetPortId":1204,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":370},"sourceArrival":{"lock":false,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":170},"targetDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":377},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":144},{"x":-2,"y":144},{"x":-446,"y":144},{"x":-510,"y":144}],"textPositions":{"0":{"x":44,"y":132},"1":{"x":16,"y":156},"2":{"x":-492,"y":156},"3":{"x":-464,"y":132},"4":{"x":-224,"y":132},"5":{"x":-224,"y":132},"6":{"x":-224,"y":156}}},"warnings":null},{"id":595,"sourceNodeId":129,"sourcePortId":1205,"targetNodeId":171,"targetPortId":1206,"travelTime":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":390},"sourceArrival":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":150},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":128},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":412},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2146,"y":144},{"x":-2210,"y":144},{"x":-2398,"y":304},{"x":-2462,"y":304}],"textPositions":{"0":{"x":-2164,"y":132},"1":{"x":-2192,"y":156},"2":{"x":-2444,"y":316},"3":{"x":-2416,"y":292},"4":{"x":-2304,"y":212},"5":{"x":-2304,"y":212},"6":{"x":-2304,"y":236}}},"warnings":null},{"id":596,"sourceNodeId":128,"sourcePortId":1207,"targetNodeId":177,"targetPortId":1208,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":463},"sourceArrival":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":77},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":472},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3074,"y":560},{"x":-3138,"y":560},{"x":-3358,"y":592},{"x":-3422,"y":592}],"textPositions":{"0":{"x":-3092,"y":548},"1":{"x":-3120,"y":572},"2":{"x":-3404,"y":604},"3":{"x":-3376,"y":580},"4":{"x":-3248,"y":564},"5":{"x":-3248,"y":564},"6":{"x":-3248,"y":588}}},"warnings":null},{"id":597,"sourceNodeId":160,"sourcePortId":1209,"targetNodeId":161,"targetPortId":1210,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":501},"sourceArrival":{"lock":true,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":39},"targetDeparture":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":32},"targetArrival":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":508},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3938,"y":624},{"x":-4002,"y":624},{"x":-4190,"y":624},{"x":-4254,"y":624}],"textPositions":{"0":{"x":-3956,"y":612},"1":{"x":-3984,"y":636},"2":{"x":-4236,"y":636},"3":{"x":-4208,"y":612},"4":{"x":-4096,"y":612},"5":{"x":-4096,"y":612},"6":{"x":-4096,"y":636}}},"warnings":null},{"id":598,"sourceNodeId":151,"sourcePortId":1211,"targetNodeId":137,"targetPortId":1212,"travelTime":{"lock":false,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":248},"sourceArrival":{"lock":true,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":292},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":248},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":292},"numberOfStops":4,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3970,"y":112},{"x":4034,"y":112},{"x":4574,"y":112},{"x":4638,"y":112}],"textPositions":{"0":{"x":3988,"y":124},"1":{"x":4016,"y":100},"2":{"x":4620,"y":100},"3":{"x":4592,"y":124},"4":{"x":4304,"y":100},"5":{"x":4304,"y":100},"6":{"x":4304,"y":124}}},"warnings":null},{"id":599,"sourceNodeId":135,"sourcePortId":1213,"targetNodeId":150,"targetPortId":1214,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":125},"sourceArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":295},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":286},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":112},{"x":2914,"y":112},{"x":3230,"y":112},{"x":3294,"y":112}],"textPositions":{"0":{"x":2868,"y":124},"1":{"x":2896,"y":100},"2":{"x":3276,"y":100},"3":{"x":3248,"y":124},"4":{"x":3072,"y":100},"5":{"x":3072,"y":100},"6":{"x":3072,"y":124}}},"warnings":null},{"id":600,"sourceNodeId":150,"sourcePortId":1215,"targetNodeId":151,"targetPortId":1216,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":136},"sourceArrival":{"lock":false,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":284},"targetDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":271},"targetArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":149},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3394,"y":112},{"x":3458,"y":112},{"x":3806,"y":112},{"x":3870,"y":112}],"textPositions":{"0":{"x":3412,"y":124},"1":{"x":3440,"y":100},"2":{"x":3852,"y":100},"3":{"x":3824,"y":124},"4":{"x":3632,"y":100},"5":{"x":3632,"y":100},"6":{"x":3632,"y":124}}},"warnings":null},{"id":601,"sourceNodeId":135,"sourcePortId":1217,"targetNodeId":149,"targetPortId":1218,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":302},"sourceArrival":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":118},"targetDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":176},{"x":2590,"y":176},{"x":2402,"y":176},{"x":2338,"y":176}],"textPositions":{"0":{"x":2636,"y":164},"1":{"x":2608,"y":188},"2":{"x":2356,"y":188},"3":{"x":2384,"y":164},"4":{"x":2496,"y":164},"5":{"x":2496,"y":164},"6":{"x":2496,"y":188}}},"warnings":null},{"id":602,"sourceNodeId":149,"sourcePortId":1219,"targetNodeId":166,"targetPortId":1220,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":176},{"x":2174,"y":176},{"x":1954,"y":176},{"x":1890,"y":176}],"textPositions":{"0":{"x":2220,"y":164},"1":{"x":2192,"y":188},"2":{"x":1908,"y":188},"3":{"x":1936,"y":164},"4":{"x":2064,"y":164},"5":{"x":2064,"y":164},"6":{"x":2064,"y":188}}},"warnings":null},{"id":603,"sourceNodeId":148,"sourcePortId":1221,"targetNodeId":147,"targetPortId":1222,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":320},"sourceArrival":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":100},"targetDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":95},"targetArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":325},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":176},{"x":1278,"y":176},{"x":1122,"y":176},{"x":1058,"y":176}],"textPositions":{"0":{"x":1324,"y":164},"1":{"x":1296,"y":188},"2":{"x":1076,"y":188},"3":{"x":1104,"y":164},"4":{"x":1200,"y":164},"5":{"x":1200,"y":164},"6":{"x":1200,"y":188}}},"warnings":null},{"id":604,"sourceNodeId":147,"sourcePortId":1223,"targetNodeId":133,"targetPortId":1224,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":325},"sourceArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":95},"targetDeparture":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetArrival":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":176},{"x":894,"y":176},{"x":322,"y":176},{"x":258,"y":176}],"textPositions":{"0":{"x":940,"y":164},"1":{"x":912,"y":188},"2":{"x":276,"y":188},"3":{"x":304,"y":164},"4":{"x":608,"y":164},"5":{"x":608,"y":164},"6":{"x":608,"y":188}}},"warnings":null},{"id":605,"sourceNodeId":133,"sourcePortId":1225,"targetNodeId":172,"targetPortId":1226,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"sourceArrival":{"lock":true,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":83},"targetArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":337},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":240},{"x":-2,"y":240},{"x":-446,"y":240},{"x":-510,"y":240}],"textPositions":{"0":{"x":44,"y":228},"1":{"x":16,"y":252},"2":{"x":-492,"y":252},"3":{"x":-464,"y":228},"4":{"x":-224,"y":228},"5":{"x":-224,"y":228},"6":{"x":-224,"y":252}}},"warnings":null},{"id":606,"sourceNodeId":151,"sourcePortId":1227,"targetNodeId":162,"targetPortId":1228,"travelTime":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":151},"sourceArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":269},"targetDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":218},"targetArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":202},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3970,"y":48},{"x":4034,"y":48},{"x":4574,"y":-176},{"x":4638,"y":-176}],"textPositions":{"0":{"x":3988,"y":60},"1":{"x":4016,"y":36},"2":{"x":4620,"y":-188},"3":{"x":4592,"y":-164},"4":{"x":4304,"y":-76},"5":{"x":4304,"y":-76},"6":{"x":4304,"y":-52}}},"warnings":null},{"id":607,"sourceNodeId":135,"sourcePortId":1229,"targetNodeId":150,"targetPortId":1230,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":125},"sourceArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":295},"targetDeparture":{"lock":true,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":286},"targetArrival":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":144},{"x":2914,"y":144},{"x":3230,"y":144},{"x":3294,"y":144}],"textPositions":{"0":{"x":2868,"y":156},"1":{"x":2896,"y":132},"2":{"x":3276,"y":132},"3":{"x":3248,"y":156},"4":{"x":3072,"y":132},"5":{"x":3072,"y":132},"6":{"x":3072,"y":156}}},"warnings":null},{"id":608,"sourceNodeId":150,"sourcePortId":1231,"targetNodeId":151,"targetPortId":1232,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":136},"sourceArrival":{"lock":false,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":284},"targetDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":271},"targetArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":149},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3394,"y":144},{"x":3458,"y":144},{"x":3806,"y":144},{"x":3870,"y":144}],"textPositions":{"0":{"x":3412,"y":156},"1":{"x":3440,"y":132},"2":{"x":3852,"y":132},"3":{"x":3824,"y":156},"4":{"x":3632,"y":132},"5":{"x":3632,"y":132},"6":{"x":3632,"y":156}}},"warnings":null},{"id":609,"sourceNodeId":135,"sourcePortId":1233,"targetNodeId":149,"targetPortId":1234,"travelTime":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":302},"sourceArrival":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":118},"targetDeparture":{"lock":true,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":103},"targetArrival":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":317},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":208},{"x":2590,"y":208},{"x":2402,"y":208},{"x":2338,"y":208}],"textPositions":{"0":{"x":2636,"y":196},"1":{"x":2608,"y":220},"2":{"x":2356,"y":220},"3":{"x":2384,"y":196},"4":{"x":2496,"y":196},"5":{"x":2496,"y":196},"6":{"x":2496,"y":220}}},"warnings":null},{"id":610,"sourceNodeId":149,"sourcePortId":1235,"targetNodeId":166,"targetPortId":1236,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":317},"sourceArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":103},"targetDeparture":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":97},"targetArrival":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":323},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":208},{"x":2174,"y":208},{"x":1954,"y":208},{"x":1890,"y":208}],"textPositions":{"0":{"x":2220,"y":196},"1":{"x":2192,"y":220},"2":{"x":1908,"y":220},"3":{"x":1936,"y":196},"4":{"x":2064,"y":196},"5":{"x":2064,"y":196},"6":{"x":2064,"y":220}}},"warnings":null},{"id":611,"sourceNodeId":148,"sourcePortId":1237,"targetNodeId":147,"targetPortId":1238,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"sourceArrival":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":85},"targetArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":335},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":208},{"x":1278,"y":208},{"x":1122,"y":208},{"x":1058,"y":208}],"textPositions":{"0":{"x":1324,"y":196},"1":{"x":1296,"y":220},"2":{"x":1076,"y":220},"3":{"x":1104,"y":196},"4":{"x":1200,"y":196},"5":{"x":1200,"y":196},"6":{"x":1200,"y":220}}},"warnings":null},{"id":612,"sourceNodeId":147,"sourcePortId":1239,"targetNodeId":133,"targetPortId":1240,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":335},"sourceArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":85},"targetDeparture":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":80},"targetArrival":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":340},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":208},{"x":894,"y":208},{"x":322,"y":208},{"x":258,"y":208}],"textPositions":{"0":{"x":940,"y":196},"1":{"x":912,"y":220},"2":{"x":276,"y":220},"3":{"x":304,"y":196},"4":{"x":608,"y":196},"5":{"x":608,"y":196},"6":{"x":608,"y":220}}},"warnings":null},{"id":613,"sourceNodeId":133,"sourcePortId":1241,"targetNodeId":172,"targetPortId":1242,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":340},"sourceArrival":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":80},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":73},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":272},{"x":-2,"y":272},{"x":-446,"y":272},{"x":-510,"y":272}],"textPositions":{"0":{"x":44,"y":260},"1":{"x":16,"y":284},"2":{"x":-492,"y":284},"3":{"x":-464,"y":260},"4":{"x":-224,"y":260},"5":{"x":-224,"y":260},"6":{"x":-224,"y":284}}},"warnings":null},{"id":614,"sourceNodeId":151,"sourcePortId":1243,"targetNodeId":162,"targetPortId":1244,"travelTime":{"lock":true,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":151},"sourceArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":269},"targetDeparture":{"lock":false,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":228},"targetArrival":{"lock":false,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":192},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3970,"y":80},{"x":4034,"y":80},{"x":4574,"y":-144},{"x":4638,"y":-144}],"textPositions":{"0":{"x":3988,"y":92},"1":{"x":4016,"y":68},"2":{"x":4620,"y":-156},"3":{"x":4592,"y":-132},"4":{"x":4304,"y":-44},"5":{"x":4304,"y":-44},"6":{"x":4304,"y":-20}}},"warnings":null},{"id":615,"sourceNodeId":135,"sourcePortId":1245,"targetNodeId":150,"targetPortId":1246,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":95},"sourceArrival":{"lock":true,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":205},"targetDeparture":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":196},"targetArrival":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":104},"numberOfStops":0,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":208},{"x":2914,"y":208},{"x":3230,"y":208},{"x":3294,"y":208}],"textPositions":{"0":{"x":2868,"y":220},"1":{"x":2896,"y":196},"2":{"x":3276,"y":196},"3":{"x":3248,"y":220},"4":{"x":3072,"y":196},"5":{"x":3072,"y":196},"6":{"x":3072,"y":220}}},"warnings":null},{"id":616,"sourceNodeId":150,"sourcePortId":1247,"targetNodeId":151,"targetPortId":1248,"travelTime":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"sourceArrival":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":194},"targetDeparture":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":181},"targetArrival":{"lock":true,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":119},"numberOfStops":0,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3394,"y":208},{"x":3458,"y":208},{"x":3806,"y":208},{"x":3870,"y":208}],"textPositions":{"0":{"x":3412,"y":220},"1":{"x":3440,"y":196},"2":{"x":3852,"y":196},"3":{"x":3824,"y":220},"4":{"x":3632,"y":196},"5":{"x":3632,"y":196},"6":{"x":3632,"y":220}}},"warnings":null},{"id":617,"sourceNodeId":151,"sourcePortId":1249,"targetNodeId":139,"targetPortId":1250,"travelTime":{"lock":false,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":121},"sourceArrival":{"lock":true,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":179},"targetDeparture":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":130},"targetArrival":{"lock":true,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":170},"numberOfStops":2,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":3888,"y":30},{"x":3888,"y":-34},{"x":4272,"y":-286},{"x":4272,"y":-350}],"textPositions":{"0":{"x":3900,"y":12},"1":{"x":3876,"y":-16},"2":{"x":4260,"y":-332},"3":{"x":4284,"y":-304},"4":{"x":4068,"y":-160},"5":{"x":4068,"y":-160},"6":{"x":4092,"y":-160}}},"warnings":null},{"id":618,"sourceNodeId":138,"sourcePortId":1251,"targetNodeId":163,"targetPortId":1252,"travelTime":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":0},"sourceArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"targetDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":59},"targetArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":1},"numberOfStops":0,"trainrunId":91,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":-1054},{"x":2672,"y":-990},{"x":2800,"y":-610},{"x":2800,"y":-546}],"textPositions":{"0":{"x":2660,"y":-1036},"1":{"x":2684,"y":-1008},"2":{"x":2812,"y":-564},"3":{"x":2788,"y":-592},"4":{"x":2748,"y":-800},"5":{"x":2748,"y":-800},"6":{"x":2724,"y":-800}}},"warnings":null},{"id":619,"sourceNodeId":163,"sourcePortId":1253,"targetNodeId":135,"targetPortId":1254,"travelTime":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":3},"sourceArrival":{"lock":false,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":57},"targetDeparture":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":56},"targetArrival":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":4},"numberOfStops":0,"trainrunId":91,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2800,"y":-478},{"x":2800,"y":-414},{"x":2704,"y":-34},{"x":2704,"y":30}],"textPositions":{"0":{"x":2788,"y":-460},"1":{"x":2812,"y":-432},"2":{"x":2716,"y":12},"3":{"x":2692,"y":-16},"4":{"x":2740,"y":-224},"5":{"x":2740,"y":-224},"6":{"x":2764,"y":-224}}},"warnings":null},{"id":620,"sourceNodeId":135,"sourcePortId":1255,"targetNodeId":138,"targetPortId":1256,"travelTime":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":120},"sourceArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"targetDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":59},"targetArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":121},"numberOfStops":0,"trainrunId":92,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":30},{"x":2672,"y":-34},{"x":2640,"y":-990},{"x":2640,"y":-1054}],"textPositions":{"0":{"x":2684,"y":12},"1":{"x":2660,"y":-16},"2":{"x":2628,"y":-1036},"3":{"x":2652,"y":-1008},"4":{"x":2668,"y":-512},"5":{"x":2668,"y":-512},"6":{"x":2644,"y":-512}}},"warnings":null},{"id":621,"sourceNodeId":166,"sourcePortId":1257,"targetNodeId":148,"targetPortId":1258,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":356},"sourceArrival":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":184},"targetDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":179},"targetArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":361},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":48},{"x":1726,"y":48},{"x":1506,"y":48},{"x":1442,"y":48}],"textPositions":{"0":{"x":1772,"y":36},"1":{"x":1744,"y":60},"2":{"x":1460,"y":60},"3":{"x":1488,"y":36},"4":{"x":1616,"y":36},"5":{"x":1616,"y":36},"6":{"x":1616,"y":60}}},"warnings":null},{"id":622,"sourceNodeId":166,"sourcePortId":1259,"targetNodeId":148,"targetPortId":1260,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":377},"sourceArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetDeparture":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":156},"targetArrival":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":384},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":144},{"x":1726,"y":144},{"x":1506,"y":144},{"x":1442,"y":144}],"textPositions":{"0":{"x":1772,"y":132},"1":{"x":1744,"y":156},"2":{"x":1460,"y":156},"3":{"x":1488,"y":132},"4":{"x":1616,"y":132},"5":{"x":1616,"y":132},"6":{"x":1616,"y":156}}},"warnings":null},{"id":623,"sourceNodeId":166,"sourcePortId":1261,"targetNodeId":148,"targetPortId":1262,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"sourceArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"targetDeparture":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":100},"targetArrival":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":320},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":176},{"x":1726,"y":176},{"x":1506,"y":176},{"x":1442,"y":176}],"textPositions":{"0":{"x":1772,"y":164},"1":{"x":1744,"y":188},"2":{"x":1460,"y":188},"3":{"x":1488,"y":164},"4":{"x":1616,"y":164},"5":{"x":1616,"y":164},"6":{"x":1616,"y":188}}},"warnings":null},{"id":624,"sourceNodeId":166,"sourcePortId":1263,"targetNodeId":148,"targetPortId":1264,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":325},"sourceArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":95},"targetDeparture":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetArrival":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":330},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":208},{"x":1726,"y":208},{"x":1506,"y":208},{"x":1442,"y":208}],"textPositions":{"0":{"x":1772,"y":196},"1":{"x":1744,"y":220},"2":{"x":1460,"y":220},"3":{"x":1488,"y":196},"4":{"x":1616,"y":196},"5":{"x":1616,"y":196},"6":{"x":1616,"y":220}}},"warnings":null},{"id":625,"sourceNodeId":166,"sourcePortId":1265,"targetNodeId":148,"targetPortId":1266,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetDeparture":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":105},"targetArrival":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":315},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":240},{"x":1726,"y":240},{"x":1506,"y":240},{"x":1442,"y":240}],"textPositions":{"0":{"x":1772,"y":228},"1":{"x":1744,"y":252},"2":{"x":1460,"y":252},"3":{"x":1488,"y":228},"4":{"x":1616,"y":228},"5":{"x":1616,"y":228},"6":{"x":1616,"y":252}}},"warnings":null},{"id":626,"sourceNodeId":134,"sourcePortId":1267,"targetNodeId":164,"targetPortId":1268,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":11},"sourceArrival":{"lock":false,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":169},"targetDeparture":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":156},"targetArrival":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":24},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":322,"y":-1872},{"x":386,"y":-1872},{"x":990,"y":-944},{"x":1054,"y":-944}],"textPositions":{"0":{"x":340,"y":-1860},"1":{"x":368,"y":-1884},"2":{"x":1036,"y":-956},"3":{"x":1008,"y":-932},"4":{"x":688,"y":-1420},"5":{"x":688,"y":-1420},"6":{"x":688,"y":-1396}}},"warnings":null},{"id":627,"sourceNodeId":164,"sourcePortId":1269,"targetNodeId":165,"targetPortId":1270,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":25},"sourceArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":155},"targetDeparture":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":146},"targetArrival":{"lock":false,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":34},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1154,"y":-944},{"x":1218,"y":-944},{"x":1726,"y":-656},{"x":1790,"y":-656}],"textPositions":{"0":{"x":1172,"y":-932},"1":{"x":1200,"y":-956},"2":{"x":1772,"y":-668},"3":{"x":1744,"y":-644},"4":{"x":1472,"y":-812},"5":{"x":1472,"y":-812},"6":{"x":1472,"y":-788}}},"warnings":null},{"id":628,"sourceNodeId":165,"sourcePortId":1271,"targetNodeId":166,"targetPortId":1272,"travelTime":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"sourceArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":145},"targetDeparture":{"lock":false,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":123},"targetArrival":{"lock":false,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":57},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1808,"y":-606},{"x":1808,"y":-542},{"x":1808,"y":-34},{"x":1808,"y":30}],"textPositions":{"0":{"x":1796,"y":-588},"1":{"x":1820,"y":-560},"2":{"x":1820,"y":12},"3":{"x":1796,"y":-16},"4":{"x":1796,"y":-288},"5":{"x":1796,"y":-288},"6":{"x":1820,"y":-288}}},"warnings":null},{"id":629,"sourceNodeId":166,"sourcePortId":1273,"targetNodeId":149,"targetPortId":1274,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"sourceArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":120},"targetDeparture":{"lock":false,"time":53,"warning":null,"timeFormatter":null,"consecutiveTime":113},"targetArrival":{"lock":false,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":67},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1890,"y":272},{"x":1954,"y":272},{"x":2174,"y":272},{"x":2238,"y":272}],"textPositions":{"0":{"x":1908,"y":284},"1":{"x":1936,"y":260},"2":{"x":2220,"y":260},"3":{"x":2192,"y":284},"4":{"x":2064,"y":260},"5":{"x":2064,"y":260},"6":{"x":2064,"y":284}}},"warnings":null},{"id":630,"sourceNodeId":149,"sourcePortId":1275,"targetNodeId":135,"targetPortId":1276,"travelTime":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetDeparture":{"lock":false,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":96},"targetArrival":{"lock":false,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":84},"numberOfStops":0,"trainrunId":93,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2338,"y":272},{"x":2402,"y":272},{"x":2590,"y":272},{"x":2654,"y":272}],"textPositions":{"0":{"x":2356,"y":284},"1":{"x":2384,"y":260},"2":{"x":2636,"y":260},"3":{"x":2608,"y":284},"4":{"x":2496,"y":260},"5":{"x":2496,"y":260},"6":{"x":2496,"y":284}}},"warnings":null},{"id":631,"sourceNodeId":134,"sourcePortId":1277,"targetNodeId":146,"targetPortId":1278,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":6},"sourceArrival":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":174},"targetDeparture":{"lock":false,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":169},"targetArrival":{"lock":false,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":11},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":-1822},{"x":144,"y":-1758},{"x":144,"y":-1474},{"x":144,"y":-1410}],"textPositions":{"0":{"x":132,"y":-1804},"1":{"x":156,"y":-1776},"2":{"x":156,"y":-1428},"3":{"x":132,"y":-1456},"4":{"x":132,"y":-1616},"5":{"x":132,"y":-1616},"6":{"x":156,"y":-1616}}},"warnings":null},{"id":632,"sourceNodeId":146,"sourcePortId":1279,"targetNodeId":145,"targetPortId":1280,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":11},"sourceArrival":{"lock":false,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":169},"targetDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":17},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":-1342},{"x":144,"y":-1278},{"x":144,"y":-994},{"x":144,"y":-930}],"textPositions":{"0":{"x":132,"y":-1324},"1":{"x":156,"y":-1296},"2":{"x":156,"y":-948},"3":{"x":132,"y":-976},"4":{"x":132,"y":-1136},"5":{"x":132,"y":-1136},"6":{"x":156,"y":-1136}}},"warnings":null},{"id":633,"sourceNodeId":145,"sourcePortId":1281,"targetNodeId":144,"targetPortId":1282,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":17},"sourceArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetDeparture":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":157},"targetArrival":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":23},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":-862},{"x":144,"y":-798},{"x":144,"y":-514},{"x":144,"y":-450}],"textPositions":{"0":{"x":132,"y":-844},"1":{"x":156,"y":-816},"2":{"x":156,"y":-468},"3":{"x":132,"y":-496},"4":{"x":132,"y":-656},"5":{"x":132,"y":-656},"6":{"x":156,"y":-656}}},"warnings":null},{"id":634,"sourceNodeId":144,"sourcePortId":1283,"targetNodeId":147,"targetPortId":1284,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":23},"sourceArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":157},"targetDeparture":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":147},"targetArrival":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":33},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":322,"y":-400},{"x":386,"y":-400},{"x":894,"y":80},{"x":958,"y":80}],"textPositions":{"0":{"x":340,"y":-388},"1":{"x":368,"y":-412},"2":{"x":940,"y":68},"3":{"x":912,"y":92},"4":{"x":640,"y":-172},"5":{"x":640,"y":-172},"6":{"x":640,"y":-148}}},"warnings":null},{"id":635,"sourceNodeId":147,"sourcePortId":1285,"targetNodeId":148,"targetPortId":1286,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":33},"sourceArrival":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":147},"targetDeparture":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":140},"targetArrival":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":40},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1058,"y":112},{"x":1122,"y":112},{"x":1278,"y":112},{"x":1342,"y":112}],"textPositions":{"0":{"x":1076,"y":124},"1":{"x":1104,"y":100},"2":{"x":1324,"y":100},"3":{"x":1296,"y":124},"4":{"x":1200,"y":100},"5":{"x":1200,"y":100},"6":{"x":1200,"y":124}}},"warnings":null},{"id":636,"sourceNodeId":148,"sourcePortId":1287,"targetNodeId":166,"targetPortId":1288,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":40},"sourceArrival":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":140},"targetDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"targetArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1442,"y":112},{"x":1506,"y":112},{"x":1726,"y":112},{"x":1790,"y":112}],"textPositions":{"0":{"x":1460,"y":124},"1":{"x":1488,"y":100},"2":{"x":1772,"y":100},"3":{"x":1744,"y":124},"4":{"x":1616,"y":100},"5":{"x":1616,"y":100},"6":{"x":1616,"y":124}}},"warnings":null},{"id":637,"sourceNodeId":166,"sourcePortId":1289,"targetNodeId":149,"targetPortId":1290,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"sourceArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":134},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":128},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1890,"y":112},{"x":1954,"y":112},{"x":2174,"y":112},{"x":2238,"y":112}],"textPositions":{"0":{"x":1908,"y":124},"1":{"x":1936,"y":100},"2":{"x":2220,"y":100},"3":{"x":2192,"y":124},"4":{"x":2064,"y":100},"5":{"x":2064,"y":100},"6":{"x":2064,"y":124}}},"warnings":null},{"id":638,"sourceNodeId":149,"sourcePortId":1291,"targetNodeId":135,"targetPortId":1292,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":128},"targetDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":120},"targetArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"numberOfStops":0,"trainrunId":94,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2338,"y":112},{"x":2402,"y":112},{"x":2590,"y":112},{"x":2654,"y":112}],"textPositions":{"0":{"x":2356,"y":124},"1":{"x":2384,"y":100},"2":{"x":2636,"y":100},"3":{"x":2608,"y":124},"4":{"x":2496,"y":100},"5":{"x":2496,"y":100},"6":{"x":2496,"y":124}}},"warnings":null},{"id":639,"sourceNodeId":147,"sourcePortId":1293,"targetNodeId":148,"targetPortId":1294,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":54},"sourceArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":126},"targetDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":120},"targetArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"numberOfStops":0,"trainrunId":97,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1058,"y":272},{"x":1122,"y":272},{"x":1278,"y":272},{"x":1342,"y":272}],"textPositions":{"0":{"x":1076,"y":284},"1":{"x":1104,"y":260},"2":{"x":1324,"y":260},"3":{"x":1296,"y":284},"4":{"x":1200,"y":260},"5":{"x":1200,"y":260},"6":{"x":1200,"y":284}}},"warnings":null},{"id":640,"sourceNodeId":148,"sourcePortId":1295,"targetNodeId":166,"targetPortId":1296,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":62},"sourceArrival":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":118},"targetDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"numberOfStops":0,"trainrunId":97,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1442,"y":272},{"x":1506,"y":272},{"x":1726,"y":272},{"x":1790,"y":272}],"textPositions":{"0":{"x":1460,"y":284},"1":{"x":1488,"y":260},"2":{"x":1772,"y":260},"3":{"x":1744,"y":284},"4":{"x":1616,"y":260},"5":{"x":1616,"y":260},"6":{"x":1616,"y":284}}},"warnings":null},{"id":641,"sourceNodeId":166,"sourcePortId":1297,"targetNodeId":149,"targetPortId":1298,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetDeparture":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":105},"targetArrival":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":75},"numberOfStops":0,"trainrunId":97,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1890,"y":304},{"x":1954,"y":304},{"x":2174,"y":304},{"x":2238,"y":304}],"textPositions":{"0":{"x":1908,"y":316},"1":{"x":1936,"y":292},"2":{"x":2220,"y":292},"3":{"x":2192,"y":316},"4":{"x":2064,"y":292},"5":{"x":2064,"y":292},"6":{"x":2064,"y":316}}},"warnings":null},{"id":642,"sourceNodeId":149,"sourcePortId":1299,"targetNodeId":135,"targetPortId":1300,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":75},"sourceArrival":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":105},"targetDeparture":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":98},"targetArrival":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":82},"numberOfStops":0,"trainrunId":97,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2338,"y":304},{"x":2402,"y":304},{"x":2590,"y":304},{"x":2654,"y":304}],"textPositions":{"0":{"x":2356,"y":316},"1":{"x":2384,"y":292},"2":{"x":2636,"y":292},"3":{"x":2608,"y":316},"4":{"x":2496,"y":292},"5":{"x":2496,"y":292},"6":{"x":2496,"y":316}}},"warnings":null},{"id":643,"sourceNodeId":134,"sourcePortId":1301,"targetNodeId":146,"targetPortId":1302,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":28},"sourceArrival":{"lock":false,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":272},"targetDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":265},"targetArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":-1822},{"x":208,"y":-1758},{"x":208,"y":-1474},{"x":208,"y":-1410}],"textPositions":{"0":{"x":196,"y":-1804},"1":{"x":220,"y":-1776},"2":{"x":220,"y":-1428},"3":{"x":196,"y":-1456},"4":{"x":196,"y":-1616},"5":{"x":196,"y":-1616},"6":{"x":220,"y":-1616}}},"warnings":null},{"id":644,"sourceNodeId":146,"sourcePortId":1303,"targetNodeId":145,"targetPortId":1304,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"sourceArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":265},"targetDeparture":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":259},"targetArrival":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":-1342},{"x":208,"y":-1278},{"x":208,"y":-994},{"x":208,"y":-930}],"textPositions":{"0":{"x":196,"y":-1324},"1":{"x":220,"y":-1296},"2":{"x":220,"y":-948},"3":{"x":196,"y":-976},"4":{"x":196,"y":-1136},"5":{"x":196,"y":-1136},"6":{"x":220,"y":-1136}}},"warnings":null},{"id":645,"sourceNodeId":145,"sourcePortId":1305,"targetNodeId":144,"targetPortId":1306,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"sourceArrival":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":259},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":253},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":47},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":208,"y":-862},{"x":208,"y":-798},{"x":208,"y":-514},{"x":208,"y":-450}],"textPositions":{"0":{"x":196,"y":-844},"1":{"x":220,"y":-816},"2":{"x":220,"y":-468},"3":{"x":196,"y":-496},"4":{"x":196,"y":-656},"5":{"x":196,"y":-656},"6":{"x":220,"y":-656}}},"warnings":null},{"id":646,"sourceNodeId":144,"sourcePortId":1307,"targetNodeId":133,"targetPortId":1308,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":47},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":253},"targetDeparture":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":245},"targetArrival":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":55},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":-354},{"x":144,"y":-290},{"x":144,"y":30},{"x":144,"y":94}],"textPositions":{"0":{"x":132,"y":-336},"1":{"x":156,"y":-308},"2":{"x":156,"y":76},"3":{"x":132,"y":48},"4":{"x":132,"y":-130},"5":{"x":132,"y":-130},"6":{"x":156,"y":-130}}},"warnings":null},{"id":647,"sourceNodeId":133,"sourcePortId":1309,"targetNodeId":172,"targetPortId":1310,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":58},"sourceArrival":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":242},"targetDeparture":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":235},"targetArrival":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":62,"y":208},{"x":-2,"y":208},{"x":-446,"y":208},{"x":-510,"y":208}],"textPositions":{"0":{"x":44,"y":196},"1":{"x":16,"y":220},"2":{"x":-492,"y":220},"3":{"x":-464,"y":196},"4":{"x":-224,"y":196},"5":{"x":-224,"y":196},"6":{"x":-224,"y":220}}},"warnings":null},{"id":648,"sourceNodeId":129,"sourcePortId":1311,"targetNodeId":167,"targetPortId":1312,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":94},"sourceArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":206},"targetDeparture":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":188},"targetArrival":{"lock":true,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2096,"y":382},{"x":-2096,"y":446},{"x":-2096,"y":574},{"x":-2096,"y":638}],"textPositions":{"0":{"x":-2108,"y":400},"1":{"x":-2084,"y":428},"2":{"x":-2084,"y":620},"3":{"x":-2108,"y":592},"4":{"x":-2108,"y":510},"5":{"x":-2108,"y":510},"6":{"x":-2084,"y":510}}},"warnings":null},{"id":649,"sourceNodeId":129,"sourcePortId":1313,"targetNodeId":167,"targetPortId":1314,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":359},"sourceArrival":{"lock":false,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":61},"targetDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":43},"targetArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":377},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2064,"y":382},{"x":-2064,"y":446},{"x":-2064,"y":574},{"x":-2064,"y":638}],"textPositions":{"0":{"x":-2076,"y":400},"1":{"x":-2052,"y":428},"2":{"x":-2052,"y":620},"3":{"x":-2076,"y":592},"4":{"x":-2076,"y":510},"5":{"x":-2076,"y":510},"6":{"x":-2052,"y":510}}},"warnings":null},{"id":650,"sourceNodeId":167,"sourcePortId":1315,"targetNodeId":168,"targetPortId":1316,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":114},"sourceArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":186},"targetDeparture":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":178},"targetArrival":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":122},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2096,"y":706},{"x":-2096,"y":770},{"x":-2096,"y":862},{"x":-2096,"y":926}],"textPositions":{"0":{"x":-2108,"y":724},"1":{"x":-2084,"y":752},"2":{"x":-2084,"y":908},"3":{"x":-2108,"y":880},"4":{"x":-2108,"y":816},"5":{"x":-2108,"y":816},"6":{"x":-2084,"y":816}}},"warnings":null},{"id":651,"sourceNodeId":168,"sourcePortId":1317,"targetNodeId":131,"targetPortId":1318,"travelTime":{"lock":true,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":124},"sourceArrival":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":176},"targetDeparture":{"lock":false,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":152},"targetArrival":{"lock":false,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":148},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2014,"y":944},{"x":-1950,"y":944},{"x":-1154,"y":944},{"x":-1090,"y":944}],"textPositions":{"0":{"x":-1996,"y":956},"1":{"x":-1968,"y":932},"2":{"x":-1108,"y":932},"3":{"x":-1136,"y":956},"4":{"x":-1552,"y":932},"5":{"x":-1552,"y":932},"6":{"x":-1552,"y":956}}},"warnings":null},{"id":652,"sourceNodeId":167,"sourcePortId":1319,"targetNodeId":168,"targetPortId":1320,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":379},"sourceArrival":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"targetDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":31},"targetArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":389},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2064,"y":706},{"x":-2064,"y":770},{"x":-2064,"y":862},{"x":-2064,"y":926}],"textPositions":{"0":{"x":-2076,"y":724},"1":{"x":-2052,"y":752},"2":{"x":-2052,"y":908},"3":{"x":-2076,"y":880},"4":{"x":-2076,"y":816},"5":{"x":-2076,"y":816},"6":{"x":-2052,"y":816}}},"warnings":null},{"id":653,"sourceNodeId":168,"sourcePortId":1321,"targetNodeId":132,"targetPortId":1322,"travelTime":{"lock":true,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":391},"sourceArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":29},"targetDeparture":{"lock":false,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":4},"targetArrival":{"lock":false,"time":56,"warning":null,"timeFormatter":null,"consecutiveTime":416},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2096,"y":1022},{"x":-2096,"y":1086},{"x":-2096,"y":1374},{"x":-2096,"y":1438}],"textPositions":{"0":{"x":-2108,"y":1040},"1":{"x":-2084,"y":1068},"2":{"x":-2084,"y":1420},"3":{"x":-2108,"y":1392},"4":{"x":-2108,"y":1230},"5":{"x":-2108,"y":1230},"6":{"x":-2084,"y":1230}}},"warnings":null},{"id":654,"sourceNodeId":132,"sourcePortId":1323,"targetNodeId":168,"targetPortId":1324,"travelTime":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":149},"sourceArrival":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":151},"targetDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":125},"targetArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":175},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2128,"y":1438},{"x":-2128,"y":1374},{"x":-2128,"y":1086},{"x":-2128,"y":1022}],"textPositions":{"0":{"x":-2116,"y":1420},"1":{"x":-2140,"y":1392},"2":{"x":-2140,"y":1040},"3":{"x":-2116,"y":1068},"4":{"x":-2140,"y":1230},"5":{"x":-2140,"y":1230},"6":{"x":-2116,"y":1230}}},"warnings":null},{"id":655,"sourceNodeId":168,"sourcePortId":1325,"targetNodeId":167,"targetPortId":1326,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":178},"sourceArrival":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":122},"targetDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":114},"targetArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":186},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2128,"y":926},{"x":-2128,"y":862},{"x":-2128,"y":770},{"x":-2128,"y":706}],"textPositions":{"0":{"x":-2116,"y":908},"1":{"x":-2140,"y":880},"2":{"x":-2140,"y":724},"3":{"x":-2116,"y":752},"4":{"x":-2140,"y":816},"5":{"x":-2140,"y":816},"6":{"x":-2116,"y":816}}},"warnings":null},{"id":656,"sourceNodeId":167,"sourcePortId":1327,"targetNodeId":129,"targetPortId":1328,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":188},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":112},"targetDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":94},"targetArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":206},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2128,"y":638},{"x":-2128,"y":574},{"x":-2128,"y":446},{"x":-2128,"y":382}],"textPositions":{"0":{"x":-2116,"y":620},"1":{"x":-2140,"y":592},"2":{"x":-2140,"y":400},"3":{"x":-2116,"y":428},"4":{"x":-2140,"y":510},"5":{"x":-2140,"y":510},"6":{"x":-2116,"y":510}}},"warnings":null},{"id":657,"sourceNodeId":129,"sourcePortId":1329,"targetNodeId":178,"targetPortId":1330,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":214},"sourceArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":86},"targetDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":83},"targetArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":217},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2014,"y":176},{"x":-1950,"y":176},{"x":-1762,"y":176},{"x":-1698,"y":176}],"textPositions":{"0":{"x":-1996,"y":188},"1":{"x":-1968,"y":164},"2":{"x":-1716,"y":164},"3":{"x":-1744,"y":188},"4":{"x":-1856,"y":164},"5":{"x":-1856,"y":164},"6":{"x":-1856,"y":188}}},"warnings":null},{"id":658,"sourceNodeId":133,"sourcePortId":1331,"targetNodeId":144,"targetPortId":1332,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":245},"sourceArrival":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":55},"targetDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":47},"targetArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":253},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":94},{"x":112,"y":30},{"x":112,"y":-290},{"x":112,"y":-354}],"textPositions":{"0":{"x":124,"y":76},"1":{"x":100,"y":48},"2":{"x":100,"y":-336},"3":{"x":124,"y":-308},"4":{"x":100,"y":-130},"5":{"x":100,"y":-130},"6":{"x":124,"y":-130}}},"warnings":null},{"id":659,"sourceNodeId":144,"sourcePortId":1333,"targetNodeId":145,"targetPortId":1334,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":253},"sourceArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":47},"targetDeparture":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"targetArrival":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":259},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":-450},{"x":176,"y":-514},{"x":176,"y":-798},{"x":176,"y":-862}],"textPositions":{"0":{"x":188,"y":-468},"1":{"x":164,"y":-496},"2":{"x":164,"y":-844},"3":{"x":188,"y":-816},"4":{"x":164,"y":-656},"5":{"x":164,"y":-656},"6":{"x":188,"y":-656}}},"warnings":null},{"id":660,"sourceNodeId":145,"sourcePortId":1335,"targetNodeId":146,"targetPortId":1336,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":259},"sourceArrival":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"targetDeparture":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"targetArrival":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":265},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":-930},{"x":176,"y":-994},{"x":176,"y":-1278},{"x":176,"y":-1342}],"textPositions":{"0":{"x":188,"y":-948},"1":{"x":164,"y":-976},"2":{"x":164,"y":-1324},"3":{"x":188,"y":-1296},"4":{"x":164,"y":-1136},"5":{"x":164,"y":-1136},"6":{"x":188,"y":-1136}}},"warnings":null},{"id":661,"sourceNodeId":146,"sourcePortId":1337,"targetNodeId":134,"targetPortId":1338,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":265},"sourceArrival":{"lock":false,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":35},"targetDeparture":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":28},"targetArrival":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":272},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":-1410},{"x":176,"y":-1474},{"x":176,"y":-1758},{"x":176,"y":-1822}],"textPositions":{"0":{"x":188,"y":-1428},"1":{"x":164,"y":-1456},"2":{"x":164,"y":-1804},"3":{"x":188,"y":-1776},"4":{"x":164,"y":-1616},"5":{"x":164,"y":-1616},"6":{"x":188,"y":-1616}}},"warnings":null},{"id":662,"sourceNodeId":129,"sourcePortId":1339,"targetNodeId":167,"targetPortId":1340,"travelTime":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":368},"sourceArrival":{"lock":true,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"targetDeparture":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":33},"targetArrival":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":387},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2032,"y":382},{"x":-2032,"y":446},{"x":-2032,"y":574},{"x":-2032,"y":638}],"textPositions":{"0":{"x":-2044,"y":400},"1":{"x":-2020,"y":428},"2":{"x":-2020,"y":620},"3":{"x":-2044,"y":592},"4":{"x":-2044,"y":510},"5":{"x":-2044,"y":510},"6":{"x":-2020,"y":510}}},"warnings":null},{"id":663,"sourceNodeId":167,"sourcePortId":1341,"targetNodeId":168,"targetPortId":1342,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":388},"sourceArrival":{"lock":false,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":32},"targetDeparture":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":22},"targetArrival":{"lock":true,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":398},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2032,"y":706},{"x":-2032,"y":770},{"x":-2032,"y":862},{"x":-2032,"y":926}],"textPositions":{"0":{"x":-2044,"y":724},"1":{"x":-2020,"y":752},"2":{"x":-2020,"y":908},"3":{"x":-2044,"y":880},"4":{"x":-2044,"y":816},"5":{"x":-2044,"y":816},"6":{"x":-2020,"y":816}}},"warnings":null},{"id":664,"sourceNodeId":168,"sourcePortId":1343,"targetNodeId":131,"targetPortId":1344,"travelTime":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":399},"sourceArrival":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":21},"targetDeparture":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":0},"targetArrival":{"lock":false,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":420},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2014,"y":976},{"x":-1950,"y":976},{"x":-1154,"y":976},{"x":-1090,"y":976}],"textPositions":{"0":{"x":-1996,"y":988},"1":{"x":-1968,"y":964},"2":{"x":-1108,"y":964},"3":{"x":-1136,"y":988},"4":{"x":-1552,"y":964},"5":{"x":-1552,"y":964},"6":{"x":-1552,"y":988}}},"warnings":null},{"id":665,"sourceNodeId":169,"sourcePortId":1345,"targetNodeId":153,"targetPortId":1346,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":48,"warning":null,"timeFormatter":null,"consecutiveTime":48},"sourceArrival":{"lock":true,"time":12,"warning":null,"timeFormatter":null,"consecutiveTime":252},"targetDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":243},"targetArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":57},"numberOfStops":0,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1954,"y":1776},{"x":2018,"y":1776},{"x":2590,"y":1360},{"x":2654,"y":1360}],"textPositions":{"0":{"x":1972,"y":1788},"1":{"x":2000,"y":1764},"2":{"x":2636,"y":1348},"3":{"x":2608,"y":1372},"4":{"x":2304,"y":1556},"5":{"x":2304,"y":1556},"6":{"x":2304,"y":1580}}},"warnings":null},{"id":666,"sourceNodeId":169,"sourcePortId":1347,"targetNodeId":153,"targetPortId":1348,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":18},"sourceArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":42},"targetDeparture":{"lock":false,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":32},"targetArrival":{"lock":false,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":28},"numberOfStops":0,"trainrunId":80,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1954,"y":1744},{"x":2018,"y":1744},{"x":2590,"y":1328},{"x":2654,"y":1328}],"textPositions":{"0":{"x":1972,"y":1756},"1":{"x":2000,"y":1732},"2":{"x":2636,"y":1316},"3":{"x":2608,"y":1340},"4":{"x":2304,"y":1524},"5":{"x":2304,"y":1524},"6":{"x":2304,"y":1548}}},"warnings":null},{"id":667,"sourceNodeId":169,"sourcePortId":1349,"targetNodeId":142,"targetPortId":1350,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":453},"sourceArrival":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":147},"targetDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":138},"targetArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":462},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1854,"y":1776},{"x":1790,"y":1776},{"x":290,"y":1776},{"x":226,"y":1776}],"textPositions":{"0":{"x":1836,"y":1764},"1":{"x":1808,"y":1788},"2":{"x":244,"y":1788},"3":{"x":272,"y":1764},"4":{"x":1040,"y":1764},"5":{"x":1040,"y":1764},"6":{"x":1040,"y":1788}}},"warnings":null},{"id":668,"sourceNodeId":169,"sourcePortId":1351,"targetNodeId":142,"targetPortId":1352,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":273},"sourceArrival":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":87},"targetDeparture":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":78},"targetArrival":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":282},"numberOfStops":0,"trainrunId":75,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1854,"y":1744},{"x":1790,"y":1744},{"x":290,"y":1744},{"x":226,"y":1744}],"textPositions":{"0":{"x":1836,"y":1732},"1":{"x":1808,"y":1756},"2":{"x":244,"y":1756},"3":{"x":272,"y":1732},"4":{"x":1040,"y":1732},"5":{"x":1040,"y":1732},"6":{"x":1040,"y":1756}}},"warnings":null},{"id":669,"sourceNodeId":170,"sourcePortId":1353,"targetNodeId":135,"targetPortId":1354,"travelTime":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":74},"sourceArrival":{"lock":true,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":226},"targetDeparture":{"lock":true,"time":35,"warning":null,"timeFormatter":null,"consecutiveTime":215},"targetArrival":{"lock":true,"time":25,"warning":null,"timeFormatter":null,"consecutiveTime":85},"numberOfStops":0,"trainrunId":79,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2832,"y":734},{"x":2832,"y":670},{"x":2832,"y":414},{"x":2832,"y":350}],"textPositions":{"0":{"x":2844,"y":716},"1":{"x":2820,"y":688},"2":{"x":2820,"y":368},"3":{"x":2844,"y":396},"4":{"x":2820,"y":542},"5":{"x":2820,"y":542},"6":{"x":2844,"y":542}}},"warnings":null},{"id":670,"sourceNodeId":170,"sourcePortId":1355,"targetNodeId":135,"targetPortId":1356,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":43},"sourceArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":17},"targetDeparture":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":10},"targetArrival":{"lock":true,"time":50,"warning":null,"timeFormatter":null,"consecutiveTime":50},"numberOfStops":0,"trainrunId":80,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2800,"y":734},{"x":2800,"y":670},{"x":2800,"y":414},{"x":2800,"y":350}],"textPositions":{"0":{"x":2812,"y":716},"1":{"x":2788,"y":688},"2":{"x":2788,"y":368},"3":{"x":2812,"y":396},"4":{"x":2788,"y":542},"5":{"x":2788,"y":542},"6":{"x":2812,"y":542}}},"warnings":null},{"id":671,"sourceNodeId":170,"sourcePortId":1357,"targetNodeId":135,"targetPortId":1358,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetDeparture":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":5},"targetArrival":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":355},"numberOfStops":0,"trainrunId":78,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2768,"y":734},{"x":2768,"y":670},{"x":2768,"y":414},{"x":2768,"y":350}],"textPositions":{"0":{"x":2780,"y":716},"1":{"x":2756,"y":688},"2":{"x":2756,"y":368},"3":{"x":2780,"y":396},"4":{"x":2756,"y":542},"5":{"x":2756,"y":542},"6":{"x":2780,"y":542}}},"warnings":null},{"id":672,"sourceNodeId":170,"sourcePortId":1359,"targetNodeId":135,"targetPortId":1360,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":107},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":13},"targetDeparture":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":5},"targetArrival":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":115},"numberOfStops":0,"trainrunId":76,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2672,"y":734},{"x":2672,"y":670},{"x":2672,"y":414},{"x":2672,"y":350}],"textPositions":{"0":{"x":2684,"y":716},"1":{"x":2660,"y":688},"2":{"x":2660,"y":368},"3":{"x":2684,"y":396},"4":{"x":2660,"y":542},"5":{"x":2660,"y":542},"6":{"x":2684,"y":542}}},"warnings":null},{"id":673,"sourceNodeId":170,"sourcePortId":1361,"targetNodeId":140,"targetPortId":1362,"travelTime":{"lock":true,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":75},"sourceArrival":{"lock":false,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":285},"targetDeparture":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":238},"targetArrival":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":122},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":752},{"x":2914,"y":752},{"x":4574,"y":1200},{"x":4638,"y":1200}],"textPositions":{"0":{"x":2868,"y":764},"1":{"x":2896,"y":740},"2":{"x":4620,"y":1188},"3":{"x":4592,"y":1212},"4":{"x":3744,"y":964},"5":{"x":3744,"y":964},"6":{"x":3744,"y":988}}},"warnings":null},{"id":674,"sourceNodeId":170,"sourcePortId":1363,"targetNodeId":140,"targetPortId":1364,"travelTime":{"lock":false,"time":61,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":141},"sourceArrival":{"lock":true,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":279},"targetDeparture":{"lock":true,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":218},"targetArrival":{"lock":true,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":202},"numberOfStops":5,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2850,"y":784},{"x":2914,"y":784},{"x":4574,"y":1232},{"x":4638,"y":1232}],"textPositions":{"0":{"x":2868,"y":796},"1":{"x":2896,"y":772},"2":{"x":4620,"y":1220},"3":{"x":4592,"y":1244},"4":{"x":3744,"y":996},"5":{"x":3744,"y":996},"6":{"x":3744,"y":1020}}},"warnings":null},{"id":675,"sourceNodeId":142,"sourcePortId":1365,"targetNodeId":141,"targetPortId":1366,"travelTime":{"lock":true,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":475},"sourceArrival":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":125},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":494},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":1726},{"x":144,"y":1662},{"x":144,"y":1314},{"x":144,"y":1250}],"textPositions":{"0":{"x":156,"y":1708},"1":{"x":132,"y":1680},"2":{"x":132,"y":1268},"3":{"x":156,"y":1296},"4":{"x":132,"y":1488},"5":{"x":132,"y":1488},"6":{"x":156,"y":1488}}},"warnings":null},{"id":676,"sourceNodeId":141,"sourcePortId":1367,"targetNodeId":143,"targetPortId":1368,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":494},"sourceArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"targetDeparture":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":99},"targetArrival":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":501},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":144,"y":1182},{"x":144,"y":1118},{"x":144,"y":866},{"x":144,"y":802}],"textPositions":{"0":{"x":156,"y":1164},"1":{"x":132,"y":1136},"2":{"x":132,"y":820},"3":{"x":156,"y":848},"4":{"x":132,"y":992},"5":{"x":132,"y":992},"6":{"x":156,"y":992}}},"warnings":null},{"id":677,"sourceNodeId":143,"sourcePortId":1369,"targetNodeId":133,"targetPortId":1370,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":503},"sourceArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":97},"targetDeparture":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":90},"targetArrival":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":510},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":734},{"x":112,"y":670},{"x":112,"y":414},{"x":112,"y":350}],"textPositions":{"0":{"x":124,"y":716},"1":{"x":100,"y":688},"2":{"x":100,"y":368},"3":{"x":124,"y":396},"4":{"x":100,"y":542},"5":{"x":100,"y":542},"6":{"x":124,"y":542}}},"warnings":null},{"id":678,"sourceNodeId":133,"sourcePortId":1371,"targetNodeId":144,"targetPortId":1372,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":32,"warning":null,"timeFormatter":null,"consecutiveTime":512},"sourceArrival":{"lock":true,"time":28,"warning":null,"timeFormatter":null,"consecutiveTime":88},"targetDeparture":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":78},"targetArrival":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":522},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":176,"y":94},{"x":176,"y":30},{"x":176,"y":-290},{"x":176,"y":-354}],"textPositions":{"0":{"x":188,"y":76},"1":{"x":164,"y":48},"2":{"x":164,"y":-336},"3":{"x":188,"y":-308},"4":{"x":164,"y":-130},"5":{"x":164,"y":-130},"6":{"x":188,"y":-130}}},"warnings":null},{"id":679,"sourceNodeId":144,"sourcePortId":1373,"targetNodeId":145,"targetPortId":1374,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":522},"sourceArrival":{"lock":false,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":78},"targetDeparture":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":73},"targetArrival":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":527},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":240,"y":-450},{"x":240,"y":-514},{"x":240,"y":-798},{"x":240,"y":-862}],"textPositions":{"0":{"x":252,"y":-468},"1":{"x":228,"y":-496},"2":{"x":228,"y":-844},"3":{"x":252,"y":-816},"4":{"x":228,"y":-656},"5":{"x":228,"y":-656},"6":{"x":252,"y":-656}}},"warnings":null},{"id":680,"sourceNodeId":145,"sourcePortId":1375,"targetNodeId":146,"targetPortId":1376,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":527},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":73},"targetDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":532},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":240,"y":-930},{"x":240,"y":-994},{"x":240,"y":-1278},{"x":240,"y":-1342}],"textPositions":{"0":{"x":252,"y":-948},"1":{"x":228,"y":-976},"2":{"x":228,"y":-1324},"3":{"x":252,"y":-1296},"4":{"x":228,"y":-1136},"5":{"x":228,"y":-1136},"6":{"x":252,"y":-1136}}},"warnings":null},{"id":681,"sourceNodeId":146,"sourcePortId":1377,"targetNodeId":134,"targetPortId":1378,"travelTime":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":532},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":63},"targetArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":537},"numberOfStops":0,"trainrunId":77,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":240,"y":-1410},{"x":240,"y":-1474},{"x":240,"y":-1758},{"x":240,"y":-1822}],"textPositions":{"0":{"x":252,"y":-1428},"1":{"x":228,"y":-1456},"2":{"x":228,"y":-1804},"3":{"x":252,"y":-1776},"4":{"x":228,"y":-1616},"5":{"x":228,"y":-1616},"6":{"x":252,"y":-1616}}},"warnings":null},{"id":682,"sourceNodeId":171,"sourcePortId":1379,"targetNodeId":128,"targetPortId":1380,"travelTime":{"lock":false,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":387},"sourceArrival":{"lock":true,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":153},"targetDeparture":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":104},"targetArrival":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":436},"numberOfStops":2,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2562,"y":336},{"x":-2626,"y":336},{"x":-2910,"y":592},{"x":-2974,"y":592}],"textPositions":{"0":{"x":-2580,"y":324},"1":{"x":-2608,"y":348},"2":{"x":-2956,"y":604},"3":{"x":-2928,"y":580},"4":{"x":-2768,"y":452},"5":{"x":-2768,"y":452},"6":{"x":-2768,"y":476}}},"warnings":null},{"id":683,"sourceNodeId":171,"sourcePortId":1381,"targetNodeId":128,"targetPortId":1382,"travelTime":{"lock":true,"time":44,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":414},"sourceArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":126},"targetDeparture":{"lock":false,"time":22,"warning":null,"timeFormatter":null,"consecutiveTime":82},"targetArrival":{"lock":false,"time":38,"warning":null,"timeFormatter":null,"consecutiveTime":458},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-2562,"y":304},{"x":-2626,"y":304},{"x":-2910,"y":560},{"x":-2974,"y":560}],"textPositions":{"0":{"x":-2580,"y":292},"1":{"x":-2608,"y":316},"2":{"x":-2956,"y":572},"3":{"x":-2928,"y":548},"4":{"x":-2768,"y":420},"5":{"x":-2768,"y":420},"6":{"x":-2768,"y":444}}},"warnings":null},{"id":684,"sourceNodeId":172,"sourcePortId":1383,"targetNodeId":178,"targetPortId":1384,"travelTime":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":339},"sourceArrival":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":201},"targetDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":185},"targetArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":355},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":304},{"x":-674,"y":304},{"x":-1534,"y":304},{"x":-1598,"y":304}],"textPositions":{"0":{"x":-628,"y":292},"1":{"x":-656,"y":316},"2":{"x":-1580,"y":316},"3":{"x":-1552,"y":292},"4":{"x":-1104,"y":292},"5":{"x":-1104,"y":292},"6":{"x":-1104,"y":316}}},"warnings":null},{"id":685,"sourceNodeId":172,"sourcePortId":1385,"targetNodeId":174,"targetPortId":1386,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":343},"sourceArrival":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":77},"targetDeparture":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":69},"targetArrival":{"lock":true,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":351},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":336},{"x":-674,"y":336},{"x":-830,"y":368},{"x":-894,"y":368}],"textPositions":{"0":{"x":-628,"y":324},"1":{"x":-656,"y":348},"2":{"x":-876,"y":380},"3":{"x":-848,"y":356},"4":{"x":-752,"y":340},"5":{"x":-752,"y":340},"6":{"x":-752,"y":364}}},"warnings":null},{"id":686,"sourceNodeId":172,"sourcePortId":1387,"targetNodeId":178,"targetPortId":1388,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":47,"warning":null,"timeFormatter":null,"consecutiveTime":347},"sourceArrival":{"lock":false,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":73},"targetDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"targetArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":355},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":272},{"x":-674,"y":272},{"x":-1534,"y":272},{"x":-1598,"y":272}],"textPositions":{"0":{"x":-628,"y":260},"1":{"x":-656,"y":284},"2":{"x":-1580,"y":284},"3":{"x":-1552,"y":260},"4":{"x":-1104,"y":260},"5":{"x":-1104,"y":260},"6":{"x":-1104,"y":284}}},"warnings":null},{"id":687,"sourceNodeId":172,"sourcePortId":1389,"targetNodeId":178,"targetPortId":1390,"travelTime":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":337},"sourceArrival":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":83},"targetDeparture":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":66},"targetArrival":{"lock":true,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":354},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":240},{"x":-674,"y":240},{"x":-1534,"y":240},{"x":-1598,"y":240}],"textPositions":{"0":{"x":-628,"y":228},"1":{"x":-656,"y":252},"2":{"x":-1580,"y":252},"3":{"x":-1552,"y":228},"4":{"x":-1104,"y":228},"5":{"x":-1104,"y":228},"6":{"x":-1104,"y":252}}},"warnings":null},{"id":688,"sourceNodeId":172,"sourcePortId":1391,"targetNodeId":178,"targetPortId":1392,"travelTime":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"sourceArrival":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":235},"targetDeparture":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":217},"targetArrival":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":83},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":208},{"x":-674,"y":208},{"x":-1534,"y":208},{"x":-1598,"y":208}],"textPositions":{"0":{"x":-628,"y":196},"1":{"x":-656,"y":220},"2":{"x":-1580,"y":220},"3":{"x":-1552,"y":196},"4":{"x":-1104,"y":196},"5":{"x":-1104,"y":196},"6":{"x":-1104,"y":220}}},"warnings":null},{"id":689,"sourceNodeId":172,"sourcePortId":1393,"targetNodeId":133,"targetPortId":1394,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":234},"sourceArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":66},"targetDeparture":{"lock":true,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":58},"targetArrival":{"lock":true,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":242},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-510,"y":176},{"x":-446,"y":176},{"x":-2,"y":176},{"x":62,"y":176}],"textPositions":{"0":{"x":-492,"y":188},"1":{"x":-464,"y":164},"2":{"x":44,"y":164},"3":{"x":16,"y":188},"4":{"x":-224,"y":164},"5":{"x":-224,"y":164},"6":{"x":-224,"y":188}}},"warnings":null},{"id":690,"sourceNodeId":172,"sourcePortId":1395,"targetNodeId":178,"targetPortId":1396,"travelTime":{"lock":true,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":377},"sourceArrival":{"lock":false,"time":43,"warning":null,"timeFormatter":null,"consecutiveTime":163},"targetDeparture":{"lock":false,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":154},"targetArrival":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":386},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-610,"y":144},{"x":-674,"y":144},{"x":-1534,"y":144},{"x":-1598,"y":144}],"textPositions":{"0":{"x":-628,"y":132},"1":{"x":-656,"y":156},"2":{"x":-1580,"y":156},"3":{"x":-1552,"y":132},"4":{"x":-1104,"y":132},"5":{"x":-1104,"y":132},"6":{"x":-1104,"y":156}}},"warnings":null},{"id":691,"sourceNodeId":173,"sourcePortId":1397,"targetNodeId":178,"targetPortId":1398,"travelTime":{"lock":true,"time":10,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":11,"warning":null,"timeFormatter":null,"consecutiveTime":371},"sourceArrival":{"lock":true,"time":49,"warning":null,"timeFormatter":null,"consecutiveTime":49},"targetDeparture":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":39},"targetArrival":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":381},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1346,"y":368},{"x":-1410,"y":368},{"x":-1534,"y":336},{"x":-1598,"y":336}],"textPositions":{"0":{"x":-1364,"y":356},"1":{"x":-1392,"y":380},"2":{"x":-1580,"y":348},"3":{"x":-1552,"y":324},"4":{"x":-1472,"y":340},"5":{"x":-1472,"y":340},"6":{"x":-1472,"y":364}}},"warnings":null},{"id":692,"sourceNodeId":174,"sourcePortId":1399,"targetNodeId":173,"targetPortId":1400,"travelTime":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":352},"sourceArrival":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetDeparture":{"lock":false,"time":51,"warning":null,"timeFormatter":null,"consecutiveTime":51},"targetArrival":{"lock":false,"time":9,"warning":null,"timeFormatter":null,"consecutiveTime":369},"numberOfStops":1,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-994,"y":368},{"x":-1058,"y":368},{"x":-1182,"y":368},{"x":-1246,"y":368}],"textPositions":{"0":{"x":-1012,"y":356},"1":{"x":-1040,"y":380},"2":{"x":-1228,"y":380},"3":{"x":-1200,"y":356},"4":{"x":-1120,"y":356},"5":{"x":-1120,"y":356},"6":{"x":-1120,"y":380}}},"warnings":null},{"id":693,"sourceNodeId":135,"sourcePortId":1401,"targetNodeId":149,"targetPortId":1402,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":300},"sourceArrival":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":60},"targetDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"targetArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2654,"y":80},{"x":2590,"y":80},{"x":2402,"y":80},{"x":2338,"y":80}],"textPositions":{"0":{"x":2636,"y":68},"1":{"x":2608,"y":92},"2":{"x":2356,"y":92},"3":{"x":2384,"y":68},"4":{"x":2496,"y":68},"5":{"x":2496,"y":68},"6":{"x":2496,"y":92}}},"warnings":null},{"id":694,"sourceNodeId":149,"sourcePortId":1403,"targetNodeId":166,"targetPortId":1404,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":308},"sourceArrival":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":52},"targetDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":2238,"y":80},{"x":2174,"y":80},{"x":1954,"y":80},{"x":1890,"y":80}],"textPositions":{"0":{"x":2220,"y":68},"1":{"x":2192,"y":92},"2":{"x":1908,"y":92},"3":{"x":1936,"y":68},"4":{"x":2064,"y":68},"5":{"x":2064,"y":68},"6":{"x":2064,"y":92}}},"warnings":null},{"id":695,"sourceNodeId":166,"sourcePortId":1405,"targetNodeId":148,"targetPortId":1406,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":314},"sourceArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":46},"targetDeparture":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":40},"targetArrival":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":320},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1790,"y":80},{"x":1726,"y":80},{"x":1506,"y":80},{"x":1442,"y":80}],"textPositions":{"0":{"x":1772,"y":68},"1":{"x":1744,"y":92},"2":{"x":1460,"y":92},"3":{"x":1488,"y":68},"4":{"x":1616,"y":68},"5":{"x":1616,"y":68},"6":{"x":1616,"y":92}}},"warnings":null},{"id":696,"sourceNodeId":148,"sourcePortId":1407,"targetNodeId":147,"targetPortId":1408,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":20,"warning":null,"timeFormatter":null,"consecutiveTime":320},"sourceArrival":{"lock":false,"time":40,"warning":null,"timeFormatter":null,"consecutiveTime":40},"targetDeparture":{"lock":false,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":34},"targetArrival":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":326},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":1342,"y":80},{"x":1278,"y":80},{"x":1122,"y":80},{"x":1058,"y":80}],"textPositions":{"0":{"x":1324,"y":68},"1":{"x":1296,"y":92},"2":{"x":1076,"y":92},"3":{"x":1104,"y":68},"4":{"x":1200,"y":68},"5":{"x":1200,"y":68},"6":{"x":1200,"y":92}}},"warnings":null},{"id":697,"sourceNodeId":147,"sourcePortId":1409,"targetNodeId":144,"targetPortId":1410,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":326},"sourceArrival":{"lock":false,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":34},"targetDeparture":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":27},"targetArrival":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":333},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":958,"y":48},{"x":894,"y":48},{"x":386,"y":-432},{"x":322,"y":-432}],"textPositions":{"0":{"x":940,"y":36},"1":{"x":912,"y":60},"2":{"x":340,"y":-420},"3":{"x":368,"y":-444},"4":{"x":640,"y":-204},"5":{"x":640,"y":-204},"6":{"x":640,"y":-180}}},"warnings":null},{"id":698,"sourceNodeId":144,"sourcePortId":1411,"targetNodeId":145,"targetPortId":1412,"travelTime":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":33,"warning":null,"timeFormatter":null,"consecutiveTime":333},"sourceArrival":{"lock":false,"time":27,"warning":null,"timeFormatter":null,"consecutiveTime":27},"targetDeparture":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":21},"targetArrival":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":339},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":-450},{"x":112,"y":-514},{"x":112,"y":-798},{"x":112,"y":-862}],"textPositions":{"0":{"x":124,"y":-468},"1":{"x":100,"y":-496},"2":{"x":100,"y":-844},"3":{"x":124,"y":-816},"4":{"x":100,"y":-656},"5":{"x":100,"y":-656},"6":{"x":124,"y":-656}}},"warnings":null},{"id":699,"sourceNodeId":145,"sourcePortId":1413,"targetNodeId":146,"targetPortId":1414,"travelTime":{"lock":true,"time":7,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":339},"sourceArrival":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":21},"targetDeparture":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":14},"targetArrival":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":346},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":-930},{"x":112,"y":-994},{"x":112,"y":-1278},{"x":112,"y":-1342}],"textPositions":{"0":{"x":124,"y":-948},"1":{"x":100,"y":-976},"2":{"x":100,"y":-1324},"3":{"x":124,"y":-1296},"4":{"x":100,"y":-1136},"5":{"x":100,"y":-1136},"6":{"x":124,"y":-1136}}},"warnings":null},{"id":700,"sourceNodeId":146,"sourcePortId":1415,"targetNodeId":134,"targetPortId":1416,"travelTime":{"lock":true,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":346},"sourceArrival":{"lock":false,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":14},"targetDeparture":{"lock":true,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":6},"targetArrival":{"lock":true,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":354},"numberOfStops":0,"trainrunId":85,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":112,"y":-1410},{"x":112,"y":-1474},{"x":112,"y":-1758},{"x":112,"y":-1822}],"textPositions":{"0":{"x":124,"y":-1428},"1":{"x":100,"y":-1456},"2":{"x":100,"y":-1804},"3":{"x":124,"y":-1776},"4":{"x":100,"y":-1616},"5":{"x":100,"y":-1616},"6":{"x":124,"y":-1616}}},"warnings":null},{"id":701,"sourceNodeId":175,"sourcePortId":1417,"targetNodeId":130,"targetPortId":1418,"travelTime":{"lock":true,"time":13,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":421},"sourceArrival":{"lock":true,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":119},"targetDeparture":{"lock":true,"time":46,"warning":null,"timeFormatter":null,"consecutiveTime":106},"targetArrival":{"lock":true,"time":14,"warning":null,"timeFormatter":null,"consecutiveTime":434},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":-16},{"x":-1762,"y":-16},{"x":-2366,"y":-16},{"x":-2430,"y":-16}],"textPositions":{"0":{"x":-1716,"y":-28},"1":{"x":-1744,"y":-4},"2":{"x":-2412,"y":-4},"3":{"x":-2384,"y":-28},"4":{"x":-2064,"y":-28},"5":{"x":-2064,"y":-28},"6":{"x":-2064,"y":-4}}},"warnings":null},{"id":702,"sourceNodeId":137,"sourcePortId":1419,"targetNodeId":176,"targetPortId":1420,"travelTime":{"lock":true,"time":16,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":245},"sourceArrival":{"lock":true,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":295},"targetDeparture":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":279},"targetArrival":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":261},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":4738,"y":112},{"x":4802,"y":112},{"x":5310,"y":112},{"x":5374,"y":112}],"textPositions":{"0":{"x":4756,"y":124},"1":{"x":4784,"y":100},"2":{"x":5356,"y":100},"3":{"x":5328,"y":124},"4":{"x":5056,"y":100},"5":{"x":5056,"y":100},"6":{"x":5056,"y":124}}},"warnings":null},{"id":703,"sourceNodeId":177,"sourcePortId":1421,"targetNodeId":160,"targetPortId":1422,"travelTime":{"lock":false,"time":30,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":true,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":451},"sourceArrival":{"lock":true,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":89},"targetDeparture":{"lock":true,"time":59,"warning":null,"timeFormatter":null,"consecutiveTime":59},"targetArrival":{"lock":true,"time":1,"warning":null,"timeFormatter":null,"consecutiveTime":481},"numberOfStops":1,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3522,"y":624},{"x":-3586,"y":624},{"x":-3774,"y":688},{"x":-3838,"y":688}],"textPositions":{"0":{"x":-3540,"y":612},"1":{"x":-3568,"y":636},"2":{"x":-3820,"y":700},"3":{"x":-3792,"y":676},"4":{"x":-3680,"y":644},"5":{"x":-3680,"y":644},"6":{"x":-3680,"y":668}}},"warnings":null},{"id":704,"sourceNodeId":177,"sourcePortId":1423,"targetNodeId":160,"targetPortId":1424,"travelTime":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":52,"warning":null,"timeFormatter":null,"consecutiveTime":472},"sourceArrival":{"lock":false,"time":8,"warning":null,"timeFormatter":null,"consecutiveTime":68},"targetDeparture":{"lock":true,"time":42,"warning":null,"timeFormatter":null,"consecutiveTime":42},"targetArrival":{"lock":true,"time":18,"warning":null,"timeFormatter":null,"consecutiveTime":498},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3522,"y":560},{"x":-3586,"y":560},{"x":-3774,"y":624},{"x":-3838,"y":624}],"textPositions":{"0":{"x":-3540,"y":548},"1":{"x":-3568,"y":572},"2":{"x":-3820,"y":636},"3":{"x":-3792,"y":612},"4":{"x":-3680,"y":580},"5":{"x":-3680,"y":580},"6":{"x":-3680,"y":604}}},"warnings":null},{"id":705,"sourceNodeId":177,"sourcePortId":1425,"targetNodeId":160,"targetPortId":1426,"travelTime":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":19,"warning":null,"timeFormatter":null,"consecutiveTime":499},"sourceArrival":{"lock":false,"time":41,"warning":null,"timeFormatter":null,"consecutiveTime":41},"targetDeparture":{"lock":true,"time":15,"warning":null,"timeFormatter":null,"consecutiveTime":15},"targetArrival":{"lock":true,"time":45,"warning":null,"timeFormatter":null,"consecutiveTime":525},"numberOfStops":0,"trainrunId":87,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-3522,"y":592},{"x":-3586,"y":592},{"x":-3774,"y":656},{"x":-3838,"y":656}],"textPositions":{"0":{"x":-3540,"y":580},"1":{"x":-3568,"y":604},"2":{"x":-3820,"y":668},"3":{"x":-3792,"y":644},"4":{"x":-3680,"y":612},"5":{"x":-3680,"y":612},"6":{"x":-3680,"y":636}}},"warnings":null},{"id":706,"sourceNodeId":178,"sourcePortId":1427,"targetNodeId":129,"targetPortId":1428,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":21,"warning":null,"timeFormatter":null,"consecutiveTime":381},"sourceArrival":{"lock":false,"time":39,"warning":null,"timeFormatter":null,"consecutiveTime":39},"targetDeparture":{"lock":true,"time":36,"warning":null,"timeFormatter":null,"consecutiveTime":36},"targetArrival":{"lock":true,"time":24,"warning":null,"timeFormatter":null,"consecutiveTime":384},"numberOfStops":0,"trainrunId":86,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":336},{"x":-1762,"y":336},{"x":-1950,"y":336},{"x":-2014,"y":336}],"textPositions":{"0":{"x":-1716,"y":324},"1":{"x":-1744,"y":348},"2":{"x":-1996,"y":348},"3":{"x":-1968,"y":324},"4":{"x":-1856,"y":324},"5":{"x":-1856,"y":324},"6":{"x":-1856,"y":348}}},"warnings":null},{"id":707,"sourceNodeId":178,"sourcePortId":1429,"targetNodeId":129,"targetPortId":1430,"travelTime":{"lock":true,"time":4,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":355},"sourceArrival":{"lock":false,"time":5,"warning":{"title":"Quelle Ankunft Warnung","description":"Quellankunftszeit kann nicht erreicht werden"},"timeFormatter":null,"consecutiveTime":185},"targetDeparture":{"lock":true,"time":0,"warning":null,"timeFormatter":null,"consecutiveTime":180},"targetArrival":{"lock":true,"time":0,"warning":{"title":"Ziel Ankunft Warnung","description":"Zielankunftszeit kann nicht erreicht werden"},"timeFormatter":null,"consecutiveTime":360},"numberOfStops":0,"trainrunId":81,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":304},{"x":-1762,"y":304},{"x":-1950,"y":304},{"x":-2014,"y":304}],"textPositions":{"0":{"x":-1716,"y":292},"1":{"x":-1744,"y":316},"2":{"x":-1996,"y":316},"3":{"x":-1968,"y":292},"4":{"x":-1856,"y":292},"5":{"x":-1856,"y":292},"6":{"x":-1856,"y":316}}},"warnings":null},{"id":708,"sourceNodeId":178,"sourcePortId":1431,"targetNodeId":129,"targetPortId":1432,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":55,"warning":null,"timeFormatter":null,"consecutiveTime":355},"sourceArrival":{"lock":false,"time":5,"warning":null,"timeFormatter":null,"consecutiveTime":65},"targetDeparture":{"lock":false,"time":2,"warning":null,"timeFormatter":null,"consecutiveTime":62},"targetArrival":{"lock":false,"time":58,"warning":null,"timeFormatter":null,"consecutiveTime":358},"numberOfStops":0,"trainrunId":90,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":272},{"x":-1762,"y":272},{"x":-1950,"y":272},{"x":-2014,"y":272}],"textPositions":{"0":{"x":-1716,"y":260},"1":{"x":-1744,"y":284},"2":{"x":-1996,"y":284},"3":{"x":-1968,"y":260},"4":{"x":-1856,"y":260},"5":{"x":-1856,"y":260},"6":{"x":-1856,"y":284}}},"warnings":null},{"id":709,"sourceNodeId":178,"sourcePortId":1433,"targetNodeId":129,"targetPortId":1434,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":354},"sourceArrival":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":66},"targetDeparture":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":63},"targetArrival":{"lock":true,"time":57,"warning":null,"timeFormatter":null,"consecutiveTime":357},"numberOfStops":0,"trainrunId":89,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":240},{"x":-1762,"y":240},{"x":-1950,"y":240},{"x":-2014,"y":240}],"textPositions":{"0":{"x":-1716,"y":228},"1":{"x":-1744,"y":252},"2":{"x":-1996,"y":252},"3":{"x":-1968,"y":228},"4":{"x":-1856,"y":228},"5":{"x":-1856,"y":228},"6":{"x":-1856,"y":252}}},"warnings":null},{"id":710,"sourceNodeId":178,"sourcePortId":1435,"targetNodeId":129,"targetPortId":1436,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":83},"sourceArrival":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":217},"targetDeparture":{"lock":true,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":214},"targetArrival":{"lock":true,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":86},"numberOfStops":0,"trainrunId":95,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":208},{"x":-1762,"y":208},{"x":-1950,"y":208},{"x":-2014,"y":208}],"textPositions":{"0":{"x":-1716,"y":196},"1":{"x":-1744,"y":220},"2":{"x":-1996,"y":220},"3":{"x":-1968,"y":196},"4":{"x":-1856,"y":196},"5":{"x":-1856,"y":196},"6":{"x":-1856,"y":220}}},"warnings":null},{"id":711,"sourceNodeId":178,"sourcePortId":1437,"targetNodeId":172,"targetPortId":1438,"travelTime":{"lock":true,"time":17,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":37,"warning":null,"timeFormatter":null,"consecutiveTime":217},"sourceArrival":{"lock":false,"time":23,"warning":null,"timeFormatter":null,"consecutiveTime":83},"targetDeparture":{"lock":false,"time":6,"warning":null,"timeFormatter":null,"consecutiveTime":66},"targetArrival":{"lock":false,"time":54,"warning":null,"timeFormatter":null,"consecutiveTime":234},"numberOfStops":0,"trainrunId":96,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1598,"y":176},{"x":-1534,"y":176},{"x":-674,"y":176},{"x":-610,"y":176}],"textPositions":{"0":{"x":-1580,"y":188},"1":{"x":-1552,"y":164},"2":{"x":-628,"y":164},"3":{"x":-656,"y":188},"4":{"x":-1104,"y":164},"5":{"x":-1104,"y":164},"6":{"x":-1104,"y":188}}},"warnings":null},{"id":712,"sourceNodeId":178,"sourcePortId":1439,"targetNodeId":129,"targetPortId":1440,"travelTime":{"lock":true,"time":3,"warning":null,"timeFormatter":null,"consecutiveTime":1},"sourceDeparture":{"lock":false,"time":26,"warning":null,"timeFormatter":null,"consecutiveTime":386},"sourceArrival":{"lock":false,"time":34,"warning":null,"timeFormatter":null,"consecutiveTime":154},"targetDeparture":{"lock":false,"time":31,"warning":null,"timeFormatter":null,"consecutiveTime":151},"targetArrival":{"lock":false,"time":29,"warning":null,"timeFormatter":null,"consecutiveTime":389},"numberOfStops":0,"trainrunId":88,"resourceId":0,"specificTrainrunSectionFrequencyId":null,"path":{"path":[{"x":-1698,"y":144},{"x":-1762,"y":144},{"x":-1950,"y":144},{"x":-2014,"y":144}],"textPositions":{"0":{"x":-1716,"y":132},"1":{"x":-1744,"y":156},"2":{"x":-1996,"y":156},"3":{"x":-1968,"y":132},"4":{"x":-1856,"y":132},"5":{"x":-1856,"y":132},"6":{"x":-1856,"y":156}}},"warnings":null}],"trainruns":[{"id":75,"name":"21","categoryId":1,"frequencyId":4,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":76,"name":"2","categoryId":1,"frequencyId":4,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":77,"name":"26","categoryId":2,"frequencyId":5,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":78,"name":"46","categoryId":2,"frequencyId":4,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":79,"name":"75","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":80,"name":"70","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":81,"name":"15","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":82,"name":"27","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":83,"name":"26","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":84,"name":"13","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":85,"name":"3","categoryId":1,"frequencyId":4,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":86,"name":"35","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":87,"name":"5","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":88,"name":"1","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":89,"name":"8","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":90,"name":"81","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":91,"name":"48","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[1,9,5]},{"id":92,"name":"","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[1,9,5]},{"id":93,"name":"36","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":94,"name":"3","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":95,"name":"61","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":96,"name":"6","categoryId":1,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]},{"id":97,"name":"37","categoryId":2,"frequencyId":3,"trainrunTimeCategoryId":0,"labelIds":[3,8,4]}],"resources":[{"id":88,"capacity":2},{"id":89,"capacity":2},{"id":90,"capacity":2},{"id":91,"capacity":2},{"id":92,"capacity":2},{"id":93,"capacity":2},{"id":94,"capacity":2},{"id":95,"capacity":2},{"id":96,"capacity":2},{"id":97,"capacity":2},{"id":98,"capacity":2},{"id":99,"capacity":2},{"id":100,"capacity":2},{"id":101,"capacity":2},{"id":102,"capacity":2},{"id":103,"capacity":2},{"id":104,"capacity":2},{"id":105,"capacity":2},{"id":106,"capacity":2},{"id":107,"capacity":2},{"id":108,"capacity":2},{"id":109,"capacity":2},{"id":110,"capacity":2},{"id":111,"capacity":2},{"id":112,"capacity":2},{"id":113,"capacity":2},{"id":114,"capacity":2},{"id":115,"capacity":2},{"id":116,"capacity":2},{"id":117,"capacity":2},{"id":118,"capacity":2},{"id":119,"capacity":2},{"id":120,"capacity":2},{"id":121,"capacity":2},{"id":122,"capacity":2},{"id":123,"capacity":2},{"id":124,"capacity":2},{"id":125,"capacity":2},{"id":126,"capacity":2},{"id":127,"capacity":2},{"id":128,"capacity":2},{"id":129,"capacity":2},{"id":130,"capacity":2},{"id":131,"capacity":2},{"id":132,"capacity":2},{"id":133,"capacity":2},{"id":134,"capacity":2},{"id":135,"capacity":2},{"id":136,"capacity":2},{"id":137,"capacity":2},{"id":138,"capacity":2},{"id":139,"capacity":2},{"id":140,"capacity":2},{"id":141,"capacity":2},{"id":142,"capacity":2},{"id":143,"capacity":2},{"id":144,"capacity":2},{"id":145,"capacity":2},{"id":146,"capacity":2},{"id":147,"capacity":2},{"id":148,"capacity":2},{"id":149,"capacity":2},{"id":150,"capacity":2},{"id":151,"capacity":2},{"id":152,"capacity":2},{"id":153,"capacity":2},{"id":154,"capacity":2},{"id":155,"capacity":2},{"id":156,"capacity":2},{"id":157,"capacity":2},{"id":158,"capacity":2},{"id":159,"capacity":2},{"id":160,"capacity":2},{"id":161,"capacity":2},{"id":162,"capacity":2},{"id":163,"capacity":2},{"id":164,"capacity":2},{"id":165,"capacity":2},{"id":166,"capacity":2},{"id":167,"capacity":2},{"id":168,"capacity":2},{"id":169,"capacity":2},{"id":170,"capacity":2},{"id":171,"capacity":2},{"id":172,"capacity":2},{"id":173,"capacity":2},{"id":174,"capacity":2},{"id":175,"capacity":2},{"id":176,"capacity":2},{"id":177,"capacity":2},{"id":178,"capacity":2},{"id":179,"capacity":2},{"id":180,"capacity":2},{"id":181,"capacity":2},{"id":182,"capacity":2},{"id":183,"capacity":2},{"id":184,"capacity":2},{"id":185,"capacity":2},{"id":186,"capacity":2},{"id":187,"capacity":2},{"id":188,"capacity":2},{"id":189,"capacity":2},{"id":190,"capacity":2},{"id":191,"capacity":2},{"id":192,"capacity":2},{"id":193,"capacity":2},{"id":194,"capacity":2},{"id":195,"capacity":2},{"id":196,"capacity":2},{"id":197,"capacity":2},{"id":198,"capacity":2},{"id":199,"capacity":2},{"id":200,"capacity":2},{"id":201,"capacity":2},{"id":202,"capacity":2}],"metadata":{"netzgrafikColors":[],"trainrunCategories":[{"id":0,"name":"International","order":0,"colorRef":"EC","shortName":"EC","fachCategory":"HaltezeitIPV","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":1,"name":"InterCity","order":1,"colorRef":"IC","shortName":"IC","fachCategory":"HaltezeitA","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":2,"name":"InterRegio","order":2,"colorRef":"IR","shortName":"IR","fachCategory":"HaltezeitB","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":3,"name":"RegioExpress","order":3,"colorRef":"RE","shortName":"RE","fachCategory":"HaltezeitC","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":4,"name":"RegioUndSBahnverkehr","order":4,"colorRef":"S","shortName":"S","fachCategory":"HaltezeitD","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":5,"name":"GüterExpress","order":5,"colorRef":"GEX","shortName":"GEX","fachCategory":"HaltezeitUncategorized","sectionHeadway":3,"nodeHeadwayStop":3,"nodeHeadwayNonStop":3,"minimalTurnaroundTime":4},{"id":6,"name":"Güterverkehr","order":6,"colorRef":"G","shortName":"G","fachCategory":"HaltezeitUncategorized","sectionHeadway":3,"nodeHeadwayStop":3,"nodeHeadwayNonStop":3,"minimalTurnaroundTime":4}],"trainrunFrequencies":[{"id":0,"name":"verkehrt viertelstündlich","order":0,"offset":0,"frequency":15,"shortName":"15","linePatternRef":"15"},{"id":1,"name":"verkehrt im 20 Minuten Takt","order":0,"offset":0,"frequency":20,"shortName":"20","linePatternRef":"20"},{"id":2,"name":"verkehrt halbstündlich","order":0,"offset":0,"frequency":30,"shortName":"30","linePatternRef":"30"},{"id":3,"name":"verkehrt stündlich","order":0,"offset":0,"frequency":60,"shortName":"60","linePatternRef":"60"},{"id":4,"name":"verkehrt zweistündlich (gerade)","order":0,"offset":0,"frequency":120,"shortName":"120","linePatternRef":"120"},{"id":5,"name":"verkehrt zweistündlich (ungerade)","order":0,"offset":60,"frequency":120,"shortName":"120+","linePatternRef":"120"}],"trainrunTimeCategories":[{"id":0,"name":"verkehrt uneingeschränkt","order":0,"weekday":[1,2,3,4,5,6,7],"shortName":"7/24","linePatternRef":"7/24","dayTimeInterval":[]},{"id":1,"name":"verkehrt zur Hauptverkehrszeit","order":0,"weekday":[1,2,3,4,5,6,7],"shortName":"HVZ","linePatternRef":"HVZ","dayTimeInterval":[{"to":420,"from":360},{"to":1140,"from":960}]},{"id":2,"name":"verkehrt zeitweise","order":0,"weekday":[],"shortName":"zeitweise","linePatternRef":"ZEITWEISE","dayTimeInterval":[]}]},"freeFloatingTexts":[{"id":1,"x":716,"y":445,"width":192,"height":64,"title":"DEMO ","text":"

This is a demonstration scenario - no guarantee that the data is correct or corresponds to reality.

","backgroundColor":"#ffffff","textColor":"#000000","labelIds":[]}],"labels":[{"id":4,"label":"OK","labelGroupId":1,"labelRef":"Trainrun"},{"id":5,"label":"Zeiten falsch","labelGroupId":3,"labelRef":"Trainrun"}],"labelGroups":[{"id":1,"name":"Standard","labelRef":"Trainrun"},{"id":2,"name":"Standard","labelRef":"Node"},{"id":3,"name":"Standard","labelRef":"Trainrun"}],"filterData":{"filterSettings":[{"id":5,"name":"Neuer Filter","description":"","filterNodeLabels":[],"filterNoteLabels":[],"filterTrainrunLabels":[],"filterArrivalDepartureTime":true,"filterTravelTime":true,"filterTrainrunName":true,"filterConnections":true,"filterShowNonStopTime":true,"filterTrainrunCategory":[{"id":0,"name":"International","order":0,"colorRef":"EC","shortName":"EC","fachCategory":"HaltezeitIPV","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":1,"name":"InterCity","order":1,"colorRef":"IC","shortName":"IC","fachCategory":"HaltezeitA","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":2,"name":"InterRegio","order":2,"colorRef":"IR","shortName":"IR","fachCategory":"HaltezeitB","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":3,"name":"RegioExpress","order":3,"colorRef":"RE","shortName":"RE","fachCategory":"HaltezeitC","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":4,"name":"RegioUndSBahnverkehr","order":4,"colorRef":"S","shortName":"S","fachCategory":"HaltezeitD","sectionHeadway":2,"nodeHeadwayStop":2,"nodeHeadwayNonStop":2,"minimalTurnaroundTime":4},{"id":5,"name":"GüterExpress","order":5,"colorRef":"GEX","shortName":"GEX","fachCategory":"HaltezeitUncategorized","sectionHeadway":3,"nodeHeadwayStop":3,"nodeHeadwayNonStop":3,"minimalTurnaroundTime":4},{"id":6,"name":"Güterverkehr","order":6,"colorRef":"G","shortName":"G","fachCategory":"HaltezeitUncategorized","sectionHeadway":3,"nodeHeadwayStop":3,"nodeHeadwayNonStop":3,"minimalTurnaroundTime":4}],"filterTrainrunFrequency":[{"id":0,"name":"verkehrt viertelstündlich","order":0,"offset":0,"frequency":15,"shortName":"15","linePatternRef":"15"},{"id":1,"name":"verkehrt im 20 Minuten Takt","order":0,"offset":0,"frequency":20,"shortName":"20","linePatternRef":"20"},{"id":2,"name":"verkehrt halbstündlich","order":0,"offset":0,"frequency":30,"shortName":"30","linePatternRef":"30"},{"id":3,"name":"verkehrt stündlich","order":0,"offset":0,"frequency":60,"shortName":"60","linePatternRef":"60"},{"id":4,"name":"verkehrt zweistündlich (gerade)","order":0,"offset":0,"frequency":120,"shortName":"120","linePatternRef":"120"},{"id":5,"name":"verkehrt zweistündlich (ungerade)","order":0,"offset":60,"frequency":120,"shortName":"120+","linePatternRef":"120"}],"filterTrainrunTimeCategory":[{"id":0,"name":"verkehrt uneingeschränkt","order":0,"weekday":[1,2,3,4,5,6,7],"shortName":"7/24","linePatternRef":"7/24","dayTimeInterval":[]},{"id":1,"name":"verkehrt zur Hauptverkehrszeit","order":0,"weekday":[1,2,3,4,5,6,7],"shortName":"HVZ","linePatternRef":"HVZ","dayTimeInterval":[{"to":420,"from":360},{"to":1140,"from":960}]},{"id":2,"name":"verkehrt zeitweise","order":0,"weekday":[],"shortName":"zeitweise","linePatternRef":"ZEITWEISE","dayTimeInterval":[]}],"filterAllEmptyNodes":false,"filterAllNonStopNodes":false,"filterNotes":false,"timeDisplayPrecision":1,"isTemporaryDisableFilteringOfItemsInView":false,"temporaryEmptyAndNonStopFilteringSwitchedOff":false}]}}' - ); + return { + nodes: [ + { + id: 128, + betriebspunktName: "Lausanne", + fullName: "Lausanne", + positionX: -3072, + positionY: 544, + ports: [ + { + id: 1207, + trainrunSectionId: 596, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1187, + trainrunSectionId: 586, + positionIndex: 1, + positionAlignment: 2 + }, + { + id: 1382, + trainrunSectionId: 683, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1380, + trainrunSectionId: 682, + positionIndex: 1, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 345, + port1Id: 1187, + port2Id: 1380, + isNonStopTransit: false + }, + { + id: 347, + port1Id: 1207, + port2Id: 1382, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 152, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 129, + betriebspunktName: "Bern", + fullName: "Bern", + positionX: -2144, + positionY: 128, + ports: [ + { + id: 1328, + trainrunSectionId: 656, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1311, + trainrunSectionId: 648, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1313, + trainrunSectionId: 649, + positionIndex: 2, + positionAlignment: 1 + }, + { + id: 1339, + trainrunSectionId: 662, + positionIndex: 3, + positionAlignment: 1 + }, + { + id: 1205, + trainrunSectionId: 595, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1109, + trainrunSectionId: 547, + positionIndex: 1, + positionAlignment: 2 + }, + { + id: 1440, + trainrunSectionId: 712, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1329, + trainrunSectionId: 657, + positionIndex: 1, + positionAlignment: 3 + }, + { + id: 1436, + trainrunSectionId: 710, + positionIndex: 2, + positionAlignment: 3 + }, + { + id: 1434, + trainrunSectionId: 709, + positionIndex: 3, + positionAlignment: 3 + }, + { + id: 1432, + trainrunSectionId: 708, + positionIndex: 4, + positionAlignment: 3 + }, + { + id: 1430, + trainrunSectionId: 707, + positionIndex: 5, + positionAlignment: 3 + }, + { + id: 1428, + trainrunSectionId: 706, + positionIndex: 6, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 315, + port1Id: 1328, + port2Id: 1329, + isNonStopTransit: false + }, + { + id: 376, + port1Id: 1109, + port2Id: 1430, + isNonStopTransit: false + }, + { + id: 378, + port1Id: 1339, + port2Id: 1432, + isNonStopTransit: false + }, + { + id: 380, + port1Id: 1313, + port2Id: 1434, + isNonStopTransit: false + }, + { + id: 382, + port1Id: 1311, + port2Id: 1436, + isNonStopTransit: false + }, + { + id: 386, + port1Id: 1205, + port2Id: 1440, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 153, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 130, + betriebspunktName: "Biel", + fullName: "Biel", + positionX: -2528, + positionY: -32, + ports: [ + { + id: 1183, + trainrunSectionId: 584, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1418, + trainrunSectionId: 701, + positionIndex: 0, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 366, + port1Id: 1183, + port2Id: 1418, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 154, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 131, + betriebspunktName: "Interlaken ", + fullName: "Interlaken Ost", + positionX: -1088, + positionY: 928, + ports: [ + { + id: 1318, + trainrunSectionId: 651, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1344, + trainrunSectionId: 664, + positionIndex: 1, + positionAlignment: 2 + } + ], + transitions: [], + connections: [], + resourceId: 155, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 132, + betriebspunktName: "Visp", + fullName: "Visp", + positionX: -2144, + positionY: 1440, + ports: [ + { + id: 1323, + trainrunSectionId: 654, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1322, + trainrunSectionId: 653, + positionIndex: 1, + positionAlignment: 0 + } + ], + transitions: [], + connections: [], + resourceId: 156, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 133, + betriebspunktName: "Olten", + fullName: "Olten", + positionX: 64, + positionY: 96, + ports: [ + { + id: 1047, + trainrunSectionId: 516, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1331, + trainrunSectionId: 658, + positionIndex: 1, + positionAlignment: 0 + }, + { + id: 1308, + trainrunSectionId: 646, + positionIndex: 2, + positionAlignment: 0 + }, + { + id: 1371, + trainrunSectionId: 678, + positionIndex: 3, + positionAlignment: 0 + }, + { + id: 1131, + trainrunSectionId: 558, + positionIndex: 4, + positionAlignment: 0 + }, + { + id: 1117, + trainrunSectionId: 551, + positionIndex: 5, + positionAlignment: 0 + }, + { + id: 1046, + trainrunSectionId: 515, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1370, + trainrunSectionId: 677, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1130, + trainrunSectionId: 557, + positionIndex: 2, + positionAlignment: 1 + }, + { + id: 1116, + trainrunSectionId: 550, + positionIndex: 3, + positionAlignment: 1 + }, + { + id: 1181, + trainrunSectionId: 583, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1203, + trainrunSectionId: 594, + positionIndex: 1, + positionAlignment: 2 + }, + { + id: 1394, + trainrunSectionId: 689, + positionIndex: 2, + positionAlignment: 2 + }, + { + id: 1309, + trainrunSectionId: 647, + positionIndex: 3, + positionAlignment: 2 + }, + { + id: 1225, + trainrunSectionId: 605, + positionIndex: 4, + positionAlignment: 2 + }, + { + id: 1241, + trainrunSectionId: 613, + positionIndex: 5, + positionAlignment: 2 + }, + { + id: 1165, + trainrunSectionId: 575, + positionIndex: 6, + positionAlignment: 2 + }, + { + id: 1202, + trainrunSectionId: 593, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1180, + trainrunSectionId: 582, + positionIndex: 1, + positionAlignment: 3 + }, + { + id: 1224, + trainrunSectionId: 604, + positionIndex: 2, + positionAlignment: 3 + }, + { + id: 1240, + trainrunSectionId: 612, + positionIndex: 3, + positionAlignment: 3 + }, + { + id: 1164, + trainrunSectionId: 574, + positionIndex: 4, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 210, + port1Id: 1047, + port2Id: 1046, + isNonStopTransit: false + }, + { + id: 236, + port1Id: 1117, + port2Id: 1116, + isNonStopTransit: false + }, + { + id: 242, + port1Id: 1131, + port2Id: 1130, + isNonStopTransit: false + }, + { + id: 253, + port1Id: 1165, + port2Id: 1164, + isNonStopTransit: false + }, + { + id: 259, + port1Id: 1181, + port2Id: 1180, + isNonStopTransit: false + }, + { + id: 264, + port1Id: 1203, + port2Id: 1202, + isNonStopTransit: true + }, + { + id: 270, + port1Id: 1225, + port2Id: 1224, + isNonStopTransit: true + }, + { + id: 276, + port1Id: 1241, + port2Id: 1240, + isNonStopTransit: true + }, + { + id: 308, + port1Id: 1308, + port2Id: 1309, + isNonStopTransit: false + }, + { + id: 340, + port1Id: 1371, + port2Id: 1370, + isNonStopTransit: false + }, + { + id: 353, + port1Id: 1331, + port2Id: 1394, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 157, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 134, + betriebspunktName: "Basel", + fullName: "Basel", + positionX: 64, + positionY: -1888, + ports: [ + { + id: 1054, + trainrunSectionId: 519, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1416, + trainrunSectionId: 700, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1277, + trainrunSectionId: 631, + positionIndex: 2, + positionAlignment: 1 + }, + { + id: 1338, + trainrunSectionId: 661, + positionIndex: 3, + positionAlignment: 1 + }, + { + id: 1301, + trainrunSectionId: 643, + positionIndex: 4, + positionAlignment: 1 + }, + { + id: 1378, + trainrunSectionId: 681, + positionIndex: 5, + positionAlignment: 1 + }, + { + id: 1138, + trainrunSectionId: 561, + positionIndex: 6, + positionAlignment: 1 + }, + { + id: 1124, + trainrunSectionId: 554, + positionIndex: 7, + positionAlignment: 1 + }, + { + id: 1267, + trainrunSectionId: 626, + positionIndex: 0, + positionAlignment: 3 + } + ], + transitions: [], + connections: [], + resourceId: 158, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 135, + betriebspunktName: "Zürich", + fullName: "Zürich", + positionX: 2656, + positionY: 32, + ports: [ + { + id: 1255, + trainrunSectionId: 620, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1254, + trainrunSectionId: 619, + positionIndex: 1, + positionAlignment: 0 + }, + { + id: 1360, + trainrunSectionId: 672, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1149, + trainrunSectionId: 567, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1153, + trainrunSectionId: 569, + positionIndex: 2, + positionAlignment: 1 + }, + { + id: 1358, + trainrunSectionId: 671, + positionIndex: 3, + positionAlignment: 1 + }, + { + id: 1356, + trainrunSectionId: 670, + positionIndex: 4, + positionAlignment: 1 + }, + { + id: 1354, + trainrunSectionId: 669, + positionIndex: 5, + positionAlignment: 1 + }, + { + id: 1195, + trainrunSectionId: 590, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1401, + trainrunSectionId: 693, + positionIndex: 1, + positionAlignment: 2 + }, + { + id: 1292, + trainrunSectionId: 638, + positionIndex: 2, + positionAlignment: 2 + }, + { + id: 1173, + trainrunSectionId: 579, + positionIndex: 3, + positionAlignment: 2 + }, + { + id: 1217, + trainrunSectionId: 601, + positionIndex: 4, + positionAlignment: 2 + }, + { + id: 1233, + trainrunSectionId: 609, + positionIndex: 5, + positionAlignment: 2 + }, + { + id: 1157, + trainrunSectionId: 571, + positionIndex: 6, + positionAlignment: 2 + }, + { + id: 1276, + trainrunSectionId: 630, + positionIndex: 7, + positionAlignment: 2 + }, + { + id: 1300, + trainrunSectionId: 642, + positionIndex: 8, + positionAlignment: 2 + }, + { + id: 1191, + trainrunSectionId: 588, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1172, + trainrunSectionId: 578, + positionIndex: 1, + positionAlignment: 3 + }, + { + id: 1213, + trainrunSectionId: 599, + positionIndex: 2, + positionAlignment: 3 + }, + { + id: 1229, + trainrunSectionId: 607, + positionIndex: 3, + positionAlignment: 3 + }, + { + id: 1139, + trainrunSectionId: 562, + positionIndex: 4, + positionAlignment: 3 + }, + { + id: 1245, + trainrunSectionId: 615, + positionIndex: 5, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 250, + port1Id: 1153, + port2Id: 1157, + isNonStopTransit: false + }, + { + id: 256, + port1Id: 1173, + port2Id: 1172, + isNonStopTransit: false + }, + { + id: 261, + port1Id: 1195, + port2Id: 1191, + isNonStopTransit: false + }, + { + id: 267, + port1Id: 1217, + port2Id: 1213, + isNonStopTransit: false + }, + { + id: 273, + port1Id: 1233, + port2Id: 1229, + isNonStopTransit: false + }, + { + id: 329, + port1Id: 1354, + port2Id: 1245, + isNonStopTransit: false + }, + { + id: 357, + port1Id: 1149, + port2Id: 1401, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 159, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 136, + betriebspunktName: "Bellinz.", + fullName: "Bellinzona", + positionX: 2592, + positionY: 3232, + ports: [ + { + id: 1059, + trainrunSectionId: 522, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1035, + trainrunSectionId: 510, + positionIndex: 1, + positionAlignment: 0 + }, + { + id: 1071, + trainrunSectionId: 528, + positionIndex: 2, + positionAlignment: 0 + }, + { + id: 1083, + trainrunSectionId: 534, + positionIndex: 3, + positionAlignment: 0 + }, + { + id: 1058, + trainrunSectionId: 521, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1034, + trainrunSectionId: 509, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1070, + trainrunSectionId: 527, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1082, + trainrunSectionId: 533, + positionIndex: 1, + positionAlignment: 2 + } + ], + transitions: [ + { + id: 206, + port1Id: 1035, + port2Id: 1034, + isNonStopTransit: false + }, + { + id: 216, + port1Id: 1059, + port2Id: 1058, + isNonStopTransit: false + }, + { + id: 221, + port1Id: 1071, + port2Id: 1070, + isNonStopTransit: false + }, + { + id: 226, + port1Id: 1083, + port2Id: 1082, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 160, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 137, + betriebspunktName: "St. Gallen", + fullName: "Sankt Gallen", + positionX: 4640, + positionY: 96, + ports: [ + { + id: 1145, + trainrunSectionId: 565, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1212, + trainrunSectionId: 598, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1167, + trainrunSectionId: 576, + positionIndex: 1, + positionAlignment: 2 + }, + { + id: 1144, + trainrunSectionId: 564, + positionIndex: 2, + positionAlignment: 2 + }, + { + id: 1419, + trainrunSectionId: 702, + positionIndex: 0, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 248, + port1Id: 1145, + port2Id: 1144, + isNonStopTransit: false + }, + { + id: 367, + port1Id: 1167, + port2Id: 1419, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 161, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 138, + betriebspunktName: "Schaffh.", + fullName: "Schaffhausen", + positionX: 2624, + positionY: -1120, + ports: [ + { + id: 1256, + trainrunSectionId: 620, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1251, + trainrunSectionId: 618, + positionIndex: 1, + positionAlignment: 1 + } + ], + transitions: [], + connections: [], + resourceId: 162, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 139, + betriebspunktName: "Konstanz", + fullName: "Konstanz", + positionX: 4256, + positionY: -416, + ports: [ + { + id: 1250, + trainrunSectionId: 617, + positionIndex: 0, + positionAlignment: 1 + } + ], + transitions: [], + connections: [], + resourceId: 163, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 140, + betriebspunktName: "Sargans", + fullName: "Sargans", + positionX: 4640, + positionY: 1184, + ports: [ + { + id: 1146, + trainrunSectionId: 565, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1151, + trainrunSectionId: 568, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1147, + trainrunSectionId: 566, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1155, + trainrunSectionId: 570, + positionIndex: 2, + positionAlignment: 1 + }, + { + id: 1362, + trainrunSectionId: 673, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1364, + trainrunSectionId: 674, + positionIndex: 1, + positionAlignment: 2 + } + ], + transitions: [ + { + id: 249, + port1Id: 1146, + port2Id: 1147, + isNonStopTransit: false + }, + { + id: 334, + port1Id: 1151, + port2Id: 1362, + isNonStopTransit: false + }, + { + id: 336, + port1Id: 1155, + port2Id: 1364, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 164, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 141, + betriebspunktName: "Sursee", + fullName: "Sursee", + positionX: 64, + positionY: 1184, + ports: [ + { + id: 1043, + trainrunSectionId: 514, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1105, + trainrunSectionId: 545, + positionIndex: 1, + positionAlignment: 0 + }, + { + id: 1367, + trainrunSectionId: 676, + positionIndex: 2, + positionAlignment: 0 + }, + { + id: 1127, + trainrunSectionId: 556, + positionIndex: 3, + positionAlignment: 0 + }, + { + id: 1113, + trainrunSectionId: 549, + positionIndex: 4, + positionAlignment: 0 + }, + { + id: 1042, + trainrunSectionId: 513, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1104, + trainrunSectionId: 544, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1366, + trainrunSectionId: 675, + positionIndex: 2, + positionAlignment: 1 + }, + { + id: 1126, + trainrunSectionId: 555, + positionIndex: 3, + positionAlignment: 1 + }, + { + id: 1112, + trainrunSectionId: 548, + positionIndex: 4, + positionAlignment: 1 + } + ], + transitions: [ + { + id: 208, + port1Id: 1043, + port2Id: 1042, + isNonStopTransit: true + }, + { + id: 232, + port1Id: 1105, + port2Id: 1104, + isNonStopTransit: false + }, + { + id: 234, + port1Id: 1113, + port2Id: 1112, + isNonStopTransit: false + }, + { + id: 240, + port1Id: 1127, + port2Id: 1126, + isNonStopTransit: true + }, + { + id: 338, + port1Id: 1367, + port2Id: 1366, + isNonStopTransit: true + } + ], + connections: [], + resourceId: 165, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 142, + betriebspunktName: "Luzern", + fullName: "Luzern", + positionX: 64, + positionY: 1728, + ports: [ + { + id: 1041, + trainrunSectionId: 513, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1103, + trainrunSectionId: 544, + positionIndex: 1, + positionAlignment: 0 + }, + { + id: 1365, + trainrunSectionId: 675, + positionIndex: 2, + positionAlignment: 0 + }, + { + id: 1125, + trainrunSectionId: 555, + positionIndex: 3, + positionAlignment: 0 + }, + { + id: 1111, + trainrunSectionId: 548, + positionIndex: 4, + positionAlignment: 0 + }, + { + id: 1352, + trainrunSectionId: 668, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1350, + trainrunSectionId: 667, + positionIndex: 1, + positionAlignment: 3 + }, + { + id: 1099, + trainrunSectionId: 542, + positionIndex: 2, + positionAlignment: 3 + }, + { + id: 1095, + trainrunSectionId: 540, + positionIndex: 3, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 327, + port1Id: 1041, + port2Id: 1352, + isNonStopTransit: false + }, + { + id: 337, + port1Id: 1365, + port2Id: 1350, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 166, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 143, + betriebspunktName: "Zofingen", + fullName: "Zofingen", + positionX: 64, + positionY: 736, + ports: [ + { + id: 1045, + trainrunSectionId: 515, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1369, + trainrunSectionId: 677, + positionIndex: 1, + positionAlignment: 0 + }, + { + id: 1129, + trainrunSectionId: 557, + positionIndex: 2, + positionAlignment: 0 + }, + { + id: 1115, + trainrunSectionId: 550, + positionIndex: 3, + positionAlignment: 0 + }, + { + id: 1044, + trainrunSectionId: 514, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1106, + trainrunSectionId: 545, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1368, + trainrunSectionId: 676, + positionIndex: 2, + positionAlignment: 1 + }, + { + id: 1128, + trainrunSectionId: 556, + positionIndex: 3, + positionAlignment: 1 + }, + { + id: 1114, + trainrunSectionId: 549, + positionIndex: 4, + positionAlignment: 1 + }, + { + id: 1107, + trainrunSectionId: 546, + positionIndex: 0, + positionAlignment: 2 + } + ], + transitions: [ + { + id: 209, + port1Id: 1045, + port2Id: 1044, + isNonStopTransit: true + }, + { + id: 233, + port1Id: 1107, + port2Id: 1106, + isNonStopTransit: false + }, + { + id: 235, + port1Id: 1115, + port2Id: 1114, + isNonStopTransit: false + }, + { + id: 241, + port1Id: 1129, + port2Id: 1128, + isNonStopTransit: true + }, + { + id: 339, + port1Id: 1369, + port2Id: 1368, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 167, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 144, + betriebspunktName: "Gelterk.", + fullName: "Gelterkinden", + positionX: 64, + positionY: -448, + ports: [ + { + id: 1049, + trainrunSectionId: 517, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1411, + trainrunSectionId: 698, + positionIndex: 1, + positionAlignment: 0 + }, + { + id: 1282, + trainrunSectionId: 633, + positionIndex: 2, + positionAlignment: 0 + }, + { + id: 1333, + trainrunSectionId: 659, + positionIndex: 3, + positionAlignment: 0 + }, + { + id: 1306, + trainrunSectionId: 645, + positionIndex: 4, + positionAlignment: 0 + }, + { + id: 1373, + trainrunSectionId: 679, + positionIndex: 5, + positionAlignment: 0 + }, + { + id: 1133, + trainrunSectionId: 559, + positionIndex: 6, + positionAlignment: 0 + }, + { + id: 1119, + trainrunSectionId: 552, + positionIndex: 7, + positionAlignment: 0 + }, + { + id: 1048, + trainrunSectionId: 516, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1332, + trainrunSectionId: 658, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1307, + trainrunSectionId: 646, + positionIndex: 2, + positionAlignment: 1 + }, + { + id: 1372, + trainrunSectionId: 678, + positionIndex: 3, + positionAlignment: 1 + }, + { + id: 1132, + trainrunSectionId: 558, + positionIndex: 4, + positionAlignment: 1 + }, + { + id: 1118, + trainrunSectionId: 551, + positionIndex: 5, + positionAlignment: 1 + }, + { + id: 1410, + trainrunSectionId: 697, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1283, + trainrunSectionId: 634, + positionIndex: 1, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 211, + port1Id: 1049, + port2Id: 1048, + isNonStopTransit: true + }, + { + id: 237, + port1Id: 1119, + port2Id: 1118, + isNonStopTransit: false + }, + { + id: 243, + port1Id: 1133, + port2Id: 1132, + isNonStopTransit: true + }, + { + id: 297, + port1Id: 1282, + port2Id: 1283, + isNonStopTransit: true + }, + { + id: 307, + port1Id: 1306, + port2Id: 1307, + isNonStopTransit: true + }, + { + id: 316, + port1Id: 1333, + port2Id: 1332, + isNonStopTransit: true + }, + { + id: 341, + port1Id: 1373, + port2Id: 1372, + isNonStopTransit: true + }, + { + id: 362, + port1Id: 1411, + port2Id: 1410, + isNonStopTransit: true + } + ], + connections: [], + resourceId: 168, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 145, + betriebspunktName: "Sissach", + fullName: "Sissach", + positionX: 64, + positionY: -928, + ports: [ + { + id: 1051, + trainrunSectionId: 518, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1413, + trainrunSectionId: 699, + positionIndex: 1, + positionAlignment: 0 + }, + { + id: 1280, + trainrunSectionId: 632, + positionIndex: 2, + positionAlignment: 0 + }, + { + id: 1335, + trainrunSectionId: 660, + positionIndex: 3, + positionAlignment: 0 + }, + { + id: 1304, + trainrunSectionId: 644, + positionIndex: 4, + positionAlignment: 0 + }, + { + id: 1375, + trainrunSectionId: 680, + positionIndex: 5, + positionAlignment: 0 + }, + { + id: 1135, + trainrunSectionId: 560, + positionIndex: 6, + positionAlignment: 0 + }, + { + id: 1121, + trainrunSectionId: 553, + positionIndex: 7, + positionAlignment: 0 + }, + { + id: 1050, + trainrunSectionId: 517, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1412, + trainrunSectionId: 698, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1281, + trainrunSectionId: 633, + positionIndex: 2, + positionAlignment: 1 + }, + { + id: 1334, + trainrunSectionId: 659, + positionIndex: 3, + positionAlignment: 1 + }, + { + id: 1305, + trainrunSectionId: 645, + positionIndex: 4, + positionAlignment: 1 + }, + { + id: 1374, + trainrunSectionId: 679, + positionIndex: 5, + positionAlignment: 1 + }, + { + id: 1134, + trainrunSectionId: 559, + positionIndex: 6, + positionAlignment: 1 + }, + { + id: 1120, + trainrunSectionId: 552, + positionIndex: 7, + positionAlignment: 1 + } + ], + transitions: [ + { + id: 212, + port1Id: 1051, + port2Id: 1050, + isNonStopTransit: true + }, + { + id: 238, + port1Id: 1121, + port2Id: 1120, + isNonStopTransit: false + }, + { + id: 244, + port1Id: 1135, + port2Id: 1134, + isNonStopTransit: true + }, + { + id: 296, + port1Id: 1280, + port2Id: 1281, + isNonStopTransit: true + }, + { + id: 306, + port1Id: 1304, + port2Id: 1305, + isNonStopTransit: true + }, + { + id: 317, + port1Id: 1335, + port2Id: 1334, + isNonStopTransit: true + }, + { + id: 342, + port1Id: 1375, + port2Id: 1374, + isNonStopTransit: true + }, + { + id: 363, + port1Id: 1413, + port2Id: 1412, + isNonStopTransit: true + } + ], + connections: [], + resourceId: 169, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 146, + betriebspunktName: "Liestal", + fullName: "Liestal", + positionX: 64, + positionY: -1408, + ports: [ + { + id: 1053, + trainrunSectionId: 519, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1415, + trainrunSectionId: 700, + positionIndex: 1, + positionAlignment: 0 + }, + { + id: 1278, + trainrunSectionId: 631, + positionIndex: 2, + positionAlignment: 0 + }, + { + id: 1337, + trainrunSectionId: 661, + positionIndex: 3, + positionAlignment: 0 + }, + { + id: 1302, + trainrunSectionId: 643, + positionIndex: 4, + positionAlignment: 0 + }, + { + id: 1377, + trainrunSectionId: 681, + positionIndex: 5, + positionAlignment: 0 + }, + { + id: 1137, + trainrunSectionId: 561, + positionIndex: 6, + positionAlignment: 0 + }, + { + id: 1123, + trainrunSectionId: 554, + positionIndex: 7, + positionAlignment: 0 + }, + { + id: 1052, + trainrunSectionId: 518, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1414, + trainrunSectionId: 699, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1279, + trainrunSectionId: 632, + positionIndex: 2, + positionAlignment: 1 + }, + { + id: 1336, + trainrunSectionId: 660, + positionIndex: 3, + positionAlignment: 1 + }, + { + id: 1303, + trainrunSectionId: 644, + positionIndex: 4, + positionAlignment: 1 + }, + { + id: 1376, + trainrunSectionId: 680, + positionIndex: 5, + positionAlignment: 1 + }, + { + id: 1136, + trainrunSectionId: 560, + positionIndex: 6, + positionAlignment: 1 + }, + { + id: 1122, + trainrunSectionId: 553, + positionIndex: 7, + positionAlignment: 1 + } + ], + transitions: [ + { + id: 213, + port1Id: 1053, + port2Id: 1052, + isNonStopTransit: true + }, + { + id: 239, + port1Id: 1123, + port2Id: 1122, + isNonStopTransit: false + }, + { + id: 245, + port1Id: 1137, + port2Id: 1136, + isNonStopTransit: true + }, + { + id: 295, + port1Id: 1278, + port2Id: 1279, + isNonStopTransit: true + }, + { + id: 305, + port1Id: 1302, + port2Id: 1303, + isNonStopTransit: true + }, + { + id: 318, + port1Id: 1337, + port2Id: 1336, + isNonStopTransit: true + }, + { + id: 343, + port1Id: 1377, + port2Id: 1376, + isNonStopTransit: true + }, + { + id: 364, + port1Id: 1415, + port2Id: 1414, + isNonStopTransit: true + } + ], + connections: [], + resourceId: 170, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 147, + betriebspunktName: "Aarau", + fullName: "Aarau", + positionX: 960, + positionY: 32, + ports: [ + { + id: 1409, + trainrunSectionId: 697, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1284, + trainrunSectionId: 634, + positionIndex: 1, + positionAlignment: 2 + }, + { + id: 1201, + trainrunSectionId: 593, + positionIndex: 2, + positionAlignment: 2 + }, + { + id: 1179, + trainrunSectionId: 582, + positionIndex: 3, + positionAlignment: 2 + }, + { + id: 1223, + trainrunSectionId: 604, + positionIndex: 4, + positionAlignment: 2 + }, + { + id: 1239, + trainrunSectionId: 612, + positionIndex: 5, + positionAlignment: 2 + }, + { + id: 1163, + trainrunSectionId: 574, + positionIndex: 6, + positionAlignment: 2 + }, + { + id: 1200, + trainrunSectionId: 592, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1408, + trainrunSectionId: 696, + positionIndex: 1, + positionAlignment: 3 + }, + { + id: 1285, + trainrunSectionId: 635, + positionIndex: 2, + positionAlignment: 3 + }, + { + id: 1178, + trainrunSectionId: 581, + positionIndex: 3, + positionAlignment: 3 + }, + { + id: 1222, + trainrunSectionId: 603, + positionIndex: 4, + positionAlignment: 3 + }, + { + id: 1238, + trainrunSectionId: 611, + positionIndex: 5, + positionAlignment: 3 + }, + { + id: 1162, + trainrunSectionId: 573, + positionIndex: 6, + positionAlignment: 3 + }, + { + id: 1293, + trainrunSectionId: 639, + positionIndex: 7, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 252, + port1Id: 1163, + port2Id: 1162, + isNonStopTransit: true + }, + { + id: 258, + port1Id: 1179, + port2Id: 1178, + isNonStopTransit: false + }, + { + id: 263, + port1Id: 1201, + port2Id: 1200, + isNonStopTransit: true + }, + { + id: 269, + port1Id: 1223, + port2Id: 1222, + isNonStopTransit: true + }, + { + id: 275, + port1Id: 1239, + port2Id: 1238, + isNonStopTransit: true + }, + { + id: 298, + port1Id: 1284, + port2Id: 1285, + isNonStopTransit: true + }, + { + id: 361, + port1Id: 1409, + port2Id: 1408, + isNonStopTransit: true + } + ], + connections: [], + resourceId: 171, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 148, + betriebspunktName: "Lenzburg", + fullName: "Lenzburg", + positionX: 1344, + positionY: 32, + ports: [ + { + id: 1199, + trainrunSectionId: 592, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1407, + trainrunSectionId: 696, + positionIndex: 1, + positionAlignment: 2 + }, + { + id: 1286, + trainrunSectionId: 635, + positionIndex: 2, + positionAlignment: 2 + }, + { + id: 1177, + trainrunSectionId: 581, + positionIndex: 3, + positionAlignment: 2 + }, + { + id: 1221, + trainrunSectionId: 603, + positionIndex: 4, + positionAlignment: 2 + }, + { + id: 1237, + trainrunSectionId: 611, + positionIndex: 5, + positionAlignment: 2 + }, + { + id: 1161, + trainrunSectionId: 573, + positionIndex: 6, + positionAlignment: 2 + }, + { + id: 1294, + trainrunSectionId: 639, + positionIndex: 7, + positionAlignment: 2 + }, + { + id: 1258, + trainrunSectionId: 621, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1406, + trainrunSectionId: 695, + positionIndex: 1, + positionAlignment: 3 + }, + { + id: 1287, + trainrunSectionId: 636, + positionIndex: 2, + positionAlignment: 3 + }, + { + id: 1260, + trainrunSectionId: 622, + positionIndex: 3, + positionAlignment: 3 + }, + { + id: 1262, + trainrunSectionId: 623, + positionIndex: 4, + positionAlignment: 3 + }, + { + id: 1264, + trainrunSectionId: 624, + positionIndex: 5, + positionAlignment: 3 + }, + { + id: 1266, + trainrunSectionId: 625, + positionIndex: 6, + positionAlignment: 3 + }, + { + id: 1295, + trainrunSectionId: 640, + positionIndex: 7, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 282, + port1Id: 1199, + port2Id: 1258, + isNonStopTransit: true + }, + { + id: 284, + port1Id: 1177, + port2Id: 1260, + isNonStopTransit: true + }, + { + id: 286, + port1Id: 1221, + port2Id: 1262, + isNonStopTransit: true + }, + { + id: 288, + port1Id: 1237, + port2Id: 1264, + isNonStopTransit: true + }, + { + id: 290, + port1Id: 1161, + port2Id: 1266, + isNonStopTransit: true + }, + { + id: 299, + port1Id: 1286, + port2Id: 1287, + isNonStopTransit: true + }, + { + id: 302, + port1Id: 1294, + port2Id: 1295, + isNonStopTransit: false + }, + { + id: 360, + port1Id: 1407, + port2Id: 1406, + isNonStopTransit: true + } + ], + connections: [], + resourceId: 172, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 149, + betriebspunktName: "Baden", + fullName: "Baden", + positionX: 2240, + positionY: 32, + ports: [ + { + id: 1197, + trainrunSectionId: 591, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1403, + trainrunSectionId: 694, + positionIndex: 1, + positionAlignment: 2 + }, + { + id: 1290, + trainrunSectionId: 637, + positionIndex: 2, + positionAlignment: 2 + }, + { + id: 1175, + trainrunSectionId: 580, + positionIndex: 3, + positionAlignment: 2 + }, + { + id: 1219, + trainrunSectionId: 602, + positionIndex: 4, + positionAlignment: 2 + }, + { + id: 1235, + trainrunSectionId: 610, + positionIndex: 5, + positionAlignment: 2 + }, + { + id: 1159, + trainrunSectionId: 572, + positionIndex: 6, + positionAlignment: 2 + }, + { + id: 1274, + trainrunSectionId: 629, + positionIndex: 7, + positionAlignment: 2 + }, + { + id: 1298, + trainrunSectionId: 641, + positionIndex: 8, + positionAlignment: 2 + }, + { + id: 1196, + trainrunSectionId: 590, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1402, + trainrunSectionId: 693, + positionIndex: 1, + positionAlignment: 3 + }, + { + id: 1291, + trainrunSectionId: 638, + positionIndex: 2, + positionAlignment: 3 + }, + { + id: 1174, + trainrunSectionId: 579, + positionIndex: 3, + positionAlignment: 3 + }, + { + id: 1218, + trainrunSectionId: 601, + positionIndex: 4, + positionAlignment: 3 + }, + { + id: 1234, + trainrunSectionId: 609, + positionIndex: 5, + positionAlignment: 3 + }, + { + id: 1158, + trainrunSectionId: 571, + positionIndex: 6, + positionAlignment: 3 + }, + { + id: 1275, + trainrunSectionId: 630, + positionIndex: 7, + positionAlignment: 3 + }, + { + id: 1299, + trainrunSectionId: 642, + positionIndex: 8, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 251, + port1Id: 1159, + port2Id: 1158, + isNonStopTransit: true + }, + { + id: 257, + port1Id: 1175, + port2Id: 1174, + isNonStopTransit: true + }, + { + id: 262, + port1Id: 1197, + port2Id: 1196, + isNonStopTransit: true + }, + { + id: 268, + port1Id: 1219, + port2Id: 1218, + isNonStopTransit: true + }, + { + id: 274, + port1Id: 1235, + port2Id: 1234, + isNonStopTransit: true + }, + { + id: 294, + port1Id: 1274, + port2Id: 1275, + isNonStopTransit: false + }, + { + id: 301, + port1Id: 1290, + port2Id: 1291, + isNonStopTransit: true + }, + { + id: 304, + port1Id: 1298, + port2Id: 1299, + isNonStopTransit: true + }, + { + id: 358, + port1Id: 1403, + port2Id: 1402, + isNonStopTransit: true + } + ], + connections: [], + resourceId: 173, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 150, + betriebspunktName: "Zürich ✈", + fullName: "Zürich Flughafen", + positionX: 3296, + positionY: 32, + ports: [ + { + id: 1192, + trainrunSectionId: 588, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1171, + trainrunSectionId: 578, + positionIndex: 1, + positionAlignment: 2 + }, + { + id: 1214, + trainrunSectionId: 599, + positionIndex: 2, + positionAlignment: 2 + }, + { + id: 1230, + trainrunSectionId: 607, + positionIndex: 3, + positionAlignment: 2 + }, + { + id: 1140, + trainrunSectionId: 562, + positionIndex: 4, + positionAlignment: 2 + }, + { + id: 1246, + trainrunSectionId: 615, + positionIndex: 5, + positionAlignment: 2 + }, + { + id: 1193, + trainrunSectionId: 589, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1170, + trainrunSectionId: 577, + positionIndex: 1, + positionAlignment: 3 + }, + { + id: 1215, + trainrunSectionId: 600, + positionIndex: 2, + positionAlignment: 3 + }, + { + id: 1231, + trainrunSectionId: 608, + positionIndex: 3, + positionAlignment: 3 + }, + { + id: 1141, + trainrunSectionId: 563, + positionIndex: 4, + positionAlignment: 3 + }, + { + id: 1247, + trainrunSectionId: 616, + positionIndex: 5, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 246, + port1Id: 1140, + port2Id: 1141, + isNonStopTransit: false + }, + { + id: 255, + port1Id: 1171, + port2Id: 1170, + isNonStopTransit: false + }, + { + id: 260, + port1Id: 1192, + port2Id: 1193, + isNonStopTransit: false + }, + { + id: 266, + port1Id: 1214, + port2Id: 1215, + isNonStopTransit: false + }, + { + id: 272, + port1Id: 1230, + port2Id: 1231, + isNonStopTransit: false + }, + { + id: 278, + port1Id: 1246, + port2Id: 1247, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 174, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 151, + betriebspunktName: "Wintert.", + fullName: "Winterthur", + positionX: 3872, + positionY: 32, + ports: [ + { + id: 1249, + trainrunSectionId: 617, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1194, + trainrunSectionId: 589, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1169, + trainrunSectionId: 577, + positionIndex: 1, + positionAlignment: 2 + }, + { + id: 1216, + trainrunSectionId: 600, + positionIndex: 2, + positionAlignment: 2 + }, + { + id: 1232, + trainrunSectionId: 608, + positionIndex: 3, + positionAlignment: 2 + }, + { + id: 1142, + trainrunSectionId: 563, + positionIndex: 4, + positionAlignment: 2 + }, + { + id: 1248, + trainrunSectionId: 616, + positionIndex: 5, + positionAlignment: 2 + }, + { + id: 1227, + trainrunSectionId: 606, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1243, + trainrunSectionId: 614, + positionIndex: 1, + positionAlignment: 3 + }, + { + id: 1211, + trainrunSectionId: 598, + positionIndex: 2, + positionAlignment: 3 + }, + { + id: 1168, + trainrunSectionId: 576, + positionIndex: 3, + positionAlignment: 3 + }, + { + id: 1143, + trainrunSectionId: 564, + positionIndex: 4, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 247, + port1Id: 1142, + port2Id: 1143, + isNonStopTransit: false + }, + { + id: 254, + port1Id: 1169, + port2Id: 1168, + isNonStopTransit: false + }, + { + id: 265, + port1Id: 1194, + port2Id: 1211, + isNonStopTransit: false + }, + { + id: 271, + port1Id: 1216, + port2Id: 1227, + isNonStopTransit: false + }, + { + id: 277, + port1Id: 1232, + port2Id: 1243, + isNonStopTransit: false + }, + { + id: 279, + port1Id: 1249, + port2Id: 1248, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 175, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 152, + betriebspunktName: "Chur", + fullName: "Chur", + positionX: 4640, + positionY: 1888, + ports: [ + { + id: 1152, + trainrunSectionId: 568, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1148, + trainrunSectionId: 566, + positionIndex: 1, + positionAlignment: 0 + }, + { + id: 1156, + trainrunSectionId: 570, + positionIndex: 2, + positionAlignment: 0 + } + ], + transitions: [], + connections: [], + resourceId: 176, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 153, + betriebspunktName: "Zug", + fullName: "Zug", + positionX: 2656, + positionY: 1312, + ports: [ + { + id: 1067, + trainrunSectionId: 526, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1093, + trainrunSectionId: 539, + positionIndex: 1, + positionAlignment: 0 + }, + { + id: 1101, + trainrunSectionId: 543, + positionIndex: 2, + positionAlignment: 0 + }, + { + id: 1097, + trainrunSectionId: 541, + positionIndex: 3, + positionAlignment: 0 + }, + { + id: 1066, + trainrunSectionId: 525, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1092, + trainrunSectionId: 538, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1348, + trainrunSectionId: 666, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1346, + trainrunSectionId: 665, + positionIndex: 1, + positionAlignment: 2 + } + ], + transitions: [ + { + id: 220, + port1Id: 1067, + port2Id: 1066, + isNonStopTransit: false + }, + { + id: 231, + port1Id: 1093, + port2Id: 1092, + isNonStopTransit: false + }, + { + id: 322, + port1Id: 1097, + port2Id: 1346, + isNonStopTransit: false + }, + { + id: 324, + port1Id: 1101, + port2Id: 1348, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 177, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 154, + betriebspunktName: "Arth-G.", + fullName: "Arth-Goldau", + positionX: 2656, + positionY: 1792, + ports: [ + { + id: 1065, + trainrunSectionId: 525, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1091, + trainrunSectionId: 538, + positionIndex: 1, + positionAlignment: 0 + }, + { + id: 1064, + trainrunSectionId: 524, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1038, + trainrunSectionId: 511, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1078, + trainrunSectionId: 531, + positionIndex: 2, + positionAlignment: 1 + }, + { + id: 1090, + trainrunSectionId: 537, + positionIndex: 3, + positionAlignment: 1 + }, + { + id: 1039, + trainrunSectionId: 512, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1079, + trainrunSectionId: 532, + positionIndex: 1, + positionAlignment: 2 + } + ], + transitions: [ + { + id: 207, + port1Id: 1038, + port2Id: 1039, + isNonStopTransit: false + }, + { + id: 219, + port1Id: 1065, + port2Id: 1064, + isNonStopTransit: false + }, + { + id: 225, + port1Id: 1078, + port2Id: 1079, + isNonStopTransit: false + }, + { + id: 230, + port1Id: 1091, + port2Id: 1090, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 178, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 155, + betriebspunktName: "Altdorf", + fullName: "Altdorf", + positionX: 2656, + positionY: 2176, + ports: [ + { + id: 1063, + trainrunSectionId: 524, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1037, + trainrunSectionId: 511, + positionIndex: 1, + positionAlignment: 0 + }, + { + id: 1077, + trainrunSectionId: 531, + positionIndex: 2, + positionAlignment: 0 + }, + { + id: 1089, + trainrunSectionId: 537, + positionIndex: 3, + positionAlignment: 0 + }, + { + id: 1062, + trainrunSectionId: 523, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1055, + trainrunSectionId: 520, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1076, + trainrunSectionId: 530, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1088, + trainrunSectionId: 536, + positionIndex: 1, + positionAlignment: 2 + } + ], + transitions: [ + { + id: 214, + port1Id: 1037, + port2Id: 1055, + isNonStopTransit: true + }, + { + id: 218, + port1Id: 1063, + port2Id: 1062, + isNonStopTransit: false + }, + { + id: 224, + port1Id: 1077, + port2Id: 1076, + isNonStopTransit: false + }, + { + id: 229, + port1Id: 1089, + port2Id: 1088, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 179, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 156, + betriebspunktName: "Lugano", + fullName: "Lugano", + positionX: 2592, + positionY: 3712, + ports: [ + { + id: 1057, + trainrunSectionId: 521, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1033, + trainrunSectionId: 509, + positionIndex: 1, + positionAlignment: 0 + } + ], + transitions: [], + connections: [], + resourceId: 180, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 157, + betriebspunktName: "Locarno", + fullName: "Locarno", + positionX: 2208, + positionY: 3232, + ports: [ + { + id: 1069, + trainrunSectionId: 527, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1081, + trainrunSectionId: 533, + positionIndex: 1, + positionAlignment: 3 + } + ], + transitions: [], + connections: [], + resourceId: 181, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 158, + betriebspunktName: "Biasca", + fullName: "Biasca", + positionX: 2592, + positionY: 2688, + ports: [ + { + id: 1073, + trainrunSectionId: 529, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1085, + trainrunSectionId: 535, + positionIndex: 1, + positionAlignment: 0 + }, + { + id: 1061, + trainrunSectionId: 523, + positionIndex: 2, + positionAlignment: 0 + }, + { + id: 1056, + trainrunSectionId: 520, + positionIndex: 3, + positionAlignment: 0 + }, + { + id: 1060, + trainrunSectionId: 522, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1036, + trainrunSectionId: 510, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1072, + trainrunSectionId: 528, + positionIndex: 2, + positionAlignment: 1 + }, + { + id: 1084, + trainrunSectionId: 534, + positionIndex: 3, + positionAlignment: 1 + } + ], + transitions: [ + { + id: 215, + port1Id: 1056, + port2Id: 1036, + isNonStopTransit: true + }, + { + id: 217, + port1Id: 1061, + port2Id: 1060, + isNonStopTransit: true + }, + { + id: 222, + port1Id: 1073, + port2Id: 1072, + isNonStopTransit: false + }, + { + id: 227, + port1Id: 1085, + port2Id: 1084, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 182, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 159, + betriebspunktName: "Göschn.", + fullName: "Göschenen", + positionX: 2272, + positionY: 2240, + ports: [ + { + id: 1074, + trainrunSectionId: 529, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1086, + trainrunSectionId: 535, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1075, + trainrunSectionId: 530, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1087, + trainrunSectionId: 536, + positionIndex: 1, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 223, + port1Id: 1074, + port2Id: 1075, + isNonStopTransit: false + }, + { + id: 228, + port1Id: 1086, + port2Id: 1087, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 183, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 160, + betriebspunktName: "Genf", + fullName: "Genf", + positionX: -3936, + positionY: 608, + ports: [ + { + id: 1209, + trainrunSectionId: 597, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1185, + trainrunSectionId: 585, + positionIndex: 1, + positionAlignment: 2 + }, + { + id: 1189, + trainrunSectionId: 587, + positionIndex: 2, + positionAlignment: 2 + }, + { + id: 1424, + trainrunSectionId: 704, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1426, + trainrunSectionId: 705, + positionIndex: 1, + positionAlignment: 3 + }, + { + id: 1422, + trainrunSectionId: 703, + positionIndex: 2, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 369, + port1Id: 1189, + port2Id: 1422, + isNonStopTransit: false + }, + { + id: 371, + port1Id: 1209, + port2Id: 1424, + isNonStopTransit: false + }, + { + id: 373, + port1Id: 1185, + port2Id: 1426, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 184, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 161, + betriebspunktName: "Genf ✈", + fullName: "Aiport", + positionX: -4352, + positionY: 608, + ports: [ + { + id: 1210, + trainrunSectionId: 597, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1186, + trainrunSectionId: 585, + positionIndex: 1, + positionAlignment: 3 + }, + { + id: 1190, + trainrunSectionId: 587, + positionIndex: 2, + positionAlignment: 3 + } + ], + transitions: [], + connections: [], + resourceId: 185, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 162, + betriebspunktName: "Romansh.", + fullName: "Romanshorn", + positionX: 4640, + positionY: -192, + ports: [ + { + id: 1228, + trainrunSectionId: 606, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1244, + trainrunSectionId: 614, + positionIndex: 1, + positionAlignment: 2 + } + ], + transitions: [], + connections: [], + resourceId: 186, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 163, + betriebspunktName: "Bülach", + fullName: "Bülach", + positionX: 2784, + positionY: -544, + ports: [ + { + id: 1252, + trainrunSectionId: 618, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1253, + trainrunSectionId: 619, + positionIndex: 0, + positionAlignment: 1 + } + ], + transitions: [ + { + id: 280, + port1Id: 1252, + port2Id: 1253, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 187, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 164, + betriebspunktName: "Reihnf.", + fullName: "Reihnfelden", + positionX: 1056, + positionY: -960, + ports: [ + { + id: 1268, + trainrunSectionId: 626, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1269, + trainrunSectionId: 627, + positionIndex: 0, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 291, + port1Id: 1268, + port2Id: 1269, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 188, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 165, + betriebspunktName: "Frick", + fullName: "Frick", + positionX: 1792, + positionY: -672, + ports: [ + { + id: 1271, + trainrunSectionId: 628, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1270, + trainrunSectionId: 627, + positionIndex: 0, + positionAlignment: 2 + } + ], + transitions: [ + { + id: 292, + port1Id: 1271, + port2Id: 1270, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 189, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 166, + betriebspunktName: "Brugg", + fullName: "Brugg", + positionX: 1792, + positionY: 32, + ports: [ + { + id: 1272, + trainrunSectionId: 628, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1257, + trainrunSectionId: 621, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1405, + trainrunSectionId: 695, + positionIndex: 1, + positionAlignment: 2 + }, + { + id: 1288, + trainrunSectionId: 636, + positionIndex: 2, + positionAlignment: 2 + }, + { + id: 1259, + trainrunSectionId: 622, + positionIndex: 3, + positionAlignment: 2 + }, + { + id: 1261, + trainrunSectionId: 623, + positionIndex: 4, + positionAlignment: 2 + }, + { + id: 1263, + trainrunSectionId: 624, + positionIndex: 5, + positionAlignment: 2 + }, + { + id: 1265, + trainrunSectionId: 625, + positionIndex: 6, + positionAlignment: 2 + }, + { + id: 1296, + trainrunSectionId: 640, + positionIndex: 7, + positionAlignment: 2 + }, + { + id: 1198, + trainrunSectionId: 591, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1404, + trainrunSectionId: 694, + positionIndex: 1, + positionAlignment: 3 + }, + { + id: 1289, + trainrunSectionId: 637, + positionIndex: 2, + positionAlignment: 3 + }, + { + id: 1176, + trainrunSectionId: 580, + positionIndex: 3, + positionAlignment: 3 + }, + { + id: 1220, + trainrunSectionId: 602, + positionIndex: 4, + positionAlignment: 3 + }, + { + id: 1236, + trainrunSectionId: 610, + positionIndex: 5, + positionAlignment: 3 + }, + { + id: 1160, + trainrunSectionId: 572, + positionIndex: 6, + positionAlignment: 3 + }, + { + id: 1273, + trainrunSectionId: 629, + positionIndex: 7, + positionAlignment: 3 + }, + { + id: 1297, + trainrunSectionId: 641, + positionIndex: 8, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 281, + port1Id: 1257, + port2Id: 1198, + isNonStopTransit: true + }, + { + id: 283, + port1Id: 1259, + port2Id: 1176, + isNonStopTransit: true + }, + { + id: 285, + port1Id: 1261, + port2Id: 1220, + isNonStopTransit: true + }, + { + id: 287, + port1Id: 1263, + port2Id: 1236, + isNonStopTransit: false + }, + { + id: 289, + port1Id: 1265, + port2Id: 1160, + isNonStopTransit: true + }, + { + id: 293, + port1Id: 1272, + port2Id: 1273, + isNonStopTransit: false + }, + { + id: 300, + port1Id: 1288, + port2Id: 1289, + isNonStopTransit: true + }, + { + id: 303, + port1Id: 1296, + port2Id: 1297, + isNonStopTransit: true + }, + { + id: 359, + port1Id: 1405, + port2Id: 1404, + isNonStopTransit: true + } + ], + connections: [], + resourceId: 190, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 167, + betriebspunktName: "Thun", + fullName: "Thun", + positionX: -2144, + positionY: 640, + ports: [ + { + id: 1327, + trainrunSectionId: 656, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1312, + trainrunSectionId: 648, + positionIndex: 1, + positionAlignment: 0 + }, + { + id: 1314, + trainrunSectionId: 649, + positionIndex: 2, + positionAlignment: 0 + }, + { + id: 1340, + trainrunSectionId: 662, + positionIndex: 3, + positionAlignment: 0 + }, + { + id: 1326, + trainrunSectionId: 655, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1315, + trainrunSectionId: 650, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1319, + trainrunSectionId: 652, + positionIndex: 2, + positionAlignment: 1 + }, + { + id: 1341, + trainrunSectionId: 663, + positionIndex: 3, + positionAlignment: 1 + } + ], + transitions: [ + { + id: 309, + port1Id: 1312, + port2Id: 1315, + isNonStopTransit: false + }, + { + id: 311, + port1Id: 1314, + port2Id: 1319, + isNonStopTransit: false + }, + { + id: 314, + port1Id: 1327, + port2Id: 1326, + isNonStopTransit: false + }, + { + id: 319, + port1Id: 1340, + port2Id: 1341, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 191, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 168, + betriebspunktName: "Spiez", + fullName: "Spiez", + positionX: -2144, + positionY: 928, + ports: [ + { + id: 1325, + trainrunSectionId: 655, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1316, + trainrunSectionId: 650, + positionIndex: 1, + positionAlignment: 0 + }, + { + id: 1320, + trainrunSectionId: 652, + positionIndex: 2, + positionAlignment: 0 + }, + { + id: 1342, + trainrunSectionId: 663, + positionIndex: 3, + positionAlignment: 0 + }, + { + id: 1324, + trainrunSectionId: 654, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1321, + trainrunSectionId: 653, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1317, + trainrunSectionId: 651, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1343, + trainrunSectionId: 664, + positionIndex: 1, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 310, + port1Id: 1316, + port2Id: 1317, + isNonStopTransit: false + }, + { + id: 312, + port1Id: 1320, + port2Id: 1321, + isNonStopTransit: false + }, + { + id: 313, + port1Id: 1325, + port2Id: 1324, + isNonStopTransit: false + }, + { + id: 320, + port1Id: 1342, + port2Id: 1343, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 192, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 169, + betriebspunktName: "Rothkr.", + fullName: "Rothkreuz", + positionX: 1856, + positionY: 1728, + ports: [ + { + id: 1351, + trainrunSectionId: 668, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1349, + trainrunSectionId: 667, + positionIndex: 1, + positionAlignment: 2 + }, + { + id: 1100, + trainrunSectionId: 542, + positionIndex: 2, + positionAlignment: 2 + }, + { + id: 1096, + trainrunSectionId: 540, + positionIndex: 3, + positionAlignment: 2 + }, + { + id: 1347, + trainrunSectionId: 666, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1345, + trainrunSectionId: 665, + positionIndex: 1, + positionAlignment: 3 + }, + { + id: 1040, + trainrunSectionId: 512, + positionIndex: 2, + positionAlignment: 3 + }, + { + id: 1080, + trainrunSectionId: 532, + positionIndex: 3, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 321, + port1Id: 1096, + port2Id: 1345, + isNonStopTransit: false + }, + { + id: 323, + port1Id: 1100, + port2Id: 1347, + isNonStopTransit: true + }, + { + id: 325, + port1Id: 1349, + port2Id: 1080, + isNonStopTransit: true + }, + { + id: 326, + port1Id: 1351, + port2Id: 1040, + isNonStopTransit: true + } + ], + connections: [], + resourceId: 193, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 170, + betriebspunktName: "Thalwil", + fullName: "Thalwil", + positionX: 2656, + positionY: 736, + ports: [ + { + id: 1359, + trainrunSectionId: 672, + positionIndex: 0, + positionAlignment: 0 + }, + { + id: 1150, + trainrunSectionId: 567, + positionIndex: 1, + positionAlignment: 0 + }, + { + id: 1154, + trainrunSectionId: 569, + positionIndex: 2, + positionAlignment: 0 + }, + { + id: 1357, + trainrunSectionId: 671, + positionIndex: 3, + positionAlignment: 0 + }, + { + id: 1355, + trainrunSectionId: 670, + positionIndex: 4, + positionAlignment: 0 + }, + { + id: 1353, + trainrunSectionId: 669, + positionIndex: 5, + positionAlignment: 0 + }, + { + id: 1068, + trainrunSectionId: 526, + positionIndex: 0, + positionAlignment: 1 + }, + { + id: 1094, + trainrunSectionId: 539, + positionIndex: 1, + positionAlignment: 1 + }, + { + id: 1102, + trainrunSectionId: 543, + positionIndex: 2, + positionAlignment: 1 + }, + { + id: 1098, + trainrunSectionId: 541, + positionIndex: 3, + positionAlignment: 1 + }, + { + id: 1361, + trainrunSectionId: 673, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1363, + trainrunSectionId: 674, + positionIndex: 1, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 328, + port1Id: 1353, + port2Id: 1098, + isNonStopTransit: false + }, + { + id: 330, + port1Id: 1355, + port2Id: 1102, + isNonStopTransit: true + }, + { + id: 331, + port1Id: 1357, + port2Id: 1094, + isNonStopTransit: true + }, + { + id: 332, + port1Id: 1359, + port2Id: 1068, + isNonStopTransit: true + }, + { + id: 333, + port1Id: 1150, + port2Id: 1361, + isNonStopTransit: true + }, + { + id: 335, + port1Id: 1154, + port2Id: 1363, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 194, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 171, + betriebspunktName: "Fribourg", + fullName: "Fribourg", + positionX: -2560, + positionY: 288, + ports: [ + { + id: 1381, + trainrunSectionId: 683, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1379, + trainrunSectionId: 682, + positionIndex: 1, + positionAlignment: 2 + }, + { + id: 1206, + trainrunSectionId: 595, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1110, + trainrunSectionId: 547, + positionIndex: 1, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 344, + port1Id: 1379, + port2Id: 1110, + isNonStopTransit: false + }, + { + id: 346, + port1Id: 1381, + port2Id: 1206, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 195, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 172, + betriebspunktName: "RTR", + fullName: "Rothrist", + positionX: -608, + positionY: 128, + ports: [ + { + id: 1395, + trainrunSectionId: 690, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1438, + trainrunSectionId: 711, + positionIndex: 1, + positionAlignment: 2 + }, + { + id: 1391, + trainrunSectionId: 688, + positionIndex: 2, + positionAlignment: 2 + }, + { + id: 1389, + trainrunSectionId: 687, + positionIndex: 3, + positionAlignment: 2 + }, + { + id: 1387, + trainrunSectionId: 686, + positionIndex: 4, + positionAlignment: 2 + }, + { + id: 1383, + trainrunSectionId: 684, + positionIndex: 5, + positionAlignment: 2 + }, + { + id: 1385, + trainrunSectionId: 685, + positionIndex: 6, + positionAlignment: 2 + }, + { + id: 1204, + trainrunSectionId: 594, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1393, + trainrunSectionId: 689, + positionIndex: 1, + positionAlignment: 3 + }, + { + id: 1310, + trainrunSectionId: 647, + positionIndex: 2, + positionAlignment: 3 + }, + { + id: 1226, + trainrunSectionId: 605, + positionIndex: 3, + positionAlignment: 3 + }, + { + id: 1242, + trainrunSectionId: 613, + positionIndex: 4, + positionAlignment: 3 + }, + { + id: 1166, + trainrunSectionId: 575, + positionIndex: 5, + positionAlignment: 3 + }, + { + id: 1108, + trainrunSectionId: 546, + positionIndex: 6, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 348, + port1Id: 1108, + port2Id: 1383, + isNonStopTransit: true + }, + { + id: 349, + port1Id: 1385, + port2Id: 1166, + isNonStopTransit: true + }, + { + id: 350, + port1Id: 1387, + port2Id: 1242, + isNonStopTransit: true + }, + { + id: 351, + port1Id: 1389, + port2Id: 1226, + isNonStopTransit: true + }, + { + id: 352, + port1Id: 1391, + port2Id: 1310, + isNonStopTransit: true + }, + { + id: 354, + port1Id: 1395, + port2Id: 1204, + isNonStopTransit: true + }, + { + id: 384, + port1Id: 1438, + port2Id: 1393, + isNonStopTransit: true + } + ], + connections: [], + resourceId: 196, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 173, + betriebspunktName: "Burgdorf", + fullName: "Burgdorf", + positionX: -1344, + positionY: 352, + ports: [ + { + id: 1397, + trainrunSectionId: 691, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1400, + trainrunSectionId: 692, + positionIndex: 0, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 356, + port1Id: 1397, + port2Id: 1400, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 197, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 174, + betriebspunktName: "Langent.", + fullName: "Langenthal", + positionX: -992, + positionY: 352, + ports: [ + { + id: 1399, + trainrunSectionId: 692, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1386, + trainrunSectionId: 685, + positionIndex: 0, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 355, + port1Id: 1399, + port2Id: 1386, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 198, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 175, + betriebspunktName: "Solothurn", + fullName: "Solothurn", + positionX: -1696, + positionY: -32, + ports: [ + { + id: 1417, + trainrunSectionId: 701, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1182, + trainrunSectionId: 583, + positionIndex: 0, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 365, + port1Id: 1417, + port2Id: 1182, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 199, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 176, + betriebspunktName: "Rohrsch.", + fullName: "Rohrschach", + positionX: 5376, + positionY: 96, + ports: [ + { + id: 1420, + trainrunSectionId: 702, + positionIndex: 0, + positionAlignment: 2 + } + ], + transitions: [], + connections: [], + resourceId: 200, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 177, + betriebspunktName: "Morges", + fullName: "Morges", + positionX: -3520, + positionY: 544, + ports: [ + { + id: 1423, + trainrunSectionId: 704, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1425, + trainrunSectionId: 705, + positionIndex: 1, + positionAlignment: 2 + }, + { + id: 1421, + trainrunSectionId: 703, + positionIndex: 2, + positionAlignment: 2 + }, + { + id: 1184, + trainrunSectionId: 584, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1208, + trainrunSectionId: 596, + positionIndex: 1, + positionAlignment: 3 + }, + { + id: 1188, + trainrunSectionId: 586, + positionIndex: 2, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 368, + port1Id: 1421, + port2Id: 1188, + isNonStopTransit: false + }, + { + id: 370, + port1Id: 1423, + port2Id: 1208, + isNonStopTransit: true + }, + { + id: 372, + port1Id: 1425, + port2Id: 1184, + isNonStopTransit: false + } + ], + connections: [], + resourceId: 201, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + }, + { + id: 178, + betriebspunktName: "BNWD", + fullName: "Bern Wankdorf", + positionX: -1696, + positionY: 128, + ports: [ + { + id: 1439, + trainrunSectionId: 712, + positionIndex: 0, + positionAlignment: 2 + }, + { + id: 1330, + trainrunSectionId: 657, + positionIndex: 1, + positionAlignment: 2 + }, + { + id: 1435, + trainrunSectionId: 710, + positionIndex: 2, + positionAlignment: 2 + }, + { + id: 1433, + trainrunSectionId: 709, + positionIndex: 3, + positionAlignment: 2 + }, + { + id: 1431, + trainrunSectionId: 708, + positionIndex: 4, + positionAlignment: 2 + }, + { + id: 1429, + trainrunSectionId: 707, + positionIndex: 5, + positionAlignment: 2 + }, + { + id: 1427, + trainrunSectionId: 706, + positionIndex: 6, + positionAlignment: 2 + }, + { + id: 1396, + trainrunSectionId: 690, + positionIndex: 0, + positionAlignment: 3 + }, + { + id: 1437, + trainrunSectionId: 711, + positionIndex: 1, + positionAlignment: 3 + }, + { + id: 1392, + trainrunSectionId: 688, + positionIndex: 2, + positionAlignment: 3 + }, + { + id: 1390, + trainrunSectionId: 687, + positionIndex: 3, + positionAlignment: 3 + }, + { + id: 1388, + trainrunSectionId: 686, + positionIndex: 4, + positionAlignment: 3 + }, + { + id: 1384, + trainrunSectionId: 684, + positionIndex: 5, + positionAlignment: 3 + }, + { + id: 1398, + trainrunSectionId: 691, + positionIndex: 6, + positionAlignment: 3 + } + ], + transitions: [ + { + id: 374, + port1Id: 1427, + port2Id: 1398, + isNonStopTransit: true + }, + { + id: 375, + port1Id: 1429, + port2Id: 1384, + isNonStopTransit: true + }, + { + id: 377, + port1Id: 1431, + port2Id: 1388, + isNonStopTransit: true + }, + { + id: 379, + port1Id: 1433, + port2Id: 1390, + isNonStopTransit: true + }, + { + id: 381, + port1Id: 1435, + port2Id: 1392, + isNonStopTransit: true + }, + { + id: 383, + port1Id: 1330, + port2Id: 1437, + isNonStopTransit: true + }, + { + id: 385, + port1Id: 1439, + port2Id: 1396, + isNonStopTransit: true + } + ], + connections: [], + resourceId: 202, + perronkanten: 5, + connectionTime: 3, + trainrunCategoryHaltezeiten: { + HaltezeitA: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitB: { + no_halt: false, + haltezeit: 2 + }, + HaltezeitC: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitD: { + no_halt: false, + haltezeit: 1 + }, + HaltezeitIPV: { + no_halt: false, + haltezeit: 3 + }, + HaltezeitUncategorized: { + no_halt: true, + haltezeit: 0 + } + }, + symmetryAxis: null, + warnings: null, + labelIds: [] + } + ], + trainrunSections: [ + { + id: 509, + sourceNodeId: 156, + sourcePortId: 1033, + targetNodeId: 136, + targetPortId: 1034, + travelTime: { + lock: true, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 2, + warning: null, + timeFormatter: null, + consecutiveTime: 182 + }, + sourceArrival: { + lock: false, + time: 58, + warning: null, + timeFormatter: null, + consecutiveTime: 178 + }, + targetDeparture: { + lock: false, + time: 44, + warning: null, + timeFormatter: null, + consecutiveTime: 164 + }, + targetArrival: { + lock: false, + time: 16, + warning: null, + timeFormatter: null, + consecutiveTime: 196 + }, + numberOfStops: 0, + trainrunId: 75, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2640, + y: 3710 + }, + { + x: 2640, + y: 3646 + }, + { + x: 2640, + y: 3390 + }, + { + x: 2640, + y: 3326 + } + ], + textPositions: { + 0: { + x: 2652, + y: 3692 + }, + 1: { + x: 2628, + y: 3664 + }, + 2: { + x: 2628, + y: 3344 + }, + 3: { + x: 2652, + y: 3372 + }, + 4: { + x: 2628, + y: 3518 + }, + 5: { + x: 2628, + y: 3518 + }, + 6: { + x: 2652, + y: 3518 + } + } + }, + warnings: null + }, + { + id: 510, + sourceNodeId: 136, + sourcePortId: 1035, + targetNodeId: 158, + targetPortId: 1036, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 198 + }, + sourceArrival: { + lock: true, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 162 + }, + targetDeparture: { + lock: false, + time: 36, + warning: null, + timeFormatter: null, + consecutiveTime: 156 + }, + targetArrival: { + lock: false, + time: 24, + warning: null, + timeFormatter: null, + consecutiveTime: 204 + }, + numberOfStops: 0, + trainrunId: 75, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2640, + y: 3230 + }, + { + x: 2640, + y: 3166 + }, + { + x: 2640, + y: 2818 + }, + { + x: 2640, + y: 2754 + } + ], + textPositions: { + 0: { + x: 2652, + y: 3212 + }, + 1: { + x: 2628, + y: 3184 + }, + 2: { + x: 2628, + y: 2772 + }, + 3: { + x: 2652, + y: 2800 + }, + 4: { + x: 2628, + y: 2992 + }, + 5: { + x: 2628, + y: 2992 + }, + 6: { + x: 2652, + y: 2992 + } + } + }, + warnings: null + }, + { + id: 511, + sourceNodeId: 155, + sourcePortId: 1037, + targetNodeId: 154, + targetPortId: 1038, + travelTime: { + lock: true, + time: 19, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 232 + }, + sourceArrival: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 128 + }, + targetDeparture: { + lock: true, + time: 49, + warning: null, + timeFormatter: null, + consecutiveTime: 109 + }, + targetArrival: { + lock: true, + time: 11, + warning: null, + timeFormatter: null, + consecutiveTime: 251 + }, + numberOfStops: 0, + trainrunId: 75, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2704, + y: 2174 + }, + { + x: 2704, + y: 2110 + }, + { + x: 2704, + y: 1950 + }, + { + x: 2704, + y: 1886 + } + ], + textPositions: { + 0: { + x: 2716, + y: 2156 + }, + 1: { + x: 2692, + y: 2128 + }, + 2: { + x: 2692, + y: 1904 + }, + 3: { + x: 2716, + y: 1932 + }, + 4: { + x: 2692, + y: 2030 + }, + 5: { + x: 2692, + y: 2030 + }, + 6: { + x: 2716, + y: 2030 + } + } + }, + warnings: null + }, + { + id: 512, + sourceNodeId: 154, + sourcePortId: 1039, + targetNodeId: 169, + targetPortId: 1040, + travelTime: { + lock: true, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 255 + }, + sourceArrival: { + lock: true, + time: 45, + warning: null, + timeFormatter: null, + consecutiveTime: 105 + }, + targetDeparture: { + lock: false, + time: 27, + warning: null, + timeFormatter: null, + consecutiveTime: 87 + }, + targetArrival: { + lock: false, + time: 33, + warning: null, + timeFormatter: null, + consecutiveTime: 273 + }, + numberOfStops: 0, + trainrunId: 75, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2654, + y: 1808 + }, + { + x: 2590, + y: 1808 + }, + { + x: 2018, + y: 1808 + }, + { + x: 1954, + y: 1808 + } + ], + textPositions: { + 0: { + x: 2636, + y: 1796 + }, + 1: { + x: 2608, + y: 1820 + }, + 2: { + x: 1972, + y: 1820 + }, + 3: { + x: 2000, + y: 1796 + }, + 4: { + x: 2304, + y: 1796 + }, + 5: { + x: 2304, + y: 1796 + }, + 6: { + x: 2304, + y: 1820 + } + } + }, + warnings: null + }, + { + id: 513, + sourceNodeId: 142, + sourcePortId: 1041, + targetNodeId: 141, + targetPortId: 1042, + travelTime: { + lock: true, + time: 19, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 295 + }, + sourceArrival: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 65 + }, + targetDeparture: { + lock: false, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 46 + }, + targetArrival: { + lock: false, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 314 + }, + numberOfStops: 0, + trainrunId: 75, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 80, + y: 1726 + }, + { + x: 80, + y: 1662 + }, + { + x: 80, + y: 1314 + }, + { + x: 80, + y: 1250 + } + ], + textPositions: { + 0: { + x: 92, + y: 1708 + }, + 1: { + x: 68, + y: 1680 + }, + 2: { + x: 68, + y: 1268 + }, + 3: { + x: 92, + y: 1296 + }, + 4: { + x: 68, + y: 1488 + }, + 5: { + x: 68, + y: 1488 + }, + 6: { + x: 92, + y: 1488 + } + } + }, + warnings: null + }, + { + id: 514, + sourceNodeId: 141, + sourcePortId: 1043, + targetNodeId: 143, + targetPortId: 1044, + travelTime: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 314 + }, + sourceArrival: { + lock: false, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 46 + }, + targetDeparture: { + lock: false, + time: 37, + warning: null, + timeFormatter: null, + consecutiveTime: 37 + }, + targetArrival: { + lock: false, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 323 + }, + numberOfStops: 0, + trainrunId: 75, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 80, + y: 1182 + }, + { + x: 80, + y: 1118 + }, + { + x: 80, + y: 866 + }, + { + x: 80, + y: 802 + } + ], + textPositions: { + 0: { + x: 92, + y: 1164 + }, + 1: { + x: 68, + y: 1136 + }, + 2: { + x: 68, + y: 820 + }, + 3: { + x: 92, + y: 848 + }, + 4: { + x: 68, + y: 992 + }, + 5: { + x: 68, + y: 992 + }, + 6: { + x: 92, + y: 992 + } + } + }, + warnings: null + }, + { + id: 515, + sourceNodeId: 143, + sourcePortId: 1045, + targetNodeId: 133, + targetPortId: 1046, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 323 + }, + sourceArrival: { + lock: false, + time: 37, + warning: null, + timeFormatter: null, + consecutiveTime: 37 + }, + targetDeparture: { + lock: true, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 30 + }, + targetArrival: { + lock: true, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 330 + }, + numberOfStops: 0, + trainrunId: 75, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 80, + y: 734 + }, + { + x: 80, + y: 670 + }, + { + x: 80, + y: 414 + }, + { + x: 80, + y: 350 + } + ], + textPositions: { + 0: { + x: 92, + y: 716 + }, + 1: { + x: 68, + y: 688 + }, + 2: { + x: 68, + y: 368 + }, + 3: { + x: 92, + y: 396 + }, + 4: { + x: 68, + y: 542 + }, + 5: { + x: 68, + y: 542 + }, + 6: { + x: 92, + y: 542 + } + } + }, + warnings: null + }, + { + id: 516, + sourceNodeId: 133, + sourcePortId: 1047, + targetNodeId: 144, + targetPortId: 1048, + travelTime: { + lock: true, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 32, + warning: null, + timeFormatter: null, + consecutiveTime: 332 + }, + sourceArrival: { + lock: true, + time: 28, + warning: null, + timeFormatter: null, + consecutiveTime: 28 + }, + targetDeparture: { + lock: false, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 18 + }, + targetArrival: { + lock: false, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 342 + }, + numberOfStops: 0, + trainrunId: 75, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 80, + y: 94 + }, + { + x: 80, + y: 30 + }, + { + x: 80, + y: -290 + }, + { + x: 80, + y: -354 + } + ], + textPositions: { + 0: { + x: 92, + y: 76 + }, + 1: { + x: 68, + y: 48 + }, + 2: { + x: 68, + y: -336 + }, + 3: { + x: 92, + y: -308 + }, + 4: { + x: 68, + y: -130 + }, + 5: { + x: 68, + y: -130 + }, + 6: { + x: 92, + y: -130 + } + } + }, + warnings: null + }, + { + id: 517, + sourceNodeId: 144, + sourcePortId: 1049, + targetNodeId: 145, + targetPortId: 1050, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 342 + }, + sourceArrival: { + lock: false, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 18 + }, + targetDeparture: { + lock: false, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 13 + }, + targetArrival: { + lock: false, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 347 + }, + numberOfStops: 0, + trainrunId: 75, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 80, + y: -450 + }, + { + x: 80, + y: -514 + }, + { + x: 80, + y: -798 + }, + { + x: 80, + y: -862 + } + ], + textPositions: { + 0: { + x: 92, + y: -468 + }, + 1: { + x: 68, + y: -496 + }, + 2: { + x: 68, + y: -844 + }, + 3: { + x: 92, + y: -816 + }, + 4: { + x: 68, + y: -656 + }, + 5: { + x: 68, + y: -656 + }, + 6: { + x: 92, + y: -656 + } + } + }, + warnings: null + }, + { + id: 518, + sourceNodeId: 145, + sourcePortId: 1051, + targetNodeId: 146, + targetPortId: 1052, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 347 + }, + sourceArrival: { + lock: false, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 13 + }, + targetDeparture: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 8 + }, + targetArrival: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 352 + }, + numberOfStops: 0, + trainrunId: 75, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 80, + y: -930 + }, + { + x: 80, + y: -994 + }, + { + x: 80, + y: -1278 + }, + { + x: 80, + y: -1342 + } + ], + textPositions: { + 0: { + x: 92, + y: -948 + }, + 1: { + x: 68, + y: -976 + }, + 2: { + x: 68, + y: -1324 + }, + 3: { + x: 92, + y: -1296 + }, + 4: { + x: 68, + y: -1136 + }, + 5: { + x: 68, + y: -1136 + }, + 6: { + x: 92, + y: -1136 + } + } + }, + warnings: null + }, + { + id: 519, + sourceNodeId: 146, + sourcePortId: 1053, + targetNodeId: 134, + targetPortId: 1054, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 352 + }, + sourceArrival: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 8 + }, + targetDeparture: { + lock: true, + time: 3, + warning: null, + timeFormatter: null, + consecutiveTime: 3 + }, + targetArrival: { + lock: true, + time: 57, + warning: null, + timeFormatter: null, + consecutiveTime: 357 + }, + numberOfStops: 0, + trainrunId: 75, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 80, + y: -1410 + }, + { + x: 80, + y: -1474 + }, + { + x: 80, + y: -1758 + }, + { + x: 80, + y: -1822 + } + ], + textPositions: { + 0: { + x: 92, + y: -1428 + }, + 1: { + x: 68, + y: -1456 + }, + 2: { + x: 68, + y: -1804 + }, + 3: { + x: 92, + y: -1776 + }, + 4: { + x: 68, + y: -1616 + }, + 5: { + x: 68, + y: -1616 + }, + 6: { + x: 92, + y: -1616 + } + } + }, + warnings: null + }, + { + id: 520, + sourceNodeId: 155, + sourcePortId: 1055, + targetNodeId: 158, + targetPortId: 1056, + travelTime: { + lock: true, + time: 28, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 128 + }, + sourceArrival: { + lock: true, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 232 + }, + targetDeparture: { + lock: false, + time: 24, + warning: null, + timeFormatter: null, + consecutiveTime: 204 + }, + targetArrival: { + lock: false, + time: 36, + warning: null, + timeFormatter: null, + consecutiveTime: 156 + }, + numberOfStops: 0, + trainrunId: 75, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2704, + y: 2270 + }, + { + x: 2704, + y: 2334 + }, + { + x: 2704, + y: 2622 + }, + { + x: 2704, + y: 2686 + } + ], + textPositions: { + 0: { + x: 2692, + y: 2288 + }, + 1: { + x: 2716, + y: 2316 + }, + 2: { + x: 2716, + y: 2668 + }, + 3: { + x: 2692, + y: 2640 + }, + 4: { + x: 2692, + y: 2478 + }, + 5: { + x: 2692, + y: 2478 + }, + 6: { + x: 2716, + y: 2478 + } + } + }, + warnings: null + }, + { + id: 521, + sourceNodeId: 156, + sourcePortId: 1057, + targetNodeId: 136, + targetPortId: 1058, + travelTime: { + lock: true, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 2, + warning: null, + timeFormatter: null, + consecutiveTime: 2 + }, + sourceArrival: { + lock: true, + time: 58, + warning: null, + timeFormatter: null, + consecutiveTime: 118 + }, + targetDeparture: { + lock: false, + time: 44, + warning: null, + timeFormatter: null, + consecutiveTime: 104 + }, + targetArrival: { + lock: false, + time: 16, + warning: null, + timeFormatter: null, + consecutiveTime: 16 + }, + numberOfStops: 0, + trainrunId: 76, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2608, + y: 3710 + }, + { + x: 2608, + y: 3646 + }, + { + x: 2608, + y: 3390 + }, + { + x: 2608, + y: 3326 + } + ], + textPositions: { + 0: { + x: 2620, + y: 3692 + }, + 1: { + x: 2596, + y: 3664 + }, + 2: { + x: 2596, + y: 3344 + }, + 3: { + x: 2620, + y: 3372 + }, + 4: { + x: 2596, + y: 3518 + }, + 5: { + x: 2596, + y: 3518 + }, + 6: { + x: 2620, + y: 3518 + } + } + }, + warnings: null + }, + { + id: 522, + sourceNodeId: 136, + sourcePortId: 1059, + targetNodeId: 158, + targetPortId: 1060, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 18 + }, + sourceArrival: { + lock: true, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 102 + }, + targetDeparture: { + lock: false, + time: 36, + warning: null, + timeFormatter: null, + consecutiveTime: 96 + }, + targetArrival: { + lock: false, + time: 24, + warning: null, + timeFormatter: null, + consecutiveTime: 24 + }, + numberOfStops: 0, + trainrunId: 76, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2608, + y: 3230 + }, + { + x: 2608, + y: 3166 + }, + { + x: 2608, + y: 2818 + }, + { + x: 2608, + y: 2754 + } + ], + textPositions: { + 0: { + x: 2620, + y: 3212 + }, + 1: { + x: 2596, + y: 3184 + }, + 2: { + x: 2596, + y: 2772 + }, + 3: { + x: 2620, + y: 2800 + }, + 4: { + x: 2596, + y: 2992 + }, + 5: { + x: 2596, + y: 2992 + }, + 6: { + x: 2620, + y: 2992 + } + } + }, + warnings: null + }, + { + id: 523, + sourceNodeId: 158, + sourcePortId: 1061, + targetNodeId: 155, + targetPortId: 1062, + travelTime: { + lock: true, + time: 28, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 24, + warning: null, + timeFormatter: null, + consecutiveTime: 24 + }, + sourceArrival: { + lock: false, + time: 36, + warning: null, + timeFormatter: null, + consecutiveTime: 96 + }, + targetDeparture: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 68 + }, + targetArrival: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 52 + }, + numberOfStops: 0, + trainrunId: 76, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2672, + y: 2686 + }, + { + x: 2672, + y: 2622 + }, + { + x: 2672, + y: 2334 + }, + { + x: 2672, + y: 2270 + } + ], + textPositions: { + 0: { + x: 2684, + y: 2668 + }, + 1: { + x: 2660, + y: 2640 + }, + 2: { + x: 2660, + y: 2288 + }, + 3: { + x: 2684, + y: 2316 + }, + 4: { + x: 2660, + y: 2478 + }, + 5: { + x: 2660, + y: 2478 + }, + 6: { + x: 2684, + y: 2478 + } + } + }, + warnings: null + }, + { + id: 524, + sourceNodeId: 155, + sourcePortId: 1063, + targetNodeId: 154, + targetPortId: 1064, + travelTime: { + lock: false, + time: 19, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 52 + }, + sourceArrival: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 68 + }, + targetDeparture: { + lock: true, + time: 49, + warning: null, + timeFormatter: null, + consecutiveTime: 49 + }, + targetArrival: { + lock: true, + time: 11, + warning: null, + timeFormatter: null, + consecutiveTime: 71 + }, + numberOfStops: 0, + trainrunId: 76, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2672, + y: 2174 + }, + { + x: 2672, + y: 2110 + }, + { + x: 2672, + y: 1950 + }, + { + x: 2672, + y: 1886 + } + ], + textPositions: { + 0: { + x: 2684, + y: 2156 + }, + 1: { + x: 2660, + y: 2128 + }, + 2: { + x: 2660, + y: 1904 + }, + 3: { + x: 2684, + y: 1932 + }, + 4: { + x: 2660, + y: 2030 + }, + 5: { + x: 2660, + y: 2030 + }, + 6: { + x: 2684, + y: 2030 + } + } + }, + warnings: null + }, + { + id: 525, + sourceNodeId: 154, + sourcePortId: 1065, + targetNodeId: 153, + targetPortId: 1066, + travelTime: { + lock: true, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 75 + }, + sourceArrival: { + lock: true, + time: 45, + warning: null, + timeFormatter: null, + consecutiveTime: 45 + }, + targetDeparture: { + lock: true, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 30 + }, + targetArrival: { + lock: true, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 90 + }, + numberOfStops: 0, + trainrunId: 76, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2672, + y: 1790 + }, + { + x: 2672, + y: 1726 + }, + { + x: 2672, + y: 1470 + }, + { + x: 2672, + y: 1406 + } + ], + textPositions: { + 0: { + x: 2684, + y: 1772 + }, + 1: { + x: 2660, + y: 1744 + }, + 2: { + x: 2660, + y: 1424 + }, + 3: { + x: 2684, + y: 1452 + }, + 4: { + x: 2660, + y: 1598 + }, + 5: { + x: 2660, + y: 1598 + }, + 6: { + x: 2684, + y: 1598 + } + } + }, + warnings: null + }, + { + id: 526, + sourceNodeId: 153, + sourcePortId: 1067, + targetNodeId: 170, + targetPortId: 1068, + travelTime: { + lock: true, + time: 16, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 31, + warning: null, + timeFormatter: null, + consecutiveTime: 91 + }, + sourceArrival: { + lock: true, + time: 29, + warning: null, + timeFormatter: null, + consecutiveTime: 29 + }, + targetDeparture: { + lock: false, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 13 + }, + targetArrival: { + lock: false, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 107 + }, + numberOfStops: 0, + trainrunId: 76, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2672, + y: 1310 + }, + { + x: 2672, + y: 1246 + }, + { + x: 2672, + y: 894 + }, + { + x: 2672, + y: 830 + } + ], + textPositions: { + 0: { + x: 2684, + y: 1292 + }, + 1: { + x: 2660, + y: 1264 + }, + 2: { + x: 2660, + y: 848 + }, + 3: { + x: 2684, + y: 876 + }, + 4: { + x: 2660, + y: 1070 + }, + 5: { + x: 2660, + y: 1070 + }, + 6: { + x: 2684, + y: 1070 + } + } + }, + warnings: null + }, + { + id: 527, + sourceNodeId: 157, + sourcePortId: 1069, + targetNodeId: 136, + targetPortId: 1070, + travelTime: { + lock: true, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 33, + warning: null, + timeFormatter: null, + consecutiveTime: 273 + }, + sourceArrival: { + lock: true, + time: 27, + warning: null, + timeFormatter: null, + consecutiveTime: 327 + }, + targetDeparture: { + lock: true, + time: 4, + warning: null, + timeFormatter: null, + consecutiveTime: 304 + }, + targetArrival: { + lock: true, + time: 56, + warning: null, + timeFormatter: null, + consecutiveTime: 296 + }, + numberOfStops: 0, + trainrunId: 77, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2306, + y: 3248 + }, + { + x: 2370, + y: 3248 + }, + { + x: 2526, + y: 3248 + }, + { + x: 2590, + y: 3248 + } + ], + textPositions: { + 0: { + x: 2324, + y: 3260 + }, + 1: { + x: 2352, + y: 3236 + }, + 2: { + x: 2572, + y: 3236 + }, + 3: { + x: 2544, + y: 3260 + }, + 4: { + x: 2448, + y: 3236 + }, + 5: { + x: 2448, + y: 3236 + }, + 6: { + x: 2448, + y: 3260 + } + } + }, + warnings: null + }, + { + id: 528, + sourceNodeId: 136, + sourcePortId: 1071, + targetNodeId: 158, + targetPortId: 1072, + travelTime: { + lock: true, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 300 + }, + sourceArrival: { + lock: true, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 300 + }, + targetDeparture: { + lock: true, + time: 45, + warning: null, + timeFormatter: null, + consecutiveTime: 285 + }, + targetArrival: { + lock: true, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 315 + }, + numberOfStops: 0, + trainrunId: 77, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2672, + y: 3230 + }, + { + x: 2672, + y: 3166 + }, + { + x: 2672, + y: 2818 + }, + { + x: 2672, + y: 2754 + } + ], + textPositions: { + 0: { + x: 2684, + y: 3212 + }, + 1: { + x: 2660, + y: 3184 + }, + 2: { + x: 2660, + y: 2772 + }, + 3: { + x: 2684, + y: 2800 + }, + 4: { + x: 2660, + y: 2992 + }, + 5: { + x: 2660, + y: 2992 + }, + 6: { + x: 2684, + y: 2992 + } + } + }, + warnings: null + }, + { + id: 529, + sourceNodeId: 158, + sourcePortId: 1073, + targetNodeId: 159, + targetPortId: 1074, + travelTime: { + lock: true, + time: 53, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 16, + warning: null, + timeFormatter: null, + consecutiveTime: 316 + }, + sourceArrival: { + lock: true, + time: 44, + warning: null, + timeFormatter: null, + consecutiveTime: 284 + }, + targetDeparture: { + lock: true, + time: 51, + warning: null, + timeFormatter: null, + consecutiveTime: 231 + }, + targetArrival: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 369 + }, + numberOfStops: 5, + trainrunId: 77, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2608, + y: 2686 + }, + { + x: 2608, + y: 2622 + }, + { + x: 2288, + y: 2398 + }, + { + x: 2288, + y: 2334 + } + ], + textPositions: { + 0: { + x: 2620, + y: 2668 + }, + 1: { + x: 2596, + y: 2640 + }, + 2: { + x: 2276, + y: 2352 + }, + 3: { + x: 2300, + y: 2380 + }, + 4: { + x: 2460, + y: 2510 + }, + 5: { + x: 2460, + y: 2510 + }, + 6: { + x: 2436, + y: 2510 + } + } + }, + warnings: null + }, + { + id: 530, + sourceNodeId: 159, + sourcePortId: 1075, + targetNodeId: 155, + targetPortId: 1076, + travelTime: { + lock: true, + time: 32, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 370 + }, + sourceArrival: { + lock: true, + time: 50, + warning: null, + timeFormatter: null, + consecutiveTime: 230 + }, + targetDeparture: { + lock: false, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 198 + }, + targetArrival: { + lock: false, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 402 + }, + numberOfStops: 1, + trainrunId: 77, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2370, + y: 2256 + }, + { + x: 2434, + y: 2256 + }, + { + x: 2590, + y: 2192 + }, + { + x: 2654, + y: 2192 + } + ], + textPositions: { + 0: { + x: 2388, + y: 2268 + }, + 1: { + x: 2416, + y: 2244 + }, + 2: { + x: 2636, + y: 2180 + }, + 3: { + x: 2608, + y: 2204 + }, + 4: { + x: 2512, + y: 2212 + }, + 5: { + x: 2512, + y: 2212 + }, + 6: { + x: 2512, + y: 2236 + } + } + }, + warnings: null + }, + { + id: 531, + sourceNodeId: 155, + sourcePortId: 1077, + targetNodeId: 154, + targetPortId: 1078, + travelTime: { + lock: true, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 403 + }, + sourceArrival: { + lock: true, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 197 + }, + targetDeparture: { + lock: true, + time: 54, + warning: null, + timeFormatter: null, + consecutiveTime: 174 + }, + targetArrival: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 426 + }, + numberOfStops: 3, + trainrunId: 77, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2736, + y: 2174 + }, + { + x: 2736, + y: 2110 + }, + { + x: 2736, + y: 1950 + }, + { + x: 2736, + y: 1886 + } + ], + textPositions: { + 0: { + x: 2748, + y: 2156 + }, + 1: { + x: 2724, + y: 2128 + }, + 2: { + x: 2724, + y: 1904 + }, + 3: { + x: 2748, + y: 1932 + }, + 4: { + x: 2724, + y: 2030 + }, + 5: { + x: 2724, + y: 2030 + }, + 6: { + x: 2748, + y: 2030 + } + } + }, + warnings: null + }, + { + id: 532, + sourceNodeId: 154, + sourcePortId: 1079, + targetNodeId: 169, + targetPortId: 1080, + travelTime: { + lock: true, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 435 + }, + sourceArrival: { + lock: true, + time: 45, + warning: null, + timeFormatter: null, + consecutiveTime: 165 + }, + targetDeparture: { + lock: false, + time: 27, + warning: null, + timeFormatter: null, + consecutiveTime: 147 + }, + targetArrival: { + lock: false, + time: 33, + warning: null, + timeFormatter: null, + consecutiveTime: 453 + }, + numberOfStops: 0, + trainrunId: 77, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2654, + y: 1840 + }, + { + x: 2590, + y: 1840 + }, + { + x: 2018, + y: 1840 + }, + { + x: 1954, + y: 1840 + } + ], + textPositions: { + 0: { + x: 2636, + y: 1828 + }, + 1: { + x: 2608, + y: 1852 + }, + 2: { + x: 1972, + y: 1852 + }, + 3: { + x: 2000, + y: 1828 + }, + 4: { + x: 2304, + y: 1828 + }, + 5: { + x: 2304, + y: 1828 + }, + 6: { + x: 2304, + y: 1852 + } + } + }, + warnings: null + }, + { + id: 533, + sourceNodeId: 157, + sourcePortId: 1081, + targetNodeId: 136, + targetPortId: 1082, + travelTime: { + lock: true, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 33, + warning: null, + timeFormatter: null, + consecutiveTime: 153 + }, + sourceArrival: { + lock: true, + time: 27, + warning: null, + timeFormatter: null, + consecutiveTime: 207 + }, + targetDeparture: { + lock: true, + time: 4, + warning: null, + timeFormatter: null, + consecutiveTime: 184 + }, + targetArrival: { + lock: true, + time: 56, + warning: null, + timeFormatter: null, + consecutiveTime: 176 + }, + numberOfStops: 3, + trainrunId: 78, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2306, + y: 3280 + }, + { + x: 2370, + y: 3280 + }, + { + x: 2526, + y: 3280 + }, + { + x: 2590, + y: 3280 + } + ], + textPositions: { + 0: { + x: 2324, + y: 3292 + }, + 1: { + x: 2352, + y: 3268 + }, + 2: { + x: 2572, + y: 3268 + }, + 3: { + x: 2544, + y: 3292 + }, + 4: { + x: 2448, + y: 3268 + }, + 5: { + x: 2448, + y: 3268 + }, + 6: { + x: 2448, + y: 3292 + } + } + }, + warnings: null + }, + { + id: 534, + sourceNodeId: 136, + sourcePortId: 1083, + targetNodeId: 158, + targetPortId: 1084, + travelTime: { + lock: true, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 180 + }, + sourceArrival: { + lock: true, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 180 + }, + targetDeparture: { + lock: true, + time: 45, + warning: null, + timeFormatter: null, + consecutiveTime: 165 + }, + targetArrival: { + lock: true, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 195 + }, + numberOfStops: 1, + trainrunId: 78, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2704, + y: 3230 + }, + { + x: 2704, + y: 3166 + }, + { + x: 2704, + y: 2818 + }, + { + x: 2704, + y: 2754 + } + ], + textPositions: { + 0: { + x: 2716, + y: 3212 + }, + 1: { + x: 2692, + y: 3184 + }, + 2: { + x: 2692, + y: 2772 + }, + 3: { + x: 2716, + y: 2800 + }, + 4: { + x: 2692, + y: 2992 + }, + 5: { + x: 2692, + y: 2992 + }, + 6: { + x: 2716, + y: 2992 + } + } + }, + warnings: null + }, + { + id: 535, + sourceNodeId: 158, + sourcePortId: 1085, + targetNodeId: 159, + targetPortId: 1086, + travelTime: { + lock: true, + time: 53, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 16, + warning: null, + timeFormatter: null, + consecutiveTime: 196 + }, + sourceArrival: { + lock: true, + time: 44, + warning: null, + timeFormatter: null, + consecutiveTime: 164 + }, + targetDeparture: { + lock: true, + time: 51, + warning: null, + timeFormatter: null, + consecutiveTime: 111 + }, + targetArrival: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 249 + }, + numberOfStops: 5, + trainrunId: 78, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2640, + y: 2686 + }, + { + x: 2640, + y: 2622 + }, + { + x: 2320, + y: 2398 + }, + { + x: 2320, + y: 2334 + } + ], + textPositions: { + 0: { + x: 2652, + y: 2668 + }, + 1: { + x: 2628, + y: 2640 + }, + 2: { + x: 2308, + y: 2352 + }, + 3: { + x: 2332, + y: 2380 + }, + 4: { + x: 2492, + y: 2510 + }, + 5: { + x: 2492, + y: 2510 + }, + 6: { + x: 2468, + y: 2510 + } + } + }, + warnings: null + }, + { + id: 536, + sourceNodeId: 159, + sourcePortId: 1087, + targetNodeId: 155, + targetPortId: 1088, + travelTime: { + lock: true, + time: 32, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 250 + }, + sourceArrival: { + lock: true, + time: 50, + warning: null, + timeFormatter: null, + consecutiveTime: 110 + }, + targetDeparture: { + lock: true, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 78 + }, + targetArrival: { + lock: true, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 282 + }, + numberOfStops: 1, + trainrunId: 78, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2370, + y: 2288 + }, + { + x: 2434, + y: 2288 + }, + { + x: 2590, + y: 2224 + }, + { + x: 2654, + y: 2224 + } + ], + textPositions: { + 0: { + x: 2388, + y: 2300 + }, + 1: { + x: 2416, + y: 2276 + }, + 2: { + x: 2636, + y: 2212 + }, + 3: { + x: 2608, + y: 2236 + }, + 4: { + x: 2512, + y: 2244 + }, + 5: { + x: 2512, + y: 2244 + }, + 6: { + x: 2512, + y: 2268 + } + } + }, + warnings: null + }, + { + id: 537, + sourceNodeId: 155, + sourcePortId: 1089, + targetNodeId: 154, + targetPortId: 1090, + travelTime: { + lock: false, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 283 + }, + sourceArrival: { + lock: true, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 77 + }, + targetDeparture: { + lock: true, + time: 54, + warning: null, + timeFormatter: null, + consecutiveTime: 54 + }, + targetArrival: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 306 + }, + numberOfStops: 3, + trainrunId: 78, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2768, + y: 2174 + }, + { + x: 2768, + y: 2110 + }, + { + x: 2768, + y: 1950 + }, + { + x: 2768, + y: 1886 + } + ], + textPositions: { + 0: { + x: 2780, + y: 2156 + }, + 1: { + x: 2756, + y: 2128 + }, + 2: { + x: 2756, + y: 1904 + }, + 3: { + x: 2780, + y: 1932 + }, + 4: { + x: 2756, + y: 2030 + }, + 5: { + x: 2756, + y: 2030 + }, + 6: { + x: 2780, + y: 2030 + } + } + }, + warnings: null + }, + { + id: 538, + sourceNodeId: 154, + sourcePortId: 1091, + targetNodeId: 153, + targetPortId: 1092, + travelTime: { + lock: true, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 315 + }, + sourceArrival: { + lock: false, + time: 45, + warning: null, + timeFormatter: null, + consecutiveTime: 45 + }, + targetDeparture: { + lock: true, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 30 + }, + targetArrival: { + lock: true, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 330 + }, + numberOfStops: 0, + trainrunId: 78, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2704, + y: 1790 + }, + { + x: 2704, + y: 1726 + }, + { + x: 2704, + y: 1470 + }, + { + x: 2704, + y: 1406 + } + ], + textPositions: { + 0: { + x: 2716, + y: 1772 + }, + 1: { + x: 2692, + y: 1744 + }, + 2: { + x: 2692, + y: 1424 + }, + 3: { + x: 2716, + y: 1452 + }, + 4: { + x: 2692, + y: 1598 + }, + 5: { + x: 2692, + y: 1598 + }, + 6: { + x: 2716, + y: 1598 + } + } + }, + warnings: null + }, + { + id: 539, + sourceNodeId: 153, + sourcePortId: 1093, + targetNodeId: 170, + targetPortId: 1094, + travelTime: { + lock: true, + time: 16, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 31, + warning: null, + timeFormatter: null, + consecutiveTime: 331 + }, + sourceArrival: { + lock: true, + time: 29, + warning: null, + timeFormatter: null, + consecutiveTime: 29 + }, + targetDeparture: { + lock: false, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 13 + }, + targetArrival: { + lock: false, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 347 + }, + numberOfStops: 0, + trainrunId: 78, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2704, + y: 1310 + }, + { + x: 2704, + y: 1246 + }, + { + x: 2704, + y: 894 + }, + { + x: 2704, + y: 830 + } + ], + textPositions: { + 0: { + x: 2716, + y: 1292 + }, + 1: { + x: 2692, + y: 1264 + }, + 2: { + x: 2692, + y: 848 + }, + 3: { + x: 2716, + y: 876 + }, + 4: { + x: 2692, + y: 1070 + }, + 5: { + x: 2692, + y: 1070 + }, + 6: { + x: 2716, + y: 1070 + } + } + }, + warnings: null + }, + { + id: 540, + sourceNodeId: 142, + sourcePortId: 1095, + targetNodeId: 169, + targetPortId: 1096, + travelTime: { + lock: false, + time: 12, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 35, + warning: null, + timeFormatter: null, + consecutiveTime: 35 + }, + sourceArrival: { + lock: true, + time: 25, + warning: null, + timeFormatter: null, + consecutiveTime: 265 + }, + targetDeparture: { + lock: true, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 253 + }, + targetArrival: { + lock: true, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 47 + }, + numberOfStops: 0, + trainrunId: 79, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 226, + y: 1840 + }, + { + x: 290, + y: 1840 + }, + { + x: 1790, + y: 1840 + }, + { + x: 1854, + y: 1840 + } + ], + textPositions: { + 0: { + x: 244, + y: 1852 + }, + 1: { + x: 272, + y: 1828 + }, + 2: { + x: 1836, + y: 1828 + }, + 3: { + x: 1808, + y: 1852 + }, + 4: { + x: 1040, + y: 1828 + }, + 5: { + x: 1040, + y: 1828 + }, + 6: { + x: 1040, + y: 1852 + } + } + }, + warnings: null + }, + { + id: 541, + sourceNodeId: 153, + sourcePortId: 1097, + targetNodeId: 170, + targetPortId: 1098, + travelTime: { + lock: false, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 58, + warning: null, + timeFormatter: null, + consecutiveTime: 58 + }, + sourceArrival: { + lock: true, + time: 2, + warning: null, + timeFormatter: null, + consecutiveTime: 242 + }, + targetDeparture: { + lock: true, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 227 + }, + targetArrival: { + lock: true, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 73 + }, + numberOfStops: 1, + trainrunId: 79, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2768, + y: 1310 + }, + { + x: 2768, + y: 1246 + }, + { + x: 2768, + y: 894 + }, + { + x: 2768, + y: 830 + } + ], + textPositions: { + 0: { + x: 2780, + y: 1292 + }, + 1: { + x: 2756, + y: 1264 + }, + 2: { + x: 2756, + y: 848 + }, + 3: { + x: 2780, + y: 876 + }, + 4: { + x: 2756, + y: 1070 + }, + 5: { + x: 2756, + y: 1070 + }, + 6: { + x: 2780, + y: 1070 + } + } + }, + warnings: null + }, + { + id: 542, + sourceNodeId: 142, + sourcePortId: 1099, + targetNodeId: 169, + targetPortId: 1100, + travelTime: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 9 + }, + sourceArrival: { + lock: true, + time: 51, + warning: null, + timeFormatter: null, + consecutiveTime: 51 + }, + targetDeparture: { + lock: false, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 42 + }, + targetArrival: { + lock: false, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 18 + }, + numberOfStops: 0, + trainrunId: 80, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 226, + y: 1808 + }, + { + x: 290, + y: 1808 + }, + { + x: 1790, + y: 1808 + }, + { + x: 1854, + y: 1808 + } + ], + textPositions: { + 0: { + x: 244, + y: 1820 + }, + 1: { + x: 272, + y: 1796 + }, + 2: { + x: 1836, + y: 1796 + }, + 3: { + x: 1808, + y: 1820 + }, + 4: { + x: 1040, + y: 1796 + }, + 5: { + x: 1040, + y: 1796 + }, + 6: { + x: 1040, + y: 1820 + } + } + }, + warnings: null + }, + { + id: 543, + sourceNodeId: 153, + sourcePortId: 1101, + targetNodeId: 170, + targetPortId: 1102, + travelTime: { + lock: true, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 29, + warning: null, + timeFormatter: null, + consecutiveTime: 29 + }, + sourceArrival: { + lock: true, + time: 31, + warning: null, + timeFormatter: null, + consecutiveTime: 31 + }, + targetDeparture: { + lock: false, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 17 + }, + targetArrival: { + lock: false, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 43 + }, + numberOfStops: 0, + trainrunId: 80, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2736, + y: 1310 + }, + { + x: 2736, + y: 1246 + }, + { + x: 2736, + y: 894 + }, + { + x: 2736, + y: 830 + } + ], + textPositions: { + 0: { + x: 2748, + y: 1292 + }, + 1: { + x: 2724, + y: 1264 + }, + 2: { + x: 2724, + y: 848 + }, + 3: { + x: 2748, + y: 876 + }, + 4: { + x: 2724, + y: 1070 + }, + 5: { + x: 2724, + y: 1070 + }, + 6: { + x: 2748, + y: 1070 + } + } + }, + warnings: null + }, + { + id: 544, + sourceNodeId: 142, + sourcePortId: 1103, + targetNodeId: 141, + targetPortId: 1104, + travelTime: { + lock: true, + time: 19, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 59, + warning: null, + timeFormatter: null, + consecutiveTime: 299 + }, + sourceArrival: { + lock: false, + time: 1, + warning: null, + timeFormatter: null, + consecutiveTime: 241 + }, + targetDeparture: { + lock: true, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 222 + }, + targetArrival: { + lock: true, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 318 + }, + numberOfStops: 0, + trainrunId: 81, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 112, + y: 1726 + }, + { + x: 112, + y: 1662 + }, + { + x: 112, + y: 1314 + }, + { + x: 112, + y: 1250 + } + ], + textPositions: { + 0: { + x: 124, + y: 1708 + }, + 1: { + x: 100, + y: 1680 + }, + 2: { + x: 100, + y: 1268 + }, + 3: { + x: 124, + y: 1296 + }, + 4: { + x: 100, + y: 1488 + }, + 5: { + x: 100, + y: 1488 + }, + 6: { + x: 124, + y: 1488 + } + } + }, + warnings: null + }, + { + id: 545, + sourceNodeId: 141, + sourcePortId: 1105, + targetNodeId: 143, + targetPortId: 1106, + travelTime: { + lock: true, + time: 12, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 19, + warning: null, + timeFormatter: null, + consecutiveTime: 319 + }, + sourceArrival: { + lock: true, + time: 41, + warning: null, + timeFormatter: null, + consecutiveTime: 221 + }, + targetDeparture: { + lock: true, + time: 29, + warning: null, + timeFormatter: null, + consecutiveTime: 209 + }, + targetArrival: { + lock: true, + time: 31, + warning: null, + timeFormatter: null, + consecutiveTime: 331 + }, + numberOfStops: 0, + trainrunId: 81, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 112, + y: 1182 + }, + { + x: 112, + y: 1118 + }, + { + x: 112, + y: 866 + }, + { + x: 112, + y: 802 + } + ], + textPositions: { + 0: { + x: 124, + y: 1164 + }, + 1: { + x: 100, + y: 1136 + }, + 2: { + x: 100, + y: 820 + }, + 3: { + x: 124, + y: 848 + }, + 4: { + x: 100, + y: 992 + }, + 5: { + x: 100, + y: 992 + }, + 6: { + x: 124, + y: 992 + } + } + }, + warnings: null + }, + { + id: 546, + sourceNodeId: 143, + sourcePortId: 1107, + targetNodeId: 172, + targetPortId: 1108, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 32, + warning: null, + timeFormatter: null, + consecutiveTime: 332 + }, + sourceArrival: { + lock: true, + time: 28, + warning: null, + timeFormatter: null, + consecutiveTime: 208 + }, + targetDeparture: { + lock: false, + time: 21, + warning: null, + timeFormatter: null, + consecutiveTime: 201 + }, + targetArrival: { + lock: false, + time: 39, + warning: null, + timeFormatter: null, + consecutiveTime: 339 + }, + numberOfStops: 0, + trainrunId: 81, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 62, + y: 752 + }, + { + x: -2, + y: 752 + }, + { + x: -446, + y: 336 + }, + { + x: -510, + y: 336 + } + ], + textPositions: { + 0: { + x: 44, + y: 740 + }, + 1: { + x: 16, + y: 764 + }, + 2: { + x: -492, + y: 348 + }, + 3: { + x: -464, + y: 324 + }, + 4: { + x: -224, + y: 532 + }, + 5: { + x: -224, + y: 532 + }, + 6: { + x: -224, + y: 556 + } + } + }, + warnings: null + }, + { + id: 547, + sourceNodeId: 129, + sourcePortId: 1109, + targetNodeId: 171, + targetPortId: 1110, + travelTime: { + lock: false, + time: 22, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 4, + warning: null, + timeFormatter: null, + consecutiveTime: 364 + }, + sourceArrival: { + lock: true, + time: 56, + warning: null, + timeFormatter: null, + consecutiveTime: 176 + }, + targetDeparture: { + lock: true, + time: 34, + warning: null, + timeFormatter: null, + consecutiveTime: 154 + }, + targetArrival: { + lock: true, + time: 26, + warning: null, + timeFormatter: null, + consecutiveTime: 386 + }, + numberOfStops: 0, + trainrunId: 81, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2146, + y: 176 + }, + { + x: -2210, + y: 176 + }, + { + x: -2398, + y: 336 + }, + { + x: -2462, + y: 336 + } + ], + textPositions: { + 0: { + x: -2164, + y: 164 + }, + 1: { + x: -2192, + y: 188 + }, + 2: { + x: -2444, + y: 348 + }, + 3: { + x: -2416, + y: 324 + }, + 4: { + x: -2304, + y: 244 + }, + 5: { + x: -2304, + y: 244 + }, + 6: { + x: -2304, + y: 268 + } + } + }, + warnings: null + }, + { + id: 548, + sourceNodeId: 142, + sourcePortId: 1111, + targetNodeId: 141, + targetPortId: 1112, + travelTime: { + lock: true, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 90 + }, + sourceArrival: { + lock: true, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 90 + }, + targetDeparture: { + lock: true, + time: 12, + warning: null, + timeFormatter: null, + consecutiveTime: 72 + }, + targetArrival: { + lock: true, + time: 48, + warning: null, + timeFormatter: null, + consecutiveTime: 108 + }, + numberOfStops: 0, + trainrunId: 82, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 208, + y: 1726 + }, + { + x: 208, + y: 1662 + }, + { + x: 208, + y: 1314 + }, + { + x: 208, + y: 1250 + } + ], + textPositions: { + 0: { + x: 220, + y: 1708 + }, + 1: { + x: 196, + y: 1680 + }, + 2: { + x: 196, + y: 1268 + }, + 3: { + x: 220, + y: 1296 + }, + 4: { + x: 196, + y: 1488 + }, + 5: { + x: 196, + y: 1488 + }, + 6: { + x: 220, + y: 1488 + } + } + }, + warnings: null + }, + { + id: 549, + sourceNodeId: 141, + sourcePortId: 1113, + targetNodeId: 143, + targetPortId: 1114, + travelTime: { + lock: true, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 49, + warning: null, + timeFormatter: null, + consecutiveTime: 109 + }, + sourceArrival: { + lock: true, + time: 11, + warning: null, + timeFormatter: null, + consecutiveTime: 71 + }, + targetDeparture: { + lock: false, + time: 58, + warning: null, + timeFormatter: null, + consecutiveTime: 58 + }, + targetArrival: { + lock: false, + time: 2, + warning: null, + timeFormatter: null, + consecutiveTime: 122 + }, + numberOfStops: 0, + trainrunId: 82, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 208, + y: 1182 + }, + { + x: 208, + y: 1118 + }, + { + x: 208, + y: 866 + }, + { + x: 208, + y: 802 + } + ], + textPositions: { + 0: { + x: 220, + y: 1164 + }, + 1: { + x: 196, + y: 1136 + }, + 2: { + x: 196, + y: 820 + }, + 3: { + x: 220, + y: 848 + }, + 4: { + x: 196, + y: 992 + }, + 5: { + x: 196, + y: 992 + }, + 6: { + x: 220, + y: 992 + } + } + }, + warnings: null + }, + { + id: 550, + sourceNodeId: 143, + sourcePortId: 1115, + targetNodeId: 133, + targetPortId: 1116, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 4, + warning: null, + timeFormatter: null, + consecutiveTime: 124 + }, + sourceArrival: { + lock: true, + time: 56, + warning: null, + timeFormatter: null, + consecutiveTime: 56 + }, + targetDeparture: { + lock: true, + time: 49, + warning: null, + timeFormatter: null, + consecutiveTime: 49 + }, + targetArrival: { + lock: true, + time: 11, + warning: null, + timeFormatter: null, + consecutiveTime: 131 + }, + numberOfStops: 0, + trainrunId: 82, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 176, + y: 734 + }, + { + x: 176, + y: 670 + }, + { + x: 176, + y: 414 + }, + { + x: 176, + y: 350 + } + ], + textPositions: { + 0: { + x: 188, + y: 716 + }, + 1: { + x: 164, + y: 688 + }, + 2: { + x: 164, + y: 368 + }, + 3: { + x: 188, + y: 396 + }, + 4: { + x: 164, + y: 542 + }, + 5: { + x: 164, + y: 542 + }, + 6: { + x: 188, + y: 542 + } + } + }, + warnings: null + }, + { + id: 551, + sourceNodeId: 133, + sourcePortId: 1117, + targetNodeId: 144, + targetPortId: 1118, + travelTime: { + lock: true, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 12, + warning: null, + timeFormatter: null, + consecutiveTime: 132 + }, + sourceArrival: { + lock: true, + time: 48, + warning: null, + timeFormatter: null, + consecutiveTime: 48 + }, + targetDeparture: { + lock: true, + time: 38, + warning: null, + timeFormatter: null, + consecutiveTime: 38 + }, + targetArrival: { + lock: true, + time: 22, + warning: null, + timeFormatter: null, + consecutiveTime: 142 + }, + numberOfStops: 0, + trainrunId: 82, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 240, + y: 94 + }, + { + x: 240, + y: 30 + }, + { + x: 240, + y: -290 + }, + { + x: 240, + y: -354 + } + ], + textPositions: { + 0: { + x: 252, + y: 76 + }, + 1: { + x: 228, + y: 48 + }, + 2: { + x: 228, + y: -336 + }, + 3: { + x: 252, + y: -308 + }, + 4: { + x: 228, + y: -130 + }, + 5: { + x: 228, + y: -130 + }, + 6: { + x: 252, + y: -130 + } + } + }, + warnings: null + }, + { + id: 552, + sourceNodeId: 144, + sourcePortId: 1119, + targetNodeId: 145, + targetPortId: 1120, + travelTime: { + lock: true, + time: 4, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 143 + }, + sourceArrival: { + lock: true, + time: 37, + warning: null, + timeFormatter: null, + consecutiveTime: 37 + }, + targetDeparture: { + lock: true, + time: 33, + warning: null, + timeFormatter: null, + consecutiveTime: 33 + }, + targetArrival: { + lock: true, + time: 27, + warning: null, + timeFormatter: null, + consecutiveTime: 147 + }, + numberOfStops: 0, + trainrunId: 82, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 304, + y: -450 + }, + { + x: 304, + y: -514 + }, + { + x: 304, + y: -798 + }, + { + x: 304, + y: -862 + } + ], + textPositions: { + 0: { + x: 316, + y: -468 + }, + 1: { + x: 292, + y: -496 + }, + 2: { + x: 292, + y: -844 + }, + 3: { + x: 316, + y: -816 + }, + 4: { + x: 292, + y: -656 + }, + 5: { + x: 292, + y: -656 + }, + 6: { + x: 316, + y: -656 + } + } + }, + warnings: null + }, + { + id: 553, + sourceNodeId: 145, + sourcePortId: 1121, + targetNodeId: 146, + targetPortId: 1122, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 28, + warning: null, + timeFormatter: null, + consecutiveTime: 148 + }, + sourceArrival: { + lock: true, + time: 32, + warning: null, + timeFormatter: null, + consecutiveTime: 32 + }, + targetDeparture: { + lock: true, + time: 27, + warning: null, + timeFormatter: null, + consecutiveTime: 27 + }, + targetArrival: { + lock: true, + time: 33, + warning: null, + timeFormatter: null, + consecutiveTime: 153 + }, + numberOfStops: 0, + trainrunId: 82, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 304, + y: -930 + }, + { + x: 304, + y: -994 + }, + { + x: 304, + y: -1278 + }, + { + x: 304, + y: -1342 + } + ], + textPositions: { + 0: { + x: 316, + y: -948 + }, + 1: { + x: 292, + y: -976 + }, + 2: { + x: 292, + y: -1324 + }, + 3: { + x: 316, + y: -1296 + }, + 4: { + x: 292, + y: -1136 + }, + 5: { + x: 292, + y: -1136 + }, + 6: { + x: 316, + y: -1136 + } + } + }, + warnings: null + }, + { + id: 554, + sourceNodeId: 146, + sourcePortId: 1123, + targetNodeId: 134, + targetPortId: 1124, + travelTime: { + lock: true, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 34, + warning: null, + timeFormatter: null, + consecutiveTime: 154 + }, + sourceArrival: { + lock: true, + time: 26, + warning: null, + timeFormatter: null, + consecutiveTime: 26 + }, + targetDeparture: { + lock: true, + time: 16, + warning: null, + timeFormatter: null, + consecutiveTime: 16 + }, + targetArrival: { + lock: true, + time: 44, + warning: null, + timeFormatter: null, + consecutiveTime: 164 + }, + numberOfStops: 0, + trainrunId: 82, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 304, + y: -1410 + }, + { + x: 304, + y: -1474 + }, + { + x: 304, + y: -1758 + }, + { + x: 304, + y: -1822 + } + ], + textPositions: { + 0: { + x: 316, + y: -1428 + }, + 1: { + x: 292, + y: -1456 + }, + 2: { + x: 292, + y: -1804 + }, + 3: { + x: 316, + y: -1776 + }, + 4: { + x: 292, + y: -1616 + }, + 5: { + x: 292, + y: -1616 + }, + 6: { + x: 316, + y: -1616 + } + } + }, + warnings: null + }, + { + id: 555, + sourceNodeId: 142, + sourcePortId: 1125, + targetNodeId: 141, + targetPortId: 1126, + travelTime: { + lock: true, + time: 19, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 115 + }, + sourceArrival: { + lock: false, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 65 + }, + targetDeparture: { + lock: false, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 46 + }, + targetArrival: { + lock: false, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 134 + }, + numberOfStops: 0, + trainrunId: 83, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 176, + y: 1726 + }, + { + x: 176, + y: 1662 + }, + { + x: 176, + y: 1314 + }, + { + x: 176, + y: 1250 + } + ], + textPositions: { + 0: { + x: 188, + y: 1708 + }, + 1: { + x: 164, + y: 1680 + }, + 2: { + x: 164, + y: 1268 + }, + 3: { + x: 188, + y: 1296 + }, + 4: { + x: 164, + y: 1488 + }, + 5: { + x: 164, + y: 1488 + }, + 6: { + x: 188, + y: 1488 + } + } + }, + warnings: null + }, + { + id: 556, + sourceNodeId: 141, + sourcePortId: 1127, + targetNodeId: 143, + targetPortId: 1128, + travelTime: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 134 + }, + sourceArrival: { + lock: false, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 46 + }, + targetDeparture: { + lock: false, + time: 38, + warning: null, + timeFormatter: null, + consecutiveTime: 38 + }, + targetArrival: { + lock: false, + time: 22, + warning: null, + timeFormatter: null, + consecutiveTime: 142 + }, + numberOfStops: 0, + trainrunId: 83, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 176, + y: 1182 + }, + { + x: 176, + y: 1118 + }, + { + x: 176, + y: 866 + }, + { + x: 176, + y: 802 + } + ], + textPositions: { + 0: { + x: 188, + y: 1164 + }, + 1: { + x: 164, + y: 1136 + }, + 2: { + x: 164, + y: 820 + }, + 3: { + x: 188, + y: 848 + }, + 4: { + x: 164, + y: 992 + }, + 5: { + x: 164, + y: 992 + }, + 6: { + x: 188, + y: 992 + } + } + }, + warnings: null + }, + { + id: 557, + sourceNodeId: 143, + sourcePortId: 1129, + targetNodeId: 133, + targetPortId: 1130, + travelTime: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 22, + warning: null, + timeFormatter: null, + consecutiveTime: 142 + }, + sourceArrival: { + lock: false, + time: 38, + warning: null, + timeFormatter: null, + consecutiveTime: 38 + }, + targetDeparture: { + lock: true, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 30 + }, + targetArrival: { + lock: true, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 150 + }, + numberOfStops: 0, + trainrunId: 83, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 144, + y: 734 + }, + { + x: 144, + y: 670 + }, + { + x: 144, + y: 414 + }, + { + x: 144, + y: 350 + } + ], + textPositions: { + 0: { + x: 156, + y: 716 + }, + 1: { + x: 132, + y: 688 + }, + 2: { + x: 132, + y: 368 + }, + 3: { + x: 156, + y: 396 + }, + 4: { + x: 132, + y: 542 + }, + 5: { + x: 132, + y: 542 + }, + 6: { + x: 156, + y: 542 + } + } + }, + warnings: null + }, + { + id: 558, + sourceNodeId: 133, + sourcePortId: 1131, + targetNodeId: 144, + targetPortId: 1132, + travelTime: { + lock: true, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 32, + warning: null, + timeFormatter: null, + consecutiveTime: 152 + }, + sourceArrival: { + lock: true, + time: 28, + warning: null, + timeFormatter: null, + consecutiveTime: 28 + }, + targetDeparture: { + lock: false, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 18 + }, + targetArrival: { + lock: false, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 162 + }, + numberOfStops: 0, + trainrunId: 83, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 208, + y: 94 + }, + { + x: 208, + y: 30 + }, + { + x: 208, + y: -290 + }, + { + x: 208, + y: -354 + } + ], + textPositions: { + 0: { + x: 220, + y: 76 + }, + 1: { + x: 196, + y: 48 + }, + 2: { + x: 196, + y: -336 + }, + 3: { + x: 220, + y: -308 + }, + 4: { + x: 196, + y: -130 + }, + 5: { + x: 196, + y: -130 + }, + 6: { + x: 220, + y: -130 + } + } + }, + warnings: null + }, + { + id: 559, + sourceNodeId: 144, + sourcePortId: 1133, + targetNodeId: 145, + targetPortId: 1134, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 162 + }, + sourceArrival: { + lock: false, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 18 + }, + targetDeparture: { + lock: false, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 13 + }, + targetArrival: { + lock: false, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 167 + }, + numberOfStops: 0, + trainrunId: 83, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 272, + y: -450 + }, + { + x: 272, + y: -514 + }, + { + x: 272, + y: -798 + }, + { + x: 272, + y: -862 + } + ], + textPositions: { + 0: { + x: 284, + y: -468 + }, + 1: { + x: 260, + y: -496 + }, + 2: { + x: 260, + y: -844 + }, + 3: { + x: 284, + y: -816 + }, + 4: { + x: 260, + y: -656 + }, + 5: { + x: 260, + y: -656 + }, + 6: { + x: 284, + y: -656 + } + } + }, + warnings: null + }, + { + id: 560, + sourceNodeId: 145, + sourcePortId: 1135, + targetNodeId: 146, + targetPortId: 1136, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 167 + }, + sourceArrival: { + lock: false, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 13 + }, + targetDeparture: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 8 + }, + targetArrival: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 172 + }, + numberOfStops: 0, + trainrunId: 83, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 272, + y: -930 + }, + { + x: 272, + y: -994 + }, + { + x: 272, + y: -1278 + }, + { + x: 272, + y: -1342 + } + ], + textPositions: { + 0: { + x: 284, + y: -948 + }, + 1: { + x: 260, + y: -976 + }, + 2: { + x: 260, + y: -1324 + }, + 3: { + x: 284, + y: -1296 + }, + 4: { + x: 260, + y: -1136 + }, + 5: { + x: 260, + y: -1136 + }, + 6: { + x: 284, + y: -1136 + } + } + }, + warnings: null + }, + { + id: 561, + sourceNodeId: 146, + sourcePortId: 1137, + targetNodeId: 134, + targetPortId: 1138, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 172 + }, + sourceArrival: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 8 + }, + targetDeparture: { + lock: false, + time: 3, + warning: null, + timeFormatter: null, + consecutiveTime: 3 + }, + targetArrival: { + lock: false, + time: 57, + warning: null, + timeFormatter: null, + consecutiveTime: 177 + }, + numberOfStops: 0, + trainrunId: 83, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 272, + y: -1410 + }, + { + x: 272, + y: -1474 + }, + { + x: 272, + y: -1758 + }, + { + x: 272, + y: -1822 + } + ], + textPositions: { + 0: { + x: 284, + y: -1428 + }, + 1: { + x: 260, + y: -1456 + }, + 2: { + x: 260, + y: -1804 + }, + 3: { + x: 284, + y: -1776 + }, + 4: { + x: 260, + y: -1616 + }, + 5: { + x: 260, + y: -1616 + }, + 6: { + x: 284, + y: -1616 + } + } + }, + warnings: null + }, + { + id: 562, + sourceNodeId: 135, + sourcePortId: 1139, + targetNodeId: 150, + targetPortId: 1140, + travelTime: { + lock: true, + time: 12, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 9 + }, + sourceArrival: { + lock: true, + time: 51, + warning: null, + timeFormatter: null, + consecutiveTime: 291 + }, + targetDeparture: { + lock: true, + time: 39, + warning: null, + timeFormatter: null, + consecutiveTime: 279 + }, + targetArrival: { + lock: true, + time: 21, + warning: null, + timeFormatter: null, + consecutiveTime: 21 + }, + numberOfStops: 1, + trainrunId: 84, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2850, + y: 176 + }, + { + x: 2914, + y: 176 + }, + { + x: 3230, + y: 176 + }, + { + x: 3294, + y: 176 + } + ], + textPositions: { + 0: { + x: 2868, + y: 188 + }, + 1: { + x: 2896, + y: 164 + }, + 2: { + x: 3276, + y: 164 + }, + 3: { + x: 3248, + y: 188 + }, + 4: { + x: 3072, + y: 164 + }, + 5: { + x: 3072, + y: 164 + }, + 6: { + x: 3072, + y: 188 + } + } + }, + warnings: null + }, + { + id: 563, + sourceNodeId: 150, + sourcePortId: 1141, + targetNodeId: 151, + targetPortId: 1142, + travelTime: { + lock: true, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 23 + }, + sourceArrival: { + lock: false, + time: 37, + warning: null, + timeFormatter: null, + consecutiveTime: 277 + }, + targetDeparture: { + lock: true, + time: 24, + warning: null, + timeFormatter: null, + consecutiveTime: 264 + }, + targetArrival: { + lock: true, + time: 36, + warning: null, + timeFormatter: null, + consecutiveTime: 36 + }, + numberOfStops: 0, + trainrunId: 84, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 3394, + y: 176 + }, + { + x: 3458, + y: 176 + }, + { + x: 3806, + y: 176 + }, + { + x: 3870, + y: 176 + } + ], + textPositions: { + 0: { + x: 3412, + y: 188 + }, + 1: { + x: 3440, + y: 164 + }, + 2: { + x: 3852, + y: 164 + }, + 3: { + x: 3824, + y: 188 + }, + 4: { + x: 3632, + y: 164 + }, + 5: { + x: 3632, + y: 164 + }, + 6: { + x: 3632, + y: 188 + } + } + }, + warnings: null + }, + { + id: 564, + sourceNodeId: 151, + sourcePortId: 1143, + targetNodeId: 137, + targetPortId: 1144, + travelTime: { + lock: true, + time: 44, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 38, + warning: null, + timeFormatter: null, + consecutiveTime: 38 + }, + sourceArrival: { + lock: false, + time: 22, + warning: null, + timeFormatter: null, + consecutiveTime: 262 + }, + targetDeparture: { + lock: false, + time: 38, + warning: null, + timeFormatter: null, + consecutiveTime: 218 + }, + targetArrival: { + lock: false, + time: 22, + warning: null, + timeFormatter: null, + consecutiveTime: 82 + }, + numberOfStops: 4, + trainrunId: 84, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 3970, + y: 176 + }, + { + x: 4034, + y: 176 + }, + { + x: 4574, + y: 176 + }, + { + x: 4638, + y: 176 + } + ], + textPositions: { + 0: { + x: 3988, + y: 188 + }, + 1: { + x: 4016, + y: 164 + }, + 2: { + x: 4620, + y: 164 + }, + 3: { + x: 4592, + y: 188 + }, + 4: { + x: 4304, + y: 164 + }, + 5: { + x: 4304, + y: 164 + }, + 6: { + x: 4304, + y: 188 + } + } + }, + warnings: null + }, + { + id: 565, + sourceNodeId: 137, + sourcePortId: 1145, + targetNodeId: 140, + targetPortId: 1146, + travelTime: { + lock: true, + time: 61, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 24, + warning: null, + timeFormatter: null, + consecutiveTime: 84 + }, + sourceArrival: { + lock: false, + time: 36, + warning: null, + timeFormatter: null, + consecutiveTime: 216 + }, + targetDeparture: { + lock: false, + time: 35, + warning: null, + timeFormatter: null, + consecutiveTime: 155 + }, + targetArrival: { + lock: false, + time: 25, + warning: null, + timeFormatter: null, + consecutiveTime: 145 + }, + numberOfStops: 5, + trainrunId: 84, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 4656, + y: 222 + }, + { + x: 4656, + y: 286 + }, + { + x: 4656, + y: 1118 + }, + { + x: 4656, + y: 1182 + } + ], + textPositions: { + 0: { + x: 4644, + y: 240 + }, + 1: { + x: 4668, + y: 268 + }, + 2: { + x: 4668, + y: 1164 + }, + 3: { + x: 4644, + y: 1136 + }, + 4: { + x: 4644, + y: 702 + }, + 5: { + x: 4644, + y: 702 + }, + 6: { + x: 4668, + y: 702 + } + } + }, + warnings: null + }, + { + id: 566, + sourceNodeId: 140, + sourcePortId: 1147, + targetNodeId: 152, + targetPortId: 1148, + travelTime: { + lock: true, + time: 22, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 26, + warning: null, + timeFormatter: null, + consecutiveTime: 146 + }, + sourceArrival: { + lock: true, + time: 34, + warning: null, + timeFormatter: null, + consecutiveTime: 154 + }, + targetDeparture: { + lock: true, + time: 12, + warning: null, + timeFormatter: null, + consecutiveTime: 132 + }, + targetArrival: { + lock: true, + time: 48, + warning: null, + timeFormatter: null, + consecutiveTime: 168 + }, + numberOfStops: 2, + trainrunId: 84, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 4688, + y: 1278 + }, + { + x: 4688, + y: 1342 + }, + { + x: 4688, + y: 1822 + }, + { + x: 4688, + y: 1886 + } + ], + textPositions: { + 0: { + x: 4676, + y: 1296 + }, + 1: { + x: 4700, + y: 1324 + }, + 2: { + x: 4700, + y: 1868 + }, + 3: { + x: 4676, + y: 1840 + }, + 4: { + x: 4676, + y: 1582 + }, + 5: { + x: 4676, + y: 1582 + }, + 6: { + x: 4700, + y: 1582 + } + } + }, + warnings: null + }, + { + id: 567, + sourceNodeId: 135, + sourcePortId: 1149, + targetNodeId: 170, + targetPortId: 1150, + travelTime: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 67 + }, + sourceArrival: { + lock: true, + time: 53, + warning: null, + timeFormatter: null, + consecutiveTime: 293 + }, + targetDeparture: { + lock: false, + time: 45, + warning: null, + timeFormatter: null, + consecutiveTime: 285 + }, + targetArrival: { + lock: false, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 75 + }, + numberOfStops: 0, + trainrunId: 85, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2704, + y: 350 + }, + { + x: 2704, + y: 414 + }, + { + x: 2704, + y: 670 + }, + { + x: 2704, + y: 734 + } + ], + textPositions: { + 0: { + x: 2692, + y: 368 + }, + 1: { + x: 2716, + y: 396 + }, + 2: { + x: 2716, + y: 716 + }, + 3: { + x: 2692, + y: 688 + }, + 4: { + x: 2692, + y: 542 + }, + 5: { + x: 2692, + y: 542 + }, + 6: { + x: 2716, + y: 542 + } + } + }, + warnings: null + }, + { + id: 568, + sourceNodeId: 140, + sourcePortId: 1151, + targetNodeId: 152, + targetPortId: 1152, + travelTime: { + lock: true, + time: 19, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 3, + warning: null, + timeFormatter: null, + consecutiveTime: 123 + }, + sourceArrival: { + lock: true, + time: 57, + warning: null, + timeFormatter: null, + consecutiveTime: 237 + }, + targetDeparture: { + lock: true, + time: 38, + warning: null, + timeFormatter: null, + consecutiveTime: 218 + }, + targetArrival: { + lock: true, + time: 22, + warning: null, + timeFormatter: null, + consecutiveTime: 142 + }, + numberOfStops: 1, + trainrunId: 85, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 4656, + y: 1278 + }, + { + x: 4656, + y: 1342 + }, + { + x: 4656, + y: 1822 + }, + { + x: 4656, + y: 1886 + } + ], + textPositions: { + 0: { + x: 4644, + y: 1296 + }, + 1: { + x: 4668, + y: 1324 + }, + 2: { + x: 4668, + y: 1868 + }, + 3: { + x: 4644, + y: 1840 + }, + 4: { + x: 4644, + y: 1582 + }, + 5: { + x: 4644, + y: 1582 + }, + 6: { + x: 4668, + y: 1582 + } + } + }, + warnings: null + }, + { + id: 569, + sourceNodeId: 135, + sourcePortId: 1153, + targetNodeId: 170, + targetPortId: 1154, + travelTime: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 12, + warning: null, + timeFormatter: null, + consecutiveTime: 132 + }, + sourceArrival: { + lock: false, + time: 48, + warning: null, + timeFormatter: null, + consecutiveTime: 288 + }, + targetDeparture: { + lock: true, + time: 40, + warning: null, + timeFormatter: null, + consecutiveTime: 280 + }, + targetArrival: { + lock: true, + time: 20, + warning: null, + timeFormatter: null, + consecutiveTime: 140 + }, + numberOfStops: 0, + trainrunId: 86, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2736, + y: 350 + }, + { + x: 2736, + y: 414 + }, + { + x: 2736, + y: 670 + }, + { + x: 2736, + y: 734 + } + ], + textPositions: { + 0: { + x: 2724, + y: 368 + }, + 1: { + x: 2748, + y: 396 + }, + 2: { + x: 2748, + y: 716 + }, + 3: { + x: 2724, + y: 688 + }, + 4: { + x: 2724, + y: 542 + }, + 5: { + x: 2724, + y: 542 + }, + 6: { + x: 2748, + y: 542 + } + } + }, + warnings: null + }, + { + id: 570, + sourceNodeId: 140, + sourcePortId: 1155, + targetNodeId: 152, + targetPortId: 1156, + travelTime: { + lock: true, + time: 20, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 203 + }, + sourceArrival: { + lock: true, + time: 37, + warning: null, + timeFormatter: null, + consecutiveTime: 217 + }, + targetDeparture: { + lock: true, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 197 + }, + targetArrival: { + lock: true, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 223 + }, + numberOfStops: 1, + trainrunId: 86, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 4720, + y: 1278 + }, + { + x: 4720, + y: 1342 + }, + { + x: 4720, + y: 1822 + }, + { + x: 4720, + y: 1886 + } + ], + textPositions: { + 0: { + x: 4708, + y: 1296 + }, + 1: { + x: 4732, + y: 1324 + }, + 2: { + x: 4732, + y: 1868 + }, + 3: { + x: 4708, + y: 1840 + }, + 4: { + x: 4708, + y: 1582 + }, + 5: { + x: 4708, + y: 1582 + }, + 6: { + x: 4732, + y: 1582 + } + } + }, + warnings: null + }, + { + id: 571, + sourceNodeId: 135, + sourcePortId: 1157, + targetNodeId: 149, + targetPortId: 1158, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 54, + warning: null, + timeFormatter: null, + consecutiveTime: 294 + }, + sourceArrival: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 126 + }, + targetDeparture: { + lock: false, + time: 59, + warning: null, + timeFormatter: null, + consecutiveTime: 119 + }, + targetArrival: { + lock: false, + time: 1, + warning: null, + timeFormatter: null, + consecutiveTime: 301 + }, + numberOfStops: 1, + trainrunId: 86, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2654, + y: 240 + }, + { + x: 2590, + y: 240 + }, + { + x: 2402, + y: 240 + }, + { + x: 2338, + y: 240 + } + ], + textPositions: { + 0: { + x: 2636, + y: 228 + }, + 1: { + x: 2608, + y: 252 + }, + 2: { + x: 2356, + y: 252 + }, + 3: { + x: 2384, + y: 228 + }, + 4: { + x: 2496, + y: 228 + }, + 5: { + x: 2496, + y: 228 + }, + 6: { + x: 2496, + y: 252 + } + } + }, + warnings: null + }, + { + id: 572, + sourceNodeId: 149, + sourcePortId: 1159, + targetNodeId: 166, + targetPortId: 1160, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 1, + warning: null, + timeFormatter: null, + consecutiveTime: 301 + }, + sourceArrival: { + lock: false, + time: 59, + warning: null, + timeFormatter: null, + consecutiveTime: 119 + }, + targetDeparture: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 112 + }, + targetArrival: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 308 + }, + numberOfStops: 0, + trainrunId: 86, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2238, + y: 240 + }, + { + x: 2174, + y: 240 + }, + { + x: 1954, + y: 240 + }, + { + x: 1890, + y: 240 + } + ], + textPositions: { + 0: { + x: 2220, + y: 228 + }, + 1: { + x: 2192, + y: 252 + }, + 2: { + x: 1908, + y: 252 + }, + 3: { + x: 1936, + y: 228 + }, + 4: { + x: 2064, + y: 228 + }, + 5: { + x: 2064, + y: 228 + }, + 6: { + x: 2064, + y: 252 + } + } + }, + warnings: null + }, + { + id: 573, + sourceNodeId: 148, + sourcePortId: 1161, + targetNodeId: 147, + targetPortId: 1162, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 315 + }, + sourceArrival: { + lock: false, + time: 45, + warning: null, + timeFormatter: null, + consecutiveTime: 105 + }, + targetDeparture: { + lock: false, + time: 38, + warning: null, + timeFormatter: null, + consecutiveTime: 98 + }, + targetArrival: { + lock: false, + time: 22, + warning: null, + timeFormatter: null, + consecutiveTime: 322 + }, + numberOfStops: 0, + trainrunId: 86, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1342, + y: 240 + }, + { + x: 1278, + y: 240 + }, + { + x: 1122, + y: 240 + }, + { + x: 1058, + y: 240 + } + ], + textPositions: { + 0: { + x: 1324, + y: 228 + }, + 1: { + x: 1296, + y: 252 + }, + 2: { + x: 1076, + y: 252 + }, + 3: { + x: 1104, + y: 228 + }, + 4: { + x: 1200, + y: 228 + }, + 5: { + x: 1200, + y: 228 + }, + 6: { + x: 1200, + y: 252 + } + } + }, + warnings: null + }, + { + id: 574, + sourceNodeId: 147, + sourcePortId: 1163, + targetNodeId: 133, + targetPortId: 1164, + travelTime: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 22, + warning: null, + timeFormatter: null, + consecutiveTime: 322 + }, + sourceArrival: { + lock: false, + time: 38, + warning: null, + timeFormatter: null, + consecutiveTime: 98 + }, + targetDeparture: { + lock: true, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 90 + }, + targetArrival: { + lock: true, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 330 + }, + numberOfStops: 0, + trainrunId: 86, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 958, + y: 240 + }, + { + x: 894, + y: 240 + }, + { + x: 322, + y: 240 + }, + { + x: 258, + y: 240 + } + ], + textPositions: { + 0: { + x: 940, + y: 228 + }, + 1: { + x: 912, + y: 252 + }, + 2: { + x: 276, + y: 252 + }, + 3: { + x: 304, + y: 228 + }, + 4: { + x: 608, + y: 228 + }, + 5: { + x: 608, + y: 228 + }, + 6: { + x: 608, + y: 252 + } + } + }, + warnings: null + }, + { + id: 575, + sourceNodeId: 133, + sourcePortId: 1165, + targetNodeId: 172, + targetPortId: 1166, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 36, + warning: null, + timeFormatter: null, + consecutiveTime: 336 + }, + sourceArrival: { + lock: true, + time: 24, + warning: null, + timeFormatter: null, + consecutiveTime: 84 + }, + targetDeparture: { + lock: false, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 77 + }, + targetArrival: { + lock: false, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 343 + }, + numberOfStops: 0, + trainrunId: 86, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 62, + y: 304 + }, + { + x: -2, + y: 304 + }, + { + x: -446, + y: 304 + }, + { + x: -510, + y: 304 + } + ], + textPositions: { + 0: { + x: 44, + y: 292 + }, + 1: { + x: 16, + y: 316 + }, + 2: { + x: -492, + y: 316 + }, + 3: { + x: -464, + y: 292 + }, + 4: { + x: -224, + y: 292 + }, + 5: { + x: -224, + y: 292 + }, + 6: { + x: -224, + y: 316 + } + } + }, + warnings: null + }, + { + id: 576, + sourceNodeId: 137, + sourcePortId: 1167, + targetNodeId: 151, + targetPortId: 1168, + travelTime: { + lock: true, + time: 33, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 58, + warning: null, + timeFormatter: null, + consecutiveTime: 298 + }, + sourceArrival: { + lock: false, + time: 2, + warning: null, + timeFormatter: null, + consecutiveTime: 242 + }, + targetDeparture: { + lock: false, + time: 29, + warning: null, + timeFormatter: null, + consecutiveTime: 209 + }, + targetArrival: { + lock: false, + time: 31, + warning: null, + timeFormatter: null, + consecutiveTime: 331 + }, + numberOfStops: 0, + trainrunId: 87, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 4638, + y: 144 + }, + { + x: 4574, + y: 144 + }, + { + x: 4034, + y: 144 + }, + { + x: 3970, + y: 144 + } + ], + textPositions: { + 0: { + x: 4620, + y: 132 + }, + 1: { + x: 4592, + y: 156 + }, + 2: { + x: 3988, + y: 156 + }, + 3: { + x: 4016, + y: 132 + }, + 4: { + x: 4304, + y: 132 + }, + 5: { + x: 4304, + y: 132 + }, + 6: { + x: 4304, + y: 156 + } + } + }, + warnings: null + }, + { + id: 577, + sourceNodeId: 151, + sourcePortId: 1169, + targetNodeId: 150, + targetPortId: 1170, + travelTime: { + lock: true, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 33, + warning: null, + timeFormatter: null, + consecutiveTime: 333 + }, + sourceArrival: { + lock: false, + time: 27, + warning: null, + timeFormatter: null, + consecutiveTime: 207 + }, + targetDeparture: { + lock: true, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 193 + }, + targetArrival: { + lock: true, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 347 + }, + numberOfStops: 0, + trainrunId: 87, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 3870, + y: 80 + }, + { + x: 3806, + y: 80 + }, + { + x: 3458, + y: 80 + }, + { + x: 3394, + y: 80 + } + ], + textPositions: { + 0: { + x: 3852, + y: 68 + }, + 1: { + x: 3824, + y: 92 + }, + 2: { + x: 3412, + y: 92 + }, + 3: { + x: 3440, + y: 68 + }, + 4: { + x: 3632, + y: 68 + }, + 5: { + x: 3632, + y: 68 + }, + 6: { + x: 3632, + y: 92 + } + } + }, + warnings: null + }, + { + id: 578, + sourceNodeId: 150, + sourcePortId: 1171, + targetNodeId: 135, + targetPortId: 1172, + travelTime: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 48, + warning: null, + timeFormatter: null, + consecutiveTime: 348 + }, + sourceArrival: { + lock: true, + time: 12, + warning: null, + timeFormatter: null, + consecutiveTime: 192 + }, + targetDeparture: { + lock: true, + time: 3, + warning: null, + timeFormatter: null, + consecutiveTime: 183 + }, + targetArrival: { + lock: true, + time: 57, + warning: null, + timeFormatter: null, + consecutiveTime: 357 + }, + numberOfStops: 0, + trainrunId: 87, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 3294, + y: 80 + }, + { + x: 3230, + y: 80 + }, + { + x: 2914, + y: 80 + }, + { + x: 2850, + y: 80 + } + ], + textPositions: { + 0: { + x: 3276, + y: 68 + }, + 1: { + x: 3248, + y: 92 + }, + 2: { + x: 2868, + y: 92 + }, + 3: { + x: 2896, + y: 68 + }, + 4: { + x: 3072, + y: 68 + }, + 5: { + x: 3072, + y: 68 + }, + 6: { + x: 3072, + y: 92 + } + } + }, + warnings: null + }, + { + id: 579, + sourceNodeId: 135, + sourcePortId: 1173, + targetNodeId: 149, + targetPortId: 1174, + travelTime: { + lock: true, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 4, + warning: null, + timeFormatter: null, + consecutiveTime: 364 + }, + sourceArrival: { + lock: true, + time: 56, + warning: { + title: "Quelle Ankunft Warnung", + description: "Quellankunftszeit kann nicht erreicht werden" + }, + timeFormatter: null, + consecutiveTime: 176 + }, + targetDeparture: { + lock: false, + time: 50, + warning: null, + timeFormatter: null, + consecutiveTime: 170 + }, + targetArrival: { + lock: false, + time: 10, + warning: { + title: "Ziel Ankunft Warnung", + description: "Zielankunftszeit kann nicht erreicht werden" + }, + timeFormatter: null, + consecutiveTime: 370 + }, + numberOfStops: 0, + trainrunId: 87, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2654, + y: 144 + }, + { + x: 2590, + y: 144 + }, + { + x: 2402, + y: 144 + }, + { + x: 2338, + y: 144 + } + ], + textPositions: { + 0: { + x: 2636, + y: 132 + }, + 1: { + x: 2608, + y: 156 + }, + 2: { + x: 2356, + y: 156 + }, + 3: { + x: 2384, + y: 132 + }, + 4: { + x: 2496, + y: 132 + }, + 5: { + x: 2496, + y: 132 + }, + 6: { + x: 2496, + y: 156 + } + } + }, + warnings: null + }, + { + id: 580, + sourceNodeId: 149, + sourcePortId: 1175, + targetNodeId: 166, + targetPortId: 1176, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 370 + }, + sourceArrival: { + lock: false, + time: 50, + warning: null, + timeFormatter: null, + consecutiveTime: 170 + }, + targetDeparture: { + lock: false, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 163 + }, + targetArrival: { + lock: false, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 377 + }, + numberOfStops: 0, + trainrunId: 87, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2238, + y: 144 + }, + { + x: 2174, + y: 144 + }, + { + x: 1954, + y: 144 + }, + { + x: 1890, + y: 144 + } + ], + textPositions: { + 0: { + x: 2220, + y: 132 + }, + 1: { + x: 2192, + y: 156 + }, + 2: { + x: 1908, + y: 156 + }, + 3: { + x: 1936, + y: 132 + }, + 4: { + x: 2064, + y: 132 + }, + 5: { + x: 2064, + y: 132 + }, + 6: { + x: 2064, + y: 156 + } + } + }, + warnings: null + }, + { + id: 581, + sourceNodeId: 148, + sourcePortId: 1177, + targetNodeId: 147, + targetPortId: 1178, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 24, + warning: null, + timeFormatter: null, + consecutiveTime: 384 + }, + sourceArrival: { + lock: false, + time: 36, + warning: null, + timeFormatter: null, + consecutiveTime: 156 + }, + targetDeparture: { + lock: true, + time: 31, + warning: null, + timeFormatter: null, + consecutiveTime: 151 + }, + targetArrival: { + lock: true, + time: 29, + warning: null, + timeFormatter: null, + consecutiveTime: 389 + }, + numberOfStops: 0, + trainrunId: 87, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1342, + y: 144 + }, + { + x: 1278, + y: 144 + }, + { + x: 1122, + y: 144 + }, + { + x: 1058, + y: 144 + } + ], + textPositions: { + 0: { + x: 1324, + y: 132 + }, + 1: { + x: 1296, + y: 156 + }, + 2: { + x: 1076, + y: 156 + }, + 3: { + x: 1104, + y: 132 + }, + 4: { + x: 1200, + y: 132 + }, + 5: { + x: 1200, + y: 132 + }, + 6: { + x: 1200, + y: 156 + } + } + }, + warnings: null + }, + { + id: 582, + sourceNodeId: 147, + sourcePortId: 1179, + targetNodeId: 133, + targetPortId: 1180, + travelTime: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 31, + warning: null, + timeFormatter: null, + consecutiveTime: 391 + }, + sourceArrival: { + lock: true, + time: 29, + warning: null, + timeFormatter: null, + consecutiveTime: 149 + }, + targetDeparture: { + lock: true, + time: 20, + warning: null, + timeFormatter: null, + consecutiveTime: 140 + }, + targetArrival: { + lock: true, + time: 40, + warning: null, + timeFormatter: null, + consecutiveTime: 400 + }, + numberOfStops: 0, + trainrunId: 87, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 958, + y: 144 + }, + { + x: 894, + y: 144 + }, + { + x: 322, + y: 144 + }, + { + x: 258, + y: 144 + } + ], + textPositions: { + 0: { + x: 940, + y: 132 + }, + 1: { + x: 912, + y: 156 + }, + 2: { + x: 276, + y: 156 + }, + 3: { + x: 304, + y: 132 + }, + 4: { + x: 608, + y: 132 + }, + 5: { + x: 608, + y: 132 + }, + 6: { + x: 608, + y: 156 + } + } + }, + warnings: null + }, + { + id: 583, + sourceNodeId: 133, + sourcePortId: 1181, + targetNodeId: 175, + targetPortId: 1182, + travelTime: { + lock: true, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 402 + }, + sourceArrival: { + lock: true, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 138 + }, + targetDeparture: { + lock: false, + time: 1, + warning: null, + timeFormatter: null, + consecutiveTime: 121 + }, + targetArrival: { + lock: false, + time: 59, + warning: null, + timeFormatter: null, + consecutiveTime: 419 + }, + numberOfStops: 0, + trainrunId: 87, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 62, + y: 112 + }, + { + x: -2, + y: 112 + }, + { + x: -1534, + y: -16 + }, + { + x: -1598, + y: -16 + } + ], + textPositions: { + 0: { + x: 44, + y: 100 + }, + 1: { + x: 16, + y: 124 + }, + 2: { + x: -1580, + y: -4 + }, + 3: { + x: -1552, + y: -28 + }, + 4: { + x: -768, + y: 36 + }, + 5: { + x: -768, + y: 36 + }, + 6: { + x: -768, + y: 60 + } + } + }, + warnings: null + }, + { + id: 584, + sourceNodeId: 130, + sourcePortId: 1183, + targetNodeId: 177, + targetPortId: 1184, + travelTime: { + lock: false, + time: 61, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 437 + }, + sourceArrival: { + lock: true, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 103 + }, + targetDeparture: { + lock: true, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 42 + }, + targetArrival: { + lock: true, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 498 + }, + numberOfStops: 2, + trainrunId: 87, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2530, + y: -16 + }, + { + x: -2594, + y: -16 + }, + { + x: -3358, + y: 560 + }, + { + x: -3422, + y: 560 + } + ], + textPositions: { + 0: { + x: -2548, + y: -28 + }, + 1: { + x: -2576, + y: -4 + }, + 2: { + x: -3404, + y: 572 + }, + 3: { + x: -3376, + y: 548 + }, + 4: { + x: -2976, + y: 260 + }, + 5: { + x: -2976, + y: 260 + }, + 6: { + x: -2976, + y: 284 + } + } + }, + warnings: null + }, + { + id: 585, + sourceNodeId: 160, + sourcePortId: 1185, + targetNodeId: 161, + targetPortId: 1186, + travelTime: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 48, + warning: null, + timeFormatter: null, + consecutiveTime: 528 + }, + sourceArrival: { + lock: true, + time: 12, + warning: null, + timeFormatter: null, + consecutiveTime: 12 + }, + targetDeparture: { + lock: false, + time: 4, + warning: null, + timeFormatter: null, + consecutiveTime: 4 + }, + targetArrival: { + lock: false, + time: 56, + warning: null, + timeFormatter: null, + consecutiveTime: 536 + }, + numberOfStops: 0, + trainrunId: 87, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -3938, + y: 656 + }, + { + x: -4002, + y: 656 + }, + { + x: -4190, + y: 656 + }, + { + x: -4254, + y: 656 + } + ], + textPositions: { + 0: { + x: -3956, + y: 644 + }, + 1: { + x: -3984, + y: 668 + }, + 2: { + x: -4236, + y: 668 + }, + 3: { + x: -4208, + y: 644 + }, + 4: { + x: -4096, + y: 644 + }, + 5: { + x: -4096, + y: 644 + }, + 6: { + x: -4096, + y: 668 + } + } + }, + warnings: null + }, + { + id: 586, + sourceNodeId: 128, + sourcePortId: 1187, + targetNodeId: 177, + targetPortId: 1188, + travelTime: { + lock: false, + time: 11, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 19, + warning: null, + timeFormatter: null, + consecutiveTime: 439 + }, + sourceArrival: { + lock: true, + time: 41, + warning: null, + timeFormatter: null, + consecutiveTime: 101 + }, + targetDeparture: { + lock: true, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 90 + }, + targetArrival: { + lock: true, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 450 + }, + numberOfStops: 0, + trainrunId: 81, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -3074, + y: 592 + }, + { + x: -3138, + y: 592 + }, + { + x: -3358, + y: 624 + }, + { + x: -3422, + y: 624 + } + ], + textPositions: { + 0: { + x: -3092, + y: 580 + }, + 1: { + x: -3120, + y: 604 + }, + 2: { + x: -3404, + y: 636 + }, + 3: { + x: -3376, + y: 612 + }, + 4: { + x: -3248, + y: 596 + }, + 5: { + x: -3248, + y: 596 + }, + 6: { + x: -3248, + y: 620 + } + } + }, + warnings: null + }, + { + id: 587, + sourceNodeId: 160, + sourcePortId: 1189, + targetNodeId: 161, + targetPortId: 1190, + travelTime: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 4, + warning: null, + timeFormatter: null, + consecutiveTime: 484 + }, + sourceArrival: { + lock: true, + time: 56, + warning: null, + timeFormatter: null, + consecutiveTime: 56 + }, + targetDeparture: { + lock: true, + time: 48, + warning: null, + timeFormatter: null, + consecutiveTime: 48 + }, + targetArrival: { + lock: true, + time: 12, + warning: null, + timeFormatter: null, + consecutiveTime: 492 + }, + numberOfStops: 0, + trainrunId: 81, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -3938, + y: 688 + }, + { + x: -4002, + y: 688 + }, + { + x: -4190, + y: 688 + }, + { + x: -4254, + y: 688 + } + ], + textPositions: { + 0: { + x: -3956, + y: 676 + }, + 1: { + x: -3984, + y: 700 + }, + 2: { + x: -4236, + y: 700 + }, + 3: { + x: -4208, + y: 676 + }, + 4: { + x: -4096, + y: 676 + }, + 5: { + x: -4096, + y: 676 + }, + 6: { + x: -4096, + y: 700 + } + } + }, + warnings: null + }, + { + id: 588, + sourceNodeId: 135, + sourcePortId: 1191, + targetNodeId: 150, + targetPortId: 1192, + travelTime: { + lock: true, + time: 12, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 39, + warning: null, + timeFormatter: null, + consecutiveTime: 219 + }, + sourceArrival: { + lock: true, + time: 21, + warning: null, + timeFormatter: null, + consecutiveTime: 321 + }, + targetDeparture: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 309 + }, + targetArrival: { + lock: true, + time: 51, + warning: null, + timeFormatter: null, + consecutiveTime: 231 + }, + numberOfStops: 1, + trainrunId: 88, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2850, + y: 48 + }, + { + x: 2914, + y: 48 + }, + { + x: 3230, + y: 48 + }, + { + x: 3294, + y: 48 + } + ], + textPositions: { + 0: { + x: 2868, + y: 60 + }, + 1: { + x: 2896, + y: 36 + }, + 2: { + x: 3276, + y: 36 + }, + 3: { + x: 3248, + y: 60 + }, + 4: { + x: 3072, + y: 36 + }, + 5: { + x: 3072, + y: 36 + }, + 6: { + x: 3072, + y: 60 + } + } + }, + warnings: null + }, + { + id: 589, + sourceNodeId: 150, + sourcePortId: 1193, + targetNodeId: 151, + targetPortId: 1194, + travelTime: { + lock: true, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 53, + warning: null, + timeFormatter: null, + consecutiveTime: 233 + }, + sourceArrival: { + lock: false, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 307 + }, + targetDeparture: { + lock: false, + time: 54, + warning: null, + timeFormatter: null, + consecutiveTime: 294 + }, + targetArrival: { + lock: false, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 246 + }, + numberOfStops: 0, + trainrunId: 88, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 3394, + y: 48 + }, + { + x: 3458, + y: 48 + }, + { + x: 3806, + y: 48 + }, + { + x: 3870, + y: 48 + } + ], + textPositions: { + 0: { + x: 3412, + y: 60 + }, + 1: { + x: 3440, + y: 36 + }, + 2: { + x: 3852, + y: 36 + }, + 3: { + x: 3824, + y: 60 + }, + 4: { + x: 3632, + y: 36 + }, + 5: { + x: 3632, + y: 36 + }, + 6: { + x: 3632, + y: 60 + } + } + }, + warnings: null + }, + { + id: 590, + sourceNodeId: 135, + sourcePortId: 1195, + targetNodeId: 149, + targetPortId: 1196, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 346 + }, + sourceArrival: { + lock: false, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 194 + }, + targetDeparture: { + lock: false, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 189 + }, + targetArrival: { + lock: false, + time: 51, + warning: null, + timeFormatter: null, + consecutiveTime: 351 + }, + numberOfStops: 0, + trainrunId: 88, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2654, + y: 48 + }, + { + x: 2590, + y: 48 + }, + { + x: 2402, + y: 48 + }, + { + x: 2338, + y: 48 + } + ], + textPositions: { + 0: { + x: 2636, + y: 36 + }, + 1: { + x: 2608, + y: 60 + }, + 2: { + x: 2356, + y: 60 + }, + 3: { + x: 2384, + y: 36 + }, + 4: { + x: 2496, + y: 36 + }, + 5: { + x: 2496, + y: 36 + }, + 6: { + x: 2496, + y: 60 + } + } + }, + warnings: null + }, + { + id: 591, + sourceNodeId: 149, + sourcePortId: 1197, + targetNodeId: 166, + targetPortId: 1198, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 51, + warning: null, + timeFormatter: null, + consecutiveTime: 351 + }, + sourceArrival: { + lock: false, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 189 + }, + targetDeparture: { + lock: false, + time: 4, + warning: null, + timeFormatter: null, + consecutiveTime: 184 + }, + targetArrival: { + lock: false, + time: 56, + warning: null, + timeFormatter: null, + consecutiveTime: 356 + }, + numberOfStops: 0, + trainrunId: 88, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2238, + y: 48 + }, + { + x: 2174, + y: 48 + }, + { + x: 1954, + y: 48 + }, + { + x: 1890, + y: 48 + } + ], + textPositions: { + 0: { + x: 2220, + y: 36 + }, + 1: { + x: 2192, + y: 60 + }, + 2: { + x: 1908, + y: 60 + }, + 3: { + x: 1936, + y: 36 + }, + 4: { + x: 2064, + y: 36 + }, + 5: { + x: 2064, + y: 36 + }, + 6: { + x: 2064, + y: 60 + } + } + }, + warnings: null + }, + { + id: 592, + sourceNodeId: 148, + sourcePortId: 1199, + targetNodeId: 147, + targetPortId: 1200, + travelTime: { + lock: true, + time: 4, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 1, + warning: null, + timeFormatter: null, + consecutiveTime: 361 + }, + sourceArrival: { + lock: false, + time: 59, + warning: null, + timeFormatter: null, + consecutiveTime: 179 + }, + targetDeparture: { + lock: false, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 175 + }, + targetArrival: { + lock: false, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 365 + }, + numberOfStops: 0, + trainrunId: 88, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1342, + y: 48 + }, + { + x: 1278, + y: 48 + }, + { + x: 1122, + y: 48 + }, + { + x: 1058, + y: 48 + } + ], + textPositions: { + 0: { + x: 1324, + y: 36 + }, + 1: { + x: 1296, + y: 60 + }, + 2: { + x: 1076, + y: 60 + }, + 3: { + x: 1104, + y: 36 + }, + 4: { + x: 1200, + y: 36 + }, + 5: { + x: 1200, + y: 36 + }, + 6: { + x: 1200, + y: 60 + } + } + }, + warnings: null + }, + { + id: 593, + sourceNodeId: 147, + sourcePortId: 1201, + targetNodeId: 133, + targetPortId: 1202, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 365 + }, + sourceArrival: { + lock: false, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 175 + }, + targetDeparture: { + lock: false, + time: 50, + warning: null, + timeFormatter: null, + consecutiveTime: 170 + }, + targetArrival: { + lock: false, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 370 + }, + numberOfStops: 0, + trainrunId: 88, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 958, + y: 112 + }, + { + x: 894, + y: 112 + }, + { + x: 322, + y: 112 + }, + { + x: 258, + y: 112 + } + ], + textPositions: { + 0: { + x: 940, + y: 100 + }, + 1: { + x: 912, + y: 124 + }, + 2: { + x: 276, + y: 124 + }, + 3: { + x: 304, + y: 100 + }, + 4: { + x: 608, + y: 100 + }, + 5: { + x: 608, + y: 100 + }, + 6: { + x: 608, + y: 124 + } + } + }, + warnings: null + }, + { + id: 594, + sourceNodeId: 133, + sourcePortId: 1203, + targetNodeId: 172, + targetPortId: 1204, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 370 + }, + sourceArrival: { + lock: false, + time: 50, + warning: null, + timeFormatter: null, + consecutiveTime: 170 + }, + targetDeparture: { + lock: false, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 163 + }, + targetArrival: { + lock: false, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 377 + }, + numberOfStops: 0, + trainrunId: 88, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 62, + y: 144 + }, + { + x: -2, + y: 144 + }, + { + x: -446, + y: 144 + }, + { + x: -510, + y: 144 + } + ], + textPositions: { + 0: { + x: 44, + y: 132 + }, + 1: { + x: 16, + y: 156 + }, + 2: { + x: -492, + y: 156 + }, + 3: { + x: -464, + y: 132 + }, + 4: { + x: -224, + y: 132 + }, + 5: { + x: -224, + y: 132 + }, + 6: { + x: -224, + y: 156 + } + } + }, + warnings: null + }, + { + id: 595, + sourceNodeId: 129, + sourcePortId: 1205, + targetNodeId: 171, + targetPortId: 1206, + travelTime: { + lock: true, + time: 22, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 390 + }, + sourceArrival: { + lock: false, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 150 + }, + targetDeparture: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 128 + }, + targetArrival: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 412 + }, + numberOfStops: 0, + trainrunId: 88, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2146, + y: 144 + }, + { + x: -2210, + y: 144 + }, + { + x: -2398, + y: 304 + }, + { + x: -2462, + y: 304 + } + ], + textPositions: { + 0: { + x: -2164, + y: 132 + }, + 1: { + x: -2192, + y: 156 + }, + 2: { + x: -2444, + y: 316 + }, + 3: { + x: -2416, + y: 292 + }, + 4: { + x: -2304, + y: 212 + }, + 5: { + x: -2304, + y: 212 + }, + 6: { + x: -2304, + y: 236 + } + } + }, + warnings: null + }, + { + id: 596, + sourceNodeId: 128, + sourcePortId: 1207, + targetNodeId: 177, + targetPortId: 1208, + travelTime: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 463 + }, + sourceArrival: { + lock: true, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 77 + }, + targetDeparture: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 68 + }, + targetArrival: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 472 + }, + numberOfStops: 0, + trainrunId: 88, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -3074, + y: 560 + }, + { + x: -3138, + y: 560 + }, + { + x: -3358, + y: 592 + }, + { + x: -3422, + y: 592 + } + ], + textPositions: { + 0: { + x: -3092, + y: 548 + }, + 1: { + x: -3120, + y: 572 + }, + 2: { + x: -3404, + y: 604 + }, + 3: { + x: -3376, + y: 580 + }, + 4: { + x: -3248, + y: 564 + }, + 5: { + x: -3248, + y: 564 + }, + 6: { + x: -3248, + y: 588 + } + } + }, + warnings: null + }, + { + id: 597, + sourceNodeId: 160, + sourcePortId: 1209, + targetNodeId: 161, + targetPortId: 1210, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 21, + warning: null, + timeFormatter: null, + consecutiveTime: 501 + }, + sourceArrival: { + lock: true, + time: 39, + warning: null, + timeFormatter: null, + consecutiveTime: 39 + }, + targetDeparture: { + lock: true, + time: 32, + warning: null, + timeFormatter: null, + consecutiveTime: 32 + }, + targetArrival: { + lock: true, + time: 28, + warning: null, + timeFormatter: null, + consecutiveTime: 508 + }, + numberOfStops: 0, + trainrunId: 88, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -3938, + y: 624 + }, + { + x: -4002, + y: 624 + }, + { + x: -4190, + y: 624 + }, + { + x: -4254, + y: 624 + } + ], + textPositions: { + 0: { + x: -3956, + y: 612 + }, + 1: { + x: -3984, + y: 636 + }, + 2: { + x: -4236, + y: 636 + }, + 3: { + x: -4208, + y: 612 + }, + 4: { + x: -4096, + y: 612 + }, + 5: { + x: -4096, + y: 612 + }, + 6: { + x: -4096, + y: 636 + } + } + }, + warnings: null + }, + { + id: 598, + sourceNodeId: 151, + sourcePortId: 1211, + targetNodeId: 137, + targetPortId: 1212, + travelTime: { + lock: false, + time: 44, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 248 + }, + sourceArrival: { + lock: true, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 292 + }, + targetDeparture: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 248 + }, + targetArrival: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 292 + }, + numberOfStops: 4, + trainrunId: 88, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 3970, + y: 112 + }, + { + x: 4034, + y: 112 + }, + { + x: 4574, + y: 112 + }, + { + x: 4638, + y: 112 + } + ], + textPositions: { + 0: { + x: 3988, + y: 124 + }, + 1: { + x: 4016, + y: 100 + }, + 2: { + x: 4620, + y: 100 + }, + 3: { + x: 4592, + y: 124 + }, + 4: { + x: 4304, + y: 100 + }, + 5: { + x: 4304, + y: 100 + }, + 6: { + x: 4304, + y: 124 + } + } + }, + warnings: null + }, + { + id: 599, + sourceNodeId: 135, + sourcePortId: 1213, + targetNodeId: 150, + targetPortId: 1214, + travelTime: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 125 + }, + sourceArrival: { + lock: false, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 295 + }, + targetDeparture: { + lock: false, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 286 + }, + targetArrival: { + lock: false, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 134 + }, + numberOfStops: 0, + trainrunId: 89, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2850, + y: 112 + }, + { + x: 2914, + y: 112 + }, + { + x: 3230, + y: 112 + }, + { + x: 3294, + y: 112 + } + ], + textPositions: { + 0: { + x: 2868, + y: 124 + }, + 1: { + x: 2896, + y: 100 + }, + 2: { + x: 3276, + y: 100 + }, + 3: { + x: 3248, + y: 124 + }, + 4: { + x: 3072, + y: 100 + }, + 5: { + x: 3072, + y: 100 + }, + 6: { + x: 3072, + y: 124 + } + } + }, + warnings: null + }, + { + id: 600, + sourceNodeId: 150, + sourcePortId: 1215, + targetNodeId: 151, + targetPortId: 1216, + travelTime: { + lock: true, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 16, + warning: null, + timeFormatter: null, + consecutiveTime: 136 + }, + sourceArrival: { + lock: false, + time: 44, + warning: null, + timeFormatter: null, + consecutiveTime: 284 + }, + targetDeparture: { + lock: false, + time: 31, + warning: null, + timeFormatter: null, + consecutiveTime: 271 + }, + targetArrival: { + lock: false, + time: 29, + warning: null, + timeFormatter: null, + consecutiveTime: 149 + }, + numberOfStops: 0, + trainrunId: 89, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 3394, + y: 112 + }, + { + x: 3458, + y: 112 + }, + { + x: 3806, + y: 112 + }, + { + x: 3870, + y: 112 + } + ], + textPositions: { + 0: { + x: 3412, + y: 124 + }, + 1: { + x: 3440, + y: 100 + }, + 2: { + x: 3852, + y: 100 + }, + 3: { + x: 3824, + y: 124 + }, + 4: { + x: 3632, + y: 100 + }, + 5: { + x: 3632, + y: 100 + }, + 6: { + x: 3632, + y: 124 + } + } + }, + warnings: null + }, + { + id: 601, + sourceNodeId: 135, + sourcePortId: 1217, + targetNodeId: 149, + targetPortId: 1218, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 2, + warning: null, + timeFormatter: null, + consecutiveTime: 302 + }, + sourceArrival: { + lock: true, + time: 58, + warning: null, + timeFormatter: null, + consecutiveTime: 118 + }, + targetDeparture: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 112 + }, + targetArrival: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 308 + }, + numberOfStops: 0, + trainrunId: 89, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2654, + y: 176 + }, + { + x: 2590, + y: 176 + }, + { + x: 2402, + y: 176 + }, + { + x: 2338, + y: 176 + } + ], + textPositions: { + 0: { + x: 2636, + y: 164 + }, + 1: { + x: 2608, + y: 188 + }, + 2: { + x: 2356, + y: 188 + }, + 3: { + x: 2384, + y: 164 + }, + 4: { + x: 2496, + y: 164 + }, + 5: { + x: 2496, + y: 164 + }, + 6: { + x: 2496, + y: 188 + } + } + }, + warnings: null + }, + { + id: 602, + sourceNodeId: 149, + sourcePortId: 1219, + targetNodeId: 166, + targetPortId: 1220, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 308 + }, + sourceArrival: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 112 + }, + targetDeparture: { + lock: false, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 106 + }, + targetArrival: { + lock: false, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 314 + }, + numberOfStops: 0, + trainrunId: 89, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2238, + y: 176 + }, + { + x: 2174, + y: 176 + }, + { + x: 1954, + y: 176 + }, + { + x: 1890, + y: 176 + } + ], + textPositions: { + 0: { + x: 2220, + y: 164 + }, + 1: { + x: 2192, + y: 188 + }, + 2: { + x: 1908, + y: 188 + }, + 3: { + x: 1936, + y: 164 + }, + 4: { + x: 2064, + y: 164 + }, + 5: { + x: 2064, + y: 164 + }, + 6: { + x: 2064, + y: 188 + } + } + }, + warnings: null + }, + { + id: 603, + sourceNodeId: 148, + sourcePortId: 1221, + targetNodeId: 147, + targetPortId: 1222, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 20, + warning: null, + timeFormatter: null, + consecutiveTime: 320 + }, + sourceArrival: { + lock: false, + time: 40, + warning: null, + timeFormatter: null, + consecutiveTime: 100 + }, + targetDeparture: { + lock: false, + time: 35, + warning: null, + timeFormatter: null, + consecutiveTime: 95 + }, + targetArrival: { + lock: false, + time: 25, + warning: null, + timeFormatter: null, + consecutiveTime: 325 + }, + numberOfStops: 0, + trainrunId: 89, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1342, + y: 176 + }, + { + x: 1278, + y: 176 + }, + { + x: 1122, + y: 176 + }, + { + x: 1058, + y: 176 + } + ], + textPositions: { + 0: { + x: 1324, + y: 164 + }, + 1: { + x: 1296, + y: 188 + }, + 2: { + x: 1076, + y: 188 + }, + 3: { + x: 1104, + y: 164 + }, + 4: { + x: 1200, + y: 164 + }, + 5: { + x: 1200, + y: 164 + }, + 6: { + x: 1200, + y: 188 + } + } + }, + warnings: null + }, + { + id: 604, + sourceNodeId: 147, + sourcePortId: 1223, + targetNodeId: 133, + targetPortId: 1224, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 25, + warning: null, + timeFormatter: null, + consecutiveTime: 325 + }, + sourceArrival: { + lock: false, + time: 35, + warning: null, + timeFormatter: null, + consecutiveTime: 95 + }, + targetDeparture: { + lock: false, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 90 + }, + targetArrival: { + lock: false, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 330 + }, + numberOfStops: 0, + trainrunId: 89, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 958, + y: 176 + }, + { + x: 894, + y: 176 + }, + { + x: 322, + y: 176 + }, + { + x: 258, + y: 176 + } + ], + textPositions: { + 0: { + x: 940, + y: 164 + }, + 1: { + x: 912, + y: 188 + }, + 2: { + x: 276, + y: 188 + }, + 3: { + x: 304, + y: 164 + }, + 4: { + x: 608, + y: 164 + }, + 5: { + x: 608, + y: 164 + }, + 6: { + x: 608, + y: 188 + } + } + }, + warnings: null + }, + { + id: 605, + sourceNodeId: 133, + sourcePortId: 1225, + targetNodeId: 172, + targetPortId: 1226, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 330 + }, + sourceArrival: { + lock: true, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 90 + }, + targetDeparture: { + lock: false, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 83 + }, + targetArrival: { + lock: false, + time: 37, + warning: null, + timeFormatter: null, + consecutiveTime: 337 + }, + numberOfStops: 0, + trainrunId: 89, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 62, + y: 240 + }, + { + x: -2, + y: 240 + }, + { + x: -446, + y: 240 + }, + { + x: -510, + y: 240 + } + ], + textPositions: { + 0: { + x: 44, + y: 228 + }, + 1: { + x: 16, + y: 252 + }, + 2: { + x: -492, + y: 252 + }, + 3: { + x: -464, + y: 228 + }, + 4: { + x: -224, + y: 228 + }, + 5: { + x: -224, + y: 228 + }, + 6: { + x: -224, + y: 252 + } + } + }, + warnings: null + }, + { + id: 606, + sourceNodeId: 151, + sourcePortId: 1227, + targetNodeId: 162, + targetPortId: 1228, + travelTime: { + lock: true, + time: 51, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 31, + warning: null, + timeFormatter: null, + consecutiveTime: 151 + }, + sourceArrival: { + lock: false, + time: 29, + warning: null, + timeFormatter: null, + consecutiveTime: 269 + }, + targetDeparture: { + lock: false, + time: 38, + warning: null, + timeFormatter: null, + consecutiveTime: 218 + }, + targetArrival: { + lock: false, + time: 22, + warning: null, + timeFormatter: null, + consecutiveTime: 202 + }, + numberOfStops: 0, + trainrunId: 89, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 3970, + y: 48 + }, + { + x: 4034, + y: 48 + }, + { + x: 4574, + y: -176 + }, + { + x: 4638, + y: -176 + } + ], + textPositions: { + 0: { + x: 3988, + y: 60 + }, + 1: { + x: 4016, + y: 36 + }, + 2: { + x: 4620, + y: -188 + }, + 3: { + x: 4592, + y: -164 + }, + 4: { + x: 4304, + y: -76 + }, + 5: { + x: 4304, + y: -76 + }, + 6: { + x: 4304, + y: -52 + } + } + }, + warnings: null + }, + { + id: 607, + sourceNodeId: 135, + sourcePortId: 1229, + targetNodeId: 150, + targetPortId: 1230, + travelTime: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 125 + }, + sourceArrival: { + lock: false, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 295 + }, + targetDeparture: { + lock: true, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 286 + }, + targetArrival: { + lock: true, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 134 + }, + numberOfStops: 0, + trainrunId: 90, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2850, + y: 144 + }, + { + x: 2914, + y: 144 + }, + { + x: 3230, + y: 144 + }, + { + x: 3294, + y: 144 + } + ], + textPositions: { + 0: { + x: 2868, + y: 156 + }, + 1: { + x: 2896, + y: 132 + }, + 2: { + x: 3276, + y: 132 + }, + 3: { + x: 3248, + y: 156 + }, + 4: { + x: 3072, + y: 132 + }, + 5: { + x: 3072, + y: 132 + }, + 6: { + x: 3072, + y: 156 + } + } + }, + warnings: null + }, + { + id: 608, + sourceNodeId: 150, + sourcePortId: 1231, + targetNodeId: 151, + targetPortId: 1232, + travelTime: { + lock: true, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 16, + warning: null, + timeFormatter: null, + consecutiveTime: 136 + }, + sourceArrival: { + lock: false, + time: 44, + warning: null, + timeFormatter: null, + consecutiveTime: 284 + }, + targetDeparture: { + lock: false, + time: 31, + warning: null, + timeFormatter: null, + consecutiveTime: 271 + }, + targetArrival: { + lock: false, + time: 29, + warning: null, + timeFormatter: null, + consecutiveTime: 149 + }, + numberOfStops: 0, + trainrunId: 90, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 3394, + y: 144 + }, + { + x: 3458, + y: 144 + }, + { + x: 3806, + y: 144 + }, + { + x: 3870, + y: 144 + } + ], + textPositions: { + 0: { + x: 3412, + y: 156 + }, + 1: { + x: 3440, + y: 132 + }, + 2: { + x: 3852, + y: 132 + }, + 3: { + x: 3824, + y: 156 + }, + 4: { + x: 3632, + y: 132 + }, + 5: { + x: 3632, + y: 132 + }, + 6: { + x: 3632, + y: 156 + } + } + }, + warnings: null + }, + { + id: 609, + sourceNodeId: 135, + sourcePortId: 1233, + targetNodeId: 149, + targetPortId: 1234, + travelTime: { + lock: true, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 2, + warning: null, + timeFormatter: null, + consecutiveTime: 302 + }, + sourceArrival: { + lock: true, + time: 58, + warning: null, + timeFormatter: null, + consecutiveTime: 118 + }, + targetDeparture: { + lock: true, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 103 + }, + targetArrival: { + lock: true, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 317 + }, + numberOfStops: 0, + trainrunId: 90, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2654, + y: 208 + }, + { + x: 2590, + y: 208 + }, + { + x: 2402, + y: 208 + }, + { + x: 2338, + y: 208 + } + ], + textPositions: { + 0: { + x: 2636, + y: 196 + }, + 1: { + x: 2608, + y: 220 + }, + 2: { + x: 2356, + y: 220 + }, + 3: { + x: 2384, + y: 196 + }, + 4: { + x: 2496, + y: 196 + }, + 5: { + x: 2496, + y: 196 + }, + 6: { + x: 2496, + y: 220 + } + } + }, + warnings: null + }, + { + id: 610, + sourceNodeId: 149, + sourcePortId: 1235, + targetNodeId: 166, + targetPortId: 1236, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 317 + }, + sourceArrival: { + lock: false, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 103 + }, + targetDeparture: { + lock: false, + time: 37, + warning: null, + timeFormatter: null, + consecutiveTime: 97 + }, + targetArrival: { + lock: false, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 323 + }, + numberOfStops: 0, + trainrunId: 90, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2238, + y: 208 + }, + { + x: 2174, + y: 208 + }, + { + x: 1954, + y: 208 + }, + { + x: 1890, + y: 208 + } + ], + textPositions: { + 0: { + x: 2220, + y: 196 + }, + 1: { + x: 2192, + y: 220 + }, + 2: { + x: 1908, + y: 220 + }, + 3: { + x: 1936, + y: 196 + }, + 4: { + x: 2064, + y: 196 + }, + 5: { + x: 2064, + y: 196 + }, + 6: { + x: 2064, + y: 220 + } + } + }, + warnings: null + }, + { + id: 611, + sourceNodeId: 148, + sourcePortId: 1237, + targetNodeId: 147, + targetPortId: 1238, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 330 + }, + sourceArrival: { + lock: false, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 90 + }, + targetDeparture: { + lock: false, + time: 25, + warning: null, + timeFormatter: null, + consecutiveTime: 85 + }, + targetArrival: { + lock: false, + time: 35, + warning: null, + timeFormatter: null, + consecutiveTime: 335 + }, + numberOfStops: 0, + trainrunId: 90, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1342, + y: 208 + }, + { + x: 1278, + y: 208 + }, + { + x: 1122, + y: 208 + }, + { + x: 1058, + y: 208 + } + ], + textPositions: { + 0: { + x: 1324, + y: 196 + }, + 1: { + x: 1296, + y: 220 + }, + 2: { + x: 1076, + y: 220 + }, + 3: { + x: 1104, + y: 196 + }, + 4: { + x: 1200, + y: 196 + }, + 5: { + x: 1200, + y: 196 + }, + 6: { + x: 1200, + y: 220 + } + } + }, + warnings: null + }, + { + id: 612, + sourceNodeId: 147, + sourcePortId: 1239, + targetNodeId: 133, + targetPortId: 1240, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 35, + warning: null, + timeFormatter: null, + consecutiveTime: 335 + }, + sourceArrival: { + lock: false, + time: 25, + warning: null, + timeFormatter: null, + consecutiveTime: 85 + }, + targetDeparture: { + lock: false, + time: 20, + warning: null, + timeFormatter: null, + consecutiveTime: 80 + }, + targetArrival: { + lock: false, + time: 40, + warning: null, + timeFormatter: null, + consecutiveTime: 340 + }, + numberOfStops: 0, + trainrunId: 90, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 958, + y: 208 + }, + { + x: 894, + y: 208 + }, + { + x: 322, + y: 208 + }, + { + x: 258, + y: 208 + } + ], + textPositions: { + 0: { + x: 940, + y: 196 + }, + 1: { + x: 912, + y: 220 + }, + 2: { + x: 276, + y: 220 + }, + 3: { + x: 304, + y: 196 + }, + 4: { + x: 608, + y: 196 + }, + 5: { + x: 608, + y: 196 + }, + 6: { + x: 608, + y: 220 + } + } + }, + warnings: null + }, + { + id: 613, + sourceNodeId: 133, + sourcePortId: 1241, + targetNodeId: 172, + targetPortId: 1242, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 40, + warning: null, + timeFormatter: null, + consecutiveTime: 340 + }, + sourceArrival: { + lock: false, + time: 20, + warning: null, + timeFormatter: null, + consecutiveTime: 80 + }, + targetDeparture: { + lock: false, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 73 + }, + targetArrival: { + lock: false, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 347 + }, + numberOfStops: 0, + trainrunId: 90, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 62, + y: 272 + }, + { + x: -2, + y: 272 + }, + { + x: -446, + y: 272 + }, + { + x: -510, + y: 272 + } + ], + textPositions: { + 0: { + x: 44, + y: 260 + }, + 1: { + x: 16, + y: 284 + }, + 2: { + x: -492, + y: 284 + }, + 3: { + x: -464, + y: 260 + }, + 4: { + x: -224, + y: 260 + }, + 5: { + x: -224, + y: 260 + }, + 6: { + x: -224, + y: 284 + } + } + }, + warnings: null + }, + { + id: 614, + sourceNodeId: 151, + sourcePortId: 1243, + targetNodeId: 162, + targetPortId: 1244, + travelTime: { + lock: true, + time: 41, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 31, + warning: null, + timeFormatter: null, + consecutiveTime: 151 + }, + sourceArrival: { + lock: false, + time: 29, + warning: null, + timeFormatter: null, + consecutiveTime: 269 + }, + targetDeparture: { + lock: false, + time: 48, + warning: null, + timeFormatter: null, + consecutiveTime: 228 + }, + targetArrival: { + lock: false, + time: 12, + warning: null, + timeFormatter: null, + consecutiveTime: 192 + }, + numberOfStops: 0, + trainrunId: 90, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 3970, + y: 80 + }, + { + x: 4034, + y: 80 + }, + { + x: 4574, + y: -144 + }, + { + x: 4638, + y: -144 + } + ], + textPositions: { + 0: { + x: 3988, + y: 92 + }, + 1: { + x: 4016, + y: 68 + }, + 2: { + x: 4620, + y: -156 + }, + 3: { + x: 4592, + y: -132 + }, + 4: { + x: 4304, + y: -44 + }, + 5: { + x: 4304, + y: -44 + }, + 6: { + x: 4304, + y: -20 + } + } + }, + warnings: null + }, + { + id: 615, + sourceNodeId: 135, + sourcePortId: 1245, + targetNodeId: 150, + targetPortId: 1246, + travelTime: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 35, + warning: null, + timeFormatter: null, + consecutiveTime: 95 + }, + sourceArrival: { + lock: true, + time: 25, + warning: null, + timeFormatter: null, + consecutiveTime: 205 + }, + targetDeparture: { + lock: true, + time: 16, + warning: null, + timeFormatter: null, + consecutiveTime: 196 + }, + targetArrival: { + lock: true, + time: 44, + warning: null, + timeFormatter: null, + consecutiveTime: 104 + }, + numberOfStops: 0, + trainrunId: 79, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2850, + y: 208 + }, + { + x: 2914, + y: 208 + }, + { + x: 3230, + y: 208 + }, + { + x: 3294, + y: 208 + } + ], + textPositions: { + 0: { + x: 2868, + y: 220 + }, + 1: { + x: 2896, + y: 196 + }, + 2: { + x: 3276, + y: 196 + }, + 3: { + x: 3248, + y: 220 + }, + 4: { + x: 3072, + y: 196 + }, + 5: { + x: 3072, + y: 196 + }, + 6: { + x: 3072, + y: 220 + } + } + }, + warnings: null + }, + { + id: 616, + sourceNodeId: 150, + sourcePortId: 1247, + targetNodeId: 151, + targetPortId: 1248, + travelTime: { + lock: false, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 106 + }, + sourceArrival: { + lock: true, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 194 + }, + targetDeparture: { + lock: true, + time: 1, + warning: null, + timeFormatter: null, + consecutiveTime: 181 + }, + targetArrival: { + lock: true, + time: 59, + warning: null, + timeFormatter: null, + consecutiveTime: 119 + }, + numberOfStops: 0, + trainrunId: 79, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 3394, + y: 208 + }, + { + x: 3458, + y: 208 + }, + { + x: 3806, + y: 208 + }, + { + x: 3870, + y: 208 + } + ], + textPositions: { + 0: { + x: 3412, + y: 220 + }, + 1: { + x: 3440, + y: 196 + }, + 2: { + x: 3852, + y: 196 + }, + 3: { + x: 3824, + y: 220 + }, + 4: { + x: 3632, + y: 196 + }, + 5: { + x: 3632, + y: 196 + }, + 6: { + x: 3632, + y: 220 + } + } + }, + warnings: null + }, + { + id: 617, + sourceNodeId: 151, + sourcePortId: 1249, + targetNodeId: 139, + targetPortId: 1250, + travelTime: { + lock: false, + time: 49, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 1, + warning: null, + timeFormatter: null, + consecutiveTime: 121 + }, + sourceArrival: { + lock: true, + time: 59, + warning: null, + timeFormatter: null, + consecutiveTime: 179 + }, + targetDeparture: { + lock: true, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 130 + }, + targetArrival: { + lock: true, + time: 50, + warning: null, + timeFormatter: null, + consecutiveTime: 170 + }, + numberOfStops: 2, + trainrunId: 79, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 3888, + y: 30 + }, + { + x: 3888, + y: -34 + }, + { + x: 4272, + y: -286 + }, + { + x: 4272, + y: -350 + } + ], + textPositions: { + 0: { + x: 3900, + y: 12 + }, + 1: { + x: 3876, + y: -16 + }, + 2: { + x: 4260, + y: -332 + }, + 3: { + x: 4284, + y: -304 + }, + 4: { + x: 4068, + y: -160 + }, + 5: { + x: 4068, + y: -160 + }, + 6: { + x: 4092, + y: -160 + } + } + }, + warnings: null + }, + { + id: 618, + sourceNodeId: 138, + sourcePortId: 1251, + targetNodeId: 163, + targetPortId: 1252, + travelTime: { + lock: true, + time: 1, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 0 + }, + sourceArrival: { + lock: false, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 60 + }, + targetDeparture: { + lock: false, + time: 59, + warning: null, + timeFormatter: null, + consecutiveTime: 59 + }, + targetArrival: { + lock: false, + time: 1, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + numberOfStops: 0, + trainrunId: 91, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2672, + y: -1054 + }, + { + x: 2672, + y: -990 + }, + { + x: 2800, + y: -610 + }, + { + x: 2800, + y: -546 + } + ], + textPositions: { + 0: { + x: 2660, + y: -1036 + }, + 1: { + x: 2684, + y: -1008 + }, + 2: { + x: 2812, + y: -564 + }, + 3: { + x: 2788, + y: -592 + }, + 4: { + x: 2748, + y: -800 + }, + 5: { + x: 2748, + y: -800 + }, + 6: { + x: 2724, + y: -800 + } + } + }, + warnings: null + }, + { + id: 619, + sourceNodeId: 163, + sourcePortId: 1253, + targetNodeId: 135, + targetPortId: 1254, + travelTime: { + lock: true, + time: 1, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 3, + warning: null, + timeFormatter: null, + consecutiveTime: 3 + }, + sourceArrival: { + lock: false, + time: 57, + warning: null, + timeFormatter: null, + consecutiveTime: 57 + }, + targetDeparture: { + lock: false, + time: 56, + warning: null, + timeFormatter: null, + consecutiveTime: 56 + }, + targetArrival: { + lock: false, + time: 4, + warning: null, + timeFormatter: null, + consecutiveTime: 4 + }, + numberOfStops: 0, + trainrunId: 91, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2800, + y: -478 + }, + { + x: 2800, + y: -414 + }, + { + x: 2704, + y: -34 + }, + { + x: 2704, + y: 30 + } + ], + textPositions: { + 0: { + x: 2788, + y: -460 + }, + 1: { + x: 2812, + y: -432 + }, + 2: { + x: 2716, + y: 12 + }, + 3: { + x: 2692, + y: -16 + }, + 4: { + x: 2740, + y: -224 + }, + 5: { + x: 2740, + y: -224 + }, + 6: { + x: 2764, + y: -224 + } + } + }, + warnings: null + }, + { + id: 620, + sourceNodeId: 135, + sourcePortId: 1255, + targetNodeId: 138, + targetPortId: 1256, + travelTime: { + lock: true, + time: 1, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 120 + }, + sourceArrival: { + lock: false, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 60 + }, + targetDeparture: { + lock: false, + time: 59, + warning: null, + timeFormatter: null, + consecutiveTime: 59 + }, + targetArrival: { + lock: false, + time: 1, + warning: null, + timeFormatter: null, + consecutiveTime: 121 + }, + numberOfStops: 0, + trainrunId: 92, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2672, + y: 30 + }, + { + x: 2672, + y: -34 + }, + { + x: 2640, + y: -990 + }, + { + x: 2640, + y: -1054 + } + ], + textPositions: { + 0: { + x: 2684, + y: 12 + }, + 1: { + x: 2660, + y: -16 + }, + 2: { + x: 2628, + y: -1036 + }, + 3: { + x: 2652, + y: -1008 + }, + 4: { + x: 2668, + y: -512 + }, + 5: { + x: 2668, + y: -512 + }, + 6: { + x: 2644, + y: -512 + } + } + }, + warnings: null + }, + { + id: 621, + sourceNodeId: 166, + sourcePortId: 1257, + targetNodeId: 148, + targetPortId: 1258, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 56, + warning: null, + timeFormatter: null, + consecutiveTime: 356 + }, + sourceArrival: { + lock: false, + time: 4, + warning: null, + timeFormatter: null, + consecutiveTime: 184 + }, + targetDeparture: { + lock: false, + time: 59, + warning: null, + timeFormatter: null, + consecutiveTime: 179 + }, + targetArrival: { + lock: false, + time: 1, + warning: null, + timeFormatter: null, + consecutiveTime: 361 + }, + numberOfStops: 0, + trainrunId: 88, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1790, + y: 48 + }, + { + x: 1726, + y: 48 + }, + { + x: 1506, + y: 48 + }, + { + x: 1442, + y: 48 + } + ], + textPositions: { + 0: { + x: 1772, + y: 36 + }, + 1: { + x: 1744, + y: 60 + }, + 2: { + x: 1460, + y: 60 + }, + 3: { + x: 1488, + y: 36 + }, + 4: { + x: 1616, + y: 36 + }, + 5: { + x: 1616, + y: 36 + }, + 6: { + x: 1616, + y: 60 + } + } + }, + warnings: null + }, + { + id: 622, + sourceNodeId: 166, + sourcePortId: 1259, + targetNodeId: 148, + targetPortId: 1260, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 377 + }, + sourceArrival: { + lock: false, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 163 + }, + targetDeparture: { + lock: false, + time: 36, + warning: null, + timeFormatter: null, + consecutiveTime: 156 + }, + targetArrival: { + lock: false, + time: 24, + warning: null, + timeFormatter: null, + consecutiveTime: 384 + }, + numberOfStops: 0, + trainrunId: 87, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1790, + y: 144 + }, + { + x: 1726, + y: 144 + }, + { + x: 1506, + y: 144 + }, + { + x: 1442, + y: 144 + } + ], + textPositions: { + 0: { + x: 1772, + y: 132 + }, + 1: { + x: 1744, + y: 156 + }, + 2: { + x: 1460, + y: 156 + }, + 3: { + x: 1488, + y: 132 + }, + 4: { + x: 1616, + y: 132 + }, + 5: { + x: 1616, + y: 132 + }, + 6: { + x: 1616, + y: 156 + } + } + }, + warnings: null + }, + { + id: 623, + sourceNodeId: 166, + sourcePortId: 1261, + targetNodeId: 148, + targetPortId: 1262, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 314 + }, + sourceArrival: { + lock: false, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 106 + }, + targetDeparture: { + lock: false, + time: 40, + warning: null, + timeFormatter: null, + consecutiveTime: 100 + }, + targetArrival: { + lock: false, + time: 20, + warning: null, + timeFormatter: null, + consecutiveTime: 320 + }, + numberOfStops: 0, + trainrunId: 89, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1790, + y: 176 + }, + { + x: 1726, + y: 176 + }, + { + x: 1506, + y: 176 + }, + { + x: 1442, + y: 176 + } + ], + textPositions: { + 0: { + x: 1772, + y: 164 + }, + 1: { + x: 1744, + y: 188 + }, + 2: { + x: 1460, + y: 188 + }, + 3: { + x: 1488, + y: 164 + }, + 4: { + x: 1616, + y: 164 + }, + 5: { + x: 1616, + y: 164 + }, + 6: { + x: 1616, + y: 188 + } + } + }, + warnings: null + }, + { + id: 624, + sourceNodeId: 166, + sourcePortId: 1263, + targetNodeId: 148, + targetPortId: 1264, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 25, + warning: null, + timeFormatter: null, + consecutiveTime: 325 + }, + sourceArrival: { + lock: false, + time: 35, + warning: null, + timeFormatter: null, + consecutiveTime: 95 + }, + targetDeparture: { + lock: false, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 90 + }, + targetArrival: { + lock: false, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 330 + }, + numberOfStops: 0, + trainrunId: 90, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1790, + y: 208 + }, + { + x: 1726, + y: 208 + }, + { + x: 1506, + y: 208 + }, + { + x: 1442, + y: 208 + } + ], + textPositions: { + 0: { + x: 1772, + y: 196 + }, + 1: { + x: 1744, + y: 220 + }, + 2: { + x: 1460, + y: 220 + }, + 3: { + x: 1488, + y: 196 + }, + 4: { + x: 1616, + y: 196 + }, + 5: { + x: 1616, + y: 196 + }, + 6: { + x: 1616, + y: 220 + } + } + }, + warnings: null + }, + { + id: 625, + sourceNodeId: 166, + sourcePortId: 1265, + targetNodeId: 148, + targetPortId: 1266, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 308 + }, + sourceArrival: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 112 + }, + targetDeparture: { + lock: false, + time: 45, + warning: null, + timeFormatter: null, + consecutiveTime: 105 + }, + targetArrival: { + lock: false, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 315 + }, + numberOfStops: 0, + trainrunId: 86, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1790, + y: 240 + }, + { + x: 1726, + y: 240 + }, + { + x: 1506, + y: 240 + }, + { + x: 1442, + y: 240 + } + ], + textPositions: { + 0: { + x: 1772, + y: 228 + }, + 1: { + x: 1744, + y: 252 + }, + 2: { + x: 1460, + y: 252 + }, + 3: { + x: 1488, + y: 228 + }, + 4: { + x: 1616, + y: 228 + }, + 5: { + x: 1616, + y: 228 + }, + 6: { + x: 1616, + y: 252 + } + } + }, + warnings: null + }, + { + id: 626, + sourceNodeId: 134, + sourcePortId: 1267, + targetNodeId: 164, + targetPortId: 1268, + travelTime: { + lock: true, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 11, + warning: null, + timeFormatter: null, + consecutiveTime: 11 + }, + sourceArrival: { + lock: false, + time: 49, + warning: null, + timeFormatter: null, + consecutiveTime: 169 + }, + targetDeparture: { + lock: false, + time: 36, + warning: null, + timeFormatter: null, + consecutiveTime: 156 + }, + targetArrival: { + lock: false, + time: 24, + warning: null, + timeFormatter: null, + consecutiveTime: 24 + }, + numberOfStops: 0, + trainrunId: 93, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 322, + y: -1872 + }, + { + x: 386, + y: -1872 + }, + { + x: 990, + y: -944 + }, + { + x: 1054, + y: -944 + } + ], + textPositions: { + 0: { + x: 340, + y: -1860 + }, + 1: { + x: 368, + y: -1884 + }, + 2: { + x: 1036, + y: -956 + }, + 3: { + x: 1008, + y: -932 + }, + 4: { + x: 688, + y: -1420 + }, + 5: { + x: 688, + y: -1420 + }, + 6: { + x: 688, + y: -1396 + } + } + }, + warnings: null + }, + { + id: 627, + sourceNodeId: 164, + sourcePortId: 1269, + targetNodeId: 165, + targetPortId: 1270, + travelTime: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 25, + warning: null, + timeFormatter: null, + consecutiveTime: 25 + }, + sourceArrival: { + lock: false, + time: 35, + warning: null, + timeFormatter: null, + consecutiveTime: 155 + }, + targetDeparture: { + lock: false, + time: 26, + warning: null, + timeFormatter: null, + consecutiveTime: 146 + }, + targetArrival: { + lock: false, + time: 34, + warning: null, + timeFormatter: null, + consecutiveTime: 34 + }, + numberOfStops: 0, + trainrunId: 93, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1154, + y: -944 + }, + { + x: 1218, + y: -944 + }, + { + x: 1726, + y: -656 + }, + { + x: 1790, + y: -656 + } + ], + textPositions: { + 0: { + x: 1172, + y: -932 + }, + 1: { + x: 1200, + y: -956 + }, + 2: { + x: 1772, + y: -668 + }, + 3: { + x: 1744, + y: -644 + }, + 4: { + x: 1472, + y: -812 + }, + 5: { + x: 1472, + y: -812 + }, + 6: { + x: 1472, + y: -788 + } + } + }, + warnings: null + }, + { + id: 628, + sourceNodeId: 165, + sourcePortId: 1271, + targetNodeId: 166, + targetPortId: 1272, + travelTime: { + lock: true, + time: 22, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 35, + warning: null, + timeFormatter: null, + consecutiveTime: 35 + }, + sourceArrival: { + lock: false, + time: 25, + warning: null, + timeFormatter: null, + consecutiveTime: 145 + }, + targetDeparture: { + lock: false, + time: 3, + warning: null, + timeFormatter: null, + consecutiveTime: 123 + }, + targetArrival: { + lock: false, + time: 57, + warning: null, + timeFormatter: null, + consecutiveTime: 57 + }, + numberOfStops: 0, + trainrunId: 93, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1808, + y: -606 + }, + { + x: 1808, + y: -542 + }, + { + x: 1808, + y: -34 + }, + { + x: 1808, + y: 30 + } + ], + textPositions: { + 0: { + x: 1796, + y: -588 + }, + 1: { + x: 1820, + y: -560 + }, + 2: { + x: 1820, + y: 12 + }, + 3: { + x: 1796, + y: -16 + }, + 4: { + x: 1796, + y: -288 + }, + 5: { + x: 1796, + y: -288 + }, + 6: { + x: 1820, + y: -288 + } + } + }, + warnings: null + }, + { + id: 629, + sourceNodeId: 166, + sourcePortId: 1273, + targetNodeId: 149, + targetPortId: 1274, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 60 + }, + sourceArrival: { + lock: false, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 120 + }, + targetDeparture: { + lock: false, + time: 53, + warning: null, + timeFormatter: null, + consecutiveTime: 113 + }, + targetArrival: { + lock: false, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 67 + }, + numberOfStops: 0, + trainrunId: 93, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1890, + y: 272 + }, + { + x: 1954, + y: 272 + }, + { + x: 2174, + y: 272 + }, + { + x: 2238, + y: 272 + } + ], + textPositions: { + 0: { + x: 1908, + y: 284 + }, + 1: { + x: 1936, + y: 260 + }, + 2: { + x: 2220, + y: 260 + }, + 3: { + x: 2192, + y: 284 + }, + 4: { + x: 2064, + y: 260 + }, + 5: { + x: 2064, + y: 260 + }, + 6: { + x: 2064, + y: 284 + } + } + }, + warnings: null + }, + { + id: 630, + sourceNodeId: 149, + sourcePortId: 1275, + targetNodeId: 135, + targetPortId: 1276, + travelTime: { + lock: true, + time: 16, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 68 + }, + sourceArrival: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 112 + }, + targetDeparture: { + lock: false, + time: 36, + warning: null, + timeFormatter: null, + consecutiveTime: 96 + }, + targetArrival: { + lock: false, + time: 24, + warning: null, + timeFormatter: null, + consecutiveTime: 84 + }, + numberOfStops: 0, + trainrunId: 93, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2338, + y: 272 + }, + { + x: 2402, + y: 272 + }, + { + x: 2590, + y: 272 + }, + { + x: 2654, + y: 272 + } + ], + textPositions: { + 0: { + x: 2356, + y: 284 + }, + 1: { + x: 2384, + y: 260 + }, + 2: { + x: 2636, + y: 260 + }, + 3: { + x: 2608, + y: 284 + }, + 4: { + x: 2496, + y: 260 + }, + 5: { + x: 2496, + y: 260 + }, + 6: { + x: 2496, + y: 284 + } + } + }, + warnings: null + }, + { + id: 631, + sourceNodeId: 134, + sourcePortId: 1277, + targetNodeId: 146, + targetPortId: 1278, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 6 + }, + sourceArrival: { + lock: false, + time: 54, + warning: null, + timeFormatter: null, + consecutiveTime: 174 + }, + targetDeparture: { + lock: false, + time: 49, + warning: null, + timeFormatter: null, + consecutiveTime: 169 + }, + targetArrival: { + lock: false, + time: 11, + warning: null, + timeFormatter: null, + consecutiveTime: 11 + }, + numberOfStops: 0, + trainrunId: 94, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 144, + y: -1822 + }, + { + x: 144, + y: -1758 + }, + { + x: 144, + y: -1474 + }, + { + x: 144, + y: -1410 + } + ], + textPositions: { + 0: { + x: 132, + y: -1804 + }, + 1: { + x: 156, + y: -1776 + }, + 2: { + x: 156, + y: -1428 + }, + 3: { + x: 132, + y: -1456 + }, + 4: { + x: 132, + y: -1616 + }, + 5: { + x: 132, + y: -1616 + }, + 6: { + x: 156, + y: -1616 + } + } + }, + warnings: null + }, + { + id: 632, + sourceNodeId: 146, + sourcePortId: 1279, + targetNodeId: 145, + targetPortId: 1280, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 11, + warning: null, + timeFormatter: null, + consecutiveTime: 11 + }, + sourceArrival: { + lock: false, + time: 49, + warning: null, + timeFormatter: null, + consecutiveTime: 169 + }, + targetDeparture: { + lock: false, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 163 + }, + targetArrival: { + lock: false, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 17 + }, + numberOfStops: 0, + trainrunId: 94, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 144, + y: -1342 + }, + { + x: 144, + y: -1278 + }, + { + x: 144, + y: -994 + }, + { + x: 144, + y: -930 + } + ], + textPositions: { + 0: { + x: 132, + y: -1324 + }, + 1: { + x: 156, + y: -1296 + }, + 2: { + x: 156, + y: -948 + }, + 3: { + x: 132, + y: -976 + }, + 4: { + x: 132, + y: -1136 + }, + 5: { + x: 132, + y: -1136 + }, + 6: { + x: 156, + y: -1136 + } + } + }, + warnings: null + }, + { + id: 633, + sourceNodeId: 145, + sourcePortId: 1281, + targetNodeId: 144, + targetPortId: 1282, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 17 + }, + sourceArrival: { + lock: false, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 163 + }, + targetDeparture: { + lock: false, + time: 37, + warning: null, + timeFormatter: null, + consecutiveTime: 157 + }, + targetArrival: { + lock: false, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 23 + }, + numberOfStops: 0, + trainrunId: 94, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 144, + y: -862 + }, + { + x: 144, + y: -798 + }, + { + x: 144, + y: -514 + }, + { + x: 144, + y: -450 + } + ], + textPositions: { + 0: { + x: 132, + y: -844 + }, + 1: { + x: 156, + y: -816 + }, + 2: { + x: 156, + y: -468 + }, + 3: { + x: 132, + y: -496 + }, + 4: { + x: 132, + y: -656 + }, + 5: { + x: 132, + y: -656 + }, + 6: { + x: 156, + y: -656 + } + } + }, + warnings: null + }, + { + id: 634, + sourceNodeId: 144, + sourcePortId: 1283, + targetNodeId: 147, + targetPortId: 1284, + travelTime: { + lock: true, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 23 + }, + sourceArrival: { + lock: false, + time: 37, + warning: null, + timeFormatter: null, + consecutiveTime: 157 + }, + targetDeparture: { + lock: false, + time: 27, + warning: null, + timeFormatter: null, + consecutiveTime: 147 + }, + targetArrival: { + lock: false, + time: 33, + warning: null, + timeFormatter: null, + consecutiveTime: 33 + }, + numberOfStops: 0, + trainrunId: 94, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 322, + y: -400 + }, + { + x: 386, + y: -400 + }, + { + x: 894, + y: 80 + }, + { + x: 958, + y: 80 + } + ], + textPositions: { + 0: { + x: 340, + y: -388 + }, + 1: { + x: 368, + y: -412 + }, + 2: { + x: 940, + y: 68 + }, + 3: { + x: 912, + y: 92 + }, + 4: { + x: 640, + y: -172 + }, + 5: { + x: 640, + y: -172 + }, + 6: { + x: 640, + y: -148 + } + } + }, + warnings: null + }, + { + id: 635, + sourceNodeId: 147, + sourcePortId: 1285, + targetNodeId: 148, + targetPortId: 1286, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 33, + warning: null, + timeFormatter: null, + consecutiveTime: 33 + }, + sourceArrival: { + lock: false, + time: 27, + warning: null, + timeFormatter: null, + consecutiveTime: 147 + }, + targetDeparture: { + lock: false, + time: 20, + warning: null, + timeFormatter: null, + consecutiveTime: 140 + }, + targetArrival: { + lock: false, + time: 40, + warning: null, + timeFormatter: null, + consecutiveTime: 40 + }, + numberOfStops: 0, + trainrunId: 94, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1058, + y: 112 + }, + { + x: 1122, + y: 112 + }, + { + x: 1278, + y: 112 + }, + { + x: 1342, + y: 112 + } + ], + textPositions: { + 0: { + x: 1076, + y: 124 + }, + 1: { + x: 1104, + y: 100 + }, + 2: { + x: 1324, + y: 100 + }, + 3: { + x: 1296, + y: 124 + }, + 4: { + x: 1200, + y: 100 + }, + 5: { + x: 1200, + y: 100 + }, + 6: { + x: 1200, + y: 124 + } + } + }, + warnings: null + }, + { + id: 636, + sourceNodeId: 148, + sourcePortId: 1287, + targetNodeId: 166, + targetPortId: 1288, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 40, + warning: null, + timeFormatter: null, + consecutiveTime: 40 + }, + sourceArrival: { + lock: false, + time: 20, + warning: null, + timeFormatter: null, + consecutiveTime: 140 + }, + targetDeparture: { + lock: false, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 134 + }, + targetArrival: { + lock: false, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 46 + }, + numberOfStops: 0, + trainrunId: 94, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1442, + y: 112 + }, + { + x: 1506, + y: 112 + }, + { + x: 1726, + y: 112 + }, + { + x: 1790, + y: 112 + } + ], + textPositions: { + 0: { + x: 1460, + y: 124 + }, + 1: { + x: 1488, + y: 100 + }, + 2: { + x: 1772, + y: 100 + }, + 3: { + x: 1744, + y: 124 + }, + 4: { + x: 1616, + y: 100 + }, + 5: { + x: 1616, + y: 100 + }, + 6: { + x: 1616, + y: 124 + } + } + }, + warnings: null + }, + { + id: 637, + sourceNodeId: 166, + sourcePortId: 1289, + targetNodeId: 149, + targetPortId: 1290, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 46 + }, + sourceArrival: { + lock: false, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 134 + }, + targetDeparture: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 128 + }, + targetArrival: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 52 + }, + numberOfStops: 0, + trainrunId: 94, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1890, + y: 112 + }, + { + x: 1954, + y: 112 + }, + { + x: 2174, + y: 112 + }, + { + x: 2238, + y: 112 + } + ], + textPositions: { + 0: { + x: 1908, + y: 124 + }, + 1: { + x: 1936, + y: 100 + }, + 2: { + x: 2220, + y: 100 + }, + 3: { + x: 2192, + y: 124 + }, + 4: { + x: 2064, + y: 100 + }, + 5: { + x: 2064, + y: 100 + }, + 6: { + x: 2064, + y: 124 + } + } + }, + warnings: null + }, + { + id: 638, + sourceNodeId: 149, + sourcePortId: 1291, + targetNodeId: 135, + targetPortId: 1292, + travelTime: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 52 + }, + sourceArrival: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 128 + }, + targetDeparture: { + lock: false, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 120 + }, + targetArrival: { + lock: false, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 60 + }, + numberOfStops: 0, + trainrunId: 94, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2338, + y: 112 + }, + { + x: 2402, + y: 112 + }, + { + x: 2590, + y: 112 + }, + { + x: 2654, + y: 112 + } + ], + textPositions: { + 0: { + x: 2356, + y: 124 + }, + 1: { + x: 2384, + y: 100 + }, + 2: { + x: 2636, + y: 100 + }, + 3: { + x: 2608, + y: 124 + }, + 4: { + x: 2496, + y: 100 + }, + 5: { + x: 2496, + y: 100 + }, + 6: { + x: 2496, + y: 124 + } + } + }, + warnings: null + }, + { + id: 639, + sourceNodeId: 147, + sourcePortId: 1293, + targetNodeId: 148, + targetPortId: 1294, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 54, + warning: null, + timeFormatter: null, + consecutiveTime: 54 + }, + sourceArrival: { + lock: false, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 126 + }, + targetDeparture: { + lock: false, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 120 + }, + targetArrival: { + lock: false, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 60 + }, + numberOfStops: 0, + trainrunId: 97, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1058, + y: 272 + }, + { + x: 1122, + y: 272 + }, + { + x: 1278, + y: 272 + }, + { + x: 1342, + y: 272 + } + ], + textPositions: { + 0: { + x: 1076, + y: 284 + }, + 1: { + x: 1104, + y: 260 + }, + 2: { + x: 1324, + y: 260 + }, + 3: { + x: 1296, + y: 284 + }, + 4: { + x: 1200, + y: 260 + }, + 5: { + x: 1200, + y: 260 + }, + 6: { + x: 1200, + y: 284 + } + } + }, + warnings: null + }, + { + id: 640, + sourceNodeId: 148, + sourcePortId: 1295, + targetNodeId: 166, + targetPortId: 1296, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 2, + warning: null, + timeFormatter: null, + consecutiveTime: 62 + }, + sourceArrival: { + lock: false, + time: 58, + warning: null, + timeFormatter: null, + consecutiveTime: 118 + }, + targetDeparture: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 112 + }, + targetArrival: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 68 + }, + numberOfStops: 0, + trainrunId: 97, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1442, + y: 272 + }, + { + x: 1506, + y: 272 + }, + { + x: 1726, + y: 272 + }, + { + x: 1790, + y: 272 + } + ], + textPositions: { + 0: { + x: 1460, + y: 284 + }, + 1: { + x: 1488, + y: 260 + }, + 2: { + x: 1772, + y: 260 + }, + 3: { + x: 1744, + y: 284 + }, + 4: { + x: 1616, + y: 260 + }, + 5: { + x: 1616, + y: 260 + }, + 6: { + x: 1616, + y: 284 + } + } + }, + warnings: null + }, + { + id: 641, + sourceNodeId: 166, + sourcePortId: 1297, + targetNodeId: 149, + targetPortId: 1298, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 68 + }, + sourceArrival: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 112 + }, + targetDeparture: { + lock: false, + time: 45, + warning: null, + timeFormatter: null, + consecutiveTime: 105 + }, + targetArrival: { + lock: false, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 75 + }, + numberOfStops: 0, + trainrunId: 97, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1890, + y: 304 + }, + { + x: 1954, + y: 304 + }, + { + x: 2174, + y: 304 + }, + { + x: 2238, + y: 304 + } + ], + textPositions: { + 0: { + x: 1908, + y: 316 + }, + 1: { + x: 1936, + y: 292 + }, + 2: { + x: 2220, + y: 292 + }, + 3: { + x: 2192, + y: 316 + }, + 4: { + x: 2064, + y: 292 + }, + 5: { + x: 2064, + y: 292 + }, + 6: { + x: 2064, + y: 316 + } + } + }, + warnings: null + }, + { + id: 642, + sourceNodeId: 149, + sourcePortId: 1299, + targetNodeId: 135, + targetPortId: 1300, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 75 + }, + sourceArrival: { + lock: false, + time: 45, + warning: null, + timeFormatter: null, + consecutiveTime: 105 + }, + targetDeparture: { + lock: false, + time: 38, + warning: null, + timeFormatter: null, + consecutiveTime: 98 + }, + targetArrival: { + lock: false, + time: 22, + warning: null, + timeFormatter: null, + consecutiveTime: 82 + }, + numberOfStops: 0, + trainrunId: 97, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2338, + y: 304 + }, + { + x: 2402, + y: 304 + }, + { + x: 2590, + y: 304 + }, + { + x: 2654, + y: 304 + } + ], + textPositions: { + 0: { + x: 2356, + y: 316 + }, + 1: { + x: 2384, + y: 292 + }, + 2: { + x: 2636, + y: 292 + }, + 3: { + x: 2608, + y: 316 + }, + 4: { + x: 2496, + y: 292 + }, + 5: { + x: 2496, + y: 292 + }, + 6: { + x: 2496, + y: 316 + } + } + }, + warnings: null + }, + { + id: 643, + sourceNodeId: 134, + sourcePortId: 1301, + targetNodeId: 146, + targetPortId: 1302, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 28, + warning: null, + timeFormatter: null, + consecutiveTime: 28 + }, + sourceArrival: { + lock: false, + time: 32, + warning: null, + timeFormatter: null, + consecutiveTime: 272 + }, + targetDeparture: { + lock: false, + time: 25, + warning: null, + timeFormatter: null, + consecutiveTime: 265 + }, + targetArrival: { + lock: false, + time: 35, + warning: null, + timeFormatter: null, + consecutiveTime: 35 + }, + numberOfStops: 0, + trainrunId: 95, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 208, + y: -1822 + }, + { + x: 208, + y: -1758 + }, + { + x: 208, + y: -1474 + }, + { + x: 208, + y: -1410 + } + ], + textPositions: { + 0: { + x: 196, + y: -1804 + }, + 1: { + x: 220, + y: -1776 + }, + 2: { + x: 220, + y: -1428 + }, + 3: { + x: 196, + y: -1456 + }, + 4: { + x: 196, + y: -1616 + }, + 5: { + x: 196, + y: -1616 + }, + 6: { + x: 220, + y: -1616 + } + } + }, + warnings: null + }, + { + id: 644, + sourceNodeId: 146, + sourcePortId: 1303, + targetNodeId: 145, + targetPortId: 1304, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 35, + warning: null, + timeFormatter: null, + consecutiveTime: 35 + }, + sourceArrival: { + lock: false, + time: 25, + warning: null, + timeFormatter: null, + consecutiveTime: 265 + }, + targetDeparture: { + lock: false, + time: 19, + warning: null, + timeFormatter: null, + consecutiveTime: 259 + }, + targetArrival: { + lock: false, + time: 41, + warning: null, + timeFormatter: null, + consecutiveTime: 41 + }, + numberOfStops: 0, + trainrunId: 95, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 208, + y: -1342 + }, + { + x: 208, + y: -1278 + }, + { + x: 208, + y: -994 + }, + { + x: 208, + y: -930 + } + ], + textPositions: { + 0: { + x: 196, + y: -1324 + }, + 1: { + x: 220, + y: -1296 + }, + 2: { + x: 220, + y: -948 + }, + 3: { + x: 196, + y: -976 + }, + 4: { + x: 196, + y: -1136 + }, + 5: { + x: 196, + y: -1136 + }, + 6: { + x: 220, + y: -1136 + } + } + }, + warnings: null + }, + { + id: 645, + sourceNodeId: 145, + sourcePortId: 1305, + targetNodeId: 144, + targetPortId: 1306, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 41, + warning: null, + timeFormatter: null, + consecutiveTime: 41 + }, + sourceArrival: { + lock: false, + time: 19, + warning: null, + timeFormatter: null, + consecutiveTime: 259 + }, + targetDeparture: { + lock: false, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 253 + }, + targetArrival: { + lock: false, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 47 + }, + numberOfStops: 0, + trainrunId: 95, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 208, + y: -862 + }, + { + x: 208, + y: -798 + }, + { + x: 208, + y: -514 + }, + { + x: 208, + y: -450 + } + ], + textPositions: { + 0: { + x: 196, + y: -844 + }, + 1: { + x: 220, + y: -816 + }, + 2: { + x: 220, + y: -468 + }, + 3: { + x: 196, + y: -496 + }, + 4: { + x: 196, + y: -656 + }, + 5: { + x: 196, + y: -656 + }, + 6: { + x: 220, + y: -656 + } + } + }, + warnings: null + }, + { + id: 646, + sourceNodeId: 144, + sourcePortId: 1307, + targetNodeId: 133, + targetPortId: 1308, + travelTime: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 47 + }, + sourceArrival: { + lock: false, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 253 + }, + targetDeparture: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 245 + }, + targetArrival: { + lock: true, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 55 + }, + numberOfStops: 0, + trainrunId: 95, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 144, + y: -354 + }, + { + x: 144, + y: -290 + }, + { + x: 144, + y: 30 + }, + { + x: 144, + y: 94 + } + ], + textPositions: { + 0: { + x: 132, + y: -336 + }, + 1: { + x: 156, + y: -308 + }, + 2: { + x: 156, + y: 76 + }, + 3: { + x: 132, + y: 48 + }, + 4: { + x: 132, + y: -130 + }, + 5: { + x: 132, + y: -130 + }, + 6: { + x: 156, + y: -130 + } + } + }, + warnings: null + }, + { + id: 647, + sourceNodeId: 133, + sourcePortId: 1309, + targetNodeId: 172, + targetPortId: 1310, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 58, + warning: null, + timeFormatter: null, + consecutiveTime: 58 + }, + sourceArrival: { + lock: true, + time: 2, + warning: null, + timeFormatter: null, + consecutiveTime: 242 + }, + targetDeparture: { + lock: false, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 235 + }, + targetArrival: { + lock: false, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 65 + }, + numberOfStops: 0, + trainrunId: 95, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 62, + y: 208 + }, + { + x: -2, + y: 208 + }, + { + x: -446, + y: 208 + }, + { + x: -510, + y: 208 + } + ], + textPositions: { + 0: { + x: 44, + y: 196 + }, + 1: { + x: 16, + y: 220 + }, + 2: { + x: -492, + y: 220 + }, + 3: { + x: -464, + y: 196 + }, + 4: { + x: -224, + y: 196 + }, + 5: { + x: -224, + y: 196 + }, + 6: { + x: -224, + y: 220 + } + } + }, + warnings: null + }, + { + id: 648, + sourceNodeId: 129, + sourcePortId: 1311, + targetNodeId: 167, + targetPortId: 1312, + travelTime: { + lock: true, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 34, + warning: null, + timeFormatter: null, + consecutiveTime: 94 + }, + sourceArrival: { + lock: true, + time: 26, + warning: null, + timeFormatter: null, + consecutiveTime: 206 + }, + targetDeparture: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 188 + }, + targetArrival: { + lock: true, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 112 + }, + numberOfStops: 0, + trainrunId: 95, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2096, + y: 382 + }, + { + x: -2096, + y: 446 + }, + { + x: -2096, + y: 574 + }, + { + x: -2096, + y: 638 + } + ], + textPositions: { + 0: { + x: -2108, + y: 400 + }, + 1: { + x: -2084, + y: 428 + }, + 2: { + x: -2084, + y: 620 + }, + 3: { + x: -2108, + y: 592 + }, + 4: { + x: -2108, + y: 510 + }, + 5: { + x: -2108, + y: 510 + }, + 6: { + x: -2084, + y: 510 + } + } + }, + warnings: null + }, + { + id: 649, + sourceNodeId: 129, + sourcePortId: 1313, + targetNodeId: 167, + targetPortId: 1314, + travelTime: { + lock: true, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 59, + warning: null, + timeFormatter: null, + consecutiveTime: 359 + }, + sourceArrival: { + lock: false, + time: 1, + warning: null, + timeFormatter: null, + consecutiveTime: 61 + }, + targetDeparture: { + lock: false, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 43 + }, + targetArrival: { + lock: false, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 377 + }, + numberOfStops: 0, + trainrunId: 89, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2064, + y: 382 + }, + { + x: -2064, + y: 446 + }, + { + x: -2064, + y: 574 + }, + { + x: -2064, + y: 638 + } + ], + textPositions: { + 0: { + x: -2076, + y: 400 + }, + 1: { + x: -2052, + y: 428 + }, + 2: { + x: -2052, + y: 620 + }, + 3: { + x: -2076, + y: 592 + }, + 4: { + x: -2076, + y: 510 + }, + 5: { + x: -2076, + y: 510 + }, + 6: { + x: -2052, + y: 510 + } + } + }, + warnings: null + }, + { + id: 650, + sourceNodeId: 167, + sourcePortId: 1315, + targetNodeId: 168, + targetPortId: 1316, + travelTime: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 54, + warning: null, + timeFormatter: null, + consecutiveTime: 114 + }, + sourceArrival: { + lock: false, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 186 + }, + targetDeparture: { + lock: false, + time: 58, + warning: null, + timeFormatter: null, + consecutiveTime: 178 + }, + targetArrival: { + lock: false, + time: 2, + warning: null, + timeFormatter: null, + consecutiveTime: 122 + }, + numberOfStops: 0, + trainrunId: 95, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2096, + y: 706 + }, + { + x: -2096, + y: 770 + }, + { + x: -2096, + y: 862 + }, + { + x: -2096, + y: 926 + } + ], + textPositions: { + 0: { + x: -2108, + y: 724 + }, + 1: { + x: -2084, + y: 752 + }, + 2: { + x: -2084, + y: 908 + }, + 3: { + x: -2108, + y: 880 + }, + 4: { + x: -2108, + y: 816 + }, + 5: { + x: -2108, + y: 816 + }, + 6: { + x: -2084, + y: 816 + } + } + }, + warnings: null + }, + { + id: 651, + sourceNodeId: 168, + sourcePortId: 1317, + targetNodeId: 131, + targetPortId: 1318, + travelTime: { + lock: true, + time: 24, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 4, + warning: null, + timeFormatter: null, + consecutiveTime: 124 + }, + sourceArrival: { + lock: false, + time: 56, + warning: null, + timeFormatter: null, + consecutiveTime: 176 + }, + targetDeparture: { + lock: false, + time: 32, + warning: null, + timeFormatter: null, + consecutiveTime: 152 + }, + targetArrival: { + lock: false, + time: 28, + warning: null, + timeFormatter: null, + consecutiveTime: 148 + }, + numberOfStops: 0, + trainrunId: 95, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2014, + y: 944 + }, + { + x: -1950, + y: 944 + }, + { + x: -1154, + y: 944 + }, + { + x: -1090, + y: 944 + } + ], + textPositions: { + 0: { + x: -1996, + y: 956 + }, + 1: { + x: -1968, + y: 932 + }, + 2: { + x: -1108, + y: 932 + }, + 3: { + x: -1136, + y: 956 + }, + 4: { + x: -1552, + y: 932 + }, + 5: { + x: -1552, + y: 932 + }, + 6: { + x: -1552, + y: 956 + } + } + }, + warnings: null + }, + { + id: 652, + sourceNodeId: 167, + sourcePortId: 1319, + targetNodeId: 168, + targetPortId: 1320, + travelTime: { + lock: true, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 19, + warning: null, + timeFormatter: null, + consecutiveTime: 379 + }, + sourceArrival: { + lock: false, + time: 41, + warning: null, + timeFormatter: null, + consecutiveTime: 41 + }, + targetDeparture: { + lock: false, + time: 31, + warning: null, + timeFormatter: null, + consecutiveTime: 31 + }, + targetArrival: { + lock: false, + time: 29, + warning: null, + timeFormatter: null, + consecutiveTime: 389 + }, + numberOfStops: 0, + trainrunId: 89, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2064, + y: 706 + }, + { + x: -2064, + y: 770 + }, + { + x: -2064, + y: 862 + }, + { + x: -2064, + y: 926 + } + ], + textPositions: { + 0: { + x: -2076, + y: 724 + }, + 1: { + x: -2052, + y: 752 + }, + 2: { + x: -2052, + y: 908 + }, + 3: { + x: -2076, + y: 880 + }, + 4: { + x: -2076, + y: 816 + }, + 5: { + x: -2076, + y: 816 + }, + 6: { + x: -2052, + y: 816 + } + } + }, + warnings: null + }, + { + id: 653, + sourceNodeId: 168, + sourcePortId: 1321, + targetNodeId: 132, + targetPortId: 1322, + travelTime: { + lock: true, + time: 25, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 31, + warning: null, + timeFormatter: null, + consecutiveTime: 391 + }, + sourceArrival: { + lock: false, + time: 29, + warning: null, + timeFormatter: null, + consecutiveTime: 29 + }, + targetDeparture: { + lock: false, + time: 4, + warning: null, + timeFormatter: null, + consecutiveTime: 4 + }, + targetArrival: { + lock: false, + time: 56, + warning: null, + timeFormatter: null, + consecutiveTime: 416 + }, + numberOfStops: 0, + trainrunId: 89, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2096, + y: 1022 + }, + { + x: -2096, + y: 1086 + }, + { + x: -2096, + y: 1374 + }, + { + x: -2096, + y: 1438 + } + ], + textPositions: { + 0: { + x: -2108, + y: 1040 + }, + 1: { + x: -2084, + y: 1068 + }, + 2: { + x: -2084, + y: 1420 + }, + 3: { + x: -2108, + y: 1392 + }, + 4: { + x: -2108, + y: 1230 + }, + 5: { + x: -2108, + y: 1230 + }, + 6: { + x: -2084, + y: 1230 + } + } + }, + warnings: null + }, + { + id: 654, + sourceNodeId: 132, + sourcePortId: 1323, + targetNodeId: 168, + targetPortId: 1324, + travelTime: { + lock: true, + time: 26, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 29, + warning: null, + timeFormatter: null, + consecutiveTime: 149 + }, + sourceArrival: { + lock: false, + time: 31, + warning: null, + timeFormatter: null, + consecutiveTime: 151 + }, + targetDeparture: { + lock: false, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 125 + }, + targetArrival: { + lock: false, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 175 + }, + numberOfStops: 0, + trainrunId: 96, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2128, + y: 1438 + }, + { + x: -2128, + y: 1374 + }, + { + x: -2128, + y: 1086 + }, + { + x: -2128, + y: 1022 + } + ], + textPositions: { + 0: { + x: -2116, + y: 1420 + }, + 1: { + x: -2140, + y: 1392 + }, + 2: { + x: -2140, + y: 1040 + }, + 3: { + x: -2116, + y: 1068 + }, + 4: { + x: -2140, + y: 1230 + }, + 5: { + x: -2140, + y: 1230 + }, + 6: { + x: -2116, + y: 1230 + } + } + }, + warnings: null + }, + { + id: 655, + sourceNodeId: 168, + sourcePortId: 1325, + targetNodeId: 167, + targetPortId: 1326, + travelTime: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 58, + warning: null, + timeFormatter: null, + consecutiveTime: 178 + }, + sourceArrival: { + lock: false, + time: 2, + warning: null, + timeFormatter: null, + consecutiveTime: 122 + }, + targetDeparture: { + lock: false, + time: 54, + warning: null, + timeFormatter: null, + consecutiveTime: 114 + }, + targetArrival: { + lock: false, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 186 + }, + numberOfStops: 0, + trainrunId: 96, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2128, + y: 926 + }, + { + x: -2128, + y: 862 + }, + { + x: -2128, + y: 770 + }, + { + x: -2128, + y: 706 + } + ], + textPositions: { + 0: { + x: -2116, + y: 908 + }, + 1: { + x: -2140, + y: 880 + }, + 2: { + x: -2140, + y: 724 + }, + 3: { + x: -2116, + y: 752 + }, + 4: { + x: -2140, + y: 816 + }, + 5: { + x: -2140, + y: 816 + }, + 6: { + x: -2116, + y: 816 + } + } + }, + warnings: null + }, + { + id: 656, + sourceNodeId: 167, + sourcePortId: 1327, + targetNodeId: 129, + targetPortId: 1328, + travelTime: { + lock: true, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 188 + }, + sourceArrival: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 112 + }, + targetDeparture: { + lock: true, + time: 34, + warning: null, + timeFormatter: null, + consecutiveTime: 94 + }, + targetArrival: { + lock: true, + time: 26, + warning: null, + timeFormatter: null, + consecutiveTime: 206 + }, + numberOfStops: 0, + trainrunId: 96, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2128, + y: 638 + }, + { + x: -2128, + y: 574 + }, + { + x: -2128, + y: 446 + }, + { + x: -2128, + y: 382 + } + ], + textPositions: { + 0: { + x: -2116, + y: 620 + }, + 1: { + x: -2140, + y: 592 + }, + 2: { + x: -2140, + y: 400 + }, + 3: { + x: -2116, + y: 428 + }, + 4: { + x: -2140, + y: 510 + }, + 5: { + x: -2140, + y: 510 + }, + 6: { + x: -2116, + y: 510 + } + } + }, + warnings: null + }, + { + id: 657, + sourceNodeId: 129, + sourcePortId: 1329, + targetNodeId: 178, + targetPortId: 1330, + travelTime: { + lock: true, + time: 3, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 34, + warning: null, + timeFormatter: null, + consecutiveTime: 214 + }, + sourceArrival: { + lock: true, + time: 26, + warning: null, + timeFormatter: null, + consecutiveTime: 86 + }, + targetDeparture: { + lock: false, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 83 + }, + targetArrival: { + lock: false, + time: 37, + warning: null, + timeFormatter: null, + consecutiveTime: 217 + }, + numberOfStops: 0, + trainrunId: 96, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2014, + y: 176 + }, + { + x: -1950, + y: 176 + }, + { + x: -1762, + y: 176 + }, + { + x: -1698, + y: 176 + } + ], + textPositions: { + 0: { + x: -1996, + y: 188 + }, + 1: { + x: -1968, + y: 164 + }, + 2: { + x: -1716, + y: 164 + }, + 3: { + x: -1744, + y: 188 + }, + 4: { + x: -1856, + y: 164 + }, + 5: { + x: -1856, + y: 164 + }, + 6: { + x: -1856, + y: 188 + } + } + }, + warnings: null + }, + { + id: 658, + sourceNodeId: 133, + sourcePortId: 1331, + targetNodeId: 144, + targetPortId: 1332, + travelTime: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 245 + }, + sourceArrival: { + lock: true, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 55 + }, + targetDeparture: { + lock: false, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 47 + }, + targetArrival: { + lock: false, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 253 + }, + numberOfStops: 0, + trainrunId: 96, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 112, + y: 94 + }, + { + x: 112, + y: 30 + }, + { + x: 112, + y: -290 + }, + { + x: 112, + y: -354 + } + ], + textPositions: { + 0: { + x: 124, + y: 76 + }, + 1: { + x: 100, + y: 48 + }, + 2: { + x: 100, + y: -336 + }, + 3: { + x: 124, + y: -308 + }, + 4: { + x: 100, + y: -130 + }, + 5: { + x: 100, + y: -130 + }, + 6: { + x: 124, + y: -130 + } + } + }, + warnings: null + }, + { + id: 659, + sourceNodeId: 144, + sourcePortId: 1333, + targetNodeId: 145, + targetPortId: 1334, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 253 + }, + sourceArrival: { + lock: false, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 47 + }, + targetDeparture: { + lock: false, + time: 41, + warning: null, + timeFormatter: null, + consecutiveTime: 41 + }, + targetArrival: { + lock: false, + time: 19, + warning: null, + timeFormatter: null, + consecutiveTime: 259 + }, + numberOfStops: 0, + trainrunId: 96, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 176, + y: -450 + }, + { + x: 176, + y: -514 + }, + { + x: 176, + y: -798 + }, + { + x: 176, + y: -862 + } + ], + textPositions: { + 0: { + x: 188, + y: -468 + }, + 1: { + x: 164, + y: -496 + }, + 2: { + x: 164, + y: -844 + }, + 3: { + x: 188, + y: -816 + }, + 4: { + x: 164, + y: -656 + }, + 5: { + x: 164, + y: -656 + }, + 6: { + x: 188, + y: -656 + } + } + }, + warnings: null + }, + { + id: 660, + sourceNodeId: 145, + sourcePortId: 1335, + targetNodeId: 146, + targetPortId: 1336, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 19, + warning: null, + timeFormatter: null, + consecutiveTime: 259 + }, + sourceArrival: { + lock: false, + time: 41, + warning: null, + timeFormatter: null, + consecutiveTime: 41 + }, + targetDeparture: { + lock: false, + time: 35, + warning: null, + timeFormatter: null, + consecutiveTime: 35 + }, + targetArrival: { + lock: false, + time: 25, + warning: null, + timeFormatter: null, + consecutiveTime: 265 + }, + numberOfStops: 0, + trainrunId: 96, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 176, + y: -930 + }, + { + x: 176, + y: -994 + }, + { + x: 176, + y: -1278 + }, + { + x: 176, + y: -1342 + } + ], + textPositions: { + 0: { + x: 188, + y: -948 + }, + 1: { + x: 164, + y: -976 + }, + 2: { + x: 164, + y: -1324 + }, + 3: { + x: 188, + y: -1296 + }, + 4: { + x: 164, + y: -1136 + }, + 5: { + x: 164, + y: -1136 + }, + 6: { + x: 188, + y: -1136 + } + } + }, + warnings: null + }, + { + id: 661, + sourceNodeId: 146, + sourcePortId: 1337, + targetNodeId: 134, + targetPortId: 1338, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 25, + warning: null, + timeFormatter: null, + consecutiveTime: 265 + }, + sourceArrival: { + lock: false, + time: 35, + warning: null, + timeFormatter: null, + consecutiveTime: 35 + }, + targetDeparture: { + lock: true, + time: 28, + warning: null, + timeFormatter: null, + consecutiveTime: 28 + }, + targetArrival: { + lock: true, + time: 32, + warning: null, + timeFormatter: null, + consecutiveTime: 272 + }, + numberOfStops: 0, + trainrunId: 96, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 176, + y: -1410 + }, + { + x: 176, + y: -1474 + }, + { + x: 176, + y: -1758 + }, + { + x: 176, + y: -1822 + } + ], + textPositions: { + 0: { + x: 188, + y: -1428 + }, + 1: { + x: 164, + y: -1456 + }, + 2: { + x: 164, + y: -1804 + }, + 3: { + x: 188, + y: -1776 + }, + 4: { + x: 164, + y: -1616 + }, + 5: { + x: 164, + y: -1616 + }, + 6: { + x: 188, + y: -1616 + } + } + }, + warnings: null + }, + { + id: 662, + sourceNodeId: 129, + sourcePortId: 1339, + targetNodeId: 167, + targetPortId: 1340, + travelTime: { + lock: false, + time: 19, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 368 + }, + sourceArrival: { + lock: true, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 52 + }, + targetDeparture: { + lock: true, + time: 33, + warning: null, + timeFormatter: null, + consecutiveTime: 33 + }, + targetArrival: { + lock: true, + time: 27, + warning: null, + timeFormatter: null, + consecutiveTime: 387 + }, + numberOfStops: 0, + trainrunId: 90, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2032, + y: 382 + }, + { + x: -2032, + y: 446 + }, + { + x: -2032, + y: 574 + }, + { + x: -2032, + y: 638 + } + ], + textPositions: { + 0: { + x: -2044, + y: 400 + }, + 1: { + x: -2020, + y: 428 + }, + 2: { + x: -2020, + y: 620 + }, + 3: { + x: -2044, + y: 592 + }, + 4: { + x: -2044, + y: 510 + }, + 5: { + x: -2044, + y: 510 + }, + 6: { + x: -2020, + y: 510 + } + } + }, + warnings: null + }, + { + id: 663, + sourceNodeId: 167, + sourcePortId: 1341, + targetNodeId: 168, + targetPortId: 1342, + travelTime: { + lock: true, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 28, + warning: null, + timeFormatter: null, + consecutiveTime: 388 + }, + sourceArrival: { + lock: false, + time: 32, + warning: null, + timeFormatter: null, + consecutiveTime: 32 + }, + targetDeparture: { + lock: true, + time: 22, + warning: null, + timeFormatter: null, + consecutiveTime: 22 + }, + targetArrival: { + lock: true, + time: 38, + warning: null, + timeFormatter: null, + consecutiveTime: 398 + }, + numberOfStops: 0, + trainrunId: 90, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2032, + y: 706 + }, + { + x: -2032, + y: 770 + }, + { + x: -2032, + y: 862 + }, + { + x: -2032, + y: 926 + } + ], + textPositions: { + 0: { + x: -2044, + y: 724 + }, + 1: { + x: -2020, + y: 752 + }, + 2: { + x: -2020, + y: 908 + }, + 3: { + x: -2044, + y: 880 + }, + 4: { + x: -2044, + y: 816 + }, + 5: { + x: -2044, + y: 816 + }, + 6: { + x: -2020, + y: 816 + } + } + }, + warnings: null + }, + { + id: 664, + sourceNodeId: 168, + sourcePortId: 1343, + targetNodeId: 131, + targetPortId: 1344, + travelTime: { + lock: true, + time: 21, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 39, + warning: null, + timeFormatter: null, + consecutiveTime: 399 + }, + sourceArrival: { + lock: true, + time: 21, + warning: null, + timeFormatter: null, + consecutiveTime: 21 + }, + targetDeparture: { + lock: false, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 0 + }, + targetArrival: { + lock: false, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 420 + }, + numberOfStops: 0, + trainrunId: 90, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2014, + y: 976 + }, + { + x: -1950, + y: 976 + }, + { + x: -1154, + y: 976 + }, + { + x: -1090, + y: 976 + } + ], + textPositions: { + 0: { + x: -1996, + y: 988 + }, + 1: { + x: -1968, + y: 964 + }, + 2: { + x: -1108, + y: 964 + }, + 3: { + x: -1136, + y: 988 + }, + 4: { + x: -1552, + y: 964 + }, + 5: { + x: -1552, + y: 964 + }, + 6: { + x: -1552, + y: 988 + } + } + }, + warnings: null + }, + { + id: 665, + sourceNodeId: 169, + sourcePortId: 1345, + targetNodeId: 153, + targetPortId: 1346, + travelTime: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 48, + warning: null, + timeFormatter: null, + consecutiveTime: 48 + }, + sourceArrival: { + lock: true, + time: 12, + warning: null, + timeFormatter: null, + consecutiveTime: 252 + }, + targetDeparture: { + lock: true, + time: 3, + warning: null, + timeFormatter: null, + consecutiveTime: 243 + }, + targetArrival: { + lock: true, + time: 57, + warning: null, + timeFormatter: null, + consecutiveTime: 57 + }, + numberOfStops: 0, + trainrunId: 79, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1954, + y: 1776 + }, + { + x: 2018, + y: 1776 + }, + { + x: 2590, + y: 1360 + }, + { + x: 2654, + y: 1360 + } + ], + textPositions: { + 0: { + x: 1972, + y: 1788 + }, + 1: { + x: 2000, + y: 1764 + }, + 2: { + x: 2636, + y: 1348 + }, + 3: { + x: 2608, + y: 1372 + }, + 4: { + x: 2304, + y: 1556 + }, + 5: { + x: 2304, + y: 1556 + }, + 6: { + x: 2304, + y: 1580 + } + } + }, + warnings: null + }, + { + id: 666, + sourceNodeId: 169, + sourcePortId: 1347, + targetNodeId: 153, + targetPortId: 1348, + travelTime: { + lock: true, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 18 + }, + sourceArrival: { + lock: false, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 42 + }, + targetDeparture: { + lock: false, + time: 32, + warning: null, + timeFormatter: null, + consecutiveTime: 32 + }, + targetArrival: { + lock: false, + time: 28, + warning: null, + timeFormatter: null, + consecutiveTime: 28 + }, + numberOfStops: 0, + trainrunId: 80, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1954, + y: 1744 + }, + { + x: 2018, + y: 1744 + }, + { + x: 2590, + y: 1328 + }, + { + x: 2654, + y: 1328 + } + ], + textPositions: { + 0: { + x: 1972, + y: 1756 + }, + 1: { + x: 2000, + y: 1732 + }, + 2: { + x: 2636, + y: 1316 + }, + 3: { + x: 2608, + y: 1340 + }, + 4: { + x: 2304, + y: 1524 + }, + 5: { + x: 2304, + y: 1524 + }, + 6: { + x: 2304, + y: 1548 + } + } + }, + warnings: null + }, + { + id: 667, + sourceNodeId: 169, + sourcePortId: 1349, + targetNodeId: 142, + targetPortId: 1350, + travelTime: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 33, + warning: null, + timeFormatter: null, + consecutiveTime: 453 + }, + sourceArrival: { + lock: false, + time: 27, + warning: null, + timeFormatter: null, + consecutiveTime: 147 + }, + targetDeparture: { + lock: false, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 138 + }, + targetArrival: { + lock: false, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 462 + }, + numberOfStops: 0, + trainrunId: 77, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1854, + y: 1776 + }, + { + x: 1790, + y: 1776 + }, + { + x: 290, + y: 1776 + }, + { + x: 226, + y: 1776 + } + ], + textPositions: { + 0: { + x: 1836, + y: 1764 + }, + 1: { + x: 1808, + y: 1788 + }, + 2: { + x: 244, + y: 1788 + }, + 3: { + x: 272, + y: 1764 + }, + 4: { + x: 1040, + y: 1764 + }, + 5: { + x: 1040, + y: 1764 + }, + 6: { + x: 1040, + y: 1788 + } + } + }, + warnings: null + }, + { + id: 668, + sourceNodeId: 169, + sourcePortId: 1351, + targetNodeId: 142, + targetPortId: 1352, + travelTime: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 33, + warning: null, + timeFormatter: null, + consecutiveTime: 273 + }, + sourceArrival: { + lock: false, + time: 27, + warning: null, + timeFormatter: null, + consecutiveTime: 87 + }, + targetDeparture: { + lock: true, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 78 + }, + targetArrival: { + lock: true, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 282 + }, + numberOfStops: 0, + trainrunId: 75, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1854, + y: 1744 + }, + { + x: 1790, + y: 1744 + }, + { + x: 290, + y: 1744 + }, + { + x: 226, + y: 1744 + } + ], + textPositions: { + 0: { + x: 1836, + y: 1732 + }, + 1: { + x: 1808, + y: 1756 + }, + 2: { + x: 244, + y: 1756 + }, + 3: { + x: 272, + y: 1732 + }, + 4: { + x: 1040, + y: 1732 + }, + 5: { + x: 1040, + y: 1732 + }, + 6: { + x: 1040, + y: 1756 + } + } + }, + warnings: null + }, + { + id: 669, + sourceNodeId: 170, + sourcePortId: 1353, + targetNodeId: 135, + targetPortId: 1354, + travelTime: { + lock: true, + time: 11, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 74 + }, + sourceArrival: { + lock: true, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 226 + }, + targetDeparture: { + lock: true, + time: 35, + warning: null, + timeFormatter: null, + consecutiveTime: 215 + }, + targetArrival: { + lock: true, + time: 25, + warning: null, + timeFormatter: null, + consecutiveTime: 85 + }, + numberOfStops: 0, + trainrunId: 79, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2832, + y: 734 + }, + { + x: 2832, + y: 670 + }, + { + x: 2832, + y: 414 + }, + { + x: 2832, + y: 350 + } + ], + textPositions: { + 0: { + x: 2844, + y: 716 + }, + 1: { + x: 2820, + y: 688 + }, + 2: { + x: 2820, + y: 368 + }, + 3: { + x: 2844, + y: 396 + }, + 4: { + x: 2820, + y: 542 + }, + 5: { + x: 2820, + y: 542 + }, + 6: { + x: 2844, + y: 542 + } + } + }, + warnings: null + }, + { + id: 670, + sourceNodeId: 170, + sourcePortId: 1355, + targetNodeId: 135, + targetPortId: 1356, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 43 + }, + sourceArrival: { + lock: false, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 17 + }, + targetDeparture: { + lock: true, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 10 + }, + targetArrival: { + lock: true, + time: 50, + warning: null, + timeFormatter: null, + consecutiveTime: 50 + }, + numberOfStops: 0, + trainrunId: 80, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2800, + y: 734 + }, + { + x: 2800, + y: 670 + }, + { + x: 2800, + y: 414 + }, + { + x: 2800, + y: 350 + } + ], + textPositions: { + 0: { + x: 2812, + y: 716 + }, + 1: { + x: 2788, + y: 688 + }, + 2: { + x: 2788, + y: 368 + }, + 3: { + x: 2812, + y: 396 + }, + 4: { + x: 2788, + y: 542 + }, + 5: { + x: 2788, + y: 542 + }, + 6: { + x: 2812, + y: 542 + } + } + }, + warnings: null + }, + { + id: 671, + sourceNodeId: 170, + sourcePortId: 1357, + targetNodeId: 135, + targetPortId: 1358, + travelTime: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 347 + }, + sourceArrival: { + lock: false, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 13 + }, + targetDeparture: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 5 + }, + targetArrival: { + lock: true, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 355 + }, + numberOfStops: 0, + trainrunId: 78, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2768, + y: 734 + }, + { + x: 2768, + y: 670 + }, + { + x: 2768, + y: 414 + }, + { + x: 2768, + y: 350 + } + ], + textPositions: { + 0: { + x: 2780, + y: 716 + }, + 1: { + x: 2756, + y: 688 + }, + 2: { + x: 2756, + y: 368 + }, + 3: { + x: 2780, + y: 396 + }, + 4: { + x: 2756, + y: 542 + }, + 5: { + x: 2756, + y: 542 + }, + 6: { + x: 2780, + y: 542 + } + } + }, + warnings: null + }, + { + id: 672, + sourceNodeId: 170, + sourcePortId: 1359, + targetNodeId: 135, + targetPortId: 1360, + travelTime: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 107 + }, + sourceArrival: { + lock: false, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 13 + }, + targetDeparture: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 5 + }, + targetArrival: { + lock: true, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 115 + }, + numberOfStops: 0, + trainrunId: 76, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2672, + y: 734 + }, + { + x: 2672, + y: 670 + }, + { + x: 2672, + y: 414 + }, + { + x: 2672, + y: 350 + } + ], + textPositions: { + 0: { + x: 2684, + y: 716 + }, + 1: { + x: 2660, + y: 688 + }, + 2: { + x: 2660, + y: 368 + }, + 3: { + x: 2684, + y: 396 + }, + 4: { + x: 2660, + y: 542 + }, + 5: { + x: 2660, + y: 542 + }, + 6: { + x: 2684, + y: 542 + } + } + }, + warnings: null + }, + { + id: 673, + sourceNodeId: 170, + sourcePortId: 1361, + targetNodeId: 140, + targetPortId: 1362, + travelTime: { + lock: true, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 75 + }, + sourceArrival: { + lock: false, + time: 45, + warning: null, + timeFormatter: null, + consecutiveTime: 285 + }, + targetDeparture: { + lock: true, + time: 58, + warning: null, + timeFormatter: null, + consecutiveTime: 238 + }, + targetArrival: { + lock: true, + time: 2, + warning: null, + timeFormatter: null, + consecutiveTime: 122 + }, + numberOfStops: 0, + trainrunId: 85, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2850, + y: 752 + }, + { + x: 2914, + y: 752 + }, + { + x: 4574, + y: 1200 + }, + { + x: 4638, + y: 1200 + } + ], + textPositions: { + 0: { + x: 2868, + y: 764 + }, + 1: { + x: 2896, + y: 740 + }, + 2: { + x: 4620, + y: 1188 + }, + 3: { + x: 4592, + y: 1212 + }, + 4: { + x: 3744, + y: 964 + }, + 5: { + x: 3744, + y: 964 + }, + 6: { + x: 3744, + y: 988 + } + } + }, + warnings: null + }, + { + id: 674, + sourceNodeId: 170, + sourcePortId: 1363, + targetNodeId: 140, + targetPortId: 1364, + travelTime: { + lock: false, + time: 61, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 21, + warning: null, + timeFormatter: null, + consecutiveTime: 141 + }, + sourceArrival: { + lock: true, + time: 39, + warning: null, + timeFormatter: null, + consecutiveTime: 279 + }, + targetDeparture: { + lock: true, + time: 38, + warning: null, + timeFormatter: null, + consecutiveTime: 218 + }, + targetArrival: { + lock: true, + time: 22, + warning: null, + timeFormatter: null, + consecutiveTime: 202 + }, + numberOfStops: 5, + trainrunId: 86, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2850, + y: 784 + }, + { + x: 2914, + y: 784 + }, + { + x: 4574, + y: 1232 + }, + { + x: 4638, + y: 1232 + } + ], + textPositions: { + 0: { + x: 2868, + y: 796 + }, + 1: { + x: 2896, + y: 772 + }, + 2: { + x: 4620, + y: 1220 + }, + 3: { + x: 4592, + y: 1244 + }, + 4: { + x: 3744, + y: 996 + }, + 5: { + x: 3744, + y: 996 + }, + 6: { + x: 3744, + y: 1020 + } + } + }, + warnings: null + }, + { + id: 675, + sourceNodeId: 142, + sourcePortId: 1365, + targetNodeId: 141, + targetPortId: 1366, + travelTime: { + lock: true, + time: 19, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 475 + }, + sourceArrival: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 125 + }, + targetDeparture: { + lock: false, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 106 + }, + targetArrival: { + lock: false, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 494 + }, + numberOfStops: 0, + trainrunId: 77, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 144, + y: 1726 + }, + { + x: 144, + y: 1662 + }, + { + x: 144, + y: 1314 + }, + { + x: 144, + y: 1250 + } + ], + textPositions: { + 0: { + x: 156, + y: 1708 + }, + 1: { + x: 132, + y: 1680 + }, + 2: { + x: 132, + y: 1268 + }, + 3: { + x: 156, + y: 1296 + }, + 4: { + x: 132, + y: 1488 + }, + 5: { + x: 132, + y: 1488 + }, + 6: { + x: 156, + y: 1488 + } + } + }, + warnings: null + }, + { + id: 676, + sourceNodeId: 141, + sourcePortId: 1367, + targetNodeId: 143, + targetPortId: 1368, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 494 + }, + sourceArrival: { + lock: false, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 106 + }, + targetDeparture: { + lock: false, + time: 39, + warning: null, + timeFormatter: null, + consecutiveTime: 99 + }, + targetArrival: { + lock: false, + time: 21, + warning: null, + timeFormatter: null, + consecutiveTime: 501 + }, + numberOfStops: 0, + trainrunId: 77, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 144, + y: 1182 + }, + { + x: 144, + y: 1118 + }, + { + x: 144, + y: 866 + }, + { + x: 144, + y: 802 + } + ], + textPositions: { + 0: { + x: 156, + y: 1164 + }, + 1: { + x: 132, + y: 1136 + }, + 2: { + x: 132, + y: 820 + }, + 3: { + x: 156, + y: 848 + }, + 4: { + x: 132, + y: 992 + }, + 5: { + x: 132, + y: 992 + }, + 6: { + x: 156, + y: 992 + } + } + }, + warnings: null + }, + { + id: 677, + sourceNodeId: 143, + sourcePortId: 1369, + targetNodeId: 133, + targetPortId: 1370, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 503 + }, + sourceArrival: { + lock: false, + time: 37, + warning: null, + timeFormatter: null, + consecutiveTime: 97 + }, + targetDeparture: { + lock: false, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 90 + }, + targetArrival: { + lock: false, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 510 + }, + numberOfStops: 0, + trainrunId: 77, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 112, + y: 734 + }, + { + x: 112, + y: 670 + }, + { + x: 112, + y: 414 + }, + { + x: 112, + y: 350 + } + ], + textPositions: { + 0: { + x: 124, + y: 716 + }, + 1: { + x: 100, + y: 688 + }, + 2: { + x: 100, + y: 368 + }, + 3: { + x: 124, + y: 396 + }, + 4: { + x: 100, + y: 542 + }, + 5: { + x: 100, + y: 542 + }, + 6: { + x: 124, + y: 542 + } + } + }, + warnings: null + }, + { + id: 678, + sourceNodeId: 133, + sourcePortId: 1371, + targetNodeId: 144, + targetPortId: 1372, + travelTime: { + lock: true, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 32, + warning: null, + timeFormatter: null, + consecutiveTime: 512 + }, + sourceArrival: { + lock: true, + time: 28, + warning: null, + timeFormatter: null, + consecutiveTime: 88 + }, + targetDeparture: { + lock: false, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 78 + }, + targetArrival: { + lock: false, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 522 + }, + numberOfStops: 0, + trainrunId: 77, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 176, + y: 94 + }, + { + x: 176, + y: 30 + }, + { + x: 176, + y: -290 + }, + { + x: 176, + y: -354 + } + ], + textPositions: { + 0: { + x: 188, + y: 76 + }, + 1: { + x: 164, + y: 48 + }, + 2: { + x: 164, + y: -336 + }, + 3: { + x: 188, + y: -308 + }, + 4: { + x: 164, + y: -130 + }, + 5: { + x: 164, + y: -130 + }, + 6: { + x: 188, + y: -130 + } + } + }, + warnings: null + }, + { + id: 679, + sourceNodeId: 144, + sourcePortId: 1373, + targetNodeId: 145, + targetPortId: 1374, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 522 + }, + sourceArrival: { + lock: false, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 78 + }, + targetDeparture: { + lock: false, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 73 + }, + targetArrival: { + lock: false, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 527 + }, + numberOfStops: 0, + trainrunId: 77, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 240, + y: -450 + }, + { + x: 240, + y: -514 + }, + { + x: 240, + y: -798 + }, + { + x: 240, + y: -862 + } + ], + textPositions: { + 0: { + x: 252, + y: -468 + }, + 1: { + x: 228, + y: -496 + }, + 2: { + x: 228, + y: -844 + }, + 3: { + x: 252, + y: -816 + }, + 4: { + x: 228, + y: -656 + }, + 5: { + x: 228, + y: -656 + }, + 6: { + x: 252, + y: -656 + } + } + }, + warnings: null + }, + { + id: 680, + sourceNodeId: 145, + sourcePortId: 1375, + targetNodeId: 146, + targetPortId: 1376, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 527 + }, + sourceArrival: { + lock: false, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 73 + }, + targetDeparture: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 68 + }, + targetArrival: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 532 + }, + numberOfStops: 0, + trainrunId: 77, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 240, + y: -930 + }, + { + x: 240, + y: -994 + }, + { + x: 240, + y: -1278 + }, + { + x: 240, + y: -1342 + } + ], + textPositions: { + 0: { + x: 252, + y: -948 + }, + 1: { + x: 228, + y: -976 + }, + 2: { + x: 228, + y: -1324 + }, + 3: { + x: 252, + y: -1296 + }, + 4: { + x: 228, + y: -1136 + }, + 5: { + x: 228, + y: -1136 + }, + 6: { + x: 252, + y: -1136 + } + } + }, + warnings: null + }, + { + id: 681, + sourceNodeId: 146, + sourcePortId: 1377, + targetNodeId: 134, + targetPortId: 1378, + travelTime: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 532 + }, + sourceArrival: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 68 + }, + targetDeparture: { + lock: true, + time: 3, + warning: null, + timeFormatter: null, + consecutiveTime: 63 + }, + targetArrival: { + lock: true, + time: 57, + warning: null, + timeFormatter: null, + consecutiveTime: 537 + }, + numberOfStops: 0, + trainrunId: 77, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 240, + y: -1410 + }, + { + x: 240, + y: -1474 + }, + { + x: 240, + y: -1758 + }, + { + x: 240, + y: -1822 + } + ], + textPositions: { + 0: { + x: 252, + y: -1428 + }, + 1: { + x: 228, + y: -1456 + }, + 2: { + x: 228, + y: -1804 + }, + 3: { + x: 252, + y: -1776 + }, + 4: { + x: 228, + y: -1616 + }, + 5: { + x: 228, + y: -1616 + }, + 6: { + x: 252, + y: -1616 + } + } + }, + warnings: null + }, + { + id: 682, + sourceNodeId: 171, + sourcePortId: 1379, + targetNodeId: 128, + targetPortId: 1380, + travelTime: { + lock: false, + time: 49, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 27, + warning: null, + timeFormatter: null, + consecutiveTime: 387 + }, + sourceArrival: { + lock: true, + time: 33, + warning: null, + timeFormatter: null, + consecutiveTime: 153 + }, + targetDeparture: { + lock: true, + time: 44, + warning: null, + timeFormatter: null, + consecutiveTime: 104 + }, + targetArrival: { + lock: true, + time: 16, + warning: null, + timeFormatter: null, + consecutiveTime: 436 + }, + numberOfStops: 2, + trainrunId: 81, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2562, + y: 336 + }, + { + x: -2626, + y: 336 + }, + { + x: -2910, + y: 592 + }, + { + x: -2974, + y: 592 + } + ], + textPositions: { + 0: { + x: -2580, + y: 324 + }, + 1: { + x: -2608, + y: 348 + }, + 2: { + x: -2956, + y: 604 + }, + 3: { + x: -2928, + y: 580 + }, + 4: { + x: -2768, + y: 452 + }, + 5: { + x: -2768, + y: 452 + }, + 6: { + x: -2768, + y: 476 + } + } + }, + warnings: null + }, + { + id: 683, + sourceNodeId: 171, + sourcePortId: 1381, + targetNodeId: 128, + targetPortId: 1382, + travelTime: { + lock: true, + time: 44, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 54, + warning: null, + timeFormatter: null, + consecutiveTime: 414 + }, + sourceArrival: { + lock: false, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 126 + }, + targetDeparture: { + lock: false, + time: 22, + warning: null, + timeFormatter: null, + consecutiveTime: 82 + }, + targetArrival: { + lock: false, + time: 38, + warning: null, + timeFormatter: null, + consecutiveTime: 458 + }, + numberOfStops: 0, + trainrunId: 88, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -2562, + y: 304 + }, + { + x: -2626, + y: 304 + }, + { + x: -2910, + y: 560 + }, + { + x: -2974, + y: 560 + } + ], + textPositions: { + 0: { + x: -2580, + y: 292 + }, + 1: { + x: -2608, + y: 316 + }, + 2: { + x: -2956, + y: 572 + }, + 3: { + x: -2928, + y: 548 + }, + 4: { + x: -2768, + y: 420 + }, + 5: { + x: -2768, + y: 420 + }, + 6: { + x: -2768, + y: 444 + } + } + }, + warnings: null + }, + { + id: 684, + sourceNodeId: 172, + sourcePortId: 1383, + targetNodeId: 178, + targetPortId: 1384, + travelTime: { + lock: true, + time: 16, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 39, + warning: null, + timeFormatter: null, + consecutiveTime: 339 + }, + sourceArrival: { + lock: false, + time: 21, + warning: null, + timeFormatter: null, + consecutiveTime: 201 + }, + targetDeparture: { + lock: false, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 185 + }, + targetArrival: { + lock: false, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 355 + }, + numberOfStops: 0, + trainrunId: 81, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -610, + y: 304 + }, + { + x: -674, + y: 304 + }, + { + x: -1534, + y: 304 + }, + { + x: -1598, + y: 304 + } + ], + textPositions: { + 0: { + x: -628, + y: 292 + }, + 1: { + x: -656, + y: 316 + }, + 2: { + x: -1580, + y: 316 + }, + 3: { + x: -1552, + y: 292 + }, + 4: { + x: -1104, + y: 292 + }, + 5: { + x: -1104, + y: 292 + }, + 6: { + x: -1104, + y: 316 + } + } + }, + warnings: null + }, + { + id: 685, + sourceNodeId: 172, + sourcePortId: 1385, + targetNodeId: 174, + targetPortId: 1386, + travelTime: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 343 + }, + sourceArrival: { + lock: false, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 77 + }, + targetDeparture: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 69 + }, + targetArrival: { + lock: true, + time: 51, + warning: null, + timeFormatter: null, + consecutiveTime: 351 + }, + numberOfStops: 0, + trainrunId: 86, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -610, + y: 336 + }, + { + x: -674, + y: 336 + }, + { + x: -830, + y: 368 + }, + { + x: -894, + y: 368 + } + ], + textPositions: { + 0: { + x: -628, + y: 324 + }, + 1: { + x: -656, + y: 348 + }, + 2: { + x: -876, + y: 380 + }, + 3: { + x: -848, + y: 356 + }, + 4: { + x: -752, + y: 340 + }, + 5: { + x: -752, + y: 340 + }, + 6: { + x: -752, + y: 364 + } + } + }, + warnings: null + }, + { + id: 686, + sourceNodeId: 172, + sourcePortId: 1387, + targetNodeId: 178, + targetPortId: 1388, + travelTime: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 47, + warning: null, + timeFormatter: null, + consecutiveTime: 347 + }, + sourceArrival: { + lock: false, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 73 + }, + targetDeparture: { + lock: false, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 65 + }, + targetArrival: { + lock: false, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 355 + }, + numberOfStops: 0, + trainrunId: 90, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -610, + y: 272 + }, + { + x: -674, + y: 272 + }, + { + x: -1534, + y: 272 + }, + { + x: -1598, + y: 272 + } + ], + textPositions: { + 0: { + x: -628, + y: 260 + }, + 1: { + x: -656, + y: 284 + }, + 2: { + x: -1580, + y: 284 + }, + 3: { + x: -1552, + y: 260 + }, + 4: { + x: -1104, + y: 260 + }, + 5: { + x: -1104, + y: 260 + }, + 6: { + x: -1104, + y: 284 + } + } + }, + warnings: null + }, + { + id: 687, + sourceNodeId: 172, + sourcePortId: 1389, + targetNodeId: 178, + targetPortId: 1390, + travelTime: { + lock: false, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 37, + warning: null, + timeFormatter: null, + consecutiveTime: 337 + }, + sourceArrival: { + lock: false, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 83 + }, + targetDeparture: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 66 + }, + targetArrival: { + lock: true, + time: 54, + warning: null, + timeFormatter: null, + consecutiveTime: 354 + }, + numberOfStops: 0, + trainrunId: 89, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -610, + y: 240 + }, + { + x: -674, + y: 240 + }, + { + x: -1534, + y: 240 + }, + { + x: -1598, + y: 240 + } + ], + textPositions: { + 0: { + x: -628, + y: 228 + }, + 1: { + x: -656, + y: 252 + }, + 2: { + x: -1580, + y: 252 + }, + 3: { + x: -1552, + y: 228 + }, + 4: { + x: -1104, + y: 228 + }, + 5: { + x: -1104, + y: 228 + }, + 6: { + x: -1104, + y: 252 + } + } + }, + warnings: null + }, + { + id: 688, + sourceNodeId: 172, + sourcePortId: 1391, + targetNodeId: 178, + targetPortId: 1392, + travelTime: { + lock: true, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 65 + }, + sourceArrival: { + lock: false, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 235 + }, + targetDeparture: { + lock: false, + time: 37, + warning: null, + timeFormatter: null, + consecutiveTime: 217 + }, + targetArrival: { + lock: false, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 83 + }, + numberOfStops: 0, + trainrunId: 95, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -610, + y: 208 + }, + { + x: -674, + y: 208 + }, + { + x: -1534, + y: 208 + }, + { + x: -1598, + y: 208 + } + ], + textPositions: { + 0: { + x: -628, + y: 196 + }, + 1: { + x: -656, + y: 220 + }, + 2: { + x: -1580, + y: 220 + }, + 3: { + x: -1552, + y: 196 + }, + 4: { + x: -1104, + y: 196 + }, + 5: { + x: -1104, + y: 196 + }, + 6: { + x: -1104, + y: 220 + } + } + }, + warnings: null + }, + { + id: 689, + sourceNodeId: 172, + sourcePortId: 1393, + targetNodeId: 133, + targetPortId: 1394, + travelTime: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 54, + warning: null, + timeFormatter: null, + consecutiveTime: 234 + }, + sourceArrival: { + lock: false, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 66 + }, + targetDeparture: { + lock: true, + time: 58, + warning: null, + timeFormatter: null, + consecutiveTime: 58 + }, + targetArrival: { + lock: true, + time: 2, + warning: null, + timeFormatter: null, + consecutiveTime: 242 + }, + numberOfStops: 0, + trainrunId: 96, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -510, + y: 176 + }, + { + x: -446, + y: 176 + }, + { + x: -2, + y: 176 + }, + { + x: 62, + y: 176 + } + ], + textPositions: { + 0: { + x: -492, + y: 188 + }, + 1: { + x: -464, + y: 164 + }, + 2: { + x: 44, + y: 164 + }, + 3: { + x: 16, + y: 188 + }, + 4: { + x: -224, + y: 164 + }, + 5: { + x: -224, + y: 164 + }, + 6: { + x: -224, + y: 188 + } + } + }, + warnings: null + }, + { + id: 690, + sourceNodeId: 172, + sourcePortId: 1395, + targetNodeId: 178, + targetPortId: 1396, + travelTime: { + lock: true, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 377 + }, + sourceArrival: { + lock: false, + time: 43, + warning: null, + timeFormatter: null, + consecutiveTime: 163 + }, + targetDeparture: { + lock: false, + time: 34, + warning: null, + timeFormatter: null, + consecutiveTime: 154 + }, + targetArrival: { + lock: false, + time: 26, + warning: null, + timeFormatter: null, + consecutiveTime: 386 + }, + numberOfStops: 0, + trainrunId: 88, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -610, + y: 144 + }, + { + x: -674, + y: 144 + }, + { + x: -1534, + y: 144 + }, + { + x: -1598, + y: 144 + } + ], + textPositions: { + 0: { + x: -628, + y: 132 + }, + 1: { + x: -656, + y: 156 + }, + 2: { + x: -1580, + y: 156 + }, + 3: { + x: -1552, + y: 132 + }, + 4: { + x: -1104, + y: 132 + }, + 5: { + x: -1104, + y: 132 + }, + 6: { + x: -1104, + y: 156 + } + } + }, + warnings: null + }, + { + id: 691, + sourceNodeId: 173, + sourcePortId: 1397, + targetNodeId: 178, + targetPortId: 1398, + travelTime: { + lock: true, + time: 10, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 11, + warning: null, + timeFormatter: null, + consecutiveTime: 371 + }, + sourceArrival: { + lock: true, + time: 49, + warning: null, + timeFormatter: null, + consecutiveTime: 49 + }, + targetDeparture: { + lock: false, + time: 39, + warning: null, + timeFormatter: null, + consecutiveTime: 39 + }, + targetArrival: { + lock: false, + time: 21, + warning: null, + timeFormatter: null, + consecutiveTime: 381 + }, + numberOfStops: 0, + trainrunId: 86, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -1346, + y: 368 + }, + { + x: -1410, + y: 368 + }, + { + x: -1534, + y: 336 + }, + { + x: -1598, + y: 336 + } + ], + textPositions: { + 0: { + x: -1364, + y: 356 + }, + 1: { + x: -1392, + y: 380 + }, + 2: { + x: -1580, + y: 348 + }, + 3: { + x: -1552, + y: 324 + }, + 4: { + x: -1472, + y: 340 + }, + 5: { + x: -1472, + y: 340 + }, + 6: { + x: -1472, + y: 364 + } + } + }, + warnings: null + }, + { + id: 692, + sourceNodeId: 174, + sourcePortId: 1399, + targetNodeId: 173, + targetPortId: 1400, + travelTime: { + lock: true, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 352 + }, + sourceArrival: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 68 + }, + targetDeparture: { + lock: false, + time: 51, + warning: null, + timeFormatter: null, + consecutiveTime: 51 + }, + targetArrival: { + lock: false, + time: 9, + warning: null, + timeFormatter: null, + consecutiveTime: 369 + }, + numberOfStops: 1, + trainrunId: 86, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -994, + y: 368 + }, + { + x: -1058, + y: 368 + }, + { + x: -1182, + y: 368 + }, + { + x: -1246, + y: 368 + } + ], + textPositions: { + 0: { + x: -1012, + y: 356 + }, + 1: { + x: -1040, + y: 380 + }, + 2: { + x: -1228, + y: 380 + }, + 3: { + x: -1200, + y: 356 + }, + 4: { + x: -1120, + y: 356 + }, + 5: { + x: -1120, + y: 356 + }, + 6: { + x: -1120, + y: 380 + } + } + }, + warnings: null + }, + { + id: 693, + sourceNodeId: 135, + sourcePortId: 1401, + targetNodeId: 149, + targetPortId: 1402, + travelTime: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 300 + }, + sourceArrival: { + lock: true, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 60 + }, + targetDeparture: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 52 + }, + targetArrival: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 308 + }, + numberOfStops: 0, + trainrunId: 85, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2654, + y: 80 + }, + { + x: 2590, + y: 80 + }, + { + x: 2402, + y: 80 + }, + { + x: 2338, + y: 80 + } + ], + textPositions: { + 0: { + x: 2636, + y: 68 + }, + 1: { + x: 2608, + y: 92 + }, + 2: { + x: 2356, + y: 92 + }, + 3: { + x: 2384, + y: 68 + }, + 4: { + x: 2496, + y: 68 + }, + 5: { + x: 2496, + y: 68 + }, + 6: { + x: 2496, + y: 92 + } + } + }, + warnings: null + }, + { + id: 694, + sourceNodeId: 149, + sourcePortId: 1403, + targetNodeId: 166, + targetPortId: 1404, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 308 + }, + sourceArrival: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 52 + }, + targetDeparture: { + lock: false, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 46 + }, + targetArrival: { + lock: false, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 314 + }, + numberOfStops: 0, + trainrunId: 85, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 2238, + y: 80 + }, + { + x: 2174, + y: 80 + }, + { + x: 1954, + y: 80 + }, + { + x: 1890, + y: 80 + } + ], + textPositions: { + 0: { + x: 2220, + y: 68 + }, + 1: { + x: 2192, + y: 92 + }, + 2: { + x: 1908, + y: 92 + }, + 3: { + x: 1936, + y: 68 + }, + 4: { + x: 2064, + y: 68 + }, + 5: { + x: 2064, + y: 68 + }, + 6: { + x: 2064, + y: 92 + } + } + }, + warnings: null + }, + { + id: 695, + sourceNodeId: 166, + sourcePortId: 1405, + targetNodeId: 148, + targetPortId: 1406, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 314 + }, + sourceArrival: { + lock: false, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 46 + }, + targetDeparture: { + lock: false, + time: 40, + warning: null, + timeFormatter: null, + consecutiveTime: 40 + }, + targetArrival: { + lock: false, + time: 20, + warning: null, + timeFormatter: null, + consecutiveTime: 320 + }, + numberOfStops: 0, + trainrunId: 85, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1790, + y: 80 + }, + { + x: 1726, + y: 80 + }, + { + x: 1506, + y: 80 + }, + { + x: 1442, + y: 80 + } + ], + textPositions: { + 0: { + x: 1772, + y: 68 + }, + 1: { + x: 1744, + y: 92 + }, + 2: { + x: 1460, + y: 92 + }, + 3: { + x: 1488, + y: 68 + }, + 4: { + x: 1616, + y: 68 + }, + 5: { + x: 1616, + y: 68 + }, + 6: { + x: 1616, + y: 92 + } + } + }, + warnings: null + }, + { + id: 696, + sourceNodeId: 148, + sourcePortId: 1407, + targetNodeId: 147, + targetPortId: 1408, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 20, + warning: null, + timeFormatter: null, + consecutiveTime: 320 + }, + sourceArrival: { + lock: false, + time: 40, + warning: null, + timeFormatter: null, + consecutiveTime: 40 + }, + targetDeparture: { + lock: false, + time: 34, + warning: null, + timeFormatter: null, + consecutiveTime: 34 + }, + targetArrival: { + lock: false, + time: 26, + warning: null, + timeFormatter: null, + consecutiveTime: 326 + }, + numberOfStops: 0, + trainrunId: 85, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 1342, + y: 80 + }, + { + x: 1278, + y: 80 + }, + { + x: 1122, + y: 80 + }, + { + x: 1058, + y: 80 + } + ], + textPositions: { + 0: { + x: 1324, + y: 68 + }, + 1: { + x: 1296, + y: 92 + }, + 2: { + x: 1076, + y: 92 + }, + 3: { + x: 1104, + y: 68 + }, + 4: { + x: 1200, + y: 68 + }, + 5: { + x: 1200, + y: 68 + }, + 6: { + x: 1200, + y: 92 + } + } + }, + warnings: null + }, + { + id: 697, + sourceNodeId: 147, + sourcePortId: 1409, + targetNodeId: 144, + targetPortId: 1410, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 26, + warning: null, + timeFormatter: null, + consecutiveTime: 326 + }, + sourceArrival: { + lock: false, + time: 34, + warning: null, + timeFormatter: null, + consecutiveTime: 34 + }, + targetDeparture: { + lock: false, + time: 27, + warning: null, + timeFormatter: null, + consecutiveTime: 27 + }, + targetArrival: { + lock: false, + time: 33, + warning: null, + timeFormatter: null, + consecutiveTime: 333 + }, + numberOfStops: 0, + trainrunId: 85, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 958, + y: 48 + }, + { + x: 894, + y: 48 + }, + { + x: 386, + y: -432 + }, + { + x: 322, + y: -432 + } + ], + textPositions: { + 0: { + x: 940, + y: 36 + }, + 1: { + x: 912, + y: 60 + }, + 2: { + x: 340, + y: -420 + }, + 3: { + x: 368, + y: -444 + }, + 4: { + x: 640, + y: -204 + }, + 5: { + x: 640, + y: -204 + }, + 6: { + x: 640, + y: -180 + } + } + }, + warnings: null + }, + { + id: 698, + sourceNodeId: 144, + sourcePortId: 1411, + targetNodeId: 145, + targetPortId: 1412, + travelTime: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 33, + warning: null, + timeFormatter: null, + consecutiveTime: 333 + }, + sourceArrival: { + lock: false, + time: 27, + warning: null, + timeFormatter: null, + consecutiveTime: 27 + }, + targetDeparture: { + lock: false, + time: 21, + warning: null, + timeFormatter: null, + consecutiveTime: 21 + }, + targetArrival: { + lock: false, + time: 39, + warning: null, + timeFormatter: null, + consecutiveTime: 339 + }, + numberOfStops: 0, + trainrunId: 85, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 112, + y: -450 + }, + { + x: 112, + y: -514 + }, + { + x: 112, + y: -798 + }, + { + x: 112, + y: -862 + } + ], + textPositions: { + 0: { + x: 124, + y: -468 + }, + 1: { + x: 100, + y: -496 + }, + 2: { + x: 100, + y: -844 + }, + 3: { + x: 124, + y: -816 + }, + 4: { + x: 100, + y: -656 + }, + 5: { + x: 100, + y: -656 + }, + 6: { + x: 124, + y: -656 + } + } + }, + warnings: null + }, + { + id: 699, + sourceNodeId: 145, + sourcePortId: 1413, + targetNodeId: 146, + targetPortId: 1414, + travelTime: { + lock: true, + time: 7, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 39, + warning: null, + timeFormatter: null, + consecutiveTime: 339 + }, + sourceArrival: { + lock: false, + time: 21, + warning: null, + timeFormatter: null, + consecutiveTime: 21 + }, + targetDeparture: { + lock: false, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 14 + }, + targetArrival: { + lock: false, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 346 + }, + numberOfStops: 0, + trainrunId: 85, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 112, + y: -930 + }, + { + x: 112, + y: -994 + }, + { + x: 112, + y: -1278 + }, + { + x: 112, + y: -1342 + } + ], + textPositions: { + 0: { + x: 124, + y: -948 + }, + 1: { + x: 100, + y: -976 + }, + 2: { + x: 100, + y: -1324 + }, + 3: { + x: 124, + y: -1296 + }, + 4: { + x: 100, + y: -1136 + }, + 5: { + x: 100, + y: -1136 + }, + 6: { + x: 124, + y: -1136 + } + } + }, + warnings: null + }, + { + id: 700, + sourceNodeId: 146, + sourcePortId: 1415, + targetNodeId: 134, + targetPortId: 1416, + travelTime: { + lock: true, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 346 + }, + sourceArrival: { + lock: false, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 14 + }, + targetDeparture: { + lock: true, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 6 + }, + targetArrival: { + lock: true, + time: 54, + warning: null, + timeFormatter: null, + consecutiveTime: 354 + }, + numberOfStops: 0, + trainrunId: 85, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 112, + y: -1410 + }, + { + x: 112, + y: -1474 + }, + { + x: 112, + y: -1758 + }, + { + x: 112, + y: -1822 + } + ], + textPositions: { + 0: { + x: 124, + y: -1428 + }, + 1: { + x: 100, + y: -1456 + }, + 2: { + x: 100, + y: -1804 + }, + 3: { + x: 124, + y: -1776 + }, + 4: { + x: 100, + y: -1616 + }, + 5: { + x: 100, + y: -1616 + }, + 6: { + x: 124, + y: -1616 + } + } + }, + warnings: null + }, + { + id: 701, + sourceNodeId: 175, + sourcePortId: 1417, + targetNodeId: 130, + targetPortId: 1418, + travelTime: { + lock: true, + time: 13, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 1, + warning: null, + timeFormatter: null, + consecutiveTime: 421 + }, + sourceArrival: { + lock: true, + time: 59, + warning: null, + timeFormatter: null, + consecutiveTime: 119 + }, + targetDeparture: { + lock: true, + time: 46, + warning: null, + timeFormatter: null, + consecutiveTime: 106 + }, + targetArrival: { + lock: true, + time: 14, + warning: null, + timeFormatter: null, + consecutiveTime: 434 + }, + numberOfStops: 0, + trainrunId: 87, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -1698, + y: -16 + }, + { + x: -1762, + y: -16 + }, + { + x: -2366, + y: -16 + }, + { + x: -2430, + y: -16 + } + ], + textPositions: { + 0: { + x: -1716, + y: -28 + }, + 1: { + x: -1744, + y: -4 + }, + 2: { + x: -2412, + y: -4 + }, + 3: { + x: -2384, + y: -28 + }, + 4: { + x: -2064, + y: -28 + }, + 5: { + x: -2064, + y: -28 + }, + 6: { + x: -2064, + y: -4 + } + } + }, + warnings: null + }, + { + id: 702, + sourceNodeId: 137, + sourcePortId: 1419, + targetNodeId: 176, + targetPortId: 1420, + travelTime: { + lock: true, + time: 16, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 245 + }, + sourceArrival: { + lock: true, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 295 + }, + targetDeparture: { + lock: false, + time: 39, + warning: null, + timeFormatter: null, + consecutiveTime: 279 + }, + targetArrival: { + lock: false, + time: 21, + warning: null, + timeFormatter: null, + consecutiveTime: 261 + }, + numberOfStops: 0, + trainrunId: 87, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: 4738, + y: 112 + }, + { + x: 4802, + y: 112 + }, + { + x: 5310, + y: 112 + }, + { + x: 5374, + y: 112 + } + ], + textPositions: { + 0: { + x: 4756, + y: 124 + }, + 1: { + x: 4784, + y: 100 + }, + 2: { + x: 5356, + y: 100 + }, + 3: { + x: 5328, + y: 124 + }, + 4: { + x: 5056, + y: 100 + }, + 5: { + x: 5056, + y: 100 + }, + 6: { + x: 5056, + y: 124 + } + } + }, + warnings: null + }, + { + id: 703, + sourceNodeId: 177, + sourcePortId: 1421, + targetNodeId: 160, + targetPortId: 1422, + travelTime: { + lock: false, + time: 30, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: true, + time: 31, + warning: null, + timeFormatter: null, + consecutiveTime: 451 + }, + sourceArrival: { + lock: true, + time: 29, + warning: null, + timeFormatter: null, + consecutiveTime: 89 + }, + targetDeparture: { + lock: true, + time: 59, + warning: null, + timeFormatter: null, + consecutiveTime: 59 + }, + targetArrival: { + lock: true, + time: 1, + warning: null, + timeFormatter: null, + consecutiveTime: 481 + }, + numberOfStops: 1, + trainrunId: 81, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -3522, + y: 624 + }, + { + x: -3586, + y: 624 + }, + { + x: -3774, + y: 688 + }, + { + x: -3838, + y: 688 + } + ], + textPositions: { + 0: { + x: -3540, + y: 612 + }, + 1: { + x: -3568, + y: 636 + }, + 2: { + x: -3820, + y: 700 + }, + 3: { + x: -3792, + y: 676 + }, + 4: { + x: -3680, + y: 644 + }, + 5: { + x: -3680, + y: 644 + }, + 6: { + x: -3680, + y: 668 + } + } + }, + warnings: null + }, + { + id: 704, + sourceNodeId: 177, + sourcePortId: 1423, + targetNodeId: 160, + targetPortId: 1424, + travelTime: { + lock: true, + time: 26, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 52, + warning: null, + timeFormatter: null, + consecutiveTime: 472 + }, + sourceArrival: { + lock: false, + time: 8, + warning: null, + timeFormatter: null, + consecutiveTime: 68 + }, + targetDeparture: { + lock: true, + time: 42, + warning: null, + timeFormatter: null, + consecutiveTime: 42 + }, + targetArrival: { + lock: true, + time: 18, + warning: null, + timeFormatter: null, + consecutiveTime: 498 + }, + numberOfStops: 0, + trainrunId: 88, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -3522, + y: 560 + }, + { + x: -3586, + y: 560 + }, + { + x: -3774, + y: 624 + }, + { + x: -3838, + y: 624 + } + ], + textPositions: { + 0: { + x: -3540, + y: 548 + }, + 1: { + x: -3568, + y: 572 + }, + 2: { + x: -3820, + y: 636 + }, + 3: { + x: -3792, + y: 612 + }, + 4: { + x: -3680, + y: 580 + }, + 5: { + x: -3680, + y: 580 + }, + 6: { + x: -3680, + y: 604 + } + } + }, + warnings: null + }, + { + id: 705, + sourceNodeId: 177, + sourcePortId: 1425, + targetNodeId: 160, + targetPortId: 1426, + travelTime: { + lock: false, + time: 26, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 19, + warning: null, + timeFormatter: null, + consecutiveTime: 499 + }, + sourceArrival: { + lock: false, + time: 41, + warning: null, + timeFormatter: null, + consecutiveTime: 41 + }, + targetDeparture: { + lock: true, + time: 15, + warning: null, + timeFormatter: null, + consecutiveTime: 15 + }, + targetArrival: { + lock: true, + time: 45, + warning: null, + timeFormatter: null, + consecutiveTime: 525 + }, + numberOfStops: 0, + trainrunId: 87, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -3522, + y: 592 + }, + { + x: -3586, + y: 592 + }, + { + x: -3774, + y: 656 + }, + { + x: -3838, + y: 656 + } + ], + textPositions: { + 0: { + x: -3540, + y: 580 + }, + 1: { + x: -3568, + y: 604 + }, + 2: { + x: -3820, + y: 668 + }, + 3: { + x: -3792, + y: 644 + }, + 4: { + x: -3680, + y: 612 + }, + 5: { + x: -3680, + y: 612 + }, + 6: { + x: -3680, + y: 636 + } + } + }, + warnings: null + }, + { + id: 706, + sourceNodeId: 178, + sourcePortId: 1427, + targetNodeId: 129, + targetPortId: 1428, + travelTime: { + lock: true, + time: 3, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 21, + warning: null, + timeFormatter: null, + consecutiveTime: 381 + }, + sourceArrival: { + lock: false, + time: 39, + warning: null, + timeFormatter: null, + consecutiveTime: 39 + }, + targetDeparture: { + lock: true, + time: 36, + warning: null, + timeFormatter: null, + consecutiveTime: 36 + }, + targetArrival: { + lock: true, + time: 24, + warning: null, + timeFormatter: null, + consecutiveTime: 384 + }, + numberOfStops: 0, + trainrunId: 86, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -1698, + y: 336 + }, + { + x: -1762, + y: 336 + }, + { + x: -1950, + y: 336 + }, + { + x: -2014, + y: 336 + } + ], + textPositions: { + 0: { + x: -1716, + y: 324 + }, + 1: { + x: -1744, + y: 348 + }, + 2: { + x: -1996, + y: 348 + }, + 3: { + x: -1968, + y: 324 + }, + 4: { + x: -1856, + y: 324 + }, + 5: { + x: -1856, + y: 324 + }, + 6: { + x: -1856, + y: 348 + } + } + }, + warnings: null + }, + { + id: 707, + sourceNodeId: 178, + sourcePortId: 1429, + targetNodeId: 129, + targetPortId: 1430, + travelTime: { + lock: true, + time: 4, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 355 + }, + sourceArrival: { + lock: false, + time: 5, + warning: { + title: "Quelle Ankunft Warnung", + description: "Quellankunftszeit kann nicht erreicht werden" + }, + timeFormatter: null, + consecutiveTime: 185 + }, + targetDeparture: { + lock: true, + time: 0, + warning: null, + timeFormatter: null, + consecutiveTime: 180 + }, + targetArrival: { + lock: true, + time: 0, + warning: { + title: "Ziel Ankunft Warnung", + description: "Zielankunftszeit kann nicht erreicht werden" + }, + timeFormatter: null, + consecutiveTime: 360 + }, + numberOfStops: 0, + trainrunId: 81, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -1698, + y: 304 + }, + { + x: -1762, + y: 304 + }, + { + x: -1950, + y: 304 + }, + { + x: -2014, + y: 304 + } + ], + textPositions: { + 0: { + x: -1716, + y: 292 + }, + 1: { + x: -1744, + y: 316 + }, + 2: { + x: -1996, + y: 316 + }, + 3: { + x: -1968, + y: 292 + }, + 4: { + x: -1856, + y: 292 + }, + 5: { + x: -1856, + y: 292 + }, + 6: { + x: -1856, + y: 316 + } + } + }, + warnings: null + }, + { + id: 708, + sourceNodeId: 178, + sourcePortId: 1431, + targetNodeId: 129, + targetPortId: 1432, + travelTime: { + lock: true, + time: 3, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 55, + warning: null, + timeFormatter: null, + consecutiveTime: 355 + }, + sourceArrival: { + lock: false, + time: 5, + warning: null, + timeFormatter: null, + consecutiveTime: 65 + }, + targetDeparture: { + lock: false, + time: 2, + warning: null, + timeFormatter: null, + consecutiveTime: 62 + }, + targetArrival: { + lock: false, + time: 58, + warning: null, + timeFormatter: null, + consecutiveTime: 358 + }, + numberOfStops: 0, + trainrunId: 90, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -1698, + y: 272 + }, + { + x: -1762, + y: 272 + }, + { + x: -1950, + y: 272 + }, + { + x: -2014, + y: 272 + } + ], + textPositions: { + 0: { + x: -1716, + y: 260 + }, + 1: { + x: -1744, + y: 284 + }, + 2: { + x: -1996, + y: 284 + }, + 3: { + x: -1968, + y: 260 + }, + 4: { + x: -1856, + y: 260 + }, + 5: { + x: -1856, + y: 260 + }, + 6: { + x: -1856, + y: 284 + } + } + }, + warnings: null + }, + { + id: 709, + sourceNodeId: 178, + sourcePortId: 1433, + targetNodeId: 129, + targetPortId: 1434, + travelTime: { + lock: true, + time: 3, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 54, + warning: null, + timeFormatter: null, + consecutiveTime: 354 + }, + sourceArrival: { + lock: false, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 66 + }, + targetDeparture: { + lock: true, + time: 3, + warning: null, + timeFormatter: null, + consecutiveTime: 63 + }, + targetArrival: { + lock: true, + time: 57, + warning: null, + timeFormatter: null, + consecutiveTime: 357 + }, + numberOfStops: 0, + trainrunId: 89, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -1698, + y: 240 + }, + { + x: -1762, + y: 240 + }, + { + x: -1950, + y: 240 + }, + { + x: -2014, + y: 240 + } + ], + textPositions: { + 0: { + x: -1716, + y: 228 + }, + 1: { + x: -1744, + y: 252 + }, + 2: { + x: -1996, + y: 252 + }, + 3: { + x: -1968, + y: 228 + }, + 4: { + x: -1856, + y: 228 + }, + 5: { + x: -1856, + y: 228 + }, + 6: { + x: -1856, + y: 252 + } + } + }, + warnings: null + }, + { + id: 710, + sourceNodeId: 178, + sourcePortId: 1435, + targetNodeId: 129, + targetPortId: 1436, + travelTime: { + lock: true, + time: 3, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 83 + }, + sourceArrival: { + lock: false, + time: 37, + warning: null, + timeFormatter: null, + consecutiveTime: 217 + }, + targetDeparture: { + lock: true, + time: 34, + warning: null, + timeFormatter: null, + consecutiveTime: 214 + }, + targetArrival: { + lock: true, + time: 26, + warning: null, + timeFormatter: null, + consecutiveTime: 86 + }, + numberOfStops: 0, + trainrunId: 95, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -1698, + y: 208 + }, + { + x: -1762, + y: 208 + }, + { + x: -1950, + y: 208 + }, + { + x: -2014, + y: 208 + } + ], + textPositions: { + 0: { + x: -1716, + y: 196 + }, + 1: { + x: -1744, + y: 220 + }, + 2: { + x: -1996, + y: 220 + }, + 3: { + x: -1968, + y: 196 + }, + 4: { + x: -1856, + y: 196 + }, + 5: { + x: -1856, + y: 196 + }, + 6: { + x: -1856, + y: 220 + } + } + }, + warnings: null + }, + { + id: 711, + sourceNodeId: 178, + sourcePortId: 1437, + targetNodeId: 172, + targetPortId: 1438, + travelTime: { + lock: true, + time: 17, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 37, + warning: null, + timeFormatter: null, + consecutiveTime: 217 + }, + sourceArrival: { + lock: false, + time: 23, + warning: null, + timeFormatter: null, + consecutiveTime: 83 + }, + targetDeparture: { + lock: false, + time: 6, + warning: null, + timeFormatter: null, + consecutiveTime: 66 + }, + targetArrival: { + lock: false, + time: 54, + warning: null, + timeFormatter: null, + consecutiveTime: 234 + }, + numberOfStops: 0, + trainrunId: 96, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -1598, + y: 176 + }, + { + x: -1534, + y: 176 + }, + { + x: -674, + y: 176 + }, + { + x: -610, + y: 176 + } + ], + textPositions: { + 0: { + x: -1580, + y: 188 + }, + 1: { + x: -1552, + y: 164 + }, + 2: { + x: -628, + y: 164 + }, + 3: { + x: -656, + y: 188 + }, + 4: { + x: -1104, + y: 164 + }, + 5: { + x: -1104, + y: 164 + }, + 6: { + x: -1104, + y: 188 + } + } + }, + warnings: null + }, + { + id: 712, + sourceNodeId: 178, + sourcePortId: 1439, + targetNodeId: 129, + targetPortId: 1440, + travelTime: { + lock: true, + time: 3, + warning: null, + timeFormatter: null, + consecutiveTime: 1 + }, + sourceDeparture: { + lock: false, + time: 26, + warning: null, + timeFormatter: null, + consecutiveTime: 386 + }, + sourceArrival: { + lock: false, + time: 34, + warning: null, + timeFormatter: null, + consecutiveTime: 154 + }, + targetDeparture: { + lock: false, + time: 31, + warning: null, + timeFormatter: null, + consecutiveTime: 151 + }, + targetArrival: { + lock: false, + time: 29, + warning: null, + timeFormatter: null, + consecutiveTime: 389 + }, + numberOfStops: 0, + trainrunId: 88, + resourceId: 0, + specificTrainrunSectionFrequencyId: null, + path: { + path: [ + { + x: -1698, + y: 144 + }, + { + x: -1762, + y: 144 + }, + { + x: -1950, + y: 144 + }, + { + x: -2014, + y: 144 + } + ], + textPositions: { + 0: { + x: -1716, + y: 132 + }, + 1: { + x: -1744, + y: 156 + }, + 2: { + x: -1996, + y: 156 + }, + 3: { + x: -1968, + y: 132 + }, + 4: { + x: -1856, + y: 132 + }, + 5: { + x: -1856, + y: 132 + }, + 6: { + x: -1856, + y: 156 + } + } + }, + warnings: null + } + ], + trainruns: [ + { + id: 75, + name: "21", + categoryId: 1, + frequencyId: 4, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 76, + name: "2", + categoryId: 1, + frequencyId: 4, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 77, + name: "26", + categoryId: 2, + frequencyId: 5, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 78, + name: "46", + categoryId: 2, + frequencyId: 4, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 79, + name: "75", + categoryId: 2, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 80, + name: "70", + categoryId: 2, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 81, + name: "15", + categoryId: 2, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 82, + name: "27", + categoryId: 2, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 83, + name: "26", + categoryId: 2, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 84, + name: "13", + categoryId: 2, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 85, + name: "3", + categoryId: 1, + frequencyId: 4, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 86, + name: "35", + categoryId: 2, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 87, + name: "5", + categoryId: 1, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 88, + name: "1", + categoryId: 1, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 89, + name: "8", + categoryId: 1, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 90, + name: "81", + categoryId: 1, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 91, + name: "48", + categoryId: 2, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 1, + 9, + 5 + ] + }, + { + id: 92, + name: "", + categoryId: 1, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 1, + 9, + 5 + ] + }, + { + id: 93, + name: "36", + categoryId: 2, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 94, + name: "3", + categoryId: 1, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 95, + name: "61", + categoryId: 1, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 96, + name: "6", + categoryId: 1, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + }, + { + id: 97, + name: "37", + categoryId: 2, + frequencyId: 3, + trainrunTimeCategoryId: 0, + labelIds: [ + 3, + 8, + 4 + ] + } + ], + resources: [ + { + id: 88, + capacity: 2 + }, + { + id: 89, + capacity: 2 + }, + { + id: 90, + capacity: 2 + }, + { + id: 91, + capacity: 2 + }, + { + id: 92, + capacity: 2 + }, + { + id: 93, + capacity: 2 + }, + { + id: 94, + capacity: 2 + }, + { + id: 95, + capacity: 2 + }, + { + id: 96, + capacity: 2 + }, + { + id: 97, + capacity: 2 + }, + { + id: 98, + capacity: 2 + }, + { + id: 99, + capacity: 2 + }, + { + id: 100, + capacity: 2 + }, + { + id: 101, + capacity: 2 + }, + { + id: 102, + capacity: 2 + }, + { + id: 103, + capacity: 2 + }, + { + id: 104, + capacity: 2 + }, + { + id: 105, + capacity: 2 + }, + { + id: 106, + capacity: 2 + }, + { + id: 107, + capacity: 2 + }, + { + id: 108, + capacity: 2 + }, + { + id: 109, + capacity: 2 + }, + { + id: 110, + capacity: 2 + }, + { + id: 111, + capacity: 2 + }, + { + id: 112, + capacity: 2 + }, + { + id: 113, + capacity: 2 + }, + { + id: 114, + capacity: 2 + }, + { + id: 115, + capacity: 2 + }, + { + id: 116, + capacity: 2 + }, + { + id: 117, + capacity: 2 + }, + { + id: 118, + capacity: 2 + }, + { + id: 119, + capacity: 2 + }, + { + id: 120, + capacity: 2 + }, + { + id: 121, + capacity: 2 + }, + { + id: 122, + capacity: 2 + }, + { + id: 123, + capacity: 2 + }, + { + id: 124, + capacity: 2 + }, + { + id: 125, + capacity: 2 + }, + { + id: 126, + capacity: 2 + }, + { + id: 127, + capacity: 2 + }, + { + id: 128, + capacity: 2 + }, + { + id: 129, + capacity: 2 + }, + { + id: 130, + capacity: 2 + }, + { + id: 131, + capacity: 2 + }, + { + id: 132, + capacity: 2 + }, + { + id: 133, + capacity: 2 + }, + { + id: 134, + capacity: 2 + }, + { + id: 135, + capacity: 2 + }, + { + id: 136, + capacity: 2 + }, + { + id: 137, + capacity: 2 + }, + { + id: 138, + capacity: 2 + }, + { + id: 139, + capacity: 2 + }, + { + id: 140, + capacity: 2 + }, + { + id: 141, + capacity: 2 + }, + { + id: 142, + capacity: 2 + }, + { + id: 143, + capacity: 2 + }, + { + id: 144, + capacity: 2 + }, + { + id: 145, + capacity: 2 + }, + { + id: 146, + capacity: 2 + }, + { + id: 147, + capacity: 2 + }, + { + id: 148, + capacity: 2 + }, + { + id: 149, + capacity: 2 + }, + { + id: 150, + capacity: 2 + }, + { + id: 151, + capacity: 2 + }, + { + id: 152, + capacity: 2 + }, + { + id: 153, + capacity: 2 + }, + { + id: 154, + capacity: 2 + }, + { + id: 155, + capacity: 2 + }, + { + id: 156, + capacity: 2 + }, + { + id: 157, + capacity: 2 + }, + { + id: 158, + capacity: 2 + }, + { + id: 159, + capacity: 2 + }, + { + id: 160, + capacity: 2 + }, + { + id: 161, + capacity: 2 + }, + { + id: 162, + capacity: 2 + }, + { + id: 163, + capacity: 2 + }, + { + id: 164, + capacity: 2 + }, + { + id: 165, + capacity: 2 + }, + { + id: 166, + capacity: 2 + }, + { + id: 167, + capacity: 2 + }, + { + id: 168, + capacity: 2 + }, + { + id: 169, + capacity: 2 + }, + { + id: 170, + capacity: 2 + }, + { + id: 171, + capacity: 2 + }, + { + id: 172, + capacity: 2 + }, + { + id: 173, + capacity: 2 + }, + { + id: 174, + capacity: 2 + }, + { + id: 175, + capacity: 2 + }, + { + id: 176, + capacity: 2 + }, + { + id: 177, + capacity: 2 + }, + { + id: 178, + capacity: 2 + }, + { + id: 179, + capacity: 2 + }, + { + id: 180, + capacity: 2 + }, + { + id: 181, + capacity: 2 + }, + { + id: 182, + capacity: 2 + }, + { + id: 183, + capacity: 2 + }, + { + id: 184, + capacity: 2 + }, + { + id: 185, + capacity: 2 + }, + { + id: 186, + capacity: 2 + }, + { + id: 187, + capacity: 2 + }, + { + id: 188, + capacity: 2 + }, + { + id: 189, + capacity: 2 + }, + { + id: 190, + capacity: 2 + }, + { + id: 191, + capacity: 2 + }, + { + id: 192, + capacity: 2 + }, + { + id: 193, + capacity: 2 + }, + { + id: 194, + capacity: 2 + }, + { + id: 195, + capacity: 2 + }, + { + id: 196, + capacity: 2 + }, + { + id: 197, + capacity: 2 + }, + { + id: 198, + capacity: 2 + }, + { + id: 199, + capacity: 2 + }, + { + id: 200, + capacity: 2 + }, + { + id: 201, + capacity: 2 + }, + { + id: 202, + capacity: 2 + } + ], + metadata: { + analyticsSettings: { + originDestinationSettings: { + connectionPenalty: 5, + } + }, + trainrunCategories: [ + { + id: 0, + order: 0, + shortName: "EC", + name: "International", + colorRef: "EC", + fachCategory: HaltezeitFachCategories.IPV, + minimalTurnaroundTime: 4, + nodeHeadwayStop: 2, + nodeHeadwayNonStop: 2, + sectionHeadway: 2, + }, // -> Gruppe ROT + { + id: 1, + order: 1, + shortName: "IC", + name: "InterCity", + colorRef: "IC", + fachCategory: HaltezeitFachCategories.A, + minimalTurnaroundTime: 4, + nodeHeadwayStop: 2, + nodeHeadwayNonStop: 2, + sectionHeadway: 2, + }, // -> Gruppe ROT + { + id: 2, + order: 2, + shortName: "IR", + name: "InterRegio", + colorRef: "IR", + fachCategory: HaltezeitFachCategories.B, + minimalTurnaroundTime: 4, + nodeHeadwayStop: 2, + nodeHeadwayNonStop: 2, + sectionHeadway: 2, + }, // -> Gruppe BLAU + { + id: 3, + order: 3, + shortName: "RE", + name: "RegioExpress", + colorRef: "RE", + fachCategory: HaltezeitFachCategories.C, + minimalTurnaroundTime: 4, + nodeHeadwayStop: 2, + nodeHeadwayNonStop: 2, + sectionHeadway: 2, + }, // -> Gruppe GRÜN + { + id: 4, + order: 4, + shortName: "S", + name: "RegioUndSBahnverkehr", + colorRef: "S", + fachCategory: HaltezeitFachCategories.D, + minimalTurnaroundTime: 4, + nodeHeadwayStop: 2, + nodeHeadwayNonStop: 2, + sectionHeadway: 2, + }, // -> Gruppe SCHWARZ + { + id: 5, + order: 5, + shortName: "GEX", + name: "GüterExpress", + colorRef: "GEX", + fachCategory: HaltezeitFachCategories.Uncategorized, + minimalTurnaroundTime: 4, + nodeHeadwayStop: 3, + nodeHeadwayNonStop: 3, + sectionHeadway: 3, + }, // -> Gruppe BLAUVIOLETT + { + id: 6, + order: 6, + shortName: "G", + name: "Güterverkehr", + colorRef: "G", + fachCategory: HaltezeitFachCategories.Uncategorized, + minimalTurnaroundTime: 4, + nodeHeadwayStop: 3, + nodeHeadwayNonStop: 3, + sectionHeadway: 3, + }, // -> Gruppe BLAUVIOLETT + ], + trainrunFrequencies: [ + { + id: 0, + order: 0, + frequency: 15, + offset: 0, + shortName: "15", + name: "verkehrt viertelstündlich", + linePatternRef: LinePatternRefs.Freq15, + }, + { + id: 1, + order: 0, + frequency: 20, + offset: 0, + shortName: "20", + name: "verkehrt im 20 Minuten Takt", + linePatternRef: LinePatternRefs.Freq20, + }, + { + id: 2, + order: 0, + frequency: 30, + offset: 0, + shortName: "30", + name: "verkehrt halbstündlich", + linePatternRef: LinePatternRefs.Freq30, + }, + { + id: 3, + order: 0, + frequency: 60, + offset: 0, + shortName: "60", + name: "verkehrt stündlich", + linePatternRef: LinePatternRefs.Freq60, + }, + { + id: 4, + order: 0, + frequency: 120, + offset: 0, + shortName: "120", + name: "verkehrt zweistündlich (gerade)", + linePatternRef: LinePatternRefs.Freq120, + }, + { + id: 5, + order: 0, + frequency: 120, + offset: 60, + shortName: "120+", + name: "verkehrt zweistündlich (ungerade)", + linePatternRef: LinePatternRefs.Freq120, + }, + ], + trainrunTimeCategories: [ + { + id: 0, + order: 0, + shortName: "7/24", + name: "verkehrt uneingeschränkt", + dayTimeInterval: [], + weekday: [1, 2, 3, 4, 5, 6, 7], + linePatternRef: LinePatternRefs.TimeCat7_24, + }, + { + id: 1, + order: 0, + shortName: "HVZ", + name: "verkehrt zur Hauptverkehrszeit", + dayTimeInterval: [ + {from: 360, to: 420}, + {from: 960, to: 1140}, + ], + weekday: [1, 2, 3, 4, 5, 6, 7], + linePatternRef: LinePatternRefs.TimeCatHVZ, + }, + { + id: 2, + order: 0, + shortName: "zeitweise", + name: "verkehrt zeitweise", + dayTimeInterval: [], + weekday: [], + linePatternRef: LinePatternRefs.TimeZeitweise, + }, + ], + netzgrafikColors: [], + }, + freeFloatingTexts: [], + labels: [], + labelGroups: [], + filterData: { + filterSettings: [], + }, + }; } } From 3d2aebb84f5109198629faf27839371345755492 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 24 Oct 2024 16:31:18 +0200 Subject: [PATCH 149/197] Update the datamodel with information about trainrun iteration (#324) * Update the datamodel with information about trainrun iteration --- documentation/DATA_MODEL.md | 49 +++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/documentation/DATA_MODEL.md b/documentation/DATA_MODEL.md index 2d46e19b..9d6bf2d0 100644 --- a/documentation/DATA_MODEL.md +++ b/documentation/DATA_MODEL.md @@ -184,6 +184,55 @@ More details can be found in the source code: - [TrainrunSection.routeEdgeAndPlaceText()](./../src/app/models/trainrunsection.model.ts#:~:text=routeEdgeAndPlaceText()%20{) - [TrainrunSectionService.initializeTrainrunSectionRouting()](./../src/app/services/data/trainrunsection.service.ts#:~:text=initializeTrainrunSectionRouting()%20{) +--- + +### Trainrun Iteration +To understand how the trainrun iteration has to work, please take another look at this illustration: +![image](https://github.com/user-attachments/assets/21fdb029-2a59-468a-ac93-11cf702536bd) + +The [TrainrunIterator](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/d170955ecc466bfa9c10071927c63199eb7a86f7/src/app/services/util/trainrun.iterator.ts#L12) operates over a structure that can be conceptualized as an undirected acyclic graph (DAG), where each trainrun is a connected component. + +#### Structure + +- **TrainrunSection:** Each section has a source and a target node, analogous to an edge in a graph. The trainrun section is not directly connected to a node. It's connected via a port. +- **Node:** Nodes manage connections through ports, ports are effectively acting as a vertex within the graph. +- **Transition:** Transitions connect two train sections within a node with the help of ports. They can be interpreted as edges in the graph. + +#### Traversal +To initiate traversal, it is important to specify a location (node) where the traversal begins. To determine the traversal direction a trainrun section is required. The trainrun section must be connected to the node. Otherwise the traversal will fail. With the help of the trainrun section the traversal method determines the travel direction. Therefore, a tuple consisting of a node and a trainrun section is needed for each traversal. This tuple determines the directed edge in the directed graph. Each edge in a directed graph points to another node. For example, if the given node is the source node, the iterator moves towards the target node; if the node is the target node, the iterator moves towards the source node. This can be defined very simply using the tuple. + +Upon reaching a node, the transition is the object that determines the transition from the input port to the output port within the node. This is important to correctly determine the transition from the incoming trainrun section to the continuing trainrun section. Therefore, to continue traversing through the next section, a transition is needed. Once no transitions are available, the traversal stops. At that point, either the target node of the trainrun or, conversely, the starting node is found. + +The TrainrunIterator can effectively traverse through the trainrun sections by utilizing the source and target nodes of each section. This approach eliminates the need to explicitly maintain a direction in the data and is independent of the input (drawing direction). This allows everything to be kept very simple for the user. + +### TrainrunIterator + +The TrainrunIterator is a concept aimed at iterating through the sections of a trainrun, similar to how one navigates through the edges of a graph. Here is a detailed description of how this iterator works and how it can be used: + +#### Structure of the Trainrun +- **Graph**: The entire graph is generally an undirected acyclic graph (DAG). Each trainrun (segment) represents a connected component. + +#### Traversal Logic +- **Starting Point**: Iteration begins with a given node and a specific trainrun section. +- **Section Connection**: The iterator moves through connected sections by utilizing the source and target nodes of each section. +- **Transitions**: When a transition is reached, the next connected section is followed through the corresponding port. +- **End of Traversal**: Iteration ends when no further sections or transitions are available. + +#### Example Application +- **Initialization**: The iterator is initialized with a start node ID and a specific trainrun section. +- **Forward Traversal**: The iterator moves from section to section by navigating from one node to the next. During traversal, the source and target nodes of the sections are used to determine the path. +- **Backward Traversal**: To traverse in the opposite direction, the iterator can be re-initialized with the end node ID of the current traversal and the corresponding trainrun section. This reverses the path and allows a return to the starting point. + +#### Detailed Steps +1. **Start with a Node ID and a Trainrun Section**: The iterator begins with a defined node ID and a specific trainrun section. This represents the starting point. +2. **Section-wise Traversal**: The iterator traverses the sections by using the connections between the nodes. It moves from the source node to the target node of a section. +3. **Handling Transitions**: When a transition within a node is reached, the iterator follows the transition to the next connected section. +4. **Traversal End**: Iteration ends when no further connected sections or transitions are available. This signals the end of the trainrun. + +#### Summary +The TrainrunIterator enables structured traversal through the sections of a trainrun by using both a node ID and a specific trainrun section as a starting point. This increases the precision and flexibility of the traversal. By utilizing the source and target nodes of each section and following transitions within the nodes, the iterator can efficiently navigate through the entire trainrun. This method is particularly useful for traversing complex trainrun paths and ensuring that the traversal logic is correctly understood and applied both forwards and backwards. + +If functionality should be initiated by providing a port ID, this could be a further extension allowing a start directly from a specific port. However, this functionality is not yet implemented. --- From 132b37b1bc0372ff05119f5df4b4952f98f6a857 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 24 Oct 2024 16:33:28 +0200 Subject: [PATCH 150/197] Update DATA_MODEL.md --- documentation/DATA_MODEL.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/documentation/DATA_MODEL.md b/documentation/DATA_MODEL.md index 9d6bf2d0..5b080681 100644 --- a/documentation/DATA_MODEL.md +++ b/documentation/DATA_MODEL.md @@ -186,50 +186,53 @@ More details can be found in the source code: --- -### Trainrun Iteration +### Iterate through all trainrun section (forward/backward) To understand how the trainrun iteration has to work, please take another look at this illustration: ![image](https://github.com/user-attachments/assets/21fdb029-2a59-468a-ac93-11cf702536bd) +#### General + The [TrainrunIterator](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/d170955ecc466bfa9c10071927c63199eb7a86f7/src/app/services/util/trainrun.iterator.ts#L12) operates over a structure that can be conceptualized as an undirected acyclic graph (DAG), where each trainrun is a connected component. -#### Structure + + +##### Structure - **TrainrunSection:** Each section has a source and a target node, analogous to an edge in a graph. The trainrun section is not directly connected to a node. It's connected via a port. - **Node:** Nodes manage connections through ports, ports are effectively acting as a vertex within the graph. - **Transition:** Transitions connect two train sections within a node with the help of ports. They can be interpreted as edges in the graph. -#### Traversal +##### Traversal To initiate traversal, it is important to specify a location (node) where the traversal begins. To determine the traversal direction a trainrun section is required. The trainrun section must be connected to the node. Otherwise the traversal will fail. With the help of the trainrun section the traversal method determines the travel direction. Therefore, a tuple consisting of a node and a trainrun section is needed for each traversal. This tuple determines the directed edge in the directed graph. Each edge in a directed graph points to another node. For example, if the given node is the source node, the iterator moves towards the target node; if the node is the target node, the iterator moves towards the source node. This can be defined very simply using the tuple. Upon reaching a node, the transition is the object that determines the transition from the input port to the output port within the node. This is important to correctly determine the transition from the incoming trainrun section to the continuing trainrun section. Therefore, to continue traversing through the next section, a transition is needed. Once no transitions are available, the traversal stops. At that point, either the target node of the trainrun or, conversely, the starting node is found. The TrainrunIterator can effectively traverse through the trainrun sections by utilizing the source and target nodes of each section. This approach eliminates the need to explicitly maintain a direction in the data and is independent of the input (drawing direction). This allows everything to be kept very simple for the user. -### TrainrunIterator +#### TrainrunIterator The TrainrunIterator is a concept aimed at iterating through the sections of a trainrun, similar to how one navigates through the edges of a graph. Here is a detailed description of how this iterator works and how it can be used: -#### Structure of the Trainrun +##### Structure of the Trainrun - **Graph**: The entire graph is generally an undirected acyclic graph (DAG). Each trainrun (segment) represents a connected component. -#### Traversal Logic +##### Traversal Logic - **Starting Point**: Iteration begins with a given node and a specific trainrun section. - **Section Connection**: The iterator moves through connected sections by utilizing the source and target nodes of each section. - **Transitions**: When a transition is reached, the next connected section is followed through the corresponding port. - **End of Traversal**: Iteration ends when no further sections or transitions are available. -#### Example Application +##### Example Application - **Initialization**: The iterator is initialized with a start node ID and a specific trainrun section. - **Forward Traversal**: The iterator moves from section to section by navigating from one node to the next. During traversal, the source and target nodes of the sections are used to determine the path. - **Backward Traversal**: To traverse in the opposite direction, the iterator can be re-initialized with the end node ID of the current traversal and the corresponding trainrun section. This reverses the path and allows a return to the starting point. -#### Detailed Steps +##### Detailed Steps 1. **Start with a Node ID and a Trainrun Section**: The iterator begins with a defined node ID and a specific trainrun section. This represents the starting point. 2. **Section-wise Traversal**: The iterator traverses the sections by using the connections between the nodes. It moves from the source node to the target node of a section. 3. **Handling Transitions**: When a transition within a node is reached, the iterator follows the transition to the next connected section. 4. **Traversal End**: Iteration ends when no further connected sections or transitions are available. This signals the end of the trainrun. -#### Summary The TrainrunIterator enables structured traversal through the sections of a trainrun by using both a node ID and a specific trainrun section as a starting point. This increases the precision and flexibility of the traversal. By utilizing the source and target nodes of each section and following transitions within the nodes, the iterator can efficiently navigate through the entire trainrun. This method is particularly useful for traversing complex trainrun paths and ensuring that the traversal logic is correctly understood and applied both forwards and backwards. If functionality should be initiated by providing a port ID, this could be a further extension allowing a start directly from a specific port. However, this functionality is not yet implemented. From de577458158b719378974d507d4fa300cc68a6b6 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 24 Oct 2024 16:35:41 +0200 Subject: [PATCH 151/197] Update DATA_MODEL.md --- documentation/DATA_MODEL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/DATA_MODEL.md b/documentation/DATA_MODEL.md index 5b080681..067c27b5 100644 --- a/documentation/DATA_MODEL.md +++ b/documentation/DATA_MODEL.md @@ -186,7 +186,7 @@ More details can be found in the source code: --- -### Iterate through all trainrun section (forward/backward) +### Iterate through all train run sections (forward/backward) To understand how the trainrun iteration has to work, please take another look at this illustration: ![image](https://github.com/user-attachments/assets/21fdb029-2a59-468a-ac93-11cf702536bd) From ff3e72c2cdf681c10884c14377448b47bded05b4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 24 Oct 2024 16:39:17 +0200 Subject: [PATCH 152/197] chore(main): release netzgrafik-frontend 2.9.0 (#315) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 13 +++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 7a564723..a3906fc0 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.8.0" + ".": "2.9.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 31488aa9..0caad61c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## [2.9.0](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.8.0...netzgrafik-frontend-v2.9.0) (2024-10-24) + + +### Features + +* migrate originDestination connectionPenalty to netzgrafikDto ([#314](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/314)) ([ce3f90d](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/ce3f90d73784fabb49f29ac3625b142ceaa4134f)) +* optimize originDestination graph ([#316](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/316)) ([83895a1](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/83895a153bcbc83cbbb692f48b8df196a56a9467)) + + +### Bug Fixes + +* fix O/D Matrix for unordered trainruns ([#321](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/321)) ([3d9644f](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/3d9644fbe94ea0a11a5403b798ea5634481166fa)) + ## [2.8.0](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.7.17...netzgrafik-frontend-v2.8.0) (2024-10-10) diff --git a/package-lock.json b/package-lock.json index 0a2e355f..1474f0ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.8.0", + "version": "2.9.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.8.0", + "version": "2.9.0", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index 0cde10b8..7d933020 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.8.0", + "version": "2.9.0", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From 790f53b7f7493cc7204719643dd368eccad89d16 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Mon, 28 Oct 2024 11:03:18 +0100 Subject: [PATCH 153/197] fix: 320 bug graphical timetable streckengrafik renders only one trainrun segement (#325) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial fix for sorting/orientation issue - partial progress * Added documentation and comments * Propagated consecutiveTime over each train run segment separately * Removed debug console logs (clean) * Fixed lint issues * Updated CREATE_TRAINRUN.md with images * Improved code (array.concat and indexOf) for data filtering * Fixed train run part issue in pearls view * Refactored and cleaned up code, added tests * Enhanced UX and documentation --------- Co-authored-by: Serge Croisé --- documentation/CREATE_TRAINRUN.md | 28 +++ documentation/USERMANUAL.md | 3 + .../technical/trainrun_iterations.md | 100 ++++++++ .../model/perlenkette-tests.spec.ts | 16 +- src/app/perlenkette/model/perlenketteNode.ts | 17 +- .../perlenkette/model/perlenketteSection.ts | 17 +- .../perlenkette/perlenkette.component.html | 13 +- src/app/perlenkette/perlenkette.component.ts | 44 +++- .../service/load-perlenkette.service.ts | 141 +++++++---- src/app/services/data/trainrun.service.ts | 129 ++++++---- .../services/util/trainrunsection.helper.ts | 16 +- .../sg-1-load-trainrun-item.service.ts | 225 ++++++++++++------ src/app/view/util/generalViewFunctions.ts | 20 ++ 13 files changed, 584 insertions(+), 185 deletions(-) create mode 100644 documentation/technical/trainrun_iterations.md diff --git a/documentation/CREATE_TRAINRUN.md b/documentation/CREATE_TRAINRUN.md index 87c6937a..146b5d38 100644 --- a/documentation/CREATE_TRAINRUN.md +++ b/documentation/CREATE_TRAINRUN.md @@ -106,3 +106,31 @@ To switch a train from a stop to a non-stop at a node, follow these steps: For more details have a look into - [Split/Combine two trainruns](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/main/documentation/Split_Combine_Trainruns.md) - [Merge Netzgrafik](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/main/documentation/Merge_Netzgrafik.md) + +## Special cases + +### Trainrun path with "holes" (missing sections) + +![image](https://github.com/user-attachments/assets/d87b842c-7696-4e81-aa78-75cc966b5306) +*Example Netzgrafik with missing sections (See the cargo trainrun GTwo_Part_trainrun)* + + +When creating a trainrun, the trairnun path should connect all nodes from start to destination using trainrun sections. +However, it can happen during the creation that not all trainrun sections have been drawn in the meantime. +Gaps may occur along the trainrun path where at least one trainrun section is missing. +These “holes” usually occur if the trainrun path has not yet been drawn completely or correctly. +For example, a trainrun path could look like this with a "hole" in the middle, + +A - B - C ---- (missing section) ---- E - F - G + +The trainrun section between C and E is missing here. However, these gaps can also occur if a partial cancelation is made for a train run. + +![image](https://github.com/user-attachments/assets/5d1ef657-e421-41ff-ae57-622eee82f295) +*Graphical timetable.* + + +In each of these cases, the trainrun has at least two parts, e.g. [(A B), (A C)] and [(E F)(F G)]. +In this case, the trainrun is interpreted as two separate trainruns. +The Netzgrafik has no information about whether the missing part could be closed between C - E, C - D - E or +another possible variant, therefore the assumption that there is an independent trainrun for each trainrun part is +the best assumption. This avoids many new problems. diff --git a/documentation/USERMANUAL.md b/documentation/USERMANUAL.md index d9427dce..694d5746 100644 --- a/documentation/USERMANUAL.md +++ b/documentation/USERMANUAL.md @@ -178,3 +178,6 @@ creation of comprehensive and visually appealing network representations. ## Links - [Netzgrafik-Editor data export/import (JSON)](DATA_MODEL_JSON.md) - [DATA MODEL](DATA_MODEL.md) + +## Technical documentation +- [Trainrun iterator](/technical/trainrun_iterations.md) diff --git a/documentation/technical/trainrun_iterations.md b/documentation/technical/trainrun_iterations.md new file mode 100644 index 00000000..903cf211 --- /dev/null +++ b/documentation/technical/trainrun_iterations.md @@ -0,0 +1,100 @@ +# Trainrun iterator + +## Sample code + +https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/pull/325 + +### Simple trainrun iterator - just one trainrun part +To iterate starting from a node of interest with the orientation passed through the trainrun section, you can use the sample code (pattern) below. +The iteration will proceed along the trainrun. Be aware that this does not ensure traveling through the full train run. + +https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/main/documentation/CREATE_TRAINRUN.md#trainrun-path-with-holes-missing-sections + +```typescript + + // create forward iterator + const iterator: TrainrunIterator = this.trainrunService.getIterator( + startForwardNode, + startTrainrunSection, + ); + while (iterator.hasNext()) { + // move iterator forward + const currentTrainrunSectionNodePair = iterator.next(); + + // get data + const trainrunSection = currentTrainrunSectionNodePair.trainrunSection; + const node = currentTrainrunSectionNodePair.node; + + ... + user + defined + data + processing + ... + + } +} +``` + +### Complete Train Run Iterator - Over All Train Run Parts +Iterator pattern for iterating through all train run parts separately. + +```typescript +getForwardTrainrunPartIterator(trainrunSection : TrainrunSection) { + // find both start nodes ( N1 - N2 - N3 - N4 ) => N1 , N2 + const bothEndNodes = + this.trainrunService.getBothEndNodesFromTrainrunPart(trainrunSection); + + // get start / end node from Top/Left -> Botton / Right + const startForwardNode = GeneralViewFunctions.getLeftOrTopNode( + bothEndNodes.endNode1, + bothEndNodes.endNode2, + ); + + // get start trainrun section -> forward direction/orientation + const startTrainrunSection = startForwardNode.getStartTrainrunSection( + trainrun.getId(), + ); + + // create forward iterator + const iterator: TrainrunIterator = this.trainrunService.getIterator( + startForwardNode, + startTrainrunSection, + ); + return iterator; +} + +simpleTrainrunAllPartsIterator(trainrun: Trainrun) { + let alltrainrunsections = + this.trainrunSectionService + .getAllTrainrunSectionsForTrainrun(trainrun.getId()); + + while (alltrainrunsections.length > 0) { + // traverse over all trainrun parts + const iterator= getForwardTrainrunPartIterator(alltrainrunsections[0]); + + while (iterator.hasNext()) { + // move iterator forward + const currentTrainrunSectionNodePair = iterator.next(); + + // get data + const trainrunSection = currentTrainrunSectionNodePair.trainrunSection; + const node = currentTrainrunSectionNodePair.node; + + ... + user + defined + data + processing + ... + + // filter all still visited trainrun sections + alltrainrunsections = alltrainrunsections.filter(ts => + ts.getId() !== trainrunSection.getId() + ); + } + + + } + } +``` diff --git a/src/app/perlenkette/model/perlenkette-tests.spec.ts b/src/app/perlenkette/model/perlenkette-tests.spec.ts index 54e9a19f..f2e560fe 100644 --- a/src/app/perlenkette/model/perlenkette-tests.spec.ts +++ b/src/app/perlenkette/model/perlenkette-tests.spec.ts @@ -3,8 +3,18 @@ import {PerlenketteSection} from "./perlenketteSection"; describe("PerlenketteModelTests", () => { it("Perlenkette-Model - Test - PerlenketteNode - 001", () => { - const node = new PerlenketteNode(0, "BN", "Berm", 10, [], undefined); + const node = new PerlenketteNode(0, + "BN", + "Berm", + 10, + [], + undefined, + false, + true + ); + expect(node.isFristTrainrunPartNode()).toBe(false); + expect(node.isLastTrainrunPartNode()).toBe(true); expect(node.isPerlenketteNode()).toBe(true); expect(node.isPerlenketteSection()).toBe(false); expect(node.getPerlenketteNode()).toEqual(node); @@ -19,8 +29,12 @@ describe("PerlenketteModelTests", () => { undefined, 0, false, + false, + true ); + expect(section.isFristTrainrunPartSection()).toBe(false); + expect(section.isLastTrainrunPartSection()).toBe(true); expect(section.isPerlenketteNode()).toBe(false); expect(section.isPerlenketteSection()).toBe(true); expect(section.getPerlenketteNode()).toEqual(undefined); diff --git a/src/app/perlenkette/model/perlenketteNode.ts b/src/app/perlenkette/model/perlenketteNode.ts index 46256a77..3e8b2315 100644 --- a/src/app/perlenkette/model/perlenketteNode.ts +++ b/src/app/perlenkette/model/perlenketteNode.ts @@ -12,7 +12,22 @@ export class PerlenketteNode implements PerlenketteItem { public connectionTime: number, public connections: PerlenketteConnection[], public transition: Transition, - ) {} + public fristTrainrunPartNode: boolean, + public lastTrainrunPartNode: boolean + ) { + } + + isFristTrainrunPartNode(): boolean { + return this.fristTrainrunPartNode; + } + + isLastTrainrunPartNode(): boolean { + return this.lastTrainrunPartNode; + } + + setLastTrainrunPartNode(flag : boolean) { + this.lastTrainrunPartNode = flag; + } isPerlenketteNode(): boolean { return true; diff --git a/src/app/perlenkette/model/perlenketteSection.ts b/src/app/perlenkette/model/perlenketteSection.ts index ccd3eaec..62d0b2c7 100644 --- a/src/app/perlenkette/model/perlenketteSection.ts +++ b/src/app/perlenkette/model/perlenketteSection.ts @@ -10,7 +10,22 @@ export class PerlenketteSection implements PerlenketteItem { public toNode: Node, public numberOfStops: number, public isBeingEdited: boolean = false, - ) {} + public fristTrainrunPartSection: boolean = false, + public lastTrainrunPartSection: boolean = false + ) { + } + + isFristTrainrunPartSection(): boolean { + return this.fristTrainrunPartSection; + } + + isLastTrainrunPartSection(): boolean { + return this.lastTrainrunPartSection; + } + + setLastTrainrunPartSection(flag : boolean) { + this.lastTrainrunPartSection = flag; + } isPerlenketteNode(): boolean { return false; diff --git a/src/app/perlenkette/perlenkette.component.html b/src/app/perlenkette/perlenkette.component.html index c9f44b63..deb722ec 100644 --- a/src/app/perlenkette/perlenkette.component.html +++ b/src/app/perlenkette/perlenkette.component.html @@ -94,7 +94,10 @@ (click)="goto(pathItem)" >{{ pathItem.getPerlenketteNode().shortName }} -

+ + + + @@ -126,6 +129,10 @@ [isBottomNode]="idx === perlenketteTrainrun.pathItems.length-1" > +
+
+
+
diff --git a/src/app/perlenkette/perlenkette.component.ts b/src/app/perlenkette/perlenkette.component.ts index 34d8e4dd..c3687e8b 100644 --- a/src/app/perlenkette/perlenkette.component.ts +++ b/src/app/perlenkette/perlenkette.component.ts @@ -54,7 +54,7 @@ export class PerlenketteComponent implements AfterContentChecked, OnDestroy { readonly filterService: FilterService, private readonly uiInteractionService: UiInteractionService, private readonly nodeService: NodeService, - private versionControlService : VersionControlService, + private versionControlService: VersionControlService, private changeDetectorRef: ChangeDetectorRef, ) { this.selectedPerlenketteConnection = undefined; @@ -215,6 +215,15 @@ export class PerlenketteComponent implements AfterContentChecked, OnDestroy { this.signalAllChildrenIsBeingEditedSubject.next(event); } + doSplitTrainrun(pathItems: PerlenketteItem[], idx: number): boolean { + if (idx >= pathItems.length - 1) { + return false; + } + const item = pathItems[idx]; + const previousItem = pathItems[idx + 1]; + return item.isPerlenketteNode() === previousItem.isPerlenketteNode(); + } + signalHeightChanged(height: number, pathItem: PerlenketteItem) { this.perlenketteRenderingElementsHeight.push([pathItem, height]); this.renderedElementsHeight = 0; @@ -225,11 +234,42 @@ export class PerlenketteComponent implements AfterContentChecked, OnDestroy { }); } + isFirstSection(item: PerlenketteItem): boolean { + if (item.isPerlenketteSection()) { + const psi = item.getPerlenketteSection(); + return psi.isFristTrainrunPartSection(); + } + return false; + } + + isLastSection(item: PerlenketteItem): boolean { + if (item.isPerlenketteSection()) { + const psi = item.getPerlenketteSection(); + return psi.isLastTrainrunPartSection(); + } + return false; + } + + isLastNode(item: PerlenketteItem): boolean { + if (item.isPerlenketteNode()) { + const pni = item.getPerlenketteNode(); + return pni.isLastTrainrunPartNode(); + } + return false; + } + + isLastNodeButNotVeryLast(item: PerlenketteItem) { + if (this.perlenketteTrainrun.pathItems.indexOf(item) === this.perlenketteTrainrun.pathItems.length - 1) { + return false; + } + return this.isLastNode(item); + } + getSignalAllChildrenIsBeingEditedObservable() { return this.signalAllChildrenIsBeingEditedSubject.asObservable(); } - getVariantIsWritable() : boolean { + getVariantIsWritable(): boolean { return this.versionControlService.getVariantIsWritable(); } diff --git a/src/app/perlenkette/service/load-perlenkette.service.ts b/src/app/perlenkette/service/load-perlenkette.service.ts index 78a62689..d28cc084 100644 --- a/src/app/perlenkette/service/load-perlenkette.service.ts +++ b/src/app/perlenkette/service/load-perlenkette.service.ts @@ -15,6 +15,7 @@ import {Node} from "../../models/node.model"; import {TrainrunSectionService} from "../../services/data/trainrunsection.service"; import {NodeService} from "../../services/data/node.service"; import {FilterService} from "../../services/ui/filter.service"; +import {TrainrunSection} from "../../models/trainrunsection.model"; @Injectable({ providedIn: "root", @@ -114,62 +115,102 @@ export class LoadPerlenketteService implements OnDestroy { private getPerlenketteItem(trainrun: Trainrun): PerlenketteItem[] { const perlenketteItem: PerlenketteItem[] = []; - const bothEndNodes = this.trainrunService.getBothEndNodesWithTrainrunId( - trainrun.getId(), - ); - const startForwardNode = GeneralViewFunctions.getLeftOrTopNode( - bothEndNodes.endNode1, - bothEndNodes.endNode2, - ); - if (startForwardNode) { - const startTrainrunSection = startForwardNode.getStartTrainrunSection( - trainrun.getId(), - ); - if (startTrainrunSection === undefined) { - return perlenketteItem; - } - // Start Node - perlenketteItem.push( - new PerlenketteNode( - startForwardNode.getId(), - startForwardNode.getBetriebspunktName(), - startForwardNode.getFullName(), - startForwardNode.getConnectionTime(), - this.getPerlenketteConnections(trainrun, startForwardNode), - startForwardNode.getTransition(startTrainrunSection.getId()), - ), - ); - let lastNode = startForwardNode; - const iterator: TrainrunIterator = this.trainrunService.getIterator( - startForwardNode, - startTrainrunSection, + + let alltrainrunsections = + this.trainrunSectionService + .getAllTrainrunSectionsForTrainrun(trainrun.getId()); + + while (alltrainrunsections.length > 0) { + // traverse over all trainrun parts + const trainrunSection = alltrainrunsections[0]; + const bothEndNodes = + this.trainrunService.getBothEndNodesFromTrainrunPart(trainrunSection); + const startForwardNode = GeneralViewFunctions.getLeftOrTopNode( + bothEndNodes.endNode1, + bothEndNodes.endNode2, ); - while (iterator.hasNext()) { - const currentTrainrunSectionNodePair = iterator.next(); - const trainrunSection = currentTrainrunSectionNodePair.trainrunSection; - const node = currentTrainrunSectionNodePair.node; - // Section X - perlenketteItem.push( - new PerlenketteSection( - trainrunSection.getId(), - trainrunSection.getTravelTime(), - lastNode, - node, - trainrunSection.getNumberOfStops(), - ), + + if (startForwardNode) { + const startTrainrunSection = startForwardNode.getStartTrainrunSection( + trainrun.getId(), ); - // Node X + if (startTrainrunSection === undefined) { + return perlenketteItem; + } + // Start Node perlenketteItem.push( new PerlenketteNode( - node.getId(), - node.getBetriebspunktName(), - node.getFullName(), - node.getConnectionTime(), - this.getPerlenketteConnections(trainrun, node), - node.getTransition(trainrunSection.getId()), + startForwardNode.getId(), + startForwardNode.getBetriebspunktName(), + startForwardNode.getFullName(), + startForwardNode.getConnectionTime(), + this.getPerlenketteConnections(trainrun, startForwardNode), + startForwardNode.getTransition(startTrainrunSection.getId()), + true, + false, ), ); - lastNode = node; + let lastNode = startForwardNode; + const iterator: TrainrunIterator = this.trainrunService.getIterator( + startForwardNode, + startTrainrunSection, + ); + + let firstSection = true; + while (iterator.hasNext()) { + const currentTrainrunSectionNodePair = iterator.next(); + const trainrunSection = currentTrainrunSectionNodePair.trainrunSection; + const node = currentTrainrunSectionNodePair.node; + // Section X + perlenketteItem.push( + new PerlenketteSection( + trainrunSection.getId(), + trainrunSection.getTravelTime(), + lastNode, + node, + trainrunSection.getNumberOfStops(), + false, + firstSection, + false + ), + ); + firstSection = false; + + // Node X + perlenketteItem.push( + new PerlenketteNode( + node.getId(), + node.getBetriebspunktName(), + node.getFullName(), + node.getConnectionTime(), + this.getPerlenketteConnections(trainrun, node), + node.getTransition(trainrunSection.getId()), + false, + false + ), + ); + lastNode = node; + + // filter all still visited trainrun sections + alltrainrunsections = alltrainrunsections.filter(ts => + ts.getId() !== currentTrainrunSectionNodePair.trainrunSection.getId() + ); + } + + if (perlenketteItem.length > 1) { + const itemSec = perlenketteItem[perlenketteItem.length - 2]; + if (itemSec.isPerlenketteSection()) { + const pn = itemSec.getPerlenketteSection(); + pn.setLastTrainrunPartSection(true); + } + const itemNode = perlenketteItem[perlenketteItem.length - 1]; + if (itemNode.isPerlenketteNode()) { + const pn = itemNode.getPerlenketteNode(); + pn.setLastTrainrunPartNode(true); + } + } + + } } return perlenketteItem; diff --git a/src/app/services/data/trainrun.service.ts b/src/app/services/data/trainrun.service.ts index 229f75ef..0af88597 100644 --- a/src/app/services/data/trainrun.service.ts +++ b/src/app/services/data/trainrun.service.ts @@ -439,7 +439,7 @@ export class TrainrunService { port2.getTrainrunSection().getSourceDeparture(); let frequencyOffset = 0; - while ( 60 + arrivalTimeAtNode > departTimeAtNode + frequencyOffset) { + while (60 + arrivalTimeAtNode > departTimeAtNode + frequencyOffset) { frequencyOffset += port1.getTrainrunSection().getFrequency(); } @@ -464,7 +464,7 @@ export class TrainrunService { const trans2 = node.getTransitionFromPortId(port2.getId()); if (trans1 === undefined && trans2 === undefined) { const trans = node.addTransitionAndComputeRouting(port1, port2, trainrun1); - if (60 + arrivalTimeAtNode === departTimeAtNode+frequencyOffset) { + if (60 + arrivalTimeAtNode === departTimeAtNode + frequencyOffset) { trans.setIsNonStopTransit(true); } else { trans.setIsNonStopTransit(false); @@ -575,48 +575,74 @@ export class TrainrunService { this.propagateConsecutiveTimesForTrainrun(ts.getId()); } + getBothEndNodesFromTrainrunPart(trainrunSection: TrainrunSection): + { + endNode1: Node; + endNode2: Node; + } { + const sourceNode = trainrunSection.getSourceNode(); + const targetNode = trainrunSection.getTargetNode(); + const endNode1 = this.getEndNode(sourceNode, trainrunSection); + const endNode2 = this.getEndNode(targetNode, trainrunSection); + return {endNode1, endNode2}; + } + propagateConsecutiveTimesForTrainrun(trainrunSectionId: number) { - const trainrunSection = + const inTrainrunSection = this.trainrunSectionService.getTrainrunSectionFromId(trainrunSectionId); - if (trainrunSection === undefined) { + if (inTrainrunSection === undefined) { return; } - // propagate Consecutive Times Forward - const bothEndNodes = this.getBothEndNodesWithTrainrunId( - trainrunSection.getTrainrunId(), - ); - const startForwardNode = GeneralViewFunctions.getLeftOrTopNode( - bothEndNodes.endNode1, - bothEndNodes.endNode2, - ); - const startBackwardNode = - bothEndNodes.endNode1.getId() === startForwardNode.getId() - ? bothEndNodes.endNode2 - : bothEndNodes.endNode1; - const arrivalTime = this.propagateConsecutiveTimes( - startForwardNode, - startForwardNode.getStartTrainrunSection( - trainrunSection.getTrainrunId(), - true - ), - trainrunSection.getFrequencyOffset(), - ); - // propagate Consecutive Times Backward - const freq = trainrunSection.getTrainrun().getTrainrunFrequency().frequency; - const restFreqArrivalTime = Math.floor(arrivalTime / freq) * freq; - const freqDependantArrivalTime = arrivalTime - restFreqArrivalTime; - let offset = freq - freqDependantArrivalTime; - offset += restFreqArrivalTime; - offset = Math.floor(offset / 60) * 60; - - this.propagateConsecutiveTimes( - startBackwardNode, - startBackwardNode.getStartTrainrunSection( - trainrunSection.getTrainrunId(), - false - ), - offset, - ); + + let alltrainrunsections = + this.trainrunSectionService + .getAllTrainrunSectionsForTrainrun(inTrainrunSection.getTrainrunId()); + + while (alltrainrunsections.length > 0) { + // propagate Consecutive Times Forward + const trainrunSection = alltrainrunsections[0]; + const bothEndNodes = + this.getBothEndNodesFromTrainrunPart(trainrunSection); + + const startForwardBackwardNode = + GeneralViewFunctions.getStartForwardAndBackwardNode( + bothEndNodes.endNode1, + bothEndNodes.endNode2, + ); + + const propDataForward = this.propagateConsecutiveTimes( + startForwardBackwardNode.startForwardNode, + startForwardBackwardNode.startForwardNode.getStartTrainrunSection( + trainrunSection.getTrainrunId(), + true + ), + trainrunSection.getFrequencyOffset(), + ); + const arrivalTime = propDataForward.cumTime; + + // propagate Consecutive Times Backward + const freq = trainrunSection.getTrainrun().getTrainrunFrequency().frequency; + const restFreqArrivalTime = Math.floor(arrivalTime / freq) * freq; + const freqDependantArrivalTime = arrivalTime - restFreqArrivalTime; + let offset = freq - freqDependantArrivalTime; + offset += restFreqArrivalTime; + offset = Math.floor(offset / 60) * 60; + + const propDataBackward = this.propagateConsecutiveTimes( + startForwardBackwardNode.startBackwardNode, + startForwardBackwardNode.startBackwardNode.getStartTrainrunSection( + trainrunSection.getTrainrunId(), + false + ), + offset, + ); + + // filter all still visited trainrun sections + alltrainrunsections = alltrainrunsections.filter(ts => + propDataForward.visitedTrainrunSections.indexOf(ts) === -1 && + propDataBackward.visitedTrainrunSections.indexOf(ts) === -1 + ); + } } getStartNodeWithTrainrunId(trainrunId: number): Node { @@ -808,11 +834,7 @@ export class TrainrunService { const trainrunSection = trainrunSections.find( (trs) => trs.getTrainrunId() === trainrunId, ); - const sourceNode = trainrunSection.getSourceNode(); - const targetNode = trainrunSection.getTargetNode(); - const endNode1 = this.getEndNode(sourceNode, trainrunSection); - const endNode2 = this.getEndNode(targetNode, trainrunSection); - return {endNode1, endNode2}; + return this.getBothEndNodesFromTrainrunPart(trainrunSection); } private createNewTrainrunFromDto(trainrun: TrainrunDto): Trainrun { @@ -836,9 +858,16 @@ export class TrainrunService { node: Node, trainrunSection: TrainrunSection, offset: number, - ): number { + ): { + cumTime: number; + visitedTrainrunSections: TrainrunSection[]; + } { + const visitedTrainrunSections: TrainrunSection[] = [trainrunSection]; if (trainrunSection === undefined) { - return 0; + return { + cumTime: 0, + visitedTrainrunSections: visitedTrainrunSections + }; } let accumulatedTime = node.getDepartureTime(trainrunSection) + offset; const iterator = this.getIterator(node, trainrunSection); @@ -885,8 +914,12 @@ export class TrainrunService { : nextDeparture - oldArrival; } accumulatedTime += halteZeit; + visitedTrainrunSections.push(nextPair.trainrunSection); } - return accumulatedTime; + return { + cumTime: accumulatedTime, + visitedTrainrunSections: visitedTrainrunSections + }; } private findClearedLabel(trainrun: Trainrun, labelIds: number[]) { diff --git a/src/app/services/util/trainrunsection.helper.ts b/src/app/services/util/trainrunsection.helper.ts index 01cae421..7b7f26a4 100644 --- a/src/app/services/util/trainrunsection.helper.ts +++ b/src/app/services/util/trainrunsection.helper.ts @@ -104,14 +104,14 @@ export class TrainrunsectionHelper { getLeftRightSections(trainrunSection: TrainrunSection) { const bothLastNonStopTransitNodes = this.trainrunService.getBothLastNonStopNodes(trainrunSection); - const lastLeftNode = GeneralViewFunctions.getLeftOrTopNode( - bothLastNonStopTransitNodes.lastNonStopNode1, - bothLastNonStopTransitNodes.lastNonStopNode2, - ); - const lastRightNode = - lastLeftNode.getId() === bothLastNonStopTransitNodes.lastNonStopNode1.getId() ? - bothLastNonStopTransitNodes.lastNonStopNode2 : - bothLastNonStopTransitNodes.lastNonStopNode1; + + const startForwardBackwardNode = + GeneralViewFunctions.getStartForwardAndBackwardNode( + bothLastNonStopTransitNodes.lastNonStopNode1, + bothLastNonStopTransitNodes.lastNonStopNode2, + ); + const lastLeftNode = startForwardBackwardNode.startForwardNode; + const lastRightNode = startForwardBackwardNode.startBackwardNode; const towardsSource = this.trainrunService.getLastNonStopTrainrunSection( diff --git a/src/app/streckengrafik/services/sg-1-load-trainrun-item.service.ts b/src/app/streckengrafik/services/sg-1-load-trainrun-item.service.ts index b8f40cdd..1e00b8d0 100644 --- a/src/app/streckengrafik/services/sg-1-load-trainrun-item.service.ts +++ b/src/app/streckengrafik/services/sg-1-load-trainrun-item.service.ts @@ -152,10 +152,13 @@ export class Sg1LoadTrainrunItemService implements OnDestroy { const selectedTrainrun: Trainrun = this.getSelectedTrainrun(); if (selectedTrainrun) { if (selectedTrainrun.selected()) { - this.cachedTrainrunItems = this.loadTrainrunItem( - selectedTrainrun, - true, - ); + // The template path (along which the graphical timetable is projected) does + // not support current trains with partial cancellations. + const ts: TrainrunSection = this.trainrunSectionService + .getAllTrainrunSectionsForTrainrun(selectedTrainrun.getId()) + .find(ts => true); + const loadeddata = this.loadTrainrunItem(ts, true); + this.cachedTrainrunItems = loadeddata.trainrunItem; } } } @@ -378,63 +381,94 @@ export class Sg1LoadTrainrunItemService implements OnDestroy { ); } + private determineForwardBackwardNodes( + trainrunSection: TrainrunSection, + onlyForward: boolean): { + startForwardNode: Node; + startBackwardNode: Node; + visitedTrainrunSections: TrainrunSection[]; + } { + let visitedTrainrunSections: TrainrunSection[] = []; + const trainrun = trainrunSection.getTrainrun(); + + const bothEndNodes = + this.trainrunService.getBothEndNodesFromTrainrunPart(trainrunSection); + + const startForwardBackwardNode = GeneralViewFunctions.getStartForwardAndBackwardNode( + bothEndNodes.endNode1, + bothEndNodes.endNode2, + ); + + if (onlyForward) { + const tsg = this.trainrunSectionGroup( + trainrun.getId(), + startForwardBackwardNode.startForwardNode, + true + ); + this.forwardTrainrunSectionGroup = tsg.trainrunSectionGroups; + visitedTrainrunSections = tsg.visitedTrainrunSections; + } else { + const extractedInfo = this.isTrainRunWayDirectionBackward( + trainrun, + startForwardBackwardNode.startForwardNode, + startForwardBackwardNode.startBackwardNode, + this.forwardTrainrunSectionGroup, + ); + visitedTrainrunSections = extractedInfo.visitedTrainrunSections; + if (extractedInfo.check) { + const nextStartForwardNode = startForwardBackwardNode.startBackwardNode; + const nextStartBackwardNode = startForwardBackwardNode.startForwardNode; + startForwardBackwardNode.startForwardNode = nextStartForwardNode; + startForwardBackwardNode.startBackwardNode = nextStartBackwardNode; + } + } + return { + startForwardNode: startForwardBackwardNode.startForwardNode, + startBackwardNode: startForwardBackwardNode.startBackwardNode, + visitedTrainrunSections: visitedTrainrunSections, + }; + } + private loadTrainrunItem( - trainrun: Trainrun, + trainrunSection: TrainrunSection, onlyForward: boolean, - ): TrainrunItem { + ): { + trainrunItem: TrainrunItem; + visitedTrainrunSections: TrainrunSection[]; + } { + let visitedTrainrunSections: TrainrunSection[] = []; let index = 0; let trainrunStartTime = 0; let trainrunEndTime = 0; + + const trainrun: Trainrun = + this.trainrunService.getTrainrunFromId(trainrunSection.getTrainrunId()); + const pathItems: PathItem[] = []; if ( this.trainrunService.getTrainrunFromId(trainrun.getId()) === undefined ) { return undefined; } - const bothEndNodes = this.trainrunService.getBothEndNodesWithTrainrunId( - trainrun.getId(), - ); - let startForwardNode = GeneralViewFunctions.getLeftOrTopNode( - bothEndNodes.endNode1, - bothEndNodes.endNode2, - ); - let startBackwardNode = - bothEndNodes.endNode1.getId() === startForwardNode.getId() - ? bothEndNodes.endNode2 - : bothEndNodes.endNode1; - if (onlyForward) { - this.forwardTrainrunSectionGroup = this.trainrunSectionGroup( - trainrun.getId(), - startForwardNode, - true - ); - } else { - if ( - this.isTrainRunWayDirectionBackward( - trainrun, - startForwardNode, - startBackwardNode, - this.forwardTrainrunSectionGroup, - ) - ) { - const nextStartForwardNode = startBackwardNode; - const nextStartBackwardNode = startForwardNode; - startForwardNode = nextStartForwardNode; - startBackwardNode = nextStartBackwardNode; - } - } + const forwardBackwardNodes = + this.determineForwardBackwardNodes(trainrunSection, onlyForward); - const forwardTrainrunSectionGroup = this.trainrunSectionGroup( + const tsgForward = this.trainrunSectionGroup( trainrun.getId(), - startForwardNode, + forwardBackwardNodes.startForwardNode, true ); - const backwardTrainrunSectionGroup = this.trainrunSectionGroup( + const forwardTrainrunSectionGroup = tsgForward.trainrunSectionGroups; + visitedTrainrunSections = visitedTrainrunSections.concat(tsgForward.visitedTrainrunSections); + + const tsgBackward = this.trainrunSectionGroup( trainrun.getId(), - startBackwardNode, + forwardBackwardNodes.startBackwardNode, false ); + const backwardTrainrunSectionGroup = tsgBackward.trainrunSectionGroups; + visitedTrainrunSections = visitedTrainrunSections.concat(tsgBackward.visitedTrainrunSections); let forwardStartNode: PathNode = undefined; let forwardEndNode: PathNode = undefined; @@ -453,7 +487,7 @@ export class Sg1LoadTrainrunItemService implements OnDestroy { } // First Node; - if (fromNode.getId() === startForwardNode.getId()) { + if (fromNode.getId() === forwardBackwardNodes.startForwardNode.getId()) { const sourcePathNode = new PathNode( fromNode.getDepartureConsecutiveTime(trainrunSection), this.getTurnaroundStartNodeForward( @@ -498,7 +532,7 @@ export class Sg1LoadTrainrunItemService implements OnDestroy { !this.filterService.filterNode(toNode), ); - if (toNode.getId() === startBackwardNode.getId()) { + if (toNode.getId() === forwardBackwardNodes.startBackwardNode.getId()) { targetPathNode.departureTime = this.getTurnaroundEndNodeForward( toNode, trainrunSection, @@ -520,7 +554,7 @@ export class Sg1LoadTrainrunItemService implements OnDestroy { trainrunSectionGroup.toTrainrunSectionWithNodes.trainrunSection; } // Erster Node - if (fromNode.getId() === startBackwardNode.getId()) { + if (fromNode.getId() === forwardBackwardNodes.startBackwardNode.getId()) { const sourcePathNode = new PathNode( fromNode.getDepartureConsecutiveTime(trainrunSection), this.getTurnaroundStartNodeBackward( @@ -565,7 +599,7 @@ export class Sg1LoadTrainrunItemService implements OnDestroy { !this.filterService.filterNode(toNode), ); - if (toNode.getId() === startForwardNode.getId()) { + if (toNode.getId() === forwardBackwardNodes.startForwardNode.getId()) { targetPathNode.departureTime = this.getTurnaroundEndNodeBackward( toNode, trainrunSection, @@ -624,33 +658,56 @@ export class Sg1LoadTrainrunItemService implements OnDestroy { } }); - return new TrainrunItem( - trainrun.getId(), - trainrun.getFrequency(), - trainrun.getFrequencyOffset(), - trainrunStartTime, - trainrunEndTime, - trainrun.getTitle(), - trainrun.getCategoryShortName(), - trainrun.getCategoryColorRef(), - pathItems, - ); + return { + trainrunItem: new TrainrunItem( + trainrun.getId(), + trainrun.getFrequency(), + trainrun.getFrequencyOffset(), + trainrunStartTime, + trainrunEndTime, + trainrun.getTitle(), + trainrun.getCategoryShortName(), + trainrun.getCategoryColorRef(), + pathItems + ), + visitedTrainrunSections: visitedTrainrunSections + }; } public loadTrainrunItems( templateTrainrunItem: TrainrunItem, ): TrainrunItem[] { + // Extract for all trainruns the sections which are part of the + // template path (along which the graphical timetable is projected) and it does + // support current for those trains with partial cancellations. const trainrunItems: TrainrunItem[] = []; if (this.trainruns) { this.trainruns.forEach((trainrun: Trainrun) => { if (this.filterService.filterTrainrun(trainrun)) { - const trainrunItem = this.loadTrainrunItem(trainrun, false); - this.sortTrainrunItemAndRotateAlongTemplatePath( - trainrun, - trainrunItem, - templateTrainrunItem, - ); - trainrunItems.push(trainrunItem); + // get all trainrun section for given trainrun + let alltrainrunsections = this.trainrunSectionService + .getAllTrainrunSectionsForTrainrun(trainrun.getId()); + + // As long not all trainrun section are visited (process) continue + // this part of code supports partial cancellations, e.g., trainrun runs from + // A - B - C [ partial canceled ] D - E + while (alltrainrunsections.length > 0) { + const ts: TrainrunSection = alltrainrunsections.find(ts => true); + const loadeddata = this.loadTrainrunItem(ts, false); + + // correct projections directions + this.sortTrainrunItemAndRotateAlongTemplatePath( + trainrun, + loadeddata.trainrunItem, + templateTrainrunItem, + ); + trainrunItems.push(loadeddata.trainrunItem); + + // filter all still visited trainrun sections + alltrainrunsections = alltrainrunsections.filter(ts => + loadeddata.visitedTrainrunSections.indexOf(ts) === -1 + ); + } } }); } @@ -902,17 +959,27 @@ export class Sg1LoadTrainrunItemService implements OnDestroy { startForwardNode, startBackwardNode, selectedForwardTrainrunSectionGroups: TrainrunSectionGroup[], - ): boolean { - const forwardTrainrunSectionGroups = this.trainrunSectionGroup( + ): { + check: boolean; + visitedTrainrunSections: TrainrunSection[]; + } { + let visitedTrainrunSections: TrainrunSection[] = []; + + const tsgForward = this.trainrunSectionGroup( trainrun.getId(), startForwardNode, true ); - const backwardTrainrunSectionGroups = this.trainrunSectionGroup( + const forwardTrainrunSectionGroups = tsgForward.trainrunSectionGroups; + visitedTrainrunSections = visitedTrainrunSections.concat(tsgForward.visitedTrainrunSections); + + const tsgBackward = this.trainrunSectionGroup( trainrun.getId(), startBackwardNode, false ); + const backwardTrainrunSectionGroups = tsgBackward.trainrunSectionGroups; + visitedTrainrunSections = visitedTrainrunSections.concat(tsgBackward.visitedTrainrunSections); const selectedPaths = this.betriebspunktNamePaths( selectedForwardTrainrunSectionGroups, @@ -942,7 +1009,10 @@ export class Sg1LoadTrainrunItemService implements OnDestroy { this.addStartEnde(backwardPaths), ); } - return rateForward < rateBackward; + return { + check: rateForward < rateBackward, + visitedTrainrunSections: visitedTrainrunSections + }; } setDataOnlyForTestPurpose() { @@ -1140,7 +1210,11 @@ export class Sg1LoadTrainrunItemService implements OnDestroy { trainrunId: number, node: Node, returnForwardStartNode: boolean - ): TrainrunSectionGroup[] { + ): { + trainrunSectionGroups: TrainrunSectionGroup[]; + visitedTrainrunSections: TrainrunSection[]; + } { + const visitedTrainrunSections: TrainrunSection[] = []; const trainrunSectionGroups: TrainrunSectionGroup[] = []; let trainrunSection = undefined; let trainrunSectionGroup: TrainrunSectionGroup = undefined; @@ -1149,14 +1223,20 @@ export class Sg1LoadTrainrunItemService implements OnDestroy { const startTrainrunSection = node.getStartTrainrunSection(trainrunId, returnForwardStartNode); if (startTrainrunSection === undefined) { - return trainrunSectionGroups; + return { + trainrunSectionGroups: trainrunSectionGroups, + visitedTrainrunSections: visitedTrainrunSections + }; } const iterator: TrainrunIterator = this.trainrunService.getIterator( node, startTrainrunSection, ); + visitedTrainrunSections.push(startTrainrunSection); while (iterator.hasNext()) { const currentTrainrunSectionNodePair = iterator.next(); + visitedTrainrunSections.push(currentTrainrunSectionNodePair.trainrunSection); + if (trainrunSectionGroup) { trainrunSectionGroup.toTrainrunSectionWithNodes = new TrainrunSectionWithNodes( @@ -1192,7 +1272,10 @@ export class Sg1LoadTrainrunItemService implements OnDestroy { trainrunSectionGroups.push(trainrunSectionGroup); } - return trainrunSectionGroups; + return { + trainrunSectionGroups: trainrunSectionGroups, + visitedTrainrunSections: visitedTrainrunSections + }; } } diff --git a/src/app/view/util/generalViewFunctions.ts b/src/app/view/util/generalViewFunctions.ts index 44af47a8..610cfb7b 100644 --- a/src/app/view/util/generalViewFunctions.ts +++ b/src/app/view/util/generalViewFunctions.ts @@ -81,6 +81,26 @@ export class GeneralViewFunctions { } } + static getStartForwardAndBackwardNode(endNode1: Node, endNode2: Node): { + startForwardNode: Node; + startBackwardNode: Node; + } { + const startForwardNode = GeneralViewFunctions.getLeftOrTopNode( + endNode1, + endNode2, + ); + + const startBackwardNode = + endNode1.getId() === startForwardNode.getId() + ? endNode2 + : endNode1; + + return { + startForwardNode: startForwardNode, + startBackwardNode: startBackwardNode + }; + } + static getRightOrBottomNode(node1: Node, node2: Node): Node { const posNode1: Vec2D = new Vec2D( node1.getPositionX(), From 48aa95625eaf562e26811c52e92dda3cee12a61b Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Mon, 28 Oct 2024 11:04:18 +0100 Subject: [PATCH 154/197] Update USERMANUAL.md --- documentation/USERMANUAL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/USERMANUAL.md b/documentation/USERMANUAL.md index 694d5746..bbe7ead6 100644 --- a/documentation/USERMANUAL.md +++ b/documentation/USERMANUAL.md @@ -180,4 +180,4 @@ creation of comprehensive and visually appealing network representations. - [DATA MODEL](DATA_MODEL.md) ## Technical documentation -- [Trainrun iterator](/technical/trainrun_iterations.md) +- [Trainrun iterator](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/main/documentation/technical/trainrun_iterations.md) From e102df2a4e26008138b7b167d7060c36f06d4b7f Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Mon, 28 Oct 2024 11:04:56 +0100 Subject: [PATCH 155/197] Update trainrun_iterations.md --- documentation/technical/trainrun_iterations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/technical/trainrun_iterations.md b/documentation/technical/trainrun_iterations.md index 903cf211..af87e51f 100644 --- a/documentation/technical/trainrun_iterations.md +++ b/documentation/technical/trainrun_iterations.md @@ -8,7 +8,7 @@ https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/pull/32 To iterate starting from a node of interest with the orientation passed through the trainrun section, you can use the sample code (pattern) below. The iteration will proceed along the trainrun. Be aware that this does not ensure traveling through the full train run. -https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/main/documentation/CREATE_TRAINRUN.md#trainrun-path-with-holes-missing-sections +[See also](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/main/documentation/CREATE_TRAINRUN.md#special-cases) ```typescript From 7cfb16df7370c1f29ca76357d5751d5c793eec80 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Mon, 28 Oct 2024 11:06:12 +0100 Subject: [PATCH 156/197] Update trainrun_iterations.md --- documentation/technical/trainrun_iterations.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/documentation/technical/trainrun_iterations.md b/documentation/technical/trainrun_iterations.md index af87e51f..3cfb3b4b 100644 --- a/documentation/technical/trainrun_iterations.md +++ b/documentation/technical/trainrun_iterations.md @@ -8,6 +8,9 @@ https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/pull/32 To iterate starting from a node of interest with the orientation passed through the trainrun section, you can use the sample code (pattern) below. The iteration will proceed along the trainrun. Be aware that this does not ensure traveling through the full train run. +![image](https://github.com/user-attachments/assets/d87b842c-7696-4e81-aa78-75cc966b5306) +*Example Netzgrafik with missing sections (See the cargo trainrun GTwo_Part_trainrun)* + [See also](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/main/documentation/CREATE_TRAINRUN.md#special-cases) ```typescript From cdaf0137c49aee7aa94d2b78413793cc732eb7da Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Mon, 28 Oct 2024 11:06:52 +0100 Subject: [PATCH 157/197] Update trainrun_iterations.md --- documentation/technical/trainrun_iterations.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/documentation/technical/trainrun_iterations.md b/documentation/technical/trainrun_iterations.md index 3cfb3b4b..ee70f63a 100644 --- a/documentation/technical/trainrun_iterations.md +++ b/documentation/technical/trainrun_iterations.md @@ -8,11 +8,6 @@ https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/pull/32 To iterate starting from a node of interest with the orientation passed through the trainrun section, you can use the sample code (pattern) below. The iteration will proceed along the trainrun. Be aware that this does not ensure traveling through the full train run. -![image](https://github.com/user-attachments/assets/d87b842c-7696-4e81-aa78-75cc966b5306) -*Example Netzgrafik with missing sections (See the cargo trainrun GTwo_Part_trainrun)* - -[See also](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/main/documentation/CREATE_TRAINRUN.md#special-cases) - ```typescript // create forward iterator @@ -41,7 +36,12 @@ The iteration will proceed along the trainrun. Be aware that this does not ensur ### Complete Train Run Iterator - Over All Train Run Parts Iterator pattern for iterating through all train run parts separately. - + +![image](https://github.com/user-attachments/assets/d87b842c-7696-4e81-aa78-75cc966b5306) +*Example Netzgrafik with missing sections (See the cargo trainrun GTwo_Part_trainrun)* + +[See also](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/main/documentation/CREATE_TRAINRUN.md#special-cases) + ```typescript getForwardTrainrunPartIterator(trainrunSection : TrainrunSection) { // find both start nodes ( N1 - N2 - N3 - N4 ) => N1 , N2 From dfdfa693f332c0c48d15912f5f1f68474d380ec1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:07:43 +0100 Subject: [PATCH 158/197] chore(main): release netzgrafik-frontend 2.9.1 (#327) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index a3906fc0..bb18e556 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.9.0" + ".": "2.9.1" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 0caad61c..fab419c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.9.1](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.0...netzgrafik-frontend-v2.9.1) (2024-10-28) + + +### Bug Fixes + +* 320 bug graphical timetable streckengrafik renders only one trainrun segement ([#325](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/325)) ([790f53b](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/790f53b7f7493cc7204719643dd368eccad89d16)) + ## [2.9.0](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.8.0...netzgrafik-frontend-v2.9.0) (2024-10-24) diff --git a/package-lock.json b/package-lock.json index 1474f0ff..8608c89c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.9.0", + "version": "2.9.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.9.0", + "version": "2.9.1", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index 7d933020..f90601bc 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.9.0", + "version": "2.9.1", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From 296d69f61b5f2843d4872e161c4976d35dbe5bef Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Mon, 28 Oct 2024 14:56:09 +0100 Subject: [PATCH 159/197] removed - no longer required (#329) --- .../continuous-integration-secure.yml | 102 ------------------ 1 file changed, 102 deletions(-) delete mode 100644 .github/workflows/continuous-integration-secure.yml diff --git a/.github/workflows/continuous-integration-secure.yml b/.github/workflows/continuous-integration-secure.yml deleted file mode 100644 index d9e00451..00000000 --- a/.github/workflows/continuous-integration-secure.yml +++ /dev/null @@ -1,102 +0,0 @@ -name: Continuous Integration Secure -# Secure execution of continuous integration jobs -# which are performed upon completion of the -# "Continuous Integration" workflow -# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ -on: - workflow_run: - workflows: ['Continuous Integration'] - types: [completed] - -permissions: - deployments: write - packages: write - pull-requests: write - -jobs: - preview-image: - runs-on: ubuntu-latest - if: > - github.event.workflow_run.conclusion == 'success' && ( - github.event.workflow_run.event == 'pull_request' || ( - github.event.workflow_run.event == 'push' && - github.event.workflow_run.head_branch == 'main' - ) - ) - env: - PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0] != null && github.event.workflow_run.pull_requests[0].number || '' }} - IMAGE_REPO: ghcr.io/${{ github.repository }}-preview - steps: - - uses: actions/checkout@v4 - - uses: actions/download-artifact@v4 - with: - name: build - path: dist/netzgrafik-frontend/ - run-id: ${{ github.event.workflow_run.id }} - # TODO: Create GH_ACTIONS_ARTIFACT_DOWNLOAD secret - github-token: ${{ secrets.GH_ACTIONS_ARTIFACT_DOWNLOAD }} - - name: Remove files without allowed extensions - uses: actions/github-script@v7 - with: - script: | - const fs = require('fs'), - path = require('path'), - allowedExtensions = - /^\.(s?css|html?|m?js|json|ts|map|ico|jpe?g|png|svg|woff2|txt|gitignore|gitkeep|stackblitzrc)$/, - distDir = path.resolve('dist/netzgrafik-frontend'); - - // Removes all files not matching allowed extensions from given directory. - fs.readdirSync(distDir, { withFileTypes: true, recursive: true }) - .filter((d) => d.isFile() && !allowedExtensions.test(path.extname(d.name))) - .forEach((d) => { - console.log(`Removing ${path.join(d.path, d.name)}`); - fs.unlinkSync(path.join(d.path, d.name)); - }); - - - name: Create GitHub Deployment - id: tag-name - uses: actions/github-script@v7 - with: - script: | - const environment = process.env.PR_NUMBER ? `pr${process.env.PR_NUMBER}` : 'main'; - const payload = { owner: context.repo.owner, repo: context.repo.repo, environment }; - const { data: deployment } = await github.rest.repos.createDeployment({ - ...payload, - ref: context.payload.workflow_run.head_sha, - auto_merge: false, - required_contexts: ['integrity', 'build', 'test', 'lint'] - }); - await github.rest.repos.createDeploymentStatus({ - ...payload, - deployment_id: deployment.id, - state: 'in_progress', - environment_url: `https://${context.repo.repo}-${environment}.app.sbb.ch`, - }); - return environment; - result-encoding: string - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to GitHub Container Repository - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Build and push - uses: docker/build-push-action@v5 - with: - push: true - tags: $IMAGE_REPO:${{ steps.tag-name.outputs.result }} - - - name: "Add 'preview-available' label" - if: env.PR_NUMBER != '' - # This label is used for filtering deployments in ArgoCD - run: gh issue edit "$NUMBER" --add-label "preview-available" - env: - NUMBER: ${{ env.PR_NUMBER }} From 3bb937668df1b9ce5a0aebe05aea8f65a434024e Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Mon, 4 Nov 2024 15:53:33 +0100 Subject: [PATCH 160/197] issue fixed. While combining two trainruns the first trainrun will "survive" and the second one will be deleted. If the trainrun which will be deleted consists of more than one trainrun segment (connected paths) the reported issue will be generated. (#331) --- src/app/services/data/trainrun.service.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/app/services/data/trainrun.service.ts b/src/app/services/data/trainrun.service.ts index 0af88597..92c256d8 100644 --- a/src/app/services/data/trainrun.service.ts +++ b/src/app/services/data/trainrun.service.ts @@ -484,6 +484,13 @@ export class TrainrunService { trainrun1.unselect(); trainrun2.unselect(); + // Change all trainrun sections' trainrunId reference from trainrun2 to trainrun1 + // There can be some other "unconnected" trainrun segments left; those have to be moved to + // trainrun1, which will "survive". + this.trainrunSectionService.getAllTrainrunSectionsForTrainrun(trainrun2.getId()).forEach( + (ts: TrainrunSection) => ts.setTrainrun(trainrun1) + ); + // remove empty trainrun this.deleteTrainrun(trainrun2, false); From c55388b2d58efd788d64f745560c4b37c5d227e9 Mon Sep 17 00:00:00 2001 From: u216993 Date: Mon, 4 Nov 2024 16:09:17 +0100 Subject: [PATCH 161/197] fix: While combining two trainruns the first trainrun will "survive" and the second one will be deleted. If the trainrun which will be deleted consists of more than one trainrun segment (connected paths) the reported issue will be generated. (Test added) --- .../services/data/trainrun.service.spec.ts | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/app/services/data/trainrun.service.spec.ts b/src/app/services/data/trainrun.service.spec.ts index 01307136..07b9c004 100644 --- a/src/app/services/data/trainrun.service.spec.ts +++ b/src/app/services/data/trainrun.service.spec.ts @@ -367,6 +367,46 @@ describe("TrainrunService", () => { expect(trainrunSections4.length).toBe(2); }); + it("combineTwoTrainruns - 002 - two trainrun segments tests", () => { + dataService.loadNetzgrafikDto( + NetzgrafikUnitTesting.getUnitTestNetzgrafik(), + ); + + trainrunSectionService.deleteTrainrunSection(4); + + const ts5: TrainrunSection = + trainrunSectionService.getTrainrunSectionFromId(5); + const ts7: TrainrunSection = + trainrunSectionService.getTrainrunSectionFromId(7); + + const node2: Node = nodeService.getNodeFromId(2); + + const trainrunSections5 = + trainrunSectionService.getAllTrainrunSectionsForTrainrun( + ts5.getTrainrunId(), + ); + const trainrunSections7 = + trainrunSectionService.getAllTrainrunSectionsForTrainrun( + ts7.getTrainrunId(), + ); + + trainrunService.combineTwoTrainruns( + node2, + node2.getPortOfTrainrunSection(7), + node2.getPortOfTrainrunSection(5), + ); + + const trainrunSections75 = + trainrunSectionService.getAllTrainrunSectionsForTrainrun( + ts7.getTrainrunId(), + ); + + expect(trainrunSections75.length).toBe( + trainrunSections5.length + + trainrunSections7.length); + expect(trainrunSections75.length).toBe(3); + }); + it("getRootIterators", () => { dataService.loadNetzgrafikDto( NetzgrafikUnitTesting.getUnitTestNetzgrafik(), From 15e56aec9f9b9c9999f84ae7c00e07d1b54868e8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:11:38 +0100 Subject: [PATCH 162/197] chore(main): release netzgrafik-frontend 2.9.2 (#332) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index bb18e556..50ea231d 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.9.1" + ".": "2.9.2" } diff --git a/CHANGELOG.md b/CHANGELOG.md index fab419c5..221d5666 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.9.2](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.1...netzgrafik-frontend-v2.9.2) (2024-11-04) + + +### Bug Fixes + +* While combining two trainruns the first trainrun will "survive" and the second one will be deleted. If the trainrun which will be deleted consists of more than one trainrun segment (connected paths) the reported issue will be generated. (Test added) ([c55388b](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/c55388b2d58efd788d64f745560c4b37c5d227e9)) + ## [2.9.1](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.0...netzgrafik-frontend-v2.9.1) (2024-10-28) diff --git a/package-lock.json b/package-lock.json index 8608c89c..6f9da32c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.9.1", + "version": "2.9.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.9.1", + "version": "2.9.2", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index f90601bc..6fe30f23 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.9.1", + "version": "2.9.2", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From 28a6d3ae56c436a40e06eed54a3bbc117b97bdb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Henriot?= <142150521+shenriotpro@users.noreply.github.com> Date: Tue, 5 Nov 2024 21:48:02 +0100 Subject: [PATCH 163/197] fix: fix O/D Matrix for trainrun 0 (#337) --- src/app/view/util/origin-destination-graph.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/view/util/origin-destination-graph.ts b/src/app/view/util/origin-destination-graph.ts index 9787d20d..c6412a3e 100644 --- a/src/app/view/util/origin-destination-graph.ts +++ b/src/app/view/util/origin-destination-graph.ts @@ -249,7 +249,8 @@ const buildSectionEdgesFromIterator = ( tsIterator.next(); const ts = tsIterator.current().trainrunSection; const trainrunId = reverseIterator - ? -ts.getTrainrunId() + ? // Minus 1 so we don't conflate 0 with -0. + -ts.getTrainrunId() - 1 : ts.getTrainrunId(); const reverseSection = tsIterator.current().node.getId() !== ts.getTargetNodeId(); From bd269ec3bcbf640e14c6821c22be082dc1ac8323 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 5 Nov 2024 22:01:08 +0100 Subject: [PATCH 164/197] chore(main): release netzgrafik-frontend 2.9.3 (#338) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 50ea231d..3542679c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.9.2" + ".": "2.9.3" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 221d5666..9fa3f5b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.9.3](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.2...netzgrafik-frontend-v2.9.3) (2024-11-05) + + +### Bug Fixes + +* fix O/D Matrix for trainrun 0 ([#337](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/337)) ([28a6d3a](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/28a6d3ae56c436a40e06eed54a3bbc117b97bdb7)) + ## [2.9.2](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.1...netzgrafik-frontend-v2.9.2) (2024-11-04) diff --git a/package-lock.json b/package-lock.json index 6f9da32c..546b1816 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.9.2", + "version": "2.9.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.9.2", + "version": "2.9.3", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index 6fe30f23..c82dc373 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.9.2", + "version": "2.9.3", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From 6275ae17929fbf564b7419896ad11946b90c20b1 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Wed, 6 Nov 2024 13:46:52 +0100 Subject: [PATCH 165/197] fix: 334 bug archived read mode allows to move nodes but not persisted (#336) * fix: problem solved. Navigate forward/backward caused the issue due of "caching" in rendering. * fix: tests and issue resolved * fix: mouse cursor for rect.node_hover_drag_root_background.readonly hover when readonly was not correctly activated --- .../data-views/connectionViewObject.ts | 4 +++- .../editor-main-view/data-views/data.view.spec.ts | 12 ++++++------ .../editor-main-view/data-views/nodeViewObject.ts | 4 +++- .../view/editor-main-view/data-views/nodes.view.scss | 8 ++++---- .../editor-main-view/data-views/noteViewObject.ts | 4 +++- .../data-views/trainrunSectionViewObject.ts | 4 +++- .../data-views/transitionViewObject.ts | 3 ++- 7 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/connectionViewObject.ts b/src/app/view/editor-main-view/data-views/connectionViewObject.ts index 739d536f..6c4899d5 100644 --- a/src/app/view/editor-main-view/data-views/connectionViewObject.ts +++ b/src/app/view/editor-main-view/data-views/connectionViewObject.ts @@ -52,7 +52,9 @@ export class ConnectionsViewObject { "_" + editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() + "_" + - editorView.getLevelOfDetail(); + editorView.getLevelOfDetail() + + "_" + + editorView.trainrunSectionPreviewLineView.getVariantIsWritable(); connection.getPath().forEach((p) => { key += p.toString(); diff --git a/src/app/view/editor-main-view/data-views/data.view.spec.ts b/src/app/view/editor-main-view/data-views/data.view.spec.ts index 79ae5eaf..62b35666 100644 --- a/src/app/view/editor-main-view/data-views/data.view.spec.ts +++ b/src/app/view/editor-main-view/data-views/data.view.spec.ts @@ -189,7 +189,7 @@ describe("Editor-DataView", () => { const cvo = new ConnectionsViewObject(editorView, con, node, false, false); expect(cvo.key).toBe( - "#2@false_15_9_false_(832,144)_(774.4,144)_(793.6,144)_(736,144)_false_false_false_0(832,144)(774.4,144)(793.6,144)(736,144)", + "#2@false_15_9_false_(832,144)_(774.4,144)_(793.6,144)_(736,144)_false_false_false_0_false(832,144)(774.4,144)(793.6,144)(736,144)", ); }); @@ -200,10 +200,10 @@ describe("Editor-DataView", () => { const node = nodeService.getNodeFromId(2); const cvo1 = new NodeViewObject(editorView, node, false); - expect(cvo1.key).toBe("#2@736_64_ZUE_6_5_96_124_false_2_false_true_false_0"); + expect(cvo1.key).toBe("#2@736_64_ZUE_6_5_96_124_false_2_false_true_false_0_false"); const cvo2 = new NodeViewObject(editorView, node, true); - expect(cvo2.key).toBe("#2@736_64_ZUE_6_5_96_124_false_2_true_true_false_0"); + expect(cvo2.key).toBe("#2@736_64_ZUE_6_5_96_124_false_2_true_true_false_0_false"); }); it("NodeViewObject - 001", () => { @@ -213,7 +213,7 @@ describe("Editor-DataView", () => { const note = noteService.getNoteFromId(3); const cvo1 = new NoteViewObject(editorView, note); expect(cvo1.key).toBe( - "#3@1312_160_64_192_

Folgendes

spannend

FETT_Frabcodierter Text_false_0_false_false_0", + "#3@1312_160_64_192_

Folgendes

spannend

FETT_Frabcodierter Text_false_0_false_false_0_false", ); }); @@ -234,7 +234,7 @@ describe("Editor-DataView", () => { false, ); expect(cvo1.key).toBe( - "#3@1234_false_0_39_49_1_21_39_0_39_141_39_0_39_0_20_0_S_20_7/24_4_1_0_S_20_7/24_20_0_false_false_false_false_false_false_false_false_true_true_true_false_false_true_true_0_2_true_true_true_1_false_true_true_0_false_true_true(130,80)(194,80)(254,80)(318,80)", + "#3@1234_false_0_39_49_1_21_39_0_39_141_39_0_39_0_20_0_S_20_7/24_4_1_0_S_20_7/24_20_0_false_false_false_false_false_false_false_false_true_true_true_false_false_true_true_0_false_2_true_true_true_1_false_true_true_0_false_true_true(130,80)(194,80)(254,80)(318,80)", ); }); @@ -245,7 +245,7 @@ describe("Editor-DataView", () => { const trans = nodeService.getNodeFromId(1).getTransitions()[0]; const cvo1 = new TransitionViewObject(editorView, trans, false); expect(cvo1.key).toBe( - "#0@false_false_IC_60_7/24_1_3_0_IC_60_7/24_60_false_false_(320,48)(324,48)(412,48)(416,48)", + "#0@false_false_IC_60_7/24_1_3_0_IC_60_7/24_60_false_false_false(320,48)(324,48)(412,48)(416,48)", ); }); diff --git a/src/app/view/editor-main-view/data-views/nodeViewObject.ts b/src/app/view/editor-main-view/data-views/nodeViewObject.ts index b8e42c70..e58752e7 100644 --- a/src/app/view/editor-main-view/data-views/nodeViewObject.ts +++ b/src/app/view/editor-main-view/data-views/nodeViewObject.ts @@ -45,7 +45,9 @@ export class NodeViewObject { "_" + editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() + "_" + - editorView.getLevelOfDetail() + editorView.getLevelOfDetail() + + "_" + + editorView.trainrunSectionPreviewLineView.getVariantIsWritable() ); } } diff --git a/src/app/view/editor-main-view/data-views/nodes.view.scss b/src/app/view/editor-main-view/data-views/nodes.view.scss index 0dab3138..c82bccca 100644 --- a/src/app/view/editor-main-view/data-views/nodes.view.scss +++ b/src/app/view/editor-main-view/data-views/nodes.view.scss @@ -59,10 +59,6 @@ cursor: default; } -::ng-deep rect.node_hover_drag_root_background.readonly { - cursor: default; -} - ::ng-deep text.node_text.hover { fill: $COLOR_Edit; } @@ -217,6 +213,10 @@ transform: translateX(-64px) translateY(-32px); } +::ng-deep rect.node_hover_drag_root_background.readonly { + cursor: default; +} + ::ng-deep path.node_edit_button { opacity: 0.01; stroke: None; diff --git a/src/app/view/editor-main-view/data-views/noteViewObject.ts b/src/app/view/editor-main-view/data-views/noteViewObject.ts index d1bc1378..0cc8d755 100644 --- a/src/app/view/editor-main-view/data-views/noteViewObject.ts +++ b/src/app/view/editor-main-view/data-views/noteViewObject.ts @@ -36,7 +36,9 @@ export class NoteViewObject { "_" + editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() + "_" + - editorView.getLevelOfDetail() + editorView.getLevelOfDetail() + + "_" + + editorView.trainrunSectionPreviewLineView.getVariantIsWritable() ); } } diff --git a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts index 1643abae..7099f834 100644 --- a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts +++ b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts @@ -135,7 +135,9 @@ export class TrainrunSectionViewObject { "_" + editorView.checkFilterNode(d.getTargetNode()) + "_" + - editorView.getLevelOfDetail(); + editorView.getLevelOfDetail() + + "_" + + editorView.trainrunSectionPreviewLineView.getVariantIsWritable(); cumulativeTravelTimeData.forEach((data) => { key += "_" + data.node.getId(); diff --git a/src/app/view/editor-main-view/data-views/transitionViewObject.ts b/src/app/view/editor-main-view/data-views/transitionViewObject.ts index da69cf39..30098f5f 100644 --- a/src/app/view/editor-main-view/data-views/transitionViewObject.ts +++ b/src/app/view/editor-main-view/data-views/transitionViewObject.ts @@ -52,7 +52,8 @@ export class TransitionViewObject { editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() + "_" + isMuted + - "_"; + "_" + + editorView.trainrunSectionPreviewLineView.getVariantIsWritable(); transition.getPath().forEach((p) => { key += p.toString(); From 9157c648857a738082c75fa8512226745ecfd0a9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:52:39 +0100 Subject: [PATCH 166/197] chore(main): release netzgrafik-frontend 2.9.4 (#339) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 3542679c..928eee2e 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.9.3" + ".": "2.9.4" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fa3f5b6..0597d0ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.9.4](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.3...netzgrafik-frontend-v2.9.4) (2024-11-06) + + +### Bug Fixes + +* 334 bug archived read mode allows to move nodes but not persisted ([#336](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/336)) ([6275ae1](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/6275ae17929fbf564b7419896ad11946b90c20b1)) + ## [2.9.3](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.2...netzgrafik-frontend-v2.9.3) (2024-11-05) diff --git a/package-lock.json b/package-lock.json index 546b1816..c4a94d8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.9.3", + "version": "2.9.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.9.3", + "version": "2.9.4", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index c82dc373..f2649d93 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.9.3", + "version": "2.9.4", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From d7d1776e7bb9fd4872821d315f9a81a8c2313c4d Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Mon, 11 Nov 2024 10:11:36 +0100 Subject: [PATCH 167/197] fix: Simplified third-party JSON import (no port alignment/path precalculation required) (#341) * fix: The import of JSON from third-party providers has been simplified - or allowed. If no node has a port or if all ports are empty or no TrainrunSection has a path, then the import should be adjusted so that all nodes are created and then each train is inserted section by section. This makes the import (exchange) from 3rd party more easy. * fix: documentation * fix: title JSON-Based Data Import from 3rd Party Data Providers --- documentation/DATA_MODEL_JSON.md | 8 +++ .../editor-tools-view.component.ts | 66 ++++++++++++++++--- 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/documentation/DATA_MODEL_JSON.md b/documentation/DATA_MODEL_JSON.md index e85e5c5d..8eea39fd 100644 --- a/documentation/DATA_MODEL_JSON.md +++ b/documentation/DATA_MODEL_JSON.md @@ -18,6 +18,14 @@ To export the current Netzgrafik use the `Export netzgrafik as JSON` button. #### Import The exported data in JSON format can be imported again using the `Import netzgrafik as JSON` button. +##### JSON-Based Data Import from 3rd Party Data Providers +If nodes have no port objects or if no TrainrunSection has a defined path element, the import process will automatically adjust, +respectively create the required elements. This adjustment ensures that all nodes are created first, followed by the systematic +insertion of each train, section by section. Inserting each section by section ensures that the Netzgrafik drawing gets well routed. +This streamlines the import process, making the exchange of data much more straightforward and efficient. +The 3rd party has to care about the nodes' position only. The TrainrunSection routing gets computed while importing, +thus no complex calculation must be reimplemented by the 3rd party provider. + ## JSON Description (basic data structure) ```json diff --git a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts index 3d0adce2..cb0627b3 100644 --- a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts +++ b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts @@ -13,7 +13,9 @@ import {VersionControlService} from "../../services/data/version-control.service import { HaltezeitFachCategories, NetzgrafikDto, + NodeDto, TrainrunCategoryHaltezeit, + TrainrunSectionDto, } from "../../data-structures/business.data.structures"; import {downloadBlob} from "../util/download-utils"; import {map} from "rxjs/operators"; @@ -21,8 +23,12 @@ import {LabelService} from "../../services/data/label.serivce"; import {NetzgrafikColoringService} from "../../services/data/netzgrafikColoring.service"; import {ViewportCullService} from "../../services/ui/viewport.cull.service"; import {LevelOfDetailService} from "../../services/ui/level.of.detail.service"; -import {_ViewRepeaterItemContext} from "@angular/cdk/collections"; -import {buildEdges, computeNeighbors, computeShortestPaths, topoSort} from "../util/origin-destination-graph"; +import { + buildEdges, + computeNeighbors, + computeShortestPaths, + topoSort +} from "../util/origin-destination-graph"; @Component({ selector: "sbb-editor-tools-view-component", @@ -67,7 +73,7 @@ export class EditorToolsViewComponent { const file = param.target.files[0]; const reader = new FileReader(); reader.onload = () => { - const netzgrafikDto = JSON.parse(reader.result.toString()); + const netzgrafikDto: NetzgrafikDto = JSON.parse(reader.result.toString()); if ( "nodes" in netzgrafikDto && "trainrunSections" in netzgrafikDto && @@ -75,12 +81,54 @@ export class EditorToolsViewComponent { "resources" in netzgrafikDto && "metadata" in netzgrafikDto ) { - this.logger.log("onLoad; load netzgrafik: ", netzgrafikDto); + // prepare JSON import this.uiInteractionService.showNetzgrafik(); this.uiInteractionService.closeNodeStammdaten(); this.uiInteractionService.closePerlenkette(); this.nodeService.unselectAllNodes(); - this.dataService.loadNetzgrafikDto(netzgrafikDto); + + // check for 3rd Party JSON generated files + const detect3rdParty = + netzgrafikDto.nodes.find((n: NodeDto) => + n.ports === undefined) !== undefined + || + netzgrafikDto.nodes.filter((n: NodeDto) => + n.ports?.length === 0).length === netzgrafikDto.nodes.length + || + netzgrafikDto.trainrunSections.find((ts: TrainrunSectionDto) => + ts.path === undefined || + ts.path?.path === undefined || + ts.path?.path?.length === 0 + ) !== undefined; + + // import data + if ( + netzgrafikDto.trainrunSections.length === 0 + || + !detect3rdParty + ) { + // ----------------------------------------------- + // Default: Netzgrafik-Editor exported JSON + // ----------------------------------------------- + this.dataService.loadNetzgrafikDto(netzgrafikDto); + // ----------------------------------------------- + } else { + // -------------------------------------------------------------------------------- + // 3rd party generated JSON detected + // -------------------------------------------------------------------------------- + console.log("Import: Automatic Port Alignment Detection - 3rd Party Data Import."); + // -------------------------------------------------------------------------------- + // (Step 1) Import only nodes + // (Step 2) Import nodes and trainrunSectiosn by trainrun inseration (copy => create) + const netzgrafikOnlyNodeDto: NetzgrafikDto = JSON.parse(reader.result.toString()); + netzgrafikOnlyNodeDto.trainruns = []; + netzgrafikOnlyNodeDto.trainrunSections = []; + this.dataService.loadNetzgrafikDto(netzgrafikOnlyNodeDto); + this.dataService.insertCopyNetzgrafikDto(netzgrafikDto); + this.trainrunService.propagateInitialConsecutiveTimes(); + } + + // recompute viewport this.uiInteractionService.viewportCenteringOnNodesBoundingBox(); } }; @@ -207,7 +255,7 @@ export class EditorToolsViewComponent { return this.versionControlService.getVariantIsWritable(); } - private buildCSVString(headers: string[], rows: string[][]): string{ + private buildCSVString(headers: string[], rows: string[][]): string { const separator = ";"; const contentData: string[] = []; @@ -503,7 +551,7 @@ export class EditorToolsViewComponent { // TODO: ideally this would be 24 hours, but performance is a concern. // One idea to optimize would be to consider the minimum time window before the schedule repeats (LCM). // Draft here: https://colab.research.google.com/drive/1Z1r2uU2pgffWxCbG_wt2zoLStZKzWleE#scrollTo=F6vOevK6znee - const timeLimit = 16*60; + const timeLimit = 16 * 60; const headers: string[] = []; headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.origin:Origin`); @@ -547,8 +595,8 @@ export class EditorToolsViewComponent { } const [totalCost, connections] = costs; const row = [origin.getBetriebspunktName(), destination.getBetriebspunktName(), - (totalCost-connections*connectionPenalty).toString(), - connections.toString(), totalCost.toString()]; + (totalCost - connections * connectionPenalty).toString(), + connections.toString(), totalCost.toString()]; rows.push(row); }); }); From 2d75f2da23d63a87638bac8ba3f1551f54054b9c Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Mon, 11 Nov 2024 12:53:16 +0100 Subject: [PATCH 168/197] fix: CSV base data export (#343) * fix: The import of JSON from third-party providers has been simplified - or allowed. If no node has a port or if all ports are empty or no TrainrunSection has a path, then the import should be adjusted so that all nodes are created and then each train is inserted section by section. This makes the import (exchange) from 3rd party more easy. * fix: documentation * fix: title JSON-Based Data Import from 3rd Party Data Providers * fix: export CSV was broken, header missed two fields (region, IPV) --- .../editor-tools-view-component/editor-tools-view.component.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts index cb0627b3..2bab9871 100644 --- a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts +++ b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts @@ -273,6 +273,8 @@ export class EditorToolsViewComponent { headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.bp:BP`); headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.station:Station`); headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.category:category`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.region:Region`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.passengerConnectionTimeIPV:passengerConnectionTimeIPV`); headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.passengerConnectionTimeA:Passenger_connection_time_A`); headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.passengerConnectionTimeB:Passenger_connection_time_B`); headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.passengerConnectionTimeC:Passenger_connection_time_C`); From a5e2a03d68c9e785be77614b506685c9d9180ebd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 13:01:54 +0100 Subject: [PATCH 169/197] chore(main): release netzgrafik-frontend 2.9.5 (#342) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 928eee2e..b111e299 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.9.4" + ".": "2.9.5" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 0597d0ae..abb61432 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [2.9.5](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.4...netzgrafik-frontend-v2.9.5) (2024-11-11) + + +### Bug Fixes + +* CSV base data export ([#343](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/343)) ([2d75f2d](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/2d75f2da23d63a87638bac8ba3f1551f54054b9c)) +* Simplified third-party JSON import (no port alignment/path precalculation required) ([#341](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/341)) ([d7d1776](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/d7d1776e7bb9fd4872821d315f9a81a8c2313c4d)) + ## [2.9.4](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.3...netzgrafik-frontend-v2.9.4) (2024-11-06) diff --git a/package-lock.json b/package-lock.json index c4a94d8f..42de0f81 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.9.4", + "version": "2.9.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.9.4", + "version": "2.9.5", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index f2649d93..2179f03c 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.9.4", + "version": "2.9.5", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From 5adbfc4ea750623f55fed4a9c7478a6a76528fba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 13:28:16 +0100 Subject: [PATCH 170/197] chore(deps): bump cookie, socket.io and express (#344) Bumps [cookie](https://github.com/jshttp/cookie), [socket.io](https://github.com/socketio/socket.io) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together. Updates `cookie` from 0.4.2 to 0.7.2 - [Release notes](https://github.com/jshttp/cookie/releases) - [Commits](https://github.com/jshttp/cookie/compare/v0.4.2...v0.7.2) Updates `socket.io` from 4.7.5 to 4.8.1 - [Release notes](https://github.com/socketio/socket.io/releases) - [Changelog](https://github.com/socketio/socket.io/blob/main/CHANGELOG.md) - [Commits](https://github.com/socketio/socket.io/compare/socket.io@4.7.5...socket.io@4.8.1) Updates `express` from 4.21.0 to 4.21.1 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/4.21.1/History.md) - [Commits](https://github.com/expressjs/express/compare/4.21.0...4.21.1) --- updated-dependencies: - dependency-name: cookie dependency-type: indirect - dependency-name: socket.io dependency-type: indirect - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 42de0f81..18539519 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7690,9 +7690,9 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, "engines": { "node": ">= 0.6" @@ -8759,9 +8759,9 @@ } }, "node_modules/engine.io": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", - "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz", + "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -8769,7 +8769,7 @@ "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "2.0.0", - "cookie": "~0.4.1", + "cookie": "~0.7.2", "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.2.1", @@ -9735,9 +9735,9 @@ "dev": true }, "node_modules/express": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", - "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "dev": true, "dependencies": { "accepts": "~1.3.8", @@ -9745,7 +9745,7 @@ "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -9777,9 +9777,9 @@ } }, "node_modules/express/node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, "engines": { "node": ">= 0.6" @@ -15924,16 +15924,16 @@ } }, "node_modules/socket.io": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", - "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", + "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", "dev": true, "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.5.2", + "engine.io": "~6.6.0", "socket.io-adapter": "~2.5.2", "socket.io-parser": "~4.2.4" }, From 9d71b4aa9608eaec4d50f7f13178693305ea4a3c Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Wed, 13 Nov 2024 10:12:01 +0100 Subject: [PATCH 171/197] fix: 346 bug importing 3rd party json misses detecting non stop transitions (#347) * fix: non-stop transition is fine and user information with the help of logService * fix: non-stop transition detection and refactoring done --- .../editor-tools-view.component.ts | 154 ++++++++++++------ src/assets/i18n/de.json | 2 + src/assets/i18n/en.json | 2 + src/assets/i18n/fr.json | 2 + src/assets/i18n/it.json | 2 + 5 files changed, 112 insertions(+), 50 deletions(-) diff --git a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts index 2bab9871..647708dc 100644 --- a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts +++ b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts @@ -73,7 +73,21 @@ export class EditorToolsViewComponent { const file = param.target.files[0]; const reader = new FileReader(); reader.onload = () => { - const netzgrafikDto: NetzgrafikDto = JSON.parse(reader.result.toString()); + let netzgrafikDto: any; + try { + netzgrafikDto = JSON.parse(reader.result.toString()); + } catch (err: any) { + const msg = $localize`:@@app.view.editor-side-view.editor-tools-view-component.import-netzgrafik-error:JSON error`; + this.logger.error(msg); + return; + } + + if (netzgrafikDto === undefined) { + const msg = $localize`:@@app.view.editor-side-view.editor-tools-view-component.import-netzgrafik-error:JSON error`; + this.logger.error(msg); + return; + } + if ( "nodes" in netzgrafikDto && "trainrunSections" in netzgrafikDto && @@ -81,56 +95,12 @@ export class EditorToolsViewComponent { "resources" in netzgrafikDto && "metadata" in netzgrafikDto ) { - // prepare JSON import - this.uiInteractionService.showNetzgrafik(); - this.uiInteractionService.closeNodeStammdaten(); - this.uiInteractionService.closePerlenkette(); - this.nodeService.unselectAllNodes(); - - // check for 3rd Party JSON generated files - const detect3rdParty = - netzgrafikDto.nodes.find((n: NodeDto) => - n.ports === undefined) !== undefined - || - netzgrafikDto.nodes.filter((n: NodeDto) => - n.ports?.length === 0).length === netzgrafikDto.nodes.length - || - netzgrafikDto.trainrunSections.find((ts: TrainrunSectionDto) => - ts.path === undefined || - ts.path?.path === undefined || - ts.path?.path?.length === 0 - ) !== undefined; - - // import data - if ( - netzgrafikDto.trainrunSections.length === 0 - || - !detect3rdParty - ) { - // ----------------------------------------------- - // Default: Netzgrafik-Editor exported JSON - // ----------------------------------------------- - this.dataService.loadNetzgrafikDto(netzgrafikDto); - // ----------------------------------------------- - } else { - // -------------------------------------------------------------------------------- - // 3rd party generated JSON detected - // -------------------------------------------------------------------------------- - console.log("Import: Automatic Port Alignment Detection - 3rd Party Data Import."); - // -------------------------------------------------------------------------------- - // (Step 1) Import only nodes - // (Step 2) Import nodes and trainrunSectiosn by trainrun inseration (copy => create) - const netzgrafikOnlyNodeDto: NetzgrafikDto = JSON.parse(reader.result.toString()); - netzgrafikOnlyNodeDto.trainruns = []; - netzgrafikOnlyNodeDto.trainrunSections = []; - this.dataService.loadNetzgrafikDto(netzgrafikOnlyNodeDto); - this.dataService.insertCopyNetzgrafikDto(netzgrafikDto); - this.trainrunService.propagateInitialConsecutiveTimes(); - } - - // recompute viewport - this.uiInteractionService.viewportCenteringOnNodesBoundingBox(); + this.processNetzgrafikJSON(netzgrafikDto); + return; } + + const msg = $localize`:@@app.view.editor-side-view.editor-tools-view-component.import-netzgrafik-error:JSON error`; + this.logger.error(msg); }; reader.readAsText(file); @@ -605,4 +575,88 @@ export class EditorToolsViewComponent { return this.buildCSVString(headers, rows); } + + private detectNetzgrafikJSON3rdParty(netzgrafikDto: NetzgrafikDto): boolean { + return netzgrafikDto.nodes.find((n: NodeDto) => + n.ports === undefined) !== undefined + || + netzgrafikDto.nodes.filter((n: NodeDto) => + n.ports?.length === 0).length === netzgrafikDto.nodes.length + || + netzgrafikDto.trainrunSections.find((ts: TrainrunSectionDto) => + ts.path === undefined || + ts.path?.path === undefined || + ts.path?.path?.length === 0 + ) !== undefined; + } + + private processNetzgrafikJSON3rdParty(netzgrafikDto: NetzgrafikDto) { + // -------------------------------------------------------------------------------- + // 3rd party generated JSON detected + // -------------------------------------------------------------------------------- + console.log("Import: Automatic Port Alignment Detection - 3rd Party Data Import."); + const msg = $localize`:@@app.view.editor-side-view.editor-tools-view-component.import-netzgrafik-as-json-info-3rd-party:3rd party import`; + this.logger.info(msg); + + + // -------------------------------------------------------------------------------- + // (Step 1) Import only nodes + const netzgrafikOnlyNodeDto: NetzgrafikDto = Object.assign({}, netzgrafikDto); + netzgrafikOnlyNodeDto.trainruns = []; + netzgrafikOnlyNodeDto.trainrunSections = []; + this.dataService.loadNetzgrafikDto(netzgrafikOnlyNodeDto); + + // (Step 2) Import nodes and trainrunSectiosn by trainrun inseration (copy => create) + this.dataService.insertCopyNetzgrafikDto(netzgrafikDto); + + // step(3) Check whether a transitions object was given when not + // departureTime - arrivatelTime == 0 => non-stop + this.nodeService.getNodes().forEach((n) => { + n.getTransitions().forEach((trans) => { + const p1 = n.getPort(trans.getPortId1()); + const p2 = n.getPort(trans.getPortId2()); + let arrivalTime = p1.getTrainrunSection().getTargetArrival(); + if (p1.getTrainrunSection().getSourceNodeId() === n.getId()) { + arrivalTime = p1.getTrainrunSection().getSourceArrival(); + } + let departureTime = p2.getTrainrunSection().getTargetDeparture(); + if (p2.getTrainrunSection().getSourceNodeId() === n.getId()) { + departureTime = p2.getTrainrunSection().getSourceDeparture(); + } + trans.setIsNonStopTransit(arrivalTime - departureTime === 0); + }); + }); + + // step(4) Recalc/propagte consecutive times + this.trainrunService.propagateInitialConsecutiveTimes(); + } + + private processNetzgrafikJSON(netzgrafikDto: NetzgrafikDto) { + // prepare JSON import + this.uiInteractionService.showNetzgrafik(); + this.uiInteractionService.closeNodeStammdaten(); + this.uiInteractionService.closePerlenkette(); + this.nodeService.unselectAllNodes(); + + // import data + if ( + netzgrafikDto.trainrunSections.length === 0 + || + !this.detectNetzgrafikJSON3rdParty(netzgrafikDto) + ) { + // ----------------------------------------------- + // Default: Netzgrafik-Editor exported JSON + // ----------------------------------------------- + this.dataService.loadNetzgrafikDto(netzgrafikDto); + // ----------------------------------------------- + } else { + // ----------------------------------------------- + // 3rd Party: Netzgrafik-Editor exported JSON + // ----------------------------------------------- + this.processNetzgrafikJSON3rdParty(netzgrafikDto); + } + + // recompute viewport + this.uiInteractionService.viewportCenteringOnNodesBoundingBox(); + } } diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index 057c7fb3..b281c335 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -441,7 +441,9 @@ "export-netzgrafik": "Netzgrafik exportieren", "export-netzgrafik-as-json": "Netzgrafik als JSON exportieren", "import-netzgrafik": "Netzgrafik importieren", + "import-netzgrafik-error": "Netzgrafik konnte nicht importiert werden.", "import-netzgrafik-as-json": "Netzgrafik aus JSON importieren", + "import-netzgrafik-as-json-info-3rd-party": "Drittanbieter JSON Daten erkannt: Import Heuristik angewandt.", "export-trainruns": "Zugfahrten exportieren", "export-trainruns-as-csv": "Zugfahrten als CSV exportieren", "export-trainruns-as-csv-excel": "In Excel: Daten -> Aus Text/CSV -> Filename ... importieren", diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index b508ee71..82afa7fd 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -441,7 +441,9 @@ "export-netzgrafik": "Export netzgrafik", "export-netzgrafik-as-json": "Export netzgrafik as JSON", "import-netzgrafik": "Import netzgrafik", + "import-netzgrafik-error": "Netzgrafik could not be imported.", "import-netzgrafik-as-json": "Import netzgrafik as JSON", + "import-netzgrafik-as-json-info-3rd-party": "Third-party JSON data detected: Import heuristic applied.", "export-trainruns": "Export trainruns", "export-trainruns-as-csv": "Export trainruns as CSV", "export-trainruns-as-csv-excel": "In Excel: Data -> From Text/CSV -> Import ... filename", diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index 9bb805f9..b7f92d9b 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -440,7 +440,9 @@ "export-netzgrafik": "Exporter le réticulaire", "export-netzgrafik-as-json": "Exporter le réticulaire au format JSON", "import-netzgrafik": "Importer le réticulaire", + "import-netzgrafik-error": "Le réticulaire au format JSON n'ont pas pu être importés.", "import-netzgrafik-as-json": "Importer le réticulaire au format JSON", + "import-netzgrafik-as-json-info-3rd-party": "Réticulaire au format JSON de tiers détectées: heuristique d'importation appliquée.", "export-trainruns": "Exporter les trajets de train", "export-trainruns-as-csv": "Exporter les trajets de train au format CSV", "export-trainruns-as-csv-excel": "Dans Excel : Données -> txt/CSV -> Importer ... nom de fichier", diff --git a/src/assets/i18n/it.json b/src/assets/i18n/it.json index b513a4c1..b0ca7ba5 100644 --- a/src/assets/i18n/it.json +++ b/src/assets/i18n/it.json @@ -438,9 +438,11 @@ "print": "Print", "netzgrafik": "Netzgrafik", "export-netzgrafik": "Export netzgrafik", + "import-netzgrafik-error": "Netzgrafik could not be imported.", "export-netzgrafik-as-json": "Export netzgrafik as JSON", "import-netzgrafik": "Import netzgrafik", "import-netzgrafik-as-json": "Import netzgrafik as JSON", + "import-netzgrafik-as-json-info-3rd-party": "Third-party JSON data detected: Import heuristic applied.", "export-trainruns": "Export trainruns", "export-trainruns-as-csv": "Export trainruns as CSV", "export-trainruns-as-csv-excel": "In Excel: Data -> From Text/CSV -> Import ... filename", From 721876e7bd0c1acbbee9804f88cb1b9eebe2a669 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 10:15:04 +0100 Subject: [PATCH 172/197] chore(main): release netzgrafik-frontend 2.9.6 (#348) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index b111e299..86dc4d17 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.9.5" + ".": "2.9.6" } diff --git a/CHANGELOG.md b/CHANGELOG.md index abb61432..bba987a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.9.6](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.5...netzgrafik-frontend-v2.9.6) (2024-11-13) + + +### Bug Fixes + +* 346 bug importing 3rd party json misses detecting non stop transitions ([#347](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/347)) ([9d71b4a](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/9d71b4aa9608eaec4d50f7f13178693305ea4a3c)) + ## [2.9.5](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.4...netzgrafik-frontend-v2.9.5) (2024-11-11) diff --git a/package-lock.json b/package-lock.json index 18539519..7d6520c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.9.5", + "version": "2.9.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.9.5", + "version": "2.9.6", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index 2179f03c..b82a9a8f 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.9.5", + "version": "2.9.6", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From 72f859920ac425668356fcb095f2ef49f019421f Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 14 Nov 2024 15:47:15 +0100 Subject: [PATCH 173/197] fix: 350 bug delete node or trainrunsections cause low performance (#351) * fix: performance issue fixed * fix: performance issue fixed --- .../services/data/trainrunsection.service.ts | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/app/services/data/trainrunsection.service.ts b/src/app/services/data/trainrunsection.service.ts index 2af4192f..b12e9370 100644 --- a/src/app/services/data/trainrunsection.service.ts +++ b/src/app/services/data/trainrunsection.service.ts @@ -814,31 +814,46 @@ export class TrainrunSectionService implements OnDestroy { this.operation.emit(new TrainrunOperation(OperationType.update, trainrunSection.getTrainrun())); } - deleteListOfTrainrunSections(trainrunSections: TrainrunSection[]) { + deleteListOfTrainrunSections(trainrunSections: TrainrunSection[], enforceUpdate = true) { trainrunSections.forEach((trainrunSection) => { - this.deleteTrainrunSectionAndCleanupNodes(trainrunSection); + this.deleteTrainrunSectionAndCleanupNodes(trainrunSection, false); }); - this.trainrunSectionsUpdated(); + if (enforceUpdate) { + this.nodeService.transitionsUpdated(); + this.nodeService.connectionsUpdated(); + this.trainrunService.trainrunsUpdated(); + this.trainrunSectionsUpdated(); + } } - deleteAllVisibleTrainrunSections() { + deleteAllVisibleTrainrunSections(enforceUpdate = true) { const allTrainrunSections = this.trainrunSectionsStore.trainrunSections; allTrainrunSections.forEach((trainrunSection: TrainrunSection) => { if (this.filterService.filterTrainrunsection(trainrunSection)) { - this.deleteTrainrunSectionAndCleanupNodes(trainrunSection); + this.deleteTrainrunSectionAndCleanupNodes(trainrunSection, false); } }); - this.trainrunSectionsUpdated(); + if (enforceUpdate){ + this.nodeService.transitionsUpdated(); + this.nodeService.connectionsUpdated(); + this.trainrunService.trainrunsUpdated(); + this.trainrunSectionsUpdated(); + } } - deleteAllNonVisibleTrainrunSections() { + deleteAllNonVisibleTrainrunSections(enforceUpdate = true) { const allTrainrunSections = this.trainrunSectionsStore.trainrunSections; allTrainrunSections.forEach((trainrunSection: TrainrunSection) => { if (!this.filterService.filterTrainrunsection(trainrunSection)) { - this.deleteTrainrunSectionAndCleanupNodes(trainrunSection); + this.deleteTrainrunSectionAndCleanupNodes(trainrunSection, false); } }); - this.trainrunSectionsUpdated(); + if (enforceUpdate) { + this.nodeService.transitionsUpdated(); + this.nodeService.connectionsUpdated(); + this.trainrunService.trainrunsUpdated(); + this.trainrunSectionsUpdated(); + } } deleteTrainrunSection(trainrunSectionId: number, enforceUpdate = true) { From 985ae287085f1d16d9cdc4dbc2f93d582bfa308d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 16:43:17 +0100 Subject: [PATCH 174/197] chore(main): release netzgrafik-frontend 2.9.7 (#352) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 86dc4d17..c20748f4 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.9.6" + ".": "2.9.7" } diff --git a/CHANGELOG.md b/CHANGELOG.md index bba987a9..582e387c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.9.7](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.6...netzgrafik-frontend-v2.9.7) (2024-11-14) + + +### Bug Fixes + +* 350 bug delete node or trainrunsections cause low performance ([#351](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/351)) ([72f8599](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/72f859920ac425668356fcb095f2ef49f019421f)) + ## [2.9.6](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.5...netzgrafik-frontend-v2.9.6) (2024-11-13) diff --git a/package-lock.json b/package-lock.json index 7d6520c6..ab4d80d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.9.6", + "version": "2.9.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.9.6", + "version": "2.9.7", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index b82a9a8f..23d3648d 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.9.6", + "version": "2.9.7", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From c8eb61364b7cf5ab8d41a2a04eba3e9d35c46562 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 14 Nov 2024 17:13:03 +0100 Subject: [PATCH 175/197] fix: performance issue fixed (part 2) (#354) --- src/app/services/data/node.service.ts | 5 +++-- .../editor-main-view/data-views/editor.keyEvents.ts | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/app/services/data/node.service.ts b/src/app/services/data/node.service.ts index e705bfb1..c49bce1a 100644 --- a/src/app/services/data/node.service.ts +++ b/src/app/services/data/node.service.ts @@ -286,7 +286,7 @@ export class NodeService implements OnDestroy { this.makeLabelIDCounterMap(this.getNodes()), ); this.filterService.clearDeletetFilterNodeLabels(deletetLabelIds); - this.deleteNodeWithoutUpdate(nodeId); + this.deleteNodeWithoutUpdate(nodeId, enforceUpdate); if (enforceUpdate) { this.nodesUpdated(); } @@ -1277,12 +1277,13 @@ export class NodeService implements OnDestroy { return {minCoordX: minX, minCoordY: minY, maxCoordX: maxX, maxCoordY: maxY}; } - private deleteNodeWithoutUpdate(nodeId: number) { + private deleteNodeWithoutUpdate(nodeId: number, enforceUpdate = true) { const node = this.getNodeFromId(nodeId); const connectedTrainrunSections = node.getConnectedTrainrunSections(); if (connectedTrainrunSections.length !== 0) { this.trainrunSectionService.deleteListOfTrainrunSections( node.getConnectedTrainrunSections(), + enforceUpdate ); } this.nodesStore.nodes = this.nodesStore.nodes.filter( diff --git a/src/app/view/editor-main-view/data-views/editor.keyEvents.ts b/src/app/view/editor-main-view/data-views/editor.keyEvents.ts index 0629dd36..6671c6b4 100644 --- a/src/app/view/editor-main-view/data-views/editor.keyEvents.ts +++ b/src/app/view/editor-main-view/data-views/editor.keyEvents.ts @@ -558,7 +558,13 @@ export class EditorKeyEvents { } } }); + + this.trainrunSectionService.trainrunSectionsUpdated(); + this.trainrunService.trainrunsUpdated(); + this.nodeSerivce.transitionsUpdated(); + this.nodeSerivce.connectionsUpdated(); this.nodeSerivce.nodesUpdated(); + if (selectedNodeDeleted) { this.uiInteractionService.closeNodeStammdaten(); } @@ -572,7 +578,13 @@ export class EditorKeyEvents { this.nodeSerivce.deleteNode(n.getId(), false); } }); + + this.trainrunSectionService.trainrunSectionsUpdated(); + this.trainrunService.trainrunsUpdated(); + this.nodeSerivce.transitionsUpdated(); + this.nodeSerivce.connectionsUpdated(); this.nodeSerivce.nodesUpdated(); + if (selectedNodeDeleted) { this.uiInteractionService.closeNodeStammdaten(); } From f0969f1594bd8e0cafbc8fa4d842bcb755d504f9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 17:14:28 +0100 Subject: [PATCH 176/197] chore(main): release netzgrafik-frontend 2.9.8 (#355) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index c20748f4..903bc7e4 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.9.7" + ".": "2.9.8" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 582e387c..c4babba3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.9.8](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.7...netzgrafik-frontend-v2.9.8) (2024-11-14) + + +### Bug Fixes + +* performance issue fixed (part 2) ([#354](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/354)) ([c8eb613](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/c8eb61364b7cf5ab8d41a2a04eba3e9d35c46562)) + ## [2.9.7](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.6...netzgrafik-frontend-v2.9.7) (2024-11-14) diff --git a/package-lock.json b/package-lock.json index ab4d80d6..a3e66579 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.9.7", + "version": "2.9.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.9.7", + "version": "2.9.8", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index 23d3648d..1fdb023e 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.9.7", + "version": "2.9.8", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From f939df6640159e868802de80f12a40469bf8d943 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 14 Nov 2024 22:08:42 +0100 Subject: [PATCH 177/197] fix: performance opt / refactored (#356) --- .../data-views/editor.keyEvents.ts | 41 ++++++++----------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/editor.keyEvents.ts b/src/app/view/editor-main-view/data-views/editor.keyEvents.ts index 6671c6b4..de57b37d 100644 --- a/src/app/view/editor-main-view/data-views/editor.keyEvents.ts +++ b/src/app/view/editor-main-view/data-views/editor.keyEvents.ts @@ -193,7 +193,7 @@ export class EditorKeyEvents { } private onInsertAllVisibleElementsFromCopyCache(): boolean { - if ( !this.trainrunSectionPreviewLineView.getVariantIsWritable() ) { + if (!this.trainrunSectionPreviewLineView.getVariantIsWritable()) { return true; } this.copyService.insertCopiedNetzgrafik(); @@ -201,7 +201,7 @@ export class EditorKeyEvents { } private onRevertLastChange(): boolean { - if ( !this.trainrunSectionPreviewLineView.getVariantIsWritable() ) { + if (!this.trainrunSectionPreviewLineView.getVariantIsWritable()) { return true; } this.undoService.undo(); @@ -209,7 +209,7 @@ export class EditorKeyEvents { } private onDuplicate(): boolean { - if ( !this.trainrunSectionPreviewLineView.getVariantIsWritable() ) { + if (!this.trainrunSectionPreviewLineView.getVariantIsWritable()) { return true; } @@ -500,7 +500,7 @@ export class EditorKeyEvents { } private onKeyPressedInsert(): boolean { - if ( !this.trainrunSectionPreviewLineView.getVariantIsWritable() ) { + if (!this.trainrunSectionPreviewLineView.getVariantIsWritable()) { return true; } @@ -559,11 +559,7 @@ export class EditorKeyEvents { } }); - this.trainrunSectionService.trainrunSectionsUpdated(); - this.trainrunService.trainrunsUpdated(); - this.nodeSerivce.transitionsUpdated(); - this.nodeSerivce.connectionsUpdated(); - this.nodeSerivce.nodesUpdated(); + this.netzgrafikElementsUpdated(); if (selectedNodeDeleted) { this.uiInteractionService.closeNodeStammdaten(); @@ -579,12 +575,6 @@ export class EditorKeyEvents { } }); - this.trainrunSectionService.trainrunSectionsUpdated(); - this.trainrunService.trainrunsUpdated(); - this.nodeSerivce.transitionsUpdated(); - this.nodeSerivce.connectionsUpdated(); - this.nodeSerivce.nodesUpdated(); - if (selectedNodeDeleted) { this.uiInteractionService.closeNodeStammdaten(); } @@ -599,7 +589,7 @@ export class EditorKeyEvents { } private onKeyPressedDelete(): boolean { - if ( !this.trainrunSectionPreviewLineView.getVariantIsWritable() ) { + if (!this.trainrunSectionPreviewLineView.getVariantIsWritable()) { return true; } const selectedTrainrunSectionId = this.getSelectedTrainSectionId(); @@ -629,18 +619,10 @@ export class EditorKeyEvents { /* handle Nodes and Trainruns/TrainrunSections */ if (this.filterService.isAnyFilterActive()) { this.deleteTrainrunsAndEmptyNodesIfFilteringActive(); - this.trainrunSectionService.trainrunSectionsUpdated(); - this.trainrunService.trainrunsUpdated(); - this.nodeSerivce.transitionsUpdated(); - this.nodeSerivce.connectionsUpdated(); - this.nodeSerivce.nodesUpdated(); - this.noteSerivce.notesUpdated(); } else { this.removeAllSelectedNodes(); - this.nodeSerivce.transitionsUpdated(); - this.nodeSerivce.connectionsUpdated(); - this.nodeSerivce.nodesUpdated(); } + this.netzgrafikElementsUpdated(); /* handle Notes */ this.removeAllSelectedNotes(); @@ -677,4 +659,13 @@ export class EditorKeyEvents { return false; } + + + private netzgrafikElementsUpdated() { + this.trainrunSectionService.trainrunSectionsUpdated(); + this.trainrunService.trainrunsUpdated(); + this.nodeSerivce.transitionsUpdated(); + this.nodeSerivce.connectionsUpdated(); + this.nodeSerivce.nodesUpdated(); + } } From e0330ff7a80eafb9a07a53259b700cf4d1f3b630 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 22:10:27 +0100 Subject: [PATCH 178/197] chore(main): release netzgrafik-frontend 2.9.9 (#357) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 903bc7e4..c9e8c89a 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.9.8" + ".": "2.9.9" } diff --git a/CHANGELOG.md b/CHANGELOG.md index c4babba3..b0bff2a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.9.9](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.8...netzgrafik-frontend-v2.9.9) (2024-11-14) + + +### Bug Fixes + +* performance opt / refactored ([#356](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/356)) ([f939df6](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/f939df6640159e868802de80f12a40469bf8d943)) + ## [2.9.8](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.7...netzgrafik-frontend-v2.9.8) (2024-11-14) diff --git a/package-lock.json b/package-lock.json index a3e66579..edfdee59 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.9.8", + "version": "2.9.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.9.8", + "version": "2.9.9", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index 1fdb023e..64397985 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.9.8", + "version": "2.9.9", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From 338b69ffc724400c3233afdcf7b87e7b0ffafdf9 Mon Sep 17 00:00:00 2001 From: Louis Greiner <57864277+louisgreiner@users.noreply.github.com> Date: Fri, 15 Nov 2024 16:02:05 +0100 Subject: [PATCH 179/197] Refacto language + add navigator preferences (#349) * feat: initialize with navigator language * rename: use language instead of locale * feat: set language as DOM property for external use * refacto: change language without reload + external language setter * feat: remove side menu language selector * fix comments * let localstorage empty if not explicitly select language * lint * refacto localStorage logic Signed-off-by: Louis Greiner * add validation for localStorage getter Signed-off-by: Louis Greiner --------- Signed-off-by: Louis Greiner --- src/app/app.component.html | 14 +-- src/app/app.component.ts | 17 ++- src/app/core/i18n/i18n.module.ts | 12 +-- src/app/core/i18n/i18n.service.ts | 161 +++++++++++++++------------- src/app/core/i18n/translate.pipe.ts | 6 +- 5 files changed, 109 insertions(+), 101 deletions(-) diff --git a/src/app/app.component.html b/src/app/app.component.html index 9e422d63..b791315f 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -10,16 +10,6 @@ > {{ 'app.user-manual' | translate }} - - 🇬🇧 English - 🇩🇪 Deutsch - 🇫🇷 Français - - {{ environmentLabel @@ -35,8 +25,8 @@ ; + protected currentLanguage: string = this.i18nService.language; projectInMenu: Observable; @@ -46,6 +47,7 @@ export class AppComponent { private trainrunSectionService: TrainrunSectionService, private nodeService: NodeService, private labelService: LabelService, + private i18nService: I18nService, ) { if (!this.disableBackend) { this.authenticated = authService.initialized; @@ -58,9 +60,16 @@ export class AppComponent { } } - changeLocale(locale: string) { - localStorage.setItem("locale", locale); - location.reload(); + @Input() + get language() { + return this.currentLanguage; + } + + set language(language: string) { + if (language !== this.currentLanguage) { + this.i18nService.setLanguage(language); + this.currentLanguage = language; + } } @Input() diff --git a/src/app/core/i18n/i18n.module.ts b/src/app/core/i18n/i18n.module.ts index e19914ff..c7929192 100644 --- a/src/app/core/i18n/i18n.module.ts +++ b/src/app/core/i18n/i18n.module.ts @@ -1,23 +1,23 @@ import {NgModule, APP_INITIALIZER, LOCALE_ID} from "@angular/core"; import {CommonModule} from "@angular/common"; import {TranslatePipe} from "./translate.pipe"; -import {I18n} from "./i18n.service"; +import {I18nService} from "./i18n.service"; @NgModule({ declarations: [TranslatePipe], // Declare the pipe imports: [CommonModule], providers: [ - I18n, + I18nService, { // Load locale data at app start-up provide: APP_INITIALIZER, - useFactory: (i18n: I18n) => () => i18n.setLocale(), - deps: [I18n], + useFactory: (i18nService: I18nService) => () => i18nService.setLanguage(), + deps: [I18nService], multi: true, }, { // Set the runtime locale for the app provide: LOCALE_ID, - useFactory: (i18n: I18n) => i18n.locale, - deps: [I18n], + useFactory: (i18nService: I18nService) => i18nService.language, + deps: [I18nService], } ], exports: [TranslatePipe] // Export the pipe diff --git a/src/app/core/i18n/i18n.service.ts b/src/app/core/i18n/i18n.service.ts index 7fdf6394..13eab38e 100644 --- a/src/app/core/i18n/i18n.service.ts +++ b/src/app/core/i18n/i18n.service.ts @@ -5,85 +5,94 @@ import {loadTranslations} from "@angular/localize"; @Injectable({ providedIn: "root", }) - export class I18n { - locale = "en"; - readonly allowedLocales = ["en", "fr", "de", "it"]; - translations: any = {}; - - async setLocale() { - const userLocale = localStorage.getItem("locale"); - - // If the user has a preferred language stored in LocalStorage, use it. - if (userLocale && this.allowedLocales.includes(userLocale)) { - this.locale = userLocale; - } else { - localStorage.setItem("locale", this.locale); - } - - // Use webpack magic string to only include required locale data - const localeModule = await import( - /* webpackInclude: /(en|de|fr|it)\.mjs$/ */ - `/node_modules/@angular/common/locales/${this.locale}.mjs` - ); - registerLocaleData(localeModule.default); - - // Load translation file initially - await this.loadTranslations(); - } - - async loadTranslations() { - const localeTranslationsModule = await import( - `src/assets/i18n/${this.locale}.json` - ); - - // Ensure translations are flattened if necessary - this.translations = this.flattenTranslations(localeTranslationsModule.default); - - // Load translations for the current locale at runtime - loadTranslations(this.translations); +export class I18nService { + readonly allowedLanguages = ["en", "fr", "de", "it"]; + private currentLanguage: string = this.getLanguageFromStorage() || this.detectNavigatorLanguage(); + translations: any = {}; + + get language(): string { + return this.currentLanguage; + } + + async setLanguage(language?: string) { + if (language && this.allowedLanguages.includes(this.language)) { + this.setLanguageToStorage(language); + this.currentLanguage = language; } - - // Helper function to flatten nested translations - // nested JSON : - // { - // "app": { - // "login": "Login", - // "models": {...} - // } - // } - // flattened JSON : - // { - // "app.login": "Login", - // "app.models...": ..., - // "app.models...": ... - // } - private flattenTranslations(translations: any): any { - const flattenedTranslations = {}; - - function flatten(obj, prefix = "") { - for (const key in obj) { - if (typeof obj[key] === "string") { - flattenedTranslations[prefix + key] = obj[key]; - } else if (typeof obj[key] === "object") { - flatten(obj[key], prefix + key + "."); - } + + const languageModule = await import( + /* webpackInclude: /(en|de|fr|it)\.mjs$/ */ + `/node_modules/@angular/common/locales/${this.language}.mjs` + ); + registerLocaleData(languageModule.default); + + await this.loadTranslations(); + } + + private setLanguageToStorage(language: string) { + localStorage.setItem("i18nLng", language); + } + + private getLanguageFromStorage(): string | null { + const lang = localStorage.getItem("i18nLng"); + return this.allowedLanguages.includes(lang) ? lang : null; + } + + private detectNavigatorLanguage(): string { + const navigatorLanguage = navigator.language.slice(0, 2); + return this.allowedLanguages.includes(navigatorLanguage) ? navigatorLanguage : this.allowedLanguages[0]; + } + + async loadTranslations() { + const languageTranslationsModule = await import( + `src/assets/i18n/${this.language}.json` + ); + + this.translations = this.flattenTranslations(languageTranslationsModule.default); + loadTranslations(this.translations); + } + + // Helper function to flatten nested translations + // nested JSON : + // { + // "app": { + // "login": "Login", + // "models": {...} + // } + // } + // flattened JSON : + // { + // "app.login": "Login", + // "app.models...": ..., + // "app.models...": ... + // } + private flattenTranslations(translations: any): any { + const flattenedTranslations = {}; + + function flatten(obj, prefix = "") { + for (const key in obj) { + if (typeof obj[key] === "string") { + flattenedTranslations[prefix + key] = obj[key]; + } else if (typeof obj[key] === "object") { + flatten(obj[key], prefix + key + "."); } } - - flatten(translations); - return flattenedTranslations; } - - // Used for the pipe and allowing parameters - translate(key: string, params?: any): string { - let translation = this.translations[key] || key; - - if (params) { - Object.keys(params).forEach(param => { - translation = translation.replace(`{$${param}}`, params[param]); - }); - } - - return translation; + + flatten(translations); + return flattenedTranslations; + } + + // Used for the pipe and allowing parameters + translate(key: string, params?: any): string { + let translation = this.translations[key] || key; + + if (params) { + Object.keys(params).forEach(param => { + translation = translation.replace(`{$${param}}`, params[param]); + }); } + + return translation; } +} diff --git a/src/app/core/i18n/translate.pipe.ts b/src/app/core/i18n/translate.pipe.ts index bb38f238..e11045a3 100644 --- a/src/app/core/i18n/translate.pipe.ts +++ b/src/app/core/i18n/translate.pipe.ts @@ -1,14 +1,14 @@ import {Pipe, PipeTransform} from "@angular/core"; -import {I18n} from "./i18n.service"; +import {I18nService} from "./i18n.service"; @Pipe({ name: "translate", pure: false }) export class TranslatePipe implements PipeTransform { - constructor(private i18n: I18n) {} + constructor(private i18nService: I18nService) {} transform(key: string, params?: any): string { - return this.i18n.translate(key, params); + return this.i18nService.translate(key, params); } } From 992356722772db594e48a1f7aa8511b904a62c79 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Fri, 22 Nov 2024 11:51:43 +0100 Subject: [PATCH 180/197] fix: warn users when having unsymmetric times (#359) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: warn users when having unsymmetric times * fix: refactored - only trainrun section elements (text) with warnings will have an .... tag. This improves rendering performance. * Update src/app/view/editor-tools-view-component/editor-tools-view.component.ts Thanks Co-authored-by: Serge Croisé * fix: message - symmetry broken a + b = sum * fix: rounding / (machine epsilon) issue fixed * fix: message output text and refactored (simplified, improved readability) for trainrun section validation * fix: epsilon issue fixed (caused by % 60 operation) * code formatting * fix: test added * Update src/assets/i18n/fr.json Co-authored-by: Serge Croisé * fix: Serge comments --------- Co-authored-by: Serge Croisé Co-authored-by: Louis Greiner --- src/app/models/trainrunsection.model.ts | 24 ++++++- .../util/trainrunsection.validator.ts | 39 ++++++++--- .../util/transition.validator.spec.ts | 61 ++++++++++-------- .../data-views/trainrunsections.view.ts | 64 +++++++++++++++++-- .../editor-tools-view.component.ts | 9 ++- src/assets/i18n/de.json | 1 + src/assets/i18n/en.json | 1 + src/assets/i18n/fr.json | 13 ++-- src/assets/i18n/it.json | 1 + 9 files changed, 165 insertions(+), 48 deletions(-) diff --git a/src/app/models/trainrunsection.model.ts b/src/app/models/trainrunsection.model.ts index 0460aee7..12d67a48 100644 --- a/src/app/models/trainrunsection.model.ts +++ b/src/app/models/trainrunsection.model.ts @@ -201,7 +201,7 @@ export class TrainrunSection { return formattedText; } - shiftAllTimes(translateMinutes: number, mirrorSourceDeparture : boolean) { + shiftAllTimes(translateMinutes: number, mirrorSourceDeparture: boolean) { this.sourceDeparture.time += translateMinutes; this.targetArrival.time += translateMinutes; this.sourceArrival.time += translateMinutes; @@ -503,6 +503,26 @@ export class TrainrunSection { }; } + getTargetArrivalWarning() { + return this.targetArrival.warning; + } + + getSourceArrivalWarning() { + return this.sourceArrival.warning; + } + + getTargetDepartureWarning() { + return this.targetDeparture.warning; + } + + getSourceDepartureWarning() { + return this.sourceDeparture.warning; + } + + getTravelTimeWarning() { + return this.travelTime.warning; + } + resetTargetArrivalWarning() { this.targetArrival.warning = null; } @@ -639,7 +659,7 @@ export class TrainrunSection { resourceId: this.resourceId, specificTrainrunSectionFrequencyId: - this.specificTrainrunSectionFrequencyId, + this.specificTrainrunSectionFrequencyId, path: this.path, warnings: this.warnings, }; diff --git a/src/app/services/util/trainrunsection.validator.ts b/src/app/services/util/trainrunsection.validator.ts index bc533598..3fd32912 100644 --- a/src/app/services/util/trainrunsection.validator.ts +++ b/src/app/services/util/trainrunsection.validator.ts @@ -6,11 +6,14 @@ export class TrainrunsectionValidator { trainrunSection.resetSourceDepartureWarning(); trainrunSection.resetTargetDepartureWarning(); + TrainrunsectionValidator.validateTravelTimeOneSection(trainrunSection); + TrainrunsectionValidator.validateUnsymmetricTimesOneSection(trainrunSection); + } + + static validateTravelTimeOneSection(trainrunSection: TrainrunSection) { const calculatedTargetArrivalTime = - (trainrunSection.getSourceDeparture() + trainrunSection.getTravelTime()) % - 60; - if (Math.abs(calculatedTargetArrivalTime - trainrunSection.getTargetArrival()) - > 1 / 60) { + (trainrunSection.getSourceDeparture() + trainrunSection.getTravelTime()) % 60; + if (Math.abs(calculatedTargetArrivalTime - trainrunSection.getTargetArrival()) > 1 / 60) { trainrunSection.setTargetArrivalWarning( $localize`:@@app.services.util.trainrunsection-validator.target-arrival-not-reacheable.title:Target Arrival Warning`, $localize`:@@app.services.util.trainrunsection-validator.target-arrival-not-reacheable.description:Target arrival time cannot be reached`, @@ -20,10 +23,8 @@ export class TrainrunsectionValidator { } const calculatedSourceArrivalTime = - (trainrunSection.getTargetDeparture() + trainrunSection.getTravelTime()) % - 60; - if (Math.abs(calculatedSourceArrivalTime - trainrunSection.getSourceArrival()) - > 1 / 60) { + (trainrunSection.getTargetDeparture() + trainrunSection.getTravelTime()) % 60; + if (Math.abs(calculatedSourceArrivalTime - trainrunSection.getSourceArrival()) > 1 / 60) { trainrunSection.setSourceArrivalWarning( $localize`:@@app.services.util.trainrunsection-validator.source-arrival-not-reacheable.title:Source Arrival Warning`, $localize`:@@app.services.util.trainrunsection-validator.source-arrival-not-reacheable.description:Source arrival time cannot be reached`, @@ -33,6 +34,28 @@ export class TrainrunsectionValidator { } } + static validateUnsymmetricTimesOneSection(trainrunSection: TrainrunSection) { + // check for broken symmetry (times) + trainrunSection.resetSourceDepartureWarning(); + trainrunSection.resetTargetDepartureWarning(); + const sourceSum = MathUtils.round(trainrunSection.getSourceArrival() + trainrunSection.getSourceDeparture(), 4); + const sourceSymmetricCheck = Math.abs(sourceSum % 60) < 1 / 60; + if (!sourceSymmetricCheck) { + trainrunSection.setSourceArrivalWarning($localize`:@@app.services.util.trainrunsection-validator.broken-symmetry:Broken symmetry`, + "" + (trainrunSection.getSourceArrival() + " + " + trainrunSection.getSourceDeparture()) + " = " + sourceSum); + trainrunSection.setSourceDepartureWarning($localize`:@@app.services.util.trainrunsection-validator.broken-symmetry:Broken symmetry`, + "" + (trainrunSection.getSourceArrival() + " + " + trainrunSection.getSourceDeparture()) + " = " + sourceSum); + } + const targetSum = MathUtils.round(trainrunSection.getTargetArrival() + trainrunSection.getTargetDeparture(), 4); + const targetSymmetricCheck = Math.abs(targetSum % 60) < 1 / 60; + if (!targetSymmetricCheck) { + trainrunSection.setTargetArrivalWarning($localize`:@@app.services.util.trainrunsection-validator.broken-symmetry:Broken symmetry`, + "" + (trainrunSection.getTargetArrival() + " + " + trainrunSection.getTargetDeparture()) + " = " + targetSum); + trainrunSection.setTargetDepartureWarning($localize`:@@app.services.util.trainrunsection-validator.broken-symmetry:Broken symmetry`, + "" + (trainrunSection.getTargetArrival() + " + " + trainrunSection.getTargetDeparture()) + " = " + targetSum); + } + } + static validateTravelTime(trainrunSection: TrainrunSection) { if (trainrunSection.getTravelTime() < 1) { trainrunSection.setTravelTimeWarning( diff --git a/src/app/services/util/transition.validator.spec.ts b/src/app/services/util/transition.validator.spec.ts index 1b26244b..a90efb83 100644 --- a/src/app/services/util/transition.validator.spec.ts +++ b/src/app/services/util/transition.validator.spec.ts @@ -184,16 +184,16 @@ describe("TransitionValidator", () => { nodeHaltezeiten[ trainrunSections.trainrunSection1.getTrainrun().getTrainrunCategory() .fachCategory - ].haltezeit; + ].haltezeit; trainrunSections.trainrunSection2.setSourceDeparture( trainrunSections.trainrunSection1.getSourceArrival() - - trainrunHaltezeit - - 1, + trainrunHaltezeit - + 1, ); trainrunSections.trainrunSection2.setTargetDeparture( trainrunSections.trainrunSection1.getTargetArrival() - - trainrunHaltezeit - - 1, + trainrunHaltezeit - + 1, ); trainrunSections.trainrunSection1.resetTargetArrivalWarning(); @@ -276,16 +276,16 @@ describe("TransitionValidator", () => { nodeHaltezeiten[ trainrunSections.trainrunSection2.getTrainrun().getTrainrunCategory() .fachCategory - ].haltezeit; + ].haltezeit; trainrunSections.trainrunSection1.setSourceDeparture( trainrunSections.trainrunSection2.getSourceArrival() - - trainrunHaltezeit - - 1, + trainrunHaltezeit - + 1, ); trainrunSections.trainrunSection1.setTargetDeparture( trainrunSections.trainrunSection2.getTargetArrival() - - trainrunHaltezeit - - 1, + trainrunHaltezeit - + 1, ); trainrunSections.trainrunSection1.resetTargetArrivalWarning(); @@ -386,16 +386,16 @@ describe("TransitionValidator", () => { nodeHaltezeiten[ trainrunSections.trainrunSection2.getTrainrun().getTrainrunCategory() .fachCategory - ].haltezeit; + ].haltezeit; trainrunSections.trainrunSection1.setSourceDeparture( trainrunSections.trainrunSection2.getSourceArrival() - - trainrunHaltezeit - - 1, + trainrunHaltezeit - + 1, ); trainrunSections.trainrunSection1.setTargetDeparture( trainrunSections.trainrunSection2.getTargetArrival() - - trainrunHaltezeit - - 1, + trainrunHaltezeit - + 1, ); trainrunSections.trainrunSection1.resetTargetArrivalWarning(); @@ -496,16 +496,16 @@ describe("TransitionValidator", () => { nodeHaltezeiten[ trainrunSections.trainrunSection2.getTrainrun().getTrainrunCategory() .fachCategory - ].haltezeit; + ].haltezeit; trainrunSections.trainrunSection1.setSourceDeparture( trainrunSections.trainrunSection2.getSourceArrival() - - trainrunHaltezeit - - 1, + trainrunHaltezeit - + 1, ); trainrunSections.trainrunSection1.setTargetDeparture( trainrunSections.trainrunSection2.getTargetArrival() - - trainrunHaltezeit - - 1, + trainrunHaltezeit - + 1, ); trainrunSections.trainrunSection1.resetTargetArrivalWarning(); @@ -606,16 +606,16 @@ describe("TransitionValidator", () => { nodeHaltezeiten[ trainrunSections.trainrunSection2.getTrainrun().getTrainrunCategory() .fachCategory - ].haltezeit; + ].haltezeit; trainrunSections.trainrunSection1.setSourceDeparture( trainrunSections.trainrunSection2.getSourceArrival() - - trainrunHaltezeit - - 1, + trainrunHaltezeit - + 1, ); trainrunSections.trainrunSection2.setTargetDeparture( trainrunSections.trainrunSection1.getTargetArrival() - - trainrunHaltezeit - - 1, + trainrunHaltezeit - + 1, ); trainrunSections.trainrunSection1.resetTargetArrivalWarning(); @@ -682,4 +682,15 @@ describe("TransitionValidator", () => { false, ); }); + + it("Validate Test - 007", () => { + dataService.loadNetzgrafikDto( + NetzgrafikUnitTesting.getUnitTestNetzgrafik(), + ); + const ts1 = trainrunSectionService.getTrainrunSectionFromId(4); + ts1.setSourceDeparture((ts1.getSourceDeparture() + 1) % 60); + const a = ts1.getSourceArrival(); + const b = ts1.getSourceDeparture(); + expect(ts1.getSourceArrivalWarning().description).toBe("" + a + " + " + b + " = " + (a + b)); + }); }); diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 0232ec33..087a05b3 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -178,6 +178,31 @@ export class TrainrunSectionsView { } } + static getWarning( + trainrunSection: TrainrunSection, + textElement: TrainrunSectionText, + ): string { + if (!TrainrunSectionsView.hasWarning(trainrunSection, textElement)) { + return ""; + } + switch (textElement) { + case TrainrunSectionText.SourceDeparture: + return trainrunSection.getSourceDepartureWarning().title + ": " + trainrunSection.getSourceDepartureWarning().description; + case TrainrunSectionText.SourceArrival: + return trainrunSection.getSourceArrivalWarning().title + ": " + trainrunSection.getSourceArrivalWarning().description; + case TrainrunSectionText.TargetDeparture: + return trainrunSection.getTargetDepartureWarning().title + ": " + trainrunSection.getTargetDepartureWarning().description; + case TrainrunSectionText.TargetArrival: + return trainrunSection.getTargetArrivalWarning().title + ": " + trainrunSection.getTargetArrivalWarning().description; + case TrainrunSectionText.TrainrunSectionTravelTime: + return trainrunSection.getTravelTimeWarning().title + ": " + trainrunSection.getTravelTimeWarning().description; + case TrainrunSectionText.TrainrunSectionName: + default: + return ""; + } + return ""; + } + static getTime( trainrunSection: TrainrunSection, textElement: TrainrunSectionText, @@ -1221,7 +1246,7 @@ export class TrainrunSectionsView { connectedTrainIds: any, atSource: boolean, ) { - if (!this.editorView.trainrunSectionPreviewLineView.getVariantIsWritable()){ + if (!this.editorView.trainrunSectionPreviewLineView.getVariantIsWritable()) { return; } groupEnter @@ -1314,21 +1339,21 @@ export class TrainrunSectionsView { ); } - createTrainrunSectionElement( + private createInternTrainrunSectionElementFilteringWarningElements( groupEnter: d3.Selector, selectedTrainrun: Trainrun, connectedTrainIds: any, textElement: TrainrunSectionText, - enableEvents = true + enableEvents = true, + hasWarning = true ) { - const atSource = textElement === TrainrunSectionText.SourceArrival || textElement === TrainrunSectionText.SourceDeparture; const isArrival = textElement === TrainrunSectionText.SourceArrival || textElement === TrainrunSectionText.TargetArrival; - groupEnter + const renderingObjects = groupEnter .filter( (d: TrainrunSectionViewObject) => this.filterTrainrunsectionAtNode(d.trainrunSection, atSource) && @@ -1336,7 +1361,8 @@ export class TrainrunSectionsView { d.trainrunSection, atSource, isArrival, - ), + ) && + TrainrunSectionsView.hasWarning(d.trainrunSection, textElement) === hasWarning ) .append(StaticDomTags.EDGE_LINE_TEXT_SVG) .attr("class", (d: TrainrunSectionViewObject) => @@ -1417,6 +1443,32 @@ export class TrainrunSectionsView { ); } }); + + if (hasWarning) { + renderingObjects + .append("svg:title") + .text((d: TrainrunSectionViewObject) => { + return TrainrunSectionsView.getWarning(d.trainrunSection, textElement); + }); + } + } + + createTrainrunSectionElement( + groupEnter: d3.Selector, + selectedTrainrun: Trainrun, + connectedTrainIds: any, + textElement: TrainrunSectionText, + enableEvents = true + ) { + // pass(1) : render all elements without warnings + this.createInternTrainrunSectionElementFilteringWarningElements( + groupEnter, selectedTrainrun, connectedTrainIds, textElement, enableEvents, false + ); + // pass(2) : render all elements with warnings + // especially warning_msg + this.createInternTrainrunSectionElementFilteringWarningElements( + groupEnter, selectedTrainrun, connectedTrainIds, textElement, enableEvents, true + ); } createTrainrunSectionGotoInfoElement( diff --git a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts index 647708dc..a4bba36d 100644 --- a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts +++ b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts @@ -29,6 +29,7 @@ import { computeShortestPaths, topoSort } from "../util/origin-destination-graph"; +import {TrainrunsectionValidator} from "../../services/util/trainrunsection.validator"; @Component({ selector: "sbb-editor-tools-view-component", @@ -627,8 +628,14 @@ export class EditorToolsViewComponent { }); }); - // step(4) Recalc/propagte consecutive times + // step(4) Recalc/propagate consecutive times this.trainrunService.propagateInitialConsecutiveTimes(); + + // step(5) Validate all trainrun sections + this.trainrunSectionService.getTrainrunSections().forEach((ts) => { + TrainrunsectionValidator.validateOneSection(ts); + TrainrunsectionValidator.validateTravelTime(ts); + }); } private processNetzgrafikJSON(netzgrafikDto: NetzgrafikDto) { diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index b281c335..2722128e 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -86,6 +86,7 @@ } }, "trainrunsection-validator": { + "broken-symmetry": "Symmetrie gebrochen", "target-arrival-not-reacheable": { "title": "Ziel Ankunft Warnung", "description": "Zielankunftszeit kann nicht erreicht werden" diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 82afa7fd..5b448180 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -86,6 +86,7 @@ } }, "trainrunsection-validator": { + "broken-symmetry": "Broken symmetry", "target-arrival-not-reacheable": { "title": "Target Arrival Warning", "description": "Target arrival time cannot be reached" diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index b7f92d9b..d729aa90 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -86,9 +86,10 @@ } }, "trainrunsection-validator": { + "broken-symmetry": "Symétrie brisée", "target-arrival-not-reacheable": { - "title": "Avertissement d'arrivée à la destination", - "description": "L'heure d'arrivée à la destination ne peut être atteinte" + "title": "Avertissement d'arrivée à destination", + "description": "L'heure d'arrivée à destination ne peut être atteinte" }, "source-arrival-not-reacheable": { "title": "Avertissement d'arrivée à l'origine", @@ -109,12 +110,12 @@ "description": "L'heure de départ à l'origine ne peut être atteinte" }, "target-arrival-not-reacheable": { - "title": "Avertissement d'arrivée à la destination", - "description": "L'heure d'arrivée à la destination ne peut être atteinte" + "title": "Avertissement d'arrivée à destination", + "description": "L'heure d'arrivée à destination ne peut être atteinte" }, "target-departure-not-reacheable": { - "title": "Avertissement de départ à la destination", - "description": "L'heure de départ à la destination ne peut être atteinte" + "title": "Avertissement de départ à destination", + "description": "L'heure de départ à destination ne peut être atteinte" } } } diff --git a/src/assets/i18n/it.json b/src/assets/i18n/it.json index b0ca7ba5..1dd450fd 100644 --- a/src/assets/i18n/it.json +++ b/src/assets/i18n/it.json @@ -86,6 +86,7 @@ } }, "trainrunsection-validator": { + "broken-symmetry": "Broken symmetry", "target-arrival-not-reacheable": { "title": "Target Arrival Warning", "description": "Target arrival time cannot be reached" From 7d3f42d1c0b670358908743316a949996548d8b8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 12:07:42 +0100 Subject: [PATCH 181/197] chore(main): release netzgrafik-frontend 2.9.10 (#362) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index c9e8c89a..0c6703ee 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.9.9" + ".": "2.9.10" } diff --git a/CHANGELOG.md b/CHANGELOG.md index b0bff2a0..c2663f78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.9.10](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.9...netzgrafik-frontend-v2.9.10) (2024-11-22) + + +### Bug Fixes + +* warn users when having unsymmetric times ([#359](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/359)) ([9923567](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/992356722772db594e48a1f7aa8511b904a62c79)) + ## [2.9.9](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.8...netzgrafik-frontend-v2.9.9) (2024-11-14) diff --git a/package-lock.json b/package-lock.json index edfdee59..8a4281c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.9.9", + "version": "2.9.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.9.9", + "version": "2.9.10", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index 64397985..f6309068 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.9.9", + "version": "2.9.10", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From b275b515ca6924fb46e91fabe804b757b163e61e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 10:10:36 +0100 Subject: [PATCH 182/197] chore(deps): bump cross-spawn from 7.0.3 to 7.0.6 (#363) Bumps [cross-spawn](https://github.com/moxystudio/node-cross-spawn) from 7.0.3 to 7.0.6. - [Changelog](https://github.com/moxystudio/node-cross-spawn/blob/master/CHANGELOG.md) - [Commits](https://github.com/moxystudio/node-cross-spawn/compare/v7.0.3...v7.0.6) --- updated-dependencies: - dependency-name: cross-spawn dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8a4281c3..94b8ad0d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7950,9 +7950,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", From 1f28a51cc1c093188f9a1a17ca06fd178c1668ff Mon Sep 17 00:00:00 2001 From: Louis Greiner <57864277+louisgreiner@users.noreply.github.com> Date: Thu, 28 Nov 2024 09:33:39 +0100 Subject: [PATCH 183/197] remove variante read/write button from standalone env (#364) Signed-off-by: Louis Greiner --- src/app/view/editor-menu/editor-menu.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/view/editor-menu/editor-menu.component.html b/src/app/view/editor-menu/editor-menu.component.html index 7ca57c1b..2f8a789f 100644 --- a/src/app/view/editor-menu/editor-menu.component.html +++ b/src/app/view/editor-menu/editor-menu.component.html @@ -1,5 +1,5 @@

-
+
{{ label$ | async }} From 454c201abf3228dacecb8685f80545ef13eea554 Mon Sep 17 00:00:00 2001 From: Louis Greiner <57864277+louisgreiner@users.noreply.github.com> Date: Thu, 28 Nov 2024 11:22:47 +0100 Subject: [PATCH 184/197] fix: correct connections->transfers naming for O/D matrix (#365) * correct connections->transfers naming for O/D matrix Signed-off-by: Louis Greiner * fixup! correct connections->transfers naming for O/D matrix --------- Signed-off-by: Louis Greiner --- documentation/ORIGIN_DESTINATION_MATRIX.md | 11 +++-------- .../editor-tools-view.component.ts | 2 +- src/assets/i18n/de.json | 10 +++++----- src/assets/i18n/en.json | 2 +- src/assets/i18n/fr.json | 2 +- src/assets/i18n/it.json | 10 +++++----- 6 files changed, 16 insertions(+), 21 deletions(-) diff --git a/documentation/ORIGIN_DESTINATION_MATRIX.md b/documentation/ORIGIN_DESTINATION_MATRIX.md index 4c78697d..0f2a1ab2 100644 --- a/documentation/ORIGIN_DESTINATION_MATRIX.md +++ b/documentation/ORIGIN_DESTINATION_MATRIX.md @@ -1,18 +1,13 @@ -## Origin Destination Matrix +# Origin Destination Matrix The Origin Destination Matrix shows the optimized travel time (total cost) between each pair of nodes. -The optimized travel time includes a fixed penalty (5 minutes) for each connection, but the Origin Destination Matrix also shows the corresponding effective travel time and number of connections. +The optimized travel time includes a fixed penalty (5 minutes) for each transfer, but the Origin Destination Matrix also shows the corresponding effective travel time and number of transfers. -### Filtering +## Filtering If some nodes are selected, then the Origin Destination Matrix will only show results between these nodes (but other nodes may be used to compute paths). The Origin Destination Matrix will only show results between visible nodes (but other nodes may be used to compute paths). The Origin Destination Matrix will only use visible trainruns to compute paths. - -### Caveats - -Split trainruns are not supported at the moment: https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/285. -As a simplification, we currently consider trains run at their frequency for a fixed schedule duration (16 hours). diff --git a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts index a4bba36d..36c2891d 100644 --- a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts +++ b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts @@ -530,7 +530,7 @@ export class EditorToolsViewComponent { headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.origin:Origin`); headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.destination:Destination`); headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.travelTime:Travel time`); - headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.connections:Connections`); + headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.transfers:Transfers`); headers.push($localize`:@@app.view.editor-side-view.editor-tools-view-component.totalCost:Total cost`); const metadata = this.dataService.getNetzgrafikDto().metadata; diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index 2722128e..f23599a7 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -490,11 +490,11 @@ "turnaroundTimeStart": "Wendezeit Startbahnhof", "turnaroundTime": "Umlaufzeit", "trainrunTimeCategory": "Verkehrt", - "origin": "Origin", - "destination": "Destination", - "travelTime": "Travel time", - "connections": "Connections", - "totalCost": "Total cost" + "origin": "Start", + "destination": "Ziel", + "travelTime": "Fahrzeit", + "transfers": "Transfers", + "totalCost": "Gesamtkosten" } }, "error-view": { diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 5b448180..3e5aadd0 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -493,7 +493,7 @@ "origin": "Origin", "destination": "Destination", "travelTime": "Travel time", - "connections": "Connections", + "transfers": "Transfers", "totalCost": "Total cost" } }, diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index d729aa90..988098f5 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -492,7 +492,7 @@ "origin": "Origine", "destination": "Destination", "travelTime": "Temps de parcours", - "connections": "Correspondances", + "transfers": "Changements", "totalCost": "Coût total" } }, diff --git a/src/assets/i18n/it.json b/src/assets/i18n/it.json index 1dd450fd..ffcfd7c1 100644 --- a/src/assets/i18n/it.json +++ b/src/assets/i18n/it.json @@ -489,11 +489,11 @@ "turnaroundTimeStart": "Turnaround time at start station", "turnaroundTime": "Turnaround time", "trainrunTimeCategory": "Trainrun time category", - "origin": "Origin", - "destination": "Destination", - "travelTime": "Travel time", - "connections": "Connections", - "totalCost": "Total cost" + "origin": "Origine", + "destination": "Destinazione", + "travelTime": "Tempo di viaggio", + "transfers": "Cambiamenti", + "totalCost": "Costo totale" } }, "error-view": { From 53ee469b7cbba5042530d6436f1dbfaa447a1285 Mon Sep 17 00:00:00 2001 From: Adrian Egli Date: Thu, 28 Nov 2024 11:52:47 +0100 Subject: [PATCH 185/197] fix: documentation for 3rd party import (#367) * fix: documentation for 3rd party import * Update documentation/DATA_MODEL_JSON.md Co-authored-by: Louis Greiner <57864277+louisgreiner@users.noreply.github.com> --------- Co-authored-by: Louis Greiner <57864277+louisgreiner@users.noreply.github.com> --- documentation/DATA_MODEL_JSON.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/documentation/DATA_MODEL_JSON.md b/documentation/DATA_MODEL_JSON.md index 8eea39fd..77f078bc 100644 --- a/documentation/DATA_MODEL_JSON.md +++ b/documentation/DATA_MODEL_JSON.md @@ -23,9 +23,37 @@ If nodes have no port objects or if no TrainrunSection has a defined path elemen respectively create the required elements. This adjustment ensures that all nodes are created first, followed by the systematic insertion of each train, section by section. Inserting each section by section ensures that the Netzgrafik drawing gets well routed. This streamlines the import process, making the exchange of data much more straightforward and efficient. -The 3rd party has to care about the nodes' position only. The TrainrunSection routing gets computed while importing, +The 3rd party has only to care about the nodes' position and ensure the trainrun sections are temporally sorted. The TrainrunSection routing gets computed while importing, thus no complex calculation must be reimplemented by the 3rd party provider. + +###### Detection of Third-Party Data +The function [detectNetzgrafikJSON3rdParty](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/blob/main/src/app/view/editor-tools-view-component/editor-tools-view.component.ts#L580) checks if the imported data comes from a third party and if it needs to be adjusted accordingly. + +```typescript +private detectNetzgrafikJSON3rdParty(netzgrafikDto: NetzgrafikDto): boolean { + return netzgrafikDto.nodes.find((n: NodeDto) => + n.ports === undefined) !== undefined + || + netzgrafikDto.nodes.filter((n: NodeDto) => + n.ports?.length === 0).length === netzgrafikDto.nodes.length + || + netzgrafikDto.trainrunSections.find((ts: TrainrunSectionDto) => + ts.path === undefined || + ts.path?.path === undefined || + ts.path?.path?.length === 0 + ) !== undefined; + } + ``` +The function performs the following checks: +- Whether there are nodes without port objects. +- Whether all nodes have empty port lists. +- Whether there are trainrun sections without a defined path. +If any of these conditions are met, the import process is adjusted to automatically create the necessary elements. + +The JSON-based data import from third parties into the net graphic system is designed to simplify the process and ensure that all required elements are correctly created and inserted. This ensures efficient and error-free data transfer. + + ## JSON Description (basic data structure) ```json From 518f760a9f9c1c80f3de3913e4bcd0cd01025220 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 12:15:56 +0100 Subject: [PATCH 186/197] chore(main): release netzgrafik-frontend 2.9.11 (#368) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 0c6703ee..4c1d523d 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.9.10" + ".": "2.9.11" } diff --git a/CHANGELOG.md b/CHANGELOG.md index c2663f78..455c06f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [2.9.11](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.10...netzgrafik-frontend-v2.9.11) (2024-11-28) + + +### Bug Fixes + +* correct connections->transfers naming for O/D matrix ([#365](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/365)) ([454c201](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/454c201abf3228dacecb8685f80545ef13eea554)) +* documentation for 3rd party import ([#367](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/issues/367)) ([53ee469](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/commit/53ee469b7cbba5042530d6436f1dbfaa447a1285)) + ## [2.9.10](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/netzgrafik-frontend-v2.9.9...netzgrafik-frontend-v2.9.10) (2024-11-22) diff --git a/package-lock.json b/package-lock.json index 94b8ad0d..c8042893 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netzgrafik-frontend", - "version": "2.9.10", + "version": "2.9.11", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netzgrafik-frontend", - "version": "2.9.10", + "version": "2.9.11", "dependencies": { "@angular/animations": "^17.0.9", "@angular/cdk": "^17.0.6", diff --git a/package.json b/package.json index f6309068..25926121 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "extract-i18n": "ng extract-i18n" }, "name": "netzgrafik-frontend", - "version": "2.9.10", + "version": "2.9.11", "repository": { "type": "git", "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" From a1e484a53a3e74cfe0682daf0ae8f5314b487cd7 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 27 Jun 2024 11:55:03 +0200 Subject: [PATCH 187/197] DO NOT MERGE: publish forked package on NPM --- .github/workflows/continuous-integration.yml | 32 +++++++--- README.md | 65 ++++++++++++++++++++ package.json | 2 +- 3 files changed, 91 insertions(+), 8 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 07f2eead..43697250 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -1,11 +1,5 @@ name: Continuous Integration -on: - push: - branches: - - main - pull_request: - branches: - - main +on: [push] concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} @@ -17,6 +11,7 @@ permissions: jobs: lint: runs-on: ubuntu-latest + continue-on-error: true steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -88,3 +83,26 @@ jobs: with: name: build-standalone-demo path: dist/netzgrafik-frontend/ + + publish: + runs-on: ubuntu-latest + needs: build-standalone + permissions: + contents: read + id-token: write + steps: + - uses: actions/checkout@v4 + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build-standalone + path: dist/netzgrafik-frontend/ + - uses: actions/setup-node@v4 + with: + registry-url: 'https://registry.npmjs.org' + - run: npm pkg set name="@osrd-project/netzgrafik-frontend" + - run: npm version --no-git-tag-version "0.0.0-snapshot.$GITHUB_SHA" + - run: npm pkg delete dependencies optionalDependencies devDependencies + - run: npm publish --provenance --access public --tag snapshot + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/README.md b/README.md index 13f52e87..5eb5af58 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,68 @@ +# Netzgrafik-Editor's OSRD fork + +Our fork uses the branch `standalone`, regularily rebased onto the base +repository's `main` branch. We try to keep the list of patches applied on top +of the base repository as small as possible, ideally upstreaming them little by +little when it makes sense. The list of patches can be viewed here: +https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/main...osrd-project:netzgrafik-editor-frontend:standalone + +A new NPM package is automatically published on all pushes to any branch of the +fork. The list of versions can be seen here: +https://www.npmjs.com/package/@osrd-project/netzgrafik-frontend?activeTab=versions + +## Initial setup + +Clone the base repository, add OSRD's fork as a separate remote, checkout the +fork's branch: + +```sh +git clone git@github.com:SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git +cd netzgrafik-editor-frontend +git remote add osrd-project git@github.com:osrd-project/netzgrafik-editor-frontend.git +git fetch osrd-project +git checkout standalone +``` + +## Pulling in changes from the base repository + +Fetch changes from the base repository and rebase our fork: + +```sh +git fetch --all +git checkout standalone +git reset --hard osrd-project/standalone +git rebase origin/main +git push --force-with-lease +``` + +## Making changes to fork patches + +Sometimes it's necessary to make a change to one of our fork's patches (as +opposed to one of the commits present in the base repository). + +First switch to the `standalone` branch and identify the commit you want to +edit. Then create a new working branch, make the changes to the source files, +and create a fixup commit: + +```sh +git checkout standalone +git checkout -b emersion/fix-all-the-bugs +# edit source files, work work work +git commit -a --fixup +git push osrd-project +``` + +A pull request can then be opened and the changes can be reviewed. Once the PR +is merged, the fixup can be squashed into its original commit: + +```sh +git fetch --all +git checkout standalone +git reset --hard osrd-project/standalone +git rebase --autosquash --keep-base origin/main +git push --force-with-lease +``` + # Netzgrafik-Editor
diff --git a/package.json b/package.json index 25926121..28cc6b39 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "version": "2.9.11", "repository": { "type": "git", - "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" + "url": "https://github.com/osrd-project/netzgrafik-editor-frontend.git" }, "files": [ "dist/*" From b1644bcf044ef2bb45b703a426a15bcafac61996 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Mon, 5 Aug 2024 15:52:36 +0200 Subject: [PATCH 188/197] hack: hide all the return-related toys - Times along edges in the editor main view - Input fields in the train run section form - Times and input fields in the perlenkette - Edges in the streckengrafik - Enforce source/target section ordering --- .../perlenkette-section.component.scss | 8 +++++++ .../service/load-perlenkette.service.ts | 5 ++-- .../services/data/trainrunsection.service.ts | 23 +++++++++++++++++-- .../services/util/trainrunsection.helper.ts | 10 ++++---- .../train-run-item.component.html | 2 +- .../trainrun-section-tab.component.scss | 14 ++++++++++- .../data-views/trainrunsections.view.scss | 4 ++++ 7 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/app/perlenkette/perlenkette-section/perlenkette-section.component.scss b/src/app/perlenkette/perlenkette-section/perlenkette-section.component.scss index 50584840..41b97510 100644 --- a/src/app/perlenkette/perlenkette-section/perlenkette-section.component.scss +++ b/src/app/perlenkette/perlenkette-section/perlenkette-section.component.scss @@ -99,6 +99,10 @@ svg text.edge_text { grid-row: 7 / span 3; } + .nodeBorderContainerTopLeft, .nodeBorderContainerBottomLeft { + display: none; + } + .nodeMinus { grid-column: 1; grid-row: 1; @@ -203,3 +207,7 @@ button.FunctionButton.Rotation90.disabled { pointer-events: none; opacity: 0; } + +.leftArrivalTime, .rightDepartureTime { + display: none; +} diff --git a/src/app/perlenkette/service/load-perlenkette.service.ts b/src/app/perlenkette/service/load-perlenkette.service.ts index d28cc084..e07dd9e2 100644 --- a/src/app/perlenkette/service/load-perlenkette.service.ts +++ b/src/app/perlenkette/service/load-perlenkette.service.ts @@ -125,10 +125,11 @@ export class LoadPerlenketteService implements OnDestroy { const trainrunSection = alltrainrunsections[0]; const bothEndNodes = this.trainrunService.getBothEndNodesFromTrainrunPart(trainrunSection); - const startForwardNode = GeneralViewFunctions.getLeftOrTopNode( + /*const startForwardNode = GeneralViewFunctions.getLeftOrTopNode( bothEndNodes.endNode1, bothEndNodes.endNode2, - ); + );*/ + const startForwardNode = bothEndNodes.endNode2; if (startForwardNode) { const startTrainrunSection = startForwardNode.getStartTrainrunSection( diff --git a/src/app/services/data/trainrunsection.service.ts b/src/app/services/data/trainrunsection.service.ts index b12e9370..2e981a79 100644 --- a/src/app/services/data/trainrunsection.service.ts +++ b/src/app/services/data/trainrunsection.service.ts @@ -697,8 +697,27 @@ export class TrainrunSectionService implements OnDestroy { ); } - const sourceNode = this.nodeService.getNodeFromId(sourceNodeId); - const targetNode = this.nodeService.getNodeFromId(targetNodeId); + let sourceNode = this.nodeService.getNodeFromId(sourceNodeId); + let targetNode = this.nodeService.getNodeFromId(targetNodeId); + + // Enforce [source → target] [source → target] sections, disallow + // [source → target] [target → source] and [target → source] [source → target] + const isUpdate = this.trainrunSectionsStore.trainrunSections.some((s) => + trainrunSection.getTrainrunId() === s.getTrainrunId() + ); + if (isUpdate) { + const { + endNode1: trainrunTargetNode, + endNode2: trainrunSourceNode + } = this.trainrunService.getBothEndNodesWithTrainrunId( + trainrunSection.getTrainrunId() + ); + if (sourceNode.getId() === trainrunSourceNode.getId() || + targetNode.getId() === trainrunTargetNode.getId()) { + [sourceNode, targetNode] = [targetNode, sourceNode]; + } + } + trainrunSection.setSourceAndTargetNodeReference(sourceNode, targetNode); this.trainrunSectionsStore.trainrunSections.push(trainrunSection); this.logger.log( diff --git a/src/app/services/util/trainrunsection.helper.ts b/src/app/services/util/trainrunsection.helper.ts index 7b7f26a4..6a1982c0 100644 --- a/src/app/services/util/trainrunsection.helper.ts +++ b/src/app/services/util/trainrunsection.helper.ts @@ -321,10 +321,11 @@ export class TrainrunsectionHelper { ) !== undefined; let leftNode; if (!bothNodesFound) { - leftNode = GeneralViewFunctions.getLeftOrTopNode( + /*leftNode = GeneralViewFunctions.getLeftOrTopNode( bothLastNonStopNodes.lastNonStopNode1, bothLastNonStopNodes.lastNonStopNode2, - ); + );*/ + leftNode = bothLastNonStopNodes.lastNonStopNode2; } else { leftNode = GeneralViewFunctions.getLeftNodeAccordingToOrder( orderedNodes, @@ -349,10 +350,11 @@ export class TrainrunsectionHelper { ) !== undefined; let rightNode; if (!bothNodesFound) { - rightNode = GeneralViewFunctions.getRightOrBottomNode( + /*rightNode = GeneralViewFunctions.getRightOrBottomNode( bothLastNonStopNodes.lastNonStopNode1, bothLastNonStopNodes.lastNonStopNode2, - ); + );*/ + rightNode = bothLastNonStopNodes.lastNonStopNode1; } else { rightNode = GeneralViewFunctions.getRightNodeAccordingToOrder( orderedNodes, diff --git a/src/app/streckengrafik/components/train-run-item/train-run-item.component.html b/src/app/streckengrafik/components/train-run-item/train-run-item.component.html index 76e48a1b..44bbe2dd 100644 --- a/src/app/streckengrafik/components/train-run-item/train-run-item.component.html +++ b/src/app/streckengrafik/components/train-run-item/train-run-item.component.html @@ -1,7 +1,7 @@ - + Date: Tue, 6 Aug 2024 15:35:48 +0200 Subject: [PATCH 189/197] hack: disable saved filters --- .../view/editor-filter-view/editor-filter-view.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/view/editor-filter-view/editor-filter-view.component.html b/src/app/view/editor-filter-view/editor-filter-view.component.html index 5bb95bd0..d1ec0e74 100644 --- a/src/app/view/editor-filter-view/editor-filter-view.component.html +++ b/src/app/view/editor-filter-view/editor-filter-view.component.html @@ -199,7 +199,7 @@

{{ 'app.view.editor-filter-view.filter' | translate }}< - + {{ 'app.view.editor-filter-view.saved-filters' | translate }} From c5f604843c0e4ac0e58d1417521fe658da191cf1 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 6 Aug 2024 15:41:15 +0200 Subject: [PATCH 190/197] hack: disable file imports --- .../editor-tools-view.component.html | 58 ++++++++++--------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/src/app/view/editor-tools-view-component/editor-tools-view.component.html b/src/app/view/editor-tools-view-component/editor-tools-view.component.html index 04347475..f480d622 100644 --- a/src/app/view/editor-tools-view-component/editor-tools-view.component.html +++ b/src/app/view/editor-tools-view-component/editor-tools-view.component.html @@ -40,7 +40,8 @@

{{ 'app.view.editor-side-view.editor-tools-view-compone {{ 'app.view.editor-side-view.editor-tools-view-component.export-netzgrafik-as-json' | translate }} - +
- {{ 'app.view.editor-side-view.editor-tools-view-component.import-base-data' | translate }} - {{ 'app.view.editor-side-view.editor-tools-view-component.help-csv-data' | translate }} - -
-
+ + diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.html b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.html index cb27024a..df35d7e2 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.html +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.html @@ -65,6 +65,7 @@ tabindex="-1" (click)="onDuplicateTrainrun()" [title]="'app.view.dialogs.trainrun-and-section-dialog.trainrun-tab.trainrunDuplicate' | translate " + *ngIf="false" > From 9724700510a0dda2fa2a7a3ef54f23d76e18b211 Mon Sep 17 00:00:00 2001 From: Uriel SAUTRON <71732278+Uriel-Sautron@users.noreply.github.com> Date: Fri, 20 Sep 2024 10:42:00 +0200 Subject: [PATCH 195/197] hack: disable in edit sidebar netzgrafik-delete netzgrafik-merge and filterable labels nodes/notes (#3) Co-authored-by: Simon Ser --- .../editor-edit-tools-view.component.html | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.html b/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.html index efc8a579..33300d3a 100644 --- a/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.html +++ b/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.html @@ -13,7 +13,8 @@

{{ 'app.view.editor-edit-tools-view-component.edit' | t [componentLabelRef]="'Trainrun'" > - + + {{ 'app.view.editor-edit-tools-view-component.nodes' | translate }} {{ 'app.view.editor-edit-tools-view-component.edit' | t + [disabled]="!getVariantIsWritable()" + *ngIf="false" + > {{ 'app.view.editor-edit-tools-view-component.delete-netzgrafik-title' | translate }} {{ 'app.view.editor-edit-tools-view-component.edit' | t + [disabled]="!getVariantIsWritable()" + *ngIf="false" + > {{ 'app.view.editor-edit-tools-view-component.merge-netzgrafik-title' | translate }} From 3298a136b3899e91c16cb836bd8cf17b1b2f2e2b Mon Sep 17 00:00:00 2001 From: Louis Greiner Date: Wed, 13 Nov 2024 16:31:59 +0100 Subject: [PATCH 196/197] hack: disable sbb header --- src/app/app.component.html | 1 + .../netzgrafik-application.component.scss | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/app.component.html b/src/app/app.component.html index b791315f..59cf3872 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -2,6 +2,7 @@ label="Netzgrafik-Editor" [subtitle]="'app.version' | translate:{ 'version': version }" class="sbb-header-fixed-columns noprint" + *ngIf="!disableBackend" > Date: Tue, 3 Dec 2024 17:18:27 +0100 Subject: [PATCH 197/197] hack: disable trainrunSection time warnings Signed-off-by: Louis Greiner --- src/app/models/trainrunsection.model.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/app/models/trainrunsection.model.ts b/src/app/models/trainrunsection.model.ts index bdf8d62c..29c5a304 100644 --- a/src/app/models/trainrunsection.model.ts +++ b/src/app/models/trainrunsection.model.ts @@ -15,6 +15,7 @@ import { } from "../data-structures/technical.data.structures"; import {TrainrunsectionValidator} from "../services/util/trainrunsection.validator"; import {formatDate} from "@angular/common"; +import {environment} from "src/environments/environment"; export class TrainrunSection { private static currentId = 0; @@ -452,22 +453,27 @@ export class TrainrunSection { } hasTravelTimeWarning(): boolean { + if (environment.disableBackend) return false return this.travelTime.warning !== null; } hasSourceDepartureWarning(): boolean { + if (environment.disableBackend) return false return this.sourceDeparture.warning !== null; } hasSourceArrivalWarning(): boolean { + if (environment.disableBackend) return false return this.sourceArrival.warning !== null; } hasTargetDepartureWarning(): boolean { + if (environment.disableBackend) return false return this.targetDeparture.warning !== null; } hasTargetArrivalWarning(): boolean { + if (environment.disableBackend) return false return this.targetArrival.warning !== null; }