span-data 0.1.3__cp311-cp311-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- span_data/id_grapher/__init__.cp311-win_amd64.pyd +0 -0
- span_data/id_grapher/clean_data.cp311-win_amd64.pyd +0 -0
- span_data/id_grapher/constants.cp311-win_amd64.pyd +0 -0
- span_data/id_grapher/field_definition_map.cp311-win_amd64.pyd +0 -0
- span_data/id_grapher/graph_result.cp311-win_amd64.pyd +0 -0
- span_data/id_grapher/id_grapher.cp311-win_amd64.pyd +0 -0
- span_data/id_grapher/overrides.cp311-win_amd64.pyd +0 -0
- span_data/id_grapher/profile_assignment_sql.cp311-win_amd64.pyd +0 -0
- span_data-0.1.3.data/data/CHANGELOG.md +16 -0
- span_data-0.1.3.data/data/LICENSE +29 -0
- span_data-0.1.3.data/data/THIRD_PARTY_NOTICES.md +35 -0
- span_data-0.1.3.data/data/USAGE.md +179 -0
- span_data-0.1.3.dist-info/METADATA +52 -0
- span_data-0.1.3.dist-info/RECORD +17 -0
- span_data-0.1.3.dist-info/WHEEL +5 -0
- span_data-0.1.3.dist-info/licenses/LICENSE +29 -0
- span_data-0.1.3.dist-info/top_level.txt +1 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## 0.1.0 - 2026-05-12
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- Initial public release of `span_data`.
|
|
9
|
+
- Identity graphing library built on Splink and DuckDB.
|
|
10
|
+
- Support for DataFrame, CSV, and Snowflake ingestion.
|
|
11
|
+
- Manual override workflows for merge, split, and assign operations.
|
|
12
|
+
|
|
13
|
+
### Packaging
|
|
14
|
+
- Added PyPI packaging metadata in `pyproject.toml`.
|
|
15
|
+
- Added BSD 3-Clause `LICENSE`.
|
|
16
|
+
- Added `THIRD_PARTY_NOTICES.md` for direct runtime dependencies.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, Data Loft Technologies Inc
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
## Third-Party Notices
|
|
2
|
+
|
|
3
|
+
This project depends on third-party Python packages. The following list covers
|
|
4
|
+
the direct runtime dependencies currently declared in `pyproject.toml`.
|
|
5
|
+
|
|
6
|
+
License data was collected from package metadata on PyPI and, where metadata
|
|
7
|
+
was missing, from the corresponding upstream repository license declaration.
|
|
8
|
+
|
|
9
|
+
If dependencies are added or updated, this file should be reviewed and updated.
|
|
10
|
+
|
|
11
|
+
### Direct Runtime Dependencies
|
|
12
|
+
|
|
13
|
+
- `duckdb` (`MIT`)
|
|
14
|
+
- PyPI: <https://pypi.org/project/duckdb/>
|
|
15
|
+
- `email-validator` (`Unlicense`)
|
|
16
|
+
- PyPI: <https://pypi.org/project/email-validator/>
|
|
17
|
+
- `pandas` (`BSD-3-Clause`)
|
|
18
|
+
- PyPI: <https://pypi.org/project/pandas/>
|
|
19
|
+
- `phonenumbers` (`Apache-2.0`)
|
|
20
|
+
- PyPI: <https://pypi.org/project/phonenumbers/>
|
|
21
|
+
- Upstream license source: <https://github.com/daviddrysdale/python-phonenumbers>
|
|
22
|
+
- `snowflake-connector-python` (`Apache-2.0`)
|
|
23
|
+
- PyPI: <https://pypi.org/project/snowflake-connector-python/>
|
|
24
|
+
- `splink` (`MIT`)
|
|
25
|
+
- PyPI: <https://pypi.org/project/splink/>
|
|
26
|
+
- Upstream license source: <https://github.com/moj-analytical-services/splink>
|
|
27
|
+
|
|
28
|
+
### Notes
|
|
29
|
+
|
|
30
|
+
- This notice file is informational and does not replace the terms of the
|
|
31
|
+
third-party licenses.
|
|
32
|
+
- The maintainers of this package, acting on behalf of Data Loft Technologies Inc.,
|
|
33
|
+
are responsible for reviewing transitive dependencies and any bundled artifacts
|
|
34
|
+
before each release. Downstream users may still perform their own license and
|
|
35
|
+
compliance reviews as required by their organization or jurisdiction.
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# Using the ID Grapher with Snowflake
|
|
2
|
+
|
|
3
|
+
This document provides a step-by-step guide on how to use the `id_grapher`
|
|
4
|
+
library to read data from and write data to Snowflake.
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
The `id_grapher` library is a tool for identity resolution. It uses the
|
|
9
|
+
`splink` library to identify and cluster records that refer to the same entity.
|
|
10
|
+
This guide focuses on using the `id_grapher` with Snowflake as the data source
|
|
11
|
+
and destination.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
Install the published package from PyPI:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install span-data
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
Here's a complete example of how to use the `id_grapher` with Snowflake:
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from span_data.id_grapher import IDGrapher, FieldDefinitionMap
|
|
27
|
+
import snowflake.connector
|
|
28
|
+
|
|
29
|
+
# 1. Connect to Snowflake
|
|
30
|
+
# Replace with your Snowflake connection details
|
|
31
|
+
con = snowflake.connector.connect(
|
|
32
|
+
user="<your_user>",
|
|
33
|
+
password="<your_password>",
|
|
34
|
+
account="<your_account>",
|
|
35
|
+
warehouse="<your_warehouse>",
|
|
36
|
+
database="<your_database>",
|
|
37
|
+
schema="<your_schema>"
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# 2. Define the field map
|
|
41
|
+
# This map tells the ID Grapher how to map the columns in your Snowflake
|
|
42
|
+
# table to the standard fields used by the grapher. The keys of the dictionary
|
|
43
|
+
# are the column names in your Snowflake table, and the values specify the
|
|
44
|
+
# 'type' of data and the 'mapping' to the ID Grapher's internal field name.
|
|
45
|
+
# This example is based on the configuration found in
|
|
46
|
+
# `libs/id_grapher/tests/config/id_graph_map_config.yaml`.
|
|
47
|
+
field_map = FieldDefinitionMap(
|
|
48
|
+
{
|
|
49
|
+
"FIRSTNAME": {
|
|
50
|
+
"type": "text",
|
|
51
|
+
"mapping": "first_name"
|
|
52
|
+
},
|
|
53
|
+
"LASTNAME": {
|
|
54
|
+
"type": "text",
|
|
55
|
+
"mapping": "last_name"
|
|
56
|
+
},
|
|
57
|
+
"USER_EMAIL": {
|
|
58
|
+
"type": "email",
|
|
59
|
+
"mapping": "email"
|
|
60
|
+
},
|
|
61
|
+
"DOB": {
|
|
62
|
+
"type": "text",
|
|
63
|
+
"mapping": "birthdate"
|
|
64
|
+
},
|
|
65
|
+
"PHONE": {
|
|
66
|
+
"type": "phonenumber",
|
|
67
|
+
"mapping": "phone"
|
|
68
|
+
},
|
|
69
|
+
"STREET_ADDRESS": {
|
|
70
|
+
"type": "text",
|
|
71
|
+
"mapping": "street_address"
|
|
72
|
+
},
|
|
73
|
+
"CITY": {
|
|
74
|
+
"type": "text",
|
|
75
|
+
"mapping": "city"
|
|
76
|
+
},
|
|
77
|
+
"STATE": {
|
|
78
|
+
"type": "text",
|
|
79
|
+
"mapping": "state"
|
|
80
|
+
},
|
|
81
|
+
"COUNTRY": {
|
|
82
|
+
"type": "text",
|
|
83
|
+
"mapping": "country"
|
|
84
|
+
},
|
|
85
|
+
"ZIP_CODE": {
|
|
86
|
+
"type": "text",
|
|
87
|
+
"mapping": "zip_code"
|
|
88
|
+
},
|
|
89
|
+
"GENDER": {
|
|
90
|
+
"type": "text",
|
|
91
|
+
"mapping": "gender"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# 3. Configure Splink
|
|
97
|
+
# The ID Grapher uses Splink for record linkage. You need to provide a
|
|
98
|
+
# Splink configuration dictionary. This configuration defines how Splink
|
|
99
|
+
# should compare records and which blocking rules to use.
|
|
100
|
+
#
|
|
101
|
+
# For more details on how to configure Splink, please refer to the
|
|
102
|
+
# official Splink documentation: https://moj-analytical-services.github.io/splink/
|
|
103
|
+
splink_config = {
|
|
104
|
+
"linkage_model": "det",
|
|
105
|
+
"blocking_rules": [
|
|
106
|
+
{"columns": ["first_name", "last_name", "birthdate", "state"]},
|
|
107
|
+
{"columns": ["first_name", "last_name", "birthdate", "city"]},
|
|
108
|
+
{"columns": ["first_name", "last_name", "zip_code"]},
|
|
109
|
+
{"columns": ["first_name", "last_name", "street_address"]},
|
|
110
|
+
{"columns": ["first_name", "email"]},
|
|
111
|
+
{"columns": ["email", "phone"]},
|
|
112
|
+
{"columns": ["phone", "gender"]}
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
# 4. Instantiate the IDGrapher and process the data
|
|
118
|
+
with IDGrapher() as grapher:
|
|
119
|
+
# Add data from a Snowflake table
|
|
120
|
+
# The 'key' parameter should be the name of the column in your table that
|
|
121
|
+
# represents a unique identifier for each record in that source.
|
|
122
|
+
grapher.add_snowflake(
|
|
123
|
+
con=con,
|
|
124
|
+
object_name="SOURCE_DATABASE.SOURCE_SCHEMA.SOURCE_TABLE",
|
|
125
|
+
key="ACCOUNT_ID",
|
|
126
|
+
field_map=field_map
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
# OPTIONAL: Add more data sources as needed
|
|
130
|
+
# grapher.add_snowflake(...)
|
|
131
|
+
|
|
132
|
+
# OPTIONAL: Add existing ID graph table if available
|
|
133
|
+
"""
|
|
134
|
+
grapher.add_snowflake(
|
|
135
|
+
con=con,
|
|
136
|
+
object_name="ID_GRAPH_DATABASE.ID_GRAPH_SCHEMA.ID_GRAPH_TABLE",
|
|
137
|
+
key="PROFILE_ID",
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
# Process the data to create the ID graph
|
|
143
|
+
graph_result = grapher.process(splink_config)
|
|
144
|
+
|
|
145
|
+
# 5. Write the results back to Snowflake
|
|
146
|
+
graph_result.to_snowflake(
|
|
147
|
+
con=con,
|
|
148
|
+
database="ID_GRAPH_DATABASE",
|
|
149
|
+
schema="ID_GRAPH_SCHEMA",
|
|
150
|
+
table_name="ID_GRAPH_TABLE"
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
# Close the Snowflake connection
|
|
154
|
+
con.close()
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Explanation
|
|
158
|
+
|
|
159
|
+
1. **Connect to Snowflake**: We establish a connection to Snowflake using the
|
|
160
|
+
`snowflake-connector-python` library.
|
|
161
|
+
|
|
162
|
+
2. **Define the Field Map**: The `FieldDefinitionMap` is used to map your
|
|
163
|
+
source table's column names to the standard field names that the
|
|
164
|
+
`id_grapher` expects. This allows the library to understand your data.
|
|
165
|
+
|
|
166
|
+
3. **Configure Splink**: The `splink_config` dictionary is crucial for the ID
|
|
167
|
+
resolution process. It tells `splink` how to compare records and what rules
|
|
168
|
+
to use for blocking (to reduce the number of comparisons) and matching. The
|
|
169
|
+
example above provides a basic configuration, but you will likely need to
|
|
170
|
+
tune it for your specific data.
|
|
171
|
+
|
|
172
|
+
4. **Instantiate and Process**: We create an `IDGrapher` instance and use the
|
|
173
|
+
`add_snowflake` method to load data from your Snowflake table. The
|
|
174
|
+
`process` method then runs the identity resolution process.
|
|
175
|
+
|
|
176
|
+
5. **Write Results to Snowflake**: The `graph_result.to_snowflake()` method
|
|
177
|
+
writes the output of the ID resolution process to a new table in Snowflake.
|
|
178
|
+
The output table will contain the original data enriched with a
|
|
179
|
+
`profile_id` column, which represents the unique entity identifier.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: span_data
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: Identity resolution library built on Splink and DuckDB.
|
|
5
|
+
Author: The Data Loft
|
|
6
|
+
License-Expression: BSD-3-Clause
|
|
7
|
+
Project-URL: Community (Slack), https://join.slack.com/t/span-data/shared_invite/zt-3xkirzw8i-w_OcmdVoyAMLSH2V83gGAw
|
|
8
|
+
Project-URL: Documentation, https://span.gitbook.io/span-docs
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Requires-Python: <3.12,>=3.11
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: duckdb<2.0.0,>=1.5.1
|
|
15
|
+
Requires-Dist: email-validator<3.0.0,>=1.3.1
|
|
16
|
+
Requires-Dist: pandas<3.0.0,>=2.3.3
|
|
17
|
+
Requires-Dist: phonenumbers<10.0.0,>=9.0.6
|
|
18
|
+
Requires-Dist: snowflake-connector-python[pandas]==4.4.0
|
|
19
|
+
Requires-Dist: splink<5.0.0,>=4.0.16
|
|
20
|
+
Dynamic: license-file
|
|
21
|
+
|
|
22
|
+
# ID Grapher
|
|
23
|
+
|
|
24
|
+
`span_data` is an identity resolution library built on Splink and DuckDB. It
|
|
25
|
+
links records that refer to the same entity and produces a unified ID graph.
|
|
26
|
+
|
|
27
|
+
## Core Features
|
|
28
|
+
|
|
29
|
+
- Ingest source data from pandas DataFrames, CSV files, and Snowflake tables or
|
|
30
|
+
views.
|
|
31
|
+
- Clean and normalize source fields using `FieldDefinitionMap`.
|
|
32
|
+
- Resolve entities into profile graphs with Splink-based matching.
|
|
33
|
+
- Export graph results to DataFrames, CSV, Parquet, DuckDB relations, and
|
|
34
|
+
Snowflake.
|
|
35
|
+
- Apply manual override workflows for merge, split, and assign operations.
|
|
36
|
+
|
|
37
|
+
## Python Support
|
|
38
|
+
|
|
39
|
+
This package currently supports Python `>=3.11,<3.12`.
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
See [SPAN Product Documentation](https://span.gitbook.io/span-docs) for usage instructions.
|
|
44
|
+
|
|
45
|
+
## License
|
|
46
|
+
|
|
47
|
+
This project is licensed under the BSD 3-Clause License. See `LICENSE`.
|
|
48
|
+
|
|
49
|
+
Third-party dependency license information is documented in
|
|
50
|
+
`THIRD_PARTY_NOTICES.md`.
|
|
51
|
+
|
|
52
|
+
Release history is documented in `CHANGELOG.md`.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
span_data/id_grapher/__init__.cp311-win_amd64.pyd,sha256=8ICY5k670HKLavTYb8_5JPPLRgJQLoZPpuYBthgQx6E,18944
|
|
2
|
+
span_data/id_grapher/clean_data.cp311-win_amd64.pyd,sha256=r5LWWbTyJ-mOJWyl4tuJn5jxvX2WcqlZ3zdCBa1UosY,78848
|
|
3
|
+
span_data/id_grapher/constants.cp311-win_amd64.pyd,sha256=0C-ea7eLMOrw1XJ-qJm_PoXVqSMmaDN9LHdBWcPSOmo,17408
|
|
4
|
+
span_data/id_grapher/field_definition_map.cp311-win_amd64.pyd,sha256=HxfqXrUhWSC5vlLAj2awqDyhqn20xTHM3HXWG8V-Hbc,67072
|
|
5
|
+
span_data/id_grapher/graph_result.cp311-win_amd64.pyd,sha256=YmgCLBvEKMT5ws0EFosmXGkh0o4G7K04L52JXCAB1Ns,70144
|
|
6
|
+
span_data/id_grapher/id_grapher.cp311-win_amd64.pyd,sha256=Rh-H5GE4w3AxUnNjA0zm8TDtlY54dfr5g_tGUNVLEFM,186880
|
|
7
|
+
span_data/id_grapher/overrides.cp311-win_amd64.pyd,sha256=N9hQwtFoOibzOM1BQmyvyeVoojBGRjDGghHb7I2Xpr0,74240
|
|
8
|
+
span_data/id_grapher/profile_assignment_sql.cp311-win_amd64.pyd,sha256=lQZa0-wWkGBMZDGzCcfNW2cho1mB3tc1Gd_lhntcTKE,83456
|
|
9
|
+
span_data-0.1.3.data/data/CHANGELOG.md,sha256=Ars7jCKy7Iv4Hlqd4-X-sTZcYGOX4VoAm4gn3rkbFuo,519
|
|
10
|
+
span_data-0.1.3.data/data/LICENSE,sha256=5N8M-KZZEWyLdn6BhblwvkK4QKFUiAKJIpcjcAdOWRs,1563
|
|
11
|
+
span_data-0.1.3.data/data/THIRD_PARTY_NOTICES.md,sha256=cUEJdSoYg41X7eNuotKsNnOq3A-wYnjyCEhZDbFcin0,1556
|
|
12
|
+
span_data-0.1.3.data/data/USAGE.md,sha256=S_7MJVv_dbwkQdQQDHkNaaa7wP4IZHHeHp4JcYVw5Go,5843
|
|
13
|
+
span_data-0.1.3.dist-info/licenses/LICENSE,sha256=5N8M-KZZEWyLdn6BhblwvkK4QKFUiAKJIpcjcAdOWRs,1563
|
|
14
|
+
span_data-0.1.3.dist-info/METADATA,sha256=oUCMxrgQrNYCgoFHxFQF8MG0XgjAni238c7-nrqsnwU,1841
|
|
15
|
+
span_data-0.1.3.dist-info/WHEEL,sha256=XHXMKJU3yoVh1ZanBXTJ5bDGb67oEYtF1S6bd8a4izI,101
|
|
16
|
+
span_data-0.1.3.dist-info/top_level.txt,sha256=ItfL4WXhvvBw4enCi2zm5Rabby0YIW5Ew9b25-NOmL8,10
|
|
17
|
+
span_data-0.1.3.dist-info/RECORD,,
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, Data Loft Technologies Inc
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
span_data
|