diff --git a/docs/modules/transform/_category_.json b/docs/modules/transform/_category_.json new file mode 100644 index 00000000000..b13550613f7 --- /dev/null +++ b/docs/modules/transform/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Transform", + "position": 9 +} \ No newline at end of file diff --git a/docs/modules/transform/configuration.md b/docs/modules/transform/configuration.md new file mode 100644 index 00000000000..3d9e6fa9450 --- /dev/null +++ b/docs/modules/transform/configuration.md @@ -0,0 +1,165 @@ +--- +title: Configuration Instructions +sidebar_position: 2 +--- + +# Parameter Configuration Description +## TransformConfig Configuration Description +```java +public class TransformConfig { + + @JsonProperty("sourceInfo") + private SourceInfo sourceInfo; // Definition of data source decoding + @JsonProperty("sinkInfo") + private SinkInfo sinkInfo; // Definition of data result encoding + @JsonProperty("transformSql") + private String transformSql; //Data transformation SQL +} +``` + +## SourceInfo Configuration Description +### CSV +```java + public CsvSourceInfo( + @JsonProperty("charset") String charset, // Character set + @JsonProperty("delimiter") String delimiter, // Delimiter + @JsonProperty("escapeChar") String escapeChar, // Escape character, if empty, no unescaping operation is performed during decoding + @JsonProperty("fields") List fields) // Field list, if empty, decode by default according to the delimiter, field names are assigned as $1, $2, $3... starting from 1; + // If the number of defined fields is less than the number of decoded fields, the extra fields will be discarded + ); +``` + +### KV +```java + public KvSourceInfo( + @JsonProperty("charset") String charset, // Character set + @JsonProperty("fields") List fields) // Field list, if empty, decode by default using the Key in KV as the field name + // If the field name does not match the decoded field name, the field value will be empty, and extra field names will be discarded + ); +``` + +### ProtoBuffer +```java + public PbSourceInfo( + @JsonProperty("charset") String charset, // Character set + @JsonProperty("protoDescription") String protoDescription, // Base64 encoded ProtoBuf protocol description + @JsonProperty("rootMessageType") String rootMessageType, // MessageType of the decoded source data, MessageType needs to be defined in the ProtoBuf protocol + @JsonProperty("rowsNodePath") String rowsNodePath) // Array node path of the ProtoBuf protocol containing multiple data to be converted + ); +``` + +#### Generate ProtoBuf Protocol Description +- Install Protocol Buffers compiler +```shell +PB_REL="https://github.com/protocolbuffers/protobuf/releases" +curl -LO $PB_REL/download/v3.15.8/protoc-3.15.8-linux-x86_64.zip +unzip protoc-3.15.8-linux-x86_64.zip -d $HOME/.local +export PATH="$HOME/.local/bin:$PATH" +protoc --version +#Displays libprotoc 3.15.8 +``` +- Parse the protocol to generate a Base64 encoded description +```shell +# transform.proto is the proto protocol file, transform.description is the binary description file after parsing the protocol +protoc --descriptor_set_out=transform.description ./transform.proto --proto_path=. +# Base64 encode the binary description file transform.description and write it to the file transform.base64, which is the parameter protoDescription in the configuration interface +base64 transform.description |tr -d '\n' > transform.base64 +``` +- Example of transform.proto +```ProtoBuf +syntax = "proto3"; +package test; +message SdkMessage { + bytes msg = 1; + int64 msgTime = 2; + map extinfo = 3; +} +message SdkDataRequest { + string sid = 1; + repeated SdkMessage msgs = 2; + uint64 packageID = 3; +} +``` +- Example of transform.base64 +```text +CrcCCg90cmFuc2Zvcm0ucHJvdG8SBHRlc3QirQEKClNka01lc3NhZ2USEAoDbXNnGAEgASgMUgNtc2cSGAoHbXNnVGltZRgCIAEoA1IHbXNnVGltZRI3CgdleHRpbmZvGAMgAygLMh0udGVzdC5TZGtNZXNzYWdlLkV4dGluZm9FbnRyeVIHZXh0aW5mbxo6CgxFeHRpbmZvRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSFAoFdmFsdWUYAiABKAlSBXZhbHVlOgI4ASJmCg5TZGtEYXRhUmVxdWVzdBIQCgNzaWQYASABKAlSA3NpZBIkCgRtc2dzGAIgAygLMhAudGVzdC5TZGtNZXNzYWdlUgRtc2dzEhwKCXBhY2thZ2VJRBgDIAEoBFIJcGFja2FnZUlEYgZwcm90bzM= +``` +- Example of transform.description +![](img/transform_description.png) + +### Json +```java + public JsonSourceInfo( + @JsonProperty("charset") String charset, // Character set + @JsonProperty("rowsNodePath") String rowsNodePath) // Array node path of the Json protocol containing multiple data to be converted + ); +``` +## SinkInfo Configuration Description +### CSV +```java + public CsvSinkInfo( + @JsonProperty("charset") String charset, // Character set + @JsonProperty("delimiter") String delimiter, // Delimiter + @JsonProperty("escapeChar") String escapeChar, // Escape character, if empty, no escaping operation is performed during encoding + @JsonProperty("fields") List fields) // Field list, if empty, encode by default according to the Select field order of TransformSQL + ); +``` +### KV +```java + public KvSinkInfo( + @JsonProperty("charset") String charset, // Character set + @JsonProperty("fields") List fields) // Field list, if empty, encode by default using the Alias of Select fields in TransformSQL as the Key + ); +``` +# TransformSQL Configuration Description +## CSV / KV Field Reference +- SourceInfo does not have a configured field list. + - For CSV format, field names are referenced using 2, $3... + - For KV format, field names directly reference the Key in the source data. +- If the field names in SourceInfo and SinkInfo are inconsistent, you can use the Alias of Select fields to map the conversion. +## ProtoBuf / Json Tree Structure Field Reference +- All fields can only be prefixed with "$root.", "$child". + - "$root" means the root node. + - "$child" means the array node of multiple rows. +- For multi-level nodes, use a decimal point to separate, such as $root.extParams.name. +- For array nodes, use parentheses to identify the array index, such as $root.msgs(1).msgTime. +## Operator Support +- Currently supported operators + - Arithmetic operators: +, -, *, /, (, ) + - Comparison operators: =, !=, >, >=, <, <= + - Logical operators: and, or, !, not, (, ) +## Function Description +- CONCAT(string1, string2, ...), returns a concatenated string of string1, string2, ... If any parameter is NULL, it returns NULL. For example, CONCAT('AA', 'BB', 'CC') returns "AABBCC". +- NOW(), returns the current SQL timestamp in the local timezone. +- See the function description section for details. +## SQL Example +```sql +select ftime,extinfo from source where extinfo='ok' + +select $1 ftime,$2 extinfo from source where $2!='ok' + +select $root.sid,$root.packageID,$child.msgTime,$child.msg from source + +select $root.sid,$root.packageID,$root.msgs(1).msgTime,$root.msgs(0).msg from source + +select $root.sid, + ($root.msgs(1).msgTime-$root.msgs(0).msgTime)/$root.packageID field2, + $root.packageID*($root.msgs(0).msgTime*$root.packageID+$root.msgs(1).msgTime/$root.packageID)*$root.packageID field3, + $root.msgs(0).msg field4 +from source +where $root.packageID<($root.msgs(0).msgTime+$root.msgs(1).msgTime+$root.msgs(0).msgTime+$root.msgs(1).msgTime) + +select $root.sid, + $root.packageID, + $child.msgTime, + concat($root.sid,$root.packageID,$child.msgTime,$child.msg) msg,$root.msgs.msgTime.msg +from source + +select now() from source +``` +# Common Issues +- SDK calls are thread-safe. +- Configuration changes, directly modifying the parameters of the configuration object will not take effect, you need to rebuild the SDK object. +- If the CSV, KV format conversion source data contains line breaks, delimiters (vertical bars, commas, etc.), backslashes (escape characters), you need to configure the correct escape character and line separator. + - If not configured, the field order of the converted data will be disordered, line breaks will cause one piece of data to become two, and vertical bar delimiters will cause field misalignment. +- Avoid creating an SDK object for each piece of data processed, SDK object initialization requires compiling the conversion SQL and establishing an AST semantic parsing tree, frequent calls will cause performance problems, the recommended usage is to reuse an initialized SDK object to process data in the program. \ No newline at end of file diff --git a/docs/modules/transform/img/transform_description.png b/docs/modules/transform/img/transform_description.png new file mode 100644 index 00000000000..81b9c70f9ed Binary files /dev/null and b/docs/modules/transform/img/transform_description.png differ diff --git a/docs/modules/transform/img/transform_introduction.png b/docs/modules/transform/img/transform_introduction.png new file mode 100644 index 00000000000..0eb1a3906fb Binary files /dev/null and b/docs/modules/transform/img/transform_introduction.png differ diff --git a/docs/modules/transform/overview.md b/docs/modules/transform/overview.md new file mode 100644 index 00000000000..d764d4e929e --- /dev/null +++ b/docs/modules/transform/overview.md @@ -0,0 +1,35 @@ +--- +title: Overview +sidebar_position: 1 +--- + +# Introduction +InLong Transform helps InLong expand its access and distribution capabilities, adapting to a richer variety of data protocols and reporting scenarios on the access side, and accommodating complex and diverse data analysis scenarios on the distribution side. It improves data quality and collaboration, providing computational capabilities decoupled from the computing engine such as connection, aggregation, filtering, grouping, value extraction, sampling, etc. It simplifies the preliminary operations for users to report data, lowers the threshold for data usage, and focuses on the business value of data, achieving the principle of "what is visible is usable." + +![](img/transform_introduction.png) + +# Application Scenarios +- Data Cleaning: During the data integration process, it is necessary to clean data from different sources to eliminate errors, duplicates, and inconsistencies. Transform capabilities can help enterprises clean data more effectively, improving data quality. +- Data Fusion: Combining data from different sources for unified analysis and reporting. Transform capabilities can handle data in various formats and structures, achieving data fusion and integration. +- Data Standardization: Converting data into a unified standard format for cross-system and cross-platform data analysis. Transform capabilities can help enterprises standardize and normalize data. +- Data Partitioning and Indexing: To improve the performance of data querying and analysis, partition data and create indexes. Transform capabilities can dynamically adjust the field values for partitioning and indexing, thereby improving the performance of data warehouses. +- Data Aggregation and Calculation: During data analysis, extract valuable business information through data aggregation and calculation. Transform capabilities can achieve complex data aggregation and calculation, covering multi-dimensional data analysis. +- Data Security and Privacy Protection: Ensure data security and privacy during the data integration process. Transform capabilities can achieve data masking, encryption, and authorization management, protecting data security and privacy. +- Cross-Team Data Sharing: Share only a filtered subset of the data stream for data security considerations; agree on data interfaces with partner teams for data dependency decoupling, dynamically adjusting the merging of multiple streams into the data stream interface. + +# Features +- Describe the Transform processing logic of the data stream through SQL, supporting standard SQL syntax. +- Provide a rich SQL Function to handle various Transform needs and support UDF extensions. +- Support CSV, KV, ProtoBuffer, JSON, and other flat table and tree structure data source decoding frameworks. +- Support CSV, KV, and other data target encoding frameworks. +- Data source decoding and data target encoding are extensible for development. + +# Future Planning +- Support richer Transform UDFs, data source decoders, and data target encoders. +- Support Group and Join capabilities based on Time Window. +- Integrate Transform into each module of InLong to enhance processing capabilities and user experience. + - Agent: Responsible for collecting raw data from various data sources. After expanding Transform capabilities, it adds support for complex data source protocols such as PB, Json, and increases data filtering and format conversion capabilities. + - Realtime Synchronization: Currently, real-time synchronization is implemented based on FlinkSQL transformation, one data stream per job; after expanding Transform capabilities, it adds support for complex data source protocols such as PB, Json; and supports multiple data streams per job. + - Offline Synchronization: Offline synchronization is currently planned to be implemented based on Flink Batch, with InLongTransform as a custom function to expand its transformation capabilities; it can use the data target of the InLong data stream as a data source, achieve internal data integration, implement preprocessing, and trigger downstream offline jobs through the end of the pre-sort job or the offline synchronization job or partition closure event. + - Manager: After expanding Transform capabilities, the Manager interface provides preliminary transformation operations for raw data, verifies the correctness of the transformation logic configuration, and improves user experience. + - Sort: Currently, Sort defines that one data stream has only one offline data target per type, but after expanding Transform capabilities, it allows multiple copies and subsets to be stored, and enriches the final storage content through association with static database tables, optimizing the processing of subsequent business tasks. \ No newline at end of file diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/modules/transform/configuration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/modules/transform/configuration.md new file mode 100644 index 00000000000..75c4821585b --- /dev/null +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/modules/transform/configuration.md @@ -0,0 +1,163 @@ +--- +title: 配置说明 +sidebar_position: 2 +--- + +# 参数配置说明 +## TransformConfig 配置说明 +```java +public class TransformConfig { + + @JsonProperty("sourceInfo") + private SourceInfo sourceInfo; //数据源的解码定义 + @JsonProperty("sinkInfo") + private SinkInfo sinkInfo; //数据结果的编码定义 + @JsonProperty("transformSql") + private String transformSql; //数据转换的 SQL +} +``` + +## SourceInfo 配置说明 +### CSV +```java + public CsvSourceInfo( + @JsonProperty("charset") String charset, //字符集 + @JsonProperty("delimiter") String delimiter, //分隔符 + @JsonProperty("escapeChar") String escapeChar, //转义符,如果为空,则解码时不进行反转义操作 + @JsonProperty("fields") List fields) //字段列表,如果为空,则解码时默认按分隔符解析,字段名按 $1、$2、$3...来分配,注意从1开始; + //如果字段定义数少于解码出来的字段数,则多出的字段数将会被丢弃 + ); +``` + +### KV +```java + public KvSourceInfo( + @JsonProperty("charset") String charset, //字符集 + @JsonProperty("fields") List fields) //字段列表,如果为空,则解码时默认按 KV 里的 Key 作为字段名 + //如果字段名不匹配解码出来的字段名,则字段值为空,多出来的字段名会被丢弃 + ); +``` + +### ProtoBuffer +```java + public PbSourceInfo( + @JsonProperty("charset") String charset, //字符集 + @JsonProperty("protoDescription") String protoDescription, // ProtoBuf 协议描述的 Base64 编码 + @JsonProperty("rootMessageType") String rootMessageType, //解码源数据的 MessageType ,MessageType 需要在 ProtoBuf 协议中已定义 + @JsonProperty("rowsNodePath") String rowsNodePath) // ProtoBuf 协议包含多条待转换数据的数组节点路径 + ); +``` + +#### 生成ProtoBuf 协议描述 +- 安装 Protocol Buffers compiler +```shell +PB_REL="https://github.com/protocolbuffers/protobuf/releases" +curl -LO $PB_REL/download/v3.15.8/protoc-3.15.8-linux-x86_64.zip +unzip protoc-3.15.8-linux-x86_64.zip -d $HOME/.local +export PATH="$HOME/.local/bin:$PATH" +protoc --version +#显示libprotoc 3.15.8 +``` +- 解析协议生成描述的 Base64 编码 +```shell +# transform.proto 是 proto 协议文件,transform.description 是协议解析后的二进制描述文件 +protoc --descriptor_set_out=transform.description ./transform.proto --proto_path=. +# 将协议解析后的二进制描述文件 transform.description 进行 Base64 编码,写入文件 transform.base64,这个文件内容就是配置接口中的参数:protoDescription +base64 transform.description |tr -d '\n' > transform.base64 +``` +- transform.proto 样例 +```ProtoBuf +syntax = "proto3"; +package test; +message SdkMessage { + bytes msg = 1; + int64 msgTime = 2; + map extinfo = 3; +} +message SdkDataRequest { + string sid = 1; + repeated SdkMessage msgs = 2; + uint64 packageID = 3; +} +``` +- transform.base64 样例 +``` +CrcCCg90cmFuc2Zvcm0ucHJvdG8SBHRlc3QirQEKClNka01lc3NhZ2USEAoDbXNnGAEgASgMUgNtc2cSGAoHbXNnVGltZRgCIAEoA1IHbXNnVGltZRI3CgdleHRpbmZvGAMgAygLMh0udGVzdC5TZGtNZXNzYWdlLkV4dGluZm9FbnRyeVIHZXh0aW5mbxo6CgxFeHRpbmZvRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSFAoFdmFsdWUYAiABKAlSBXZhbHVlOgI4ASJmCg5TZGtEYXRhUmVxdWVzdBIQCgNzaWQYASABKAlSA3NpZBIkCgRtc2dzGAIgAygLMhAudGVzdC5TZGtNZXNzYWdlUgRtc2dzEhwKCXBhY2thZ2VJRBgDIAEoBFIJcGFja2FnZUlEYgZwcm90bzM= +``` +- transform.description 样例 +![](img/transform_description.png) + +### Json +```java + public JsonSourceInfo( + @JsonProperty("charset") String charset, //字符集 + @JsonProperty("rowsNodePath") String rowsNodePath) // Json 协议包含多条待转换数据的数组节点路径 + ); +``` +## SinkInfo 配置说明 +### CSV +```java + public CsvSinkInfo( + @JsonProperty("charset") String charset, //字符集 + @JsonProperty("delimiter") String delimiter, //分隔符 + @JsonProperty("escapeChar") String escapeChar, //转义符,如果为空,则编码时不进行转义操作 + @JsonProperty("fields") List fields) //字段列表,如果为空,则编码时默认按 TransformSQL 的 Select 字段顺序拼接 + ); +``` +### KV +```java + public KvSinkInfo( + @JsonProperty("charset") String charset, //字符集 + @JsonProperty("fields") List fields) //字段列表,如果为空,则编码时默认按 TransformSQL 的 Select 字段 Alias 作为 Key 拼接 + ); +``` +# TransformSQL 配置说明 +## CSV / KV 字段引用 +- SourceInfo 没有配置字段列表。 + - CSV 格式,字段名用 $1、$2、$3... 来引用。 + - KV 格式,字段名直接引用源数据中的 Key。 +- SourceInfo 的字段名和 SinkInfo 字段名不一致,可以通过 Select 字段的别名映射转换。 +## ProtoBuf / Json 树形字段引用 +- 所有字段只能以 $root.、$child. 作为前缀,$root 表示根节点,$child 表示多行的数组节点。 +- 多级节点,用小数点分隔,如 $root.extParams.name。 +- 对于数组节点,用小括号标识数组下标,如 $root.msgs(1).msgTime。 +## 运算符支持 +- 目前已支持运算符 + - 算术运算符,+、-、*、/、(、) + - 比较运算符,=、!=、>、>=、<、<= + - 逻辑运算符,and、or、!、not、(、) +## 函数说明 +- CONCAT(string1, string2, ...),返回连接 string1,string2, … 的字符串。如果有任一参数为 NULL,则返回 NULL。 例如 CONCAT('AA', 'BB', 'CC') 返回 "AABBCC"。 +- NOW(),返回本地时区的当前 SQL 时间戳。 +- 详见函数说明章节。 +## SQL 样例 +```sql +select ftime,extinfo from source where extinfo='ok' + +select $1 ftime,$2 extinfo from source where $2!='ok' + +select $root.sid,$root.packageID,$child.msgTime,$child.msg from source + +select $root.sid,$root.packageID,$root.msgs(1).msgTime,$root.msgs(0).msg from source + +select $root.sid, + ($root.msgs(1).msgTime-$root.msgs(0).msgTime)/$root.packageID field2, + $root.packageID*($root.msgs(0).msgTime*$root.packageID+$root.msgs(1).msgTime/$root.packageID)*$root.packageID field3, + $root.msgs(0).msg field4 +from source +where $root.packageID<($root.msgs(0).msgTime+$root.msgs(1).msgTime+$root.msgs(0).msgTime+$root.msgs(1).msgTime) + +select $root.sid, + $root.packageID, + $child.msgTime, + concat($root.sid,$root.packageID,$child.msgTime,$child.msg) msg,$root.msgs.msgTime.msg +from source + +select now() from source +``` +# 常见问题 +- SDK 调用是线程安全的。 +- 配置变更,直接修改配置对象的参数是不起效果的,需要重建 SDK 对象。 +- 如果 CSV、KV 格式的转换源数据里包含换行符、分隔符(竖线、逗号等)、反斜杠(转义符),需要配置正确的转义符和行分隔符。 + - 如果不配置,那么转换后数据的字段顺序会发生错乱,换行符会导致一条数据变两条,竖线分隔符会导致字段错位。 +- 避免在处理每条数据时都创建一个 SDK 对象,SDK 对象初始化需要编译转换 SQL 并建立 AST 语义解析树,频繁调用会引发性能问题,推荐的使用方式为在程序中复用一个初始化好的 SDK 对象处理数据。 \ No newline at end of file diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/modules/transform/img/transform_description.png b/i18n/zh-CN/docusaurus-plugin-content-docs/current/modules/transform/img/transform_description.png new file mode 100644 index 00000000000..81b9c70f9ed Binary files /dev/null and b/i18n/zh-CN/docusaurus-plugin-content-docs/current/modules/transform/img/transform_description.png differ diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/modules/transform/img/transform_introduction.png b/i18n/zh-CN/docusaurus-plugin-content-docs/current/modules/transform/img/transform_introduction.png new file mode 100644 index 00000000000..0eb1a3906fb Binary files /dev/null and b/i18n/zh-CN/docusaurus-plugin-content-docs/current/modules/transform/img/transform_introduction.png differ diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/modules/transform/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/modules/transform/overview.md new file mode 100644 index 00000000000..b50a1a75c64 --- /dev/null +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/modules/transform/overview.md @@ -0,0 +1,35 @@ +--- +title: 总览 +sidebar_position: 1 +--- + +# 简介 +InLong Transform 助力 InLong 扩展接入分发能力,接入侧适配更丰富的数据协议和上报场景,分发侧适配复杂多样的数据分析场景,提高数据质量和数据协作,提供连接、聚合、筛选、分组、取值、抽样等和计算引擎解耦的计算能力,简化用户上报数据的前置操作,降低数据使用门槛,简化用户开始分析数据前的前置操作,聚焦数据的业务价值,实现数据“可见即可用”。 + +![](img/transform_introduction.png) + +# 应用场景 +- 数据清洗:在数据集成过程中,需要对来自不同源的数据进行清洗,以消除数据中的错误、重复和不一致。Transform 能力可以帮助企业更有效地进行数据清洗,提高数据质量。 +- 数据融合:将来自不同数据源的数据融合在一起,以便进行统一的分析和报告。Transform 能力可以处理不同格式和结构的数据,实现数据的融合和集成。 +- 数据标准化:将数据转换为统一的标准格式,以便进行跨系统和跨平台的数据分析。Transform 能力可以帮助企业实现数据的标准化和规范化。 +- 数据分区和索引:为了提高数据查询和分析的性能,对数据进行分区和建立索引。Transform 能力可以实现分区和索引的字段值动态调整,从而提高数据仓库的性能。 +- 数据聚合和计算:在数据分析过程中,通过对数据进行聚合和计算,提取有价值的业务信息。Transform 能力可以实现复杂的数据聚合和计算,覆盖多维度的数据分析。 +- 数据安全和隐私保护:在数据集成过程中,需要确保数据的安全和隐私。Transform 能力可以实现数据的脱敏、加密和授权管理,保护数据的安全和隐私。 +- 跨团队数据共享:出于数据安全考虑,只共享数据流的筛选子集;出于数据依赖解耦考虑,和合作团队约定数据接口,动态调整多流合并到数据流接口。 + +# 特性 +- 通过 SQL 来描述数据流的 Transform 处理逻辑,支持标准 SQL 的语法。 +- 提供丰富的 SQL Function 处理各种 Transform 需求,并支持 UDF 扩展。 +- 支持 CSV、KV、ProtoBuffer、JSON 等扁平表格和树形结构的数据源解码解析框架。 +- 支持 CSV、KV 等数据目标的编码框架。 +- 数据源解码和数据目标编码可扩展开发。 + +# 未来规划 +- 支持更丰富的 Transform UDF、数据源解码器、数据目标编码器。 +- 支持基于 Time Window 的 Group 和 Join 能力。 +- 将 Transform 集成到 InLong 的各个模块,提升模块的处理能力和使用体验。 + - Agent:负责从各个数据源采集原始数据,扩展 Transform 能力后,增加 PB、Json 等复杂的数据源协议的支持,增加数据过滤和格式转换的能力。 + - Realtime Synchronization:目前实时同步基于 FlinkSQL 实现转换,一个数据流一个作业;扩展 Transform 能力后,增加 PB、Json 等复杂的数据源协议的支持;并且支持一个作业多个数据流。 + - Offline Synchronization:离线同步目前规划基于 Flink Batch 实现,InLongTransform 作为自定义函数拓展其转换能力;可以将 InLong 数据流的落库数据目标作为数据源,实现内部数据集成,实现预处理,通过前置 Sort 作业或离线同步作业的结束或者分区关闭事件触发下游离线作业。 + - Manager:Manager 扩展 Transform 能力后,界面提供原始数据的预转换操作,验证转换逻辑配置的正确性,提高用户体验。 + - Sort:目前 Sort 定义是一个数据流每种离线数据目标只落库一份,扩展 Transform 能力后,允许落库多份并且是子集合,并且通过关联静态库表丰富最终落库的内容,优化后续业务任务的处理。 \ No newline at end of file diff --git a/image_raw/modules/transform_introduction.excalidraw b/image_raw/modules/transform_introduction.excalidraw new file mode 100644 index 00000000000..8b280da407d --- /dev/null +++ b/image_raw/modules/transform_introduction.excalidraw @@ -0,0 +1,2707 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "rectangle", + "version": 90, + "versionNonce": 1730363996, + "index": "bFh", + "isDeleted": false, + "id": "TC690jPwppWjEz1vdQ_io", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 3965.6662912214983, + "y": 543.8904002990286, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 150.1523746972248, + "height": 30, + "seed": 942522773, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "5CbGTcXaWAQ5DIReh-FKz" + }, + { + "id": "AM3YaRCXrr87mghApw61q", + "type": "arrow" + }, + { + "id": "pNz3hgiz0LCrzo28knc8Y", + "type": "arrow" + } + ], + "updated": 1727579500803, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 73, + "versionNonce": 1227702108, + "index": "bFi", + "isDeleted": false, + "id": "5CbGTcXaWAQ5DIReh-FKz", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 3984.110505303509, + "y": 548.8904002990286, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 113.26394653320312, + "height": 20, + "seed": 159040085, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579503962, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "SDK Reporting", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "TC690jPwppWjEz1vdQ_io", + "originalText": "SDK Reporting", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 246, + "versionNonce": 186548566, + "index": "bFj", + "isDeleted": false, + "id": "ddXzNcnGRU5pQY40b8ps6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 3962.5099153681244, + "y": 618.9665360453289, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 153.30875055059957, + "height": 34.268958167594626, + "seed": 1978897237, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "UhN4OMvK5fbXL2jBU8do6" + }, + { + "id": "jJm9iUed5wE1y415bJTWa", + "type": "arrow" + } + ], + "updated": 1714030247199, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 243, + "versionNonce": 1856627556, + "index": "bFk", + "isDeleted": false, + "id": "UhN4OMvK5fbXL2jBU8do6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 3982.7163307435217, + "y": 626.1010151291262, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 112.89591979980469, + "height": 20, + "seed": 1429233845, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579514131, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "APP Reporting", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "ddXzNcnGRU5pQY40b8ps6", + "originalText": "APP Reporting", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 150, + "versionNonce": 620797834, + "index": "bFl", + "isDeleted": false, + "id": "--a-rB0zDHte86UmfI2jn", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4169.025776001938, + "y": 548.3994103708721, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e7f5ff", + "width": 134.37056423343984, + "height": 278.21015282237556, + "seed": 928059323, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "isN6iMHayOjmMYb4pn5VT" + }, + { + "id": "AM3YaRCXrr87mghApw61q", + "type": "arrow" + }, + { + "id": "jJm9iUed5wE1y415bJTWa", + "type": "arrow" + }, + { + "id": "KJzzTMh3EGwXXA04teHFj", + "type": "arrow" + }, + { + "id": "pNz3hgiz0LCrzo28knc8Y", + "type": "arrow" + }, + { + "id": "LkbKcjiDVBg8UBn_KTIvC", + "type": "arrow" + }, + { + "id": "lwXr1xHXO826CDV455r22", + "type": "arrow" + } + ], + "updated": 1714030304233, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 122, + "versionNonce": 1435162084, + "index": "bFm", + "isDeleted": false, + "id": "isN6iMHayOjmMYb4pn5VT", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4174.751089551763, + "y": 677.50448678206, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e7f5ff", + "width": 122.91993713378906, + "height": 20, + "seed": 1830791989, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579097909, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Data Ingestion", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "--a-rB0zDHte86UmfI2jn", + "originalText": "Data Ingestion", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 190, + "versionNonce": 450054742, + "index": "bFn", + "isDeleted": false, + "id": "AM3YaRCXrr87mghApw61q", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4299.365409806035, + "y": 565.4140343368681, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e7f5ff", + "width": 2.2155666312155518, + "height": 1.7727130789717194, + "seed": 1497899317, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1714030115521, + "link": null, + "locked": false, + "startBinding": { + "elementId": "y8jn0cnTWiiIRX_MJ4Fwg", + "gap": 26.14554996957301, + "focus": 0.8934333405690041, + "fixedPoint": null + }, + "endBinding": { + "elementId": "y8jn0cnTWiiIRX_MJ4Fwg", + "gap": 24.37283689060129, + "focus": 0.20092898009060267, + "fixedPoint": null + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 2.2155666312155518, + -1.7727130789717194 + ] + ] + }, + { + "type": "arrow", + "version": 636, + "versionNonce": 1005721692, + "index": "bFo", + "isDeleted": false, + "id": "jJm9iUed5wE1y415bJTWa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4119.491739323314, + "y": 639.5374512109647, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e7f5ff", + "width": 45.926759818064966, + "height": 1.3306427393649756, + "seed": 2010983445, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1727579508715, + "link": null, + "locked": false, + "startBinding": { + "elementId": "ddXzNcnGRU5pQY40b8ps6", + "gap": 3.6730734045893314, + "focus": 0.057301698076008704, + "fixedPoint": null + }, + "endBinding": { + "elementId": "--a-rB0zDHte86UmfI2jn", + "gap": 3.6072768605581587, + "focus": 0.3150063636655132, + "fixedPoint": null + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 45.926759818064966, + 1.3306427393649756 + ] + ] + }, + { + "type": "rectangle", + "version": 266, + "versionNonce": 720398090, + "index": "bFp", + "isDeleted": false, + "id": "a6hoYitEkaEYXpQcFyCal", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4357.505149128331, + "y": 547.4976083565035, + "strokeColor": "#1e1e1e", + "backgroundColor": "#f8f9fa", + "width": 138.42877650272476, + "height": 271.4466033130685, + "seed": 1255069307, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "XpQpv_VuRzddY0ijb2INP" + }, + { + "id": "KJzzTMh3EGwXXA04teHFj", + "type": "arrow" + }, + { + "id": "VuyLXt9kzNeWYhzyMVYt6", + "type": "arrow" + } + ], + "updated": 1714030316395, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 149, + "versionNonce": 472944100, + "index": "bFq", + "isDeleted": false, + "id": "XpQpv_VuRzddY0ijb2INP", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4365.703561427545, + "y": 673.2209100130378, + "strokeColor": "#1e1e1e", + "backgroundColor": "#f8f9fa", + "width": 122.03195190429688, + "height": 20, + "seed": 1462663157, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579104814, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Message Queue", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "a6hoYitEkaEYXpQcFyCal", + "originalText": "Message Queue", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 634, + "versionNonce": 68865878, + "index": "bFr", + "isDeleted": false, + "id": "KJzzTMh3EGwXXA04teHFj", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4310.159958547768, + "y": 684.9515378973877, + "strokeColor": "#1e1e1e", + "backgroundColor": "#f8f9fa", + "width": 43.73805132617326, + "height": 0.12394970510229086, + "seed": 993815861, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1714030345037, + "link": null, + "locked": false, + "startBinding": { + "elementId": "--a-rB0zDHte86UmfI2jn", + "focus": -0.019832040132688664, + "gap": 6.763618312390918, + "fixedPoint": null + }, + "endBinding": { + "elementId": "a6hoYitEkaEYXpQcFyCal", + "focus": -0.015163004752090096, + "gap": 3.6071392543894945, + "fixedPoint": null + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 43.73805132617326, + 0.12394970510229086 + ] + ] + }, + { + "type": "rectangle", + "version": 270, + "versionNonce": 1077483612, + "index": "bFs", + "isDeleted": false, + "id": "DcM59w91TgCz5JWvF6pS9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4545.759501770408, + "y": 548.3993759693304, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e7f5ff", + "width": 315.63545244180216, + "height": 355.4537137142932, + "seed": 474924437, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "EUY8igjQkF3VIBTFC9ECH" + }, + { + "id": "VuyLXt9kzNeWYhzyMVYt6", + "type": "arrow" + } + ], + "updated": 1727579429800, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 167, + "versionNonce": 17969764, + "index": "bFt", + "isDeleted": false, + "id": "EUY8igjQkF3VIBTFC9ECH", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4604.777278345313, + "y": 553.3993759693304, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e7f5ff", + "width": 197.5998992919922, + "height": 20, + "seed": 1709918965, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579118079, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Data Sort(Transform)", + "textAlign": "center", + "verticalAlign": "top", + "containerId": "DcM59w91TgCz5JWvF6pS9", + "originalText": "Data Sort(Transform)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 363, + "versionNonce": 1250356452, + "index": "bFu", + "isDeleted": false, + "id": "VuyLXt9kzNeWYhzyMVYt6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4499.592243324517, + "y": 690.9411388247416, + "strokeColor": "#1e1e1e", + "backgroundColor": "#f8f9fa", + "width": 70.64335456028584, + "height": 0.6920095117945948, + "seed": 2024199003, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1727579446058, + "link": null, + "locked": false, + "startBinding": { + "elementId": "a6hoYitEkaEYXpQcFyCal", + "focus": 0.061832811163396575, + "gap": 3.658317693461413, + "fixedPoint": null + }, + "endBinding": { + "elementId": "boiX6aFGs1P_uqS_fol1-", + "focus": 1.2078622640631564, + "gap": 10.083149480855354, + "fixedPoint": null + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 70.64335456028584, + -0.6920095117945948 + ] + ] + }, + { + "type": "rectangle", + "version": 133, + "versionNonce": 1527591140, + "index": "bFv", + "isDeleted": false, + "id": "dHdIAuKDXDpxoQtxVDzH3", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4640.682694079993, + "y": 577.4611160919711, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffd8a8", + "width": 129.27242022867898, + "height": 34.800018310546875, + "seed": 174481781, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "KY32jTTZlVV51bHRDyGJe" + } + ], + "updated": 1727579254631, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 111, + "versionNonce": 326988900, + "index": "bFw", + "isDeleted": false, + "id": "KY32jTTZlVV51bHRDyGJe", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4648.6949265332, + "y": 584.8611252472446, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 113.24795532226562, + "height": 20, + "seed": 1854934229, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579254631, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Data Cleaning", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "dHdIAuKDXDpxoQtxVDzH3", + "originalText": "Data Cleaning", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 430, + "versionNonce": 533453540, + "index": "bFx", + "isDeleted": false, + "id": "vZsd50wEeF8zoTmMc29ai", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4571.235597884803, + "y": 621.7772462345066, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e3fafc", + "width": 267.83939525559515, + "height": 264.6032069013264, + "seed": 218367893, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "32t02Gig4rFShMlsTEGP1" + }, + { + "id": "MgYi0wfWPbNZ3H9hKWnRp", + "type": "arrow" + }, + { + "id": "VuyLXt9kzNeWYhzyMVYt6", + "type": "arrow" + } + ], + "updated": 1727579432414, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 341, + "versionNonce": 1636153052, + "index": "bFy", + "isDeleted": false, + "id": "32t02Gig4rFShMlsTEGP1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4628.263342997951, + "y": 626.7772462345066, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 153.78390502929688, + "height": 20, + "seed": 1386761461, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579532511, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Protocol Processing", + "textAlign": "center", + "verticalAlign": "top", + "containerId": "vZsd50wEeF8zoTmMc29ai", + "originalText": "Protocol Processing", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 206, + "versionNonce": 1857481436, + "index": "bFz", + "isDeleted": false, + "id": "Gfa_PFHawiwkhgGydlf3h", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4576.857289948351, + "y": 660.5553520801118, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffd8a8", + "width": 125.65073169227419, + "height": 30, + "seed": 857237141, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "27XZmXyMA8NswptD_dUnj" + } + ], + "updated": 1727579194470, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 196, + "versionNonce": 341508188, + "index": "bG0", + "isDeleted": false, + "id": "27XZmXyMA8NswptD_dUnj", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4596.182686312066, + "y": 665.5553520801118, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 86.99993896484375, + "height": 20, + "seed": 349752309, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579239715, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "PB Parsing", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Gfa_PFHawiwkhgGydlf3h", + "originalText": "PB Parsing", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 215, + "versionNonce": 806477412, + "index": "bG1", + "isDeleted": false, + "id": "MfaXQhhMxmgY57r8j6hTr", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4713.664305584444, + "y": 661.0062874888379, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffd8a8", + "width": 118.45782988646718, + "height": 30, + "seed": 191547611, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "5gSngAN2P88FAG7t0UU_S" + } + ], + "updated": 1727579228450, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 214, + "versionNonce": 1052648036, + "index": "bG2", + "isDeleted": false, + "id": "5gSngAN2P88FAG7t0UU_S", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4719.601251228361, + "y": 666.0062874888379, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 106.58393859863281, + "height": 20, + "seed": 846394747, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579262593, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "JSON Parsing", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "MfaXQhhMxmgY57r8j6hTr", + "originalText": "JSON Parsing", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 346, + "versionNonce": 1365237860, + "index": "bG3", + "isDeleted": false, + "id": "CbvnhT8NnTLUSeeYLWQIk", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4578.159116376781, + "y": 751.2753449770939, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffd8a8", + "width": 126.8506218289931, + "height": 70, + "seed": 931544629, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "uZAl_4BAWaF0PZo6EjK17" + } + ], + "updated": 1727579412996, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 341, + "versionNonce": 449721316, + "index": "bG4", + "isDeleted": false, + "id": "uZAl_4BAWaF0PZo6EjK17", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4594.096458846453, + "y": 756.2753449770939, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 94.97593688964844, + "height": 60, + "seed": 1760210837, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579412996, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Associating \nDimension \nTables", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "CbvnhT8NnTLUSeeYLWQIk", + "originalText": "Associating Dimension Tables", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 243, + "versionNonce": 1087827684, + "index": "bG5", + "isDeleted": false, + "id": "2EAYUhd4g6xdZujThdIDe", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4713.118796193782, + "y": 696.1771164738847, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffd8a8", + "width": 118.05069507118054, + "height": 50, + "seed": 381352859, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "yv4sFHpBq6F8irGaoFWjd" + }, + { + "id": "MgYi0wfWPbNZ3H9hKWnRp", + "type": "arrow" + } + ], + "updated": 1727579448641, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 241, + "versionNonce": 357792484, + "index": "bG6", + "isDeleted": false, + "id": "yv4sFHpBq6F8irGaoFWjd", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4719.744165091677, + "y": 701.1771164738847, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 104.79995727539062, + "height": 40, + "seed": 850317371, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579272775, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "One-to-Many \nSplitting", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "2EAYUhd4g6xdZujThdIDe", + "originalText": "One-to-Many Splitting", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 402, + "versionNonce": 691656540, + "index": "bG7", + "isDeleted": false, + "id": "XEh093T6jAzdBsQGt-Vq8", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4580.282708824588, + "y": 827.5915673860056, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffd8a8", + "width": 124.8506828641493, + "height": 30, + "seed": 1935007995, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "WmTCfWeV6_6AF0m1ua5Ko" + } + ], + "updated": 1727579434847, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 409, + "versionNonce": 457083868, + "index": "bG8", + "isDeleted": false, + "id": "WmTCfWeV6_6AF0m1ua5Ko", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4594.384075647287, + "y": 832.5915673860056, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 96.64794921875, + "height": 20, + "seed": 2038827419, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579434847, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "URL Parsing", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "XEh093T6jAzdBsQGt-Vq8", + "originalText": "URL Parsing", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 343, + "versionNonce": 805026148, + "index": "bG9", + "isDeleted": false, + "id": "boiX6aFGs1P_uqS_fol1-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4580.318747365658, + "y": 695.4679139030425, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffd8a8", + "width": 118.85062182899307, + "height": 50, + "seed": 813843963, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "USFXa8GLGfkdJCQe4oX4k" + }, + { + "id": "VuyLXt9kzNeWYhzyMVYt6", + "type": "arrow" + } + ], + "updated": 1727579445098, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 350, + "versionNonce": 15923684, + "index": "bGA", + "isDeleted": false, + "id": "USFXa8GLGfkdJCQe4oX4k", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4599.516084342166, + "y": 700.4679139030425, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 80.45594787597656, + "height": 40, + "seed": 2111688347, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579376783, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Tag \nProcessing", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "boiX6aFGs1P_uqS_fol1-", + "originalText": "Tag Processing", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 365, + "versionNonce": 971342308, + "index": "bGB", + "isDeleted": false, + "id": "MKM3BVCmUelKDhydpJXNl", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4712.908330781253, + "y": 808.4351410789038, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffd8a8", + "width": 122.45059741493056, + "height": 50, + "seed": 331955515, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "FsNcSDnEt4oKt9Qt0Quei" + } + ], + "updated": 1727579439196, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 366, + "versionNonce": 1965270372, + "index": "bGC", + "isDeleted": false, + "id": "FsNcSDnEt4oKt9Qt0Quei", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4725.269661593211, + "y": 813.4351410789038, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 97.72793579101562, + "height": 40, + "seed": 600038875, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579439196, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Aggregation \nCalculation", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "MKM3BVCmUelKDhydpJXNl", + "originalText": "Aggregation Calculation", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 330, + "versionNonce": 1811851740, + "index": "bGD", + "isDeleted": false, + "id": "_c9_AUA837Nq3pgnzgeEa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4714.442461883777, + "y": 750.7333817891445, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffd8a8", + "width": 119.25076831336807, + "height": 50, + "seed": 403875867, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "yYkm0-2Vow4BDmN_SvukY" + } + ], + "updated": 1727579392877, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 340, + "versionNonce": 656782684, + "index": "bGE", + "isDeleted": false, + "id": "yYkm0-2Vow4BDmN_SvukY", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4732.459874849054, + "y": 755.7333817891445, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 83.2159423828125, + "height": 40, + "seed": 1969024187, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579392877, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Field \nAssignment", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "_c9_AUA837Nq3pgnzgeEa", + "originalText": "Field Assignment", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 328, + "versionNonce": 1928947989, + "index": "bGF", + "isDeleted": false, + "id": "tbjn9jVFbTi7QwFbk-KQI", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4906.936609567127, + "y": 544.9048329609536, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e7f5ff", + "width": 222.74840009707364, + "height": 279.1119548367442, + "seed": 1795434197, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "MgYi0wfWPbNZ3H9hKWnRp", + "type": "arrow" + }, + { + "id": "JzVp-srhGqWlG7-lZd6Al", + "type": "text" + } + ], + "updated": 1714029566154, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 258, + "versionNonce": 1849448156, + "index": "bGG", + "isDeleted": false, + "id": "JzVp-srhGqWlG7-lZd6Al", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4960.778834823183, + "y": 549.9048329609536, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e7f5ff", + "width": 115.06394958496094, + "height": 20, + "seed": 300057653, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579461131, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Data Storage", + "textAlign": "center", + "verticalAlign": "top", + "containerId": "tbjn9jVFbTi7QwFbk-KQI", + "originalText": "Data Storage", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 429, + "versionNonce": 1561036260, + "index": "bGH", + "isDeleted": false, + "id": "MgYi0wfWPbNZ3H9hKWnRp", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4840.074993140398, + "y": 686.5409756628627, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e3fafc", + "width": 56.87598240596435, + "height": 0.053941180360880026, + "seed": 1290759419, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1727579449567, + "link": null, + "locked": false, + "startBinding": { + "elementId": "2EAYUhd4g6xdZujThdIDe", + "focus": -1.384921560763295, + "gap": 9.63614081102196, + "fixedPoint": null + }, + "endBinding": { + "elementId": "tbjn9jVFbTi7QwFbk-KQI", + "focus": -0.01610467051671235, + "gap": 9.985634020763882, + "fixedPoint": null + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 56.87598240596435, + 0.053941180360880026 + ] + ] + }, + { + "type": "rectangle", + "version": 100, + "versionNonce": 934054666, + "index": "bGI", + "isDeleted": false, + "id": "33TWhBBNcU_6wpFklFLJK", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4950.449021181231, + "y": 583.9083377078383, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e3fafc", + "width": 141.58518675763935, + "height": 50, + "seed": 770091643, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "7y2jpwW9YC_GxMBiLTNx6" + }, + { + "id": "gFTgof--p6zsvrMm43_uB", + "type": "arrow" + } + ], + "updated": 1714029788137, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 100, + "versionNonce": 1701467484, + "index": "bGJ", + "isDeleted": false, + "id": "7y2jpwW9YC_GxMBiLTNx6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4983.985640744133, + "y": 588.9083377078383, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e3fafc", + "width": 74.51194763183594, + "height": 40, + "seed": 1235607445, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579470340, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Business \nStorage", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "33TWhBBNcU_6wpFklFLJK", + "originalText": "Business Storage", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 179, + "versionNonce": 2043280604, + "index": "bGK", + "isDeleted": false, + "id": "eEgRdNhiN824REhoQwc7F", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4951.125355491236, + "y": 678.1480930741197, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e3fafc", + "width": 141.58518675763935, + "height": 50, + "seed": 152824603, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "n5Hr2IoIGndcC3-rGMv7W", + "type": "text" + }, + { + "id": "gFTgof--p6zsvrMm43_uB", + "type": "arrow" + }, + { + "id": "3WgezDEDjPoD_Ym0ejslT", + "type": "arrow" + } + ], + "updated": 1727579479282, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 166, + "versionNonce": 950688348, + "index": "bGL", + "isDeleted": false, + "id": "n5Hr2IoIGndcC3-rGMv7W", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4984.661975054138, + "y": 683.1480930741197, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e3fafc", + "width": 74.51194763183594, + "height": 40, + "seed": 440782779, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579481738, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Business \nAnalysis", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "eEgRdNhiN824REhoQwc7F", + "originalText": "Business Analysis", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 246, + "versionNonce": 408363748, + "index": "bGM", + "isDeleted": false, + "id": "29jxMdndfdnY2-8B-on_6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4952.8274127429795, + "y": 766.5333642913993, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e3fafc", + "width": 141.58518675763935, + "height": 50, + "seed": 1092395542, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "h7FD0V1mkI5g0KYYW4_03", + "type": "text" + }, + { + "id": "3WgezDEDjPoD_Ym0ejslT", + "type": "arrow" + } + ], + "updated": 1727579538001, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 230, + "versionNonce": 918103652, + "index": "bGN", + "isDeleted": false, + "id": "h7FD0V1mkI5g0KYYW4_03", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4975.380023516818, + "y": 771.5333642913993, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e3fafc", + "width": 96.47996520996094, + "height": 40, + "seed": 1756098390, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579538001, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Business \nEnhancement", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "29jxMdndfdnY2-8B-on_6", + "originalText": "Business Enhancement", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 67, + "versionNonce": 213470282, + "index": "bGO", + "isDeleted": false, + "id": "gFTgof--p6zsvrMm43_uB", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 5021.692549968777, + "y": 634.4100761494868, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e3fafc", + "width": 0, + "height": 38.778037042521646, + "seed": 1021765590, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1714029778296, + "link": null, + "locked": false, + "startBinding": { + "elementId": "33TWhBBNcU_6wpFklFLJK", + "gap": 3.6072768605582155, + "focus": -0.006369810557904621, + "fixedPoint": null + }, + "endBinding": { + "elementId": "eEgRdNhiN824REhoQwc7F", + "gap": 4.959979882111213, + "focus": -0.0031839333823057707, + "fixedPoint": null + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 38.778037042521646 + ] + ] + }, + { + "type": "arrow", + "version": 67, + "versionNonce": 1707316060, + "index": "bGP", + "isDeleted": false, + "id": "3WgezDEDjPoD_Ym0ejslT", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 5022.543387721253, + "y": 730.5189381501615, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e3fafc", + "width": 0.050079892498615663, + "height": 32.18171597785806, + "seed": 971412054, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1727579485374, + "link": null, + "locked": false, + "startBinding": { + "elementId": "eEgRdNhiN824REhoQwc7F", + "focus": -0.015354748556384388, + "gap": 2.3708450760417463, + "fixedPoint": null + }, + "endBinding": { + "elementId": "29jxMdndfdnY2-8B-on_6", + "focus": -0.014079676425677087, + "gap": 3.8327101633796588, + "fixedPoint": null + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 0.050079892498615663, + 32.18171597785806 + ] + ] + }, + { + "type": "rectangle", + "version": 124, + "versionNonce": 1242482646, + "index": "bGQ", + "isDeleted": false, + "id": "y8jn0cnTWiiIRX_MJ4Fwg", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 3960.255410332208, + "y": 417.9742901529938, + "strokeColor": "#1e1e1e", + "backgroundColor": "#fff9db", + "width": 1158.382335447498, + "height": 121.29419421430129, + "seed": 323370506, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "AM3YaRCXrr87mghApw61q", + "type": "arrow" + } + ], + "updated": 1714030115521, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 249, + "versionNonce": 172945738, + "index": "bGR", + "isDeleted": false, + "id": "nnxtivUvLcOvIXZid-dAo", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4443.676046916468, + "y": 437.41791299202873, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e3fafc", + "width": 264.2321183950353, + "height": 30, + "seed": 1585118358, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "aMDHhh73Kq_exjFjSphhA" + } + ], + "updated": 1714030137312, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 266, + "versionNonce": 277931356, + "index": "bGS", + "isDeleted": false, + "id": "aMDHhh73Kq_exjFjSphhA", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4507.264152012423, + "y": 442.41791299202873, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e3fafc", + "width": 137.055908203125, + "height": 20, + "seed": 777714134, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727578912987, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Business Analysis", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "nnxtivUvLcOvIXZid-dAo", + "originalText": "Business Analysis", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 537, + "versionNonce": 1117610204, + "index": "bGT", + "isDeleted": false, + "id": "9ThktV_bUfVHep-Sif8TV", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4039.3479453708087, + "y": 494.0741078293049, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffd8a8", + "width": 152.54881771363654, + "height": 30, + "seed": 1324532310, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "-htaAKMVSY2NEcmoFIdKn" + } + ], + "updated": 1727579082778, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 540, + "versionNonce": 578086236, + "index": "bGU", + "isDeleted": false, + "id": "-htaAKMVSY2NEcmoFIdKn", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4047.062394816006, + "y": 499.0741078293049, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 137.1199188232422, + "height": 20, + "seed": 1330907030, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579082778, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Behavior Analysis", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "9ThktV_bUfVHep-Sif8TV", + "originalText": "Behavior Analysis", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 525, + "versionNonce": 367516124, + "index": "bGV", + "isDeleted": false, + "id": "-VrMOFPDnwJXt3DFDqXgb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4205.287524804471, + "y": 493.1486066841543, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffd8a8", + "width": 128.34879024781614, + "height": 30, + "seed": 1654166550, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "hasuh6ZKCLmCJ6L9OtfRL" + } + ], + "updated": 1727579082778, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 528, + "versionNonce": 2013806172, + "index": "bGW", + "isDeleted": false, + "id": "hasuh6ZKCLmCJ6L9OtfRL", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4212.481947089023, + "y": 498.1486066841543, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 113.95994567871094, + "height": 20, + "seed": 433693014, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579082778, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Event Analysis", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "-VrMOFPDnwJXt3DFDqXgb", + "originalText": "Event Analysis", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 563, + "versionNonce": 1906840284, + "index": "bGX", + "isDeleted": false, + "id": "bWg3se45RBn2GVWmwkHj-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4343.672565276057, + "y": 492.7995198983699, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffd8a8", + "width": 111.94882686891003, + "height": 32.41458550747666, + "seed": 1042595414, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "Q7ElK4uca6xViRkUDRSZr" + } + ], + "updated": 1727579082778, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 566, + "versionNonce": 1096374108, + "index": "bGY", + "isDeleted": false, + "id": "Q7ElK4uca6xViRkUDRSZr", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4350.031011913637, + "y": 499.00681265210824, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 99.23193359375, + "height": 20, + "seed": 2129036182, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579082778, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Path Analysi", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "bWg3se45RBn2GVWmwkHj-", + "originalText": "Path Analysi", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 524, + "versionNonce": 57543644, + "index": "bGZ", + "isDeleted": false, + "id": "Ny0Xk_5-yAsdZlc9IeH_O", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4466.028602817622, + "y": 494.27587640288607, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffd8a8", + "width": 201.9487047985972, + "height": 32.41458550747666, + "seed": 1565331222, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "AyDjHSFC6pwFl1oBpEbyl" + } + ], + "updated": 1727579082778, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 540, + "versionNonce": 2046308444, + "index": "bGa", + "isDeleted": false, + "id": "AyDjHSFC6pwFl1oBpEbyl", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4471.999010819948, + "y": 500.4831691566244, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 190.0078887939453, + "height": 20, + "seed": 1581694038, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579082778, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Multidimensional Analysis", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Ny0Xk_5-yAsdZlc9IeH_O", + "originalText": "Multidimensional Analysis", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 529, + "versionNonce": 1422509276, + "index": "bGb", + "isDeleted": false, + "id": "P-N3vRnP0D0c-Psym7S4k", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4674.486141636881, + "y": 493.9994710702449, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffd8a8", + "width": 159.94888790406614, + "height": 32.4145855074766, + "seed": 1718836310, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "A5CRFhUSftYzqgwPuR8Ov" + } + ], + "updated": 1727579082778, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 552, + "versionNonce": 2037696860, + "index": "bGc", + "isDeleted": false, + "id": "A5CRFhUSftYzqgwPuR8Ov", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4682.816618914109, + "y": 500.20676382398324, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 143.28793334960938, + "height": 20, + "seed": 531718550, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579082778, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Retention Analysis", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "P-N3vRnP0D0c-Psym7S4k", + "originalText": "Retention Analysis", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 431, + "versionNonce": 1263222236, + "index": "bGd", + "isDeleted": false, + "id": "_O8hfukISlrMxz25rZkb5", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4843.234890309177, + "y": 494.05040869852303, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffd8a8", + "width": 201.14877804078483, + "height": 32.4145855074766, + "seed": 1667054806, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "WNYXK-Zi8oOVcmZK57Egp" + } + ], + "updated": 1727579082778, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 477, + "versionNonce": 1935614556, + "index": "bGe", + "isDeleted": false, + "id": "WNYXK-Zi8oOVcmZK57Egp", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4848.377341158182, + "y": 500.25770145226136, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 190.86387634277344, + "height": 20, + "seed": 361443862, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579082778, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "A/B Experiment Analysis", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "_O8hfukISlrMxz25rZkb5", + "originalText": "A/B Experiment Analysis", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 324, + "versionNonce": 439677322, + "index": "bGf", + "isDeleted": false, + "id": "JrjxYVBF6d8YI8CJYs0uk", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 3962.9608163753137, + "y": 700.0171531387487, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 153.30875055059957, + "height": 34.268958167594626, + "seed": 591551318, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "omernCfZ2U7BFScf5B-mc" + }, + { + "id": "LkbKcjiDVBg8UBn_KTIvC", + "type": "arrow" + } + ], + "updated": 1714030297768, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 328, + "versionNonce": 143501404, + "index": "bGg", + "isDeleted": false, + "id": "omernCfZ2U7BFScf5B-mc", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 3987.1552230837187, + "y": 707.1516322225459, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 104.91993713378906, + "height": 20, + "seed": 138969238, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579517376, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "File Collector", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "JrjxYVBF6d8YI8CJYs0uk", + "originalText": "File Collector", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 311, + "versionNonce": 1064049162, + "index": "bGh", + "isDeleted": false, + "id": "ETqPn5gTT-lCKj2dr3Da3", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 3963.411751784041, + "y": 782.307773803082, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 153.30875055059957, + "height": 34.268958167594626, + "seed": 372805898, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "yiqf1Qrj7gSAl7mUK8jJM" + }, + { + "id": "lwXr1xHXO826CDV455r22", + "type": "arrow" + } + ], + "updated": 1714030304232, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 319, + "versionNonce": 1131890404, + "index": "bGi", + "isDeleted": false, + "id": "yiqf1Qrj7gSAl7mUK8jJM", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 3975.8741714929342, + "y": 789.4422528868793, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 128.3839111328125, + "height": 20, + "seed": 802545610, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1727579524437, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Pulsar Collector", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "ETqPn5gTT-lCKj2dr3Da3", + "originalText": "Pulsar Collector", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 30, + "versionNonce": 2095481546, + "index": "bGn", + "isDeleted": false, + "id": "pNz3hgiz0LCrzo28knc8Y", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4125.2876902742255, + "y": 572.6356749220628, + "strokeColor": "#1e1e1e", + "backgroundColor": "#fff9db", + "width": 41.03264528306863, + "height": 0, + "seed": 1408952074, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1714030292265, + "link": null, + "locked": false, + "startBinding": { + "elementId": "TC690jPwppWjEz1vdQ_io", + "focus": 0.6139210617045316, + "gap": 9.469024355502597, + "fixedPoint": null + }, + "endBinding": { + "elementId": "--a-rB0zDHte86UmfI2jn", + "focus": 0.8257700928214197, + "gap": 2.7054404446430453, + "fixedPoint": null + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 41.03264528306863, + 0 + ] + ] + }, + { + "type": "arrow", + "version": 50, + "versionNonce": 165181788, + "index": "bGo", + "isDeleted": false, + "id": "LkbKcjiDVBg8UBn_KTIvC", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4122.131348822393, + "y": 717.3770999269092, + "strokeColor": "#1e1e1e", + "backgroundColor": "#fff9db", + "width": 41.48351188871129, + "height": 0.45086660564254544, + "seed": 1476909130, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1727579514140, + "link": null, + "locked": false, + "startBinding": { + "elementId": "JrjxYVBF6d8YI8CJYs0uk", + "focus": -0.03736532007677751, + "gap": 5.861781896480352, + "fixedPoint": null + }, + "endBinding": { + "elementId": "--a-rB0zDHte86UmfI2jn", + "focus": -0.22249389315525986, + "gap": 5.4109152908326905, + "fixedPoint": null + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 41.48351188871129, + 0.45086660564254544 + ] + ] + }, + { + "type": "arrow", + "version": 38, + "versionNonce": 185352540, + "index": "bGp", + "isDeleted": false, + "id": "lwXr1xHXO826CDV455r22", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 4118.975007370562, + "y": 800.3441237043315, + "strokeColor": "#1e1e1e", + "backgroundColor": "#fff9db", + "width": 47.34532818673233, + "height": 1.3527374230948226, + "seed": 1638278602, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1727579518744, + "link": null, + "locked": false, + "startBinding": { + "elementId": "ETqPn5gTT-lCKj2dr3Da3", + "focus": -0.06999832899324306, + "gap": 2.2545050359210563, + "fixedPoint": null + }, + "endBinding": { + "elementId": "--a-rB0zDHte86UmfI2jn", + "focus": -0.8238932094270057, + "gap": 2.7054404446430453, + "fixedPoint": null + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 47.34532818673233, + 1.3527374230948226 + ] + ] + } + ], + "appState": { + "gridSize": 20, + "gridStep": 5, + "gridModeEnabled": false, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file