diff --git a/Dockerfile b/Dockerfile index 39c70241463b4eebd6f935ad20eb0dbee962c535..b9ba18921c5640e3c63e289fc41b00281b9324cd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,12 @@ -# Prepare nginx -FROM nginx:1.19-alpine -WORKDIR /app - -COPY ./dist/apps/web-graphpolaris /usr/share/nginx/html - -RUN rm /etc/nginx/conf.d/default.conf -COPY nginx/nginx.conf /etc/nginx/conf.d - -# Fire up nginx -EXPOSE 80 -CMD ["nginx", "-g", "daemon off;"] +# Prepare nginx +FROM nginx:1.19-alpine +WORKDIR /app + +COPY ./apps/web/dist /usr/share/nginx/html + +RUN rm /etc/nginx/conf.d/default.conf +COPY nginx/nginx.conf /etc/nginx/conf.d + +# Fire up nginx +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..3e03b769651dfa232b38a4f8825f9bfea9a0fa9d --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ + +# windows: +# pnpm build + +# macos: +# pnpm build + +# linux: +# pnpm build + +docker: login + @docker build -t graphpolaris/frontend:latest . + @docker push graphpolaris/frontend\:latest + +login: + echo -e "machine git.science.uu.nl\nlogin gitlab-ci-token\npassword ${CI_JOB_TOKEN}" > ~/.netrc \ No newline at end of file diff --git a/apps/web/node.d.ts b/apps/web/node.d.ts index 3d2ced5bc73ee7e961f830942deb2a6115058ed5..544d25be2e3874c8a1e1fac2cb9507e4ff20a295 100644 --- a/apps/web/node.d.ts +++ b/apps/web/node.d.ts @@ -11,3 +11,8 @@ interface ImportMeta { VITE_KEYCLOAK_CLIENT: string; }; } + +declare module "*.png"; +declare module "*.svg"; +declare module "*.jpeg"; +declare module "*.jpg"; \ No newline at end of file diff --git a/apps/web/package.json b/apps/web/package.json index 6de2cebe71dacf6ce24a715c6936e14316ac2c9e..24c4e5bfc0da9e8dc4326f8cf8e9f0efe279d257 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -7,6 +7,7 @@ "dev2": "vite --host local.graphpolaris.com --port 4200", "dev": "vite --port 4200", "build": "tsc && vite build", + "build-dev": "tsc && vite build --mode development", "preview": "vite preview", "lint": "eslint *.ts*", "test": "vitest run" diff --git a/apps/web/src/app/app.tsx b/apps/web/src/app/app.tsx index 9a83b2497da962384faec024e0ef86c4a55136d6..0ecebbec8facf92f7c03a8f4a5116fccbef50c03 100644 --- a/apps/web/src/app/app.tsx +++ b/apps/web/src/app/app.tsx @@ -12,7 +12,11 @@ import { import { WebSocketHandler } from '@graphpolaris/shared/lib/data-access/socket'; import Broker from '@graphpolaris/shared/lib/data-access/socket/broker'; import { assignNewGraphQueryResult, useAppDispatch } from '@graphpolaris/shared/lib/data-access/store'; -import { GraphQueryResultFromBackend, resetGraphQueryResults } from '@graphpolaris/shared/lib/data-access/store/graphQueryResultSlice'; +import { + GraphQueryResultFromBackend, + GraphQueryResultFromBackendPayload, + resetGraphQueryResults, +} from '@graphpolaris/shared/lib/data-access/store/graphQueryResultSlice'; import { Query2BackendQuery, QueryBuilder } from '@graphpolaris/shared/lib/querybuilder'; import { Schema } from '@graphpolaris/shared/lib/schema/panel'; import { useEffect, useRef, useState } from 'react'; @@ -23,9 +27,7 @@ import styles from './app.module.scss'; import { logout } from '@graphpolaris/shared/lib/data-access/store/authSlice'; import { SchemaFromBackend } from '@graphpolaris/shared/lib/schema'; -export interface App { - styles: any; -} +export interface App {} export function App(props: App) { const isLogin = useAuth(); @@ -49,7 +51,7 @@ export function App(props: App) { // Default Broker.instance().subscribe((data: SchemaFromBackend) => dispatch(readInSchemaFromBackend(data)), 'schema_result'); - Broker.instance().subscribe((data: GraphQueryResultFromBackend) => dispatch(assignNewGraphQueryResult(data)), 'query_result'); + Broker.instance().subscribe((data: GraphQueryResultFromBackendPayload) => dispatch(assignNewGraphQueryResult(data)), 'query_result'); return () => { Broker.instance().unSubscribeAll('schema_result'); diff --git a/apps/web/src/environments/variables.ts b/apps/web/src/environments/variables.ts deleted file mode 100644 index b8c2d6b48aaf1ea6efaaffca1bb3ef8e4ea4b45a..0000000000000000000000000000000000000000 --- a/apps/web/src/environments/variables.ts +++ /dev/null @@ -1,2 +0,0 @@ -// export const domainPrefix = import.meta.env.VITE_STAGING === 'development' ? '' : 'https://'; -// export const domain = domainPrefix + import.meta.env.VITE_BACKEND_URL; diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index 3dae4981ca079ef523ea4d9b97b4a5835f0acb67..e3f42121eadfdee5dbebd030346e1e78f3fa4b7d 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -1,30 +1,30 @@ -{ - "compilerOptions": { - "jsx": "react-jsx", - "allowJs": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "target": "ESNext", - "useDefineForClassFields": true, - "lib": ["DOM", "DOM.Iterable", "ESNext"], - "skipLibCheck": true, - "module": "ESNext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "baseUrl": ".", - "paths": { - "@graphpolaris/shared/lib/*": ["../../libs/shared/lib/*"] - } - }, - "exclude": ["node_modules", "public"], - "include": ["src", "../../libs/shared/lib/querybuilder/panel/attributepill"], - "files": ["./node.d.ts"], - "references": [{ "path": "./tsconfig.node.json" }] -} +{ + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": false, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "target": "ESNext", + "useDefineForClassFields": true, + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "baseUrl": ".", + "paths": { + "@graphpolaris/shared/lib/*": ["../../libs/shared/lib/*"] + } + }, + "exclude": ["node_modules", "public"], + "include": ["src", "../../libs/shared/lib/querybuilder/panel/attributepill"], + "files": ["./node.d.ts"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/libs/shared/lib/data-access/socket/DELETE-repository-interfaces/DatabaseRepository.tsx b/libs/shared/lib/data-access/socket/DELETE-repository-interfaces/DatabaseRepository.tsx deleted file mode 100644 index e1d3a49b2e5fcbbfc6e6a638e8b8f6b98f47a3b8..0000000000000000000000000000000000000000 --- a/libs/shared/lib/data-access/socket/DELETE-repository-interfaces/DatabaseRepository.tsx +++ /dev/null @@ -1,36 +0,0 @@ -/** - * This program has been developed by students from the bachelor Computer Science at - * Utrecht University within the Software Project course. - * © Copyright Utrecht University (Department of Information and Computing Sciences) - */ - -/** Contains interface for adding user databases and fetching the connected databases */ -export type Database = { - // The user specified database, can be anything - databaseName: string; - username: string; - password: string; - port: number; - hostname: string; - // The database for the internal database - internalDatabaseName: string; - // The database type vendor, currently only arangodb and neo4j are supported - databaseType: string; - // Password for speficied databasehost -}; - -// Interface for a database api repository -export default interface DatabaseRepository { - /** - * Adds a database for the currently logged in user. - * @param database {Database} The database to add for the user. - * @returns A promise with a standard Response. - */ - addDatabase(database: Database): Promise<Response>; - - /** - * Fetches the currently connected database of the user. - * @returns The database names. - */ - fetchUserDatabases(): Promise<string[]>; -} diff --git a/libs/shared/lib/data-access/socket/DELETE-repository-interfaces/QueryRepository.tsx b/libs/shared/lib/data-access/socket/DELETE-repository-interfaces/QueryRepository.tsx deleted file mode 100644 index 244a610146916c858eefa7044d99511663cda3f7..0000000000000000000000000000000000000000 --- a/libs/shared/lib/data-access/socket/DELETE-repository-interfaces/QueryRepository.tsx +++ /dev/null @@ -1,27 +0,0 @@ -/** - * This program has been developed by students from the bachelor Computer Science at - * Utrecht University within the Software Project course. - * © Copyright Utrecht University (Department of Information and Computing Sciences) - */ - -import { TranslatedJSONQuery } from './TranslatedJSONQuery'; - -/** A type for a query to send to the backend. */ -export interface Query extends TranslatedJSONQuery { - databaseName: string; -} - -export default interface QueryRepository { - /** - * Sends a query to the database to execute. - * @param query {Query} The query to execute. - * @returns A promise with the assigned queryID. - */ - sendQuery(query: Query): Promise<string>; - - /** - * Sends a message to the backend to retrieve a cached query - * @param queryID {string} The id of the query to retrieve. - */ - retrieveCachedQuery(queryID: string): Promise<Response>; -} diff --git a/libs/shared/lib/data-access/socket/DELETE-repository-interfaces/TranslatedJSONQuery.tsx b/libs/shared/lib/data-access/socket/DELETE-repository-interfaces/TranslatedJSONQuery.tsx deleted file mode 100644 index 7d645f7457888aa32c25af47fd8868eaaa74dde5..0000000000000000000000000000000000000000 --- a/libs/shared/lib/data-access/socket/DELETE-repository-interfaces/TranslatedJSONQuery.tsx +++ /dev/null @@ -1,85 +0,0 @@ -/** - * This program has been developed by students from the bachelor Computer Science at - * Utrecht University within the Software Project course. - * © Copyright Utrecht University (Department of Information and Computing Sciences) - */ - -/** JSON query format used to send a query to the backend. */ -export interface TranslatedJSONQuery { - return: { - entities: number[]; - relations: number[]; - groupBys: number[]; - }; - entities: Entity[]; - relations: Relation[]; - groupBys: GroupBy[]; - machineLearning: MachineLearning[]; - limit: number; -} - -/** Interface for an entity in the JSON for the query. */ -export interface Entity { - name: string; - ID: number; - constraints: Constraint[]; -} - -/** Interface for an relation in the JSON for the query. */ -export interface Relation { - name: string; - ID: number; - fromType: string; - fromID: number; - toType: string; - toID: number; - depth: { min: number; max: number }; - constraints: Constraint[]; -} - -/** - * Constraint datatypes created from the attributes of a relation or entity. - * - * string MatchTypes: exact/contains/startswith/endswith. - * int MatchTypes: GT/LT/EQ. - * bool MatchTypes: EQ/NEQ. - */ -export interface Constraint { - attribute: string; - dataType: string; - - matchType: string; - value: string; -} - -/** Interface for a function in the JSON for the query. */ -export interface GroupBy { - ID: number; - - groupType: string; - groupID: number[]; - groupAttribute: string; - - byType: string; - byID: number[]; - byAttribute: string; - - appliedModifier: string; - relationID: number; - constraints: Constraint[]; -} - -/** Interface for Machine Learning algorithm */ -export interface MachineLearning { - ID?: number; - queuename: string; - parameters: string[]; -} -/** Interface for what the JSON needs for link predicition */ -export interface LinkPrediction { - queuename: string; - parameters: { - key: string; - value: string; - }[]; -} diff --git a/libs/shared/lib/data-access/socket/backend-messenger/BackendMessengerMock.tsx b/libs/shared/lib/data-access/socket/backend-messenger/BackendMessengerMock.tsx index ada2ac8a98dd15e2ab281566c801f0844950311b..f06c167be3b10cda1285e8da6f55902f21ec5fe3 100644 --- a/libs/shared/lib/data-access/socket/backend-messenger/BackendMessengerMock.tsx +++ b/libs/shared/lib/data-access/socket/backend-messenger/BackendMessengerMock.tsx @@ -4,13 +4,13 @@ * © Copyright Utrecht University (Department of Information and Computing Sciences) */ +import BackendMessengerRepository from '../backend-message-receiver/BackendMessengerRepository'; + /* istanbul ignore file */ /* The comment above was added so the code coverage wouldn't count this file towards code coverage. * We do not test mock implementations. * See testing plan for more details.*/ -import BackendMessengerRepository from '../../../domain/repository-interfaces/BackendMessengerRepository'; - /** Mock repository used for testing. */ export default class BackendMessengerMock implements BackendMessengerRepository { /** A mock version of the sendMessage function sends a fake message. */ diff --git a/libs/shared/lib/data-access/socket/broker/index.tsx b/libs/shared/lib/data-access/socket/broker/index.tsx index de47aca9f0554b9eac12b7508a7b083446469bdf..b78b7acc9d08ddcc40ce9d1c605cbe71d6c77eb8 100644 --- a/libs/shared/lib/data-access/socket/broker/index.tsx +++ b/libs/shared/lib/data-access/socket/broker/index.tsx @@ -3,7 +3,6 @@ * Utrecht University within the Software Project course. * © Copyright Utrecht University (Department of Information and Computing Sciences) */ -import BrokerListener from './BrokerListenerInterface'; /** * A broker that handles incoming messages from the backend. diff --git a/libs/shared/lib/data-access/socket/listeners/SchemaViewModelImpl.tsx b/libs/shared/lib/data-access/socket/listeners/SchemaViewModelImpl.tsx deleted file mode 100644 index fb00f32ea005dded1dfa9265dd71fe5fcfd9a519..0000000000000000000000000000000000000000 --- a/libs/shared/lib/data-access/socket/listeners/SchemaViewModelImpl.tsx +++ /dev/null @@ -1,802 +0,0 @@ -/** - * This program has been developed by students from the bachelor Computer Science at - * Utrecht University within the Software Project course. - * © Copyright Utrecht University (Department of Information and Computing Sciences) - */ - -/** This class is responsible for updating and creating the graph schema. */ -export default class SchemaViewModelImpl extends AbstractBaseViewModelImpl implements SchemaViewModel { - private reactFlowInstance: any; - private relationCounter: number; - private drawOrderUseCase: DrawOrderUseCase; - private nodeUseCase: NodeUseCase; - private edgeUseCase: EdgeUseCase; - private graphUseCase: GraphUseCase; - private placeInQueryBuilder: (name: string, type: string) => void; - public elements: SchemaElements = { nodes: [], edges: [], selfEdges: [] }; - public zoom: number; - public visible: boolean; - - public nodeQualityPopup: NodeQualityPopupNode; - public attributeAnalyticsPopupMenu: AttributeAnalyticsPopupMenuNode; - - public nodeQualityData: Record<string, NodeQualityDataForEntities | NodeQualityDataForRelations>; - public attributeAnalyticsData: Record<string, AttributeAnalyticsData>; - - private entityPopupOffsets = { - nodeQualityOffset: { - x: SchemaThemeHolder.entity.width, - y: SchemaThemeHolder.entity.height - 3, - }, - attributeQualityOffset: { - x: SchemaThemeHolder.entity.width, - y: -SchemaThemeHolder.entity.height + 12, - }, - }; - - private relationPopupOffsets = { - nodeQualityOffset: { - x: SchemaThemeHolder.relation.width + 50, - y: SchemaThemeHolder.relation.height + 2, - }, - attributeQualityOffset: { - x: SchemaThemeHolder.relation.width + 50, - y: -SchemaThemeHolder.relation.height + 17, - }, - }; - // React flow reference for positioning on drop. - public myRef: React.RefObject<HTMLDivElement>; - - public nodeTypes = { - entity: EntityNode, - relation: RelationNode, - nodeQualityEntityPopup: NodeQualityEntityPopupNode, - nodeQualityRelationPopup: NodeQualityRelationPopupNode, - attributeAnalyticsPopupMenu: AttributeAnalyticsPopupMenu, - }; - - public edgeTypes = { - nodeEdge: NodeEdge, - selfEdge: SelfEdge, - }; - - public constructor( - drawOrderUseCase: DrawOrderUseCase, - nodeUseCase: NodeUseCase, - edgeUseCase: EdgeUseCase, - graphUseCase: GraphUseCase, - addAttribute: (name: string, type: string) => void - ) { - super(); - - this.myRef = React.createRef(); - // TODO: These values need to not be hardcoded. - this.zoom = 1.3; - this.relationCounter = 0; - this.reactFlowInstance = 0; - this.visible = true; - this.edgeUseCase = edgeUseCase; - this.nodeUseCase = nodeUseCase; - this.drawOrderUseCase = drawOrderUseCase; - this.graphUseCase = graphUseCase; - this.placeInQueryBuilder = addAttribute; - - this.nodeQualityPopup = this.emptyNodeQualityPopupNode(); - this.attributeAnalyticsPopupMenu = this.emptyAttributeAnalyticsPopupMenuNode(); - - this.nodeQualityData = {}; - this.attributeAnalyticsData = {}; - } - - /** - * Containts all function calls to create the graph schema. - * Notifies the view about the changes at the end. - */ - public createSchema = (elements: SchemaElements): SchemaElements => { - let drawOrder: Node[]; - - drawOrder = this.drawOrderUseCase.createDrawOrder(elements); - // Create nodes with start position. - elements.nodes = this.nodeUseCase.setEntityNodePosition( - drawOrder, - { - x: 0, - y: 0, - }, - this.toggleNodeQualityPopup, - this.toggleAttributeAnalyticsPopupMenu - ); - - // Create the relation-nodes. - elements.edges.forEach((relation) => { - this.createRelationNode(relation.id, relation.data.attributes, relation.data.collection, elements); - }); - - elements.selfEdges.forEach((relation) => { - this.createRelationNode(relation.id, relation.data.attributes, relation.data.collection, elements); - }); - - // Complement the relation-nodes with extra data that is now accessible. - elements.edges = this.edgeUseCase.positionEdges(drawOrder, elements, this.setRelationNodePosition); - - this.visible = false; - this.notifyViewAboutChanges(); - return elements; - }; - - /** - * consumes the schema send from the backend and uses it to create the SchemaElements for the schema - * @param jsonObject - */ - public consumeMessageFromBackend(jsonObject: unknown): void { - if (isSchemaResult(jsonObject)) { - // This is always the first message to receive, so reset the global variables. - this.visible = false; - this.createSchema({ nodes: [], edges: [], selfEdges: [] }); - - this.relationCounter = 0; - - this.nodeQualityPopup.isHidden = true; - this.attributeAnalyticsPopupMenu.isHidden = true; - - /* Create the graph-schema and add the popup-menu's for as far as possible. - * Runs underlying useCase trice to fix a bug with lingering selfEdges. - TODO: clean this up.*/ - this.elements = this.createSchema({ - nodes: [], - edges: [], - selfEdges: [], - }); - let schemaElements = this.graphUseCase.createGraphFromInputData(jsonObject); - this.elements = this.createSchema(schemaElements); - this.notifyViewAboutChanges(); - //End weird fix - - this.visible = true; - schemaElements = this.graphUseCase.createGraphFromInputData(jsonObject); - this.elements = this.createSchema(schemaElements); - this.notifyViewAboutChanges(); - - this.addAttributesToAnalyticsPopupMenus(jsonObject); - } else if (isAttributeDataEntity(jsonObject)) { - // Add all information from the received message to the popup-menu's. - this.addAttributeDataToPopupMenusAndElements(jsonObject, 'gsa_node_result', this.elements); - } else if (isAttributeDataRelation(jsonObject)) { - // Add all information from the received message to the popup-menu's. - this.addAttributeDataToPopupMenusAndElements(jsonObject, 'gsa_edge_result', this.elements); - } else { - // TODO: This should be an error screen eventually. - console.log('This is no valid input!'); - } - this.notifyViewAboutChanges(); - } - - /** - * Create a reference to the reactflow schema component on load - * @param reactFlowInstance reactflow instance - */ - public onLoad = (reactFlowInstance: OnLoadParams<any>): void => { - this.reactFlowInstance = reactFlowInstance; - }; - - /** - * Complements the relation-nodes with data that had default values before. - * It determines the position of the relation-node and the connected entity-nodes. - * @param centerX Used to determine the center of the edge. - * @param centerY Used to determine the center of the edge. - * @param id The id of the relation node. - * @param from The id of the entity where the edge should connect from. - * @param to The id of the entity where the edge should connect to. - * @param attributes The attributes of the relation node. - */ - public setRelationNodePosition = ( - centerX: number, - centerY: number, - id: string, - from: string, - to: string, - attributes: Attribute[] - ): void => { - let width: number; - let overlap: boolean; - let y: number; - - // Check if the relation-node is in the list of nodes. - let relation = this.elements.nodes.find((node) => node.id == id); - if (relation == undefined) throw new Error('Relation ' + id + ' does not exist.'); - - // Height of relation/entity + external buttons. - const height = 20; - - width = SchemaThemeHolder.relation.width + calcWidthRelationNodeBox(attributes.length, 0); - let x = centerX - SchemaThemeHolder.relation.width / 2; - y = centerY - height / 2; - - while (this.CheckForOverlap(x, y, width, height)) { - y = y + 1; - } - - // Replace the default values for the correct values. - relation.position = { x: x, y: y }; - relation.data.from = from; - relation.data.to = to; - - this.relationCounter++; - if (this.relationCounter == this.elements.edges.length) { - this.fitToView(); - } - this.notifyViewAboutChanges(); - }; - - /** - * Creates a new relation-node with some default values. - * @param id The id of the relation node. - * @param attributes The list of attributes that this relation-node has. - * @param collection The collection this relation-node is in. - */ - public createRelationNode = (id: string, attributes: Attribute[], collection: string, schemaElements: SchemaElements): void => { - // Height of relation/entity + external buttons. - const height = 20; - const width = SchemaThemeHolder.relation.width + calcWidthRelationNodeBox(attributes.length, 0); - - schemaElements.nodes.push({ - type: NodeType.relation, - id: id, - position: { x: 0, y: 0 }, - data: { - width: width, - height: height, - collection: collection, - attributes: attributes, - from: '', - to: '', - nodeCount: 0, - summedNullAmount: 0, - fromRatio: 0, - toRatio: 0, - toggleNodeQualityPopup: this.toggleNodeQualityPopup, - toggleAttributeAnalyticsPopupMenu: this.toggleAttributeAnalyticsPopupMenu, - }, - }); - }; - - /** - * Calculates the width and height of the graph-schema-panel. - * @returns { number; number } The width and the height of the graph-schema-panel. - */ - public getWidthHeight = (): { width: number; height: number } => { - const reactFlow = this.myRef.current as HTMLDivElement; - const reactFlowBounds = reactFlow.getBoundingClientRect(); - const width = reactFlowBounds.right - reactFlowBounds.left; - const height = reactFlowBounds.bottom - reactFlowBounds.top; - return { width, height }; - }; - - /** Placeholder function for fitting the schema into the view. */ - public fitToView = (): void => { - let minX = Infinity; - let maxX = 0; - let minY = Infinity; - let maxY = 0; - let xZoom = 0; - let yZoom = 0; - - let setY = 0; - let setX = 0; - let setZoom = 0; - - this.elements.nodes.forEach((node) => { - const attributeCount: number = node.data.attributes.length; - const nodeCount: number = node.data.nodeCount; - const nodeWidth: number = - node.type == NodeType.entity - ? SchemaThemeHolder.entity.width + calcWidthEntityNodeBox(attributeCount, nodeCount) - : SchemaThemeHolder.relation.width + calcWidthRelationNodeBox(attributeCount, nodeCount); - - if (node.position.x < minX) minX = node.position.x; - if (node.position.x + nodeWidth > maxX) maxX = node.position.x + nodeWidth; - if (node.position.y < minY) minY = node.position.y; - if (node.position.y + node.data.height > maxY) maxY = node.position.y + node.data.height; - }); - - minX -= 10; - maxX += 90; - - const { width, height } = this.getWidthHeight(); - - // Correct for X and Y position with width and height. - let nodeWidth = Math.abs(maxX - minX); - let nodeHeight = Math.abs(maxY - minY); - - setX = minX * -1; - xZoom = width / nodeWidth; - setY = minY * -1; - yZoom = height / nodeHeight; - - // TODO: Correct position and zoom for selfEdges. - - if (xZoom >= yZoom) { - setZoom = yZoom; - setX = setX + width / 2 - nodeWidth / 2; - } else { - setZoom = xZoom; - setY = setY + height / 2 - nodeHeight / 2; - } - - try { - this.reactFlowInstance.setTransform({ x: setX, y: setY, zoom: setZoom }); - } catch { - console.log('this.reactFlowInstance is undefined!'); - } - }; - - /** - * this function check for a relation node if it overlaps with any of the other nodes in the schema. - * It creates boundingbox for the node and checks with all the other nodes if the boxes overlap. - * @param x Top left x of the node. - * @param y Top left y of the node. - * @param width Width of the node. - * @param height Height of the node. - * @returns {bool} whether it overlaps.*/ - public CheckForOverlap = (x: number, y: number, width: number, height: number): boolean => { - const boundingBox = makeBoundingBox(x, y, width, height); - let elements = this.elements; - - let boundingTemporary: BoundingBox; - for (let i = 0; i < elements.nodes.length; i++) { - boundingTemporary = makeBoundingBox( - elements.nodes[i].position.x, - elements.nodes[i].position.y, - elements.nodes[i].data.width, - elements.nodes[i].data.height - ); - if (doBoxesOverlap(boundingBox, boundingTemporary)) { - return true; - } - } - return false; - }; - - /** Exports the schema builder to a beautiful png file */ - public exportToPNG(): void { - const { width, height } = this.getWidthHeight(); - exportComponentAsPNG(this.myRef, { - fileName: 'schemaBuilder', - pdfOptions: { - x: 0, - y: 0, - w: width, - h: height, - unit: 'px', - } as Partial<PDFOptions>, - } as Params); - } - - /** Not implemented method for exporting the schema builder visualisation to PDF. */ - public exportToPDF(): void { - console.log('Method not implemented.'); - } - - /** Attach the listener to the broker. */ - public subscribeToSchemaResult(): void { - Broker.instance().subscribe(this, 'schema_result'); - } - - /** Detach the listener to the broker. */ - public unSubscribeFromSchemaResult(): void { - Broker.instance().unSubscribe(this, 'schema_result'); - } - - /** Attach the listeners to the broker. */ - public subscribeToAnalyticsData(): void { - Broker.instance().subscribe(this, 'gsa_node_result'); - Broker.instance().subscribe(this, 'gsa_edge_result'); - } - - /** Detach the listeners to the broker. */ - public unSubscribeFromAnalyticsData(): void { - Broker.instance().unSubscribe(this, 'gsa_node_result'); - Broker.instance().unSubscribe(this, 'gsa_edge_result'); - } - - /** - * This function is used by relation and entity nodes to hide or show the node-quality popup of that node. - * @param id of the node for which the new popup is. - */ - public toggleNodeQualityPopup = (id: string): void => { - const popup = this.nodeQualityPopup; - - // Hide the popup if the current popup is visible and if the popup belongs to the same node as the given id. - if (popup.nodeID == id && !popup.isHidden) popup.isHidden = true; - // Else make and show a new popup for the node with the given id. - else this.updateNodeQualityPopup(id, this.elements); - - this.notifyViewAboutChanges(); - }; - - /** - * This function shows and updates the node-quality popup for the node which has the given id. - * @param id of the node for which the new popup is. - */ - private updateNodeQualityPopup(id: string, schemaElements: SchemaElements) { - let node = schemaElements.nodes.find((node) => node.id == id); - if (node == undefined) { - throw new Error('Node does not exist therefore no popup can be shown.'); - } - - const popup = this.nodeQualityPopup; - popup.nodeID = id; - popup.isHidden = false; - popup.data = this.nodeQualityData[id]; - - if (node.type == 'entity') { - // Make changes to the popup, to make it a popup for entities. - this.updateToNodeQualityEntityPopup(node); - } else { - // Make changes to the popup, to make it a popup for relations. - this.updateToNodeQualityRelationPopup(node); - } - - // Hide the attributeAnalyticsPopupMenu so that only one popup is displayed. - this.attributeAnalyticsPopupMenu.isHidden = true; - - this.notifyViewAboutChanges(); - this.relationCounter++; - if (this.relationCounter == schemaElements.edges.length) { - this.fitToView(); - } - } - - /** - * This displays the new node-quality popup for the given entity. - * @param node This is the entity of which you want to display the popup. - */ - private updateToNodeQualityEntityPopup(node: Node) { - const popup = this.nodeQualityPopup; - const offset = this.entityPopupOffsets.nodeQualityOffset; - - popup.position = { - x: node.position.x + offset.x, - y: node.position.y + offset.y, - }; - - popup.type = 'nodeQualityEntityPopup'; - } - - /** - * This displays the new node-quality popup for the given relation. - * @param node This is the relation of which you want to display the popup. - */ - private updateToNodeQualityRelationPopup(node: Node) { - const popup = this.nodeQualityPopup; - const offset = this.relationPopupOffsets.nodeQualityOffset; - - popup.position = { - x: node.position.x + offset.x, - y: node.position.y + offset.y, - }; - - popup.type = 'nodeQualityRelationPopup'; - } - - /** - * This function is used by relation and entity nodes to hide or show the attribute analyics popup menu of that node. - * @param id of the node for which the popup is. - */ - public toggleAttributeAnalyticsPopupMenu = (id: string): void => { - const popupMenu = this.attributeAnalyticsPopupMenu; - - // Hide the popup menu if the current popup menu is visible and if the popup menu belongs to the same node as the given id. - if (popupMenu.nodeID == id && !popupMenu.isHidden) popupMenu.isHidden = true; - // Else make and show a new popup menu for the node with the given id. - else this.updateAttributeAnalyticsPopupMenu(id, this.elements); - - this.notifyViewAboutChanges(); - }; - - /** - * This displays the attribute-analytics popup menu for the given node (entity or relation). - * It removes the other menus from the screen. - * @param id This is the id of the node (entity or relation) of which you want to display the menu. - */ - public updateAttributeAnalyticsPopupMenu = (id: string, schemaElements: SchemaElements): void => { - const node = schemaElements.nodes.find((node) => node.id == id); - - if (node == undefined) throw new Error('Node ' + id + ' does not exist therefore no popup menu can be shown.'); - - const popupMenu = this.attributeAnalyticsPopupMenu; - // Make new popup menu for the node. - popupMenu.nodeID = id; - popupMenu.isHidden = false; - popupMenu.data = { ...this.attributeAnalyticsData[id] }; - - if (node.type == NodeType.entity) { - const offset = this.entityPopupOffsets.attributeQualityOffset; - popupMenu.position = { - x: node.position.x + offset.x, - y: node.position.y + offset.y, - }; - } else { - const offset = this.relationPopupOffsets.attributeQualityOffset; - popupMenu.position = { - x: node.position.x + offset.x, - y: node.position.y + offset.y, - }; - } - - // Hide the nodeQualityPopup so that only one popup is displayed. - this.nodeQualityPopup.isHidden = true; - - this.notifyViewAboutChanges(); - }; - - /** This removes the node quality popup from the screen. */ - public hideNodeQualityPopup = (): void => { - this.nodeQualityPopup.isHidden = true; - this.notifyViewAboutChanges(); - }; - - /** This removes the attribute-analytics popup menu from the screen. */ - public hideAttributeAnalyticsPopupMenu = (): void => { - this.attributeAnalyticsPopupMenu.isHidden = true; - this.notifyViewAboutChanges(); - }; - - /** - * This sets all the data for the attributesPopupMenu without the attribute data. - * @param schemaResult This is the schema result that you get (so no attribute data yet). - */ - addAttributesToAnalyticsPopupMenus = (schemaResult: Schema): void => { - this.nodeQualityData = {}; - this.attributeAnalyticsData = {}; - - // Firstly, loop over all entities and add the quality-data (as far as possible). - // Then add the attribute-data (as far as possible). - schemaResult.nodes.forEach((node) => { - this.nodeQualityData[node.name] = { - nodeCount: 0, - notConnectedNodeCount: 0, - attributeNullCount: 0, - isAttributeDataIn: false, - onClickCloseButton: this.hideNodeQualityPopup, - }; - let attributes: any = []; - node.attributes.forEach((attribute) => { - attributes.push({ - attribute: attribute, - category: AttributeCategory.undefined, - nullAmount: 0, - }); - }); - this.attributeAnalyticsData[node.name] = { - nodeID: node.name, - nodeType: NodeType.entity, - attributes: attributes, - isAttributeDataIn: false, - onClickCloseButton: this.hideAttributeAnalyticsPopupMenu, - onClickPlaceInQueryBuilderButton: this.placeInQueryBuilder, - searchForAttributes: this.searchForAttributes, - resetAttributeFilters: this.resetAttributeFilters, - applyAttributeFilters: this.applyAttributeFilters, - }; - }); - // Secondly, loop over all relations and add the quality-data (as far as possible). - // Then add the attribute-data (as far as possible). - schemaResult.edges.forEach((edge) => { - this.nodeQualityData[edge.collection] = { - nodeCount: 0, - fromRatio: 0, - toRatio: 0, - attributeNullCount: 0, - notConnectedNodeCount: 0, - isAttributeDataIn: false, - onClickCloseButton: this.hideNodeQualityPopup, - }; - let attributes: any = []; - edge.attributes.forEach((attribute) => { - attributes.push({ - attribute: attribute, - category: AttributeCategory.undefined, - nullAmount: 0, - }); - }); - this.attributeAnalyticsData[edge.collection] = { - nodeID: edge.collection, - nodeType: NodeType.relation, - attributes: attributes, - isAttributeDataIn: false, - onClickCloseButton: this.hideAttributeAnalyticsPopupMenu, - onClickPlaceInQueryBuilderButton: this.placeInQueryBuilder, - searchForAttributes: this.searchForAttributes, - resetAttributeFilters: this.resetAttributeFilters, - applyAttributeFilters: this.applyAttributeFilters, - }; - }); - }; - - /** Returns an empty quality popup node for react-flow. */ - public emptyAttributeAnalyticsPopupMenuNode(): AttributeAnalyticsPopupMenuNode { - return { - id: 'attributeAnalyticsPopupMenu', - nodeID: '', - position: { x: 0, y: 0 }, - data: { - nodeID: '', - nodeType: NodeType.relation, - attributes: [], - isAttributeDataIn: false, - onClickCloseButton: this.hideAttributeAnalyticsPopupMenu, - onClickPlaceInQueryBuilderButton: this.placeInQueryBuilder, - searchForAttributes: this.searchForAttributes, - resetAttributeFilters: this.resetAttributeFilters, - applyAttributeFilters: this.applyAttributeFilters, - }, - type: 'attributeAnalyticsPopupMenu', - isHidden: true, - className: 'attributeAnalyticsPopupMenu', - }; - } - /** Returns an empty quality popup node for react-flow. */ - public emptyNodeQualityPopupNode(): NodeQualityPopupNode { - return { - id: 'nodeQualityPopup', - position: { x: 0, y: 0 }, - data: { - nodeCount: 0, - notConnectedNodeCount: 0, - attributeNullCount: 0, - isAttributeDataIn: false, - onClickCloseButton: this.hideNodeQualityPopup, - }, - type: 'nodeQualityEntityPopup', - isHidden: true, - nodeID: '', - className: 'nodeQualityPopup', - }; - } - - /** - * This function adjusts the values from the new attribute data into - * the attribute-analytics data and the node-quality data. - * @param attributeData The data that comes from the backend with (some) data about the attributes. - */ - public addAttributeDataToPopupMenusAndElements = ( - attributeData: AttributeData, - attributeDataType: string, - schemaElements: SchemaElements - ): void => { - // Check if attributeData is a node/entity. - if (attributeDataType === 'gsa_node_result') { - const entity = attributeData as NodeAttributeData; - // If it is a entity then add the data for the corresponding entity. - if (entity.id in this.attributeAnalyticsData) { - const attributeDataOfEntity = this.attributeAnalyticsData[entity.id]; - attributeDataOfEntity.isAttributeDataIn = true; - - entity.attributes.forEach((attribute) => { - // Check if attribute is in the list with attributes from the correct entity. - const attributeFound = attributeDataOfEntity.attributes.find((attribute_) => attribute_.attribute.name == attribute.name); - if (attributeFound !== undefined) { - attributeFound.category = attribute.type; - attributeFound.nullAmount = attribute.nullAmount; - } - }); - } // Not throw new error, because it should not crash, a message is enough and not all data will be shown. - else console.log('entity ' + entity.id + ' is not in attributeAnalyticsData'); - - if (entity.id in this.nodeQualityData) { - const qualityDataOfEntity = this.nodeQualityData[entity.id] as NodeQualityDataForEntities; - qualityDataOfEntity.nodeCount = entity.length; - qualityDataOfEntity.attributeNullCount = entity.summedNullAmount; - qualityDataOfEntity.notConnectedNodeCount = Number((1 - entity.connectedRatio).toFixed(2)); - qualityDataOfEntity.isAttributeDataIn = true; - } // Not throw new error, because it should not crash, a message is enough and not all data will be shown. - else console.log('entity ' + entity.id + ' is not in nodeQualityData'); - - // Check also if the entity exists in the this.elements-list. - // If so, add the new data to it. - const elementsNode = schemaElements.nodes.find((node_) => node_.id == entity.id); - if (elementsNode !== undefined) { - elementsNode.data.nodeCount = entity.length; - elementsNode.data.summedNullAmount = entity.summedNullAmount; - elementsNode.data.connectedRatio = entity.connectedRatio; - } - } - - // Check if attributeData is an edge/relation. - else if (attributeDataType === 'gsa_edge_result') { - const relation = attributeData as EdgeAttributeData; - // If it is a relation then add the data for the corresponding relation. - if (relation.id in this.attributeAnalyticsData) { - const attributeDataOfRelation = this.attributeAnalyticsData[relation.id]; - attributeDataOfRelation.isAttributeDataIn = true; - - relation.attributes.forEach((attribute) => { - // Check if attribute is in the list with attributes from the correct relation. - const attributeFound = attributeDataOfRelation.attributes.find((attribute_) => attribute_.attribute.name == attribute.name); - if (attributeFound !== undefined) { - attributeFound.category = attribute.type; - attributeFound.nullAmount = attribute.nullAmount; - } - }); - } // Not throw new error, because it should not crash, a message is enough and not all data will be shown. - else console.log('relation ' + relation.id + ' is not in attributeAnalyticsData'); - - if (relation.id in this.nodeQualityData) { - const qualityDataOfRelation = this.nodeQualityData[relation.id] as NodeQualityDataForRelations; - qualityDataOfRelation.nodeCount = relation.length; - qualityDataOfRelation.attributeNullCount = relation.summedNullAmount; - qualityDataOfRelation.fromRatio = Number(relation.fromRatio.toFixed(2)); - qualityDataOfRelation.toRatio = Number(relation.toRatio.toFixed(2)); - qualityDataOfRelation.isAttributeDataIn = true; - } // Not throw new error, because it should not crash, a message is enough and not all data will be shown. - else console.log('relation ' + relation.id + ' is not in nodeQualityData'); - - // Check also if the entity exists in the this.elements-list. - // If so, add the new data to it. - const elementsNode = schemaElements.nodes.find((node_) => node_.id == relation.id); - if (elementsNode !== undefined) { - elementsNode.data.nodeCount = relation.length; - elementsNode.data.summedNullAmount = relation.summedNullAmount; - elementsNode.data.fromRatio = relation.fromRatio; - elementsNode.data.toRatio = relation.toRatio; - } - } else throw new Error('This data is not valid!'); - }; - - /** - * Filter out attributes that do not contain the given searchbar-value. - * @param id The id of the node the attributes are from. - * @param searchbarValue The value of the searchbar. - */ - public searchForAttributes = (id: string, searchbarValue: string): void => { - const data = this.attributeAnalyticsData[id]; - // Check if there is data available. - if (data !== undefined) { - let passedAttributes: AttributeWithData[] = []; - data.attributes.forEach((attribute) => { - if (attribute.attribute.name.toLowerCase().includes(searchbarValue.toLowerCase())) passedAttributes.push(attribute); - }); - this.attributeAnalyticsPopupMenu.data.attributes = passedAttributes; - this.notifyViewAboutChanges(); - } - }; - - /** - * Reset the current used filters for the attribute-list. - * @param id The id of the node the attributes are from. - */ - public resetAttributeFilters = (id: string): void => { - const data = this.attributeAnalyticsData[id]; - // Check if there is data available. - if (data !== undefined) { - this.attributeAnalyticsPopupMenu.data.attributes = data.attributes; - this.notifyViewAboutChanges(); - } - }; - - /** - * Applies the chosen filters on the list of attributes of the particular node. - * @param id The id of the node the attributes are from. - * @param dataType The given type of the data you want to filter on (numerical, categorical, other). - * @param predicate The given predicate. - * @param percentage The given percentage you want to compare the null-values on. - */ - public applyAttributeFilters = (id: string, dataType: AttributeCategory, predicate: string, percentage: number): void => { - const data = this.attributeAnalyticsData[id]; - // Check if there is data available. - if (data !== undefined) { - let passedAttributes: AttributeWithData[] = []; - data.attributes.forEach((attribute) => { - // If the value is undefined it means that this filter is not chosen, so that must not be taken into account for further filtering. - if (attribute.category == dataType || dataType == AttributeCategory.undefined) - if (predicate == '' || percentage == -1) - // If the string is empty it means that this filter is not chosen, so that must not be taken into account for filtering. - passedAttributes.push(attribute); - else if (numberPredicates[predicate](attribute.nullAmount, percentage)) passedAttributes.push(attribute); - }); - this.attributeAnalyticsPopupMenu.data.attributes = passedAttributes; - this.notifyViewAboutChanges(); - } - }; -} diff --git a/libs/shared/lib/data-access/socket/query/QueryApi.tsx b/libs/shared/lib/data-access/socket/query/QueryApi.tsx deleted file mode 100644 index 451a57efcb7c02fc9afb5d87c44a68ad0fb7fed9..0000000000000000000000000000000000000000 --- a/libs/shared/lib/data-access/socket/query/QueryApi.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import BackendMessengerRepository from '../../../domain/repository-interfaces/BackendMessengerRepository'; -import QueryRepository, { Query } from '../../../domain/repository-interfaces/QueryRepository'; - -/** - * Implementation of the QueryRepository. - * Contains function for sending a query to the database and retrieving a cached query. - */ -export default class QueryApi implements QueryRepository { - backendMessenger: BackendMessengerRepository; - - /** @param backendMessenger {BackendMessengerRepository} A BackendMessengerRepository implementation. */ - constructor(backendMessenger: BackendMessengerRepository) { - this.backendMessenger = backendMessenger; - } - - async sendQuery(query: Query): Promise<string> { - const body = JSON.stringify(query); - return this.backendMessenger.SendMessage(body, 'query/execute/', 'POST').then((response) => { - return response.json().then((obj) => obj.queryID); - }); - } - - async retrieveCachedQuery(queryID: string): Promise<Response> { - return this.backendMessenger.SendMessage(JSON.stringify({ queryID }), 'query/retrieve-cached/', 'POST'); - } -} diff --git a/libs/shared/lib/data-access/store/graphQueryResultSlice.ts b/libs/shared/lib/data-access/store/graphQueryResultSlice.ts index 1f8e0562fb4de431c987611ee8ff3484c7b684c2..95c98320965e379babcb4a1e92eb44bc4a1e04d8 100644 --- a/libs/shared/lib/data-access/store/graphQueryResultSlice.ts +++ b/libs/shared/lib/data-access/store/graphQueryResultSlice.ts @@ -9,13 +9,13 @@ export interface GraphQueryResultFromBackendPayload { export interface GraphQueryResultFromBackend { nodes: { id: string; - label: string; + label?: string; attributes: { [key: string]: unknown }; }[]; edges: { id: string; - label: string; + label?: string; attributes: { [key: string]: unknown }; from: string; to: string; @@ -75,8 +75,9 @@ export const graphQueryResultSlice = createSlice({ payload.nodes = payload.nodes.map((node) => { // TODO FIXME!! Note: works only for arangodb let nodeType = node.id.split('/')[0]; - if (node.attributes?.labels?.length > 0) { - nodeType = node.attributes.labels[0] as string; // TODO: Not sure it works yet + let innerLabels = node?.attributes?.labels as string[]; + if (innerLabels.length > 0) { + nodeType = innerLabels[0] as string; // TODO: Not sure it works yet } if (!nodeTypes.includes(nodeType)) nodeTypes.push(nodeType); node.label = nodeType; @@ -94,7 +95,7 @@ export const graphQueryResultSlice = createSlice({ // Assign new state state.nodes = payload.nodes as Node[]; - state.edges = payload.edges; + state.edges = payload.edges as Edge[]; state.nodeTypes = nodeTypes; }, resetGraphQueryResults: (state) => { diff --git a/libs/shared/lib/data-access/store/querybuilderSlice.ts b/libs/shared/lib/data-access/store/querybuilderSlice.ts index 724dafd9709dabb2f366cff132f8e33debe6d6d0..09903d7870398b4b40d53e9837321ebe180c5f55 100644 --- a/libs/shared/lib/data-access/store/querybuilderSlice.ts +++ b/libs/shared/lib/data-access/store/querybuilderSlice.ts @@ -2,7 +2,7 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import type { RootState } from './store'; import { MultiGraph } from 'graphology'; import { Attributes, SerializedGraph } from 'graphology-types'; -import { QueryMultiGraphology } from '../../querybuilder'; +import { QueryMultiGraph, QueryMultiGraphology } from '../../querybuilder'; // Define the initial state using that type export const initialState = { @@ -19,16 +19,16 @@ export const querybuilderSlice = createSlice({ // console.log('setQuerybuilderNodes', action.payload); state.graphologySerialized = QueryMultiGraphology.from(action.payload).export() as QueryMultiGraph; }, - updateQBAttributeOperator: (state, action: PayloadAction<{ id: string; operator: string }>) => { - const graph = QueryMultiGraphology.from(state.graphologySerialized); - graph.setNodeAttribute(action.payload.id, 'operator', action.payload.operator); - state.graphologySerialized = graph.export(); - }, - updateQBAttributeValue: (state, action: PayloadAction<{ id: string; value: string }>) => { - const graph = QueryMultiGraphology.from(state.graphologySerialized); - graph.setNodeAttribute(action.payload.id, 'value', action.payload.value); - state.graphologySerialized = graph.export(); - }, + // updateQBAttributeOperator: (state, action: PayloadAction<{ id: string; operator: string }>) => { + // const graph = QueryMultiGraphology.from(state.graphologySerialized); + // graph.setNodeAttribute(action.payload.id, 'operator', action.payload.operator); + // state.graphologySerialized = graph.export(); + // }, + // updateQBAttributeValue: (state, action: PayloadAction<{ id: string; value: string }>) => { + // const graph = QueryMultiGraphology.from(state.graphologySerialized); + // graph.setNodeAttribute(action.payload.id, 'value', action.payload.value); + // state.graphologySerialized = graph.export(); + // }, clearQB: (state) => { state.graphologySerialized = new QueryMultiGraphology().export(); }, @@ -47,7 +47,7 @@ export const querybuilderSlice = createSlice({ }, }); -export const { setQuerybuilderNodes, updateQBAttributeOperator, updateQBAttributeValue, clearQB } = querybuilderSlice.actions; +export const { setQuerybuilderNodes, clearQB } = querybuilderSlice.actions; /** Select the querybuilder nodes in serialized fromat */ export const selectQuerybuilderGraphology = (state: RootState): QueryMultiGraphology => { diff --git a/libs/shared/lib/mock-data/query-result/big2ndChamberQueryResult.ts b/libs/shared/lib/mock-data/query-result/big2ndChamberQueryResult.js similarity index 99% rename from libs/shared/lib/mock-data/query-result/big2ndChamberQueryResult.ts rename to libs/shared/lib/mock-data/query-result/big2ndChamberQueryResult.js index 6d07b2402facfa8417169dce177ceea64ae0c5dc..2cbb5c56688fa7b79290212a43e10b6e0f4302d5 100644 --- a/libs/shared/lib/mock-data/query-result/big2ndChamberQueryResult.ts +++ b/libs/shared/lib/mock-data/query-result/big2ndChamberQueryResult.js @@ -10,7 +10,7 @@ * See testing plan for more details.*/ /** Mock elements used for testing the query results. */ -export const big2ndChamberQueryResult: GraphQueryResultFromBackend = { +export const big2ndChamberQueryResult = { edges: [ { from: 'kamerleden/148', diff --git a/libs/shared/lib/mock-data/query-result/geo-mock-data.js b/libs/shared/lib/mock-data/query-result/geo-mock-data.js index 84a17eac354115c429d43d79b53de83fdb541717..dc0c8e4b40160d408df211cf95b27b83c974fe46 100644 --- a/libs/shared/lib/mock-data/query-result/geo-mock-data.js +++ b/libs/shared/lib/mock-data/query-result/geo-mock-data.js @@ -19481,22987 +19481,22987 @@ export const flights = { ], edges: [ { - id: 0, + id: '0', from: 'AMM', to: 'ALY', attributes: { prediction: 1540 }, }, { - id: 1, + id: '1', from: 'AMS', to: 'ABV', attributes: { prediction: 2581 }, }, { - id: 2, + id: '2', from: 'BHX', to: 'KTW', attributes: { prediction: 1209 }, }, { - id: 3, + id: '3', from: 'BIL', to: 'MSP', attributes: { prediction: 4134 }, }, { - id: 4, + id: '4', from: 'BLA', to: 'VLN', attributes: { prediction: 2635 }, }, { - id: 5, + id: '5', from: 'DME', to: 'LED', attributes: { prediction: 24341 }, }, { - id: 6, + id: '6', from: 'DMM', to: 'ALY', attributes: { prediction: 449 }, }, { - id: 7, + id: '7', from: 'DNH', to: 'XIY', attributes: { prediction: 449 }, }, { - id: 8, + id: '8', from: 'DOH', to: 'AMM', attributes: { prediction: 6127 }, }, { - id: 9, + id: '9', from: 'DOH', to: 'KRT', attributes: { prediction: 7872 }, }, { - id: 10, + id: '10', from: 'DRW', to: 'DIL', attributes: { prediction: 1144 }, }, { - id: 11, + id: '11', from: 'DSN', to: 'NAY', attributes: { prediction: 3554 }, }, { - id: 12, + id: '12', from: 'DTM', to: 'BUD', attributes: { prediction: 1174 }, }, { - id: 13, + id: '13', from: 'DTW', to: 'CUN', attributes: { prediction: 5807 }, }, { - id: 14, + id: '14', from: 'DTW', to: 'FRA', attributes: { prediction: 10022 }, }, { - id: 15, + id: '15', from: 'DTW', to: 'FWA', attributes: { prediction: 3402 }, }, { - id: 16, + id: '16', from: 'DTW', to: 'SNA', attributes: { prediction: 2225 }, }, { - id: 17, + id: '17', from: 'DUB', to: 'AGA', attributes: { prediction: 659 }, }, { - id: 18, + id: '18', from: 'FAR', to: 'SLC', attributes: { prediction: 965 }, }, { - id: 19, + id: '19', from: 'FCO', to: 'ALP', attributes: { prediction: 114 }, }, { - id: 20, + id: '20', from: 'FCO', to: 'MLE', attributes: { prediction: 2017 }, }, { - id: 21, + id: '21', from: 'HAM', to: 'EWR', attributes: { prediction: 3456 }, }, { - id: 22, + id: '22', from: 'ACE', to: 'LGW', attributes: { prediction: 11927 }, }, { - id: 23, + id: '23', from: 'AGP', to: 'CMN', attributes: { prediction: 808 }, }, { - id: 24, + id: '24', from: 'AGP', to: 'SVO', attributes: { prediction: 989 }, }, { - id: 25, + id: '25', from: 'AHU', to: 'TNG', attributes: { prediction: 100 }, }, { - id: 26, + id: '26', from: 'ALB', to: 'ART', attributes: { prediction: 355 }, }, { - id: 27, + id: '27', from: 'ALC', to: 'CRL', attributes: { prediction: 4697 }, }, { - id: 28, + id: '28', from: 'ALC', to: 'EDI', attributes: { prediction: 1396 }, }, { - id: 29, + id: '29', from: 'HGH', to: 'TYN', attributes: { prediction: 9358 }, }, { - id: 30, + id: '30', from: 'LIS', to: 'CNF', attributes: { prediction: 4060 }, }, { - id: 31, + id: '31', from: 'LLW', to: 'BLZ', attributes: { prediction: 3294 }, }, { - id: 32, + id: '32', from: 'LPA', to: 'OSL', attributes: { prediction: 5701 }, }, { - id: 33, + id: '33', from: 'LPL', to: 'PRG', attributes: { prediction: 1320 }, }, { - id: 34, + id: '34', from: 'LPL', to: 'SNN', attributes: { prediction: 3943 }, }, { - id: 35, + id: '35', from: 'LSH', to: 'HEH', attributes: { prediction: 260 }, }, { - id: 36, + id: '36', from: 'LUO', to: 'LAD', attributes: { prediction: 2307 }, }, { - id: 37, + id: '37', from: 'LWO', to: 'FCO', attributes: { prediction: 448 }, }, { - id: 38, + id: '38', from: 'LWO', to: 'VKO', attributes: { prediction: 1346 }, }, { - id: 39, + id: '39', from: 'LYS', to: 'BCN', attributes: { prediction: 5450 }, }, { - id: 40, + id: '40', from: 'LYS', to: 'BSK', attributes: { prediction: 455 }, }, { - id: 41, + id: '41', from: 'MGA', to: 'MIA', attributes: { prediction: 13456 }, }, { - id: 42, + id: '42', from: 'MHD', to: 'BND', attributes: { prediction: 2521 }, }, { - id: 43, + id: '43', from: 'PEC', to: 'JNU', attributes: { prediction: 145 }, }, { - id: 44, + id: '44', from: 'PEK', to: 'IKT', attributes: { prediction: 1568 }, }, { - id: 45, + id: '45', from: 'PEK', to: 'TGO', attributes: { prediction: 1651 }, }, { - id: 46, + id: '46', from: 'PEK', to: 'TPE', attributes: { prediction: 18633 }, }, { - id: 47, + id: '47', from: 'PER', to: 'CNS', attributes: { prediction: 2571 }, }, { - id: 48, + id: '48', from: 'PEW', to: 'ISB', attributes: { prediction: 2145 }, }, { - id: 49, + id: '49', from: 'PFO', to: 'DSA', attributes: { prediction: 735 }, }, { - id: 50, + id: '50', from: 'PFO', to: 'GLA', attributes: { prediction: 791 }, }, { - id: 51, + id: '51', from: 'PHF', to: 'MCO', attributes: { prediction: 2549 }, }, { - id: 52, + id: '52', from: 'PHL', to: 'MIA', attributes: { prediction: 19207 }, }, { - id: 53, + id: '53', from: 'PIS', to: 'LYS', attributes: { prediction: 1430 }, }, { - id: 54, + id: '54', from: 'PMI', to: 'LBC', attributes: { prediction: 2445 }, }, { - id: 55, + id: '55', from: 'PNH', to: 'TPE', attributes: { prediction: 5071 }, }, { - id: 56, + id: '56', from: 'REC', to: 'SDU', attributes: { prediction: 2782 }, }, { - id: 57, + id: '57', from: 'RIC', to: 'YYZ', attributes: { prediction: 988 }, }, { - id: 58, + id: '58', from: 'SPN', to: 'TIQ', attributes: { prediction: 152 }, }, { - id: 59, + id: '59', from: 'TAS', to: 'KSQ', attributes: { prediction: 2358 }, }, { - id: 60, + id: '60', from: 'TAS', to: 'VKO', attributes: { prediction: 2312 }, }, { - id: 61, + id: '61', from: 'TBU', to: 'SUV', attributes: { prediction: 315 }, }, { - id: 62, + id: '62', from: 'TBZ', to: 'PGU', attributes: { prediction: 274 }, }, { - id: 63, + id: '63', from: 'TFS', to: 'DSA', attributes: { prediction: 1563 }, }, { - id: 64, + id: '64', from: 'TFS', to: 'HAJ', attributes: { prediction: 4084 }, }, { - id: 65, + id: '65', from: 'TFS', to: 'LNZ', attributes: { prediction: 804 }, }, { - id: 66, + id: '66', from: 'THR', to: 'KHY', attributes: { prediction: 433 }, }, { - id: 67, + id: '67', from: 'THR', to: 'PFQ', attributes: { prediction: 268 }, }, { - id: 68, + id: '68', from: 'TIA', to: 'STN', attributes: { prediction: 1158 }, }, { - id: 69, + id: '69', from: 'TIJ', to: 'UPN', attributes: { prediction: 2423 }, }, { - id: 70, + id: '70', from: 'TIV', to: 'BEG', attributes: { prediction: 5331 }, }, { - id: 71, + id: '71', from: 'TLL', to: 'LPP', attributes: { prediction: 1140 }, }, { - id: 72, + id: '72', from: 'TLV', to: 'GYD', attributes: { prediction: 448 }, }, { - id: 73, + id: '73', from: 'BAQ', to: 'MAR', attributes: { prediction: 84 }, }, { - id: 74, + id: '74', from: 'BBO', to: 'ADE', attributes: { prediction: 495 }, }, { - id: 75, + id: '75', from: 'BCN', to: 'STR', attributes: { prediction: 4386 }, }, { - id: 76, + id: '76', from: 'BDA', to: 'EWR', attributes: { prediction: 3831 }, }, { - id: 77, + id: '77', from: 'BEG', to: 'LHR', attributes: { prediction: 5149 }, }, { - id: 78, + id: '78', from: 'AMS', to: 'LUX', attributes: { prediction: 4075 }, }, { - id: 79, + id: '79', from: 'AMS', to: 'PEK', attributes: { prediction: 12316 }, }, { - id: 80, + id: '80', from: 'ARD', to: 'KOE', attributes: { prediction: 1194 }, }, { - id: 81, + id: '81', from: 'ARN', to: 'TLL', attributes: { prediction: 5113 }, }, { - id: 82, + id: '82', from: 'ASB', to: 'TAS', attributes: { prediction: 307 }, }, { - id: 83, + id: '83', from: 'ASO', to: 'JIM', attributes: { prediction: 617 }, }, { - id: 84, + id: '84', from: 'ATH', to: 'MXP', attributes: { prediction: 18303 }, }, { - id: 85, + id: '85', from: 'ATL', to: 'MTY', attributes: { prediction: 1704 }, }, { - id: 86, + id: '86', from: 'ATL', to: 'SAP', attributes: { prediction: 1605 }, }, { - id: 87, + id: '87', from: 'ATL', to: 'SMF', attributes: { prediction: 6641 }, }, { - id: 88, + id: '88', from: 'ATL', to: 'STX', attributes: { prediction: 1089 }, }, { - id: 89, + id: '89', from: 'ATL', to: 'TYS', attributes: { prediction: 8891 }, }, { - id: 90, + id: '90', from: 'AUC', to: 'BOG', attributes: { prediction: 2368 }, }, { - id: 91, + id: '91', from: 'AUH', to: 'BEY', attributes: { prediction: 12811 }, }, { - id: 92, + id: '92', from: 'AUS', to: 'LNK', attributes: { prediction: 40 }, }, { - id: 93, + id: '93', from: 'AUS', to: 'MSP', attributes: { prediction: 3321 }, }, { - id: 94, + id: '94', from: 'AUS', to: 'TPA', attributes: { prediction: 2954 }, }, { - id: 95, + id: '95', from: 'AYP', to: 'LIM', attributes: { prediction: 1700 }, }, { - id: 96, + id: '96', from: 'BEY', to: 'KBP', attributes: { prediction: 356 }, }, { - id: 97, + id: '97', from: 'BGY', to: 'BTS', attributes: { prediction: 4613 }, }, { - id: 98, + id: '98', from: 'BGY', to: 'CIA', attributes: { prediction: 15052 }, }, { - id: 99, + id: '99', from: 'BGY', to: 'GRO', attributes: { prediction: 13017 }, }, { - id: 100, + id: '100', from: 'BGY', to: 'NTE', attributes: { prediction: 2508 }, }, { - id: 101, + id: '101', from: 'TOY', to: 'ICN', attributes: { prediction: 1330 }, }, { - id: 102, + id: '102', from: 'TOY', to: 'PVG', attributes: { prediction: 660 }, }, { - id: 103, + id: '103', from: 'TPA', to: 'EWR', attributes: { prediction: 25177 }, }, { - id: 104, + id: '104', from: 'TPA', to: 'ISP', attributes: { prediction: 5100 }, }, { - id: 105, + id: '105', from: 'TPE', to: 'BKK', attributes: { prediction: 72122 }, }, { - id: 106, + id: '106', from: 'TPE', to: 'NGO', attributes: { prediction: 16707 }, }, { - id: 107, + id: '107', from: 'TRV', to: 'BAH', attributes: { prediction: 3757 }, }, { - id: 108, + id: '108', from: 'CID', to: 'LAN', attributes: { prediction: 74 }, }, { - id: 109, + id: '109', from: 'CIJ', to: 'TDD', attributes: { prediction: 1594 }, }, { - id: 110, + id: '110', from: 'CJU', to: 'CJJ', attributes: { prediction: 14731 }, }, { - id: 111, + id: '111', from: 'CKG', to: 'XMN', attributes: { prediction: 6952 }, }, { - id: 112, + id: '112', from: 'CLE', to: 'CUN', attributes: { prediction: 3089 }, }, { - id: 113, + id: '113', from: 'CLJ', to: 'BCN', attributes: { prediction: 2239 }, }, { - id: 114, + id: '114', from: 'BNE', to: 'GLT', attributes: { prediction: 4747 }, }, { - id: 115, + id: '115', from: 'BOM', to: 'IKA', attributes: { prediction: 1983 }, }, { - id: 116, + id: '116', from: 'BOM', to: 'SHJ', attributes: { prediction: 7381 }, }, { - id: 117, + id: '117', from: 'BOM', to: 'SIN', attributes: { prediction: 30126 }, }, { - id: 118, + id: '118', from: 'BOS', to: 'SLC', attributes: { prediction: 5875 }, }, { - id: 119, + id: '119', from: 'BPX', to: 'CTU', attributes: { prediction: 2991 }, }, { - id: 120, + id: '120', from: 'BRU', to: 'KGL', attributes: { prediction: 2595 }, }, { - id: 121, + id: '121', from: 'BTS', to: 'NYO', attributes: { prediction: 1719 }, }, { - id: 122, + id: '122', from: 'BUD', to: 'FCO', attributes: { prediction: 10501 }, }, { - id: 123, + id: '123', from: 'CLT', to: 'MGM', attributes: { prediction: 2016 }, }, { - id: 124, + id: '124', from: 'BWI', to: 'SDF', attributes: { prediction: 6945 }, }, { - id: 125, + id: '125', from: 'CCS', to: 'EWR', attributes: { prediction: 1018 }, }, { - id: 126, + id: '126', from: 'CDG', to: 'TRS', attributes: { prediction: 1725 }, }, { - id: 127, + id: '127', from: 'CEB', to: 'OZC', attributes: { prediction: 2072 }, }, { - id: 128, + id: '128', from: 'CGK', to: 'PKY', attributes: { prediction: 3264 }, }, { - id: 129, + id: '129', from: 'CMN', to: 'ORY', attributes: { prediction: 26831 }, }, { - id: 130, + id: '130', from: 'COQ', to: 'ULN', attributes: { prediction: 201 }, }, { - id: 131, + id: '131', from: 'CPH', to: 'BGO', attributes: { prediction: 12329 }, }, { - id: 132, + id: '132', from: 'CPT', to: 'DXB', attributes: { prediction: 9583 }, }, { - id: 133, + id: '133', from: 'CRW', to: 'IAD', attributes: { prediction: 2409 }, }, { - id: 134, + id: '134', from: 'VCE', to: 'NAP', attributes: { prediction: 14043 }, }, { - id: 135, + id: '135', from: 'VDM', to: 'BHI', attributes: { prediction: 283 }, }, { - id: 136, + id: '136', from: 'VGO', to: 'CDG', attributes: { prediction: 3353 }, }, { - id: 137, + id: '137', from: 'VKO', to: 'HMA', attributes: { prediction: 2523 }, }, { - id: 138, + id: '138', from: 'ZIH', to: 'PHX', attributes: { prediction: 1451 }, }, { - id: 139, + id: '139', from: 'ZIH', to: 'YYC', attributes: { prediction: 1432 }, }, { - id: 140, + id: '140', from: 'DIK', to: 'ISN', attributes: { prediction: 286 }, }, { - id: 141, + id: '141', from: 'DIR', to: 'ABK', attributes: { prediction: 182 }, }, { - id: 142, + id: '142', from: 'CSX', to: 'YIW', attributes: { prediction: 830 }, }, { - id: 143, + id: '143', from: 'CTS', to: 'TPE', attributes: { prediction: 10977 }, }, { - id: 144, + id: '144', from: 'CUF', to: 'BBU', attributes: { prediction: 934 }, }, { - id: 145, + id: '145', from: 'CUR', to: 'YYZ', attributes: { prediction: 1038 }, }, { - id: 146, + id: '146', from: 'CWB', to: 'CAC', attributes: { prediction: 1004 }, }, { - id: 147, + id: '147', from: 'CZL', to: 'LYS', attributes: { prediction: 2316 }, }, { - id: 148, + id: '148', from: 'DAC', to: 'BKK', attributes: { prediction: 10593 }, }, { - id: 149, + id: '149', from: 'DAC', to: 'JED', attributes: { prediction: 5880 }, }, { - id: 150, + id: '150', from: 'DAM', to: 'CDG', attributes: { prediction: 1958 }, }, { - id: 151, + id: '151', from: 'DAM', to: 'LCA', attributes: { prediction: 2466 }, }, { - id: 152, + id: '152', from: 'DCA', to: 'BUF', attributes: { prediction: 4445 }, }, { - id: 153, + id: '153', from: 'DEN', to: 'DAY', attributes: { prediction: 4061 }, }, { - id: 154, + id: '154', from: 'DEN', to: 'SLC', attributes: { prediction: 55602 }, }, { - id: 155, + id: '155', from: 'DLC', to: 'WUH', attributes: { prediction: 6212 }, }, { - id: 156, + id: '156', from: 'DLH', to: 'LAS', attributes: { prediction: 784 }, }, { - id: 157, + id: '157', from: 'TUP', to: 'ATL', attributes: { prediction: 601 }, }, { - id: 158, + id: '158', from: 'COK', to: 'AUH', attributes: { prediction: 6538 }, }, { - id: 159, + id: '159', from: 'KBP', to: 'AUH', attributes: { prediction: 3072 }, }, { - id: 160, + id: '160', from: 'EWR', to: 'AUS', attributes: { prediction: 5781 }, }, { - id: 161, + id: '161', from: 'ALG', to: 'ETZ', attributes: { prediction: 839 }, }, { - id: 162, + id: '162', from: 'DXB', to: 'EVN', attributes: { prediction: 1481 }, }, { - id: 163, + id: '163', from: 'LED', to: 'EVN', attributes: { prediction: 799 }, }, { - id: 164, + id: '164', from: 'BWI', to: 'EWR', attributes: { prediction: 3213 }, }, { - id: 165, + id: '165', from: 'CLE', to: 'EWR', attributes: { prediction: 13730 }, }, { - id: 166, + id: '166', from: 'DXB', to: 'MUC', attributes: { prediction: 22894 }, }, { - id: 167, + id: '167', from: 'EBL', to: 'BEY', attributes: { prediction: 286 }, }, { - id: 168, + id: '168', from: 'EDI', to: 'CMF', attributes: { prediction: 651 }, }, { - id: 169, + id: '169', from: 'ETZ', to: 'NCE', attributes: { prediction: 549 }, }, { - id: 170, + id: '170', from: 'EVN', to: 'HRK', attributes: { prediction: 258 }, }, { - id: 171, + id: '171', from: 'EVN', to: 'KBP', attributes: { prediction: 1091 }, }, { - id: 172, + id: '172', from: 'EWR', to: 'LGA', attributes: { prediction: 2 }, }, { - id: 173, + id: '173', from: 'EWR', to: 'TUL', attributes: { prediction: 888 }, }, { - id: 174, + id: '174', from: 'GND', to: 'JFK', attributes: { prediction: 1331 }, }, { - id: 175, + id: '175', from: 'GRU', to: 'SCL', attributes: { prediction: 25868 }, }, { - id: 176, + id: '176', from: 'GSO', to: 'FLL', attributes: { prediction: 36 }, }, { - id: 177, + id: '177', from: 'FKB', to: 'ALC', attributes: { prediction: 2688 }, }, { - id: 178, + id: '178', from: 'FKI', to: 'GOM', attributes: { prediction: 1327 }, }, { - id: 179, + id: '179', from: 'FRA', to: 'TSE', attributes: { prediction: 4767 }, }, { - id: 180, + id: '180', from: 'FRA', to: 'XRY', attributes: { prediction: 735 }, }, { - id: 181, + id: '181', from: 'FRO', to: 'OSL', attributes: { prediction: 2774 }, }, { - id: 182, + id: '182', from: 'FUE', to: 'ZRH', attributes: { prediction: 407 }, }, { - id: 183, + id: '183', from: 'GAJ', to: 'NKM', attributes: { prediction: 830 }, }, { - id: 184, + id: '184', from: 'GCM', to: 'MBJ', attributes: { prediction: 302 }, }, { - id: 185, + id: '185', from: 'GDL', to: 'SMF', attributes: { prediction: 2823 }, }, { - id: 186, + id: '186', from: 'GIZ', to: 'DMM', attributes: { prediction: 1737 }, }, { - id: 187, + id: '187', from: 'GLK', to: 'JIB', attributes: { prediction: 381 }, }, { - id: 188, + id: '188', from: 'GZO', to: 'BAS', attributes: { prediction: 72 }, }, { - id: 189, + id: '189', from: 'JOG', to: 'CGK', attributes: { prediction: 82842 }, }, { - id: 190, + id: '190', from: 'KHH', to: 'KMG', attributes: { prediction: 144 }, }, { - id: 191, + id: '191', from: 'KHN', to: 'HKG', attributes: { prediction: 1055 }, }, { - id: 192, + id: '192', from: 'KHZ', to: 'MKP', attributes: { prediction: 48 }, }, { - id: 193, + id: '193', from: 'HGH', to: 'WNZ', attributes: { prediction: 1208 }, }, { - id: 194, + id: '194', from: 'HKG', to: 'NAN', attributes: { prediction: 1729 }, }, { - id: 195, + id: '195', from: 'HOB', to: 'CNM', attributes: { prediction: 387 }, }, { - id: 196, + id: '196', from: 'HPN', to: 'PHL', attributes: { prediction: 2453 }, }, { - id: 197, + id: '197', from: 'HSV', to: 'ORD', attributes: { prediction: 3797 }, }, { - id: 198, + id: '198', from: 'HTY', to: 'IST', attributes: { prediction: 9676 }, }, { - id: 199, + id: '199', from: 'IAD', to: 'BUF', attributes: { prediction: 4058 }, }, { - id: 200, + id: '200', from: 'IAH', to: 'SMF', attributes: { prediction: 12616 }, }, { - id: 201, + id: '201', from: 'IAH', to: 'VER', attributes: { prediction: 1111 }, }, { - id: 202, + id: '202', from: 'ICN', to: 'OKA', attributes: { prediction: 2677 }, }, { - id: 203, + id: '203', from: 'KIX', to: 'DOH', attributes: { prediction: 5789 }, }, { - id: 204, + id: '204', from: 'KKR', to: 'RGI', attributes: { prediction: 27 }, }, { - id: 205, + id: '205', from: 'KLU', to: 'TXL', attributes: { prediction: 2212 }, }, { - id: 206, + id: '206', from: 'IKA', to: 'SAW', attributes: { prediction: 851 }, }, { - id: 207, + id: '207', from: 'IND', to: 'FWA', attributes: { prediction: 23 }, }, { - id: 208, + id: '208', from: 'IND', to: 'TPA', attributes: { prediction: 8287 }, }, { - id: 209, + id: '209', from: 'IQQ', to: 'CPO', attributes: { prediction: 1700 }, }, { - id: 210, + id: '210', from: 'ISG', to: 'MMY', attributes: { prediction: 2772 }, }, { - id: 211, + id: '211', from: 'IXS', to: 'CCU', attributes: { prediction: 2583 }, }, { - id: 212, + id: '212', from: 'JFK', to: 'PVR', attributes: { prediction: 130 }, }, { - id: 213, + id: '213', from: 'JFK', to: 'YUL', attributes: { prediction: 4841 }, }, { - id: 214, + id: '214', from: 'JIB', to: 'ADE', attributes: { prediction: 332 }, }, { - id: 215, + id: '215', from: 'JJU', to: 'UAK', attributes: { prediction: 356 }, }, { - id: 216, + id: '216', from: 'KMG', to: 'HFE', attributes: { prediction: 6540 }, }, { - id: 217, + id: '217', from: 'KMI', to: 'FUK', attributes: { prediction: 11491 }, }, { - id: 218, + id: '218', from: 'KOT', to: 'BET', attributes: { prediction: 90 }, }, { - id: 219, + id: '219', from: 'KRK', to: 'BGO', attributes: { prediction: 1045 }, }, { - id: 220, + id: '220', from: 'KRR', to: 'UFA', attributes: { prediction: 615 }, }, { - id: 221, + id: '221', from: 'TLL', to: 'GOT', attributes: { prediction: 399 }, }, { - id: 222, + id: '222', from: 'JNB', to: 'GRJ', attributes: { prediction: 12980 }, }, { - id: 223, + id: '223', from: 'CAG', to: 'GRO', attributes: { prediction: 4152 }, }, { - id: 224, + id: '224', from: 'TLV', to: 'GRZ', attributes: { prediction: 243 }, }, { - id: 225, + id: '225', from: 'MCO', to: 'GSP', attributes: { prediction: 1248 }, }, { - id: 226, + id: '226', from: 'LHR', to: 'DTW', attributes: { prediction: 4770 }, }, { - id: 227, + id: '227', from: 'LHR', to: 'EDI', attributes: { prediction: 43251 }, }, { - id: 228, + id: '228', from: 'LHR', to: 'SVG', attributes: { prediction: 4734 }, }, { - id: 229, + id: '229', from: 'LHW', to: 'HAK', attributes: { prediction: 1372 }, }, { - id: 230, + id: '230', from: 'LCA', to: 'AUH', attributes: { prediction: 1608 }, }, { - id: 231, + id: '231', from: 'LED', to: 'GOJ', attributes: { prediction: 127 }, }, { - id: 232, + id: '232', from: 'LEX', to: 'ORD', attributes: { prediction: 2780 }, }, { - id: 233, + id: '233', from: 'LGW', to: 'LIN', attributes: { prediction: 3361 }, }, { - id: 234, + id: '234', from: 'LIM', to: 'PTY', attributes: { prediction: 12750 }, }, { - id: 235, + id: '235', from: 'GRU', to: 'GYN', attributes: { prediction: 11993 }, }, { - id: 236, + id: '236', from: 'RUN', to: 'HAH', attributes: { prediction: 773 }, }, { - id: 237, + id: '237', from: 'CTU', to: 'HAK', attributes: { prediction: 12961 }, }, { - id: 238, + id: '238', from: 'SPC', to: 'HAM', attributes: { prediction: 1195 }, }, { - id: 239, + id: '239', from: 'LPA', to: 'HEL', attributes: { prediction: 1590 }, }, { - id: 240, + id: '240', from: 'MXP', to: 'OTP', attributes: { prediction: 5053 }, }, { - id: 241, + id: '241', from: 'MAA', to: 'GOI', attributes: { prediction: 2706 }, }, { - id: 242, + id: '242', from: 'MAD', to: 'HAM', attributes: { prediction: 1453 }, }, { - id: 243, + id: '243', from: 'MAD', to: 'ZAZ', attributes: { prediction: 1114 }, }, { - id: 244, + id: '244', from: 'MAN', to: 'BGI', attributes: { prediction: 1937 }, }, { - id: 245, + id: '245', from: 'MAR', to: 'LSP', attributes: { prediction: 1273 }, }, { - id: 246, + id: '246', from: 'MCM', to: 'NCE', attributes: { prediction: 566 }, }, { - id: 247, + id: '247', from: 'MCO', to: 'BOS', attributes: { prediction: 28652 }, }, { - id: 248, + id: '248', from: 'MCO', to: 'YYZ', attributes: { prediction: 26354 }, }, { - id: 249, + id: '249', from: 'MCT', to: 'BLR', attributes: { prediction: 2195 }, }, { - id: 250, + id: '250', from: 'MCT', to: 'DAC', attributes: { prediction: 1092 }, }, { - id: 251, + id: '251', from: 'MDE', to: 'BAQ', attributes: { prediction: 1857 }, }, { - id: 252, + id: '252', from: 'MEL', to: 'BME', attributes: { prediction: 403 }, }, { - id: 253, + id: '253', from: 'MEM', to: 'AEX', attributes: { prediction: 1976 }, }, { - id: 254, + id: '254', from: 'MEM', to: 'PHL', attributes: { prediction: 3466 }, }, { - id: 255, + id: '255', from: 'MEX', to: 'HUX', attributes: { prediction: 9436 }, }, { - id: 256, + id: '256', from: 'MZV', to: 'MYY', attributes: { prediction: 2253 }, }, { - id: 257, + id: '257', from: 'NAN', to: 'KDV', attributes: { prediction: 292 }, }, { - id: 258, + id: '258', from: 'NAY', to: 'UYN', attributes: { prediction: 1789 }, }, { - id: 259, + id: '259', from: 'MHK', to: 'MCK', attributes: { prediction: 342 }, }, { - id: 260, + id: '260', from: 'MIA', to: 'UVF', attributes: { prediction: 5299 }, }, { - id: 261, + id: '261', from: 'MJF', to: 'SSJ', attributes: { prediction: 168 }, }, { - id: 262, + id: '262', from: 'MKE', to: 'BWI', attributes: { prediction: 12409 }, }, { - id: 263, + id: '263', from: 'MLE', to: 'FCO', attributes: { prediction: 2441 }, }, { - id: 264, + id: '264', from: 'MOB', to: 'LAX', attributes: { prediction: 117 }, }, { - id: 265, + id: '265', from: 'MSN', to: 'ORD', attributes: { prediction: 10135 }, }, { - id: 266, + id: '266', from: 'MSP', to: 'CWA', attributes: { prediction: 2462 }, }, { - id: 267, + id: '267', from: 'MUC', to: 'HKT', attributes: { prediction: 3804 }, }, { - id: 268, + id: '268', from: 'NBO', to: 'LKG', attributes: { prediction: 1046 }, }, { - id: 269, + id: '269', from: 'NOU', to: 'NRT', attributes: { prediction: 3692 }, }, { - id: 270, + id: '270', from: 'OTZ', to: 'IAN', attributes: { prediction: 123 }, }, { - id: 271, + id: '271', from: 'FIH', to: 'LOS', attributes: { prediction: 1045 }, }, { - id: 272, + id: '272', from: 'GRO', to: 'LPA', attributes: { prediction: 2065 }, }, { - id: 273, + id: '273', from: 'SDR', to: 'LPA', attributes: { prediction: 174 }, }, { - id: 274, + id: '274', from: 'MFU', to: 'LUN', attributes: { prediction: 410 }, }, { - id: 275, + id: '275', from: 'YYZ', to: 'MHT', attributes: { prediction: 658 }, }, { - id: 276, + id: '276', from: 'BUR', to: 'MIA', attributes: { prediction: 10 }, }, { - id: 277, + id: '277', from: 'PAD', to: 'FUE', attributes: { prediction: 1875 }, }, { - id: 278, + id: '278', from: 'PBI', to: 'CVG', attributes: { prediction: 1561 }, }, { - id: 279, + id: '279', from: 'PBM', to: 'CAY', attributes: { prediction: 413 }, }, { - id: 280, + id: '280', from: 'PDA', to: 'VVC', attributes: { prediction: 636 }, }, { - id: 281, + id: '281', from: 'NUX', to: 'UFA', attributes: { prediction: 477 }, }, { - id: 282, + id: '282', from: 'NYU', to: 'MDL', attributes: { prediction: 3681 }, }, { - id: 283, + id: '283', from: 'OAK', to: 'LGB', attributes: { prediction: 9271 }, }, { - id: 284, + id: '284', from: 'OKC', to: 'LNK', attributes: { prediction: 38 }, }, { - id: 285, + id: '285', from: 'OLH', to: 'ADQ', attributes: { prediction: 218 }, }, { - id: 286, + id: '286', from: 'ONT', to: 'DFW', attributes: { prediction: 13072 }, }, { - id: 287, + id: '287', from: 'OOL', to: 'NRT', attributes: { prediction: 6358 }, }, { - id: 288, + id: '288', from: 'ORD', to: 'NRT', attributes: { prediction: 32584 }, }, { - id: 289, + id: '289', from: 'ORY', to: 'PGX', attributes: { prediction: 407 }, }, { - id: 290, + id: '290', from: 'OSL', to: 'BCN', attributes: { prediction: 2645 }, }, { - id: 291, + id: '291', from: 'OSL', to: 'MAN', attributes: { prediction: 1879 }, }, { - id: 292, + id: '292', from: 'OSL', to: 'TRD', attributes: { prediction: 49883 }, }, { - id: 293, + id: '293', from: 'OSR', to: 'MUC', attributes: { prediction: 253 }, }, { - id: 294, + id: '294', from: 'OVB', to: 'PEK', attributes: { prediction: 2291 }, }, { - id: 295, + id: '295', from: 'SEA', to: 'MIA', attributes: { prediction: 3685 }, }, { - id: 296, + id: '296', from: 'FLL', to: 'MKE', attributes: { prediction: 4123 }, }, { - id: 297, + id: '297', from: 'STL', to: 'MKE', attributes: { prediction: 4155 }, }, { - id: 298, + id: '298', from: 'CTA', to: 'MLA', attributes: { prediction: 3127 }, }, { - id: 299, + id: '299', from: 'ESB', to: 'MLX', attributes: { prediction: 1967 }, }, { - id: 300, + id: '300', from: 'PEK', to: 'MNL', attributes: { prediction: 3139 }, }, { - id: 301, + id: '301', from: 'MXM', to: 'MOQ', attributes: { prediction: 19 }, }, { - id: 302, + id: '302', from: 'RVK', to: 'MQN', attributes: { prediction: 109 }, }, { - id: 303, + id: '303', from: 'BCN', to: 'MRS', attributes: { prediction: 1056 }, }, { - id: 304, + id: '304', from: 'LIS', to: 'MRS', attributes: { prediction: 3067 }, }, { - id: 305, + id: '305', from: 'DUR', to: 'MRU', attributes: { prediction: 521 }, }, { - id: 306, + id: '306', from: 'BJI', to: 'MSP', attributes: { prediction: 1056 }, }, { - id: 307, + id: '307', from: 'MZT', to: 'MSP', attributes: { prediction: 2887 }, }, { - id: 308, + id: '308', from: 'CMN', to: 'NKC', attributes: { prediction: 3555 }, }, { - id: 309, + id: '309', from: 'PSC', to: 'SEA', attributes: { prediction: 8034 }, }, { - id: 310, + id: '310', from: 'STL', to: 'SEA', attributes: { prediction: 2671 }, }, { - id: 311, + id: '311', from: 'SHA', to: 'JIU', attributes: { prediction: 1111 }, }, { - id: 312, + id: '312', from: 'SHA', to: 'LYI', attributes: { prediction: 2837 }, }, { - id: 313, + id: '313', from: 'SHA', to: 'WEH', attributes: { prediction: 2091 }, }, { - id: 314, + id: '314', from: 'SHE', to: 'HGH', attributes: { prediction: 15577 }, }, { - id: 315, + id: '315', from: 'POP', to: 'MIA', attributes: { prediction: 3387 }, }, { - id: 316, + id: '316', from: 'POS', to: 'CUR', attributes: { prediction: 2047 }, }, { - id: 317, + id: '317', from: 'POW', to: 'BEG', attributes: { prediction: 115 }, }, { - id: 318, + id: '318', from: 'PPT', to: 'KXU', attributes: { prediction: 48 }, }, { - id: 319, + id: '319', from: 'PRG', to: 'MAD', attributes: { prediction: 9526 }, }, { - id: 320, + id: '320', from: 'PRG', to: 'STN', attributes: { prediction: 4510 }, }, { - id: 321, + id: '321', from: 'PSA', to: 'EDI', attributes: { prediction: 1300 }, }, { - id: 322, + id: '322', from: 'PSA', to: 'EIN', attributes: { prediction: 4266 }, }, { - id: 323, + id: '323', from: 'PSA', to: 'HHN', attributes: { prediction: 4325 }, }, { - id: 324, + id: '324', from: 'PSA', to: 'MAD', attributes: { prediction: 902 }, }, { - id: 325, + id: '325', from: 'PTP', to: 'PAP', attributes: { prediction: 4025 }, }, { - id: 326, + id: '326', from: 'PTY', to: 'IAH', attributes: { prediction: 10810 }, }, { - id: 327, + id: '327', from: 'PYY', to: 'CNX', attributes: { prediction: 339 }, }, { - id: 328, + id: '328', from: 'QSF', to: 'LYS', attributes: { prediction: 3622 }, }, { - id: 329, + id: '329', from: 'RAI', to: 'BOS', attributes: { prediction: 1412 }, }, { - id: 330, + id: '330', from: 'RAK', to: 'EMA', attributes: { prediction: 1233 }, }, { - id: 331, + id: '331', from: 'RAP', to: 'DEN', attributes: { prediction: 8645 }, }, { - id: 332, + id: '332', from: 'RBQ', to: 'LPB', attributes: { prediction: 1541 }, }, { - id: 333, + id: '333', from: 'RDV', to: 'SLQ', attributes: { prediction: 5 }, }, { - id: 334, + id: '334', from: 'SHJ', to: 'GOI', attributes: { prediction: 1542 }, }, { - id: 335, + id: '335', from: 'RSW', to: 'ORD', attributes: { prediction: 16617 }, }, { - id: 336, + id: '336', from: 'RUT', to: 'BOS', attributes: { prediction: 322 }, }, { - id: 337, + id: '337', from: 'RVK', to: 'MQN', attributes: { prediction: 107 }, }, { - id: 338, + id: '338', from: 'SAL', to: 'IAH', attributes: { prediction: 12641 }, }, { - id: 339, + id: '339', from: 'SAN', to: 'MCO', attributes: { prediction: 107 }, }, { - id: 340, + id: '340', from: 'SCU', to: 'FCO', attributes: { prediction: 1380 }, }, { - id: 341, + id: '341', from: 'SDR', to: 'ALC', attributes: { prediction: 3169 }, }, { - id: 342, + id: '342', from: 'SEA', to: 'FAI', attributes: { prediction: 6606 }, }, { - id: 343, + id: '343', from: 'SEA', to: 'HLN', attributes: { prediction: 1308 }, }, { - id: 344, + id: '344', from: 'SJU', to: 'SLU', attributes: { prediction: 2119 }, }, { - id: 345, + id: '345', from: 'SJW', to: 'CAN', attributes: { prediction: 2703 }, }, { - id: 346, + id: '346', from: 'SKK', to: 'UNK', attributes: { prediction: 62 }, }, { - id: 347, + id: '347', from: 'SLU', to: 'BGI', attributes: { prediction: 3838 }, }, { - id: 348, + id: '348', from: 'YXL', to: 'SUR', attributes: { prediction: 113 }, }, { - id: 349, + id: '349', from: 'KDV', to: 'SUV', attributes: { prediction: 415 }, }, { - id: 350, + id: '350', from: 'FCO', to: 'SVQ', attributes: { prediction: 3739 }, }, { - id: 351, + id: '351', from: 'PEK', to: 'SWA', attributes: { prediction: 6730 }, }, { - id: 352, + id: '352', from: 'ABX', to: 'SYD', attributes: { prediction: 7627 }, }, { - id: 353, + id: '353', from: 'POM', to: 'SYD', attributes: { prediction: 1284 }, }, { - id: 354, + id: '354', from: 'LRR', to: 'SYZ', attributes: { prediction: 177 }, }, { - id: 355, + id: '355', from: 'GUM', to: 'TPE', attributes: { prediction: 4268 }, }, { - id: 356, + id: '356', from: 'STN', to: 'KIR', attributes: { prediction: 2557 }, }, { - id: 357, + id: '357', from: 'STN', to: 'TFS', attributes: { prediction: 5514 }, }, { - id: 358, + id: '358', from: 'STR', to: 'SPC', attributes: { prediction: 694 }, }, { - id: 359, + id: '359', from: 'SVO', to: 'LEJ', attributes: { prediction: 928 }, }, { - id: 360, + id: '360', from: 'SWJ', to: 'NUS', attributes: { prediction: 39 }, }, { - id: 361, + id: '361', from: 'SYD', to: 'ARM', attributes: { prediction: 1681 }, }, { - id: 362, + id: '362', from: 'SYX', to: 'SHE', attributes: { prediction: 1562 }, }, { - id: 363, + id: '363', from: 'SZX', to: 'FOC', attributes: { prediction: 15783 }, }, { - id: 364, + id: '364', from: 'DUB', to: 'TRF', attributes: { prediction: 2163 }, }, { - id: 365, + id: '365', from: 'TSA', to: 'TSN', attributes: { prediction: 967 }, }, { - id: 366, + id: '366', from: 'FLR', to: 'TSR', attributes: { prediction: 843 }, }, { - id: 367, + id: '367', from: 'GVA', to: 'TUN', attributes: { prediction: 3547 }, }, { - id: 368, + id: '368', from: 'ELQ', to: 'TUU', attributes: { prediction: 571 }, }, { - id: 369, + id: '369', from: 'FRL', to: 'TXL', attributes: { prediction: 973 }, }, { - id: 370, + id: '370', from: 'SOF', to: 'TXL', attributes: { prediction: 2077 }, }, { - id: 371, + id: '371', from: 'UDI', to: 'UBA', attributes: { prediction: 1992 }, }, { - id: 372, + id: '372', from: 'DME', to: 'UGC', attributes: { prediction: 791 }, }, { - id: 373, + id: '373', from: 'XMS', to: 'UIO', attributes: { prediction: 262 }, }, { - id: 374, + id: '374', from: 'KGF', to: 'UKK', attributes: { prediction: 189 }, }, { - id: 375, + id: '375', from: 'WNR', to: 'ULP', attributes: { prediction: 170 }, }, { - id: 376, + id: '376', from: 'LBD', to: 'URC', attributes: { prediction: 158 }, }, { - id: 377, + id: '377', from: 'DME', to: 'UUA', attributes: { prediction: 441 }, }, { - id: 378, + id: '378', from: 'BKK', to: 'XMN', attributes: { prediction: 2189 }, }, { - id: 379, + id: '379', from: 'YNJ', to: 'ICN', attributes: { prediction: 8334 }, }, { - id: 380, + id: '380', from: 'YNT', to: 'CGQ', attributes: { prediction: 116 }, }, { - id: 381, + id: '381', from: 'YOW', to: 'DCA', attributes: { prediction: 1401 }, }, { - id: 382, + id: '382', from: 'TSN', to: 'KUL', attributes: { prediction: 6717 }, }, { - id: 383, + id: '383', from: 'TSN', to: 'SZX', attributes: { prediction: 17715 }, }, { - id: 384, + id: '384', from: 'TUP', to: 'ATL', attributes: { prediction: 573 }, }, { - id: 385, + id: '385', from: 'YQB', to: 'YOW', attributes: { prediction: 920 }, }, { - id: 386, + id: '386', from: 'YTE', to: 'YFB', attributes: { prediction: 588 }, }, { - id: 387, + id: '387', from: 'YVR', to: 'IAH', attributes: { prediction: 4260 }, }, { - id: 388, + id: '388', from: 'YVR', to: 'MSP', attributes: { prediction: 1718 }, }, { - id: 389, + id: '389', from: 'VOZ', to: 'LED', attributes: { prediction: 448 }, }, { - id: 390, + id: '390', from: 'VSG', to: 'KBP', attributes: { prediction: 1026 }, }, { - id: 391, + id: '391', from: 'WAW', to: 'RIX', attributes: { prediction: 2677 }, }, { - id: 392, + id: '392', from: 'WNZ', to: 'HAK', attributes: { prediction: 3608 }, }, { - id: 393, + id: '393', from: 'WRO', to: 'DTM', attributes: { prediction: 1652 }, }, { - id: 394, + id: '394', from: 'WRO', to: 'STN', attributes: { prediction: 4712 }, }, { - id: 395, + id: '395', from: 'WUH', to: 'XFN', attributes: { prediction: 240 }, }, { - id: 396, + id: '396', from: 'XKS', to: 'WNN', attributes: { prediction: 44 }, }, { - id: 397, + id: '397', from: 'YEV', to: 'YHI', attributes: { prediction: 86 }, }, { - id: 398, + id: '398', from: 'YHD', to: 'YQT', attributes: { prediction: 169 }, }, { - id: 399, + id: '399', from: 'YHZ', to: 'IAD', attributes: { prediction: 190 }, }, { - id: 400, + id: '400', from: 'YXS', to: 'YXJ', attributes: { prediction: 213 }, }, { - id: 401, + id: '401', from: 'YXY', to: 'YFS', attributes: { prediction: 139 }, }, { - id: 402, + id: '402', from: 'YYC', to: 'YVR', attributes: { prediction: 60230 }, }, { - id: 403, + id: '403', from: 'YYZ', to: 'ANU', attributes: { prediction: 1355 }, }, { - id: 404, + id: '404', from: 'YYZ', to: 'PVG', attributes: { prediction: 3161 }, }, { - id: 405, + id: '405', from: 'FOC', to: 'XUZ', attributes: { prediction: 1354 }, }, { - id: 406, + id: '406', from: 'YBX', to: 'YAY', attributes: { prediction: 630 }, }, { - id: 407, + id: '407', from: 'GLA', to: 'AMS', attributes: { prediction: 9297 }, }, { - id: 408, + id: '408', from: 'LGW', to: 'AMS', attributes: { prediction: 19761 }, }, { - id: 409, + id: '409', from: 'STN', to: 'AMS', attributes: { prediction: 8014 }, }, { - id: 410, + id: '410', from: 'LFW', to: 'ABJ', attributes: { prediction: 1940 }, }, { - id: 411, + id: '411', from: 'HYA', to: 'ACK', attributes: { prediction: 2036 }, }, { - id: 412, + id: '412', from: 'AFA', to: 'AEP', attributes: { prediction: 781 }, }, { - id: 413, + id: '413', from: 'CDG', to: 'AGP', attributes: { prediction: 12126 }, }, { - id: 414, + id: '414', from: 'MDW', to: 'ALB', attributes: { prediction: 4248 }, }, { - id: 415, + id: '415', from: 'ACE', to: 'ALC', attributes: { prediction: 177 }, }, { - id: 416, + id: '416', from: 'TRD', to: 'ALC', attributes: { prediction: 337 }, }, { - id: 417, + id: '417', from: 'AGP', to: 'AMS', attributes: { prediction: 5834 }, }, { - id: 418, + id: '418', from: 'BGO', to: 'AMS', attributes: { prediction: 9580 }, }, { - id: 419, + id: '419', from: 'PHX', to: 'ANC', attributes: { prediction: 2599 }, }, { - id: 420, + id: '420', from: 'SXM', to: 'ANU', attributes: { prediction: 4105 }, }, { - id: 421, + id: '421', from: 'ITM', to: 'AOJ', attributes: { prediction: 4041 }, }, { - id: 422, + id: '422', from: 'KRN', to: 'ARN', attributes: { prediction: 5791 }, }, { - id: 423, + id: '423', from: 'CAI', to: 'ASW', attributes: { prediction: 17584 }, }, { - id: 424, + id: '424', from: 'CAI', to: 'BGW', attributes: { prediction: 1197 }, }, { - id: 425, + id: '425', from: 'MAD', to: 'BVA', attributes: { prediction: 5200 }, }, { - id: 426, + id: '426', from: 'MEM', to: 'BWI', attributes: { prediction: 4300 }, }, { - id: 427, + id: '427', from: 'ZHA', to: 'CAN', attributes: { prediction: 7045 }, }, { - id: 428, + id: '428', from: 'MDE', to: 'CCS', attributes: { prediction: 1100 }, }, { - id: 429, + id: '429', from: 'TYN', to: 'BAV', attributes: { prediction: 2610 }, }, { - id: 430, + id: '430', from: 'ISB', to: 'BCN', attributes: { prediction: 897 }, }, { - id: 431, + id: '431', from: 'VIE', to: 'BCN', attributes: { prediction: 8619 }, }, { - id: 432, + id: '432', from: 'MCO', to: 'BDL', attributes: { prediction: 13958 }, }, { - id: 433, + id: '433', from: 'LGW', to: 'BGI', attributes: { prediction: 19270 }, }, { - id: 434, + id: '434', from: 'BLL', to: 'BGY', attributes: { prediction: 1724 }, }, { - id: 435, + id: '435', from: 'MSY', to: 'BHM', attributes: { prediction: 4582 }, }, { - id: 436, + id: '436', from: 'FNC', to: 'BHX', attributes: { prediction: 822 }, }, { - id: 437, + id: '437', from: 'MCO', to: 'BKG', attributes: { prediction: 298 }, }, { - id: 438, + id: '438', from: 'BBU', to: 'BLQ', attributes: { prediction: 1465 }, }, { - id: 439, + id: '439', from: 'COK', to: 'BLR', attributes: { prediction: 8217 }, }, { - id: 440, + id: '440', from: 'PHX', to: 'BNA', attributes: { prediction: 7493 }, }, { - id: 441, + id: '441', from: 'ADZ', to: 'BOG', attributes: { prediction: 19886 }, }, { - id: 442, + id: '442', from: 'VVC', to: 'BOG', attributes: { prediction: 1875 }, }, { - id: 443, + id: '443', from: 'JAX', to: 'BOS', attributes: { prediction: 2052 }, }, { - id: 444, + id: '444', from: 'TIA', to: 'BRI', attributes: { prediction: 3706 }, }, { - id: 445, + id: '445', from: 'GRO', to: 'BRS', attributes: { prediction: 1690 }, }, { - id: 446, + id: '446', from: 'SID', to: 'BRU', attributes: { prediction: 1268 }, }, { - id: 447, + id: '447', from: 'LYS', to: 'BSK', attributes: { prediction: 484 }, }, { - id: 448, + id: '448', from: 'NCE', to: 'BSL', attributes: { prediction: 1807 }, }, { - id: 449, + id: '449', from: 'SXM', to: 'CDG', attributes: { prediction: 7099 }, }, { - id: 450, + id: '450', from: 'ARN', to: 'CGN', attributes: { prediction: 1709 }, }, { - id: 451, + id: '451', from: 'GGW', to: 'BIL', attributes: { prediction: 327 }, }, { - id: 452, + id: '452', from: 'SEA', to: 'BIL', attributes: { prediction: 3329 }, }, { - id: 453, + id: '453', from: 'MRS', to: 'BJA', attributes: { prediction: 779 }, }, { - id: 454, + id: '454', from: 'VDS', to: 'BJF', attributes: { prediction: 487 }, }, { - id: 455, + id: '455', from: 'KIX', to: 'BKK', attributes: { prediction: 21154 }, }, { - id: 456, + id: '456', from: 'CLJ', to: 'CUF', attributes: { prediction: 765 }, }, { - id: 457, + id: '457', from: 'CVG', to: 'CUN', attributes: { prediction: 2625 }, }, { - id: 458, + id: '458', from: 'DFW', to: 'CUN', attributes: { prediction: 18996 }, }, { - id: 459, + id: '459', from: 'YYJ', to: 'CUN', attributes: { prediction: 445 }, }, { - id: 460, + id: '460', from: 'ISB', to: 'CJL', attributes: { prediction: 707 }, }, { - id: 461, + id: '461', from: 'BSB', to: 'CNF', attributes: { prediction: 35848 }, }, { - id: 462, + id: '462', from: 'CNF', to: 'CPQ', attributes: { prediction: 6375 }, }, { - id: 463, + id: '463', from: 'DEN', to: 'DAL', attributes: { prediction: 102 }, }, { - id: 464, + id: '464', from: 'IND', to: 'DAL', attributes: { prediction: 98 }, }, { - id: 465, + id: '465', from: 'CAN', to: 'DAX', attributes: { prediction: 2891 }, }, { - id: 466, + id: '466', from: 'TPA', to: 'DAY', attributes: { prediction: 1914 }, }, { - id: 467, + id: '467', from: 'JLR', to: 'DEL', attributes: { prediction: 722 }, }, { - id: 468, + id: '468', from: 'BNA', to: 'DEN', attributes: { prediction: 18422 }, }, { - id: 469, + id: '469', from: 'PIA', to: 'DEN', attributes: { prediction: 962 }, }, { - id: 470, + id: '470', from: 'SSH', to: 'BRU', attributes: { prediction: 977 }, }, { - id: 471, + id: '471', from: 'CDG', to: 'BSL', attributes: { prediction: 6922 }, }, { - id: 472, + id: '472', from: 'BEY', to: 'DXB', attributes: { prediction: 34030 }, }, { - id: 473, + id: '473', from: 'JAI', to: 'DXB', attributes: { prediction: 1628 }, }, { - id: 474, + id: '474', from: 'ISU', to: 'EBL', attributes: { prediction: 2227 }, }, { - id: 475, + id: '475', from: 'SAV', to: 'DFW', attributes: { prediction: 2176 }, }, { - id: 476, + id: '476', from: 'SFO', to: 'DFW', attributes: { prediction: 34973 }, }, { - id: 477, + id: '477', from: 'AUH', to: 'DME', attributes: { prediction: 3413 }, }, { - id: 478, + id: '478', from: 'KGF', to: 'DME', attributes: { prediction: 503 }, }, { - id: 479, + id: '479', from: 'VOG', to: 'DME', attributes: { prediction: 5751 }, }, { - id: 480, + id: '480', from: 'BEY', to: 'DOH', attributes: { prediction: 10169 }, }, { - id: 481, + id: '481', from: 'SJO', to: 'DRK', attributes: { prediction: 115 }, }, { - id: 482, + id: '482', from: 'LGA', to: 'DTW', attributes: { prediction: 23366 }, }, { - id: 483, + id: '483', from: 'RSW', to: 'DTW', attributes: { prediction: 27675 }, }, { - id: 484, + id: '484', from: 'EIN', to: 'DUB', attributes: { prediction: 2818 }, }, { - id: 485, + id: '485', from: 'FCO', to: 'DUB', attributes: { prediction: 4672 }, }, { - id: 486, + id: '486', from: 'RIX', to: 'DUB', attributes: { prediction: 4864 }, }, { - id: 487, + id: '487', from: 'AUS', to: 'ELP', attributes: { prediction: 8923 }, }, { - id: 488, + id: '488', from: 'STL', to: 'DSM', attributes: { prediction: 2751 }, }, { - id: 489, + id: '489', from: 'RTM', to: 'FCO', attributes: { prediction: 4189 }, }, { - id: 490, + id: '490', from: 'TAS', to: 'FCO', attributes: { prediction: 760 }, }, { - id: 491, + id: '491', from: 'BNA', to: 'FLL', attributes: { prediction: 7449 }, }, { - id: 492, + id: '492', from: 'MHT', to: 'FLL', attributes: { prediction: 236 }, }, { - id: 493, + id: '493', from: 'PEK', to: 'FOC', attributes: { prediction: 36688 }, }, { - id: 494, + id: '494', from: 'GIG', to: 'FOR', attributes: { prediction: 14641 }, }, { - id: 495, + id: '495', from: 'DFW', to: 'FRA', attributes: { prediction: 12173 }, }, { - id: 496, + id: '496', from: 'ZRH', to: 'FCO', attributes: { prediction: 10996 }, }, { - id: 497, + id: '497', from: 'PVG', to: 'FKS', attributes: { prediction: 457 }, }, { - id: 498, + id: '498', from: 'DKR', to: 'FNA', attributes: { prediction: 1788 }, }, { - id: 499, + id: '499', from: 'DUB', to: 'FNC', attributes: { prediction: 549 }, }, { - id: 500, + id: '500', from: 'STR', to: 'FNC', attributes: { prediction: 914 }, }, { - id: 501, + id: '501', from: 'BCN', to: 'FRA', attributes: { prediction: 21399 }, }, { - id: 502, + id: '502', from: 'FCO', to: 'FRA', attributes: { prediction: 26744 }, }, { - id: 503, + id: '503', from: 'MEX', to: 'FRA', attributes: { prediction: 6862 }, }, { - id: 504, + id: '504', from: 'ROV', to: 'FRA', attributes: { prediction: 1601 }, }, { - id: 505, + id: '505', from: 'PUS', to: 'FUK', attributes: { prediction: 8054 }, }, { - id: 506, + id: '506', from: 'ACI', to: 'GCI', attributes: { prediction: 687 }, }, { - id: 507, + id: '507', from: 'CEN', to: 'GDL', attributes: { prediction: 2012 }, }, { - id: 508, + id: '508', from: 'SNA', to: 'LAX', attributes: { prediction: 17 }, }, { - id: 509, + id: '509', from: 'PUW', to: 'LWS', attributes: { prediction: 1306 }, }, { - id: 510, + id: '510', from: 'KIX', to: 'LXR', attributes: { prediction: 1646 }, }, { - id: 511, + id: '511', from: 'SXB', to: 'LYS', attributes: { prediction: 7887 }, }, { - id: 512, + id: '512', from: 'PEN', to: 'JHB', attributes: { prediction: 5257 }, }, { - id: 513, + id: '513', from: 'MTS', to: 'JNB', attributes: { prediction: 2204 }, }, { - id: 514, + id: '514', from: 'REC', to: 'JPA', attributes: { prediction: 3788 }, }, { - id: 515, + id: '515', from: 'DTM', to: 'KBP', attributes: { prediction: 2009 }, }, { - id: 516, + id: '516', from: 'MUC', to: 'KBP', attributes: { prediction: 5587 }, }, { - id: 517, + id: '517', from: 'PRG', to: 'KBP', attributes: { prediction: 5904 }, }, { - id: 518, + id: '518', from: 'RNL', to: 'HIR', attributes: { prediction: 72 }, }, { - id: 519, + id: '519', from: 'BKK', to: 'HKG', attributes: { prediction: 95668 }, }, { - id: 520, + id: '520', from: 'CEB', to: 'HKG', attributes: { prediction: 10545 }, }, { - id: 521, + id: '521', from: 'PVG', to: 'HKG', attributes: { prediction: 105231 }, }, { - id: 522, + id: '522', from: 'TNA', to: 'HKG', attributes: { prediction: 2203 }, }, { - id: 523, + id: '523', from: 'WUH', to: 'HKG', attributes: { prediction: 4806 }, }, { - id: 524, + id: '524', from: 'AOJ', to: 'HND', attributes: { prediction: 22770 }, }, { - id: 525, + id: '525', from: 'ASJ', to: 'HND', attributes: { prediction: 2974 }, }, { - id: 526, + id: '526', from: 'NTQ', to: 'HND', attributes: { prediction: 3978 }, }, { - id: 527, + id: '527', from: 'TPA', to: 'HPN', attributes: { prediction: 2785 }, }, { - id: 528, + id: '528', from: 'DSN', to: 'HRB', attributes: { prediction: 667 }, }, { - id: 529, + id: '529', from: 'HEK', to: 'HRB', attributes: { prediction: 1611 }, }, { - id: 530, + id: '530', from: 'LAD', to: 'HRE', attributes: { prediction: 333 }, }, { - id: 531, + id: '531', from: 'VFA', to: 'HRE', attributes: { prediction: 481 }, }, { - id: 532, + id: '532', from: 'CLT', to: 'HTS', attributes: { prediction: 2322 }, }, { - id: 533, + id: '533', from: 'ZAH', to: 'KER', attributes: { prediction: 241 }, }, { - id: 534, + id: '534', from: 'PER', to: 'KGI', attributes: { prediction: 6908 }, }, { - id: 535, + id: '535', from: 'FCO', to: 'ICN', attributes: { prediction: 2661 }, }, { - id: 536, + id: '536', from: 'NAG', to: 'IDR', attributes: { prediction: 591 }, }, { - id: 537, + id: '537', from: 'RUH', to: 'ISB', attributes: { prediction: 7546 }, }, { - id: 538, + id: '538', from: 'YYZ', to: 'ISB', attributes: { prediction: 954 }, }, { - id: 539, + id: '539', from: 'MUC', to: 'IST', attributes: { prediction: 18909 }, }, { - id: 540, + id: '540', from: 'IXC', to: 'IXJ', attributes: { prediction: 575 }, }, { - id: 541, + id: '541', from: 'DEN', to: 'JAC', attributes: { prediction: 4336 }, }, { - id: 542, + id: '542', from: 'JCH', to: 'JAV', attributes: { prediction: 62 }, }, { - id: 543, + id: '543', from: 'CMB', to: 'JED', attributes: { prediction: 1841 }, }, { - id: 544, + id: '544', from: 'DUB', to: 'JFK', attributes: { prediction: 12974 }, }, { - id: 545, + id: '545', from: 'RDU', to: 'JFK', attributes: { prediction: 11242 }, }, { - id: 546, + id: '546', from: 'IST', to: 'KIV', attributes: { prediction: 6181 }, }, { - id: 547, + id: '547', from: 'HYN', to: 'KMG', attributes: { prediction: 1462 }, }, { - id: 548, + id: '548', from: 'BET', to: 'KPN', attributes: { prediction: 412 }, }, { - id: 549, + id: '549', from: 'BJZ', to: 'MAD', attributes: { prediction: 1598 }, }, { - id: 550, + id: '550', from: 'FCO', to: 'MAD', attributes: { prediction: 50764 }, }, { - id: 551, + id: '551', from: 'NTE', to: 'MAD', attributes: { prediction: 2663 }, }, { - id: 552, + id: '552', from: 'SXB', to: 'MAD', attributes: { prediction: 1026 }, }, { - id: 553, + id: '553', from: 'FCO', to: 'LGW', attributes: { prediction: 11681 }, }, { - id: 554, + id: '554', from: 'LPA', to: 'LGW', attributes: { prediction: 8719 }, }, { - id: 555, + id: '555', from: 'UVF', to: 'LGW', attributes: { prediction: 8471 }, }, { - id: 556, + id: '556', from: 'KBP', to: 'KTW', attributes: { prediction: 1519 }, }, { - id: 557, + id: '557', from: 'BOM', to: 'KWI', attributes: { prediction: 10030 }, }, { - id: 558, + id: '558', from: 'JFK', to: 'KWI', attributes: { prediction: 2414 }, }, { - id: 559, + id: '559', from: 'MTY', to: 'LAP', attributes: { prediction: 787 }, }, { - id: 560, + id: '560', from: 'IDA', to: 'LAS', attributes: { prediction: 915 }, }, { - id: 561, + id: '561', from: 'RNO', to: 'LAS', attributes: { prediction: 31201 }, }, { - id: 562, + id: '562', from: 'TUL', to: 'LAS', attributes: { prediction: 3079 }, }, { - id: 563, + id: '563', from: 'YQR', to: 'LAS', attributes: { prediction: 858 }, }, { - id: 564, + id: '564', from: 'TUL', to: 'LAX', attributes: { prediction: 1088 }, }, { - id: 565, + id: '565', from: 'STN', to: 'LBC', attributes: { prediction: 5664 }, }, { - id: 566, + id: '566', from: 'FRA', to: 'LEJ', attributes: { prediction: 8978 }, }, { - id: 567, + id: '567', from: 'BNA', to: 'LGA', attributes: { prediction: 6074 }, }, { - id: 568, + id: '568', from: 'VCE', to: 'LHR', attributes: { prediction: 2557 }, }, { - id: 569, + id: '569', from: 'WNZ', to: 'LHW', attributes: { prediction: 1072 }, }, { - id: 570, + id: '570', from: 'PIU', to: 'LIM', attributes: { prediction: 8532 }, }, { - id: 571, + id: '571', from: 'FRA', to: 'LIS', attributes: { prediction: 20468 }, }, { - id: 572, + id: '572', from: 'MCT', to: 'LKO', attributes: { prediction: 2802 }, }, { - id: 573, + id: '573', from: 'JRO', to: 'MBA', attributes: { prediction: 3883 }, }, { - id: 574, + id: '574', from: 'DUS', to: 'MLE', attributes: { prediction: 2413 }, }, { - id: 575, + id: '575', from: 'ROR', to: 'MNL', attributes: { prediction: 1116 }, }, { - id: 576, + id: '576', from: 'DPS', to: 'MOF', attributes: { prediction: 853 }, }, { - id: 577, + id: '577', from: 'CDG', to: 'MPL', attributes: { prediction: 13023 }, }, { - id: 578, + id: '578', from: 'VPY', to: 'MPM', attributes: { prediction: 895 }, }, { - id: 579, + id: '579', from: 'BOO', to: 'MQN', attributes: { prediction: 1817 }, }, { - id: 580, + id: '580', from: 'SXB', to: 'MRS', attributes: { prediction: 3391 }, }, { - id: 581, + id: '581', from: 'GVA', to: 'MRU', attributes: { prediction: 949 }, }, { - id: 582, + id: '582', from: 'EWR', to: 'MSN', attributes: { prediction: 1005 }, }, { - id: 583, + id: '583', from: 'MSY', to: 'MEM', attributes: { prediction: 7437 }, }, { - id: 584, + id: '584', from: 'MTT', to: 'MEX', attributes: { prediction: 4561 }, }, { - id: 585, + id: '585', from: 'MKK', to: 'LUP', attributes: { prediction: 112 }, }, { - id: 586, + id: '586', from: 'FRA', to: 'LUX', attributes: { prediction: 3343 }, }, { - id: 587, + id: '587', from: 'CDG', to: 'LYS', attributes: { prediction: 18150 }, }, { - id: 588, + id: '588', from: 'NTE', to: 'LYS', attributes: { prediction: 15488 }, }, { - id: 589, + id: '589', from: 'STR', to: 'MAD', attributes: { prediction: 1242 }, }, { - id: 590, + id: '590', from: 'BRU', to: 'MAN', attributes: { prediction: 7215 }, }, { - id: 591, + id: '591', from: 'BDL', to: 'MCO', attributes: { prediction: 14861 }, }, { - id: 592, + id: '592', from: 'PWM', to: 'MCO', attributes: { prediction: 2517 }, }, { - id: 593, + id: '593', from: 'DXB', to: 'MEL', attributes: { prediction: 5702 }, }, { - id: 594, + id: '594', from: 'YVR', to: 'MSP', attributes: { prediction: 3523 }, }, { - id: 595, + id: '595', from: 'CLE', to: 'MSY', attributes: { prediction: 1095 }, }, { - id: 596, + id: '596', from: 'MOB', to: 'MSY', attributes: { prediction: 54 }, }, { - id: 597, + id: '597', from: 'SLC', to: 'MSY', attributes: { prediction: 1839 }, }, { - id: 598, + id: '598', from: 'VSA', to: 'MTY', attributes: { prediction: 2907 }, }, { - id: 599, + id: '599', from: 'BDU', to: 'OSL', attributes: { prediction: 5442 }, }, { - id: 600, + id: '600', from: 'DXB', to: 'OSL', attributes: { prediction: 1776 }, }, { - id: 601, + id: '601', from: 'AMS', to: 'PBM', attributes: { prediction: 9059 }, }, { - id: 602, + id: '602', from: 'CKG', to: 'PEK', attributes: { prediction: 60119 }, }, { - id: 603, + id: '603', from: 'HFE', to: 'PEK', attributes: { prediction: 26735 }, }, { - id: 604, + id: '604', from: 'DJE', to: 'MUC', attributes: { prediction: 486 }, }, { - id: 605, + id: '605', from: 'LNZ', to: 'MUC', attributes: { prediction: 2235 }, }, { - id: 606, + id: '606', from: 'MRU', to: 'MUC', attributes: { prediction: 1067 }, }, { - id: 607, + id: '607', from: 'FRA', to: 'MXP', attributes: { prediction: 13986 }, }, { - id: 608, + id: '608', from: 'SVO', to: 'MXP', attributes: { prediction: 9785 }, }, { - id: 609, + id: '609', from: 'MIM', to: 'MYA', attributes: { prediction: 717 }, }, { - id: 610, + id: '610', from: 'BBN', to: 'MYY', attributes: { prediction: 418 }, }, { - id: 611, + id: '611', from: 'LED', to: 'NCE', attributes: { prediction: 485 }, }, { - id: 612, + id: '612', from: 'KUL', to: 'NNG', attributes: { prediction: 808 }, }, { - id: 613, + id: '613', from: 'LGW', to: 'NOC', attributes: { prediction: 3209 }, }, { - id: 614, + id: '614', from: 'BNE', to: 'NRT', attributes: { prediction: 5259 }, }, { - id: 615, + id: '615', from: 'IST', to: 'NRT', attributes: { prediction: 3523 }, }, { - id: 616, + id: '616', from: 'PDX', to: 'NRT', attributes: { prediction: 4287 }, }, { - id: 617, + id: '617', from: 'NBO', to: 'NSI', attributes: { prediction: 1105 }, }, { - id: 618, + id: '618', from: 'EGO', to: 'NUX', attributes: { prediction: 709 }, }, { - id: 619, + id: '619', from: 'BTS', to: 'NYO', attributes: { prediction: 1574 }, }, { - id: 620, + id: '620', from: 'MCI', to: 'OKC', attributes: { prediction: 4722 }, }, { - id: 621, + id: '621', from: 'MCO', to: 'OMA', attributes: { prediction: 1340 }, }, { - id: 622, + id: '622', from: 'HHN', to: 'OPO', attributes: { prediction: 3794 }, }, { - id: 623, + id: '623', from: 'AUH', to: 'ORD', attributes: { prediction: 6346 }, }, { - id: 624, + id: '624', from: 'PIT', to: 'ORD', attributes: { prediction: 11560 }, }, { - id: 625, + id: '625', from: 'XNA', to: 'ORD', attributes: { prediction: 9632 }, }, { - id: 626, + id: '626', from: 'ZIH', to: 'ORD', attributes: { prediction: 139 }, }, { - id: 627, + id: '627', from: 'EDI', to: 'ORK', attributes: { prediction: 1298 }, }, { - id: 628, + id: '628', from: 'CVG', to: 'PHL', attributes: { prediction: 6628 }, }, { - id: 629, + id: '629', from: 'RSW', to: 'PHL', attributes: { prediction: 11075 }, }, { - id: 630, + id: '630', from: 'SAN', to: 'PHL', attributes: { prediction: 6503 }, }, { - id: 631, + id: '631', from: 'PIT', to: 'PHX', attributes: { prediction: 9717 }, }, { - id: 632, + id: '632', from: 'CUN', to: 'PIT', attributes: { prediction: 1164 }, }, { - id: 633, + id: '633', from: 'GLF', to: 'PJM', attributes: { prediction: 90 }, }, { - id: 634, + id: '634', from: 'STL', to: 'MWA', attributes: { prediction: 751 }, }, { - id: 635, + id: '635', from: 'MWQ', to: 'RGN', attributes: { prediction: 339 }, }, { - id: 636, + id: '636', from: 'VIE', to: 'RIX', attributes: { prediction: 1932 }, }, { - id: 637, + id: '637', from: 'MKY', to: 'ROK', attributes: { prediction: 1745 }, }, { - id: 638, + id: '638', from: 'BOM', to: 'RPR', attributes: { prediction: 3897 }, }, { - id: 639, + id: '639', from: 'LAS', to: 'RST', attributes: { prediction: 811 }, }, { - id: 640, + id: '640', from: 'ORD', to: 'RSW', attributes: { prediction: 15722 }, }, { - id: 641, + id: '641', from: 'LIM', to: 'POA', attributes: { prediction: 957 }, }, { - id: 642, + id: '642', from: 'HNL', to: 'PPT', attributes: { prediction: 783 }, }, { - id: 643, + id: '643', from: 'RAR', to: 'PPT', attributes: { prediction: 216 }, }, { - id: 644, + id: '644', from: 'GVA', to: 'PRG', attributes: { prediction: 2053 }, }, { - id: 645, + id: '645', from: 'HAJ', to: 'PRG', attributes: { prediction: 1501 }, }, { - id: 646, + id: '646', from: 'MUC', to: 'PSA', attributes: { prediction: 2235 }, }, { - id: 647, + id: '647', from: 'FNC', to: 'PXO', attributes: { prediction: 2713 }, }, { - id: 648, + id: '648', from: 'SJP', to: 'RAO', attributes: { prediction: 624 }, }, { - id: 649, + id: '649', from: 'SHJ', to: 'SAW', attributes: { prediction: 1410 }, }, { - id: 650, + id: '650', from: 'ANC', to: 'SCC', attributes: { prediction: 1392 }, }, { - id: 651, + id: '651', from: 'KMQ', to: 'SDJ', attributes: { prediction: 952 }, }, { - id: 652, + id: '652', from: 'SXM', to: 'SDQ', attributes: { prediction: 2486 }, }, { - id: 653, + id: '653', from: 'FAO', to: 'NYO', attributes: { prediction: 165 }, }, { - id: 654, + id: '654', from: 'SEA', to: 'OAK', attributes: { prediction: 35647 }, }, { - id: 655, + id: '655', from: 'CLE', to: 'SFO', attributes: { prediction: 3190 }, }, { - id: 656, + id: '656', from: 'ORD', to: 'SFO', attributes: { prediction: 61103 }, }, { - id: 657, + id: '657', from: 'YVR', to: 'SFO', attributes: { prediction: 19887 }, }, { - id: 658, + id: '658', from: 'ATL', to: 'SFO', attributes: { prediction: 28467 }, }, { - id: 659, + id: '659', from: 'FAT', to: 'SFO', attributes: { prediction: 3857 }, }, { - id: 660, + id: '660', from: 'DLI', to: 'SGN', attributes: { prediction: 6163 }, }, { - id: 661, + id: '661', from: 'HET', to: 'SHE', attributes: { prediction: 1174 }, }, { - id: 662, + id: '662', from: 'ICN', to: 'SIN', attributes: { prediction: 30167 }, }, { - id: 663, + id: '663', from: 'PLU', to: 'SJK', attributes: { prediction: 111 }, }, { - id: 664, + id: '664', from: 'TNO', to: 'SJO', attributes: { prediction: 620 }, }, { - id: 665, + id: '665', from: 'SJU', to: 'SKB', attributes: { prediction: 1320 }, }, { - id: 666, + id: '666', from: 'BOS', to: 'SLK', attributes: { prediction: 338 }, }, { - id: 667, + id: '667', from: 'IMP', to: 'SLZ', attributes: { prediction: 6045 }, }, { - id: 668, + id: '668', from: 'HER', to: 'SMI', attributes: { prediction: 128 }, }, { - id: 669, + id: '669', from: 'RDU', to: 'STL', attributes: { prediction: 2657 }, }, { - id: 670, + id: '670', from: 'GNB', to: 'STN', attributes: { prediction: 3256 }, }, { - id: 671, + id: '671', from: 'CPH', to: 'STR', attributes: { prediction: 2725 }, }, { - id: 672, + id: '672', from: 'ATZ', to: 'SHJ', attributes: { prediction: 2174 }, }, { - id: 673, + id: '673', from: 'DAM', to: 'SVO', attributes: { prediction: 834 }, }, { - id: 674, + id: '674', from: 'ZAG', to: 'SXF', attributes: { prediction: 2018 }, }, { - id: 675, + id: '675', from: 'MNL', to: 'SYD', attributes: { prediction: 4670 }, }, { - id: 676, + id: '676', from: 'GLF', to: 'SYQ', attributes: { prediction: 454 }, }, { - id: 677, + id: '677', from: 'PHL', to: 'SYR', attributes: { prediction: 7859 }, }, { - id: 678, + id: '678', from: 'HGH', to: 'SYX', attributes: { prediction: 24720 }, }, { - id: 679, + id: '679', from: 'BRS', to: 'SZG', attributes: { prediction: 176 }, }, { - id: 680, + id: '680', from: 'EXT', to: 'SZG', attributes: { prediction: 262 }, }, { - id: 681, + id: '681', from: 'SRZ', to: 'TDD', attributes: { prediction: 3336 }, }, { - id: 682, + id: '682', from: 'FLW', to: 'TER', attributes: { prediction: 191 }, }, { - id: 683, + id: '683', from: 'MAN', to: 'TFS', attributes: { prediction: 18176 }, }, { - id: 684, + id: '684', from: 'LCE', to: 'TGU', attributes: { prediction: 4447 }, }, { - id: 685, + id: '685', from: 'CBH', to: 'TIN', attributes: { prediction: 336 }, }, { - id: 686, + id: '686', from: 'BRU', to: 'TIP', attributes: { prediction: 1403 }, }, { - id: 687, + id: '687', from: 'CUU', to: 'TLC', attributes: { prediction: 4868 }, }, { - id: 688, + id: '688', from: 'MSQ', to: 'TLL', attributes: { prediction: 272 }, }, { - id: 689, + id: '689', from: 'SNR', to: 'TLS', attributes: { prediction: 1070 }, }, { - id: 690, + id: '690', from: 'TAS', to: 'TMJ', attributes: { prediction: 2997 }, }, { - id: 691, + id: '691', from: 'GEA', to: 'TOU', attributes: { prediction: 274 }, }, { - id: 692, + id: '692', from: 'BNA', to: 'TPA', attributes: { prediction: 11321 }, }, { - id: 693, + id: '693', from: 'MTY', to: 'TAM', attributes: { prediction: 1676 }, }, { - id: 694, + id: '694', from: 'MUC', to: 'TAS', attributes: { prediction: 92 }, }, { - id: 695, + id: '695', from: 'DME', to: 'TSE', attributes: { prediction: 3842 }, }, { - id: 696, + id: '696', from: 'HFE', to: 'TSN', attributes: { prediction: 3556 }, }, { - id: 697, + id: '697', from: 'VLL', to: 'BCN', attributes: { prediction: 3959 }, }, { - id: 698, + id: '698', from: 'STN', to: 'BDS', attributes: { prediction: 1218 }, }, { - id: 699, + id: '699', from: 'VPY', to: 'BEW', attributes: { prediction: 224 }, }, { - id: 700, + id: '700', from: 'MAN', to: 'BGI', attributes: { prediction: 1300 }, }, { - id: 701, + id: '701', from: 'MAN', to: 'ZRH', attributes: { prediction: 6742 }, }, { - id: 702, + id: '702', from: 'RIX', to: 'VNO', attributes: { prediction: 6503 }, }, { - id: 703, + id: '703', from: 'BOG', to: 'VUP', attributes: { prediction: 4738 }, }, { - id: 704, + id: '704', from: 'SLA', to: 'VVI', attributes: { prediction: 771 }, }, { - id: 705, + id: '705', from: 'KIJ', to: 'VVO', attributes: { prediction: 754 }, }, { - id: 706, + id: '706', from: 'JJN', to: 'WUH', attributes: { prediction: 5520 }, }, { - id: 707, + id: '707', from: 'DME', to: 'BHK', attributes: { prediction: 2349 }, }, { - id: 708, + id: '708', from: 'YRL', to: 'YHP', attributes: { prediction: 72 }, }, { - id: 709, + id: '709', from: 'PYJ', to: 'YKS', attributes: { prediction: 35 }, }, { - id: 710, + id: '710', from: 'CUN', to: 'YQR', attributes: { prediction: 466 }, }, { - id: 711, + id: '711', from: 'YHZ', to: 'YQY', attributes: { prediction: 2110 }, }, { - id: 712, + id: '712', from: 'PSP', to: 'YVR', attributes: { prediction: 3194 }, }, { - id: 713, + id: '713', from: 'YPW', to: 'YVR', attributes: { prediction: 1109 }, }, { - id: 714, + id: '714', from: 'PHX', to: 'YYZ', attributes: { prediction: 6222 }, }, { - id: 715, + id: '715', from: 'TLV', to: 'YYZ', attributes: { prediction: 3714 }, }, { - id: 716, + id: '716', from: 'EXT', to: 'AMS', attributes: { prediction: 1501 }, }, { - id: 717, + id: '717', from: 'SKB', to: 'ANU', attributes: { prediction: 4584 }, }, { - id: 718, + id: '718', from: 'KGX', to: 'ANV', attributes: { prediction: 58 }, }, { - id: 719, + id: '719', from: 'EWR', to: 'ARN', attributes: { prediction: 8445 }, }, { - id: 720, + id: '720', from: 'RYG', to: 'ATH', attributes: { prediction: 121 }, }, { - id: 721, + id: '721', from: 'BMI', to: 'ATL', attributes: { prediction: 13667 }, }, { - id: 722, + id: '722', from: 'GRK', to: 'ATL', attributes: { prediction: 2362 }, }, { - id: 723, + id: '723', from: 'MAO', to: 'ATL', attributes: { prediction: 869 }, }, { - id: 724, + id: '724', from: 'MEI', to: 'ATL', attributes: { prediction: 1851 }, }, { - id: 725, + id: '725', from: 'SFO', to: 'ABQ', attributes: { prediction: 1239 }, }, { - id: 726, + id: '726', from: 'LHR', to: 'ABZ', attributes: { prediction: 25897 }, }, { - id: 727, + id: '727', from: 'HAJ', to: 'ACE', attributes: { prediction: 1481 }, }, { - id: 728, + id: '728', from: 'SVI', to: 'ACR', attributes: { prediction: 128 }, }, { - id: 729, + id: '729', from: 'PTY', to: 'ADZ', attributes: { prediction: 2138 }, }, { - id: 730, + id: '730', from: 'CNQ', to: 'AEP', attributes: { prediction: 2030 }, }, { - id: 731, + id: '731', from: 'VKO', to: 'AER', attributes: { prediction: 17801 }, }, { - id: 732, + id: '732', from: 'HIR', to: 'AFT', attributes: { prediction: 36 }, }, { - id: 733, + id: '733', from: 'BWN', to: 'AKL', attributes: { prediction: 2141 }, }, { - id: 734, + id: '734', from: 'EWR', to: 'ALB', attributes: { prediction: 4841 }, }, { - id: 735, + id: '735', from: 'TRD', to: 'ALC', attributes: { prediction: 433 }, }, { - id: 736, + id: '736', from: 'TEE', to: 'ALG', attributes: { prediction: 641 }, }, { - id: 737, + id: '737', from: 'IAM', to: 'AZR', attributes: { prediction: 235 }, }, { - id: 738, + id: '738', from: 'ZCO', to: 'BBA', attributes: { prediction: 193 }, }, { - id: 739, + id: '739', from: 'NCE', to: 'BCN', attributes: { prediction: 3752 }, }, { - id: 740, + id: '740', from: 'EIN', to: 'BDS', attributes: { prediction: 1148 }, }, { - id: 741, + id: '741', from: 'GVA', to: 'BIQ', attributes: { prediction: 934 }, }, { - id: 742, + id: '742', from: 'AZA', to: 'BIS', attributes: { prediction: 1015 }, }, { - id: 743, + id: '743', from: 'OAK', to: 'BJX', attributes: { prediction: 352 }, }, { - id: 744, + id: '744', from: 'CAI', to: 'BKK', attributes: { prediction: 6033 }, }, { - id: 745, + id: '745', from: 'BRU', to: 'BLL', attributes: { prediction: 1235 }, }, { - id: 746, + id: '746', from: 'GRO', to: 'BTS', attributes: { prediction: 1826 }, }, { - id: 747, + id: '747', from: 'MYY', to: 'BTU', attributes: { prediction: 1339 }, }, { - id: 748, + id: '748', from: 'FUE', to: 'DUS', attributes: { prediction: 5544 }, }, { - id: 749, + id: '749', from: 'NUE', to: 'DUS', attributes: { prediction: 16238 }, }, { - id: 750, + id: '750', from: 'ORD', to: 'DUS', attributes: { prediction: 3596 }, }, { - id: 751, + id: '751', from: 'BKI', to: 'CGK', attributes: { prediction: 1285 }, }, { - id: 752, + id: '752', from: 'MDC', to: 'CGK', attributes: { prediction: 12774 }, }, { - id: 753, + id: '753', from: 'BBU', to: 'CGN', attributes: { prediction: 1545 }, }, { - id: 754, + id: '754', from: 'MAN', to: 'CGN', attributes: { prediction: 2496 }, }, { - id: 755, + id: '755', from: 'SVQ', to: 'CIA', attributes: { prediction: 2436 }, }, { - id: 756, + id: '756', from: 'NIM', to: 'BKO', attributes: { prediction: 669 }, }, { - id: 757, + id: '757', from: 'OAK', to: 'BLI', attributes: { prediction: 920 }, }, { - id: 758, + id: '758', from: 'GRU', to: 'BOG', attributes: { prediction: 9475 }, }, { - id: 759, + id: '759', from: 'TME', to: 'BOG', attributes: { prediction: 146 }, }, { - id: 760, + id: '760', from: 'EDI', to: 'BOH', attributes: { prediction: 4893 }, }, { - id: 761, + id: '761', from: 'SJU', to: 'BOS', attributes: { prediction: 16422 }, }, { - id: 762, + id: '762', from: 'CPH', to: 'BRE', attributes: { prediction: 611 }, }, { - id: 763, + id: '763', from: 'BTS', to: 'BRS', attributes: { prediction: 1171 }, }, { - id: 764, + id: '764', from: 'GLA', to: 'BRS', attributes: { prediction: 10441 }, }, { - id: 765, + id: '765', from: 'PVG', to: 'CKG', attributes: { prediction: 55962 }, }, { - id: 766, + id: '766', from: 'DEN', to: 'CLE', attributes: { prediction: 6563 }, }, { - id: 767, + id: '767', from: 'SBW', to: 'BTU', attributes: { prediction: 1361 }, }, { - id: 768, + id: '768', from: 'LTN', to: 'BUD', attributes: { prediction: 12415 }, }, { - id: 769, + id: '769', from: 'MMX', to: 'BUD', attributes: { prediction: 2394 }, }, { - id: 770, + id: '770', from: 'TGD', to: 'BUD', attributes: { prediction: 465 }, }, { - id: 771, + id: '771', from: 'PHX', to: 'BUR', attributes: { prediction: 30550 }, }, { - id: 772, + id: '772', from: 'DOK', to: 'BUS', attributes: { prediction: 176 }, }, { - id: 773, + id: '773', from: 'KCH', to: 'BWN', attributes: { prediction: 718 }, }, { - id: 774, + id: '774', from: 'NRN', to: 'CAG', attributes: { prediction: 1960 }, }, { - id: 775, + id: '775', from: 'BGW', to: 'CAI', attributes: { prediction: 773 }, }, { - id: 776, + id: '776', from: 'DAM', to: 'CAI', attributes: { prediction: 6322 }, }, { - id: 777, + id: '777', from: 'RSW', to: 'CAK', attributes: { prediction: 2854 }, }, { - id: 778, + id: '778', from: 'DEL', to: 'CAN', attributes: { prediction: 2403 }, }, { - id: 779, + id: '779', from: 'DOH', to: 'CAN', attributes: { prediction: 5155 }, }, { - id: 780, + id: '780', from: 'YOW', to: 'CCC', attributes: { prediction: 577 }, }, { - id: 781, + id: '781', from: 'LYS', to: 'CDG', attributes: { prediction: 21175 }, }, { - id: 782, + id: '782', from: 'PRG', to: 'CDG', attributes: { prediction: 29124 }, }, { - id: 783, + id: '783', from: 'VKO', to: 'CEK', attributes: { prediction: 3254 }, }, { - id: 784, + id: '784', from: 'CWB', to: 'CGH', attributes: { prediction: 45034 }, }, { - id: 785, + id: '785', from: 'EUN', to: 'CMN', attributes: { prediction: 3271 }, }, { - id: 786, + id: '786', from: 'LIL', to: 'CMN', attributes: { prediction: 768 }, }, { - id: 787, + id: '787', from: 'INN', to: 'CPH', attributes: { prediction: 2493 }, }, { - id: 788, + id: '788', from: 'KBP', to: 'CPH', attributes: { prediction: 1472 }, }, { - id: 789, + id: '789', from: 'LED', to: 'CPH', attributes: { prediction: 1749 }, }, { - id: 790, + id: '790', from: 'BEY', to: 'DXB', attributes: { prediction: 30885 }, }, { - id: 791, + id: '791', from: 'DMM', to: 'DXB', attributes: { prediction: 6901 }, }, { - id: 792, + id: '792', from: 'LYP', to: 'DXB', attributes: { prediction: 569 }, }, { - id: 793, + id: '793', from: 'TBZ', to: 'DXB', attributes: { prediction: 838 }, }, { - id: 794, + id: '794', from: 'ZRH', to: 'DXB', attributes: { prediction: 18802 }, }, { - id: 795, + id: '795', from: 'REN', to: 'DYU', attributes: { prediction: 1256 }, }, { - id: 796, + id: '796', from: 'KRT', to: 'EBD', attributes: { prediction: 368 }, }, { - id: 797, + id: '797', from: 'OKC', to: 'DEN', attributes: { prediction: 27820 }, }, { - id: 798, + id: '798', from: 'YOW', to: 'DEN', attributes: { prediction: 1433 }, }, { - id: 799, + id: '799', from: 'MSN', to: 'DFW', attributes: { prediction: 2500 }, }, { - id: 800, + id: '800', from: 'BSB', to: 'CPQ', attributes: { prediction: 8791 }, }, { - id: 801, + id: '801', from: 'NGB', to: 'CSX', attributes: { prediction: 10730 }, }, { - id: 802, + id: '802', from: 'HAK', to: 'CTU', attributes: { prediction: 14379 }, }, { - id: 803, + id: '803', from: 'HKG', to: 'CTU', attributes: { prediction: 9627 }, }, { - id: 804, + id: '804', from: 'PZI', to: 'CTU', attributes: { prediction: 7051 }, }, { - id: 805, + id: '805', from: 'HMO', to: 'CUL', attributes: { prediction: 2040 }, }, { - id: 806, + id: '806', from: 'LAP', to: 'CUL', attributes: { prediction: 2725 }, }, { - id: 807, + id: '807', from: 'IAH', to: 'CUU', attributes: { prediction: 1188 }, }, { - id: 808, + id: '808', from: 'CFC', to: 'CWB', attributes: { prediction: 366 }, }, { - id: 809, + id: '809', from: 'KPN', to: 'CYF', attributes: { prediction: 149 }, }, { - id: 810, + id: '810', from: 'SGN', to: 'DAD', attributes: { prediction: 41185 }, }, { - id: 811, + id: '811', from: 'MAF', to: 'DAL', attributes: { prediction: 12965 }, }, { - id: 812, + id: '812', from: 'AUH', to: 'DAM', attributes: { prediction: 7993 }, }, { - id: 813, + id: '813', from: 'MIA', to: 'DCA', attributes: { prediction: 36318 }, }, { - id: 814, + id: '814', from: 'ICN', to: 'DEL', attributes: { prediction: 3092 }, }, { - id: 815, + id: '815', from: 'JFK', to: 'DEL', attributes: { prediction: 6018 }, }, { - id: 816, + id: '816', from: 'SIN', to: 'DEL', attributes: { prediction: 17631 }, }, { - id: 817, + id: '817', from: 'HRG', to: 'DME', attributes: { prediction: 18584 }, }, { - id: 818, + id: '818', from: 'LHR', to: 'DME', attributes: { prediction: 21916 }, }, { - id: 819, + id: '819', from: 'BHH', to: 'DMM', attributes: { prediction: 164 }, }, { - id: 820, + id: '820', from: 'MEL', to: 'DOH', attributes: { prediction: 6382 }, }, { - id: 821, + id: '821', from: 'MXL', to: 'GDL', attributes: { prediction: 4959 }, }, { - id: 822, + id: '822', from: 'TKU', to: 'GDN', attributes: { prediction: 1903 }, }, { - id: 823, + id: '823', from: 'GVA', to: 'GLA', attributes: { prediction: 659 }, }, { - id: 824, + id: '824', from: 'JFK', to: 'EZE', attributes: { prediction: 5777 }, }, { - id: 825, + id: '825', from: 'BTT', to: 'FAI', attributes: { prediction: 373 }, }, { - id: 826, + id: '826', from: 'LTN', to: 'DUB', attributes: { prediction: 13021 }, }, { - id: 827, + id: '827', from: 'LBA', to: 'DUS', attributes: { prediction: 2847 }, }, { - id: 828, + id: '828', from: 'SPC', to: 'DUS', attributes: { prediction: 2569 }, }, { - id: 829, + id: '829', from: 'GYD', to: 'DXB', attributes: { prediction: 8543 }, }, { - id: 830, + id: '830', from: 'PNQ', to: 'DXB', attributes: { prediction: 1706 }, }, { - id: 831, + id: '831', from: 'PEK', to: 'DYG', attributes: { prediction: 4862 }, }, { - id: 832, + id: '832', from: 'FRU', to: 'DYU', attributes: { prediction: 1146 }, }, { - id: 833, + id: '833', from: 'BUD', to: 'EIN', attributes: { prediction: 4426 }, }, { - id: 834, + id: '834', from: 'IST', to: 'ERZ', attributes: { prediction: 3871 }, }, { - id: 835, + id: '835', from: 'BAL', to: 'ESB', attributes: { prediction: 2730 }, }, { - id: 836, + id: '836', from: 'LAS', to: 'EUG', attributes: { prediction: 1395 }, }, { - id: 837, + id: '837', from: 'HDN', to: 'EWR', attributes: { prediction: 391 }, }, { - id: 838, + id: '838', from: 'NCL', to: 'EXT', attributes: { prediction: 2058 }, }, { - id: 839, + id: '839', from: 'DEN', to: 'FAR', attributes: { prediction: 6340 }, }, { - id: 840, + id: '840', from: 'ALG', to: 'FCO', attributes: { prediction: 5006 }, }, { - id: 841, + id: '841', from: 'RTM', to: 'GNB', attributes: { prediction: 500 }, }, { - id: 842, + id: '842', from: 'ATH', to: 'GOT', attributes: { prediction: 79 }, }, { - id: 843, + id: '843', from: 'IAH', to: 'GRK', attributes: { prediction: 3885 }, }, { - id: 844, + id: '844', from: 'RAB', to: 'HKN', attributes: { prediction: 64 }, }, { - id: 845, + id: '845', from: 'CPH', to: 'IAD', attributes: { prediction: 4553 }, }, { - id: 846, + id: '846', from: 'LGA', to: 'IAD', attributes: { prediction: 6901 }, }, { - id: 847, + id: '847', from: 'BON', to: 'IAH', attributes: { prediction: 1382 }, }, { - id: 848, + id: '848', from: 'FSZ', to: 'ICN', attributes: { prediction: 7052 }, }, { - id: 849, + id: '849', from: 'MEM', to: 'ICT', attributes: { prediction: 2468 }, }, { - id: 850, + id: '850', from: 'NAY', to: 'FUO', attributes: { prediction: 2402 }, }, { - id: 851, + id: '851', from: 'HSV', to: 'FWA', attributes: { prediction: 34 }, }, { - id: 852, + id: '852', from: 'PDX', to: 'GEG', attributes: { prediction: 15298 }, }, { - id: 853, + id: '853', from: 'NQY', to: 'GLA', attributes: { prediction: 1082 }, }, { - id: 854, + id: '854', from: 'PPT', to: 'GMR', attributes: { prediction: 99 }, }, { - id: 855, + id: '855', from: 'BLL', to: 'GRO', attributes: { prediction: 1418 }, }, { - id: 856, + id: '856', from: 'PSR', to: 'GRO', attributes: { prediction: 1305 }, }, { - id: 857, + id: '857', from: 'DTW', to: 'GSO', attributes: { prediction: 3500 }, }, { - id: 858, + id: '858', from: 'EWR', to: 'GSP', attributes: { prediction: 3033 }, }, { - id: 859, + id: '859', from: 'HOU', to: 'GVA', attributes: { prediction: 10 }, }, { - id: 860, + id: '860', from: 'LIS', to: 'GVA', attributes: { prediction: 15353 }, }, { - id: 861, + id: '861', from: 'MIA', to: 'IND', attributes: { prediction: 1358 }, }, { - id: 862, + id: '862', from: 'SBN', to: 'IND', attributes: { prediction: 29 }, }, { - id: 863, + id: '863', from: 'SIN', to: 'HAK', attributes: { prediction: 6099 }, }, { - id: 864, + id: '864', from: 'NRT', to: 'HAN', attributes: { prediction: 6463 }, }, { - id: 865, + id: '865', from: 'FRA', to: 'HAV', attributes: { prediction: 1207 }, }, { - id: 866, + id: '866', from: 'SFB', to: 'HGR', attributes: { prediction: 1179 }, }, { - id: 867, + id: '867', from: 'KTM', to: 'HKG', attributes: { prediction: 1656 }, }, { - id: 868, + id: '868', from: 'RUH', to: 'HKG', attributes: { prediction: 6747 }, }, { - id: 869, + id: '869', from: 'LGW', to: 'HME', attributes: { prediction: 1765 }, }, { - id: 870, + id: '870', from: 'PEK', to: 'HND', attributes: { prediction: 18832 }, }, { - id: 871, + id: '871', from: 'DNZ', to: 'IST', attributes: { prediction: 6712 }, }, { - id: 872, + id: '872', from: 'DUB', to: 'IST', attributes: { prediction: 3986 }, }, { - id: 873, + id: '873', from: 'MCT', to: 'IST', attributes: { prediction: 2501 }, }, { - id: 874, + id: '874', from: 'TIP', to: 'IST', attributes: { prediction: 8830 }, }, { - id: 875, + id: '875', from: 'BWI', to: 'LIT', attributes: { prediction: 2792 }, }, { - id: 876, + id: '876', from: 'DGO', to: 'MEX', attributes: { prediction: 4455 }, }, { - id: 877, + id: '877', from: 'LED', to: 'KJA', attributes: { prediction: 2240 }, }, { - id: 878, + id: '878', from: 'GSE', to: 'KLU', attributes: { prediction: 512 }, }, { - id: 879, + id: '879', from: 'FUK', to: 'KMI', attributes: { prediction: 14009 }, }, { - id: 880, + id: '880', from: 'HND', to: 'KUH', attributes: { prediction: 11642 }, }, { - id: 881, + id: '881', from: 'LAX', to: 'IYK', attributes: { prediction: 1383 }, }, { - id: 882, + id: '882', from: 'EWR', to: 'JAX', attributes: { prediction: 7384 }, }, { - id: 883, + id: '883', from: 'MAN', to: 'JER', attributes: { prediction: 4158 }, }, { - id: 884, + id: '884', from: 'MSY', to: 'JFK', attributes: { prediction: 10638 }, }, { - id: 885, + id: '885', from: 'BKI', to: 'JHB', attributes: { prediction: 6420 }, }, { - id: 886, + id: '886', from: 'SFJ', to: 'JSU', attributes: { prediction: 474 }, }, { - id: 887, + id: '887', from: 'DUS', to: 'KGF', attributes: { prediction: 501 }, }, { - id: 888, + id: '888', from: 'TNA', to: 'KHN', attributes: { prediction: 2433 }, }, { - id: 889, + id: '889', from: 'CGK', to: 'KUL', attributes: { prediction: 56287 }, }, { - id: 890, + id: '890', from: 'LTN', to: 'KUN', attributes: { prediction: 2469 }, }, { - id: 891, + id: '891', from: 'KKH', to: 'KWK', attributes: { prediction: 77 }, }, { - id: 892, + id: '892', from: 'SVO', to: 'LAD', attributes: { prediction: 418 }, }, { - id: 893, + id: '893', from: 'MRY', to: 'LAS', attributes: { prediction: 897 }, }, { - id: 894, + id: '894', from: 'YYZ', to: 'MHT', attributes: { prediction: 915 }, }, { - id: 895, + id: '895', from: 'CLO', to: 'MIA', attributes: { prediction: 6472 }, }, { - id: 896, + id: '896', from: 'IND', to: 'MIA', attributes: { prediction: 1254 }, }, { - id: 897, + id: '897', from: 'NCE', to: 'MIR', attributes: { prediction: 1555 }, }, { - id: 898, + id: '898', from: 'MEM', to: 'MKE', attributes: { prediction: 3666 }, }, { - id: 899, + id: '899', from: 'MIA', to: 'MKE', attributes: { prediction: 161 }, }, { - id: 900, + id: '900', from: 'STN', to: 'LNZ', attributes: { prediction: 2555 }, }, { - id: 901, + id: '901', from: 'MAD', to: 'LPA', attributes: { prediction: 81530 }, }, { - id: 902, + id: '902', from: 'KZN', to: 'LBD', attributes: { prediction: 392 }, }, { - id: 903, + id: '903', from: 'EDI', to: 'LCJ', attributes: { prediction: 1341 }, }, { - id: 904, + id: '904', from: 'YUL', to: 'LGA', attributes: { prediction: 12235 }, }, { - id: 905, + id: '905', from: 'JER', to: 'LGW', attributes: { prediction: 29212 }, }, { - id: 906, + id: '906', from: 'KRK', to: 'LGW', attributes: { prediction: 3596 }, }, { - id: 907, + id: '907', from: 'RTM', to: 'LGW', attributes: { prediction: 6443 }, }, { - id: 908, + id: '908', from: 'VNO', to: 'LGW', attributes: { prediction: 4063 }, }, { - id: 909, + id: '909', from: 'BEY', to: 'LHR', attributes: { prediction: 9191 }, }, { - id: 910, + id: '910', from: 'PHX', to: 'LIH', attributes: { prediction: 4173 }, }, { - id: 911, + id: '911', from: 'BSL', to: 'LIS', attributes: { prediction: 1568 }, }, { - id: 912, + id: '912', from: 'ORK', to: 'LPL', attributes: { prediction: 5623 }, }, { - id: 913, + id: '913', from: 'MHD', to: 'LRR', attributes: { prediction: 939 }, }, { - id: 914, + id: '914', from: 'TIP', to: 'LTD', attributes: { prediction: 298 }, }, { - id: 915, + id: '915', from: 'BRU', to: 'MLA', attributes: { prediction: 3873 }, }, { - id: 916, + id: '916', from: 'MRS', to: 'MLA', attributes: { prediction: 933 }, }, { - id: 917, + id: '917', from: 'YYC', to: 'NAS', attributes: { prediction: 330 }, }, { - id: 918, + id: '918', from: 'ADD', to: 'NBO', attributes: { prediction: 9210 }, }, { - id: 919, + id: '919', from: 'FBM', to: 'NBO', attributes: { prediction: 786 }, }, { - id: 920, + id: '920', from: 'MPM', to: 'NBO', attributes: { prediction: 829 }, }, { - id: 921, + id: '921', from: 'DUS', to: 'NCE', attributes: { prediction: 5021 }, }, { - id: 922, + id: '922', from: 'CDG', to: 'NCL', attributes: { prediction: 6904 }, }, { - id: 923, + id: '923', from: 'SBH', to: 'NEV', attributes: { prediction: 33 }, }, { - id: 924, + id: '924', from: 'CSX', to: 'NKG', attributes: { prediction: 13645 }, }, { - id: 925, + id: '925', from: 'PEK', to: 'NKG', attributes: { prediction: 69058 }, }, { - id: 926, + id: '926', from: 'FUK', to: 'NKM', attributes: { prediction: 6483 }, }, { - id: 927, + id: '927', from: 'CDB', to: 'NLG', attributes: { prediction: 22 }, }, { - id: 928, + id: '928', from: 'TMU', to: 'NOB', attributes: { prediction: 550 }, }, { - id: 929, + id: '929', from: 'LEQ', to: 'NQY', attributes: { prediction: 221 }, }, { - id: 930, + id: '930', from: 'CUN', to: 'MCI', attributes: { prediction: 1460 }, }, { - id: 931, + id: '931', from: 'SJU', to: 'MCO', attributes: { prediction: 37987 }, }, { - id: 932, + id: '932', from: 'SYD', to: 'MCY', attributes: { prediction: 10076 }, }, { - id: 933, + id: '933', from: 'COU', to: 'MEM', attributes: { prediction: 2537 }, }, { - id: 934, + id: '934', from: 'PNS', to: 'MEM', attributes: { prediction: 3680 }, }, { - id: 935, + id: '935', from: 'TPA', to: 'MEM', attributes: { prediction: 8807 }, }, { - id: 936, + id: '936', from: 'HUX', to: 'MEX', attributes: { prediction: 10256 }, }, { - id: 937, + id: '937', from: 'DFW', to: 'MFE', attributes: { prediction: 12303 }, }, { - id: 938, + id: '938', from: 'CGK', to: 'MFM', attributes: { prediction: 2898 }, }, { - id: 939, + id: '939', from: 'FLL', to: 'MGA', attributes: { prediction: 907 }, }, { - id: 940, + id: '940', from: 'DEN', to: 'MIA', attributes: { prediction: 11811 }, }, { - id: 941, + id: '941', from: 'UIO', to: 'MIA', attributes: { prediction: 14052 }, }, { - id: 942, + id: '942', from: 'LEA', to: 'MJK', attributes: { prediction: 143 }, }, { - id: 943, + id: '943', from: 'PIK', to: 'MJV', attributes: { prediction: 1498 }, }, { - id: 944, + id: '944', from: 'HOU', to: 'OAK', attributes: { prediction: 6715 }, }, { - id: 945, + id: '945', from: 'LGW', to: 'SVG', attributes: { prediction: 2763 }, }, { - id: 946, + id: '946', from: 'MFM', to: 'PEK', attributes: { prediction: 6910 }, }, { - id: 947, + id: '947', from: 'DTW', to: 'PHL', attributes: { prediction: 24598 }, }, { - id: 948, + id: '948', from: 'ISP', to: 'PHL', attributes: { prediction: 3184 }, }, { - id: 949, + id: '949', from: 'MBJ', to: 'PHL', attributes: { prediction: 9137 }, }, { - id: 950, + id: '950', from: 'TRN', to: 'NAP', attributes: { prediction: 20775 }, }, { - id: 951, + id: '951', from: 'MBJ', to: 'NAS', attributes: { prediction: 526 }, }, { - id: 952, + id: '952', from: 'HAM', to: 'NCE', attributes: { prediction: 613 }, }, { - id: 953, + id: '953', from: 'CMF', to: 'NCL', attributes: { prediction: 448 }, }, { - id: 954, + id: '954', from: 'TPE', to: 'NGB', attributes: { prediction: 6886 }, }, { - id: 955, + id: '955', from: 'AXT', to: 'NGO', attributes: { prediction: 764 }, }, { - id: 956, + id: '956', from: 'SPN', to: 'NGO', attributes: { prediction: 4401 }, }, { - id: 957, + id: '957', from: 'SHE', to: 'NKG', attributes: { prediction: 14965 }, }, { - id: 958, + id: '958', from: 'BRI', to: 'NRN', attributes: { prediction: 1974 }, }, { - id: 959, + id: '959', from: 'FAO', to: 'NRN', attributes: { prediction: 1699 }, }, { - id: 960, + id: '960', from: 'HGH', to: 'NRT', attributes: { prediction: 1515 }, }, { - id: 961, + id: '961', from: 'KUL', to: 'NRT', attributes: { prediction: 14605 }, }, { - id: 962, + id: '962', from: 'PHX', to: 'PIT', attributes: { prediction: 12104 }, }, { - id: 963, + id: '963', from: 'GUM', to: 'OKJ', attributes: { prediction: 1072 }, }, { - id: 964, + id: '964', from: 'WMO', to: 'OME', attributes: { prediction: 107 }, }, { - id: 965, + id: '965', from: 'KUL', to: 'OOL', attributes: { prediction: 7344 }, }, { - id: 966, + id: '966', from: 'HPN', to: 'ORD', attributes: { prediction: 10820 }, }, { - id: 967, + id: '967', from: 'PEK', to: 'ORD', attributes: { prediction: 5941 }, }, { - id: 968, + id: '968', from: 'PUJ', to: 'ORD', attributes: { prediction: 2677 }, }, { - id: 969, + id: '969', from: 'CFE', to: 'ORY', attributes: { prediction: 10255 }, }, { - id: 970, + id: '970', from: 'LDE', to: 'ORY', attributes: { prediction: 4450 }, }, { - id: 971, + id: '971', from: 'LYS', to: 'OTP', attributes: { prediction: 1783 }, }, { - id: 972, + id: '972', from: 'AZN', to: 'OVB', attributes: { prediction: 605 }, }, { - id: 973, + id: '973', from: 'HNL', to: 'PDX', attributes: { prediction: 11270 }, }, { - id: 974, + id: '974', from: 'ELS', to: 'PLZ', attributes: { prediction: 810 }, }, { - id: 975, + id: '975', from: 'REP', to: 'PNH', attributes: { prediction: 22917 }, }, { - id: 976, + id: '976', from: 'REC', to: 'PNZ', attributes: { prediction: 5820 }, }, { - id: 977, + id: '977', from: 'TIH', to: 'PPT', attributes: { prediction: 868 }, }, { - id: 978, + id: '978', from: 'SPU', to: 'SXF', attributes: { prediction: 1516 }, }, { - id: 979, + id: '979', from: 'MIA', to: 'RSW', attributes: { prediction: 3984 }, }, { - id: 980, + id: '980', from: 'BGA', to: 'RVE', attributes: { prediction: 242 }, }, { - id: 981, + id: '981', from: 'TAI', to: 'SAH', attributes: { prediction: 2254 }, }, { - id: 982, + id: '982', from: 'BZE', to: 'SAL', attributes: { prediction: 2041 }, }, { - id: 983, + id: '983', from: 'SAN', to: 'SAT', attributes: { prediction: 6075 }, }, { - id: 984, + id: '984', from: 'OTP', to: 'PRG', attributes: { prediction: 5589 }, }, { - id: 985, + id: '985', from: 'TRD', to: 'PRG', attributes: { prediction: 1147 }, }, { - id: 986, + id: '986', from: 'ZRH', to: 'PRN', attributes: { prediction: 4576 }, }, { - id: 987, + id: '987', from: 'LGW', to: 'PSA', attributes: { prediction: 4276 }, }, { - id: 988, + id: '988', from: 'MCO', to: 'PSE', attributes: { prediction: 2979 }, }, { - id: 989, + id: '989', from: 'MWX', to: 'PVG', attributes: { prediction: 811 }, }, { - id: 990, + id: '990', from: 'YXE', to: 'PVR', attributes: { prediction: 1834 }, }, { - id: 991, + id: '991', from: 'MAN', to: 'RHO', attributes: { prediction: 170 }, }, { - id: 992, + id: '992', from: 'MJT', to: 'RHO', attributes: { prediction: 58 }, }, { - id: 993, + id: '993', from: 'BRU', to: 'ROB', attributes: { prediction: 2091 }, }, { - id: 994, + id: '994', from: 'SJU', to: 'SBH', attributes: { prediction: 49 }, }, { - id: 995, + id: '995', from: 'NOV', to: 'SDD', attributes: { prediction: 322 }, }, { - id: 996, + id: '996', from: 'CDG', to: 'SDQ', attributes: { prediction: 1133 }, }, { - id: 997, + id: '997', from: 'SFO', to: 'SEA', attributes: { prediction: 60048 }, }, { - id: 998, + id: '998', from: 'ELM', to: 'SFB', attributes: { prediction: 1040 }, }, { - id: 999, + id: '999', from: 'BEN', to: 'TUN', attributes: { prediction: 4593 }, }, { - id: 1000, + id: '1000', from: 'DOH', to: 'TUN', attributes: { prediction: 4639 }, }, { - id: 1001, + id: '1001', from: 'IST', to: 'TUN', attributes: { prediction: 7844 }, }, { - id: 1002, + id: '1002', from: 'SLC', to: 'TWF', attributes: { prediction: 1970 }, }, { - id: 1003, + id: '1003', from: 'XRY', to: 'TXL', attributes: { prediction: 645 }, }, { - id: 1004, + id: '1004', from: 'CAN', to: 'TXN', attributes: { prediction: 1724 }, }, { - id: 1005, + id: '1005', from: 'SBZ', to: 'STR', attributes: { prediction: 1728 }, }, { - id: 1006, + id: '1006', from: 'AMS', to: 'SIN', attributes: { prediction: 18327 }, }, { - id: 1007, + id: '1007', from: 'MES', to: 'SIN', attributes: { prediction: 7533 }, }, { - id: 1008, + id: '1008', from: 'SHJ', to: 'SKT', attributes: { prediction: 924 }, }, { - id: 1009, + id: '1009', from: 'SXF', to: 'SPU', attributes: { prediction: 130 }, }, { - id: 1010, + id: '1010', from: 'BPS', to: 'SSA', attributes: { prediction: 8485 }, }, { - id: 1011, + id: '1011', from: 'EMA', to: 'SSH', attributes: { prediction: 2424 }, }, { - id: 1012, + id: '1012', from: 'PAP', to: 'STI', attributes: { prediction: 92 }, }, { - id: 1013, + id: '1013', from: 'MSP', to: 'STL', attributes: { prediction: 29356 }, }, { - id: 1014, + id: '1014', from: 'BFS', to: 'STN', attributes: { prediction: 15810 }, }, { - id: 1015, + id: '1015', from: 'FLL', to: 'STT', attributes: { prediction: 3329 }, }, { - id: 1016, + id: '1016', from: 'KKN', to: 'VDS', attributes: { prediction: 1039 }, }, { - id: 1017, + id: '1017', from: 'CPH', to: 'VIE', attributes: { prediction: 16354 }, }, { - id: 1018, + id: '1018', from: 'KRR', to: 'VIE', attributes: { prediction: 2239 }, }, { - id: 1019, + id: '1019', from: 'PEN', to: 'BKK', attributes: { prediction: 7026 }, }, { - id: 1020, + id: '1020', from: 'LYS', to: 'BLJ', attributes: { prediction: 391 }, }, { - id: 1021, + id: '1021', from: 'EVN', to: 'VOZ', attributes: { prediction: 347 }, }, { - id: 1022, + id: '1022', from: 'CBT', to: 'VPE', attributes: { prediction: 840 }, }, { - id: 1023, + id: '1023', from: 'AGA', to: 'VRN', attributes: { prediction: 484 }, }, { - id: 1024, + id: '1024', from: 'CPH', to: 'VRN', attributes: { prediction: 306 }, }, { - id: 1025, + id: '1025', from: 'BOG', to: 'VVC', attributes: { prediction: 2006 }, }, { - id: 1026, + id: '1026', from: 'MEL', to: 'WGA', attributes: { prediction: 1216 }, }, { - id: 1027, + id: '1027', from: 'MYD', to: 'WIL', attributes: { prediction: 1313 }, }, { - id: 1028, + id: '1028', from: 'HAK', to: 'WUX', attributes: { prediction: 1382 }, }, { - id: 1029, + id: '1029', from: 'NUE', to: 'TFS', attributes: { prediction: 5759 }, }, { - id: 1030, + id: '1030', from: 'UPN', to: 'TIJ', attributes: { prediction: 2403 }, }, { - id: 1031, + id: '1031', from: 'HMA', to: 'TJM', attributes: { prediction: 1546 }, }, { - id: 1032, + id: '1032', from: 'TBO', to: 'TKQ', attributes: { prediction: 821 }, }, { - id: 1033, + id: '1033', from: 'HEL', to: 'TKU', attributes: { prediction: 3288 }, }, { - id: 1034, + id: '1034', from: 'HKG', to: 'TNA', attributes: { prediction: 2683 }, }, { - id: 1035, + id: '1035', from: 'ORD', to: 'TOL', attributes: { prediction: 2711 }, }, { - id: 1036, + id: '1036', from: 'DTW', to: 'TPA', attributes: { prediction: 35140 }, }, { - id: 1037, + id: '1037', from: 'HGH', to: 'TPE', attributes: { prediction: 9304 }, }, { - id: 1038, + id: '1038', from: 'KWI', to: 'TRV', attributes: { prediction: 2779 }, }, { - id: 1039, + id: '1039', from: 'XNN', to: 'XIY', attributes: { prediction: 18846 }, }, { - id: 1040, + id: '1040', from: 'PPT', to: 'TUB', attributes: { prediction: 502 }, }, { - id: 1041, + id: '1041', from: 'DFW', to: 'TXK', attributes: { prediction: 3467 }, }, { - id: 1042, + id: '1042', from: 'OSL', to: 'TXL', attributes: { prediction: 2963 }, }, { - id: 1043, + id: '1043', from: 'TRN', to: 'TXL', attributes: { prediction: 967 }, }, { - id: 1044, + id: '1044', from: 'CGH', to: 'UDI', attributes: { prediction: 11695 }, }, { - id: 1045, + id: '1045', from: 'NSK', to: 'UFA', attributes: { prediction: 248 }, }, { - id: 1046, + id: '1046', from: 'KUL', to: 'UPG', attributes: { prediction: 1724 }, }, { - id: 1047, + id: '1047', from: 'PHL', to: 'UVF', attributes: { prediction: 375 }, }, { - id: 1048, + id: '1048', from: 'ARN', to: 'VAA', attributes: { prediction: 2191 }, }, { - id: 1049, + id: '1049', from: 'GOT', to: 'VBY', attributes: { prediction: 161 }, }, { - id: 1050, + id: '1050', from: 'ZRH', to: 'VIE', attributes: { prediction: 33396 }, }, { - id: 1051, + id: '1051', from: 'NKG', to: 'XMN', attributes: { prediction: 20177 }, }, { - id: 1052, + id: '1052', from: 'LUX', to: 'XRY', attributes: { prediction: 112 }, }, { - id: 1053, + id: '1053', from: 'YCB', to: 'YHK', attributes: { prediction: 81 }, }, { - id: 1054, + id: '1054', from: 'YUL', to: 'YHZ', attributes: { prediction: 11774 }, }, { - id: 1055, + id: '1055', from: 'YVR', to: 'YKA', attributes: { prediction: 8018 }, }, { - id: 1056, + id: '1056', from: 'YQB', to: 'YKL', attributes: { prediction: 341 }, }, { - id: 1057, + id: '1057', from: 'BLA', to: 'CCS', attributes: { prediction: 19054 }, }, { - id: 1058, + id: '1058', from: 'CTA', to: 'CDG', attributes: { prediction: 8373 }, }, { - id: 1059, + id: '1059', from: 'DLA', to: 'CDG', attributes: { prediction: 5010 }, }, { - id: 1060, + id: '1060', from: 'FCO', to: 'CDG', attributes: { prediction: 57913 }, }, { - id: 1061, + id: '1061', from: 'TPE', to: 'CDG', attributes: { prediction: 3491 }, }, { - id: 1062, + id: '1062', from: 'WAW', to: 'CDG', attributes: { prediction: 19796 }, }, { - id: 1063, + id: '1063', from: 'YYY', to: 'YQB', attributes: { prediction: 256 }, }, { - id: 1064, + id: '1064', from: 'YWG', to: 'YTH', attributes: { prediction: 2907 }, }, { - id: 1065, + id: '1065', from: 'YYC', to: 'YXX', attributes: { prediction: 11064 }, }, { - id: 1066, + id: '1066', from: 'DXB', to: 'YYZ', attributes: { prediction: 6192 }, }, { - id: 1067, + id: '1067', from: 'YVR', to: 'YZF', attributes: { prediction: 1048 }, }, { - id: 1068, + id: '1068', from: 'PUJ', to: 'AMS', attributes: { prediction: 888 }, }, { - id: 1069, + id: '1069', from: 'BRW', to: 'ANC', attributes: { prediction: 2545 }, }, { - id: 1070, + id: '1070', from: 'CDV', to: 'ANC', attributes: { prediction: 2347 }, }, { - id: 1071, + id: '1071', from: 'JNU', to: 'ANC', attributes: { prediction: 7692 }, }, { - id: 1072, + id: '1072', from: 'LIS', to: 'ARN', attributes: { prediction: 3552 }, }, { - id: 1073, + id: '1073', from: 'WAW', to: 'ARN', attributes: { prediction: 3489 }, }, { - id: 1074, + id: '1074', from: 'AGS', to: 'ATL', attributes: { prediction: 15089 }, }, { - id: 1075, + id: '1075', from: 'FPO', to: 'ATL', attributes: { prediction: 909 }, }, { - id: 1076, + id: '1076', from: 'NAS', to: 'ATL', attributes: { prediction: 15005 }, }, { - id: 1077, + id: '1077', from: 'RTB', to: 'ATL', attributes: { prediction: 743 }, }, { - id: 1078, + id: '1078', from: 'BET', to: 'ATT', attributes: { prediction: 91 }, }, { - id: 1079, + id: '1079', from: 'AMS', to: 'AUH', attributes: { prediction: 3921 }, }, { - id: 1080, + id: '1080', from: 'SFO', to: 'AUS', attributes: { prediction: 5725 }, }, { - id: 1081, + id: '1081', from: 'IKT', to: 'BAX', attributes: { prediction: 1372 }, }, { - id: 1082, + id: '1082', from: 'BKO', to: 'ABJ', attributes: { prediction: 651 }, }, { - id: 1083, + id: '1083', from: 'ROB', to: 'ABJ', attributes: { prediction: 1227 }, }, { - id: 1084, + id: '1084', from: 'NUE', to: 'ACE', attributes: { prediction: 2519 }, }, { - id: 1085, + id: '1085', from: 'DLA', to: 'ADD', attributes: { prediction: 1790 }, }, { - id: 1086, + id: '1086', from: 'SVO', to: 'AGP', attributes: { prediction: 1424 }, }, { - id: 1087, + id: '1087', from: 'IST', to: 'ALA', attributes: { prediction: 5091 }, }, { - id: 1088, + id: '1088', from: 'JED', to: 'ALG', attributes: { prediction: 2544 }, }, { - id: 1089, + id: '1089', from: 'DXB', to: 'ALP', attributes: { prediction: 2100 }, }, { - id: 1090, + id: '1090', from: 'DAR', to: 'AMS', attributes: { prediction: 5093 }, }, { - id: 1091, + id: '1091', from: 'FRL', to: 'BBU', attributes: { prediction: 1079 }, }, { - id: 1092, + id: '1092', from: 'PRG', to: 'BCN', attributes: { prediction: 11501 }, }, { - id: 1093, + id: '1093', from: 'RUH', to: 'CGK', attributes: { prediction: 2250 }, }, { - id: 1094, + id: '1094', from: 'FCO', to: 'CGN', attributes: { prediction: 3903 }, }, { - id: 1095, + id: '1095', from: 'CTU', to: 'CSX', attributes: { prediction: 16493 }, }, { - id: 1096, + id: '1096', from: 'BKK', to: 'CTU', attributes: { prediction: 3245 }, }, { - id: 1097, + id: '1097', from: 'VER', to: 'CUN', attributes: { prediction: 3594 }, }, { - id: 1098, + id: '1098', from: 'DTW', to: 'CVG', attributes: { prediction: 7417 }, }, { - id: 1099, + id: '1099', from: 'BCN', to: 'CWL', attributes: { prediction: 229 }, }, { - id: 1100, + id: '1100', from: 'VLY', to: 'CWL', attributes: { prediction: 89 }, }, { - id: 1101, + id: '1101', from: 'BGW', to: 'DAM', attributes: { prediction: 2872 }, }, { - id: 1102, + id: '1102', from: 'BJL', to: 'CKY', attributes: { prediction: 188 }, }, { - id: 1103, + id: '1103', from: 'AMI', to: 'BMU', attributes: { prediction: 1401 }, }, { - id: 1104, + id: '1104', from: 'DEN', to: 'BNA', attributes: { prediction: 22772 }, }, { - id: 1105, + id: '1105', from: 'SOF', to: 'BOJ', attributes: { prediction: 1435 }, }, { - id: 1106, + id: '1106', from: 'BHU', to: 'BOM', attributes: { prediction: 1606 }, }, { - id: 1107, + id: '1107', from: 'ICN', to: 'BOM', attributes: { prediction: 2180 }, }, { - id: 1108, + id: '1108', from: 'PHX', to: 'BOS', attributes: { prediction: 11203 }, }, { - id: 1109, + id: '1109', from: 'ALC', to: 'BRE', attributes: { prediction: 1268 }, }, { - id: 1110, + id: '1110', from: 'PMI', to: 'BRE', attributes: { prediction: 8106 }, }, { - id: 1111, + id: '1111', from: 'NSI', to: 'BRU', attributes: { prediction: 2167 }, }, { - id: 1112, + id: '1112', from: 'AUX', to: 'BSB', attributes: { prediction: 761 }, }, { - id: 1113, + id: '1113', from: 'MSP', to: 'CMH', attributes: { prediction: 7148 }, }, { - id: 1114, + id: '1114', from: 'ALB', to: 'BWI', attributes: { prediction: 16563 }, }, { - id: 1115, + id: '1115', from: 'BDL', to: 'BWI', attributes: { prediction: 21996 }, }, { - id: 1116, + id: '1116', from: 'YIW', to: 'CAN', attributes: { prediction: 9198 }, }, { - id: 1117, + id: '1117', from: 'BRM', to: 'CCS', attributes: { prediction: 10344 }, }, { - id: 1118, + id: '1118', from: 'CLT', to: 'CDG', attributes: { prediction: 4402 }, }, { - id: 1119, + id: '1119', from: 'PNR', to: 'CDG', attributes: { prediction: 2001 }, }, { - id: 1120, + id: '1120', from: 'CXJ', to: 'CGH', attributes: { prediction: 3575 }, }, { - id: 1121, + id: '1121', from: 'BWN', to: 'CGK', attributes: { prediction: 3174 }, }, { - id: 1122, + id: '1122', from: 'LIM', to: 'CHM', attributes: { prediction: 220 }, }, { - id: 1123, + id: '1123', from: 'SLC', to: 'COS', attributes: { prediction: 2152 }, }, { - id: 1124, + id: '1124', from: 'SIN', to: 'CPH', attributes: { prediction: 3762 }, }, { - id: 1125, + id: '1125', from: 'SJJ', to: 'CPH', attributes: { prediction: 824 }, }, { - id: 1126, + id: '1126', from: 'TLL', to: 'CPH', attributes: { prediction: 6778 }, }, { - id: 1127, + id: '1127', from: 'MTR', to: 'CTG', attributes: { prediction: 664 }, }, { - id: 1128, + id: '1128', from: 'FLL', to: 'DCA', attributes: { prediction: 25347 }, }, { - id: 1129, + id: '1129', from: 'MIA', to: 'DCA', attributes: { prediction: 35214 }, }, { - id: 1130, + id: '1130', from: 'ORF', to: 'DCA', attributes: { prediction: 3054 }, }, { - id: 1131, + id: '1131', from: 'BOM', to: 'DEL', attributes: { prediction: 247120 }, }, { - id: 1132, + id: '1132', from: 'GOI', to: 'DEL', attributes: { prediction: 21494 }, }, { - id: 1133, + id: '1133', from: 'MAA', to: 'DEL', attributes: { prediction: 63796 }, }, { - id: 1134, + id: '1134', from: 'FRA', to: 'DLM', attributes: { prediction: 263 }, }, { - id: 1135, + id: '1135', from: 'TIF', to: 'DMM', attributes: { prediction: 1027 }, }, { - id: 1136, + id: '1136', from: 'DAC', to: 'DOH', attributes: { prediction: 9757 }, }, { - id: 1137, + id: '1137', from: 'CBR', to: 'DRW', attributes: { prediction: 1447 }, }, { - id: 1138, + id: '1138', from: 'SYR', to: 'CVG', attributes: { prediction: 1154 }, }, { - id: 1139, + id: '1139', from: 'ABQ', to: 'CVN', attributes: { prediction: 436 }, }, { - id: 1140, + id: '1140', from: 'EWR', to: 'CZM', attributes: { prediction: 430 }, }, { - id: 1141, + id: '1141', from: 'IAD', to: 'DAY', attributes: { prediction: 4617 }, }, { - id: 1142, + id: '1142', from: 'HPN', to: 'DCA', attributes: { prediction: 3668 }, }, { - id: 1143, + id: '1143', from: 'JFK', to: 'DCA', attributes: { prediction: 13150 }, }, { - id: 1144, + id: '1144', from: 'LAS', to: 'DCA', attributes: { prediction: 3379 }, }, { - id: 1145, + id: '1145', from: 'MSY', to: 'DCA', attributes: { prediction: 8436 }, }, { - id: 1146, + id: '1146', from: 'IDR', to: 'DEL', attributes: { prediction: 4275 }, }, { - id: 1147, + id: '1147', from: 'BUR', to: 'DEN', attributes: { prediction: 2433 }, }, { - id: 1148, + id: '1148', from: 'RDM', to: 'DEN', attributes: { prediction: 1083 }, }, { - id: 1149, + id: '1149', from: 'FWA', to: 'DFW', attributes: { prediction: 2260 }, }, { - id: 1150, + id: '1150', from: 'CDG', to: 'DUB', attributes: { prediction: 29719 }, }, { - id: 1151, + id: '1151', from: 'DBV', to: 'DUB', attributes: { prediction: 1795 }, }, { - id: 1152, + id: '1152', from: 'COD', to: 'DEN', attributes: { prediction: 946 }, }, { - id: 1153, + id: '1153', from: 'LNK', to: 'DEN', attributes: { prediction: 3095 }, }, { - id: 1154, + id: '1154', from: 'BNA', to: 'DFW', attributes: { prediction: 27050 }, }, { - id: 1155, + id: '1155', from: 'LGA', to: 'DFW', attributes: { prediction: 50462 }, }, { - id: 1156, + id: '1156', from: 'HRG', to: 'DUS', attributes: { prediction: 2045 }, }, { - id: 1157, + id: '1157', from: 'SOU', to: 'DUS', attributes: { prediction: 1355 }, }, { - id: 1158, + id: '1158', from: 'SUF', to: 'DUS', attributes: { prediction: 1760 }, }, { - id: 1159, + id: '1159', from: 'CGY', to: 'DVO', attributes: { prediction: 532 }, }, { - id: 1160, + id: '1160', from: 'TPA', to: 'IAD', attributes: { prediction: 14856 }, }, { - id: 1161, + id: '1161', from: 'CLE', to: 'IAH', attributes: { prediction: 21592 }, }, { - id: 1162, + id: '1162', from: 'DUB', to: 'FMM', attributes: { prediction: 3902 }, }, { - id: 1163, + id: '1163', from: 'BHX', to: 'FNC', attributes: { prediction: 677 }, }, { - id: 1164, + id: '1164', from: 'EMA', to: 'EDI', attributes: { prediction: 6463 }, }, { - id: 1165, + id: '1165', from: 'LGW', to: 'EDI', attributes: { prediction: 27776 }, }, { - id: 1166, + id: '1166', from: 'NAS', to: 'ELH', attributes: { prediction: 1827 }, }, { - id: 1167, + id: '1167', from: 'IKA', to: 'ESB', attributes: { prediction: 1659 }, }, { - id: 1168, + id: '1168', from: 'STR', to: 'ESB', attributes: { prediction: 594 }, }, { - id: 1169, + id: '1169', from: 'SXF', to: 'ESB', attributes: { prediction: 369 }, }, { - id: 1170, + id: '1170', from: 'LIR', to: 'EWR', attributes: { prediction: 970 }, }, { - id: 1171, + id: '1171', from: 'FRA', to: 'FAO', attributes: { prediction: 2310 }, }, { - id: 1172, + id: '1172', from: 'PTY', to: 'FLL', attributes: { prediction: 1431 }, }, { - id: 1173, + id: '1173', from: 'AGA', to: 'FRA', attributes: { prediction: 489 }, }, { - id: 1174, + id: '1174', from: 'JED', to: 'FRA', attributes: { prediction: 6559 }, }, { - id: 1175, + id: '1175', from: 'MZT', to: 'IAH', attributes: { prediction: 1800 }, }, { - id: 1176, + id: '1176', from: 'NRT', to: 'IAH', attributes: { prediction: 6745 }, }, { - id: 1177, + id: '1177', from: 'XNA', to: 'IAH', attributes: { prediction: 3892 }, }, { - id: 1178, + id: '1178', from: 'DPS', to: 'ICN', attributes: { prediction: 11446 }, }, { - id: 1179, + id: '1179', from: 'LGW', to: 'KEF', attributes: { prediction: 3767 }, }, { - id: 1180, + id: '1180', from: 'MZH', to: 'IST', attributes: { prediction: 3261 }, }, { - id: 1181, + id: '1181', from: 'SZF', to: 'IST', attributes: { prediction: 12305 }, }, { - id: 1182, + id: '1182', from: 'HEL', to: 'IVL', attributes: { prediction: 4360 }, }, { - id: 1183, + id: '1183', from: 'IAD', to: 'JED', attributes: { prediction: 838 }, }, { - id: 1184, + id: '1184', from: 'GIG', to: 'JFK', attributes: { prediction: 2922 }, }, { - id: 1185, + id: '1185', from: 'GVA', to: 'JFK', attributes: { prediction: 5028 }, }, { - id: 1186, + id: '1186', from: 'SMF', to: 'JFK', attributes: { prediction: 4008 }, }, { - id: 1187, + id: '1187', from: 'GYN', to: 'GRU', attributes: { prediction: 15379 }, }, { - id: 1188, + id: '1188', from: 'GRO', to: 'GSE', attributes: { prediction: 1210 }, }, { - id: 1189, + id: '1189', from: 'SFO', to: 'GUM', attributes: { prediction: 2424 }, }, { - id: 1190, + id: '1190', from: 'MIR', to: 'GVA', attributes: { prediction: 543 }, }, { - id: 1191, + id: '1191', from: 'STN', to: 'HAJ', attributes: { prediction: 5619 }, }, { - id: 1192, + id: '1192', from: 'SPU', to: 'HAM', attributes: { prediction: 453 }, }, { - id: 1193, + id: '1193', from: 'PTP', to: 'HAV', attributes: { prediction: 298 }, }, { - id: 1194, + id: '1194', from: 'KUO', to: 'HEL', attributes: { prediction: 11820 }, }, { - id: 1195, + id: '1195', from: 'CPH', to: 'HER', attributes: { prediction: 408 }, }, { - id: 1196, + id: '1196', from: 'CIF', to: 'HET', attributes: { prediction: 2131 }, }, { - id: 1197, + id: '1197', from: 'SFB', to: 'HGR', attributes: { prediction: 1149 }, }, { - id: 1198, + id: '1198', from: 'SAH', to: 'JIB', attributes: { prediction: 1366 }, }, { - id: 1199, + id: '1199', from: 'KTM', to: 'JKR', attributes: { prediction: 275 }, }, { - id: 1200, + id: '1200', from: 'AKJ', to: 'HND', attributes: { prediction: 41911 }, }, { - id: 1201, + id: '1201', from: 'KWI', to: 'HRG', attributes: { prediction: 1920 }, }, { - id: 1202, + id: '1202', from: 'BQS', to: 'HTA', attributes: { prediction: 502 }, }, { - id: 1203, + id: '1203', from: 'RJA', to: 'HYD', attributes: { prediction: 1661 }, }, { - id: 1204, + id: '1204', from: 'TPA', to: 'IAH', attributes: { prediction: 20735 }, }, { - id: 1205, + id: '1205', from: 'CDG', to: 'IBZ', attributes: { prediction: 1621 }, }, { - id: 1206, + id: '1206', from: 'STL', to: 'ICT', attributes: { prediction: 260 }, }, { - id: 1207, + id: '1207', from: 'LDB', to: 'IGU', attributes: { prediction: 606 }, }, { - id: 1208, + id: '1208', from: 'ANC', to: 'ILI', attributes: { prediction: 288 }, }, { - id: 1209, + id: '1209', from: 'DCA', to: 'ILM', attributes: { prediction: 105 }, }, { - id: 1210, + id: '1210', from: 'MPM', to: 'INH', attributes: { prediction: 192 }, }, { - id: 1211, + id: '1211', from: 'GVA', to: 'IOM', attributes: { prediction: 112 }, }, { - id: 1212, + id: '1212', from: 'JJU', to: 'JNS', attributes: { prediction: 42 }, }, { - id: 1213, + id: '1213', from: 'ATH', to: 'JSH', attributes: { prediction: 595 }, }, { - id: 1214, + id: '1214', from: 'ALA', to: 'KBL', attributes: { prediction: 299 }, }, { - id: 1215, + id: '1215', from: 'GYD', to: 'KBP', attributes: { prediction: 1909 }, }, { - id: 1216, + id: '1216', from: 'DLG', to: 'KGK', attributes: { prediction: 98 }, }, { - id: 1217, + id: '1217', from: 'PTY', to: 'KIN', attributes: { prediction: 937 }, }, { - id: 1218, + id: '1218', from: 'HND', to: 'KIX', attributes: { prediction: 68270 }, }, { - id: 1219, + id: '1219', from: 'AZN', to: 'KJA', attributes: { prediction: 500 }, }, { - id: 1220, + id: '1220', from: 'CMF', to: 'LBA', attributes: { prediction: 629 }, }, { - id: 1221, + id: '1221', from: 'LBD', to: 'LED', attributes: { prediction: 1016 }, }, { - id: 1222, + id: '1222', from: 'NJC', to: 'LED', attributes: { prediction: 767 }, }, { - id: 1223, + id: '1223', from: 'ILM', to: 'LGA', attributes: { prediction: 2848 }, }, { - id: 1224, + id: '1224', from: 'CAI', to: 'KIX', attributes: { prediction: 2558 }, }, { - id: 1225, + id: '1225', from: 'PVG', to: 'KIX', attributes: { prediction: 35499 }, }, { - id: 1226, + id: '1226', from: 'OSL', to: 'KKN', attributes: { prediction: 6304 }, }, { - id: 1227, + id: '1227', from: 'RUH', to: 'KMC', attributes: { prediction: 385 }, }, { - id: 1228, + id: '1228', from: 'CGD', to: 'KMG', attributes: { prediction: 2228 }, }, { - id: 1229, + id: '1229', from: 'MDL', to: 'KMG', attributes: { prediction: 1031 }, }, { - id: 1230, + id: '1230', from: 'WRY', to: 'KOI', attributes: { prediction: 97 }, }, { - id: 1231, + id: '1231', from: 'STN', to: 'KRK', attributes: { prediction: 8021 }, }, { - id: 1232, + id: '1232', from: 'BVA', to: 'KTW', attributes: { prediction: 1624 }, }, { - id: 1233, + id: '1233', from: 'CAN', to: 'KUL', attributes: { prediction: 10406 }, }, { - id: 1234, + id: '1234', from: 'DPS', to: 'KUL', attributes: { prediction: 22278 }, }, { - id: 1235, + id: '1235', from: 'MYY', to: 'KUL', attributes: { prediction: 15526 }, }, { - id: 1236, + id: '1236', from: 'LPL', to: 'KUN', attributes: { prediction: 1119 }, }, { - id: 1237, + id: '1237', from: 'HFE', to: 'KWE', attributes: { prediction: 1109 }, }, { - id: 1238, + id: '1238', from: 'AMM', to: 'KWI', attributes: { prediction: 11221 }, }, { - id: 1239, + id: '1239', from: 'LXR', to: 'KWI', attributes: { prediction: 6041 }, }, { - id: 1240, + id: '1240', from: 'BIS', to: 'LAS', attributes: { prediction: 1737 }, }, { - id: 1241, + id: '1241', from: 'FAT', to: 'LAS', attributes: { prediction: 6068 }, }, { - id: 1242, + id: '1242', from: 'LAS', to: 'LAX', attributes: { prediction: 92849 }, }, { - id: 1243, + id: '1243', from: 'MXP', to: 'LGW', attributes: { prediction: 12414 }, }, { - id: 1244, + id: '1244', from: 'EMK', to: 'KOT', attributes: { prediction: 321 }, }, { - id: 1245, + id: '1245', from: 'VNS', to: 'KTM', attributes: { prediction: 1780 }, }, { - id: 1246, + id: '1246', from: 'FRA', to: 'KTW', attributes: { prediction: 4848 }, }, { - id: 1247, + id: '1247', from: 'TRN', to: 'KTW', attributes: { prediction: 971 }, }, { - id: 1248, + id: '1248', from: 'AER', to: 'KUF', attributes: { prediction: 447 }, }, { - id: 1249, + id: '1249', from: 'FNT', to: 'MCO', attributes: { prediction: 2699 }, }, { - id: 1250, + id: '1250', from: 'DEL', to: 'LKO', attributes: { prediction: 22983 }, }, { - id: 1251, + id: '1251', from: 'ARN', to: 'LPA', attributes: { prediction: 477 }, }, { - id: 1252, + id: '1252', from: 'TXL', to: 'LPA', attributes: { prediction: 2834 }, }, { - id: 1253, + id: '1253', from: 'IQQ', to: 'LPB', attributes: { prediction: 1011 }, }, { - id: 1254, + id: '1254', from: 'RAK', to: 'LUX', attributes: { prediction: 382 }, }, { - id: 1255, + id: '1255', from: 'CPH', to: 'LYS', attributes: { prediction: 1252 }, }, { - id: 1256, + id: '1256', from: 'PTP', to: 'LYS', attributes: { prediction: 1727 }, }, { - id: 1257, + id: '1257', from: 'LIM', to: 'MAD', attributes: { prediction: 16042 }, }, { - id: 1258, + id: '1258', from: 'MUC', to: 'MAD', attributes: { prediction: 22356 }, }, { - id: 1259, + id: '1259', from: 'MVD', to: 'MAD', attributes: { prediction: 4336 }, }, { - id: 1260, + id: '1260', from: 'HRG', to: 'MAN', attributes: { prediction: 902 }, }, { - id: 1261, + id: '1261', from: 'ATL', to: 'MBJ', attributes: { prediction: 12368 }, }, { - id: 1262, + id: '1262', from: 'CVG', to: 'MCI', attributes: { prediction: 3411 }, }, { - id: 1263, + id: '1263', from: 'DOH', to: 'MEL', attributes: { prediction: 5896 }, }, { - id: 1264, + id: '1264', from: 'GLH', to: 'MEM', attributes: { prediction: 1148 }, }, { - id: 1265, + id: '1265', from: 'HEL', to: 'LGW', attributes: { prediction: 3587 }, }, { - id: 1266, + id: '1266', from: 'IBZ', to: 'NRN', attributes: { prediction: 2802 }, }, { - id: 1267, + id: '1267', from: 'SDJ', to: 'NRT', attributes: { prediction: 1923 }, }, { - id: 1268, + id: '1268', from: 'GDL', to: 'PHX', attributes: { prediction: 5725 }, }, { - id: 1269, + id: '1269', from: 'TUL', to: 'PHX', attributes: { prediction: 6509 }, }, { - id: 1270, + id: '1270', from: 'BFS', to: 'PMI', attributes: { prediction: 3876 }, }, { - id: 1271, + id: '1271', from: 'GRO', to: 'PMI', attributes: { prediction: 2560 }, }, { - id: 1272, + id: '1272', from: 'NBO', to: 'MRE', attributes: { prediction: 233 }, }, { - id: 1273, + id: '1273', from: 'ORY', to: 'MRU', attributes: { prediction: 3771 }, }, { - id: 1274, + id: '1274', from: 'ZRH', to: 'MUC', attributes: { prediction: 15775 }, }, { - id: 1275, + id: '1275', from: 'BUD', to: 'MXP', attributes: { prediction: 7540 }, }, { - id: 1276, + id: '1276', from: 'SVO', to: 'MXP', attributes: { prediction: 11101 }, }, { - id: 1277, + id: '1277', from: 'ITM', to: 'MYJ', attributes: { prediction: 9897 }, }, { - id: 1278, + id: '1278', from: 'MXP', to: 'RMF', attributes: { prediction: 146 }, }, { - id: 1279, + id: '1279', from: 'TIF', to: 'RUH', attributes: { prediction: 7259 }, }, { - id: 1280, + id: '1280', from: 'DOH', to: 'SAH', attributes: { prediction: 4119 }, }, { - id: 1281, + id: '1281', from: 'SVQ', to: 'SCQ', attributes: { prediction: 725 }, }, { - id: 1282, + id: '1282', from: 'YKS', to: 'PYJ', attributes: { prediction: 114 }, }, { - id: 1283, + id: '1283', from: 'BLA', to: 'PZO', attributes: { prediction: 1316 }, }, { - id: 1284, + id: '1284', from: 'GRU', to: 'REC', attributes: { prediction: 63786 }, }, { - id: 1285, + id: '1285', from: 'PIE', to: 'RFD', attributes: { prediction: 1614 }, }, { - id: 1286, + id: '1286', from: 'DSM', to: 'ORD', attributes: { prediction: 15664 }, }, { - id: 1287, + id: '1287', from: 'GSP', to: 'ORD', attributes: { prediction: 3501 }, }, { - id: 1288, + id: '1288', from: 'IAD', to: 'ORF', attributes: { prediction: 6398 }, }, { - id: 1289, + id: '1289', from: 'OSL', to: 'ORY', attributes: { prediction: 3425 }, }, { - id: 1290, + id: '1290', from: 'DXB', to: 'OTP', attributes: { prediction: 1191 }, }, { - id: 1291, + id: '1291', from: 'TGM', to: 'OTP', attributes: { prediction: 423 }, }, { - id: 1292, + id: '1292', from: 'LFW', to: 'OUA', attributes: { prediction: 3196 }, }, { - id: 1293, + id: '1293', from: 'JFK', to: 'PAP', attributes: { prediction: 7416 }, }, { - id: 1294, + id: '1294', from: 'CAY', to: 'PBM', attributes: { prediction: 310 }, }, { - id: 1295, + id: '1295', from: 'BKK', to: 'PEK', attributes: { prediction: 20200 }, }, { - id: 1296, + id: '1296', from: 'HAK', to: 'PEK', attributes: { prediction: 21245 }, }, { - id: 1297, + id: '1297', from: 'KVL', to: 'PHO', attributes: { prediction: 72 }, }, { - id: 1298, + id: '1298', from: 'SBP', to: 'PHX', attributes: { prediction: 3918 }, }, { - id: 1299, + id: '1299', from: 'AZA', to: 'PIA', attributes: { prediction: 1832 }, }, { - id: 1300, + id: '1300', from: 'PHL', to: 'PIT', attributes: { prediction: 25681 }, }, { - id: 1301, + id: '1301', from: 'AAX', to: 'PLU', attributes: { prediction: 1012 }, }, { - id: 1302, + id: '1302', from: 'WAW', to: 'PMI', attributes: { prediction: 954 }, }, { - id: 1303, + id: '1303', from: 'JNB', to: 'PNR', attributes: { prediction: 1888 }, }, { - id: 1304, + id: '1304', from: 'HHN', to: 'PRG', attributes: { prediction: 2197 }, }, { - id: 1305, + id: '1305', from: 'VNO', to: 'PRG', attributes: { prediction: 4713 }, }, { - id: 1306, + id: '1306', from: 'NNL', to: 'PTA', attributes: { prediction: 76 }, }, { - id: 1307, + id: '1307', from: 'GDL', to: 'PTY', attributes: { prediction: 1182 }, }, { - id: 1308, + id: '1308', from: 'DLC', to: 'PVG', attributes: { prediction: 52859 }, }, { - id: 1309, + id: '1309', from: 'MSP', to: 'RST', attributes: { prediction: 4038 }, }, { - id: 1310, + id: '1310', from: 'KHI', to: 'RZS', attributes: { prediction: 311 }, }, { - id: 1311, + id: '1311', from: 'SAT', to: 'SAN', attributes: { prediction: 6155 }, }, { - id: 1312, + id: '1312', from: 'ADB', to: 'SAW', attributes: { prediction: 28308 }, }, { - id: 1313, + id: '1313', from: 'BLE', to: 'SDL', attributes: { prediction: 79 }, }, { - id: 1314, + id: '1314', from: 'CDB', to: 'SDP', attributes: { prediction: 215 }, }, { - id: 1315, + id: '1315', from: 'EWR', to: 'SNN', attributes: { prediction: 3558 }, }, { - id: 1316, + id: '1316', from: 'AGP', to: 'SOF', attributes: { prediction: 436 }, }, { - id: 1317, + id: '1317', from: 'SVO', to: 'SOF', attributes: { prediction: 4264 }, }, { - id: 1318, + id: '1318', from: 'NDY', to: 'SOY', attributes: { prediction: 22 }, }, { - id: 1319, + id: '1319', from: 'BGO', to: 'SPU', attributes: { prediction: 460 }, }, { - id: 1320, + id: '1320', from: 'VIE', to: 'SPU', attributes: { prediction: 2478 }, }, { - id: 1321, + id: '1321', from: 'CTA', to: 'SSH', attributes: { prediction: 205 }, }, { - id: 1322, + id: '1322', from: 'ZRH', to: 'SSH', attributes: { prediction: 1950 }, }, { - id: 1323, + id: '1323', from: 'FLN', to: 'SCL', attributes: { prediction: 103 }, }, { - id: 1324, + id: '1324', from: 'MAD', to: 'SCU', attributes: { prediction: 950 }, }, { - id: 1325, + id: '1325', from: 'MCO', to: 'SEA', attributes: { prediction: 4667 }, }, { - id: 1326, + id: '1326', from: 'JSU', to: 'SFJ', attributes: { prediction: 316 }, }, { - id: 1327, + id: '1327', from: 'DFW', to: 'SFO', attributes: { prediction: 41616 }, }, { - id: 1328, + id: '1328', from: 'XMN', to: 'SHE', attributes: { prediction: 4524 }, }, { - id: 1329, + id: '1329', from: 'NBO', to: 'SHJ', attributes: { prediction: 1670 }, }, { - id: 1330, + id: '1330', from: 'MDW', to: 'SJC', attributes: { prediction: 3171 }, }, { - id: 1331, + id: '1331', from: 'SMF', to: 'SJC', attributes: { prediction: 2269 }, }, { - id: 1332, + id: '1332', from: 'IST', to: 'SJJ', attributes: { prediction: 5430 }, }, { - id: 1333, + id: '1333', from: 'SAT', to: 'SLC', attributes: { prediction: 3492 }, }, { - id: 1334, + id: '1334', from: 'ACE', to: 'STR', attributes: { prediction: 1205 }, }, { - id: 1335, + id: '1335', from: 'SAW', to: 'STR', attributes: { prediction: 9503 }, }, { - id: 1336, + id: '1336', from: 'LEJ', to: 'SUF', attributes: { prediction: 542 }, }, { - id: 1337, + id: '1337', from: 'OTP', to: 'SUJ', attributes: { prediction: 681 }, }, { - id: 1338, + id: '1338', from: 'DFW', to: 'SGF', attributes: { prediction: 10256 }, }, { - id: 1339, + id: '1339', from: 'LPL', to: 'TPS', attributes: { prediction: 1186 }, }, { - id: 1340, + id: '1340', from: 'NCE', to: 'TRD', attributes: { prediction: 472 }, }, { - id: 1341, + id: '1341', from: 'EZE', to: 'SYD', attributes: { prediction: 3181 }, }, { - id: 1342, + id: '1342', from: 'LNZ', to: 'SZG', attributes: { prediction: 1827 }, }, { - id: 1343, + id: '1343', from: 'CTU', to: 'SZX', attributes: { prediction: 35827 }, }, { - id: 1344, + id: '1344', from: 'NGB', to: 'TAO', attributes: { prediction: 5057 }, }, { - id: 1345, + id: '1345', from: 'DXB', to: 'TIP', attributes: { prediction: 6707 }, }, { - id: 1346, + id: '1346', from: 'GOT', to: 'TLL', attributes: { prediction: 411 }, }, { - id: 1347, + id: '1347', from: 'KRK', to: 'TLV', attributes: { prediction: 106 }, }, { - id: 1348, + id: '1348', from: 'ACY', to: 'TPA', attributes: { prediction: 3224 }, }, { - id: 1349, + id: '1349', from: 'HPN', to: 'TPA', attributes: { prediction: 2264 }, }, { - id: 1350, + id: '1350', from: 'HIJ', to: 'TPE', attributes: { prediction: 2037 }, }, { - id: 1351, + id: '1351', from: 'TIA', to: 'TSF', attributes: { prediction: 1443 }, }, { - id: 1352, + id: '1352', from: 'ZSJ', to: 'YWG', attributes: { prediction: 180 }, }, { - id: 1353, + id: '1353', from: 'YQT', to: 'YWP', attributes: { prediction: 50 }, }, { - id: 1354, + id: '1354', from: 'ZRH', to: 'ACE', attributes: { prediction: 1268 }, }, { - id: 1355, + id: '1355', from: 'PLO', to: 'ADL', attributes: { prediction: 8558 }, }, { - id: 1356, + id: '1356', from: 'EQS', to: 'AEP', attributes: { prediction: 595 }, }, { - id: 1357, + id: '1357', from: 'KRR', to: 'AER', attributes: { prediction: 1666 }, }, { - id: 1358, + id: '1358', from: 'STR', to: 'AGP', attributes: { prediction: 3633 }, }, { - id: 1359, + id: '1359', from: 'ALC', to: 'VLL', attributes: { prediction: 1986 }, }, { - id: 1360, + id: '1360', from: 'SLA', to: 'VVI', attributes: { prediction: 774 }, }, { - id: 1361, + id: '1361', from: 'EIN', to: 'WAW', attributes: { prediction: 1662 }, }, { - id: 1362, + id: '1362', from: 'EWR', to: 'WAW', attributes: { prediction: 2154 }, }, { - id: 1363, + id: '1363', from: 'FRL', to: 'WAW', attributes: { prediction: 1704 }, }, { - id: 1364, + id: '1364', from: 'LYG', to: 'XMN', attributes: { prediction: 500 }, }, { - id: 1365, + id: '1365', from: 'YOW', to: 'YEG', attributes: { prediction: 4011 }, }, { - id: 1366, + id: '1366', from: 'YVR', to: 'YPR', attributes: { prediction: 1226 }, }, { - id: 1367, + id: '1367', from: 'CUN', to: 'YUL', attributes: { prediction: 5347 }, }, { - id: 1368, + id: '1368', from: 'PVR', to: 'YUL', attributes: { prediction: 198 }, }, { - id: 1369, + id: '1369', from: 'YYC', to: 'YVR', attributes: { prediction: 69520 }, }, { - id: 1370, + id: '1370', from: 'SUR', to: 'YWP', attributes: { prediction: 62 }, }, { - id: 1371, + id: '1371', from: 'SFO', to: 'YYC', attributes: { prediction: 6213 }, }, { - id: 1372, + id: '1372', from: 'YLW', to: 'YYJ', attributes: { prediction: 2445 }, }, { - id: 1373, + id: '1373', from: 'GGT', to: 'YYZ', attributes: { prediction: 282 }, }, { - id: 1374, + id: '1374', from: 'YKT', to: 'ZEL', attributes: { prediction: 17 }, }, { - id: 1375, + id: '1375', from: 'FUE', to: 'ZQW', attributes: { prediction: 625 }, }, { - id: 1376, + id: '1376', from: 'SOF', to: 'ZRH', attributes: { prediction: 3799 }, }, { - id: 1377, + id: '1377', from: 'TIA', to: 'ZRH', attributes: { prediction: 660 }, }, { - id: 1378, + id: '1378', from: 'VIE', to: 'ZRH', attributes: { prediction: 36870 }, }, { - id: 1379, + id: '1379', from: 'SEA', to: 'ALW', attributes: { prediction: 2326 }, }, { - id: 1380, + id: '1380', from: 'MXP', to: 'AMM', attributes: { prediction: 1657 }, }, { - id: 1381, + id: '1381', from: 'AMM', to: 'ALY', attributes: { prediction: 1491 }, }, { - id: 1382, + id: '1382', from: 'ATH', to: 'AMM', attributes: { prediction: 1698 }, }, { - id: 1383, + id: '1383', from: 'YUL', to: 'BDL', attributes: { prediction: 1135 }, }, { - id: 1384, + id: '1384', from: 'EMK', to: 'BET', attributes: { prediction: 224 }, }, { - id: 1385, + id: '1385', from: 'BCN', to: 'BFS', attributes: { prediction: 4583 }, }, { - id: 1386, + id: '1386', from: 'LED', to: 'AMS', attributes: { prediction: 6427 }, }, { - id: 1387, + id: '1387', from: 'TMM', to: 'ANM', attributes: { prediction: 196 }, }, { - id: 1388, + id: '1388', from: 'NRN', to: 'AOI', attributes: { prediction: 1920 }, }, { - id: 1389, + id: '1389', from: 'SCL', to: 'ARI', attributes: { prediction: 4254 }, }, { - id: 1390, + id: '1390', from: 'SYD', to: 'ASP', attributes: { prediction: 3360 }, }, { - id: 1391, + id: '1391', from: 'BNA', to: 'ATL', attributes: { prediction: 20604 }, }, { - id: 1392, + id: '1392', from: 'GTR', to: 'ATL', attributes: { prediction: 1606 }, }, { - id: 1393, + id: '1393', from: 'MEX', to: 'ATL', attributes: { prediction: 12813 }, }, { - id: 1394, + id: '1394', from: 'ASB', to: 'ATQ', attributes: { prediction: 3991 }, }, { - id: 1395, + id: '1395', from: 'MCO', to: 'AUA', attributes: { prediction: 520 }, }, { - id: 1396, + id: '1396', from: 'LHR', to: 'AUH', attributes: { prediction: 23795 }, }, { - id: 1397, + id: '1397', from: 'FLL', to: 'AUS', attributes: { prediction: 5953 }, }, { - id: 1398, + id: '1398', from: 'CTS', to: 'AXT', attributes: { prediction: 3658 }, }, { - id: 1399, + id: '1399', from: 'TLV', to: 'AYT', attributes: { prediction: 2923 }, }, { - id: 1400, + id: '1400', from: 'MFR', to: 'AZA', attributes: { prediction: 1165 }, }, { - id: 1401, + id: '1401', from: 'DEL', to: 'BAH', attributes: { prediction: 8425 }, }, { - id: 1402, + id: '1402', from: 'SHJ', to: 'BAH', attributes: { prediction: 6639 }, }, { - id: 1403, + id: '1403', from: 'NTE', to: 'BGY', attributes: { prediction: 2619 }, }, { - id: 1404, + id: '1404', from: 'LPL', to: 'BHD', attributes: { prediction: 13082 }, }, { - id: 1405, + id: '1405', from: 'YYZ', to: 'BHX', attributes: { prediction: 1633 }, }, { - id: 1406, + id: '1406', from: 'BRU', to: 'BJM', attributes: { prediction: 1708 }, }, { - id: 1407, + id: '1407', from: 'DLM', to: 'BHX', attributes: { prediction: 3147 }, }, { - id: 1408, + id: '1408', from: 'ADD', to: 'BJR', attributes: { prediction: 4528 }, }, { - id: 1409, + id: '1409', from: 'SZX', to: 'BKI', attributes: { prediction: 3752 }, }, { - id: 1410, + id: '1410', from: 'NGO', to: 'BKK', attributes: { prediction: 11347 }, }, { - id: 1411, + id: '1411', from: 'AHO', to: 'BVA', attributes: { prediction: 1341 }, }, { - id: 1412, + id: '1412', from: 'MAN', to: 'BVC', attributes: { prediction: 796 }, }, { - id: 1413, + id: '1413', from: 'AUS', to: 'BWI', attributes: { prediction: 6636 }, }, { - id: 1414, + id: '1414', from: 'RSW', to: 'BWI', attributes: { prediction: 10642 }, }, { - id: 1415, + id: '1415', from: 'ZAG', to: 'BWK', attributes: { prediction: 292 }, }, { - id: 1416, + id: '1416', from: 'NYO', to: 'BZR', attributes: { prediction: 1279 }, }, { - id: 1417, + id: '1417', from: 'HAD', to: 'BMA', attributes: { prediction: 1122 }, }, { - id: 1418, + id: '1418', from: 'BDB', to: 'BNE', attributes: { prediction: 3414 }, }, { - id: 1419, + id: '1419', from: 'PMI', to: 'BOH', attributes: { prediction: 473 }, }, { - id: 1420, + id: '1420', from: 'AUS', to: 'BOS', attributes: { prediction: 2621 }, }, { - id: 1421, + id: '1421', from: 'PQI', to: 'BOS', attributes: { prediction: 1810 }, }, { - id: 1422, + id: '1422', from: 'SNW', to: 'BSX', attributes: { prediction: 106 }, }, { - id: 1423, + id: '1423', from: 'BRU', to: 'BUD', attributes: { prediction: 8781 }, }, { - id: 1424, + id: '1424', from: 'CGN', to: 'CAI', attributes: { prediction: 1221 }, }, { - id: 1425, + id: '1425', from: 'CGN', to: 'CAG', attributes: { prediction: 1923 }, }, { - id: 1426, + id: '1426', from: 'VIE', to: 'CAG', attributes: { prediction: 380 }, }, { - id: 1427, + id: '1427', from: 'LUX', to: 'CDG', attributes: { prediction: 2818 }, }, { - id: 1428, + id: '1428', from: 'RBA', to: 'CDG', attributes: { prediction: 7123 }, }, { - id: 1429, + id: '1429', from: 'ICN', to: 'CEB', attributes: { prediction: 13565 }, }, { - id: 1430, + id: '1430', from: 'FAI', to: 'CEM', attributes: { prediction: 160 }, }, { - id: 1431, + id: '1431', from: 'MEL', to: 'CHC', attributes: { prediction: 8615 }, }, { - id: 1432, + id: '1432', from: 'CJU', to: 'CJJ', attributes: { prediction: 21188 }, }, { - id: 1433, + id: '1433', from: 'CSX', to: 'CKG', attributes: { prediction: 10201 }, }, { - id: 1434, + id: '1434', from: 'MEX', to: 'CLQ', attributes: { prediction: 2619 }, }, { - id: 1435, + id: '1435', from: 'ICN', to: 'CNX', attributes: { prediction: 856 }, }, { - id: 1436, + id: '1436', from: 'SFO', to: 'COS', attributes: { prediction: 1107 }, }, { - id: 1437, + id: '1437', from: 'AGP', to: 'CPH', attributes: { prediction: 12520 }, }, { - id: 1438, + id: '1438', from: 'KEF', to: 'CPH', attributes: { prediction: 15650 }, }, { - id: 1439, + id: '1439', from: 'PMI', to: 'CPH', attributes: { prediction: 7624 }, }, { - id: 1440, + id: '1440', from: 'PSA', to: 'CPH', attributes: { prediction: 2612 }, }, { - id: 1441, + id: '1441', from: 'WAW', to: 'CPH', attributes: { prediction: 9537 }, }, { - id: 1442, + id: '1442', from: 'NQN', to: 'CRD', attributes: { prediction: 887 }, }, { - id: 1443, + id: '1443', from: 'GRO', to: 'CRL', attributes: { prediction: 9873 }, }, { - id: 1444, + id: '1444', from: 'JFK', to: 'CPH', attributes: { prediction: 4636 }, }, { - id: 1445, + id: '1445', from: 'KRP', to: 'CPH', attributes: { prediction: 19106 }, }, { - id: 1446, + id: '1446', from: 'SLC', to: 'HLN', attributes: { prediction: 3349 }, }, { - id: 1447, + id: '1447', from: 'SAN', to: 'HOU', attributes: { prediction: 6589 }, }, { - id: 1448, + id: '1448', from: 'BSL', to: 'HRG', attributes: { prediction: 1779 }, }, { - id: 1449, + id: '1449', from: 'LAS', to: 'HSV', attributes: { prediction: 250 }, }, { - id: 1450, + id: '1450', from: 'RDU', to: 'IAD', attributes: { prediction: 13043 }, }, { - id: 1451, + id: '1451', from: 'EBA', to: 'FDH', attributes: { prediction: 323 }, }, { - id: 1452, + id: '1452', from: 'GRZ', to: 'FDH', attributes: { prediction: 922 }, }, { - id: 1453, + id: '1453', from: 'VIE', to: 'FDH', attributes: { prediction: 3350 }, }, { - id: 1454, + id: '1454', from: 'ELH', to: 'FLL', attributes: { prediction: 1137 }, }, { - id: 1455, + id: '1455', from: 'XAP', to: 'FLN', attributes: { prediction: 7329 }, }, { - id: 1456, + id: '1456', from: 'CMN', to: 'FNA', attributes: { prediction: 1068 }, }, { - id: 1457, + id: '1457', from: 'LOS', to: 'FNA', attributes: { prediction: 271 }, }, { - id: 1458, + id: '1458', from: 'SFO', to: 'DFW', attributes: { prediction: 41850 }, }, { - id: 1459, + id: '1459', from: 'SCO', to: 'DME', attributes: { prediction: 1351 }, }, { - id: 1460, + id: '1460', from: 'SIN', to: 'DOH', attributes: { prediction: 7307 }, }, { - id: 1461, + id: '1461', from: 'MIR', to: 'DSA', attributes: { prediction: 676 }, }, { - id: 1462, + id: '1462', from: 'BWI', to: 'DTW', attributes: { prediction: 31859 }, }, { - id: 1463, + id: '1463', from: 'NTE', to: 'DUB', attributes: { prediction: 1849 }, }, { - id: 1464, + id: '1464', from: 'SVO', to: 'DXB', attributes: { prediction: 4635 }, }, { - id: 1465, + id: '1465', from: 'BWI', to: 'ECP', attributes: { prediction: 853 }, }, { - id: 1466, + id: '1466', from: 'MAD', to: 'EDI', attributes: { prediction: 3765 }, }, { - id: 1467, + id: '1467', from: 'SOU', to: 'EDI', attributes: { prediction: 11269 }, }, { - id: 1468, + id: '1468', from: 'AKN', to: 'EGX', attributes: { prediction: 34 }, }, { - id: 1469, + id: '1469', from: 'ORD', to: 'ELP', attributes: { prediction: 9941 }, }, { - id: 1470, + id: '1470', from: 'AUA', to: 'EWR', attributes: { prediction: 5108 }, }, { - id: 1471, + id: '1471', from: 'FLL', to: 'EWR', attributes: { prediction: 36389 }, }, { - id: 1472, + id: '1472', from: 'FRA', to: 'EWR', attributes: { prediction: 27494 }, }, { - id: 1473, + id: '1473', from: 'KBC', to: 'FAI', attributes: { prediction: 113 }, }, { - id: 1474, + id: '1474', from: 'SEA', to: 'FAI', attributes: { prediction: 14403 }, }, { - id: 1475, + id: '1475', from: 'GLA', to: 'FAO', attributes: { prediction: 1104 }, }, { - id: 1476, + id: '1476', from: 'ALG', to: 'FCO', attributes: { prediction: 6057 }, }, { - id: 1477, + id: '1477', from: 'FLR', to: 'FCO', attributes: { prediction: 8556 }, }, { - id: 1478, + id: '1478', from: 'MAD', to: 'FCO', attributes: { prediction: 55689 }, }, { - id: 1479, + id: '1479', from: 'MAN', to: 'FCO', attributes: { prediction: 2576 }, }, { - id: 1480, + id: '1480', from: 'EWR', to: 'GCM', attributes: { prediction: 1232 }, }, { - id: 1481, + id: '1481', from: 'IAH', to: 'GDL', attributes: { prediction: 6564 }, }, { - id: 1482, + id: '1482', from: 'TLC', to: 'GDL', attributes: { prediction: 13069 }, }, { - id: 1483, + id: '1483', from: 'CGN', to: 'GDN', attributes: { prediction: 1849 }, }, { - id: 1484, + id: '1484', from: 'EDI', to: 'GDN', attributes: { prediction: 2022 }, }, { - id: 1485, + id: '1485', from: 'DFW', to: 'GJT', attributes: { prediction: 2295 }, }, { - id: 1486, + id: '1486', from: 'BJF', to: 'HFT', attributes: { prediction: 137 }, }, { - id: 1487, + id: '1487', from: 'KIX', to: 'GMP', attributes: { prediction: 26359 }, }, { - id: 1488, + id: '1488', from: 'IST', to: 'GNY', attributes: { prediction: 6011 }, }, { - id: 1489, + id: '1489', from: 'BRS', to: 'GRO', attributes: { prediction: 1957 }, }, { - id: 1490, + id: '1490', from: 'BDL', to: 'GRR', attributes: { prediction: 81 }, }, { - id: 1491, + id: '1491', from: 'FSD', to: 'GRR', attributes: { prediction: 38 }, }, { - id: 1492, + id: '1492', from: 'IAH', to: 'GSP', attributes: { prediction: 3378 }, }, { - id: 1493, + id: '1493', from: 'BIA', to: 'GVA', attributes: { prediction: 586 }, }, { - id: 1494, + id: '1494', from: 'MIA', to: 'GYE', attributes: { prediction: 10718 }, }, { - id: 1495, + id: '1495', from: 'BHX', to: 'HAJ', attributes: { prediction: 2539 }, }, { - id: 1496, + id: '1496', from: 'KRK', to: 'HEL', attributes: { prediction: 860 }, }, { - id: 1497, + id: '1497', from: 'SVO', to: 'HEL', attributes: { prediction: 7296 }, }, { - id: 1498, + id: '1498', from: 'FRA', to: 'HER', attributes: { prediction: 4981 }, }, { - id: 1499, + id: '1499', from: 'DTW', to: 'HPN', attributes: { prediction: 4626 }, }, { - id: 1500, + id: '1500', from: 'IND', to: 'HSV', attributes: { prediction: 152 }, }, { - id: 1501, + id: '1501', from: 'PEK', to: 'JJN', attributes: { prediction: 1765 }, }, { - id: 1502, + id: '1502', from: 'MQP', to: 'JNB', attributes: { prediction: 7410 }, }, { - id: 1503, + id: '1503', from: 'ATH', to: 'JNX', attributes: { prediction: 1044 }, }, { - id: 1504, + id: '1504', from: 'KUL', to: 'JOG', attributes: { prediction: 5152 }, }, { - id: 1505, + id: '1505', from: 'DBV', to: 'KBP', attributes: { prediction: 657 }, }, { - id: 1506, + id: '1506', from: 'DTM', to: 'KBP', attributes: { prediction: 3679 }, }, { - id: 1507, + id: '1507', from: 'DUS', to: 'KBP', attributes: { prediction: 4782 }, }, { - id: 1508, + id: '1508', from: 'HAN', to: 'KHH', attributes: { prediction: 1233 }, }, { - id: 1509, + id: '1509', from: 'NGB', to: 'KHH', attributes: { prediction: 1119 }, }, { - id: 1510, + id: '1510', from: 'JEG', to: 'JQA', attributes: { prediction: 266 }, }, { - id: 1511, + id: '1511', from: 'XIY', to: 'JZH', attributes: { prediction: 2532 }, }, { - id: 1512, + id: '1512', from: 'WUH', to: 'ICN', attributes: { prediction: 1652 }, }, { - id: 1513, + id: '1513', from: 'ANC', to: 'ILI', attributes: { prediction: 367 }, }, { - id: 1514, + id: '1514', from: 'JGO', to: 'JEG', attributes: { prediction: 46 }, }, { - id: 1515, + id: '1515', from: 'ACK', to: 'JFK', attributes: { prediction: 334 }, }, { - id: 1516, + id: '1516', from: 'ARN', to: 'JFK', attributes: { prediction: 597 }, }, { - id: 1517, + id: '1517', from: 'DCA', to: 'JFK', attributes: { prediction: 13578 }, }, { - id: 1518, + id: '1518', from: 'GND', to: 'JFK', attributes: { prediction: 959 }, }, { - id: 1519, + id: '1519', from: 'MCI', to: 'JFK', attributes: { prediction: 2042 }, }, { - id: 1520, + id: '1520', from: 'SAN', to: 'JFK', attributes: { prediction: 19532 }, }, { - id: 1521, + id: '1521', from: 'SBW', to: 'JHB', attributes: { prediction: 1647 }, }, { - id: 1522, + id: '1522', from: 'ASO', to: 'JIM', attributes: { prediction: 639 }, }, { - id: 1523, + id: '1523', from: 'NKM', to: 'KMJ', attributes: { prediction: 1297 }, }, { - id: 1524, + id: '1524', from: 'DME', to: 'MAD', attributes: { prediction: 6280 }, }, { - id: 1525, + id: '1525', from: 'MVD', to: 'MAD', attributes: { prediction: 4200 }, }, { - id: 1526, + id: '1526', from: 'TFS', to: 'MAN', attributes: { prediction: 19768 }, }, { - id: 1527, + id: '1527', from: 'FLL', to: 'MCI', attributes: { prediction: 3405 }, }, { - id: 1528, + id: '1528', from: 'BNA', to: 'MCO', attributes: { prediction: 17466 }, }, { - id: 1529, + id: '1529', from: 'BQN', to: 'MCO', attributes: { prediction: 3903 }, }, { - id: 1530, + id: '1530', from: 'CNP', to: 'KUS', attributes: { prediction: 94 }, }, { - id: 1531, + id: '1531', from: 'MJT', to: 'KVA', attributes: { prediction: 370 }, }, { - id: 1532, + id: '1532', from: 'XUZ', to: 'KWE', attributes: { prediction: 458 }, }, { - id: 1533, + id: '1533', from: 'KHZ', to: 'KXU', attributes: { prediction: 126 }, }, { - id: 1534, + id: '1534', from: 'RHO', to: 'KZS', attributes: { prediction: 639 }, }, { - id: 1535, + id: '1535', from: 'JNB', to: 'LAD', attributes: { prediction: 8914 }, }, { - id: 1536, + id: '1536', from: 'BZN', to: 'LAS', attributes: { prediction: 911 }, }, { - id: 1537, + id: '1537', from: 'TUL', to: 'LAS', attributes: { prediction: 3510 }, }, { - id: 1538, + id: '1538', from: 'DUS', to: 'LAX', attributes: { prediction: 1706 }, }, { - id: 1539, + id: '1539', from: 'RKT', to: 'LBD', attributes: { prediction: 319 }, }, { - id: 1540, + id: '1540', from: 'ATH', to: 'LCA', attributes: { prediction: 38863 }, }, { - id: 1541, + id: '1541', from: 'HAM', to: 'LCA', attributes: { prediction: 680 }, }, { - id: 1542, + id: '1542', from: 'EIN', to: 'LCY', attributes: { prediction: 1604 }, }, { - id: 1543, + id: '1543', from: 'MJK', to: 'LEA', attributes: { prediction: 91 }, }, { - id: 1544, + id: '1544', from: 'CHO', to: 'LGA', attributes: { prediction: 1769 }, }, { - id: 1545, + id: '1545', from: 'YYZ', to: 'LGA', attributes: { prediction: 31265 }, }, { - id: 1546, + id: '1546', from: 'CTG', to: 'MDE', attributes: { prediction: 3064 }, }, { - id: 1547, + id: '1547', from: 'ABZ', to: 'LHR', attributes: { prediction: 30223 }, }, { - id: 1548, + id: '1548', from: 'YOW', to: 'LHR', attributes: { prediction: 4837 }, }, { - id: 1549, + id: '1549', from: 'GIG', to: 'LIM', attributes: { prediction: 2385 }, }, { - id: 1550, + id: '1550', from: 'MHT', to: 'LIR', attributes: { prediction: 139 }, }, { - id: 1551, + id: '1551', from: 'MYY', to: 'LMN', attributes: { prediction: 2149 }, }, { - id: 1552, + id: '1552', from: 'BRS', to: 'LRH', attributes: { prediction: 519 }, }, { - id: 1553, + id: '1553', from: 'CYB', to: 'LYB', attributes: { prediction: 176 }, }, { - id: 1554, + id: '1554', from: 'BES', to: 'LYS', attributes: { prediction: 5123 }, }, { - id: 1555, + id: '1555', from: 'LUX', to: 'LYS', attributes: { prediction: 527 }, }, { - id: 1556, + id: '1556', from: 'MLM', to: 'MEX', attributes: { prediction: 4929 }, }, { - id: 1557, + id: '1557', from: 'SAL', to: 'MGA', attributes: { prediction: 6995 }, }, { - id: 1558, + id: '1558', from: 'KRR', to: 'LED', attributes: { prediction: 1440 }, }, { - id: 1559, + id: '1559', from: 'ICN', to: 'MUC', attributes: { prediction: 4476 }, }, { - id: 1560, + id: '1560', from: 'JTR', to: 'MUC', attributes: { prediction: 400 }, }, { - id: 1561, + id: '1561', from: 'IAD', to: 'MVD', attributes: { prediction: 114 }, }, { - id: 1562, + id: '1562', from: 'BHX', to: 'MXP', attributes: { prediction: 2484 }, }, { - id: 1563, + id: '1563', from: 'GRU', to: 'MXP', attributes: { prediction: 6633 }, }, { - id: 1564, + id: '1564', from: 'DCA', to: 'MYR', attributes: { prediction: 357 }, }, { - id: 1565, + id: '1565', from: 'TSA', to: 'MZG', attributes: { prediction: 19062 }, }, { - id: 1566, + id: '1566', from: 'HKG', to: 'NAN', attributes: { prediction: 1638 }, }, { - id: 1567, + id: '1567', from: 'TCB', to: 'MHH', attributes: { prediction: 125 }, }, { - id: 1568, + id: '1568', from: 'CVG', to: 'MIA', attributes: { prediction: 4897 }, }, { - id: 1569, + id: '1569', from: 'SXM', to: 'MIA', attributes: { prediction: 5597 }, }, { - id: 1570, + id: '1570', from: 'TGZ', to: 'MID', attributes: { prediction: 1844 }, }, { - id: 1571, + id: '1571', from: 'MAN', to: 'MJV', attributes: { prediction: 5755 }, }, { - id: 1572, + id: '1572', from: 'BNA', to: 'MKE', attributes: { prediction: 2670 }, }, { - id: 1573, + id: '1573', from: 'MCO', to: 'MLI', attributes: { prediction: 1633 }, }, { - id: 1574, + id: '1574', from: 'AUH', to: 'MNL', attributes: { prediction: 15674 }, }, { - id: 1575, + id: '1575', from: 'HKG', to: 'MNL', attributes: { prediction: 86110 }, }, { - id: 1576, + id: '1576', from: 'CDG', to: 'MPL', attributes: { prediction: 14134 }, }, { - id: 1577, + id: '1577', from: 'AXU', to: 'MQX', attributes: { prediction: 143 }, }, { - id: 1578, + id: '1578', from: 'ORD', to: 'MSN', attributes: { prediction: 14543 }, }, { - id: 1579, + id: '1579', from: 'ESB', to: 'MSR', attributes: { prediction: 1689 }, }, { - id: 1580, + id: '1580', from: 'ALB', to: 'MSS', attributes: { prediction: 573 }, }, { - id: 1581, + id: '1581', from: 'SLP', to: 'MTY', attributes: { prediction: 1543 }, }, { - id: 1582, + id: '1582', from: 'CGN', to: 'NCE', attributes: { prediction: 3786 }, }, { - id: 1583, + id: '1583', from: 'CPH', to: 'NCE', attributes: { prediction: 13036 }, }, { - id: 1584, + id: '1584', from: 'SOU', to: 'NCE', attributes: { prediction: 1097 }, }, { - id: 1585, + id: '1585', from: 'SSH', to: 'NCL', attributes: { prediction: 2451 }, }, { - id: 1586, + id: '1586', from: 'BOM', to: 'NDC', attributes: { prediction: 354 }, }, { - id: 1587, + id: '1587', from: 'SYX', to: 'NGB', attributes: { prediction: 4319 }, }, { - id: 1588, + id: '1588', from: 'AOJ', to: 'NGO', attributes: { prediction: 6843 }, }, { - id: 1589, + id: '1589', from: 'HKG', to: 'NGO', attributes: { prediction: 8646 }, }, { - id: 1590, + id: '1590', from: 'MNL', to: 'NGO', attributes: { prediction: 13334 }, }, { - id: 1591, + id: '1591', from: 'PRG', to: 'NAP', attributes: { prediction: 3388 }, }, { - id: 1592, + id: '1592', from: 'FEN', to: 'NAT', attributes: { prediction: 1123 }, }, { - id: 1593, + id: '1593', from: 'CMN', to: 'NCE', attributes: { prediction: 2439 }, }, { - id: 1594, + id: '1594', from: 'AGP', to: 'NCL', attributes: { prediction: 9294 }, }, { - id: 1595, + id: '1595', from: 'PTP', to: 'PAP', attributes: { prediction: 3189 }, }, { - id: 1596, + id: '1596', from: 'BOS', to: 'PDX', attributes: { prediction: 4104 }, }, { - id: 1597, + id: '1597', from: 'IAH', to: 'PDX', attributes: { prediction: 17260 }, }, { - id: 1598, + id: '1598', from: 'BHY', to: 'PEK', attributes: { prediction: 2849 }, }, { - id: 1599, + id: '1599', from: 'CHG', to: 'PEK', attributes: { prediction: 318 }, }, { - id: 1600, + id: '1600', from: 'YYC', to: 'NRT', attributes: { prediction: 2172 }, }, { - id: 1601, + id: '1601', from: 'EDI', to: 'NWI', attributes: { prediction: 3412 }, }, { - id: 1602, + id: '1602', from: 'LBC', to: 'NYO', attributes: { prediction: 4255 }, }, { - id: 1603, + id: '1603', from: 'STL', to: 'OKC', attributes: { prediction: 5633 }, }, { - id: 1604, + id: '1604', from: 'EWR', to: 'OMA', attributes: { prediction: 3274 }, }, { - id: 1605, + id: '1605', from: 'GIG', to: 'OPO', attributes: { prediction: 1575 }, }, { - id: 1606, + id: '1606', from: 'BOS', to: 'ORD', attributes: { prediction: 67269 }, }, { - id: 1607, + id: '1607', from: 'PUJ', to: 'ORD', attributes: { prediction: 1744 }, }, { - id: 1608, + id: '1608', from: 'TRD', to: 'OSY', attributes: { prediction: 1034 }, }, { - id: 1609, + id: '1609', from: 'BNE', to: 'PER', attributes: { prediction: 27372 }, }, { - id: 1610, + id: '1610', from: 'CDG', to: 'PHL', attributes: { prediction: 10387 }, }, { - id: 1611, + id: '1611', from: 'MAD', to: 'OTP', attributes: { prediction: 9466 }, }, { - id: 1612, + id: '1612', from: 'SKG', to: 'OTP', attributes: { prediction: 1768 }, }, { - id: 1613, + id: '1613', from: 'TLV', to: 'OTP', attributes: { prediction: 12540 }, }, { - id: 1614, + id: '1614', from: 'LFW', to: 'OUA', attributes: { prediction: 4689 }, }, { - id: 1615, + id: '1615', from: 'CLE', to: 'PBI', attributes: { prediction: 1259 }, }, { - id: 1616, + id: '1616', from: 'TYS', to: 'PGD', attributes: { prediction: 1161 }, }, { - id: 1617, + id: '1617', from: 'DUB', to: 'PHL', attributes: { prediction: 4807 }, }, { - id: 1618, + id: '1618', from: 'ANC', to: 'PHX', attributes: { prediction: 2849 }, }, { - id: 1619, + id: '1619', from: 'SXB', to: 'PRG', attributes: { prediction: 1326 }, }, { - id: 1620, + id: '1620', from: 'SFO', to: 'PSP', attributes: { prediction: 11454 }, }, { - id: 1621, + id: '1621', from: 'MGA', to: 'PTY', attributes: { prediction: 3687 }, }, { - id: 1622, + id: '1622', from: 'LGW', to: 'PUJ', attributes: { prediction: 1621 }, }, { - id: 1623, + id: '1623', from: 'KIX', to: 'PVG', attributes: { prediction: 42652 }, }, { - id: 1624, + id: '1624', from: 'LGA', to: 'PWM', attributes: { prediction: 5434 }, }, { - id: 1625, + id: '1625', from: 'AZA', to: 'RDM', attributes: { prediction: 1141 }, }, { - id: 1626, + id: '1626', from: 'PDX', to: 'RDM', attributes: { prediction: 6597 }, }, { - id: 1627, + id: '1627', from: 'LGA', to: 'RDU', attributes: { prediction: 21322 }, }, { - id: 1628, + id: '1628', from: 'SXF', to: 'RHO', attributes: { prediction: 434 }, }, { - id: 1629, + id: '1629', from: 'HAM', to: 'RIX', attributes: { prediction: 4625 }, }, { - id: 1630, + id: '1630', from: 'VNO', to: 'RIX', attributes: { prediction: 11920 }, }, { - id: 1631, + id: '1631', from: 'PMV', to: 'PZO', attributes: { prediction: 1290 }, }, { - id: 1632, + id: '1632', from: 'VIE', to: 'TPE', attributes: { prediction: 2948 }, }, { - id: 1633, + id: '1633', from: 'CKG', to: 'XIY', attributes: { prediction: 12639 }, }, { - id: 1634, + id: '1634', from: 'JZH', to: 'XIY', attributes: { prediction: 2619 }, }, { - id: 1635, + id: '1635', from: 'IKS', to: 'YKS', attributes: { prediction: 624 }, }, { - id: 1636, + id: '1636', from: 'YVR', to: 'YLW', attributes: { prediction: 16858 }, }, { - id: 1637, + id: '1637', from: 'BRI', to: 'TIA', attributes: { prediction: 4281 }, }, { - id: 1638, + id: '1638', from: 'CUU', to: 'TLC', attributes: { prediction: 6807 }, }, { - id: 1639, + id: '1639', from: 'AUS', to: 'TLN', attributes: { prediction: 10 }, }, { - id: 1640, + id: '1640', from: 'DUS', to: 'TLV', attributes: { prediction: 638 }, }, { - id: 1641, + id: '1641', from: 'CTU', to: 'TNA', attributes: { prediction: 11263 }, }, { - id: 1642, + id: '1642', from: 'WAA', to: 'SHH', attributes: { prediction: 24 }, }, { - id: 1643, + id: '1643', from: 'ALA', to: 'SHJ', attributes: { prediction: 2429 }, }, { - id: 1644, + id: '1644', from: 'IAH', to: 'SHV', attributes: { prediction: 5737 }, }, { - id: 1645, + id: '1645', from: 'CPH', to: 'SIN', attributes: { prediction: 3279 }, }, { - id: 1646, + id: '1646', from: 'HRE', to: 'SIN', attributes: { prediction: 529 }, }, { - id: 1647, + id: '1647', from: 'PNH', to: 'SIN', attributes: { prediction: 8842 }, }, { - id: 1648, + id: '1648', from: 'FRA', to: 'SIP', attributes: { prediction: 621 }, }, { - id: 1649, + id: '1649', from: 'SKD', to: 'SIP', attributes: { prediction: 587 }, }, { - id: 1650, + id: '1650', from: 'SNA', to: 'SJC', attributes: { prediction: 19716 }, }, { - id: 1651, + id: '1651', from: 'MNL', to: 'SJI', attributes: { prediction: 3077 }, }, { - id: 1652, + id: '1652', from: 'SMI', to: 'SKG', attributes: { prediction: 488 }, }, { - id: 1653, + id: '1653', from: 'IAH', to: 'SLC', attributes: { prediction: 14582 }, }, { - id: 1654, + id: '1654', from: 'TOS', to: 'SOJ', attributes: { prediction: 911 }, }, { - id: 1655, + id: '1655', from: 'AMS', to: 'SPU', attributes: { prediction: 520 }, }, { - id: 1656, + id: '1656', from: 'LKL', to: 'TOS', attributes: { prediction: 1792 }, }, { - id: 1657, + id: '1657', from: 'KMQ', to: 'TPE', attributes: { prediction: 828 }, }, { - id: 1658, + id: '1658', from: 'MEX', to: 'TRC', attributes: { prediction: 11964 }, }, { - id: 1659, + id: '1659', from: 'ZAG', to: 'STR', attributes: { prediction: 2673 }, }, { - id: 1660, + id: '1660', from: 'MXP', to: 'SUF', attributes: { prediction: 8468 }, }, { - id: 1661, + id: '1661', from: 'WNN', to: 'SUR', attributes: { prediction: 36 }, }, { - id: 1662, + id: '1662', from: 'BLL', to: 'SVG', attributes: { prediction: 579 }, }, { - id: 1663, + id: '1663', from: 'TRD', to: 'SVG', attributes: { prediction: 3454 }, }, { - id: 1664, + id: '1664', from: 'SVO', to: 'SVX', attributes: { prediction: 15163 }, }, { - id: 1665, + id: '1665', from: 'PVG', to: 'TAE', attributes: { prediction: 2017 }, }, { - id: 1666, + id: '1666', from: 'KSQ', to: 'TAS', attributes: { prediction: 3326 }, }, { - id: 1667, + id: '1667', from: 'ROV', to: 'TAS', attributes: { prediction: 1459 }, }, { - id: 1668, + id: '1668', from: 'SCO', to: 'TBS', attributes: { prediction: 566 }, }, { - id: 1669, + id: '1669', from: 'TLV', to: 'TBS', attributes: { prediction: 1507 }, }, { - id: 1670, + id: '1670', from: 'APW', to: 'TBU', attributes: { prediction: 620 }, }, { - id: 1671, + id: '1671', from: 'GUA', to: 'TGU', attributes: { prediction: 1706 }, }, { - id: 1672, + id: '1672', from: 'NAP', to: 'TRS', attributes: { prediction: 2157 }, }, { - id: 1673, + id: '1673', from: 'DTM', to: 'TSR', attributes: { prediction: 1330 }, }, { - id: 1674, + id: '1674', from: 'OOL', to: 'TSV', attributes: { prediction: 1529 }, }, { - id: 1675, + id: '1675', from: 'CAI', to: 'TXL', attributes: { prediction: 1232 }, }, { - id: 1676, + id: '1676', from: 'CLE', to: 'ABE', attributes: { prediction: 3111 }, }, { - id: 1677, + id: '1677', from: 'YRF', to: 'YBI', attributes: { prediction: 97 }, }, { - id: 1678, + id: '1678', from: 'DMK', to: 'URT', attributes: { prediction: 3746 }, }, { - id: 1679, + id: '1679', from: 'DUS', to: 'VAR', attributes: { prediction: 1102 }, }, { - id: 1680, + id: '1680', from: 'BJF', to: 'VAW', attributes: { prediction: 131 }, }, { - id: 1681, + id: '1681', from: 'ARC', to: 'VEE', attributes: { prediction: 142 }, }, { - id: 1682, + id: '1682', from: 'CUN', to: 'VER', attributes: { prediction: 3615 }, }, { - id: 1683, + id: '1683', from: 'FNC', to: 'VIE', attributes: { prediction: 2087 }, }, { - id: 1684, + id: '1684', from: 'KHV', to: 'VKO', attributes: { prediction: 4716 }, }, { - id: 1685, + id: '1685', from: 'MAH', to: 'VLC', attributes: { prediction: 1238 }, }, { - id: 1686, + id: '1686', from: 'VLL', to: 'VLC', attributes: { prediction: 335 }, }, { - id: 1687, + id: '1687', from: 'PTY', to: 'VLN', attributes: { prediction: 1963 }, }, { - id: 1688, + id: '1688', from: 'VKO', to: 'VVO', attributes: { prediction: 9273 }, }, { - id: 1689, + id: '1689', from: 'SZZ', to: 'WAW', attributes: { prediction: 3940 }, }, { - id: 1690, + id: '1690', from: 'DTW', to: 'YHZ', attributes: { prediction: 1812 }, }, { - id: 1691, + id: '1691', from: 'YTZ', to: 'YOW', attributes: { prediction: 24641 }, }, { - id: 1692, + id: '1692', from: 'BHX', to: 'ABZ', attributes: { prediction: 7653 }, }, { - id: 1693, + id: '1693', from: 'LHR', to: 'ACC', attributes: { prediction: 4294 }, }, { - id: 1694, + id: '1694', from: 'OVD', to: 'ACE', attributes: { prediction: 1611 }, }, { - id: 1695, + id: '1695', from: 'SVI', to: 'ACR', attributes: { prediction: 160 }, }, { - id: 1696, + id: '1696', from: 'BOS', to: 'ACY', attributes: { prediction: 6701 }, }, { - id: 1697, + id: '1697', from: 'AMS', to: 'ADB', attributes: { prediction: 5023 }, }, { - id: 1698, + id: '1698', from: 'AKL', to: 'ADL', attributes: { prediction: 2273 }, }, { - id: 1699, + id: '1699', from: 'CBR', to: 'ADL', attributes: { prediction: 9104 }, }, { - id: 1700, + id: '1700', from: 'AFA', to: 'AEP', attributes: { prediction: 1230 }, }, { - id: 1701, + id: '1701', from: 'LEN', to: 'AGP', attributes: { prediction: 47 }, }, { - id: 1702, + id: '1702', from: 'TRD', to: 'AGP', attributes: { prediction: 693 }, }, { - id: 1703, + id: '1703', from: 'UIP', to: 'AJA', attributes: { prediction: 307 }, }, { - id: 1704, + id: '1704', from: 'LYC', to: 'AJR', attributes: { prediction: 1468 }, }, { - id: 1705, + id: '1705', from: 'NAN', to: 'AKL', attributes: { prediction: 16540 }, }, { - id: 1706, + id: '1706', from: 'BRU', to: 'ABJ', attributes: { prediction: 2037 }, }, { - id: 1707, + id: '1707', from: 'YXC', to: 'YYC', attributes: { prediction: 1209 }, }, { - id: 1708, + id: '1708', from: 'YYR', to: 'YYT', attributes: { prediction: 1367 }, }, { - id: 1709, + id: '1709', from: 'ATL', to: 'YYZ', attributes: { prediction: 16899 }, }, { - id: 1710, + id: '1710', from: 'YNA', to: 'YZV', attributes: { prediction: 225 }, }, { - id: 1711, + id: '1711', from: 'SJJ', to: 'ZAG', attributes: { prediction: 3232 }, }, { - id: 1712, + id: '1712', from: 'MTV', to: 'ZGU', attributes: { prediction: 54 }, }, { - id: 1713, + id: '1713', from: 'CGN', to: 'ZRH', attributes: { prediction: 10039 }, }, { - id: 1714, + id: '1714', from: 'PRG', to: 'ZRH', attributes: { prediction: 14025 }, }, { - id: 1715, + id: '1715', from: 'TLV', to: 'ZRH', attributes: { prediction: 16857 }, }, { - id: 1716, + id: '1716', from: 'TXL', to: 'ZRH', attributes: { prediction: 37000 }, }, { - id: 1717, + id: '1717', from: 'MEX', to: 'ACA', attributes: { prediction: 15450 }, }, { - id: 1718, + id: '1718', from: 'DUS', to: 'ACE', attributes: { prediction: 4448 }, }, { - id: 1719, + id: '1719', from: 'SXF', to: 'ADB', attributes: { prediction: 5171 }, }, { - id: 1720, + id: '1720', from: 'MRS', to: 'AGA', attributes: { prediction: 1561 }, }, { - id: 1721, + id: '1721', from: 'REC', to: 'AJU', attributes: { prediction: 2792 }, }, { - id: 1722, + id: '1722', from: 'SNW', to: 'AKY', attributes: { prediction: 19 }, }, { - id: 1723, + id: '1723', from: 'FKB', to: 'ALC', attributes: { prediction: 2475 }, }, { - id: 1724, + id: '1724', from: 'FRA', to: 'ALC', attributes: { prediction: 2477 }, }, { - id: 1725, + id: '1725', from: 'LGW', to: 'ALC', attributes: { prediction: 34009 }, }, { - id: 1726, + id: '1726', from: 'MME', to: 'ALC', attributes: { prediction: 701 }, }, { - id: 1727, + id: '1727', from: 'MIA', to: 'BAQ', attributes: { prediction: 3381 }, }, { - id: 1728, + id: '1728', from: 'ORD', to: 'BDL', attributes: { prediction: 23886 }, }, { - id: 1729, + id: '1729', from: 'TGD', to: 'BEG', attributes: { prediction: 5710 }, }, { - id: 1730, + id: '1730', from: 'JNU', to: 'ANC', attributes: { prediction: 10542 }, }, { - id: 1731, + id: '1731', from: 'SDP', to: 'ANC', attributes: { prediction: 540 }, }, { - id: 1732, + id: '1732', from: 'CTS', to: 'AOJ', attributes: { prediction: 4888 }, }, { - id: 1733, + id: '1733', from: 'HFS', to: 'ARN', attributes: { prediction: 611 }, }, { - id: 1734, + id: '1734', from: 'KLR', to: 'ARN', attributes: { prediction: 6095 }, }, { - id: 1735, + id: '1735', from: 'PMO', to: 'ARN', attributes: { prediction: 500 }, }, { - id: 1736, + id: '1736', from: 'KRT', to: 'ASM', attributes: { prediction: 353 }, }, { - id: 1737, + id: '1737', from: 'LPB', to: 'ASU', attributes: { prediction: 1821 }, }, { - id: 1738, + id: '1738', from: 'LGW', to: 'ATH', attributes: { prediction: 8141 }, }, { - id: 1739, + id: '1739', from: 'BAH', to: 'AUH', attributes: { prediction: 33485 }, }, { - id: 1740, + id: '1740', from: 'MSQ', to: 'AUH', attributes: { prediction: 1020 }, }, { - id: 1741, + id: '1741', from: 'MUC', to: 'AUH', attributes: { prediction: 6524 }, }, { - id: 1742, + id: '1742', from: 'ELP', to: 'AUS', attributes: { prediction: 11999 }, }, { - id: 1743, + id: '1743', from: 'AKI', to: 'BET', attributes: { prediction: 62 }, }, { - id: 1744, + id: '1744', from: 'LBA', to: 'BHD', attributes: { prediction: 5436 }, }, { - id: 1745, + id: '1745', from: 'GHA', to: 'ALG', attributes: { prediction: 1188 }, }, { - id: 1746, + id: '1746', from: 'AGA', to: 'AMS', attributes: { prediction: 1538 }, }, { - id: 1747, + id: '1747', from: 'JFK', to: 'AUH', attributes: { prediction: 7238 }, }, { - id: 1748, + id: '1748', from: 'CLT', to: 'AVL', attributes: { prediction: 6470 }, }, { - id: 1749, + id: '1749', from: 'DXB', to: 'AWZ', attributes: { prediction: 1030 }, }, { - id: 1750, + id: '1750', from: 'NAS', to: 'AXP', attributes: { prediction: 228 }, }, { - id: 1751, + id: '1751', from: 'LLI', to: 'AXU', attributes: { prediction: 1506 }, }, { - id: 1752, + id: '1752', from: 'AMS', to: 'AYT', attributes: { prediction: 9471 }, }, { - id: 1753, + id: '1753', from: 'ESB', to: 'AYT', attributes: { prediction: 11384 }, }, { - id: 1754, + id: '1754', from: 'LHR', to: 'CMN', attributes: { prediction: 4304 }, }, { - id: 1755, + id: '1755', from: 'JFK', to: 'BUD', attributes: { prediction: 5367 }, }, { - id: 1756, + id: '1756', from: 'PZO', to: 'BLA', attributes: { prediction: 1179 }, }, { - id: 1757, + id: '1757', from: 'OSD', to: 'BMA', attributes: { prediction: 1139 }, }, { - id: 1758, + id: '1758', from: 'MIA', to: 'BNA', attributes: { prediction: 6469 }, }, { - id: 1759, + id: '1759', from: 'HVB', to: 'BNE', attributes: { prediction: 2643 }, }, { - id: 1760, + id: '1760', from: 'MAR', to: 'BOG', attributes: { prediction: 780 }, }, { - id: 1761, + id: '1761', from: 'AUS', to: 'BOS', attributes: { prediction: 2654 }, }, { - id: 1762, + id: '1762', from: 'LAS', to: 'BOS', attributes: { prediction: 8568 }, }, { - id: 1763, + id: '1763', from: 'TMP', to: 'BRE', attributes: { prediction: 3020 }, }, { - id: 1764, + id: '1764', from: 'TXL', to: 'BRI', attributes: { prediction: 1134 }, }, { - id: 1765, + id: '1765', from: 'ESB', to: 'BRU', attributes: { prediction: 2073 }, }, { - id: 1766, + id: '1766', from: 'PEK', to: 'BRU', attributes: { prediction: 5587 }, }, { - id: 1767, + id: '1767', from: 'PIZ', to: 'BRW', attributes: { prediction: 275 }, }, { - id: 1768, + id: '1768', from: 'FAI', to: 'BTI', attributes: { prediction: 337 }, }, { - id: 1769, + id: '1769', from: 'AHO', to: 'BVA', attributes: { prediction: 1524 }, }, { - id: 1770, + id: '1770', from: 'MAN', to: 'BVC', attributes: { prediction: 764 }, }, { - id: 1771, + id: '1771', from: 'BEU', to: 'BVI', attributes: { prediction: 127 }, }, { - id: 1772, + id: '1772', from: 'BWI', to: 'COS', attributes: { prediction: 137 }, }, { - id: 1773, + id: '1773', from: 'BNA', to: 'DFW', attributes: { prediction: 28305 }, }, { - id: 1774, + id: '1774', from: 'JAC', to: 'DFW', attributes: { prediction: 3384 }, }, { - id: 1775, + id: '1775', from: 'NCE', to: 'DJE', attributes: { prediction: 457 }, }, { - id: 1776, + id: '1776', from: 'BTK', to: 'DME', attributes: { prediction: 1664 }, }, { - id: 1777, + id: '1777', from: 'LIS', to: 'DME', attributes: { prediction: 3434 }, }, { - id: 1778, + id: '1778', from: 'AHB', to: 'DMM', attributes: { prediction: 2979 }, }, { - id: 1779, + id: '1779', from: 'CAN', to: 'DOH', attributes: { prediction: 5508 }, }, { - id: 1780, + id: '1780', from: 'DTW', to: 'CHO', attributes: { prediction: 1237 }, }, { - id: 1781, + id: '1781', from: 'BUF', to: 'CLT', attributes: { prediction: 13687 }, }, { - id: 1782, + id: '1782', from: 'SHJ', to: 'CMB', attributes: { prediction: 5233 }, }, { - id: 1783, + id: '1783', from: 'CGR', to: 'CMG', attributes: { prediction: 753 }, }, { - id: 1784, + id: '1784', from: 'RAK', to: 'CMN', attributes: { prediction: 13513 }, }, { - id: 1785, + id: '1785', from: 'TIP', to: 'CMN', attributes: { prediction: 4264 }, }, { - id: 1786, + id: '1786', from: 'PSA', to: 'CND', attributes: { prediction: 1701 }, }, { - id: 1787, + id: '1787', from: 'UDI', to: 'CNF', attributes: { prediction: 2397 }, }, { - id: 1788, + id: '1788', from: 'TIM', to: 'DPS', attributes: { prediction: 2485 }, }, { - id: 1789, + id: '1789', from: 'CFU', to: 'DRS', attributes: { prediction: 1468 }, }, { - id: 1790, + id: '1790', from: 'BCN', to: 'DTM', attributes: { prediction: 2132 }, }, { - id: 1791, + id: '1791', from: 'HGH', to: 'CSX', attributes: { prediction: 9834 }, }, { - id: 1792, + id: '1792', from: 'CUR', to: 'CTG', attributes: { prediction: 289 }, }, { - id: 1793, + id: '1793', from: 'XMN', to: 'CTU', attributes: { prediction: 7401 }, }, { - id: 1794, + id: '1794', from: 'GYE', to: 'CUE', attributes: { prediction: 5908 }, }, { - id: 1795, + id: '1795', from: 'CLJ', to: 'CUF', attributes: { prediction: 1954 }, }, { - id: 1796, + id: '1796', from: 'MEX', to: 'CUL', attributes: { prediction: 16187 }, }, { - id: 1797, + id: '1797', from: 'TLC', to: 'CUN', attributes: { prediction: 17845 }, }, { - id: 1798, + id: '1798', from: 'DAY', to: 'CVG', attributes: { prediction: 53 }, }, { - id: 1799, + id: '1799', from: 'YWH', to: 'CXH', attributes: { prediction: 1807 }, }, { - id: 1800, + id: '1800', from: 'BET', to: 'CYF', attributes: { prediction: 620 }, }, { - id: 1801, + id: '1801', from: 'TRI', to: 'DAY', attributes: { prediction: 47 }, }, { - id: 1802, + id: '1802', from: 'GRB', to: 'DEN', attributes: { prediction: 1004 }, }, { - id: 1803, + id: '1803', from: 'GRR', to: 'DEN', attributes: { prediction: 1915 }, }, { - id: 1804, + id: '1804', from: 'MEM', to: 'DEN', attributes: { prediction: 6799 }, }, { - id: 1805, + id: '1805', from: 'MSN', to: 'DTW', attributes: { prediction: 14830 }, }, { - id: 1806, + id: '1806', from: 'ORD', to: 'DTW', attributes: { prediction: 39367 }, }, { - id: 1807, + id: '1807', from: 'SFO', to: 'DTW', attributes: { prediction: 17960 }, }, { - id: 1808, + id: '1808', from: 'FKB', to: 'DUB', attributes: { prediction: 2189 }, }, { - id: 1809, + id: '1809', from: 'IBZ', to: 'DUB', attributes: { prediction: 1987 }, }, { - id: 1810, + id: '1810', from: 'JER', to: 'DUB', attributes: { prediction: 1935 }, }, { - id: 1811, + id: '1811', from: 'DRS', to: 'DUS', attributes: { prediction: 18533 }, }, { - id: 1812, + id: '1812', from: 'FRU', to: 'DME', attributes: { prediction: 1344 }, }, { - id: 1813, + id: '1813', from: 'FRA', to: 'DMM', attributes: { prediction: 633 }, }, { - id: 1814, + id: '1814', from: 'KTM', to: 'DMM', attributes: { prediction: 2011 }, }, { - id: 1815, + id: '1815', from: 'IAD', to: 'DOH', attributes: { prediction: 8733 }, }, { - id: 1816, + id: '1816', from: 'FRA', to: 'FLL', attributes: { prediction: 1977 }, }, { - id: 1817, + id: '1817', from: 'SJO', to: 'FLL', attributes: { prediction: 4195 }, }, { - id: 1818, + id: '1818', from: 'GVA', to: 'FLR', attributes: { prediction: 1105 }, }, { - id: 1819, + id: '1819', from: 'ASM', to: 'DXB', attributes: { prediction: 1160 }, }, { - id: 1820, + id: '1820', from: 'CDG', to: 'DXB', attributes: { prediction: 28635 }, }, { - id: 1821, + id: '1821', from: 'FRU', to: 'DXB', attributes: { prediction: 593 }, }, { - id: 1822, + id: '1822', from: 'OTP', to: 'DXB', attributes: { prediction: 1187 }, }, { - id: 1823, + id: '1823', from: 'ASR', to: 'ECN', attributes: { prediction: 901 }, }, { - id: 1824, + id: '1824', from: 'BOH', to: 'EDI', attributes: { prediction: 5670 }, }, { - id: 1825, + id: '1825', from: 'ORK', to: 'EMA', attributes: { prediction: 2301 }, }, { - id: 1826, + id: '1826', from: 'ANF', to: 'ESR', attributes: { prediction: 781 }, }, { - id: 1827, + id: '1827', from: 'EDI', to: 'EWR', attributes: { prediction: 8784 }, }, { - id: 1828, + id: '1828', from: 'LIT', to: 'EWR', attributes: { prediction: 1351 }, }, { - id: 1829, + id: '1829', from: 'SPU', to: 'FRA', attributes: { prediction: 3637 }, }, { - id: 1830, + id: '1830', from: 'WDH', to: 'FRA', attributes: { prediction: 7368 }, }, { - id: 1831, + id: '1831', from: 'PRG', to: 'FRL', attributes: { prediction: 1332 }, }, { - id: 1832, + id: '1832', from: 'WRO', to: 'DTM', attributes: { prediction: 2426 }, }, { - id: 1833, + id: '1833', from: 'MDT', to: 'DTW', attributes: { prediction: 5372 }, }, { - id: 1834, + id: '1834', from: 'MAD', to: 'HAV', attributes: { prediction: 14391 }, }, { - id: 1835, + id: '1835', from: 'FRA', to: 'HEL', attributes: { prediction: 22037 }, }, { - id: 1836, + id: '1836', from: 'ATH', to: 'HER', attributes: { prediction: 53075 }, }, { - id: 1837, + id: '1837', from: 'PRG', to: 'HER', attributes: { prediction: 5028 }, }, { - id: 1838, + id: '1838', from: 'MIA', to: 'GHB', attributes: { prediction: 509 }, }, { - id: 1839, + id: '1839', from: 'TRE', to: 'GLA', attributes: { prediction: 504 }, }, { - id: 1840, + id: '1840', from: 'LPL', to: 'GNB', attributes: { prediction: 706 }, }, { - id: 1841, + id: '1841', from: 'CLE', to: 'GRB', attributes: { prediction: 2424 }, }, { - id: 1842, + id: '1842', from: 'LPL', to: 'GRO', attributes: { prediction: 2858 }, }, { - id: 1843, + id: '1843', from: 'MKE', to: 'GRR', attributes: { prediction: 3330 }, }, { - id: 1844, + id: '1844', from: 'CDG', to: 'GVA', attributes: { prediction: 37883 }, }, { - id: 1845, + id: '1845', from: 'DUB', to: 'GVA', attributes: { prediction: 4724 }, }, { - id: 1846, + id: '1846', from: 'HIR', to: 'GZO', attributes: { prediction: 845 }, }, { - id: 1847, + id: '1847', from: 'STN', to: 'GZT', attributes: { prediction: 1274 }, }, { - id: 1848, + id: '1848', from: 'TOS', to: 'HAA', attributes: { prediction: 552 }, }, { - id: 1849, + id: '1849', from: 'CAN', to: 'HAK', attributes: { prediction: 22209 }, }, { - id: 1850, + id: '1850', from: 'CTU', to: 'HAK', attributes: { prediction: 5808 }, }, { - id: 1851, + id: '1851', from: 'LGW', to: 'HAM', attributes: { prediction: 6849 }, }, { - id: 1852, + id: '1852', from: 'MAH', to: 'HAM', attributes: { prediction: 660 }, }, { - id: 1853, + id: '1853', from: 'NUE', to: 'HAM', attributes: { prediction: 18349 }, }, { - id: 1854, + id: '1854', from: 'BGO', to: 'HAU', attributes: { prediction: 997 }, }, { - id: 1855, + id: '1855', from: 'HAK', to: 'HGH', attributes: { prediction: 3166 }, }, { - id: 1856, + id: '1856', from: 'SOF', to: 'HHN', attributes: { prediction: 2218 }, }, { - id: 1857, + id: '1857', from: 'CGO', to: 'HKG', attributes: { prediction: 1694 }, }, { - id: 1858, + id: '1858', from: 'GUM', to: 'HKG', attributes: { prediction: 810 }, }, { - id: 1859, + id: '1859', from: 'JFK', to: 'DUB', attributes: { prediction: 24051 }, }, { - id: 1860, + id: '1860', from: 'ACE', to: 'DUS', attributes: { prediction: 3405 }, }, { - id: 1861, + id: '1861', from: 'VVI', to: 'EZE', attributes: { prediction: 6533 }, }, { - id: 1862, + id: '1862', from: 'TIJ', to: 'LAP', attributes: { prediction: 5124 }, }, { - id: 1863, + id: '1863', from: 'LIT', to: 'LAS', attributes: { prediction: 3333 }, }, { - id: 1864, + id: '1864', from: 'FRA', to: 'LAX', attributes: { prediction: 17561 }, }, { - id: 1865, + id: '1865', from: 'XNA', to: 'LAX', attributes: { prediction: 1131 }, }, { - id: 1866, + id: '1866', from: 'DAM', to: 'LCA', attributes: { prediction: 1507 }, }, { - id: 1867, + id: '1867', from: 'BKK', to: 'ICN', attributes: { prediction: 49214 }, }, { - id: 1868, + id: '1868', from: 'KKJ', to: 'ICN', attributes: { prediction: 2078 }, }, { - id: 1869, + id: '1869', from: 'MAD', to: 'ICN', attributes: { prediction: 3227 }, }, { - id: 1870, + id: '1870', from: 'TLV', to: 'ICN', attributes: { prediction: 3361 }, }, { - id: 1871, + id: '1871', from: 'IAD', to: 'ICT', attributes: { prediction: 141 }, }, { - id: 1872, + id: '1872', from: 'OMA', to: 'ICT', attributes: { prediction: 116 }, }, { - id: 1873, + id: '1873', from: 'ANC', to: 'ILI', attributes: { prediction: 409 }, }, { - id: 1874, + id: '1874', from: 'KNK', to: 'ILI', attributes: { prediction: 59 }, }, { - id: 1875, + id: '1875', from: 'UET', to: 'ISB', attributes: { prediction: 3932 }, }, { - id: 1876, + id: '1876', from: 'NAV', to: 'IST', attributes: { prediction: 7381 }, }, { - id: 1877, + id: '1877', from: 'HOU', to: 'JAN', attributes: { prediction: 8787 }, }, { - id: 1878, + id: '1878', from: 'CFC', to: 'JCB', attributes: { prediction: 396 }, }, { - id: 1879, + id: '1879', from: 'TUN', to: 'JED', attributes: { prediction: 3057 }, }, { - id: 1880, + id: '1880', from: 'MAN', to: 'JER', attributes: { prediction: 7579 }, }, { - id: 1881, + id: '1881', from: 'BDA', to: 'JFK', attributes: { prediction: 8595 }, }, { - id: 1882, + id: '1882', from: 'FEG', to: 'LED', attributes: { prediction: 736 }, }, { - id: 1883, + id: '1883', from: 'TRN', to: 'LUX', attributes: { prediction: 927 }, }, { - id: 1884, + id: '1884', from: 'KOE', to: 'LWE', attributes: { prediction: 598 }, }, { - id: 1885, + id: '1885', from: 'MAD', to: 'LYS', attributes: { prediction: 10718 }, }, { - id: 1886, + id: '1886', from: 'CMB', to: 'MAA', attributes: { prediction: 25877 }, }, { - id: 1887, + id: '1887', from: 'EAS', to: 'MAD', attributes: { prediction: 11635 }, }, { - id: 1888, + id: '1888', from: 'SDR', to: 'MAD', attributes: { prediction: 21012 }, }, { - id: 1889, + id: '1889', from: 'TXL', to: 'MAD', attributes: { prediction: 10314 }, }, { - id: 1890, + id: '1890', from: 'ABQ', to: 'MAF', attributes: { prediction: 2609 }, }, { - id: 1891, + id: '1891', from: 'WAT', to: 'LTN', attributes: { prediction: 3754 }, }, { - id: 1892, + id: '1892', from: 'FUE', to: 'LUX', attributes: { prediction: 552 }, }, { - id: 1893, + id: '1893', from: 'LEI', to: 'LUX', attributes: { prediction: 196 }, }, { - id: 1894, + id: '1894', from: 'WRL', to: 'LWT', attributes: { prediction: 418 }, }, { - id: 1895, + id: '1895', from: 'MCT', to: 'MAA', attributes: { prediction: 7102 }, }, { - id: 1896, + id: '1896', from: 'EMK', to: 'KSM', attributes: { prediction: 334 }, }, { - id: 1897, + id: '1897', from: 'BOM', to: 'KTM', attributes: { prediction: 1862 }, }, { - id: 1898, + id: '1898', from: 'MLE', to: 'KUL', attributes: { prediction: 2798 }, }, { - id: 1899, + id: '1899', from: 'CVG', to: 'LAS', attributes: { prediction: 6576 }, }, { - id: 1900, + id: '1900', from: 'DTW', to: 'LAS', attributes: { prediction: 32964 }, }, { - id: 1901, + id: '1901', from: 'PSP', to: 'LAS', attributes: { prediction: 1987 }, }, { - id: 1902, + id: '1902', from: 'BRU', to: 'LBA', attributes: { prediction: 1784 }, }, { - id: 1903, + id: '1903', from: 'GDN', to: 'LBC', attributes: { prediction: 3360 }, }, { - id: 1904, + id: '1904', from: 'URC', to: 'LBD', attributes: { prediction: 615 }, }, { - id: 1905, + id: '1905', from: 'GRX', to: 'MAD', attributes: { prediction: 18097 }, }, { - id: 1906, + id: '1906', from: 'DLA', to: 'LFW', attributes: { prediction: 1638 }, }, { - id: 1907, + id: '1907', from: 'ORF', to: 'LGA', attributes: { prediction: 7860 }, }, { - id: 1908, + id: '1908', from: 'LAX', to: 'LGB', attributes: { prediction: 10 }, }, { - id: 1909, + id: '1909', from: 'PMI', to: 'LIL', attributes: { prediction: 501 }, }, { - id: 1910, + id: '1910', from: 'DXB', to: 'LOS', attributes: { prediction: 21345 }, }, { - id: 1911, + id: '1911', from: 'BGY', to: 'LPL', attributes: { prediction: 2821 }, }, { - id: 1912, + id: '1912', from: 'SPC', to: 'MAN', attributes: { prediction: 709 }, }, { - id: 1913, + id: '1913', from: 'JFK', to: 'MCI', attributes: { prediction: 2034 }, }, { - id: 1914, + id: '1914', from: 'BKG', to: 'MCO', attributes: { prediction: 343 }, }, { - id: 1915, + id: '1915', from: 'EYW', to: 'MCO', attributes: { prediction: 1733 }, }, { - id: 1916, + id: '1916', from: 'BOB', to: 'MAU', attributes: { prediction: 81 }, }, { - id: 1917, + id: '1917', from: 'BOI', to: 'MSP', attributes: { prediction: 5531 }, }, { - id: 1918, + id: '1918', from: 'OKC', to: 'MSP', attributes: { prediction: 3812 }, }, { - id: 1919, + id: '1919', from: 'IAH', to: 'MSY', attributes: { prediction: 38380 }, }, { - id: 1920, + id: '1920', from: 'PKU', to: 'MES', attributes: { prediction: 4478 }, }, { - id: 1921, + id: '1921', from: 'VER', to: 'MEX', attributes: { prediction: 20266 }, }, { - id: 1922, + id: '1922', from: 'YYZ', to: 'MEX', attributes: { prediction: 10107 }, }, { - id: 1923, + id: '1923', from: 'GND', to: 'MIA', attributes: { prediction: 1212 }, }, { - id: 1924, + id: '1924', from: 'VKO', to: 'MJZ', attributes: { prediction: 1312 }, }, { - id: 1925, + id: '1925', from: 'CDG', to: 'MLA', attributes: { prediction: 3496 }, }, { - id: 1926, + id: '1926', from: 'EDI', to: 'MLA', attributes: { prediction: 1548 }, }, { - id: 1927, + id: '1927', from: 'DFW', to: 'MLI', attributes: { prediction: 2339 }, }, { - id: 1928, + id: '1928', from: 'MUC', to: 'MRS', attributes: { prediction: 9292 }, }, { - id: 1929, + id: '1929', from: 'LAX', to: 'MRY', attributes: { prediction: 7067 }, }, { - id: 1930, + id: '1930', from: 'DEA', to: 'MUX', attributes: { prediction: 190 }, }, { - id: 1931, + id: '1931', from: 'JMK', to: 'MXP', attributes: { prediction: 4272 }, }, { - id: 1932, + id: '1932', from: 'RIX', to: 'MXP', attributes: { prediction: 4444 }, }, { - id: 1933, + id: '1933', from: 'VLC', to: 'MXP', attributes: { prediction: 2529 }, }, { - id: 1934, + id: '1934', from: 'HYD', to: 'NAG', attributes: { prediction: 966 }, }, { - id: 1935, + id: '1935', from: 'IAD', to: 'MCO', attributes: { prediction: 38122 }, }, { - id: 1936, + id: '1936', from: 'HYD', to: 'MCT', attributes: { prediction: 5591 }, }, { - id: 1937, + id: '1937', from: 'ORB', to: 'MMX', attributes: { prediction: 76 }, }, { - id: 1938, + id: '1938', from: 'TUG', to: 'MNL', attributes: { prediction: 4319 }, }, { - id: 1939, + id: '1939', from: 'VNX', to: 'MPM', attributes: { prediction: 231 }, }, { - id: 1940, + id: '1940', from: 'AXU', to: 'MQX', attributes: { prediction: 178 }, }, { - id: 1941, + id: '1941', from: 'FLL', to: 'PTY', attributes: { prediction: 1496 }, }, { - id: 1942, + id: '1942', from: 'SVQ', to: 'ORY', attributes: { prediction: 13458 }, }, { - id: 1943, + id: '1943', from: 'PUS', to: 'NGO', attributes: { prediction: 3430 }, }, { - id: 1944, + id: '1944', from: 'GDN', to: 'NRN', attributes: { prediction: 2437 }, }, { - id: 1945, + id: '1945', from: 'MXP', to: 'NUE', attributes: { prediction: 3242 }, }, { - id: 1946, + id: '1946', from: 'GCI', to: 'NWI', attributes: { prediction: 284 }, }, { - id: 1947, + id: '1947', from: 'FMM', to: 'NYO', attributes: { prediction: 3026 }, }, { - id: 1948, + id: '1948', from: 'IAH', to: 'OKC', attributes: { prediction: 12792 }, }, { - id: 1949, + id: '1949', from: 'TNC', to: 'OME', attributes: { prediction: 152 }, }, { - id: 1950, + id: '1950', from: 'BOD', to: 'OPO', attributes: { prediction: 2099 }, }, { - id: 1951, + id: '1951', from: 'ABQ', to: 'ORD', attributes: { prediction: 9524 }, }, { - id: 1952, + id: '1952', from: 'FLL', to: 'ORD', attributes: { prediction: 16675 }, }, { - id: 1953, + id: '1953', from: 'ZRH', to: 'ORD', attributes: { prediction: 5760 }, }, { - id: 1954, + id: '1954', from: 'IAH', to: 'ORF', attributes: { prediction: 2770 }, }, { - id: 1955, + id: '1955', from: 'PSA', to: 'OSL', attributes: { prediction: 1749 }, }, { - id: 1956, + id: '1956', from: 'TOY', to: 'PVG', attributes: { prediction: 996 }, }, { - id: 1957, + id: '1957', from: 'HNL', to: 'SFO', attributes: { prediction: 43885 }, }, { - id: 1958, + id: '1958', from: 'LIH', to: 'SFO', attributes: { prediction: 7815 }, }, { - id: 1959, + id: '1959', from: 'AKL', to: 'SIN', attributes: { prediction: 10983 }, }, { - id: 1960, + id: '1960', from: 'CMB', to: 'SIN', attributes: { prediction: 21683 }, }, { - id: 1961, + id: '1961', from: 'MEL', to: 'SIN', attributes: { prediction: 41472 }, }, { - id: 1962, + id: '1962', from: 'MCO', to: 'PNS', attributes: { prediction: 1086 }, }, { - id: 1963, + id: '1963', from: 'KPB', to: 'PPV', attributes: { prediction: 0 }, }, { - id: 1964, + id: '1964', from: 'RHO', to: 'PRG', attributes: { prediction: 4173 }, }, { - id: 1965, + id: '1965', from: 'TIA', to: 'PSR', attributes: { prediction: 1830 }, }, { - id: 1966, + id: '1966', from: 'EZE', to: 'PUJ', attributes: { prediction: 753 }, }, { - id: 1967, + id: '1967', from: 'BWI', to: 'PVD', attributes: { prediction: 30951 }, }, { - id: 1968, + id: '1968', from: 'ZRH', to: 'PVG', attributes: { prediction: 5144 }, }, { - id: 1969, + id: '1969', from: 'GDL', to: 'SJD', attributes: { prediction: 6516 }, }, { - id: 1970, + id: '1970', from: 'DOM', to: 'SJU', attributes: { prediction: 2657 }, }, { - id: 1971, + id: '1971', from: 'CZS', to: 'RBR', attributes: { prediction: 2219 }, }, { - id: 1972, + id: '1972', from: 'WLH', to: 'RCL', attributes: { prediction: 95 }, }, { - id: 1973, + id: '1973', from: 'SFO', to: 'RDD', attributes: { prediction: 2358 }, }, { - id: 1974, + id: '1974', from: 'SZB', to: 'RDN', attributes: { prediction: 2665 }, }, { - id: 1975, + id: '1975', from: 'LAS', to: 'RDU', attributes: { prediction: 3866 }, }, { - id: 1976, + id: '1976', from: 'BSB', to: 'REC', attributes: { prediction: 29232 }, }, { - id: 1977, + id: '1977', from: 'KGD', to: 'RIX', attributes: { prediction: 2004 }, }, { - id: 1978, + id: '1978', from: 'BWI', to: 'ROC', attributes: { prediction: 5534 }, }, { - id: 1979, + id: '1979', from: 'SYD', to: 'ROT', attributes: { prediction: 887 }, }, { - id: 1980, + id: '1980', from: 'FNT', to: 'RSW', attributes: { prediction: 3234 }, }, { - id: 1981, + id: '1981', from: 'HKG', to: 'RUH', attributes: { prediction: 5937 }, }, { - id: 1982, + id: '1982', from: 'NYO', to: 'RYG', attributes: { prediction: 10048 }, }, { - id: 1983, + id: '1983', from: 'TSF', to: 'RYG', attributes: { prediction: 2457 }, }, { - id: 1984, + id: '1984', from: 'HOD', to: 'SAH', attributes: { prediction: 2786 }, }, { - id: 1985, + id: '1985', from: 'AUS', to: 'SAN', attributes: { prediction: 6560 }, }, { - id: 1986, + id: '1986', from: 'HPB', to: 'SCM', attributes: { prediction: 128 }, }, { - id: 1987, + id: '1987', from: 'EVN', to: 'SCO', attributes: { prediction: 440 }, }, { - id: 1988, + id: '1988', from: 'MUC', to: 'SKG', attributes: { prediction: 12690 }, }, { - id: 1989, + id: '1989', from: 'ANC', to: 'SNP', attributes: { prediction: 486 }, }, { - id: 1990, + id: '1990', from: 'LAS', to: 'SGF', attributes: { prediction: 2731 }, }, { - id: 1991, + id: '1991', from: 'XIY', to: 'SHE', attributes: { prediction: 4194 }, }, { - id: 1992, + id: '1992', from: 'CCU', to: 'SIN', attributes: { prediction: 4105 }, }, { - id: 1993, + id: '1993', from: 'HET', to: 'SZX', attributes: { prediction: 1500 }, }, { - id: 1994, + id: '1994', from: 'TZX', to: 'TBS', attributes: { prediction: 740 }, }, { - id: 1995, + id: '1995', from: 'VLI', to: 'TGH', attributes: { prediction: 72 }, }, { - id: 1996, + id: '1996', from: 'MAN', to: 'SOF', attributes: { prediction: 1329 }, }, { - id: 1997, + id: '1997', from: 'VIE', to: 'SPU', attributes: { prediction: 3706 }, }, { - id: 1998, + id: '1998', from: 'PEG', to: 'STN', attributes: { prediction: 2143 }, }, { - id: 1999, + id: '1999', from: 'BGO', to: 'SXF', attributes: { prediction: 1079 }, }, { - id: 2000, + id: '2000', from: 'KIN', to: 'SXM', attributes: { prediction: 2002 }, }, { - id: 2001, + id: '2001', from: 'SKB', to: 'SXM', attributes: { prediction: 2440 }, }, { - id: 2002, + id: '2002', from: 'BRU', to: 'TLS', attributes: { prediction: 6064 }, }, { - id: 2003, + id: '2003', from: 'CAN', to: 'TNA', attributes: { prediction: 10335 }, }, { - id: 2004, + id: '2004', from: 'ACY', to: 'TPA', attributes: { prediction: 3434 }, }, { - id: 2005, + id: '2005', from: 'CSX', to: 'TPE', attributes: { prediction: 2927 }, }, { - id: 2006, + id: '2006', from: 'PJM', to: 'SJO', attributes: { prediction: 1116 }, }, { - id: 2007, + id: '2007', from: 'CTU', to: 'SJW', attributes: { prediction: 4952 }, }, { - id: 2008, + id: '2008', from: 'NKG', to: 'SJW', attributes: { prediction: 388 }, }, { - id: 2009, + id: '2009', from: 'OVD', to: 'VLC', attributes: { prediction: 1639 }, }, { - id: 2010, + id: '2010', from: 'MQP', to: 'VNX', attributes: { prediction: 557 }, }, { - id: 2011, + id: '2011', from: 'XIY', to: 'TYN', attributes: { prediction: 4993 }, }, { - id: 2012, + id: '2012', from: 'CPH', to: 'UAK', attributes: { prediction: 741 }, }, { - id: 2013, + id: '2013', from: 'CNF', to: 'UDI', attributes: { prediction: 2518 }, }, { - id: 2014, + id: '2014', from: 'GWD', to: 'UET', attributes: { prediction: 192 }, }, { - id: 2015, + id: '2015', from: 'PBJ', to: 'ULB', attributes: { prediction: 9 }, }, { - id: 2016, + id: '2016', from: 'KDI', to: 'UPG', attributes: { prediction: 12569 }, }, { - id: 2017, + id: '2017', from: 'NRK', to: 'VBY', attributes: { prediction: 798 }, }, { - id: 2018, + id: '2018', from: 'RMI', to: 'VIE', attributes: { prediction: 1120 }, }, { - id: 2019, + id: '2019', from: 'BTK', to: 'VKO', attributes: { prediction: 1341 }, }, { - id: 2020, + id: '2020', from: 'WAG', to: 'WLG', attributes: { prediction: 257 }, }, { - id: 2021, + id: '2021', from: 'YGK', to: 'YYZ', attributes: { prediction: 3502 }, }, { - id: 2022, + id: '2022', from: 'LIS', to: 'ZAG', attributes: { prediction: 1702 }, }, { - id: 2023, + id: '2023', from: 'LAX', to: 'ZCL', attributes: { prediction: 3387 }, }, { - id: 2024, + id: '2024', from: 'ZTB', to: 'ZLT', attributes: { prediction: 102 }, }, { - id: 2025, + id: '2025', from: 'AKL', to: 'ZQN', attributes: { prediction: 20501 }, }, { - id: 2026, + id: '2026', from: 'DTW', to: 'APN', attributes: { prediction: 1517 }, }, { - id: 2027, + id: '2027', from: 'YYZ', to: 'YQG', attributes: { prediction: 4966 }, }, { - id: 2028, + id: '2028', from: 'YQD', to: 'YWG', attributes: { prediction: 1332 }, }, { - id: 2029, + id: '2029', from: 'YVR', to: 'YXY', attributes: { prediction: 11588 }, }, { - id: 2030, + id: '2030', from: 'YYJ', to: 'YYZ', attributes: { prediction: 9649 }, }, { - id: 2031, + id: '2031', from: 'ATL', to: 'ZRH', attributes: { prediction: 5593 }, }, { - id: 2032, + id: '2032', from: 'JFK', to: 'ZRH', attributes: { prediction: 21969 }, }, { - id: 2033, + id: '2033', from: 'MIA', to: 'ZRH', attributes: { prediction: 5615 }, }, { - id: 2034, + id: '2034', from: 'MJT', to: 'ATH', attributes: { prediction: 16124 }, }, { - id: 2035, + id: '2035', from: 'MLA', to: 'ATH', attributes: { prediction: 1084 }, }, { - id: 2036, + id: '2036', from: 'MYR', to: 'ATL', attributes: { prediction: 16946 }, }, { - id: 2037, + id: '2037', from: 'PUJ', to: 'ATL', attributes: { prediction: 3797 }, }, { - id: 2038, + id: '2038', from: 'BOG', to: 'AUC', attributes: { prediction: 2561 }, }, { - id: 2039, + id: '2039', from: 'DAC', to: 'AUH', attributes: { prediction: 9076 }, }, { - id: 2040, + id: '2040', from: 'SIN', to: 'AUH', attributes: { prediction: 9835 }, }, { - id: 2041, + id: '2041', from: 'FRA', to: 'BLQ', attributes: { prediction: 12169 }, }, { - id: 2042, + id: '2042', from: 'IXE', to: 'BLR', attributes: { prediction: 5440 }, }, { - id: 2043, + id: '2043', from: 'DAD', to: 'BMV', attributes: { prediction: 678 }, }, { - id: 2044, + id: '2044', from: 'KUL', to: 'BNE', attributes: { prediction: 2293 }, }, { - id: 2045, + id: '2045', from: 'RVK', to: 'BNN', attributes: { prediction: 486 }, }, { - id: 2046, + id: '2046', from: 'DTW', to: 'AMS', attributes: { prediction: 30707 }, }, { - id: 2047, + id: '2047', from: 'SNP', to: 'ANC', attributes: { prediction: 337 }, }, { - id: 2048, + id: '2048', from: 'CPO', to: 'ANF', attributes: { prediction: 304 }, }, { - id: 2049, + id: '2049', from: 'JFK', to: 'ANU', attributes: { prediction: 2380 }, }, { - id: 2050, + id: '2050', from: 'RHO', to: 'AOK', attributes: { prediction: 2809 }, }, { - id: 2051, + id: '2051', from: 'LYC', to: 'ARN', attributes: { prediction: 2793 }, }, { - id: 2052, + id: '2052', from: 'WAW', to: 'ARN', attributes: { prediction: 4265 }, }, { - id: 2053, + id: '2053', from: 'LRS', to: 'ATH', attributes: { prediction: 952 }, }, { - id: 2054, + id: '2054', from: 'PHL', to: 'ATH', attributes: { prediction: 5024 }, }, { - id: 2055, + id: '2055', from: 'BOG', to: 'ATL', attributes: { prediction: 5099 }, }, { - id: 2056, + id: '2056', from: 'BUF', to: 'ATL', attributes: { prediction: 29953 }, }, { - id: 2057, + id: '2057', from: 'GSO', to: 'ATL', attributes: { prediction: 13038 }, }, { - id: 2058, + id: '2058', from: 'VPS', to: 'ATL', attributes: { prediction: 14139 }, }, { - id: 2059, + id: '2059', from: 'CLT', to: 'AUA', attributes: { prediction: 6063 }, }, { - id: 2060, + id: '2060', from: 'VLN', to: 'AUA', attributes: { prediction: 1220 }, }, { - id: 2061, + id: '2061', from: 'CDG', to: 'AUH', attributes: { prediction: 14701 }, }, { - id: 2062, + id: '2062', from: 'DAC', to: 'AUH', attributes: { prediction: 9968 }, }, { - id: 2063, + id: '2063', from: 'VUP', to: 'BOG', attributes: { prediction: 6729 }, }, { - id: 2064, + id: '2064', from: 'SMF', to: 'BOI', attributes: { prediction: 1608 }, }, { - id: 2065, + id: '2065', from: 'SAH', to: 'BAH', attributes: { prediction: 5791 }, }, { - id: 2066, + id: '2066', from: 'MRV', to: 'BAX', attributes: { prediction: 820 }, }, { - id: 2067, + id: '2067', from: 'BFS', to: 'BCN', attributes: { prediction: 4790 }, }, { - id: 2068, + id: '2068', from: 'OTP', to: 'BEG', attributes: { prediction: 554 }, }, { - id: 2069, + id: '2069', from: 'CAI', to: 'BEN', attributes: { prediction: 3931 }, }, { - id: 2070, + id: '2070', from: 'FCO', to: 'BGO', attributes: { prediction: 1411 }, }, { - id: 2071, + id: '2071', from: 'BDS', to: 'BGY', attributes: { prediction: 5619 }, }, { - id: 2072, + id: '2072', from: 'KTM', to: 'BHR', attributes: { prediction: 310 }, }, { - id: 2073, + id: '2073', from: 'LXR', to: 'BHX', attributes: { prediction: 806 }, }, { - id: 2074, + id: '2074', from: 'SDY', to: 'BIL', attributes: { prediction: 427 }, }, { - id: 2075, + id: '2075', from: 'ORY', to: 'BIQ', attributes: { prediction: 27474 }, }, { - id: 2076, + id: '2076', from: 'ACC', to: 'BJL', attributes: { prediction: 3053 }, }, { - id: 2077, + id: '2077', from: 'LAX', to: 'BJX', attributes: { prediction: 3247 }, }, { - id: 2078, + id: '2078', from: 'MIR', to: 'BRS', attributes: { prediction: 589 }, }, { - id: 2079, + id: '2079', from: 'BBU', to: 'BRU', attributes: { prediction: 2894 }, }, { - id: 2080, + id: '2080', from: 'CAI', to: 'BRU', attributes: { prediction: 3414 }, }, { - id: 2081, + id: '2081', from: 'WST', to: 'BID', attributes: { prediction: 304 }, }, { - id: 2082, + id: '2082', from: 'LHR', to: 'BIO', attributes: { prediction: 4534 }, }, { - id: 2083, + id: '2083', from: 'DEN', to: 'BIS', attributes: { prediction: 4657 }, }, { - id: 2084, + id: '2084', from: 'PNK', to: 'CGK', attributes: { prediction: 20827 }, }, { - id: 2085, + id: '2085', from: 'CAI', to: 'CGN', attributes: { prediction: 1375 }, }, { - id: 2086, + id: '2086', from: 'VLC', to: 'CGN', attributes: { prediction: 3881 }, }, { - id: 2087, + id: '2087', from: 'TPE', to: 'CGO', attributes: { prediction: 2048 }, }, { - id: 2088, + id: '2088', from: 'CRL', to: 'CIA', attributes: { prediction: 16381 }, }, { - id: 2089, + id: '2089', from: 'WRO', to: 'BVA', attributes: { prediction: 1335 }, }, { - id: 2090, + id: '2090', from: 'MEM', to: 'BWI', attributes: { prediction: 5961 }, }, { - id: 2091, + id: '2091', from: 'EMA', to: 'BZG', attributes: { prediction: 1512 }, }, { - id: 2092, + id: '2092', from: 'HHN', to: 'CAG', attributes: { prediction: 1444 }, }, { - id: 2093, + id: '2093', from: 'BKK', to: 'CAN', attributes: { prediction: 35016 }, }, { - id: 2094, + id: '2094', from: 'NKG', to: 'CAN', attributes: { prediction: 25641 }, }, { - id: 2095, + id: '2095', from: 'FRA', to: 'CCS', attributes: { prediction: 8525 }, }, { - id: 2096, + id: '2096', from: 'DIB', to: 'CCU', attributes: { prediction: 5837 }, }, { - id: 2097, + id: '2097', from: 'NAG', to: 'CCU', attributes: { prediction: 3513 }, }, { - id: 2098, + id: '2098', from: 'DTW', to: 'CDG', attributes: { prediction: 7351 }, }, { - id: 2099, + id: '2099', from: 'HKG', to: 'CDG', attributes: { prediction: 29316 }, }, { - id: 2100, + id: '2100', from: 'KRK', to: 'CDG', attributes: { prediction: 4716 }, }, { - id: 2101, + id: '2101', from: 'KJA', to: 'CEK', attributes: { prediction: 656 }, }, { - id: 2102, + id: '2102', from: 'AVP', to: 'CLT', attributes: { prediction: 1982 }, }, { - id: 2103, + id: '2103', from: 'JED', to: 'CMB', attributes: { prediction: 3261 }, }, { - id: 2104, + id: '2104', from: 'ACK', to: 'DCA', attributes: { prediction: 1258 }, }, { - id: 2105, + id: '2105', from: 'KHI', to: 'DEL', attributes: { prediction: 383 }, }, { - id: 2106, + id: '2106', from: 'BNA', to: 'DEN', attributes: { prediction: 24716 }, }, { - id: 2107, + id: '2107', from: 'CLT', to: 'DEN', attributes: { prediction: 21670 }, }, { - id: 2108, + id: '2108', from: 'BGW', to: 'EBL', attributes: { prediction: 2293 }, }, { - id: 2109, + id: '2109', from: 'LIG', to: 'EDI', attributes: { prediction: 303 }, }, { - id: 2110, + id: '2110', from: 'EGN', to: 'ELF', attributes: { prediction: 372 }, }, { - id: 2111, + id: '2111', from: 'OME', to: 'ELI', attributes: { prediction: 157 }, }, { - id: 2112, + id: '2112', from: 'GRK', to: 'DFW', attributes: { prediction: 11361 }, }, { - id: 2113, + id: '2113', from: 'LHR', to: 'CPT', attributes: { prediction: 14966 }, }, { - id: 2114, + id: '2114', from: 'CTU', to: 'CSX', attributes: { prediction: 16785 }, }, { - id: 2115, + id: '2115', from: 'PER', to: 'CVQ', attributes: { prediction: 815 }, }, { - id: 2116, + id: '2116', from: 'GRU', to: 'CWB', attributes: { prediction: 55908 }, }, { - id: 2117, + id: '2117', from: 'CCU', to: 'DAC', attributes: { prediction: 10389 }, }, { - id: 2118, + id: '2118', from: 'BGW', to: 'DAM', attributes: { prediction: 3244 }, }, { - id: 2119, + id: '2119', from: 'PVD', to: 'DCA', attributes: { prediction: 9705 }, }, { - id: 2120, + id: '2120', from: 'ZRH', to: 'DEL', attributes: { prediction: 4441 }, }, { - id: 2121, + id: '2121', from: 'LBF', to: 'DEN', attributes: { prediction: 969 }, }, { - id: 2122, + id: '2122', from: 'MTY', to: 'DFW', attributes: { prediction: 13098 }, }, { - id: 2123, + id: '2123', from: 'TPA', to: 'DFW', attributes: { prediction: 27429 }, }, { - id: 2124, + id: '2124', from: 'YYZ', to: 'DFW', attributes: { prediction: 16162 }, }, { - id: 2125, + id: '2125', from: 'ESB', to: 'DIY', attributes: { prediction: 6590 }, }, { - id: 2126, + id: '2126', from: 'JNU', to: 'ELV', attributes: { prediction: 11 }, }, { - id: 2127, + id: '2127', from: 'BUD', to: 'EMA', attributes: { prediction: 1686 }, }, { - id: 2128, + id: '2128', from: 'TPA', to: 'EWR', attributes: { prediction: 26060 }, }, { - id: 2129, + id: '2129', from: 'CWL', to: 'GLA', attributes: { prediction: 3764 }, }, { - id: 2130, + id: '2130', from: 'LAS', to: 'GRI', attributes: { prediction: 1028 }, }, { - id: 2131, + id: '2131', from: 'GOT', to: 'DUS', attributes: { prediction: 2946 }, }, { - id: 2132, + id: '2132', from: 'NAP', to: 'DUS', attributes: { prediction: 1912 }, }, { - id: 2133, + id: '2133', from: 'BBO', to: 'DXB', attributes: { prediction: 451 }, }, { - id: 2134, + id: '2134', from: 'SFO', to: 'DXB', attributes: { prediction: 9233 }, }, { - id: 2135, + id: '2135', from: 'IST', to: 'DYU', attributes: { prediction: 1068 }, }, { - id: 2136, + id: '2136', from: 'HOU', to: 'ELP', attributes: { prediction: 8825 }, }, { - id: 2137, + id: '2137', from: 'STR', to: 'ESB', attributes: { prediction: 2094 }, }, { - id: 2138, + id: '2138', from: 'ATL', to: 'EWR', attributes: { prediction: 57613 }, }, { - id: 2139, + id: '2139', from: 'SFB', to: 'GSO', attributes: { prediction: 1350 }, }, { - id: 2140, + id: '2140', from: 'CTS', to: 'GUM', attributes: { prediction: 1070 }, }, { - id: 2141, + id: '2141', from: 'DBV', to: 'FCO', attributes: { prediction: 2176 }, }, { - id: 2142, + id: '2142', from: 'VCE', to: 'FCO', attributes: { prediction: 36910 }, }, { - id: 2143, + id: '2143', from: 'REC', to: 'FEN', attributes: { prediction: 5379 }, }, { - id: 2144, + id: '2144', from: 'CAP', to: 'FLL', attributes: { prediction: 96 }, }, { - id: 2145, + id: '2145', from: 'CTG', to: 'FLL', attributes: { prediction: 3617 }, }, { - id: 2146, + id: '2146', from: 'CLE', to: 'FNT', attributes: { prediction: 2386 }, }, { - id: 2147, + id: '2147', from: 'CMN', to: 'FRA', attributes: { prediction: 7091 }, }, { - id: 2148, + id: '2148', from: 'VRA', to: 'FRA', attributes: { prediction: 2914 }, }, { - id: 2149, + id: '2149', from: 'LGW', to: 'FRL', attributes: { prediction: 1108 }, }, { - id: 2150, + id: '2150', from: 'MSP', to: 'FSD', attributes: { prediction: 10049 }, }, { - id: 2151, + id: '2151', from: 'BCN', to: 'FUE', attributes: { prediction: 1518 }, }, { - id: 2152, + id: '2152', from: 'FMO', to: 'FUE', attributes: { prediction: 744 }, }, { - id: 2153, + id: '2153', from: 'CAI', to: 'GVA', attributes: { prediction: 4511 }, }, { - id: 2154, + id: '2154', from: 'CPH', to: 'HAJ', attributes: { prediction: 1616 }, }, { - id: 2155, + id: '2155', from: 'KSN', to: 'HAJ', attributes: { prediction: 556 }, }, { - id: 2156, + id: '2156', from: 'MAH', to: 'HAM', attributes: { prediction: 648 }, }, { - id: 2157, + id: '2157', from: 'TLS', to: 'HAM', attributes: { prediction: 2385 }, }, { - id: 2158, + id: '2158', from: 'BOG', to: 'EZE', attributes: { prediction: 5817 }, }, { - id: 2159, + id: '2159', from: 'SVG', to: 'FAE', attributes: { prediction: 468 }, }, { - id: 2160, + id: '2160', from: 'LEJ', to: 'FAO', attributes: { prediction: 883 }, }, { - id: 2161, + id: '2161', from: 'DRT', to: 'IAH', attributes: { prediction: 1451 }, }, { - id: 2162, + id: '2162', from: 'LRD', to: 'IAH', attributes: { prediction: 4196 }, }, { - id: 2163, + id: '2163', from: 'DPS', to: 'ICN', attributes: { prediction: 12479 }, }, { - id: 2164, + id: '2164', from: 'KHV', to: 'ICN', attributes: { prediction: 3215 }, }, { - id: 2165, + id: '2165', from: 'KJA', to: 'IKT', attributes: { prediction: 2336 }, }, { - id: 2166, + id: '2166', from: 'SDQ', to: 'HAV', attributes: { prediction: 1793 }, }, { - id: 2167, + id: '2167', from: 'BRE', to: 'HDF', attributes: { prediction: 250 }, }, { - id: 2168, + id: '2168', from: 'LGW', to: 'HEL', attributes: { prediction: 3132 }, }, { - id: 2169, + id: '2169', from: 'LGW', to: 'HER', attributes: { prediction: 8612 }, }, { - id: 2170, + id: '2170', from: 'WWK', to: 'HGU', attributes: { prediction: 185 }, }, { - id: 2171, + id: '2171', from: 'BGY', to: 'HHN', attributes: { prediction: 8737 }, }, { - id: 2172, + id: '2172', from: 'PSA', to: 'HHN', attributes: { prediction: 5133 }, }, { - id: 2173, + id: '2173', from: 'CEB', to: 'HKG', attributes: { prediction: 10151 }, }, { - id: 2174, + id: '2174', from: 'USM', to: 'HKG', attributes: { prediction: 2535 }, }, { - id: 2175, + id: '2175', from: 'YNZ', to: 'HKG', attributes: { prediction: 784 }, }, { - id: 2176, + id: '2176', from: 'KIX', to: 'HND', attributes: { prediction: 65345 }, }, { - id: 2177, + id: '2177', from: 'SNA', to: 'HNL', attributes: { prediction: 3318 }, }, { - id: 2178, + id: '2178', from: 'PPT', to: 'HOI', attributes: { prediction: 408 }, }, { - id: 2179, + id: '2179', from: 'RDU', to: 'HPN', attributes: { prediction: 185 }, }, { - id: 2180, + id: '2180', from: 'DXB', to: 'HYD', attributes: { prediction: 28894 }, }, { - id: 2181, + id: '2181', from: 'ALB', to: 'IAD', attributes: { prediction: 5402 }, }, { - id: 2182, + id: '2182', from: 'YUL', to: 'IAD', attributes: { prediction: 8024 }, }, { - id: 2183, + id: '2183', from: 'BWI', to: 'ISP', attributes: { prediction: 15890 }, }, { - id: 2184, + id: '2184', from: 'BGW', to: 'IST', attributes: { prediction: 5104 }, }, { - id: 2185, + id: '2185', from: 'ORD', to: 'JAX', attributes: { prediction: 11170 }, }, { - id: 2186, + id: '2186', from: 'BOM', to: 'JDH', attributes: { prediction: 1351 }, }, { - id: 2187, + id: '2187', from: 'DXB', to: 'KRT', attributes: { prediction: 13195 }, }, { - id: 2188, + id: '2188', from: 'IQT', to: 'LIM', attributes: { prediction: 16243 }, }, { - id: 2189, + id: '2189', from: 'FCO', to: 'KRK', attributes: { prediction: 766 }, }, { - id: 2190, + id: '2190', from: 'NRN', to: 'KRK', attributes: { prediction: 2646 }, }, { - id: 2191, + id: '2191', from: 'KWF', to: 'KTN', attributes: { prediction: 64 }, }, { - id: 2192, + id: '2192', from: 'FLL', to: 'JFK', attributes: { prediction: 39185 }, }, { - id: 2193, + id: '2193', from: 'JED', to: 'JFK', attributes: { prediction: 1188 }, }, { - id: 2194, + id: '2194', from: 'MUC', to: 'JFK', attributes: { prediction: 5848 }, }, { - id: 2195, + id: '2195', from: 'VIE', to: 'JMK', attributes: { prediction: 639 }, }, { - id: 2196, + id: '2196', from: 'AXD', to: 'JSH', attributes: { prediction: 618 }, }, { - id: 2197, + id: '2197', from: 'DUS', to: 'JSI', attributes: { prediction: 381 }, }, { - id: 2198, + id: '2198', from: 'TLV', to: 'KBP', attributes: { prediction: 8512 }, }, { - id: 2199, + id: '2199', from: 'KCG', to: 'KCL', attributes: { prediction: 3 }, }, { - id: 2200, + id: '2200', from: 'FRA', to: 'KEF', attributes: { prediction: 8262 }, }, { - id: 2201, + id: '2201', from: 'SEA', to: 'KEF', attributes: { prediction: 3865 }, }, { - id: 2202, + id: '2202', from: 'FRA', to: 'KIX', attributes: { prediction: 7707 }, }, { - id: 2203, + id: '2203', from: 'ARN', to: 'KLR', attributes: { prediction: 3004 }, }, { - id: 2204, + id: '2204', from: 'BSD', to: 'KMG', attributes: { prediction: 1434 }, }, { - id: 2205, + id: '2205', from: 'FUK', to: 'KMI', attributes: { prediction: 13973 }, }, { - id: 2206, + id: '2206', from: 'ITM', to: 'KMJ', attributes: { prediction: 21316 }, }, { - id: 2207, + id: '2207', from: 'HEL', to: 'KUO', attributes: { prediction: 6326 }, }, { - id: 2208, + id: '2208', from: 'HEL', to: 'LIS', attributes: { prediction: 4970 }, }, { - id: 2209, + id: '2209', from: 'VCE', to: 'LIS', attributes: { prediction: 3691 }, }, { - id: 2210, + id: '2210', from: 'VLI', to: 'LNE', attributes: { prediction: 170 }, }, { - id: 2211, + id: '2211', from: 'CRL', to: 'LPA', attributes: { prediction: 2457 }, }, { - id: 2212, + id: '2212', from: 'CIA', to: 'LPL', attributes: { prediction: 2268 }, }, { - id: 2213, + id: '2213', from: 'MIA', to: 'LRM', attributes: { prediction: 777 }, }, { - id: 2214, + id: '2214', from: 'IAH', to: 'MEM', attributes: { prediction: 11341 }, }, { - id: 2215, + id: '2215', from: 'PDX', to: 'MFR', attributes: { prediction: 6831 }, }, { - id: 2216, + id: '2216', from: 'LAS', to: 'MHT', attributes: { prediction: 3592 }, }, { - id: 2217, + id: '2217', from: 'AUA', to: 'MIA', attributes: { prediction: 10076 }, }, { - id: 2218, + id: '2218', from: 'CDG', to: 'LFW', attributes: { prediction: 3669 }, }, { - id: 2219, + id: '2219', from: 'EIN', to: 'LGW', attributes: { prediction: 4250 }, }, { - id: 2220, + id: '2220', from: 'ARN', to: 'LHR', attributes: { prediction: 39159 }, }, { - id: 2221, + id: '2221', from: 'GIG', to: 'LHR', attributes: { prediction: 2698 }, }, { - id: 2222, + id: '2222', from: 'CPH', to: 'LIN', attributes: { prediction: 3116 }, }, { - id: 2223, + id: '2223', from: 'FNC', to: 'LIS', attributes: { prediction: 52941 }, }, { - id: 2224, + id: '2224', from: 'ORD', to: 'LIT', attributes: { prediction: 11071 }, }, { - id: 2225, + id: '2225', from: 'STN', to: 'LJU', attributes: { prediction: 4729 }, }, { - id: 2226, + id: '2226', from: 'DKR', to: 'LOS', attributes: { prediction: 1024 }, }, { - id: 2227, + id: '2227', from: 'DRS', to: 'LPA', attributes: { prediction: 738 }, }, { - id: 2228, + id: '2228', from: 'BRS', to: 'MJV', attributes: { prediction: 4719 }, }, { - id: 2229, + id: '2229', from: 'ROK', to: 'MKY', attributes: { prediction: 1346 }, }, { - id: 2230, + id: '2230', from: 'KTW', to: 'MMX', attributes: { prediction: 1891 }, }, { - id: 2231, + id: '2231', from: 'DTW', to: 'MSN', attributes: { prediction: 15408 }, }, { - id: 2232, + id: '2232', from: 'PFO', to: 'NCL', attributes: { prediction: 2566 }, }, { - id: 2233, + id: '2233', from: 'ITM', to: 'NGS', attributes: { prediction: 15533 }, }, { - id: 2234, + id: '2234', from: 'PVG', to: 'NGS', attributes: { prediction: 720 }, }, { - id: 2235, + id: '2235', from: 'WUH', to: 'NNG', attributes: { prediction: 3132 }, }, { - id: 2236, + id: '2236', from: 'SZZ', to: 'NRN', attributes: { prediction: 1655 }, }, { - id: 2237, + id: '2237', from: 'AUH', to: 'MEL', attributes: { prediction: 7428 }, }, { - id: 2238, + id: '2238', from: 'MFE', to: 'MEM', attributes: { prediction: 3723 }, }, { - id: 2239, + id: '2239', from: 'CLT', to: 'MEX', attributes: { prediction: 3977 }, }, { - id: 2240, + id: '2240', from: 'TIJ', to: 'MEX', attributes: { prediction: 41437 }, }, { - id: 2241, + id: '2241', from: 'KIH', to: 'MHD', attributes: { prediction: 841 }, }, { - id: 2242, + id: '2242', from: 'LUX', to: 'MIR', attributes: { prediction: 3942 }, }, { - id: 2243, + id: '2243', from: 'BLK', to: 'MJV', attributes: { prediction: 1890 }, }, { - id: 2244, + id: '2244', from: 'EDI', to: 'MJV', attributes: { prediction: 3217 }, }, { - id: 2245, + id: '2245', from: 'NCL', to: 'MJV', attributes: { prediction: 6389 }, }, { - id: 2246, + id: '2246', from: 'LAX', to: 'MKE', attributes: { prediction: 14819 }, }, { - id: 2247, + id: '2247', from: 'DUS', to: 'MLA', attributes: { prediction: 4557 }, }, { - id: 2248, + id: '2248', from: 'BIA', to: 'NTE', attributes: { prediction: 791 }, }, { - id: 2249, + id: '2249', from: 'GTF', to: 'MSP', attributes: { prediction: 4101 }, }, { - id: 2250, + id: '2250', from: 'FWA', to: 'MSY', attributes: { prediction: 40 }, }, { - id: 2251, + id: '2251', from: 'YYC', to: 'MUC', attributes: { prediction: 1289 }, }, { - id: 2252, + id: '2252', from: 'CGN', to: 'MXP', attributes: { prediction: 4757 }, }, { - id: 2253, + id: '2253', from: 'KBP', to: 'MXP', attributes: { prediction: 4426 }, }, { - id: 2254, + id: '2254', from: 'HTS', to: 'MYR', attributes: { prediction: 1078 }, }, { - id: 2255, + id: '2255', from: 'LBV', to: 'NBO', attributes: { prediction: 932 }, }, { - id: 2256, + id: '2256', from: 'POL', to: 'NBO', attributes: { prediction: 782 }, }, { - id: 2257, + id: '2257', from: 'BUR', to: 'OAK', attributes: { prediction: 35876 }, }, { - id: 2258, + id: '2258', from: 'ALB', to: 'OGS', attributes: { prediction: 727 }, }, { - id: 2259, + id: '2259', from: 'GVA', to: 'OLB', attributes: { prediction: 1955 }, }, { - id: 2260, + id: '2260', from: 'LGA', to: 'OMA', attributes: { prediction: 1452 }, }, { - id: 2261, + id: '2261', from: 'TFS', to: 'OPO', attributes: { prediction: 1344 }, }, { - id: 2262, + id: '2262', from: 'GRU', to: 'ORD', attributes: { prediction: 5155 }, }, { - id: 2263, + id: '2263', from: 'CDG', to: 'NDJ', attributes: { prediction: 3243 }, }, { - id: 2264, + id: '2264', from: 'ABR', to: 'PIR', attributes: { prediction: 642 }, }, { - id: 2265, + id: '2265', from: 'MIA', to: 'PLS', attributes: { prediction: 10410 }, }, { - id: 2266, + id: '2266', from: 'ORY', to: 'PMI', attributes: { prediction: 2974 }, }, { - id: 2267, + id: '2267', from: 'BIQ', to: 'ORY', attributes: { prediction: 26810 }, }, { - id: 2268, + id: '2268', from: 'PRG', to: 'OSL', attributes: { prediction: 11584 }, }, { - id: 2269, + id: '2269', from: 'RJK', to: 'OSL', attributes: { prediction: 1116 }, }, { - id: 2270, + id: '2270', from: 'FAO', to: 'PAD', attributes: { prediction: 701 }, }, { - id: 2271, + id: '2271', from: 'DSN', to: 'PEK', attributes: { prediction: 7266 }, }, { - id: 2272, + id: '2272', from: 'IAD', to: 'PEK', attributes: { prediction: 6573 }, }, { - id: 2273, + id: '2273', from: 'EWR', to: 'PHL', attributes: { prediction: 6001 }, }, { - id: 2274, + id: '2274', from: 'MAG', to: 'POM', attributes: { prediction: 5212 }, }, { - id: 2275, + id: '2275', from: 'BEY', to: 'PRG', attributes: { prediction: 6835 }, }, { - id: 2276, + id: '2276', from: 'BOJ', to: 'PRG', attributes: { prediction: 3868 }, }, { - id: 2277, + id: '2277', from: 'SMF', to: 'SAN', attributes: { prediction: 34073 }, }, { - id: 2278, + id: '2278', from: 'CLT', to: 'STL', attributes: { prediction: 12970 }, }, { - id: 2279, + id: '2279', from: 'GLA', to: 'STN', attributes: { prediction: 17472 }, }, { - id: 2280, + id: '2280', from: 'MKE', to: 'SDF', attributes: { prediction: 1671 }, }, { - id: 2281, + id: '2281', from: 'TSO', to: 'PZE', attributes: { prediction: 871 }, }, { - id: 2282, + id: '2282', from: 'VLC', to: 'RAK', attributes: { prediction: 152 }, }, { - id: 2283, + id: '2283', from: 'VER', to: 'REX', attributes: { prediction: 1264 }, }, { - id: 2284, + id: '2284', from: 'JFK', to: 'RIC', attributes: { prediction: 9547 }, }, { - id: 2285, + id: '2285', from: 'EMA', to: 'RIX', attributes: { prediction: 2646 }, }, { - id: 2286, + id: '2286', from: 'MUC', to: 'RIX', attributes: { prediction: 3401 }, }, { - id: 2287, + id: '2287', from: 'HIR', to: 'RNA', attributes: { prediction: 72 }, }, { - id: 2288, + id: '2288', from: 'OSL', to: 'RRS', attributes: { prediction: 1244 }, }, { - id: 2289, + id: '2289', from: 'ORD', to: 'RST', attributes: { prediction: 5730 }, }, { - id: 2290, + id: '2290', from: 'MIA', to: 'RTB', attributes: { prediction: 466 }, }, { - id: 2291, + id: '2291', from: 'LGW', to: 'RTM', attributes: { prediction: 7433 }, }, { - id: 2292, + id: '2292', from: 'EVN', to: 'RTW', attributes: { prediction: 188 }, }, { - id: 2293, + id: '2293', from: 'EAM', to: 'RUH', attributes: { prediction: 3269 }, }, { - id: 2294, + id: '2294', from: 'MEX', to: 'SAL', attributes: { prediction: 4910 }, }, { - id: 2295, + id: '2295', from: 'AZA', to: 'SAT', attributes: { prediction: 255 }, }, { - id: 2296, + id: '2296', from: 'DFW', to: 'SAT', attributes: { prediction: 51702 }, }, { - id: 2297, + id: '2297', from: 'FRA', to: 'SAW', attributes: { prediction: 12066 }, }, { - id: 2298, + id: '2298', from: 'KIX', to: 'SEA', attributes: { prediction: 5387 }, }, { - id: 2299, + id: '2299', from: 'SKG', to: 'STR', attributes: { prediction: 11490 }, }, { - id: 2300, + id: '2300', from: 'WAW', to: 'SVG', attributes: { prediction: 1188 }, }, { - id: 2301, + id: '2301', from: 'TLL', to: 'SVO', attributes: { prediction: 1681 }, }, { - id: 2302, + id: '2302', from: 'FLL', to: 'SWF', attributes: { prediction: 3755 }, }, { - id: 2303, + id: '2303', from: 'TLS', to: 'SXB', attributes: { prediction: 4806 }, }, { - id: 2304, + id: '2304', from: 'STR', to: 'SXF', attributes: { prediction: 13091 }, }, { - id: 2305, + id: '2305', from: 'DXB', to: 'SXR', attributes: { prediction: 649 }, }, { - id: 2306, + id: '2306', from: 'BLQ', to: 'TPS', attributes: { prediction: 8516 }, }, { - id: 2307, + id: '2307', from: 'LTN', to: 'TPS', attributes: { prediction: 1650 }, }, { - id: 2308, + id: '2308', from: 'DUB', to: 'TRF', attributes: { prediction: 4606 }, }, { - id: 2309, + id: '2309', from: 'BRU', to: 'TRN', attributes: { prediction: 3503 }, }, { - id: 2310, + id: '2310', from: 'DMM', to: 'TRV', attributes: { prediction: 882 }, }, { - id: 2311, + id: '2311', from: 'SEA', to: 'TUS', attributes: { prediction: 3790 }, }, { - id: 2312, + id: '2312', from: 'CLY', to: 'TXL', attributes: { prediction: 601 }, }, { - id: 2313, + id: '2313', from: 'LAX', to: 'SMF', attributes: { prediction: 34362 }, }, { - id: 2314, + id: '2314', from: 'LAS', to: 'SMX', attributes: { prediction: 923 }, }, { - id: 2315, + id: '2315', from: 'YYZ', to: 'SNU', attributes: { prediction: 3294 }, }, { - id: 2316, + id: '2316', from: 'SZG', to: 'SOU', attributes: { prediction: 374 }, }, { - id: 2317, + id: '2317', from: 'TXL', to: 'SPC', attributes: { prediction: 826 }, }, { - id: 2318, + id: '2318', from: 'ABQ', to: 'STL', attributes: { prediction: 3600 }, }, { - id: 2319, + id: '2319', from: 'KDV', to: 'SUV', attributes: { prediction: 515 }, }, { - id: 2320, + id: '2320', from: 'ATH', to: 'SVO', attributes: { prediction: 6409 }, }, { - id: 2321, + id: '2321', from: 'TLL', to: 'SVO', attributes: { prediction: 1611 }, }, { - id: 2322, + id: '2322', from: 'UUS', to: 'SVO', attributes: { prediction: 10577 }, }, { - id: 2323, + id: '2323', from: 'DME', to: 'SVX', attributes: { prediction: 33056 }, }, { - id: 2324, + id: '2324', from: 'IAH', to: 'TYS', attributes: { prediction: 5075 }, }, { - id: 2325, + id: '2325', from: 'BSB', to: 'UDI', attributes: { prediction: 1018 }, }, { - id: 2326, + id: '2326', from: 'JFK', to: 'SYR', attributes: { prediction: 15385 }, }, { - id: 2327, + id: '2327', from: 'TSN', to: 'SZX', attributes: { prediction: 10317 }, }, { - id: 2328, + id: '2328', from: 'VGO', to: 'TFS', attributes: { prediction: 711 }, }, { - id: 2329, + id: '2329', from: 'LJU', to: 'TGD', attributes: { prediction: 1419 }, }, { - id: 2330, + id: '2330', from: 'PVG', to: 'TIJ', attributes: { prediction: 1892 }, }, { - id: 2331, + id: '2331', from: 'OSL', to: 'TLL', attributes: { prediction: 6345 }, }, { - id: 2332, + id: '2332', from: 'CMN', to: 'TLS', attributes: { prediction: 5982 }, }, { - id: 2333, + id: '2333', from: 'HAM', to: 'TLS', attributes: { prediction: 2361 }, }, { - id: 2334, + id: '2334', from: 'LIL', to: 'TLS', attributes: { prediction: 5779 }, }, { - id: 2335, + id: '2335', from: 'LIS', to: 'TLS', attributes: { prediction: 4605 }, }, { - id: 2336, + id: '2336', from: 'DME', to: 'TLV', attributes: { prediction: 23214 }, }, { - id: 2337, + id: '2337', from: 'GRU', to: 'TLV', attributes: { prediction: 3028 }, }, { - id: 2338, + id: '2338', from: 'LCA', to: 'TLV', attributes: { prediction: 4854 }, }, { - id: 2339, + id: '2339', from: 'XIY', to: 'TNA', attributes: { prediction: 4764 }, }, { - id: 2340, + id: '2340', from: 'AUS', to: 'TPA', attributes: { prediction: 3673 }, }, { - id: 2341, + id: '2341', from: 'PBI', to: 'TPA', attributes: { prediction: 10482 }, }, { - id: 2342, + id: '2342', from: 'HKT', to: 'TPE', attributes: { prediction: 933 }, }, { - id: 2343, + id: '2343', from: 'BMA', to: 'UME', attributes: { prediction: 6882 }, }, { - id: 2344, + id: '2344', from: 'TBG', to: 'UNG', attributes: { prediction: 698 }, }, { - id: 2345, + id: '2345', from: 'CAG', to: 'VCE', attributes: { prediction: 7794 }, }, { - id: 2346, + id: '2346', from: 'DBV', to: 'VIE', attributes: { prediction: 5711 }, }, { - id: 2347, + id: '2347', from: 'DLM', to: 'VIE', attributes: { prediction: 647 }, }, { - id: 2348, + id: '2348', from: 'LGW', to: 'VIE', attributes: { prediction: 13592 }, }, { - id: 2349, + id: '2349', from: 'LIN', to: 'VIE', attributes: { prediction: 2274 }, }, { - id: 2350, + id: '2350', from: 'PEK', to: 'SYX', attributes: { prediction: 12927 }, }, { - id: 2351, + id: '2351', from: 'YEV', to: 'YOC', attributes: { prediction: 125 }, }, { - id: 2352, + id: '2352', from: 'EWR', to: 'YQB', attributes: { prediction: 5188 }, }, { - id: 2353, + id: '2353', from: 'YXN', to: 'YRT', attributes: { prediction: 252 }, }, { - id: 2354, + id: '2354', from: 'MAN', to: 'YVR', attributes: { prediction: 3179 }, }, { - id: 2355, + id: '2355', from: 'ZRH', to: 'VIE', attributes: { prediction: 41013 }, }, { - id: 2356, + id: '2356', from: 'CRL', to: 'VLL', attributes: { prediction: 4158 }, }, { - id: 2357, + id: '2357', from: 'TLL', to: 'VNO', attributes: { prediction: 3625 }, }, { - id: 2358, + id: '2358', from: 'PAZ', to: 'VSA', attributes: { prediction: 1623 }, }, { - id: 2359, + id: '2359', from: 'BGY', to: 'WRO', attributes: { prediction: 2389 }, }, { - id: 2360, + id: '2360', from: 'HGU', to: 'WWK', attributes: { prediction: 148 }, }, { - id: 2361, + id: '2361', from: 'IAH', to: 'XNA', attributes: { prediction: 4932 }, }, { - id: 2362, + id: '2362', from: 'XIY', to: 'XNN', attributes: { prediction: 5572 }, }, { - id: 2363, + id: '2363', from: 'YXL', to: 'YAC', attributes: { prediction: 513 }, }, { - id: 2364, + id: '2364', from: 'YRL', to: 'YHD', attributes: { prediction: 494 }, }, { - id: 2365, + id: '2365', from: 'ZLT', to: 'YIF', attributes: { prediction: 182 }, }, { - id: 2366, + id: '2366', from: 'YVR', to: 'YXC', attributes: { prediction: 2470 }, }, { - id: 2367, + id: '2367', from: 'ABE', to: 'YYZ', attributes: { prediction: 754 }, }, { - id: 2368, + id: '2368', from: 'ISB', to: 'YYZ', attributes: { prediction: 1490 }, }, { - id: 2369, + id: '2369', from: 'BOS', to: 'BGR', attributes: { prediction: 214 }, }, { - id: 2370, + id: '2370', from: 'BHX', to: 'BHD', attributes: { prediction: 13388 }, }, { - id: 2371, + id: '2371', from: 'STR', to: 'BIA', attributes: { prediction: 732 }, }, { - id: 2372, + id: '2372', from: 'AZA', to: 'BIS', attributes: { prediction: 820 }, }, { - id: 2373, + id: '2373', from: 'KOE', to: 'BJW', attributes: { prediction: 524 }, }, { - id: 2374, + id: '2374', from: 'FNA', to: 'ACC', attributes: { prediction: 2322 }, }, { - id: 2375, + id: '2375', from: 'VIE', to: 'ACE', attributes: { prediction: 1035 }, }, { - id: 2376, + id: '2376', from: 'CTG', to: 'ADZ', attributes: { prediction: 3534 }, }, { - id: 2377, + id: '2377', from: 'PIK', to: 'AGP', attributes: { prediction: 3402 }, }, { - id: 2378, + id: '2378', from: 'SVO', to: 'AGP', attributes: { prediction: 2722 }, }, { - id: 2379, + id: '2379', from: 'URC', to: 'AKU', attributes: { prediction: 2891 }, }, { - id: 2380, + id: '2380', from: 'KYP', to: 'AKY', attributes: { prediction: 55 }, }, { - id: 2381, + id: '2381', from: 'ART', to: 'ALB', attributes: { prediction: 627 }, }, { - id: 2382, + id: '2382', from: 'YYZ', to: 'ALB', attributes: { prediction: 1142 }, }, { - id: 2383, + id: '2383', from: 'SVG', to: 'ALC', attributes: { prediction: 1083 }, }, { - id: 2384, + id: '2384', from: 'ZRH', to: 'ALC', attributes: { prediction: 2301 }, }, { - id: 2385, + id: '2385', from: 'MUC', to: 'AMM', attributes: { prediction: 916 }, }, { - id: 2386, + id: '2386', from: 'TLV', to: 'AMM', attributes: { prediction: 4695 }, }, { - id: 2387, + id: '2387', from: 'DUB', to: 'AMS', attributes: { prediction: 25571 }, }, { - id: 2388, + id: '2388', from: 'JFK', to: 'AMS', attributes: { prediction: 22213 }, }, { - id: 2389, + id: '2389', from: 'SGN', to: 'BKK', attributes: { prediction: 30496 }, }, { - id: 2390, + id: '2390', from: 'DAM', to: 'BUD', attributes: { prediction: 3164 }, }, { - id: 2391, + id: '2391', from: 'PMI', to: 'BUD', attributes: { prediction: 300 }, }, { - id: 2392, + id: '2392', from: 'CLE', to: 'BUF', attributes: { prediction: 3711 }, }, { - id: 2393, + id: '2393', from: 'AKL', to: 'BWN', attributes: { prediction: 2407 }, }, { - id: 2394, + id: '2394', from: 'KUL', to: 'BWN', attributes: { prediction: 6868 }, }, { - id: 2395, + id: '2395', from: 'DUB', to: 'BZG', attributes: { prediction: 2186 }, }, { - id: 2396, + id: '2396', from: 'FCO', to: 'CCS', attributes: { prediction: 5616 }, }, { - id: 2397, + id: '2397', from: 'LGA', to: 'BTV', attributes: { prediction: 4951 }, }, { - id: 2398, + id: '2398', from: 'SKP', to: 'BUD', attributes: { prediction: 4106 }, }, { - id: 2399, + id: '2399', from: 'SLC', to: 'BZN', attributes: { prediction: 6321 }, }, { - id: 2400, + id: '2400', from: 'BBU', to: 'BCN', attributes: { prediction: 4067 }, }, { - id: 2401, + id: '2401', from: 'CMN', to: 'BCN', attributes: { prediction: 9685 }, }, { - id: 2402, + id: '2402', from: 'MEX', to: 'BCN', attributes: { prediction: 1333 }, }, { - id: 2403, + id: '2403', from: 'BNE', to: 'BDB', attributes: { prediction: 3488 }, }, { - id: 2404, + id: '2404', from: 'YYZ', to: 'BDL', attributes: { prediction: 2918 }, }, { - id: 2405, + id: '2405', from: 'TPS', to: 'BDS', attributes: { prediction: 2192 }, }, { - id: 2406, + id: '2406', from: 'MAO', to: 'BEL', attributes: { prediction: 12738 }, }, { - id: 2407, + id: '2407', from: 'CDG', to: 'BES', attributes: { prediction: 8396 }, }, { - id: 2408, + id: '2408', from: 'JFK', to: 'CAI', attributes: { prediction: 13307 }, }, { - id: 2409, + id: '2409', from: 'TSV', to: 'CBR', attributes: { prediction: 1468 }, }, { - id: 2410, + id: '2410', from: 'AUH', to: 'CCJ', attributes: { prediction: 4802 }, }, { - id: 2411, + id: '2411', from: 'FRA', to: 'BLL', attributes: { prediction: 7858 }, }, { - id: 2412, + id: '2412', from: 'PHE', to: 'BME', attributes: { prediction: 138 }, }, { - id: 2413, + id: '2413', from: 'UIB', to: 'BOG', attributes: { prediction: 1690 }, }, { - id: 2414, + id: '2414', from: 'GRO', to: 'BOH', attributes: { prediction: 2332 }, }, { - id: 2415, + id: '2415', from: 'DAC', to: 'BOM', attributes: { prediction: 4538 }, }, { - id: 2416, + id: '2416', from: 'ICN', to: 'BOM', attributes: { prediction: 2645 }, }, { - id: 2417, + id: '2417', from: 'ZRH', to: 'BOS', attributes: { prediction: 6201 }, }, { - id: 2418, + id: '2418', from: 'SSA', to: 'BPS', attributes: { prediction: 7696 }, }, { - id: 2419, + id: '2419', from: 'HAM', to: 'BRI', attributes: { prediction: 1178 }, }, { - id: 2420, + id: '2420', from: 'MXP', to: 'BRI', attributes: { prediction: 19439 }, }, { - id: 2421, + id: '2421', from: 'TPS', to: 'BRI', attributes: { prediction: 1514 }, }, { - id: 2422, + id: '2422', from: 'MAN', to: 'BRU', attributes: { prediction: 9759 }, }, { - id: 2423, + id: '2423', from: 'PMI', to: 'BRU', attributes: { prediction: 539 }, }, { - id: 2424, + id: '2424', from: 'FAI', to: 'BRW', attributes: { prediction: 2654 }, }, { - id: 2425, + id: '2425', from: 'HER', to: 'BSL', attributes: { prediction: 2479 }, }, { - id: 2426, + id: '2426', from: 'TRV', to: 'CCJ', attributes: { prediction: 622 }, }, { - id: 2427, + id: '2427', from: 'DUB', to: 'CDG', attributes: { prediction: 33434 }, }, { - id: 2428, + id: '2428', from: 'KUL', to: 'CDG', attributes: { prediction: 7822 }, }, { - id: 2429, + id: '2429', from: 'OZC', to: 'CEB', attributes: { prediction: 2447 }, }, { - id: 2430, + id: '2430', from: 'BKK', to: 'CEI', attributes: { prediction: 19202 }, }, { - id: 2431, + id: '2431', from: 'DFW', to: 'CDG', attributes: { prediction: 5656 }, }, { - id: 2432, + id: '2432', from: 'PUF', to: 'CDG', attributes: { prediction: 11771 }, }, { - id: 2433, + id: '2433', from: 'CRK', to: 'CEB', attributes: { prediction: 1361 }, }, { - id: 2434, + id: '2434', from: 'KUN', to: 'CRL', attributes: { prediction: 2457 }, }, { - id: 2435, + id: '2435', from: 'ACA', to: 'CRP', attributes: { prediction: 30 }, }, { - id: 2436, + id: '2436', from: 'ZRH', to: 'CTA', attributes: { prediction: 2083 }, }, { - id: 2437, + id: '2437', from: 'RIS', to: 'CTS', attributes: { prediction: 1876 }, }, { - id: 2438, + id: '2438', from: 'SJW', to: 'CTU', attributes: { prediction: 4457 }, }, { - id: 2439, + id: '2439', from: 'TIA', to: 'CGN', attributes: { prediction: 732 }, }, { - id: 2440, + id: '2440', from: 'CAN', to: 'CGO', attributes: { prediction: 10471 }, }, { - id: 2441, + id: '2441', from: 'GRO', to: 'CIA', attributes: { prediction: 11877 }, }, { - id: 2442, + id: '2442', from: 'CJU', to: 'CJJ', attributes: { prediction: 17156 }, }, { - id: 2443, + id: '2443', from: 'BNA', to: 'CLE', attributes: { prediction: 7238 }, }, { - id: 2444, + id: '2444', from: 'MBJ', to: 'CLT', attributes: { prediction: 8988 }, }, { - id: 2445, + id: '2445', from: 'STT', to: 'CLT', attributes: { prediction: 4830 }, }, { - id: 2446, + id: '2446', from: 'AGP', to: 'CMN', attributes: { prediction: 1725 }, }, { - id: 2447, + id: '2447', from: 'EWR', to: 'CPH', attributes: { prediction: 12005 }, }, { - id: 2448, + id: '2448', from: 'VNO', to: 'CPH', attributes: { prediction: 11198 }, }, { - id: 2449, + id: '2449', from: 'YYZ', to: 'CZM', attributes: { prediction: 373 }, }, { - id: 2450, + id: '2450', from: 'DXB', to: 'DAC', attributes: { prediction: 25557 }, }, { - id: 2451, + id: '2451', from: 'ZNZ', to: 'DAR', attributes: { prediction: 5956 }, }, { - id: 2452, + id: '2452', from: 'BUD', to: 'CFU', attributes: { prediction: 446 }, }, { - id: 2453, + id: '2453', from: 'CGN', to: 'CPH', attributes: { prediction: 3144 }, }, { - id: 2454, + id: '2454', from: 'JNB', to: 'CPT', attributes: { prediction: 164691 }, }, { - id: 2455, + id: '2455', from: 'PGF', to: 'CRL', attributes: { prediction: 1332 }, }, { - id: 2456, + id: '2456', from: 'EMA', to: 'GCI', attributes: { prediction: 1824 }, }, { - id: 2457, + id: '2457', from: 'NDR', to: 'DUS', attributes: { prediction: 1371 }, }, { - id: 2458, + id: '2458', from: 'ORD', to: 'DUS', attributes: { prediction: 6154 }, }, { - id: 2459, + id: '2459', from: 'CUU', to: 'DFW', attributes: { prediction: 2198 }, }, { - id: 2460, + id: '2460', from: 'LBB', to: 'DFW', attributes: { prediction: 11064 }, }, { - id: 2461, + id: '2461', from: 'ABJ', to: 'DKR', attributes: { prediction: 5033 }, }, { - id: 2462, + id: '2462', from: 'VLI', to: 'DLY', attributes: { prediction: 33 }, }, { - id: 2463, + id: '2463', from: 'BAX', to: 'DME', attributes: { prediction: 6138 }, }, { - id: 2464, + id: '2464', from: 'BAH', to: 'DMM', attributes: { prediction: 5938 }, }, { - id: 2465, + id: '2465', from: 'CGK', to: 'DOH', attributes: { prediction: 7177 }, }, { - id: 2466, + id: '2466', from: 'SKG', to: 'DRS', attributes: { prediction: 786 }, }, { - id: 2467, + id: '2467', from: 'IST', to: 'DTM', attributes: { prediction: 674 }, }, { - id: 2468, + id: '2468', from: 'TOL', to: 'DTW', attributes: { prediction: 2097 }, }, { - id: 2469, + id: '2469', from: 'CPT', to: 'DUR', attributes: { prediction: 37541 }, }, { - id: 2470, + id: '2470', from: 'GPA', to: 'DUS', attributes: { prediction: 847 }, }, { - id: 2471, + id: '2471', from: 'LKO', to: 'DXB', attributes: { prediction: 2660 }, }, { - id: 2472, + id: '2472', from: 'PHX', to: 'GEG', attributes: { prediction: 5109 }, }, { - id: 2473, + id: '2473', from: 'CVQ', to: 'GET', attributes: { prediction: 297 }, }, { - id: 2474, + id: '2474', from: 'LIM', to: 'GIG', attributes: { prediction: 2090 }, }, { - id: 2475, + id: '2475', from: 'HAC', to: 'HND', attributes: { prediction: 9368 }, }, { - id: 2476, + id: '2476', from: 'MMY', to: 'HND', attributes: { prediction: 3128 }, }, { - id: 2477, + id: '2477', from: 'SYD', to: 'HBA', attributes: { prediction: 18349 }, }, { - id: 2478, + id: '2478', from: 'CGN', to: 'HDF', attributes: { prediction: 200 }, }, { - id: 2479, + id: '2479', from: 'ALC', to: 'HEL', attributes: { prediction: 772 }, }, { - id: 2480, + id: '2480', from: 'KEM', to: 'HEL', attributes: { prediction: 6931 }, }, { - id: 2481, + id: '2481', from: 'TKU', to: 'HEL', attributes: { prediction: 4164 }, }, { - id: 2482, + id: '2482', from: 'LCA', to: 'HER', attributes: { prediction: 2405 }, }, { - id: 2483, + id: '2483', from: 'TSN', to: 'HET', attributes: { prediction: 1307 }, }, { - id: 2484, + id: '2484', from: 'NRT', to: 'HGH', attributes: { prediction: 1456 }, }, { - id: 2485, + id: '2485', from: 'TAO', to: 'HGH', attributes: { prediction: 3388 }, }, { - id: 2486, + id: '2486', from: 'KIX', to: 'HKD', attributes: { prediction: 2511 }, }, { - id: 2487, + id: '2487', from: 'JFK', to: 'HKG', attributes: { prediction: 15981 }, }, { - id: 2488, + id: '2488', from: 'MEL', to: 'HKG', attributes: { prediction: 31598 }, }, { - id: 2489, + id: '2489', from: 'WNZ', to: 'HKG', attributes: { prediction: 2281 }, }, { - id: 2490, + id: '2490', from: 'GDL', to: 'HMO', attributes: { prediction: 6773 }, }, { - id: 2491, + id: '2491', from: 'AKL', to: 'HNL', attributes: { prediction: 2120 }, }, { - id: 2492, + id: '2492', from: 'OGG', to: 'HNL', attributes: { prediction: 56268 }, }, { - id: 2493, + id: '2493', from: 'NAP', to: 'FCO', attributes: { prediction: 12893 }, }, { - id: 2494, + id: '2494', from: 'REC', to: 'FEN', attributes: { prediction: 4437 }, }, { - id: 2495, + id: '2495', from: 'ATL', to: 'FLL', attributes: { prediction: 92677 }, }, { - id: 2496, + id: '2496', from: 'LGW', to: 'FLR', attributes: { prediction: 7142 }, }, { - id: 2497, + id: '2497', from: 'TIA', to: 'FLR', attributes: { prediction: 4313 }, }, { - id: 2498, + id: '2498', from: 'STN', to: 'FNC', attributes: { prediction: 3588 }, }, { - id: 2499, + id: '2499', from: 'RZE', to: 'FRA', attributes: { prediction: 1833 }, }, { - id: 2500, + id: '2500', from: 'SKG', to: 'FRA', attributes: { prediction: 6232 }, }, { - id: 2501, + id: '2501', from: 'SOF', to: 'FRL', attributes: { prediction: 2215 }, }, { - id: 2502, + id: '2502', from: 'REL', to: 'FTE', attributes: { prediction: 2756 }, }, { - id: 2503, + id: '2503', from: 'FLL', to: 'HPN', attributes: { prediction: 10531 }, }, { - id: 2504, + id: '2504', from: 'AYT', to: 'GLA', attributes: { prediction: 1004 }, }, { - id: 2505, + id: '2505', from: 'EWR', to: 'GLA', attributes: { prediction: 4705 }, }, { - id: 2506, + id: '2506', from: 'KUS', to: 'GOH', attributes: { prediction: 135 }, }, { - id: 2507, + id: '2507', from: 'EIN', to: 'GRO', attributes: { prediction: 5415 }, }, { - id: 2508, + id: '2508', from: 'KGS', to: 'GRZ', attributes: { prediction: 653 }, }, { - id: 2509, + id: '2509', from: 'DFW', to: 'GSP', attributes: { prediction: 4940 }, }, { - id: 2510, + id: '2510', from: 'DJE', to: 'GVA', attributes: { prediction: 1045 }, }, { - id: 2511, + id: '2511', from: 'ACE', to: 'HAJ', attributes: { prediction: 889 }, }, { - id: 2512, + id: '2512', from: 'MVY', to: 'HYA', attributes: { prediction: 229 }, }, { - id: 2513, + id: '2513', from: 'FRA', to: 'HYD', attributes: { prediction: 2296 }, }, { - id: 2514, + id: '2514', from: 'BRU', to: 'IAD', attributes: { prediction: 4868 }, }, { - id: 2515, + id: '2515', from: 'KWI', to: 'IAD', attributes: { prediction: 6332 }, }, { - id: 2516, + id: '2516', from: 'SAH', to: 'HOD', attributes: { prediction: 2293 }, }, { - id: 2517, + id: '2517', from: 'CVG', to: 'HOU', attributes: { prediction: 119 }, }, { - id: 2518, + id: '2518', from: 'VFA', to: 'HRE', attributes: { prediction: 810 }, }, { - id: 2519, + id: '2519', from: 'BOM', to: 'HYD', attributes: { prediction: 60215 }, }, { - id: 2520, + id: '2520', from: 'PHX', to: 'JFK', attributes: { prediction: 19740 }, }, { - id: 2521, + id: '2521', from: 'DXB', to: 'JNB', attributes: { prediction: 26022 }, }, { - id: 2522, + id: '2522', from: 'JAV', to: 'JQA', attributes: { prediction: 212 }, }, { - id: 2523, + id: '2523', from: 'RUH', to: 'KBL', attributes: { prediction: 1062 }, }, { - id: 2524, + id: '2524', from: 'HEL', to: 'KBP', attributes: { prediction: 3063 }, }, { - id: 2525, + id: '2525', from: 'UIO', to: 'IAH', attributes: { prediction: 3441 }, }, { - id: 2526, + id: '2526', from: 'MAH', to: 'IBZ', attributes: { prediction: 1546 }, }, { - id: 2527, + id: '2527', from: 'GOT', to: 'IST', attributes: { prediction: 2482 }, }, { - id: 2528, + id: '2528', from: 'KRT', to: 'IST', attributes: { prediction: 4081 }, }, { - id: 2529, + id: '2529', from: 'CCU', to: 'IXA', attributes: { prediction: 9314 }, }, { - id: 2530, + id: '2530', from: 'IXS', to: 'IXA', attributes: { prediction: 225 }, }, { - id: 2531, + id: '2531', from: 'DEN', to: 'JAC', attributes: { prediction: 16997 }, }, { - id: 2532, + id: '2532', from: 'KEF', to: 'JFK', attributes: { prediction: 10935 }, }, { - id: 2533, + id: '2533', from: 'NBO', to: 'KGL', attributes: { prediction: 6398 }, }, { - id: 2534, + id: '2534', from: 'MDL', to: 'KHM', attributes: { prediction: 290 }, }, { - id: 2535, + id: '2535', from: 'AXR', to: 'KKR', attributes: { prediction: 82 }, }, { - id: 2536, + id: '2536', from: 'MNL', to: 'KLO', attributes: { prediction: 22141 }, }, { - id: 2537, + id: '2537', from: 'RNB', to: 'KLR', attributes: { prediction: 334 }, }, { - id: 2538, + id: '2538', from: 'LJG', to: 'KMG', attributes: { prediction: 9136 }, }, { - id: 2539, + id: '2539', from: 'NGO', to: 'KMI', attributes: { prediction: 8235 }, }, { - id: 2540, + id: '2540', from: 'PEK', to: 'HYN', attributes: { prediction: 5336 }, }, { - id: 2541, + id: '2541', from: 'IND', to: 'IAD', attributes: { prediction: 5425 }, }, { - id: 2542, + id: '2542', from: 'CAE', to: 'IAH', attributes: { prediction: 3288 }, }, { - id: 2543, + id: '2543', from: 'HNL', to: 'IAH', attributes: { prediction: 12247 }, }, { - id: 2544, + id: '2544', from: 'DLA', to: 'LFW', attributes: { prediction: 1820 }, }, { - id: 2545, + id: '2545', from: 'DTW', to: 'LGA', attributes: { prediction: 41696 }, }, { - id: 2546, + id: '2546', from: 'LEI', to: 'LGW', attributes: { prediction: 4404 }, }, { - id: 2547, + id: '2547', from: 'HYL', to: 'KTN', attributes: { prediction: 774 }, }, { - id: 2548, + id: '2548', from: 'OME', to: 'KTS', attributes: { prediction: 12 }, }, { - id: 2549, + id: '2549', from: 'NYO', to: 'KTW', attributes: { prediction: 2252 }, }, { - id: 2550, + id: '2550', from: 'PEK', to: 'KUL', attributes: { prediction: 10225 }, }, { - id: 2551, + id: '2551', from: 'RHO', to: 'KZS', attributes: { prediction: 657 }, }, { - id: 2552, + id: '2552', from: 'LAX', to: 'LAP', attributes: { prediction: 629 }, }, { - id: 2553, + id: '2553', from: 'SGF', to: 'LAS', attributes: { prediction: 2600 }, }, { - id: 2554, + id: '2554', from: 'DXB', to: 'LAX', attributes: { prediction: 6398 }, }, { - id: 2555, + id: '2555', from: 'TUS', to: 'LAX', attributes: { prediction: 22338 }, }, { - id: 2556, + id: '2556', from: 'BHD', to: 'LBA', attributes: { prediction: 5740 }, }, { - id: 2557, + id: '2557', from: 'DUB', to: 'LBC', attributes: { prediction: 3100 }, }, { - id: 2558, + id: '2558', from: 'DUB', to: 'LCY', attributes: { prediction: 12178 }, }, { - id: 2559, + id: '2559', from: 'RTM', to: 'LCY', attributes: { prediction: 6331 }, }, { - id: 2560, + id: '2560', from: 'MUC', to: 'LED', attributes: { prediction: 13917 }, }, { - id: 2561, + id: '2561', from: 'PMI', to: 'LEJ', attributes: { prediction: 13315 }, }, { - id: 2562, + id: '2562', from: 'SSH', to: 'LGW', attributes: { prediction: 14598 }, }, { - id: 2563, + id: '2563', from: 'AUH', to: 'LHR', attributes: { prediction: 25581 }, }, { - id: 2564, + id: '2564', from: 'CTU', to: 'LHW', attributes: { prediction: 9815 }, }, { - id: 2565, + id: '2565', from: 'ZIH', to: 'MEX', attributes: { prediction: 7737 }, }, { - id: 2566, + id: '2566', from: 'LUX', to: 'NCE', attributes: { prediction: 1584 }, }, { - id: 2567, + id: '2567', from: 'DPS', to: 'NGO', attributes: { prediction: 2408 }, }, { - id: 2568, + id: '2568', from: 'LDY', to: 'LTN', attributes: { prediction: 3213 }, }, { - id: 2569, + id: '2569', from: 'FCO', to: 'LWO', attributes: { prediction: 1226 }, }, { - id: 2570, + id: '2570', from: 'GOT', to: 'LYS', attributes: { prediction: 885 }, }, { - id: 2571, + id: '2571', from: 'SPU', to: 'LYS', attributes: { prediction: 286 }, }, { - id: 2572, + id: '2572', from: 'LGW', to: 'MAD', attributes: { prediction: 24585 }, }, { - id: 2573, + id: '2573', from: 'BOH', to: 'MAH', attributes: { prediction: 659 }, }, { - id: 2574, + id: '2574', from: 'BIA', to: 'MAN', attributes: { prediction: 828 }, }, { - id: 2575, + id: '2575', from: 'CAI', to: 'MCT', attributes: { prediction: 6595 }, }, { - id: 2576, + id: '2576', from: 'GIG', to: 'MCZ', attributes: { prediction: 3038 }, }, { - id: 2577, + id: '2577', from: 'MHT', to: 'MDW', attributes: { prediction: 12600 }, }, { - id: 2578, + id: '2578', from: 'VLL', to: 'NRN', attributes: { prediction: 2255 }, }, { - id: 2579, + id: '2579', from: 'TAS', to: 'NRT', attributes: { prediction: 1379 }, }, { - id: 2580, + id: '2580', from: 'CGK', to: 'PGK', attributes: { prediction: 16555 }, }, { - id: 2581, + id: '2581', from: 'DSM', to: 'PHX', attributes: { prediction: 2808 }, }, { - id: 2582, + id: '2582', from: 'IKA', to: 'ORY', attributes: { prediction: 1958 }, }, { - id: 2583, + id: '2583', from: 'LRT', to: 'ORY', attributes: { prediction: 6965 }, }, { - id: 2584, + id: '2584', from: 'NCY', to: 'ORY', attributes: { prediction: 3960 }, }, { - id: 2585, + id: '2585', from: 'SXB', to: 'ORY', attributes: { prediction: 7681 }, }, { - id: 2586, + id: '2586', from: 'RIX', to: 'OSL', attributes: { prediction: 11636 }, }, { - id: 2587, + id: '2587', from: 'CDG', to: 'MSP', attributes: { prediction: 6001 }, }, { - id: 2588, + id: '2588', from: 'PIA', to: 'MSP', attributes: { prediction: 2437 }, }, { - id: 2589, + id: '2589', from: 'STL', to: 'MSY', attributes: { prediction: 3211 }, }, { - id: 2590, + id: '2590', from: 'ATL', to: 'MTY', attributes: { prediction: 3521 }, }, { - id: 2591, + id: '2591', from: 'MIR', to: 'MUC', attributes: { prediction: 1780 }, }, { - id: 2592, + id: '2592', from: 'DBV', to: 'MXP', attributes: { prediction: 2380 }, }, { - id: 2593, + id: '2593', from: 'SSH', to: 'MXP', attributes: { prediction: 810 }, }, { - id: 2594, + id: '2594', from: 'NGO', to: 'MYJ', attributes: { prediction: 1974 }, }, { - id: 2595, + id: '2595', from: 'MUR', to: 'MYY', attributes: { prediction: 535 }, }, { - id: 2596, + id: '2596', from: 'MEL', to: 'NAN', attributes: { prediction: 4397 }, }, { - id: 2597, + id: '2597', from: 'BIM', to: 'NAS', attributes: { prediction: 953 }, }, { - id: 2598, + id: '2598', from: 'KUL', to: 'PDG', attributes: { prediction: 4363 }, }, { - id: 2599, + id: '2599', from: 'DEN', to: 'PDX', attributes: { prediction: 45779 }, }, { - id: 2600, + id: '2600', from: 'BUD', to: 'PEK', attributes: { prediction: 3475 }, }, { - id: 2601, + id: '2601', from: 'EWR', to: 'PEK', attributes: { prediction: 6461 }, }, { - id: 2602, + id: '2602', from: 'HLD', to: 'PEK', attributes: { prediction: 2287 }, }, { - id: 2603, + id: '2603', from: 'CGN', to: 'NUE', attributes: { prediction: 874 }, }, { - id: 2604, + id: '2604', from: 'FWA', to: 'ORD', attributes: { prediction: 6275 }, }, { - id: 2605, + id: '2605', from: 'LGB', to: 'ORD', attributes: { prediction: 4095 }, }, { - id: 2606, + id: '2606', from: 'NRT', to: 'ORD', attributes: { prediction: 38429 }, }, { - id: 2607, + id: '2607', from: 'SAT', to: 'ORD', attributes: { prediction: 16482 }, }, { - id: 2608, + id: '2608', from: 'YHZ', to: 'ORD', attributes: { prediction: 1877 }, }, { - id: 2609, + id: '2609', from: 'YYC', to: 'ORD', attributes: { prediction: 10639 }, }, { - id: 2610, + id: '2610', from: 'LIS', to: 'ORK', attributes: { prediction: 1341 }, }, { - id: 2611, + id: '2611', from: 'ORY', to: 'ORN', attributes: { prediction: 4068 }, }, { - id: 2612, + id: '2612', from: 'YNZ', to: 'PEK', attributes: { prediction: 2584 }, }, { - id: 2613, + id: '2613', from: 'AKL', to: 'PER', attributes: { prediction: 4010 }, }, { - id: 2614, + id: '2614', from: 'EPR', to: 'PER', attributes: { prediction: 1640 }, }, { - id: 2615, + id: '2615', from: 'BDL', to: 'PHL', attributes: { prediction: 14487 }, }, { - id: 2616, + id: '2616', from: 'BWI', to: 'PHL', attributes: { prediction: 10102 }, }, { - id: 2617, + id: '2617', from: 'IAH', to: 'PHL', attributes: { prediction: 26302 }, }, { - id: 2618, + id: '2618', from: 'MDT', to: 'PHL', attributes: { prediction: 4029 }, }, { - id: 2619, + id: '2619', from: 'GYM', to: 'PHX', attributes: { prediction: 485 }, }, { - id: 2620, + id: '2620', from: 'MSP', to: 'PIA', attributes: { prediction: 2382 }, }, { - id: 2621, + id: '2621', from: 'SBN', to: 'PIE', attributes: { prediction: 1200 }, }, { - id: 2622, + id: '2622', from: 'GDX', to: 'PKC', attributes: { prediction: 127 }, }, { - id: 2623, + id: '2623', from: 'TAL', to: 'RBY', attributes: { prediction: 64 }, }, { - id: 2624, + id: '2624', from: 'BOS', to: 'RDU', attributes: { prediction: 17436 }, }, { - id: 2625, + id: '2625', from: 'SNW', to: 'RGN', attributes: { prediction: 1034 }, }, { - id: 2626, + id: '2626', from: 'CTA', to: 'PMF', attributes: { prediction: 4651 }, }, { - id: 2627, + id: '2627', from: 'MXP', to: 'PMO', attributes: { prediction: 23291 }, }, { - id: 2628, + id: '2628', from: 'ORY', to: 'PMO', attributes: { prediction: 4507 }, }, { - id: 2629, + id: '2629', from: 'FLG', to: 'PRC', attributes: { prediction: 1283 }, }, { - id: 2630, + id: '2630', from: 'ROV', to: 'PRG', attributes: { prediction: 2169 }, }, { - id: 2631, + id: '2631', from: 'LIN', to: 'PSR', attributes: { prediction: 2716 }, }, { - id: 2632, + id: '2632', from: 'PAP', to: 'PTP', attributes: { prediction: 2963 }, }, { - id: 2633, + id: '2633', from: 'SJU', to: 'PUJ', attributes: { prediction: 2697 }, }, { - id: 2634, + id: '2634', from: 'EWR', to: 'PVD', attributes: { prediction: 5933 }, }, { - id: 2635, + id: '2635', from: 'EMA', to: 'RAK', attributes: { prediction: 1586 }, }, { - id: 2636, + id: '2636', from: 'MDW', to: 'RNO', attributes: { prediction: 3453 }, }, { - id: 2637, + id: '2637', from: 'ACC', to: 'ROB', attributes: { prediction: 4206 }, }, { - id: 2638, + id: '2638', from: 'AMM', to: 'RUH', attributes: { prediction: 8945 }, }, { - id: 2639, + id: '2639', from: 'ATH', to: 'RYG', attributes: { prediction: 1435 }, }, { - id: 2640, + id: '2640', from: 'KHI', to: 'RYK', attributes: { prediction: 1608 }, }, { - id: 2641, + id: '2641', from: 'RLG', to: 'PMI', attributes: { prediction: 1102 }, }, { - id: 2642, + id: '2642', from: 'REC', to: 'PNZ', attributes: { prediction: 5570 }, }, { - id: 2643, + id: '2643', from: 'HGU', to: 'POM', attributes: { prediction: 5587 }, }, { - id: 2644, + id: '2644', from: 'HKN', to: 'POM', attributes: { prediction: 1068 }, }, { - id: 2645, + id: '2645', from: 'KUL', to: 'TRZ', attributes: { prediction: 7330 }, }, { - id: 2646, + id: '2646', from: 'BBU', to: 'TSF', attributes: { prediction: 3023 }, }, { - id: 2647, + id: '2647', from: 'ALC', to: 'SOU', attributes: { prediction: 2958 }, }, { - id: 2648, + id: '2648', from: 'GUM', to: 'SPN', attributes: { prediction: 3291 }, }, { - id: 2649, + id: '2649', from: 'KBP', to: 'SPU', attributes: { prediction: 1295 }, }, { - id: 2650, + id: '2650', from: 'RAO', to: 'SDU', attributes: { prediction: 3848 }, }, { - id: 2651, + id: '2651', from: 'DFW', to: 'SEA', attributes: { prediction: 44715 }, }, { - id: 2652, + id: '2652', from: 'KOA', to: 'SFO', attributes: { prediction: 10799 }, }, { - id: 2653, + id: '2653', from: 'MKE', to: 'SFO', attributes: { prediction: 7115 }, }, { - id: 2654, + id: '2654', from: 'CJB', to: 'SHJ', attributes: { prediction: 2554 }, }, { - id: 2655, + id: '2655', from: 'MXP', to: 'SIN', attributes: { prediction: 6621 }, }, { - id: 2656, + id: '2656', from: 'GYE', to: 'SJO', attributes: { prediction: 3062 }, }, { - id: 2657, + id: '2657', from: 'OBX', to: 'SKC', attributes: { prediction: 180 }, }, { - id: 2658, + id: '2658', from: 'CUN', to: 'SLC', attributes: { prediction: 2136 }, }, { - id: 2659, + id: '2659', from: 'DXB', to: 'SLL', attributes: { prediction: 851 }, }, { - id: 2660, + id: '2660', from: 'TNR', to: 'SMS', attributes: { prediction: 1785 }, }, { - id: 2661, + id: '2661', from: 'TFS', to: 'SNN', attributes: { prediction: 612 }, }, { - id: 2662, + id: '2662', from: 'BSX', to: 'SNW', attributes: { prediction: 36 }, }, { - id: 2663, + id: '2663', from: 'VLC', to: 'TSR', attributes: { prediction: 1408 }, }, { - id: 2664, + id: '2664', from: 'DFW', to: 'TXK', attributes: { prediction: 3499 }, }, { - id: 2665, + id: '2665', from: 'YVR', to: 'YCD', attributes: { prediction: 3587 }, }, { - id: 2666, + id: '2666', from: 'YYR', to: 'YDF', attributes: { prediction: 1461 }, }, { - id: 2667, + id: '2667', from: 'YZF', to: 'YEV', attributes: { prediction: 1086 }, }, { - id: 2668, + id: '2668', from: 'DUS', to: 'VOL', attributes: { prediction: 601 }, }, { - id: 2669, + id: '2669', from: 'CAG', to: 'VRN', attributes: { prediction: 7378 }, }, { - id: 2670, + id: '2670', from: 'TIA', to: 'VRN', attributes: { prediction: 7692 }, }, { - id: 2671, + id: '2671', from: 'LTN', to: 'WAT', attributes: { prediction: 3703 }, }, { - id: 2672, + id: '2672', from: 'VIE', to: 'WAW', attributes: { prediction: 13983 }, }, { - id: 2673, + id: '2673', from: 'YVP', to: 'XGR', attributes: { prediction: 196 }, }, { - id: 2674, + id: '2674', from: 'TXL', to: 'XRY', attributes: { prediction: 1412 }, }, { - id: 2675, + id: '2675', from: 'SHJ', to: 'SYZ', attributes: { prediction: 2073 }, }, { - id: 2676, + id: '2676', from: 'KWL', to: 'SZX', attributes: { prediction: 5983 }, }, { - id: 2677, + id: '2677', from: 'BGI', to: 'TAB', attributes: { prediction: 760 }, }, { - id: 2678, + id: '2678', from: 'SHA', to: 'TAO', attributes: { prediction: 20613 }, }, { - id: 2679, + id: '2679', from: 'IKA', to: 'TAS', attributes: { prediction: 598 }, }, { - id: 2680, + id: '2680', from: 'GRW', to: 'TER', attributes: { prediction: 1279 }, }, { - id: 2681, + id: '2681', from: 'RZR', to: 'THR', attributes: { prediction: 768 }, }, { - id: 2682, + id: '2682', from: 'KTS', to: 'TLA', attributes: { prediction: 0 }, }, { - id: 2683, + id: '2683', from: 'BEG', to: 'TLV', attributes: { prediction: 556 }, }, { - id: 2684, + id: '2684', from: 'SJO', to: 'TNO', attributes: { prediction: 695 }, }, { - id: 2685, + id: '2685', from: 'FTU', to: 'TNR', attributes: { prediction: 1761 }, }, { - id: 2686, + id: '2686', from: 'YCB', to: 'YCO', attributes: { prediction: 315 }, }, { - id: 2687, + id: '2687', from: 'CRL', to: 'TRN', attributes: { prediction: 2914 }, }, { - id: 2688, + id: '2688', from: 'CGN', to: 'TXL', attributes: { prediction: 68704 }, }, { - id: 2689, + id: '2689', from: 'HAK', to: 'TYN', attributes: { prediction: 3040 }, }, { - id: 2690, + id: '2690', from: 'SXF', to: 'VCE', attributes: { prediction: 7261 }, }, { - id: 2691, + id: '2691', from: 'CNF', to: 'VIX', attributes: { prediction: 14847 }, }, { - id: 2692, + id: '2692', from: 'KEF', to: 'YHZ', attributes: { prediction: 1278 }, }, { - id: 2693, + id: '2693', from: 'YQC', to: 'YKG', attributes: { prediction: 195 }, }, { - id: 2694, + id: '2694', from: 'YVZ', to: 'YPM', attributes: { prediction: 128 }, }, { - id: 2695, + id: '2695', from: 'YYZ', to: 'YQM', attributes: { prediction: 11791 }, }, { - id: 2696, + id: '2696', from: 'YYH', to: 'YHK', attributes: { prediction: 436 }, }, { - id: 2697, + id: '2697', from: 'LHR', to: 'YHZ', attributes: { prediction: 4804 }, }, { - id: 2698, + id: '2698', from: 'YDF', to: 'YJT', attributes: { prediction: 348 }, }, { - id: 2699, + id: '2699', from: 'SHE', to: 'YNJ', attributes: { prediction: 1559 }, }, { - id: 2700, + id: '2700', from: 'YGW', to: 'YPH', attributes: { prediction: 73 }, }, { - id: 2701, + id: '2701', from: 'PMI', to: 'AAL', attributes: { prediction: 447 }, }, { - id: 2702, + id: '2702', from: 'BKO', to: 'ABJ', attributes: { prediction: 137 }, }, { - id: 2703, + id: '2703', from: 'JER', to: 'ABZ', attributes: { prediction: 230 }, }, { - id: 2704, + id: '2704', from: 'BJL', to: 'ACC', attributes: { prediction: 2258 }, }, { - id: 2705, + id: '2705', from: 'FRA', to: 'ADA', attributes: { prediction: 988 }, }, { - id: 2706, + id: '2706', from: 'DEL', to: 'ADD', attributes: { prediction: 3706 }, }, { - id: 2707, + id: '2707', from: 'BBO', to: 'ADE', attributes: { prediction: 522 }, }, { - id: 2708, + id: '2708', from: 'AKL', to: 'ADL', attributes: { prediction: 2107 }, }, { - id: 2709, + id: '2709', from: 'MRV', to: 'AER', attributes: { prediction: 1385 }, }, { - id: 2710, + id: '2710', from: 'LUX', to: 'AGA', attributes: { prediction: 244 }, }, { - id: 2711, + id: '2711', from: 'YFB', to: 'YRT', attributes: { prediction: 952 }, }, { - id: 2712, + id: '2712', from: 'MAN', to: 'YVR', attributes: { prediction: 2680 }, }, { - id: 2713, + id: '2713', from: 'YYC', to: 'YXE', attributes: { prediction: 18215 }, }, { - id: 2714, + id: '2714', from: 'YLW', to: 'YXS', attributes: { prediction: 269 }, }, { - id: 2715, + id: '2715', from: 'YXJ', to: 'YYE', attributes: { prediction: 623 }, }, { - id: 2716, + id: '2716', from: 'PIE', to: 'YYZ', attributes: { prediction: 139 }, }, { - id: 2717, + id: '2717', from: 'YSB', to: 'YYZ', attributes: { prediction: 7934 }, }, { - id: 2718, + id: '2718', from: 'YZR', to: 'YYZ', attributes: { prediction: 1192 }, }, { - id: 2719, + id: '2719', from: 'AKL', to: 'ZQN', attributes: { prediction: 18073 }, }, { - id: 2720, + id: '2720', from: 'LPA', to: 'ZQW', attributes: { prediction: 704 }, }, { - id: 2721, + id: '2721', from: 'GRO', to: 'AHO', attributes: { prediction: 2179 }, }, { - id: 2722, + id: '2722', from: 'FMM', to: 'ALC', attributes: { prediction: 1903 }, }, { - id: 2723, + id: '2723', from: 'ALG', to: 'YUL', attributes: { prediction: 1614 }, }, { - id: 2724, + id: '2724', from: 'YUL', to: 'YVR', attributes: { prediction: 27290 }, }, { - id: 2725, + id: '2725', from: 'ABA', to: 'BAX', attributes: { prediction: 820 }, }, { - id: 2726, + id: '2726', from: 'TLV', to: 'BCN', attributes: { prediction: 4834 }, }, { - id: 2727, + id: '2727', from: 'SOU', to: 'AMS', attributes: { prediction: 3747 }, }, { - id: 2728, + id: '2728', from: 'TIP', to: 'AMS', attributes: { prediction: 3458 }, }, { - id: 2729, + id: '2729', from: 'BOO', to: 'ANX', attributes: { prediction: 595 }, }, { - id: 2730, + id: '2730', from: 'ATL', to: 'ATH', attributes: { prediction: 3747 }, }, { - id: 2731, + id: '2731', from: 'JTY', to: 'ATH', attributes: { prediction: 694 }, }, { - id: 2732, + id: '2732', from: 'TBS', to: 'ATH', attributes: { prediction: 407 }, }, { - id: 2733, + id: '2733', from: 'VCE', to: 'ATH', attributes: { prediction: 1227 }, }, { - id: 2734, + id: '2734', from: 'ABE', to: 'ATL', attributes: { prediction: 3075 }, }, { - id: 2735, + id: '2735', from: 'EVV', to: 'ATL', attributes: { prediction: 3342 }, }, { - id: 2736, + id: '2736', from: 'PHF', to: 'ATL', attributes: { prediction: 14276 }, }, { - id: 2737, + id: '2737', from: 'PRG', to: 'ATL', attributes: { prediction: 2826 }, }, { - id: 2738, + id: '2738', from: 'COK', to: 'AUH', attributes: { prediction: 6415 }, }, { - id: 2739, + id: '2739', from: 'EXT', to: 'AVN', attributes: { prediction: 215 }, }, { - id: 2740, + id: '2740', from: 'BJV', to: 'AYT', attributes: { prediction: 381 }, }, { - id: 2741, + id: '2741', from: 'FMO', to: 'AYT', attributes: { prediction: 467 }, }, { - id: 2742, + id: '2742', from: 'BOG', to: 'BAQ', attributes: { prediction: 34973 }, }, { - id: 2743, + id: '2743', from: 'GRU', to: 'BEL', attributes: { prediction: 11856 }, }, { - id: 2744, + id: '2744', from: 'AUC', to: 'BGA', attributes: { prediction: 308 }, }, { - id: 2745, + id: '2745', from: 'DXB', to: 'BLR', attributes: { prediction: 20201 }, }, { - id: 2746, + id: '2746', from: 'ZAG', to: 'BUD', attributes: { prediction: 1327 }, }, { - id: 2747, + id: '2747', from: 'JNB', to: 'BUQ', attributes: { prediction: 1179 }, }, { - id: 2748, + id: '2748', from: 'MRS', to: 'BVA', attributes: { prediction: 7356 }, }, { - id: 2749, + id: '2749', from: 'TZX', to: 'ECN', attributes: { prediction: 742 }, }, { - id: 2750, + id: '2750', from: 'IOM', to: 'EDI', attributes: { prediction: 848 }, }, { - id: 2751, + id: '2751', from: 'CWB', to: 'GIG', attributes: { prediction: 31241 }, }, { - id: 2752, + id: '2752', from: 'AKL', to: 'GIS', attributes: { prediction: 2553 }, }, { - id: 2753, + id: '2753', from: 'KWI', to: 'GOI', attributes: { prediction: 1157 }, }, { - id: 2754, + id: '2754', from: 'BGO', to: 'BLL', attributes: { prediction: 998 }, }, { - id: 2755, + id: '2755', from: 'RVK', to: 'BNN', attributes: { prediction: 345 }, }, { - id: 2756, + id: '2756', from: 'FLA', to: 'BOG', attributes: { prediction: 769 }, }, { - id: 2757, + id: '2757', from: 'LET', to: 'BOG', attributes: { prediction: 3999 }, }, { - id: 2758, + id: '2758', from: 'CCU', to: 'BOM', attributes: { prediction: 55817 }, }, { - id: 2759, + id: '2759', from: 'MXP', to: 'BPS', attributes: { prediction: 641 }, }, { - id: 2760, + id: '2760', from: 'EDI', to: 'BRE', attributes: { prediction: 2868 }, }, { - id: 2761, + id: '2761', from: 'FRA', to: 'BRE', attributes: { prediction: 20578 }, }, { - id: 2762, + id: '2762', from: 'HAJ', to: 'BRU', attributes: { prediction: 2489 }, }, { - id: 2763, + id: '2763', from: 'MRS', to: 'BRU', attributes: { prediction: 5273 }, }, { - id: 2764, + id: '2764', from: 'SXF', to: 'BRU', attributes: { prediction: 7045 }, }, { - id: 2765, + id: '2765', from: 'BGW', to: 'BSR', attributes: { prediction: 426 }, }, { - id: 2766, + id: '2766', from: 'TBS', to: 'HRK', attributes: { prediction: 164 }, }, { - id: 2767, + id: '2767', from: 'JED', to: 'IAD', attributes: { prediction: 1021 }, }, { - id: 2768, + id: '2768', from: 'MHT', to: 'IAD', attributes: { prediction: 3811 }, }, { - id: 2769, + id: '2769', from: 'SAN', to: 'IAD', attributes: { prediction: 14686 }, }, { - id: 2770, + id: '2770', from: 'BGF', to: 'DLA', attributes: { prediction: 978 }, }, { - id: 2771, + id: '2771', from: 'VLI', to: 'DLY', attributes: { prediction: 32 }, }, { - id: 2772, + id: '2772', from: 'LBD', to: 'DME', attributes: { prediction: 2761 }, }, { - id: 2773, + id: '2773', from: 'NVI', to: 'DME', attributes: { prediction: 864 }, }, { - id: 2774, + id: '2774', from: 'UUS', to: 'DME', attributes: { prediction: 6900 }, }, { - id: 2775, + id: '2775', from: 'BLR', to: 'CJB', attributes: { prediction: 4099 }, }, { - id: 2776, + id: '2776', from: 'MCO', to: 'CLE', attributes: { prediction: 7480 }, }, { - id: 2777, + id: '2777', from: 'ORF', to: 'CLE', attributes: { prediction: 2242 }, }, { - id: 2778, + id: '2778', from: 'LGW', to: 'CLT', attributes: { prediction: 6650 }, }, { - id: 2779, + id: '2779', from: 'SAV', to: 'CLT', attributes: { prediction: 11642 }, }, { - id: 2780, + id: '2780', from: 'IST', to: 'CMN', attributes: { prediction: 5918 }, }, { - id: 2781, + id: '2781', from: 'BMU', to: 'DPS', attributes: { prediction: 1393 }, }, { - id: 2782, + id: '2782', from: 'WRO', to: 'DSA', attributes: { prediction: 1291 }, }, { - id: 2783, + id: '2783', from: 'BNA', to: 'DTW', attributes: { prediction: 20408 }, }, { - id: 2784, + id: '2784', from: 'ZRH', to: 'CTA', attributes: { prediction: 1578 }, }, { - id: 2785, + id: '2785', from: 'MAD', to: 'CUN', attributes: { prediction: 4089 }, }, { - id: 2786, + id: '2786', from: 'MEM', to: 'DAL', attributes: { prediction: 3145 }, }, { - id: 2787, + id: '2787', from: 'CLE', to: 'DAY', attributes: { prediction: 3541 }, }, { - id: 2788, + id: '2788', from: 'SXF', to: 'DBV', attributes: { prediction: 1077 }, }, { - id: 2789, + id: '2789', from: 'ALB', to: 'DCA', attributes: { prediction: 4410 }, }, { - id: 2790, + id: '2790', from: 'BNA', to: 'DCA', attributes: { prediction: 7722 }, }, { - id: 2791, + id: '2791', from: 'JAX', to: 'DCA', attributes: { prediction: 8237 }, }, { - id: 2792, + id: '2792', from: 'BIL', to: 'DEN', attributes: { prediction: 11947 }, }, { - id: 2793, + id: '2793', from: 'BCN', to: 'DUB', attributes: { prediction: 8341 }, }, { - id: 2794, + id: '2794', from: 'JFK', to: 'DUS', attributes: { prediction: 6488 }, }, { - id: 2795, + id: '2795', from: 'ALG', to: 'DXB', attributes: { prediction: 2361 }, }, { - id: 2796, + id: '2796', from: 'FSZ', to: 'ICN', attributes: { prediction: 7911 }, }, { - id: 2797, + id: '2797', from: 'FUE', to: 'FMO', attributes: { prediction: 644 }, }, { - id: 2798, + id: '2798', from: 'CKY', to: 'FNA', attributes: { prediction: 137 }, }, { - id: 2799, + id: '2799', from: 'NBO', to: 'EBB', attributes: { prediction: 15647 }, }, { - id: 2800, + id: '2800', from: 'CPH', to: 'EDI', attributes: { prediction: 3839 }, }, { - id: 2801, + id: '2801', from: 'LGW', to: 'EGC', attributes: { prediction: 379 }, }, { - id: 2802, + id: '2802', from: 'AGP', to: 'EMA', attributes: { prediction: 11394 }, }, { - id: 2803, + id: '2803', from: 'PMY', to: 'EQS', attributes: { prediction: 300 }, }, { - id: 2804, + id: '2804', from: 'ERC', to: 'ESB', attributes: { prediction: 1876 }, }, { - id: 2805, + id: '2805', from: 'AZA', to: 'EUG', attributes: { prediction: 980 }, }, { - id: 2806, + id: '2806', from: 'BOO', to: 'EVE', attributes: { prediction: 1096 }, }, { - id: 2807, + id: '2807', from: 'AER', to: 'EVN', attributes: { prediction: 1345 }, }, { - id: 2808, + id: '2808', from: 'NRT', to: 'EWR', attributes: { prediction: 6151 }, }, { - id: 2809, + id: '2809', from: 'PMI', to: 'EXT', attributes: { prediction: 792 }, }, { - id: 2810, + id: '2810', from: 'CGN', to: 'FAO', attributes: { prediction: 2854 }, }, { - id: 2811, + id: '2811', from: 'CMN', to: 'FCO', attributes: { prediction: 8412 }, }, { - id: 2812, + id: '2812', from: 'TXL', to: 'FRL', attributes: { prediction: 1408 }, }, { - id: 2813, + id: '2813', from: 'OSS', to: 'FRU', attributes: { prediction: 4772 }, }, { - id: 2814, + id: '2814', from: 'TPE', to: 'ICN', attributes: { prediction: 46869 }, }, { - id: 2815, + id: '2815', from: 'MUC', to: 'IKA', attributes: { prediction: 909 }, }, { - id: 2816, + id: '2816', from: 'CPO', to: 'IQQ', attributes: { prediction: 1549 }, }, { - id: 2817, + id: '2817', from: 'BQL', to: 'ISA', attributes: { prediction: 146 }, }, { - id: 2818, + id: '2818', from: 'HKG', to: 'KHN', attributes: { prediction: 1228 }, }, { - id: 2819, + id: '2819', from: 'FEZ', to: 'HHN', attributes: { prediction: 1330 }, }, { - id: 2820, + id: '2820', from: 'SVD', to: 'GND', attributes: { prediction: 1351 }, }, { - id: 2821, + id: '2821', from: 'GRX', to: 'GRO', attributes: { prediction: 7546 }, }, { - id: 2822, + id: '2822', from: 'LHR', to: 'GRU', attributes: { prediction: 16357 }, }, { - id: 2823, + id: '2823', from: 'ALC', to: 'GSE', attributes: { prediction: 1914 }, }, { - id: 2824, + id: '2824', from: 'BOD', to: 'GVA', attributes: { prediction: 5826 }, }, { - id: 2825, + id: '2825', from: 'CDG', to: 'GVA', attributes: { prediction: 38417 }, }, { - id: 2826, + id: '2826', from: 'RIX', to: 'GVA', attributes: { prediction: 1351 }, }, { - id: 2827, + id: '2827', from: 'BSB', to: 'GYN', attributes: { prediction: 19135 }, }, { - id: 2828, + id: '2828', from: 'MUA', to: 'GZO', attributes: { prediction: 438 }, }, { - id: 2829, + id: '2829', from: 'MIR', to: 'HAJ', attributes: { prediction: 590 }, }, { - id: 2830, + id: '2830', from: 'VCE', to: 'HAJ', attributes: { prediction: 1458 }, }, { - id: 2831, + id: '2831', from: 'NHA', to: 'HAN', attributes: { prediction: 7148 }, }, { - id: 2832, + id: '2832', from: 'CGO', to: 'HKG', attributes: { prediction: 1473 }, }, { - id: 2833, + id: '2833', from: 'PUS', to: 'HKG', attributes: { prediction: 4047 }, }, { - id: 2834, + id: '2834', from: 'KUL', to: 'HKT', attributes: { prediction: 13818 }, }, { - id: 2835, + id: '2835', from: 'BOO', to: 'MJF', attributes: { prediction: 493 }, }, { - id: 2836, + id: '2836', from: 'FLL', to: 'MKE', attributes: { prediction: 559 }, }, { - id: 2837, + id: '2837', from: 'MAA', to: 'KWI', attributes: { prediction: 2874 }, }, { - id: 2838, + id: '2838', from: 'BOS', to: 'LAS', attributes: { prediction: 7684 }, }, { - id: 2839, + id: '2839', from: 'MFR', to: 'LAX', attributes: { prediction: 4462 }, }, { - id: 2840, + id: '2840', from: 'BAH', to: 'LCA', attributes: { prediction: 1637 }, }, { - id: 2841, + id: '2841', from: 'BBU', to: 'LCA', attributes: { prediction: 1519 }, }, { - id: 2842, + id: '2842', from: 'LHR', to: 'LCA', attributes: { prediction: 19284 }, }, { - id: 2843, + id: '2843', from: 'MEM', to: 'ICT', attributes: { prediction: 1941 }, }, { - id: 2844, + id: '2844', from: 'EVN', to: 'IKA', attributes: { prediction: 1160 }, }, { - id: 2845, + id: '2845', from: 'BOS', to: 'IND', attributes: { prediction: 3705 }, }, { - id: 2846, + id: '2846', from: 'SAT', to: 'IND', attributes: { prediction: 46 }, }, { - id: 2847, + id: '2847', from: 'SSA', to: 'IOS', attributes: { prediction: 5875 }, }, { - id: 2848, + id: '2848', from: 'MUX', to: 'ISB', attributes: { prediction: 755 }, }, { - id: 2849, + id: '2849', from: 'DEL', to: 'IST', attributes: { prediction: 6005 }, }, { - id: 2850, + id: '2850', from: 'KIX', to: 'IST', attributes: { prediction: 2861 }, }, { - id: 2851, + id: '2851', from: 'SIC', to: 'IST', attributes: { prediction: 3780 }, }, { - id: 2852, + id: '2852', from: 'MDE', to: 'JFK', attributes: { prediction: 2772 }, }, { - id: 2853, + id: '2853', from: 'PMO', to: 'JFK', attributes: { prediction: 663 }, }, { - id: 2854, + id: '2854', from: 'YHZ', to: 'JFK', attributes: { prediction: 3062 }, }, { - id: 2855, + id: '2855', from: 'JEG', to: 'JHS', attributes: { prediction: 651 }, }, { - id: 2856, + id: '2856', from: 'FAO', to: 'LDY', attributes: { prediction: 1213 }, }, { - id: 2857, + id: '2857', from: 'KCL', to: 'KCQ', attributes: { prediction: 10 }, }, { - id: 2858, + id: '2858', from: 'JFK', to: 'KEF', attributes: { prediction: 4536 }, }, { - id: 2859, + id: '2859', from: 'LED', to: 'KGD', attributes: { prediction: 12800 }, }, { - id: 2860, + id: '2860', from: 'HAM', to: 'KGS', attributes: { prediction: 2107 }, }, { - id: 2861, + id: '2861', from: 'NAS', to: 'KIN', attributes: { prediction: 1716 }, }, { - id: 2862, + id: '2862', from: 'ALC', to: 'KIR', attributes: { prediction: 1147 }, }, { - id: 2863, + id: '2863', from: 'PRG', to: 'KIV', attributes: { prediction: 337 }, }, { - id: 2864, + id: '2864', from: 'MMY', to: 'KIX', attributes: { prediction: 3550 }, }, { - id: 2865, + id: '2865', from: 'MRV', to: 'KJA', attributes: { prediction: 656 }, }, { - id: 2866, + id: '2866', from: 'OKA', to: 'KMQ', attributes: { prediction: 2900 }, }, { - id: 2867, + id: '2867', from: 'GEA', to: 'KNQ', attributes: { prediction: 384 }, }, { - id: 2868, + id: '2868', from: 'BGO', to: 'KRS', attributes: { prediction: 4488 }, }, { - id: 2869, + id: '2869', from: 'DYU', to: 'KUF', attributes: { prediction: 360 }, }, { - id: 2870, + id: '2870', from: 'BKI', to: 'KUL', attributes: { prediction: 82660 }, }, { - id: 2871, + id: '2871', from: 'ICN', to: 'KUL', attributes: { prediction: 9726 }, }, { - id: 2872, + id: '2872', from: 'SVX', to: 'LED', attributes: { prediction: 10562 }, }, { - id: 2873, + id: '2873', from: 'SJU', to: 'LGA', attributes: { prediction: 108 }, }, { - id: 2874, + id: '2874', from: 'BDA', to: 'LGW', attributes: { prediction: 6720 }, }, { - id: 2875, + id: '2875', from: 'MLE', to: 'LGW', attributes: { prediction: 4976 }, }, { - id: 2876, + id: '2876', from: 'ORK', to: 'LGW', attributes: { prediction: 4605 }, }, { - id: 2877, + id: '2877', from: 'OTP', to: 'LGW', attributes: { prediction: 4318 }, }, { - id: 2878, + id: '2878', from: 'DUB', to: 'NOC', attributes: { prediction: 1159 }, }, { - id: 2879, + id: '2879', from: 'GRO', to: 'NRN', attributes: { prediction: 7068 }, }, { - id: 2880, + id: '2880', from: 'BUD', to: 'MAD', attributes: { prediction: 6541 }, }, { - id: 2881, + id: '2881', from: 'MUC', to: 'MAD', attributes: { prediction: 25519 }, }, { - id: 2882, + id: '2882', from: 'BEL', to: 'MAO', attributes: { prediction: 12290 }, }, { - id: 2883, + id: '2883', from: 'MSP', to: 'MBS', attributes: { prediction: 1211 }, }, { - id: 2884, + id: '2884', from: 'CVG', to: 'MCI', attributes: { prediction: 3170 }, }, { - id: 2885, + id: '2885', from: 'DTW', to: 'MCI', attributes: { prediction: 9013 }, }, { - id: 2886, + id: '2886', from: 'SNN', to: 'LGW', attributes: { prediction: 9346 }, }, { - id: 2887, + id: '2887', from: 'AUH', to: 'LHE', attributes: { prediction: 9032 }, }, { - id: 2888, + id: '2888', from: 'HEL', to: 'LHR', attributes: { prediction: 29960 }, }, { - id: 2889, + id: '2889', from: 'BIA', to: 'LIL', attributes: { prediction: 535 }, }, { - id: 2890, + id: '2890', from: 'LHR', to: 'LIN', attributes: { prediction: 25169 }, }, { - id: 2891, + id: '2891', from: 'FON', to: 'LIR', attributes: { prediction: 151 }, }, { - id: 2892, + id: '2892', from: 'HAM', to: 'LIS', attributes: { prediction: 6052 }, }, { - id: 2893, + id: '2893', from: 'PDL', to: 'LIS', attributes: { prediction: 17268 }, }, { - id: 2894, + id: '2894', from: 'TMS', to: 'LIS', attributes: { prediction: 1880 }, }, { - id: 2895, + id: '2895', from: 'ALF', to: 'LKL', attributes: { prediction: 435 }, }, { - id: 2896, + id: '2896', from: 'PAD', to: 'LPA', attributes: { prediction: 1951 }, }, { - id: 2897, + id: '2897', from: 'CCF', to: 'LPL', attributes: { prediction: 1392 }, }, { - id: 2898, + id: '2898', from: 'OMA', to: 'LRD', attributes: { prediction: 107 }, }, { - id: 2899, + id: '2899', from: 'PHF', to: 'MCO', attributes: { prediction: 2650 }, }, { - id: 2900, + id: '2900', from: 'KHI', to: 'MCT', attributes: { prediction: 7920 }, }, { - id: 2901, + id: '2901', from: 'RUH', to: 'MCT', attributes: { prediction: 3955 }, }, { - id: 2902, + id: '2902', from: 'CHC', to: 'MEL', attributes: { prediction: 10108 }, }, { - id: 2903, + id: '2903', from: 'PHL', to: 'MEM', attributes: { prediction: 3282 }, }, { - id: 2904, + id: '2904', from: 'YVR', to: 'NRT', attributes: { prediction: 21763 }, }, { - id: 2905, + id: '2905', from: 'ADB', to: 'NUE', attributes: { prediction: 1212 }, }, { - id: 2906, + id: '2906', from: 'AMS', to: 'NUE', attributes: { prediction: 7746 }, }, { - id: 2907, + id: '2907', from: 'CGN', to: 'NUE', attributes: { prediction: 706 }, }, { - id: 2908, + id: '2908', from: 'HNL', to: 'OGG', attributes: { prediction: 62209 }, }, { - id: 2909, + id: '2909', from: 'HEL', to: 'MUC', attributes: { prediction: 16663 }, }, { - id: 2910, + id: '2910', from: 'SKG', to: 'MUC', attributes: { prediction: 11297 }, }, { - id: 2911, + id: '2911', from: 'THR', to: 'MHD', attributes: { prediction: 60586 }, }, { - id: 2912, + id: '2912', from: 'CFG', to: 'MIA', attributes: { prediction: 454 }, }, { - id: 2913, + id: '2913', from: 'TPA', to: 'MIA', attributes: { prediction: 17327 }, }, { - id: 2914, + id: '2914', from: 'TSF', to: 'MLA', attributes: { prediction: 1862 }, }, { - id: 2915, + id: '2915', from: 'ATL', to: 'MLB', attributes: { prediction: 7575 }, }, { - id: 2916, + id: '2916', from: 'HND', to: 'MMY', attributes: { prediction: 2285 }, }, { - id: 2917, + id: '2917', from: 'AMS', to: 'MNL', attributes: { prediction: 8591 }, }, { - id: 2918, + id: '2918', from: 'CYP', to: 'MNL', attributes: { prediction: 1706 }, }, { - id: 2919, + id: '2919', from: 'GUM', to: 'MNL', attributes: { prediction: 6196 }, }, { - id: 2920, + id: '2920', from: 'MKE', to: 'MQT', attributes: { prediction: 1079 }, }, { - id: 2921, + id: '2921', from: 'CDG', to: 'MRS', attributes: { prediction: 32401 }, }, { - id: 2922, + id: '2922', from: 'DUB', to: 'MRS', attributes: { prediction: 1186 }, }, { - id: 2923, + id: '2923', from: 'DVL', to: 'MSP', attributes: { prediction: 792 }, }, { - id: 2924, + id: '2924', from: 'LGA', to: 'MSP', attributes: { prediction: 23060 }, }, { - id: 2925, + id: '2925', from: 'MEM', to: 'MSP', attributes: { prediction: 15652 }, }, { - id: 2926, + id: '2926', from: 'TLL', to: 'MSQ', attributes: { prediction: 361 }, }, { - id: 2927, + id: '2927', from: 'VIE', to: 'MSQ', attributes: { prediction: 5023 }, }, { - id: 2928, + id: '2928', from: 'LAS', to: 'MSY', attributes: { prediction: 5671 }, }, { - id: 2929, + id: '2929', from: 'ACE', to: 'MUC', attributes: { prediction: 598 }, }, { - id: 2930, + id: '2930', from: 'RIX', to: 'MXP', attributes: { prediction: 4138 }, }, { - id: 2931, + id: '2931', from: 'TIP', to: 'MXP', attributes: { prediction: 1393 }, }, { - id: 2932, + id: '2932', from: 'LWY', to: 'MYY', attributes: { prediction: 1409 }, }, { - id: 2933, + id: '2933', from: 'MXP', to: 'NAP', attributes: { prediction: 33780 }, }, { - id: 2934, + id: '2934', from: 'VBS', to: 'NAP', attributes: { prediction: 3323 }, }, { - id: 2935, + id: '2935', from: 'LIL', to: 'OPO', attributes: { prediction: 1698 }, }, { - id: 2936, + id: '2936', from: 'CDG', to: 'VCE', attributes: { prediction: 32565 }, }, { - id: 2937, + id: '2937', from: 'DEL', to: 'VIE', attributes: { prediction: 5523 }, }, { - id: 2938, + id: '2938', from: 'FNC', to: 'VIE', attributes: { prediction: 561 }, }, { - id: 2939, + id: '2939', from: 'TFS', to: 'VIE', attributes: { prediction: 1287 }, }, { - id: 2940, + id: '2940', from: 'ONT', to: 'OAK', attributes: { prediction: 22385 }, }, { - id: 2941, + id: '2941', from: 'IST', to: 'ODS', attributes: { prediction: 3697 }, }, { - id: 2942, + id: '2942', from: 'BEG', to: 'OHD', attributes: { prediction: 434 }, }, { - id: 2943, + id: '2943', from: 'NRT', to: 'OKA', attributes: { prediction: 9007 }, }, { - id: 2944, + id: '2944', from: 'GAM', to: 'OME', attributes: { prediction: 335 }, }, { - id: 2945, + id: '2945', from: 'NRT', to: 'OOL', attributes: { prediction: 5505 }, }, { - id: 2946, + id: '2946', from: 'ARN', to: 'ORD', attributes: { prediction: 6508 }, }, { - id: 2947, + id: '2947', from: 'CAE', to: 'ORD', attributes: { prediction: 3487 }, }, { - id: 2948, + id: '2948', from: 'PIT', to: 'ORD', attributes: { prediction: 22256 }, }, { - id: 2949, + id: '2949', from: 'PRG', to: 'OSR', attributes: { prediction: 5240 }, }, { - id: 2950, + id: '2950', from: 'MUC', to: 'OTP', attributes: { prediction: 17321 }, }, { - id: 2951, + id: '2951', from: 'SFB', to: 'OWB', attributes: { prediction: 1238 }, }, { - id: 2952, + id: '2952', from: 'NRN', to: 'VLL', attributes: { prediction: 1804 }, }, { - id: 2953, + id: '2953', from: 'HJR', to: 'VNS', attributes: { prediction: 3447 }, }, { - id: 2954, + id: '2954', from: 'LIS', to: 'VRL', attributes: { prediction: 505 }, }, { - id: 2955, + id: '2955', from: 'TSR', to: 'VRN', attributes: { prediction: 899 }, }, { - id: 2956, + id: '2956', from: 'YYY', to: 'YUL', attributes: { prediction: 900 }, }, { - id: 2957, + id: '2957', from: 'YQB', to: 'YVB', attributes: { prediction: 91 }, }, { - id: 2958, + id: '2958', from: 'YOW', to: 'YVR', attributes: { prediction: 16189 }, }, { - id: 2959, + id: '2959', from: 'YXE', to: 'YWG', attributes: { prediction: 2101 }, }, { - id: 2960, + id: '2960', from: 'FSP', to: 'YYT', attributes: { prediction: 251 }, }, { - id: 2961, + id: '2961', from: 'YUL', to: 'YYY', attributes: { prediction: 845 }, }, { - id: 2962, + id: '2962', from: 'BNA', to: 'YYZ', attributes: { prediction: 2071 }, }, { - id: 2963, + id: '2963', from: 'MIA', to: 'YYZ', attributes: { prediction: 15992 }, }, { - id: 2964, + id: '2964', from: 'NRT', to: 'YYZ', attributes: { prediction: 8659 }, }, { - id: 2965, + id: '2965', from: 'SKB', to: 'YYZ', attributes: { prediction: 811 }, }, { - id: 2966, + id: '2966', from: 'TPE', to: 'SHE', attributes: { prediction: 1905 }, }, { - id: 2967, + id: '2967', from: 'BDO', to: 'SIN', attributes: { prediction: 3032 }, }, { - id: 2968, + id: '2968', from: 'LED', to: 'SIP', attributes: { prediction: 2625 }, }, { - id: 2969, + id: '2969', from: 'PLS', to: 'POP', attributes: { prediction: 145 }, }, { - id: 2970, + id: '2970', from: 'STN', to: 'POZ', attributes: { prediction: 5149 }, }, { - id: 2971, + id: '2971', from: 'NDY', to: 'PPW', attributes: { prediction: 17 }, }, { - id: 2972, + id: '2972', from: 'FRA', to: 'PRG', attributes: { prediction: 28046 }, }, { - id: 2973, + id: '2973', from: 'LBA', to: 'PRG', attributes: { prediction: 2192 }, }, { - id: 2974, + id: '2974', from: 'MVD', to: 'PTY', attributes: { prediction: 2420 }, }, { - id: 2975, + id: '2975', from: 'CLO', to: 'PUU', attributes: { prediction: 364 }, }, { - id: 2976, + id: '2976', from: 'CVG', to: 'PVD', attributes: { prediction: 141 }, }, { - id: 2977, + id: '2977', from: 'SPN', to: 'PVG', attributes: { prediction: 1750 }, }, { - id: 2978, + id: '2978', from: 'TPE', to: 'PVG', attributes: { prediction: 34751 }, }, { - id: 2979, + id: '2979', from: 'IAH', to: 'PVR', attributes: { prediction: 4539 }, }, { - id: 2980, + id: '2980', from: 'BOM', to: 'RAJ', attributes: { prediction: 6200 }, }, { - id: 2981, + id: '2981', from: 'SEA', to: 'RNO', attributes: { prediction: 7747 }, }, { - id: 2982, + id: '2982', from: 'CHC', to: 'ROT', attributes: { prediction: 3684 }, }, { - id: 2983, + id: '2983', from: 'ORD', to: 'RSW', attributes: { prediction: 10048 }, }, { - id: 2984, + id: '2984', from: 'ALY', to: 'RUH', attributes: { prediction: 2069 }, }, { - id: 2985, + id: '2985', from: 'KMC', to: 'RUH', attributes: { prediction: 401 }, }, { - id: 2986, + id: '2986', from: 'KHI', to: 'RYK', attributes: { prediction: 2001 }, }, { - id: 2987, + id: '2987', from: 'AMM', to: 'SAH', attributes: { prediction: 2303 }, }, { - id: 2988, + id: '2988', from: 'MIA', to: 'SAV', attributes: { prediction: 1060 }, }, { - id: 2989, + id: '2989', from: 'ZRH', to: 'SAW', attributes: { prediction: 3930 }, }, { - id: 2990, + id: '2990', from: 'LAS', to: 'SBN', attributes: { prediction: 1141 }, }, { - id: 2991, + id: '2991', from: 'MUC', to: 'SCN', attributes: { prediction: 4301 }, }, { - id: 2992, + id: '2992', from: 'ITM', to: 'SDJ', attributes: { prediction: 34777 }, }, { - id: 2993, + id: '2993', from: 'BOG', to: 'SDQ', attributes: { prediction: 1316 }, }, { - id: 2994, + id: '2994', from: 'BOS', to: 'SDQ', attributes: { prediction: 2054 }, }, { - id: 2995, + id: '2995', from: 'CCS', to: 'SDQ', attributes: { prediction: 3561 }, }, { - id: 2996, + id: '2996', from: 'LAX', to: 'SGF', attributes: { prediction: 1033 }, }, { - id: 2997, + id: '2997', from: 'HAJ', to: 'STN', attributes: { prediction: 6971 }, }, { - id: 2998, + id: '2998', from: 'YQB', to: 'YZV', attributes: { prediction: 2407 }, }, { - id: 2999, + id: '2999', from: 'CHC', to: 'ZQN', attributes: { prediction: 8465 }, }, { - id: 3000, + id: '3000', from: 'BDS', to: 'ZRH', attributes: { prediction: 589 }, }, { - id: 3001, + id: '3001', from: 'CAI', to: 'ZRH', attributes: { prediction: 4920 }, }, { - id: 3002, + id: '3002', from: 'STN', to: 'TIA', attributes: { prediction: 3790 }, }, { - id: 3003, + id: '3003', from: 'SVO', to: 'TJM', attributes: { prediction: 4168 }, }, { - id: 3004, + id: '3004', from: 'CDG', to: 'TLV', attributes: { prediction: 27859 }, }, { - id: 3005, + id: '3005', from: 'CGN', to: 'TLV', attributes: { prediction: 1965 }, }, { - id: 3006, + id: '3006', from: 'TRD', to: 'STN', attributes: { prediction: 2100 }, }, { - id: 3007, + id: '3007', from: 'BOJ', to: 'STR', attributes: { prediction: 403 }, }, { - id: 3008, + id: '3008', from: 'TRF', to: 'SVG', attributes: { prediction: 4708 }, }, { - id: 3009, + id: '3009', from: 'LEI', to: 'SVQ', attributes: { prediction: 1795 }, }, { - id: 3010, + id: '3010', from: 'IST', to: 'SVX', attributes: { prediction: 3617 }, }, { - id: 3011, + id: '3011', from: 'GVA', to: 'SXF', attributes: { prediction: 4075 }, }, { - id: 3012, + id: '3012', from: 'NRN', to: 'SXF', attributes: { prediction: 11340 }, }, { - id: 3013, + id: '3013', from: 'SAW', to: 'SXF', attributes: { prediction: 9048 }, }, { - id: 3014, + id: '3014', from: 'AMS', to: 'SXM', attributes: { prediction: 3381 }, }, { - id: 3015, + id: '3015', from: 'BHS', to: 'SYD', attributes: { prediction: 1439 }, }, { - id: 3016, + id: '3016', from: 'PEK', to: 'SZX', attributes: { prediction: 105881 }, }, { - id: 3017, + id: '3017', from: 'POS', to: 'TAB', attributes: { prediction: 10798 }, }, { - id: 3018, + id: '3018', from: 'IST', to: 'TBS', attributes: { prediction: 7307 }, }, { - id: 3019, + id: '3019', from: 'FMO', to: 'TFS', attributes: { prediction: 934 }, }, { - id: 3020, + id: '3020', from: 'LCG', to: 'TFS', attributes: { prediction: 413 }, }, { - id: 3021, + id: '3021', from: 'ELU', to: 'TGR', attributes: { prediction: 235 }, }, { - id: 3022, + id: '3022', from: 'CRL', to: 'TPS', attributes: { prediction: 2661 }, }, { - id: 3023, + id: '3023', from: 'COL', to: 'TRE', attributes: { prediction: 27 }, }, { - id: 3024, + id: '3024', from: 'TLV', to: 'ZRH', attributes: { prediction: 16852 }, }, { - id: 3025, + id: '3025', from: 'NVK', to: 'ANX', attributes: { prediction: 261 }, }, { - id: 3026, + id: '3026', from: 'AYT', to: 'ARN', attributes: { prediction: 452 }, }, { - id: 3027, + id: '3027', from: 'UME', to: 'ARN', attributes: { prediction: 12371 }, }, { - id: 3028, + id: '3028', from: 'BKK', to: 'ASB', attributes: { prediction: 1227 }, }, { - id: 3029, + id: '3029', from: 'CAE', to: 'ATL', attributes: { prediction: 11751 }, }, { - id: 3030, + id: '3030', from: 'BVA', to: 'WRO', attributes: { prediction: 1319 }, }, { - id: 3031, + id: '3031', from: 'AKN', to: 'WSN', attributes: { prediction: 9 }, }, { - id: 3032, + id: '3032', from: 'KKA', to: 'UNK', attributes: { prediction: 103 }, }, { - id: 3033, + id: '3033', from: 'LYS', to: 'VIE', attributes: { prediction: 5777 }, }, { - id: 3034, + id: '3034', from: 'SJU', to: 'VIJ', attributes: { prediction: 777 }, }, { - id: 3035, + id: '3035', from: 'LNB', to: 'VLI', attributes: { prediction: 88 }, }, { - id: 3036, + id: '3036', from: 'STN', to: 'VLL', attributes: { prediction: 2219 }, }, { - id: 3037, + id: '3037', from: 'PTY', to: 'VLN', attributes: { prediction: 1879 }, }, { - id: 3038, + id: '3038', from: 'LMC', to: 'VVC', attributes: { prediction: 169 }, }, { - id: 3039, + id: '3039', from: 'CMN', to: 'WAW', attributes: { prediction: 1154 }, }, { - id: 3040, + id: '3040', from: 'GVA', to: 'WAW', attributes: { prediction: 1987 }, }, { - id: 3041, + id: '3041', from: 'DUS', to: 'XRY', attributes: { prediction: 3779 }, }, { - id: 3042, + id: '3042', from: 'YQT', to: 'YAG', attributes: { prediction: 611 }, }, { - id: 3043, + id: '3043', from: 'ROR', to: 'YAP', attributes: { prediction: 500 }, }, { - id: 3044, + id: '3044', from: 'TUN', to: 'AMS', attributes: { prediction: 872 }, }, { - id: 3045, + id: '3045', from: 'KGX', to: 'ANV', attributes: { prediction: 64 }, }, { - id: 3046, + id: '3046', from: 'BNE', to: 'APW', attributes: { prediction: 470 }, }, { - id: 3047, + id: '3047', from: 'FRA', to: 'YYC', attributes: { prediction: 13995 }, }, { - id: 3048, + id: '3048', from: 'MCO', to: 'YYC', attributes: { prediction: 374 }, }, { - id: 3049, + id: '3049', from: 'LIS', to: 'YYZ', attributes: { prediction: 1649 }, }, { - id: 3050, + id: '3050', from: 'SPU', to: 'ZAG', attributes: { prediction: 10140 }, }, { - id: 3051, + id: '3051', from: 'RHO', to: 'ZQW', attributes: { prediction: 665 }, }, { - id: 3052, + id: '3052', from: 'CPH', to: 'ZRH', attributes: { prediction: 23377 }, }, { - id: 3053, + id: '3053', from: 'DOH', to: 'ZRH', attributes: { prediction: 5055 }, }, { - id: 3054, + id: '3054', from: 'GOT', to: 'ZRH', attributes: { prediction: 832 }, }, { - id: 3055, + id: '3055', from: 'LAX', to: 'ZRH', attributes: { prediction: 5788 }, }, { - id: 3056, + id: '3056', from: 'NBO', to: 'ZRH', attributes: { prediction: 5108 }, }, { - id: 3057, + id: '3057', from: 'RTM', to: 'AYT', attributes: { prediction: 472 }, }, { - id: 3058, + id: '3058', from: 'DXB', to: 'BAH', attributes: { prediction: 66757 }, }, { - id: 3059, + id: '3059', from: 'OTP', to: 'BCM', attributes: { prediction: 658 }, }, { - id: 3060, + id: '3060', from: 'DFW', to: 'ABQ', attributes: { prediction: 29605 }, }, { - id: 3061, + id: '3061', from: 'HAJ', to: 'ADB', attributes: { prediction: 1785 }, }, { - id: 3062, + id: '3062', from: 'MQX', to: 'ADD', attributes: { prediction: 4793 }, }, { - id: 3063, + id: '3063', from: 'PIK', to: 'AGP', attributes: { prediction: 2696 }, }, { - id: 3064, + id: '3064', from: 'PMI', to: 'AGP', attributes: { prediction: 15033 }, }, { - id: 3065, + id: '3065', from: 'LGW', to: 'AJA', attributes: { prediction: 114 }, }, { - id: 3066, + id: '3066', from: 'GOT', to: 'ALC', attributes: { prediction: 772 }, }, { - id: 3067, + id: '3067', from: 'ETZ', to: 'ALG', attributes: { prediction: 1287 }, }, { - id: 3068, + id: '3068', from: 'PMI', to: 'ALG', attributes: { prediction: 987 }, }, { - id: 3069, + id: '3069', from: 'DUS', to: 'AMS', attributes: { prediction: 7837 }, }, { - id: 3070, + id: '3070', from: 'KAN', to: 'AMS', attributes: { prediction: 2238 }, }, { - id: 3071, + id: '3071', from: 'SAH', to: 'BEY', attributes: { prediction: 707 }, }, { - id: 3072, + id: '3072', from: 'MAN', to: 'BFS', attributes: { prediction: 6365 }, }, { - id: 3073, + id: '3073', from: 'FRA', to: 'BGO', attributes: { prediction: 4258 }, }, { - id: 3074, + id: '3074', from: 'GRO', to: 'BGY', attributes: { prediction: 13415 }, }, { - id: 3075, + id: '3075', from: 'IAH', to: 'BHM', attributes: { prediction: 8769 }, }, { - id: 3076, + id: '3076', from: 'ORY', to: 'BIA', attributes: { prediction: 16482 }, }, { - id: 3077, + id: '3077', from: 'DEN', to: 'BIS', attributes: { prediction: 4330 }, }, { - id: 3078, + id: '3078', from: 'CPH', to: 'BKK', attributes: { prediction: 15001 }, }, { - id: 3079, + id: '3079', from: 'DXB', to: 'AUH', attributes: { prediction: 3461 }, }, { - id: 3080, + id: '3080', from: 'ECN', to: 'AYT', attributes: { prediction: 1670 }, }, { - id: 3081, + id: '3081', from: 'ALP', to: 'BAH', attributes: { prediction: 1046 }, }, { - id: 3082, + id: '3082', from: 'SYZ', to: 'BAH', attributes: { prediction: 3026 }, }, { - id: 3083, + id: '3083', from: 'AMM', to: 'BCN', attributes: { prediction: 835 }, }, { - id: 3084, + id: '3084', from: 'BRU', to: 'CMN', attributes: { prediction: 7142 }, }, { - id: 3085, + id: '3085', from: 'IOS', to: 'CNF', attributes: { prediction: 2920 }, }, { - id: 3086, + id: '3086', from: 'BLR', to: 'COK', attributes: { prediction: 12605 }, }, { - id: 3087, + id: '3087', from: 'BLQ', to: 'BOD', attributes: { prediction: 2202 }, }, { - id: 3088, + id: '3088', from: 'BBI', to: 'BOM', attributes: { prediction: 7013 }, }, { - id: 3089, + id: '3089', from: 'RET', to: 'BOO', attributes: { prediction: 295 }, }, { - id: 3090, + id: '3090', from: 'LHR', to: 'BOS', attributes: { prediction: 38162 }, }, { - id: 3091, + id: '3091', from: 'PIT', to: 'BOS', attributes: { prediction: 13096 }, }, { - id: 3092, + id: '3092', from: 'BHD', to: 'BRS', attributes: { prediction: 11144 }, }, { - id: 3093, + id: '3093', from: 'CPH', to: 'BRU', attributes: { prediction: 24249 }, }, { - id: 3094, + id: '3094', from: 'CTA', to: 'BSL', attributes: { prediction: 838 }, }, { - id: 3095, + id: '3095', from: 'NAP', to: 'BSL', attributes: { prediction: 1966 }, }, { - id: 3096, + id: '3096', from: 'TLV', to: 'BTS', attributes: { prediction: 1757 }, }, { - id: 3097, + id: '3097', from: 'DTM', to: 'BUD', attributes: { prediction: 1979 }, }, { - id: 3098, + id: '3098', from: 'AGP', to: 'CPH', attributes: { prediction: 12451 }, }, { - id: 3099, + id: '3099', from: 'MSP', to: 'BZN', attributes: { prediction: 6283 }, }, { - id: 3100, + id: '3100', from: 'SGN', to: 'CAH', attributes: { prediction: 1104 }, }, { - id: 3101, + id: '3101', from: 'KRT', to: 'CAI', attributes: { prediction: 22899 }, }, { - id: 3102, + id: '3102', from: 'TLV', to: 'CAI', attributes: { prediction: 3096 }, }, { - id: 3103, + id: '3103', from: 'VVI', to: 'CBB', attributes: { prediction: 13959 }, }, { - id: 3104, + id: '3104', from: 'HEA', to: 'CCN', attributes: { prediction: 82 }, }, { - id: 3105, + id: '3105', from: 'PBH', to: 'CCU', attributes: { prediction: 1079 }, }, { - id: 3106, + id: '3106', from: 'NAP', to: 'CDG', attributes: { prediction: 4552 }, }, { - id: 3107, + id: '3107', from: 'NCE', to: 'CDG', attributes: { prediction: 40980 }, }, { - id: 3108, + id: '3108', from: 'SGN', to: 'CDG', attributes: { prediction: 4216 }, }, { - id: 3109, + id: '3109', from: 'TNR', to: 'CDG', attributes: { prediction: 4045 }, }, { - id: 3110, + id: '3110', from: 'PSA', to: 'CGN', attributes: { prediction: 1842 }, }, { - id: 3111, + id: '3111', from: 'DFW', to: 'CHA', attributes: { prediction: 1152 }, }, { - id: 3112, + id: '3112', from: 'NAN', to: 'CHC', attributes: { prediction: 510 }, }, { - id: 3113, + id: '3113', from: 'WVB', to: 'CPT', attributes: { prediction: 1321 }, }, { - id: 3114, + id: '3114', from: 'MNL', to: 'CRM', attributes: { prediction: 2453 }, }, { - id: 3115, + id: '3115', from: 'SUB', to: 'BDJ', attributes: { prediction: 29897 }, }, { - id: 3116, + id: '3116', from: 'SHJ', to: 'BEY', attributes: { prediction: 5331 }, }, { - id: 3117, + id: '3117', from: 'HKT', to: 'DMK', attributes: { prediction: 9256 }, }, { - id: 3118, + id: '3118', from: 'DAC', to: 'DMM', attributes: { prediction: 776 }, }, { - id: 3119, + id: '3119', from: 'LOS', to: 'DOH', attributes: { prediction: 6109 }, }, { - id: 3120, + id: '3120', from: 'MKE', to: 'DTW', attributes: { prediction: 15695 }, }, { - id: 3121, + id: '3121', from: 'BOM', to: 'DAC', attributes: { prediction: 8088 }, }, { - id: 3122, + id: '3122', from: 'LCA', to: 'DAM', attributes: { prediction: 1316 }, }, { - id: 3123, + id: '3123', from: 'HAH', to: 'DAR', attributes: { prediction: 1536 }, }, { - id: 3124, + id: '3124', from: 'SYR', to: 'DAY', attributes: { prediction: 88 }, }, { - id: 3125, + id: '3125', from: 'GOP', to: 'DEL', attributes: { prediction: 818 }, }, { - id: 3126, + id: '3126', from: 'RUH', to: 'DEL', attributes: { prediction: 3948 }, }, { - id: 3127, + id: '3127', from: 'DSM', to: 'DEN', attributes: { prediction: 12295 }, }, { - id: 3128, + id: '3128', from: 'FLL', to: 'DEN', attributes: { prediction: 10529 }, }, { - id: 3129, + id: '3129', from: 'IDA', to: 'DEN', attributes: { prediction: 3378 }, }, { - id: 3130, + id: '3130', from: 'YQR', to: 'DEN', attributes: { prediction: 1899 }, }, { - id: 3131, + id: '3131', from: 'BNA', to: 'DFW', attributes: { prediction: 28451 }, }, { - id: 3132, + id: '3132', from: 'EVV', to: 'DFW', attributes: { prediction: 1213 }, }, { - id: 3133, + id: '3133', from: 'EWR', to: 'DUS', attributes: { prediction: 5246 }, }, { - id: 3134, + id: '3134', from: 'HDF', to: 'DUS', attributes: { prediction: 306 }, }, { - id: 3135, + id: '3135', from: 'KGS', to: 'DUS', attributes: { prediction: 2751 }, }, { - id: 3136, + id: '3136', from: 'IAH', to: 'BRO', attributes: { prediction: 5175 }, }, { - id: 3137, + id: '3137', from: 'MLA', to: 'BRU', attributes: { prediction: 4116 }, }, { - id: 3138, + id: '3138', from: 'PHL', to: 'BRU', attributes: { prediction: 2690 }, }, { - id: 3139, + id: '3139', from: 'NUE', to: 'FNC', attributes: { prediction: 554 }, }, { - id: 3140, + id: '3140', from: 'NDR', to: 'FRA', attributes: { prediction: 949 }, }, { - id: 3141, + id: '3141', from: 'NUE', to: 'FRA', attributes: { prediction: 15715 }, }, { - id: 3142, + id: '3142', from: 'ADF', to: 'ESB', attributes: { prediction: 1288 }, }, { - id: 3143, + id: '3143', from: 'FRA', to: 'EWR', attributes: { prediction: 23991 }, }, { - id: 3144, + id: '3144', from: 'BDS', to: 'FCO', attributes: { prediction: 19443 }, }, { - id: 3145, + id: '3145', from: 'EVN', to: 'FCO', attributes: { prediction: 1168 }, }, { - id: 3146, + id: '3146', from: 'POZ', to: 'FCO', attributes: { prediction: 1148 }, }, { - id: 3147, + id: '3147', from: 'SOG', to: 'FDE', attributes: { prediction: 31 }, }, { - id: 3148, + id: '3148', from: 'ALC', to: 'FEZ', attributes: { prediction: 1215 }, }, { - id: 3149, + id: '3149', from: 'BIM', to: 'FLL', attributes: { prediction: 237 }, }, { - id: 3150, + id: '3150', from: 'FRA', to: 'FLR', attributes: { prediction: 13531 }, }, { - id: 3151, + id: '3151', from: 'KMJ', to: 'FSZ', attributes: { prediction: 1371 }, }, { - id: 3152, + id: '3152', from: 'CGN', to: 'FUE', attributes: { prediction: 3075 }, }, { - id: 3153, + id: '3153', from: 'CTS', to: 'GAJ', attributes: { prediction: 950 }, }, { - id: 3154, + id: '3154', from: 'ADA', to: 'ESB', attributes: { prediction: 6445 }, }, { - id: 3155, + id: '3155', from: 'BJV', to: 'ESB', attributes: { prediction: 2004 }, }, { - id: 3156, + id: '3156', from: 'LED', to: 'EVN', attributes: { prediction: 503 }, }, { - id: 3157, + id: '3157', from: 'IAH', to: 'EWR', attributes: { prediction: 54169 }, }, { - id: 3158, + id: '3158', from: 'BHX', to: 'FAO', attributes: { prediction: 5792 }, }, { - id: 3159, + id: '3159', from: 'BRE', to: 'FAO', attributes: { prediction: 1308 }, }, { - id: 3160, + id: '3160', from: 'KBP', to: 'GYD', attributes: { prediction: 500 }, }, { - id: 3161, + id: '3161', from: 'DXB', to: 'HAM', attributes: { prediction: 9479 }, }, { - id: 3162, + id: '3162', from: 'OSL', to: 'HAU', attributes: { prediction: 10849 }, }, { - id: 3163, + id: '3163', from: 'CCN', to: 'HEA', attributes: { prediction: 73 }, }, { - id: 3164, + id: '3164', from: 'WWK', to: 'HGU', attributes: { prediction: 100 }, }, { - id: 3165, + id: '3165', from: 'PHL', to: 'GSP', attributes: { prediction: 2075 }, }, { - id: 3166, + id: '3166', from: 'CTS', to: 'GUM', attributes: { prediction: 861 }, }, { - id: 3167, + id: '3167', from: 'AYT', to: 'HAJ', attributes: { prediction: 5734 }, }, { - id: 3168, + id: '3168', from: 'SZX', to: 'HAK', attributes: { prediction: 8017 }, }, { - id: 3169, + id: '3169', from: 'SZX', to: 'HGH', attributes: { prediction: 40943 }, }, { - id: 3170, + id: '3170', from: 'NGB', to: 'HKG', attributes: { prediction: 6946 }, }, { - id: 3171, + id: '3171', from: 'SYD', to: 'HLZ', attributes: { prediction: 1279 }, }, { - id: 3172, + id: '3172', from: 'JFK', to: 'HKG', attributes: { prediction: 19034 }, }, { - id: 3173, + id: '3173', from: 'MUC', to: 'HKG', attributes: { prediction: 8102 }, }, { - id: 3174, + id: '3174', from: 'NRT', to: 'HKG', attributes: { prediction: 83625 }, }, { - id: 3175, + id: '3175', from: 'BHM', to: 'HOU', attributes: { prediction: 6459 }, }, { - id: 3176, + id: '3176', from: 'LAS', to: 'HOU', attributes: { prediction: 14851 }, }, { - id: 3177, + id: '3177', from: 'UFA', to: 'IST', attributes: { prediction: 1409 }, }, { - id: 3178, + id: '3178', from: 'DEL', to: 'IXB', attributes: { prediction: 9416 }, }, { - id: 3179, + id: '3179', from: 'BGY', to: 'OPO', attributes: { prediction: 2056 }, }, { - id: 3180, + id: '3180', from: 'BHM', to: 'ORD', attributes: { prediction: 3495 }, }, { - id: 3181, + id: '3181', from: 'BOS', to: 'LEB', attributes: { prediction: 1006 }, }, { - id: 3182, + id: '3182', from: 'LHR', to: 'LED', attributes: { prediction: 4716 }, }, { - id: 3183, + id: '3183', from: 'SXF', to: 'IST', attributes: { prediction: 2169 }, }, { - id: 3184, + id: '3184', from: 'TLV', to: 'IST', attributes: { prediction: 15053 }, }, { - id: 3185, + id: '3185', from: 'EWR', to: 'ITH', attributes: { prediction: 1978 }, }, { - id: 3186, + id: '3186', from: 'ISB', to: 'JED', attributes: { prediction: 2224 }, }, { - id: 3187, + id: '3187', from: 'BHX', to: 'JER', attributes: { prediction: 4307 }, }, { - id: 3188, + id: '3188', from: 'GEO', to: 'JFK', attributes: { prediction: 1839 }, }, { - id: 3189, + id: '3189', from: 'NRT', to: 'JFK', attributes: { prediction: 42692 }, }, { - id: 3190, + id: '3190', from: 'POS', to: 'JFK', attributes: { prediction: 14338 }, }, { - id: 3191, + id: '3191', from: 'MCI', to: 'JLN', attributes: { prediction: 728 }, }, { - id: 3192, + id: '3192', from: 'REC', to: 'JPA', attributes: { prediction: 5452 }, }, { - id: 3193, + id: '3193', from: 'DXB', to: 'LGW', attributes: { prediction: 25577 }, }, { - id: 3194, + id: '3194', from: 'NGO', to: 'KMJ', attributes: { prediction: 4741 }, }, { - id: 3195, + id: '3195', from: 'DXB', to: 'KRT', attributes: { prediction: 15919 }, }, { - id: 3196, + id: '3196', from: 'EGN', to: 'KRT', attributes: { prediction: 918 }, }, { - id: 3197, + id: '3197', from: 'BTS', to: 'KSC', attributes: { prediction: 2672 }, }, { - id: 3198, + id: '3198', from: 'BOM', to: 'KTM', attributes: { prediction: 3793 }, }, { - id: 3199, + id: '3199', from: 'IVL', to: 'KTT', attributes: { prediction: 154 }, }, { - id: 3200, + id: '3200', from: 'KSO', to: 'KZI', attributes: { prediction: 219 }, }, { - id: 3201, + id: '3201', from: 'ABQ', to: 'LAS', attributes: { prediction: 19402 }, }, { - id: 3202, + id: '3202', from: 'ORF', to: 'LAS', attributes: { prediction: 3549 }, }, { - id: 3203, + id: '3203', from: 'IAD', to: 'LAX', attributes: { prediction: 47824 }, }, { - id: 3204, + id: '3204', from: 'JFK', to: 'LAX', attributes: { prediction: 129906 }, }, { - id: 3205, + id: '3205', from: 'MSY', to: 'LAX', attributes: { prediction: 10920 }, }, { - id: 3206, + id: '3206', from: 'PPT', to: 'LAX', attributes: { prediction: 13024 }, }, { - id: 3207, + id: '3207', from: 'ALG', to: 'LHR', attributes: { prediction: 4220 }, }, { - id: 3208, + id: '3208', from: 'LCG', to: 'LHR', attributes: { prediction: 3782 }, }, { - id: 3209, + id: '3209', from: 'LIS', to: 'LIN', attributes: { prediction: 3036 }, }, { - id: 3210, + id: '3210', from: 'BRS', to: 'LIS', attributes: { prediction: 1453 }, }, { - id: 3211, + id: '3211', from: 'CLT', to: 'LIT', attributes: { prediction: 4776 }, }, { - id: 3212, + id: '3212', from: 'MYR', to: 'ORD', attributes: { prediction: 1146 }, }, { - id: 3213, + id: '3213', from: 'YVR', to: 'ORD', attributes: { prediction: 10076 }, }, { - id: 3214, + id: '3214', from: 'DXB', to: 'MCT', attributes: { prediction: 34173 }, }, { - id: 3215, + id: '3215', from: 'LGA', to: 'MDW', attributes: { prediction: 32972 }, }, { - id: 3216, + id: '3216', from: 'MKE', to: 'MEM', attributes: { prediction: 3984 }, }, { - id: 3217, + id: '3217', from: 'MLU', to: 'MEM', attributes: { prediction: 2286 }, }, { - id: 3218, + id: '3218', from: 'ADD', to: 'LOS', attributes: { prediction: 6455 }, }, { - id: 3219, + id: '3219', from: 'BSL', to: 'LPA', attributes: { prediction: 1939 }, }, { - id: 3220, + id: '3220', from: 'CNX', to: 'LPQ', attributes: { prediction: 1194 }, }, { - id: 3221, + id: '3221', from: 'DXB', to: 'LRR', attributes: { prediction: 1062 }, }, { - id: 3222, + id: '3222', from: 'MLA', to: 'LUX', attributes: { prediction: 169 }, }, { - id: 3223, + id: '3223', from: 'BCN', to: 'LXR', attributes: { prediction: 633 }, }, { - id: 3224, + id: '3224', from: 'SHJ', to: 'LXR', attributes: { prediction: 1317 }, }, { - id: 3225, + id: '3225', from: 'BOD', to: 'LYS', attributes: { prediction: 25727 }, }, { - id: 3226, + id: '3226', from: 'PUF', to: 'LYS', attributes: { prediction: 3863 }, }, { - id: 3227, + id: '3227', from: 'TOE', to: 'LYS', attributes: { prediction: 658 }, }, { - id: 3228, + id: '3228', from: 'LHR', to: 'MAA', attributes: { prediction: 4051 }, }, { - id: 3229, + id: '3229', from: 'TRN', to: 'MAD', attributes: { prediction: 5084 }, }, { - id: 3230, + id: '3230', from: 'KWA', to: 'MAJ', attributes: { prediction: 910 }, }, { - id: 3231, + id: '3231', from: 'WIL', to: 'MBA', attributes: { prediction: 1788 }, }, { - id: 3232, + id: '3232', from: 'FLL', to: 'MBJ', attributes: { prediction: 6011 }, }, { - id: 3233, + id: '3233', from: 'ECP', to: 'MCO', attributes: { prediction: 6493 }, }, { - id: 3234, + id: '3234', from: 'SLC', to: 'MEX', attributes: { prediction: 1695 }, }, { - id: 3235, + id: '3235', from: 'ADE', to: 'MGQ', attributes: { prediction: 381 }, }, { - id: 3236, + id: '3236', from: 'LAS', to: 'MHT', attributes: { prediction: 3543 }, }, { - id: 3237, + id: '3237', from: 'CTG', to: 'MIA', attributes: { prediction: 2524 }, }, { - id: 3238, + id: '3238', from: 'MHH', to: 'MIA', attributes: { prediction: 2330 }, }, { - id: 3239, + id: '3239', from: 'DYU', to: 'OVB', attributes: { prediction: 391 }, }, { - id: 3240, + id: '3240', from: 'GIG', to: 'PTY', attributes: { prediction: 3426 }, }, { - id: 3241, + id: '3241', from: 'JFK', to: 'PVG', attributes: { prediction: 5178 }, }, { - id: 3242, + id: '3242', from: 'EWR', to: 'PWM', attributes: { prediction: 6814 }, }, { - id: 3243, + id: '3243', from: 'MMO', to: 'RAI', attributes: { prediction: 180 }, }, { - id: 3244, + id: '3244', from: 'LED', to: 'NCE', attributes: { prediction: 967 }, }, { - id: 3245, + id: '3245', from: 'PQS', to: 'MOU', attributes: { prediction: 115 }, }, { - id: 3246, + id: '3246', from: 'CEB', to: 'MPH', attributes: { prediction: 3072 }, }, { - id: 3247, + id: '3247', from: 'CDG', to: 'MPL', attributes: { prediction: 16126 }, }, { - id: 3248, + id: '3248', from: 'MNL', to: 'MRQ', attributes: { prediction: 751 }, }, { - id: 3249, + id: '3249', from: 'LGA', to: 'MSN', attributes: { prediction: 1028 }, }, { - id: 3250, + id: '3250', from: 'TOH', to: 'MTV', attributes: { prediction: 48 }, }, { - id: 3251, + id: '3251', from: 'TIJ', to: 'MTY', attributes: { prediction: 6923 }, }, { - id: 3252, + id: '3252', from: 'SPU', to: 'MUC', attributes: { prediction: 2690 }, }, { - id: 3253, + id: '3253', from: 'AUH', to: 'MXP', attributes: { prediction: 4273 }, }, { - id: 3254, + id: '3254', from: 'BEY', to: 'MXP', attributes: { prediction: 1719 }, }, { - id: 3255, + id: '3255', from: 'MLA', to: 'MXP', attributes: { prediction: 4682 }, }, { - id: 3256, + id: '3256', from: 'MRU', to: 'MXP', attributes: { prediction: 1710 }, }, { - id: 3257, + id: '3257', from: 'SOF', to: 'MXP', attributes: { prediction: 3510 }, }, { - id: 3258, + id: '3258', from: 'LUX', to: 'NAP', attributes: { prediction: 185 }, }, { - id: 3259, + id: '3259', from: 'HUH', to: 'RFP', attributes: { prediction: 520 }, }, { - id: 3260, + id: '3260', from: 'DEN', to: 'RNO', attributes: { prediction: 11370 }, }, { - id: 3261, + id: '3261', from: 'LAX', to: 'RDD', attributes: { prediction: 1347 }, }, { - id: 3262, + id: '3262', from: 'EWR', to: 'RDU', attributes: { prediction: 13165 }, }, { - id: 3263, + id: '3263', from: 'ATH', to: 'RHO', attributes: { prediction: 45986 }, }, { - id: 3264, + id: '3264', from: 'PRG', to: 'RHO', attributes: { prediction: 2201 }, }, { - id: 3265, + id: '3265', from: 'MIA', to: 'RIC', attributes: { prediction: 1303 }, }, { - id: 3266, + id: '3266', from: 'KUN', to: 'RIX', attributes: { prediction: 1928 }, }, { - id: 3267, + id: '3267', from: 'TLS', to: 'RNS', attributes: { prediction: 3185 }, }, { - id: 3268, + id: '3268', from: 'ORD', to: 'ROA', attributes: { prediction: 3878 }, }, { - id: 3269, + id: '3269', from: 'PAH', to: 'ORD', attributes: { prediction: 2385 }, }, { - id: 3270, + id: '3270', from: 'BNA', to: 'ORF', attributes: { prediction: 3261 }, }, { - id: 3271, + id: '3271', from: 'BIA', to: 'ORY', attributes: { prediction: 15749 }, }, { - id: 3272, + id: '3272', from: 'DUS', to: 'ORY', attributes: { prediction: 3977 }, }, { - id: 3273, + id: '3273', from: 'FAO', to: 'OSL', attributes: { prediction: 1057 }, }, { - id: 3274, + id: '3274', from: 'DUB', to: 'OTP', attributes: { prediction: 2365 }, }, { - id: 3275, + id: '3275', from: 'FRL', to: 'OTP', attributes: { prediction: 986 }, }, { - id: 3276, + id: '3276', from: 'OMR', to: 'OTP', attributes: { prediction: 1820 }, }, { - id: 3277, + id: '3277', from: 'MAN', to: 'PAD', attributes: { prediction: 2038 }, }, { - id: 3278, + id: '3278', from: 'ELV', to: 'PEC', attributes: { prediction: 1 }, }, { - id: 3279, + id: '3279', from: 'BWN', to: 'PER', attributes: { prediction: 2546 }, }, { - id: 3280, + id: '3280', from: 'MEL', to: 'PER', attributes: { prediction: 65191 }, }, { - id: 3281, + id: '3281', from: 'MHT', to: 'PHL', attributes: { prediction: 24439 }, }, { - id: 3282, + id: '3282', from: 'BOO', to: 'RYG', attributes: { prediction: 3321 }, }, { - id: 3283, + id: '3283', from: 'DXB', to: 'SAH', attributes: { prediction: 9672 }, }, { - id: 3284, + id: '3284', from: 'LBA', to: 'PMI', attributes: { prediction: 6265 }, }, { - id: 3285, + id: '3285', from: 'TKK', to: 'PNI', attributes: { prediction: 1040 }, }, { - id: 3286, + id: '3286', from: 'SSA', to: 'PNZ', attributes: { prediction: 647 }, }, { - id: 3287, + id: '3287', from: 'CRL', to: 'PRG', attributes: { prediction: 3279 }, }, { - id: 3288, + id: '3288', from: 'ZAG', to: 'PRG', attributes: { prediction: 1499 }, }, { - id: 3289, + id: '3289', from: 'TIA', to: 'PRN', attributes: { prediction: 1820 }, }, { - id: 3290, + id: '3290', from: 'CCS', to: 'PTY', attributes: { prediction: 15444 }, }, { - id: 3291, + id: '3291', from: 'MEX', to: 'PTY', attributes: { prediction: 8508 }, }, { - id: 3292, + id: '3292', from: 'MAD', to: 'PUJ', attributes: { prediction: 4099 }, }, { - id: 3293, + id: '3293', from: 'LGW', to: 'PUY', attributes: { prediction: 933 }, }, { - id: 3294, + id: '3294', from: 'YYC', to: 'PVR', attributes: { prediction: 1272 }, }, { - id: 3295, + id: '3295', from: 'CTU', to: 'PZI', attributes: { prediction: 4502 }, }, { - id: 3296, + id: '3296', from: 'JFK', to: 'SAN', attributes: { prediction: 24126 }, }, { - id: 3297, + id: '3297', from: 'MIA', to: 'SAP', attributes: { prediction: 11103 }, }, { - id: 3298, + id: '3298', from: 'TGU', to: 'SAP', attributes: { prediction: 4115 }, }, { - id: 3299, + id: '3299', from: 'ATL', to: 'SAT', attributes: { prediction: 33584 }, }, { - id: 3300, + id: '3300', from: 'CCP', to: 'SCL', attributes: { prediction: 15269 }, }, { - id: 3301, + id: '3301', from: 'PUJ', to: 'SCL', attributes: { prediction: 777 }, }, { - id: 3302, + id: '3302', from: 'LAD', to: 'SDD', attributes: { prediction: 341 }, }, { - id: 3303, + id: '3303', from: 'ITM', to: 'SDJ', attributes: { prediction: 41559 }, }, { - id: 3304, + id: '3304', from: 'PAP', to: 'SDQ', attributes: { prediction: 1271 }, }, { - id: 3305, + id: '3305', from: 'ABZ', to: 'SOU', attributes: { prediction: 234 }, }, { - id: 3306, + id: '3306', from: 'MAN', to: 'SSH', attributes: { prediction: 8805 }, }, { - id: 3307, + id: '3307', from: 'DUS', to: 'STN', attributes: { prediction: 9821 }, }, { - id: 3308, + id: '3308', from: 'BIL', to: 'SDY', attributes: { prediction: 238 }, }, { - id: 3309, + id: '3309', from: 'CUN', to: 'SEA', attributes: { prediction: 104 }, }, { - id: 3310, + id: '3310', from: 'PHX', to: 'SEA', attributes: { prediction: 49603 }, }, { - id: 3311, + id: '3311', from: 'BAH', to: 'SHJ', attributes: { prediction: 6725 }, }, { - id: 3312, + id: '3312', from: 'AUH', to: 'SIN', attributes: { prediction: 7907 }, }, { - id: 3313, + id: '3313', from: 'VKO', to: 'SIP', attributes: { prediction: 487 }, }, { - id: 3314, + id: '3314', from: 'BUR', to: 'SJC', attributes: { prediction: 21530 }, }, { - id: 3315, + id: '3315', from: 'SBA', to: 'SJC', attributes: { prediction: 2571 }, }, { - id: 3316, + id: '3316', from: 'IAH', to: 'SJU', attributes: { prediction: 3945 }, }, { - id: 3317, + id: '3317', from: 'MUC', to: 'SKG', attributes: { prediction: 11894 }, }, { - id: 3318, + id: '3318', from: 'KWI', to: 'SKT', attributes: { prediction: 735 }, }, { - id: 3319, + id: '3319', from: 'BUR', to: 'SMF', attributes: { prediction: 21896 }, }, { - id: 3320, + id: '3320', from: 'BWN', to: 'SUB', attributes: { prediction: 1227 }, }, { - id: 3321, + id: '3321', from: 'BLQ', to: 'SUF', attributes: { prediction: 7109 }, }, { - id: 3322, + id: '3322', from: 'MSP', to: 'SUX', attributes: { prediction: 1707 }, }, { - id: 3323, + id: '3323', from: 'SXF', to: 'SVG', attributes: { prediction: 854 }, }, { - id: 3324, + id: '3324', from: 'CSX', to: 'SWA', attributes: { prediction: 4207 }, }, { - id: 3325, + id: '3325', from: 'LSY', to: 'SYD', attributes: { prediction: 2499 }, }, { - id: 3326, + id: '3326', from: 'PTP', to: 'SJU', attributes: { prediction: 1602 }, }, { - id: 3327, + id: '3327', from: 'YYZ', to: 'SJU', attributes: { prediction: 684 }, }, { - id: 3328, + id: '3328', from: 'HGH', to: 'TSN', attributes: { prediction: 4336 }, }, { - id: 3329, + id: '3329', from: 'GWD', to: 'TUK', attributes: { prediction: 432 }, }, { - id: 3330, + id: '3330', from: 'OKA', to: 'TAK', attributes: { prediction: 4521 }, }, { - id: 3331, + id: '3331', from: 'KUL', to: 'TGG', attributes: { prediction: 12947 }, }, { - id: 3332, + id: '3332', from: 'BEG', to: 'TIV', attributes: { prediction: 2937 }, }, { - id: 3333, + id: '3333', from: 'CUN', to: 'TLC', attributes: { prediction: 18045 }, }, { - id: 3334, + id: '3334', from: 'SZX', to: 'TNA', attributes: { prediction: 1534 }, }, { - id: 3335, + id: '3335', from: 'ORY', to: 'TOE', attributes: { prediction: 1581 }, }, { - id: 3336, + id: '3336', from: 'SSJ', to: 'TRD', attributes: { prediction: 139 }, }, { - id: 3337, + id: '3337', from: 'RHO', to: 'TXL', attributes: { prediction: 1005 }, }, { - id: 3338, + id: '3338', from: 'MEM', to: 'TYS', attributes: { prediction: 3987 }, }, { - id: 3339, + id: '3339', from: 'PIE', to: 'TYS', attributes: { prediction: 2075 }, }, { - id: 3340, + id: '3340', from: 'KGF', to: 'UKK', attributes: { prediction: 224 }, }, { - id: 3341, + id: '3341', from: 'DLA', to: 'ZRH', attributes: { prediction: 2759 }, }, { - id: 3342, + id: '3342', from: 'NUE', to: 'ZRH', attributes: { prediction: 6967 }, }, { - id: 3343, + id: '3343', from: 'SJU', to: 'AXA', attributes: { prediction: 1584 }, }, { - id: 3344, + id: '3344', from: 'LCA', to: 'BBU', attributes: { prediction: 2042 }, }, { - id: 3345, + id: '3345', from: 'ARN', to: 'BCN', attributes: { prediction: 9272 }, }, { - id: 3346, + id: '3346', from: 'LCG', to: 'BCN', attributes: { prediction: 6659 }, }, { - id: 3347, + id: '3347', from: 'SVQ', to: 'BCN', attributes: { prediction: 12213 }, }, { - id: 3348, + id: '3348', from: 'TNG', to: 'BCN', attributes: { prediction: 136 }, }, { - id: 3349, + id: '3349', from: 'ORD', to: 'BDL', attributes: { prediction: 19030 }, }, { - id: 3350, + id: '3350', from: 'DPS', to: 'BDO', attributes: { prediction: 4533 }, }, { - id: 3351, + id: '3351', from: 'IOM', to: 'BFS', attributes: { prediction: 524 }, }, { - id: 3352, + id: '3352', from: 'PHL', to: 'BGM', attributes: { prediction: 3248 }, }, { - id: 3353, + id: '3353', from: 'TBS', to: 'WAW', attributes: { prediction: 986 }, }, { - id: 3354, + id: '3354', from: 'DFW', to: 'XNA', attributes: { prediction: 14514 }, }, { - id: 3355, + id: '3355', from: 'FRA', to: 'XRY', attributes: { prediction: 2666 }, }, { - id: 3356, + id: '3356', from: 'LYG', to: 'XUZ', attributes: { prediction: 1787 }, }, { - id: 3357, + id: '3357', from: 'CDV', to: 'YAK', attributes: { prediction: 1336 }, }, { - id: 3358, + id: '3358', from: 'LAX', to: 'YEG', attributes: { prediction: 3229 }, }, { - id: 3359, + id: '3359', from: 'YQD', to: 'YFO', attributes: { prediction: 357 }, }, { - id: 3360, + id: '3360', from: 'YKU', to: 'YKQ', attributes: { prediction: 707 }, }, { - id: 3361, + id: '3361', from: 'EWR', to: 'YOW', attributes: { prediction: 4038 }, }, { - id: 3362, + id: '3362', from: 'YZF', to: 'YRA', attributes: { prediction: 224 }, }, { - id: 3363, + id: '3363', from: 'YCS', to: 'YRT', attributes: { prediction: 96 }, }, { - id: 3364, + id: '3364', from: 'DOK', to: 'BUS', attributes: { prediction: 112 }, }, { - id: 3365, + id: '3365', from: 'DAM', to: 'CAI', attributes: { prediction: 7190 }, }, { - id: 3366, + id: '3366', from: 'DUS', to: 'CAI', attributes: { prediction: 2166 }, }, { - id: 3367, + id: '3367', from: 'VVI', to: 'CBB', attributes: { prediction: 24130 }, }, { - id: 3368, + id: '3368', from: 'DAM', to: 'CCS', attributes: { prediction: 2141 }, }, { - id: 3369, + id: '3369', from: 'BOS', to: 'CDG', attributes: { prediction: 11636 }, }, { - id: 3370, + id: '3370', from: 'SXM', to: 'CDG', attributes: { prediction: 6034 }, }, { - id: 3371, + id: '3371', from: 'CGR', to: 'CGB', attributes: { prediction: 20328 }, }, { - id: 3372, + id: '3372', from: 'ICN', to: 'CGO', attributes: { prediction: 1716 }, }, { - id: 3373, + id: '3373', from: 'ACC', to: 'ABJ', attributes: { prediction: 3887 }, }, { - id: 3374, + id: '3374', from: 'OUA', to: 'ABJ', attributes: { prediction: 632 }, }, { - id: 3375, + id: '3375', from: 'TLC', to: 'ACA', attributes: { prediction: 5530 }, }, { - id: 3376, + id: '3376', from: 'KLN', to: 'ADQ', attributes: { prediction: 267 }, }, { - id: 3377, + id: '3377', from: 'CPH', to: 'AGP', attributes: { prediction: 3296 }, }, { - id: 3378, + id: '3378', from: 'GSE', to: 'AGP', attributes: { prediction: 1202 }, }, { - id: 3379, + id: '3379', from: 'SNN', to: 'AGP', attributes: { prediction: 1611 }, }, { - id: 3380, + id: '3380', from: 'ICN', to: 'ALA', attributes: { prediction: 1521 }, }, { - id: 3381, + id: '3381', from: 'TFS', to: 'ALC', attributes: { prediction: 930 }, }, { - id: 3382, + id: '3382', from: 'MSP', to: 'AMS', attributes: { prediction: 12744 }, }, { - id: 3383, + id: '3383', from: 'SEA', to: 'CUN', attributes: { prediction: 4867 }, }, { - id: 3384, + id: '3384', from: 'LEX', to: 'CVG', attributes: { prediction: 3177 }, }, { - id: 3385, + id: '3385', from: 'PER', to: 'HKG', attributes: { prediction: 10696 }, }, { - id: 3386, + id: '3386', from: 'IAH', to: 'HNL', attributes: { prediction: 14570 }, }, { - id: 3387, + id: '3387', from: 'SHE', to: 'CJU', attributes: { prediction: 663 }, }, { - id: 3388, + id: '3388', from: 'DAB', to: 'CLT', attributes: { prediction: 5672 }, }, { - id: 3389, + id: '3389', from: 'JAX', to: 'BHM', attributes: { prediction: 2767 }, }, { - id: 3390, + id: '3390', from: 'ACC', to: 'BJL', attributes: { prediction: 1386 }, }, { - id: 3391, + id: '3391', from: 'NCE', to: 'BLL', attributes: { prediction: 366 }, }, { - id: 3392, + id: '3392', from: 'RNO', to: 'BOI', attributes: { prediction: 5633 }, }, { - id: 3393, + id: '3393', from: 'MQN', to: 'BOO', attributes: { prediction: 1464 }, }, { - id: 3394, + id: '3394', from: 'SEA', to: 'BOS', attributes: { prediction: 5483 }, }, { - id: 3395, + id: '3395', from: 'PHX', to: 'CMH', attributes: { prediction: 10003 }, }, { - id: 3396, + id: '3396', from: 'PSA', to: 'CND', attributes: { prediction: 850 }, }, { - id: 3397, + id: '3397', from: 'CGH', to: 'CNF', attributes: { prediction: 67866 }, }, { - id: 3398, + id: '3398', from: 'ARN', to: 'CPH', attributes: { prediction: 38751 }, }, { - id: 3399, + id: '3399', from: 'PDG', to: 'BTH', attributes: { prediction: 6172 }, }, { - id: 3400, + id: '3400', from: 'AET', to: 'BTT', attributes: { prediction: 117 }, }, { - id: 3401, + id: '3401', from: 'BRS', to: 'BUD', attributes: { prediction: 1347 }, }, { - id: 3402, + id: '3402', from: 'VAR', to: 'BUD', attributes: { prediction: 1303 }, }, { - id: 3403, + id: '3403', from: 'NRN', to: 'BZR', attributes: { prediction: 1154 }, }, { - id: 3404, + id: '3404', from: 'PEN', to: 'CAN', attributes: { prediction: 1668 }, }, { - id: 3405, + id: '3405', from: 'JFK', to: 'CCS', attributes: { prediction: 1310 }, }, { - id: 3406, + id: '3406', from: 'VIG', to: 'CCS', attributes: { prediction: 9560 }, }, { - id: 3407, + id: '3407', from: 'ABJ', to: 'CDG', attributes: { prediction: 8399 }, }, { - id: 3408, + id: '3408', from: 'JFK', to: 'CDG', attributes: { prediction: 38937 }, }, { - id: 3409, + id: '3409', from: 'LIN', to: 'CDG', attributes: { prediction: 8782 }, }, { - id: 3410, + id: '3410', from: 'LIS', to: 'CDG', attributes: { prediction: 22122 }, }, { - id: 3411, + id: '3411', from: 'MRS', to: 'CDG', attributes: { prediction: 26251 }, }, { - id: 3412, + id: '3412', from: 'ROO', to: 'CGB', attributes: { prediction: 999 }, }, { - id: 3413, + id: '3413', from: 'HKG', to: 'CGK', attributes: { prediction: 29583 }, }, { - id: 3414, + id: '3414', from: 'VIE', to: 'CPH', attributes: { prediction: 14793 }, }, { - id: 3415, + id: '3415', from: 'DTW', to: 'CUN', attributes: { prediction: 1798 }, }, { - id: 3416, + id: '3416', from: 'GOH', to: 'JFR', attributes: { prediction: 700 }, }, { - id: 3417, + id: '3417', from: 'DXB', to: 'JNB', attributes: { prediction: 29756 }, }, { - id: 3418, + id: '3418', from: 'UTT', to: 'JNB', attributes: { prediction: 1032 }, }, { - id: 3419, + id: '3419', from: 'EVV', to: 'DTW', attributes: { prediction: 3367 }, }, { - id: 3420, + id: '3420', from: 'CCF', to: 'DUB', attributes: { prediction: 1716 }, }, { - id: 3421, + id: '3421', from: 'JNB', to: 'DUR', attributes: { prediction: 107579 }, }, { - id: 3422, + id: '3422', from: 'KRK', to: 'DUS', attributes: { prediction: 2916 }, }, { - id: 3423, + id: '3423', from: 'SDP', to: 'DUT', attributes: { prediction: 251 }, }, { - id: 3424, + id: '3424', from: 'AMS', to: 'DXB', attributes: { prediction: 26145 }, }, { - id: 3425, + id: '3425', from: 'IXB', to: 'DEL', attributes: { prediction: 8035 }, }, { - id: 3426, + id: '3426', from: 'TPE', to: 'DEL', attributes: { prediction: 4741 }, }, { - id: 3427, + id: '3427', from: 'SAW', to: 'DIY', attributes: { prediction: 4172 }, }, { - id: 3428, + id: '3428', from: 'PHC', to: 'DLA', attributes: { prediction: 373 }, }, { - id: 3429, + id: '3429', from: 'CGO', to: 'DLC', attributes: { prediction: 4608 }, }, { - id: 3430, + id: '3430', from: 'HIJ', to: 'DLC', attributes: { prediction: 3091 }, }, { - id: 3431, + id: '3431', from: 'HKG', to: 'DLC', attributes: { prediction: 3120 }, }, { - id: 3432, + id: '3432', from: 'ZRH', to: 'DOH', attributes: { prediction: 5386 }, }, { - id: 3433, + id: '3433', from: 'DUS', to: 'DRS', attributes: { prediction: 14280 }, }, { - id: 3434, + id: '3434', from: 'SYD', to: 'DRW', attributes: { prediction: 9357 }, }, { - id: 3435, + id: '3435', from: 'JIB', to: 'DXB', attributes: { prediction: 1956 }, }, { - id: 3436, + id: '3436', from: 'NCE', to: 'DXB', attributes: { prediction: 5825 }, }, { - id: 3437, + id: '3437', from: 'ABZ', to: 'EBJ', attributes: { prediction: 343 }, }, { - id: 3438, + id: '3438', from: 'AMM', to: 'EBL', attributes: { prediction: 736 }, }, { - id: 3439, + id: '3439', from: 'ZTH', to: 'EFL', attributes: { prediction: 122 }, }, { - id: 3440, + id: '3440', from: 'GRO', to: 'EMA', attributes: { prediction: 2538 }, }, { - id: 3441, + id: '3441', from: 'LHR', to: 'KEF', attributes: { prediction: 6157 }, }, { - id: 3442, + id: '3442', from: 'HRB', to: 'KIJ', attributes: { prediction: 1675 }, }, { - id: 3443, + id: '3443', from: 'PLS', to: 'KIN', attributes: { prediction: 208 }, }, { - id: 3444, + id: '3444', from: 'ALC', to: 'KIR', attributes: { prediction: 1325 }, }, { - id: 3445, + id: '3445', from: 'SVO', to: 'KLV', attributes: { prediction: 1378 }, }, { - id: 3446, + id: '3446', from: 'ARN', to: 'KRN', attributes: { prediction: 2346 }, }, { - id: 3447, + id: '3447', from: 'BLQ', to: 'GRO', attributes: { prediction: 4139 }, }, { - id: 3448, + id: '3448', from: 'MSP', to: 'FAR', attributes: { prediction: 10869 }, }, { - id: 3449, + id: '3449', from: 'MJM', to: 'FIH', attributes: { prediction: 1260 }, }, { - id: 3450, + id: '3450', from: 'TPA', to: 'FLL', attributes: { prediction: 32133 }, }, { - id: 3451, + id: '3451', from: 'FDH', to: 'FRA', attributes: { prediction: 3250 }, }, { - id: 3452, + id: '3452', from: 'SIN', to: 'FRA', attributes: { prediction: 37548 }, }, { - id: 3453, + id: '3453', from: 'DEN', to: 'GCK', attributes: { prediction: 1127 }, }, { - id: 3454, + id: '3454', from: 'LAX', to: 'GDL', attributes: { prediction: 32086 }, }, { - id: 3455, + id: '3455', from: 'ATL', to: 'GIG', attributes: { prediction: 5632 }, }, { - id: 3456, + id: '3456', from: 'REC', to: 'GIG', attributes: { prediction: 42627 }, }, { - id: 3457, + id: '3457', from: 'BCN', to: 'GRX', attributes: { prediction: 5800 }, }, { - id: 3458, + id: '3458', from: 'SEA', to: 'GTF', attributes: { prediction: 2972 }, }, { - id: 3459, + id: '3459', from: 'MYY', to: 'LGL', attributes: { prediction: 16 }, }, { - id: 3460, + id: '3460', from: 'BEL', to: 'PBM', attributes: { prediction: 497 }, }, { - id: 3461, + id: '3461', from: 'RGA', to: 'RGL', attributes: { prediction: 945 }, }, { - id: 3462, + id: '3462', from: 'HAM', to: 'RIX', attributes: { prediction: 2670 }, }, { - id: 3463, + id: '3463', from: 'CRK', to: 'KUL', attributes: { prediction: 4209 }, }, { - id: 3464, + id: '3464', from: 'XMN', to: 'KUL', attributes: { prediction: 7062 }, }, { - id: 3465, + id: '3465', from: 'LCA', to: 'KWI', attributes: { prediction: 614 }, }, { - id: 3466, + id: '3466', from: 'CJU', to: 'KWJ', attributes: { prediction: 15622 }, }, { - id: 3467, + id: '3467', from: 'MAN', to: 'LAS', attributes: { prediction: 860 }, }, { - id: 3468, + id: '3468', from: 'PSP', to: 'LAX', attributes: { prediction: 4368 }, }, { - id: 3469, + id: '3469', from: 'AMD', to: 'HYD', attributes: { prediction: 9730 }, }, { - id: 3470, + id: '3470', from: 'JAX', to: 'IAD', attributes: { prediction: 5098 }, }, { - id: 3471, + id: '3471', from: 'CLT', to: 'IAH', attributes: { prediction: 34369 }, }, { - id: 3472, + id: '3472', from: 'LNK', to: 'IAH', attributes: { prediction: 40 }, }, { - id: 3473, + id: '3473', from: 'MAF', to: 'IAH', attributes: { prediction: 7542 }, }, { - id: 3474, + id: '3474', from: 'SJU', to: 'IAH', attributes: { prediction: 8488 }, }, { - id: 3475, + id: '3475', from: 'BNE', to: 'ICN', attributes: { prediction: 4984 }, }, { - id: 3476, + id: '3476', from: 'NGO', to: 'ICN', attributes: { prediction: 25317 }, }, { - id: 3477, + id: '3477', from: 'PEK', to: 'ICN', attributes: { prediction: 55983 }, }, { - id: 3478, + id: '3478', from: 'BAH', to: 'ISB', attributes: { prediction: 2044 }, }, { - id: 3479, + id: '3479', from: 'FLL', to: 'ISP', attributes: { prediction: 6700 }, }, { - id: 3480, + id: '3480', from: 'FRU', to: 'IST', attributes: { prediction: 3458 }, }, { - id: 3481, + id: '3481', from: 'CGP', to: 'JED', attributes: { prediction: 2882 }, }, { - id: 3482, + id: '3482', from: 'DEN', to: 'JFK', attributes: { prediction: 4164 }, }, { - id: 3483, + id: '3483', from: 'SJU', to: 'JFK', attributes: { prediction: 23336 }, }, { - id: 3484, + id: '3484', from: 'GRU', to: 'JNB', attributes: { prediction: 11584 }, }, { - id: 3485, + id: '3485', from: 'FRA', to: 'KBP', attributes: { prediction: 10720 }, }, { - id: 3486, + id: '3486', from: 'IMK', to: 'KEP', attributes: { prediction: 44 }, }, { - id: 3487, + id: '3487', from: 'SYZ', to: 'KIH', attributes: { prediction: 1104 }, }, { - id: 3488, + id: '3488', from: 'SGN', to: 'KIX', attributes: { prediction: 5672 }, }, { - id: 3489, + id: '3489', from: 'NYO', to: 'KLU', attributes: { prediction: 417 }, }, { - id: 3490, + id: '3490', from: 'ICN', to: 'KMJ', attributes: { prediction: 1184 }, }, { - id: 3491, + id: '3491', from: 'KTN', to: 'KPB', attributes: { prediction: 156 }, }, { - id: 3492, + id: '3492', from: 'LED', to: 'KRR', attributes: { prediction: 1436 }, }, { - id: 3493, + id: '3493', from: 'AMS', to: 'KRS', attributes: { prediction: 3082 }, }, { - id: 3494, + id: '3494', from: 'SVG', to: 'KRS', attributes: { prediction: 1325 }, }, { - id: 3495, + id: '3495', from: 'AMM', to: 'KRT', attributes: { prediction: 2503 }, }, { - id: 3496, + id: '3496', from: 'AER', to: 'LED', attributes: { prediction: 2438 }, }, { - id: 3497, + id: '3497', from: 'OVB', to: 'LED', attributes: { prediction: 2706 }, }, { - id: 3498, + id: '3498', from: 'LCR', to: 'LET', attributes: { prediction: 88 }, }, { - id: 3499, + id: '3499', from: 'MCO', to: 'LGA', attributes: { prediction: 20360 }, }, { - id: 3500, + id: '3500', from: 'EYW', to: 'RSW', attributes: { prediction: 1084 }, }, { - id: 3501, + id: '3501', from: 'LCA', to: 'RUH', attributes: { prediction: 504 }, }, { - id: 3502, + id: '3502', from: 'RAH', to: 'RUH', attributes: { prediction: 1436 }, }, { - id: 3503, + id: '3503', from: 'MHK', to: 'MCK', attributes: { prediction: 230 }, }, { - id: 3504, + id: '3504', from: 'MIA', to: 'MCO', attributes: { prediction: 36538 }, }, { - id: 3505, + id: '3505', from: 'JAI', to: 'MCT', attributes: { prediction: 2828 }, }, { - id: 3506, + id: '3506', from: 'KUL', to: 'MDC', attributes: { prediction: 2155 }, }, { - id: 3507, + id: '3507', from: 'PHX', to: 'MDW', attributes: { prediction: 23505 }, }, { - id: 3508, + id: '3508', from: 'YYZ', to: 'LHE', attributes: { prediction: 1645 }, }, { - id: 3509, + id: '3509', from: 'ORD', to: 'LHR', attributes: { prediction: 39966 }, }, { - id: 3510, + id: '3510', from: 'IQT', to: 'LIM', attributes: { prediction: 15421 }, }, { - id: 3511, + id: '3511', from: 'LAX', to: 'LIM', attributes: { prediction: 9670 }, }, { - id: 3512, + id: '3512', from: 'GVA', to: 'LIS', attributes: { prediction: 10075 }, }, { - id: 3513, + id: '3513', from: 'ZRH', to: 'LJU', attributes: { prediction: 2835 }, }, { - id: 3514, + id: '3514', from: 'LAP', to: 'LMM', attributes: { prediction: 824 }, }, { - id: 3515, + id: '3515', from: 'MIA', to: 'LNK', attributes: { prediction: 115 }, }, { - id: 3516, + id: '3516', from: 'GRO', to: 'LPA', attributes: { prediction: 2397 }, }, { - id: 3517, + id: '3517', from: 'SHE', to: 'LYG', attributes: { prediction: 568 }, }, { - id: 3518, + id: '3518', from: 'BOS', to: 'MAD', attributes: { prediction: 2108 }, }, { - id: 3519, + id: '3519', from: 'SDR', to: 'MAD', attributes: { prediction: 10458 }, }, { - id: 3520, + id: '3520', from: 'PUJ', to: 'MAN', attributes: { prediction: 1809 }, }, { - id: 3521, + id: '3521', from: 'MIA', to: 'MAO', attributes: { prediction: 4609 }, }, { - id: 3522, + id: '3522', from: 'MEM', to: 'MBJ', attributes: { prediction: 2745 }, }, { - id: 3523, + id: '3523', from: 'SAT', to: 'MEX', attributes: { prediction: 5488 }, }, { - id: 3524, + id: '3524', from: 'CLO', to: 'MIA', attributes: { prediction: 7017 }, }, { - id: 3525, + id: '3525', from: 'PTP', to: 'MIA', attributes: { prediction: 121 }, }, { - id: 3526, + id: '3526', from: 'SYD', to: 'MIM', attributes: { prediction: 266 }, }, { - id: 3527, + id: '3527', from: 'ADE', to: 'SAH', attributes: { prediction: 11058 }, }, { - id: 3528, + id: '3528', from: 'ZRH', to: 'SAW', attributes: { prediction: 2854 }, }, { - id: 3529, + id: '3529', from: 'SEA', to: 'SMF', attributes: { prediction: 32991 }, }, { - id: 3530, + id: '3530', from: 'OAK', to: 'SNA', attributes: { prediction: 20100 }, }, { - id: 3531, + id: '3531', from: 'WNP', to: 'MNL', attributes: { prediction: 9695 }, }, { - id: 3532, + id: '3532', from: 'DUR', to: 'MQP', attributes: { prediction: 1055 }, }, { - id: 3533, + id: '3533', from: 'AUS', to: 'MSN', attributes: { prediction: 85 }, }, { - id: 3534, + id: '3534', from: 'LAX', to: 'MSO', attributes: { prediction: 903 }, }, { - id: 3535, + id: '3535', from: 'INL', to: 'MSP', attributes: { prediction: 1206 }, }, { - id: 3536, + id: '3536', from: 'MCO', to: 'MSP', attributes: { prediction: 17919 }, }, { - id: 3537, + id: '3537', from: 'IST', to: 'MSQ', attributes: { prediction: 2008 }, }, { - id: 3538, + id: '3538', from: 'JNB', to: 'MTS', attributes: { prediction: 2002 }, }, { - id: 3539, + id: '3539', from: 'DOH', to: 'MUC', attributes: { prediction: 6836 }, }, { - id: 3540, + id: '3540', from: 'LCY', to: 'MUC', attributes: { prediction: 3982 }, }, { - id: 3541, + id: '3541', from: 'OSL', to: 'MUC', attributes: { prediction: 7573 }, }, { - id: 3542, + id: '3542', from: 'TLV', to: 'MUC', attributes: { prediction: 5332 }, }, { - id: 3543, + id: '3543', from: 'TRS', to: 'MUC', attributes: { prediction: 4439 }, }, { - id: 3544, + id: '3544', from: 'CUL', to: 'MXL', attributes: { prediction: 1767 }, }, { - id: 3545, + id: '3545', from: 'BUD', to: 'MXP', attributes: { prediction: 7466 }, }, { - id: 3546, + id: '3546', from: 'WAW', to: 'MXP', attributes: { prediction: 4558 }, }, { - id: 3547, + id: '3547', from: 'MIM', to: 'MYA', attributes: { prediction: 607 }, }, { - id: 3548, + id: '3548', from: 'SHJ', to: 'NAG', attributes: { prediction: 1305 }, }, { - id: 3549, + id: '3549', from: 'SYD', to: 'NAN', attributes: { prediction: 19113 }, }, { - id: 3550, + id: '3550', from: 'NLA', to: 'NBO', attributes: { prediction: 473 }, }, { - id: 3551, + id: '3551', from: 'ABZ', to: 'NCL', attributes: { prediction: 2488 }, }, { - id: 3552, + id: '3552', from: 'SJC', to: 'OGG', attributes: { prediction: 1550 }, }, { - id: 3553, + id: '3553', from: 'HIJ', to: 'OKA', attributes: { prediction: 5806 }, }, { - id: 3554, + id: '3554', from: 'MAN', to: 'SPC', attributes: { prediction: 494 }, }, { - id: 3555, + id: '3555', from: 'FLL', to: 'STL', attributes: { prediction: 4696 }, }, { - id: 3556, + id: '3556', from: 'OPO', to: 'STN', attributes: { prediction: 10759 }, }, { - id: 3557, + id: '3557', from: 'ATL', to: 'STR', attributes: { prediction: 5236 }, }, { - id: 3558, + id: '3558', from: 'CEB', to: 'SUG', attributes: { prediction: 854 }, }, { - id: 3559, + id: '3559', from: 'XKS', to: 'SUR', attributes: { prediction: 66 }, }, { - id: 3560, + id: '3560', from: 'ANU', to: 'SVD', attributes: { prediction: 1343 }, }, { - id: 3561, + id: '3561', from: 'NUX', to: 'SVX', attributes: { prediction: 298 }, }, { - id: 3562, + id: '3562', from: 'ATL', to: 'SWF', attributes: { prediction: 1448 }, }, { - id: 3563, + id: '3563', from: 'SKB', to: 'SXM', attributes: { prediction: 2542 }, }, { - id: 3564, + id: '3564', from: 'VIE', to: 'SZG', attributes: { prediction: 5388 }, }, { - id: 3565, + id: '3565', from: 'RMQ', to: 'SZX', attributes: { prediction: 505 }, }, { - id: 3566, + id: '3566', from: 'APW', to: 'TBU', attributes: { prediction: 1071 }, }, { - id: 3567, + id: '3567', from: 'BDO', to: 'PDG', attributes: { prediction: 679 }, }, { - id: 3568, + id: '3568', from: 'BOI', to: 'PDX', attributes: { prediction: 10798 }, }, { - id: 3569, + id: '3569', from: 'EGX', to: 'PIP', attributes: { prediction: 16 }, }, { - id: 3570, + id: '3570', from: 'DFW', to: 'PIT', attributes: { prediction: 11268 }, }, { - id: 3571, + id: '3571', from: 'PUJ', to: 'PIT', attributes: { prediction: 1091 }, }, { - id: 3572, + id: '3572', from: 'NRN', to: 'PMI', attributes: { prediction: 2487 }, }, { - id: 3573, + id: '3573', from: 'SJO', to: 'PMZ', attributes: { prediction: 249 }, }, { - id: 3574, + id: '3574', from: 'FMN', to: 'PRC', attributes: { prediction: 323 }, }, { - id: 3575, + id: '3575', from: 'BRQ', to: 'PRG', attributes: { prediction: 2476 }, }, { - id: 3576, + id: '3576', from: 'LPL', to: 'TFS', attributes: { prediction: 2457 }, }, { - id: 3577, + id: '3577', from: 'SYZ', to: 'THR', attributes: { prediction: 3653 }, }, { - id: 3578, + id: '3578', from: 'STL', to: 'UIN', attributes: { prediction: 562 }, }, { - id: 3579, + id: '3579', from: 'CTS', to: 'UKB', attributes: { prediction: 11271 }, }, { - id: 3580, + id: '3580', from: 'BYN', to: 'ULN', attributes: { prediction: 131 }, }, { - id: 3581, + id: '3581', from: 'CNX', to: 'USM', attributes: { prediction: 3390 }, }, { - id: 3582, + id: '3582', from: 'VIE', to: 'VAR', attributes: { prediction: 2638 }, }, { - id: 3583, + id: '3583', from: 'MXP', to: 'TIA', attributes: { prediction: 3979 }, }, { - id: 3584, + id: '3584', from: 'DJJ', to: 'TIM', attributes: { prediction: 6082 }, }, { - id: 3585, + id: '3585', from: 'OAK', to: 'TLC', attributes: { prediction: 2011 }, }, { - id: 3586, + id: '3586', from: 'GOT', to: 'TLL', attributes: { prediction: 99 }, }, { - id: 3587, + id: '3587', from: 'EDI', to: 'TMP', attributes: { prediction: 1510 }, }, { - id: 3588, + id: '3588', from: 'CGQ', to: 'TNA', attributes: { prediction: 1855 }, }, { - id: 3589, + id: '3589', from: 'ONT', to: 'SFO', attributes: { prediction: 4824 }, }, { - id: 3590, + id: '3590', from: 'TWB', to: 'SGO', attributes: { prediction: 169 }, }, { - id: 3591, + id: '3591', from: 'HYN', to: 'SHA', attributes: { prediction: 2397 }, }, { - id: 3592, + id: '3592', from: 'OME', to: 'SHH', attributes: { prediction: 339 }, }, { - id: 3593, + id: '3593', from: 'KTM', to: 'SIN', attributes: { prediction: 2364 }, }, { - id: 3594, + id: '3594', from: 'DRK', to: 'SJO', attributes: { prediction: 124 }, }, { - id: 3595, + id: '3595', from: 'TMU', to: 'SJO', attributes: { prediction: 806 }, }, { - id: 3596, + id: '3596', from: 'KTW', to: 'TRN', attributes: { prediction: 653 }, }, { - id: 3597, + id: '3597', from: 'FCO', to: 'TRS', attributes: { prediction: 2268 }, }, { - id: 3598, + id: '3598', from: 'ALA', to: 'TSE', attributes: { prediction: 136 }, }, { - id: 3599, + id: '3599', from: 'MEM', to: 'STL', attributes: { prediction: 3601 }, }, { - id: 3600, + id: '3600', from: 'BDO', to: 'SUB', attributes: { prediction: 6388 }, }, { - id: 3601, + id: '3601', from: 'IXJ', to: 'SXR', attributes: { prediction: 9174 }, }, { - id: 3602, + id: '3602', from: 'NAA', to: 'SYD', attributes: { prediction: 615 }, }, { - id: 3603, + id: '3603', from: 'CLT', to: 'SYR', attributes: { prediction: 5011 }, }, { - id: 3604, + id: '3604', from: 'CAI', to: 'TAI', attributes: { prediction: 476 }, }, { - id: 3605, + id: '3605', from: 'RIX', to: 'TAS', attributes: { prediction: 992 }, }, { - id: 3606, + id: '3606', from: 'TZX', to: 'TBS', attributes: { prediction: 503 }, }, { - id: 3607, + id: '3607', from: 'NGO', to: 'TSN', attributes: { prediction: 4941 }, }, { - id: 3608, + id: '3608', from: 'VRN', to: 'TSR', attributes: { prediction: 936 }, }, { - id: 3609, + id: '3609', from: 'DUS', to: 'TXL', attributes: { prediction: 53030 }, }, { - id: 3610, + id: '3610', from: 'ULG', to: 'ULN', attributes: { prediction: 175 }, }, { - id: 3611, + id: '3611', from: 'YWB', to: 'YQC', attributes: { prediction: 338 }, }, { - id: 3612, + id: '3612', from: 'YYZ', to: 'YTS', attributes: { prediction: 4747 }, }, { - id: 3613, + id: '3613', from: 'YZF', to: 'YVR', attributes: { prediction: 955 }, }, { - id: 3614, + id: '3614', from: 'LIS', to: 'VCE', attributes: { prediction: 3675 }, }, { - id: 3615, + id: '3615', from: 'DEN', to: 'VEL', attributes: { prediction: 457 }, }, { - id: 3616, + id: '3616', from: 'ASU', to: 'VVI', attributes: { prediction: 2605 }, }, { - id: 3617, + id: '3617', from: 'CDG', to: 'WAW', attributes: { prediction: 19511 }, }, { - id: 3618, + id: '3618', from: 'MAD', to: 'WAW', attributes: { prediction: 3282 }, }, { - id: 3619, + id: '3619', from: 'ICN', to: 'WEH', attributes: { prediction: 2897 }, }, { - id: 3620, + id: '3620', from: 'RYG', to: 'WRO', attributes: { prediction: 1515 }, }, { - id: 3621, + id: '3621', from: 'NKG', to: 'XIY', attributes: { prediction: 4554 }, }, { - id: 3622, + id: '3622', from: 'YTL', to: 'XKS', attributes: { prediction: 79 }, }, { - id: 3623, + id: '3623', from: 'TPE', to: 'XMN', attributes: { prediction: 7084 }, }, { - id: 3624, + id: '3624', from: 'YVR', to: 'YBL', attributes: { prediction: 993 }, }, { - id: 3625, + id: '3625', from: 'YVR', to: 'YDQ', attributes: { prediction: 461 }, }, { - id: 3626, + id: '3626', from: 'LAX', to: 'YEG', attributes: { prediction: 1921 }, }, { - id: 3627, + id: '3627', from: 'HKG', to: 'YNZ', attributes: { prediction: 1049 }, }, { - id: 3628, + id: '3628', from: 'YQT', to: 'YOW', attributes: { prediction: 1039 }, }, { - id: 3629, + id: '3629', from: 'LAX', to: 'YYC', attributes: { prediction: 5879 }, }, { - id: 3630, + id: '3630', from: 'YQR', to: 'YYC', attributes: { prediction: 4033 }, }, { - id: 3631, + id: '3631', from: 'ACA', to: 'YYZ', attributes: { prediction: 882 }, }, { - id: 3632, + id: '3632', from: 'ANU', to: 'ATL', attributes: { prediction: 401 }, }, { - id: 3633, + id: '3633', from: 'FWA', to: 'ATL', attributes: { prediction: 2098 }, }, { - id: 3634, + id: '3634', from: 'ATL', to: 'ABE', attributes: { prediction: 3186 }, }, { - id: 3635, + id: '3635', from: 'DTW', to: 'ABE', attributes: { prediction: 4439 }, }, { - id: 3636, + id: '3636', from: 'OUA', to: 'ABJ', attributes: { prediction: 849 }, }, { - id: 3637, + id: '3637', from: 'PIK', to: 'AGP', attributes: { prediction: 2905 }, }, { - id: 3638, + id: '3638', from: 'CLT', to: 'AGS', attributes: { prediction: 4169 }, }, { - id: 3639, + id: '3639', from: 'VBS', to: 'AHO', attributes: { prediction: 2124 }, }, { - id: 3640, + id: '3640', from: 'ADD', to: 'AMM', attributes: { prediction: 4441 }, }, { - id: 3641, + id: '3641', from: 'DME', to: 'AMM', attributes: { prediction: 2184 }, }, { - id: 3642, + id: '3642', from: 'AYT', to: 'AMS', attributes: { prediction: 2653 }, }, { - id: 3643, + id: '3643', from: 'TRF', to: 'AMS', attributes: { prediction: 3062 }, }, { - id: 3644, + id: '3644', from: 'NEV', to: 'ANU', attributes: { prediction: 1072 }, }, { - id: 3645, + id: '3645', from: 'KEF', to: 'ARN', attributes: { prediction: 3868 }, }, { - id: 3646, + id: '3646', from: 'MJV', to: 'BHX', attributes: { prediction: 1738 }, }, { - id: 3647, + id: '3647', from: 'FLL', to: 'BIM', attributes: { prediction: 220 }, }, { - id: 3648, + id: '3648', from: 'KGL', to: 'BJM', attributes: { prediction: 2052 }, }, { - id: 3649, + id: '3649', from: 'AKL', to: 'BNE', attributes: { prediction: 37394 }, }, { - id: 3650, + id: '3650', from: 'DXB', to: 'BNE', attributes: { prediction: 6851 }, }, { - id: 3651, + id: '3651', from: 'GRO', to: 'BOH', attributes: { prediction: 2073 }, }, { - id: 3652, + id: '3652', from: 'JED', to: 'BOM', attributes: { prediction: 8414 }, }, { - id: 3653, + id: '3653', from: 'HYA', to: 'BOS', attributes: { prediction: 517 }, }, { - id: 3654, + id: '3654', from: 'IAH', to: 'BOS', attributes: { prediction: 22507 }, }, { - id: 3655, + id: '3655', from: 'EWR', to: 'BQN', attributes: { prediction: 2719 }, }, { - id: 3656, + id: '3656', from: 'AEP', to: 'BRC', attributes: { prediction: 13643 }, }, { - id: 3657, + id: '3657', from: 'SFB', to: 'CID', attributes: { prediction: 1139 }, }, { - id: 3658, + id: '3658', from: 'HKG', to: 'CLE', attributes: { prediction: 237 }, }, { - id: 3659, + id: '3659', from: 'SXM', to: 'CLT', attributes: { prediction: 5680 }, }, { - id: 3660, + id: '3660', from: 'DEN', to: 'CMH', attributes: { prediction: 6166 }, }, { - id: 3661, + id: '3661', from: 'CRL', to: 'CMN', attributes: { prediction: 4765 }, }, { - id: 3662, + id: '3662', from: 'BKO', to: 'COO', attributes: { prediction: 540 }, }, { - id: 3663, + id: '3663', from: 'PMI', to: 'CPH', attributes: { prediction: 965 }, }, { - id: 3664, + id: '3664', from: 'BOM', to: 'DXB', attributes: { prediction: 60277 }, }, { - id: 3665, + id: '3665', from: 'PEW', to: 'DXB', attributes: { prediction: 5894 }, }, { - id: 3666, + id: '3666', from: 'MAN', to: 'EDI', attributes: { prediction: 4712 }, }, { - id: 3667, + id: '3667', from: 'PRG', to: 'EDI', attributes: { prediction: 2389 }, }, { - id: 3668, + id: '3668', from: 'CAN', to: 'DAC', attributes: { prediction: 2171 }, }, { - id: 3669, + id: '3669', from: 'SGN', to: 'DAD', attributes: { prediction: 32295 }, }, { - id: 3670, + id: '3670', from: 'IXU', to: 'DEL', attributes: { prediction: 1221 }, }, { - id: 3671, + id: '3671', from: 'IAD', to: 'DFW', attributes: { prediction: 26287 }, }, { - id: 3672, + id: '3672', from: 'ONT', to: 'DFW', attributes: { prediction: 17616 }, }, { - id: 3673, + id: '3673', from: 'ORF', to: 'DFW', attributes: { prediction: 7486 }, }, { - id: 3674, + id: '3674', from: 'NRT', to: 'DLC', attributes: { prediction: 16594 }, }, { - id: 3675, + id: '3675', from: 'WUH', to: 'DLC', attributes: { prediction: 3614 }, }, { - id: 3676, + id: '3676', from: 'ISA', to: 'DMD', attributes: { prediction: 666 }, }, { - id: 3677, + id: '3677', from: 'HKT', to: 'DMK', attributes: { prediction: 4603 }, }, { - id: 3678, + id: '3678', from: 'MUC', to: 'DOH', attributes: { prediction: 8432 }, }, { - id: 3679, + id: '3679', from: 'PER', to: 'DRW', attributes: { prediction: 8287 }, }, { - id: 3680, + id: '3680', from: 'SSH', to: 'DSA', attributes: { prediction: 1352 }, }, { - id: 3681, + id: '3681', from: 'ATL', to: 'ELP', attributes: { prediction: 6942 }, }, { - id: 3682, + id: '3682', from: 'TPE', to: 'EWR', attributes: { prediction: 4920 }, }, { - id: 3683, + id: '3683', from: 'YYC', to: 'EWR', attributes: { prediction: 1819 }, }, { - id: 3684, + id: '3684', from: 'PVD', to: 'GRR', attributes: { prediction: 93 }, }, { - id: 3685, + id: '3685', from: 'ORD', to: 'GRU', attributes: { prediction: 5511 }, }, { - id: 3686, + id: '3686', from: 'ATL', to: 'GTR', attributes: { prediction: 1519 }, }, { - id: 3687, + id: '3687', from: 'CPH', to: 'GVA', attributes: { prediction: 5632 }, }, { - id: 3688, + id: '3688', from: 'BOG', to: 'GYE', attributes: { prediction: 7073 }, }, { - id: 3689, + id: '3689', from: 'AMM', to: 'FCO', attributes: { prediction: 3027 }, }, { - id: 3690, + id: '3690', from: 'DUJ', to: 'FKL', attributes: { prediction: 432 }, }, { - id: 3691, + id: '3691', from: 'FLL', to: 'FPO', attributes: { prediction: 2454 }, }, { - id: 3692, + id: '3692', from: 'KRK', to: 'FRA', attributes: { prediction: 3481 }, }, { - id: 3693, + id: '3693', from: 'LNK', to: 'GEG', attributes: { prediction: 28 }, }, { - id: 3694, + id: '3694', from: 'ORD', to: 'GLA', attributes: { prediction: 146 }, }, { - id: 3695, + id: '3695', from: 'ALC', to: 'GOT', attributes: { prediction: 930 }, }, { - id: 3696, + id: '3696', from: 'HND', to: 'HAC', attributes: { prediction: 4801 }, }, { - id: 3697, + id: '3697', from: 'ANI', to: 'HCR', attributes: { prediction: 106 }, }, { - id: 3698, + id: '3698', from: 'CDG', to: 'HEL', attributes: { prediction: 18513 }, }, { - id: 3699, + id: '3699', from: 'JFK', to: 'HEL', attributes: { prediction: 5578 }, }, { - id: 3700, + id: '3700', from: 'ATH', to: 'HER', attributes: { prediction: 39730 }, }, { - id: 3701, + id: '3701', from: 'KUL', to: 'HGH', attributes: { prediction: 8855 }, }, { - id: 3702, + id: '3702', from: 'WNZ', to: 'HGH', attributes: { prediction: 3917 }, }, { - id: 3703, + id: '3703', from: 'MEX', to: 'JAL', attributes: { prediction: 1389 }, }, { - id: 3704, + id: '3704', from: 'ALF', to: 'HVG', attributes: { prediction: 33 }, }, { - id: 3705, + id: '3705', from: 'AMA', to: 'IAH', attributes: { prediction: 5713 }, }, { - id: 3706, + id: '3706', from: 'GOT', to: 'IKA', attributes: { prediction: 678 }, }, { - id: 3707, + id: '3707', from: 'GRU', to: 'IPN', attributes: { prediction: 467 }, }, { - id: 3708, + id: '3708', from: 'MSQ', to: 'IST', attributes: { prediction: 1985 }, }, { - id: 3709, + id: '3709', from: 'MXP', to: 'IST', attributes: { prediction: 12676 }, }, { - id: 3710, + id: '3710', from: 'NBO', to: 'IST', attributes: { prediction: 3242 }, }, { - id: 3711, + id: '3711', from: 'CHC', to: 'IVC', attributes: { prediction: 10577 }, }, { - id: 3712, + id: '3712', from: 'DEL', to: 'IXB', attributes: { prediction: 10721 }, }, { - id: 3713, + id: '3713', from: 'BDA', to: 'JFK', attributes: { prediction: 3256 }, }, { - id: 3714, + id: '3714', from: 'LKO', to: 'MCT', attributes: { prediction: 4126 }, }, { - id: 3715, + id: '3715', from: 'YYC', to: 'MDW', attributes: { prediction: 29 }, }, { - id: 3716, + id: '3716', from: 'KWI', to: 'MED', attributes: { prediction: 421 }, }, { - id: 3717, + id: '3717', from: 'BIR', to: 'KTM', attributes: { prediction: 6804 }, }, { - id: 3718, + id: '3718', from: 'KTM', to: 'KUL', attributes: { prediction: 4545 }, }, { - id: 3719, + id: '3719', from: 'KHZ', to: 'KXU', attributes: { prediction: 192 }, }, { - id: 3720, + id: '3720', from: 'CPR', to: 'LAS', attributes: { prediction: 977 }, }, { - id: 3721, + id: '3721', from: 'GTF', to: 'LAS', attributes: { prediction: 2215 }, }, { - id: 3722, + id: '3722', from: 'SJC', to: 'LAS', attributes: { prediction: 25188 }, }, { - id: 3723, + id: '3723', from: 'ZLO', to: 'LAX', attributes: { prediction: 1915 }, }, { - id: 3724, + id: '3724', from: 'CDG', to: 'LBV', attributes: { prediction: 4671 }, }, { - id: 3725, + id: '3725', from: 'GJA', to: 'LCE', attributes: { prediction: 300 }, }, { - id: 3726, + id: '3726', from: 'ACR', to: 'LCR', attributes: { prediction: 104 }, }, { - id: 3727, + id: '3727', from: 'KGD', to: 'LED', attributes: { prediction: 8662 }, }, { - id: 3728, + id: '3728', from: 'PEK', to: 'LED', attributes: { prediction: 2765 }, }, { - id: 3729, + id: '3729', from: 'ROV', to: 'LED', attributes: { prediction: 1348 }, }, { - id: 3730, + id: '3730', from: 'CVG', to: 'LEX', attributes: { prediction: 3156 }, }, { - id: 3731, + id: '3731', from: 'AZD', to: 'MHD', attributes: { prediction: 1962 }, }, { - id: 3732, + id: '3732', from: 'CCS', to: 'LIS', attributes: { prediction: 2770 }, }, { - id: 3733, + id: '3733', from: 'LAP', to: 'LMM', attributes: { prediction: 1166 }, }, { - id: 3734, + id: '3734', from: 'STN', to: 'LPA', attributes: { prediction: 3213 }, }, { - id: 3735, + id: '3735', from: 'VIE', to: 'LPA', attributes: { prediction: 736 }, }, { - id: 3736, + id: '3736', from: 'DTW', to: 'MAD', attributes: { prediction: 153 }, }, { - id: 3737, + id: '3737', from: 'ORD', to: 'MAD', attributes: { prediction: 5248 }, }, { - id: 3738, + id: '3738', from: 'LAS', to: 'MAF', attributes: { prediction: 3333 }, }, { - id: 3739, + id: '3739', from: 'LHR', to: 'MAN', attributes: { prediction: 39824 }, }, { - id: 3740, + id: '3740', from: 'MAN', to: 'MBJ', attributes: { prediction: 917 }, }, { - id: 3741, + id: '3741', from: 'MEM', to: 'MIA', attributes: { prediction: 6448 }, }, { - id: 3742, + id: '3742', from: 'BFS', to: 'MJV', attributes: { prediction: 1430 }, }, { - id: 3743, + id: '3743', from: 'FNT', to: 'MKE', attributes: { prediction: 2526 }, }, { - id: 3744, + id: '3744', from: 'VLI', to: 'NOU', attributes: { prediction: 1958 }, }, { - id: 3745, + id: '3745', from: 'WLS', to: 'NOU', attributes: { prediction: 584 }, }, { - id: 3746, + id: '3746', from: 'PMI', to: 'NRN', attributes: { prediction: 3238 }, }, { - id: 3747, + id: '3747', from: 'NOU', to: 'NRT', attributes: { prediction: 3006 }, }, { - id: 3748, + id: '3748', from: 'TLC', to: 'OAK', attributes: { prediction: 2179 }, }, { - id: 3749, + id: '3749', from: 'DTW', to: 'OMA', attributes: { prediction: 4407 }, }, { - id: 3750, + id: '3750', from: 'TVC', to: 'MSP', attributes: { prediction: 852 }, }, { - id: 3751, + id: '3751', from: 'RIX', to: 'MUC', attributes: { prediction: 3231 }, }, { - id: 3752, + id: '3752', from: 'NAT', to: 'MXP', attributes: { prediction: 1123 }, }, { - id: 3753, + id: '3753', from: 'SEZ', to: 'NBO', attributes: { prediction: 1044 }, }, { - id: 3754, + id: '3754', from: 'GUM', to: 'NGO', attributes: { prediction: 12174 }, }, { - id: 3755, + id: '3755', from: 'TUS', to: 'ORD', attributes: { prediction: 6339 }, }, { - id: 3756, + id: '3756', from: 'AES', to: 'OSL', attributes: { prediction: 11922 }, }, { - id: 3757, + id: '3757', from: 'KRS', to: 'OSL', attributes: { prediction: 8710 }, }, { - id: 3758, + id: '3758', from: 'IST', to: 'OTP', attributes: { prediction: 14043 }, }, { - id: 3759, + id: '3759', from: 'DRG', to: 'OTZ', attributes: { prediction: 274 }, }, { - id: 3760, + id: '3760', from: 'KAJ', to: 'OUL', attributes: { prediction: 85 }, }, { - id: 3761, + id: '3761', from: 'TKU', to: 'OUL', attributes: { prediction: 1120 }, }, { - id: 3762, + id: '3762', from: 'SCL', to: 'PUJ', attributes: { prediction: 825 }, }, { - id: 3763, + id: '3763', from: 'ABQ', to: 'PDX', attributes: { prediction: 2949 }, }, { - id: 3764, + id: '3764', from: 'JFK', to: 'PDX', attributes: { prediction: 4281 }, }, { - id: 3765, + id: '3765', from: 'FNJ', to: 'PEK', attributes: { prediction: 1246 }, }, { - id: 3766, + id: '3766', from: 'SOV', to: 'PGM', attributes: { prediction: 7 }, }, { - id: 3767, + id: '3767', from: 'EWR', to: 'PHL', attributes: { prediction: 4833 }, }, { - id: 3768, + id: '3768', from: 'MCI', to: 'PHL', attributes: { prediction: 3084 }, }, { - id: 3769, + id: '3769', from: 'GYM', to: 'PHX', attributes: { prediction: 465 }, }, { - id: 3770, + id: '3770', from: 'BGR', to: 'PIE', attributes: { prediction: 1350 }, }, { - id: 3771, + id: '3771', from: 'DOM', to: 'PMV', attributes: { prediction: 166 }, }, { - id: 3772, + id: '3772', from: 'VTE', to: 'PNH', attributes: { prediction: 3600 }, }, { - id: 3773, + id: '3773', from: 'KVG', to: 'POM', attributes: { prediction: 388 }, }, { - id: 3774, + id: '3774', from: 'TPI', to: 'POM', attributes: { prediction: 180 }, }, { - id: 3775, + id: '3775', from: 'AXR', to: 'PPT', attributes: { prediction: 192 }, }, { - id: 3776, + id: '3776', from: 'RFP', to: 'PPT', attributes: { prediction: 6828 }, }, { - id: 3777, + id: '3777', from: 'TIH', to: 'PPT', attributes: { prediction: 1087 }, }, { - id: 3778, + id: '3778', from: 'BHX', to: 'PSA', attributes: { prediction: 1239 }, }, { - id: 3779, + id: '3779', from: 'SRZ', to: 'PSZ', attributes: { prediction: 424 }, }, { - id: 3780, + id: '3780', from: 'GTA', to: 'RBV', attributes: { prediction: 50 }, }, { - id: 3781, + id: '3781', from: 'PHX', to: 'RDU', attributes: { prediction: 3190 }, }, { - id: 3782, + id: '3782', from: 'LPQ', to: 'REP', attributes: { prediction: 1082 }, }, { - id: 3783, + id: '3783', from: 'MEX', to: 'SCL', attributes: { prediction: 8822 }, }, { - id: 3784, + id: '3784', from: 'YKM', to: 'SEA', attributes: { prediction: 4388 }, }, { - id: 3785, + id: '3785', from: 'LAS', to: 'SFO', attributes: { prediction: 62881 }, }, { - id: 3786, + id: '3786', from: 'VKG', to: 'SGN', attributes: { prediction: 1248 }, }, { - id: 3787, + id: '3787', from: 'JJN', to: 'SHA', attributes: { prediction: 3616 }, }, { - id: 3788, + id: '3788', from: 'BAV', to: 'SHE', attributes: { prediction: 1187 }, }, { - id: 3789, + id: '3789', from: 'BNE', to: 'SIN', attributes: { prediction: 37681 }, }, { - id: 3790, + id: '3790', from: 'FUK', to: 'SIN', attributes: { prediction: 9219 }, }, { - id: 3791, + id: '3791', from: 'PNH', to: 'SIN', attributes: { prediction: 8072 }, }, { - id: 3792, + id: '3792', from: 'SMF', to: 'SJD', attributes: { prediction: 1920 }, }, { - id: 3793, + id: '3793', from: 'IAH', to: 'SJO', attributes: { prediction: 13188 }, }, { - id: 3794, + id: '3794', from: 'NOB', to: 'SJO', attributes: { prediction: 134 }, }, { - id: 3795, + id: '3795', from: 'SJD', to: 'SLC', attributes: { prediction: 496 }, }, { - id: 3796, + id: '3796', from: 'ATL', to: 'YUL', attributes: { prediction: 6133 }, }, { - id: 3797, + id: '3797', from: 'YSJ', to: 'YUL', attributes: { prediction: 2420 }, }, { - id: 3798, + id: '3798', from: 'YYZ', to: 'YUL', attributes: { prediction: 67535 }, }, { - id: 3799, + id: '3799', from: 'YEV', to: 'YVQ', attributes: { prediction: 694 }, }, { - id: 3800, + id: '3800', from: 'YRT', to: 'YWG', attributes: { prediction: 1402 }, }, { - id: 3801, + id: '3801', from: 'AGU', to: 'TIJ', attributes: { prediction: 1950 }, }, { - id: 3802, + id: '3802', from: 'DAM', to: 'TIP', attributes: { prediction: 2329 }, }, { - id: 3803, + id: '3803', from: 'EWR', to: 'TLV', attributes: { prediction: 25294 }, }, { - id: 3804, + id: '3804', from: 'IAH', to: 'TPA', attributes: { prediction: 24019 }, }, { - id: 3805, + id: '3805', from: 'CDG', to: 'TRN', attributes: { prediction: 15497 }, }, { - id: 3806, + id: '3806', from: 'AOI', to: 'TSR', attributes: { prediction: 1190 }, }, { - id: 3807, + id: '3807', from: 'MUC', to: 'TSR', attributes: { prediction: 7243 }, }, { - id: 3808, + id: '3808', from: 'TOG', to: 'TWA', attributes: { prediction: 36 }, }, { - id: 3809, + id: '3809', from: 'GRU', to: 'UBA', attributes: { prediction: 473 }, }, { - id: 3810, + id: '3810', from: 'YDQ', to: 'YYE', attributes: { prediction: 325 }, }, { - id: 3811, + id: '3811', from: 'GEO', to: 'YYZ', attributes: { prediction: 777 }, }, { - id: 3812, + id: '3812', from: 'GRR', to: 'YYZ', attributes: { prediction: 647 }, }, { - id: 3813, + id: '3813', from: 'LAS', to: 'YYZ', attributes: { prediction: 7856 }, }, { - id: 3814, + id: '3814', from: 'YQG', to: 'YYZ', attributes: { prediction: 3997 }, }, { - id: 3815, + id: '3815', from: 'YXU', to: 'YYZ', attributes: { prediction: 5558 }, }, { - id: 3816, + id: '3816', from: 'YCO', to: 'YZF', attributes: { prediction: 1363 }, }, { - id: 3817, + id: '3817', from: 'GRZ', to: 'VIE', attributes: { prediction: 5844 }, }, { - id: 3818, + id: '3818', from: 'KRR', to: 'VIE', attributes: { prediction: 2058 }, }, { - id: 3819, + id: '3819', from: 'VQS', to: 'VIJ', attributes: { prediction: 311 }, }, { - id: 3820, + id: '3820', from: 'TSV', to: 'WIN', attributes: { prediction: 302 }, }, { - id: 3821, + id: '3821', from: 'NPE', to: 'WLG', attributes: { prediction: 7849 }, }, { - id: 3822, + id: '3822', from: 'KTN', to: 'WMK', attributes: { prediction: 19 }, }, { - id: 3823, + id: '3823', from: 'GDT', to: 'XSC', attributes: { prediction: 312 }, }, { - id: 3824, + id: '3824', from: 'YQT', to: 'YFH', attributes: { prediction: 728 }, }, { - id: 3825, + id: '3825', from: 'YVO', to: 'YHU', attributes: { prediction: 138 }, }, { - id: 3826, + id: '3826', from: 'ICN', to: 'YNJ', attributes: { prediction: 8082 }, }, { - id: 3827, + id: '3827', from: 'YPX', to: 'YZG', attributes: { prediction: 798 }, }, { - id: 3828, + id: '3828', from: 'YNC', to: 'ZEM', attributes: { prediction: 375 }, }, { - id: 3829, + id: '3829', from: 'FRA', to: 'ZRH', attributes: { prediction: 27983 }, }, { - id: 3830, + id: '3830', from: 'OPO', to: 'ZRH', attributes: { prediction: 3531 }, diff --git a/libs/shared/lib/mock-data/schema/twitterSchemaRaw.ts b/libs/shared/lib/mock-data/schema/twitterSchemaRaw.ts index e36722df363a4a4b48db2a3b3fe5ba19f5f87c40..7637bdb26a9ab4d97627b6eb02470c81622ba742 100644 --- a/libs/shared/lib/mock-data/schema/twitterSchemaRaw.ts +++ b/libs/shared/lib/mock-data/schema/twitterSchemaRaw.ts @@ -1,5 +1,5 @@ import { SchemaUtils } from '@graphpolaris/shared/lib/schema/schema-utils'; -import { SchemaFromBackend } from '@graphpolaris/shared/lib/model/backend'; +import { SchemaFromBackend } from '../../schema'; export const twitterSchemaRaw: SchemaFromBackend = { nodes: [ diff --git a/libs/shared/lib/querybuilder/model/graphology/model.ts b/libs/shared/lib/querybuilder/model/graphology/model.ts index 6fe37af6f1f55dbb78f7e42aab33131da2e3bb27..650f0e48901f7b18847091279af808f215597e43 100644 --- a/libs/shared/lib/querybuilder/model/graphology/model.ts +++ b/libs/shared/lib/querybuilder/model/graphology/model.ts @@ -2,8 +2,9 @@ import { Attributes as GAttributes } from 'graphology-types'; import { XYPosition } from 'reactflow'; import { MultiGraph } from 'graphology'; import './utils'; -import { AllLogicTypes, SchemaAttribute } from '@graphpolaris/shared/lib/schema'; +import { SchemaAttribute } from '@graphpolaris/shared/lib/schema'; import { GeneralDescription, InputNodeType } from '../logic/general'; +import { AllLogicTypes } from '../logic'; // export interface Attributes extends EntityNode | RelationNode | AttributeNode | FunctionNode | ModifierNode { // } diff --git a/libs/shared/lib/querybuilder/model/logic/index.ts b/libs/shared/lib/querybuilder/model/logic/index.ts index 6fdc60f27d21cc97d04be62cea637473005bb59b..9b2dd330196c59dd261d22584884c1f92025fc5c 100644 --- a/libs/shared/lib/querybuilder/model/logic/index.ts +++ b/libs/shared/lib/querybuilder/model/logic/index.ts @@ -19,4 +19,3 @@ export * from './mathFunctions'; export * from './mathFilters'; export * from './stringFunctions'; export * from './stringFilters'; -export * from './utils'; diff --git a/libs/shared/lib/querybuilder/model/reactflow/handles.tsx b/libs/shared/lib/querybuilder/model/reactflow/handles.tsx index cb55e4d7d3a9d52006445e1b53ce18307f0cf13e..c0b7fdca504a8302e946def1ae9f3625dbfcfe09 100644 --- a/libs/shared/lib/querybuilder/model/reactflow/handles.tsx +++ b/libs/shared/lib/querybuilder/model/reactflow/handles.tsx @@ -66,13 +66,14 @@ export function nodeToHandlesThatCanReceiveDragconnect(node: SchemaReactflowNode /** * Return a list of handles from which a connection can be made while dragging the node they are on + * @deprecated */ export function nodeToHandlesThatCanSendDragconnect(node: SchemaReactflowNode): string[] { switch (node.type) { - case QueryElementTypes.Entity: - return [Handles.ToRelation]; - case QueryElementTypes.Relation: - return []; + // case QueryElementTypes.Entity: + // return [Handles.ToRelation]; + // case QueryElementTypes.Relation: + // return []; // case QueryElementTypes.Function: // return []; // case QueryElementTypes.Attribute: diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.tsx b/libs/shared/lib/querybuilder/panel/querybuilder.tsx index ececf913264fab302d728cd826fae0c0752a6b7e..93f4bb8dea83994eb9c825b58cd2347348477a53 100644 --- a/libs/shared/lib/querybuilder/panel/querybuilder.tsx +++ b/libs/shared/lib/querybuilder/panel/querybuilder.tsx @@ -68,6 +68,7 @@ import { } from '../model/logic'; import LogicPill from '../pills/customFlowPills/logicpill/logicpill'; import { current } from '@reduxjs/toolkit'; +import { SchemaAttributeTypes } from '../../schema'; const nodeTypes = { entity: EntityFlowElement, @@ -315,7 +316,12 @@ export const QueryBuilderInner: React.FC = () => { const { attributeName, attributeType } = fromHandleId(params.handleId); // console.log(attributeName, attributeType, node.attributes?.filter((a) => a.name === attributeName)?.[0]); - connectingNodeId.current = { params, node, position: { x: 0, y: 0 }, attribute: { name: attributeName, type: attributeType } }; + connectingNodeId.current = { + params, + node, + position: { x: 0, y: 0 }, + attribute: { name: attributeName, type: attributeType as SchemaAttributeTypes, handleId: params.handleId }, + }; }, [graph] ); @@ -368,11 +374,12 @@ export const QueryBuilderInner: React.FC = () => { y: position.y, logic: logic, }); + if (!logicNode?.id) throw new Error('Logic node has no id'); graphologyGraph.addEdge(params.nodeId, logicNode.id, { type: 'connection', sourceHandle: params.handleId, // newAttribute data? - targetHandle: getHandleId(logicNode.name, logicNode.type, firstLeftLogicInput.name, firstLeftLogicInput.type.join(''), { + targetHandle: getHandleId(logicNode.id, logicNode.name, logicNode.type, firstLeftLogicInput.name, firstLeftLogicInput.type.join(''), { extra: 'left', }), }); diff --git a/libs/shared/lib/querybuilder/panel/stories/querybuilder-simple-disconnected.stories.tsx b/libs/shared/lib/querybuilder/panel/stories/querybuilder-simple-disconnected.stories.tsx index c5498bae2df34ce81dde258262f008b62d72a5b9..a71f52347fb878fd59b815c88c6ecf5793d548ab 100644 --- a/libs/shared/lib/querybuilder/panel/stories/querybuilder-simple-disconnected.stories.tsx +++ b/libs/shared/lib/querybuilder/panel/stories/querybuilder-simple-disconnected.stories.tsx @@ -24,7 +24,7 @@ const Component: Meta<typeof QueryBuilderInner> = { export const SimpleDisconnected = { args: {}, decorators: [ - (story) => { + (story: any) => { const graph = new QueryMultiGraphology(); const schema = SchemaUtils.schemaBackend2Graphology({ nodes: [ diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill-full.storiesDEFUNCT.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill-full.storiesDEFUNCT.tsx deleted file mode 100644 index 01e3095c81e8eb757a9082ee0c65992c077605d9..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill-full.storiesDEFUNCT.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import React from 'react'; -import { colorPaletteConfigSlice, querybuilderSlice, setQuerybuilderNodes } from '@graphpolaris/shared/lib/data-access/store'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; -import { configureStore } from '@reduxjs/toolkit'; -import { Meta } from '@storybook/react'; -import { Provider } from 'react-redux'; -import { MultiGraph } from 'graphology'; -import { QueryBuilder } from '../../../panel'; -import { QueryGraph } from '../../../model/graphology/model'; -import { circular } from 'graphology-layout'; -import { QueryMultiGraphology } from '@graphpolaris/shared/lib/querybuilder/model/graphology/utils'; - -const Component: Meta<typeof QueryBuilder> = { - component: QueryBuilder, - title: 'Querybuilder/Pills/AttributePill', - decorators: [ - (story) => ( - <Provider store={mockStore}> - <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider> - </Provider> - ), - ], -}; - -// Mock palette store -const mockStore = configureStore({ - reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, - querybuilder: querybuilderSlice.reducer, - }, -}); -const graph = new QueryMultiGraphology(); -graph.addPill2Graphology( - { - type: 'attribute', - x: 170, - y: 160, - name: 'Attr string', - dataType: 'string', - matchType: 'NEQ', - value: 'mark', - // depth: { min: 0, max: 1 }, - }, - '2' -); -console.log(graph.export()); - -mockStore.dispatch(setQuerybuilderNodes(graph.export())); - -export const Flow = { - args: {}, -}; - -export default Component; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.tsx index afbec63c92cd353eb9e3071b00d2570e9560abda..0875fe2a2661ca5efb771afb596b0e4c07dd30e7 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.tsx @@ -4,13 +4,13 @@ import styles from './attributepill.module.scss'; import { Handle, NodeProps, Position } from 'reactflow'; import { AttributeOperatorSelect } from './operator'; import Select from './select-component'; -import { AttributeNode, Handles } from '../../../model'; +import { Handles } from '../../../model'; /** * Component to render an attribute flow element * @param {FlowElement<EntityData>)} param0 The data of an entity flow element. */ -export const AttributePill = React.memo(({ id, data }: AttributeNode) => { +export const AttributePill = React.memo(({ id, data }: any) => { const theme = useTheme(); const [read, setRead] = useState(true); // console.log('AttributePill', data); diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/select-component.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/select-component.tsx index 09324005b0f3303bbf7e69aa46c54d5f7fd1b0aa..2f804d657771df47ec71a84a381c175c630ffca8 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/select-component.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/select-component.tsx @@ -11,9 +11,8 @@ import { useTheme } from '@mui/material'; import React, { useState } from 'react'; import styles from './attributepill.module.scss'; -import { AttributeData } from '../../../model'; -export default function SelectComponent({ data }: { data: AttributeData }) { +export default function SelectComponent({ data }: { data: any }) { const theme = useTheme(); /** diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/edge-line.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/edge-line.tsx index ffb9270950e3b3a39026383055ca5c17a2b79d21..328e49613876ac0350e7eb204c90a6ae1179bc30 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/edge-line.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/edge-line.tsx @@ -22,9 +22,9 @@ export default function EdgeLine({ id, sourceX, sourceY, targetX, targetY, style targetY -= 3; // Correct line positions with hardcoded numbers, because react flow lacks this functionality - if (sourceHandleId == Handles.ToAttributeHandle) sourceX += 2; + if (sourceHandleId == Handles.EntityLeft) sourceX += 2; - if (targetHandleId == Handles.ToAttributeHandle) targetX += 2; + if (targetHandleId == Handles.EntityRight) targetX += 2; let spos: Position = Position.Bottom; if (sourceHandleId == Handles.RelationLeft) { diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill-full.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill-full.stories.tsx index 2e408ee62b6e25df8612c1c806a27f2af91e3d7b..ac79584b6fb78aec820b5319d8e2d2e585f83cca 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill-full.stories.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill-full.stories.tsx @@ -27,7 +27,7 @@ const mockStore = configureStore({ }, }); const graph = new QueryMultiGraphology(); -graph.addPill2Graphology({ type: 'entity', x: 100, y: 100, name: 'Entity Pill' }, '2'); +graph.addPill2Graphology({ id: '2', type: 'entity', x: 100, y: 100, name: 'Entity Pill' }); console.log(graph.export()); mockStore.dispatch(setQuerybuilderNodes(graph.export())); diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.tsx index 960834e2d7abc722a3821e1af1b94329608ea488..c2b191fda7947648eb6a7803b9f4badd83cd1cde 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.tsx @@ -19,7 +19,7 @@ export const EntityFlowElement = React.memo((node: SchemaReactflowEntityNode) => const graph = useQuerybuilderGraph(); const myEdges = graph.edges.filter( - (edge) => (edge.source === node.id || edge.target === node.id) && !edge?.attributes?.sourceHandle.includes(Handles.ToRelation) // no need to show if only the relation handle is connected + (edge) => (edge.source === node.id || edge.target === node.id) && !edge?.attributes?.sourceHandle.includes(Handles.EntityRight) // no need to show if only the relation handle is connected ); const [hovered, setHovered] = React.useState(false); diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/SelectFunction.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/SelectFunction.tsx index 70f71de4766bacb10a167b06891ea320b56a81a6..5a6fd8c4c5b1a7c57186fb5217534496f1a3dbe8 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/SelectFunction.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/SelectFunction.tsx @@ -8,21 +8,20 @@ /* The comment above was added so the code coverage wouldn't count this file towards code coverage. * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ +import { makeStyles } from '@mui/material'; import React, { useState } from 'react'; -import { makeStyles } from '@material-ui/core/styles'; -import { useStyles } from '../../QueryBuilderStylesheet'; +import styles from './functionpill.module.scss'; // Create style constant to prevent rereaction of styles -const madeStyles = makeStyles(useStyles); +// const madeStyles = makeStyles(useStyles); /** * The flow element for the modifier. * @param param0 The data of the modifier flow element. */ export default function ModifierFlowElement({ data }: any) { - const styles = madeStyles(); const [disable, setDisable] = useState(true); - const [disClass, setDisClass] = useState(styles.disable); + const [disClass, setDisClass] = useState<string>(styles.disable); /** * Calculate the width of the select element based on the displayed value. diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss index 7e589ded73a5eb5010a10401e4f25fefc54460ad..ec1d4a5e97eba412aea899ab181fbea3bf072ca1 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss @@ -1,167 +1,175 @@ -@import '../entitypill/entitypill.module.scss'; - -$baseColor: #8c75c9; - -// Function element -.function { - background-color: $baseColor; - display: 'flex'; - border-radius: '1px'; - font-family: monospace; - font-weight: 'bold'; - font-size: 11px; - color: black; - min-width: '140px'; - text-align: 'center'; - line-height: 20px; - padding-top: 2; - padding-right: 5; - padding-bottom: 4; - padding-left: 5; - - &::before { - position: 'absolute'; - content: '""'; - width: '100%'; - left: '0px'; - top: '0px'; - height: '100%'; - border-radius: '3px'; - z-index: -1; - background-color: $baseColor; - border-bottom: 'none'; - } - - &::after { - position: 'absolute'; - content: '""'; - width: '100%'; - left: '0px'; - top: '0'; - height: '100%'; - border-radius: '3px'; - z-index: -1; - background-color: $baseColor; - border-top: 'none'; - } -} - -.functionWrapper { - display: 'block'; - width: 'inherit'; - align-items: 'center'; - justify-content: 'space-between'; -} -.functionHandleFiller { - flex: '1 1 0'; - display: 'flow-root'; -} -.functionHandle { - border: 0; - border-radius: 0; - width: 8; - height: 8; - left: 9; - top: 7; - background: 'rgba(0, 0, 0, 0.3)'; - transform-origin: 'center'; - position: 'relative'; - float: 'right'; - margin-right: '20px'; - &::before { - content: '""'; - width: 6; - height: 6; - left: 1; - bottom: 1; - border: 0; - border-radius: 0; - background: 'rgba(255, 255, 255, 0.6)'; - z-index: -1; - display: 'inline-block'; - position: 'fixed'; - } -} -.functionHandleBottom { - border: 0; - border-radius: 0; - width: 8; - height: 8; - left: 27.5; - margin-bottom: 10; - background-color: 'rgba(255, 255, 255, 0.6)'; - transform: 'rotate(-45deg)'; - transform-origin: 'center'; - &::before { - content: '""'; - width: 6; - height: 6; - left: 1; - bottom: 1; - border: 0; - border-radius: 0; - background-color: 'rgba(255, 255, 255, 0.6)'; - z-index: -1; - display: 'inline-block'; - position: 'fixed'; - } -} -.functionInputHolder { - display: 'flex'; - float: 'right'; - margin-right: '20px'; - margin-top: '4px'; - margin-left: '5px'; - max-width: '80px'; - background-color: 'rgba(255, 255, 255, 0.6)'; - border-radius: '2px'; - align-items: 'center'; - max-height: '12px'; -} -.functionInput { - z-index: 1; - cursor: 'text'; - min-width: '0px'; - max-width: '1.5ch'; - height: '14px'; - border: 'none'; - background-color: 'rgba(255, 255, 255, 0.6)'; - text-align: 'center'; - font-family: 'monospace'; - font-weight: 'bold'; - font-size: '11px'; - color: '#181520'; - user-select: 'none'; - font-style: 'italic'; - float: 'right'; - margin: '3px 0'; - margin-right: '10px'; - &:focus { - outline: 'none'; - user-select: 'none'; - } - &::placeholder { - outline: 'none'; - user-select: 'none'; - font-style: 'italic'; - } -} -.functionReadonly { - cursor: 'grab !important'; - color: '#181520 !important'; - user-select: 'none'; - font-style: 'normal !important'; -} -.functionSpan { - float: 'left'; - margin-left: 20; - margin-right: 20; -} -.functionSpanRight { - float: 'right'; - margin-right: 10; -} - -.functionDataWrapper { - display: block; -} +@import '../entitypill/entitypill.module.scss'; + +$baseColor: #8c75c9; + +.disable { + pointer-events: none; + opacity: 0.4; +} +.matchModifierTypeSelect { + opacity: 0.4; +} + +// Function element +.function { + background-color: $baseColor; + display: 'flex'; + border-radius: '1px'; + font-family: monospace; + font-weight: 'bold'; + font-size: 11px; + color: black; + min-width: '140px'; + text-align: 'center'; + line-height: 20px; + padding-top: 2; + padding-right: 5; + padding-bottom: 4; + padding-left: 5; + + &::before { + position: 'absolute'; + content: '""'; + width: '100%'; + left: '0px'; + top: '0px'; + height: '100%'; + border-radius: '3px'; + z-index: -1; + background-color: $baseColor; + border-bottom: 'none'; + } + + &::after { + position: 'absolute'; + content: '""'; + width: '100%'; + left: '0px'; + top: '0'; + height: '100%'; + border-radius: '3px'; + z-index: -1; + background-color: $baseColor; + border-top: 'none'; + } +} + +.functionWrapper { + display: 'block'; + width: 'inherit'; + align-items: 'center'; + justify-content: 'space-between'; +} +.functionHandleFiller { + flex: '1 1 0'; + display: 'flow-root'; +} +.functionHandle { + border: 0; + border-radius: 0; + width: 8; + height: 8; + left: 9; + top: 7; + background: 'rgba(0, 0, 0, 0.3)'; + transform-origin: 'center'; + position: 'relative'; + float: 'right'; + margin-right: '20px'; + &::before { + content: '""'; + width: 6; + height: 6; + left: 1; + bottom: 1; + border: 0; + border-radius: 0; + background: 'rgba(255, 255, 255, 0.6)'; + z-index: -1; + display: 'inline-block'; + position: 'fixed'; + } +} +.functionHandleBottom { + border: 0; + border-radius: 0; + width: 8; + height: 8; + left: 27.5; + margin-bottom: 10; + background-color: 'rgba(255, 255, 255, 0.6)'; + transform: 'rotate(-45deg)'; + transform-origin: 'center'; + &::before { + content: '""'; + width: 6; + height: 6; + left: 1; + bottom: 1; + border: 0; + border-radius: 0; + background-color: 'rgba(255, 255, 255, 0.6)'; + z-index: -1; + display: 'inline-block'; + position: 'fixed'; + } +} +.functionInputHolder { + display: 'flex'; + float: 'right'; + margin-right: '20px'; + margin-top: '4px'; + margin-left: '5px'; + max-width: '80px'; + background-color: 'rgba(255, 255, 255, 0.6)'; + border-radius: '2px'; + align-items: 'center'; + max-height: '12px'; +} +.functionInput { + z-index: 1; + cursor: 'text'; + min-width: '0px'; + max-width: '1.5ch'; + height: '14px'; + border: 'none'; + background-color: 'rgba(255, 255, 255, 0.6)'; + text-align: 'center'; + font-family: 'monospace'; + font-weight: 'bold'; + font-size: '11px'; + color: '#181520'; + user-select: 'none'; + font-style: 'italic'; + float: 'right'; + margin: '3px 0'; + margin-right: '10px'; + &:focus { + outline: 'none'; + user-select: 'none'; + } + &::placeholder { + outline: 'none'; + user-select: 'none'; + font-style: 'italic'; + } +} +.functionReadonly { + cursor: 'grab !important'; + color: '#181520 !important'; + user-select: 'none'; + font-style: 'normal !important'; +} +.functionSpan { + float: 'left'; + margin-left: 20; + margin-right: 20; +} +.functionSpanRight { + float: 'right'; + margin-right: 10; +} + +.functionDataWrapper { + display: block; +} diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss.d.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss.d.ts index ad71989191962359a7790c262b5a76922dc393f6..ae6d376d7d5e2717be1aec03dfb15ef173fcea35 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss.d.ts +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss.d.ts @@ -1,4 +1,6 @@ declare const classNames: { + readonly disable: 'disable'; + readonly matchModifierTypeSelect: 'matchModifierTypeSelect'; readonly handle: 'handle'; readonly handle_logic: 'handle_logic'; readonly handle_logic_duration: 'handle_logic_duration'; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.stories.tsx index d4a14678df3b32ec7839f112ce515532c71c9e87..b086172fde78bfdb8dded949a4d1ec6e014f8e1b 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.stories.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.stories.tsx @@ -7,7 +7,6 @@ import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/ import { colorPaletteConfigSlice, querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; import { ReactFlowProvider } from 'reactflow'; -import { FunctionData } from '../../../model'; const Component: Meta<typeof FunctionFlowElement> = { /* 👇 The title prop is optional. @@ -40,7 +39,7 @@ const Mockstore = configureStore({ // const Template = (args: any) => <EntityRFPill {...args} />; -export const Default: StoryObj<{ data: FunctionData }> = { +export const Default: StoryObj = { args: { data: { functionType: 'test', diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.tsx index 7d8513500427cc78cdcfc2e1be2bdd7905ba6606..aeaa2b0039324401a7960f73462704c7e84dcce5 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.tsx @@ -12,9 +12,9 @@ import React, { useState } from 'react'; import { Handle, Position } from 'reactflow'; import styles from './functionpill.module.scss'; import { useTheme } from '@mui/material'; -import { FunctionData, Handles } from '../../../model'; +import { Handles } from '../../../model'; -const countArgs = (data: FunctionData | undefined) => { +const countArgs = (data: any) => { if (data !== undefined) { let count = 0; @@ -41,7 +41,7 @@ export const capitalizeFirstLetter = (string: string) => { * Component to render a relation flow element * @param { FlowElement<FunctionData>} param0 The data of a relation flow element. */ -export default function RelationFlowElement({ data }: FunctionNode) { +export default function RelationFlowElement({ data }: any) { const [read, setRead] = useState(true); const theme = useTheme(); @@ -52,7 +52,7 @@ export default function RelationFlowElement({ data }: FunctionNode) { if (event.key == 'Enter') setRead(true); }; - const getArgs = (styles: any, data: FunctionData | undefined, setRead: any) => { + const getArgs = (styles: any, data: any, setRead: any) => { let rows: JSX.Element[] = []; if (data != undefined) { @@ -123,7 +123,7 @@ export default function RelationFlowElement({ data }: FunctionNode) { </div> <div className={`${styles.entity} entityWrapper ${entity === undefined ? 'hidden' : ''}`}> <Handle - id={Handles.ToRelation} + id={Handles.FromAttribute} type="source" position={Position.Bottom} className={styles.entityHandleLeft + ' ' + (false ? styles.handleConnectedFill : '')} diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.tsx index 1afadd3aaf9c04738cd178a164485fe952219bb9..37294f09e566d212cf7ccd20dbbcddddb61a8ddd 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.tsx @@ -39,7 +39,8 @@ export default function LogicPill(node: SchemaReactflowLogicNode) { positionSide === Position.Left && !leftEdges.some( (edge) => - edge?.attributes?.targetHandle === getHandleId(data.name, node.type, input.name, input.type.join(''), { extra: positionSide }) + edge?.attributes?.targetHandle === + getHandleId(data?.id || 'awkudgi', data.name, node.type, input.name, input.type.join(''), { extra: positionSide }) // TODO ) ) { inputTextBox = ( @@ -56,7 +57,7 @@ export default function LogicPill(node: SchemaReactflowLogicNode) { <Handle type={handleType} position={positionSide} - id={getHandleId(data.name, node.type, input.name, input.type.join(''), { extra: positionSide })} + id={getHandleId(data?.id || 'awkudgi', data.name, node.type, input.name, input.type.join(''), { extra: positionSide })} // TODO key={input.name + input.type} // style={{ top: `${((i + 0.8) / (side.length + 0.6)) * 120}%` }} style={{ top: `${((i + 0.8) / (side.length + 0.6)) * 100}%` }} diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.module.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.module.scss deleted file mode 100644 index 2e259083fc99e05883812b703d90b10380bcb4e6..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.module.scss +++ /dev/null @@ -1,55 +0,0 @@ -@import '../../querypills.module.scss'; - -.modifier { - color: '#181520'; - background-color: #d56a50; - border-radius: 5px; - font-family: monospace; - font-weight: bolder; - font-size: 11; - padding-top: 2; - padding-right: 5; - padding-bottom: 12; - padding-left: 5; -} -.modifierWrapper { - height: 6; - margin-left: 5; - margin-right: 5; - color: black; -} -.modifierInput { - float: right; - background-color: #ee917a; - border-radius: 2px; - padding-left: 2px; - padding-right: 2px; - display: flex; -} -.modifierSpan { - float: left; -} - -.matchModifierTypeSelect { - float: left; - background-color: rgba(255, 255, 255, 0.6); - border-radius: 2px; - text-align: center; - & select { - background: transparent; - border: none; - appearance: none; - font-family: monospace; - font-weight: bolder; - color: black; - font-size: 11; - } - & option { - font-family: monospace; - font-size: 11px; - } -} -.disable { - opacity: 1 !important; - pointer-events: none; -} diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.module.scss.d.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.module.scss.d.ts deleted file mode 100644 index d22770e4487c411c24d1fedf852dbe55ea42f79c..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.module.scss.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -declare const classNames: { - readonly 'react-flow__node': 'react-flow__node'; - readonly selected: 'selected'; - readonly entityWrapper: 'entityWrapper'; - readonly hidden: 'hidden'; - readonly 'react-flow__edges': 'react-flow__edges'; - readonly 'react-flow__edge-default': 'react-flow__edge-default'; - readonly handleConnectedFill: 'handleConnectedFill'; - readonly handleConnectedBorderRight: 'handleConnectedBorderRight'; - readonly handleConnectedBorderLeft: 'handleConnectedBorderLeft'; - readonly handleFunction: 'handleFunction'; - readonly modifier: 'modifier'; - readonly modifierWrapper: 'modifierWrapper'; - readonly modifierInput: 'modifierInput'; - readonly modifierSpan: 'modifierSpan'; - readonly matchModifierTypeSelect: 'matchModifierTypeSelect'; - readonly disable: 'disable'; -}; -export = classNames; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.tsx deleted file mode 100644 index 6041c775e13891b6f55ad41588ddd523fbfda34d..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.tsx +++ /dev/null @@ -1,33 +0,0 @@ -/** - * This program has been developed by students from the bachelor Computer Science at - * Utrecht University within the Software Project course. - * © Copyright Utrecht University (Department of Information and Computing Sciences) - */ - -/* istanbul ignore file */ -/* The comment above was added so the code coverage wouldn't count this file towards code coverage. - * We do not test components/renderfunctions/styling files. - * See testing plan for more details.*/ -import React from 'react'; -import { Handle, NodeProps, Position } from 'reactflow'; -import Select from './select-modifier'; -import styles from './modifierpill.module.scss'; -import { ModifierData, ModifierNode } from '../../../graph-reactflow/model'; - -/** - * Component to render an entity flow element - * @param param0 Data of the flow element. - */ -export default function ModifierFlowElement({ data }: ModifierNode) { - return ( - <div className={styles.modifier}> - <div className={styles.modifierWrapper}> - <span className={styles.modifierInput}> - <span className={styles.modifierSpan}> - <Select data={data} /> - </span> - </span> - </div> - </div> - ); -} diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/mopdifierpill.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/mopdifierpill.stories.tsx deleted file mode 100644 index 7c76a5226221978e5019824b746404aeaf797182..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/mopdifierpill.stories.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import React from 'react'; -import { Meta, StoryObj } from '@storybook/react'; -import ModifierPill from './modifierpill'; -import { configureStore } from '@reduxjs/toolkit'; -import { Provider } from 'react-redux'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; - -import { colorPaletteConfigSlice, querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; -import { ReactFlowProvider } from 'reactflow'; -import { ModifierData } from '../../../model'; - -const Component: Meta<typeof ModifierPill> = { - /* 👇 The title prop is optional. - * See https://storybook.js.org/docs/react/configure/overview#configure-story-loading - * to learn how to generate automatic titles - */ - title: 'Querybuilder/Pills/ModifierPill', - component: ModifierPill, - decorators: [ - (story) => ( - <Provider store={Mockstore}> - <GraphPolarisThemeProvider> - <ReactFlowProvider>{story()}</ReactFlowProvider> - </GraphPolarisThemeProvider> - </Provider> - ), - ], -}; - -export default Component; - -// A super-simple mock of a redux store -const Mockstore = configureStore({ - reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, - querybuilder: querybuilderSlice.reducer, - // schema: schemaSlice.reducer, - }, -}); - -// const Template = (args: any) => <EntityRFPill {...args} />; - -export const Default: StoryObj<{ data: ModifierData }> = { - args: { - data: { - type: 'SUM', - }, - }, -}; - -// Default.decorators = [ -// (story) => ( -// <Provider store={Mockstore}> -// <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider> -// </Provider> -// ), -// ]; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/select-modifier.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/select-modifier.tsx deleted file mode 100644 index 7182d285caf38092fcb6ad1b457e4b8bb1295c79..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/select-modifier.tsx +++ /dev/null @@ -1,82 +0,0 @@ -/** - * This program has been developed by students from the bachelor Computer Science at - * Utrecht University within the Software Project course. - * © Copyright Utrecht University (Department of Information and Computing Sciences) - */ - -/* istanbul ignore file */ -/* The comment above was added so the code coverage wouldn't count this file towards code coverage. - * We do not test components/renderfunctions/styling files. - * See testing plan for more details.*/ -import React, { useState } from 'react'; -import { NodeProps } from 'reactflow'; -import styles from './modifierpill.module.scss'; -import { ModifierData } from '../../../graph-reactflow/model'; - -/** - * The flow element for the modifier. - * @param param0 The data of the modifier flow element. - */ -export default function SelectModifier({ data }: { data: ModifierData }) { - const [disable, setDisable] = useState(true); - const [disClass, setDisClass] = useState<string>(styles.disable); - - /** - * Calculate the width of the select element based on the displayed value. - * @param str Input string. - * @returns String containg the length in css format. - */ - const calcSelectWidth = (str: string): string => { - if (str == '') return 1.5 + 'ch'; - return str.length + 1.5 + 'ch'; - }; - - /** Disable the select field */ - const disableSelect = (): void => { - setDisable(true); - setDisClass(styles.disable); - }; - - /** Enable the select field */ - const enableSelect = (): void => { - setDisable(false); - setDisClass(''); - }; - - /** - * Constant switch to append the right options for the select element based on the data.type. - * @returns {JSX.Element} Option list using React.Fragment as parent element. - */ - const list = (): JSX.Element => { - return ( - <React.Fragment> - <option color="black" value="COUNT"> - COUNT - </option> - <option value="SUM">SUM</option> - <option value="MIN">MIN</option> - <option value="MAX">MAX</option> - </React.Fragment> - ); - }; - - return ( - <div className={styles.matchModifierTypeSelect} onBlur={disableSelect} onDoubleClick={enableSelect}> - <select - style={{ - color: disable ? 'black' : 'black', - maxWidth: calcSelectWidth('COUNT'), - }} - name="operators" - className={disClass} - disabled={disable} - onChange={(e) => { - data.type = e.target.value; - e.target.style.maxWidth = calcSelectWidth(e.target.value); - }} - > - {list()} - </select> - </div> - ); -} diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relation-full_reactflow.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relation-full_reactflow.stories.tsx index d62df834326f071166ead39183deb9f30c766364..ad157810b71186da356bba689eee980639a33a1b 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relation-full_reactflow.stories.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relation-full_reactflow.stories.tsx @@ -28,16 +28,14 @@ const mockStore = configureStore({ }, }); const graph = new QueryMultiGraphology(); -graph.addPill2Graphology( - { - type: 'relation', - x: 140, - y: 140, - name: 'Relation Pill', - depth: { min: 0, max: 1 }, - }, - '2' -); +graph.addPill2Graphology({ + id: '2', + type: 'relation', + x: 140, + y: 140, + name: 'Relation Pill', + depth: { min: 0, max: 1 }, +}); console.log(graph.export()); mockStore.dispatch(setQuerybuilderNodes(graph.export())); diff --git a/libs/shared/lib/schema/pills/nodes/popup/attribute-analytics-popup-menu.stories.tsx b/libs/shared/lib/schema/pills/nodes/popup/attribute-analytics-popup-menu.stories.tsx index 65bd6757c3197dce2342a8398faa17b5cbc1649f..ad5a59f0d2f2be9abe09bf6deaba2d6f6832a236 100644 --- a/libs/shared/lib/schema/pills/nodes/popup/attribute-analytics-popup-menu.stories.tsx +++ b/libs/shared/lib/schema/pills/nodes/popup/attribute-analytics-popup-menu.stories.tsx @@ -51,6 +51,7 @@ export const Default: Story = { attribute: { name: 'Foo', type: 'string', + attributes: [], }, }, ], diff --git a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/attribute-analytics-popup-menu.stories.tsx b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/attribute-analytics-popup-menu.stories.tsx index e15d9fac1b0c1f13f174e19d18dcc7226f8926da..053778e329ec9ca22c5afb921292d28dcd1228bd 100644 --- a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/attribute-analytics-popup-menu.stories.tsx +++ b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/attribute-analytics-popup-menu.stories.tsx @@ -51,6 +51,7 @@ export const Default: Story = { attribute: { name: 'Foo', type: 'string', + attributes: [], }, }, ], diff --git a/libs/shared/lib/schema/schema-utils/schema-usecases.spec.ts b/libs/shared/lib/schema/schema-utils/schema-usecases.spec.ts index e23549351149414e52dcb78f6ccc020f21908b85..42c767efd7a1ec5fd68dac611b10fc4c2d912950 100644 --- a/libs/shared/lib/schema/schema-utils/schema-usecases.spec.ts +++ b/libs/shared/lib/schema/schema-utils/schema-usecases.spec.ts @@ -1,10 +1,9 @@ import { assert, describe, expect, it, test } from 'vitest'; -import { SchemaFromBackend } from '@graphpolaris/shared/lib/model/backend'; import { SchemaUtils } from '@graphpolaris/shared/lib/schema/schema-utils'; import { MultiGraph } from 'graphology'; import { Attributes } from 'graphology-types'; import { movieSchemaRaw, northwindSchemaRaw, simpleSchemaRaw, twitterSchemaRaw } from '@graphpolaris/shared/lib/mock-data'; -import { SchemaGraphology } from '../model'; +import { SchemaFromBackend, SchemaGraphology } from '../model'; describe('SchemaUsecases', () => { test.each([{ data: simpleSchemaRaw }, { data: movieSchemaRaw }, { data: northwindSchemaRaw }, { data: twitterSchemaRaw }])( diff --git a/libs/shared/lib/vis/geovis/GeoNodeLinkMap.stories.tsx b/libs/shared/lib/vis/geovis/GeoNodeLinkMap.stories.tsx index 613fbd23aad0822ac80f9208b108e788bbf10116..501880b4b672ac4ff09ce3bc58d3751e03657e28 100644 --- a/libs/shared/lib/vis/geovis/GeoNodeLinkMap.stories.tsx +++ b/libs/shared/lib/vis/geovis/GeoNodeLinkMap.stories.tsx @@ -42,7 +42,7 @@ export const Flights = { }, play: async () => { const dispatch = Mockstore.dispatch; - dispatch(assignNewGraphQueryResult(flights)); + dispatch(assignNewGraphQueryResult({ type: 'nodelink', payload: flights })); }, }; @@ -54,7 +54,7 @@ export const FlightsAggregated = { }, play: async () => { const dispatch = Mockstore.dispatch; - dispatch(assignNewGraphQueryResult(flights)); + dispatch(assignNewGraphQueryResult({ type: 'nodelink', payload: flights })); }, }; @@ -66,7 +66,7 @@ export const FlightsClustered = { }, play: async () => { const dispatch = Mockstore.dispatch; - dispatch(assignNewGraphQueryResult(flights)); + dispatch(assignNewGraphQueryResult({ type: 'nodelink', payload: flights })); }, }; diff --git a/libs/shared/lib/vis/geovis/GeoNodeLinkMap.tsx b/libs/shared/lib/vis/geovis/GeoNodeLinkMap.tsx index 56b613db8a50f6fe7be3617fb64b92bfbba981ca..127b5fc3c4c9eb01fd9d177202d6ff5692993f5f 100644 --- a/libs/shared/lib/vis/geovis/GeoNodeLinkMap.tsx +++ b/libs/shared/lib/vis/geovis/GeoNodeLinkMap.tsx @@ -41,7 +41,7 @@ export const GeoNodeLinkMap = React.memo(({ mapType = 0, isAggregated, isFanned, useEffect(() => { if (graphQueryResult) { const graphModel = new NodeLinkViewModel({ - nodes: graphQueryResult.nodes, + nodes: graphQueryResult.nodes as unknown as Node[], //TODO! must check if there is coordinates before accepting this cast edges: graphQueryResult.edges, }); setGraph(graphModel); @@ -49,7 +49,7 @@ export const GeoNodeLinkMap = React.memo(({ mapType = 0, isAggregated, isFanned, } }, [graphQueryResult]); - const onViewStateChange = (viewState) => { + const onViewStateChange = (viewState: { [key: string]: number }) => { setViewport(viewState); }; @@ -62,7 +62,7 @@ export const GeoNodeLinkMap = React.memo(({ mapType = 0, isAggregated, isFanned, .domain([0, 10000]) // TODO: this is not ideal and makes the color mean nothing .range(['#ef8a62', '#1D6600', '#85327B']); // use theme? - const layers = [generateBaseLayer(mapType)]; + const layers: any = [generateBaseLayer(mapType)]; if (nodelink === 'cluster') { layers.push( diff --git a/libs/shared/lib/vis/geovis/GeoNodeLinkViewModel.tsx b/libs/shared/lib/vis/geovis/GeoNodeLinkViewModel.tsx index 7f41a57026fbce9ff45e21a8b178e3e0a3f0c90c..f729d3bc22488ab2b890b0fd4bdb601f9af61ccb 100644 --- a/libs/shared/lib/vis/geovis/GeoNodeLinkViewModel.tsx +++ b/libs/shared/lib/vis/geovis/GeoNodeLinkViewModel.tsx @@ -10,7 +10,7 @@ export class NodeLinkViewModel implements ViewModel { data: Graph; private original_data: Graph; - constructor(data) { + constructor(data: Graph) { this.data = data; this.addCoordinatesToEdges(); this.original_data = this.data; @@ -22,7 +22,7 @@ export class NodeLinkViewModel implements ViewModel { addCoordinatesToEdges() { // Add coordinates to edges based on nodes - const edges = {}; + const edges: Record<string, any> = {}; this.data.edges.forEach((edge: Edge) => { const key = `${edge.from}_${edge.to}`; diff --git a/libs/shared/lib/vis/geovis/aggregateCommand.tsx b/libs/shared/lib/vis/geovis/aggregateCommand.tsx index ab96662e90e9784633fdc4077703c14bf1823471..c6ed214b1c5bff768404f1c92a9622886229259e 100644 --- a/libs/shared/lib/vis/geovis/aggregateCommand.tsx +++ b/libs/shared/lib/vis/geovis/aggregateCommand.tsx @@ -61,7 +61,7 @@ const aggregateNodes = (graph: Graph, dimension: string): Node[] => { }; const aggregateEdges = (data: Graph): Edge[] => { - const locations: { [key: string]: string[] } = data.nodes.reduce((locations, node) => { + const locations: { [key: string]: string[] } = data.nodes.reduce((locations: any, node) => { locations[node.id] = node.attributes.locations; return locations; }, {}); diff --git a/libs/shared/lib/vis/geovis/layers/BaseLayer.tsx b/libs/shared/lib/vis/geovis/layers/BaseLayer.tsx index c00f461ebb3dafce859014a61cbbd6f903dbebb5..7a09a53b659a4da4657070530bb3c259efb89c7d 100644 --- a/libs/shared/lib/vis/geovis/layers/BaseLayer.tsx +++ b/libs/shared/lib/vis/geovis/layers/BaseLayer.tsx @@ -4,7 +4,7 @@ * © Copyright Utrecht University (Department of Information and Computing Sciences) */ -import { TileLayer, BitmapLayer } from 'deck.gl'; +import { TileLayer, BitmapLayer } from 'deck.gl/typed'; import { mapTypes } from '../config'; export const generateBaseLayer = (mapType: number) => { @@ -22,13 +22,13 @@ export const generateBaseLayer = (mapType: number) => { maxZoom: 19, tileSize: 256, - renderSubLayers: (props) => { + renderSubLayers: (props: any) => { const { bbox: { west, south, east, north }, } = props.tile; return new BitmapLayer(props, { - data: null, + data: undefined, image: props.data, bounds: [west, south, east, north], }); diff --git a/libs/shared/lib/vis/geovis/layers/ClusterLayer.tsx b/libs/shared/lib/vis/geovis/layers/ClusterLayer.tsx index 7afcc99b916d3c1fadd485ac6fcd07a7d28c5e74..4f59d9cbbf6cdeef390416f67ebf2a4022557c2f 100644 --- a/libs/shared/lib/vis/geovis/layers/ClusterLayer.tsx +++ b/libs/shared/lib/vis/geovis/layers/ClusterLayer.tsx @@ -21,11 +21,11 @@ export class ClusterLayer extends CompositeLayer<LayerProps> { */ static componentName = 'Cluster Layer'; - shouldUpdateState({ changeFlags }) { + shouldUpdateState({ changeFlags }: any) { return changeFlags.somethingChanged; } - updateState({ props, oldProps, changeFlags }) { + updateState({ props, oldProps, changeFlags }: any) { const rebuildIndex = changeFlags.dataChanged; const zoom = Math.floor(this.context.viewport.zoom); @@ -40,7 +40,7 @@ export class ClusterLayer extends CompositeLayer<LayerProps> { }, }); index.load( - props.graph.data.nodes.map((node) => ({ + props.graph.data.nodes.map((node: any) => ({ geometry: { coordinates: node.attributes.coordinates }, properties: node, })) @@ -52,7 +52,7 @@ export class ClusterLayer extends CompositeLayer<LayerProps> { const nodes = this.state.index.getClusters([-180, -85, 180, 85], zoom); // Create node index for faster coordinate search - const node_index = {}; + const node_index: Record<string, any> = {}; for (const node of nodes) { const coordinates = node.geometry.coordinates; if (node.properties.hasOwnProperty('attributes')) { @@ -61,7 +61,7 @@ export class ClusterLayer extends CompositeLayer<LayerProps> { coordinates: coordinates, }; } else { - const ids = node.properties.ids; + const ids = node.properties.ids as string[]; for (const id of ids) { if (!node_index[id]) { node_index[id] = { @@ -74,8 +74,8 @@ export class ClusterLayer extends CompositeLayer<LayerProps> { } // Add updated coordinates to edges - const edges = {}; - props.graph.data.edges.forEach((edge) => { + const edges: Record<string, any> = {}; + props.graph.data.edges.forEach((edge: any) => { const source = node_index[edge.from]; const target = node_index[edge.to]; @@ -111,7 +111,6 @@ export class ClusterLayer extends CompositeLayer<LayerProps> { } renderLayers() { - console.log(new Color('#77A0A9').rgb().color); return [ new LineLayer({ id: 'edges', @@ -138,7 +137,7 @@ export class ClusterLayer extends CompositeLayer<LayerProps> { radiusMinPixels: 6, radiusMaxPixels: 20, getPosition: (d) => d.geometry.coordinates, - getFillColor: (d) => (d.properties.cluster ? new Color('#7D1128').rgb().color : new Color('#000000').rgb().color), + getFillColor: (d) => (d.properties.cluster ? (new Color('#7D1128').rgb() as any).color : (new Color('#000000').rgb() as any).color), getRadius: (d) => (d.hasOwnProperty('type') ? d.properties.ids.length * 1000 : 10), }), ]; diff --git a/libs/shared/lib/vis/geovis/layers/FacetingLayer.tsx b/libs/shared/lib/vis/geovis/layers/FacetingLayer.tsx index 47767b46ba3fb0b02cd61a95901b99276b220121..1c4a85797afa978075ae2b2d37af91034c2a9e5b 100644 --- a/libs/shared/lib/vis/geovis/layers/FacetingLayer.tsx +++ b/libs/shared/lib/vis/geovis/layers/FacetingLayer.tsx @@ -19,11 +19,11 @@ export class FacetingLayer extends CompositeLayer<LayerProps> { */ static componentName = 'FacetingLayer Layer'; - shouldUpdateState({ changeFlags }) { + shouldUpdateState({ changeFlags }: any) { return changeFlags.somethingChanged; } - updateState({ props, oldProps, changeFlags }) { + updateState({ props, oldProps, changeFlags }: any) { const rebuildIndex = changeFlags.dataChanged; const zoom = Math.floor(this.context.viewport.zoom); diff --git a/libs/shared/lib/vis/geovis/layers/NodeLinkLayer.tsx b/libs/shared/lib/vis/geovis/layers/NodeLinkLayer.tsx index db44e9d22703c004c31dad1b49f916596118f276..183f72df031ac964b7193d4443c55a6c888d39f0 100644 --- a/libs/shared/lib/vis/geovis/layers/NodeLinkLayer.tsx +++ b/libs/shared/lib/vis/geovis/layers/NodeLinkLayer.tsx @@ -16,7 +16,7 @@ export class NodeLinkLayer extends CompositeLayer<LayerProps> { */ static componentName = 'Knowledge Graph Layer'; - shouldUpdateState({ changeFlags }) { + shouldUpdateState({ changeFlags }: any) { return changeFlags.somethingChanged; } diff --git a/libs/shared/lib/vis/geovis/readability.tsx b/libs/shared/lib/vis/geovis/readability.tsx index 6f0c5881af1bbdee853836424fdaa16083b58890..6a152eeb73b1af65dd6f1b3928ad3b009b9eb02a 100644 --- a/libs/shared/lib/vis/geovis/readability.tsx +++ b/libs/shared/lib/vis/geovis/readability.tsx @@ -39,7 +39,7 @@ export const EdgeCrossings = (edges: Edge[]) => { return n_crossings; }; -const doEdgesCross = (edge_one, edge_two) => { +const doEdgesCross = (edge_one: any, edge_two: any) => { const from1 = edge_one.from_coordinates; const to1 = edge_one.to_coordinates; const from2 = edge_two.from_coordinates; @@ -50,19 +50,19 @@ const doEdgesCross = (edge_one, edge_two) => { // Inspiration: https://github.com/rpgove/greadability/blob/master/greadability.js -const direction = (pi, pj, pk) => { +const direction = (pi: any, pj: any, pk: any) => { var p1 = [pk[0] - pi[0], pk[1] - pi[1]]; var p2 = [pj[0] - pi[0], pj[1] - pi[1]]; return p1[0] * p2[1] - p2[0] * p1[1]; }; -const onSegment = (pi, pj, pk) => { +const onSegment = (pi: any, pj: any, pk: any) => { return ( Math.min(pi[0], pj[0]) <= pk[0] && pk[0] <= Math.max(pi[0], pj[0]) && Math.min(pi[1], pj[1]) <= pk[1] && pk[1] <= Math.max(pi[1], pj[1]) ); }; -const linesCross = (line1, line2) => { +const linesCross = (line1: any, line2: any) => { var d1, d2, d3, d4; d1 = direction(line2[0], line2[1], line1[0]); diff --git a/libs/shared/lib/vis/geovis/utils.tsx b/libs/shared/lib/vis/geovis/utils.tsx index 291a308d2ecc23df5a6d3082cd097907ce9aaf0e..465f4bff24b23be5fe837ad761b356034d975b00 100644 --- a/libs/shared/lib/vis/geovis/utils.tsx +++ b/libs/shared/lib/vis/geovis/utils.tsx @@ -11,7 +11,7 @@ export const calcMaxWidth = (viewport: Viewport): number => { return Math.sqrt(Math.pow(vpBounds[0] - vpBounds[2], 2) + Math.pow(vpBounds[1] - vpBounds[3], 2)); }; -export const getColor = (prediction, colorScale): [number, number, number] => { +export const getColor = (prediction: any, colorScale: any): [number, number, number] => { return colorScale(prediction) .replace(/[^\d,]/g, '') .split(',') @@ -58,7 +58,7 @@ export const getInitialViewState = (graph: Graph, coordinate_path: string = 'att }; }; -export const getKeys = (graph, prefix = '', paths = { nodes: new Set(), edges: new Set() }) => { +export const getKeys = (graph: any, prefix = '', paths = { nodes: new Set(), edges: new Set() }) => { for (const key in graph) { if (typeof graph[key] === 'object' && graph[key] !== null) { if (Array.isArray(graph[key])) { diff --git a/libs/shared/lib/vis/nodelink/NodeLinkViewModel.tsx b/libs/shared/lib/vis/nodelink/NodeLinkViewModel.tsx index f910470768d78b543d77df82923b99ac8682354a..c1548f3c0560591c10f2f33a04d188ee01a0c9eb 100644 --- a/libs/shared/lib/vis/nodelink/NodeLinkViewModel.tsx +++ b/libs/shared/lib/vis/nodelink/NodeLinkViewModel.tsx @@ -3,7 +3,8 @@ * Utrecht University within the Software Project course. * © Copyright Utrecht University (Department of Information and Computing Sciences) */ -import { GraphType, LinkType, NodeType } from './nodelinkviz.types'; +import { GraphType, LinkType, NodeType } from '../nodelink/Types'; + import * as PIXI from 'pixi.js'; import React from 'react'; import * as d3 from 'd3'; @@ -429,7 +430,7 @@ export default class NodeLinkViewModel { if (node.attributes) { let index = 0; for (const key in node.attributes) { - const attributes = this.visibleAttributes[node.label]; + const attributes = this.visibleAttributes[node?.label || node.id]; const attributeHidden = attributes ? attributes[key] === false : false; if (attributeHidden) continue; // if attribute should be hidden, then skip this.addAttribute(keys, values, key, String(node.attributes[key]), index); diff --git a/libs/shared/lib/vis/nodelink/Types.tsx b/libs/shared/lib/vis/nodelink/Types.tsx index 591ef18c86f8f7d72aed08fa412da8bdc5dd4659..377847dc51a5c265da1e1002e8d708df4bfc4fb4 100644 --- a/libs/shared/lib/vis/nodelink/Types.tsx +++ b/libs/shared/lib/vis/nodelink/Types.tsx @@ -21,6 +21,7 @@ export interface NodeType extends d3.SimulationNodeDatum { id: string; // Number to determine the color of the node + label?: string; type: number; attributes?: Record<string, any>; cluster?: number; diff --git a/libs/shared/lib/vis/nodelink/nodelinkvis.stories.tsx b/libs/shared/lib/vis/nodelink/nodelinkvis.stories.tsx index c93b4e136fe1474043a47b628af5d2cd6aae54c3..113e73554ae23c0a0f0e30960bee464b2609770e 100644 --- a/libs/shared/lib/vis/nodelink/nodelinkvis.stories.tsx +++ b/libs/shared/lib/vis/nodelink/nodelinkvis.stories.tsx @@ -54,11 +54,14 @@ export const TestWithData = { const dispatch = Mockstore.dispatch; dispatch( assignNewGraphQueryResult({ - nodes: [ - { id: 'agent/007', attributes: { name: 'Daniel Craig' } }, - { id: 'villain', attributes: { name: 'Le Chiffre' } }, - ], - edges: [{ from: 'agent/007', to: 'villain', attributes: { name: 'Escape' } }], + type: 'nodelink', + payload: { + nodes: [ + { id: 'agent/007', attributes: { name: 'Daniel Craig' } }, + { id: 'villain', attributes: { name: 'Le Chiffre' } }, + ], + edges: [{ id: 'escape/escape', from: 'agent/007', to: 'villain', attributes: { name: 'Escape' } }], + }, }) ); }, @@ -70,8 +73,11 @@ export const TestWithNoData = { const dispatch = Mockstore.dispatch; dispatch( assignNewGraphQueryResult({ - nodes: [], - edges: [], + type: 'nodelink', + payload: { + nodes: [], + edges: [], + }, }) ); }, @@ -81,7 +87,7 @@ export const TestWithBig2ndChamber = { args: { loading: false }, play: async () => { const dispatch = Mockstore.dispatch; - dispatch(assignNewGraphQueryResult(big2ndChamberQueryResult)); + dispatch(assignNewGraphQueryResult({ type: 'nodelink', payload: big2ndChamberQueryResult })); }, }; @@ -89,7 +95,7 @@ export const TestWithSmallFlights = { args: { loading: false }, play: async () => { const dispatch = Mockstore.dispatch; - dispatch(assignNewGraphQueryResult(smallFlightsQueryResults)); + dispatch(assignNewGraphQueryResult({ type: 'nodelink', payload: smallFlightsQueryResults })); }, }; @@ -97,7 +103,7 @@ export const TestWithLargeQueryResult = { args: { loading: false }, play: async () => { const dispatch = Mockstore.dispatch; - dispatch(assignNewGraphQueryResult(mockLargeQueryResults)); + dispatch(assignNewGraphQueryResult({ type: 'nodelink', payload: mockLargeQueryResults })); }, }; diff --git a/libs/shared/lib/vis/nodelink/nodelinkvis.tsx b/libs/shared/lib/vis/nodelink/nodelinkvis.tsx index 3e28c34c97768aef601080a5cba6edfb1fd083b0..1c6d4b2c60e7609c7b7b80280e61fa5f79092e3c 100644 --- a/libs/shared/lib/vis/nodelink/nodelinkvis.tsx +++ b/libs/shared/lib/vis/nodelink/nodelinkvis.tsx @@ -9,7 +9,6 @@ import { GraphType, LinkType, NodeType } from './Types'; import NodeLinkViewModel from './NodeLinkViewModel'; import ResultNodeLinkParserUseCase from '../shared/ResultNodeLinkParserUseCase'; import VisConfigPanelComponent from '../shared/VisConfigPanel/VisConfigPanel'; -import NodeLinkConfigPanelComponent from './config-panel/NodeConfigPanelComponent'; import { use } from 'cytoscape'; interface Props { diff --git a/libs/shared/lib/vis/nodelink/nodelinkviz.types.tsx b/libs/shared/lib/vis/nodelink/nodelinkviz.types.tsx deleted file mode 100644 index 7174e205a03130e1597c76897c35de5198cedc41..0000000000000000000000000000000000000000 --- a/libs/shared/lib/vis/nodelink/nodelinkviz.types.tsx +++ /dev/null @@ -1,98 +0,0 @@ -/** - * This program has been developed by students from the bachelor Computer Science at - * Utrecht University within the Software Project course. - * © Copyright Utrecht University (Department of Information and Computing Sciences) - */ - -import * as PIXI from 'pixi.js'; - -/** Types for the nodes and links in the node-link diagram. */ -export type GraphType = { - nodes: NodeType[]; - links: LinkType[]; - linkPrediction: boolean; - shortestPath: boolean; - communityDetection: boolean; - numberOfMlClusters?: number; -}; - -/** The interface for a node in the node-link diagram */ -export interface NodeType extends d3.SimulationNodeDatum { - id: string; - label: string; - - // Number to determine the color of the node - type: number; - attributes?: Record<string, any>; - cluster?: number; - clusterAccoringToMLData?: number; - shortestPathData?: Record<string, string[]>; - - // Node that is drawn. - gfx?: PIXI.Graphics; - radius?: number; - // Text to be displayed on top of the node. - gfxtext?: PIXI.Text; - gfxAttributes?: PIXI.Graphics; - selected?: boolean; - index?: number; - - // The text that will be shown on top of the node if selected. - displayInfo?: string; - - // Node’s current x-position. - x?: number; - - // Node’s current y-position. - y?: number; - - // Node’s current x-velocity - vx?: number; - - // Node’s current y-velocity - vy?: number; - - // Node’s fixed x-position (if position was fixed) - fx?: number | null; - - // Node’s fixed y-position (if position was fixed) - fy?: number | null; -} - -/** The interface for a link in the node-link diagram */ -export interface LinkType extends d3.SimulationLinkDatum<NodeType> { - // The thickness of a line - value: number; - // To check if an edge is calculated based on a ML algorithm - mlEdge: boolean; -} - -/**collectionNode holds 1 entry per node kind (so for example a MockNode with name "parties" and all associated attributes,) */ -export type TypeNode = { - name: string; //Collection name - attributes: string[]; //attributes. This includes all attributes found in the collection - type: number | undefined; //number that represents collection of node, for colorscheme - visualisations: Visualisation[]; //The way to visualize attributes of this Node kind -}; - -export type CommunityDetectionNode = { - cluster: number; //group as used by colouring scheme -}; - -/**Visualisation holds the visualisation method for an attribute */ -export type Visualisation = { - attribute: string; //attribute type (e.g. 'age') - vis: string; //visualisation type (e.g. 'radius') -}; - -/** possible colors to pick from*/ -export type Colors = { - name: string; -}; - -/**AssignedColors is a simple holder for color selection */ -export type AssignedColors = { - collection: number | undefined; //number of the collection (type or group) - color: string; //color in hex - default: string; //default color, for easy switching back -}; diff --git a/libs/shared/lib/vis/paohvis/components/PaohvisFilterComponent.tsx b/libs/shared/lib/vis/paohvis/components/PaohvisFilterComponent.tsx index 3ad50edbc150fa138085078f243d0c7b32a674fd..76377ee7d0077e7134dfae6f13b97773c3ed410a 100644 --- a/libs/shared/lib/vis/paohvis/components/PaohvisFilterComponent.tsx +++ b/libs/shared/lib/vis/paohvis/components/PaohvisFilterComponent.tsx @@ -15,7 +15,6 @@ import { useImmer } from 'use-immer'; import { Button, MenuItem, TextField } from '@mui/material'; import { useGraphQueryResult, useSchemaGraph } from '@graphpolaris/shared/lib/data-access'; import { isNodeLinkResult } from '../../shared/ResultNodeLinkParserUseCase'; -import { isSchemaResult } from '../../shared/SchemaResultType'; import { calculateAttributesAndRelations, calculateAttributesFromRelation } from '../utils/utils'; import { boolPredicates, numberPredicates, textPredicates } from '../models/FilterPredicates'; import { style } from 'd3'; diff --git a/libs/shared/lib/vis/paohvis/components/Tooltip.tsx b/libs/shared/lib/vis/paohvis/components/Tooltip.tsx index faf885025f6feedfac6ce22226a8be65cdcd9eb4..2ee467411bac3c92fd860d47e5001b01670697fb 100644 --- a/libs/shared/lib/vis/paohvis/components/Tooltip.tsx +++ b/libs/shared/lib/vis/paohvis/components/Tooltip.tsx @@ -13,18 +13,18 @@ import React from 'react'; import './Tooltip.scss'; import { pointer, select } from 'd3'; -export default class Tooltip extends React.Component { - onMouseOver(e: any) { +export const Tooltip = () => { + function onMouseOver(e: any) { select('.tooltip') .style('top', pointer(e)[1]) .style('left', pointer(e)[0] + 5); } - render() { - return ( - <div style={{ position: 'absolute' }} className="tooltip"> - {' '} - </div> - ); - } -} + return ( + <div style={{ position: 'absolute' }} className="tooltip"> + {' '} + </div> + ); +}; + +export default Tooltip; diff --git a/libs/shared/lib/vis/paohvis/paohvis.module.scss b/libs/shared/lib/vis/paohvis/paohvis.module.scss index 04d9b30d2389a0ac213b526ed883474037ff32ed..b69ef02e3f6c6008cfe84e1a52385c293ec40354 100644 --- a/libs/shared/lib/vis/paohvis/paohvis.module.scss +++ b/libs/shared/lib/vis/paohvis/paohvis.module.scss @@ -58,10 +58,10 @@ $tableFontWeight: 600; font-size: $tableFontSize; font-weight: $tableFontWeight; } - #tableMessage { + .tableMessage { margin: 1em; } - #configPanelMessage { + .configPanelMessage { margin: 1em; } } diff --git a/libs/shared/lib/vis/paohvis/paohvis.module.scss.d.ts b/libs/shared/lib/vis/paohvis/paohvis.module.scss.d.ts index 171993a6d01f7e9c214688fe9d9145dc7698da37..cebc85c3f7d20544de57312f165ada2c75a685a5 100644 --- a/libs/shared/lib/vis/paohvis/paohvis.module.scss.d.ts +++ b/libs/shared/lib/vis/paohvis/paohvis.module.scss.d.ts @@ -7,5 +7,7 @@ declare const classNames: { readonly visContainer: 'visContainer'; readonly full: 'full'; readonly visContainerSvg: 'visContainerSvg'; + readonly tableMessage: 'tableMessage'; + readonly configPanelMessage: 'configPanelMessage'; }; export = classNames; diff --git a/libs/shared/lib/vis/paohvis/paohvis.stories.tsx b/libs/shared/lib/vis/paohvis/paohvis.stories.tsx index c4858a37e34f6b1b634414d7556b031e81e2370a..a06fae382ded0af732c5ab1f38ef0df0bd3ddc3f 100644 --- a/libs/shared/lib/vis/paohvis/paohvis.stories.tsx +++ b/libs/shared/lib/vis/paohvis/paohvis.stories.tsx @@ -70,18 +70,21 @@ export const TestWithData = { dispatch(setSchema(schema.export())); dispatch( assignNewGraphQueryResult({ - nodes: [ - { id: '1/a', attributes: { a: 's1' } }, - { id: '1/b1', attributes: { a: 's1' } }, - { id: '1/b2', attributes: { a: 's1' } }, - { id: '1/b3', attributes: { a: 's1' } }, - ], - edges: [ - { id: '1c/z1', from: '1/b1', to: '1/a', attributes: { a: 's1' } }, - // { from: 'b2', to: 'a', attributes: {} }, - // { from: 'b3', to: 'a', attributes: {} }, - { id: '1c/z1', from: '1/a', to: '1/b1', attributes: { a: 's1' } }, - ], + type: 'nodelink', + payload: { + nodes: [ + { id: '1/a', label: 'a', attributes: { a: 's1' } }, + { id: '1/b1', label: 'b1', attributes: { a: 's1' } }, + { id: '1/b2', label: 'b2', attributes: { a: 's1' } }, + { id: '1/b3', label: 'b3', attributes: { a: 's1' } }, + ], + edges: [ + { id: '1c/z1', label: 'z1', from: '1/b1', to: '1/a', attributes: { a: 's1' } }, + // { from: 'b2', to: 'a', attributes: {} }, + // { from: 'b3', to: 'a', attributes: {} }, + { id: '1c/z1', label: 'z1', from: '1/a', to: '1/b1', attributes: { a: 's1' } }, + ], + }, }) ); }, @@ -99,7 +102,7 @@ export const TestWithAirportSimple = { const schema = SchemaUtils.schemaBackend2Graphology(simpleSchemaRaw); dispatch(setSchema(schema.export())); - dispatch(assignNewGraphQueryResult(smallFlightsQueryResults)); + dispatch(assignNewGraphQueryResult({ type: 'nodelink', payload: smallFlightsQueryResults })); }, }; @@ -115,7 +118,7 @@ export const TestWithAirport = { const schema = SchemaUtils.schemaBackend2Graphology(simpleSchemaAirportRaw); dispatch(setSchema(schema.export())); - dispatch(assignNewGraphQueryResult(bigMockQueryResults)); + dispatch(assignNewGraphQueryResult({ type: 'nodelink', payload: bigMockQueryResults })); }, }; diff --git a/libs/shared/lib/vis/paohvis/paohvis.tsx b/libs/shared/lib/vis/paohvis/paohvis.tsx index 38148a9cd57e7bc8b0ed8bf86e72c62f62e02755..4c2ab978d030686205b55ebab9f2ad75e4499ddb 100644 --- a/libs/shared/lib/vis/paohvis/paohvis.tsx +++ b/libs/shared/lib/vis/paohvis/paohvis.tsx @@ -18,7 +18,6 @@ import { useImmer } from 'use-immer'; import { getWidthOfText } from '../../schema/schema-utils'; import { useGraphQueryResult, useSchemaGraph } from '../../data-access'; import { isNodeLinkResult } from '../shared/ResultNodeLinkParserUseCase'; -import { isSchemaResult } from '../shared/SchemaResultType'; import { calculateAttributesAndRelations, calculateAttributesFromRelation } from './utils/utils'; import VisConfigPanelComponent from '../shared/VisConfigPanel/VisConfigPanel'; import { PaohvisFilterComponent } from './components/PaohvisFilterComponent'; @@ -465,16 +464,12 @@ export const PaohVis = (props: Props) => { // useEffect(() => { - // if (isSchemaResult(schema)) { setViewModel((draft) => { // When a schema is received, extract the entity names, and attributes per data type draft.entitiesFromSchema = calculateAttributesAndRelations(schema); draft.relationsFromSchema = calculateAttributesFromRelation(schema); return draft; }); - // } else { - // console.error('Invalid schema!') - // } }, [schema]); /** This method filters and makes a new Paohvis table. */ diff --git a/libs/shared/lib/vis/paohvis/utils/ToPaohvisDataParserUsecase.tsx b/libs/shared/lib/vis/paohvis/utils/ToPaohvisDataParserUsecase.tsx index ae8cb2e3ae886d10df125519dc7a326cc91c8b64..de75b4d88b39d21886fb1cd6714e8d5bb2d1d8ad 100644 --- a/libs/shared/lib/vis/paohvis/utils/ToPaohvisDataParserUsecase.tsx +++ b/libs/shared/lib/vis/paohvis/utils/ToPaohvisDataParserUsecase.tsx @@ -22,7 +22,7 @@ import { import AttributeFilterUsecase, { filterUnusedEdges, getIds } from './AttributesFilterUseCase'; import SortUseCase from './SortUseCase'; import { getWidthOfText, uniq } from './utils'; -import style from '../Paohvis.module.scss'; +import style from '../paohvis.module.scss'; type Index = number; diff --git a/libs/shared/lib/vis/rawjsonvis/rawjsonvis.stories.tsx b/libs/shared/lib/vis/rawjsonvis/rawjsonvis.stories.tsx index 534cd6b36a2367cff35b857f1377e0721c7a903b..70492c16e01d919d772367dbbbc4361fc11800be 100644 --- a/libs/shared/lib/vis/rawjsonvis/rawjsonvis.stories.tsx +++ b/libs/shared/lib/vis/rawjsonvis/rawjsonvis.stories.tsx @@ -45,11 +45,14 @@ export const SimpleData = { const dispatch = Mockstore.dispatch; dispatch( assignNewGraphQueryResult({ - nodes: [ - { id: 'agent/007', attributes: { name: 'Daniel Craig' } }, - { id: 'villain', attributes: { name: 'Le Chiffre' } }, - ], - edges: [], + type: 'nodelink', + payload: { + nodes: [ + { id: 'agent/007', attributes: { name: 'Daniel Craig' } }, + { id: 'villain', attributes: { name: 'Le Chiffre' } }, + ], + edges: [], + }, }) ); }, @@ -61,7 +64,12 @@ export const LargeData = { }, play: async () => { const dispatch = Mockstore.dispatch; - dispatch(assignNewGraphQueryResult(mockLargeQueryResults)); + dispatch( + assignNewGraphQueryResult({ + type: 'nodelink', + payload: mockLargeQueryResults, + }) + ); }, }; diff --git a/libs/shared/lib/vis/semanticsubstrates/SemanticSubstratesViewModel.t b/libs/shared/lib/vis/semanticsubstrates/SemanticSubstratesViewModel.t deleted file mode 100644 index 2b1b6b26775e238d0f5e8e1f64089e00e83f6ec4..0000000000000000000000000000000000000000 --- a/libs/shared/lib/vis/semanticsubstrates/SemanticSubstratesViewModel.t +++ /dev/null @@ -1,1156 +0,0 @@ -import Broker from '../../../../domain/entity/broker/broker'; -import SemanticSubstratesViewModelImpl from './SemanticSubstratesViewModelImpl'; -import mockNodeLinkResult from '../../../../data/mock-data/query-result/big2ndChamberQueryResult'; -import mockSchema from '../../../../data/mock-data/schema-result/2ndChamberSchemaMock'; -import { MinMaxType } from '../../../../domain/entity/semantic-substrates/structures/Types'; - -jest.mock('../../../view/result-visualisations/semantic-substrates/SemanticSubstratesStylesheet'); - -describe('SemanticSubstratesViewModelImpl: Broker subscriptions', () => { - it('should consume schema results when subscribed', () => { - const viewModel = new SemanticSubstratesViewModelImpl(); - - const mockConsumeMessages = jest.fn(); - viewModel.consumeMessageFromBackend = mockConsumeMessages; - - viewModel.subscribeToSchemaResult(); - Broker.instance().publish('test schema result', 'schema_result'); - expect(mockConsumeMessages.mock.calls[0][0]).toEqual('test schema result'); - - viewModel.unSubscribeFromSchemaResult(); - Broker.instance().publish('test schema result', 'schema_result'); - expect(mockConsumeMessages).toBeCalledTimes(1); - }); -}); - -describe('SemanticSubstratesViewModelImpl:OnPlotTitleChanged', () => { - it('should change the plot title', () => { - // Initialize a ViewModel with some plots. - const viewModelImpl = new SemanticSubstratesViewModelImpl(); - viewModelImpl.consumeMessageFromBackend(mockSchema); - viewModelImpl.consumeMessageFromBackend(mockNodeLinkResult); - - const onViewModelChangedMock = jest.fn(); - const baseViewMock = { - onViewModelChanged: onViewModelChangedMock, - }; - viewModelImpl.attachView(baseViewMock); - - const i = 1; - const oldPlotSpec = viewModelImpl.plotSpecifications[i]; - viewModelImpl.onPlotTitleChanged(i, 'commissies', 'naam', 'Defensie'); - - expect(viewModelImpl.plotSpecifications[i]).toEqual({ - ...oldPlotSpec, - entity: 'commissies', - labelAttributeType: 'naam', - labelAttributeValue: 'Defensie', - }); - - // And check if the NotifyViewAboutChanges is called. - expect(onViewModelChangedMock).toBeCalledTimes(1); - - viewModelImpl.onPlotTitleChanged(i, 'commissies', 'id', 'Defensie'); - expect(viewModelImpl.plotSpecifications[i]).toEqual({ - ...oldPlotSpec, - entity: 'commissies', - labelAttributeType: 'id', - labelAttributeValue: 'Defensie', - }); - }); -}); - -describe('SemanticSubstratesViewModelImpl', () => { - it('should apply default specs on consuming a new node link result', () => { - const viewModelImpl = new SemanticSubstratesViewModelImpl(); - - const onViewModelChangedMock = jest.fn(); - const baseViewMock = { - onViewModelChanged: onViewModelChangedMock, - }; - viewModelImpl.attachView(baseViewMock); - - viewModelImpl.consumeMessageFromBackend(mockSchema); - - // Consume a nodelink query result. - viewModelImpl.consumeMessageFromBackend(mockNodeLinkResult); - - let mockCalc = viewModelImpl.scaleCalculation; - let mockCalcColour = viewModelImpl.colourCalculation; - - const expectedPlots = [ - { - title: 'partij:VVD', - nodes: [ - { - id: 'kamerleden/148', - data: { text: 'kamerleden/148' }, - originalPosition: { x: 1, y: 0 }, - attributes: { - anc: 1526, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/9ab41898-332f-4c08-a834-d58b4669c990.jpg?itok=pbUPRriP', - leeftijd: 43, - naam: 'Dilan Yeilgz-Zegerius', - partij: 'VVD', - woonplaats: 'Amsterdam', - }, - scaledPosition: { x: 114.28571428571432, y: 100 }, - }, - { - id: 'kamerleden/132', - data: { text: 'kamerleden/132' }, - originalPosition: { x: 2, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/b625d2bf-da74-40a2-b013-2069a09dcb6c.jpg?itok=zMgno8bi', - leeftijd: 36, - naam: 'Peter Valstar', - partij: 'VVD', - woonplaats: "'s-Gravenzande", - }, - scaledPosition: { x: 133.99014778325127, y: 100 }, - }, - { - id: 'kamerleden/131', - data: { text: 'kamerleden/131' }, - originalPosition: { x: 3, y: 0 }, - attributes: { - anc: 1304, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/97ffe642-648f-4dab-a0e8-0720e96e3e35.jpg?itok=eDllv9dS', - leeftijd: 49, - naam: 'Judith Tielen', - partij: 'VVD', - woonplaats: 'Utrecht', - }, - scaledPosition: { x: 153.6945812807882, y: 100 }, - }, - { - id: 'kamerleden/128', - data: { text: 'kamerleden/128' }, - originalPosition: { x: 4, y: 0 }, - attributes: { - anc: 3171, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/2538ca6a-8254-4c7e-af71-a20db82afd30.jpg?itok=GvwO8NYO', - leeftijd: 46, - naam: 'Ockje Tellegen', - partij: 'VVD', - woonplaats: "'s-Gravenhage", - }, - scaledPosition: { x: 173.39901477832515, y: 100 }, - }, - { - id: 'kamerleden/117', - data: { text: 'kamerleden/117' }, - originalPosition: { x: 5, y: 0 }, - attributes: { - anc: 2004, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/8b3664bd-77e4-468b-af96-f3f4ec27fcce.jpg?itok=ofrc9cnP', - leeftijd: 54, - naam: 'Mark Rutte', - partij: 'VVD', - woonplaats: "'s-Gravenhage", - }, - scaledPosition: { x: 193.1034482758621, y: 100 }, - }, - { - id: 'kamerleden/106', - data: { text: 'kamerleden/106' }, - originalPosition: { x: 6, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/0e34f732-337a-4339-961f-8c18d68e714d.jpg?itok=FTBMCT9a', - leeftijd: 54, - naam: 'Marille Paul', - partij: 'VVD', - woonplaats: 'Amsterdam', - }, - scaledPosition: { x: 212.80788177339906, y: 100 }, - }, - { - id: 'kamerleden/100', - data: { text: 'kamerleden/100' }, - originalPosition: { x: 7, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/2b223ce1-e251-462b-a5fc-971c92bbf37c.jpg?itok=MD8qI-l1', - leeftijd: 43, - naam: 'Daan de Neef', - partij: 'VVD', - woonplaats: 'Breda', - }, - scaledPosition: { x: 232.512315270936, y: 100 }, - }, - { - id: 'kamerleden/97', - data: { text: 'kamerleden/97' }, - originalPosition: { x: 8, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/cd02edbc-106e-46d1-8d70-6594741356ea.jpg?itok=Q9q13ntf', - leeftijd: 33, - naam: 'Fahid Minhas', - partij: 'VVD', - woonplaats: 'Schiedam', - }, - scaledPosition: { x: 252.21674876847294, y: 100 }, - }, - { - id: 'kamerleden/81', - data: { text: 'kamerleden/81' }, - originalPosition: { x: 9, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/8767e9de-869e-4e8a-940f-1a63d15eab3c.jpg?itok=tdoE8yQX', - leeftijd: 28, - naam: 'Daan de Kort', - partij: 'VVD', - woonplaats: 'Veldhoven', - }, - scaledPosition: { x: 271.9211822660099, y: 100 }, - }, - { - id: 'kamerleden/79', - data: { text: 'kamerleden/79' }, - originalPosition: { x: 10, y: 0 }, - attributes: { - anc: 1526, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/88e0734b-8c03-4daa-8ec5-055e36c07030.jpg?itok=_ZteUeWk', - leeftijd: 39, - naam: 'Daniel Koerhuis', - partij: 'VVD', - woonplaats: 'Raalte', - }, - scaledPosition: { x: 291.6256157635468, y: 100 }, - }, - { - id: 'kamerleden/145', - data: { text: 'kamerleden/145' }, - originalPosition: { x: 11, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/8ee20f38-f3f0-4ff9-b5d9-84557b5ddcb1.jpg?itok=ExYCR1Ti', - leeftijd: 51, - naam: 'Hatte van der Woude', - partij: 'VVD', - woonplaats: 'Delft', - }, - scaledPosition: { x: 311.3300492610838, y: 100 }, - }, - { - id: 'kamerleden/70', - data: { text: 'kamerleden/70' }, - originalPosition: { x: 12, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/f23be4bd-7b2b-45dd-be84-4f76f11b624a.jpg?itok=DsfJ-8o0', - leeftijd: 43, - naam: 'Roelien Kamminga', - partij: 'VVD', - woonplaats: 'Groningen', - }, - scaledPosition: { x: 331.03448275862075, y: 100 }, - }, - { - id: 'kamerleden/127', - data: { text: 'kamerleden/127' }, - originalPosition: { x: 13, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/ce400601-651e-4ac9-a43e-ed8d4817b7fd.jpg?itok=wsISYKCx', - leeftijd: 44, - naam: 'Pim van Strien', - partij: 'VVD', - woonplaats: 'Amsterdam', - }, - scaledPosition: { x: 350.7389162561577, y: 100 }, - }, - { - id: 'kamerleden/115', - data: { text: 'kamerleden/115' }, - originalPosition: { x: 14, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/4bf69aa9-29a7-44db-b7ee-8bfa40e343dd.jpg?itok=-BKeAg8F', - leeftijd: 32, - naam: 'Queeny Rajkowski', - partij: 'VVD', - woonplaats: 'Utrecht', - }, - scaledPosition: { x: 370.44334975369463, y: 100 }, - }, - { - id: 'kamerleden/64', - data: { text: 'kamerleden/64' }, - originalPosition: { x: 15, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/7954eb2c-1bf5-42af-80dc-85f29b367db0.jpg?itok=9ucjAERV', - leeftijd: 49, - naam: 'Folkert Idsinga', - partij: 'VVD', - woonplaats: 'Amsterdam', - }, - scaledPosition: { x: 390.1477832512316, y: 100 }, - }, - { - id: 'kamerleden/60', - data: { text: 'kamerleden/60' }, - originalPosition: { x: 16, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/8509e44d-0f9b-413a-a2cd-f64d656c3955.jpg?itok=Iy2_G4Jx', - leeftijd: 53, - naam: 'Jacqueline van den Hil', - partij: 'VVD', - woonplaats: 'Goes', - }, - scaledPosition: { x: 409.8522167487685, y: 100 }, - }, - { - id: 'kamerleden/143', - data: { text: 'kamerleden/143' }, - originalPosition: { x: 17, y: 0 }, - attributes: { - anc: 1823, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/7d18b6e3-de0c-4aea-bef8-242bbc38e936.jpg?itok=zebZoGjq', - leeftijd: 43, - naam: 'Jeroen van Wijngaarden', - partij: 'VVD', - woonplaats: 'Amsterdam', - }, - scaledPosition: { x: 429.55665024630554, y: 100 }, - }, - { - id: 'kamerleden/56', - data: { text: 'kamerleden/56' }, - originalPosition: { x: 18, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/a3b17348-54cf-4bca-82d4-e62bd46c2fbc.jpg?itok=MF1OOpeK', - leeftijd: 40, - naam: 'Eelco Heinen', - partij: 'VVD', - woonplaats: "'s-Gravenhage", - }, - scaledPosition: { x: 449.26108374384245, y: 100 }, - }, - { - id: 'kamerleden/142', - data: { text: 'kamerleden/142' }, - originalPosition: { x: 19, y: 0 }, - attributes: { - anc: 1526, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/c3b1dca8-2cb4-4025-9527-36163a098c1f.jpg?itok=3BnXwQgy', - leeftijd: 35, - naam: 'Dennis Wiersma', - partij: 'VVD', - woonplaats: 'De Bilt', - }, - scaledPosition: { x: 468.96551724137936, y: 100 }, - }, - { - id: 'kamerleden/46', - data: { text: 'kamerleden/46' }, - originalPosition: { x: 20, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/a0b48551-42b7-4c55-9556-6b997d978ff2.jpg?itok=-A3mAzHe', - leeftijd: 41, - naam: 'Peter de Groot', - partij: 'VVD', - woonplaats: 'Harderwijk', - }, - scaledPosition: { x: 488.6699507389164, y: 100 }, - }, - { - id: 'kamerleden/38', - data: { text: 'kamerleden/38' }, - originalPosition: { x: 21, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/9c8bc5bc-8d13-4c11-be37-57a43a1d734b.jpg?itok=TqEaAJCz', - leeftijd: 30, - naam: 'Silvio Erkens', - partij: 'VVD', - woonplaats: 'Kerkrade', - }, - scaledPosition: { x: 508.3743842364533, y: 100 }, - }, - { - id: 'kamerleden/35', - data: { text: 'kamerleden/35' }, - originalPosition: { x: 22, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/ea21d788-7cfe-41ff-b22f-0664397139af.jpg?itok=4G8NOaak', - leeftijd: 32, - naam: 'Ulysse Ellian', - partij: 'VVD', - woonplaats: 'Almere', - }, - scaledPosition: { x: 528.0788177339903, y: 100 }, - }, - { - id: 'kamerleden/33', - data: { text: 'kamerleden/33' }, - originalPosition: { x: 23, y: 0 }, - attributes: { - anc: 1526, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/c4f7c468-721e-4953-97f2-bff05fe570c4.jpg?itok=MmXfOgJx', - leeftijd: 41, - naam: 'Zohair El Yassini', - partij: 'VVD', - woonplaats: 'Utrecht', - }, - scaledPosition: { x: 547.7832512315272, y: 100 }, - }, - { - id: 'kamerleden/25', - data: { text: 'kamerleden/25' }, - originalPosition: { x: 24, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/bf494e35-c009-4c74-a5c6-3cb2cd26bb51.jpg?itok=2CTfrPhP', - leeftijd: 31, - naam: 'Thom van Campen', - partij: 'VVD', - woonplaats: 'Zwolle', - }, - scaledPosition: { x: 567.4876847290642, y: 100 }, - }, - { - id: 'kamerleden/54', - data: { text: 'kamerleden/54' }, - originalPosition: { x: 25, y: 0 }, - attributes: { - anc: 2601, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/522d59a0-10ba-488f-a27a-a1dda7581900.jpg?itok=5b_3G5nE', - leeftijd: 43, - naam: 'Rudmer Heerema', - partij: 'VVD', - woonplaats: 'Alkmaar', - }, - scaledPosition: { x: 587.1921182266011, y: 100 }, - }, - { - id: 'kamerleden/96', - data: { text: 'kamerleden/96' }, - originalPosition: { x: 26, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/973da897-66c7-4010-a98d-505e0e97a60c.jpg?itok=HLNJtdsA', - leeftijd: 44, - naam: 'Ingrid Michon-Derkzen', - partij: 'VVD', - woonplaats: "'s-Gravenhage", - }, - scaledPosition: { x: 606.896551724138, y: 100 }, - }, - { - id: 'kamerleden/9', - data: { text: 'kamerleden/9' }, - originalPosition: { x: 27, y: 0 }, - attributes: { - anc: 1414, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/a962ffcb-a300-45e1-8850-70c7173c233e.jpg?itok=0f-c2lGz', - leeftijd: 35, - naam: 'Bente Becker', - partij: 'VVD', - woonplaats: "'s-Gravenhage", - }, - scaledPosition: { x: 626.600985221675, y: 100 }, - }, - { - id: 'kamerleden/23', - data: { text: 'kamerleden/23' }, - originalPosition: { x: 28, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/e5c4753f-d2d8-4a4a-ae9d-62118892a731.jpg?itok=iGnPsRMX', - leeftijd: 34, - naam: 'Ruben Brekelmans', - partij: 'VVD', - woonplaats: 'Oisterwijk', - }, - scaledPosition: { x: 646.3054187192118, y: 100 }, - }, - { - id: 'kamerleden/135', - data: { text: 'kamerleden/135' }, - originalPosition: { x: 29, y: 0 }, - attributes: { - anc: 3122, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/b8d002bc-ea6c-4f57-b36e-38415b205e09.jpg?itok=tHQU-Qrn', - leeftijd: 56, - naam: 'Aukje de Vries', - partij: 'VVD', - woonplaats: 'Leeuwarden', - }, - scaledPosition: { x: 666.0098522167489, y: 100 }, - }, - { - id: 'kamerleden/0', - data: { text: 'kamerleden/0' }, - originalPosition: { x: 30, y: 0 }, - attributes: { - anc: 987, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/397c857a-fda0-414d-8fdc-8288cd3284aa.jpg?itok=55l5zRvr', - leeftijd: 31, - naam: 'Thierry Aartsen', - partij: 'VVD', - woonplaats: 'Breda', - }, - scaledPosition: { x: 685.7142857142858, y: 100 }, - }, - ], - selectedAttributeCatecorigal: 'state', - selectedAttributeNumerical: 'long', - scaleCalculation: mockCalc, - colourCalculation: mockCalcColour, - minmaxXAxis: { min: -4.800000000000001, max: 35.8 }, - minmaxYAxis: { min: -1, max: 1 }, - width: 800, - height: 200, - yOffset: 0, - possibleTitleAttributeValues: [ - 'VVD', - 'D66', - 'GL', - 'PVV', - 'PvdD', - 'PvdA', - 'SGP', - 'BIJ1', - 'CU', - 'BBB', - 'CDA', - 'SP', - 'FVD', - 'DENK', - 'Fractie Den Haan', - 'Volt', - 'JA21', - ], - }, - { - title: 'partij:D66', - nodes: [ - { - id: 'kamerleden/141', - data: { text: 'kamerleden/141' }, - originalPosition: { x: 1, y: 0 }, - attributes: { - anc: 3171, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/d1bb566e-a111-43b7-8856-273ebac1f753.jpg?itok=-k-RCynx', - leeftijd: 48, - naam: 'Steven van Weyenberg', - partij: 'D66', - woonplaats: "'s-Gravenhage", - }, - scaledPosition: { x: 114.2857142857143, y: 100 }, - }, - { - id: 'kamerleden/138', - data: { text: 'kamerleden/138' }, - originalPosition: { x: 2, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/6a54c095-9872-4322-81be-114b74233d40.jpg?itok=uf9jc1Gk', - leeftijd: 36, - naam: 'Hanneke van der Werf', - partij: 'D66', - woonplaats: "'s-Gravenhage", - }, - scaledPosition: { x: 140.25974025974028, y: 100 }, - }, - { - id: 'kamerleden/123', - data: { text: 'kamerleden/123' }, - originalPosition: { x: 3, y: 0 }, - attributes: { - anc: 1304, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/da9f33b0-80ca-49eb-a1ec-def3b46538d9.jpg?itok=nL6HIBWH', - leeftijd: 38, - naam: 'Joost Sneller', - partij: 'D66', - woonplaats: "'s-Gravenhage", - }, - scaledPosition: { x: 166.23376623376626, y: 100 }, - }, - { - id: 'kamerleden/114', - data: { text: 'kamerleden/114' }, - originalPosition: { x: 4, y: 0 }, - attributes: { - anc: 1414, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/6fc5878e-d76a-4e9d-a4e3-e5ef581bb2ff.jpg?itok=qf_oudwu', - leeftijd: 30, - naam: 'Rens Raemakers', - partij: 'D66', - woonplaats: 'Neer', - }, - scaledPosition: { x: 192.20779220779224, y: 100 }, - }, - { - id: 'kamerleden/147', - data: { text: 'kamerleden/147' }, - originalPosition: { x: 5, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/45ef5aae-a6d0-4bad-861e-dd5b883a9665.jpg?itok=h5aEZJVM', - leeftijd: 56, - naam: 'Jorien Wuite', - partij: 'D66', - woonplaats: 'Voorburg', - }, - scaledPosition: { x: 218.18181818181822, y: 100 }, - }, - { - id: 'kamerleden/107', - data: { text: 'kamerleden/107' }, - originalPosition: { x: 6, y: 0 }, - attributes: { - anc: 42, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/d89044ef-b7df-4a15-be10-d342fe381664.jpg?itok=gmiV1adi', - leeftijd: 42, - naam: 'Wieke Paulusma', - partij: 'D66', - woonplaats: 'Groningen', - }, - scaledPosition: { x: 244.1558441558442, y: 100 }, - }, - { - id: 'kamerleden/105', - data: { text: 'kamerleden/105' }, - originalPosition: { x: 7, y: 0 }, - attributes: { - anc: 1526, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/2690bccc-5463-459a-b1df-cb93e222b348.jpg?itok=UZOQRvuv', - leeftijd: 37, - naam: 'Jan Paternotte', - partij: 'D66', - woonplaats: 'Leiden', - }, - scaledPosition: { x: 270.1298701298702, y: 100 }, - }, - { - id: 'kamerleden/94', - data: { text: 'kamerleden/94' }, - originalPosition: { x: 8, y: 0 }, - attributes: { - anc: 3171, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/17f26a48-9f54-42a1-9890-c6da761a9a2f.jpg?itok=BA8JoO5G', - leeftijd: 65, - naam: 'Paul van Meenen', - partij: 'D66', - woonplaats: 'Leiden', - }, - scaledPosition: { x: 296.10389610389615, y: 100 }, - }, - { - id: 'kamerleden/86', - data: { text: 'kamerleden/86' }, - originalPosition: { x: 9, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/fb291eb2-962a-482f-971a-0b62673f9a86.jpg?itok=2J7OszgV', - leeftijd: 41, - naam: 'Jeanet van der Laan', - partij: 'D66', - woonplaats: 'Lisse', - }, - scaledPosition: { x: 322.0779220779221, y: 100 }, - }, - { - id: 'kamerleden/71', - data: { text: 'kamerleden/71' }, - originalPosition: { x: 10, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/8349fff0-99b3-449a-bd4d-932ae95b29da.jpg?itok=xYICmuaX', - leeftijd: 37, - naam: 'Hlya Kat', - partij: 'D66', - woonplaats: 'Amsterdam', - }, - scaledPosition: { x: 348.0519480519481, y: 100 }, - }, - { - id: 'kamerleden/69', - data: { text: 'kamerleden/69' }, - originalPosition: { x: 11, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/64457f28-37b6-4948-860a-f28bc62b99ae.jpg?itok=Q2hiR0vj', - leeftijd: 59, - naam: 'Sigrid Kaag', - partij: 'D66', - woonplaats: "'s-Gravenhage", - }, - scaledPosition: { x: 374.02597402597405, y: 100 }, - }, - { - id: 'kamerleden/68', - data: { text: 'kamerleden/68' }, - originalPosition: { x: 12, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/666f31ca-041f-466d-9e78-804317921d69.jpg?itok=G3ozh6C3', - leeftijd: 37, - naam: 'Romke de Jong', - partij: 'D66', - woonplaats: 'Gorredijk', - }, - scaledPosition: { x: 400.0000000000001, y: 100 }, - }, - { - id: 'kamerleden/66', - data: { text: 'kamerleden/66' }, - originalPosition: { x: 13, y: 0 }, - attributes: { - anc: 1527, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/49be3576-cea3-46c0-87eb-89beb108248d.jpg?itok=VfqikY8P', - leeftijd: 34, - naam: 'Rob Jetten', - partij: 'D66', - woonplaats: 'Ubbergen', - }, - scaledPosition: { x: 425.97402597402595, y: 100 }, - }, - { - id: 'kamerleden/134', - data: { text: 'kamerleden/134' }, - originalPosition: { x: 14, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/19c8d0fb-66ca-4b45-be82-057cb36e1e61.jpg?itok=Bkq8gaTU', - leeftijd: 57, - naam: 'Hans Vijlbrief', - partij: 'D66', - woonplaats: 'Woubrugge', - }, - scaledPosition: { x: 451.94805194805195, y: 100 }, - }, - { - id: 'kamerleden/52', - data: { text: 'kamerleden/52' }, - originalPosition: { x: 15, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/03d66e4a-8698-44fb-9c29-625630da268c.jpg?itok=hZ9q6Llc', - leeftijd: 39, - naam: 'Alexander Hammelburg', - partij: 'D66', - woonplaats: 'Amsterdam', - }, - scaledPosition: { x: 477.9220779220779, y: 100 }, - }, - { - id: 'kamerleden/51', - data: { text: 'kamerleden/51' }, - originalPosition: { x: 16, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/425ddb12-0b71-44b6-9875-70b075dc99f7.jpg?itok=txVxBI0l', - leeftijd: 34, - naam: 'Kiki Hagen', - partij: 'D66', - woonplaats: 'Mijdrecht', - }, - scaledPosition: { x: 503.8961038961039, y: 100 }, - }, - { - id: 'kamerleden/47', - data: { text: 'kamerleden/47' }, - originalPosition: { x: 17, y: 0 }, - attributes: { - anc: 1525, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/762e0f40-f100-4896-85a2-b1d8818fae41.jpg?itok=YM5w7UBV', - leeftijd: 53, - naam: 'Tjeerd de Groot', - partij: 'D66', - woonplaats: 'Haarlem', - }, - scaledPosition: { x: 529.8701298701299, y: 100 }, - }, - { - id: 'kamerleden/121', - data: { text: 'kamerleden/121' }, - originalPosition: { x: 18, y: 0 }, - attributes: { - anc: 3171, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/bf030048-0434-42f1-bbed-8b0c04014db4.jpg?itok=G35Rmw4M', - leeftijd: 39, - naam: 'Sjoerd Sjoerdsma', - partij: 'D66', - woonplaats: "'s-Gravenhage", - }, - scaledPosition: { x: 555.8441558441559, y: 100 }, - }, - { - id: 'kamerleden/42', - data: { text: 'kamerleden/42' }, - originalPosition: { x: 19, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/49e7fc50-90f5-4476-9275-c31f88864082.jpg?itok=n7ZLWx8e', - leeftijd: 48, - naam: 'Lisa van Ginneken', - partij: 'D66', - woonplaats: 'Amsterdam', - }, - scaledPosition: { x: 581.8181818181819, y: 100 }, - }, - { - id: 'kamerleden/22', - data: { text: 'kamerleden/22' }, - originalPosition: { x: 20, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/e85125f3-b7cf-426c-9355-412838893f55.jpg?itok=Qs1_f_yV', - leeftijd: 42, - naam: 'Faissal Boulakjar', - partij: 'D66', - woonplaats: 'Teteringen', - }, - scaledPosition: { x: 607.7922077922078, y: 100 }, - }, - { - id: 'kamerleden/21', - data: { text: 'kamerleden/21' }, - originalPosition: { x: 21, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/13e26587-88d8-440b-bb93-527a8e845342.jpg?itok=18OPNvjY', - leeftijd: 45, - naam: 'Raoul Boucke', - partij: 'D66', - woonplaats: 'Rotterdam', - }, - scaledPosition: { x: 633.7662337662338, y: 100 }, - }, - { - id: 'kamerleden/14', - data: { text: 'kamerleden/14' }, - originalPosition: { x: 22, y: 0 }, - attributes: { - anc: 3171, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/aa0272f6-6e3c-41f7-b040-b774b30d2196.jpg?itok=IQu5H4Bx', - leeftijd: 49, - naam: 'Vera Bergkamp', - partij: 'D66', - woonplaats: 'Amsterdam', - }, - scaledPosition: { x: 659.7402597402597, y: 100 }, - }, - { - id: 'kamerleden/12', - data: { text: 'kamerleden/12' }, - originalPosition: { x: 23, y: 0 }, - attributes: { - anc: 1948, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/29124ef6-e1d5-4138-bf01-8433afde7269.jpg?itok=qw0TE4jl', - leeftijd: 42, - naam: 'Salima Belhaj', - partij: 'D66', - woonplaats: 'Rotterdam', - }, - scaledPosition: { x: 685.7142857142858, y: 100 }, - }, - ], - selectedAttributeCatecorigal: 'state', - selectedAttributeNumerical: 'long', - scaleCalculation: mockCalc, - colourCalculation: mockCalcColour, - minmaxXAxis: { min: -3.4000000000000004, max: 27.4 }, - minmaxYAxis: { min: -1, max: 1 }, - width: 800, - height: 200, - yOffset: 250, - possibleTitleAttributeValues: [ - 'VVD', - 'D66', - 'GL', - 'PVV', - 'PvdD', - 'PvdA', - 'SGP', - 'BIJ1', - 'CU', - 'BBB', - 'CDA', - 'SP', - 'FVD', - 'DENK', - 'Fractie Den Haan', - 'Volt', - 'JA21', - ], - }, - { - title: 'partij:GL', - nodes: [ - { - id: 'kamerleden/140', - data: { text: 'kamerleden/140' }, - originalPosition: { x: 1, y: 0 }, - attributes: { - anc: 1526, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/c7822b58-103f-4612-87ef-648be97192c6.jpg?itok=jDwKCC26', - leeftijd: 39, - naam: 'Lisa Westerveld', - partij: 'GL', - woonplaats: 'Nijmegen', - }, - scaledPosition: { x: 114.28571428571432, y: 100 }, - }, - { - id: 'kamerleden/89', - data: { text: 'kamerleden/89' }, - originalPosition: { x: 2, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/66b2be3d-10f8-46a4-90c6-b86005df0a50.jpg?itok=obcIgEe-', - leeftijd: 31, - naam: 'Senna Maatoug', - partij: 'GL', - woonplaats: 'Leiden', - }, - scaledPosition: { x: 209.52380952380958, y: 100 }, - }, - { - id: 'kamerleden/124', - data: { text: 'kamerleden/124' }, - originalPosition: { x: 3, y: 0 }, - attributes: { - anc: 1526, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/b50b3f0b-afc8-46e5-bfda-cb60e2935a5a.jpg?itok=7R0cTE10', - leeftijd: 55, - naam: 'Bart Snels', - partij: 'GL', - woonplaats: 'Utrecht', - }, - scaledPosition: { x: 304.7619047619048, y: 100 }, - }, - { - id: 'kamerleden/87', - data: { text: 'kamerleden/87' }, - originalPosition: { x: 4, y: 0 }, - attributes: { - anc: 1526, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/75a44c3a-5914-4c8e-9ca4-d987853f5844.jpg?itok=kA8ZaoNf', - leeftijd: 56, - naam: 'Tom van der Lee', - partij: 'GL', - woonplaats: 'Amsterdam', - }, - scaledPosition: { x: 400.0000000000001, y: 100 }, - }, - { - id: 'kamerleden/24', - data: { text: 'kamerleden/24' }, - originalPosition: { x: 5, y: 0 }, - attributes: { - anc: 1085, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/ccea26dd-dcae-4174-8945-ec5cb568e951.jpg?itok=z7gsBQYd', - leeftijd: 51, - naam: 'Laura Bromet', - partij: 'GL', - woonplaats: 'Monnickendam', - }, - scaledPosition: { x: 495.23809523809535, y: 100 }, - }, - { - id: 'kamerleden/20', - data: { text: 'kamerleden/20' }, - originalPosition: { x: 6, y: 0 }, - attributes: { - anc: 57, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/dab4cf29-4843-4261-b09b-973fe98dbf65.jpg?itok=szVeNy9I', - leeftijd: 27, - naam: 'Kauthar Bouchallikh', - partij: 'GL', - woonplaats: 'Amsterdam', - }, - scaledPosition: { x: 590.4761904761906, y: 100 }, - }, - { - id: 'kamerleden/34', - data: { text: 'kamerleden/34' }, - originalPosition: { x: 7, y: 0 }, - attributes: { - anc: 1637, - img: 'https://www.tweedekamer.nl/sites/default/files/styles/member_parlement_profile_square/public/551f9a19-738c-4298-afe1-5ca7959ab74b.jpg?itok=24RXpYrd', - leeftijd: 45, - naam: 'Corinne Ellemeet', - partij: 'GL', - woonplaats: 'Abcoude', - }, - scaledPosition: { x: 685.7142857142859, y: 100 }, - }, - ], - selectedAttributeCatecorigal: 'state', - selectedAttributeNumerical: 'long', - scaleCalculation: mockCalc, - colourCalculation: mockCalcColour, - minmaxXAxis: { min: -0.20000000000000018, max: 8.2 }, - minmaxYAxis: { min: -1, max: 1 }, - width: 800, - height: 200, - yOffset: 500, - possibleTitleAttributeValues: [ - 'VVD', - 'D66', - 'GL', - 'PVV', - 'PvdD', - 'PvdA', - 'SGP', - 'BIJ1', - 'CU', - 'BBB', - 'CDA', - 'SP', - 'FVD', - 'DENK', - 'Fractie Den Haan', - 'Volt', - 'JA21', - ], - }, - ]; - - // Check the plots and the relations. - expect(viewModelImpl.plots).toEqual(expectedPlots); - expect(viewModelImpl.allRelations).toEqual(expectedRelations); - - // Also check if notifyViewAboutChanges is called. - expect(onViewModelChangedMock).toHaveBeenCalledTimes(2); - }); - - it('add a plot and delete itonDelete', () => { - const viewModelImpl = new SemanticSubstratesViewModelImpl(); - - const onViewModelChangedMock = jest.fn(); - const baseViewMock = { - onViewModelChanged: onViewModelChangedMock, - }; - viewModelImpl.attachView(baseViewMock); - - viewModelImpl.onDelete(1); - }); - - it('onBrush', () => { - const viewModelImpl = new SemanticSubstratesViewModelImpl(); - viewModelImpl.consumeMessageFromBackend(mockSchema); - viewModelImpl.consumeMessageFromBackend(mockNodeLinkResult); - - const onViewModelChangedMock = jest.fn(); - const baseViewMock = { - onViewModelChanged: onViewModelChangedMock, - }; - viewModelImpl.attachView(baseViewMock); - - let expectedFilters: { x: MinMaxType; y: MinMaxType } = { - x: { min: 30, max: 40 }, - y: { min: 30, max: 40 }, - }; - - viewModelImpl.onBrush(1, { min: 30, max: 40 }, { min: 30, max: 40 }); - - expect(viewModelImpl.filtersPerPlot[1]).toEqual(expectedFilters); - }); - - it('onAxisChanges', () => { - const viewModelImpl = new SemanticSubstratesViewModelImpl(); - viewModelImpl.consumeMessageFromBackend(mockSchema); - viewModelImpl.consumeMessageFromBackend(mockNodeLinkResult); - - const onViewModelChangedMock = jest.fn(); - const baseViewMock = { - onViewModelChanged: onViewModelChangedMock, - }; - viewModelImpl.attachView(baseViewMock); - - const expectedX = 'nieuweXaxis'; - const expectedY = 'nieuweYaxis'; - const expectedX2 = 'evenly spaced'; - const expectedY2 = '# outbound connections'; - - // change labels - viewModelImpl.onAxisLabelChanged(1, 'x', 'nieuweXaxis'); - viewModelImpl.onAxisLabelChanged(1, 'y', 'nieuweYaxis'); - - expect(viewModelImpl.plotSpecifications[1].xAxisAttributeType).toEqual(expectedX); - expect(viewModelImpl.plotSpecifications[1].yAxisAttributeType).toEqual(expectedY); - - // change labels again - viewModelImpl.onAxisLabelChanged(1, 'x', 'evenly spaced'); - viewModelImpl.onAxisLabelChanged(1, 'y', '# outbound connections'); - - expect(viewModelImpl.plotSpecifications[1].xAxis).toEqual(expectedX2); - expect(viewModelImpl.plotSpecifications[1].yAxis).toEqual(expectedY2); - }); - - it('onCheckboxChanges', () => { - const viewModelImpl = new SemanticSubstratesViewModelImpl(); - viewModelImpl.consumeMessageFromBackend(mockSchema); - viewModelImpl.consumeMessageFromBackend(mockNodeLinkResult); - - const onViewModelChangedMock = jest.fn(); - const baseViewMock = { - onViewModelChanged: onViewModelChangedMock, - }; - viewModelImpl.attachView(baseViewMock); - - viewModelImpl.onCheckboxChanged(1, 2, true); - - expect(viewModelImpl.visibleRelations[1][2]).toBeTruthy(); - }); - - it('addPlot', () => { - const viewModelImpl = new SemanticSubstratesViewModelImpl(); - viewModelImpl.consumeMessageFromBackend(mockSchema); - viewModelImpl.consumeMessageFromBackend(mockNodeLinkResult); - - const onViewModelChangedMock = jest.fn(); - const baseViewMock = { - onViewModelChanged: onViewModelChangedMock, - }; - viewModelImpl.attachView(baseViewMock); - - expect(viewModelImpl.plots).toHaveLength(3); - - viewModelImpl.addPlot('partij', 'naam', 'VVD'); - - expect(viewModelImpl.plots).toHaveLength(4); - }); -}); - -const deletePlot = [ - { - title: 'partij:VVD', - nodes: [ - { - id: 'kamerleden/148', - data: { - text: 'kamerleden/148', - }, - originalPosition: { - x: 1, - y: 0, - }, - scaledPosition: { - x: 114.28571428571432, - y: 100, - }, - }, - ], - }, -]; - -const expectedRelations = [ - [[], [], []], - [[], [], []], - [[], [], []], -]; diff --git a/libs/shared/lib/vis/semanticsubstrates/SemanticSubstratesViewModel.tsx b/libs/shared/lib/vis/semanticsubstrates/SemanticSubstratesViewModel.tsx deleted file mode 100644 index 14bd63f9113b5237634bf5e482c0d1eaa98a6f6b..0000000000000000000000000000000000000000 --- a/libs/shared/lib/vis/semanticsubstrates/SemanticSubstratesViewModel.tsx +++ /dev/null @@ -1,57 +0,0 @@ -/** - * This program has been developed by students from the bachelor Computer Science at - * Utrecht University within the Software Project course. - * © Copyright Utrecht University (Department of Information and Computing Sciences) - */ -import { MinMaxType, PlotType, RelationType, AxisLabel, PlotSpecifications, EntitiesFromSchema } from './Types'; -import CalcScaledPosUseCase from './utils/CalcScaledPositionsUseCase'; -import FilterUseCase from './utils/FilterUseCase'; - -import CalcDefaultPlotSpecsUseCase from './utils/CalcDefaultPlotSpecsUseCase'; -import ToPlotDataParserUseCase from './utils/ToPlotDataParserUseCase'; -import CalcXYMinMaxUseCase from './utils/CalcXYMinMaxUseCase'; - -import { ClassNameMap } from '@mui/material'; -import { NodeLinkResultType, isNodeLinkResult } from '../shared/ResultNodeLinkParserUseCase'; -import CalcEntityAttrNamesFromSchemaUseCase from './utils/CalcEntityAttrNamesFromSchemaUseCase'; -import CalcEntityAttrNamesFromResultUseCase from './utils/CalcEntityAttrNamesFromResultUseCase'; -import { isSchemaResult } from '../shared/SchemaResultType'; - -/** An implementation of the `SemanticSubstratesViewModel` to be used by the semantic-substrates view. */ -export default class SemanticSubstratesViewModel { - /** - * These functions are mock function for now, but can be properly implemented later down the line. - */ - public scaleCalculation: (x: number) => number = (x: number) => { - return 3; - }; - public colourCalculation: (x: string) => string = (x: string) => { - return '#d56a50'; - }; - public relationColourCalculation: (x: string) => string = (x: string) => { - return '#d49350'; - }; - private relationScaleCalculation: (x: number) => number = (x: number) => { - return 1; - }; - - /** Initializes the plots and relations arrays as empty arrays. */ - public constructor(state: SemanticSubstratesState, setState) { - this.state = state; - this.setState = setState; - } - - // /** - // * Subscribe to the schema result routing key so that this view model is receiving results that are to be visualised. - // */ - // public subscribeToSchemaResult(): void { - // Broker.instance().subscribe(this, 'schema_result'); - // } - - // /** - // * Unsubscribe from the schema result routing key so that this view model no longer handles query results from the backend. - // */ - // public unSubscribeFromSchemaResult(): void { - // Broker.instance().unSubscribe(this, 'schema_result'); - // } -} diff --git a/libs/shared/lib/vis/semanticsubstrates/configpanel/SemanticSubstrateConfigPanel.tsx b/libs/shared/lib/vis/semanticsubstrates/configpanel/SemanticSubstrateConfigPanel.tsx index 6f49d0f72f6bdcd58261f54ed7e83fe892a73580..1f680d78ab9d3ce9565314095ecdc7981d6269ee 100644 --- a/libs/shared/lib/vis/semanticsubstrates/configpanel/SemanticSubstrateConfigPanel.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/configpanel/SemanticSubstrateConfigPanel.tsx @@ -9,7 +9,7 @@ * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ import React, { useRef, useState } from 'react'; -import styles from '../SemanticSubstratesComponent.module.scss'; +import styles from '../semanticsubstrates.module.scss'; import { EntityWithAttributes, FSSConfigPanelProps } from './Types'; import SemanticSubstratesConfigPanelViewModelImpl from './SemanticSubstratesConfigPanelViewModel'; import SemanticSubstratesConfigPanelViewModel from './SemanticSubstratesConfigPanelViewModel'; diff --git a/libs/shared/lib/vis/semanticsubstrates/configpanel/SemanticSubstratesConfigPanelViewModel.tsx b/libs/shared/lib/vis/semanticsubstrates/configpanel/SemanticSubstratesConfigPanelViewModel.tsx index 4d93fc9184495cf9fa110e6563f637424816f61c..9e0d1fce2b17d98c1d2e22b2cab662a12ab6ffc9 100644 --- a/libs/shared/lib/vis/semanticsubstrates/configpanel/SemanticSubstratesConfigPanelViewModel.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/configpanel/SemanticSubstratesConfigPanelViewModel.tsx @@ -1,8 +1,7 @@ import { range } from 'd3'; import { EntityWithAttributes, FSSConfigPanelProps } from './Types'; -import { Link, Node } from '../../shared/ResultNodeLinkParserUseCase'; -import SemanticSubstratesViewModel from '../SemanticSubstratesViewModel'; +import { Edge, Node } from '@graphpolaris/shared/lib/data-access'; /** Viewmodel for rendering config input fields for Faceted Semantic Substrate attributes. */ export default class SemanticSubstratesConfigPanelViewModel { @@ -16,13 +15,12 @@ export default class SemanticSubstratesConfigPanelViewModel { maximalRelationWidth = 4; nodesloaded: Node[]; - relationsloaded: Link[]; + relationsloaded: Edge[]; public currentNode = ''; currentRelation = ''; currentAttribute = ''; currentRelationAttribute = ''; - // Faceted Semantic Substrates View Model. - fssViewModel: SemanticSubstratesViewModel; + /** * The constructor for the FSSConfigPanelViewModelImpl (FacetedSemanticSubstratesConfigPanelViewModelImpl). * This handles the view for changing how to display the attributes of the nodes and relations @@ -32,21 +30,19 @@ export default class SemanticSubstratesConfigPanelViewModel { */ public constructor(props: FSSConfigPanelProps) { let graph = props.graph; - let fssViewModel = props.fssViewModel; this.nodes = []; this.relations = []; this.nodesloaded = graph.nodes; this.relationsloaded = graph.edges; - this.fssViewModel = fssViewModel; } /** * Creates a list of unique node types based on the current list of nodes. */ public makeNodeTypes() { - this.nodes = MakeTypesFromGraphUseCase.makeNodeTypes(this.nodesloaded); + // this.nodes = MakeTypesFromGraphUseCase.makeNodeTypes(this.nodesloaded); if (!this.isNodeSet()) { if (this.nodes[0]) { this.currentNode = this.nodes[0].name; @@ -58,7 +54,7 @@ export default class SemanticSubstratesConfigPanelViewModel { * Creates a list of unique relation types based on the current list of relations. */ public makeRelationTypes() { - this.relations = MakeTypesFromGraphUseCase.makeRelationTypes(this.relationsloaded); + // this.relations = MakeTypesFromGraphUseCase.makeRelationTypes(this.relationsloaded); if (!this.isRelationSet()) { if (this.relations[0]) { this.currentRelation = this.relations[0].name; @@ -110,13 +106,13 @@ export default class SemanticSubstratesConfigPanelViewModel { //Retrieve the current visualisation and set the vis dropdown to this. this.currentAttribute = attributeSelected; if (this.isNodeAttributeNumber(attributeSelected)) { - this.fssViewModel.selectedAttributeNumerical = attributeSelected; - this.fssViewModel.changeSelectedAttributeNumerical( - this.getTheScaleCalculationForNodes(attributeSelected, this.minimalNodeSize, this.maximalNodeSize) - ); + // this.fssViewModel.selectedAttributeNumerical = attributeSelected; + // this.fssViewModel.changeSelectedAttributeNumerical( + // this.getTheScaleCalculationForNodes(attributeSelected, this.minimalNodeSize, this.maximalNodeSize) + // ); } else { - this.fssViewModel.selectedAttributeCatecorigal = attributeSelected; - this.fssViewModel.changeSelectedAttributeCatecorigal(this.getTheColourCalculationForNodes(attributeSelected)); + // this.fssViewModel.selectedAttributeCatecorigal = attributeSelected; + // this.fssViewModel.changeSelectedAttributeCatecorigal(this.getTheColourCalculationForNodes(attributeSelected)); } } @@ -127,19 +123,19 @@ export default class SemanticSubstratesConfigPanelViewModel { //Retrieve the current visualisation and set the vis dropdown to this. this.currentRelationAttribute = attributeSelected; if (this.isRelationAttributeNumber(attributeSelected)) { - this.fssViewModel.relationSelectedAttributeNumerical = attributeSelected; - this.fssViewModel.changeRelationSelectedAttributeNumerical( - this.getTheScaleCalculationForRelations( - this.fssViewModel.relationSelectedAttributeNumerical, - this.minimalRelationWidth, - this.maximalRelationWidth - ) - ); + // this.fssViewModel.relationSelectedAttributeNumerical = attributeSelected; + // this.fssViewModel.changeRelationSelectedAttributeNumerical( + // this.getTheScaleCalculationForRelations( + // this.fssViewModel.relationSelectedAttributeNumerical, + // this.minimalRelationWidth, + // this.maximalRelationWidth + // ) + // ); } else { - this.fssViewModel.relationSelectedAttributeCatecorigal = attributeSelected; - this.fssViewModel.changeRelationSelectedAttributeCatecorigal( - this.getTheColourCalculationForRelations(this.fssViewModel.relationSelectedAttributeCatecorigal) - ); + // this.fssViewModel.relationSelectedAttributeCatecorigal = attributeSelected; + // this.fssViewModel.changeRelationSelectedAttributeCatecorigal( + // this.getTheColourCalculationForRelations(this.fssViewModel.relationSelectedAttributeCatecorigal) + // ); } } @@ -190,7 +186,7 @@ export default class SemanticSubstratesConfigPanelViewModel { for (const node of this.nodesloaded) { if (node.attributes) { if (node.attributes[attribute] != undefined) { - if (isNaN(node.attributes[attribute])) return false; + // if (isNaN(node.attributes[attribute])) return false; } } } @@ -207,7 +203,7 @@ export default class SemanticSubstratesConfigPanelViewModel { for (const relation of this.relationsloaded) { if (relation.attributes) { if (relation.attributes[attribute] != undefined) { - if (isNaN(relation.attributes[attribute])) return false; + // if (isNaN(relation.attributes[attribute])) return false; } } } @@ -226,7 +222,7 @@ export default class SemanticSubstratesConfigPanelViewModel { this.nodesloaded.forEach((node) => { if (node.attributes) { if (node.attributes[attribute] != undefined) { - values.push(node.attributes[attribute]); + // values.push(node.attributes[attribute]); } } }); @@ -252,22 +248,22 @@ export default class SemanticSubstratesConfigPanelViewModel { this.nodesloaded.forEach((node) => { if (node.attributes) { if (node.attributes[attribute] != undefined) { - uniqueValues.push(node.attributes[attribute]); + // uniqueValues.push(node.attributes[attribute]); } } }); - let colours = ColourPalettes['default'].nodes; + // let colours = ColourPalettes['default'].nodes; // Create the key value pairs. let valueToColour: Record<string, string> = {}; let i = 0; uniqueValues.forEach((uniqueValue) => { - valueToColour[uniqueValue] = '#' + colours[i]; - i++; - if (i > colours.length) { - i = 0; - } + // valueToColour[uniqueValue] = '#' + colours[i]; + // i++; + // if (i > colours.length) { + // i = 0; + // } }); //Get a colour for each attribute @@ -286,7 +282,7 @@ export default class SemanticSubstratesConfigPanelViewModel { this.relationsloaded.forEach((relation) => { if (relation.attributes) { if (relation.attributes[attribute] != undefined) { - values.push(relation.attributes[attribute]); + // values.push(relation.attributes[attribute]); } } }); @@ -312,22 +308,22 @@ export default class SemanticSubstratesConfigPanelViewModel { this.relationsloaded.forEach((relation) => { if (relation.attributes) { if (relation.attributes[attribute] != undefined) { - uniqueValues.push(relation.attributes[attribute]); + // uniqueValues.push(relation.attributes[attribute]); } } }); - let colours = ColourPalettes['default'].elements.relation; + // let colours = ColourPalettes['default'].elements.relation; // Create the key value pairs. let valueToColour: Record<string, string> = {}; let i = 0; uniqueValues.forEach((uniqueValue) => { - valueToColour[uniqueValue] = '#' + colours[i]; - i++; - if (i > colours.length) { - i = 0; - } + // valueToColour[uniqueValue] = '#' + colours[i]; + // i++; + // if (i > colours.length) { + // i = 0; + // } }); //Get a colour for each attribute diff --git a/libs/shared/lib/vis/semanticsubstrates/configpanel/Types.tsx b/libs/shared/lib/vis/semanticsubstrates/configpanel/Types.tsx index 1e478c6acddfc6e824fb7a4e4770caf9f03b8f8d..58e7f4dcc78a7ca0b2c6fb5e80edb2045d030052 100644 --- a/libs/shared/lib/vis/semanticsubstrates/configpanel/Types.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/configpanel/Types.tsx @@ -4,8 +4,7 @@ * © Copyright Utrecht University (Department of Information and Computing Sciences) */ -import { NodeLinkResultType } from '../../shared/ResultNodeLinkParserUseCase'; -import SemanticSubstratesViewModel from '../SemanticSubstratesViewModel'; +import { GraphQueryResult } from '@graphpolaris/shared/lib/data-access'; /* An entity that has an attribute (Either a node with attributes or an edges with attributes) For the config-panel of semantic-substrates.*/ @@ -17,7 +16,6 @@ export type EntityWithAttributes = { /** Props for this component */ export type FSSConfigPanelProps = { - graph: NodeLinkResultType; + graph: GraphQueryResult; // currentColours: any; - fssViewModel: SemanticSubstratesViewModel; }; diff --git a/libs/shared/lib/vis/semanticsubstrates/semanticsubstrates.stories.tsx b/libs/shared/lib/vis/semanticsubstrates/semanticsubstrates.stories.tsx index a650520eda7b0c92e8e112b3dedb5e4a5de4cb2c..448b1edf9cb49575b82546e3f9c22c82faf79252 100644 --- a/libs/shared/lib/vis/semanticsubstrates/semanticsubstrates.stories.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/semanticsubstrates.stories.tsx @@ -60,18 +60,21 @@ export const TestWithData = { dispatch(setSchema(schema.export())); dispatch( assignNewGraphQueryResult({ - nodes: [ - { id: '1/a', attributes: { a: 's1' } }, - { id: '1/b1', attributes: { a: 's1' } }, - { id: '1/b2', attributes: { a: 's1' } }, - { id: '1/b3', attributes: { a: 's1' } }, - ], - edges: [ - { id: '12/z1', from: '1/b1', to: '1/a', attributes: { a: 's1' } }, - // { from: 'b2', to: 'a', attributes: {} }, - // { from: 'b3', to: 'a', attributes: {} }, - { id: '12/z1', from: '1/a', to: '1/b1', attributes: { a: 's1' } }, - ], + type: 'nodelink', + payload: { + nodes: [ + { id: '1/a', attributes: { a: 's1' } }, + { id: '1/b1', attributes: { a: 's1' } }, + { id: '1/b2', attributes: { a: 's1' } }, + { id: '1/b3', attributes: { a: 's1' } }, + ], + edges: [ + { id: '12/z1', from: '1/b1', to: '1/a', attributes: { a: 's1' } }, + // { from: 'b2', to: 'a', attributes: {} }, + // { from: 'b3', to: 'a', attributes: {} }, + { id: '12/z1', from: '1/a', to: '1/b1', attributes: { a: 's1' } }, + ], + }, }) ); }, @@ -89,7 +92,7 @@ export const TestWithAirport = { const schema = SchemaUtils.schemaBackend2Graphology(simpleSchemaAirportRaw); dispatch(setSchema(schema.export())); - dispatch(assignNewGraphQueryResult(bigMockQueryResults)); + dispatch(assignNewGraphQueryResult({ type: 'nodelink', payload: bigMockQueryResults })); }, }; diff --git a/libs/shared/lib/vis/semanticsubstrates/semanticsubstrates.tsx b/libs/shared/lib/vis/semanticsubstrates/semanticsubstrates.tsx index 644c12a1db08150516c1194fd5e4c35cfffde8bb..b05dcb58c0ad6b4d2e3846ddd493b1bfd02c268c 100644 --- a/libs/shared/lib/vis/semanticsubstrates/semanticsubstrates.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/semanticsubstrates.tsx @@ -2,7 +2,7 @@ import { useTheme } from '@mui/material'; import { useAppDispatch, useGraphQueryResult, useSchemaGraph } from '@graphpolaris/shared/lib/data-access/store'; import { useEffect, useRef, useState } from 'react'; import { AxisLabel, EntitiesFromSchema, MinMaxType, PlotSpecifications, PlotType, RelationType } from './Types'; -import { NodeLinkResultType, isNodeLinkResult } from '../shared/ResultNodeLinkParserUseCase'; +import { isNodeLinkResult } from '../shared/ResultNodeLinkParserUseCase'; import styles from './semanticsubstrates.module.scss'; import AddPlotButtonComponent from './subcomponents/AddPlotButtonComponent'; import SVGCheckboxesWithSemanticSubstrLabel from './subcomponents/SVGCheckBoxComponent'; diff --git a/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotButtonComponent.module.scss b/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotButtonComponent.module.scss index 72574e2237948f516527644cf84493f134fdd873..4ab1febb10c70fc1f01d13e5f09bf5a863a9f227 100644 --- a/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotButtonComponent.module.scss +++ b/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotButtonComponent.module.scss @@ -1,63 +1,63 @@ -root { - &:hover { - & .display { - & .background { - fill: '#009100'; - transition-delay: 0s; - } - & .plus { - transform: translate(-4px, 0); - transition-delay: 0s; - - & line { - transition: 0.2s; - transition-delay: 0s; - stroke-width: 3; - } - & .xAxis { - transform: translate(0, 0) scale(1, 1); - } - & .yAxis { - transform: translate(0, 0); - } - & .nodes { - opacity: 0; - transition-delay: 0s; - } - } - } - } -} - -.background { - transition: 0.1s; - transition-delay: 0.1s; -} - -.plus { - transform-box: fill-box; - transform-origin: center center; - transition: 0.2s; - transition-delay: 0.1s; - transform: translate(0, 0); - - & line { - transition: 0.2s; - transition-delay: 0.1s; - stroke-width: 1; - } - - & .nodes { - transition-delay: 0.1s; - } -} - -.xAxis { - transform-box: fill-box; - transform-origin: center right; - transform: translate(0, 5px) scale(1.4, 1); -} - -.yAxis { - transform: translate(-11px, 0); -} +.root { + &:hover { + & .display { + & .background { + fill: '#009100'; + transition-delay: 0s; + } + & .plus { + transform: translate(-4px, 0); + transition-delay: 0s; + + & line { + transition: 0.2s; + transition-delay: 0s; + stroke-width: 3; + } + & .xAxis { + transform: translate(0, 0) scale(1, 1); + } + & .yAxis { + transform: translate(0, 0); + } + & .nodes { + opacity: 0; + transition-delay: 0s; + } + } + } + } +} + +.background { + transition: 0.1s; + transition-delay: 0.1s; +} + +.plus { + transform-box: fill-box; + transform-origin: center center; + transition: 0.2s; + transition-delay: 0.1s; + transform: translate(0, 0); + + & line { + transition: 0.2s; + transition-delay: 0.1s; + stroke-width: 1; + } + + & .nodes { + transition-delay: 0.1s; + } +} + +.xAxis { + transform-box: fill-box; + transform-origin: center right; + transform: translate(0, 5px) scale(1.4, 1); +} + +.yAxis { + transform: translate(-11px, 0); +} diff --git a/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotButtonComponent.module.scss.d.ts b/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotButtonComponent.module.scss.d.ts index 0d249f1229f4c5f24f4487d0c6c29d9e31d1b45d..022b03b83bb5e7f5680405e10e6a111e5db37c11 100644 --- a/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotButtonComponent.module.scss.d.ts +++ b/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotButtonComponent.module.scss.d.ts @@ -1,4 +1,5 @@ declare const classNames: { + readonly root: 'root'; readonly display: 'display'; readonly background: 'background'; readonly plus: 'plus'; diff --git a/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotPopup.tsx b/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotPopup.tsx index 687c79387e12dd7e402c40cef6184f0197d5c7df..d770915c30412a1172df07fbd7f60cc4a279d908 100644 --- a/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotPopup.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotPopup.tsx @@ -8,11 +8,11 @@ /* The comment above was added so the code coverage wouldn't count this file towards code coverage. * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ -import { Link, Node } from '../../shared/ResultNodeLinkParserUseCase'; import { Button, MenuItem, Popover, TextField } from '@mui/material'; import React, { ReactElement } from 'react'; import { EntitiesFromSchema } from '../Types'; import OptimizedAutocomplete from './OptimizedAutocomplete'; +import { Node } from '@graphpolaris/shared/lib/data-access'; /** The typing for the props of the plot popups */ type AddPlotPopupProps = { @@ -82,7 +82,7 @@ export default class AddPlotPopup extends React.Component<AddPlotPopupProps, Add this.possibleAttrValues = Array.from( this.props.nodeLinkResultNodes.reduce((values: Set<string>, node) => { - if (this.state.entity == node.label && newAttrName in node.attributes) values.add(node.attributes[newAttrName]); + if (this.state.entity == node.label && newAttrName in node.attributes) values.add(node.attributes[newAttrName] as string); return values; }, new Set<string>()) ); diff --git a/libs/shared/lib/vis/semanticsubstrates/subcomponents/OptimizedAutocomplete.tsx b/libs/shared/lib/vis/semanticsubstrates/subcomponents/OptimizedAutocomplete.tsx index 08fa738cfde749747f81285d56cd92bf403acd9b..47d3f8c03f3f69b39ab3fd49201eb80587a45be2 100644 --- a/libs/shared/lib/vis/semanticsubstrates/subcomponents/OptimizedAutocomplete.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/subcomponents/OptimizedAutocomplete.tsx @@ -54,7 +54,7 @@ function useResetCache(data: any) { } // Adapter for react-window -const ListboxComponent = React.forwardRef<HTMLDivElement>(function ListboxComponent(props, ref) { +const ListboxComponent = React.forwardRef<HTMLDivElement>(function ListboxComponent(props: any, ref) { const { children, ...other } = props; const itemData = React.Children.toArray(children); const theme = useTheme(); diff --git a/libs/shared/lib/vis/semanticsubstrates/subcomponents/PlotTitleComponent.tsx b/libs/shared/lib/vis/semanticsubstrates/subcomponents/PlotTitleComponent.tsx index 483634d4fb4f0271974c95a4b5b6a2935ee2bbea..6247214dd6637b9aee14edbf34270be038433134 100644 --- a/libs/shared/lib/vis/semanticsubstrates/subcomponents/PlotTitleComponent.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/subcomponents/PlotTitleComponent.tsx @@ -10,7 +10,7 @@ * See testing plan for more details.*/ import { Menu, MenuItem } from '@mui/material'; import Color from 'color'; -import React, { ReactElement } from 'react'; +import React, { ReactElement, useState } from 'react'; import { EntitiesFromSchema } from '../Types'; import styles from './PlotTitleStyles.module.css'; import { XYPosition } from 'reactflow'; @@ -42,52 +42,49 @@ type PlotTitleState = { * A semantic substrates React component for rendering a plot title. * With functionality to change the entity, attributeType and attributeName. */ -export default class PlotTitleComponent extends React.Component<PlotTitleProps, PlotTitleState> { - constructor(props: PlotTitleProps) { - super(props); - - this.state = { - isEditingAttrValue: false, - menuAnchor: null, - menuItems: [], - menuItemsOnClick: () => true, - }; - } +export default function PlotTitleComponent(props: PlotTitleProps) { + const [state, setState] = useState<PlotTitleState>({ + isEditingAttrValue: false, + menuAnchor: null, + menuItems: [], + menuItemsOnClick: () => true, + }); /** * Will be called when the value of the entity changes. * @param {string} value The new entity value. */ - private onEntityChanged(value: string): void { + function onEntityChanged(value: string): void { // Get the first attribute name for this entity. const attrName = - this.props.entitiesFromSchema.attributesPerEntity[value].textAttributeNames.length > 0 - ? this.props.entitiesFromSchema.attributesPerEntity[value].textAttributeNames[0] + props.entitiesFromSchema.attributesPerEntity[value].textAttributeNames.length > 0 + ? props.entitiesFromSchema.attributesPerEntity[value].textAttributeNames[0] : '?'; - this.props.onTitleChanged(value, attrName, '?'); + props.onTitleChanged(value, attrName, '?'); } /** * Will be called when the attribute name changes. * @param {string} value The new attribute name value. */ - private onAttrNameChanged(value: string): void { - this.props.onTitleChanged(this.props.entity, value, '?'); + function onAttrNameChanged(value: string): void { + props.onTitleChanged(props.entity, value, '?'); } /** * Will be called when the attribute value changes. * @param {string} value The new value of the attribute value. */ - private onAttrValueChanged(value: string): void { + function onAttrValueChanged(value: string): void { if (value == '') value = '?'; // only update the state if the attribute value didn't change // If the attribute value did change, this component will be rerendered anyway - if (value != this.props.attributeValue) this.props.onTitleChanged(this.props.entity, this.props.attributeName, value); + if (value != props.attributeValue) props.onTitleChanged(props.entity, props.attributeName, value); else - this.setState({ + setState({ + ...state, isEditingAttrValue: false, }); } @@ -97,105 +94,123 @@ export default class PlotTitleComponent extends React.Component<PlotTitleProps, * @param {number} xOffset The x position offset. * @returns {ReactElement} The svg elements to render for the attribute value. */ - private renderAttributeValue(xOffset: number): ReactElement { - if (this.state.isEditingAttrValue) + function renderAttributeValue(xOffset: number): ReactElement { + if (state.isEditingAttrValue) return ( <foreignObject x={xOffset} y="-16" width="200" height="150"> <div> <OptimizedAutocomplete - options={this.props.possibleAttrValues} - currentValue={this.props.attributeValue} - onLeave={(v: string) => this.onAttrValueChanged(v)} + options={props.possibleAttrValues} + currentValue={props.attributeValue} + onLeave={(v: string) => onAttrValueChanged(v)} /> </div> </foreignObject> ); else return ( - <text x={xOffset} className={styles.clickable} onClick={() => this.setState({ isEditingAttrValue: true })}> - {this.props.attributeValue} - </text> - ); - } - - render(): ReactElement { - const { entity, attributeName, entitiesFromSchema, pos, nodeColor } = this.props; - - const withOffset = getWidthOfText(entity + ' ', 'arial', '15px', 'bold'); - const attrNameOffset = getWidthOfText('with ', 'arial', '15px') + withOffset; - const colonOffset = getWidthOfText(attributeName + ' ', 'arial', '15px', 'bold') + attrNameOffset; - const attrValueOffset = getWidthOfText(': ', 'arial', '15px', 'bold') + colonOffset; - - const nodeColorDarkened = Color(nodeColor).darken(0.3).hex(); - - return ( - <g transform={`translate(${pos.x},${pos.y})`}> - <text - className={styles.clickable} - fill={nodeColorDarkened} - onClick={(event: React.MouseEvent<SVGTextElement>) => { - this.setState({ - menuAnchor: event.currentTarget, - menuItems: entitiesFromSchema.entityNames, - menuItemsOnClick: (v: string) => this.onEntityChanged(v), - }); - }} - > - {entity} - </text> - <text x={withOffset} fontSize={15}> - with - </text> <text + x={xOffset} className={styles.clickable} - x={attrNameOffset} - onClick={(event: React.MouseEvent<SVGTextElement>) => { - this.setState({ - menuAnchor: event.currentTarget, - menuItems: entitiesFromSchema.attributesPerEntity[entity].textAttributeNames, - menuItemsOnClick: (v: string) => this.onAttrNameChanged(v), - }); - }} + onClick={() => + setState({ + ...state, + isEditingAttrValue: true, + }) + } > - {attributeName} - </text> - <text x={colonOffset} fontWeight="bold" fontSize={15}> - : + {props.attributeValue} </text> - - {this.renderAttributeValue(attrValueOffset)} - - <Menu - id="simple-menu" - anchorEl={this.state.menuAnchor} - keepMounted - // getContentAnchorEl={null} - anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} - transformOrigin={{ vertical: 'top', horizontal: 'center' }} - open={Boolean(this.state.menuAnchor)} - onClose={() => this.setState({ menuAnchor: null })} - transitionDuration={150} - PaperProps={{ - style: { - maxHeight: 48 * 4.5, // 48 ITEM_HEIGHT - }, - }} - > - {this.state.menuItems.map((option) => ( - <MenuItem - key={option} - selected={option == this.state.menuAnchor?.innerHTML} - onClick={() => { - this.setState({ menuAnchor: null, menuItems: [] }); - - this.state.menuItemsOnClick(option); - }} - > - {option} - </MenuItem> - ))} - </Menu> - </g> - ); + ); } + + const { entity, attributeName, entitiesFromSchema, pos, nodeColor } = props; + + const withOffset = getWidthOfText(entity + ' ', 'arial', '15px', 'bold'); + const attrNameOffset = getWidthOfText('with ', 'arial', '15px') + withOffset; + const colonOffset = getWidthOfText(attributeName + ' ', 'arial', '15px', 'bold') + attrNameOffset; + const attrValueOffset = getWidthOfText(': ', 'arial', '15px', 'bold') + colonOffset; + + const nodeColorDarkened = Color(nodeColor).darken(0.3).hex(); + + return ( + <g transform={`translate(${pos.x},${pos.y})`}> + <text + className={styles.clickable} + fill={nodeColorDarkened} + onClick={(event: React.MouseEvent<SVGTextElement>) => { + setState({ + ...state, + menuAnchor: event.currentTarget, + menuItems: entitiesFromSchema.entityNames, + menuItemsOnClick: (v: string) => onEntityChanged(v), + }); + }} + > + {entity} + </text> + <text x={withOffset} fontSize={15}> + with + </text> + <text + className={styles.clickable} + x={attrNameOffset} + onClick={(event: React.MouseEvent<SVGTextElement>) => { + setState({ + ...state, + menuAnchor: event.currentTarget, + menuItems: entitiesFromSchema.attributesPerEntity[entity].textAttributeNames, + menuItemsOnClick: (v: string) => onAttrNameChanged(v), + }); + }} + > + {attributeName} + </text> + <text x={colonOffset} fontWeight="bold" fontSize={15}> + : + </text> + + {renderAttributeValue(attrValueOffset)} + + <Menu + id="simple-menu" + anchorEl={state.menuAnchor} + keepMounted + // getContentAnchorEl={null} + anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} + transformOrigin={{ vertical: 'top', horizontal: 'center' }} + open={Boolean(state.menuAnchor)} + onClose={() => + setState({ + ...state, + menuAnchor: null, + }) + } + transitionDuration={150} + PaperProps={{ + style: { + maxHeight: 48 * 4.5, // 48 ITEM_HEIGHT + }, + }} + > + {state.menuItems.map((option) => ( + <MenuItem + key={option} + selected={option == state.menuAnchor?.innerHTML} + onClick={() => { + setState({ + ...state, + menuAnchor: null, + menuItems: [], + }); + + state.menuItemsOnClick(option); + }} + > + {option} + </MenuItem> + ))} + </Menu> + </g> + ); } diff --git a/libs/shared/lib/vis/semanticsubstrates/subcomponents/SVGCheckBoxComponent.tsx b/libs/shared/lib/vis/semanticsubstrates/subcomponents/SVGCheckBoxComponent.tsx index 9d65dfb11068fe9a76d5e4c0344bca930c77aa69..4b66a6e4c75fa6bed4b050af5095a6ebd45532cc 100644 --- a/libs/shared/lib/vis/semanticsubstrates/subcomponents/SVGCheckBoxComponent.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/subcomponents/SVGCheckBoxComponent.tsx @@ -9,7 +9,7 @@ * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ import Color from 'color'; -import React, { ReactElement } from 'react'; +import React, { ReactElement, useState } from 'react'; import { PlotType, RelationType } from '../Types'; /** All the props needed to visualize all the semantic substrates checkboxes. */ @@ -22,61 +22,59 @@ type SVGCheckboxesWithSemanticSubstrLabelProps = { }; /** Renders all the checkboxes for a semantic substrates visualisation. */ -export default class SVGCheckboxesWithSemanticSubstrLabel extends React.Component<SVGCheckboxesWithSemanticSubstrLabelProps> { - render(): ReactElement { - const { plots, relations, visibleRelations, nodeColors, onCheckboxChanged } = this.props; +export default function SVGCheckboxesWithSemanticSubstrLabel(props: SVGCheckboxesWithSemanticSubstrLabelProps) { + const { plots, relations, visibleRelations, nodeColors, onCheckboxChanged } = props; - const checkboxGroups: ReactElement[] = []; + const checkboxGroups: ReactElement[] = []; - // Go through each relation. - for (let fromPlot = 0; fromPlot < relations.length; fromPlot++) { - const checkboxes: JSX.Element[] = []; - // The from- and toPlot title color will be a bit darker than the node colors for their plots. - const fromColor = Color(nodeColors[fromPlot]).darken(0.3).hex(); - for (let toPlot = 0; toPlot < relations[fromPlot].length; toPlot++) { - if ( - !!relations?.[fromPlot]?.[toPlot] && - visibleRelations?.[fromPlot]?.[toPlot] !== undefined && - relations[fromPlot][toPlot].length > 0 - ) { - // Add a checkbox for the connections between fromPlot and toPlot. - checkboxes.push( - <g key={plots[fromPlot].title + fromPlot + '-' + plots[toPlot].title + toPlot} transform={'translate(0,' + toPlot * 30 + ')'}> - <text x={20} y={12} fill={fromColor} style={{ fontWeight: 'bold' }}> - {plots[fromPlot].title} - </text> - <path fill="transparent" stroke={'black'} d={`M${110} 7 l40 0 l-0 0 l-15 -5 m15 5 l-15 5`} /> - <text x={170} y={12} fill={Color(nodeColors[toPlot]).darken(0.3).hex()} style={{ fontWeight: 'bold' }}> - {plots[toPlot].title} - </text> - <SVGCheckboxComponent - x={0} - y={0} - key={plots[fromPlot].title + plots[toPlot].title + fromPlot + toPlot} - width={15} - value={visibleRelations[fromPlot][toPlot]} - onChange={(value: boolean) => { - onCheckboxChanged(fromPlot, toPlot, value); - }} - /> - </g> - ); - } + // Go through each relation. + for (let fromPlot = 0; fromPlot < relations.length; fromPlot++) { + const checkboxes: JSX.Element[] = []; + // The from- and toPlot title color will be a bit darker than the node colors for their plots. + const fromColor = Color(nodeColors[fromPlot]).darken(0.3).hex(); + for (let toPlot = 0; toPlot < relations[fromPlot].length; toPlot++) { + if ( + !!relations?.[fromPlot]?.[toPlot] && + visibleRelations?.[fromPlot]?.[toPlot] !== undefined && + relations[fromPlot][toPlot].length > 0 + ) { + // Add a checkbox for the connections between fromPlot and toPlot. + checkboxes.push( + <g key={plots[fromPlot].title + fromPlot + '-' + plots[toPlot].title + toPlot} transform={'translate(0,' + toPlot * 30 + ')'}> + <text x={20} y={12} fill={fromColor} style={{ fontWeight: 'bold' }}> + {plots[fromPlot].title} + </text> + <path fill="transparent" stroke={'black'} d={`M${110} 7 l40 0 l-0 0 l-15 -5 m15 5 l-15 5`} /> + <text x={170} y={12} fill={Color(nodeColors[toPlot]).darken(0.3).hex()} style={{ fontWeight: 'bold' }}> + {plots[toPlot].title} + </text> + <SVGCheckboxComponent + x={0} + y={0} + key={plots[fromPlot].title + plots[toPlot].title + fromPlot + toPlot} + width={15} + value={visibleRelations[fromPlot][toPlot]} + onChange={(value: boolean) => { + onCheckboxChanged(fromPlot, toPlot, value); + }} + /> + </g> + ); } - - // Offset the height of the checkboxes for each plot. - checkboxGroups.push( - <g - key={plots[fromPlot].title + fromPlot} - transform={'translate(' + (plots[fromPlot].width + 30) + ',' + plots[fromPlot].yOffset + ')'} - > - {checkboxes} - </g> - ); } - return <g>{checkboxGroups}</g>; + // Offset the height of the checkboxes for each plot. + checkboxGroups.push( + <g + key={plots[fromPlot].title + fromPlot} + transform={'translate(' + (plots[fromPlot].width + 30) + ',' + plots[fromPlot].yOffset + ')'} + > + {checkboxes} + </g> + ); } + + return <g>{checkboxGroups}</g>; } /** The props for the SVG checkbox component */ @@ -94,49 +92,46 @@ type SVGCheckBoxState = { value: boolean; }; /** Renders a simple checkbox in SVG elements. */ -export class SVGCheckboxComponent extends React.Component<SVGCheckBoxProps, SVGCheckBoxState> { - static defaultProps = { +export function SVGCheckboxComponent( + props: SVGCheckBoxProps = { + x: 0, + y: 0, width: 15, value: false, onChange: () => true, - }; - constructor(props: SVGCheckBoxProps) { - super(props); - this.state = { value: this.props.value }; - } - - render(): ReactElement { - return ( - <g> - <rect - x={this.props.x} - y={this.props.y} - rx="0" - ry="0" - width={this.props.width} - height={this.props.width} - style={{ fill: 'transparent', stroke: 'grey', strokeWidth: 2 }} - onClick={() => { - const newVal = this.state.value ? false : true; - this.props.onChange(newVal); - this.setState({ value: newVal }); - }} - /> - <rect - x={this.props.x + 3} - y={this.props.y + 3} - rx="0" - ry="0" - width={this.props.width - 6} - height={this.props.width - 6} - style={{ fill: this.state.value ? '#00a300' : 'white' }} - onClick={() => { - const newVal = this.state.value ? false : true; - this.props.onChange(newVal); - this.setState({ value: newVal }); - }} - /> - </g> - ); } +) { + const [state, setState] = useState<SVGCheckBoxState>({ value: props.value }); + return ( + <g> + <rect + x={props.x} + y={props.y} + rx="0" + ry="0" + width={props.width} + height={props.width} + style={{ fill: 'transparent', stroke: 'grey', strokeWidth: 2 }} + onClick={() => { + const newVal = state.value ? false : true; + props.onChange(newVal); + setState({ ...state, value: newVal }); + }} + /> + <rect + x={props.x + 3} + y={props.y + 3} + rx="0" + ry="0" + width={props.width - 6} + height={props.width - 6} + style={{ fill: state.value ? '#00a300' : 'white' }} + onClick={() => { + const newVal = state.value ? false : true; + props.onChange(newVal); + setState({ ...state, value: newVal }); + }} + /> + </g> + ); } diff --git a/libs/shared/lib/vis/semanticsubstrates/utils/CalcDefaultPlotSpecsUseCase.tsx b/libs/shared/lib/vis/semanticsubstrates/utils/CalcDefaultPlotSpecsUseCase.tsx index f46e9c02ec70f145d8f626ded456d6baf793a05e..f4b3db4ebe661c9c2103004475d4487776b27de9 100644 --- a/libs/shared/lib/vis/semanticsubstrates/utils/CalcDefaultPlotSpecsUseCase.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/utils/CalcDefaultPlotSpecsUseCase.tsx @@ -4,7 +4,7 @@ * © Copyright Utrecht University (Department of Information and Computing Sciences) */ -import { NodeLinkResultType } from '../../shared/ResultNodeLinkParserUseCase'; +import { GraphQueryResult } from '@graphpolaris/shared/lib/data-access'; import { AxisLabel, PlotSpecifications } from '../Types'; /** UseCase for calculating default plots from node link query result data. */ @@ -12,10 +12,10 @@ export default class CalcDefaultPlotSpecsUseCase { /** * Calculates default plot specifications for incoming query result data. * This determines what the default plots will be after executing a new query. - * @param {NodeLinkResultType} nodeLinkResult Query result data in the node link format. + * @param {GraphQueryResult} nodeLinkResult Query result data in the node link format. * @returns {PlotSpecifications[]} PlotSpecifications to generate the plots with the result data. */ - public static calculate(nodeLinkResult: NodeLinkResultType): PlotSpecifications[] { + public static calculate(nodeLinkResult: GraphQueryResult): PlotSpecifications[] { // Search through the first nodes' attributes for the shortest attribute value const plotSpecifications: PlotSpecifications[] = []; if (nodeLinkResult.nodes.length > 0) { @@ -26,7 +26,7 @@ export default class CalcDefaultPlotSpecsUseCase { let shortestStringValueLength: number = Number.MAX_VALUE; for (let key in firstNodeAttributes) { if (typeof firstNodeAttributes[key] == 'string') { - const v = firstNodeAttributes[key]; + const v = firstNodeAttributes[key] as string; if (v.length < shortestStringValueLength) { shortestStringKey = key; shortestStringValueLength = v.length; @@ -41,18 +41,15 @@ export default class CalcDefaultPlotSpecsUseCase { if (nodeLinkResult.nodes[i].label != firstNodeEntity) continue; - const v = nodeLinkResult.nodes[i].attributes[shortestStringKey]; + const v = nodeLinkResult.nodes[i].attributes[shortestStringKey] as string; if (values.includes(v)) continue; values.push(v); - let entity = nodeLinkResult.nodes[i].id; - if (nodeLinkResult.nodes[i].id.includes('/')) entity = entity.label; - else if (!!nodeLinkResult.nodes[i]?.attributes?.labels) entity = nodeLinkResult.nodes[i]?.attributes?.labels[0]; plotSpecifications.push({ entity: nodeLinkResult.nodes[i].label, labelAttributeType: shortestStringKey, - labelAttributeValue: nodeLinkResult.nodes[i].attributes[shortestStringKey], + labelAttributeValue: v, xAxis: AxisLabel.evenlySpaced, // Use default evenly spaced and # outbound connections on the x and y axis. yAxis: AxisLabel.outboundConnections, xAxisAttributeType: '', diff --git a/libs/shared/lib/vis/semanticsubstrates/utils/CalcEntityAttrNamesFromResultUseCase.tsx b/libs/shared/lib/vis/semanticsubstrates/utils/CalcEntityAttrNamesFromResultUseCase.tsx index edcfb0f70b873126e65073426c2eeef3f664af79..05dc2909bb71ffc626bce5371c26f39d6de8c60b 100644 --- a/libs/shared/lib/vis/semanticsubstrates/utils/CalcEntityAttrNamesFromResultUseCase.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/utils/CalcEntityAttrNamesFromResultUseCase.tsx @@ -4,20 +4,22 @@ * © Copyright Utrecht University (Department of Information and Computing Sciences) */ -import { NodeLinkResultType } from '../../shared/ResultNodeLinkParserUseCase'; +import { SchemaFromBackend } from '@graphpolaris/shared/lib/schema'; import { EntitiesFromSchema } from '../Types'; +import { GraphQueryResult } from '@graphpolaris/shared/lib/data-access'; /** Use case for retrieving entity names and attribute names from a schema result. */ export default class CalcEntityAttrNamesFromResultUseCase { /** * Takes a schema result and calculates all the entity names and attribute names per datatype. * Used by semantic substrates for the plot titles and add plot selections. - * @param {NodeLinkResultType} schemaResult A new schema result from the backend. + * @param {SchemaFromBackend} schemaResult A new schema result from the backend. * @param {EntitiesFromSchema} All entity names and attribute names per datatype. So we know what is in the Schema. * @returns {EntitiesFromSchema} All entity names and attribute names per datatype. + * @deprecated //TODO remove */ public static CalcEntityAttrNamesFromResult( - nodeLinkResult: NodeLinkResultType, + nodeLinkResult: GraphQueryResult, entitiesFromSchema: EntitiesFromSchema ): EntitiesFromSchema { const listOfNodeTypes: string[] = []; diff --git a/libs/shared/lib/vis/semanticsubstrates/utils/CalcEntityAttrNamesFromSchemaUseCase.tsx b/libs/shared/lib/vis/semanticsubstrates/utils/CalcEntityAttrNamesFromSchemaUseCase.tsx index c41788718473aee7b51a1372a79585ee5c98f876..2f1adef76a83eb39e51bb74f77d0b9f704a0b351 100644 --- a/libs/shared/lib/vis/semanticsubstrates/utils/CalcEntityAttrNamesFromSchemaUseCase.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/utils/CalcEntityAttrNamesFromSchemaUseCase.tsx @@ -4,7 +4,6 @@ * © Copyright Utrecht University (Department of Information and Computing Sciences) */ import { SchemaGraph } from '@graphpolaris/shared/lib/schema'; -import { Schema } from '../../shared/InputDataTypes'; import { AttributeNames, EntitiesFromSchema } from '../Types'; /** Use case for retrieving entity names and attribute names from a schema result. */ diff --git a/libs/shared/lib/vis/semanticsubstrates/utils/ToPlotDataParserUseCase.tsx b/libs/shared/lib/vis/semanticsubstrates/utils/ToPlotDataParserUseCase.tsx index abf74fdf655309572419a6ff4f61e5a84a90502e..bcaa713af5cad10656afe475af3cc0c403d0d8d3 100644 --- a/libs/shared/lib/vis/semanticsubstrates/utils/ToPlotDataParserUseCase.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/utils/ToPlotDataParserUseCase.tsx @@ -4,7 +4,8 @@ * © Copyright Utrecht University (Department of Information and Computing Sciences) */ import { GraphQueryResult } from '@graphpolaris/shared/lib/data-access'; -import { NodeLinkResultType, Node, ParseToUniqueEdges } from '../../shared/ResultNodeLinkParserUseCase'; +import { ParseToUniqueEdges } from '../../shared/ResultNodeLinkParserUseCase'; +import { Edge, Node } from '../../../data-access/store'; import { AxisLabel, PlotInputData, PlotSpecifications, RelationType } from '../Types'; /** A use case for parsing incoming node-link data to plot data */ diff --git a/libs/shared/lib/vis/shared/SchemaResultType.tsx b/libs/shared/lib/vis/shared/SchemaResultType.tsx index 7e21b48dfd85bc23ae13e6e92cc8a1fc35735831..804ed3f9c469e44033f1970d9225877c421d9063 100644 --- a/libs/shared/lib/vis/shared/SchemaResultType.tsx +++ b/libs/shared/lib/vis/shared/SchemaResultType.tsx @@ -3,14 +3,14 @@ * Utrecht University within the Software Project course. * © Copyright Utrecht University (Department of Information and Computing Sciences) */ -import { Attribute, Schema } from './InputDataTypes'; /** * Checks if an object has all the properties of a schema result. If true, the object will be casted to SchemaResultType * @param {any} object The object to check if it is a SchemaResult object. * @returns If true, the object is a of type SchemaResultType. + * @deprecated //TODO remove */ -export function isSchemaResult(object: any): object is Schema { +export function isSchemaResult(object: any): object is any { if (typeof object === 'object' && 'nodes' in object && object.nodes != undefined && 'edges' in object && object.edges != undefined) { if (!Array.isArray(object.nodes) || !Array.isArray(object.edges)) return false; @@ -35,8 +35,9 @@ export function isSchemaResult(object: any): object is Schema { * Checks if an object has the structure of a SchemaAttribute. * @param {any} object The object to check. * @returns If true, the object has the structure of SchemaAttribute type. + * @deprecated //TODO remove */ -function isAttributeArray(object: any): object is Attribute[] { +function isAttributeArray(object: any): object is any[] { if (!Array.isArray(object)) { return false; } diff --git a/libs/shared/lib/vis/shared/Types.tsx b/libs/shared/lib/vis/shared/Types.tsx index cc57707577c807571e5f49a22af6bf5a290d6625..18616628186351da17989aa1487dde8cdd6e2ce2 100644 --- a/libs/shared/lib/vis/shared/Types.tsx +++ b/libs/shared/lib/vis/shared/Types.tsx @@ -4,7 +4,6 @@ * © Copyright Utrecht University (Department of Information and Computing Sciences) */ import { Edge, Node } from 'reactflow'; -import { Attribute } from './InputDataTypes'; /** * List of schema elements for react flow @@ -114,7 +113,7 @@ export interface AttributeAnalyticsPopupMenuNode extends Node { /** Typing of the attributes which are stored in the popup menu's */ export type AttributeWithData = { - attribute: Attribute; + attribute: any; category: AttributeCategory; nullAmount: number; }; diff --git a/libs/shared/package.json b/libs/shared/package.json index d601b2019fe3b0068188d4de37cecab61d2fcc46..2fd83cbbb5b3e8cc30e82ff772213eac1b15a635 100644 --- a/libs/shared/package.json +++ b/libs/shared/package.json @@ -5,6 +5,7 @@ "type": "module", "scripts": { "build": "tsc && vite build", + "build-dev": "tsc && vite build --mode development", "lint": "eslint *.ts*", "test": "vitest run", "coverage": "vitest run --coverage" @@ -72,6 +73,7 @@ "@types/node": "18.13.0", "@types/react": "^18.0.27", "@types/react-dom": "^18.0.10", + "@types/react-window": "^1.8.5", "@typescript-eslint/eslint-plugin": "~5.52.0", "@typescript-eslint/parser": "~5.52.0", "@vitejs/plugin-react": "^3.1.0", diff --git a/libs/shared/tsconfig.json b/libs/shared/tsconfig.json index b2617928c44407db846e43650c9ceb2caac043fc..0f1e0dd82a0b4f829bc2ef3b38c1af3d013c6c5d 100644 --- a/libs/shared/tsconfig.json +++ b/libs/shared/tsconfig.json @@ -23,6 +23,7 @@ "resolveJsonModule": true, "noEmit": true, "baseUrl": ".", + "noImplicitOverride": false, "paths": { "@graphpolaris/shared/lib/*": ["./lib/*"] } diff --git a/nginx/nginx.conf b/nginx/nginx.conf index ef2e21a890fc402b46472b5c18fd5b95c3a53a2e..e053b4e8a9e8301982f60cccb9c857ee51d75f08 100644 --- a/nginx/nginx.conf +++ b/nginx/nginx.conf @@ -1,16 +1,16 @@ -server { - listen 80; - - location / { - root /usr/share/nginx/html; - index index.html index.htm; - try_files $uri $uri/ /index.html; - } - - error_page 500 502 503 504 /50x.html; - - location = /50x.html { - root /usr/share/nginx/html; - } - -} +server { + listen 4200; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri $uri/ /index.html; + } + + error_page 500 502 503 504 /50x.html; + + location = /50x.html { + root /usr/share/nginx/html; + } + +} diff --git a/package.json b/package.json index c9e130644f5d094c62bca9ce1260e1126dfd59a8..0fdb684e1eeb7601d0de848eb29945db3f1e9034 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ ], "scripts": { "build": "turbo run build --no-daemon", + "build-dev": "turbo run build-dev --no-daemon", "dev": "turbo run dev --no-daemon", "sb": "turbo run sb --no-daemon", "lint": "turbo run lint --no-daemon", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 64a3fc97ab951e4d3c335f593fd5b7d6580e3a4d..abdb21d3a6fe4c393cca5b9cfb8aa1c625ccbd08 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -332,6 +332,9 @@ importers: '@types/react-dom': specifier: ^18.0.10 version: 18.0.11 + '@types/react-window': + specifier: ^1.8.5 + version: 1.8.5 '@typescript-eslint/eslint-plugin': specifier: ~5.52.0 version: 5.52.0(@typescript-eslint/parser@5.52.0)(eslint@7.32.0)(typescript@4.9.5) @@ -370,7 +373,7 @@ importers: version: 8.7.0(eslint@7.32.0) eslint-config-turbo: specifier: latest - version: 1.10.6(eslint@7.32.0) + version: 1.10.9(eslint@7.32.0) eslint-plugin-import: specifier: 2.27.5 version: 2.27.5(@typescript-eslint/parser@5.52.0)(eslint-import-resolver-typescript@2.7.1)(eslint@7.32.0) @@ -6646,6 +6649,12 @@ packages: '@types/react': 18.0.28 dev: false + /@types/react-window@1.8.5: + resolution: {integrity: sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw==} + dependencies: + '@types/react': 18.0.28 + dev: true + /@types/react@18.0.28: resolution: {integrity: sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==} dependencies: @@ -9233,6 +9242,16 @@ packages: dependencies: eslint: 7.32.0 eslint-plugin-turbo: 1.10.6(eslint@7.32.0) + dev: false + + /eslint-config-turbo@1.10.9(eslint@7.32.0): + resolution: {integrity: sha512-YA5QWxWte/NiRJL0/Cv7aATfIvS5sUAuyD6ZuyTZEzwyU7E6FUXGo44amjf9INkyj96HrJ2nYWoFkCRx3vs6Ag==} + peerDependencies: + eslint: '>6.6.0' + dependencies: + eslint: 7.32.0 + eslint-plugin-turbo: 1.10.9(eslint@7.32.0) + dev: true /eslint-import-resolver-node@0.3.7: resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==} @@ -9382,6 +9401,16 @@ packages: dependencies: dotenv: 16.0.3 eslint: 7.32.0 + dev: false + + /eslint-plugin-turbo@1.10.9(eslint@7.32.0): + resolution: {integrity: sha512-o8Nga4WFMvzF0lo3d3UyjGli2JOUn/4SRtRdvcf4EA9/TPotU/NUHqO16Cp0SHZJG/tGYIy5LY1O/EO7Mxbd1A==} + peerDependencies: + eslint: '>6.6.0' + dependencies: + dotenv: 16.0.3 + eslint: 7.32.0 + dev: true /eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} diff --git a/turbo.json b/turbo.json index 131b3025a964238f0c3a421e332d2bc80cede422..ad609769f5dcfe6c0bd66457376354b98cb5edd2 100644 --- a/turbo.json +++ b/turbo.json @@ -6,6 +6,10 @@ "dependsOn": ["^build"], "outputs": ["dist/**", ".next/**"] }, + "build-dev": { + "dependsOn": ["^build-dev"], + "outputs": ["dist/**", ".next/**"] + }, "lint": { "outputs": [] },