Compare commits

..
Author SHA1 Message Date
John Colvin c80374579e fix build: Add a few includes, suppress some werrors
Not sure how this slipped through the cracks, but I'm guessing the build
broke when we upgraded the cpp compilers (to clang 17 and gcc 13).

* Include <cstdint> in a few places
* Suppress -Wstringop-overflow in sparkd-gcc-release build
* Change const char * param to explicit std::string for proper type
  deduction in call to 'std::make_tuple'. For some reason, the gcc build
  was failing with an array-bounds werror (changing the arg fixed it).
2024-03-18 19:14:48 +00:00
John Colvin 81cc0892f2 fix build: Remove version suffix from RuntimeIdentifiers in csprojs
They aren't required (nor supported) in dotnet 8
2024-03-18 15:13:01 -04:00
John Colvin 88714bb4b5 cleanup: Remove unnused token in BooleanExpression lex 2024-03-18 15:09:49 -04:00
John Colvin f39f1784a8 cleanup: Remove 'global.json' file
This config file is an artifact leftover from dotnet 6. I'm pretty sure
it's useless now.
2024-03-18 15:09:49 -04:00
John Colvin b7c8e72a07 feat: Add [incremental] MongoCollectionStream 2024-03-18 15:09:27 -04:00
John Colvin eea4af1f9b refactor: Impl IDictionary<int, IBlueRow> in BlueTable 2024-03-13 13:43:35 -05:00
John Colvin 6a244fee35 Normalize indentation in MongoDBStream 2024-03-13 13:43:35 -05:00
John Colvin d6a744e5ab Add echoDelay param to SimpleTCPServer 2024-03-13 13:43:35 -05:00
John Colvin 6f86b41f02 Add IObservable ViewStream wrapper 2024-03-13 13:43:35 -05:00
John Colvin faaa0ba8f1 refactor: Rename WebsocketServerConfig proto pkg 'bts.websocket_core'
This matches the namespace used in spark_websocket csproj. Eventually,
I'd like to use conventional capitalization (TitleCase namespaces/types,
etc.), but let's shelf that until we have enough time/energy to do a
more comprehensive refactoring.
2024-03-13 13:43:35 -05:00
John Colvin be97879db0 Add json facilities for DataStream websocket api 2024-03-13 13:43:34 -05:00
John Colvin b54d839aaf refactor: Add handy WebsocketExtensions
* IsSocketStateOpen
* IsClosedProperly
2024-03-13 13:43:34 -05:00
John Colvin 3af79a239a feat: Add Bts.DataStream.Websocket/Server 2024-03-13 13:43:34 -05:00
John Colvin d6d5e1d292 Add bones for Bts.DataStreamWebApp.Client 2024-03-13 13:43:33 -05:00
John Colvin e92e5d5039 Add bones for Bts.DataStreamWebApp.Server 2024-03-13 13:43:33 -05:00
John Colvin c47226f965 feat: Add JsonRpc types for websocket paradigm 2024-03-13 13:43:33 -05:00
John Colvin f19f2c7a81 cleanup: Remove empty file (clearly added by accident) 2024-03-13 13:43:33 -05:00
John Colvin b92fac9e55 Add more descriptive logs (via stdout) during initialization
The C++ configure/initialize routines were particularly opaque
2024-03-13 13:43:33 -05:00
John Colvin a1fe672271 fix: Fix improper 'OfType' linq cast
Previously, animations were expressed through polymorphism (derived from the
base class CellAnimation), but the new impl uses composition. This 'OfType' call
was leftover from the polymorphism implementation, an attempt to linq cast
elements of base class (CellAnimation) to BackgroundAnimation.
2024-03-13 13:43:33 -05:00
John Colvin 99d01fd25d cleanup: Remove static service Locator class
It relied on a static singleton 'ServiceContext'. Replace references with a
properly scoped (i.e., non-static) ServiceContext
2024-03-13 13:43:32 -05:00
John Colvin ae1a420d5f refactor: Reduce code (simplify) in BTS.init
Remove the 'args' parameter, since the cmd line can be obtained from
Environment.GetCommandLine anyways
2024-03-13 13:43:32 -05:00
John Colvin a162640b5e Dispose connections in SimpleTCPServer.Dispose 2024-03-13 13:43:32 -05:00
John Colvin 61db677c2a improvement: Polish clis in DataStreamSuite
Namely, PubSubServer and DataStreamPublisher

* Use CommandLineParser (nuget pkg)
* Clean up csproj files a bit while we're at it
2024-03-13 13:43:32 -05:00
John Colvin c1ebb1f7c5 editorconfig: Use standard c# capitalization rules
* Use 'PascalCase' for public members (instead of 'snake_case')
* Use 'camelCase' for private members (instead of '_snake_case')
2024-03-13 13:43:32 -05:00
John Colvin 96cb88505d refactor: Change WebsocketServerConfig.port to uint32
It should always be a number between 1-65535
2024-03-13 13:43:32 -05:00
John Colvin ed31ea8c67 refactor: Add WebsocketClient class
Basically an ISubject (I/O) wrapper for IWebsocketConnectionGateway
2024-03-13 13:43:31 -05:00
John Colvin 82e9939343 refactor: Remove nullability constraint in GetValueOrDefault 2024-03-13 13:43:31 -05:00
John Colvin 8021cb49cc refactor: Use events to avoid circular deps for ws sync/gateway 2024-03-13 13:43:31 -05:00
John Colvin a7eb58311d refactor: Let caller specify nullability of T in json parse fn 2024-03-13 13:43:31 -05:00
John Colvin 45ea54bdde refactor: Reorganize NumericComparer, support all types
Get rid of redundant UniversalNumericComparer while we're at it
2024-03-13 13:43:31 -05:00
John Colvin 0266d09e20 docker: Update and clean up Dockerfile
* Upgrade dotnet 7 -> 8
* Upgrade clang (13, 15) -> 17
* Upgrade gcc (11, 12) -> 13
* Remove kitware release candidate apt repo (probably shouldn't have
  been added in the first place).
* Install gdb for c++ debugging (VS Code debugger depends on this)
* Use explicit release ubuntu:22.04 (not 'latest'). We don't want the
  distro to automatically upgrade one day, when 'latest' suddenly points
  to a new release. Upgrades like that need to be done deliberately.
* Use more granular RUN cmds to reduce rebuild times.

  When a Dockerfile is built, the RUN cmds are executed in the order
  in which they were written (duh!). Checkpoints called "cache layers"
  are saved for each RUN cmd, so if the Dockerfile is later modified,
  the image can be rebuilt from the most recent layer that wasn't
  invalidated by the modifications.
2024-03-13 13:43:31 -05:00
John Colvin b6fa2bd1c2 cleanup: Remove leftover legacy files 2024-03-13 13:43:30 -05:00
John Colvin d43fd5bce7 build: Upgrade c# to net8.0 2024-03-13 13:43:30 -05:00
3972 changed files with 93007 additions and 157513 deletions

No files matched your search

+2 -8
View File
@@ -9,7 +9,7 @@
]
},
"fable": {
"version": "4.24.0",
"version": "4.0.6",
"commands": [
"fable"
]
@@ -25,12 +25,6 @@
"commands": [
"fake"
]
},
"dotnet-t4": {
"version": "3.0.0",
"commands": [
"t4"
]
}
}
}
}
-38
View File
@@ -1,38 +0,0 @@
{
"build": {
"dockerfile": "../docker/images/bluetradingsystems/linux_dotnet8_dev/Dockerfile",
"options": [
"--secret",
"id=bitbucket_access_token,src=${localWorkspaceFolder}/.secrets/bitbucket_access_token.txt"
]
},
"hostRequirements": {
"memory": "8gb",
"storage": "10gb"
},
"containerUser": "bts",
"updateRemoteUserUID": true,
"shutdownAction": "none",
// Note: If running multiple containers on the same host, each must use a
// unique set of ports. Usually we just add 1000 to each port as needed. For
// example, if 8000-8003 is taken, go with 9000-9003, then 10000-10003, etc.
"runArgs": [
"--shm-size",
"8gb"
],
"mounts": [
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"
],
"customizations": {
"vscode": {
"extensions": [
"eamodio.gitlens",
"llvm-vs-code-extensions.vscode-clangd",
"ms-python.python",
"ms-vscode.cmake-tools",
"ms-vscode.cpptools",
"xaver.clang-format"
]
}
}
}
-64
View File
@@ -1,64 +0,0 @@
# This file defines the global default configuration for docker deployments.
# It is tracked in source control. For temporary modifications, please create
# a separate file called ".env.local" (it's in .gitignore, so won't be tracked).
# If a variable is defined in both files, the value in .env.local will be used.
#
# About the deployment procedure:
# We use Docker Compose to build images and launch containers for various services
# that make up our software suite:
# - sparkd
# - TODO: pubsub
# - TODO: md-publisher
# - TODO: webapp (DSQA on the web)
# - TODO: api-server (websocket based)
# From inside a devcontainer, you can launch all services in separate containers
# on your machine by running:
#
# tools/deploy.sh
#
# This script builds release versions for each service, packaged (generally) in
# self-contained directories. Next, it runs a few "docker compose" commands to
# build docker images loaded with the self-contained binaries from the previous
# step, and start containers with those images to run each service. To view the
# commands that deploy.sh runs internally (without actually running them), run:
#
# tools/deploy.sh --dry-run
#
# For additional information/help, run:
#
# tools/deploy.sh --help
#
### Host/Runtime ###
TZ=Etc/UTC
### Sparkd ###
# The internal image for sparkd to use. For more info, view:
# src/server/sparkd/Dockerfile
SPARKD__IMAGE=sparkd
# The config dir for this service to use
SPARKD__CONFIG_DIR=src/app_sparkd/configurations/dev
# Mount a specific volume or dir to "~/sparkdata/data" inside the docker.
# Defaults to a volume named "sparkd_<config_port>" (e.g., sparkd_8000).
# SPARKD__DATA_DIR=/home/bts/sparkdata/data
# Mount volume or dir to "/md_recording" inside the docker. Defaults to volume
# "sparkd_md_recording_<config_port>" (e.g., sparkd_md_recording_8000).
# SPARKD__MD_RECORDING_DIR=/home/bts/md_recording
SPARKD__SOURCE_DIR=install/sparkd-release-gcc
SPARKD__RUNTIME_CONF_DIR=/home/ubuntu/8000/sparkdata/conf/
SPARKD__CONFIG_PORT=8000
SPARKD__QUICKBUS_PORT=8001
SPARKD__SIM_FIX_PORT=8002
SPARKD__SHM_SIZE=4gb
SPARKD__PYTHON_REQUIREMENTS=requirements.txt
SPARKD__SPARKD_ENTRYPOINT=src/app_sparkd/sparkd-entrypoint.sh
SPARKD__MAIN_ENTRYPOINT=./sparkd-entrypoint.sh
### PubSubServer ###
PUBSUB__CONFIG_DIR=src/DataStreamSuite/PubSubServer/Configurations/Development
PUBSUB__SOURCE_DIR=build/Release/bin/net8.0/linux-x64/publish
### MdPublisher ###
MD_PUBLISHER__CONFIG_DIR=src/DataStreamSuite/DataStreamPublisher/Configurations/ReplayMarketData
MD_PUBLISHER__SOURCE_DIR=build/Release/bin/net8.0/linux-x64/publish
# TODO: add config for other services (pubsub, md-publisher, webapp, api-server, etc.)
-3
View File
@@ -1,3 +0,0 @@
*.cmd text=auto eol=crlf
*.cs text=auto eol=crlf
*.sh text=auto eol=lf
+2 -9
View File
@@ -8,10 +8,7 @@ cmake-build-debug/
.idea/
.dir-locals.el
*.pyc
**.vscode/*
!.vscode/launch.json
!.vscode/tasks.json
!.vscode/*.env
**.vscode
.vs
obj/
*.csproj.user
@@ -55,12 +52,8 @@ trace_data/
.cache/
/src/Spark.Admin.WebApp/tsconfig.*.g.json
/src/Spark.Admin.WebApp/src/bin/
/src/**/*appsettings.Local.json
/src/**/*/Configurations/Local/
**/CMakeDeps.cmake
**/CMakeDeps_win.cmake
.devcontainer/
**/.devcontainer
*.Generated.cs
*.lst
.env.local
.secrets
+1 -1
View File
@@ -1,6 +1,6 @@
[submodule "externals"]
path = externals
url = https://bitbucket.org/bluetradesys/externals.git
url = git@bitbucket.org:bluetradesys/externals.git
[submodule "vcpkg"]
path = vcpkg
url = https://github.com/microsoft/vcpkg.git
-499
View File
@@ -1,499 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Python Debugger: Current File with Arguments",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"args": "${command:pickArgs}"
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
},
{
"name": "Api Server",
"type": "coreclr",
"request": "launch",
"program": "",
"preLaunchTask": "Build Api Server (Debug)",
"windows": {
"program": "spark_api_server.exe",
},
"linux": {
"program": "spark_api_server",
},
"args": [
"run",
],
"cwd": "build/Debug/bin/net8.0",
"env": {
"DOTNET_ENVIRONMENT": "${input:apiServerEnvironment}",
},
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "Api Server (Skip Build)",
"type": "coreclr",
"request": "launch",
"program": "",
"windows": {
"program": "spark_api_server.exe",
},
"linux": {
"program": "spark_api_server",
},
"args": [
"run",
],
"cwd": "build/Debug/bin/net8.0",
"env": {
"DOTNET_ENVIRONMENT": "${input:apiServerEnvironment}",
},
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "DataStreamPublisher",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "Build DataStream (Debug)",
"program": "",
"linux": {
"program": "DataStreamPublisher",
},
"windows": {
"program": "DataStreamPublisher.exe",
},
"cwd": "build/Debug/bin/net8.0",
"env": {
"DOTNET_ENVIRONMENT": "${input:dataStreamPublisherEnvironment}",
},
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "DataStreamPublisher (Skip Build)",
"type": "coreclr",
"request": "launch",
"program": "",
"linux": {
"program": "DataStreamPublisher",
},
"windows": {
"program": "DataStreamPublisher.exe",
},
"cwd": "${workspaceFolder}/build/Debug/bin/net8.0",
"env": {
"DOTNET_ENVIRONMENT": "${input:dataStreamPublisherEnvironment}",
},
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "/home/bts/spark/build/sparkd-debug-clang/server/sparkd",
"args": [
"run"
],
"stopAtEntry": false,
"cwd": "/home/bts/spark/build/sparkd-debug-clang/server",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
},
{
"name": "spreader tests2",
"type": "cppdbg",
"request": "launch",
"program": "/home/bts/spark/build/sparkd-debug-clang/server/sparkd",
"args": [
"test",
"[spreader2]"
],
"stopAtEntry": false,
"cwd": "/home/bts/spark/build/sparkd-debug-clang/server",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
},
{
"name": "spreader tests",
"type": "cppdbg",
"request": "launch",
"program": "/home/bts/spark/build/sparkd-debug-clang/server/sparkd",
"args": [
"test",
"[spreader]"
],
"stopAtEntry": false,
"cwd": "/home/bts/spark/build/sparkd-debug-clang/server",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
},
{
"name": "DataStreamQueryAnalyzer",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "Build DataStream (Debug)",
"program": "",
"windows": {
"program": "DataStreamQueryAnalyzer.exe",
"cwd": "build/Debug/bin/net8.0-windows",
"env": {
"PYTHON_EXE": "${workspaceFolder}/.venv/Scripts/python.exe",
"DOTNET_ENVIRONMENT": "${input:dataStreamQueryAnalyzerEnvironment}",
},
},
"stopAtEntry": false,
"console": "integratedTerminal",
},
{
"name": "DataStreamQueryAnalyzer (Skip Build)",
"type": "coreclr",
"request": "launch",
"program": "",
"windows": {
"program": "DataStreamQueryAnalyzer.exe",
"cwd": "build/Debug/bin/net8.0-windows",
"env": {
"PYTHON_EXE": "${workspaceFolder}/.venv/Scripts/python.exe",
"DOTNET_ENVIRONMENT": "${input:dataStreamQueryAnalyzerEnvironment}",
},
},
"stopAtEntry": false,
"console": "integratedTerminal",
},
{
"name": "PubSubServer",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "Build DataStream (Debug)",
"program": "",
"linux": {
"program": "PubSubServer",
},
"windows": {
"program": "PubSubServer.exe",
},
"cwd": "build/Debug/bin/net8.0",
"env": {
"DOTNET_ENVIRONMENT": "${input:pubSubServerEnvironment}",
},
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "PubSubServer (Skip Build)",
"type": "coreclr",
"request": "launch",
"program": "",
"linux": {
"program": "PubSubServer",
},
"windows": {
"program": "PubSubServer.exe",
},
"cwd": "build/Debug/bin/net8.0",
"env": {
"DOTNET_ENVIRONMENT": "${input:pubSubServerEnvironment}",
},
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "Sdk Demo",
"type": "coreclr",
"request": "launch",
"program": "",
"preLaunchTask": "Build Api Server (Debug)",
"windows": {
"program": "Bts.Spark.Sdk.Demo.exe",
},
"linux": {
"program": "Bts.Spark.Sdk.Demo",
},
"cwd": "build/Debug/bin/net8.0",
"env": {
"DOTNET_ENVIRONMENT": "${input:sdkDemoEnvironment}",
},
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "Sdk Demo (Skip Build)",
"type": "coreclr",
"request": "launch",
"program": "",
"windows": {
"program": "Bts.Spark.Sdk.Demo.exe",
},
"linux": {
"program": "Bts.Spark.Sdk.Demo.exe",
},
"cwd": "build/Debug/bin/net8.0",
"env": {
"DOTNET_ENVIRONMENT": "${input:sdkDemoEnvironment}",
},
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "Spark",
"type": "coreclr",
"request": "launch",
"program": "",
"windows": {
"preLaunchTask": "Build Spark (Debug)",
"program": "Spark.exe",
"cwd": "build/Debug/bin/net8.0-windows",
"env": {
"DOTNET_ENVIRONMENT": "${input:sparkEnvironment}",
}
},
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "Spark (Skip Build)",
"type": "coreclr",
"request": "launch",
"program": "",
"windows": {
"program": "Spark.exe",
"cwd": "build/Debug/bin/net8.0-windows",
"env": {
"DOTNET_ENVIRONMENT": "${input:sparkEnvironment}",
}
},
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "Spark (Parameterized)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "Build Spark (Debug)",
"program": "",
"windows": {
"program": "Spark.exe",
"args": [
"--sparkd",
"${input:sparkConfigServer}"
],
"cwd": "build/Debug/bin/net8.0-windows",
},
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "Spark Test",
"type": "coreclr",
"request": "launch",
"program": "",
"windows": {
"preLaunchTask": "Build Spark (Debug)",
"program": "Spark.Console.exe",
"cwd": "build/Debug/bin/net8.0",
"args": [
"test",
"${input:sparkTest}"
]
},
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "Spark Test (Skip Build)",
"type": "coreclr",
"request": "launch",
"program": "",
"windows": {
"program": "Spark.Console.exe",
"cwd": "build/Debug/bin/net8.0",
"args": [
"test",
"${input:sparkTest}"
]
},
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "Sparkd",
"type": "cppdbg",
"request": "launch",
"program": "",
"linux": {
"program": "${workspaceFolder}/build/sparkd-debug-clang/src/app_sparkd/sparkd",
"preLaunchTask": "Build Sparkd (Debug | Clang)",
},
"args": [
"run"
],
"cwd": "${workspaceFolder}/build/sparkd-debug-clang/src/app_sparkd",
"stopAtEntry": false,
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
},
{
"name": "Sparkd (Skip Build)",
"type": "cppdbg",
"request": "launch",
"program": "",
"linux": {
"program": "${workspaceFolder}/build/sparkd-debug-clang/src/app_sparkd/sparkd",
},
"args": [
"run"
],
"cwd": "${workspaceFolder}/build/sparkd-debug-clang/src/app_sparkd",
"stopAtEntry": false,
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
},
{
"name": "Sparkd Attach",
"type": "cppdbg",
"request": "attach",
"program": "${workspaceFolder}/build/sparkd-debug-clang/src/app_sparkd/sparkd",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
},
],
"inputs": [
{
"id": "apiServerEnvironment",
"type": "pickString",
"description": "Api Server Configuration",
"options": [
"Development",
"Local",
"Staging",
],
"default": "Development",
},
{
"id": "dataStreamPublisherConfig",
"type": "pickString",
"description": "Publisher Configuration",
"options": [
"MarketDataPublisher",
"SimpleEchoClient",
"SimpleTestDataPublisher",
"TestDataPublisher",
],
"default": "MarketDataPublisher",
},
{
"id": "dataStreamQueryAnalyzerEnvironment",
"type": "pickString",
"description": "DataStreamQueryAnalyzer Configuration",
"options": [
"Development",
"Local",
],
"default": "Development",
},
{
"id": "dataStreamPublisherEnvironment",
"type": "pickString",
"description": "DataStreamPublisher Configuration",
"options": [
"Local",
"ReplayMarketData",
],
"default": "Local",
},
{
"id": "pubSubServerEnvironment",
"type": "pickString",
"description": "PubSubServer Configuration",
"options": [
"Development",
"EchoServer",
"Local",
],
"default": "Development",
},
{
"id": "sdkDemoEnvironment",
"type": "pickString",
"description": "Sdk Demo Configuration",
"options": [
"Development",
"Local",
"Staging",
],
"default": "Development",
},
{
"id": "sparkConfigServer",
"type": "promptString",
"description": "Config Server URL",
"default": "http://localhost:8000/config",
},
{
"id": "sparkEnvironment",
"type": "pickString",
"description": "Spark Configuration",
"options": [
"Development",
"Local",
],
"default": "Development",
},
{
"id": "sparkTest",
"type": "promptString",
"description": "Test to run",
},
{
"id": "sparkdTest",
"type": "promptString",
"description": "Test to run",
},
]
}
-1
View File
@@ -1 +0,0 @@
PYTHONPATH=/workspaces/spark/build/sparkd-debug-clang/src/lib_python_interop;/workspaces/spark/src/lib_python_interop/python_interop_plugins;/workspaces/spark/tools/py
-1127
View File
File diff suppressed because it is too large. Load diff
-102
View File
@@ -1,102 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{827E0CD3-B72D-47B6-A68D-7590B98EB39B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cs", "cs", "{C5A3B5EA-BE9F-76E5-E9B8-8A22B289B295}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bts.Spark.Core", "src\cs\Bts.Spark.Core\Bts.Spark.Core.csproj", "{E3BF9514-CB1A-4E07-A8DD-73300FD9726C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bts.Spark.Api", "src\cs\Bts.Spark.Api\Bts.Spark.Api.csproj", "{8949AF88-F1D3-4BC4-827F-B088B555F7B9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bts.Extensions.Hosting", "src\cs\Bts.Extensions.Hosting\Bts.Extensions.Hosting.csproj", "{37E4E890-D025-4729-90F9-6F95862F47BC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bts.Spark.Sdk", "src\cs\Bts.Spark.Sdk\Bts.Spark.Sdk.csproj", "{A5FF3FAF-43CB-496B-AF4B-F61EFD645579}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bts.Spark.Sdk.Demo", "src\cs\Bts.Spark.Sdk.Demo\Bts.Spark.Sdk.Demo.csproj", "{FCFDBDBE-74B0-41C4-9011-C651B21056D4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E3BF9514-CB1A-4E07-A8DD-73300FD9726C}.Debug|Any CPU.ActiveCfg = Debug|x64
{E3BF9514-CB1A-4E07-A8DD-73300FD9726C}.Debug|Any CPU.Build.0 = Debug|x64
{E3BF9514-CB1A-4E07-A8DD-73300FD9726C}.Debug|x64.ActiveCfg = Debug|x64
{E3BF9514-CB1A-4E07-A8DD-73300FD9726C}.Debug|x64.Build.0 = Debug|x64
{E3BF9514-CB1A-4E07-A8DD-73300FD9726C}.Debug|x86.ActiveCfg = Debug|x64
{E3BF9514-CB1A-4E07-A8DD-73300FD9726C}.Debug|x86.Build.0 = Debug|x64
{E3BF9514-CB1A-4E07-A8DD-73300FD9726C}.Release|Any CPU.ActiveCfg = Release|x64
{E3BF9514-CB1A-4E07-A8DD-73300FD9726C}.Release|Any CPU.Build.0 = Release|x64
{E3BF9514-CB1A-4E07-A8DD-73300FD9726C}.Release|x64.ActiveCfg = Release|x64
{E3BF9514-CB1A-4E07-A8DD-73300FD9726C}.Release|x64.Build.0 = Release|x64
{E3BF9514-CB1A-4E07-A8DD-73300FD9726C}.Release|x86.ActiveCfg = Release|x64
{E3BF9514-CB1A-4E07-A8DD-73300FD9726C}.Release|x86.Build.0 = Release|x64
{8949AF88-F1D3-4BC4-827F-B088B555F7B9}.Debug|Any CPU.ActiveCfg = Debug|x64
{8949AF88-F1D3-4BC4-827F-B088B555F7B9}.Debug|Any CPU.Build.0 = Debug|x64
{8949AF88-F1D3-4BC4-827F-B088B555F7B9}.Debug|x64.ActiveCfg = Debug|x64
{8949AF88-F1D3-4BC4-827F-B088B555F7B9}.Debug|x64.Build.0 = Debug|x64
{8949AF88-F1D3-4BC4-827F-B088B555F7B9}.Debug|x86.ActiveCfg = Debug|x64
{8949AF88-F1D3-4BC4-827F-B088B555F7B9}.Debug|x86.Build.0 = Debug|x64
{8949AF88-F1D3-4BC4-827F-B088B555F7B9}.Release|Any CPU.ActiveCfg = Release|x64
{8949AF88-F1D3-4BC4-827F-B088B555F7B9}.Release|Any CPU.Build.0 = Release|x64
{8949AF88-F1D3-4BC4-827F-B088B555F7B9}.Release|x64.ActiveCfg = Release|x64
{8949AF88-F1D3-4BC4-827F-B088B555F7B9}.Release|x64.Build.0 = Release|x64
{8949AF88-F1D3-4BC4-827F-B088B555F7B9}.Release|x86.ActiveCfg = Release|x64
{8949AF88-F1D3-4BC4-827F-B088B555F7B9}.Release|x86.Build.0 = Release|x64
{37E4E890-D025-4729-90F9-6F95862F47BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{37E4E890-D025-4729-90F9-6F95862F47BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{37E4E890-D025-4729-90F9-6F95862F47BC}.Debug|x64.ActiveCfg = Debug|Any CPU
{37E4E890-D025-4729-90F9-6F95862F47BC}.Debug|x64.Build.0 = Debug|Any CPU
{37E4E890-D025-4729-90F9-6F95862F47BC}.Debug|x86.ActiveCfg = Debug|Any CPU
{37E4E890-D025-4729-90F9-6F95862F47BC}.Debug|x86.Build.0 = Debug|Any CPU
{37E4E890-D025-4729-90F9-6F95862F47BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{37E4E890-D025-4729-90F9-6F95862F47BC}.Release|Any CPU.Build.0 = Release|Any CPU
{37E4E890-D025-4729-90F9-6F95862F47BC}.Release|x64.ActiveCfg = Release|Any CPU
{37E4E890-D025-4729-90F9-6F95862F47BC}.Release|x64.Build.0 = Release|Any CPU
{37E4E890-D025-4729-90F9-6F95862F47BC}.Release|x86.ActiveCfg = Release|Any CPU
{37E4E890-D025-4729-90F9-6F95862F47BC}.Release|x86.Build.0 = Release|Any CPU
{A5FF3FAF-43CB-496B-AF4B-F61EFD645579}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A5FF3FAF-43CB-496B-AF4B-F61EFD645579}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5FF3FAF-43CB-496B-AF4B-F61EFD645579}.Debug|x64.ActiveCfg = Debug|Any CPU
{A5FF3FAF-43CB-496B-AF4B-F61EFD645579}.Debug|x64.Build.0 = Debug|Any CPU
{A5FF3FAF-43CB-496B-AF4B-F61EFD645579}.Debug|x86.ActiveCfg = Debug|Any CPU
{A5FF3FAF-43CB-496B-AF4B-F61EFD645579}.Debug|x86.Build.0 = Debug|Any CPU
{A5FF3FAF-43CB-496B-AF4B-F61EFD645579}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A5FF3FAF-43CB-496B-AF4B-F61EFD645579}.Release|Any CPU.Build.0 = Release|Any CPU
{A5FF3FAF-43CB-496B-AF4B-F61EFD645579}.Release|x64.ActiveCfg = Release|Any CPU
{A5FF3FAF-43CB-496B-AF4B-F61EFD645579}.Release|x64.Build.0 = Release|Any CPU
{A5FF3FAF-43CB-496B-AF4B-F61EFD645579}.Release|x86.ActiveCfg = Release|Any CPU
{A5FF3FAF-43CB-496B-AF4B-F61EFD645579}.Release|x86.Build.0 = Release|Any CPU
{FCFDBDBE-74B0-41C4-9011-C651B21056D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FCFDBDBE-74B0-41C4-9011-C651B21056D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FCFDBDBE-74B0-41C4-9011-C651B21056D4}.Debug|x64.ActiveCfg = Debug|Any CPU
{FCFDBDBE-74B0-41C4-9011-C651B21056D4}.Debug|x64.Build.0 = Debug|Any CPU
{FCFDBDBE-74B0-41C4-9011-C651B21056D4}.Debug|x86.ActiveCfg = Debug|Any CPU
{FCFDBDBE-74B0-41C4-9011-C651B21056D4}.Debug|x86.Build.0 = Debug|Any CPU
{FCFDBDBE-74B0-41C4-9011-C651B21056D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FCFDBDBE-74B0-41C4-9011-C651B21056D4}.Release|Any CPU.Build.0 = Release|Any CPU
{FCFDBDBE-74B0-41C4-9011-C651B21056D4}.Release|x64.ActiveCfg = Release|Any CPU
{FCFDBDBE-74B0-41C4-9011-C651B21056D4}.Release|x64.Build.0 = Release|Any CPU
{FCFDBDBE-74B0-41C4-9011-C651B21056D4}.Release|x86.ActiveCfg = Release|Any CPU
{FCFDBDBE-74B0-41C4-9011-C651B21056D4}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{C5A3B5EA-BE9F-76E5-E9B8-8A22B289B295} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
{E3BF9514-CB1A-4E07-A8DD-73300FD9726C} = {C5A3B5EA-BE9F-76E5-E9B8-8A22B289B295}
{8949AF88-F1D3-4BC4-827F-B088B555F7B9} = {C5A3B5EA-BE9F-76E5-E9B8-8A22B289B295}
{37E4E890-D025-4729-90F9-6F95862F47BC} = {C5A3B5EA-BE9F-76E5-E9B8-8A22B289B295}
{A5FF3FAF-43CB-496B-AF4B-F61EFD645579} = {C5A3B5EA-BE9F-76E5-E9B8-8A22B289B295}
{FCFDBDBE-74B0-41C4-9011-C651B21056D4} = {C5A3B5EA-BE9F-76E5-E9B8-8A22B289B295}
EndGlobalSection
EndGlobal
+58 -35
View File
@@ -1,10 +1,7 @@
cmake_minimum_required(VERSION 3.12)
project(spark)
include(GNUInstallDirs)
include(${CMAKE_SOURCE_DIR}/cmake/GitVersion.cmake)
set(CMAKE_CXX_STANDARD 20)
get_version_from_git()
if(WIN32)
set(platform "windows")
else()
@@ -17,17 +14,12 @@ set(
CACHE
STRING
"External dependencies root folder (should contain folders: lib, bin, include")
# SHARED_MEMORY_PREFIX serves as a kind of namespace so multiple applications
# can run simultaneously without fighting over the same shm files (e.g., sparkd,
# api server, etc.).
set(SHARED_MEMORY_PREFIX "\${BTS_SHARED_MEMORY_PREFIX}" CACHE STRING "Prefix to use when creating shared memory files")
set(EXTERNALS_BIN "${EXTERNALS_ROOT}/bin")
set(EXTERNALS_INCLUDE "${EXTERNALS_ROOT}/include")
set(EXTERNALS_LIB "${EXTERNALS_ROOT}/lib/$<CONFIG>")
set(SPARK_BIN "${EXTERNALS_ROOT}/bin")
set(SPARK_INCLUDE "${EXTERNALS_ROOT}/include")
set(SPARK_LIB "${EXTERNALS_ROOT}/lib/$<CONFIG>")
set(BUILD_API_SERVER OFF CACHE BOOL "Build the api server")
set(BUILD_DOCS OFF CACHE BOOL "Build documentation")
set(BUILD_SDK OFF CACHE BOOL "Build the sdk")
set(EXPORT_MD_CONSUMER OFF CACHE BOOL "Export (extern) C functions for MD consumer interop")
if (WIN32)
set(BUILD_SPARKD OFF CACHE BOOL "Build sparkd")
set(BUILD_ADMIN_WEB_APP OFF CACHE BOOL "Build the Admin WebApp")
@@ -36,19 +28,32 @@ else()
set(BUILD_ADMIN_WEB_APP ON CACHE BOOL "Build the Admin WebApp")
endif()
include_directories(BEFORE SYSTEM ${EXTERNALS_INCLUDE} ${EXTERNALS_ROOT}/include/zlib)
link_directories(${EXTERNALS_LIB})
include_directories(BEFORE SYSTEM ${SPARK_INCLUDE} ${EXTERNALS_ROOT}/include/zlib)
link_directories(${SPARK_LIB})
add_compile_definitions(SHARED_MEMORY_PREFIX="${SHARED_MEMORY_PREFIX}")
if(DEFINED APP_DATA_DIR)
add_compile_definitions(APP_DATA_DIR="${APP_DATA_DIR}")
if(BUILD_API_SERVER)
add_compile_definitions(SPARK_ENABLE_API_SERVER)
endif()
add_compile_definitions(EXPORT_MD_CONSUMER="${EXPORT_MD_CONSUMER}")
if(WIN32)
add_compile_definitions(SHARED_MEMORY_PREFIX="spark")
add_compile_definitions(APP_DATA_DIR="\$\{APPDATA\}/bts/")
# subdirs
add_subdirectory(src/lib_spark)
add_subdirectory(src/lib)
else()
if(BUILD_SPARKD)
# make sparkd look for libspark.so in its directory
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH ".")
set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/install")
set(SPARK_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/$<CONFIG>")
if(BUILD_API_SERVER)
add_compile_definitions(APP_DATA_DIR="\$\{HOME\}/spark_api/")
add_compile_definitions(SHARED_MEMORY_PREFIX="spark_api")
elseif(BUILD_SPARKD)
add_compile_definitions(SHARED_MEMORY_PREFIX="sparkd")
add_compile_definitions(APP_DATA_DIR="\$\{HOME\}/sparkdata/")
# Note: All macros that begin w/ 'CCAPI' are ccapi's macros (defined and/or
# read by their code). We override some below.
add_compile_definitions(SPARK_ENABLE_CCAPI)
@@ -85,15 +90,9 @@ else()
add_compile_definitions(BINANCE_US_PRICE_STATS_PATH="/api/v3/ticker/24hr")
# ** Binance USDS Futures **
add_compile_definitions(CCAPI_BINANCE_USDS_FUTURES_URL_REST_BASE="https://fapi.binance.com")
add_compile_definitions(BINANCE_USDS_FUTURES_INSTRUMENTS_PATH="/fapi/v1/exchangeInfo")
add_compile_definitions(BINANCE_USDS_FUTURES_PRICE_STATS_PATH="/fapi/v1/ticker/24hr")
add_compile_definitions(BINANCE_USDS_FUTURES_USER_DATA_PATH="/api/v3/userDataStream")
# ** Binance Coin Futures **
add_compile_definitions(CCAPI_BINANCE_COIN_FUTURES_URL_REST_BASE="https://dapi.binance.com")
add_compile_definitions(BINANCE_COIN_FUTURES_INSTRUMENTS_PATH="/dapi/v1/exchangeInfo")
add_compile_definitions(BINANCE_COIN_FUTURES_PRICE_STATS_PATH="/dapi/v1/ticker/24hr")
add_compile_definitions(CCAPI_BINANCE_USDS_FUTURES_URL_REST_BASE="https://dapi.binance.com")
add_compile_definitions(BINANCE_USDS_FUTURES_INSTRUMENTS_PATH="/dapi/v1/exchangeInfo")
add_compile_definitions(BINANCE_USDS_FUTURES_PRICE_STATS_PATH="/dapi/v1/ticker/24hr")
# ** Deribit **
add_compile_definitions(DERIBIT_INSTRUMENT_PATH="/api/v2/public/get_instrument")
@@ -112,15 +111,11 @@ else()
endif()
# subdirs
add_subdirectory(src/lib_spark)
if (BUILD_SPARKD)
add_subdirectory(src/lib_python_interop)
add_subdirectory(src/lib_onixs_fix)
add_subdirectory(src/lib_binance)
add_subdirectory(src/lib_okx_execution)
add_subdirectory(src/app_sparkd)
add_subdirectory(src/server/sparkd)
add_subdirectory(src/data_files)
endif()
add_subdirectory(src/lib)
if (BUILD_ADMIN_WEB_APP)
add_subdirectory(src/Spark.Admin.WebApp)
endif()
@@ -130,4 +125,32 @@ else()
if(BUILD_SDK)
add_subdirectory(src/sdk)
endif()
if(BUILD_SPARKD)
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/server
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/server
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/src/server/sparkd/sparkd ${CMAKE_BINARY_DIR}/server
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/data_files ${CMAKE_BINARY_DIR}/server
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/src/lib/libspark.so ${CMAKE_BINARY_DIR}/server
COMMAND
ln ARGS -sf
${EXTERNALS_ROOT}/lib/Release/libOnixS.IceImpactMulticastPriceFeedHandlerCpp.so.3.16.0.0
${CMAKE_BINARY_DIR}/server
COMMAND ln ARGS -sf ${EXTERNALS_ROOT}/lib/Release/libACE-5.7.5.so ${CMAKE_BINARY_DIR}/server
COMMAND mkdir ARGS -p ${CMAKE_BINARY_DIR}/server/plugins
COMMENT "Creating server runtime layout"
DEPENDS sparkd data_files_dir)
add_custom_target(server_layout ALL DEPENDS ${CMAKE_BINARY_DIR}/server)
install(
DIRECTORY "${CMAKE_BINARY_DIR}/server/plugins"
DESTINATION "${SPARK_INSTALL_PREFIX}/bin")
install(
FILES
"${SPARK_LIB}/libACE-5.7.5.so"
"${SPARK_LIB}/libOnixS.IceImpactMulticastPriceFeedHandlerCpp.so.3.16.0.0"
DESTINATION "${SPARK_INSTALL_PREFIX}/bin")
endif()
endif()
+145 -85
View File
@@ -8,31 +8,14 @@
"configurePresets": [
{
"name": "spark-base",
"hidden": true,
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"CMAKE_CXX_STANDARD": "20",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/${presetName}",
"CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake",
"CONFIG_DEFAULTS_PATH": "spark/config/profiles/default/*.conf",
"EXPORT_MD_CONSUMER": {
"type": "BOOL",
"value": "ON"
}
}
},
{
"name": "spark-windows",
"inherits": "spark-base",
"displayName": "Spark",
"name": "spark",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"generator": "Visual Studio 17 2022",
"binaryDir": "${sourceDir}/build",
"environment": {
"SPARK_CMAKE_CXX_FLAGS": "/MP /WX /wd4250 /wd4251 /wd4244 /wd4267 /wd4355 /wd4275 /wd4345 /bigobj /EHsc /DCURL_STATICLIB /D_WINSOCK_DEPRECATED_NO_WARNINGS /D__TBB_NO_IMPLICIT_LINKAGE /DBOOST_ALL_NO_LIB /std:c++20 /D_SCL_SECURE_NO_WARNINGS /D_CRT_SECURE_NO_WARNINGS /D_WIN32_WINNT=0x0600"
},
@@ -40,9 +23,14 @@
"CMAKE_CXX_FLAGS": "$env{SPARK_CMAKE_CXX_FLAGS}",
"CMAKE_CXX_FLAGS_DEBUG": "$env{SPARK_CMAKE_CXX_FLAGS} /MTd",
"CMAKE_CXX_FLAGS_RELEASE": "$env{SPARK_CMAKE_CXX_FLAGS} /MT",
"CMAKE_CXX_STANDARD": "20",
"CMAKE_SHARED_LINKER_FLAGS_DEBUG": "/DEBUG",
"CMAKE_SHARED_LINKER_FLAGS_RELEASE": "/OPT:REF /OPT:ICF /LTCG",
"EXTERNALS_ROOT": "${sourceDir}/externals/windows"
"CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake",
"EXTERNALS_ROOT": "${sourceDir}/externals/windows",
"CONFIG_DEFAULTS_PATH": "config/profiles/default/*.conf",
"DOTNET_BINARY_DIR": "${sourceDir}/build/$<CONFIG>/bin/net8.0",
"DOTNET_WINDOWS_BINARY_DIR": "${sourceDir}/build/$<CONFIG>/bin/net8.0-windows"
}
},
@@ -60,18 +48,12 @@
"platform": "",
"CMAKE_BUILD_WITH_INSTALL_RPATH": {
"type": "BOOL",
"value": "OFF"
"value": "ON"
},
"CMAKE_CXX_STANDARD": "20",
"CMAKE_INSTALL_RPATH": ".",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/${presetName}",
"CMAKE_PREFIX_PATH": "${sourceDir}/cmake/;${sourceDir}/.venv/lib/python3.10/site-packages/pybind11/share/cmake/pybind11",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/${presetName}/sparkd",
"CMAKE_EXE_LINKER_FLAGS": "-Wno-undef",
"CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake",
"DATABENTO_USE_EXTERNAL_JSON": {
"type": "BOOL",
"value": "ON"
},
"EXTERNALS_ROOT": "${sourceDir}/externals/linux",
"BUILD_SDK": {
"type": "BOOL",
@@ -95,7 +77,7 @@
"value": "ON"
},
"CCAPI_LOG_LEVEL": "Info",
"CONFIG_DEFAULTS_PATH": "spark/config/profiles/md_dev/*.conf;spark/config/profiles/default/*.conf"
"CONFIG_DEFAULTS_PATH": "config/profiles/md_dev/*.conf;config/profiles/default/*.conf"
}
},
@@ -106,79 +88,106 @@
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CCAPI_LOG_LEVEL": "Warn",
"CONFIG_DEFAULTS_PATH": "spark/config/profiles/md_prod/*.conf;spark/config/profiles/default/*.conf"
"CONFIG_DEFAULTS_PATH": "config/profiles/md_prod/*.conf;config/profiles/default/*.conf"
}
},
{
"name": "sparkd-debug-clang",
"inherits": "sparkd-debug",
"displayName": "Sparkd (Debug | Clang)",
"displayName": "Debug (clang)",
"description": "Debug build compiled w/ clang",
"binaryDir": "${sourceDir}/build/clang/debug",
"cacheVariables": {
"CMAKE_C_COMPILER": "clang",
"CMAKE_CXX_COMPILER": "clang++",
"CMAKE_CXX_FLAGS_DEBUG": "-g -fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -DDEBUG"
"CMAKE_CXX_FLAGS_DEBUG": "-g -fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -DDEBUG",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/clang/debug/sparkd"
}
},
{
"name": "sparkd-debug-gcc",
"inherits": "sparkd-debug",
"displayName": "Sparkd (Debug | Gcc)",
"displayName": "Debug (gcc)",
"description": "Debug build compiled w/ gcc",
"binaryDir": "${sourceDir}/build/gcc/debug",
"cacheVariables": {
"CMAKE_C_COMPILER": "gcc",
"CMAKE_CXX_COMPILER": "g++",
"CMAKE_CXX_FLAGS_DEBUG": "-g -fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -Wno-stringop-overread -DDEBUG"
"CMAKE_CXX_FLAGS_DEBUG": "-g -fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -Wno-stringop-overread -DDEBUG",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/gcc/debug/sparkd"
}
},
{
"name": "sparkd-release-clang",
"inherits": "sparkd-release",
"displayName": "Sparkd (Release | Clang)",
"displayName": "Release (clang)",
"description": "Release build compiled w/ clang",
"binaryDir": "${sourceDir}/build/clang/release",
"cacheVariables": {
"CMAKE_C_COMPILER": "clang",
"CMAKE_CXX_COMPILER": "clang++",
"CMAKE_CXX_FLAGS_RELEASE": "-fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -fno-omit-frame-pointer -DNDEBUG -O3"
"CMAKE_CXX_FLAGS_RELEASE": "-fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -fno-omit-frame-pointer -DNDEBUG -O3",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/clang/release/sparkd"
}
},
{
"name": "sparkd-release-gcc",
"inherits": "sparkd-release",
"displayName": "Sparkd (Release | Gcc)",
"displayName": "Release (gcc)",
"description": "Release build compiled w/ gcc",
"binaryDir": "${sourceDir}/build/gcc/release",
"cacheVariables": {
"CMAKE_C_COMPILER": "gcc",
"CMAKE_CXX_COMPILER": "g++",
"CMAKE_CXX_FLAGS_RELEASE": "-fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers -Wno-stringop-overflow --std=c++20 -fdiagnostics-color -Wno-stringop-overread -Wno-maybe-uninitialized -fno-omit-frame-pointer -DNDEBUG -O3"
"CMAKE_CXX_FLAGS_RELEASE": "-fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers -Wno-stringop-overflow --std=c++20 -fdiagnostics-color -Wno-stringop-overread -Wno-maybe-uninitialized -fno-omit-frame-pointer -DNDEBUG -O3",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/gcc/release/sparkd"
}
},
{
"name": "spark-linux",
"inherits": "spark-base",
"displayName": "Spark",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
},
"name": "spark-api-server-base",
"hidden": true,
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"BUILD_API_SERVER": {
"type": "bool",
"value": "ON"
},
"CONFIG_DEFAULTS_PATH": "config/profiles/md_dev/*.conf;config/profiles/default/*.conf"
}
},
{
"name": "spark-api-server-windows",
"inherits": "spark",
"displayName": "Spark Api Server",
"cacheVariables": {
"BUILD_API_SERVER": {
"type": "bool",
"value": "ON"
}
}
},
{
"name": "spark-api-server-linux",
"inherits": "sparkd",
"displayName": "Spark Api Server",
"generator": "Ninja Multi-Config",
"cacheVariables": {
"platform": "linux",
"BUILD_ADMIN_WEB_APP": {
"type": "BOOL",
"value": "OFF"
},
"BUILD_SPARKD": {
"type": "BOOL",
"value": "OFF"
"BUILD_API_SERVER": {
"type": "bool",
"value": "ON"
},
"CMAKE_BUILD_WITH_INSTALL_RPATH": {
"BUILD_SPARKD": {
"type": "BOOL",
"value": "OFF"
},
@@ -186,18 +195,9 @@
"CMAKE_CXX_COMPILER": "clang++",
"CMAKE_CXX_FLAGS_DEBUG": "-g -fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -DDEBUG",
"CMAKE_CXX_FLAGS_RELEASE": "-fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -fno-omit-frame-pointer -DNDEBUG -O3",
"CMAKE_EXE_LINKER_FLAGS": "-Wno-undef",
"CMAKE_EXPORT_COMPILE_COMMANDS": {
"type": "BOOL",
"value": "ON"
},
"CMAKE_INSTALL_RPATH": ".",
"CMAKE_PREFIX_PATH": "${sourceDir}/cmake/;${sourceDir}/.venv/lib/python3.10/site-packages/pybind11/share/cmake/pybind11",
"DATABENTO_USE_EXTERNAL_JSON": {
"type": "BOOL",
"value": "ON"
},
"EXTERNALS_ROOT": "${sourceDir}/externals/linux"
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/${presetName}",
"CONFIG_DEFAULTS_PATH": "config/profiles/default/*.conf",
"DOTNET_BINARY_DIR": "${sourceDir}/build/$<CONFIG>/bin/net8.0"
}
},
@@ -217,32 +217,44 @@
"cacheVariables": {
"CCAPI_LOG_LEVEL": "Trace"
}
},
{
"name": "data-stream-suite",
"inherits": "spark",
"displayName": "Data Stream Suite",
"description": "Data Stream utils ported over from Edge",
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"CONFIG_DEFAULTS_PATH": "config/profiles/default/*.conf;config/profiles/data_stream/*.conf"
}
}
],
"buildPresets": [
{
"name": "spark-windows",
"name": "spark",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"hidden": true,
"configurePreset": "spark-windows"
"hidden": true
},
{
"name": "spark-windows-debug",
"displayName": "Spark (Debug)",
"inherits": "spark-windows",
"name": "spark-debug",
"displayName": "Debug",
"inherits": "spark",
"configurePreset": "spark",
"configuration": "Debug"
},
{
"name": "spark-windows-release",
"displayName": "Spark (Release)",
"inherits": "spark-windows",
"name": "spark-release",
"displayName": "Release",
"inherits": "spark",
"configurePreset": "spark",
"configuration": "Release"
},
@@ -253,59 +265,93 @@
"lhs": "${hostSystemName}",
"rhs": "Linux"
},
"hidden": true
"hidden": true,
"targets": [
"data_files_dir",
"admin_web_app_bundle",
"install",
"libspark",
"rapidjson_project",
"server_layout",
"sparkd"
]
},
{
"name": "sparkd-debug-clang",
"configurePreset": "sparkd-debug-clang",
"displayName": "Sparkd (Debug | Clang)",
"displayName": "Debug (clang)",
"inherits": "sparkd"
},
{
"name": "sparkd-debug-gcc",
"configurePreset": "sparkd-debug-gcc",
"displayName": "Sparkd (Debug | Gcc)",
"displayName": "Debug (gcc)",
"inherits": "sparkd"
},
{
"name": "sparkd-release-clang",
"configurePreset": "sparkd-release-clang",
"displayName": "Sparkd (Release | Clang)",
"displayName": "Release (clang)",
"inherits": "sparkd"
},
{
"name": "sparkd-release-gcc",
"configurePreset": "sparkd-release-gcc",
"displayName": "Sparkd (Release | Gcc)",
"displayName": "Release (gcc)",
"inherits": "sparkd"
},
{
"name": "spark-linux",
"name": "spark-api-server-windows",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"hidden": true,
"configurePreset": "spark-api-server-windows"
},
{
"name": "spark-api-server-windows-debug",
"displayName": "Spark Api Server (Debug)",
"inherits": "spark-api-server-windows",
"configuration": "Debug"
},
{
"name": "spark-api-server-windows-release",
"displayName": "Spark Api Server (Debug)",
"inherits": "spark-api-server-windows",
"configuration": "Release"
},
{
"name": "spark-api-server-linux",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
},
"hidden": true,
"configurePreset": "spark-linux"
"configurePreset": "spark-api-server-linux"
},
{
"name": "spark-linux-debug",
"inherits": "spark-linux",
"displayName": "Spark (Linux | Debug)",
"name": "spark-api-server-linux-debug",
"inherits": "spark-api-server-linux",
"displayName": "Spark Api Server (Debug)",
"configuration": "Debug"
},
{
"name": "spark-linux-release",
"inherits": "spark-linux",
"displayName": "Spark (Linux | Release)",
"name": "spark-api-server-linux-release",
"inherits": "spark-api-server-linux",
"displayName": "Spark Api Server (Release)",
"configuration": "Release"
},
@@ -322,6 +368,20 @@
"configurePreset": "sparkd-ccapi-diag",
"displayName": "Debug (ccapi diag)",
"inherits": "sparkd"
},
{
"name": "data-stream-suite-debug",
"displayName": "DataStreamSuite (Debug)",
"configurePreset": "data-stream-suite",
"configuration": "Debug"
},
{
"name": "data-stream-suite-release",
"displayName": "DataStreamSuite (Release)",
"configurePreset": "data-stream-suite",
"configuration": "Release"
}
]
}
+3 -522
View File
@@ -1,11 +1,10 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32922.545
MinimumVisualStudioVersion = 15.0.26124.0
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bts.Spark.Api", "src\cs\Bts.Spark.Api\Bts.Spark.Api.csproj", "{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_api", "src\client\spark_api\spark_api.csproj", "{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bts.Spark.Core", "src\cs\Bts.Spark.Core\Bts.Spark.Core.csproj", "{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_core", "src\client\spark_core\spark_core.csproj", "{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_websocket", "src\client\spark_websocket\spark_websocket.csproj", "{3201359D-C071-4089-9EDE-B04D759F1508}"
EndProject
@@ -15,584 +14,66 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "spark_test", "src\client\sp
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spark.Console", "src\client\Spark.Console\Spark.Console.csproj", "{89D666E6-B500-498F-B026-4D167F68ADFC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{267F81EF-A8AB-49FD-9F56-D7EC3C1F7C7C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataStreamSuite", "DataStreamSuite", "{C09ED521-D2DF-40BC-A76F-EB3CB870B2F6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataStreamCore", "src\DataStreamSuite\DataStreamCore\DataStreamCore.csproj", "{EF26A475-6101-4C9C-A717-D60BB92A2302}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedStreams", "src\DataStreamSuite\SharedStreams\SharedStreams.csproj", "{911B08A3-515A-441D-84C8-8A43740B5FC1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PubSub", "src\DataStreamSuite\PubSub\PubSub.csproj", "{14140310-2233-430A-821B-F3058A25234B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BaseUtilities", "src\DataStreamSuite\BaseUtilities\BaseUtilities.csproj", "{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExpressionCore", "src\DataStreamSuite\ExpressionCore\ExpressionCore.csproj", "{6F22DB96-6EAB-4034-99D9-287021C36F01}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArithmeticExpressions", "src\DataStreamSuite\ArithmeticExpressions\ArithmeticExpressions.csproj", "{A5C33956-A41F-49B3-A41D-1082CBA59D02}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataStreamExpressions", "src\DataStreamSuite\DataStreamExpressions\DataStreamExpressions.csproj", "{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bts.ColumnSortExpressions", "src\DataStreamSuite\Bts.ColumnSortExpressions\Bts.ColumnSortExpressions.csproj", "{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColumnMapExpressions", "src\DataStreamSuite\ColumnMapExpressions\ColumnMapExpressions.csproj", "{B945A183-2174-4ACB-B289-8A5C546656FE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BooleanExpressions", "src\DataStreamSuite\BooleanExpressions\BooleanExpressions.csproj", "{9F6D7DE8-185B-4C1D-B809-3314D092DF28}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bts.ColumnExpressions", "src\DataStreamSuite\Bts.ColumnExpressions\Bts.ColumnExpressions.csproj", "{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataStream", "src\DataStreamSuite\DataStream\DataStream.csproj", "{39AEA075-6457-46C0-8821-1158BE6EFA57}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bts.Extensions.Hosting", "src\cs\Bts.Extensions.Hosting\Bts.Extensions.Hosting.csproj", "{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cs", "cs", "{385C4948-E080-56A6-E29E-8B0F4913175C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bts.Net", "src\cs\Bts.Net\Bts.Net.csproj", "{43FB297B-7A4D-4835-A878-E6DF345B580C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bts.IO.Compression", "src\cs\Bts.IO.Compression\Bts.IO.Compression.csproj", "{BC277499-8215-4F9F-B9AB-07B6391110BF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|Any CPU = Debug|Any CPU
Debug|x86 = Debug|x86
MinSizeRel|x64 = MinSizeRel|x64
MinSizeRel|Any CPU = MinSizeRel|Any CPU
MinSizeRel|x86 = MinSizeRel|x86
Release|x64 = Release|x64
Release|Any CPU = Release|Any CPU
Release|x86 = Release|x86
RelWithDebInfo|x64 = RelWithDebInfo|x64
RelWithDebInfo|Any CPU = RelWithDebInfo|Any CPU
RelWithDebInfo|x86 = RelWithDebInfo|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Debug|x64.ActiveCfg = Debug|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Debug|x64.Build.0 = Debug|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Debug|x86.ActiveCfg = Debug|Any CPU
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Debug|x86.Build.0 = Debug|Any CPU
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|x64.ActiveCfg = Release|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|x64.Build.0 = Release|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|x64.ActiveCfg = Release|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|x64.Build.0 = Release|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|Any CPU.Build.0 = Release|Any CPU
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|x86.ActiveCfg = Release|Any CPU
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|x86.Build.0 = Release|Any CPU
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|x64.Build.0 = Release|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Debug|x64.ActiveCfg = Debug|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Debug|x64.Build.0 = Debug|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Debug|x86.ActiveCfg = Debug|Any CPU
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Debug|x86.Build.0 = Debug|Any CPU
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|x64.ActiveCfg = Release|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|x64.Build.0 = Release|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Release|x64.ActiveCfg = Release|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Release|x64.Build.0 = Release|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Release|Any CPU.Build.0 = Release|Any CPU
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Release|x86.ActiveCfg = Release|Any CPU
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Release|x86.Build.0 = Release|Any CPU
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|x64.Build.0 = Release|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{3201359D-C071-4089-9EDE-B04D759F1508}.Debug|x64.ActiveCfg = Debug|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.Debug|x64.Build.0 = Debug|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3201359D-C071-4089-9EDE-B04D759F1508}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3201359D-C071-4089-9EDE-B04D759F1508}.Debug|x86.ActiveCfg = Debug|Any CPU
{3201359D-C071-4089-9EDE-B04D759F1508}.Debug|x86.Build.0 = Debug|Any CPU
{3201359D-C071-4089-9EDE-B04D759F1508}.MinSizeRel|x64.ActiveCfg = Debug|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.MinSizeRel|x64.Build.0 = Debug|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{3201359D-C071-4089-9EDE-B04D759F1508}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{3201359D-C071-4089-9EDE-B04D759F1508}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{3201359D-C071-4089-9EDE-B04D759F1508}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{3201359D-C071-4089-9EDE-B04D759F1508}.Release|x64.ActiveCfg = Release|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.Release|x64.Build.0 = Release|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3201359D-C071-4089-9EDE-B04D759F1508}.Release|Any CPU.Build.0 = Release|Any CPU
{3201359D-C071-4089-9EDE-B04D759F1508}.Release|x86.ActiveCfg = Release|Any CPU
{3201359D-C071-4089-9EDE-B04D759F1508}.Release|x86.Build.0 = Release|Any CPU
{3201359D-C071-4089-9EDE-B04D759F1508}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.RelWithDebInfo|x64.Build.0 = Release|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{3201359D-C071-4089-9EDE-B04D759F1508}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{3201359D-C071-4089-9EDE-B04D759F1508}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{3201359D-C071-4089-9EDE-B04D759F1508}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Debug|x64.ActiveCfg = Debug|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Debug|x64.Build.0 = Debug|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Debug|x86.ActiveCfg = Debug|Any CPU
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Debug|x86.Build.0 = Debug|Any CPU
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.MinSizeRel|x64.ActiveCfg = Debug|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.MinSizeRel|x64.Build.0 = Debug|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Release|x64.ActiveCfg = Release|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Release|x64.Build.0 = Release|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Release|Any CPU.Build.0 = Release|Any CPU
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Release|x86.ActiveCfg = Release|Any CPU
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Release|x86.Build.0 = Release|Any CPU
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.RelWithDebInfo|x64.Build.0 = Release|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.Debug|x64.ActiveCfg = Debug|x64
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.Debug|x64.Build.0 = Debug|x64
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.Debug|x86.ActiveCfg = Debug|Any CPU
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.Debug|x86.Build.0 = Debug|Any CPU
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.MinSizeRel|x64.ActiveCfg = Debug|x64
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.MinSizeRel|x64.Build.0 = Debug|x64
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.Release|x64.ActiveCfg = Release|x64
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.Release|x64.Build.0 = Release|x64
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.Release|Any CPU.Build.0 = Release|Any CPU
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.Release|x86.ActiveCfg = Release|Any CPU
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.Release|x86.Build.0 = Release|Any CPU
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.RelWithDebInfo|x64.ActiveCfg = Debug|x64
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.RelWithDebInfo|x64.Build.0 = Debug|x64
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{89D666E6-B500-498F-B026-4D167F68ADFC}.Debug|x64.ActiveCfg = Debug|x64
{89D666E6-B500-498F-B026-4D167F68ADFC}.Debug|x64.Build.0 = Debug|x64
{89D666E6-B500-498F-B026-4D167F68ADFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{89D666E6-B500-498F-B026-4D167F68ADFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{89D666E6-B500-498F-B026-4D167F68ADFC}.Debug|x86.ActiveCfg = Debug|Any CPU
{89D666E6-B500-498F-B026-4D167F68ADFC}.Debug|x86.Build.0 = Debug|Any CPU
{89D666E6-B500-498F-B026-4D167F68ADFC}.MinSizeRel|x64.ActiveCfg = Debug|x64
{89D666E6-B500-498F-B026-4D167F68ADFC}.MinSizeRel|x64.Build.0 = Debug|x64
{89D666E6-B500-498F-B026-4D167F68ADFC}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{89D666E6-B500-498F-B026-4D167F68ADFC}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{89D666E6-B500-498F-B026-4D167F68ADFC}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{89D666E6-B500-498F-B026-4D167F68ADFC}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{89D666E6-B500-498F-B026-4D167F68ADFC}.Release|x64.ActiveCfg = Release|x64
{89D666E6-B500-498F-B026-4D167F68ADFC}.Release|x64.Build.0 = Release|x64
{89D666E6-B500-498F-B026-4D167F68ADFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{89D666E6-B500-498F-B026-4D167F68ADFC}.Release|Any CPU.Build.0 = Release|Any CPU
{89D666E6-B500-498F-B026-4D167F68ADFC}.Release|x86.ActiveCfg = Release|Any CPU
{89D666E6-B500-498F-B026-4D167F68ADFC}.Release|x86.Build.0 = Release|Any CPU
{89D666E6-B500-498F-B026-4D167F68ADFC}.RelWithDebInfo|x64.ActiveCfg = Debug|x64
{89D666E6-B500-498F-B026-4D167F68ADFC}.RelWithDebInfo|x64.Build.0 = Debug|x64
{89D666E6-B500-498F-B026-4D167F68ADFC}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{89D666E6-B500-498F-B026-4D167F68ADFC}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{89D666E6-B500-498F-B026-4D167F68ADFC}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{89D666E6-B500-498F-B026-4D167F68ADFC}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.Debug|x64.ActiveCfg = Debug|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.Debug|x64.Build.0 = Debug|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.Debug|x86.ActiveCfg = Debug|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.Debug|x86.Build.0 = Debug|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.Release|x64.ActiveCfg = Release|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.Release|x64.Build.0 = Release|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.Release|Any CPU.Build.0 = Release|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.Release|x86.ActiveCfg = Release|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.Release|x86.Build.0 = Release|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{EF26A475-6101-4C9C-A717-D60BB92A2302}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.Debug|x64.ActiveCfg = Debug|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.Debug|x64.Build.0 = Debug|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.Debug|x86.ActiveCfg = Debug|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.Debug|x86.Build.0 = Debug|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.Release|x64.ActiveCfg = Release|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.Release|x64.Build.0 = Release|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.Release|Any CPU.Build.0 = Release|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.Release|x86.ActiveCfg = Release|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.Release|x86.Build.0 = Release|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{911B08A3-515A-441D-84C8-8A43740B5FC1}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.Debug|x64.ActiveCfg = Debug|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.Debug|x64.Build.0 = Debug|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.Debug|x86.ActiveCfg = Debug|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.Debug|x86.Build.0 = Debug|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.Release|x64.ActiveCfg = Release|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.Release|x64.Build.0 = Release|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.Release|Any CPU.Build.0 = Release|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.Release|x86.ActiveCfg = Release|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.Release|x86.Build.0 = Release|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{14140310-2233-430A-821B-F3058A25234B}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.Debug|x64.ActiveCfg = Debug|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.Debug|x64.Build.0 = Debug|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.Debug|x86.ActiveCfg = Debug|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.Debug|x86.Build.0 = Debug|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.Release|x64.ActiveCfg = Release|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.Release|x64.Build.0 = Release|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.Release|Any CPU.Build.0 = Release|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.Release|x86.ActiveCfg = Release|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.Release|x86.Build.0 = Release|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.Debug|x64.ActiveCfg = Debug|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.Debug|x64.Build.0 = Debug|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.Debug|x86.ActiveCfg = Debug|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.Debug|x86.Build.0 = Debug|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.Release|x64.ActiveCfg = Release|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.Release|x64.Build.0 = Release|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.Release|Any CPU.Build.0 = Release|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.Release|x86.ActiveCfg = Release|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.Release|x86.Build.0 = Release|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{6F22DB96-6EAB-4034-99D9-287021C36F01}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.Debug|x64.ActiveCfg = Debug|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.Debug|x64.Build.0 = Debug|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.Debug|x86.ActiveCfg = Debug|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.Debug|x86.Build.0 = Debug|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.Release|x64.ActiveCfg = Release|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.Release|x64.Build.0 = Release|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.Release|Any CPU.Build.0 = Release|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.Release|x86.ActiveCfg = Release|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.Release|x86.Build.0 = Release|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{A5C33956-A41F-49B3-A41D-1082CBA59D02}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.Debug|x64.ActiveCfg = Debug|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.Debug|x64.Build.0 = Debug|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.Debug|x86.ActiveCfg = Debug|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.Debug|x86.Build.0 = Debug|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.Release|x64.ActiveCfg = Release|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.Release|x64.Build.0 = Release|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.Release|Any CPU.Build.0 = Release|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.Release|x86.ActiveCfg = Release|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.Release|x86.Build.0 = Release|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.Debug|x64.ActiveCfg = Debug|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.Debug|x64.Build.0 = Debug|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.Debug|x86.ActiveCfg = Debug|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.Debug|x86.Build.0 = Debug|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.Release|x64.ActiveCfg = Release|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.Release|x64.Build.0 = Release|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.Release|Any CPU.Build.0 = Release|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.Release|x86.ActiveCfg = Release|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.Release|x86.Build.0 = Release|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.Debug|x64.ActiveCfg = Debug|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.Debug|x64.Build.0 = Debug|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.Debug|x86.ActiveCfg = Debug|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.Debug|x86.Build.0 = Debug|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.Release|x64.ActiveCfg = Release|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.Release|x64.Build.0 = Release|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.Release|Any CPU.Build.0 = Release|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.Release|x86.ActiveCfg = Release|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.Release|x86.Build.0 = Release|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{B945A183-2174-4ACB-B289-8A5C546656FE}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.Debug|x64.ActiveCfg = Debug|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.Debug|x64.Build.0 = Debug|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.Debug|x86.ActiveCfg = Debug|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.Debug|x86.Build.0 = Debug|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.Release|x64.ActiveCfg = Release|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.Release|x64.Build.0 = Release|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.Release|Any CPU.Build.0 = Release|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.Release|x86.ActiveCfg = Release|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.Release|x86.Build.0 = Release|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{9F6D7DE8-185B-4C1D-B809-3314D092DF28}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.Debug|x64.ActiveCfg = Debug|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.Debug|x64.Build.0 = Debug|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.Debug|x86.ActiveCfg = Debug|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.Debug|x86.Build.0 = Debug|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.Release|x64.ActiveCfg = Release|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.Release|x64.Build.0 = Release|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.Release|Any CPU.Build.0 = Release|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.Release|x86.ActiveCfg = Release|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.Release|x86.Build.0 = Release|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.Debug|x64.ActiveCfg = Debug|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.Debug|x64.Build.0 = Debug|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.Debug|Any CPU.Build.0 = Debug|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.Debug|x86.ActiveCfg = Debug|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.Debug|x86.Build.0 = Debug|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.MinSizeRel|Any CPU.Build.0 = MinSizeRel|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.MinSizeRel|x86.Build.0 = MinSizeRel|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.Release|x64.ActiveCfg = Release|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.Release|x64.Build.0 = Release|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.Release|Any CPU.ActiveCfg = Release|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.Release|Any CPU.Build.0 = Release|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.Release|x86.ActiveCfg = Release|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.Release|x86.Build.0 = Release|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.RelWithDebInfo|Any CPU.Build.0 = RelWithDebInfo|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Any CPU
{39AEA075-6457-46C0-8821-1158BE6EFA57}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.Debug|x64.ActiveCfg = Debug|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.Debug|x64.Build.0 = Debug|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.Debug|x86.ActiveCfg = Debug|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.Debug|x86.Build.0 = Debug|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.MinSizeRel|x86.ActiveCfg = Debug|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.MinSizeRel|x86.Build.0 = Debug|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.Release|x64.ActiveCfg = Release|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.Release|x64.Build.0 = Release|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.Release|Any CPU.Build.0 = Release|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.Release|x86.ActiveCfg = Release|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.Release|x86.Build.0 = Release|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.RelWithDebInfo|Any CPU.ActiveCfg = Debug|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.RelWithDebInfo|Any CPU.Build.0 = Debug|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.RelWithDebInfo|x86.ActiveCfg = Debug|Any CPU
{F3DC52D7-8C59-4EC0-86D9-0E5732EAFCF7}.RelWithDebInfo|x86.Build.0 = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.Debug|x64.ActiveCfg = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.Debug|x64.Build.0 = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.Debug|x86.ActiveCfg = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.Debug|x86.Build.0 = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.MinSizeRel|x86.ActiveCfg = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.MinSizeRel|x86.Build.0 = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.Release|x64.ActiveCfg = Release|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.Release|x64.Build.0 = Release|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.Release|Any CPU.Build.0 = Release|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.Release|x86.ActiveCfg = Release|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.Release|x86.Build.0 = Release|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.RelWithDebInfo|Any CPU.ActiveCfg = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.RelWithDebInfo|Any CPU.Build.0 = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.RelWithDebInfo|x86.ActiveCfg = Debug|Any CPU
{43FB297B-7A4D-4835-A878-E6DF345B580C}.RelWithDebInfo|x86.Build.0 = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.Debug|x64.ActiveCfg = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.Debug|x64.Build.0 = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.Debug|x86.ActiveCfg = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.Debug|x86.Build.0 = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.MinSizeRel|x86.ActiveCfg = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.MinSizeRel|x86.Build.0 = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.Release|x64.ActiveCfg = Release|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.Release|x64.Build.0 = Release|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.Release|Any CPU.Build.0 = Release|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.Release|x86.ActiveCfg = Release|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.Release|x86.Build.0 = Release|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.RelWithDebInfo|Any CPU.ActiveCfg = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.RelWithDebInfo|Any CPU.Build.0 = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.RelWithDebInfo|x86.ActiveCfg = Debug|Any CPU
{BC277499-8215-4F9F-B9AB-07B6391110BF}.RelWithDebInfo|x86.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{C09ED521-D2DF-40BC-A76F-EB3CB870B2F6} = {267F81EF-A8AB-49FD-9F56-D7EC3C1F7C7C}
{EF26A475-6101-4C9C-A717-D60BB92A2302} = {C09ED521-D2DF-40BC-A76F-EB3CB870B2F6}
{911B08A3-515A-441D-84C8-8A43740B5FC1} = {C09ED521-D2DF-40BC-A76F-EB3CB870B2F6}
{14140310-2233-430A-821B-F3058A25234B} = {C09ED521-D2DF-40BC-A76F-EB3CB870B2F6}
{43146EA8-6FCC-46B8-88B0-42F9BB5E6E0A} = {C09ED521-D2DF-40BC-A76F-EB3CB870B2F6}
{6F22DB96-6EAB-4034-99D9-287021C36F01} = {C09ED521-D2DF-40BC-A76F-EB3CB870B2F6}
{A5C33956-A41F-49B3-A41D-1082CBA59D02} = {C09ED521-D2DF-40BC-A76F-EB3CB870B2F6}
{2FE745C3-1EDF-4421-8CD7-A63EE0C1AE43} = {C09ED521-D2DF-40BC-A76F-EB3CB870B2F6}
{FDA791E0-2B91-4AD5-B91D-CF920A4C4E38} = {C09ED521-D2DF-40BC-A76F-EB3CB870B2F6}
{B945A183-2174-4ACB-B289-8A5C546656FE} = {C09ED521-D2DF-40BC-A76F-EB3CB870B2F6}
{9F6D7DE8-185B-4C1D-B809-3314D092DF28} = {C09ED521-D2DF-40BC-A76F-EB3CB870B2F6}
{6BD3F6D8-B6FC-44E8-B8FE-06352F638B9B} = {C09ED521-D2DF-40BC-A76F-EB3CB870B2F6}
{39AEA075-6457-46C0-8821-1158BE6EFA57} = {C09ED521-D2DF-40BC-A76F-EB3CB870B2F6}
{385C4948-E080-56A6-E29E-8B0F4913175C} = {267F81EF-A8AB-49FD-9F56-D7EC3C1F7C7C}
{43FB297B-7A4D-4835-A878-E6DF345B580C} = {385C4948-E080-56A6-E29E-8B0F4913175C}
{BC277499-8215-4F9F-B9AB-07B6391110BF} = {385C4948-E080-56A6-E29E-8B0F4913175C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {422D1620-0166-4C26-9A81-CA8A2EB1AB58}
EndGlobalSection
-7
View File
@@ -1,7 +0,0 @@
include_guard(GLOBAL)
macro(export_to_parent)
foreach(var IN ITEMS ${ARGN})
set(${var} ${${var}} PARENT_SCOPE)
endforeach()
endmacro()
-48
View File
@@ -1,48 +0,0 @@
include_guard(GLOBAL)
function(get_version_from_git)
find_package(Git QUIET)
if(NOT Git_FOUND)
message(WARNING "Git not found")
return()
endif()
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags --always
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_TAG
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE GIT_RESULT
)
if(NOT GIT_RESULT EQUAL 0)
message(WARNING "Failed to get git tag")
return()
endif()
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-parse --short=7 HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT_SHORT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
set(PROJECT_VERSION_BUILD_METADATA ${GIT_COMMIT_SHORT_HASH})
set(PROJECT_VERSION_BUILD_METADATA ${GIT_COMMIT_SHORT_HASH} PARENT_SCOPE)
string(REGEX REPLACE "^v" "" CLEAN_TAG "${GIT_TAG}")
if(CLEAN_TAG MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(-.*)?$")
set(PROJECT_VERSION_MAJOR ${CMAKE_MATCH_1})
set(PROJECT_VERSION_MAJOR ${CMAKE_MATCH_1} PARENT_SCOPE)
set(PROJECT_VERSION_MINOR ${CMAKE_MATCH_2})
set(PROJECT_VERSION_MINOR ${CMAKE_MATCH_2} PARENT_SCOPE)
set(PROJECT_VERSION_PATCH ${CMAKE_MATCH_3})
set(PROJECT_VERSION_PATCH ${CMAKE_MATCH_3} PARENT_SCOPE)
set(PROJECT_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
set(PROJECT_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}" PARENT_SCOPE)
set(PROJECT_VERSION_FULL "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}+${GIT_COMMIT_SHORT_HASH}")
set(PROJECT_VERSION_FULL "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}+${GIT_COMMIT_SHORT_HASH}" PARENT_SCOPE)
else()
message(WARNING "Tag '${CLEAN_TAG}' does not match semver format")
endif()
endfunction()
-142
View File
@@ -1,142 +0,0 @@
include_guard(DIRECTORY)
include(${CMAKE_SOURCE_DIR}/cmake/ExportToParent.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/InstallBasic.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/ProtobufGenerateCpp.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/SetFirstDefined.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/safe_dep_glob.cmake)
function(init_library)
set(_options SHARED STATIC)
set(_one_value_args
NAME
SOURCE_DIR
INCLUDE_DIR
)
set(_multi_value_args)
cmake_parse_arguments(_ARGS "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
if (_ARGS_SHARED AND _ARGS_STATIC)
message(FATAL_ERROR "Invalid args passed to init_library: cannot specify STATIC and SHARED")
endif()
set_first_defined(_name _ARGS_NAME PROJECT_NAME)
set_first_defined(_source_dir _ARGS_SOURCE_DIR _name)
set_first_defined(_include_dir _ARGS_INCLUDE_DIR _source_dir)
# Cpp sources
file(
GLOB_RECURSE ${_name}_SOURCES
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
${_source_dir}/*.cpp
)
# Note: cpp files inside 'tests' dir(s) are considered tests.
# Remove tests from main sources, and add them to test sources
foreach(item ${${_name}_SOURCES})
if(${item} MATCHES "tests/.*\.cpp$")
list(APPEND ${_name}_TEST_SOURCES ${item})
endif()
endforeach()
foreach(item ${${_name}_TEST_SOURCES})
list(REMOVE_ITEM ${_name}_SOURCES ${item})
endforeach()
# Proto sources
file(
GLOB_RECURSE ${_name}_PROTO_SOURCES
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
${_source_dir}/protobufs/*.proto
)
update_deps_file("${${_name}_PROTO_SOURCES};")
protobuf_generate_cpp(
CXX_SOURCES ${_name}_CXX_PROTO_SOURCES
CXX_HEADERS ${_name}_CXX_PROTO_HEADERS
CXX_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}
PROTO_INCLUDE_DIRS
${EXTERNALS_INCLUDE}
${CMAKE_CURRENT_SOURCE_DIR}
PROTO_SOURCES
${${_name}_PROTO_SOURCES}
)
export_to_parent(
${_name}_SOURCES
${_name}_TEST_SOURCES
${_name}_PROTO_SOURCES
${_name}_CXX_PROTO_SOURCES
${_name}_CXX_PROTO_HEADERS
)
# Add main lib
if (_ARGS_STATIC)
add_library(${_name} STATIC ${${_name}_SOURCES} ${${_name}_CXX_PROTO_SOURCES})
elseif(_ARGS_SHARED)
add_library(${_name} SHARED ${${_name}_SOURCES} ${${_name}_CXX_PROTO_SOURCES})
else()
add_library(${_name} ${${_name}_SOURCES} ${${_name}_CXX_PROTO_SOURCES})
endif()
target_include_directories(
${_name}
SYSTEM
BEFORE
PUBLIC
$<BUILD_INTERFACE:${EXTERNALS_ROOT}/include>
$<BUILD_INTERFACE:${EXTERNALS_ROOT}/include/zlib>
)
target_include_directories(
${_name}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
# Include protos (if any)
if (${_name}_PROTO_SOURCES)
target_include_directories(
${_name}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
)
endif()
target_link_directories(
${_name}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
$<BUILD_INTERFACE:${EXTERNALS_ROOT}/lib/$<CONFIG>>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_LIBDIR}>
)
# Install main lib
foreach(_hdr ${${_name}_CXX_PROTO_HEADERS})
file(RELATIVE_PATH _relative_path ${CMAKE_CURRENT_BINARY_DIR} ${_hdr})
install(FILES ${_hdr} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${_relative_path})
endforeach()
install_basic(
NAME ${_name}
INCLUDE_DIR ${_include_dir}
)
# Add tests executable (if there are any)
if (${_name}_TEST_SOURCES AND NOT WIN32)
add_executable(${_name}-tests ${${_name}_TEST_SOURCES})
get_target_property(_lib_type ${_name} TYPE)
if (_lib_type STREQUAL "SHARED_LIBRARY")
# Set RPATH so the tests exe knows where to find the shared lib.
set_target_properties(
${_name}-tests
PROPERTIES
BUILD_RPATH "$ORIGIN"
INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}"
)
endif()
# Link main lib
target_link_directories(
${_name}-tests
PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_LIBDIR}>
)
target_link_libraries(${_name}-tests PRIVATE ${_name})
# Catch2
find_package(Catch2 CONFIG REQUIRED COMPONENTS Catch2WithMain)
target_link_libraries(${_name}-tests PRIVATE Catch2::Catch2WithMain)
endif()
endfunction()
-71
View File
@@ -1,71 +0,0 @@
include_guard(DIRECTORY)
include(GNUInstallDirs)
include(${CMAKE_SOURCE_DIR}/cmake/ExportToParent.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/SetFirstDefined.cmake)
function(init_python_module)
set(_options)
set(_one_value_args
NAME
)
set(_multi_value_args
SOURCES
)
cmake_parse_arguments(_ARGS "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
set_first_defined(_name _ARGS_NAME PROJECT_NAME)
set_first_defined(_sources _ARGS_SOURCES ${_name}_SOURCES)
set(module_proj ${_name}_module)
set(${module_proj}_SOURCES ${_sources})
pybind11_add_module(${module_proj} SHARED ${_sources})
target_link_libraries(
${module_proj}
PUBLIC
pybind11::embed
spark
${_name}
)
target_include_directories(
${module_proj}
PRIVATE
$<BUILD_INTERFACE:${pybind11_INCLUDE_DIRS}>
)
target_include_directories(
${module_proj}
PUBLIC
${Python3_INCLUDE_DIRS}
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/stubs/${_name}.pyi
DEPENDS ${_name} ${module_proj}
COMMAND PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR} pybind11-stubgen --numpy-array-use-type-var --ignore-invalid-expressions '.*' ${_name}_module
COMMENT "Generating py stubs"
)
add_custom_target(
"${_name}_py_stubs"
ALL
DEPENDS
${CMAKE_CURRENT_BINARY_DIR}/stubs/${_name}.pyi
)
install(
TARGETS ${module_proj}
EXPORT ${module_proj}Targets
RUNTIME
DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY
DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE
DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
foreach(dir ${pybind11_INCLUDE_DIRS})
install(DIRECTORY ${dir} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
endforeach()
install(
EXPORT ${module_proj}Targets
FILE ${module_proj}Targets.cmake
NAMESPACE ${_name}::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${_name}
)
endfunction()
-65
View File
@@ -1,65 +0,0 @@
include_guard(DIRECTORY)
include(GNUInstallDirs)
function(init_python_plugin)
set(_options)
set(_one_value_args NAME PLUGIN_NAME)
set(_multi_value_args SOURCES)
cmake_parse_arguments(_ARGS "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
set_first_defined(_name _ARGS_NAME PROJECT_NAME)
set(_plugin_name ${_ARGS_PLUGIN_NAME})
if (NOT DEFINED _ARGS_PLUGIN_NAME)
set(_plugin_name ${_name}_plugins)
endif()
set(${_plugin_name}_SOURCES ${_ARGS_SOURCES})
if (NOT DEFINED _ARGS_SOURCES)
file(
GLOB_RECURSE ${_plugin_name}_SOURCES
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
${_plugin_name}/*.py)
endif()
set(src_outs)
foreach(_src ${${_plugin_name}_SOURCES})
set(_src_in ${CMAKE_CURRENT_SOURCE_DIR}/${_src})
set(_src_out ${CMAKE_CURRENT_BINARY_DIR}/${_src})
add_custom_command(
OUTPUT ${_src_out}
COMMAND ${CMAKE_COMMAND} -E copy ${_src_in} ${_src_out}
DEPENDS ${_src_in}
COMMENT "Copying ${_plugin_name} plugin ${_src} to ${_src_out}"
)
list(APPEND src_outs ${_src_out})
endforeach()
add_custom_target(copy_${_plugin_name} ALL DEPENDS ${src_outs})
add_library(${_plugin_name} INTERFACE)
add_library(${_name}::${_plugin_name} ALIAS ${_plugin_name})
set_target_properties(
${_plugin_name}
PROPERTIES
INTERFACE_PYTHON_SCRIPTS_DIR
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/${_plugin_name}>$<INSTALL_INTERFACE:${CMAKE_INSTALL_BINDIR}/${_plugin_name}>
)
set_target_properties(
${_plugin_name}
PROPERTIES
INTERFACE_PYTHON_SCRIPTS $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/${${_plugin_name}_SOURCES}>$<INSTALL_INTERFACE:${CMAKE_INSTALL_BINDIR}/${${_plugin_name}_SOURCES}>
)
install(
TARGETS ${_plugin_name}
EXPORT ${_plugin_name}Targets
DESTINATION ${CMAKE_INSTALL_BINDIR}
)
install(
EXPORT ${_plugin_name}Targets
FILE ${_plugin_name}Targets.cmake
NAMESPACE ${_name}::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${_name}
)
install(DIRECTORY ${_plugin_name} DESTINATION ${CMAKE_INSTALL_BINDIR})
endfunction()
-39
View File
@@ -1,39 +0,0 @@
include_guard(DIRECTORY)
include(GNUInstallDirs)
include(${CMAKE_SOURCE_DIR}/cmake/PackBasic.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/SetFirstDefined.cmake)
function(install_basic)
set(_options)
set(_one_value_args NAME INCLUDE_DIR)
set(_multi_value_args)
cmake_parse_arguments(_ARGS "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
set_first_defined(_name _ARGS_NAME PROJECT_NAME)
set_first_defined(_include_dir _ARGS_INCLUDE_DIR _name)
file(
GLOB_RECURSE ${_name}_HEADERS
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
${_include_dir}/*.h)
target_sources(${_name}
PUBLIC
FILE_SET HEADERS FILES ${${_name}_HEADERS})
install(
TARGETS ${_name}
EXPORT ${_name}Targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
FILE_SET HEADERS DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
EXPORT ${_name}Targets
FILE ${_name}Targets.cmake
NAMESPACE ${_name}::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${_name})
pack_basic()
endfunction()
-44
View File
@@ -1,44 +0,0 @@
include_guard(DIRECTORY)
include(CMakePackageConfigHelpers)
include(${CMAKE_SOURCE_DIR}/cmake/SetFirstDefined.cmake)
function(pack_basic)
set(_options)
set(_one_value_args NAME)
set(_multi_value_args)
cmake_parse_arguments(_ARGS "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
set_first_defined(_name _ARGS_NAME PROJECT_NAME)
find_package(Git QUIET)
if(GIT_FOUND)
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags --always --dirty
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE PROJECT_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
if(NOT GIT_FOUND OR PROJECT_VERSION STREQUAL "")
set(PROJECT_VERSION "0.0.0")
endif()
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/${_name}ConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/${_name}Config.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${_name}
)
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/${_name}Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${_name}ConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${_name})
endfunction()
+145
View File
@@ -0,0 +1,145 @@
set(Protobuf_PROTOC_EXECUTABLE "${SPARK_BIN}/protoc")
set(PROTOBUF_INCLUDE_DIRS "${SPARK_INCLUDE}")
set(PROTOBUF_STATIC_LIB "libprotobuf")
function(Protobuf_Generate_Cpp SRCS HDRS)
set(${SRCS})
set(${HDRS})
foreach(FIL ${ARGN})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(FIL_WE ${FIL} NAME_WE)
get_filename_component(FIL_DIR ${FIL} DIRECTORY)
if(FIL_DIR)
set(FIL_WE "${FIL_DIR}/${FIL_WE}")
endif()
list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc")
list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
COMMAND
${Protobuf_PROTOC_EXECUTABLE} ARGS --cpp_out=${CMAKE_BINARY_DIR}/src -I
${PROTOBUF_INCLUDE_DIRS} -I ${CMAKE_SOURCE_DIR}/src ${ABS_FIL}
DEPENDS ${ABS_FIL}
COMMENT "Running C++ protocol buffer compiler on ${FIL}"
VERBATIM)
endforeach()
set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
# remove some warnings from protobuf generated files
if(WIN32)
set_source_files_properties(${${SRCS}} PROPERTIES COMPILE_FLAGS
"/wd4309 /wd4838")
else()
set_source_files_properties(
${${SRCS}}
PROPERTIES
COMPILE_FLAGS
"-Wno-unused-parameter -Wno-effc++ -Wno-pedantic -Wno-sign-compare -Wno-uninitialized"
)
endif()
set(${SRCS}
${${SRCS}}
PARENT_SCOPE)
set(${HDRS}
${${HDRS}}
PARENT_SCOPE)
endfunction()
function(Service_Compiler_Generate_Cpp SRCS HDRS)
set(${SRCS})
set(${HDRS})
foreach(FIL ${ARGN})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(FIL_WE ${FIL} NAME_WE)
get_filename_component(FIL_DIR ${FIL} DIRECTORY)
if(FIL_DIR)
set(FIL_WE "${FIL_DIR}/${FIL_WE}")
endif()
list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc")
list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.client.pb.cc")
list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.client.pb.h")
list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.server.pb.cc")
list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.server.pb.h")
set(TEMPLATES
${CMAKE_CURRENT_SOURCE_DIR}/api/service_compiler/templates/cpp/client.pb.cc
${CMAKE_CURRENT_SOURCE_DIR}/api/service_compiler/templates/cpp/client.pb.h
${CMAKE_CURRENT_SOURCE_DIR}/api/service_compiler/templates/cpp/server.pb.cc
${CMAKE_CURRENT_SOURCE_DIR}/api/service_compiler/templates/cpp/server.pb.h
)
if(WIN32)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.client.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.client.pb.h"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.server.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.server.pb.h"
COMMAND SET PYTHONPATH=${SPARK_PYTHON}
COMMAND ${CMAKE_SOURCE_DIR}/.venv/Scripts/activate.bat
COMMAND
${Protobuf_PROTOC_EXECUTABLE} ARGS --cpp_out=${CMAKE_BINARY_DIR}/src
--plugin=protoc-gen-service=${CMAKE_SOURCE_DIR}/src/lib/api/service_compiler/plugin.cmd
--service_out=lang=cpp:${CMAKE_BINARY_DIR}/src -I
${PROTOBUF_INCLUDE_DIRS} -I ${CMAKE_SOURCE_DIR}/src ${ABS_FIL}
DEPENDS ${ABS_FIL} ${TEMPLATES}
${CMAKE_CURRENT_SOURCE_DIR}/api/service_compiler/plugin.py
COMMENT "Running C++ service compiler on ${FIL}"
VERBATIM)
else()
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.client.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.client.pb.h"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.server.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.server.pb.h"
COMMAND ${CMAKE_SOURCE_DIR}/tools/venv_exec.sh
ARGS
${Protobuf_PROTOC_EXECUTABLE}
--cpp_out=${CMAKE_BINARY_DIR}/src
--plugin=protoc-gen-service=${CMAKE_SOURCE_DIR}/src/lib/api/service_compiler/plugin.py
--service_out=lang=cpp,make_file_name=${ABS_FIL}:${CMAKE_BINARY_DIR}/src
-I ${PROTOBUF_INCLUDE_DIRS} -I ${CMAKE_SOURCE_DIR}/src ${ABS_FIL}
DEPENDS ${ABS_FIL} ${TEMPLATES}
${CMAKE_CURRENT_SOURCE_DIR}/api/service_compiler/plugin.py
COMMENT "Running C++ service compiler on ${FIL}"
VERBATIM)
endif()
endforeach()
# remove some warnings from protobuf generated files
if(WIN32)
set_source_files_properties(${${SRCS}} PROPERTIES COMPILE_FLAGS
"/wd4309 /wd4838")
else()
set_source_files_properties(
${${SRCS}}
PROPERTIES
COMPILE_FLAGS
"-Wno-unused-parameter -Wno-effc++ -Wno-pedantic -Wno-sign-compare -Wno-uninitialized"
)
endif()
set(${SRCS}
${${SRCS}}
PARENT_SCOPE)
set(${HDRS}
${${HDRS}}
PARENT_SCOPE)
endfunction()
-83
View File
@@ -1,83 +0,0 @@
include_guard(GLOBAL)
function(protobuf_generate_cpp)
set(_options)
set(_one_value_args
CXX_SOURCES
CXX_HEADERS
CXX_OUT_DIR
PROTOC
)
set(_multi_value_args
PROTO_INCLUDE_DIRS
PROTO_SOURCES
)
cmake_parse_arguments(_ARGS "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
if (NOT DEFINED _ARGS_PROTOC)
if (WIN32)
set(_ARGS_PROTOC "${EXTERNALS_BIN}/protoc.exe")
else()
set(_ARGS_PROTOC "${EXTERNALS_BIN}/protoc")
endif()
endif()
set(${_ARGS_CXX_SOURCES})
set(${_ARGS_CXX_HEADERS})
set(_proto_include_cli_args)
foreach(_dir ${_ARGS_PROTO_INCLUDE_DIRS})
list(APPEND _proto_include_cli_args -I ${_dir})
endforeach()
foreach(_fil ${_ARGS_PROTO_SOURCES})
get_filename_component(_abs_fil ${_fil} ABSOLUTE)
get_filename_component(_fil_we ${_fil} NAME_WE)
get_filename_component(_fil_dir ${_fil} DIRECTORY)
if(_fil_dir)
set(_fil_we "${_fil_dir}/${_fil_we}")
endif()
list(APPEND ${_ARGS_CXX_SOURCES} "${_ARGS_CXX_OUT_DIR}/${_fil_we}.pb.cc")
list(APPEND ${_ARGS_CXX_HEADERS} "${_ARGS_CXX_OUT_DIR}/${_fil_we}.pb.h")
message(STATUS "add_custom_command for ${_fil} -> ${_ARGS_CXX_OUT_DIR}/${_fil_we}.pb.h")
# TODO: Pass proto sources by relative path (so this fn can be called from
# arbitrary subdirs).
add_custom_command(
OUTPUT
"${_ARGS_CXX_OUT_DIR}/${_fil_we}.pb.cc"
"${_ARGS_CXX_OUT_DIR}/${_fil_we}.pb.h"
COMMAND
${_ARGS_PROTOC}
ARGS
--cpp_out=${_ARGS_CXX_OUT_DIR} ${_proto_include_cli_args} ${_abs_fil}
DEPENDS ${_abs_fil}
COMMENT "Running C++ protocol buffer compiler on ${_fil}"
VERBATIM
)
endforeach()
set_source_files_properties(
${${_ARGS_CXX_SOURCES}}
${${_ARGS_CXX_HEADERS}}
PROPERTIES
GENERATED TRUE
)
# remove some warnings from protobuf generated files
if(WIN32)
set_source_files_properties(
${${_ARGS_CXX_SOURCES}}
PROPERTIES
COMPILE_FLAGS "/wd4309 /wd4838"
)
else()
set_source_files_properties(
${${_ARGS_CXX_SOURCES}}
PROPERTIES
COMPILE_FLAGS "-Wno-unused-parameter -Wno-effc++ -Wno-pedantic -Wno-sign-compare -Wno-uninitialized"
)
endif()
set(${_ARGS_CXX_SOURCES} ${${_ARGS_CXX_SOURCES}} PARENT_SCOPE)
set(${_ARGS_CXX_HEADERS} ${${_ARGS_CXX_HEADERS}} PARENT_SCOPE)
endfunction()
-61
View File
@@ -1,61 +0,0 @@
include_guard(GLOBAL)
function(protobuf_generate_cpp_config)
set(_options)
set(_one_value_args
PROTO_SOURCES_HEADER
PROTO_DEFAULTS_HEADER
)
set(_multi_value_args
PROTO_SOURCES
PROTO_DEFAULTS
)
cmake_parse_arguments(_ARGS "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
# Configure the 'config_proto_files' header. It provides an array of strings populated with the
# files in PROTO_SOURCES. At runtime, we use this array to generate a special 'config' proto
# message with fields for each message defined in said files. A global instance of this 'config'
# proto is then constructed, and populated with [compile-time] defaults, and [runtime] overrides
# (i.e., in spark.conf). Calls to `bts::config::get<T>()` retrieve the value from the field
# associated with type `T` in this global instance.
message(STATUS "PROTO_SOURCES: ${_ARGS_PROTO_SOURCES}")
message(STATUS "PROTO_SOURCES_HEADER: ${_ARGS_PROTO_SOURCES_HEADER}")
message(STATUS "PROTO_DEFAULTS_HEADER: ${_ARGS_PROTO_DEFAULTS_HEADER}")
if (_ARGS_PROTO_SOURCES_HEADER)
set(PROTO_SOURCES)
set(PROTO_SOURCES_CXX_ARRAY_ITEMS "")
foreach(_proto_path ${_ARGS_PROTO_SOURCES})
list(APPEND PROTO_SOURCES ${_proto_path})
string(APPEND PROTO_SOURCES_CXX_ARRAY_ITEMS "\"${_proto_path}\",\n")
endforeach()
list(LENGTH PROTO_SOURCES PROTO_SOURCES_LENGTH)
message(STATUS "CONFIGURING PROTO_SOURCES_HEADER): ${_ARGS_PROTO_SOURCES_HEADER}")
configure_file(${CMAKE_SOURCE_DIR}/cmake/config_proto_files.h.in ${_ARGS_PROTO_SOURCES_HEADER})
endif()
# Generate static defaults. Ideally, this would be a single string, but we use an array because
# the compiler complains if the string is longer than 65k.
set(_cfg_defaults_str "inline const char * config_static_defaults[] = { ")
foreach(_cfg_file_path ${_ARGS_PROTO_DEFAULTS})
file(READ ${_cfg_file_path} _cfg_file_content)
string(REPLACE "\"" "\\\"" _cfg_file_content_escaped ${_cfg_file_content})
string(REPLACE "\n" ";" _cfg_lines ${_cfg_file_content_escaped})
foreach(_line ${_cfg_lines})
string(APPEND _cfg_defaults_str "\n \"${_line}\",")
endforeach(_line)
endforeach(_cfg_file_path)
string(APPEND _cfg_defaults_str "};")
set(_old_cfg_defaults_str "")
if(EXISTS ${_ARGS_PROTO_DEFAULTS_HEADER})
file(READ ${_ARGS_PROTO_DEFAULTS_HEADER} _old_cfg_defaults_str)
endif()
if(NOT _cfg_defaults_str STREQUAL _old_cfg_defaults_str)
file(WRITE "${_ARGS_PROTO_DEFAULTS_HEADER}" "${_cfg_defaults_str}")
endif()
endfunction()
-49
View File
@@ -1,49 +0,0 @@
include_guard(DIRECTORY)
function(protobuf_generate_fs)
set(_options)
set(_one_value_args TARGET_NAME OUT_DIR PROTOC)
set(_multi_value_args PROTO_INCLUDE_DIRS PROTO_SOURCES)
cmake_parse_arguments(_ARGS "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
if (NOT DEFINED _ARGS_TARGET_NAME)
set(_ARGS_TARGET_NAME "${PROJECT_NAME}_generate_fs_protos")
endif()
if (NOT DEFINED _ARGS_PROTOC)
set(_ARGS_PROTOC "${EXTERNALS_BIN}/protoc")
endif()
set(_proto_include_cli_args)
foreach(_dir ${_ARGS_PROTO_INCLUDE_DIRS})
list(APPEND _proto_include_cli_args -I ${_dir})
endforeach()
set(_outputs)
foreach(_proto_source ${_ARGS_PROTO_SOURCES})
# get_filename_component(_abs_proto_source ${_proto_source} ABSOLUTE)
get_filename_component(_proto_source_we ${_proto_source} NAME_WE)
# get_filename_component(_proto_source_dir ${_proto_source} DIRECTORY)
list(APPEND _outputs ${_ARGS_OUT_DIR}/${_proto_source_we}.fable.fs)
endforeach()
set(_venv_exec ${CMAKE_SOURCE_DIR}/tools/venv_exec.sh)
set(_plugin_py ${CMAKE_SOURCE_DIR}/src/lib_spark/spark/api/service_compiler/plugin.py)
set(_template_fs ${CMAKE_SOURCE_DIR}/src/lib_spark/spark/api/service_compiler/templates/fs/fable.fs)
add_custom_command(
OUTPUT ${_outputs}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${_venv_exec}
${_ARGS_PROTOC}
--plugin=protoc-gen-service=${_plugin_py}
--service_out=lang=fs,strip_out_path=1:${_ARGS_OUT_DIR}
${_proto_include_cli_args}
${_ARGS_PROTO_SOURCES}
DEPENDS
${_venv_exec}
${_plugin_py}
${_template_fs}
${CMAKE_CURRENT_SOURCE_DIR}/package-lock.json
${_ARGS_PROTO_SOURCES}
)
add_custom_target(${_ARGS_TARGET_NAME} ALL DEPENDS "${_outputs}")
endfunction()
-33
View File
@@ -1,33 +0,0 @@
include_guard(DIRECTORY)
function(protobuf_generate_js)
set(_options)
set(_one_value_args TARGET_NAME OUTPUT)
set(_multi_value_args PROTO_INCLUDE_DIRS PROTO_SOURCES)
cmake_parse_arguments(_ARGS "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
if (NOT DEFINED _ARGS_TARGET_NAME)
set(_ARGS_TARGET_NAME "${PROJECT_NAME}_generate_js_protos")
endif()
set(_proto_include_cli_args)
foreach(_dir ${_ARGS_PROTO_INCLUDE_DIRS})
list(APPEND _proto_include_cli_args -p ${_dir})
endforeach()
add_custom_command(
OUTPUT ${_ARGS_OUTPUT}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND npx
--no-install pbjs
-t json-module
-w commonjs
-o ${_ARGS_OUTPUT}
${_proto_include_cli_args}
${_ARGS_PROTO_SOURCES}
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/package-lock.json
${_ARGS_PROTO_SOURCES}
)
add_custom_target(${_ARGS_TARGET_NAME} ALL DEPENDS ${_ARGS_OUTPUT})
endfunction()
-10
View File
@@ -1,10 +0,0 @@
include_guard(GLOBAL)
macro(set_first_defined RESULT)
foreach(_arg ${ARGN})
if (DEFINED ${_arg})
set(${RESULT} ${${_arg}})
break()
endif()
endforeach()
endmacro()
-49
View File
@@ -1,49 +0,0 @@
include_guard(DIRECTORY)
include(${CMAKE_SOURCE_DIR}/cmake/TernaryOperator.cmake)
function(sym_link_dir)
set(_options)
set(_one_value_args TARGET_NAME SOURCE DEST COMMENT)
set(_multi_value_args)
cmake_parse_arguments(_ARGS "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
add_custom_command(
OUTPUT ${_ARGS_DEST}
COMMAND ln ARGS -sf ${_ARGS_SOURCE} ${_ARGS_DEST}
)
set_ternary(_comment _ARGS_COMMENT "${_ARGS_COMMENT}" "linking dir ${_ARGS_SOURCE} -> ${_ARGS_DEST}")
add_custom_target(
${_ARGS_TARGET_NAME} ALL
DEPENDS ${_ARGS_DEST}
COMMENT "${_comment}"
)
endfunction()
function(sym_link_file)
set(_options)
set(_one_value_args SOURCE DEST INSTALL_DEST)
set(_multi_value_args)
cmake_parse_arguments(_ARGS "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
file(
CREATE_LINK
${_ARGS_SOURCE}
${_ARGS_DEST}
SYMBOLIC
)
if (DEFINED _ARGS_INSTALL_DEST)
install(
FILES
${_ARGS_SOURCE}
DESTINATION ${_ARGS_INSTALL_DEST}
)
endif()
endfunction()
function(sym_link_local_lib LIB_NAME)
set(_lib_file_name "${CMAKE_SHARED_LIBRARY_PREFIX}${LIB_NAME}.so")
file(
CREATE_LINK
"${CMAKE_BINARY_DIR}/src/lib_${LIB_NAME}/${_lib_file_name}"
"${CMAKE_CURRENT_BINARY_DIR}/${_lib_file_name}"
SYMBOLIC
)
endfunction()
-39
View File
@@ -1,39 +0,0 @@
include_guard(DIRECTORY)
include(${CMAKE_SOURCE_DIR}/cmake/SymLink.cmake)
function(sym_link_python_module)
set(_options)
set(_one_value_args LIB_NAME MODULE_NAME PLUGIN_NAME)
set(_multi_value_args)
cmake_parse_arguments(_ARGS "${_options}" "${_one_value_args}"
"${_multi_value_args}" ${ARGN})
if(NOT DEFINED _ARGS_LIB_NAME)
message(
FATAL_ERROR "LIB_NAME must be specified for sym_link_python_module()")
endif()
set(_lib_name ${_ARGS_LIB_NAME})
set(_module_name ${_ARGS_MODULE_NAME})
if(NOT DEFINED _ARGS_MODULE_NAME)
set(_module_name ${_lib_name}_module)
endif()
set(_plugin_name ${_ARGS_PLUGIN_NAME})
set(_deps ${_lib_name} ${_module_name})
if(DEFINED _ARGS_PLUGIN_NAME)
list(APPEND _deps ${_plugin_name} copy_${_plugin_name})
endif()
add_dependencies(${PROJECT_NAME} ${_deps})
sym_link_local_lib(${_lib_name})
set(_module_suffix cpython-310-x86_64-linux-gnu.so)
sym_link_file(
SOURCE
${CMAKE_BINARY_DIR}/src/lib_${_lib_name}/${_module_name}.${_module_suffix}
DEST
${CMAKE_CURRENT_BINARY_DIR}/${_module_name}.${_module_suffix}
INSTALL_DEST
${CMAKE_INSTALL_BINDIR}/)
if(DEFINED _ARGS_PLUGIN_NAME)
get_target_property(plugins ${_plugin_name} INTERFACE_PYTHON_SCRIPTS_DIR)
sym_link_dir(TARGET_NAME ${PROJECT_NAME}_link_${_plugin_name} SOURCE
${plugins} DEST ${CMAKE_CURRENT_BINARY_DIR}/${_plugin_name})
endif()
endfunction()
-9
View File
@@ -1,9 +0,0 @@
include_guard(GLOBAL)
macro(set_ternary RESULT CONDITION TRUE_VALUE FALSE_VALUE)
if(${CONDITION})
set(${RESULT} ${TRUE_VALUE})
else()
set(${RESULT} ${FALSE_VALUE})
endif()
endmacro()
-11
View File
@@ -1,11 +0,0 @@
#pragma once
#include <array>
namespace bts::@PROJECT_NAME@::protobufs {
inline std::array<const char *, @PROTO_SOURCES_LENGTH@> config_proto_files = {
@PROTO_SOURCES_CXX_ARRAY_ITEMS@
};
} // namespace bts::@PROJECT_NAME@::protobufs
-11
View File
@@ -1,11 +0,0 @@
#ifndef BTS_SPARK_VERSION_H
#define BTS_SPARK_VERSION_H
#define BTS_SPARK_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
#define BTS_SPARK_VERSION_MINOR @PROJECT_VERSION_MINOR@
#define BTS_SPARK_VERSION_PATCH @PROJECT_VERSION_PATCH@
#define BTS_SPARK_VERSION_BUILD_METADATA @PROJECT_VERSION_BUILD_METADATA@
#define BTS_SPARK_VERSION "@PROJECT_VERSION@"
#define BTS_SPARK_VERSION_FULL "@PROJECT_VERSION_FULL@"
#endif
+24
View File
@@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.5)
# Explicitly set policy to convert relative paths to absolute (although this is a default policy,
# setting it explicitly prevents a compile-warning)
cmake_policy(SET CMP0076 NEW)
# add protos to the library to facilitate source_group
target_sources(libspark PUBLIC ${Config_Protos} ${NonConfig_Protos} ${Service_Protos})
function(assign_source_group)
foreach(_source IN ITEMS ${ARGN})
if(IS_ABSOLUTE "${_source}")
file(RELATIVE_PATH _source_rel "${CMAKE_CURRENT_SOURCE_DIR}" "${_source}")
else()
set(_source_rel "${_source}")
endif()
get_filename_component(_source_path "${_source_rel}" PATH)
string(REPLACE "/" "\\" _source_path_msvc "${_source_path}")
source_group("${_source_path_msvc}" FILES "${_source}")
set(SOURCE_FILES "${_source}")
endforeach()
endfunction(assign_source_group)
assign_source_group(${SparkLib_Sources} ${Config_Protos} ${NonConfig_Protos} ${Service_Protos})
-221
View File
@@ -1,221 +0,0 @@
services:
sparkd:
volumes:
- ${SPARKD__DATA_DIR:-sparkd_data}:/home/bts/.local/share/bts/sparkd/data
- ${SPARKD__MD_RECORDING_DIR:-md_recording}:/md_recording
build:
dockerfile: src/app_sparkd/Dockerfile
args:
- IMAGE=${SPARKD__IMAGE}
- SOURCE_DIR=${SPARKD__SOURCE_DIR}
- CONFIG_DIR=${SPARKD__CONFIG_DIR}
- PYTHON_REQUIREMENTS=${SPARKD__PYTHON_REQUIREMENTS}
- SPARKD_ENTRYPOINT=${SPARKD__SPARKD_ENTRYPOINT}
shm_size: "${SPARKD__SHM_SIZE:-512mb}"
env_file:
- .env
- ${SPARKD__CONFIG_DIR}/.env
ports:
- "${SPARKD__CONFIG_PORT}:${SPARKD__CONFIG_PORT}"
- "${SPARKD__QUICKBUS_PORT}:${SPARKD__QUICKBUS_PORT}"
- "${SPARKD__SIM_FIX_PORT}:${SPARKD__SIM_FIX_PORT}"
entrypoint: ${SPARKD__MAIN_ENTRYPOINT}
deploy:
resources:
limits:
memory: "${SPARKD__MEMORY:-4gb}"
sparkd-shell:
volumes:
- ${SPARKD__DATA_DIR:-sparkd_data}:/home/bts/.local/share/bts/sparkd/data
- ${SPARKD__MD_RECORDING_DIR:-md_recording}:/md_recording
build:
dockerfile: docker/images/bluetradingsystems/linux_shell/Dockerfile
args:
- IMAGE=${SPARKD__IMAGE}
- SOURCE_DIR=${SPARKD__SOURCE_DIR}
- CONFIG_DIR=${SPARKD__CONFIG_DIR}
- PYTHON_REQUIREMENTS=${SPARKD__PYTHON_REQUIREMENTS}
- SPARKD_ENTRYPOINT=${SPARKD__SPARKD_ENTRYPOINT}
shm_size: "${SPARKD__SHM_SIZE:-512mb}"
command: "do sleep 1; done"
env_file:
- .env
- ${SPARKD__CONFIG_DIR}/.env
ports:
- "${SPARKD__CONFIG_PORT}:${SPARKD__CONFIG_PORT}"
- "${SPARKD__QUICKBUS_PORT}:${SPARKD__QUICKBUS_PORT}"
- "${SPARKD__SIM_FIX_PORT}:${SPARKD__SIM_FIX_PORT}"
deploy:
resources:
limits:
memory: "${SPARKD__MEMORY:-4gb}"
sparkd-symbols:
volumes:
- ${SPARKD__DATA_DIR:-sparkd_data}:/home/bts/.local/share/bts/sparkd/data
- ${SPARKD__MD_RECORDING_DIR:-md_recording}:/md_recording
- ${SPARKD__RUNTIME_CONF_DIR:-sparkd_conf}:/home/bts/.local/share/bts/sparkd/conf
build:
dockerfile: src/app_sparkd/Dockerfile
args:
- IMAGE=${SPARKD__IMAGE}
- SOURCE_DIR=${SPARKD__SOURCE_DIR}
- CONFIG_DIR=${SPARKD__CONFIG_DIR}
- PYTHON_REQUIREMENTS=${SPARKD__PYTHON_REQUIREMENTS}
- SPARKD_ENTRYPOINT=${SPARKD__SPARKD_ENTRYPOINT}
shm_size: "${SPARKD__SHM_SIZE:-512mb}"
env_file:
- .env
- ${SPARKD__CONFIG_DIR}/.env
ports:
- "${SPARKD__CONFIG_PORT}:${SPARKD__CONFIG_PORT}"
- "${SPARKD__QUICKBUS_PORT}:${SPARKD__QUICKBUS_PORT}"
- "${SPARKD__SIM_FIX_PORT}:${SPARKD__SIM_FIX_PORT}"
entrypoint: ${SPARKD__MAIN_ENTRYPOINT}
deploy:
restart_policy:
condition: any
delay: 3s
resources:
limits:
memory: "${SPARKD__MEMORY:-4gb}"
sparkd-multicast:
volumes:
- ${SPARKD__DATA_DIR:-sparkd_data}:/home/bts/.local/share/bts/sparkd/data
- ${SPARKD__MD_RECORDING_DIR:-md_recording}:/md_recording
- ${SPARKD__RUNTIME_CONF_DIR:-sparkd_conf}:/home/bts/.local/share/bts/sparkd/conf
build:
dockerfile: src/app_sparkd/Dockerfile
args:
- IMAGE=${SPARKD__IMAGE}
- SOURCE_DIR=${SPARKD__SOURCE_DIR}
- CONFIG_DIR=${SPARKD__CONFIG_DIR}
- PYTHON_REQUIREMENTS=${SPARKD__PYTHON_REQUIREMENTS}
- SPARKD_ENTRYPOINT=${SPARKD__SPARKD_ENTRYPOINT}
shm_size: "${SPARKD__SHM_SIZE:-2048mb}"
env_file:
- .env
- ${SPARKD__CONFIG_DIR}/.env
network_mode: "host"
entrypoint: ${SPARKD__MAIN_ENTRYPOINT}
deploy:
restart_policy:
condition: any
delay: 3s
resources:
limits:
memory: "${SPARKD__MEMORY:-4gb}"
sparkd-tail:
image: bluetradingsystems/linux_dotnet8
volumes:
- type: volume
read_only: true
source: sparkd_data
target: /home/bts/.local/share/bts/sparkd/data/logging.sparkd
volume:
subpath: logging.sparkd
command: ["tail", "-f", "/home/bts/.local/share/bts/sparkd/data/logging.sparkd/log"]
sparkd-ping-test:
depends_on:
- sparkd
profiles:
- ping-test
build:
context: .
dockerfile_inline: |
FROM bluetradingsystems/linux_dotnet8
USER "root"
RUN apt-get update && apt-get -y install iputils-ping
command: [ "ping", "sparkd" ]
pubsub:
volumes:
- ${PUBSUB__DATA_DIR:-pubsub_data}:/home/bts/.local/share/bts/pubsub/data
build:
dockerfile: src/DataStreamSuite/PubSubServer/Dockerfile
args:
- SOURCE_DIR=${PUBSUB__SOURCE_DIR}
- CONFIG_DIR=${PUBSUB__CONFIG_DIR}
ports:
- 22019:22019
command: >
sh -c "
echo bts | sudo -S chown -R bts:bts /home/bts/.local/share/bts/pubsub/data
if [ -e "/home/bts/.local/share/bts/pubsub/data/logging.PubSubServer/log" ]; then
mv "/home/bts/.local/share/bts/pubsub/data/logging.PubSubServer/log" "/home/bts/.local/share/bts/pubsub/data/logging.PubSubServer/log_$(date '+%Y%m%d-%H%M')"
fi
if [ -e "/home/bts/.local/share/bts/pubsub/conf/.env" ]; then
echo 'Sourcing /home/bts/.local/share/bts/pubsub/conf/.env'
set -a
. /home/bts/.local/share/bts/pubsub/conf/.env
set +a
fi
if [ -e "/home/bts/.local/share/bts/pubsub/conf/.env.local" ]; then
echo 'Sourcing /home/bts/.local/share/bts/pubsub/conf/.env.local'
set -a
. /home/bts/.local/share/bts/pubsub/conf/.env.local
set +a
fi
./PubSubServer"
env_file:
- .env
- ${PUBSUB__CONFIG_DIR}/.env
md-publisher:
volumes:
- ${MD_PUBLISHER__DATA_DIR:-md_publisher_data}:/home/bts/.local/share/bts/md_publisher/data
- historic_md:/home/bts/.local/share/bts/md_publisher/data/databento
build:
dockerfile: src/DataStreamSuite/DataStreamPublisher/Dockerfile
args:
- SOURCE_DIR=${MD_PUBLISHER__SOURCE_DIR}
- CONFIG_DIR=${MD_PUBLISHER__CONFIG_DIR}
command: >
sh -c "
echo bts | sudo -S chown -R bts:bts /home/bts/.local/share/bts/md_publisher/data
if [ -e "/home/bts/.local/share/bts/md_publisher/data/logging.DataStreamPublisher/log" ]; then
mv "/home/bts/.local/share/bts/md_publisher/data/logging.DataStreamPublisher/log" "/home/bts/.local/share/bts/md_publisher/data/logging.DataStreamPublisher/log_$(date '+%Y%m%d-%H%M')"
fi
if [ -e "/home/bts/.local/share/bts/md_publisher/conf/.env" ]; then
echo 'Sourcing /home/bts/.local/share/bts/md_publisher/conf/.env'
set -a
. /home/bts/.local/share/bts/md_publisher/conf/.env
set +a
fi
if [ -e "/home/bts/.local/share/bts/md_publisher/conf/.env.local" ]; then
echo 'Sourcing /home/bts/.local/share/bts/md_publisher/conf/.env.local'
set -a
. /home/bts/.local/share/bts/md_publisher/conf/.env.local
set +a
fi
dockerize -wait tcp://pubsub:22019 -timeout 10s ./DataStreamPublisher"
env_file:
- .env
- ${MD_PUBLISHER__CONFIG_DIR}/.env
api-server:
depends_on:
- sparkd
ports:
- 8008:8008
- 9443:9443
build:
dockerfile: src/client/spark_api_server/Dockerfile
command: [ "dockerize", "-wait", "tcp://sparkd:8000", "-timeout", "10s", "./spark_api_server", "run" ]
environment:
- ASPNETCORE_ENVIRONMENT=Staging
volumes:
sparkd_data:
name: "sparkd_${SPARKD__CONFIG_PORT:-8000}"
pubsub_data:
name: "pubsub_22019"
md_publisher_data:
name: "md_publisher_22019"
historic_md:
name: "historic_md"
md_recording:
name: "sparkd_md_recording_${SPARKD__CONFIG_PORT:-8000}"
external: true
@@ -124,8 +124,8 @@ service OrderService {
```
### C++ Example
```cpp
#include "spark/api/public/ServiceContext.h"
#include "spark/api/services/OrderService.client.pb.h"
#include "lib/api/public/ServiceContext.h"
#include "lib/api/services/OrderService.client.pb.h"
using namespace bts::api;
ServiceContext ctx;
auto orders = ctx.locate<orderman::OrderService>();
@@ -29,9 +29,9 @@ namespace sample {
```
```cpp
#include "spark/api/public/ServiceContext.h"
#include "spark/domain_model/Security.h"
#include "spark/api/services/MarketDataService.client.pb.h"
#include "lib/api/public/ServiceContext.h"
#include "spark/lib/domain_model/Security.h"
#include "lib/api/services/MarketDataService.client.pb.h"
#include <thread>
using namespace bts::api;
@@ -1,38 +0,0 @@
FROM ubuntu:22.04
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y pkg-config
RUN apt-get update && apt-get install -y locales
RUN apt-get update && apt-get install -y ca-certificates
RUN apt-get update && apt-get install -y libssh2-1-dev
RUN apt-get update && apt-get install -y software-properties-common
RUN apt-get update && apt-get install -y sudo
# GCC
ARG gcc_major=13
RUN add-apt-repository ppa:ubuntu-toolchain-r/test \
&& apt-get update \
&& apt-get install -y g++-$gcc_major
RUN apt-get update \
&& apt-get install -y dotnet7
RUN locale-gen en_US.UTF-8
ARG docker_user="bts"
ARG docker_uid="1000"
ARG docker_pass="bts"
RUN \
groupadd -g "$docker_uid" "$docker_user" \
&& useradd \
-m \
-u "$docker_uid" \
-g "$docker_uid" \
-G sudo \
--password "$(openssl passwd -1 "$docker_pass")" \
"$docker_user"
USER bts
WORKDIR /home/bts
@@ -1,39 +0,0 @@
FROM ubuntu:22.04
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y pkg-config
RUN apt-get update && apt-get install -y locales
RUN apt-get update && apt-get install -y ca-certificates
RUN apt-get update && apt-get install -y libssh2-1-dev
RUN apt-get update && apt-get install -y software-properties-common
RUN apt-get update && apt-get install -y sudo
RUN apt-get update && apt-get install -y tzdata
# GCC
ARG gcc_major=13
RUN add-apt-repository ppa:ubuntu-toolchain-r/test \
&& apt-get update \
&& apt-get install -y g++-$gcc_major
RUN apt-get update \
&& apt-get install -y dotnet8
RUN locale-gen en_US.UTF-8
ARG docker_user="bts"
ARG docker_uid="1000"
ARG docker_pass="bts"
RUN \
groupadd -g "$docker_uid" "$docker_user" \
&& useradd \
-m \
-u "$docker_uid" \
-g "$docker_uid" \
-G sudo \
--password "$(openssl passwd -1 "$docker_pass")" \
"$docker_user"
USER bts
WORKDIR /home/bts
@@ -1,150 +0,0 @@
FROM ubuntu:22.04
ARG DEBIAN_FRONTEND=noninteractive
# Note installations that take a while (more than 10s)
RUN apt-get update
RUN apt-get install -y ca-certificates
RUN apt-get install -y ccache
RUN apt-get install -y curl
RUN apt-get install -y fish
RUN apt-get install -y gdb
# git-all: ~250s
RUN apt-get install -y git-all
RUN apt-get install -y gnupg
# liblttng-ust-dev: ~30s
RUN apt-get install -y liblttng-ust-dev
RUN apt-get install -y libssh2-1-dev
RUN apt-get install -y locales
RUN apt-get install -y ninja-build
# openssh-server: ~40s
RUN apt-get install -y openssh-server
RUN apt-get install -y pkg-config
RUN apt-get install -y software-properties-common
RUN apt-get install -y sudo
RUN apt-get install -y tzdata
RUN apt-get install -y vim
RUN apt-get install -y zip
# Python: ~30s
RUN apt-get install -y \
python3-pip \
python3-venv \
&& python3 -m pip install --upgrade pip
# GCC
ARG gcc_major=13
RUN \
add-apt-repository ppa:ubuntu-toolchain-r/test \
&& apt-get update \
&& apt-get install -y g++-$gcc_major
# Clang
ARG clang_major=17
RUN \
curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key 2> /dev/null \
| gpg --dearmor - \
| tee /usr/share/keyrings/llvm-snapshot.gpg > /dev/null \
&& echo "deb [signed-by=/usr/share/keyrings/llvm-snapshot.gpg] http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-$clang_major main" \
| tee -a "/etc/apt/sources.list.d/llvm.list" \
&& apt-get update \
&& apt-get install -y \
clang-$clang_major \
clang-format-$clang_major \
clangd-$clang_major
# CMake
RUN set -eux \
&& apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates curl gpg \
&& curl -fsSL https://apt.kitware.com/keys/kitware-archive-latest.asc \
| gpg --dearmor -o /usr/share/keyrings/kitware-archive-keyring.gpg \
&& echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main" \
> /etc/apt/sources.list.d/kitware.list \
&& apt-get update \
&& apt-get install -y --no-install-recommends cmake \
&& rm -rf /var/lib/apt/lists/*
# Dotnet
RUN apt-get update && apt-get install -y dotnet8
# Node
ARG node_major=18
RUN mkdir -p /etc/apt/keyrings \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
| gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$node_major.x nodistro main" \
| tee /etc/apt/sources.list.d/nodesource.list \
&& apt-get update \
&& apt-get install -y nodejs
# Emumba (deps)
RUN apt-get update && apt-get -y install rapidjson-dev
# Emumba
ARG EMUMBA_DERIBIT_CONNECTOR_DEB_URL="https://api.bitbucket.org/2.0/repositories/bluetradesys/spark/downloads/emumba-deribit-connector-3.3.1-Linux.LICENSE_DISABLED.deb"
RUN --mount=type=secret,id=bitbucket_access_token \
set -eux \
&& apt-get update \
&& TOKEN="$(cat /run/secrets/bitbucket_access_token)" \
&& curl -fL -H "Authorization: Bearer ${TOKEN}" $EMUMBA_DERIBIT_CONNECTOR_DEB_URL -o /tmp/emumba-deribit-connector.deb \
&& apt-get install -y /tmp/emumba-deribit-connector.deb \
&& rm -f /tmp/emumba-deribit-connector.deb
# Pcap
RUN apt-get update && apt-get install -y libpcap0.8-dev
# Databento (deps)
RUN apt-get update && apt-get -y install libzstd-dev
# Rakurai
ARG RAKURAI_DEB_URL="https://api.bitbucket.org/2.0/repositories/bluetradesys/spark/downloads/rakurai-dex-connector_0.0.5_amd64.deb"
RUN --mount=type=secret,id=bitbucket_access_token \
set -eux \
&& apt-get update \
&& TOKEN="$(cat /run/secrets/bitbucket_access_token)" \
&& curl -fL -H "Authorization: Bearer ${TOKEN}" $RAKURAI_DEB_URL -o /tmp/rakurai.deb \
# Need --force-overwrite because rakuirai and emumba-deribit-connector both include the same
# spdlog headers.
&& apt-get install -y -o Dpkg::Options::="--force-overwrite" /tmp/rakurai.deb \
&& rm -f /tmp/rakuirai.deb
# Docker in Docker
RUN apt-get update && apt-get install -y \
docker.io \
docker-compose \
docker-compose-v2
# Set up default executables (update-alternatives)
RUN \
update-alternatives --install /usr/bin/clang clang /usr/bin/clang-$clang_major 100; \
update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-$clang_major 100; \
update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-$clang_major 100; \
update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-$clang_major 100; \
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-$gcc_major 100; \
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-$gcc_major 100
# Add compiler symlinks for ccache
RUN \
ln -s /usr/bin/ccache /usr/local/bin/clang; \
ln -s /usr/bin/ccache /usr/local/bin/clang++; \
ln -s /usr/bin/ccache /usr/local/bin/clang-$clang_major; \
ln -s /usr/bin/ccache /usr/local/bin/clang++-$clang_major; \
ln -s /usr/bin/ccache /usr/local/bin/gcc; \
ln -s /usr/bin/ccache /usr/local/bin/g++
RUN locale-gen en_US.UTF-8
ARG docker_user="bts"
ARG docker_uid="1000"
ARG docker_pass="bts"
RUN \
groupadd -g "$docker_uid" "$docker_user" \
&& useradd \
-m \
-u "$docker_uid" \
-g "$docker_uid" \
-G sudo \
--password "$(openssl passwd -1 "$docker_pass")" \
"$docker_user"
@@ -1,11 +0,0 @@
FROM ubuntu:24.04
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y \
fish \
less \
vim
USER bts
WORKDIR /home/bts
Submodule docker/linux deleted from 6537812262.
+70 -87
View File
@@ -1,65 +1,74 @@
FROM ubuntu:latest
FROM ubuntu:22.04
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=America/New_York
# light deps (should be quick to download/install)
RUN apt-get update && apt-get install -y \
ca-certificates \
curl \
gnupg \
liblttng-ust-dev \
libpcap0.8-dev \
locales \
ninja-build \
software-properties-common \
sqlite3 \
tzdata
# Note installations that take a while (more than 10s)
# clang
RUN apt-get update && apt-get install -y \
clang-13 \
clang-format-13 \
clangd-13 \
clang-15 \
clang-format-15 \
clangd-15
RUN apt-get update
RUN apt-get install -y ca-certificates
RUN apt-get install -y ccache
RUN apt-get install -y curl
RUN apt-get install -y fish
RUN apt-get install -y gdb
# git-all: ~250s
RUN apt-get install -y git-all
RUN apt-get install -y gnupg
# liblttng-ust-dev: ~30s
RUN apt-get install -y liblttng-ust-dev
RUN apt-get install -y libssh2-1-dev
RUN apt-get install -y locales
RUN apt-get install -y ninja-build
# openssh-server: ~40s
RUN apt-get install -y openssh-server
RUN apt-get install -y pkg-config
RUN apt-get install -y software-properties-common
RUN apt-get install -y sudo
RUN apt-get install -y tzdata
RUN apt-get install -y vim
RUN apt-get install -y zip
# g++
RUN apt-get update && apt-get install -y \
g++-11 \
g++-12
# python
RUN apt-get update && apt-get install -y \
# Python: ~30s
RUN apt-get install -y \
python3-pip \
python3-venv \
&& python3 -m pip install --upgrade pip
# dotnet
RUN apt-get update && apt-get install -y \
dotnet7
# GCC
ARG gcc_major=13
RUN add-apt-repository ppa:ubuntu-toolchain-r/test \
&& apt-get update \
&& apt-get install -y g++-$gcc_major
# ssh
RUN apt-get update && apt-get install -y \
libssh2-1-dev \
openssh-server
# Clang
ARG clang_major=17
RUN curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key 2> /dev/null \
| gpg --dearmor - \
| tee /usr/share/keyrings/llvm-snapshot.gpg > /dev/null \
&& echo "deb [signed-by=/usr/share/keyrings/llvm-snapshot.gpg] http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-$clang_major main" \
| tee -a "/etc/apt/sources.list.d/llvm.list" \
&& apt-get update \
&& apt-get install -y \
clang-$clang_major \
clang-format-$clang_major \
clangd-$clang_major
# cmake
RUN \
curl -fsSL https://apt.kitware.com/keys/kitware-archive-latest.asc 2> /dev/null \
# CMake
RUN curl -fsSL https://apt.kitware.com/keys/kitware-archive-latest.asc 2> /dev/null \
| gpg --dearmor - \
| tee /usr/share/keyrings/kitware-archive-keyring.gpg > /dev/null \
&& echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main" \
| tee /etc/apt/sources.list.d/kitware.list > /dev/null \
&& apt-get update \
&& rm /usr/share/keyrings/kitware-archive-keyring.gpg \
&& apt-get install -y kitware-archive-keyring \
&& echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ $(lsb_release -cs)-rc main" \
| tee -a /etc/apt/sources.list.d/kitware.list >/dev/null \
&& apt-get install -y cmake
# node
# Dotnet
RUN curl -fsSLO "https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb" \
&& dpkg -i packages-microsoft-prod.deb \
&& rm packages-microsoft-prod.deb \
&& apt-get update \
&& apt-get install -y dotnet-sdk-8.0
# Node
ARG node_major=18
RUN mkdir -p /etc/apt/keyrings \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
@@ -69,60 +78,35 @@ RUN mkdir -p /etc/apt/keyrings \
&& apt-get update \
&& apt-get install -y nodejs
# ccache is done here so that ccache sees clang++ installed, not clang-10
RUN apt-get update && apt-get install -y \
ccache
# emumba (light deps)
# Emumba deps
RUN apt-get update && apt-get install -y \
build-essential \
doxygen \
python3-sphinx \
graphviz \
libgtest-dev \
libssl-dev \
pkg-config \
python3-sphinx \
rapidjson-dev \
zlib1g-dev \
pkg-config
zlib1g-dev
# emumba (boost)
RUN apt-get update && apt-get install -y \
libboost-filesystem-dev \
libboost-program-options-dev \
libboost-test-dev \
libboost-date-time-dev
# dev utils
RUN apt-get update && apt-get install -y \
fish \
git-all \
sudo \
vim \
wget
# set up default executables (update-alternatives)
RUN \
update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-13 100; \
update-alternatives --install /usr/bin/clang clang /usr/bin/clang-13 100; \
update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-13 100; \
update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-13 100; \
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 100; \
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 100
# Set up default executables (update-alternatives)
RUN update-alternatives --install /usr/bin/clang clang /usr/bin/clang-$clang_major 100; \
update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-$clang_major 100; \
update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-$clang_major 100; \
update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-$clang_major 100; \
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-$gcc_major 100; \
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-$gcc_major 100
# Add compiler symlinks for ccache
RUN \
ln -s /usr/bin/ccache /usr/local/bin/clang; \
RUN ln -s /usr/bin/ccache /usr/local/bin/clang; \
ln -s /usr/bin/ccache /usr/local/bin/clang++; \
ln -s /usr/bin/ccache /usr/local/bin/clang-13; \
ln -s /usr/bin/ccache /usr/local/bin/clang++-13; \
ln -s /usr/bin/ccache /usr/local/bin/clang-15; \
ln -s /usr/bin/ccache /usr/local/bin/clang++-15; \
ln -s /usr/bin/ccache /usr/local/bin/clang-$clang_major; \
ln -s /usr/bin/ccache /usr/local/bin/clang++-$clang_major; \
ln -s /usr/bin/ccache /usr/local/bin/gcc; \
ln -s /usr/bin/ccache /usr/local/bin/g++; \
ln -s /usr/bin/ccache /usr/local/bin/gcc-11; \
ln -s /usr/bin/ccache /usr/local/bin/g++-11; \
ln -s /usr/bin/ccache /usr/local/bin/gcc-12; \
ln -s /usr/bin/ccache /usr/local/bin/g++-12
ln -s /usr/bin/ccache /usr/local/bin/gcc-$gcc_major; \
ln -s /usr/bin/ccache /usr/local/bin/g++-$gcc_major
RUN locale-gen en_US.UTF-8
@@ -130,8 +114,7 @@ ARG docker_user="bts"
ARG docker_uid="1000"
ARG docker_pass="bts"
RUN \
groupadd -g "$docker_uid" "$docker_user" \
RUN groupadd -g "$docker_uid" "$docker_user" \
&& useradd \
-m \
-u "$docker_uid" \
Submodule docker/windows deleted from de7d40c09d.
-6
View File
@@ -1,6 +0,0 @@
{
"sdk": {
"version": "6.0.200",
"rollForward": "latestMajor"
}
}
+45
View File
@@ -0,0 +1,45 @@
/* global use, db */
// MongoDB Playground
// To disable this template go to Settings | MongoDB | Use Default Template For Playground.
// Make sure you are connected to enable completions and to be able to run a playground.
// Use Ctrl+Space inside a snippet or a string literal to trigger completions.
// The result of the last command run in a playground is shown on the results panel.
// By default the first 20 documents will be returned with a cursor.
// Use 'console.log()' to print to the debug output.
// For more documentation on playgrounds please refer to
// https://www.mongodb.com/docs/mongodb-vscode/playgrounds/
// Select the database to use.
use('mongodbVSCodePlaygroundDB');
// Insert a few documents into the sales collection.
db.getCollection('sales').insertMany([
{ 'item': 'abc', 'price': 10, 'quantity': 2, 'date': new Date('2014-03-01T08:00:00Z') },
{ 'item': 'jkl', 'price': 20, 'quantity': 1, 'date': new Date('2014-03-01T09:00:00Z') },
{ 'item': 'xyz', 'price': 5, 'quantity': 10, 'date': new Date('2014-03-15T09:00:00Z') },
{ 'item': 'xyz', 'price': 5, 'quantity': 20, 'date': new Date('2014-04-04T11:21:39.736Z') },
{ 'item': 'abc', 'price': 10, 'quantity': 10, 'date': new Date('2014-04-04T21:23:13.331Z') },
{ 'item': 'def', 'price': 7.5, 'quantity': 5, 'date': new Date('2015-06-04T05:08:13Z') },
{ 'item': 'def', 'price': 7.5, 'quantity': 10, 'date': new Date('2015-09-10T08:43:00Z') },
{ 'item': 'abc', 'price': 10, 'quantity': 5, 'date': new Date('2016-02-06T20:20:13Z') },
]);
// Run a find command to view items sold on April 4th, 2014.
const salesOnApril4th = db.getCollection('sales').find({
date: { $gte: new Date('2014-04-04'), $lt: new Date('2014-04-05') }
}).count();
// Print a message to the output window.
console.log(`${salesOnApril4th} sales occurred in 2014.`);
// Here we run an aggregation and open a cursor to the results.
// Use '.toArray()' to exhaust the cursor to return the whole result set.
// You can use '.hasNext()/.next()' to iterate through the cursor page by page.
db.getCollection('sales').aggregate([
// Find all of the sales that occurred in 2014.
{ $match: { date: { $gte: new Date('2014-01-01'), $lt: new Date('2015-01-01') } } },
// Group the total sales for each product.
{ $group: { _id: '$item', totalSaleAmount: { $sum: { $multiply: ['$price', '$quantity'] } } } }
]);
+1 -21
View File
@@ -1,42 +1,22 @@
astroid==2.7.3
autopep8==1.5.7
blinker==1.9.0
boto3==1.37.9
botocore==1.37.9
certifi==2023.5.7
charset-normalizer==3.1.0
click==8.1.8
colorama==0.4.4
Flask==3.1.0
idna==3.4
isort==5.9.3
itsdangerous==2.2.0
Jinja2==3.1.6
jmespath==1.0.1
lazy-object-proxy==1.6.0
MarkupSafe==3.0.2
mccabe==0.6.1
numpy==2.2.6
platformdirs==2.3.0
protobuf==6.33.4
protobuf==4.21.12
pybars3==0.9.7
pybind11==3.0.1
pybind11-stubgen==2.5.5
pybit==5.11.0
pycodestyle==2.7.0
pycparser==2.20
pycryptodome==3.23.0
pylint==2.10.2
PyMeta3==0.5.1
python-dateutil==2.9.0.post0
python-dotenv==1.0.1
requests==2.31.0
s3transfer==0.11.4
six==1.17.0
termcolor==1.1.0
toml==0.10.2
urllib3==2.0.3
websocket-client==1.8.0
Werkzeug==3.1.3
wrapt==1.12.1
yapf==0.31.0
+82 -285
View File
@@ -1,306 +1,103 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{827E0CD3-B72D-47B6-A68D-7590B98EB39B}"
VisualStudioVersion = 17.3.32922.545
MinimumVisualStudioVersion = 15.0.26124.0
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_api", "src\client\spark_api\spark_api.csproj", "{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cs", "cs", "{D7C6B9C7-1058-B1EA-FEE6-34C56B05AEDB}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spark", "src\client\spark\Spark.csproj", "{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bts.Spark.Core", "src\cs\Bts.Spark.Core\Bts.Spark.Core.csproj", "{684863A1-3396-4D31-A731-C0725CF07F4E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spark.Console", "src\client\Spark.Console\Spark.Console.csproj", "{387566C6-C6F6-412C-A30C-9855BBCB4816}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bts.Spark.Api", "src\cs\Bts.Spark.Api\Bts.Spark.Api.csproj", "{45292808-4EF3-4D4A-B3F5-B75C42EE5870}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_core", "src\client\spark_core\spark_core.csproj", "{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bts.Extensions.Hosting", "src\cs\Bts.Extensions.Hosting\Bts.Extensions.Hosting.csproj", "{AA57F8D9-7BD6-4161-881B-AD2CEF9A30F6}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_sdk", "src\client\spark_sdk\spark_sdk.csproj", "{6963C314-83C4-4667-B0D0-C2F7AE208C29}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bts.IO.Compression", "src\cs\Bts.IO.Compression\Bts.IO.Compression.csproj", "{28A26DF7-5F7A-43A2-A548-B55FEBCC3958}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_test", "src\client\spark_test\spark_test.csproj", "{ECD78CC5-138F-4809-A764-2358C2AC2E82}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bts.Net", "src\cs\Bts.Net\Bts.Net.csproj", "{7543386A-5EBA-4AF0-9E0F-35657B58557D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_websocket", "src\client\spark_websocket\spark_websocket.csproj", "{3201359D-C071-4089-9EDE-B04D759F1508}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataStreamSuite", "DataStreamSuite", "{60E0D592-FFB3-0D0A-C4AA-E88919B48F9D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PubSub", "src\DataStreamSuite\PubSub\PubSub.csproj", "{C13A5ABD-F739-4BE8-A2FE-511E989A5B43}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataStreamCore", "src\DataStreamSuite\DataStreamCore\DataStreamCore.csproj", "{F7C6F079-67BA-4899-9B43-D3F8C121D264}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArithmeticExpressions", "src\DataStreamSuite\ArithmeticExpressions\ArithmeticExpressions.csproj", "{E60C119D-2919-4E2F-9D39-90DB1A8FF9A7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BaseUtilities", "src\DataStreamSuite\BaseUtilities\BaseUtilities.csproj", "{ECBAA198-EC93-4174-8156-BDA5F5E95042}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BooleanExpressions", "src\DataStreamSuite\BooleanExpressions\BooleanExpressions.csproj", "{F54AE5C0-2ECA-4151-82E6-0D7EFE88FF40}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bts.ColumnExpressions", "src\DataStreamSuite\Bts.ColumnExpressions\Bts.ColumnExpressions.csproj", "{A898C6C3-F134-4AF0-AFB3-3834C58CC0D7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bts.ColumnSortExpressions", "src\DataStreamSuite\Bts.ColumnSortExpressions\Bts.ColumnSortExpressions.csproj", "{1E296FB3-D185-4A95-A1EB-AA5B37B85C60}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataStreamExpressions", "src\DataStreamSuite\DataStreamExpressions\DataStreamExpressions.csproj", "{B6070F41-8759-448B-B56D-A7D15D489569}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataStream", "src\DataStreamSuite\DataStream\DataStream.csproj", "{B2D721AB-920C-4CD6-8DBF-6778A115A449}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedStreams", "src\DataStreamSuite\SharedStreams\SharedStreams.csproj", "{38EE36C6-892C-4C94-8BB0-1ACB164E1F20}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "client", "client", "{C5A3B5EA-BE9F-76E5-E9B8-8A22B289B295}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "spark", "spark", "{42C014A0-00C5-0620-8552-38912E891A7F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spark", "src\client\spark\Spark.csproj", "{D432F3E9-3D2F-4623-B7B9-CEBA6701FFC3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "spark_test", "src\client\spark_test\spark_test.csproj", "{DD00F5D5-6C2F-4FDA-AE3D-25CF01A9A224}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spark.Console", "src\client\Spark.Console\Spark.Console.csproj", "{2B8243FF-60C6-4607-8AAE-7762D29B0A48}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_api_server", "src\client\spark_api_server\spark_api_server.csproj", "{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
MinSizeRel|x64 = MinSizeRel|x64
Release|x64 = Release|x64
Release|x86 = Release|x86
RelWithDebInfo|x64 = RelWithDebInfo|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{684863A1-3396-4D31-A731-C0725CF07F4E}.Debug|Any CPU.ActiveCfg = Debug|x64
{684863A1-3396-4D31-A731-C0725CF07F4E}.Debug|Any CPU.Build.0 = Debug|x64
{684863A1-3396-4D31-A731-C0725CF07F4E}.Debug|x64.ActiveCfg = Debug|x64
{684863A1-3396-4D31-A731-C0725CF07F4E}.Debug|x64.Build.0 = Debug|x64
{684863A1-3396-4D31-A731-C0725CF07F4E}.Debug|x86.ActiveCfg = Debug|x64
{684863A1-3396-4D31-A731-C0725CF07F4E}.Debug|x86.Build.0 = Debug|x64
{684863A1-3396-4D31-A731-C0725CF07F4E}.Release|Any CPU.ActiveCfg = Release|x64
{684863A1-3396-4D31-A731-C0725CF07F4E}.Release|Any CPU.Build.0 = Release|x64
{684863A1-3396-4D31-A731-C0725CF07F4E}.Release|x64.ActiveCfg = Release|x64
{684863A1-3396-4D31-A731-C0725CF07F4E}.Release|x64.Build.0 = Release|x64
{684863A1-3396-4D31-A731-C0725CF07F4E}.Release|x86.ActiveCfg = Release|x64
{684863A1-3396-4D31-A731-C0725CF07F4E}.Release|x86.Build.0 = Release|x64
{45292808-4EF3-4D4A-B3F5-B75C42EE5870}.Debug|Any CPU.ActiveCfg = Debug|x64
{45292808-4EF3-4D4A-B3F5-B75C42EE5870}.Debug|Any CPU.Build.0 = Debug|x64
{45292808-4EF3-4D4A-B3F5-B75C42EE5870}.Debug|x64.ActiveCfg = Debug|x64
{45292808-4EF3-4D4A-B3F5-B75C42EE5870}.Debug|x64.Build.0 = Debug|x64
{45292808-4EF3-4D4A-B3F5-B75C42EE5870}.Debug|x86.ActiveCfg = Debug|x64
{45292808-4EF3-4D4A-B3F5-B75C42EE5870}.Debug|x86.Build.0 = Debug|x64
{45292808-4EF3-4D4A-B3F5-B75C42EE5870}.Release|Any CPU.ActiveCfg = Release|x64
{45292808-4EF3-4D4A-B3F5-B75C42EE5870}.Release|Any CPU.Build.0 = Release|x64
{45292808-4EF3-4D4A-B3F5-B75C42EE5870}.Release|x64.ActiveCfg = Release|x64
{45292808-4EF3-4D4A-B3F5-B75C42EE5870}.Release|x64.Build.0 = Release|x64
{45292808-4EF3-4D4A-B3F5-B75C42EE5870}.Release|x86.ActiveCfg = Release|x64
{45292808-4EF3-4D4A-B3F5-B75C42EE5870}.Release|x86.Build.0 = Release|x64
{AA57F8D9-7BD6-4161-881B-AD2CEF9A30F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA57F8D9-7BD6-4161-881B-AD2CEF9A30F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA57F8D9-7BD6-4161-881B-AD2CEF9A30F6}.Debug|x64.ActiveCfg = Debug|Any CPU
{AA57F8D9-7BD6-4161-881B-AD2CEF9A30F6}.Debug|x64.Build.0 = Debug|Any CPU
{AA57F8D9-7BD6-4161-881B-AD2CEF9A30F6}.Debug|x86.ActiveCfg = Debug|Any CPU
{AA57F8D9-7BD6-4161-881B-AD2CEF9A30F6}.Debug|x86.Build.0 = Debug|Any CPU
{AA57F8D9-7BD6-4161-881B-AD2CEF9A30F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA57F8D9-7BD6-4161-881B-AD2CEF9A30F6}.Release|Any CPU.Build.0 = Release|Any CPU
{AA57F8D9-7BD6-4161-881B-AD2CEF9A30F6}.Release|x64.ActiveCfg = Release|Any CPU
{AA57F8D9-7BD6-4161-881B-AD2CEF9A30F6}.Release|x64.Build.0 = Release|Any CPU
{AA57F8D9-7BD6-4161-881B-AD2CEF9A30F6}.Release|x86.ActiveCfg = Release|Any CPU
{AA57F8D9-7BD6-4161-881B-AD2CEF9A30F6}.Release|x86.Build.0 = Release|Any CPU
{28A26DF7-5F7A-43A2-A548-B55FEBCC3958}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{28A26DF7-5F7A-43A2-A548-B55FEBCC3958}.Debug|Any CPU.Build.0 = Debug|Any CPU
{28A26DF7-5F7A-43A2-A548-B55FEBCC3958}.Debug|x64.ActiveCfg = Debug|Any CPU
{28A26DF7-5F7A-43A2-A548-B55FEBCC3958}.Debug|x64.Build.0 = Debug|Any CPU
{28A26DF7-5F7A-43A2-A548-B55FEBCC3958}.Debug|x86.ActiveCfg = Debug|Any CPU
{28A26DF7-5F7A-43A2-A548-B55FEBCC3958}.Debug|x86.Build.0 = Debug|Any CPU
{28A26DF7-5F7A-43A2-A548-B55FEBCC3958}.Release|Any CPU.ActiveCfg = Release|Any CPU
{28A26DF7-5F7A-43A2-A548-B55FEBCC3958}.Release|Any CPU.Build.0 = Release|Any CPU
{28A26DF7-5F7A-43A2-A548-B55FEBCC3958}.Release|x64.ActiveCfg = Release|Any CPU
{28A26DF7-5F7A-43A2-A548-B55FEBCC3958}.Release|x64.Build.0 = Release|Any CPU
{28A26DF7-5F7A-43A2-A548-B55FEBCC3958}.Release|x86.ActiveCfg = Release|Any CPU
{28A26DF7-5F7A-43A2-A548-B55FEBCC3958}.Release|x86.Build.0 = Release|Any CPU
{7543386A-5EBA-4AF0-9E0F-35657B58557D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7543386A-5EBA-4AF0-9E0F-35657B58557D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7543386A-5EBA-4AF0-9E0F-35657B58557D}.Debug|x64.ActiveCfg = Debug|Any CPU
{7543386A-5EBA-4AF0-9E0F-35657B58557D}.Debug|x64.Build.0 = Debug|Any CPU
{7543386A-5EBA-4AF0-9E0F-35657B58557D}.Debug|x86.ActiveCfg = Debug|Any CPU
{7543386A-5EBA-4AF0-9E0F-35657B58557D}.Debug|x86.Build.0 = Debug|Any CPU
{7543386A-5EBA-4AF0-9E0F-35657B58557D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7543386A-5EBA-4AF0-9E0F-35657B58557D}.Release|Any CPU.Build.0 = Release|Any CPU
{7543386A-5EBA-4AF0-9E0F-35657B58557D}.Release|x64.ActiveCfg = Release|Any CPU
{7543386A-5EBA-4AF0-9E0F-35657B58557D}.Release|x64.Build.0 = Release|Any CPU
{7543386A-5EBA-4AF0-9E0F-35657B58557D}.Release|x86.ActiveCfg = Release|Any CPU
{7543386A-5EBA-4AF0-9E0F-35657B58557D}.Release|x86.Build.0 = Release|Any CPU
{C13A5ABD-F739-4BE8-A2FE-511E989A5B43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C13A5ABD-F739-4BE8-A2FE-511E989A5B43}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C13A5ABD-F739-4BE8-A2FE-511E989A5B43}.Debug|x64.ActiveCfg = Debug|Any CPU
{C13A5ABD-F739-4BE8-A2FE-511E989A5B43}.Debug|x64.Build.0 = Debug|Any CPU
{C13A5ABD-F739-4BE8-A2FE-511E989A5B43}.Debug|x86.ActiveCfg = Debug|Any CPU
{C13A5ABD-F739-4BE8-A2FE-511E989A5B43}.Debug|x86.Build.0 = Debug|Any CPU
{C13A5ABD-F739-4BE8-A2FE-511E989A5B43}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C13A5ABD-F739-4BE8-A2FE-511E989A5B43}.Release|Any CPU.Build.0 = Release|Any CPU
{C13A5ABD-F739-4BE8-A2FE-511E989A5B43}.Release|x64.ActiveCfg = Release|Any CPU
{C13A5ABD-F739-4BE8-A2FE-511E989A5B43}.Release|x64.Build.0 = Release|Any CPU
{C13A5ABD-F739-4BE8-A2FE-511E989A5B43}.Release|x86.ActiveCfg = Release|Any CPU
{C13A5ABD-F739-4BE8-A2FE-511E989A5B43}.Release|x86.Build.0 = Release|Any CPU
{F7C6F079-67BA-4899-9B43-D3F8C121D264}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F7C6F079-67BA-4899-9B43-D3F8C121D264}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F7C6F079-67BA-4899-9B43-D3F8C121D264}.Debug|x64.ActiveCfg = Debug|Any CPU
{F7C6F079-67BA-4899-9B43-D3F8C121D264}.Debug|x64.Build.0 = Debug|Any CPU
{F7C6F079-67BA-4899-9B43-D3F8C121D264}.Debug|x86.ActiveCfg = Debug|Any CPU
{F7C6F079-67BA-4899-9B43-D3F8C121D264}.Debug|x86.Build.0 = Debug|Any CPU
{F7C6F079-67BA-4899-9B43-D3F8C121D264}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F7C6F079-67BA-4899-9B43-D3F8C121D264}.Release|Any CPU.Build.0 = Release|Any CPU
{F7C6F079-67BA-4899-9B43-D3F8C121D264}.Release|x64.ActiveCfg = Release|Any CPU
{F7C6F079-67BA-4899-9B43-D3F8C121D264}.Release|x64.Build.0 = Release|Any CPU
{F7C6F079-67BA-4899-9B43-D3F8C121D264}.Release|x86.ActiveCfg = Release|Any CPU
{F7C6F079-67BA-4899-9B43-D3F8C121D264}.Release|x86.Build.0 = Release|Any CPU
{E60C119D-2919-4E2F-9D39-90DB1A8FF9A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E60C119D-2919-4E2F-9D39-90DB1A8FF9A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E60C119D-2919-4E2F-9D39-90DB1A8FF9A7}.Debug|x64.ActiveCfg = Debug|Any CPU
{E60C119D-2919-4E2F-9D39-90DB1A8FF9A7}.Debug|x64.Build.0 = Debug|Any CPU
{E60C119D-2919-4E2F-9D39-90DB1A8FF9A7}.Debug|x86.ActiveCfg = Debug|Any CPU
{E60C119D-2919-4E2F-9D39-90DB1A8FF9A7}.Debug|x86.Build.0 = Debug|Any CPU
{E60C119D-2919-4E2F-9D39-90DB1A8FF9A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E60C119D-2919-4E2F-9D39-90DB1A8FF9A7}.Release|Any CPU.Build.0 = Release|Any CPU
{E60C119D-2919-4E2F-9D39-90DB1A8FF9A7}.Release|x64.ActiveCfg = Release|Any CPU
{E60C119D-2919-4E2F-9D39-90DB1A8FF9A7}.Release|x64.Build.0 = Release|Any CPU
{E60C119D-2919-4E2F-9D39-90DB1A8FF9A7}.Release|x86.ActiveCfg = Release|Any CPU
{E60C119D-2919-4E2F-9D39-90DB1A8FF9A7}.Release|x86.Build.0 = Release|Any CPU
{ECBAA198-EC93-4174-8156-BDA5F5E95042}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ECBAA198-EC93-4174-8156-BDA5F5E95042}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ECBAA198-EC93-4174-8156-BDA5F5E95042}.Debug|x64.ActiveCfg = Debug|Any CPU
{ECBAA198-EC93-4174-8156-BDA5F5E95042}.Debug|x64.Build.0 = Debug|Any CPU
{ECBAA198-EC93-4174-8156-BDA5F5E95042}.Debug|x86.ActiveCfg = Debug|Any CPU
{ECBAA198-EC93-4174-8156-BDA5F5E95042}.Debug|x86.Build.0 = Debug|Any CPU
{ECBAA198-EC93-4174-8156-BDA5F5E95042}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ECBAA198-EC93-4174-8156-BDA5F5E95042}.Release|Any CPU.Build.0 = Release|Any CPU
{ECBAA198-EC93-4174-8156-BDA5F5E95042}.Release|x64.ActiveCfg = Release|Any CPU
{ECBAA198-EC93-4174-8156-BDA5F5E95042}.Release|x64.Build.0 = Release|Any CPU
{ECBAA198-EC93-4174-8156-BDA5F5E95042}.Release|x86.ActiveCfg = Release|Any CPU
{ECBAA198-EC93-4174-8156-BDA5F5E95042}.Release|x86.Build.0 = Release|Any CPU
{F54AE5C0-2ECA-4151-82E6-0D7EFE88FF40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F54AE5C0-2ECA-4151-82E6-0D7EFE88FF40}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F54AE5C0-2ECA-4151-82E6-0D7EFE88FF40}.Debug|x64.ActiveCfg = Debug|Any CPU
{F54AE5C0-2ECA-4151-82E6-0D7EFE88FF40}.Debug|x64.Build.0 = Debug|Any CPU
{F54AE5C0-2ECA-4151-82E6-0D7EFE88FF40}.Debug|x86.ActiveCfg = Debug|Any CPU
{F54AE5C0-2ECA-4151-82E6-0D7EFE88FF40}.Debug|x86.Build.0 = Debug|Any CPU
{F54AE5C0-2ECA-4151-82E6-0D7EFE88FF40}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F54AE5C0-2ECA-4151-82E6-0D7EFE88FF40}.Release|Any CPU.Build.0 = Release|Any CPU
{F54AE5C0-2ECA-4151-82E6-0D7EFE88FF40}.Release|x64.ActiveCfg = Release|Any CPU
{F54AE5C0-2ECA-4151-82E6-0D7EFE88FF40}.Release|x64.Build.0 = Release|Any CPU
{F54AE5C0-2ECA-4151-82E6-0D7EFE88FF40}.Release|x86.ActiveCfg = Release|Any CPU
{F54AE5C0-2ECA-4151-82E6-0D7EFE88FF40}.Release|x86.Build.0 = Release|Any CPU
{A898C6C3-F134-4AF0-AFB3-3834C58CC0D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A898C6C3-F134-4AF0-AFB3-3834C58CC0D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A898C6C3-F134-4AF0-AFB3-3834C58CC0D7}.Debug|x64.ActiveCfg = Debug|Any CPU
{A898C6C3-F134-4AF0-AFB3-3834C58CC0D7}.Debug|x64.Build.0 = Debug|Any CPU
{A898C6C3-F134-4AF0-AFB3-3834C58CC0D7}.Debug|x86.ActiveCfg = Debug|Any CPU
{A898C6C3-F134-4AF0-AFB3-3834C58CC0D7}.Debug|x86.Build.0 = Debug|Any CPU
{A898C6C3-F134-4AF0-AFB3-3834C58CC0D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A898C6C3-F134-4AF0-AFB3-3834C58CC0D7}.Release|Any CPU.Build.0 = Release|Any CPU
{A898C6C3-F134-4AF0-AFB3-3834C58CC0D7}.Release|x64.ActiveCfg = Release|Any CPU
{A898C6C3-F134-4AF0-AFB3-3834C58CC0D7}.Release|x64.Build.0 = Release|Any CPU
{A898C6C3-F134-4AF0-AFB3-3834C58CC0D7}.Release|x86.ActiveCfg = Release|Any CPU
{A898C6C3-F134-4AF0-AFB3-3834C58CC0D7}.Release|x86.Build.0 = Release|Any CPU
{1E296FB3-D185-4A95-A1EB-AA5B37B85C60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E296FB3-D185-4A95-A1EB-AA5B37B85C60}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E296FB3-D185-4A95-A1EB-AA5B37B85C60}.Debug|x64.ActiveCfg = Debug|Any CPU
{1E296FB3-D185-4A95-A1EB-AA5B37B85C60}.Debug|x64.Build.0 = Debug|Any CPU
{1E296FB3-D185-4A95-A1EB-AA5B37B85C60}.Debug|x86.ActiveCfg = Debug|Any CPU
{1E296FB3-D185-4A95-A1EB-AA5B37B85C60}.Debug|x86.Build.0 = Debug|Any CPU
{1E296FB3-D185-4A95-A1EB-AA5B37B85C60}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E296FB3-D185-4A95-A1EB-AA5B37B85C60}.Release|Any CPU.Build.0 = Release|Any CPU
{1E296FB3-D185-4A95-A1EB-AA5B37B85C60}.Release|x64.ActiveCfg = Release|Any CPU
{1E296FB3-D185-4A95-A1EB-AA5B37B85C60}.Release|x64.Build.0 = Release|Any CPU
{1E296FB3-D185-4A95-A1EB-AA5B37B85C60}.Release|x86.ActiveCfg = Release|Any CPU
{1E296FB3-D185-4A95-A1EB-AA5B37B85C60}.Release|x86.Build.0 = Release|Any CPU
{B6070F41-8759-448B-B56D-A7D15D489569}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6070F41-8759-448B-B56D-A7D15D489569}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6070F41-8759-448B-B56D-A7D15D489569}.Debug|x64.ActiveCfg = Debug|Any CPU
{B6070F41-8759-448B-B56D-A7D15D489569}.Debug|x64.Build.0 = Debug|Any CPU
{B6070F41-8759-448B-B56D-A7D15D489569}.Debug|x86.ActiveCfg = Debug|Any CPU
{B6070F41-8759-448B-B56D-A7D15D489569}.Debug|x86.Build.0 = Debug|Any CPU
{B6070F41-8759-448B-B56D-A7D15D489569}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6070F41-8759-448B-B56D-A7D15D489569}.Release|Any CPU.Build.0 = Release|Any CPU
{B6070F41-8759-448B-B56D-A7D15D489569}.Release|x64.ActiveCfg = Release|Any CPU
{B6070F41-8759-448B-B56D-A7D15D489569}.Release|x64.Build.0 = Release|Any CPU
{B6070F41-8759-448B-B56D-A7D15D489569}.Release|x86.ActiveCfg = Release|Any CPU
{B6070F41-8759-448B-B56D-A7D15D489569}.Release|x86.Build.0 = Release|Any CPU
{B2D721AB-920C-4CD6-8DBF-6778A115A449}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B2D721AB-920C-4CD6-8DBF-6778A115A449}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B2D721AB-920C-4CD6-8DBF-6778A115A449}.Debug|x64.ActiveCfg = Debug|Any CPU
{B2D721AB-920C-4CD6-8DBF-6778A115A449}.Debug|x64.Build.0 = Debug|Any CPU
{B2D721AB-920C-4CD6-8DBF-6778A115A449}.Debug|x86.ActiveCfg = Debug|Any CPU
{B2D721AB-920C-4CD6-8DBF-6778A115A449}.Debug|x86.Build.0 = Debug|Any CPU
{B2D721AB-920C-4CD6-8DBF-6778A115A449}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B2D721AB-920C-4CD6-8DBF-6778A115A449}.Release|Any CPU.Build.0 = Release|Any CPU
{B2D721AB-920C-4CD6-8DBF-6778A115A449}.Release|x64.ActiveCfg = Release|Any CPU
{B2D721AB-920C-4CD6-8DBF-6778A115A449}.Release|x64.Build.0 = Release|Any CPU
{B2D721AB-920C-4CD6-8DBF-6778A115A449}.Release|x86.ActiveCfg = Release|Any CPU
{B2D721AB-920C-4CD6-8DBF-6778A115A449}.Release|x86.Build.0 = Release|Any CPU
{38EE36C6-892C-4C94-8BB0-1ACB164E1F20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38EE36C6-892C-4C94-8BB0-1ACB164E1F20}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38EE36C6-892C-4C94-8BB0-1ACB164E1F20}.Debug|x64.ActiveCfg = Debug|Any CPU
{38EE36C6-892C-4C94-8BB0-1ACB164E1F20}.Debug|x64.Build.0 = Debug|Any CPU
{38EE36C6-892C-4C94-8BB0-1ACB164E1F20}.Debug|x86.ActiveCfg = Debug|Any CPU
{38EE36C6-892C-4C94-8BB0-1ACB164E1F20}.Debug|x86.Build.0 = Debug|Any CPU
{38EE36C6-892C-4C94-8BB0-1ACB164E1F20}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38EE36C6-892C-4C94-8BB0-1ACB164E1F20}.Release|Any CPU.Build.0 = Release|Any CPU
{38EE36C6-892C-4C94-8BB0-1ACB164E1F20}.Release|x64.ActiveCfg = Release|Any CPU
{38EE36C6-892C-4C94-8BB0-1ACB164E1F20}.Release|x64.Build.0 = Release|Any CPU
{38EE36C6-892C-4C94-8BB0-1ACB164E1F20}.Release|x86.ActiveCfg = Release|Any CPU
{38EE36C6-892C-4C94-8BB0-1ACB164E1F20}.Release|x86.Build.0 = Release|Any CPU
{D432F3E9-3D2F-4623-B7B9-CEBA6701FFC3}.Debug|Any CPU.ActiveCfg = Debug|x64
{D432F3E9-3D2F-4623-B7B9-CEBA6701FFC3}.Debug|Any CPU.Build.0 = Debug|x64
{D432F3E9-3D2F-4623-B7B9-CEBA6701FFC3}.Debug|x64.ActiveCfg = Debug|x64
{D432F3E9-3D2F-4623-B7B9-CEBA6701FFC3}.Debug|x64.Build.0 = Debug|x64
{D432F3E9-3D2F-4623-B7B9-CEBA6701FFC3}.Debug|x86.ActiveCfg = Debug|x64
{D432F3E9-3D2F-4623-B7B9-CEBA6701FFC3}.Debug|x86.Build.0 = Debug|x64
{D432F3E9-3D2F-4623-B7B9-CEBA6701FFC3}.Release|Any CPU.ActiveCfg = Release|x64
{D432F3E9-3D2F-4623-B7B9-CEBA6701FFC3}.Release|Any CPU.Build.0 = Release|x64
{D432F3E9-3D2F-4623-B7B9-CEBA6701FFC3}.Release|x64.ActiveCfg = Release|x64
{D432F3E9-3D2F-4623-B7B9-CEBA6701FFC3}.Release|x64.Build.0 = Release|x64
{D432F3E9-3D2F-4623-B7B9-CEBA6701FFC3}.Release|x86.ActiveCfg = Release|x64
{D432F3E9-3D2F-4623-B7B9-CEBA6701FFC3}.Release|x86.Build.0 = Release|x64
{DD00F5D5-6C2F-4FDA-AE3D-25CF01A9A224}.Debug|Any CPU.ActiveCfg = Debug|x64
{DD00F5D5-6C2F-4FDA-AE3D-25CF01A9A224}.Debug|Any CPU.Build.0 = Debug|x64
{DD00F5D5-6C2F-4FDA-AE3D-25CF01A9A224}.Debug|x64.ActiveCfg = Debug|x64
{DD00F5D5-6C2F-4FDA-AE3D-25CF01A9A224}.Debug|x64.Build.0 = Debug|x64
{DD00F5D5-6C2F-4FDA-AE3D-25CF01A9A224}.Debug|x86.ActiveCfg = Debug|x64
{DD00F5D5-6C2F-4FDA-AE3D-25CF01A9A224}.Debug|x86.Build.0 = Debug|x64
{DD00F5D5-6C2F-4FDA-AE3D-25CF01A9A224}.Release|Any CPU.ActiveCfg = Release|x64
{DD00F5D5-6C2F-4FDA-AE3D-25CF01A9A224}.Release|Any CPU.Build.0 = Release|x64
{DD00F5D5-6C2F-4FDA-AE3D-25CF01A9A224}.Release|x64.ActiveCfg = Release|x64
{DD00F5D5-6C2F-4FDA-AE3D-25CF01A9A224}.Release|x64.Build.0 = Release|x64
{DD00F5D5-6C2F-4FDA-AE3D-25CF01A9A224}.Release|x86.ActiveCfg = Release|x64
{DD00F5D5-6C2F-4FDA-AE3D-25CF01A9A224}.Release|x86.Build.0 = Release|x64
{2B8243FF-60C6-4607-8AAE-7762D29B0A48}.Debug|Any CPU.ActiveCfg = Debug|x64
{2B8243FF-60C6-4607-8AAE-7762D29B0A48}.Debug|Any CPU.Build.0 = Debug|x64
{2B8243FF-60C6-4607-8AAE-7762D29B0A48}.Debug|x64.ActiveCfg = Debug|x64
{2B8243FF-60C6-4607-8AAE-7762D29B0A48}.Debug|x64.Build.0 = Debug|x64
{2B8243FF-60C6-4607-8AAE-7762D29B0A48}.Debug|x86.ActiveCfg = Debug|x64
{2B8243FF-60C6-4607-8AAE-7762D29B0A48}.Debug|x86.Build.0 = Debug|x64
{2B8243FF-60C6-4607-8AAE-7762D29B0A48}.Release|Any CPU.ActiveCfg = Release|x64
{2B8243FF-60C6-4607-8AAE-7762D29B0A48}.Release|Any CPU.Build.0 = Release|x64
{2B8243FF-60C6-4607-8AAE-7762D29B0A48}.Release|x64.ActiveCfg = Release|x64
{2B8243FF-60C6-4607-8AAE-7762D29B0A48}.Release|x64.Build.0 = Release|x64
{2B8243FF-60C6-4607-8AAE-7762D29B0A48}.Release|x86.ActiveCfg = Release|x64
{2B8243FF-60C6-4607-8AAE-7762D29B0A48}.Release|x86.Build.0 = Release|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Debug|x64.ActiveCfg = Debug|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Debug|x64.Build.0 = Debug|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|x64.ActiveCfg = Release|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|x64.Build.0 = Release|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|x64.ActiveCfg = Release|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|x64.Build.0 = Release|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|x64.Build.0 = Release|x64
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Debug|x64.ActiveCfg = Debug|x64
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Debug|x64.Build.0 = Debug|x64
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.MinSizeRel|x64.ActiveCfg = Release|x64
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.MinSizeRel|x64.Build.0 = Release|x64
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Release|x64.ActiveCfg = Release|x64
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Release|x64.Build.0 = Release|x64
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.RelWithDebInfo|x64.Build.0 = Release|x64
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Debug|x64.ActiveCfg = Debug|x64
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Debug|x64.Build.0 = Debug|x64
{387566C6-C6F6-412C-A30C-9855BBCB4816}.MinSizeRel|x64.ActiveCfg = Debug|x64
{387566C6-C6F6-412C-A30C-9855BBCB4816}.MinSizeRel|x64.Build.0 = Debug|x64
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Release|x64.ActiveCfg = Release|x64
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Release|x64.Build.0 = Release|x64
{387566C6-C6F6-412C-A30C-9855BBCB4816}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{387566C6-C6F6-412C-A30C-9855BBCB4816}.RelWithDebInfo|x64.Build.0 = Release|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Debug|x64.ActiveCfg = Debug|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Debug|x64.Build.0 = Debug|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|x64.ActiveCfg = Release|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|x64.Build.0 = Release|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Release|x64.ActiveCfg = Release|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Release|x64.Build.0 = Release|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|x64.Build.0 = Release|x64
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Debug|x64.ActiveCfg = Debug|x64
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Debug|x64.Build.0 = Debug|x64
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.MinSizeRel|x64.ActiveCfg = Release|x64
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.MinSizeRel|x64.Build.0 = Release|x64
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Release|x64.ActiveCfg = Release|x64
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Release|x64.Build.0 = Release|x64
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.RelWithDebInfo|x64.Build.0 = Release|x64
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Debug|x64.ActiveCfg = Debug|x64
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Debug|x64.Build.0 = Debug|x64
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.MinSizeRel|x64.ActiveCfg = Debug|x64
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.MinSizeRel|x64.Build.0 = Debug|x64
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Release|x64.ActiveCfg = Release|x64
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Release|x64.Build.0 = Release|x64
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|x64.Build.0 = Release|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.Debug|x64.ActiveCfg = Debug|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.Debug|x64.Build.0 = Debug|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.MinSizeRel|x64.ActiveCfg = Debug|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.MinSizeRel|x64.Build.0 = Debug|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.Release|x64.ActiveCfg = Release|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.Release|x64.Build.0 = Release|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.RelWithDebInfo|x64.Build.0 = Release|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Debug|x64.ActiveCfg = Debug|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Debug|x64.Build.0 = Debug|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.MinSizeRel|x64.ActiveCfg = Debug|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.MinSizeRel|x64.Build.0 = Debug|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Release|x64.ActiveCfg = Release|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Release|x64.Build.0 = Release|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.RelWithDebInfo|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{D7C6B9C7-1058-B1EA-FEE6-34C56B05AEDB} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
{684863A1-3396-4D31-A731-C0725CF07F4E} = {D7C6B9C7-1058-B1EA-FEE6-34C56B05AEDB}
{45292808-4EF3-4D4A-B3F5-B75C42EE5870} = {D7C6B9C7-1058-B1EA-FEE6-34C56B05AEDB}
{AA57F8D9-7BD6-4161-881B-AD2CEF9A30F6} = {D7C6B9C7-1058-B1EA-FEE6-34C56B05AEDB}
{28A26DF7-5F7A-43A2-A548-B55FEBCC3958} = {D7C6B9C7-1058-B1EA-FEE6-34C56B05AEDB}
{7543386A-5EBA-4AF0-9E0F-35657B58557D} = {D7C6B9C7-1058-B1EA-FEE6-34C56B05AEDB}
{60E0D592-FFB3-0D0A-C4AA-E88919B48F9D} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
{C13A5ABD-F739-4BE8-A2FE-511E989A5B43} = {60E0D592-FFB3-0D0A-C4AA-E88919B48F9D}
{F7C6F079-67BA-4899-9B43-D3F8C121D264} = {60E0D592-FFB3-0D0A-C4AA-E88919B48F9D}
{E60C119D-2919-4E2F-9D39-90DB1A8FF9A7} = {60E0D592-FFB3-0D0A-C4AA-E88919B48F9D}
{ECBAA198-EC93-4174-8156-BDA5F5E95042} = {60E0D592-FFB3-0D0A-C4AA-E88919B48F9D}
{F54AE5C0-2ECA-4151-82E6-0D7EFE88FF40} = {60E0D592-FFB3-0D0A-C4AA-E88919B48F9D}
{A898C6C3-F134-4AF0-AFB3-3834C58CC0D7} = {60E0D592-FFB3-0D0A-C4AA-E88919B48F9D}
{1E296FB3-D185-4A95-A1EB-AA5B37B85C60} = {60E0D592-FFB3-0D0A-C4AA-E88919B48F9D}
{B6070F41-8759-448B-B56D-A7D15D489569} = {60E0D592-FFB3-0D0A-C4AA-E88919B48F9D}
{B2D721AB-920C-4CD6-8DBF-6778A115A449} = {60E0D592-FFB3-0D0A-C4AA-E88919B48F9D}
{38EE36C6-892C-4C94-8BB0-1ACB164E1F20} = {60E0D592-FFB3-0D0A-C4AA-E88919B48F9D}
{C5A3B5EA-BE9F-76E5-E9B8-8A22B289B295} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
{42C014A0-00C5-0620-8552-38912E891A7F} = {C5A3B5EA-BE9F-76E5-E9B8-8A22B289B295}
{D432F3E9-3D2F-4623-B7B9-CEBA6701FFC3} = {42C014A0-00C5-0620-8552-38912E891A7F}
{DD00F5D5-6C2F-4FDA-AE3D-25CF01A9A224} = {C5A3B5EA-BE9F-76E5-E9B8-8A22B289B295}
{2B8243FF-60C6-4607-8AAE-7762D29B0A48} = {C5A3B5EA-BE9F-76E5-E9B8-8A22B289B295}
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {422D1620-0166-4C26-9A81-CA8A2EB1AB58}
EndGlobalSection
GlobalSection(Performance) = preSolution
HasPerformanceSessions = true
EndGlobalSection
EndGlobal
@@ -8,6 +8,7 @@
public int Integer;
public double Real;
public string Identifier;
public DateTime DateTime;
public ImmutableList<IArithmeticExpression> Arguments;
public ImmutableList<Assignment> Assignments;
public IArithmeticExpression Argument;
@@ -11,20 +11,10 @@
<PackageReference Include="YaccLexTools" Version="1.2.2" />
</ItemGroup>
<Choose>
<When Condition="'$(UseProjectRefs)' == 'true'">
<ItemGroup>
<ProjectReference Include="..\ExpressionCore\ExpressionCore.csproj" />
<ProjectReference Include="..\..\cs\Bts.Spark.Core\Bts.Spark.Core.csproj" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<PackageReference Include="ExpressionCore" Version="$(SparkVersion)" />
<PackageReference Include="Bts.Spark.Core" Version="$(SparkVersion)" />
</ItemGroup>
</Otherwise>
</Choose>
<ItemGroup>
<ProjectReference Include="..\ExpressionCore\ExpressionCore.csproj" />
<ProjectReference Include="..\..\client\spark_core\spark_core.csproj" />
</ItemGroup>
<ItemGroup Label="ArithmeticExpression">
<Scanner Include="ArithmeticExpressionTokens.lex" />
File diff suppressed because it is too large. Load diff
@@ -5,5 +5,9 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\client\spark_core\spark_core.csproj" />
</ItemGroup>
</Project>
+34 -15
View File
@@ -1,22 +1,41 @@
using System.Diagnostics;
using mbts.spark;
namespace BCG.Utilities.General;
using System;
using System.Runtime;
/// <summary>
/// Summary description for Crono.
/// </summary>
public class Crono {
readonly Stopwatch myTimer = new();
namespace BCG.Utilities.General
{
/// <summary>
/// Summary description for Crono.
/// </summary>
public class Crono
{
public Crono()
{
myTimer = new HighPerformanceTimer();
}
public void start() =>
myTimer.Start();
public void start()
{myTimer.start();}
public void stop() =>
myTimer.Stop();
public void stop()
{myTimer.stop();}
public TimeSpan time =>
myTimer.Elapsed;
public TimeSpan time
{
get
{
return new TimeSpan((long) (myTimer.totalMilliseconds * TimeSpan.TicksPerMillisecond));
}
}
public double miliseconds
{
get
{return myTimer.totalMilliseconds;}
}
private HighPerformanceTimer myTimer;
}
public double miliseconds =>
myTimer.Elapsed.TotalMilliseconds;
}
@@ -1 +0,0 @@
r=TimeSeriesStream(ReplayFutureLiveBBOStream("ES"))
@@ -1,3 +0,0 @@
x,y,z,id
123,1.001,abc,1
123,1.001,abc,0
1 x y z id
2 123 1.001 abc 1
3 123 1.001 abc 0
@@ -1,3 +0,0 @@
x,y,z,id
123,1.001,abc,1
123,1.001,abc,0
1 x y z id
2 123 1.001 abc 1
3 123 1.001 abc 0
@@ -1,78 +0,0 @@
id,ts_event,contract,bid_price,bid_size,ask_price,ask_size,timestamp
76,2026-03-13T05:57:25.177965500Z,ESU5,6363.75,51,6364,63,3/13/2026 5:57:25 AM
75,2026-03-13T05:57:25.068062900Z,ESU5,6363.75,52,6364,63,3/13/2026 5:57:25 AM
74,2026-03-13T05:57:24.963428500Z,ESU5,6363.75,56,6364,63,3/13/2026 5:57:24 AM
73,2026-03-13T05:57:24.781215700Z,ESU5,6363.75,57,6364,63,3/13/2026 5:57:24 AM
72,2026-03-13T05:57:24.676290100Z,ESU5,6363.75,57,6364,63,3/13/2026 5:57:24 AM
71,2026-03-13T05:57:24.566898400Z,ESU5,6363.75,56,6364,63,3/13/2026 5:57:24 AM
70,2026-03-13T05:57:24.430800400Z,ESU5,6363.75,57,6364,63,3/13/2026 5:57:24 AM
69,2026-03-13T05:57:24.273683400Z,ESU5,6363.75,56,6364,63,3/13/2026 5:57:24 AM
68,2026-03-13T05:57:24.167656100Z,ESU5,6363.75,56,6364,64,3/13/2026 5:57:24 AM
67,2026-03-13T05:57:23.995720100Z,ESU5,6363.75,56,6364,65,3/13/2026 5:57:23 AM
66,2026-03-13T05:57:23.894029100Z,ESU5,6363.75,56,6364,68,3/13/2026 5:57:23 AM
65,2026-03-13T05:57:23.728897300Z,ESU5,6363.75,56,6364,68,3/13/2026 5:57:23 AM
64,2026-03-13T05:57:23.614316800Z,ESU5,6363.75,52,6364,68,3/13/2026 5:57:23 AM
63,2026-03-13T05:57:23.503752700Z,ESU5,6363.75,51,6364,68,3/13/2026 5:57:23 AM
62,2026-03-13T05:57:23.289108200Z,ESU5,6363.75,50,6364,68,3/13/2026 5:57:23 AM
61,2026-03-13T05:57:23.155673400Z,ESU5,6363.75,49,6364,68,3/13/2026 5:57:23 AM
60,2026-03-13T05:57:23.028898400Z,ESU5,6363.75,48,6364,68,3/13/2026 5:57:23 AM
59,2026-03-13T05:57:22.887132700Z,ESU5,6363.75,46,6364,68,3/13/2026 5:57:22 AM
58,2026-03-13T05:57:22.676916300Z,ESU5,6363.75,44,6364,68,3/13/2026 5:57:22 AM
57,2026-03-13T05:57:22.520328000Z,ESU5,6363.75,43,6364,68,3/13/2026 5:57:22 AM
56,2026-03-13T05:57:22.405244600Z,ESU5,6363.75,43,6364,69,3/13/2026 5:57:22 AM
55,2026-03-13T05:57:22.294674100Z,ESU5,6363.75,41,6364,69,3/13/2026 5:57:22 AM
54,2026-03-13T05:57:22.163467900Z,ESU5,6363.75,38,6364,69,3/13/2026 5:57:22 AM
53,2026-03-13T05:57:21.992443000Z,ESU5,6363.75,38,6364,71,3/13/2026 5:57:21 AM
52,2026-03-13T05:57:21.872338400Z,ESU5,6363.75,38,6364,71,3/13/2026 5:57:21 AM
51,2026-03-13T05:57:21.742801800Z,ESU5,6363.75,37,6364,71,3/13/2026 5:57:21 AM
50,2026-03-13T05:57:21.557711100Z,ESU5,6363.75,37,6364,72,3/13/2026 5:57:21 AM
49,2026-03-13T05:57:21.434977000Z,ESU5,6363.75,37,6364,73,3/13/2026 5:57:21 AM
48,2026-03-13T05:57:21.285751600Z,ESU5,6363.75,37,6364,72,3/13/2026 5:57:21 AM
47,2026-03-13T05:57:21.184392000Z,ESU5,6363.75,37,6364,73,3/13/2026 5:57:21 AM
46,2026-03-13T05:57:21.076843800Z,ESU5,6363.75,34,6364,73,3/13/2026 5:57:21 AM
45,2026-03-13T05:57:20.894131800Z,ESU5,6363.75,32,6364,73,3/13/2026 5:57:20 AM
44,2026-03-13T05:57:20.759550000Z,ESU5,6363.75,30,6364,73,3/13/2026 5:57:20 AM
43,2026-03-13T05:57:20.641547900Z,ESU5,6363.75,28,6364,73,3/13/2026 5:57:20 AM
42,2026-03-13T05:57:20.540293200Z,ESU5,6363.75,27,6364,73,3/13/2026 5:57:20 AM
41,2026-03-13T05:57:20.439034600Z,ESU5,6363.75,27,6364,74,3/13/2026 5:57:20 AM
40,2026-03-13T05:57:20.337795000Z,ESU5,6363.75,27,6364,73,3/13/2026 5:57:20 AM
39,2026-03-13T05:57:20.236606600Z,ESU5,6363.75,27,6364,72,3/13/2026 5:57:20 AM
38,2026-03-13T05:57:20.135417700Z,ESU5,6363.75,30,6364,72,3/13/2026 5:57:20 AM
37,2026-03-13T05:57:20.034272700Z,ESU5,6363.75,32,6364,72,3/13/2026 5:57:20 AM
36,2026-03-13T05:57:19.933096800Z,ESU5,6363.75,34,6364,72,3/13/2026 5:57:19 AM
35,2026-03-13T05:57:19.832012600Z,ESU5,6363.75,36,6364,72,3/13/2026 5:57:19 AM
34,2026-03-13T05:57:19.730878500Z,ESU5,6363.75,38,6364,72,3/13/2026 5:57:19 AM
33,2026-03-13T05:57:19.629787400Z,ESU5,6363.75,38,6364,71,3/13/2026 5:57:19 AM
32,2026-03-13T05:57:19.528697000Z,ESU5,6363.75,38,6364,70,3/13/2026 5:57:19 AM
31,2026-03-13T05:57:19.427077000Z,ESU5,6363.75,38,6364,71,3/13/2026 5:57:19 AM
30,2026-03-13T05:57:19.326450300Z,ESU5,6363.75,39,6364,71,3/13/2026 5:57:19 AM
29,2026-03-13T05:57:19.225427900Z,ESU5,6363.75,39,6364,70,3/13/2026 5:57:19 AM
28,2026-03-13T05:57:19.123339800Z,ESU5,6363.75,40,6364,70,3/13/2026 5:57:19 AM
27,2026-03-13T05:57:19.021936500Z,ESU5,6363.75,41,6364,70,3/13/2026 5:57:19 AM
26,2026-03-13T05:57:18.920859200Z,ESU5,6363.75,45,6364,70,3/13/2026 5:57:18 AM
25,2026-03-13T05:57:18.820148400Z,ESU5,6363.75,46,6364,70,3/13/2026 5:57:18 AM
24,2026-03-13T05:57:18.718988100Z,ESU5,6363.75,46,6364,69,3/13/2026 5:57:18 AM
23,2026-03-13T05:57:18.618299700Z,ESU5,6363.75,49,6364,69,3/13/2026 5:57:18 AM
22,2026-03-13T05:57:18.517138100Z,ESU5,6363.75,52,6364,69,3/13/2026 5:57:18 AM
21,2026-03-13T05:57:18.416335200Z,ESU5,6363.75,53,6364,69,3/13/2026 5:57:18 AM
20,2026-03-13T05:57:18.315335900Z,ESU5,6363.75,55,6364,69,3/13/2026 5:57:18 AM
19,2026-03-13T05:57:18.214368600Z,ESU5,6363.75,57,6364,69,3/13/2026 5:57:18 AM
18,2026-03-13T05:57:18.113754700Z,ESU5,6363.75,57,6364,65,3/13/2026 5:57:18 AM
17,2026-03-13T05:57:18.012706500Z,ESU5,6363.75,56,6364,65,3/13/2026 5:57:18 AM
16,2026-03-13T05:57:17.911672600Z,ESU5,6363.75,54,6364,65,3/13/2026 5:57:17 AM
15,2026-03-13T05:57:17.810879900Z,ESU5,6363.75,52,6364,65,3/13/2026 5:57:17 AM
14,2026-03-13T05:57:17.710089700Z,ESU5,6363.75,49,6364,65,3/13/2026 5:57:17 AM
13,2026-03-13T05:57:17.609388300Z,ESU5,6363.75,49,6364,67,3/13/2026 5:57:17 AM
12,2026-03-13T05:57:17.508697400Z,ESU5,6363.75,49,6364,67,3/13/2026 5:57:17 AM
11,2026-03-13T05:57:17.408027000Z,ESU5,6363.75,53,6364,67,3/13/2026 5:57:17 AM
10,2026-03-13T05:57:17.307406200Z,ESU5,6363.75,49,6364,67,3/13/2026 5:57:17 AM
9,2026-03-13T05:57:17.206714300Z,ESU5,6363.75,49,6364,71,3/13/2026 5:57:17 AM
8,2026-03-13T05:57:17.105530300Z,ESU5,6363.75,48,6364,71,3/13/2026 5:57:17 AM
7,2026-03-13T05:57:17.004796800Z,ESU5,6363.75,47,6364,71,3/13/2026 5:57:17 AM
6,2026-03-13T05:57:16.904113900Z,ESU5,6363.75,46,6364,71,3/13/2026 5:57:16 AM
5,2026-03-13T05:57:16.803381900Z,ESU5,6363.75,43,6364,71,3/13/2026 5:57:16 AM
4,2026-03-13T05:57:16.701969600Z,ESU5,6363.75,43,6364,72,3/13/2026 5:57:16 AM
3,2026-03-13T05:57:16.600765600Z,ESU5,6363.75,43,6364,73,3/13/2026 5:57:16 AM
2,2026-03-13T05:57:16.499986300Z,ESU5,6363.75,43,6364,74,3/13/2026 5:57:16 AM
1,2026-03-13T05:57:16.399241700Z,ESU5,6363.75,43,6364,75,3/13/2026 5:57:16 AM
0,2026-03-13T05:57:16.264038000Z,ESU5,6363.75,43,6364,76,3/13/2026 5:57:16 AM
1 id ts_event contract bid_price bid_size ask_price ask_size timestamp
2 76 2026-03-13T05:57:25.177965500Z ESU5 6363.75 51 6364 63 3/13/2026 5:57:25 AM
3 75 2026-03-13T05:57:25.068062900Z ESU5 6363.75 52 6364 63 3/13/2026 5:57:25 AM
4 74 2026-03-13T05:57:24.963428500Z ESU5 6363.75 56 6364 63 3/13/2026 5:57:24 AM
5 73 2026-03-13T05:57:24.781215700Z ESU5 6363.75 57 6364 63 3/13/2026 5:57:24 AM
6 72 2026-03-13T05:57:24.676290100Z ESU5 6363.75 57 6364 63 3/13/2026 5:57:24 AM
7 71 2026-03-13T05:57:24.566898400Z ESU5 6363.75 56 6364 63 3/13/2026 5:57:24 AM
8 70 2026-03-13T05:57:24.430800400Z ESU5 6363.75 57 6364 63 3/13/2026 5:57:24 AM
9 69 2026-03-13T05:57:24.273683400Z ESU5 6363.75 56 6364 63 3/13/2026 5:57:24 AM
10 68 2026-03-13T05:57:24.167656100Z ESU5 6363.75 56 6364 64 3/13/2026 5:57:24 AM
11 67 2026-03-13T05:57:23.995720100Z ESU5 6363.75 56 6364 65 3/13/2026 5:57:23 AM
12 66 2026-03-13T05:57:23.894029100Z ESU5 6363.75 56 6364 68 3/13/2026 5:57:23 AM
13 65 2026-03-13T05:57:23.728897300Z ESU5 6363.75 56 6364 68 3/13/2026 5:57:23 AM
14 64 2026-03-13T05:57:23.614316800Z ESU5 6363.75 52 6364 68 3/13/2026 5:57:23 AM
15 63 2026-03-13T05:57:23.503752700Z ESU5 6363.75 51 6364 68 3/13/2026 5:57:23 AM
16 62 2026-03-13T05:57:23.289108200Z ESU5 6363.75 50 6364 68 3/13/2026 5:57:23 AM
17 61 2026-03-13T05:57:23.155673400Z ESU5 6363.75 49 6364 68 3/13/2026 5:57:23 AM
18 60 2026-03-13T05:57:23.028898400Z ESU5 6363.75 48 6364 68 3/13/2026 5:57:23 AM
19 59 2026-03-13T05:57:22.887132700Z ESU5 6363.75 46 6364 68 3/13/2026 5:57:22 AM
20 58 2026-03-13T05:57:22.676916300Z ESU5 6363.75 44 6364 68 3/13/2026 5:57:22 AM
21 57 2026-03-13T05:57:22.520328000Z ESU5 6363.75 43 6364 68 3/13/2026 5:57:22 AM
22 56 2026-03-13T05:57:22.405244600Z ESU5 6363.75 43 6364 69 3/13/2026 5:57:22 AM
23 55 2026-03-13T05:57:22.294674100Z ESU5 6363.75 41 6364 69 3/13/2026 5:57:22 AM
24 54 2026-03-13T05:57:22.163467900Z ESU5 6363.75 38 6364 69 3/13/2026 5:57:22 AM
25 53 2026-03-13T05:57:21.992443000Z ESU5 6363.75 38 6364 71 3/13/2026 5:57:21 AM
26 52 2026-03-13T05:57:21.872338400Z ESU5 6363.75 38 6364 71 3/13/2026 5:57:21 AM
27 51 2026-03-13T05:57:21.742801800Z ESU5 6363.75 37 6364 71 3/13/2026 5:57:21 AM
28 50 2026-03-13T05:57:21.557711100Z ESU5 6363.75 37 6364 72 3/13/2026 5:57:21 AM
29 49 2026-03-13T05:57:21.434977000Z ESU5 6363.75 37 6364 73 3/13/2026 5:57:21 AM
30 48 2026-03-13T05:57:21.285751600Z ESU5 6363.75 37 6364 72 3/13/2026 5:57:21 AM
31 47 2026-03-13T05:57:21.184392000Z ESU5 6363.75 37 6364 73 3/13/2026 5:57:21 AM
32 46 2026-03-13T05:57:21.076843800Z ESU5 6363.75 34 6364 73 3/13/2026 5:57:21 AM
33 45 2026-03-13T05:57:20.894131800Z ESU5 6363.75 32 6364 73 3/13/2026 5:57:20 AM
34 44 2026-03-13T05:57:20.759550000Z ESU5 6363.75 30 6364 73 3/13/2026 5:57:20 AM
35 43 2026-03-13T05:57:20.641547900Z ESU5 6363.75 28 6364 73 3/13/2026 5:57:20 AM
36 42 2026-03-13T05:57:20.540293200Z ESU5 6363.75 27 6364 73 3/13/2026 5:57:20 AM
37 41 2026-03-13T05:57:20.439034600Z ESU5 6363.75 27 6364 74 3/13/2026 5:57:20 AM
38 40 2026-03-13T05:57:20.337795000Z ESU5 6363.75 27 6364 73 3/13/2026 5:57:20 AM
39 39 2026-03-13T05:57:20.236606600Z ESU5 6363.75 27 6364 72 3/13/2026 5:57:20 AM
40 38 2026-03-13T05:57:20.135417700Z ESU5 6363.75 30 6364 72 3/13/2026 5:57:20 AM
41 37 2026-03-13T05:57:20.034272700Z ESU5 6363.75 32 6364 72 3/13/2026 5:57:20 AM
42 36 2026-03-13T05:57:19.933096800Z ESU5 6363.75 34 6364 72 3/13/2026 5:57:19 AM
43 35 2026-03-13T05:57:19.832012600Z ESU5 6363.75 36 6364 72 3/13/2026 5:57:19 AM
44 34 2026-03-13T05:57:19.730878500Z ESU5 6363.75 38 6364 72 3/13/2026 5:57:19 AM
45 33 2026-03-13T05:57:19.629787400Z ESU5 6363.75 38 6364 71 3/13/2026 5:57:19 AM
46 32 2026-03-13T05:57:19.528697000Z ESU5 6363.75 38 6364 70 3/13/2026 5:57:19 AM
47 31 2026-03-13T05:57:19.427077000Z ESU5 6363.75 38 6364 71 3/13/2026 5:57:19 AM
48 30 2026-03-13T05:57:19.326450300Z ESU5 6363.75 39 6364 71 3/13/2026 5:57:19 AM
49 29 2026-03-13T05:57:19.225427900Z ESU5 6363.75 39 6364 70 3/13/2026 5:57:19 AM
50 28 2026-03-13T05:57:19.123339800Z ESU5 6363.75 40 6364 70 3/13/2026 5:57:19 AM
51 27 2026-03-13T05:57:19.021936500Z ESU5 6363.75 41 6364 70 3/13/2026 5:57:19 AM
52 26 2026-03-13T05:57:18.920859200Z ESU5 6363.75 45 6364 70 3/13/2026 5:57:18 AM
53 25 2026-03-13T05:57:18.820148400Z ESU5 6363.75 46 6364 70 3/13/2026 5:57:18 AM
54 24 2026-03-13T05:57:18.718988100Z ESU5 6363.75 46 6364 69 3/13/2026 5:57:18 AM
55 23 2026-03-13T05:57:18.618299700Z ESU5 6363.75 49 6364 69 3/13/2026 5:57:18 AM
56 22 2026-03-13T05:57:18.517138100Z ESU5 6363.75 52 6364 69 3/13/2026 5:57:18 AM
57 21 2026-03-13T05:57:18.416335200Z ESU5 6363.75 53 6364 69 3/13/2026 5:57:18 AM
58 20 2026-03-13T05:57:18.315335900Z ESU5 6363.75 55 6364 69 3/13/2026 5:57:18 AM
59 19 2026-03-13T05:57:18.214368600Z ESU5 6363.75 57 6364 69 3/13/2026 5:57:18 AM
60 18 2026-03-13T05:57:18.113754700Z ESU5 6363.75 57 6364 65 3/13/2026 5:57:18 AM
61 17 2026-03-13T05:57:18.012706500Z ESU5 6363.75 56 6364 65 3/13/2026 5:57:18 AM
62 16 2026-03-13T05:57:17.911672600Z ESU5 6363.75 54 6364 65 3/13/2026 5:57:17 AM
63 15 2026-03-13T05:57:17.810879900Z ESU5 6363.75 52 6364 65 3/13/2026 5:57:17 AM
64 14 2026-03-13T05:57:17.710089700Z ESU5 6363.75 49 6364 65 3/13/2026 5:57:17 AM
65 13 2026-03-13T05:57:17.609388300Z ESU5 6363.75 49 6364 67 3/13/2026 5:57:17 AM
66 12 2026-03-13T05:57:17.508697400Z ESU5 6363.75 49 6364 67 3/13/2026 5:57:17 AM
67 11 2026-03-13T05:57:17.408027000Z ESU5 6363.75 53 6364 67 3/13/2026 5:57:17 AM
68 10 2026-03-13T05:57:17.307406200Z ESU5 6363.75 49 6364 67 3/13/2026 5:57:17 AM
69 9 2026-03-13T05:57:17.206714300Z ESU5 6363.75 49 6364 71 3/13/2026 5:57:17 AM
70 8 2026-03-13T05:57:17.105530300Z ESU5 6363.75 48 6364 71 3/13/2026 5:57:17 AM
71 7 2026-03-13T05:57:17.004796800Z ESU5 6363.75 47 6364 71 3/13/2026 5:57:17 AM
72 6 2026-03-13T05:57:16.904113900Z ESU5 6363.75 46 6364 71 3/13/2026 5:57:16 AM
73 5 2026-03-13T05:57:16.803381900Z ESU5 6363.75 43 6364 71 3/13/2026 5:57:16 AM
74 4 2026-03-13T05:57:16.701969600Z ESU5 6363.75 43 6364 72 3/13/2026 5:57:16 AM
75 3 2026-03-13T05:57:16.600765600Z ESU5 6363.75 43 6364 73 3/13/2026 5:57:16 AM
76 2 2026-03-13T05:57:16.499986300Z ESU5 6363.75 43 6364 74 3/13/2026 5:57:16 AM
77 1 2026-03-13T05:57:16.399241700Z ESU5 6363.75 43 6364 75 3/13/2026 5:57:16 AM
78 0 2026-03-13T05:57:16.264038000Z ESU5 6363.75 43 6364 76 3/13/2026 5:57:16 AM
@@ -1,91 +0,0 @@
id,ts_event,contract,bid_price,bid_size,ask_price,ask_size,timestamp
89,2026-03-13T05:57:26.904401600Z,ESU5,6363.75,43,6364,67,3/13/2026 5:57:26 AM
88,2026-03-13T05:57:26.778037200Z,ESU5,6363.75,43,6364,69,3/13/2026 5:57:26 AM
87,2026-03-13T05:57:26.597038500Z,ESU5,6363.75,43,6364,69,3/13/2026 5:57:26 AM
86,2026-03-13T05:57:26.438768300Z,ESU5,6363.75,43,6364,68,3/13/2026 5:57:26 AM
85,2026-03-13T05:57:26.328259100Z,ESU5,6363.75,43,6364,67,3/13/2026 5:57:26 AM
84,2026-03-13T05:57:26.216211200Z,ESU5,6363.75,44,6364,67,3/13/2026 5:57:26 AM
83,2026-03-13T05:57:26.099281200Z,ESU5,6363.75,46,6364,67,3/13/2026 5:57:26 AM
82,2026-03-13T05:57:25.979814900Z,ESU5,6363.75,48,6364,67,3/13/2026 5:57:25 AM
81,2026-03-13T05:57:25.852317700Z,ESU5,6363.75,48,6364,66,3/13/2026 5:57:25 AM
80,2026-03-13T05:57:25.684323100Z,ESU5,6363.75,48,6364,65,3/13/2026 5:57:25 AM
79,2026-03-13T05:57:25.539436900Z,ESU5,6363.75,48,6364,64,3/13/2026 5:57:25 AM
78,2026-03-13T05:57:25.425439200Z,ESU5,6363.75,49,6364,64,3/13/2026 5:57:25 AM
77,2026-03-13T05:57:25.298054100Z,ESU5,6363.75,51,6364,64,3/13/2026 5:57:25 AM
76,2026-03-13T05:57:25.177965500Z,ESU5,6363.75,51,6364,63,3/13/2026 5:57:25 AM
75,2026-03-13T05:57:25.068062900Z,ESU5,6363.75,52,6364,63,3/13/2026 5:57:25 AM
74,2026-03-13T05:57:24.963428500Z,ESU5,6363.75,56,6364,63,3/13/2026 5:57:24 AM
73,2026-03-13T05:57:24.781215700Z,ESU5,6363.75,57,6364,63,3/13/2026 5:57:24 AM
72,2026-03-13T05:57:24.676290100Z,ESU5,6363.75,57,6364,63,3/13/2026 5:57:24 AM
71,2026-03-13T05:57:24.566898400Z,ESU5,6363.75,56,6364,63,3/13/2026 5:57:24 AM
70,2026-03-13T05:57:24.430800400Z,ESU5,6363.75,57,6364,63,3/13/2026 5:57:24 AM
69,2026-03-13T05:57:24.273683400Z,ESU5,6363.75,56,6364,63,3/13/2026 5:57:24 AM
68,2026-03-13T05:57:24.167656100Z,ESU5,6363.75,56,6364,64,3/13/2026 5:57:24 AM
67,2026-03-13T05:57:23.995720100Z,ESU5,6363.75,56,6364,65,3/13/2026 5:57:23 AM
66,2026-03-13T05:57:23.894029100Z,ESU5,6363.75,56,6364,68,3/13/2026 5:57:23 AM
65,2026-03-13T05:57:23.728897300Z,ESU5,6363.75,56,6364,68,3/13/2026 5:57:23 AM
64,2026-03-13T05:57:23.614316800Z,ESU5,6363.75,52,6364,68,3/13/2026 5:57:23 AM
63,2026-03-13T05:57:23.503752700Z,ESU5,6363.75,51,6364,68,3/13/2026 5:57:23 AM
62,2026-03-13T05:57:23.289108200Z,ESU5,6363.75,50,6364,68,3/13/2026 5:57:23 AM
61,2026-03-13T05:57:23.155673400Z,ESU5,6363.75,49,6364,68,3/13/2026 5:57:23 AM
60,2026-03-13T05:57:23.028898400Z,ESU5,6363.75,48,6364,68,3/13/2026 5:57:23 AM
59,2026-03-13T05:57:22.887132700Z,ESU5,6363.75,46,6364,68,3/13/2026 5:57:22 AM
58,2026-03-13T05:57:22.676916300Z,ESU5,6363.75,44,6364,68,3/13/2026 5:57:22 AM
57,2026-03-13T05:57:22.520328000Z,ESU5,6363.75,43,6364,68,3/13/2026 5:57:22 AM
56,2026-03-13T05:57:22.405244600Z,ESU5,6363.75,43,6364,69,3/13/2026 5:57:22 AM
55,2026-03-13T05:57:22.294674100Z,ESU5,6363.75,41,6364,69,3/13/2026 5:57:22 AM
54,2026-03-13T05:57:22.163467900Z,ESU5,6363.75,38,6364,69,3/13/2026 5:57:22 AM
53,2026-03-13T05:57:21.992443000Z,ESU5,6363.75,38,6364,71,3/13/2026 5:57:21 AM
52,2026-03-13T05:57:21.872338400Z,ESU5,6363.75,38,6364,71,3/13/2026 5:57:21 AM
51,2026-03-13T05:57:21.742801800Z,ESU5,6363.75,37,6364,71,3/13/2026 5:57:21 AM
50,2026-03-13T05:57:21.557711100Z,ESU5,6363.75,37,6364,72,3/13/2026 5:57:21 AM
49,2026-03-13T05:57:21.434977000Z,ESU5,6363.75,37,6364,73,3/13/2026 5:57:21 AM
48,2026-03-13T05:57:21.285751600Z,ESU5,6363.75,37,6364,72,3/13/2026 5:57:21 AM
47,2026-03-13T05:57:21.184392000Z,ESU5,6363.75,37,6364,73,3/13/2026 5:57:21 AM
46,2026-03-13T05:57:21.076843800Z,ESU5,6363.75,34,6364,73,3/13/2026 5:57:21 AM
45,2026-03-13T05:57:20.894131800Z,ESU5,6363.75,32,6364,73,3/13/2026 5:57:20 AM
44,2026-03-13T05:57:20.759550000Z,ESU5,6363.75,30,6364,73,3/13/2026 5:57:20 AM
43,2026-03-13T05:57:20.641547900Z,ESU5,6363.75,28,6364,73,3/13/2026 5:57:20 AM
42,2026-03-13T05:57:20.540293200Z,ESU5,6363.75,27,6364,73,3/13/2026 5:57:20 AM
41,2026-03-13T05:57:20.439034600Z,ESU5,6363.75,27,6364,74,3/13/2026 5:57:20 AM
40,2026-03-13T05:57:20.337795000Z,ESU5,6363.75,27,6364,73,3/13/2026 5:57:20 AM
39,2026-03-13T05:57:20.236606600Z,ESU5,6363.75,27,6364,72,3/13/2026 5:57:20 AM
38,2026-03-13T05:57:20.135417700Z,ESU5,6363.75,30,6364,72,3/13/2026 5:57:20 AM
37,2026-03-13T05:57:20.034272700Z,ESU5,6363.75,32,6364,72,3/13/2026 5:57:20 AM
36,2026-03-13T05:57:19.933096800Z,ESU5,6363.75,34,6364,72,3/13/2026 5:57:19 AM
35,2026-03-13T05:57:19.832012600Z,ESU5,6363.75,36,6364,72,3/13/2026 5:57:19 AM
34,2026-03-13T05:57:19.730878500Z,ESU5,6363.75,38,6364,72,3/13/2026 5:57:19 AM
33,2026-03-13T05:57:19.629787400Z,ESU5,6363.75,38,6364,71,3/13/2026 5:57:19 AM
32,2026-03-13T05:57:19.528697000Z,ESU5,6363.75,38,6364,70,3/13/2026 5:57:19 AM
31,2026-03-13T05:57:19.427077000Z,ESU5,6363.75,38,6364,71,3/13/2026 5:57:19 AM
30,2026-03-13T05:57:19.326450300Z,ESU5,6363.75,39,6364,71,3/13/2026 5:57:19 AM
29,2026-03-13T05:57:19.225427900Z,ESU5,6363.75,39,6364,70,3/13/2026 5:57:19 AM
28,2026-03-13T05:57:19.123339800Z,ESU5,6363.75,40,6364,70,3/13/2026 5:57:19 AM
27,2026-03-13T05:57:19.021936500Z,ESU5,6363.75,41,6364,70,3/13/2026 5:57:19 AM
26,2026-03-13T05:57:18.920859200Z,ESU5,6363.75,45,6364,70,3/13/2026 5:57:18 AM
25,2026-03-13T05:57:18.820148400Z,ESU5,6363.75,46,6364,70,3/13/2026 5:57:18 AM
24,2026-03-13T05:57:18.718988100Z,ESU5,6363.75,46,6364,69,3/13/2026 5:57:18 AM
23,2026-03-13T05:57:18.618299700Z,ESU5,6363.75,49,6364,69,3/13/2026 5:57:18 AM
22,2026-03-13T05:57:18.517138100Z,ESU5,6363.75,52,6364,69,3/13/2026 5:57:18 AM
21,2026-03-13T05:57:18.416335200Z,ESU5,6363.75,53,6364,69,3/13/2026 5:57:18 AM
20,2026-03-13T05:57:18.315335900Z,ESU5,6363.75,55,6364,69,3/13/2026 5:57:18 AM
19,2026-03-13T05:57:18.214368600Z,ESU5,6363.75,57,6364,69,3/13/2026 5:57:18 AM
18,2026-03-13T05:57:18.113754700Z,ESU5,6363.75,57,6364,65,3/13/2026 5:57:18 AM
17,2026-03-13T05:57:18.012706500Z,ESU5,6363.75,56,6364,65,3/13/2026 5:57:18 AM
16,2026-03-13T05:57:17.911672600Z,ESU5,6363.75,54,6364,65,3/13/2026 5:57:17 AM
15,2026-03-13T05:57:17.810879900Z,ESU5,6363.75,52,6364,65,3/13/2026 5:57:17 AM
14,2026-03-13T05:57:17.710089700Z,ESU5,6363.75,49,6364,65,3/13/2026 5:57:17 AM
13,2026-03-13T05:57:17.609388300Z,ESU5,6363.75,49,6364,67,3/13/2026 5:57:17 AM
12,2026-03-13T05:57:17.508697400Z,ESU5,6363.75,49,6364,67,3/13/2026 5:57:17 AM
11,2026-03-13T05:57:17.408027000Z,ESU5,6363.75,53,6364,67,3/13/2026 5:57:17 AM
10,2026-03-13T05:57:17.307406200Z,ESU5,6363.75,49,6364,67,3/13/2026 5:57:17 AM
9,2026-03-13T05:57:17.206714300Z,ESU5,6363.75,49,6364,71,3/13/2026 5:57:17 AM
8,2026-03-13T05:57:17.105530300Z,ESU5,6363.75,48,6364,71,3/13/2026 5:57:17 AM
7,2026-03-13T05:57:17.004796800Z,ESU5,6363.75,47,6364,71,3/13/2026 5:57:17 AM
6,2026-03-13T05:57:16.904113900Z,ESU5,6363.75,46,6364,71,3/13/2026 5:57:16 AM
5,2026-03-13T05:57:16.803381900Z,ESU5,6363.75,43,6364,71,3/13/2026 5:57:16 AM
4,2026-03-13T05:57:16.701969600Z,ESU5,6363.75,43,6364,72,3/13/2026 5:57:16 AM
3,2026-03-13T05:57:16.600765600Z,ESU5,6363.75,43,6364,73,3/13/2026 5:57:16 AM
2,2026-03-13T05:57:16.499986300Z,ESU5,6363.75,43,6364,74,3/13/2026 5:57:16 AM
1,2026-03-13T05:57:16.399241700Z,ESU5,6363.75,43,6364,75,3/13/2026 5:57:16 AM
0,2026-03-13T05:57:16.264038000Z,ESU5,6363.75,43,6364,76,3/13/2026 5:57:16 AM
1 id ts_event contract bid_price bid_size ask_price ask_size timestamp
2 89 2026-03-13T05:57:26.904401600Z ESU5 6363.75 43 6364 67 3/13/2026 5:57:26 AM
3 88 2026-03-13T05:57:26.778037200Z ESU5 6363.75 43 6364 69 3/13/2026 5:57:26 AM
4 87 2026-03-13T05:57:26.597038500Z ESU5 6363.75 43 6364 69 3/13/2026 5:57:26 AM
5 86 2026-03-13T05:57:26.438768300Z ESU5 6363.75 43 6364 68 3/13/2026 5:57:26 AM
6 85 2026-03-13T05:57:26.328259100Z ESU5 6363.75 43 6364 67 3/13/2026 5:57:26 AM
7 84 2026-03-13T05:57:26.216211200Z ESU5 6363.75 44 6364 67 3/13/2026 5:57:26 AM
8 83 2026-03-13T05:57:26.099281200Z ESU5 6363.75 46 6364 67 3/13/2026 5:57:26 AM
9 82 2026-03-13T05:57:25.979814900Z ESU5 6363.75 48 6364 67 3/13/2026 5:57:25 AM
10 81 2026-03-13T05:57:25.852317700Z ESU5 6363.75 48 6364 66 3/13/2026 5:57:25 AM
11 80 2026-03-13T05:57:25.684323100Z ESU5 6363.75 48 6364 65 3/13/2026 5:57:25 AM
12 79 2026-03-13T05:57:25.539436900Z ESU5 6363.75 48 6364 64 3/13/2026 5:57:25 AM
13 78 2026-03-13T05:57:25.425439200Z ESU5 6363.75 49 6364 64 3/13/2026 5:57:25 AM
14 77 2026-03-13T05:57:25.298054100Z ESU5 6363.75 51 6364 64 3/13/2026 5:57:25 AM
15 76 2026-03-13T05:57:25.177965500Z ESU5 6363.75 51 6364 63 3/13/2026 5:57:25 AM
16 75 2026-03-13T05:57:25.068062900Z ESU5 6363.75 52 6364 63 3/13/2026 5:57:25 AM
17 74 2026-03-13T05:57:24.963428500Z ESU5 6363.75 56 6364 63 3/13/2026 5:57:24 AM
18 73 2026-03-13T05:57:24.781215700Z ESU5 6363.75 57 6364 63 3/13/2026 5:57:24 AM
19 72 2026-03-13T05:57:24.676290100Z ESU5 6363.75 57 6364 63 3/13/2026 5:57:24 AM
20 71 2026-03-13T05:57:24.566898400Z ESU5 6363.75 56 6364 63 3/13/2026 5:57:24 AM
21 70 2026-03-13T05:57:24.430800400Z ESU5 6363.75 57 6364 63 3/13/2026 5:57:24 AM
22 69 2026-03-13T05:57:24.273683400Z ESU5 6363.75 56 6364 63 3/13/2026 5:57:24 AM
23 68 2026-03-13T05:57:24.167656100Z ESU5 6363.75 56 6364 64 3/13/2026 5:57:24 AM
24 67 2026-03-13T05:57:23.995720100Z ESU5 6363.75 56 6364 65 3/13/2026 5:57:23 AM
25 66 2026-03-13T05:57:23.894029100Z ESU5 6363.75 56 6364 68 3/13/2026 5:57:23 AM
26 65 2026-03-13T05:57:23.728897300Z ESU5 6363.75 56 6364 68 3/13/2026 5:57:23 AM
27 64 2026-03-13T05:57:23.614316800Z ESU5 6363.75 52 6364 68 3/13/2026 5:57:23 AM
28 63 2026-03-13T05:57:23.503752700Z ESU5 6363.75 51 6364 68 3/13/2026 5:57:23 AM
29 62 2026-03-13T05:57:23.289108200Z ESU5 6363.75 50 6364 68 3/13/2026 5:57:23 AM
30 61 2026-03-13T05:57:23.155673400Z ESU5 6363.75 49 6364 68 3/13/2026 5:57:23 AM
31 60 2026-03-13T05:57:23.028898400Z ESU5 6363.75 48 6364 68 3/13/2026 5:57:23 AM
32 59 2026-03-13T05:57:22.887132700Z ESU5 6363.75 46 6364 68 3/13/2026 5:57:22 AM
33 58 2026-03-13T05:57:22.676916300Z ESU5 6363.75 44 6364 68 3/13/2026 5:57:22 AM
34 57 2026-03-13T05:57:22.520328000Z ESU5 6363.75 43 6364 68 3/13/2026 5:57:22 AM
35 56 2026-03-13T05:57:22.405244600Z ESU5 6363.75 43 6364 69 3/13/2026 5:57:22 AM
36 55 2026-03-13T05:57:22.294674100Z ESU5 6363.75 41 6364 69 3/13/2026 5:57:22 AM
37 54 2026-03-13T05:57:22.163467900Z ESU5 6363.75 38 6364 69 3/13/2026 5:57:22 AM
38 53 2026-03-13T05:57:21.992443000Z ESU5 6363.75 38 6364 71 3/13/2026 5:57:21 AM
39 52 2026-03-13T05:57:21.872338400Z ESU5 6363.75 38 6364 71 3/13/2026 5:57:21 AM
40 51 2026-03-13T05:57:21.742801800Z ESU5 6363.75 37 6364 71 3/13/2026 5:57:21 AM
41 50 2026-03-13T05:57:21.557711100Z ESU5 6363.75 37 6364 72 3/13/2026 5:57:21 AM
42 49 2026-03-13T05:57:21.434977000Z ESU5 6363.75 37 6364 73 3/13/2026 5:57:21 AM
43 48 2026-03-13T05:57:21.285751600Z ESU5 6363.75 37 6364 72 3/13/2026 5:57:21 AM
44 47 2026-03-13T05:57:21.184392000Z ESU5 6363.75 37 6364 73 3/13/2026 5:57:21 AM
45 46 2026-03-13T05:57:21.076843800Z ESU5 6363.75 34 6364 73 3/13/2026 5:57:21 AM
46 45 2026-03-13T05:57:20.894131800Z ESU5 6363.75 32 6364 73 3/13/2026 5:57:20 AM
47 44 2026-03-13T05:57:20.759550000Z ESU5 6363.75 30 6364 73 3/13/2026 5:57:20 AM
48 43 2026-03-13T05:57:20.641547900Z ESU5 6363.75 28 6364 73 3/13/2026 5:57:20 AM
49 42 2026-03-13T05:57:20.540293200Z ESU5 6363.75 27 6364 73 3/13/2026 5:57:20 AM
50 41 2026-03-13T05:57:20.439034600Z ESU5 6363.75 27 6364 74 3/13/2026 5:57:20 AM
51 40 2026-03-13T05:57:20.337795000Z ESU5 6363.75 27 6364 73 3/13/2026 5:57:20 AM
52 39 2026-03-13T05:57:20.236606600Z ESU5 6363.75 27 6364 72 3/13/2026 5:57:20 AM
53 38 2026-03-13T05:57:20.135417700Z ESU5 6363.75 30 6364 72 3/13/2026 5:57:20 AM
54 37 2026-03-13T05:57:20.034272700Z ESU5 6363.75 32 6364 72 3/13/2026 5:57:20 AM
55 36 2026-03-13T05:57:19.933096800Z ESU5 6363.75 34 6364 72 3/13/2026 5:57:19 AM
56 35 2026-03-13T05:57:19.832012600Z ESU5 6363.75 36 6364 72 3/13/2026 5:57:19 AM
57 34 2026-03-13T05:57:19.730878500Z ESU5 6363.75 38 6364 72 3/13/2026 5:57:19 AM
58 33 2026-03-13T05:57:19.629787400Z ESU5 6363.75 38 6364 71 3/13/2026 5:57:19 AM
59 32 2026-03-13T05:57:19.528697000Z ESU5 6363.75 38 6364 70 3/13/2026 5:57:19 AM
60 31 2026-03-13T05:57:19.427077000Z ESU5 6363.75 38 6364 71 3/13/2026 5:57:19 AM
61 30 2026-03-13T05:57:19.326450300Z ESU5 6363.75 39 6364 71 3/13/2026 5:57:19 AM
62 29 2026-03-13T05:57:19.225427900Z ESU5 6363.75 39 6364 70 3/13/2026 5:57:19 AM
63 28 2026-03-13T05:57:19.123339800Z ESU5 6363.75 40 6364 70 3/13/2026 5:57:19 AM
64 27 2026-03-13T05:57:19.021936500Z ESU5 6363.75 41 6364 70 3/13/2026 5:57:19 AM
65 26 2026-03-13T05:57:18.920859200Z ESU5 6363.75 45 6364 70 3/13/2026 5:57:18 AM
66 25 2026-03-13T05:57:18.820148400Z ESU5 6363.75 46 6364 70 3/13/2026 5:57:18 AM
67 24 2026-03-13T05:57:18.718988100Z ESU5 6363.75 46 6364 69 3/13/2026 5:57:18 AM
68 23 2026-03-13T05:57:18.618299700Z ESU5 6363.75 49 6364 69 3/13/2026 5:57:18 AM
69 22 2026-03-13T05:57:18.517138100Z ESU5 6363.75 52 6364 69 3/13/2026 5:57:18 AM
70 21 2026-03-13T05:57:18.416335200Z ESU5 6363.75 53 6364 69 3/13/2026 5:57:18 AM
71 20 2026-03-13T05:57:18.315335900Z ESU5 6363.75 55 6364 69 3/13/2026 5:57:18 AM
72 19 2026-03-13T05:57:18.214368600Z ESU5 6363.75 57 6364 69 3/13/2026 5:57:18 AM
73 18 2026-03-13T05:57:18.113754700Z ESU5 6363.75 57 6364 65 3/13/2026 5:57:18 AM
74 17 2026-03-13T05:57:18.012706500Z ESU5 6363.75 56 6364 65 3/13/2026 5:57:18 AM
75 16 2026-03-13T05:57:17.911672600Z ESU5 6363.75 54 6364 65 3/13/2026 5:57:17 AM
76 15 2026-03-13T05:57:17.810879900Z ESU5 6363.75 52 6364 65 3/13/2026 5:57:17 AM
77 14 2026-03-13T05:57:17.710089700Z ESU5 6363.75 49 6364 65 3/13/2026 5:57:17 AM
78 13 2026-03-13T05:57:17.609388300Z ESU5 6363.75 49 6364 67 3/13/2026 5:57:17 AM
79 12 2026-03-13T05:57:17.508697400Z ESU5 6363.75 49 6364 67 3/13/2026 5:57:17 AM
80 11 2026-03-13T05:57:17.408027000Z ESU5 6363.75 53 6364 67 3/13/2026 5:57:17 AM
81 10 2026-03-13T05:57:17.307406200Z ESU5 6363.75 49 6364 67 3/13/2026 5:57:17 AM
82 9 2026-03-13T05:57:17.206714300Z ESU5 6363.75 49 6364 71 3/13/2026 5:57:17 AM
83 8 2026-03-13T05:57:17.105530300Z ESU5 6363.75 48 6364 71 3/13/2026 5:57:17 AM
84 7 2026-03-13T05:57:17.004796800Z ESU5 6363.75 47 6364 71 3/13/2026 5:57:17 AM
85 6 2026-03-13T05:57:16.904113900Z ESU5 6363.75 46 6364 71 3/13/2026 5:57:16 AM
86 5 2026-03-13T05:57:16.803381900Z ESU5 6363.75 43 6364 71 3/13/2026 5:57:16 AM
87 4 2026-03-13T05:57:16.701969600Z ESU5 6363.75 43 6364 72 3/13/2026 5:57:16 AM
88 3 2026-03-13T05:57:16.600765600Z ESU5 6363.75 43 6364 73 3/13/2026 5:57:16 AM
89 2 2026-03-13T05:57:16.499986300Z ESU5 6363.75 43 6364 74 3/13/2026 5:57:16 AM
90 1 2026-03-13T05:57:16.399241700Z ESU5 6363.75 43 6364 75 3/13/2026 5:57:16 AM
91 0 2026-03-13T05:57:16.264038000Z ESU5 6363.75 43 6364 76 3/13/2026 5:57:16 AM
-187
View File
@@ -1,187 +0,0 @@
from __future__ import annotations
from dataclasses import dataclass
import json
import os
import subprocess
import threading
from typing import Any, Callable, Dict, List, Optional
@dataclass
class DataPacket:
state: List[Any]
deleted_ids: List[int]
added_ids: List[int]
@dataclass
class DslResponse:
data_packet: DataPacket | None
req_id: str | None
error: str | None
def _resolve_interop_exe() -> str:
env_path = os.environ.get("BLUEORB_DSL_INTEROP")
if env_path and os.path.isfile(env_path):
return env_path
candidates = [
"/workspaces/spark/build/Debug/bin/net8.0/BlueOrbDSLInteropServer",
"/workspaces/spark/build/Release/bin/net8.0/BlueOrbDSLInteropServer",
]
for path in candidates:
if os.path.isfile(path):
return path
raise FileNotFoundError(
"BlueOrbDSLInterop executable not found. "
"Set BLUEORB_DSL_INTEROP to the full path."
)
_interop_proc: Optional[subprocess.Popen] = None
_reader_thread: Optional[threading.Thread] = None
_callbacks: Dict[str, Callable[[DslResponse], None]] = {}
_first_response_events: Dict[str, threading.Event] = {}
_first_responses: Dict[str, DslResponse] = {}
_state_lock = threading.Lock()
def start_interop() -> None:
"""
Start the BlueOrbDSLInteropServer process if it's not already running.
"""
global _interop_proc
if _interop_proc is not None and _interop_proc.poll() is None:
return
exe = _resolve_interop_exe()
_interop_proc = subprocess.Popen(
[exe],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
)
_start_reader_thread()
def stop_interop() -> None:
"""
Stop the BlueOrbDSLInteropServer process if it's running.
"""
global _interop_proc
if _interop_proc is None:
return
if _interop_proc.poll() is None and _interop_proc.stdin is not None:
_interop_proc.stdin.write(":exit\n")
_interop_proc.stdin.flush()
_interop_proc.stdin.close()
_interop_proc.wait(timeout=5)
global _reader_thread
if _reader_thread is not None:
_reader_thread.join(timeout=1)
_reader_thread = None
with _state_lock:
_callbacks.clear()
_first_response_events.clear()
_first_responses.clear()
_interop_proc = None
def get_interop_status() -> tuple[bool, int | None]:
"""
Returns current interop process status as (is_running, exit_code).
exit_code is None when process was never started or is still running.
"""
proc = _interop_proc
if proc is None:
return (False, None)
rc = proc.poll()
return (rc is None, rc)
def get_dsl(dsl: str, req_id: str, callback: Callable[[DslResponse], None]) -> DslResponse:
"""
Sends the DSL to BlueOrbDSLInteropServer and returns the first response for this req_id.
Subsequent streaming updates for the same req_id are delivered via callback.
Requires start_interop() to be called first.
"""
assert _interop_proc is not None and _interop_proc.poll() is None, (
"Interop process is not running. Call start_interop() first."
)
assert _interop_proc.stdin is not None
payload = {"dsl": dsl, "req_id": req_id}
first_event = threading.Event()
with _state_lock:
_callbacks[req_id] = callback
_first_response_events[req_id] = first_event
_first_responses.pop(req_id, None)
_interop_proc.stdin.write(json.dumps(payload) + "\n")
_interop_proc.stdin.flush()
if not first_event.wait(timeout=10):
with _state_lock:
_first_response_events.pop(req_id, None)
_callbacks.pop(req_id, None)
raise TimeoutError(f"No response received for req_id '{req_id}' from BlueOrbDSLInterop.")
with _state_lock:
response = _first_responses.pop(req_id, None)
_first_response_events.pop(req_id, None)
if response is None:
raise RuntimeError(f"Missing first response for req_id '{req_id}'.")
return response
def _start_reader_thread() -> None:
global _reader_thread
if _reader_thread is not None and _reader_thread.is_alive():
return
_reader_thread = threading.Thread(target=_reader_loop, daemon=True)
_reader_thread.start()
def _reader_loop() -> None:
while True:
proc = _interop_proc
if proc is None or proc.poll() is not None:
return
assert proc.stdout is not None
raw = proc.stdout.readline()
if raw == "":
return
line = raw.strip()
if not line:
continue
try:
payload = json.loads(line)
except json.JSONDecodeError:
continue
response = DslResponse(
data_packet=DataPacket(state=[payload.get("data_packet")], deleted_ids=[], added_ids=[]),
req_id=payload.get("req_id"),
error=payload.get("error"),
)
req_id = response.req_id
if not req_id:
continue
callback: Optional[Callable[[DslResponse], None]]
event: Optional[threading.Event]
with _state_lock:
callback = _callbacks.get(req_id)
event = _first_response_events.get(req_id)
if event is not None and req_id not in _first_responses:
_first_responses[req_id] = response
event.set()
if callback is not None:
try:
callback(response)
except Exception:
# Keep the reader alive if callback logic fails.
pass
@@ -1,33 +0,0 @@
import os
import sys
import uuid
_here = os.path.dirname(os.path.abspath(__file__))
_parent = os.path.dirname(_here)
if _parent not in sys.path:
sys.path.insert(0, _parent)
from BlueOrbDSL import get_dsl, start_interop, stop_interop, DslResponse
def on_packet(response: DslResponse) -> None:
print("callback from DSL Server, DslResponse:", response)
def main() -> None:
start_interop()
try:
while True:
dsl = input("Enter DSL (or 'quit'): ").strip()
if dsl.lower() == "quit":
break
if not dsl:
continue
response = get_dsl(dsl, str(uuid.uuid4()), on_packet)
print("return:", response)
finally:
stop_interop()
if __name__ == "__main__":
main()
-844
View File
@@ -1,844 +0,0 @@
from __future__ import annotations
import csv
import time
import os
import sys
import threading
import uuid
from collections import deque
from datetime import datetime
from typing import Any
from rich.text import Text
from rich.style import Style
from textual import events
from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.containers import Container, Horizontal, Vertical
from textual.widgets.text_area import TextAreaTheme
from textual.widgets import Button, DataTable, Input, Static, TabbedContent, TabPane, TextArea, Tree
_here = os.path.dirname(os.path.abspath(__file__))
_parent = os.path.dirname(_here)
if _parent not in sys.path:
sys.path.insert(0, _parent)
from BlueOrbDSL import DslResponse, get_dsl, get_interop_status, start_interop, stop_interop
class DSQALiveConsole(App):
DEFAULT_QUERY = (
'FROM market.ticks\n'
'WHERE symbol IN ("BTCUSD", "ETHUSD")\n'
"SELECT symbol, price, change, time"
)
LAST_QUERY_PATH = os.path.join(_here, "DSQA_LAST_EXECUTED_QUERY.txt")
DSL_HIGHLIGHT_QUERY = r"""
; comments
(comment) @comment
; assignment vars: lhs in x = SomeStream(...)
(assignment_expression
left: (identifier) @variable)
; stream operators (function names ending with Stream)
(call_expression
function: (identifier) @function
(#match? @function "^[A-Za-z_][A-Za-z0-9_]*Stream$"))
; normal function calls
(call_expression
function: (identifier) @function.method)
; arguments and literals
(arguments (identifier) @parameter)
(string) @string
(number) @number
(true) @constant.builtin
(false) @constant.builtin
(null) @constant.builtin
"""
BINDINGS = [
Binding("ctrl+r", "execute", "Execute"),
Binding("f11", "execute", show=False),
Binding("alt+enter", "execute", show=False),
# Override Textual's default Ctrl+Q quit to avoid accidental VS Code close.
Binding("ctrl+q", "noop", show=False),
Binding("ctrl+x", "quit", "Quit"),
]
CSS = """
Screen {
background: #060a1c;
color: #d8dff4;
}
#window_close_button {
width: 3;
min-width: 3;
height: 1;
margin: 0;
border: none;
background: #3a1015;
color: #ff9ca8;
text-style: bold;
}
#window_close_button:hover,
#window_close_button:focus {
background: #5a1620;
color: #ffd6db;
}
#root {
padding: 0 1 0 1;
height: 1fr;
}
#query_panel {
background: #070d27;
height: 33%;
margin-top: 1;
}
#query_header_row {
height: 1;
border-bottom: solid #596285;
}
#query_header {
width: auto;
color: #9eb0d4;
content-align: left middle;
}
#query_header_spacer {
width: 1fr;
}
#query_input {
border: solid #697597;
background: #050b22;
color: #cfd7eb;
height: 1fr;
padding-left: 1;
}
#results_panel {
background: #070d27;
height: 1fr;
margin-top: 1;
}
#results_toolbar {
height: 3;
padding: 0 1;
}
#results_left {
width: auto;
height: 3;
margin-top: 0;
}
#stream_toggle_button {
width: auto;
min-width: 11;
margin-top: 0;
margin-left: 1;
border: none;
background: #070d27;
color: #79afe7;
}
#stream_toggle_button:hover,
#stream_toggle_button:focus {
background: #111a3f;
color: #9bc9f6;
}
#execute_button {
width: 5;
min-width: 5;
margin-top: 0;
margin-left: 1;
border: none;
background: #10341f;
color: #7ef1ac;
text-style: bold;
}
#execute_button:hover,
#execute_button:focus {
background: #1a4f30;
color: #b3ffd0;
}
#results_actions {
width: auto;
height: 3;
margin-top: 0;
}
#results_spacer {
width: 1fr;
}
#results_search {
width: 30;
min-width: 24;
margin-right: 1;
border: none;
background: #060d28;
color: #d5def3;
padding: 0 1;
}
#search_button,
#copy_button,
#export_button {
width: auto;
min-width: 11;
margin-left: 1;
border: none;
background: #070d27;
color: #79afe7;
}
#search_button:hover,
#copy_button:hover,
#export_button:hover,
#search_button:focus,
#copy_button:focus,
#export_button:focus {
background: #111a3f;
color: #9bc9f6;
}
#results_table {
border: solid #697597;
background: #050b22;
height: 1fr;
}
#results_table .datatable--header,
#results_table .datatable--header-hover,
#results_table .datatable--header-cursor {
background: #0c1535;
color: #6ea6df;
text-style: bold;
}
#results_table .datatable--even-row {
background: #050b22;
}
#results_table .datatable--odd-row {
background: #07102a;
}
#results_table .datatable--cursor {
background: #19335b;
color: #dbe8ff;
}
#results_table .datatable--fixed-cursor {
background: #132949;
color: #c8dbff;
}
#results_table.error .datatable--odd-row,
#results_table.error .datatable--even-row,
#results_table.error .datatable--cursor,
#results_table.error .datatable--fixed-cursor {
color: #f17486;
text-style: bold;
}
#results_panel.paused {
background: #150f1f;
}
#results_table.paused {
background: #130f18;
}
#results_table.paused .datatable--header,
#results_table.paused .datatable--header-hover,
#results_table.paused .datatable--header-cursor {
background: #262338;
color: #8b90a1;
text-style: bold;
}
#results_tabs {
height: 1fr;
background: #070d27;
}
#data_tab,
#tree_tab {
padding: 0;
}
#ops_tree {
border: solid #697597;
background: #050b22;
color: #cfd7eb;
height: 1fr;
}
#bottom_status_bar {
border-top: solid #596285;
background: #070d27;
height: 2;
margin: 0;
padding: 0 1;
}
#status_right_wrap {
width: 1fr;
}
#status_row {
height: 1;
margin-top: 0;
width: 1fr;
}
#live_status {
width: 1fr;
color: #b3bed9;
content-align: right middle;
}
"""
def compose(self) -> ComposeResult:
with Container(id="root"):
with Vertical(id="query_panel"):
with Horizontal(id="query_header_row"):
yield Static("DSL Query", id="query_header")
yield Static("", id="query_header_spacer")
yield Button("✕", id="window_close_button")
yield TextArea(
text=self._load_last_query(),
id="query_input",
language="javascript",
theme="vscode_dark",
show_line_numbers=True,
)
with Vertical(id="results_panel"):
with Horizontal(id="results_toolbar"):
with Horizontal(id="results_left"):
yield Button("▶", id="execute_button")
yield Button("⏸ Pause", id="stream_toggle_button")
yield Static("", id="results_spacer")
with Horizontal(id="results_actions"):
yield Input(placeholder="Search: col:value", id="results_search")
yield Button("⌕ Search", id="search_button")
yield Button("⧉ Copy", id="copy_button")
yield Button("⇩ Export", id="export_button")
with TabbedContent(initial="data_tab", id="results_tabs"):
with TabPane("Data", id="data_tab"):
table = DataTable(id="results_table")
table.cursor_type = "cell"
table.show_cursor = True
table.zebra_stripes = True
yield table
with TabPane("Operators", id="tree_tab"):
tree = Tree("Assemblies", id="ops_tree")
tree.show_root = False
yield tree
with Horizontal(id="bottom_status_bar"):
with Horizontal(id="status_right_wrap"):
with Horizontal(id="status_row"):
yield Static(
"Rows: 0 | Rate: 0.0/s | Total Updates: 0 | Uptime: 00:00:00 | Last Update: --:--:--",
id="live_status",
)
def on_mount(self) -> None:
self._update_timestamps: deque[float] = deque()
self._last_update_at: datetime | None = None
self._stream_started_at: float | None = None
self._total_updates = 0
self._last_row_count = 0
self._current_col_names: list[str] = []
self._current_rows: list[dict[str, Any]] = []
self._column_width_cache: dict[str, int] = {}
self._ops_catalog_rows: list[dict[str, Any]] = []
self._ops_catalog_error: str | None = None
self._ops_catalog_loaded = False
self._ops_catalog_loading = False
self._interop_is_running = False
self._interop_exit_code: int | None = None
self._grid_updates_enabled = True
self._paused_latest_response: DslResponse | None = None
self._ensure_interop_started()
self._refresh_ops_tree()
self._refresh_ops_tree_async()
self._configure_query_highlighting()
self._set_pause_visuals()
self.set_interval(0.5, self._refresh_status)
def _configure_query_highlighting(self) -> None:
query_input = self.query_one("#query_input", TextArea)
query_input.language = "javascript"
dsl_theme = TextAreaTheme(
"dsqa_ide",
base_style=Style.parse("#d7deee on #171a22"),
gutter_style=Style.parse("#8a93a8 on #1c212b"),
cursor_style=Style.parse("#ffffff on #2b3242"),
cursor_line_style=Style.parse("on #202534"),
cursor_line_gutter_style=Style.parse("#a6afc4 on #202534"),
selection_style=Style.parse("on #2a3f67"),
bracket_matching_style=Style.parse("bold #7fd9ff"),
syntax_styles={
"comment": Style.parse("italic #6f778a"),
"variable": Style.parse("bold #4ec9b0"),
"function": Style.parse("bold #4fc1ff"),
"function.method": Style.parse("bold #70d4ff"),
"parameter": Style.parse("#c6d4f8"),
"string": Style.parse("#d7ba7d"),
"number": Style.parse("#b5cea8"),
"constant.builtin": Style.parse("bold #569cd6"),
},
)
query_input.register_theme(dsl_theme)
query_input.theme = "dsqa_ide"
try:
query_input.update_highlight_query(self.DSL_HIGHLIGHT_QUERY)
except Exception:
pass
def on_shutdown(self) -> None:
stop_interop()
@staticmethod
def _ensure_interop_started() -> None:
try:
start_interop()
except Exception:
pass
def action_execute(self) -> None:
tabs = self.query_one("#results_tabs", TabbedContent)
tabs.active = "data_tab"
self._grid_updates_enabled = True
self._set_stream_toggle_label()
self._set_pause_visuals()
self._execute_query_async()
def action_noop(self) -> None:
pass
def on_button_pressed(self, event: Button.Pressed) -> None:
button_id = event.button.id
if button_id == "search_button":
self._search_results()
elif button_id == "copy_button":
self._copy_selected_cell()
elif button_id == "export_button":
self._export_results_csv()
elif button_id == "execute_button":
self.action_execute()
elif button_id == "window_close_button":
self.exit()
elif button_id == "stream_toggle_button":
self._toggle_stream_painting()
def on_input_submitted(self, event: Input.Submitted) -> None:
if event.input.id == "results_search":
self._search_results()
def on_click(self, event: events.Click) -> None:
if getattr(event.widget, "id", None) != "ops_tree":
return
line = event.style.meta.get("line")
if line is None:
return
tree = self.query_one("#ops_tree", Tree)
node = tree.get_node_at_line(line)
if node is None:
return
node_data = node.data
if not isinstance(node_data, dict) or node_data.get("kind") != "constructor":
return
self._append_operator_to_query(self._stringify(node_data.get("op", "")).strip())
def _append_operator_to_query(self, op_name: str) -> None:
if not op_name:
return
query_input = self.query_one("#query_input", TextArea)
existing = query_input.text
if existing.strip():
separator = "" if existing.endswith("\n") else "\n"
query_input.text = f"{existing}{separator}{op_name}"
else:
query_input.text = op_name
query_input.focus()
def _execute_query_async(self) -> None:
self._ensure_interop_started()
query = self.query_one(TextArea).text.strip()
if not query:
return
self._column_width_cache.clear()
self._save_last_query(query)
self._update_timestamps.clear()
self._last_update_at = None
self._stream_started_at = time.monotonic()
self._total_updates = 0
self._last_row_count = 0
self._paused_latest_response = None
self._refresh_status()
req_id = str(uuid.uuid4())
def _run() -> None:
try:
def _on_response(resp: DslResponse) -> None:
self.call_from_thread(self._render_response, resp)
get_dsl(query, req_id, _on_response)
except Exception as exc:
error_resp = DslResponse(data_packet=None, req_id=req_id, error=str(exc))
self.call_from_thread(self._render_response, error_resp)
threading.Thread(target=_run, daemon=True).start()
def _render_response(self, response: DslResponse) -> None:
if not self._grid_updates_enabled:
self._paused_latest_response = response
return
self._render_response_internal(response)
def _render_response_internal(self, response: DslResponse) -> None:
self._record_update()
table = self.query_one(DataTable)
table.remove_class("error")
prev_scroll_x = table.scroll_offset.x
prev_scroll_y = table.scroll_offset.y
table.clear(columns=True)
if response.error:
table.add_class("error")
error_text = self._stringify(response.error)
error_lines = error_text.splitlines() or [error_text]
self._current_col_names = []
self._current_rows = []
self._last_row_count = len(error_lines)
self._refresh_ops_tree()
table.add_columns("error")
for line in error_lines:
table.add_row(Text(line, style="bold #f17486"))
return
if response.data_packet is None or not response.data_packet.state:
self._current_col_names = []
self._current_rows = []
self._last_row_count = 0
self._refresh_ops_tree()
table.add_columns("empty")
table.add_row("no data")
return
data_packet = response.data_packet.state[0]
columns = data_packet.get("columns", [])
rows = data_packet.get("all", [])
if not isinstance(rows, list):
rows = []
col_names = [c.get("name", "") for c in columns]
if not col_names:
col_names = list(rows[0].keys()) if rows else ["empty"]
self._current_col_names = col_names
self._current_rows = rows
self._last_row_count = len(rows)
self._refresh_ops_tree()
for col_name in col_names:
width = self._column_width_cache.get(col_name, len(col_name))
for row in rows:
if not isinstance(row, dict):
continue
cell_text = self._stringify(row.get(col_name, ""))
width = max(width, len(cell_text))
self._column_width_cache[col_name] = width
table.add_column(col_name, width=width)
for row in rows:
table.add_row(*[self._format_cell(c, row.get(c, "")) for c in col_names])
# Preserve user's viewport during streaming refreshes.
table.scroll_to(
x=min(prev_scroll_x, table.max_scroll_x),
y=min(prev_scroll_y, table.max_scroll_y),
animate=False,
)
@staticmethod
def _stringify(value: Any) -> str:
return "" if value is None else str(value)
@staticmethod
def _format_cell(column_name: str, value: Any) -> str | Text:
text = DSQALiveConsole._stringify(value)
lowered = column_name.lower()
if lowered == "id":
return Text(text, style="bold #9eb1d8")
if lowered == "symbol":
return Text(text, style="bold #dce6ff")
if lowered == "price":
return Text(text, style="bold #d4ddf2")
if lowered == "time":
return Text(text, style="#aab5d0")
if lowered == "change":
cleaned = text.strip()
if cleaned.startswith("-"):
return Text(text, style="bold #f17486")
if cleaned.startswith("+"):
return Text(text, style="bold #92d67e")
return Text(text, style="bold #c7d3ef")
if lowered == "bid":
return Text(text, style="bold #8cf3c0 on #123526")
if lowered == "ask":
return Text(text, style="bold #ffd5d9 on #3b1b25")
return text
def _record_update(self) -> None:
now = time.monotonic()
self._update_timestamps.append(now)
self._total_updates += 1
if self._stream_started_at is None:
self._stream_started_at = now
self._last_update_at = datetime.now()
self._refresh_status()
def _refresh_status(self) -> None:
self._refresh_interop_heartbeat()
now = time.monotonic()
cutoff = now - 1.0
while self._update_timestamps and self._update_timestamps[0] < cutoff:
self._update_timestamps.popleft()
rate = float(len(self._update_timestamps))
if self._stream_started_at is not None:
uptime_seconds = max(0, int(now - self._stream_started_at))
uptime = self._format_duration(uptime_seconds)
else:
uptime = "--:--:--"
last_update = self._last_update_at.strftime("%H:%M:%S") if self._last_update_at else "--:--:--"
status = Text()
if self._interop_is_running:
status.append("Interop: ● UP", style="bold #92d67e")
elif self._interop_exit_code is not None:
status.append(f"Interop: ● DOWN({self._interop_exit_code})", style="bold #f17486")
else:
status.append("Interop: ● DOWN", style="bold #8b90a1")
status.append(" | ")
status.append(f"Rows: {self._last_row_count} | Rate: {rate:.1f}/s | ")
status.append(f"Total Updates: {self._total_updates}", style="bold #79afe7")
status.append(f" | Uptime: {uptime} | ")
status.append(f"Last Update: {last_update}", style="bold #79afe7")
self.query_one("#live_status", Static).update(status)
def _refresh_interop_heartbeat(self) -> None:
is_running, exit_code = get_interop_status()
self._interop_is_running = is_running
self._interop_exit_code = exit_code
@staticmethod
def _format_duration(total_seconds: int) -> str:
hours = total_seconds // 3600
minutes = (total_seconds % 3600) // 60
seconds = total_seconds % 60
return f"{hours:02d}:{minutes:02d}:{seconds:02d}"
def _search_results(self) -> None:
raw = self.query_one("#results_search", Input).value.strip()
if ":" not in raw:
return
col_part, value_part = raw.split(":", 1)
target_col = col_part.strip()
target_value = value_part.strip()
if not target_col:
return
lookup = {name.lower(): idx for idx, name in enumerate(self._current_col_names)}
col_idx = lookup.get(target_col.lower())
if col_idx is None:
return
col_name = self._current_col_names[col_idx]
needle = target_value.lower()
for row_idx, row in enumerate(self._current_rows):
if not isinstance(row, dict):
continue
cell_value = self._stringify(row.get(col_name, ""))
if needle in cell_value.lower():
table = self.query_one("#results_table", DataTable)
table.move_cursor(row=row_idx, column=col_idx)
table.focus()
return
def _copy_selected_cell(self) -> None:
table = self.query_one("#results_table", DataTable)
if table.row_count == 0 or not self._current_col_names:
return
coordinate = table.cursor_coordinate
try:
cell = table.get_cell_at(coordinate)
except Exception:
return
if isinstance(cell, Text):
value = cell.plain
else:
value = self._stringify(cell)
self.copy_to_clipboard(value)
def _export_results_csv(self) -> None:
if not self._current_col_names:
return
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
export_path = os.path.join(_here, f"DSQA_RESULTS_EXPORT_{timestamp}.csv")
with open(export_path, "w", newline="", encoding="utf-8") as csv_file:
writer = csv.writer(csv_file)
writer.writerow(self._current_col_names)
for row in self._current_rows:
if isinstance(row, dict):
writer.writerow([self._stringify(row.get(col, "")) for col in self._current_col_names])
def _refresh_ops_tree(self) -> None:
tree = self.query_one("#ops_tree", Tree)
root = tree.root
root.remove_children()
if self._ops_catalog_error:
root.add(Text(self._ops_catalog_error, style="bold #f17486"))
root.expand()
return
grouped: dict[str, dict[str, dict[str, set[str]]]] = {}
for row in self._ops_catalog_rows:
if not isinstance(row, dict):
continue
row_lookup = {self._stringify(k).lower(): v for k, v in row.items()}
assembly_name = self._stringify(row_lookup.get("assembly_name", "")).strip() or "(unknown assembly)"
namespace = self._stringify(row_lookup.get("namespace", "")).strip() or "(global)"
op = self._stringify(row_lookup.get("op", "")).strip() or "(unknown op)"
constructor = self._stringify(row_lookup.get("constructor", "")).strip() or "(none)"
grouped.setdefault(assembly_name, {}).setdefault(namespace, {}).setdefault(op, set()).add(constructor)
if not grouped:
root.add(Text("No operator metadata available", style="#8ea0c6"))
root.expand()
return
for assembly_name in sorted(grouped.keys(), key=str.lower):
assembly_node = root.add(Text(assembly_name, style="bold #79afe7"))
for namespace in sorted(grouped[assembly_name].keys(), key=str.lower):
namespace_node = assembly_node.add(Text(namespace, style="#cfd7eb"))
for op in sorted(grouped[assembly_name][namespace].keys(), key=str.lower):
op_node = namespace_node.add(
Text(op, style="#b8c8e7"),
data={"kind": "op", "op": op},
)
for constructor in sorted(grouped[assembly_name][namespace][op], key=str.lower):
op_node.add(
Text(constructor, style="#9eb0d4"),
data={"kind": "constructor", "op": op, "constructor": constructor},
)
op_node.expand()
namespace_node.expand()
assembly_node.expand()
root.expand()
def _refresh_ops_tree_async(self) -> None:
if self._ops_catalog_loaded or self._ops_catalog_loading:
return
self._ensure_interop_started()
self._ops_catalog_loading = True
req_id = str(uuid.uuid4())
def _run() -> None:
try:
def _on_response(resp: DslResponse) -> None:
self.call_from_thread(self._update_ops_catalog, resp)
get_dsl("OpsStream()", req_id, _on_response)
except Exception as exc:
error_resp = DslResponse(data_packet=None, req_id=req_id, error=str(exc))
self.call_from_thread(self._update_ops_catalog, error_resp)
threading.Thread(target=_run, daemon=True).start()
def _update_ops_catalog(self, response: DslResponse) -> None:
self._ops_catalog_loading = False
if response.error:
self._ops_catalog_rows = []
self._ops_catalog_error = self._stringify(response.error)
self._refresh_ops_tree()
return
if response.data_packet is None or not response.data_packet.state:
self._ops_catalog_rows = []
self._ops_catalog_error = "OpsStream() returned no data"
self._refresh_ops_tree()
return
data_packet = response.data_packet.state[0]
rows = data_packet.get("all", [])
if not isinstance(rows, list):
rows = []
normalized_rows: list[dict[str, Any]] = []
for row in rows:
if isinstance(row, dict):
normalized_rows.append(row)
self._ops_catalog_rows = normalized_rows
self._ops_catalog_error = None
self._ops_catalog_loaded = True
self._refresh_ops_tree()
def _toggle_stream_painting(self) -> None:
self._grid_updates_enabled = not self._grid_updates_enabled
self._set_stream_toggle_label()
self._set_pause_visuals()
if self._grid_updates_enabled and self._paused_latest_response is not None:
latest = self._paused_latest_response
self._paused_latest_response = None
self._render_response_internal(latest)
def _set_stream_toggle_label(self) -> None:
button = self.query_one("#stream_toggle_button", Button)
button.label = "⏸ Pause" if self._grid_updates_enabled else "▶ Play"
def _set_pause_visuals(self) -> None:
table = self.query_one("#results_table", DataTable)
panel = self.query_one("#results_panel", Vertical)
if self._grid_updates_enabled:
table.remove_class("paused")
panel.remove_class("paused")
else:
table.add_class("paused")
panel.add_class("paused")
def _load_last_query(self) -> str:
try:
with open(self.LAST_QUERY_PATH, "r", encoding="utf-8") as file:
text = file.read().strip()
return text if text else self.DEFAULT_QUERY
except FileNotFoundError:
return self.DEFAULT_QUERY
except OSError:
return self.DEFAULT_QUERY
def _save_last_query(self, query: str) -> None:
try:
with open(self.LAST_QUERY_PATH, "w", encoding="utf-8") as file:
file.write(query)
except OSError:
pass
if __name__ == "__main__":
DSQALiveConsole().run()
@@ -1,31 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AssemblyName>BlueOrbDSLInteropServer</AssemblyName>
<RootNamespace>BlueOrbDSLInteropServer</RootNamespace>
</PropertyGroup>
<Choose>
<When Condition="'$(UseProjectRefs)' == 'true'">
<ItemGroup>
<ProjectReference Include="..\..\cs\Bts.Spark.Api\Bts.Spark.Api.csproj" />
<ProjectReference Include="..\DataStream\DataStream.csproj" />
<ProjectReference Include="..\PubSub\PubSub.csproj" />
<ProjectReference Include="..\BlueOrbOperatorStreams\BlueOrbOperatorStreams.csproj" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<PackageReference Include="Bts.Spark.Api" Version="$(SparkVersion)" />
<PackageReference Include="DataStream" Version="$(SparkVersion)" />
<PackageReference Include="PubSub" Version="$(SparkVersion)" />
<PackageReference Include="BlueOrbOperatorStreams" Version="$(SparkVersion)" />
</ItemGroup>
</Otherwise>
</Choose>
</Project>
@@ -1,122 +0,0 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using BCG;
using bts.BlueOrb;
using Bts.DataStream;
using Bts.DataStreamCore;
using Bts.DataStreamExpressions;
using Bts.PubSub;
using MathNet.Numerics.Statistics;
namespace BlueOrbDSLInteropServer {
// BlueOrbDSLInteropServer reads DSL lines from stdin, validates them,
// and writes one DataPacket JSON line to stdout per input.
internal static class Program {
private const string ExitSignal = ":exit";
private static SyncQueue<DslRequest> _work_queue = new SyncQueue<DslRequest>();
private static JsonSerializerOptions response_json_options = new JsonSerializerOptions {
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals
};
private static string _current_req_id;
// Request from Python
private sealed class DslRequest {
public string? dsl { get; set; }
public string? req_id { get; set; }
}
// Response envelope for Python: includes DataPacket, request id, and optional error.
private sealed class DslResponse {
public DataPacket? data_packet { get; set; }
public string? req_id { get; set; }
public string? error { get; set; }
}
private static void Main(string[] args) {
//System.Threading.Thread.Sleep(20000);
System.Threading.Thread thread = new Thread(_worker_loop);
thread.IsBackground = true;
thread.Start();
response_json_options.Converters.Add(new DataPacketJsonConverter {
IncludeCurrent = true,
UseObjectRows = true,
});
string? line;
while ((line = Console.ReadLine()) != null) {
line = line.Trim();
if (line.Length == 0) {
continue;
}
if (string.Equals(line, ExitSignal, StringComparison.OrdinalIgnoreCase)) {
break;
}
try {
DslRequest req = JsonSerializer.Deserialize<DslRequest>(line);
_work_queue.enqueue(req);
} catch (Exception ex) {
bts.Log.assert(false, ex.ToString());
}
}
}
private static void _worker_loop() {
Dictionary<string, ViewStream> req_map = new Dictionary<string, ViewStream>();
while (true) {
System.Threading.Thread.Sleep(100);
ViewStreamDatabase.instance.doWork();
var new_reqs = _work_queue.dequeue_all();
if (new_reqs == null || new_reqs.Count == 0) {
continue;
}
// ubsubscribing to previous stream(s)
foreach (var kv in req_map) {
kv.Value.onChange -= dp_obj => _on_dp(kv.Key, dp_obj);
}
foreach (var r in new_reqs) {
var req_id = string.IsNullOrWhiteSpace(r.req_id) ? Guid.NewGuid().ToString() : r.req_id;
_current_req_id = req_id;
try {
DSLStream dsl_str = new DSLStream(r.dsl);
req_map[req_id] = dsl_str;
dsl_str.onChange += dp_obj => _on_dp(req_id, dp_obj);
} catch (Exception ex) {
_write_error(req_id, ex.StackTrace);
}
}
}
}
private static void _on_dp(string req_id, object dp_obj) {
// eventhough we unsubscribe to all the other streams except the currrent one,
// sometimes the onLastSub is not implemented and we still get updates, this masks them
if (req_id != _current_req_id)
return;
DataPacket dp = dp_obj as DataPacket;
DslResponse response = new DslResponse() {
data_packet = dp,
req_id = req_id,
error = ""
};
var json = JsonSerializer.Serialize(response, response_json_options);
Console.WriteLine(json);
}
private static void _write_error(string req_id, string error) {
DslResponse response = new DslResponse() {
data_packet = null,
req_id = req_id,
error = error
};
var json = JsonSerializer.Serialize(response, response_json_options);
Console.WriteLine(json);
}
}
}
@@ -1,514 +0,0 @@
// namespace BlueOrb.Operators.Signal;
// using BCG;
// using bts;
// using System;
// using System.Collections.Generic;
// using System.Globalization;
// using System.Linq;
// [DataStreamUserRespresentation("BarBuilderStream")]
// public class BarBuilderStream : ViewStream
// {
// enum BarType
// {
// TIME,
// TICK,
// VOLUME,
// DOLLAR,
// }
// enum PriceSource
// {
// trade_price,
// mid,
// bid,
// ask,
// }
// enum VolumeSource
// {
// trade_size,
// none,
// }
// enum SessionReset
// {
// NONE,
// DAY,
// RTH,
// ETH,
// }
// sealed class BarState
// {
// public string Contract = string.Empty;
// public DateTime StartTs;
// public DateTime EndTs;
// public double Open;
// public double High;
// public double Low;
// public double Close;
// public double Volume;
// public int TradeCount;
// public double SumPriceSize;
// public double SumSize;
// public double DollarNotional;
// public bool HasData;
// public DateTime SessionDay;
// public bool InitialSnapshotEmitted;
// }
// readonly ViewStream _priceStream;
// readonly BarType _barType;
// readonly int _barSize;
// readonly PriceSource _priceSource;
// readonly VolumeSource _volumeSource;
// readonly string _timestampCol;
// readonly bool _emitForming;
// readonly bool _emitInitialSnapshot;
// readonly SessionReset _sessionReset;
// readonly Dictionary<string, BarState> _stateByContract = new(StringComparer.Ordinal);
// readonly Dictionary<string, bool> _validCols = new(StringComparer.OrdinalIgnoreCase);
// bool _validated;
// int _nextId;
// readonly BlueTable _outTable;
// readonly IBlueTableSchema _outSchema;
// public BarBuilderStream(
// ViewStream price_stream,
// string bar_type,
// int bar_size,
// string price_source,
// string volume_source,
// string timestamp_col = "ts_event",
// int emit_forming_i = 0,
// string session_reset = "NONE",
// int emit_initial_snapshot_i = 0
// )
// {
// _priceStream = price_stream;
// _barType = ParseBarType(bar_type);
// _barSize = bar_size;
// _priceSource = ParsePriceSource(price_source);
// _volumeSource = ParseVolumeSource(volume_source);
// _timestampCol = timestamp_col;
// _emitForming = emit_forming_i == 1;
// _emitInitialSnapshot = emit_initial_snapshot_i == 1;
// _sessionReset = ParseSessionReset(session_reset);
// if (_barSize <= 0)
// {
// throw new ArgumentException("bar_size must be > 0");
// }
// _outSchema = BlueDataUtility.form_schema(
// "BarBuilder",
// Tuple.Create("id", TypeCode.Int32),
// Tuple.Create("ts_event", TypeCode.String),
// Tuple.Create("bar_start_ts", TypeCode.String),
// Tuple.Create("bar_end_ts", TypeCode.String),
// Tuple.Create("contract", TypeCode.String),
// Tuple.Create("open", TypeCode.Double),
// Tuple.Create("high", TypeCode.Double),
// Tuple.Create("low", TypeCode.Double),
// Tuple.Create("close", TypeCode.Double),
// Tuple.Create("volume", TypeCode.Double),
// Tuple.Create("trade_count", TypeCode.Int32),
// Tuple.Create("vwap", TypeCode.Double),
// Tuple.Create("is_forming", TypeCode.Boolean)
// );
// _outTable = new BlueTable(_outSchema);
// }
// protected override void myOnFirstSubscriber()
// {
// _priceStream.onChange += _on_price_change;
// }
// protected override void myOnLastSubscriber()
// {
// _priceStream.onChange -= _on_price_change;
// }
// void _on_price_change(object newValue)
// {
// var dp = newValue as IDataPacket;
// if (dp is null)
// {
// return;
// }
// if (!_validated)
// {
// ValidateInputSchema(dp.newRows.schema);
// _validated = true;
// }
// var emitted = new List<IBlueRow>();
// foreach (IBlueRow row in dp.addedRows)
// {
// ProcessEvent(row, emitted);
// }
// if (emitted.Count == 0)
// {
// return;
// }
// foreach (var r in emitted)
// {
// _outTable.addRow(r);
// }
// var outDp = BlueDataUtility.build_dp_inc(_outTable, myLastValue as IDataPacket);
// myFireEvent(outDp);
// }
// void ValidateInputSchema(IBlueTableSchema schema)
// {
// _validCols.Clear();
// foreach (var name in schema.columnNames)
// {
// _validCols[name] = true;
// }
// if (!_validCols.ContainsKey(_timestampCol))
// {
// throw new ArgumentException($"Missing required column: {_timestampCol}");
// }
// switch (_priceSource)
// {
// case PriceSource.trade_price:
// RequireCol("trade_price");
// break;
// case PriceSource.mid:
// RequireCol("bid_price");
// RequireCol("ask_price");
// break;
// case PriceSource.bid:
// RequireCol("bid_price");
// break;
// case PriceSource.ask:
// RequireCol("ask_price");
// break;
// }
// if (_barType is BarType.VOLUME or BarType.DOLLAR)
// {
// if (_volumeSource == VolumeSource.none || !_validCols.ContainsKey("trade_size"))
// {
// throw new ArgumentException("VOLUME/DOLLAR require executed trade volume; invalid for BBO-only streams.");
// }
// }
// else if (_volumeSource == VolumeSource.trade_size)
// {
// RequireCol("trade_size");
// }
// }
// void RequireCol(string name)
// {
// if (!_validCols.ContainsKey(name))
// {
// throw new ArgumentException($"Missing required column for selected source: {name}");
// }
// }
// void ProcessEvent(IBlueRow row, List<IBlueRow> emitted)
// {
// var ts = ParseTimestamp(row);
// var contract = ResolveContract(row);
// var price = ResolvePrice(row);
// var size = ResolveSize(row);
// var state = GetOrCreateState(contract);
// if (state.HasData && _sessionReset != SessionReset.NONE && ts.Date != state.SessionDay.Date)
// {
// emitted.Add(ToBarRow(state, ts_event: state.EndTs, isForming: false));
// state.HasData = false;
// }
// switch (_barType)
// {
// case BarType.TIME:
// ProcessTimeBar(state, ts, price, size, emitted);
// break;
// case BarType.TICK:
// ProcessThresholdBar(state, ts, price, size, emitted, state.TradeCount + 1 >= _barSize);
// break;
// case BarType.VOLUME:
// ProcessThresholdBar(state, ts, price, size, emitted, state.Volume + size >= _barSize);
// break;
// case BarType.DOLLAR:
// ProcessThresholdBar(state, ts, price, size, emitted, state.DollarNotional + (price * size) >= _barSize);
// break;
// }
// }
// void ProcessTimeBar(BarState state, DateTime ts, double price, double size, List<IBlueRow> emitted)
// {
// var bucketStart = AlignTimeBucket(ts, _barSize);
// var bucketEnd = bucketStart.AddSeconds(_barSize);
// if (!state.HasData)
// {
// StartBar(state, ts, bucketStart, bucketEnd, price, size);
// MaybeEmitInitialSnapshot(state, ts, emitted);
// if (_emitForming)
// {
// emitted.Add(ToBarRow(state, ts, isForming: true));
// }
// return;
// }
// if (bucketStart < state.StartTs)
// {
// Log.Gen.error(
// $"BarBuilderStream ignored out-of-order event. contract={state.Contract} ts={ToIso(ts)} " +
// $"current_bar_start={ToIso(state.StartTs)}");
// return;
// }
// if (bucketStart > state.StartTs)
// {
// emitted.Add(ToBarRow(state, state.EndTs, isForming: false));
// StartBar(state, ts, bucketStart, bucketEnd, price, size);
// if (_emitForming)
// {
// emitted.Add(ToBarRow(state, ts, isForming: true));
// }
// return;
// }
// Accumulate(state, price, size);
// state.EndTs = bucketEnd;
// if (_emitForming)
// {
// emitted.Add(ToBarRow(state, ts, isForming: true));
// }
// }
// void ProcessThresholdBar(
// BarState state,
// DateTime ts,
// double price,
// double size,
// List<IBlueRow> emitted,
// bool shouldClose
// )
// {
// if (!state.HasData)
// {
// StartBar(state, ts, ts, ts, price, size);
// MaybeEmitInitialSnapshot(state, ts, emitted);
// }
// else
// {
// Accumulate(state, price, size);
// }
// state.EndTs = ts;
// if (_emitForming)
// {
// emitted.Add(ToBarRow(state, ts, isForming: true));
// }
// if (shouldClose)
// {
// emitted.Add(ToBarRow(state, ts, isForming: false));
// state.HasData = false;
// }
// }
// static DateTime AlignTimeBucket(DateTime ts, int seconds)
// {
// var utc = ts.ToUniversalTime();
// long bucketTicks = TimeSpan.FromSeconds(seconds).Ticks;
// long aligned = (utc.Ticks / bucketTicks) * bucketTicks;
// return new DateTime(aligned, DateTimeKind.Utc);
// }
// void MaybeEmitInitialSnapshot(BarState state, DateTime ts, List<IBlueRow> emitted)
// {
// if (!_emitInitialSnapshot || state.InitialSnapshotEmitted)
// {
// return;
// }
// emitted.Add(ToBarRow(state, ts, isForming: false));
// state.InitialSnapshotEmitted = true;
// }
// void StartBar(
// BarState state,
// DateTime ts,
// DateTime barStart,
// DateTime barEnd,
// double price,
// double size
// )
// {
// state.StartTs = barStart;
// state.EndTs = barEnd;
// state.Open = price;
// state.High = price;
// state.Low = price;
// state.Close = price;
// state.Volume = 0;
// state.TradeCount = 0;
// state.SumPriceSize = 0;
// state.SumSize = 0;
// state.DollarNotional = 0;
// state.SessionDay = ts.Date;
// state.HasData = true;
// Accumulate(state, price, size);
// }
// static void Accumulate(BarState state, double price, double size)
// {
// state.High = Math.Max(state.High, price);
// state.Low = Math.Min(state.Low, price);
// state.Close = price;
// state.TradeCount++;
// if (size > 0)
// {
// state.Volume += size;
// state.SumSize += size;
// state.SumPriceSize += price * size;
// state.DollarNotional += price * size;
// }
// }
// IBlueRow ToBarRow(BarState state, DateTime ts_event, bool isForming)
// {
// double vwap = state.SumSize > 0 ? state.SumPriceSize / state.SumSize : state.Close;
// var row = new MutableBlueRow(_outSchema);
// row.setValue("id", _nextId++);
// row.setValue("ts_event", ToIso(ts_event));
// row.setValue("bar_start_ts", ToIso(state.StartTs));
// row.setValue("bar_end_ts", ToIso(state.EndTs));
// row.setValue("contract", state.Contract);
// row.setValue("open", state.Open);
// row.setValue("high", state.High);
// row.setValue("low", state.Low);
// row.setValue("close", state.Close);
// row.setValue("volume", _volumeSource == VolumeSource.none ? 0.0 : state.Volume);
// row.setValue("trade_count", state.TradeCount);
// row.setValue("vwap", vwap);
// row.setValue("is_forming", isForming);
// return row;
// }
// BarState GetOrCreateState(string contract)
// {
// if (_stateByContract.TryGetValue(contract, out var existing))
// {
// return existing;
// }
// var created = new BarState { Contract = contract };
// _stateByContract[contract] = created;
// return created;
// }
// DateTime ParseTimestamp(IBlueRow row)
// {
// object? raw = row[_timestampCol];
// if (raw is DateTime dt)
// {
// return dt;
// }
// if (raw is string s && DateTime.TryParse(s, null, DateTimeStyles.RoundtripKind, out dt))
// {
// return dt;
// }
// throw new ArgumentException($"Invalid timestamp value in column '{_timestampCol}'.");
// }
// string ResolveContract(IBlueRow row)
// {
// if (_validCols.ContainsKey("contract"))
// {
// return (row["contract"]?.ToString() ?? string.Empty).Trim();
// }
// if (_validCols.ContainsKey("symbol"))
// {
// return (row["symbol"]?.ToString() ?? string.Empty).Trim();
// }
// return string.Empty;
// }
// double ResolvePrice(IBlueRow row)
// {
// return _priceSource switch
// {
// PriceSource.trade_price => ToDouble(row["trade_price"], "trade_price"),
// PriceSource.mid => (ToDouble(row["bid_price"], "bid_price") + ToDouble(row["ask_price"], "ask_price")) / 2.0,
// PriceSource.bid => ToDouble(row["bid_price"], "bid_price"),
// PriceSource.ask => ToDouble(row["ask_price"], "ask_price"),
// _ => throw new ArgumentOutOfRangeException()
// };
// }
// double ResolveSize(IBlueRow row)
// {
// if (_volumeSource == VolumeSource.none)
// {
// return 0;
// }
// return ToDouble(row["trade_size"], "trade_size");
// }
// static double ToDouble(object? value, string colName)
// {
// var d = BlueDataUtility.GetDouble(value!);
// if (!d.HasValue)
// {
// throw new ArgumentException($"Column '{colName}' must be numeric.");
// }
// return d.Value;
// }
// static string ToIso(DateTime dt) =>
// dt.ToUniversalTime().ToString("O");
// static BarType ParseBarType(string value)
// {
// if (Enum.TryParse<BarType>(value, true, out var parsed))
// {
// return parsed;
// }
// throw new ArgumentException("bar_type must be one of: TIME | TICK | VOLUME | DOLLAR");
// }
// static PriceSource ParsePriceSource(string value)
// {
// if (Enum.TryParse<PriceSource>(value, true, out var parsed))
// {
// return parsed;
// }
// throw new ArgumentException("price_source must be one of: trade_price | mid | bid | ask");
// }
// static VolumeSource ParseVolumeSource(string value)
// {
// if (Enum.TryParse<VolumeSource>(value, true, out var parsed))
// {
// return parsed;
// }
// throw new ArgumentException("volume_source must be one of: trade_size | none");
// }
// static SessionReset ParseSessionReset(string value)
// {
// if (!Enum.TryParse<SessionReset>(value, true, out var parsed))
// {
// throw new ArgumentException("session_reset must be one of: NONE | DAY | RTH | ETH");
// }
// // TODO: differentiate RTH/ETH session boundaries; currently treated as DAY.
// if (parsed is SessionReset.RTH or SessionReset.ETH)
// {
// return SessionReset.DAY;
// }
// return parsed;
// }
// }
@@ -1,41 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MathNet.Numerics" Version="5.0.0" />
<PackageReference Include="OpenAI" Version="2.0.0" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
</ItemGroup>
<Choose>
<When Condition="'$(UseProjectRefs)' == 'true'">
<ItemGroup>
<ProjectReference Include="..\..\cs\Bts.Spark.Api\Bts.Spark.Api.csproj" />
<ProjectReference Include="..\DataStreamCore\DataStreamCore.csproj" />
<ProjectReference Include="..\DataStream\DataStream.csproj" />
<ProjectReference Include="..\PubSub\PubSub.csproj" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<PackageReference Include="Bts.Spark.Api" Version="$(SparkVersion)" />
<PackageReference Include="DataStream" Version="$(SparkVersion)" />
<PackageReference Include="PubSub" Version="$(SparkVersion)" />
</ItemGroup>
</Otherwise>
</Choose>
<!-- <ItemGroup>
<RowType Include="RowTemplates\RefTypeRow.tt" SchemaJson="RowTemplates\PubSubHeartbeatSchema.json" TypeName="PubSubHeartbeatRow" TableName="PubSubHeartbeat" />
<RowType Include="RowTemplates\RefTypeRow.tt" SchemaJson="RowTemplates\PubSubRouteSchema.json" TypeName="PubSubRouteRow" TableName="PubSubRoute" />
<RowType Include="RowTemplates\RefTypeRow.tt" SchemaJson="RowTemplates\PubSubServerStateSchema.json" TypeName="PubSubServerStateRow" TableName="PubSubServerState" />
<RowType Include="RowTemplates\RefTypeRow.tt" SchemaJson="RowTemplates\PubSubServerTagStatsSchema.json" TypeName="PubSubServerTagStatsRow" TableName="PubSubServerTagStats" />
<RowType Include="RowTemplates\RefTypeRow.tt" SchemaJson="RowTemplates\TableMetadataSchema.json" TypeName="TableMetadataRow" TableName="TableMetadata" />
</ItemGroup> -->
</Project>
@@ -1,294 +0,0 @@
namespace BlueOrb.Internal
{
using bts;
//using bts.api;
//using bts.spark;
using System;
using System.Diagnostics.CodeAnalysis;
public static class ContractUtils
{
public record FutureTradableContract(
string Symbol,
DateTime Expiration,
Exchange Exchange,
string? ContractText);
public class FutureSpreadContract
{
public List<Tuple<double, FutureTradableContract>> legs = new(2);
public string Symbol
{
get
{
return legs == null || legs.Count == 0 ? string.Empty : legs.ElementAt(0).Item2.Symbol;
}
}
public string? ContractText;
}
public record FutureContinousContract(string Symbol, Exchange Exchange);
// this is for all future conytracts belonging to a symbol
public record FutureWildcardContract(string Symbol, Exchange Exchange);
public class FutureContract
{
public FutureWildcardContract? wildcard_contract;
public FutureTradableContract? future_tradable_contract;
public FutureSpreadContract? spread_tradable_contract;
public FutureContinousContract? continous_constract;
public FutureContract(string txt)
{
wildcard_contract = parse_wildcard_contract(txt);
if (wildcard_contract != null)
return;
var fc = parse_future_contract(txt);
if (fc != null)
{
future_tradable_contract = fc;
return;
}
var sc = parse_future_spread_contract(txt);
if (sc != null)
{
spread_tradable_contract = sc;
return;
}
// this is not totally true, since ParseFutureSpreadContract does not
// parse ICS spreads
continous_constract = new(txt, Exchange.CME);
}
[MemberNotNullWhen(true, nameof(continous_constract))]
public bool is_continous_contract => continous_constract != null;
[MemberNotNullWhen(true, nameof(wildcard_contract))]
public bool is_wildcard_contract => wildcard_contract != null;
[MemberNotNullWhen(true, nameof(future_tradable_contract))]
public bool is_future_tradable_contract => future_tradable_contract != null;
[MemberNotNullWhen(true, nameof(spread_tradable_contract))]
public bool is_spread_tradable_contract => spread_tradable_contract != null;
public string symbol()
{
if (wildcard_contract != null)
return wildcard_contract.Symbol;
if (continous_constract != null)
{
return continous_constract.Symbol;
}
else if (future_tradable_contract != null)
{
return future_tradable_contract.Symbol;
}
else if (spread_tradable_contract != null)
{
return spread_tradable_contract.Symbol;
}
Log.assert(false);
return string.Empty;
}
public string? contract_text
{
get
{
if (future_tradable_contract != null)
return future_tradable_contract.ContractText;
if (spread_tradable_contract != null)
return spread_tradable_contract.ContractText;
return null;
}
}
}
#region Parsing
public static FutureWildcardContract? parse_wildcard_contract(string contract_txt, Exchange exchange = Exchange.CME)
{
if (contract_txt.EndsWith("*"))
{
contract_txt = contract_txt.Replace("*", string.Empty);
return new FutureWildcardContract(contract_txt, exchange);
}
return null;
}
public static FutureTradableContract? parse_future_contract(string contract_txt, Exchange exchange = Exchange.CME)
{
// Validate the future string length
if (!contract_txt.All(c => char.IsLetterOrDigit(c)))
return null;
if (contract_txt.Length < 4)
{
return null;
}
// Extract the symbol and the expiration month/year codes
string symbol = contract_txt.Substring(0, contract_txt.Length - 2);
char monthCode = contract_txt[contract_txt.Length - 2];
char yearCode = contract_txt[contract_txt.Length - 1];
// Map month code to month, return null if the month code is invalid
int month = monthCode switch
{
'F' => 1, // January
'G' => 2, // February
'H' => 3, // March
'J' => 4, // April
'K' => 5, // May
'M' => 6, // June
'N' => 7, // July
'Q' => 8, // August
'U' => 9, // September
'V' => 10, // October
'X' => 11, // November
'Z' => 12, // December
_ => 0 // Return 0 for invalid month code
};
if (month == 0)
{
return null; // Invalid month code
}
// Calculate the year based on the current decade
int currentYear = DateTime.Now.Year;
int decadeStart = currentYear / 10 * 10;
int year = decadeStart + (yearCode - '0');
// If the year is in the past, assume the next decade
if (year < currentYear)
{
year += 10;
}
// Create the FutureContract instance and set its properties
DateTime expiration = new DateTime(year, month, 1);
return new(symbol, expiration, exchange, contract_txt);
}
// Method to parse a futures spread, e.g. "CLX4-CLZ4"
public static FutureSpreadContract? parse_future_spread_contract(string contract_txt, Exchange exchange = Exchange.CME)
{
// Split the string by '-' to handle each leg
var spreadParts = contract_txt.Split('-');
if (spreadParts.Length < 2)
{
return null; // Not a valid spread format
}
var spreadContract = new FutureSpreadContract { legs = new List<Tuple<double, FutureTradableContract>>() };
foreach (var part in spreadParts)
{
// Split each leg by '*', assuming the format is weight*future or just future
string[] legParts = part.Split('*');
double weight = 1.0;
string futurePart;
if (legParts.Length == 2)
{
if (!double.TryParse(legParts[0], out weight))
{
return null; // Invalid weight, parsing failed
}
futurePart = legParts[1];
}
else if (legParts.Length == 1)
{
futurePart = legParts[0];
}
else
{
return null; // Invalid format, too many '*' parts
}
// Parse the future contract
var futureContract = parse_future_contract(futurePart, exchange);
if (futureContract == null)
{
return null; // Failed to parse the future part
}
// Add the leg to the spread contract
spreadContract.legs.Add(new Tuple<double, FutureTradableContract>(weight, futureContract));
}
return spreadContract;
}
// public static ContractType DetermineFutureOrSpread(string contract) {
// if (contract.Contains("-")) {
// return ContractType.FutureSpread;
// } else {
// return ContractType.Future;
// }
// }
#endregion
public static ContractType get_type(string contract_txt)
{
var fc = parse_future_contract(contract_txt);
if (fc != null)
{
return ContractType.Future;
}
var sc = parse_future_spread_contract(contract_txt);
if (sc != null)
{
return ContractType.FutureSpread;
}
// tehre are some non calendar spreads we cant parse
//Log.assert(false);
return ContractType.FutureSpread;
}
public static ContractCategory get_category(string symbol)
{
var tp = get_symbol_category(symbol);
return tp.Item1;
}
public static Tuple<ContractCategory, string> get_symbol_category(string symbol)
{
var fc = parse_future_contract(symbol);
if (fc != null)
{
return Tuple.Create(ContractCategory.FutureString, fc.Symbol);
}
var sc = parse_future_spread_contract(symbol);
if (sc != null)
{
return Tuple.Create(ContractCategory.FutureString, sc.Symbol);
}
return Tuple.Create(ContractCategory.Symbol, symbol);
}
public enum ContractType
{
Spot,
Option,
Future,
FutureSpread,
OptionSpread
}
public enum ContractCategory
{
Symbol = 0,
FutureString,
SpreadString
}
public enum CallPut
{
Call,
Put
}
public enum Exchange
{
CME
}
}
}
@@ -1,99 +0,0 @@
namespace BlueOrb.Operators.Data {
using BCG;
using bts;
using Spark.Core.Diagnostics;
using BlueOrb.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
[DataStreamUserRespresentation("ReplayFutureLiveBBOStream")]
public class ReplayFutureLiveBBOStream : ViewStream, BCG.Utilities.General.IWorker {
private class LastFireTime {
public DateTime last_fireitme_file = DateTime.MinValue;
public DateTime last_firetime_clock = DateTime.MinValue;
}
private class RowsWithPointer {
public List<IBlueRow>? rows;
public int pointer;
}
readonly ViewStreamDatabase? _vsd;
readonly ContractUtils.FutureContinousContract? _fcc;
private readonly LastFireTime _last_fire_time = new LastFireTime();
private RowsWithPointer _rows = new RowsWithPointer();
public ReplayFutureLiveBBOStream(string continous_contract) {
Func<string> iso_8601_now = () => {
DateTime utc_now = DateTime.UtcNow;
long ticks = utc_now.Ticks; // 1 tick = 100 ns
long nanoseconds = ticks % TimeSpan.TicksPerSecond * 100;
string formatted = utc_now.ToString("yyyy-MM-ddTHH:mm:ss");
formatted += $".{nanoseconds:D9}Z";
return formatted;
};
ViewStream rs = new ReplayFutureLiveBBOStream(continous_contract, true);
IBlueTableSchema schema_out = BlueDataUtility.form_schema("BBO",
Tuple.Create("id", TypeCode.Int32),
Tuple.Create("ts_event", TypeCode.String),
Tuple.Create("contract", TypeCode.String),
Tuple.Create("bid_price", TypeCode.Double),
Tuple.Create("bid_size", TypeCode.Int32),
Tuple.Create("ask_price", TypeCode.Double),
Tuple.Create("ask_size", TypeCode.Int32));
rs = new MapStream(rs, s => schema_out,
r =>
new BlueRow(schema_out, r["id"], /*r.get<string>("ts_event")*/iso_8601_now(), r.get<string>("symbol"),
r.get<double>("bid_px_00"), r.get<int>("bid_sz_00"),
r.get<double>("ask_px_00"), r.get<int>("ask_sz_00")));
mySetRealSource(rs);
}
private ReplayFutureLiveBBOStream(string continous_contract, bool noop)
: this(ViewStreamDatabase.instance, new ContractUtils.FutureContract(continous_contract)) { }
public ReplayFutureLiveBBOStream(ViewStreamDatabase vsd, ContractUtils.FutureContract fc) {
var fcc = fc.continous_constract;
Log.assert(fcc != null);
_vsd = vsd;
_fcc = fcc;
}
protected override void myOnFirstSubscriber() {
Log.notnull(_fcc);
var file_path = Path.Combine(SQLiteHelper.location, $"mbp1_{_fcc.Symbol}_small.csv".ToLower());
var rows = BCG.CSVReaderStream.LoadFile(file_path);
_rows.rows = new(rows.Count);
_rows.rows.AddRange(rows.OfType<IBlueRow>().OrderBy(r => r.get<string>("ts_event")));
_rows.pointer = 0;
ExceptionAssert.NotNull(_vsd).addWorker(this);
}
protected override void myOnLastSubscriber() {
ExceptionAssert.NotNull(_vsd).removeWorker(this);
}
public void doWork() {
var rows = ExceptionAssert.NotNull(_rows.rows);
IBlueRow cand_row = rows[_rows.pointer];
string cand_ts_event = cand_row.get<string>("ts_event");
DateTime cand_ts_event_dt = DateTime.Parse(cand_ts_event, null, System.Globalization.DateTimeStyles.RoundtripKind);
TimeSpan cand_ts_span_file = cand_ts_event_dt - _last_fire_time.last_fireitme_file;
TimeSpan ts_clock = DateTime.Now - _last_fire_time.last_firetime_clock;
if (ts_clock >= cand_ts_span_file) {
_rows.pointer++;
_last_fire_time.last_firetime_clock = DateTime.Now;
_last_fire_time.last_fireitme_file = cand_ts_event_dt;
BlueTable bt_out = new BlueTable(cand_row.schema);
bt_out.addRow(cand_row);
var dp_out = BlueDataUtility.build_dp(bt_out, myLastValue as IDataPacket);
myFireEvent(dp_out);
}
}
}
}
@@ -1,111 +0,0 @@
namespace Blueorb.Operators.Data
{
using BCG;
using Spark.Core.Diagnostics;
using BlueOrb.Internal;
using bts;
using BlueOrb.Operators.Core;
using System;
using System.Collections.Generic;
using System.Linq;
[DataStreamUserRespresentation("ReplayFutureLiveTradeStream")]
public class ReplayFutureLiveTradeStream : ViewStream, BCG.Utilities.General.IWorker
{
private class LastFireTime
{
public DateTime last_fireitme_file = DateTime.MinValue;
public DateTime last_firetime_clock = DateTime.MinValue;
}
private class RowsWithPointer
{
public List<IBlueRow>? rows;
public int pointer;
}
readonly ViewStreamDatabase? _vsd;
readonly ContractUtils.FutureContinousContract? _fcc;
private readonly LastFireTime _last_fire_time = new LastFireTime();
readonly RowsWithPointer _rows = new();
public ReplayFutureLiveTradeStream(string continous_contract)
{
Func<string> iso_8601_now = () =>
{
DateTime utc_now = DateTime.UtcNow;
long ticks = utc_now.Ticks; // 1 tick = 100 ns
long nanoseconds = ticks % TimeSpan.TicksPerSecond * 100;
string formatted = utc_now.ToString("yyyy-MM-ddTHH:mm:ss");
formatted += $".{nanoseconds:D9}Z";
return formatted;
};
ViewStream rs = new ReplayFutureLiveTradeStream(continous_contract, true);
IBlueTableSchema schema_out = BlueDataUtility.form_schema("BBO",
Tuple.Create("id", TypeCode.Int32),
Tuple.Create("ts_event", TypeCode.String),
Tuple.Create("contract", TypeCode.String),
Tuple.Create("trade_size", TypeCode.Double),
Tuple.Create("trade_price", TypeCode.Int32),
Tuple.Create("aggressor_side", TypeCode.String));
rs = new MapStream(rs, s => schema_out,
r =>
new BlueRow(schema_out, r["id"], /*r.get<string>("ts_event")*/iso_8601_now(), r.get<string>("symbol"),
r.get<double>("size"), r.get<double>("price"),
r.get<string>("side").StartsWith("B") ? "BUY" : (r.get<string>("side").StartsWith("A") ? "SELL" : "NONE")));
rs = new TimeSeriesStream(rs);
mySetRealSource(rs);
}
private ReplayFutureLiveTradeStream(string continous_contract, bool noop)
: this(ViewStreamDatabase.instance, new ContractUtils.FutureContract(continous_contract)) { }
public ReplayFutureLiveTradeStream(ViewStreamDatabase vsd, ContractUtils.FutureContract fc)
{
var fcc = fc.continous_constract;
Log.assert(fcc != null);
_vsd = vsd;
_fcc = fcc;
}
protected override void myOnFirstSubscriber()
{
Log.notnull(_vsd);
Log.notnull(_fcc);
var file_path = Path.Combine(SQLiteHelper.location, $"trades_{_fcc.Symbol}.csv");
var csv_rd = new BlueOrb.Operators.Core.CSVReaderStream(file_path, false);
var rows = BCG.CSVReaderStream.LoadFile(file_path);
_rows.rows = new(rows.Count);
_rows.rows.AddRange(rows.OfType<IBlueRow>().OrderBy(r => r.get<string>("ts_event")));
_rows.pointer = 0;
ExceptionAssert.NotNull(_vsd).addWorker(this);
}
protected override void myOnLastSubscriber()
{
ExceptionAssert.NotNull(_vsd).removeWorker(this);
}
public void doWork()
{
var rows = ExceptionAssert.NotNull(_rows.rows);
IBlueRow cand_row = rows[_rows.pointer];
string cand_ts_event = cand_row.get<string>("ts_event");
DateTime cand_ts_event_dt = DateTime.Parse(cand_ts_event, null, System.Globalization.DateTimeStyles.RoundtripKind);
TimeSpan cand_ts_span_file = cand_ts_event_dt - _last_fire_time.last_fireitme_file;
TimeSpan ts_clock = DateTime.Now - _last_fire_time.last_firetime_clock;
if (ts_clock >= cand_ts_span_file)
{
_rows.pointer++;
_last_fire_time.last_firetime_clock = DateTime.Now;
_last_fire_time.last_fireitme_file = cand_ts_event_dt;
BlueTable bt_out = new BlueTable(cand_row.schema);
bt_out.addRow(cand_row);
var dp_out = BlueDataUtility.build_dp(bt_out, myLastValue as IDataPacket);
myFireEvent(dp_out);
}
}
}
}
@@ -1,144 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.IO;
using System.Runtime.InteropServices;
namespace BlueOrb.Internal
{
public static class SQLiteHelper
{
public static string location = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? "C:\\BlueOrb_Data\\"
: Path.Combine(Environment.GetEnvironmentVariable("HOME") ?? string.Empty, "BlueOrb_Data");
public static string db_name = "stream_data.db";
public static DataTable execute_select_query(string connection_string, string query)
{
// Create a new DataTable to store the results
DataTable dataTable = new DataTable();
// Create and open a SQLite connection using the provided connection string
using (SQLiteConnection connection = new SQLiteConnection(connection_string))
{
try
{
connection.Open();
// Create a SQLite command with the provided query
using (SQLiteCommand command = new SQLiteCommand(query, connection))
{
// Use SQLiteDataAdapter to fill the DataTable
using (SQLiteDataAdapter adapter = new SQLiteDataAdapter(command))
{
adapter.Fill(dataTable);
}
}
}
catch (Exception ex)
{
Console.WriteLine("An error occurred: " + ex.Message);
}
}
// Return the populated DataTable
return dataTable;
}
public static List<Dictionary<string, object>> ExecuteBulkRead(string connectionString, string query)
{
var result = new List<Dictionary<string, object>>();
using (var connection = new SQLiteConnection(connectionString))
{
connection.Open();
// Begin a transaction to optimize read speed
using (var transaction = connection.BeginTransaction())
using (var command = new SQLiteCommand(query, connection, transaction))
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var row = new Dictionary<string, object>();
for (int i = 0; i < reader.FieldCount; i++)
{
string columnName = reader.GetName(i);
object columnValue = reader.IsDBNull(i) ? null : reader.GetValue(i);
row[columnName] = columnValue;
}
result.Add(row);
}
// Commit the transaction
transaction.Commit();
}
}
return result;
}
public static List<Dictionary<string, object>> get_table(string connectionString, string query)
{
var result = new List<Dictionary<string, object>>();
using (var connection = new SQLiteConnection(connectionString))
{
try
{
connection.Open();
using (var command = new SQLiteCommand(query, connection))
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var row = new Dictionary<string, object>();
for (int i = 0; i < reader.FieldCount; i++)
{
string columnName = reader.GetName(i);
object columnValue = reader.IsDBNull(i) ? null : reader.GetValue(i);
row[columnName] = columnValue;
}
result.Add(row);
}
}
}
catch (Exception ex)
{
Console.WriteLine("An error occurred: " + ex.Message);
}
}
return result;
}
public static IEnumerable<Dictionary<string, object>> get_table_2(string connectionString, string query)
{
using (var connection = new SQLiteConnection(connectionString))
{
connection.Open();
using (var command = new SQLiteCommand(query, connection))
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var row = new Dictionary<string, object>();
for (int i = 0; i < reader.FieldCount; i++)
{
string columnName = reader.GetName(i);
object columnValue = reader.IsDBNull(i) ? null : reader.GetValue(i);
row[columnName] = columnValue;
}
yield return row;
}
}
}
}
}
}
@@ -1,43 +0,0 @@
namespace BlueOrb.Internal
{
using bts;
using System;
using BCG;
using System.Collections.Generic;
using Bts.DataStreamExpressions;
using System.Xml;
// All this does is take in a dsl expression, parse it and fire the data that come out of running it.
// So for example, if an expresison is passed
[DataStreamUserRespresentation("dsl")]
public class DSLStream : ViewStream
{
private readonly string _dsl;
public DSLStream(string dsl)
{
Log.Gen.info($"DSLStream.cons dsl: {dsl}");
// Remove all colons
string sanitizedDsl = dsl.Replace(":", "COLON");
_dsl = dsl;
ViewStream rs = build_stream(dsl) ?? new LiteralStream("error", $"msg:invalid dsl");
mySetRealSource(rs);
}
static ViewStream? build_stream(string stream_expression)
{
try
{
var exp = DataStreamExpressionsInterpreter.Evaluate(stream_expression);
var rv = exp.getView(new Dictionary<string, StatementExpression>(0));
return rv;
}
catch (Exception ex)
{
//send to blueorb
Log.Gen.error($"Could not build stream: {stream_expression} ex: {ex}");
return null;
}
}
}
}
@@ -1,103 +0,0 @@
using System;
using BCG.Utilities.General;
using BCG;
using bts;
namespace BlueOrb.Internal
{
[DataStreamUserRespresentation("MillisecondStream")]
public class MillisecondStream : ViewStream, IWorker
{
private DateTime _last_fire_time = DateTime.MinValue;
private readonly TimeSpan _period;
private readonly int _size;
private readonly ViewStreamDatabase _vsd;
private IBlueTableSchema _schema;
private bts.CircularBufferTable _table;
public MillisecondStream(int interval_msecs, int size)
: this(ViewStreamDatabase.instance, interval_msecs, size)
{
}
public MillisecondStream(ViewStreamDatabase vsd, int interval_msecs, int size)
{
_vsd = vsd;
_period = TimeSpan.FromMilliseconds(interval_msecs);
_size = size;
_schema = BlueDataUtility.form_schema("Milliseconds",
Tuple.Create("id", TypeCode.Int32),
Tuple.Create("time", TypeCode.DateTime),
Tuple.Create("display_time", TypeCode.String));
_table = new CircularBufferTable(_schema, _size);
}
protected override void myOnFirstSubscriber()
{
_vsd.addWorker(this);
}
protected override void myOnLastSubscriber()
{
_vsd.removeWorker(this);
}
private int _id = 0;
public void doWork()
{
if (DateTime.Now - _last_fire_time >= _period)
{
_last_fire_time = DateTime.Now;
IBlueRow nr = new BlueRow(_schema, _id++, _last_fire_time,
_last_fire_time.ToString("yyyy-MM-dd HH:mm:ss.fff"));
_table.add_row(nr);
var dp = BlueDataUtility.build_dp_inc(_table, myLastValue as DataPacket);
myFireEvent(dp);
}
}
}
internal class MSecondStream : TimeUnitStream
{
public MSecondStream(int intervalInms, int size)
: base(DateTime.Now, new TimeSpan(0, 0, 0, 0, intervalInms), size, ViewStreamDatabase.instance) { }
protected override DateTime myRoundTime(DateTime dt) { return dt; }
}
internal class DisplayableMillisecondStream : ViewStream, IStreamMapper
{
private IBlueTableSchema mySchema = new BlueTableSchema("ms",
new ColumnInfo("id", 0, typeof(int)),
new ColumnInfo("time", 1, typeof(string)));
public DisplayableMillisecondStream(int intervalInMs, int sz)
{
mySetRealSource(new MapStream(new MSecondStream(intervalInMs, sz), this));
}
#region IStreamMapper Members
public IBlueTableSchema getOutputSchema(IBlueTableSchema inputSchema)
{
return mySchema;
}
#endregion
#region IDynamicStreamMapper Members
public IBlueRow map(IBlueRow row)
{
DateTime time = row.get_datetime("time");
var time_txt = time.ToString("yyyy-MM-dd HH:mm:ss.fff");
return new BlueRow(mySchema, row["id"], time_txt);
}
#endregion
private string myToString(DateTime dt)
{
string sep = ":";
return dt.Hour + sep + dt.Minute + sep + dt.Second + sep + dt.Millisecond;
}
}
}
@@ -1,348 +0,0 @@
namespace BlueOrb.Operators.Signal
{
using System;
using System.Collections.Concurrent;
using System.IO.MemoryMappedFiles;
using BCG;
using System.Text.Json.Serialization;
using System.Text.Json;
using System.Data;
public enum BarType
{
TIME,
TICK,
VOLUME,
DOLLAR,
}
public class BarBuilderSchemaInfo
{
[JsonPropertyName("price_col")]
public string price_col { get; set; } = "trade_price";
[JsonPropertyName("volume_col")]
public string volume_col { get; set; } = "trade_size";
[JsonPropertyName("timestamp_col")]
public string timestamp_col { get; set; } = "ts_event";
}
public class SingleBar : IBlueRow
{
private BarBuilderStream _parent_str;
private IBlueTableSchema _schema;
private MutableBlueRow _row;
public SingleBar(BarBuilderStream parent_str)
{
_parent_str = parent_str;
_schema = BlueDataUtility.form_schema(
"bar_builder_single_bar",
Tuple.Create("id", TypeCode.Int32),
Tuple.Create("ts_event", TypeCode.DateTime),
Tuple.Create("bar_start_ts", TypeCode.DateTime),
Tuple.Create("bar_end_ts", TypeCode.DateTime),
Tuple.Create("open", TypeCode.Double),
Tuple.Create("high", TypeCode.Double),
Tuple.Create("low", TypeCode.Double),
Tuple.Create("close", TypeCode.Double),
Tuple.Create("volume", TypeCode.Double),
Tuple.Create("notional", TypeCode.Double),
Tuple.Create("trade_count", TypeCode.Int32),
Tuple.Create("n_events", TypeCode.Int32),
Tuple.Create("vwap", TypeCode.Double),
Tuple.Create("is_active", TypeCode.Boolean)
);
_row = new MutableBlueRow(_schema);
}
public IBlueTableSchema schema => _row.schema;
public object this[int index] => _row[index];
public object this[string col_name] => _row[col_name];
public IBlueRow add_event(IBlueRow r)
{
// initiaizes _row
void reset_new_bar()
{
_row = new MutableBlueRow(_schema);
_row.setValue("id", _parent_str.get_new_id());
_row.setValue("volume", 0.0);
_row.setValue("notional", 0.0);
_row.setValue("trade_count", 0);
_row.setValue("n_events", 0);
_row.setValue("is_active", true);
}
void absorb_into_row(IBlueRow input_row)
{
var ts = input_row.get_datetime(_parent_str._schema_info.timestamp_col, DateTime.UtcNow).ToUniversalTime();
var price = input_row.get<double>(_parent_str._schema_info.price_col, 0.0);
var volume = input_row.get<double>(_parent_str._schema_info.volume_col, 0.0);
var notional = price * volume;
if (_row.is_null("bar_start_ts"))
{
DateTime bar_start_ts;
DateTime bar_end_ts;
if (_parent_str._bar_type == BarType.TIME)
{
var bucket_ticks = (long)(Math.Max(1.0, _parent_str._bar_size) * TimeSpan.TicksPerSecond);
var start_ticks = (ts.Ticks / bucket_ticks) * bucket_ticks;
bar_start_ts = new DateTime(start_ticks, DateTimeKind.Utc);
bar_end_ts = bar_start_ts.AddTicks(bucket_ticks);
}
else
{
bar_start_ts = ts;
bar_end_ts = ts;
}
_row.setValue("bar_start_ts", bar_start_ts);
_row.setValue("bar_end_ts", bar_end_ts);
_row.setValue("open", price);
_row.setValue("high", price);
_row.setValue("low", price);
}
else
{
var high = _row.get<double>("high", price);
var low = _row.get<double>("low", price);
_row.setValue("high", Math.Max(high, price));
_row.setValue("low", Math.Min(low, price));
}
_row.setValue("ts_event", ts);
_row.setValue("close", price);
_row.setValue("volume", _row.get<double>("volume", 0.0) + volume);
_row.setValue("notional", _row.get<double>("notional", 0.0) + notional);
_row.setValue("trade_count", _row.get<int>("trade_count", 0) + 1);
_row.setValue("n_events", _row.get<int>("n_events", 0) + 1);
var running_volume = _row.get<double>("volume", 0.0);
var running_notional = _row.get<double>("notional", 0.0);
_row.setValue("vwap", running_volume > 0.0 ? running_notional / running_volume : price);
}
bool is_closed()
{
bool closed;
if (_parent_str._bar_type == BarType.TIME)
{
var ts = _row.get_datetime("ts_event", DateTime.MinValue);
var bar_end_ts = _row.get_datetime("bar_end_ts", DateTime.MaxValue);
closed = ts >= bar_end_ts;
}
else if (_parent_str._bar_type == BarType.TICK)
{
closed = _row.get<int>("n_events", 0) >= _parent_str._bar_size;
}
else if (_parent_str._bar_type == BarType.VOLUME)
{
closed = _row.get<double>("volume", 0.0) >= _parent_str._bar_size;
}
else
{
closed = _row.get<double>("notional", 0.0) >= _parent_str._bar_size;
}
_row.setValue("is_active", !closed);
return closed;
}
if (_row == null)
{
reset_new_bar();
}
absorb_into_row(r);
if (is_closed())
{
IBlueRow closed_row = new BlueRow(_row);
reset_new_bar();
return closed_row;
}
return null;
}
}
public class BarState : IBlueRowCollection
{
private SingleBar _curr_row;
private BlueTable _state;
public BarState(BarBuilderStream parent_str)
{
_curr_row = new SingleBar(parent_str);
_state = new BlueTable(_curr_row.schema);
}
public bool add_event(IBlueRow r)
{
var closed_bar = _curr_row.add_event(r);
if (closed_bar is not null)
{
// curr bar is closed, only then its added
// when bars are evolving we dont add it
_state.addRow(closed_bar);
return true;
}
return false;
}
public IBlueRow this[int id] => _state[id];
public IBlueTableSchema schema => _state.schema;
public bool containsID(int id) => _state.containsID(id);
public int Count => _state.Count;
public System.Collections.IEnumerator GetEnumerator() => _state.GetEnumerator();
}
[DataStreamUserRespresentation("BarBuilderStream")]
public class BarBuilderStream : ViewStream
{
readonly ViewStream _price_stream;
internal readonly BarType _bar_type;
internal readonly double _bar_size;
internal readonly bool _show_open_bars;
internal readonly BarBuilderSchemaInfo _schema_info;
private BarState _state;
public BarBuilderStream(ViewStream price_stream,
BarType bar_type,
double bar_size,
bool show_open_bars,
BarBuilderSchemaInfo schema_info)
{
_price_stream = price_stream;
_bar_type = bar_type;
_bar_size = bar_size;
_show_open_bars = show_open_bars;
_schema_info = schema_info;
_state = new BarState(this);
}
int _id = 0;
internal int get_new_id()
{
return _id++;
}
public BarBuilderStream(ViewStream price_stream,
string bar_type,
double bar_size,
string schema_info_json)
:
this(price_stream,
Enum.Parse<BarType>(bar_type),
bar_size,
true,
_parse_and_validate_schema_info_json(schema_info_json))
{
}
public BarBuilderStream(ViewStream price_stream,
string bar_type,
double bar_size,
string price_col,
string volume_col,
string timestamp_col)
:
this(price_stream,
Enum.Parse<BarType>(bar_type),
bar_size,
true,
_create_and_validate_schema_info(price_col, volume_col, timestamp_col))
{
}
protected override void myOnFirstSubscriber()
{
_price_stream.onChange += _on_price_stream_change;
}
protected override void myOnLastSubscriber()
{
_price_stream.onChange -= _on_price_stream_change;
}
void _on_price_stream_change(object dp_obj)
{
DataPacket dp = dp_obj as DataPacket;
var sz_0 = _state.Count;
foreach (IBlueRow r in dp.addedRows)
{
_state.add_event(r);
}
if (_state.Count != sz_0)
// we will check for _show_open_bars here
{
var dp_out = BlueDataUtility.build_dp_inc(_state, myLastValue as DataPacket, false);
myFireEvent(dp_out);
}
}
static BarBuilderSchemaInfo _parse_and_validate_schema_info_json(string schema_info_json)
{
if (string.IsNullOrWhiteSpace(schema_info_json))
{
throw new ArgumentException("schema_info_json cannot be null or empty.", nameof(schema_info_json));
}
var schema_info = JsonSerializer.Deserialize<BarBuilderSchemaInfo>(schema_info_json);
_validate_schema_info(schema_info);
return schema_info!;
}
static BarBuilderSchemaInfo _create_and_validate_schema_info(
string price_col,
string volume_col,
string timestamp_col)
{
var schema_info = new BarBuilderSchemaInfo
{
price_col = price_col,
volume_col = volume_col,
timestamp_col = timestamp_col,
};
_validate_schema_info(schema_info);
return schema_info;
}
static void _validate_schema_info(BarBuilderSchemaInfo? schema_info)
{
if (schema_info is null)
{
throw new ArgumentException("schema_info_json did not deserialize into BarBuilderSchemaInfo.");
}
if (string.IsNullOrWhiteSpace(schema_info.price_col))
{
throw new ArgumentException("BarBuilderSchemaInfo.PriceCol cannot be null or empty.");
}
if (string.IsNullOrWhiteSpace(schema_info.volume_col))
{
throw new ArgumentException("BarBuilderSchemaInfo.VolumeCol cannot be null or empty.");
}
if (string.IsNullOrWhiteSpace(schema_info.timestamp_col))
{
throw new ArgumentException("BarBuilderSchemaInfo.TimestampCol cannot be null or empty.");
}
if (schema_info.price_col.Equals(schema_info.volume_col, StringComparison.OrdinalIgnoreCase) ||
schema_info.price_col.Equals(schema_info.timestamp_col, StringComparison.OrdinalIgnoreCase) ||
schema_info.volume_col.Equals(schema_info.timestamp_col, StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException("BarBuilderSchemaInfo columns must be distinct.");
}
}
}
}
+192 -192
View File
@@ -1,192 +1,192 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Reflection;
using Microsoft.Win32;
namespace BCG
{
public enum RegistryRoot { HKCU, HKLM }
[Serializable]
public class BlueRegistry
{
public const string BlueSubKey = @"Software\Blue Capital Group\";
public static readonly string ApplicationPrefix;
protected string myFullPath;
public BlueRegistry(string subPath)
{
myFullPath = string.Concat(BlueRegistry.ApplicationPrefix, @"\", subPath);
}
public BlueRegistry(BlueRegistry parent, string subPath)
{
myFullPath = string.Concat(parent.myFullPath, @"\", subPath);
}
static BlueRegistry()
{
string app = "Applications";
Assembly ass = Assembly.GetEntryAssembly();
if (ass != null)
{
app = ass.GetName().Name;
object[] attrs = ass.GetCustomAttributes(
Type.GetType("System.Reflection.AssemblyTitleAttribute"), true);
if (attrs.Length > 0 && ((AssemblyTitleAttribute)attrs[0]).Title != string.Empty)
{
app = ((AssemblyTitleAttribute)attrs[0]).Title;
}
}
ApplicationPrefix = string.Concat(BlueRegistry.BlueSubKey, app);
}
public object getValue(string name)
{
return getValue(RegistryRoot.HKCU, name);
}
public object getValue(string name, object defaultValue)
{
return getValue(RegistryRoot.HKCU, name, defaultValue);
}
public void setValue(string name, object value)
{
setValue(RegistryRoot.HKCU, name, value);
}
public void deleteValue(string name)
{
deleteValue(RegistryRoot.HKCU, name);
}
private RegistryKey myGetRegistryKey(RegistryRoot root)
{
if (root == RegistryRoot.HKCU)
return Registry.CurrentUser.CreateSubKey(myFullPath);
else
return Registry.LocalMachine.CreateSubKey(myFullPath);
}
#region Generic Methods
public virtual void setValue(RegistryRoot root, string name, object value)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
rk.SetValue(name, value);
}
}
internal virtual object getValue(RegistryRoot root, string name)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
return rk.GetValue(name);
}
}
internal virtual void deleteValue(RegistryRoot root, string name)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
rk.DeleteValue(name);
}
}
public virtual object getValue(RegistryRoot root, string name, object defaultValue)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
return rk.GetValue(name, defaultValue);
}
}
#endregion
#region Double
internal virtual void setDouble(RegistryRoot root, string name, double value)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
DoubleRegistryHandler.setValue(rk, name, value);
}
}
internal virtual double getDouble(RegistryRoot root, string name)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
return DoubleRegistryHandler.getValue(rk, name);
}
}
#endregion
#region Enum
internal virtual void setEnum(RegistryRoot root, string name, Enum value)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
EnumRegistryHandler.setValue(rk, name, value);
}
}
internal virtual Enum getEnum(RegistryRoot root, string name, Type enumType)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
return EnumRegistryHandler.getValue(rk, name, enumType);
}
}
#endregion
#region Array
internal virtual void setArray(RegistryRoot root, string name, Array array)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
ArrayRegistryHandler.setValue(rk, name, array);
}
}
internal virtual Array getArray(RegistryRoot root, string name, Type elementType)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
return ArrayRegistryHandler.getValue(rk, name, elementType);
}
}
#endregion
#region SortedList
internal virtual void setSortedList(RegistryRoot root, string name, SortedList slist)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
SortedListRegistryHandler.setValue(rk, name, slist);
}
}
internal virtual SortedList getSortedList(RegistryRoot root, string name)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
return SortedListRegistryHandler.getValue(rk, name);
}
}
internal virtual void deleteSortedList(RegistryRoot root, string name)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
SortedListRegistryHandler.deleteValue(rk, name);
}
}
#endregion
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Reflection;
using Microsoft.Win32;
namespace BCG
{
public enum RegistryRoot { HKCU, HKLM }
[Serializable]
public class BlueRegistry
{
public const string BlueSubKey = @"Software\Blue Capital Group\";
public static readonly string ApplicationPrefix;
protected string myFullPath;
public BlueRegistry(string subPath)
{
myFullPath = string.Concat(BlueRegistry.ApplicationPrefix, @"\", subPath);
}
public BlueRegistry(BlueRegistry parent, string subPath)
{
myFullPath = string.Concat(parent.myFullPath, @"\", subPath);
}
static BlueRegistry()
{
string app = "Applications";
Assembly ass = Assembly.GetEntryAssembly();
if (ass != null)
{
app = ass.GetName().Name;
object[] attrs = ass.GetCustomAttributes(
Type.GetType("System.Reflection.AssemblyTitleAttribute"), true);
if (attrs.Length > 0 && ((AssemblyTitleAttribute)attrs[0]).Title != string.Empty)
{
app = ((AssemblyTitleAttribute)attrs[0]).Title;
}
}
ApplicationPrefix = string.Concat(BlueRegistry.BlueSubKey, app);
}
public object getValue(string name)
{
return getValue(RegistryRoot.HKCU, name);
}
public object getValue(string name, object defaultValue)
{
return getValue(RegistryRoot.HKCU, name, defaultValue);
}
public void setValue(string name, object value)
{
setValue(RegistryRoot.HKCU, name, value);
}
public void deleteValue(string name)
{
deleteValue(RegistryRoot.HKCU, name);
}
private RegistryKey myGetRegistryKey(RegistryRoot root)
{
if (root == RegistryRoot.HKCU)
return Registry.CurrentUser.CreateSubKey(myFullPath);
else
return Registry.LocalMachine.CreateSubKey(myFullPath);
}
#region Generic Methods
internal virtual void setValue(RegistryRoot root, string name, object value)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
rk.SetValue(name, value);
}
}
internal virtual object getValue(RegistryRoot root, string name)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
return rk.GetValue(name);
}
}
internal virtual void deleteValue(RegistryRoot root, string name)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
rk.DeleteValue(name);
}
}
internal virtual object getValue(RegistryRoot root, string name, object defaultValue)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
return rk.GetValue(name, defaultValue);
}
}
#endregion
#region Double
internal virtual void setDouble(RegistryRoot root, string name, double value)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
DoubleRegistryHandler.setValue(rk, name, value);
}
}
internal virtual double getDouble(RegistryRoot root, string name)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
return DoubleRegistryHandler.getValue(rk, name);
}
}
#endregion
#region Enum
internal virtual void setEnum(RegistryRoot root, string name, Enum value)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
EnumRegistryHandler.setValue(rk, name, value);
}
}
internal virtual Enum getEnum(RegistryRoot root, string name, Type enumType)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
return EnumRegistryHandler.getValue(rk, name, enumType);
}
}
#endregion
#region Array
internal virtual void setArray(RegistryRoot root, string name, Array array)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
ArrayRegistryHandler.setValue(rk, name, array);
}
}
internal virtual Array getArray(RegistryRoot root, string name, Type elementType)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
return ArrayRegistryHandler.getValue(rk, name, elementType);
}
}
#endregion
#region SortedList
internal virtual void setSortedList(RegistryRoot root, string name, SortedList slist)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
SortedListRegistryHandler.setValue(rk, name, slist);
}
}
internal virtual SortedList getSortedList(RegistryRoot root, string name)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
return SortedListRegistryHandler.getValue(rk, name);
}
}
internal virtual void deleteSortedList(RegistryRoot root, string name)
{
using (RegistryKey rk = myGetRegistryKey(root))
{
SortedListRegistryHandler.deleteValue(rk, name);
}
}
#endregion
}
}
@@ -1,9 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
</Project>
@@ -1,6 +1,4 @@
using System;
using System.Runtime.Versioning;
using Microsoft.Win32;
namespace BCG
@@ -12,7 +10,6 @@ namespace BCG
rk.SetValue (name, value.ToString ());
}
[SupportedOSPlatform("windows")]
public static double getValue (RegistryKey rk, string name)
{
object v = rk.GetValue (name);
@@ -1,166 +1,166 @@
using System;
using System.Reflection;
using System.Windows.Forms;
using System.Drawing;
using System.Diagnostics;
using Microsoft.Win32;
namespace BCG
{
public class PersistWindowState
{
// event info that allows form to persist extra window state data
public delegate void WindowStateHandler (object sender, BlueRegistry bluereg);
public event WindowStateHandler LoadState;
public event WindowStateHandler SaveState;
private Form myParent;
private BlueRegistry myRegistry;
private int myNormalLeft;
private int myNormalTop;
private int myNormalWidth;
private int myNormalHeight;
private bool myResizable = true;
private FormWindowState myWindowState;
private bool myAllowSaveMinimized = false;
private bool mySavePosition = true;
private bool mySaveState = true;
public PersistWindowState (bool savePosition)
{
mySavePosition = savePosition;
}
public PersistWindowState ()
{
}
public bool saveState
{
[DebuggerStepThrough]
set { mySaveState = value; }
}
public Form parent
{
[DebuggerStepThrough]
get { return myParent; }
set
{
myParent = value;
myRegistry = new BlueRegistry (myParent.Text);
// subscribe to parent form's events
myParent.Closing += new System.ComponentModel.CancelEventHandler(myOnClosing);
myParent.Resize += new System.EventHandler(myOnResize);
myParent.Move += new System.EventHandler(myOnMove);
myParent.Load += new System.EventHandler(myOnLoad);
// get initial width and height in case form is never resized
myNormalWidth = myParent.Width;
myNormalHeight = myParent.Height;
}
}
public BlueRegistry blueRegistry
{
[DebuggerStepThrough]
get { return myRegistry; }
[DebuggerStepThrough]
set { myRegistry = value; }
}
public bool resizable
{
[DebuggerStepThrough]
set { myResizable = value; }
}
public bool allowSaveMinimized
{
[DebuggerStepThrough]
set { myAllowSaveMinimized = value; }
}
private void myOnResize(object sender, System.EventArgs e)
{
// save width and height
if (myParent.WindowState == FormWindowState.Normal && myResizable)
{
myNormalWidth = myParent.Width;
myNormalHeight = myParent.Height;
}
}
private void myOnMove(object sender, System.EventArgs e)
{
// save position
if(myParent.WindowState == FormWindowState.Normal)
{
myNormalLeft = myParent.Left;
myNormalTop = myParent.Top;
}
// save state
myWindowState = myParent.WindowState;
}
private void myOnClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
// save position, size and state
if (mySavePosition)
{
myRegistry.setValue (RegistryRoot.HKCU, "Left", myNormalLeft);
myRegistry.setValue (RegistryRoot.HKCU, "Top", myNormalTop);
}
if (myResizable)
{
myRegistry.setValue (RegistryRoot.HKCU, "Width", myNormalWidth);
myRegistry.setValue (RegistryRoot.HKCU, "Height", myNormalHeight);
}
// check if we are allowed to save the state as minimized (not normally)
if (!myAllowSaveMinimized)
{
if(myWindowState == FormWindowState.Minimized)
myWindowState = FormWindowState.Normal;
}
if (mySaveState)
myRegistry.setValue (RegistryRoot.HKCU, "WindowState", (int) myWindowState);
// fire SaveState event
if (SaveState != null)
SaveState (this, myRegistry);
}
private void myOnLoad (object sender, System.EventArgs e)
{
if (mySavePosition)
{
int left = (int) myRegistry.getValue (RegistryRoot.HKCU, "Left", myParent.Left);
int top = (int) myRegistry.getValue (RegistryRoot.HKCU, "Top", myParent.Top);
myParent.Location = new Point (left, top);
}
if (myResizable)
{
int width = (int) myRegistry.getValue (RegistryRoot.HKCU, "Width", myParent.Width);
int height = (int) myRegistry.getValue (RegistryRoot.HKCU, "Height", myParent.Height);
myParent.Size = new Size (width, height);
}
if (mySaveState)
{
FormWindowState windowState = (FormWindowState) myRegistry.getValue (RegistryRoot.HKCU, "WindowState",
(int) myParent.WindowState);
myParent.WindowState = windowState;
}
// fire LoadState event
if(LoadState != null)
LoadState (this, myRegistry);
}
}
}
using System;
using System.Reflection;
using System.Windows.Forms;
using System.Drawing;
using System.Diagnostics;
using Microsoft.Win32;
namespace BCG
{
public class PersistWindowState
{
// event info that allows form to persist extra window state data
public delegate void WindowStateHandler (object sender, BlueRegistry bluereg);
public event WindowStateHandler LoadState;
public event WindowStateHandler SaveState;
private Form myParent;
private BlueRegistry myRegistry;
private int myNormalLeft;
private int myNormalTop;
private int myNormalWidth;
private int myNormalHeight;
private bool myResizable = true;
private FormWindowState myWindowState;
private bool myAllowSaveMinimized = false;
private bool mySavePosition = true;
private bool mySaveState = true;
public PersistWindowState (bool savePosition)
{
mySavePosition = savePosition;
}
public PersistWindowState ()
{
}
public bool saveState
{
[DebuggerStepThrough]
set { mySaveState = value; }
}
public Form parent
{
[DebuggerStepThrough]
get { return myParent; }
set
{
myParent = value;
myRegistry = new BlueRegistry (myParent.Text);
// subscribe to parent form's events
myParent.Closing += new System.ComponentModel.CancelEventHandler(myOnClosing);
myParent.Resize += new System.EventHandler(myOnResize);
myParent.Move += new System.EventHandler(myOnMove);
myParent.Load += new System.EventHandler(myOnLoad);
// get initial width and height in case form is never resized
myNormalWidth = myParent.Width;
myNormalHeight = myParent.Height;
}
}
public BlueRegistry blueRegistry
{
[DebuggerStepThrough]
get { return myRegistry; }
[DebuggerStepThrough]
set { myRegistry = value; }
}
public bool resizable
{
[DebuggerStepThrough]
set { myResizable = value; }
}
public bool allowSaveMinimized
{
[DebuggerStepThrough]
set { myAllowSaveMinimized = value; }
}
private void myOnResize(object sender, System.EventArgs e)
{
// save width and height
if (myParent.WindowState == FormWindowState.Normal && myResizable)
{
myNormalWidth = myParent.Width;
myNormalHeight = myParent.Height;
}
}
private void myOnMove(object sender, System.EventArgs e)
{
// save position
if(myParent.WindowState == FormWindowState.Normal)
{
myNormalLeft = myParent.Left;
myNormalTop = myParent.Top;
}
// save state
myWindowState = myParent.WindowState;
}
private void myOnClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
// save position, size and state
if (mySavePosition)
{
myRegistry.setValue (RegistryRoot.HKCU, "Left", myNormalLeft);
myRegistry.setValue (RegistryRoot.HKCU, "Top", myNormalTop);
}
if (myResizable)
{
myRegistry.setValue (RegistryRoot.HKCU, "Width", myNormalWidth);
myRegistry.setValue (RegistryRoot.HKCU, "Height", myNormalHeight);
}
// check if we are allowed to save the state as minimized (not normally)
if (!myAllowSaveMinimized)
{
if(myWindowState == FormWindowState.Minimized)
myWindowState = FormWindowState.Normal;
}
if (mySaveState)
myRegistry.setValue (RegistryRoot.HKCU, "WindowState", (int) myWindowState);
// fire SaveState event
if (SaveState != null)
SaveState (this, myRegistry);
}
private void myOnLoad (object sender, System.EventArgs e)
{
if (mySavePosition)
{
int left = (int) myRegistry.getValue (RegistryRoot.HKCU, "Left", myParent.Left);
int top = (int) myRegistry.getValue (RegistryRoot.HKCU, "Top", myParent.Top);
myParent.Location = new Point (left, top);
}
if (myResizable)
{
int width = (int) myRegistry.getValue (RegistryRoot.HKCU, "Width", myParent.Width);
int height = (int) myRegistry.getValue (RegistryRoot.HKCU, "Height", myParent.Height);
myParent.Size = new Size (width, height);
}
if (mySaveState)
{
FormWindowState windowState = (FormWindowState) myRegistry.getValue (RegistryRoot.HKCU, "WindowState",
(int) myParent.WindowState);
myParent.WindowState = windowState;
}
// fire LoadState event
if(LoadState != null)
LoadState (this, myRegistry);
}
}
}
@@ -6,80 +6,23 @@ using Spark.Core.Collections;
static class ArgumentComparer {
public static int Compare(
IArgument value1, IArgument value2, IDictionary<string, object?> env) {
IArgument value1, IArgument value2, IDictionary<string,object?> env) {
if (value1 is null) {
throw new ArgumentNullException(nameof(value1));
}
if (value2 is null) {
throw new ArgumentNullException(nameof(value2));
}
var obj1 = value1.GetValue(env);
var obj2 = value2.GetValue(env);
if (obj1 is null) {
if (obj2 is null) {
return 0;
}
return -1;
}
if (obj2 is null) {
return 1;
}
return compareObjs(obj1, obj2);
}
static int compareObjs(object obj1, object obj2) {
var cmp1 = value1.Cast<IComparable>();
var cmp2 = value2.Cast<IComparable>();
try {
var typ1 = obj1.GetType();
var typ2 = obj2.GetType();
bool areSameTypes = typ1 == typ2;
if (areSameTypes) {
return ((IComparable)obj1).CompareTo(obj2);
}
if (typ1.IsNumeric()) {
return tryCompareNumeric(obj1, obj2);
} else if (typ2.IsNumeric()) {
return -tryCompareNumeric(obj2, obj1);
} else if (typ1.IsEnum) {
if (typ2 == typeof(string)) {
return -((string)obj2).CompareTo(obj1.ToString());
}
} else if (typ1 == typeof(string)) {
return ((string)obj1).CompareTo(obj2.ToString());
} else if (typ1 == typeof(DateTime)) {
if (typ2 == typeof(TimeSpan)) {
return ((DateTime)obj1).Ticks.CompareTo(((TimeSpan)obj2).Ticks);
}
} else if (typ1 == typeof(TimeSpan)) {
if (typ2 == typeof(DateTime)) {
return ((TimeSpan)obj1).Ticks.CompareTo(((DateTime)obj2).Ticks);
}
}
var v1 = cmp1.GetValue(env);
var v2 = cmp2.GetValue(env);
return v1.GetType().IsNumeric() ?
new NumericComparer().Compare(v1, v2) : v1.CompareTo(v2);
} catch (Exception ex) {
Log.Ui.error($"Comparison failed: {ex}");
throw;
}
throw new ArgumentException("Failed to compare obj1 and obj2", nameof(obj1));
}
static int tryCompareNumeric(object numericObj1, object obj2) {
var typ2 = obj2.GetType();
if (typ2.IsNumeric()) {
return new NumericComparer().Compare(numericObj1, obj2);
} else if (typ2.IsEnum) {
var undTyp2 = typ2.GetEnumUnderlyingType();
if (undTyp2 == typeof(byte)) {
return new NumericComparer().Compare(numericObj1, (byte)obj2);
}
if (undTyp2 == typeof(short)) {
return new NumericComparer().Compare(numericObj1, (short)obj2);
}
if (undTyp2 == typeof(int)) {
return new NumericComparer().Compare(numericObj1, (int)obj2);
}
if (undTyp2 == typeof(long)) {
return new NumericComparer().Compare(numericObj1, (long)obj2);
}
}
throw new ArgumentException("Failed to compare numeric obj1 and obj2", nameof(obj2));
}
}
@@ -1,11 +1,19 @@
namespace Bts.BooleanExpressions;
using bts;
class BooleanExpression : IBooleanExpression {
readonly Func<IDictionary<string, object?>, bool> evaluate;
public BooleanExpression(Func<IDictionary<string, object?>, bool> evaluate) =>
this.evaluate = evaluate;
public bool Evaluate(IDictionary<string, object?> env) =>
evaluate(env);
public bool Evaluate(IDictionary<string, object?> env) {
try {
return evaluate(env);
} catch (Exception ex) {
Log.assert(false, $"BooleanExpression.Evaluate failed: {ex}");
throw;
}
}
}
@@ -42,11 +42,15 @@ OpenParenthesis \(
CloseParenthesis \)
Comma ,
Negate '!'
MapsTo ':'
IsOfType '/'
%%
{StringConstant} {
yylval.String = yytext.Substring(1, yytext.Length - 2).Replace(@"\'", "'");
return (int)Token.STRING_CONSTANT;
}
{BooleanConstant} {
yylval.Boolean = yytext.ToLower() switch {
"true" => true,
@@ -57,11 +61,6 @@ IsOfType '/'
return (int)Token.BOOLEAN_CONSTANT;
}
{StringConstant} {
yylval.String = yytext.Substring(1, yytext.Length - 2).Replace(@"\'", "'");
return (int)Token.STRING_CONSTANT;
}
{NullConstant} {
yylval.Null = DBNull.Value;
return (int)Token.NULL_CONSTANT;
@@ -98,10 +97,6 @@ IsOfType '/'
return (int)Token.NEGATE;
}
{MapsTo} {
return (int)Token.MAPS_TO;
}
{Equal} {
return (int)Token.EQUAL;
}
@@ -8,23 +8,13 @@
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.24.3" />
<PackageReference Include="YaccLexTools" Version="1.2.3" />
<PackageReference Include="YaccLexTools" Version="1.2.0" />
</ItemGroup>
<Choose>
<When Condition="'$(UseProjectRefs)' == 'true'">
<ItemGroup>
<ProjectReference Include="..\ExpressionCore\ExpressionCore.csproj" />
<ProjectReference Include="..\..\cs\Bts.Spark.Core\Bts.Spark.Core.csproj" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<PackageReference Include="ExpressionCore" Version="$(SparkVersion)" />
<PackageReference Include="Bts.Spark.Core" Version="$(SparkVersion)" />
</ItemGroup>
</Otherwise>
</Choose>
<ItemGroup>
<ProjectReference Include="..\ExpressionCore\ExpressionCore.csproj" />
<ProjectReference Include="..\..\client\spark_core\spark_core.csproj" />
</ItemGroup>
<ItemGroup>
<Scanner Include="BooleanExpressionTokens.lex" />
File diff suppressed because it is too large. Load diff
@@ -10,20 +10,11 @@
<PackageReference Include="YaccLexTools" Version="1.2.2" />
</ItemGroup>
<Choose>
<When Condition="'$(UseProjectRefs)' == 'true'">
<ItemGroup>
<ProjectReference Include="..\DataStreamCore\DataStreamCore.csproj" />
<ProjectReference Include="..\ExpressionCore\ExpressionCore.csproj" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<PackageReference Include="DataStreamCore" Version="$(SparkVersion)" />
<PackageReference Include="ExpressionCore" Version="$(SparkVersion)" />
</ItemGroup>
</Otherwise>
</Choose>
<ItemGroup>
<ProjectReference Include="..\DataStreamCore\DataStreamCore.csproj" />
<ProjectReference Include="..\ExpressionCore\ExpressionCore.csproj" />
<ProjectReference Include="..\..\client\spark_core\spark_core.csproj" />
</ItemGroup>
<ItemGroup Label="ColumnExpression">
<Scanner Include="ColumnExpressionTokens.lex" />
File diff suppressed because it is too large. Load diff
@@ -10,20 +10,11 @@
<PackageReference Include="YaccLexTools" Version="1.2.2" />
</ItemGroup>
<Choose>
<When Condition="'$(UseProjectRefs)' == 'true'">
<ItemGroup>
<ProjectReference Include="..\DataStreamCore\DataStreamCore.csproj" />
<ProjectReference Include="..\ExpressionCore\ExpressionCore.csproj" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<PackageReference Include="DataStreamCore" Version="$(SparkVersion)" />
<PackageReference Include="ExpressionCore" Version="$(SparkVersion)" />
</ItemGroup>
</Otherwise>
</Choose>
<ItemGroup>
<ProjectReference Include="..\DataStreamCore\DataStreamCore.csproj" />
<ProjectReference Include="..\ExpressionCore\ExpressionCore.csproj" />
<ProjectReference Include="..\..\client\spark_core\spark_core.csproj" />
</ItemGroup>
<ItemGroup Label="ColumnSortExpression">
<Scanner Include="ColumnSortExpressionTokens.lex" />
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\client\spark_websocket\spark_websocket.csproj" />
<ProjectReference Include="..\DataStreamExpressions\DataStreamExpressions.csproj" />
<ProjectReference Include="..\..\client\spark_core\spark_core.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,9 @@
namespace Bts.DataStream.Websocket;
class ClientSubscription(WebsocketClientID id, SubscriptionParams @params, IDisposable dispose) : IDisposable {
public SubscriptionParams Params => @params;
public WebsocketClientID Id => id;
public void Dispose() =>
dispose.Dispose();
}
@@ -0,0 +1,301 @@
namespace Bts.DataStream.Websocket;
using BCG;
using bts;
using bts.api.core;
using bts.collections;
using bts.websocket_core.json_rpc;
using Bts.DataStreamExpressions;
using mbts.utils;
using Spark.Core.Disposables;
using Spark.Core.Json;
using System.Buffers;
using System.Reactive.Subjects;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
/// <summary>
/// Represents an I/O model (<see cref="ISubject{TSource, TResult}"/>), that accepts websocket
/// requests (from clients) as input, and emits data/notifications (to clients) as output.
/// This class's chief role is managing data subscriptions to sparkd on the clients' behalf.
/// </summary>
public class DataSync(JsonSerializerOptions? serializerOpts = null) :
ISubject<WebsocketConnectionUpdate, IEnumerable<WebsocketOutgoingMessage>> {
protected readonly object lockObj = new();
readonly JsonSerializerOptions serializerOpts = serializerOpts ?? JsonSerializerOptions.Default;
readonly Dictionary<WebsocketClientID, List<ClientSubscription>> clients = [];
event Action<IEnumerable<WebsocketOutgoingMessage>>? requestSend;
public void OnCompleted() =>
Log.Api.info("DataSync incoming request stream has completed.");
public void OnError(Exception error) =>
Log.Api.error($"DataSync error: {error}");
public void OnNext(WebsocketConnectionUpdate value) {
switch (value.Type) {
case WebsocketConnectionUpdateType.IncomingMessage:
onIncomingMessage(value.IncomingMessage);
break;
case WebsocketConnectionUpdateType.Connect:
onConnect(value.Connect);
break;
case WebsocketConnectionUpdateType.Disconnect:
onDisconnect(value.Disconnect);
break;
default:
Log.assert(false, $"Unexpected WebsocketConnectionUpdate type: {value.Type}");
break;
}
}
public IDisposable Subscribe(IObserver<IEnumerable<WebsocketOutgoingMessage>> observer) {
lock (lockObj) {
requestSend += observer.OnNext;
return Disposable.Create(Dispose);
}
void Dispose() {
lock (lockObj) {
requestSend -= observer.OnNext;
}
}
}
static JsonRpcId? extractRpcId(string messageBody) {
try {
return JsonNode.Parse(messageBody)
?.AsObject()
?.GetValueOrDefault("id")
?.Deserialize<JsonRpcId>();
} catch {
return null;
}
}
static string getRpcNotification(DataPacket dp) {
using (var buffer = new MemoryStream())
using (var writer = new Utf8JsonWriter(buffer))
using (writer.WriteObject()) {
writer.WriteString("method", "subscription");
using (writer.WriteObject("params")) {
writer.Write("tableName", dp.schema.tableName);
writer.Write("columns", dp.schema.columnInfo);
var cellJsonFactories = dp.schema.columnInfo.Select(getCellJsonFactory).ToList();
using (writer.WriteArray("added")) {
foreach (IBlueRow row in (dp.addedRows?.Cast<IBlueRow>()).empty_if_null()) {
using (writer.WriteObject()) {
for (int i = 0; i < cellJsonFactories.Count; i++) {
writer.Write(dp.schema.columnInfo[i].colName, cellJsonFactories[i](row));
}
}
}
}
using (writer.WriteArray("deleted")) {
foreach (IBlueRow row in (dp.deletedRows?.Cast<IBlueRow>()).empty_if_null()) {
using (writer.WriteObject()) {
for (int i = 0; i < cellJsonFactories.Count; i++) {
writer.Write(dp.schema.columnInfo[i].colName, cellJsonFactories[i](row));
}
}
}
}
}
writer.WriteString("jsonrpc", "2.0");
writer.Flush();
return Encoding.UTF8.GetString(buffer.ToArray());
}
}
static Func<IBlueRow, JsonNode?> getCellJsonFactory(ColumnInfo colInfo) {
var t = colInfo.colType;
if (t == typeof(int)) {
return NullCheckWrapper(v => (int)v);
}
if (t == typeof(uint)) {
return NullCheckWrapper(v => (uint)v);
}
if (t == typeof(long)) {
return NullCheckWrapper(v => (long)v);
}
if (t == typeof(ulong)) {
return NullCheckWrapper(v => (ulong)v);
}
if (t == typeof(short)) {
return NullCheckWrapper(v => (short)v);
}
if (t == typeof(ushort)) {
return NullCheckWrapper(v => (ushort)v);
}
if (t == typeof(double)) {
return NullCheckWrapper(v => (double)v);
}
if (t == typeof(float)) {
return NullCheckWrapper(v => (float)v);
}
if (t == typeof(bool)) {
return NullCheckWrapper(v => (bool)v);
}
return NullCheckWrapper(v => (string)v);
Func<IBlueRow, JsonNode?> NullCheckWrapper(Func<object, JsonNode> toJson) =>
r => {
var obj = r[colInfo.colNo];
if (obj is null) {
return null;
}
return toJson(obj);
};
}
void onConnect(WebsocketConnectNotification notification) {
var id = notification.Id;
lock (lockObj) {
clients.Add(id, []);
}
Log.Api.info($"DataStreamWebsocketDataSync client connected. clientId: {notification.Id}");
if (notification.Message is not null) {
onIncomingMessage(notification.Message);
}
}
void onDisconnect(WebsocketDisconnectNotification notification) {
Log.Api.warn($"DataStreamWebsocketDataSync client disconnected. clientId: {notification.Id}");
unsubscribeAll(notification.Id);
clients.Remove(notification.Id);
}
void onIncomingMessage(WebsocketIncomingMessage message) {
var id = message.sender_client_id;
if (!JsonRpcRequest.TryDeserialize(message, out var req, out var err)) {
onBadRequest(message, err);
return;
}
switch (req.Method!.ToLower()) {
case "subscribe":
subscribe(id, req);
break;
case "publish":
Log.Api.error("DataStreamWebsocket api 'publish' not implemented.");
// TODO
break;
case "unsubscribe":
unsubscribe(id, req);
break;
case "unsubscribe_all":
unsubscribeAll(id);
break;
default:
Log.Api.error($"Received request of unknown type: {req}");
break;
}
}
void sendResponse<T>(WebsocketClientID id, JsonRpcId rpcId, T rpcParams) {
var rpcRes = JsonRpcResponse.Create(rpcId, rpcParams);
var rpcResStr = JsonSerializer.Serialize(rpcRes, serializerOpts);
send([new(id, rpcResStr)]);
}
void sendError<T>(WebsocketClientID id, JsonRpcId rpcId, JsonRpcError<T> error) {
var rpcRes = JsonRpcResponse.CreateError(rpcId, error);
var rpcResStr = JsonSerializer.Serialize(rpcRes, serializerOpts);
send([new(id, rpcResStr)]);
}
bool send(IEnumerable<WebsocketOutgoingMessage> messages) {
lock (lockObj) {
if (requestSend is null) {
Log.Api.warn(
$"Unable to send message(s) because '{nameof(requestSend)}' handler is null");
return false;
}
requestSend(messages);
return true;
}
}
void subscribe(WebsocketClientID id, JsonRpcRequest<JsonObject?> req) {
var subParams = req.Params!.Deserialize<SubscriptionParams>()!;
var exp = DataStreamExpressionsInterpreter.Evaluate(subParams.Query!);
var stream = exp.getView(new Dictionary<string, StatementExpression>(0));
var sub = new ClientSubscription(id, subParams, Disposable.Create(Dispose));
lock (lockObj) {
clients[id].Add(sub);
sendResponse(id, req.Id!.Value, req.Params);
stream.onChange += OnChange;
}
void OnChange(object? newValue) {
var dp = ExceptionAssert.of_type<DataPacket>(newValue);
var notif = getRpcNotification(dp);
send([new(id, notif)]);
}
void Dispose() =>
stream.onChange -= OnChange;
}
void unsubscribe(WebsocketClientID id, JsonRpcRequest<JsonObject?> req) {
var subParams = req.Params!.Deserialize<SubscriptionParams>();
var subParamsStr = JsonSerializer.Serialize(subParams, serializerOpts);
// Minimize amount of code inside lock (just need it to find/remove the subscription)
List<ClientSubscription>? subs = null;
ClientSubscription? sub = null;
lock (lockObj) {
subs = clients.GetValueOrDefault(id);
subs?.TryRemoveFirst(s => s!.Params.Equals(subParams), out sub);
}
if (subs is null) {
// Didn't find client (log/throw).
var msg = $"Unable to unsubscribe: did not find client. Id: {id}.\nParams:\n{subParamsStr}";
Log.Api.error(msg);
throw new Exception(msg);
}
if (sub is null) {
// Found client, but didn't find subscription (log/throw).
var msg = $"Unable to unsubscribe: did not find the specified subscription. " +
$"Id: {id}. Request:\n{subParams}";
Log.Api.error(msg);
throw new Exception(msg);
}
// Found client and subscription (dispose/remove subscription).
Log.Api.info($"Unsubscribing client. Id: {id}.\nParams:\n{subParamsStr}");
sub.Dispose();
}
void unsubscribeAll(WebsocketClientID id) {
lock (lockObj) {
if (!clients.TryGetValue(id, out var subs)) {
throw new Exception(
$"Unable to unsubscribe: did not find client with id {id}");
}
subs.DisposeAll();
subs.Clear();
}
}
void onBadRequest(WebsocketIncomingMessage req, string? errorMsg) {
var rpcId = extractRpcId(req.message_body);
var logMsg = $"Recieved invalid request:\n{req.message_body}";
if (errorMsg is not null) {
logMsg += $"\n\n**Exception**\n{errorMsg}";
}
Log.Api.error(logMsg);
if (rpcId is null) {
return;
}
// Send error back to client
var rpcErr = JsonRpcError.Create(
(long)JsonRpcErrorCode.InvalidRequest,
$"Received invalid request: {errorMsg ?? "unknown error"}",
req.message_body);
sendError(req.sender_client_id, rpcId.Value, rpcErr);
}
}
@@ -0,0 +1,34 @@
namespace Bts.DataStream.Websocket;
using Newtonsoft.Json.Linq;
using System.Diagnostics.CodeAnalysis;
public static class JObjectExtensions {
public static bool TryParse<T>(
this JObject filter, string key, [MaybeNull] out T obj, [NotNullWhen(false)] out string? error) {
obj = default;
var value = filter.GetValueOrDefault(key)?.ToString();
if (value == null) {
error = $"{key} not present";
return true;
}
return WebsocketJsonParsers.TryParse(value, key, out obj, out error);
}
public static bool TryParse<T>(
this JObject filter, string key, out T result, [NotNullWhen(false)] out string? error, T defaultValue) {
var value = filter.GetValueOrDefault(key)?.ToString();
if (value == null) {
result = defaultValue;
error = $"{key} not present";
return true;
}
if (WebsocketJsonParsers.TryParse<T>(value, key, out var maybeRes, out error)) {
result = maybeRes ?? defaultValue;
return true;
}
result = defaultValue;
return false;
}
}
@@ -0,0 +1,48 @@
namespace Bts.DataStream.Websocket;
using Spark.Core;
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
class MultilineStringJsonConverter : JsonConverter<string> {
public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
if (typeToConvert != typeof(string)) {
throw new ArgumentException($"Unable to parse {typeToConvert}", nameof(typeToConvert));
}
return reader.TokenType switch {
JsonTokenType.String => StringImpl(ref reader),
JsonTokenType.StartArray => ArrayImpl(ref reader),
_ => throw new ArgumentException(
$"Unable to parse {typeof(SubscriptionParams)} from {reader.TokenType}"),
};
static string? StringImpl(ref Utf8JsonReader reader) =>
new(reader.GetString()!);
static string? ArrayImpl(ref Utf8JsonReader reader) {
var lines = new List<string>(2);
while (reader.Read()) {
switch (reader.TokenType) {
case JsonTokenType.String:
lines.Add(reader.GetString()!);
break;
case JsonTokenType.EndArray:
return string.Join("\n", lines);
}
}
throw new JsonException(
$"Failed to parse {typeof(SubscriptionParams)} (did not reach end of array)");
}
}
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) {
var lines = value.Split("\n");
if (lines.Length < 2) {
writer.WriteRawValue(value);
return;
}
writer.WriteRawValue($"[{", ".join(lines)}]");
}
}
@@ -0,0 +1,8 @@
namespace Bts.DataStream.Websocket;
public enum RequestType {
Unspecified,
Subscribe,
Unsubscribe,
UnsubscribeAll,
}
@@ -0,0 +1,25 @@
namespace Bts.DataStream.Websocket;
using bts;
using Google.Protobuf;
using System.Text.Json;
public static class Session {
static int sessionIdCounter;
public static async Task Start(
WebsocketServerConfig config, JsonSerializerOptions? opts) {
opts ??= JsonSerializerOptions.Default;
var sessionId = Interlocked.Increment(ref sessionIdCounter);
var gateway = new WebsocketClient(config);
var sync = new DataSync(opts);
using (gateway.Subscribe(sync))
using (sync.Subscribe(gateway)) {
Log.Api.info($"Starting DataStream Websocket Session {sessionId}");
Log.Api.info($"DataStream Websocket Session {sessionId} config:\n{JsonFormatter.Default.Format(config)}");
await gateway.ConnectAsync();
}
}
}
@@ -0,0 +1,112 @@
namespace Bts.DataStream.Websocket;
using bts.utils;
using Spark.Core;
using Spark.Core.Json;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using System.Text.Json.Serialization;
public class SubscriptionParams(string? query = null) : IEquatable<SubscriptionParams> {
static class PropNames {
public const string QUERY = "query";
}
// Serializer supports plain string, or an array of lines for convenience
[MaybeNull]
[JsonPropertyName(PropNames.QUERY)]
[JsonConverter(typeof(MultilineStringJsonConverter))]
public string? Query { get; set; } = query;
public bool Equals(SubscriptionParams? other) =>
other is not null &&
// Not the most elegant equals impl, but it'll work
Query.safe_equals(other.Query, (a, b) => a?.ToString() == b?.ToString());
class SubscriptionParamsConverter : JsonConverter<SubscriptionParams> {
public override bool CanConvert(Type typeToConvert) =>
typeToConvert == typeof(SubscriptionParams);
public override SubscriptionParams Read(
ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
if (typeToConvert != typeof(SubscriptionParams)) {
throw new ArgumentException($"Unable to parse {typeToConvert}", nameof(typeToConvert));
}
return read(ref reader);
}
static SubscriptionParams read(ref Utf8JsonReader reader) {
return reader.TokenType switch {
JsonTokenType.String => StringImpl(ref reader),
JsonTokenType.StartArray => ArrayImpl(ref reader),
JsonTokenType.StartObject => ObjectImpl(ref reader),
_ => throw new ArgumentException(
$"Unable to parse {typeof(SubscriptionParams)} from {reader.TokenType}"),
};
static SubscriptionParams StringImpl(ref Utf8JsonReader reader) =>
new(reader.GetString()!);
static SubscriptionParams ArrayImpl(ref Utf8JsonReader reader) {
var lines = new List<string>(2);
while (reader.Read()) {
switch (reader.TokenType) {
case JsonTokenType.String:
lines.Add(reader.GetString()!);
break;
case JsonTokenType.EndArray:
return new("\n".join(lines));
}
}
throw new JsonException(
$"Failed to parse {typeof(SubscriptionParams)} (did not reach end of array)");
}
static SubscriptionParams ObjectImpl(ref Utf8JsonReader reader) {
var lines = new List<string>(2);
while (reader.Read()) {
switch (reader.TokenType) {
case JsonTokenType.PropertyName:
var propName = reader.GetString()!;
if (propName == PropNames.QUERY) {
switch (reader.TokenType) {
case JsonTokenType.StartArray:
return ArrayImpl(ref reader);
case JsonTokenType.String:
return StringImpl(ref reader);
}
}
break;
case JsonTokenType.String:
lines.Add(reader.GetString()!);
break;
case JsonTokenType.EndArray:
return new("\n".join(lines));
}
}
throw new JsonException(
$"Failed to parse {typeof(SubscriptionParams)} (did not reach end of array)");
}
}
public override void Write(
Utf8JsonWriter writer, SubscriptionParams value, JsonSerializerOptions options) {
var q = value.Query;
var lines = q?.Split("\n");
if (lines is null || lines.Length < 2) {
writer.WriteString(PropNames.QUERY, value.Query);
return;
}
writer.WriteArray(PropNames.QUERY, lines);
}
}
public override bool Equals(object? obj) =>
Equals(obj as SubscriptionParams);
public override int GetHashCode() =>
Query?.Length ?? typeof(SubscriptionParams).GetHashCode();
}
@@ -0,0 +1,5 @@
global using bts.websocket_core;
global using System;
global using System.Collections.Immutable;
@@ -0,0 +1,41 @@
#nullable enable
using BCG;
using Spark.Core.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Bts.DataStreamCore;
class ViewStreamUpdate {
[JsonPropertyName("tableName")]
public string? TableName { get; set; }
[JsonPropertyName("columns")]
public List<ColumnInfo>? Columns { get; set; }
[JsonPropertyName("addedRows")]
public List<Dictionary<string, object?>>? AddedRows { get; set; }
[JsonPropertyName("deletedRows")]
public List<Dictionary<string, object?>>? DeletedRows { get; set; }
public DataPacket ToDataPacket(BlueTable state, bool applyChanges = true) {
var schema = new BlueTableSchema([.. Columns!], TableName);
var addedRowsTable = new BlueTable(schema);
var deletedRowsTable = new BlueTable(schema);
if (applyChanges) {
state.deleteRows(deletedRowsTable);
state.addRows(addedRowsTable);
}
return new(state, addedRowsTable, deletedRowsTable);
}
public static string ToJson() {
return "";
}
}
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Bts.DataStream.Websocket\Bts.DataStream.Websocket.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,7 @@
{
"host": "localhost",
"port": 8080,
"scheme": "ws",
"default_end_point": "/",
"keep_alive_interval_secs": 1
}
@@ -0,0 +1,76 @@
using bts.api.core;
using Bts.DataStream.Websocket;
using Google.Protobuf;
using System.CommandLine.Parsing;
using System.Text.Json;
static WebsocketServerConfig readConfigFile(string path) {
using var fs = File.OpenRead(path);
using var sr = new StreamReader(fs);
return JsonParser.Default.Parse<WebsocketServerConfig>(sr);
}
static WebsocketServerConfig? readConfigArg(ArgumentResult result) {
var path = result.Tokens.Select(t => t.Value).FirstOrDefault() ?? string.Empty;
return readConfigFile(path);
}
static WebsocketServerConfig getDefaultConfig() {
const string defaultCfgPath = "DataStreamWebsocketServer.conf";
if (File.Exists(defaultCfgPath)) {
return readConfigFile(defaultCfgPath);
}
return new() {
Scheme = "http",
Host = "localhost",
Port = 8080,
DefaultEndPoint = "/",
KeepAliveIntervalSecs = 1
};
}
static async Task run(
WebsocketServerConfig? wssConfig, string user, string password, string? sparkdConfigSource) {
var opts = new JsonSerializerOptions(JsonSerializerDefaults.Web);
wssConfig ??= getDefaultConfig();
Console.WriteLine("Starting DataStreamWebsocketServer...");
var serviceCtx = ServiceContext.create(sparkdConfigSource);
await serviceCtx.login(user, password);
await Session.Start(wssConfig, opts);
// if (sparkdConfigSource is not null && sparkdConfigSource.Length > 9999) {
// } else {
// await ChatGptSession.Start();
// }
}
var userOpt = new Option<string>("--user", () => "bts");
var passOpt = new Option<string>("--password", () => string.Empty);
var sparkdConfigSourceOpt = new Option<string>(
"--sparkd", description: "The sparkd config server url");
// var bling = new ParseArgument<WebsocketServerConfig?>(parseWsConfig);
// WebsocketServerConfig? parseWsConfig(ArgumentResult result) {
// Token t;
// TokenType tt;
// Symbol s;
// throw new NotImplementedException();
// }
var configOpt = new Option<WebsocketServerConfig?>(
"--config", readConfigArg, description: "WebsocketServerConfig file path");
configOpt.SetDefaultValue(new());
var rootCommand = new RootCommand("Starts a DataStream Websocket Server");
rootCommand.AddOption(configOpt);
rootCommand.AddOption(userOpt);
rootCommand.AddOption(passOpt);
rootCommand.SetHandler(run, configOpt, userOpt, passOpt, sparkdConfigSourceOpt);
try {
return await rootCommand.InvokeAsync(args);
} catch (Exception ex) {
Console.WriteLine($"Error: {ex}");
}
return 1;
@@ -0,0 +1,6 @@
global using bts.websocket_core;
global using bts.websocket_core.json_rpc;
global using System.CommandLine;
global using System.Collections.Immutable;
Loaded 100 of 3972 files, more files were not shown because too many files have changed in this diff. Show more