conceptql 0.6.0 → 0.7.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +176 -0
- data/README.md +4 -2
- data/assets/diagram/diagram.css +331 -0
- data/assets/diagram/fonts/OFL.txt +93 -0
- data/assets/diagram/fonts/Roboto-400.ttf +0 -0
- data/assets/diagram/fonts/Roboto-700.ttf +0 -0
- data/assets/diagram/fonts/Roboto-Italic-400.ttf +0 -0
- data/assets/diagram/fonts/Roboto-Italic-Latin.woff2 +0 -0
- data/assets/diagram/fonts/Roboto-Normal-Latin.woff2 +0 -0
- data/assets/diagram/operators.svg +224 -0
- data/config/vocabularies.csv +85 -85
- data/docs/spec/README.md +2624 -0
- data/docs/spec/examples/after-operator.json +562 -0
- data/docs/spec/examples/any-overlap-operator.json +106 -0
- data/docs/spec/examples/before-operator.json +437 -0
- data/docs/spec/examples/co-reported-operator.json +168 -0
- data/docs/spec/examples/contains-operator.json +97 -0
- data/docs/spec/examples/date-range-operator.json +275 -0
- data/docs/spec/examples/death-operator.json +103 -0
- data/docs/spec/examples/during-operator.json +178 -0
- data/docs/spec/examples/episode-operator.json +80 -0
- data/docs/spec/examples/equal-operator.json +79 -0
- data/docs/spec/examples/ethnicity-operator.json +86 -0
- data/docs/spec/examples/except-operator.json +536 -0
- data/docs/spec/examples/filter-operator.json +218 -0
- data/docs/spec/examples/first-operator.json +148 -0
- data/docs/spec/examples/gender-operator.json +257 -0
- data/docs/spec/examples/hospice-operator.json +40 -0
- data/docs/spec/examples/hospitalization-operator.json +131 -0
- data/docs/spec/examples/information-periods-operator.json +131 -0
- data/docs/spec/examples/last-operator.json +148 -0
- data/docs/spec/examples/match-operator.json +186 -0
- data/docs/spec/examples/nth-occurrence-operator.json +300 -0
- data/docs/spec/examples/numeric-filter-operator.json +77 -0
- data/docs/spec/examples/one-in-two-out-operator.json +158 -0
- data/docs/spec/examples/person-filter-operator.json +919 -0
- data/docs/spec/examples/person-operator.json +274 -0
- data/docs/spec/examples/place-of-service-filter-operator.json +57 -0
- data/docs/spec/examples/provenance-operator.json +148 -0
- data/docs/spec/examples/provider-filter-operator.json +77 -0
- data/docs/spec/examples/race-operator.json +131 -0
- data/docs/spec/examples/recall-operator.json +289 -0
- data/docs/spec/examples/snf-operator.json +40 -0
- data/docs/spec/examples/time-window-operator.json +736 -0
- data/docs/spec/examples/trim-date-end-operator.json +201 -0
- data/docs/spec/examples/trim-date-start-operator.json +201 -0
- data/docs/spec/examples/union-operator.json +547 -0
- data/docs/spec/examples/vocabulary-operator.json +232 -0
- data/lib/conceptql/behaviors/metadatable.rb +68 -2
- data/lib/conceptql/behaviors/provenanceable.rb +4 -1
- data/lib/conceptql/behaviors/utilizable.rb +3 -0
- data/lib/conceptql/code_case_mismatch_error.rb +50 -0
- data/lib/conceptql/data_model/gdm.rb +23 -2
- data/lib/conceptql/diagram_renderer/app.rb +59 -0
- data/lib/conceptql/diagram_renderer/configuration.rb +87 -0
- data/lib/conceptql/diagram_renderer/diagram_data.rb +80 -0
- data/lib/conceptql/diagram_renderer/drawing.rb +255 -0
- data/lib/conceptql/diagram_renderer/geometry.rb +380 -0
- data/lib/conceptql/diagram_renderer/input_error.rb +11 -0
- data/lib/conceptql/diagram_renderer/js_format.rb +112 -0
- data/lib/conceptql/diagram_renderer/resvg.rb +120 -0
- data/lib/conceptql/diagram_renderer/sprite.rb +73 -0
- data/lib/conceptql/diagram_renderer/static.rb +70 -0
- data/lib/conceptql/diagram_renderer/svg.rb +73 -0
- data/lib/conceptql/diagram_renderer/tree_layout.rb +287 -0
- data/lib/conceptql/diagram_renderer.rb +82 -0
- data/lib/conceptql/lexicon/lexicon_strategy.rb +16 -0
- data/lib/conceptql/lexicon.rb +63 -11
- data/lib/conceptql/nodifier.rb +5 -3
- data/lib/conceptql/operators/after.rb +15 -1
- data/lib/conceptql/operators/any_overlap.rb +6 -1
- data/lib/conceptql/operators/before.rb +11 -1
- data/lib/conceptql/operators/binary_operator_operator.rb +12 -2
- data/lib/conceptql/operators/co_reported.rb +9 -4
- data/lib/conceptql/operators/contains.rb +6 -1
- data/lib/conceptql/operators/count.rb +2 -0
- data/lib/conceptql/operators/date_range.rb +15 -3
- data/lib/conceptql/operators/death.rb +5 -1
- data/lib/conceptql/operators/dedup.rb +2 -0
- data/lib/conceptql/operators/during.rb +6 -1
- data/lib/conceptql/operators/episode.rb +13 -2
- data/lib/conceptql/operators/equal.rb +11 -1
- data/lib/conceptql/operators/ethnicity.rb +19 -7
- data/lib/conceptql/operators/except.rb +10 -1
- data/lib/conceptql/operators/filter.rb +6 -1
- data/lib/conceptql/operators/first.rb +19 -9
- data/lib/conceptql/operators/from.rb +3 -0
- data/lib/conceptql/operators/gender.rb +10 -2
- data/lib/conceptql/operators/hospice.rb +7 -1
- data/lib/conceptql/operators/hospitalization.rb +6 -1
- data/lib/conceptql/operators/information_periods.rb +26 -7
- data/lib/conceptql/operators/invalid.rb +4 -0
- data/lib/conceptql/operators/last.rb +19 -9
- data/lib/conceptql/operators/match.rb +6 -1
- data/lib/conceptql/operators/multiple_vocabularies.rb +17 -3
- data/lib/conceptql/operators/numeric.rb +4 -0
- data/lib/conceptql/operators/numeric_filter.rb +13 -3
- data/lib/conceptql/operators/occurrence.rb +33 -12
- data/lib/conceptql/operators/one_in_two_out.rb +22 -5
- data/lib/conceptql/operators/operator.rb +8 -4
- data/lib/conceptql/operators/person.rb +5 -1
- data/lib/conceptql/operators/person_filter.rb +14 -1
- data/lib/conceptql/operators/place_of_service_filter.rb +14 -3
- data/lib/conceptql/operators/provenance.rb +17 -8
- data/lib/conceptql/operators/provider_filter.rb +18 -6
- data/lib/conceptql/operators/race.rb +14 -9
- data/lib/conceptql/operators/read.rb +11 -1
- data/lib/conceptql/operators/recall.rb +34 -2
- data/lib/conceptql/operators/snf.rb +7 -1
- data/lib/conceptql/operators/sum.rb +4 -0
- data/lib/conceptql/operators/temporal_operator.rb +4 -2
- data/lib/conceptql/operators/time_window.rb +27 -4
- data/lib/conceptql/operators/trim_date.rb +6 -14
- data/lib/conceptql/operators/trim_date_end.rb +9 -3
- data/lib/conceptql/operators/trim_date_start.rb +9 -3
- data/lib/conceptql/operators/union.rb +13 -1
- data/lib/conceptql/operators/vocabulary.rb +80 -6
- data/lib/conceptql/paths.rb +9 -1
- data/lib/conceptql/version.rb +1 -1
- data/lib/conceptql/vocabularies/drg_systems.rb +3 -2
- data/lib/conceptql/vocabularies/entry.rb +14 -11
- data/lib/conceptql/vocabularies/vocabulary_class_factory.rb +2 -1
- data/lib/conceptql.rb +3 -0
- metadata +75 -2
- data/doc/spec.md +0 -2091
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cf5cfc7db1200e2f00e6006a54f138e6837c1d05483330c7dccb5f9b8a93a907
|
|
4
|
+
data.tar.gz: 8095c96f350258266df92fcd521d99460a9ff48af70657b6b980294a29fa6a47
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3a04d687527d5d808446f3fef305805a6915679c1c079dc1edf98afdb9fa7c650525e929b89ee227fe0e9066d58c81585e8c027ff18efc5a793c30bece1454cd
|
|
7
|
+
data.tar.gz: c4302550620621d1dc241c60a0a47fe4fe31b9ee0dc143d4bd467fb52a775aff5f46eeac815a1470ef661c0103e716e518610f04d55f8ec4b4975a6c4ba9d3f4
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,182 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.7.0] - 2026-11-09
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `ConceptQL::DiagramRenderer`, the diagram renderer of the Jigsaw diagram editor, moved into
|
|
12
|
+
the gem. It draws a diagram tree (`ConceptQL::Diagram.render`) as a standalone static SVG
|
|
13
|
+
(`render_static`), a PNG (`png`) or the in-app SVG (`render_app`), with the same drawing as in
|
|
14
|
+
the editor. Its SVG output differs from the editor's only in the text of the `<style>` element,
|
|
15
|
+
and its PNG output is byte-identical. The gem ships its assets under `assets/diagram/`: the
|
|
16
|
+
operator icons, the diagram CSS, and the Roboto fonts with their license (SIL Open Font
|
|
17
|
+
License 1.1). The gemspec lists both licenses, `MIT` and `OFL-1.1`. The configuration
|
|
18
|
+
points at them by default, so a host needs no configure call. `require "conceptql"` loads
|
|
19
|
+
none of the renderer until its first use. `render_static` and `png` run the resvg program,
|
|
20
|
+
version 0.33.0. `just test-diagram` runs the renderer's tests against the
|
|
21
|
+
editor's JavaScript references, and `just ci` and GitHub CI run it. The release workflow
|
|
22
|
+
checks that the built gem contains every file under `assets/diagram/`, and it draws one
|
|
23
|
+
diagram with the installed gem. See `docs/diagram_renderer.md`.
|
|
24
|
+
- The renderer's diagram CSS (`assets/diagram/diagram.css`) holds only the rules of the
|
|
25
|
+
editor's stylesheet that can match an element of a diagram. The editor's page rules (for
|
|
26
|
+
`html`, `body`, `h1`, `.sidebar` and the like) are left out. In a page, the `<style>` of the
|
|
27
|
+
in-app SVG applies to the whole page, so a page that used those rules must supply them.
|
|
28
|
+
- The first `render_static` or `png` call in a process runs `resvg --version`. When resvg
|
|
29
|
+
reports another version than 0.33.0, the call writes one warning to stderr that names both
|
|
30
|
+
versions. Then it draws the diagram anyway, and later calls do not check again.
|
|
31
|
+
- An operator class can say `hidden`. A hidden operator still runs, but `ConceptQL.metadata`
|
|
32
|
+
leaves it out. An operator is not hidden unless it says so, and a subclass does not inherit
|
|
33
|
+
the mark. `invalid`, `from`, `numeric`, `dedup`, `sum` and `count` are hidden. Before,
|
|
34
|
+
`ConceptQL.metadata` left out each operator without a category, and these six were the only
|
|
35
|
+
such operators. Now every operator has a category from `ConceptQL.categories`. The metadata
|
|
36
|
+
has no `hidden` key, and it publishes the same 119 operators on `gdm` as before.
|
|
37
|
+
- Operator reference documentation in the operator classes. `ConceptQL.metadata` serves two new
|
|
38
|
+
keys for each operator: `returns`, a text that says which records the operator returns, and
|
|
39
|
+
`examples`, a list of `{title, statement, help}`. An option or an argument can have a
|
|
40
|
+
`meaning` key, a text that says what it does. `instructions` stays the hint for typing a
|
|
41
|
+
value. The `label` option and the `left` and `right` options have a `meaning`. The Metadatable
|
|
42
|
+
DSL has `returns`, `example` and `option_meaning`, which replaces the meaning of one inherited
|
|
43
|
+
option. A subclass does not inherit `returns` or the examples. The vocabulary operators serve
|
|
44
|
+
the `returns` text and the examples of `ConceptQL::Operators::Vocabulary`, each operator
|
|
45
|
+
only the examples whose statement starts with its own name. All texts are plain text.
|
|
46
|
+
- `ConceptQL.spec_examples_path`, the directory `docs/spec/examples/` in the gem. It holds one
|
|
47
|
+
file, `<spec_id>.json`, for each spec_id of the operator reference. The file has the
|
|
48
|
+
examples of that section, each with its `title`, `statement`, `help`, the `columns` and the
|
|
49
|
+
first 10 `rows` of its result on the test data, and its diagram `tree`
|
|
50
|
+
(`conceptql-diagram/v1`, with counts). An application can show an operator's help from the
|
|
51
|
+
file of that operator, without a database. `just spec` writes the files, and
|
|
52
|
+
`just spec-check` fails when one of them would change.
|
|
53
|
+
- `information_periods` declares its argument, Information Types (a comma-separated list), so
|
|
54
|
+
an editor can offer the field. The argument is optional: without it, the operator still
|
|
55
|
+
selects every information period. Each value is a concept ID or a concept code of the
|
|
56
|
+
`GDM_INFORMATION_TYPE` vocabulary, such as `PARTD`, and a statement can mix both. An unknown
|
|
57
|
+
code gets the warning `unknown code(s)` and selects no period. Before, every argument went
|
|
58
|
+
through `to_i`, so a code silently became concept ID 0.
|
|
59
|
+
- `cpt` and `hcpcs` warn when the data has no record of their vocabulary but has CPT4_HCPCS
|
|
60
|
+
records, and the lexicon carries CPT4_HCPCS. Production ETL data stores CPT-4 and HCPCS codes
|
|
61
|
+
only as CPT4_HCPCS, so on that data the two operators select nothing (known issue, bead
|
|
62
|
+
`conceptql-rpy3`). The warning is "the data has no records of this vocabulary", and it says
|
|
63
|
+
to use `cpt_or_hcpcs`, which also reads CPT4_HCPCS. `cpt_or_hcpcs` does not give it. The
|
|
64
|
+
check runs two small existence queries on the data, and it skips a mock database as the
|
|
65
|
+
other code warnings do.
|
|
66
|
+
|
|
67
|
+
### Changed
|
|
68
|
+
|
|
69
|
+
- The `inpatient_length_of_stay` and `outpatient_event_to_return` options of `one_in_two_out`
|
|
70
|
+
serve their text as `meaning`. Before, it was a `desc` key that the diagram editor did not
|
|
71
|
+
read.
|
|
72
|
+
- **Breaking:** a code lookup raises `ConceptQL::CodeCaseMismatchError` for a code that its
|
|
73
|
+
vocabulary stores only in another case. Since 0.6.0 a lookup compares codes case-exactly, so
|
|
74
|
+
`data_model.concept_ids(db, "GDM_PROV", ["line"])` returned `[]` without a word, because the
|
|
75
|
+
vocabulary stores `LINE`. t_shank made that call and lost every line row of an export. Now it
|
|
76
|
+
raises, and the message names the vocabulary, each such code and its stored spellings. The
|
|
77
|
+
error's `mismatches` attribute holds the same facts. It is an `ArgumentError`. The lookups
|
|
78
|
+
that take codes raise it: `concept_ids`, `known_codes`, `concepts_to_codes`,
|
|
79
|
+
`concepts_to_codes_in_class`, `code_meanings`, `concepts` and `concepts_ds`, on the
|
|
80
|
+
`Lexicon` and on the data model. `concepts` and `concepts_ds` check when they build the
|
|
81
|
+
dataset. A code that a lookup vocabulary stores in this case is no error, and neither is a
|
|
82
|
+
code that matches nothing in any case: it still finds no concept. A vocabulary whose
|
|
83
|
+
vocabulary_formats row declares `(?i:...)` already ignores case, so it never raises. The
|
|
84
|
+
check reads the concept table without a guard. When the concept table is missing,
|
|
85
|
+
`known_codes`, `code_meanings` and `concepts_to_codes_in_class` raise
|
|
86
|
+
`Sequel::DatabaseError`. 0.6.0 returned `[]`, `{}` and `nil`. Each of these lookups takes
|
|
87
|
+
`check_case: false`, which skips the check and keeps the 0.6.0 answer. A statement does not
|
|
88
|
+
raise: a vocabulary operator, `provenance` and `place_of_service_filter` pass
|
|
89
|
+
`check_case: false`. So `["icd10cm", "i16.5"]` still gets the warning
|
|
90
|
+
`improperly formatted code` and selects no rows. The utilization operators
|
|
91
|
+
(`hospitalization`, `hospice`, `snf`) look up their own codes with the check.
|
|
92
|
+
- **Breaking:** a positional upstream is a validation error (`has upstreams`) on `after`,
|
|
93
|
+
`any_overlap`, `before`, `contains`, `during`, `equal`, `except`, `filter`, `match`,
|
|
94
|
+
`person_filter`, `trim_date_end`, `trim_date_start` and `read`. The first twelve take their
|
|
95
|
+
operands from the `left` and `right` options, and `read` takes codes. Before, each of them
|
|
96
|
+
ignored a positional upstream without a word.
|
|
97
|
+
- **Breaking:** `occurrence`, `first` and `last` accept exactly one upstream. A second
|
|
98
|
+
positional upstream is a validation error (`has multiple upstreams`). Before, they used only
|
|
99
|
+
the first upstream and dropped the others without a word.
|
|
100
|
+
- **Breaking:** `equal` no longer offers the `within` option, and `first` and `last` no longer
|
|
101
|
+
offer `group_by_date`. The options had no effect on these operators. A statement that sets
|
|
102
|
+
one of them fails validation (`unsupported option`). A blank value or `false` passes, so a
|
|
103
|
+
cleared checkbox in the Jigsaw diagram editor still validates.
|
|
104
|
+
- **Breaking:** `DataModel::Gdm#information_period_where_clause` takes the database as its
|
|
105
|
+
first argument: `(db, arguments)`. Before, it took only `(arguments)`. It needs the database
|
|
106
|
+
to look up the concept codes of `information_periods`.
|
|
107
|
+
- The specification moved to `docs/spec/README.md`, and `ConceptQL.spec_path` returns it. Its
|
|
108
|
+
text comes from the conceptql_spec repository, which held the published spec, and it replaces
|
|
109
|
+
the copy that was `doc/spec.md`. `just spec` builds it from `docs/spec/README.cql.md` on the
|
|
110
|
+
DuckDB test data. It draws the diagram images with `ConceptQL::DiagramRenderer`, so it needs
|
|
111
|
+
resvg 0.33.0, and it needs no checkout of the Jigsaw diagram editor. `just spec-check`
|
|
112
|
+
draws every image again and fails when a committed image differs from its new drawing, is
|
|
113
|
+
missing, or is not used. The gem does not ship its diagram images.
|
|
114
|
+
- The `desc` of the published operators changed. The operator classes now hold the reference
|
|
115
|
+
documentation of the spec, so each `desc` is the summary of its operator's reference section.
|
|
116
|
+
`ConceptQL.metadata` serves the new texts, so a system that keeps a copy of the metadata,
|
|
117
|
+
such as the Jigsaw diagram editor, sees a different payload.
|
|
118
|
+
- The spec build writes the reference section of each published `spec_id` and the quick
|
|
119
|
+
reference of Appendix E from `ConceptQL.metadata` of `Database.new(nil, data_model: :gdm)`.
|
|
120
|
+
A section has the operator's `desc`, its upstream operators or its `left` and `right`
|
|
121
|
+
operands, its arguments and options with their `meaning`, its `returns` text and its examples
|
|
122
|
+
with their results and diagrams. `docs/spec/README.cql.md` marks the place of each generated
|
|
123
|
+
block with a directive, `<!-- conceptql-spec: operator <spec_id> -->`, and the spec's
|
|
124
|
+
Appendix D describes the directives. The hand-written copies of these texts are removed from
|
|
125
|
+
the spec.
|
|
126
|
+
- The spec lists every vocabulary operator with the full name of its vocabulary and its
|
|
127
|
+
domain, in a table that the build writes from `ConceptQL.metadata` at the new directive
|
|
128
|
+
`<!-- conceptql-spec: vocabulary-operators -->`. It marks a deprecated operator, such as
|
|
129
|
+
`drg`. The `Vocabulary` Operator section is now a `##` section of its own, so that it stays
|
|
130
|
+
under the 40,000-byte limit of a spec section. The other selection operators moved under a
|
|
131
|
+
new heading, Other Selection Operators. The anchors of the operator sections did not change.
|
|
132
|
+
- `ConceptQL.metadata` gives `read` and the multiple vocabulary operators, such as
|
|
133
|
+
`cpt_or_hcpcs`, a `long_name`. Before, it was empty. `read` has the long name of the Read
|
|
134
|
+
vocabulary in the OHDSI vocabulary table, "NHS UK Read Codes Version 2 (HSCIC)". A multiple
|
|
135
|
+
vocabulary operator names its vocabularies, for example "CPT4, HCPCS and CPT4_HCPCS". The
|
|
136
|
+
metadata of `read` also has `predominant_domains`, `["condition_occurrence"]`. Before, it was
|
|
137
|
+
empty.
|
|
138
|
+
|
|
139
|
+
### Removed
|
|
140
|
+
|
|
141
|
+
- The `hidden` column of `config/vocabularies.csv`, with `Vocabularies::Entry#hidden?` and
|
|
142
|
+
`Vocabularies::Entry#visible?`. No code used them. The column did not hide any operator, and
|
|
143
|
+
it is not connected to the new `hidden` mark of an operator.
|
|
144
|
+
- **Breaking:** `Vocabularies::Entry#vocabulary_long_name`.
|
|
145
|
+
`Vocabularies::Entry#vocabulary_full_name` replaces it and reads the `vocabulary_full_name`
|
|
146
|
+
column. An `Entry` built from a hash takes the key `vocabulary_full_name`, not
|
|
147
|
+
`vocabulary_long_name`. `Entry#long_name` stays.
|
|
148
|
+
|
|
149
|
+
### Fixed
|
|
150
|
+
|
|
151
|
+
- `min_upstreams` and `max_upstreams` in `ConceptQL.metadata` say how many positional
|
|
152
|
+
upstreams pass validation (99 means no limit). Before, `min_upstreams` always equalled
|
|
153
|
+
`max_upstreams`. `union` and `co_reported` served 99/99 and now serve 1/99. `first`, `last`
|
|
154
|
+
and `occurrence` served 99/99 and now serve 1/1. `person` and `death` served 1/1 and now
|
|
155
|
+
serve 0/1. `trim_date_end` and `trim_date_start` served 1/1 and now serve 0/0.
|
|
156
|
+
|
|
157
|
+
- The `long_name` in a vocabulary operator's metadata is the vocabulary's full name, read from
|
|
158
|
+
the `vocabulary_full_name` column of `config/vocabularies.csv` and the lexicons. Before, it
|
|
159
|
+
fell back to the short name (`atc` served "WHO ATC", not "WHO Anatomic Therapeutic Chemical
|
|
160
|
+
Classification") or was nil. The `short_name` does not change.
|
|
161
|
+
|
|
162
|
+
- `race`: an Unknown argument selected no patients. It now selects the patients with no race or
|
|
163
|
+
race concept ID 0. A race concept ID argument now also selects the more detailed races of
|
|
164
|
+
`config/race.yml`, as a race name does. Before, that was missed, which showed only with the
|
|
165
|
+
GDM vocabularies.
|
|
166
|
+
|
|
167
|
+
- `ethnicity`: Unknown now also selects the patients with no ethnicity, not only ethnicity
|
|
168
|
+
concept ID 0.
|
|
169
|
+
|
|
170
|
+
- Operator help texts that disagreed with the code: the input hints of `within` and `at_least`
|
|
171
|
+
(the temporal operators and `occurrence`), of `time_window`'s `start` and `end`, and of
|
|
172
|
+
`episode`'s `gap_of`; the old `desc` of the `TrimDate` base class; and the summary `desc` of
|
|
173
|
+
the vocabulary operators.
|
|
174
|
+
|
|
175
|
+
- A vocabulary whose domain is blank has no domain, so its operators select
|
|
176
|
+
`condition_occurrence` records. The GDM vocabulary table (`gdm_vocabs.vocabularies` in the
|
|
177
|
+
test data) gives all but one of its vocabularies the domain `''`, and the last one a NULL
|
|
178
|
+
domain. Before, the operators of the `''` vocabularies, such as
|
|
179
|
+
`cms_place_of_service`, got `criterion_domain` `''`, their predominant domain in the
|
|
180
|
+
metadata was `''`, and their annotation counts were keyed by `''`. The OHDSI vocabulary
|
|
181
|
+
tables give no domain, so they were not affected.
|
|
182
|
+
|
|
7
183
|
## [0.6.0] - 2026-11-02
|
|
8
184
|
|
|
9
185
|
### Added
|
data/README.md
CHANGED
|
@@ -6,7 +6,9 @@ This gem interprets the ConceptQL language and translates it into SQL queries co
|
|
|
6
6
|
|
|
7
7
|
## Further Reading
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
The ConceptQL specification is [docs/spec/README.md](docs/spec/README.md).
|
|
10
|
+
|
|
11
|
+
`ConceptQL::DiagramRenderer` draws a statement's diagram as an SVG or a PNG. See [docs/diagram_renderer.md](docs/diagram_renderer.md).
|
|
10
12
|
|
|
11
13
|
## Motivation for ConceptQL
|
|
12
14
|
|
|
@@ -31,7 +33,7 @@ For instance, using ConceptQL we can take a statement that looks like this:
|
|
|
31
33
|
|
|
32
34
|
And generate a diagram that looks like this:
|
|
33
35
|
|
|
34
|
-

|
|
35
37
|
|
|
36
38
|
And generate SQL that looks like this:
|
|
37
39
|
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Hide the overflow in IE.
|
|
5
|
+
*/
|
|
6
|
+
/* line 240, frontend/app/styles/mvcss/modules/../_01_reset.scss */
|
|
7
|
+
svg:not(:root) {
|
|
8
|
+
overflow: hidden;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/* line 141, frontend/app/styles/mvcss/modules/../_04_base.sass */
|
|
12
|
+
svg {
|
|
13
|
+
display: block;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/* line 17, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
17
|
+
.vis {
|
|
18
|
+
bottom: 0;
|
|
19
|
+
left: 0;
|
|
20
|
+
position: absolute;
|
|
21
|
+
right: 0;
|
|
22
|
+
top: 0;
|
|
23
|
+
animation: vis 0.5s cubic-bezier(0.215, 0.61, 0.355, 1) 0.2s backwards;
|
|
24
|
+
background: #f4f2f3;
|
|
25
|
+
cursor: move;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* line 30, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
29
|
+
.vis.is-new .vis-link-new,
|
|
30
|
+
.vis.is-new .vis-link-text {
|
|
31
|
+
display: none;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@keyframes vis {
|
|
35
|
+
from {
|
|
36
|
+
opacity: 0;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* line 52, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
41
|
+
.vis-connect {
|
|
42
|
+
fill: none;
|
|
43
|
+
opacity: 0;
|
|
44
|
+
pointer-events: none;
|
|
45
|
+
stroke: rgba(96, 82, 93, 0.5);
|
|
46
|
+
stroke-linecap: round;
|
|
47
|
+
stroke-width: 2px;
|
|
48
|
+
transition: all 1s cubic-bezier(0.215, 0.61, 0.355, 1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* line 63, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
52
|
+
.vis-connect.is-visible {
|
|
53
|
+
opacity: 1;
|
|
54
|
+
transform: none;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* line 87, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
58
|
+
.vis-link-new {
|
|
59
|
+
cursor: pointer;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* line 91, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
63
|
+
.vis-link-new:hover circle, .vis-link-new:focus circle {
|
|
64
|
+
fill: #60525d;
|
|
65
|
+
stroke: #60525d;
|
|
66
|
+
stroke-width: 4px;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* line 95, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
70
|
+
.vis-link-new:hover use, .vis-link-new:focus use {
|
|
71
|
+
color: white;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* line 97, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
75
|
+
.vis-link-new circle {
|
|
76
|
+
fill: #f4f2f3;
|
|
77
|
+
stroke: rgba(64, 55, 63, 0.2);
|
|
78
|
+
stroke-width: 2px;
|
|
79
|
+
transition: fill 0.1s cubic-bezier(0.215, 0.61, 0.355, 1), stroke 0.4s cubic-bezier(0.215, 0.61, 0.355, 1), stroke-width 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* line 102, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
83
|
+
.vis-link-new use {
|
|
84
|
+
color: rgba(64, 55, 63, 0.2);
|
|
85
|
+
transition: color 0.1s cubic-bezier(0.215, 0.61, 0.355, 1);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* line 106, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
89
|
+
.vis-link-new.is-selectable {
|
|
90
|
+
display: block !important;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* line 110, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
94
|
+
.vis-link-new.is-selectable:hover circle, .vis-link-new.is-selectable:focus circle {
|
|
95
|
+
fill: #7193cd;
|
|
96
|
+
stroke: #7193cd;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* line 113, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
100
|
+
.vis-link-new.is-selectable circle {
|
|
101
|
+
animation: vis-link-new 1s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
|
|
102
|
+
fill: rgba(113, 147, 205, 0.8);
|
|
103
|
+
stroke: #7193cd;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/* line 117, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
107
|
+
.vis-link-new.is-selectable use {
|
|
108
|
+
display: none;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
@keyframes vis-link-new {
|
|
112
|
+
to {
|
|
113
|
+
stroke: rgba(113, 147, 205, 0);
|
|
114
|
+
stroke-width: 8px;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* line 127, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
119
|
+
.vis-link-path-source {
|
|
120
|
+
fill: none;
|
|
121
|
+
stroke-linecap: round;
|
|
122
|
+
stroke-width: 5.5px;
|
|
123
|
+
transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/* line 133, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
127
|
+
.vis-link-path-target {
|
|
128
|
+
fill: none;
|
|
129
|
+
stroke-linecap: round;
|
|
130
|
+
stroke: #959294;
|
|
131
|
+
stroke-width: 5px;
|
|
132
|
+
transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* line 140, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
136
|
+
.vis-link-path-target[data-color="condition_occurrence"] {
|
|
137
|
+
stroke: #d6758a;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/* line 142, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
141
|
+
.vis-link-path-target[data-color="death"] {
|
|
142
|
+
stroke: #a7736f;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/* line 144, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
146
|
+
.vis-link-path-target[data-color="drug_exposure"] {
|
|
147
|
+
stroke: #cf92d2;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* line 146, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
151
|
+
.vis-link-path-target[data-color="observation_period"] {
|
|
152
|
+
stroke: #a6dddc;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/* line 148, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
156
|
+
.vis-link-path-target[data-color="person"] {
|
|
157
|
+
stroke: #a9c9e7;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/* line 150, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
161
|
+
.vis-link-path-target[data-color="placeholder"] {
|
|
162
|
+
stroke: #f6f3f5;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* line 152, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
166
|
+
.vis-link-path-target[data-color="procedure_occurrence"] {
|
|
167
|
+
stroke: #a7e2ac;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* line 154, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
171
|
+
.vis-link-path-target[data-color="visit_occurrence"] {
|
|
172
|
+
stroke: #e8d4b3;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* line 159, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
176
|
+
.vis-link-text {
|
|
177
|
+
dominant-baseline: middle;
|
|
178
|
+
font-size: 86.7%;
|
|
179
|
+
font-weight: bold;
|
|
180
|
+
user-select: none;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* line 169, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
184
|
+
.vis-node {
|
|
185
|
+
cursor: pointer;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* line 174, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
189
|
+
.vis-node:hover .vis-node-warning circle, .vis-node:hover .vis-node-error circle, .vis-node:focus .vis-node-warning circle, .vis-node:focus .vis-node-error circle {
|
|
190
|
+
fill: #833341;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/* line 178, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
194
|
+
.vis-node:hover .vis-node-point, .vis-node:focus .vis-node-point {
|
|
195
|
+
color: #60525d !important;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* line 184, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
199
|
+
.vis-node.is-active .vis-node-description-heading {
|
|
200
|
+
fill: #5f6493 !important;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/* line 188, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
204
|
+
.vis-node.is-warning .vis-node-warning {
|
|
205
|
+
opacity: 1;
|
|
206
|
+
transform: translate(6px, 34px);
|
|
207
|
+
visibility: visible;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/* line 194, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
211
|
+
.vis-node.is-error .vis-node-error {
|
|
212
|
+
opacity: 1;
|
|
213
|
+
transform: translate(6px, 34px);
|
|
214
|
+
visibility: visible;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/* line 203, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
218
|
+
.vis-node-description {
|
|
219
|
+
transition: opacity 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
|
|
220
|
+
user-select: none;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/* line 206, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
224
|
+
.vis-node-description tspan {
|
|
225
|
+
dominant-baseline: middle;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/* line 209, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
229
|
+
.vis-node-description-heading {
|
|
230
|
+
font-weight: bold;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/* line 212, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
234
|
+
.vis-node-description-value {
|
|
235
|
+
fill: #817980;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/* line 216, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
239
|
+
.is-label .vis-node-description-heading + .vis-node-description-value {
|
|
240
|
+
fill: #afa8ad;
|
|
241
|
+
font-style: italic;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/* line 222, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
245
|
+
.vis-node-warning, .vis-node-error {
|
|
246
|
+
color: white;
|
|
247
|
+
opacity: 0;
|
|
248
|
+
transform: scale(0.0001) translate(6px, 34px);
|
|
249
|
+
transform-origin: 6px 34px;
|
|
250
|
+
transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
|
|
251
|
+
visibility: hidden;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/* line 229, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
255
|
+
.vis-node-warning circle, .vis-node-error circle {
|
|
256
|
+
fill: #262125;
|
|
257
|
+
stroke: #f4f2f3;
|
|
258
|
+
stroke-width: 3px;
|
|
259
|
+
transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/* line 237, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
263
|
+
.vis-node-icon {
|
|
264
|
+
color: white;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/* line 242, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
268
|
+
.vis-node-label {
|
|
269
|
+
color: #afa8ad;
|
|
270
|
+
opacity: 0;
|
|
271
|
+
transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
|
|
272
|
+
visibility: hidden;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/* line 249, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
276
|
+
.is-label .vis-node-label {
|
|
277
|
+
opacity: 1;
|
|
278
|
+
visibility: visible;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/* line 255, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
282
|
+
.vis-node-point {
|
|
283
|
+
color: #959294;
|
|
284
|
+
transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/* line 259, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
288
|
+
.vis-node-point[data-color="condition_occurrence"] {
|
|
289
|
+
color: #ad4a5b;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/* line 261, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
293
|
+
.vis-node-point[data-color="death"] {
|
|
294
|
+
color: #704a4a;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/* line 263, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
298
|
+
.vis-node-point[data-color="drug_exposure"] {
|
|
299
|
+
color: #9f57a5;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/* line 265, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
303
|
+
.vis-node-point[data-color="observation_period"] {
|
|
304
|
+
color: #6fbbba;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/* line 267, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
308
|
+
.vis-node-point[data-color="person"] {
|
|
309
|
+
color: #7193cd;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/* line 269, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
313
|
+
.vis-node-point[data-color="placeholder"] {
|
|
314
|
+
color: #f6f3f5;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/* line 271, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
318
|
+
.vis-node-point[data-color="procedure_occurrence"] {
|
|
319
|
+
color: #90d796;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/* line 273, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
323
|
+
.vis-node-point[data-color="visit_occurrence"] {
|
|
324
|
+
color: #d1a776;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/* line 276, frontend/app/styles/mvcss/modules/_vis.sass */
|
|
328
|
+
.vis-node-point-base {
|
|
329
|
+
stroke: #f4f2f3;
|
|
330
|
+
stroke-width: 3px;
|
|
331
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright 2011 The Roboto Project Authors (https://github.com/googlefonts/roboto-classic)
|
|
2
|
+
|
|
3
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
4
|
+
This license is copied below, and is also available with a FAQ at:
|
|
5
|
+
https://openfontlicense.org
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
-----------------------------------------------------------
|
|
9
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
10
|
+
-----------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
PREAMBLE
|
|
13
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
14
|
+
development of collaborative font projects, to support the font creation
|
|
15
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
16
|
+
open framework in which fonts may be shared and improved in partnership
|
|
17
|
+
with others.
|
|
18
|
+
|
|
19
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
20
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
21
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
22
|
+
redistributed and/or sold with any software provided that any reserved
|
|
23
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
24
|
+
however, cannot be released under any other type of license. The
|
|
25
|
+
requirement for fonts to remain under this license does not apply
|
|
26
|
+
to any document created using the fonts or their derivatives.
|
|
27
|
+
|
|
28
|
+
DEFINITIONS
|
|
29
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
30
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
31
|
+
include source files, build scripts and documentation.
|
|
32
|
+
|
|
33
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
34
|
+
copyright statement(s).
|
|
35
|
+
|
|
36
|
+
"Original Version" refers to the collection of Font Software components as
|
|
37
|
+
distributed by the Copyright Holder(s).
|
|
38
|
+
|
|
39
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
40
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
41
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
42
|
+
new environment.
|
|
43
|
+
|
|
44
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
45
|
+
writer or other person who contributed to the Font Software.
|
|
46
|
+
|
|
47
|
+
PERMISSION & CONDITIONS
|
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
49
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
50
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
51
|
+
Software, subject to the following conditions:
|
|
52
|
+
|
|
53
|
+
1) Neither the Font Software nor any of its individual components,
|
|
54
|
+
in Original or Modified Versions, may be sold by itself.
|
|
55
|
+
|
|
56
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
57
|
+
redistributed and/or sold with any software, provided that each copy
|
|
58
|
+
contains the above copyright notice and this license. These can be
|
|
59
|
+
included either as stand-alone text files, human-readable headers or
|
|
60
|
+
in the appropriate machine-readable metadata fields within text or
|
|
61
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
62
|
+
|
|
63
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
64
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
65
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
66
|
+
presented to the users.
|
|
67
|
+
|
|
68
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
69
|
+
Software shall not be used to promote, endorse or advertise any
|
|
70
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
71
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
72
|
+
permission.
|
|
73
|
+
|
|
74
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
75
|
+
must be distributed entirely under this license, and must not be
|
|
76
|
+
distributed under any other license. The requirement for fonts to
|
|
77
|
+
remain under this license does not apply to any document created
|
|
78
|
+
using the Font Software.
|
|
79
|
+
|
|
80
|
+
TERMINATION
|
|
81
|
+
This license becomes null and void if any of the above conditions are
|
|
82
|
+
not met.
|
|
83
|
+
|
|
84
|
+
DISCLAIMER
|
|
85
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
88
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
89
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
90
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
91
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
92
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
93
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|