edoxen 0.5.0 → 0.7.2
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/CLAUDE.md +10 -6
- data/Gemfile +4 -0
- data/README.adoc +12 -8
- data/TODO.meeting-agenda/02-lutaml-canonical.md +1 -1
- data/TODO.meeting-agenda/09-verify-and-release.md +3 -3
- data/TODO.meeting-agenda/README.md +2 -2
- data/edoxen.gemspec +1 -0
- data/lib/edoxen/attendance.rb +23 -0
- data/lib/edoxen/cli.rb +18 -0
- data/lib/edoxen/enums.rb +7 -0
- data/lib/edoxen/link_checker.rb +85 -0
- data/lib/edoxen/meeting.rb +14 -0
- data/lib/edoxen/minutes.rb +31 -0
- data/lib/edoxen/minutes_section.rb +27 -0
- data/lib/edoxen/reference_data.rb +95 -0
- data/lib/edoxen/resolution_metadata.rb +8 -0
- data/lib/edoxen/schedule_item.rb +16 -5
- data/lib/edoxen/schedule_item_localization.rb +21 -0
- data/lib/edoxen/version.rb +1 -1
- data/lib/edoxen/vote_record.rb +25 -0
- data/lib/edoxen.rb +7 -0
- data/schema/edoxen.yaml +4 -3
- data/schema/meeting.yaml +125 -3
- metadata +23 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 69a86986a86602665699b5598622d32a63658c302737587f68b7a9b095a471e1
|
|
4
|
+
data.tar.gz: 1201e014ac06c2e4accb00dfd00660f577f6f6464f5d7990553714b796af8314
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7ec73b629af4dd2997fea614665347177f273569349d0221e414f9dc9b2dbb8f083b3d964675286bb9a76d449a5a4c7c2cf2981db028ebf5f0d2e54249abb77d
|
|
7
|
+
data.tar.gz: 52534618f6468c4da8effd9bcb23e978487e1857da1a9832fa8d1ed665e72324a13397657b0cb8f6c828be4ef45e9d669781a208b7135c09e97a1b833cc6c69e
|
data/CLAUDE.md
CHANGED
|
@@ -4,15 +4,19 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|
|
4
4
|
|
|
5
5
|
## What this gem is
|
|
6
6
|
|
|
7
|
-
`edoxen` is an information model for formal
|
|
8
|
-
|
|
7
|
+
`edoxen` is an information model for formal proceedings — meetings,
|
|
8
|
+
agendas, minutes, attendance, votes, and the resolutions adopted by
|
|
9
|
+
standards bodies (ISO/TC 154, CIPM, OIML, etc.). It provides:
|
|
9
10
|
|
|
10
11
|
- A set of `Lutaml::Model::Serializable` subclasses that mirror the canonical
|
|
11
12
|
LutaML UML model in `../edoxen-model/models/*.lutaml`.
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
- Two JSON-Schemas — `schema/edoxen.yaml` for `ResolutionCollection`
|
|
14
|
+
and `schema/meeting.yaml` for `Meeting` / `MeetingCollection` — used
|
|
15
|
+
to validate real-world YAML files via `SchemaValidator`
|
|
16
|
+
(`json_schemer`).
|
|
17
|
+
- A Thor CLI that wraps both schemas and both model parsers:
|
|
18
|
+
`edoxen validate` / `edoxen normalize` for resolutions;
|
|
19
|
+
`edoxen validate-meetings` / `edoxen normalize-meetings` for meetings.
|
|
16
20
|
|
|
17
21
|
## Architecture
|
|
18
22
|
|
data/Gemfile
CHANGED
|
@@ -5,6 +5,10 @@ source "https://rubygems.org"
|
|
|
5
5
|
# Specify your gem's dependencies in edoxen.gemspec
|
|
6
6
|
gemspec
|
|
7
7
|
|
|
8
|
+
# Pre-release sources. Move to RubyGems once published; the gemspec
|
|
9
|
+
# dep stays as `add_dependency "unlocode", "~> 0.1"` either way.
|
|
10
|
+
gem "unlocodes", github: "metanorma/unlocode"
|
|
11
|
+
|
|
8
12
|
gem "rake"
|
|
9
13
|
gem "rspec"
|
|
10
14
|
gem "rubocop"
|
data/README.adoc
CHANGED
|
@@ -1,26 +1,30 @@
|
|
|
1
1
|
= Edoxen
|
|
2
2
|
|
|
3
|
-
https://github.com/
|
|
4
|
-
image:https://img.shields.io/github/license/
|
|
5
|
-
image:https://img.shields.io/github/actions/workflow/status/
|
|
3
|
+
https://github.com/edoxen/edoxen[image:https://img.shields.io/github/stars/edoxen/edoxen.svg?style=social[GitHub Stars]]
|
|
4
|
+
image:https://img.shields.io/github/license/edoxen/edoxen.svg[License]
|
|
5
|
+
image:https://img.shields.io/github/actions/workflow/status/edoxen/edoxen/test.yml?branch=main[Build Status]
|
|
6
6
|
image:https://img.shields.io/gem/v/edoxen.svg[RubyGems Version]
|
|
7
7
|
|
|
8
8
|
== Purpose
|
|
9
9
|
|
|
10
10
|
Edoxen is a Ruby library for the canonical Edoxen information model of
|
|
11
|
-
formal
|
|
11
|
+
formal proceedings — meetings, agendas, minutes, attendance, votes,
|
|
12
|
+
and the resolutions adopted by standards bodies and governance
|
|
13
|
+
organisations. It is built on top of the
|
|
12
14
|
https://github.com/lutaml/lutaml[ lutaml-model] serialization framework.
|
|
13
15
|
|
|
14
16
|
The information model is defined in
|
|
15
|
-
https://github.com/
|
|
17
|
+
https://github.com/edoxen/edoxen-model/tree/main/models[ LutaML UML
|
|
16
18
|
files] (one `.lutaml` per concept). This gem mirrors that model exactly —
|
|
17
19
|
attribute declarations, enum values, and field shapes — so that anything
|
|
18
20
|
you can express in LutaML you can also construct, serialize, and validate
|
|
19
21
|
in Ruby.
|
|
20
22
|
|
|
21
23
|
The intended users are standards organizations and governance bodies that
|
|
22
|
-
need to publish structured records of formal
|
|
23
|
-
|
|
24
|
+
need to publish structured records of formal proceedings — the full
|
|
25
|
+
lifecycle from draft agenda through adopted resolution, in any ISO 639-3
|
|
26
|
+
language. Real-world samples (ISO/TC 154, CIPM, OIML CIML) ship in
|
|
27
|
+
`spec/fixtures/`.
|
|
24
28
|
|
|
25
29
|
== Installation
|
|
26
30
|
|
|
@@ -228,7 +232,7 @@ MeetingCollection
|
|
|
228
232
|
├── date_range: DateRange {start, end}
|
|
229
233
|
├── committee, committee_group
|
|
230
234
|
├── venues: Location[] (multi-venue supported)
|
|
231
|
-
├── general_area, city (
|
|
235
|
+
├── general_area, city (UN/LOCODE, e.g. FRPAR), country_code (ISO 3166-1), virtual
|
|
232
236
|
├── chair, secretary: Person
|
|
233
237
|
├── host, hosts: HostRef[] (typed: national_body/liaison/associate/organizer)
|
|
234
238
|
├── source_urls: SourceUrl[] (with `kind` discriminator)
|
|
@@ -58,4 +58,4 @@ LUTAML notation, wire names are snake_case per D7.)
|
|
|
58
58
|
- [ ] `README.adoc` updated: new "Meeting model" section, file index
|
|
59
59
|
extended.
|
|
60
60
|
- [ ] Old `meeting-model.adoc` renamed to `.deprecated`.
|
|
61
|
-
- [ ] Commit + PR to `
|
|
61
|
+
- [ ] Commit + PR to `edoxen/edoxen-model`.
|
|
@@ -11,8 +11,8 @@ Land everything via PRs. Verify GHA passes. Merge. Bump edoxen minor
|
|
|
11
11
|
|
|
12
12
|
| Repo | Branch | PRs against |
|
|
13
13
|
|---|---|---|
|
|
14
|
-
| `
|
|
15
|
-
| `
|
|
14
|
+
| `edoxen/edoxen-model` | `feat/meeting-agenda-model` | main |
|
|
15
|
+
| `edoxen/edoxen` | `feat/meeting-agenda-model` | main |
|
|
16
16
|
|
|
17
17
|
Order: edoxen-model first (canonical), then edoxen (mirror).
|
|
18
18
|
|
|
@@ -31,7 +31,7 @@ Per branch, before pushing:
|
|
|
31
31
|
## Post-merge
|
|
32
32
|
|
|
33
33
|
- [ ] Trigger `gh workflow run release.yml --ref main -f next_version=minor`
|
|
34
|
-
on `
|
|
34
|
+
on `edoxen/edoxen`.
|
|
35
35
|
- [ ] Confirm new version appears on rubygems.org.
|
|
36
36
|
- [ ] Confirm tag `vX.Y.Z` pushed.
|
|
37
37
|
|
|
@@ -25,6 +25,6 @@ work only.
|
|
|
25
25
|
|
|
26
26
|
## Branches
|
|
27
27
|
|
|
28
|
-
- `
|
|
29
|
-
- `
|
|
28
|
+
- `edoxen/edoxen-model` ← `feat/meeting-agenda-model` (Phase 2)
|
|
29
|
+
- `edoxen/edoxen` ← `feat/meeting-agenda-model` (Phases 3–8)
|
|
30
30
|
- Phase 9 merges both, then releases `edoxen` as a minor bump.
|
data/edoxen.gemspec
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Edoxen
|
|
4
|
+
# One attendance record per person. Mirrors the ParticipationStatus
|
|
5
|
+
# enum from edoxen-model/models/participation_status.lutaml.
|
|
6
|
+
# Optional `affiliation` and `notes` fields let callers annotate
|
|
7
|
+
# proxy representatives and any meeting-specific details.
|
|
8
|
+
class Attendance < Lutaml::Model::Serializable
|
|
9
|
+
attribute :person, Person
|
|
10
|
+
attribute :status, :string, values: Enums::PARTICIPATION_STATUS
|
|
11
|
+
attribute :affiliation, :string
|
|
12
|
+
attribute :proxy_for, Person
|
|
13
|
+
attribute :notes, :string
|
|
14
|
+
|
|
15
|
+
key_value do
|
|
16
|
+
map "person", to: :person
|
|
17
|
+
map "status", to: :status
|
|
18
|
+
map "affiliation", to: :affiliation
|
|
19
|
+
map "proxy_for", to: :proxy_for
|
|
20
|
+
map "notes", to: :notes
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
data/lib/edoxen/cli.rb
CHANGED
|
@@ -166,6 +166,24 @@ module Edoxen
|
|
|
166
166
|
end
|
|
167
167
|
end
|
|
168
168
|
|
|
169
|
+
desc "unlocode CODE", "Resolve a UN/LOCODE via the canonical registry."
|
|
170
|
+
def unlocode(code)
|
|
171
|
+
entry = Edoxen::ReferenceData.find_unlocode(code)
|
|
172
|
+
if entry.nil?
|
|
173
|
+
say "No entry for #{code.upcase} in the UN/LOCODE registry.", :red
|
|
174
|
+
exit 1
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
say "UN/LOCODE: #{entry.code}", :blue
|
|
178
|
+
say " Name: #{entry.name}"
|
|
179
|
+
say " Country: #{entry.country}"
|
|
180
|
+
say " Subdiv: #{entry.subdivision}" if entry.subdivision
|
|
181
|
+
coords = entry.coordinates
|
|
182
|
+
say " Coords: #{coords}" if coords
|
|
183
|
+
funcs = entry.functions.compact.map(&:to_s)
|
|
184
|
+
say " Functions: #{funcs.join(", ")}" unless funcs.empty?
|
|
185
|
+
end
|
|
186
|
+
|
|
169
187
|
private
|
|
170
188
|
|
|
171
189
|
def meeting_schema_path
|
data/lib/edoxen/enums.rb
CHANGED
|
@@ -63,5 +63,12 @@ module Edoxen
|
|
|
63
63
|
SOURCE_URL_KIND = %w[
|
|
64
64
|
agenda_pdf minutes_pdf resolutions_pdf report_pdf register_url landing_page
|
|
65
65
|
].freeze
|
|
66
|
+
|
|
67
|
+
# P2.6 / P2.7 — Attendance and Vote records.
|
|
68
|
+
PARTICIPATION_STATUS = %w[present absent apologies observer excused].freeze
|
|
69
|
+
|
|
70
|
+
VOTE_TYPE = %w[
|
|
71
|
+
affirmative negative abstain absent not_applicable
|
|
72
|
+
].freeze
|
|
66
73
|
end
|
|
67
74
|
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Edoxen
|
|
4
|
+
# Walks a directory tree of Meeting and ResolutionCollection YAML
|
|
5
|
+
# files and asserts that every cross-document URN link resolves.
|
|
6
|
+
#
|
|
7
|
+
# Invariants enforced:
|
|
8
|
+
#
|
|
9
|
+
# * Every Meeting#urn (if set) is referenced by exactly one
|
|
10
|
+
# ResolutionCollection#metadata.meeting_urn (if the collection
|
|
11
|
+
# exists in the scanned directory).
|
|
12
|
+
# * Every ResolutionCollection#metadata.meeting_urn (if set)
|
|
13
|
+
# resolves to a Meeting whose urn matches.
|
|
14
|
+
#
|
|
15
|
+
# Use from CLI / scripts via the public `check` class method. Returns
|
|
16
|
+
# an array of `LinkError` records (empty = ok).
|
|
17
|
+
#
|
|
18
|
+
# All file IO is read-only. No edits to the YAMLs.
|
|
19
|
+
class LinkChecker
|
|
20
|
+
LinkError = Struct.new(:file, :pointer, :urn, :kind) do
|
|
21
|
+
def message
|
|
22
|
+
"#{file}: #{pointer} references #{urn} (#{kind})"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Walk `dir` (recursive scan of *.yaml and *.yml), classify each
|
|
27
|
+
# file as Meeting or ResolutionCollection, and assert every
|
|
28
|
+
# cross-document URN resolves to a real record.
|
|
29
|
+
#
|
|
30
|
+
# @return [Array<LinkError>] empty when all links resolve.
|
|
31
|
+
def self.check(dir)
|
|
32
|
+
new(dir).check
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def initialize(dir)
|
|
36
|
+
@dir = dir
|
|
37
|
+
@meetings_by_urn = {} # urn → file
|
|
38
|
+
@collections_by_meeting_urn = {} # meeting_urn → file
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def check
|
|
42
|
+
require "yaml"
|
|
43
|
+
|
|
44
|
+
Dir.glob(File.join(@dir, "**", "*.{yaml,yml}")).sort.each do |file|
|
|
45
|
+
data = safe_load_yaml(file)
|
|
46
|
+
next unless data.is_a?(Hash)
|
|
47
|
+
|
|
48
|
+
if meeting_shape?(data)
|
|
49
|
+
urn = data["urn"]
|
|
50
|
+
@meetings_by_urn[urn] = file if urn
|
|
51
|
+
elsif collection_shape?(data)
|
|
52
|
+
meeting_urn = data.dig("metadata", "meeting_urn")
|
|
53
|
+
@collections_by_meeting_urn[meeting_urn] = file if meeting_urn
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
errors = []
|
|
58
|
+
|
|
59
|
+
# ResolutionCollection → Meeting
|
|
60
|
+
@collections_by_meeting_urn.each do |meeting_urn, file|
|
|
61
|
+
next if @meetings_by_urn.key?(meeting_urn)
|
|
62
|
+
|
|
63
|
+
errors << LinkError.new(file, "metadata.meeting_urn", meeting_urn, "no matching Meeting")
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
errors
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
def safe_load_yaml(file)
|
|
72
|
+
YAML.safe_load(File.read(file))
|
|
73
|
+
rescue Psych::SyntaxError, ArgumentError
|
|
74
|
+
nil
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def meeting_shape?(data)
|
|
78
|
+
data["identifier"].is_a?(Array) && data.key?("type")
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def collection_shape?(data)
|
|
82
|
+
data["resolutions"].is_a?(Array) || data["metadata"].is_a?(Hash)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
data/lib/edoxen/meeting.rb
CHANGED
|
@@ -42,6 +42,10 @@ module Edoxen
|
|
|
42
42
|
attribute :schedule, ScheduleItem, collection: true
|
|
43
43
|
attribute :deadlines, Deadline, collection: true
|
|
44
44
|
|
|
45
|
+
attribute :attendance, Attendance, collection: true
|
|
46
|
+
attribute :vote_records, VoteRecord, collection: true
|
|
47
|
+
attribute :minutes, Minutes, collection: true
|
|
48
|
+
|
|
45
49
|
attribute :localizations, MeetingLocalization, collection: true
|
|
46
50
|
attribute :relations, MeetingRelation, collection: true
|
|
47
51
|
attribute :resolution_refs, :string, collection: true
|
|
@@ -64,5 +68,15 @@ module Edoxen
|
|
|
64
68
|
def find_agenda_item(label)
|
|
65
69
|
agenda&.find_item(label)
|
|
66
70
|
end
|
|
71
|
+
|
|
72
|
+
# Resolve the meeting's UN/LOCODE via the canonical `unlocode` gem
|
|
73
|
+
# registry. Returns an `Unlocodes::Entry` (with `#name`, `#country`,
|
|
74
|
+
# `#coordinates`, `#iata`, `#functions`, etc.) or nil when the
|
|
75
|
+
# city field is empty / not in the registry.
|
|
76
|
+
def city_entry
|
|
77
|
+
return nil if city.nil? || city.to_s.empty?
|
|
78
|
+
|
|
79
|
+
Edoxen::ReferenceData.find_unlocode(city)
|
|
80
|
+
end
|
|
67
81
|
end
|
|
68
82
|
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Edoxen
|
|
4
|
+
# The narrative record of a Meeting — what was said, by whom, in
|
|
5
|
+
# what order, with what outcome. Mirrors
|
|
6
|
+
# edoxen-model/models/minutes.lutaml (P2.8 from
|
|
7
|
+
# TODO.meeting-agenda/10-future-enhancements.md).
|
|
8
|
+
#
|
|
9
|
+
# Distinct from Agenda (the business order drafted before the
|
|
10
|
+
# meeting) and from ResolutionCollection (the formal decisions
|
|
11
|
+
# adopted). The Minutes are the running record.
|
|
12
|
+
#
|
|
13
|
+
# Sections are typically keyed by agenda-item number so consumers
|
|
14
|
+
# can join Minutes ↔ AgendaItem ↔ Resolution by `number`/`label`.
|
|
15
|
+
class Minutes < Lutaml::Model::Serializable
|
|
16
|
+
attribute :identifier, StructuredIdentifier, collection: true
|
|
17
|
+
attribute :urn, :string
|
|
18
|
+
attribute :language_code, :string
|
|
19
|
+
attribute :script, :string
|
|
20
|
+
attribute :source_doc, :string
|
|
21
|
+
attribute :source_pages, :string
|
|
22
|
+
attribute :sections, MinutesSection, collection: true
|
|
23
|
+
|
|
24
|
+
def find_section(number)
|
|
25
|
+
return nil if number.nil?
|
|
26
|
+
|
|
27
|
+
target = number.to_s
|
|
28
|
+
sections&.find { |s| s.number.to_s == target }
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Edoxen
|
|
4
|
+
# One section of a Meeting's minutes — typically tied to an agenda
|
|
5
|
+
# item by its `number` field. Carries the narrative as Markdown
|
|
6
|
+
# (the format the GLM-OCR pipeline emits) plus optional page range
|
|
7
|
+
# for provenance back to the source PDF.
|
|
8
|
+
class MinutesSection < Lutaml::Model::Serializable
|
|
9
|
+
attribute :number, :string
|
|
10
|
+
attribute :title, :string
|
|
11
|
+
attribute :narrative, :string
|
|
12
|
+
attribute :page_start, :integer
|
|
13
|
+
attribute :page_end, :integer
|
|
14
|
+
attribute :references, Reference, collection: true
|
|
15
|
+
|
|
16
|
+
def in_language(code, fallback: false)
|
|
17
|
+
match = localizations&.find { |loc| loc.language_code == code.to_s }
|
|
18
|
+
return match if match
|
|
19
|
+
|
|
20
|
+
fallback ? localizations&.first : nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def primary_localization
|
|
24
|
+
in_language("eng", fallback: true)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Edoxen
|
|
4
|
+
# Built-in reference data for ISO codes used across the Edoxen model:
|
|
5
|
+
# ISO 3166-1 alpha-2 country codes, ISO 639-3 language codes, ISO
|
|
6
|
+
# 15924 script codes, and UN/LOCODEs.
|
|
7
|
+
#
|
|
8
|
+
# UN/LOCODE lookups delegate to the `unlocode` gem (the canonical
|
|
9
|
+
# Ruby registry of the UNECE UN/LOCODE dataset). The frozen
|
|
10
|
+
# ReferenceData::UNLOCODES list stays as a curated offline subset
|
|
11
|
+
# — used by specs and consumers that don't want to load the full
|
|
12
|
+
# ~100k-entry registry.
|
|
13
|
+
#
|
|
14
|
+
# Reference data sources:
|
|
15
|
+
# * https://www.iso.org/iso-3166-country-codes.html
|
|
16
|
+
# * https://iso639-3.sil.org/
|
|
17
|
+
# * https://unicode.org/iso15924/
|
|
18
|
+
# * https://unece.org/trade/cefact/unlocode-code-list-country-and-territory
|
|
19
|
+
#
|
|
20
|
+
# UN/LOCODE format: 2-letter ISO 3166-1 country code + 3-character
|
|
21
|
+
# location alphanumeric (e.g., FRPAR = Paris, France; HKHKG = Hong
|
|
22
|
+
# Kong; THCNM = Chiang Mai). UN-maintained, supersedes the
|
|
23
|
+
# airport-centric IATA city codes edoxen previously used.
|
|
24
|
+
module ReferenceData
|
|
25
|
+
# Hard require the unlocode gem. It's a declared runtime dep, so a
|
|
26
|
+
# clean install of edoxen brings it in. The bundled dataset ships
|
|
27
|
+
# 4 sample entries; full coverage requires `rake unlocodes:fetch`
|
|
28
|
+
# from the unlocode gem.
|
|
29
|
+
require "unlocodes"
|
|
30
|
+
|
|
31
|
+
# ISO 3166-1 alpha-2 — countries ISO/TC 154 / OIML / BIPM operate in.
|
|
32
|
+
# Two-letter uppercase.
|
|
33
|
+
COUNTRY_CODES = %w[
|
|
34
|
+
AE AF AR AT AU BE BG BR BY CA CH CL CN CO CY CZ DE DK EE ES FI FR
|
|
35
|
+
GB GR HK HR HU ID IE IL IN IS IT JP KE KR LK LT LU LV MT MX MY NL NO PH
|
|
36
|
+
NZ PL PT RO RS RU SA SE SG SI SK TH TN TR TW UA US VN ZA
|
|
37
|
+
].freeze
|
|
38
|
+
|
|
39
|
+
# ISO 639-3 — languages actually used in the edoxen fixtures
|
|
40
|
+
# (eng + fra in OIML, plus the ISO official languages).
|
|
41
|
+
# Three-letter lowercase.
|
|
42
|
+
LANGUAGE_CODES = %w[
|
|
43
|
+
ara chi deu eng fra jpn rus spa zho
|
|
44
|
+
].freeze
|
|
45
|
+
|
|
46
|
+
# ISO 15924 — scripts. Latn + Cyrl + Hant + Hans cover every script
|
|
47
|
+
# ISO and OIML resolutions are written in.
|
|
48
|
+
SCRIPT_CODES = %w[
|
|
49
|
+
Arab Cyrl Hans Hant Hang Hebr Jpan Kore Latn
|
|
50
|
+
].freeze
|
|
51
|
+
|
|
52
|
+
# Curated offline subset of UN/LOCODEs — the cities ISO/TC 154 and
|
|
53
|
+
# OIML actually meet in plus the major transit hubs. Used by specs
|
|
54
|
+
# and consumers that don't want to load the full registry. For
|
|
55
|
+
# arbitrary lookups, use {find_unlocode}.
|
|
56
|
+
UNLOCODES = %w[
|
|
57
|
+
AUMEL ATVIE BEBRU BGSOF BRBSB CHGVA CNCAN CNHKG CNSHA CNXSZ COCTG
|
|
58
|
+
CYLCA CZPRG DEBER DEHAM DEFRA DKCPH ESMAD FIHEL FRARC FRLYS FRMRS
|
|
59
|
+
FRPAR GBLON HKHKG HUBUD IDJKT IEDUB IEORK ILTLV INDEL ISREY ITROM
|
|
60
|
+
JPTYO KEMBA KRSEL LKCMB LVRIX LULUX MYKUL NLRTM NOOSL NZAKL PHMNL
|
|
61
|
+
PLWAW PTLIS ROBUH RSBEG SESTO SGSIN SKBTS THBKK THCNM TRIST TWTPE
|
|
62
|
+
UAIEV USMIA USNYC USORL VNSGN ZACPT
|
|
63
|
+
].freeze
|
|
64
|
+
|
|
65
|
+
# @deprecated Use {UNLOCODES}. Retained for one release to ease
|
|
66
|
+
# migration; will be removed in the next minor.
|
|
67
|
+
CITY_CODES = UNLOCODES
|
|
68
|
+
|
|
69
|
+
class << self
|
|
70
|
+
# Look up a UN/LOCODE entry via the canonical `unlocode` gem.
|
|
71
|
+
# Returns an `Unlocodes::Entry` (with `#name`, `#country`,
|
|
72
|
+
# `#coordinates`, `#iata`, `#functions`, etc.) or nil when the
|
|
73
|
+
# code is not in the registry.
|
|
74
|
+
#
|
|
75
|
+
# Requires the full UN/LOCODE dataset to be loaded. The gem
|
|
76
|
+
# ships a 4-entry sample by default; run `rake unlocodes:fetch`
|
|
77
|
+
# from the unlocode gem to populate the full ~100k-entry
|
|
78
|
+
# registry.
|
|
79
|
+
#
|
|
80
|
+
# @param code [String, #to_s] 5-character UN/LOCODE
|
|
81
|
+
# @return [Unlocodes::Entry, nil]
|
|
82
|
+
def find_unlocode(code)
|
|
83
|
+
Unlocodes.find(code.to_s.upcase)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# True when the code resolves to a real UN/LOCODE entry via the
|
|
87
|
+
# canonical registry. Use this when validating user-supplied
|
|
88
|
+
# city codes; use the schema's pattern check for cheap shape
|
|
89
|
+
# validation.
|
|
90
|
+
def unlocode_exists?(code)
|
|
91
|
+
!find_unlocode(code).nil?
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -18,5 +18,13 @@ module Edoxen
|
|
|
18
18
|
# collections without a parent meeting (e.g., ad-hoc resolution
|
|
19
19
|
# sets) simply omit it.
|
|
20
20
|
attribute :meeting_urn, :string
|
|
21
|
+
|
|
22
|
+
# Resolve the collection's host-city UN/LOCODE via the canonical
|
|
23
|
+
# `unlocode` gem registry. Returns an `Unlocodes::Entry` or nil.
|
|
24
|
+
def city_entry
|
|
25
|
+
return nil if city.nil? || city.to_s.empty?
|
|
26
|
+
|
|
27
|
+
Edoxen::ReferenceData.find_unlocode(city)
|
|
28
|
+
end
|
|
21
29
|
end
|
|
22
30
|
end
|
data/lib/edoxen/schedule_item.rb
CHANGED
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Edoxen
|
|
4
|
-
# One entry in
|
|
5
|
-
# room) are language-agnostic;
|
|
6
|
-
# description)
|
|
7
|
-
#
|
|
8
|
-
# localization.
|
|
4
|
+
# One entry in the meeting timetable. Structural fields (date, time,
|
|
5
|
+
# room) are language-agnostic; per-language content (event name,
|
|
6
|
+
# description) lives in `localizations[]`. Mirrors the glossarist
|
|
7
|
+
# LocalizedConcept pattern.
|
|
9
8
|
class ScheduleItem < Lutaml::Model::Serializable
|
|
10
9
|
attribute :date, :date
|
|
11
10
|
attribute :time, :string
|
|
12
11
|
attribute :event, :string
|
|
13
12
|
attribute :description, :string
|
|
14
13
|
attribute :room, :string
|
|
14
|
+
attribute :localizations, ScheduleItemLocalization, collection: true
|
|
15
|
+
|
|
16
|
+
def in_language(code, fallback: false)
|
|
17
|
+
match = localizations&.find { |loc| loc.language_code == code.to_s }
|
|
18
|
+
return match if match
|
|
19
|
+
|
|
20
|
+
fallback ? localizations&.first : nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def primary_localization
|
|
24
|
+
in_language("eng", fallback: true)
|
|
25
|
+
end
|
|
15
26
|
end
|
|
16
27
|
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Edoxen
|
|
4
|
+
# Per-language content for a ScheduleItem. Mirrors the glossarist
|
|
5
|
+
# LocalizedConcept pattern: structural fields (date, time, room) live
|
|
6
|
+
# on the parent ScheduleItem; per-language content (event name,
|
|
7
|
+
# description) lives here.
|
|
8
|
+
class ScheduleItemLocalization < Lutaml::Model::Serializable
|
|
9
|
+
attribute :language_code, :string
|
|
10
|
+
attribute :script, :string
|
|
11
|
+
attribute :event, :string
|
|
12
|
+
attribute :description, :string
|
|
13
|
+
|
|
14
|
+
key_value do
|
|
15
|
+
map "language_code", to: :language_code
|
|
16
|
+
map "script", to: :script
|
|
17
|
+
map "event", to: :event
|
|
18
|
+
map "description", to: :description
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/lib/edoxen/version.rb
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Edoxen
|
|
4
|
+
# A single vote on a Resolution, recorded against the meeting at
|
|
5
|
+
# which the vote was taken. Mirrors
|
|
6
|
+
# edoxen-model/models/vote_record.lutaml. Each record carries the
|
|
7
|
+
# person, their affiliation (national body / liaison / committee),
|
|
8
|
+
# and the outcome (affirmative / negative / abstain / absent /
|
|
9
|
+
# not_applicable).
|
|
10
|
+
class VoteRecord < Lutaml::Model::Serializable
|
|
11
|
+
attribute :resolution_ref, :string
|
|
12
|
+
attribute :person, Person
|
|
13
|
+
attribute :affiliation, :string
|
|
14
|
+
attribute :vote, :string, values: Enums::VOTE_TYPE
|
|
15
|
+
attribute :notes, :string
|
|
16
|
+
|
|
17
|
+
key_value do
|
|
18
|
+
map "resolution_ref", to: :resolution_ref
|
|
19
|
+
map "person", to: :person
|
|
20
|
+
map "affiliation", to: :affiliation
|
|
21
|
+
map "vote", to: :vote
|
|
22
|
+
map "notes", to: :notes
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/edoxen.rb
CHANGED
|
@@ -23,6 +23,7 @@ module Edoxen
|
|
|
23
23
|
autoload :Error, "edoxen/error"
|
|
24
24
|
autoload :ValidationError, "edoxen/error"
|
|
25
25
|
autoload :Enums, "edoxen/enums"
|
|
26
|
+
autoload :ReferenceData, "edoxen/reference_data"
|
|
26
27
|
|
|
27
28
|
# Information-model classes (one per file, one concept per class).
|
|
28
29
|
# Names mirror ../edoxen-model/models/*.lutaml.
|
|
@@ -45,11 +46,16 @@ module Edoxen
|
|
|
45
46
|
autoload :Location, "edoxen/location"
|
|
46
47
|
autoload :Person, "edoxen/person"
|
|
47
48
|
autoload :HostRef, "edoxen/host_ref"
|
|
49
|
+
autoload :ScheduleItemLocalization, "edoxen/schedule_item_localization"
|
|
48
50
|
autoload :ScheduleItem, "edoxen/schedule_item"
|
|
49
51
|
autoload :Deadline, "edoxen/deadline"
|
|
50
52
|
autoload :Reference, "edoxen/reference"
|
|
51
53
|
autoload :AgendaItem, "edoxen/agenda_item"
|
|
52
54
|
autoload :Agenda, "edoxen/agenda"
|
|
55
|
+
autoload :Attendance, "edoxen/attendance"
|
|
56
|
+
autoload :VoteRecord, "edoxen/vote_record"
|
|
57
|
+
autoload :MinutesSection, "edoxen/minutes_section"
|
|
58
|
+
autoload :Minutes, "edoxen/minutes"
|
|
53
59
|
autoload :MeetingRelation, "edoxen/meeting_relation"
|
|
54
60
|
autoload :MeetingLocalization, "edoxen/meeting_localization"
|
|
55
61
|
autoload :Meeting, "edoxen/meeting"
|
|
@@ -58,5 +64,6 @@ module Edoxen
|
|
|
58
64
|
|
|
59
65
|
# Services.
|
|
60
66
|
autoload :SchemaValidator, "edoxen/schema_validator"
|
|
67
|
+
autoload :LinkChecker, "edoxen/link_checker"
|
|
61
68
|
autoload :Cli, "edoxen/cli"
|
|
62
69
|
end
|
data/schema/edoxen.yaml
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
$schema: "http://json-schema.org/draft-07/schema#"
|
|
3
|
-
$id: "https://github.com/
|
|
3
|
+
$id: "https://github.com/edoxen/edoxen/schema/edoxen.yaml"
|
|
4
4
|
title: "Edoxen Resolution Collection Schema"
|
|
5
5
|
description: |
|
|
6
6
|
Schema for validating Edoxen ResolutionCollection YAML files.
|
|
7
7
|
|
|
8
8
|
Mirrors the canonical LutaML information model in
|
|
9
|
-
https://github.com/
|
|
9
|
+
https://github.com/edoxen/edoxen-model/tree/main/models .
|
|
10
10
|
|
|
11
11
|
The enum constants declared under `$defs` (ActionType,
|
|
12
12
|
ConsiderationType, ApprovalType, ApprovalDegree, ResolutionType,
|
|
@@ -289,7 +289,8 @@ $defs:
|
|
|
289
289
|
description: "Canonical URLs to the source PDFs in each available language."
|
|
290
290
|
city:
|
|
291
291
|
type: string
|
|
292
|
-
|
|
292
|
+
pattern: "^[A-Z]{2}[A-Z0-9]{3}$"
|
|
293
|
+
description: "UN/LOCODE of the host city (5-char: 2-letter ISO 3166-1 country + 3-char location, e.g. FRPAR, CNSHA, HKHKG). Supersedes the IATA city code."
|
|
293
294
|
country_code:
|
|
294
295
|
type: string
|
|
295
296
|
description: "ISO 3166-1 alpha-2 country code (2-letter, e.g. DE, FR, JP) of the host country."
|
data/schema/meeting.yaml
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
$schema: "http://json-schema.org/draft-07/schema#"
|
|
3
|
-
$id: "https://github.com/
|
|
3
|
+
$id: "https://github.com/edoxen/edoxen/schema/meeting.yaml"
|
|
4
4
|
title: "Edoxen Meeting Schema"
|
|
5
5
|
description: |
|
|
6
6
|
Schema for validating Edoxen Meeting/Agenda YAML files.
|
|
7
7
|
|
|
8
8
|
Mirrors the canonical LutaML information model in
|
|
9
|
-
https://github.com/
|
|
9
|
+
https://github.com/edoxen/edoxen-model/tree/main/models (meeting*.lutaml,
|
|
10
10
|
agenda*.lutaml, etc.).
|
|
11
11
|
|
|
12
12
|
The root accepts either a single Meeting or a MeetingCollection.
|
|
@@ -104,6 +104,21 @@ $defs:
|
|
|
104
104
|
contact:
|
|
105
105
|
$ref: "#/$defs/Person"
|
|
106
106
|
|
|
107
|
+
ScheduleItemLocalization:
|
|
108
|
+
type: object
|
|
109
|
+
description: "Per-language content for a ScheduleItem."
|
|
110
|
+
additionalProperties: false
|
|
111
|
+
required: [language_code]
|
|
112
|
+
properties:
|
|
113
|
+
language_code:
|
|
114
|
+
type: string
|
|
115
|
+
pattern: "^[a-z]{3}$"
|
|
116
|
+
script:
|
|
117
|
+
type: string
|
|
118
|
+
pattern: "^[A-Z][a-z]{3}$"
|
|
119
|
+
event: { type: string }
|
|
120
|
+
description: { type: string }
|
|
121
|
+
|
|
107
122
|
ScheduleItem:
|
|
108
123
|
type: object
|
|
109
124
|
description: "One entry in the meeting timetable."
|
|
@@ -116,6 +131,88 @@ $defs:
|
|
|
116
131
|
event: { type: string }
|
|
117
132
|
description: { type: string }
|
|
118
133
|
room: { type: string }
|
|
134
|
+
localizations:
|
|
135
|
+
type: array
|
|
136
|
+
items:
|
|
137
|
+
$ref: "#/$defs/ScheduleItemLocalization"
|
|
138
|
+
|
|
139
|
+
Attendance:
|
|
140
|
+
type: object
|
|
141
|
+
description: "One attendance record per person at a Meeting."
|
|
142
|
+
additionalProperties: false
|
|
143
|
+
required: [person, status]
|
|
144
|
+
properties:
|
|
145
|
+
person:
|
|
146
|
+
$ref: "#/$defs/Person"
|
|
147
|
+
status:
|
|
148
|
+
$ref: "#/$defs/ParticipationStatus"
|
|
149
|
+
affiliation: { type: string }
|
|
150
|
+
proxy_for:
|
|
151
|
+
$ref: "#/$defs/Person"
|
|
152
|
+
notes: { type: string }
|
|
153
|
+
|
|
154
|
+
VoteRecord:
|
|
155
|
+
type: object
|
|
156
|
+
description: "One vote by one person on one resolution at one meeting."
|
|
157
|
+
additionalProperties: false
|
|
158
|
+
required: [resolution_ref, person, vote]
|
|
159
|
+
properties:
|
|
160
|
+
resolution_ref: { type: string }
|
|
161
|
+
person:
|
|
162
|
+
$ref: "#/$defs/Person"
|
|
163
|
+
affiliation: { type: string }
|
|
164
|
+
vote:
|
|
165
|
+
$ref: "#/$defs/VoteType"
|
|
166
|
+
notes: { type: string }
|
|
167
|
+
|
|
168
|
+
MinutesSection:
|
|
169
|
+
type: object
|
|
170
|
+
description: |
|
|
171
|
+
One section of a Meeting's minutes — typically tied to an agenda
|
|
172
|
+
item by its `number` field. Carries the narrative as Markdown
|
|
173
|
+
(the format the GLM-OCR pipeline emits) plus an optional page
|
|
174
|
+
range for provenance back to the source PDF.
|
|
175
|
+
additionalProperties: false
|
|
176
|
+
properties:
|
|
177
|
+
number: { type: string }
|
|
178
|
+
title: { type: string }
|
|
179
|
+
narrative: { type: string }
|
|
180
|
+
page_start: { type: integer }
|
|
181
|
+
page_end: { type: integer }
|
|
182
|
+
references:
|
|
183
|
+
type: array
|
|
184
|
+
items:
|
|
185
|
+
$ref: "#/$defs/Reference"
|
|
186
|
+
|
|
187
|
+
Minutes:
|
|
188
|
+
type: object
|
|
189
|
+
description: |
|
|
190
|
+
The narrative record of a Meeting — what was said, by whom, in
|
|
191
|
+
what order, with what outcome. Distinct from Agenda (the business
|
|
192
|
+
order drafted before the meeting) and from ResolutionCollection
|
|
193
|
+
(the formal decisions adopted). The Minutes are the running
|
|
194
|
+
record. One Minutes document per language; sections are typically
|
|
195
|
+
keyed by agenda-item number so consumers can join
|
|
196
|
+
Minutes ↔ AgendaItem ↔ Resolution.
|
|
197
|
+
additionalProperties: false
|
|
198
|
+
properties:
|
|
199
|
+
identifier:
|
|
200
|
+
type: array
|
|
201
|
+
items:
|
|
202
|
+
$ref: "#/$defs/StructuredIdentifier"
|
|
203
|
+
urn: { type: string }
|
|
204
|
+
language_code:
|
|
205
|
+
type: string
|
|
206
|
+
pattern: "^[a-z]{3}$"
|
|
207
|
+
script:
|
|
208
|
+
type: string
|
|
209
|
+
pattern: "^[A-Z][a-z]{3}$"
|
|
210
|
+
source_doc: { type: string }
|
|
211
|
+
source_pages: { type: string }
|
|
212
|
+
sections:
|
|
213
|
+
type: array
|
|
214
|
+
items:
|
|
215
|
+
$ref: "#/$defs/MinutesSection"
|
|
119
216
|
|
|
120
217
|
Deadline:
|
|
121
218
|
type: object
|
|
@@ -247,7 +344,10 @@ $defs:
|
|
|
247
344
|
items:
|
|
248
345
|
$ref: "#/$defs/Location"
|
|
249
346
|
general_area: { type: string }
|
|
250
|
-
city:
|
|
347
|
+
city:
|
|
348
|
+
type: string
|
|
349
|
+
pattern: "^[A-Z]{2}[A-Z0-9]{3}$"
|
|
350
|
+
description: "UN/LOCODE of the host city (5-char: 2-letter ISO 3166-1 country + 3-char location, e.g. FRPAR, HKHKG, THCNM)."
|
|
251
351
|
country_code:
|
|
252
352
|
type: string
|
|
253
353
|
pattern: "^[A-Z]{2}$"
|
|
@@ -278,6 +378,18 @@ $defs:
|
|
|
278
378
|
type: array
|
|
279
379
|
items:
|
|
280
380
|
$ref: "#/$defs/Deadline"
|
|
381
|
+
attendance:
|
|
382
|
+
type: array
|
|
383
|
+
items:
|
|
384
|
+
$ref: "#/$defs/Attendance"
|
|
385
|
+
vote_records:
|
|
386
|
+
type: array
|
|
387
|
+
items:
|
|
388
|
+
$ref: "#/$defs/VoteRecord"
|
|
389
|
+
minutes:
|
|
390
|
+
type: array
|
|
391
|
+
items:
|
|
392
|
+
$ref: "#/$defs/Minutes"
|
|
281
393
|
|
|
282
394
|
localizations:
|
|
283
395
|
type: array
|
|
@@ -356,3 +468,13 @@ $defs:
|
|
|
356
468
|
type: string
|
|
357
469
|
description: "Edoxen::Enums::SOURCE_URL_KIND."
|
|
358
470
|
enum: [agenda_pdf, minutes_pdf, resolutions_pdf, report_pdf, register_url, landing_page]
|
|
471
|
+
|
|
472
|
+
ParticipationStatus:
|
|
473
|
+
type: string
|
|
474
|
+
description: "Edoxen::Enums::PARTICIPATION_STATUS."
|
|
475
|
+
enum: [present, absent, apologies, observer, excused]
|
|
476
|
+
|
|
477
|
+
VoteType:
|
|
478
|
+
type: string
|
|
479
|
+
description: "Edoxen::Enums::VOTE_TYPE."
|
|
480
|
+
enum: [affirmative, negative, abstain, absent, not_applicable]
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: edoxen
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-07-
|
|
11
|
+
date: 2026-07-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: json_schemer
|
|
@@ -52,6 +52,20 @@ dependencies:
|
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: '1.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: unlocodes
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0.1'
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0.1'
|
|
55
69
|
description: |
|
|
56
70
|
Edoxen provides a Ruby library for working with resolution models, allowing
|
|
57
71
|
users to create, manipulate, and serialize resolution data in a structured
|
|
@@ -92,6 +106,7 @@ files:
|
|
|
92
106
|
- lib/edoxen/agenda.rb
|
|
93
107
|
- lib/edoxen/agenda_item.rb
|
|
94
108
|
- lib/edoxen/approval.rb
|
|
109
|
+
- lib/edoxen/attendance.rb
|
|
95
110
|
- lib/edoxen/cli.rb
|
|
96
111
|
- lib/edoxen/consideration.rb
|
|
97
112
|
- lib/edoxen/date_range.rb
|
|
@@ -99,6 +114,7 @@ files:
|
|
|
99
114
|
- lib/edoxen/enums.rb
|
|
100
115
|
- lib/edoxen/error.rb
|
|
101
116
|
- lib/edoxen/host_ref.rb
|
|
117
|
+
- lib/edoxen/link_checker.rb
|
|
102
118
|
- lib/edoxen/localization.rb
|
|
103
119
|
- lib/edoxen/location.rb
|
|
104
120
|
- lib/edoxen/meeting.rb
|
|
@@ -107,8 +123,11 @@ files:
|
|
|
107
123
|
- lib/edoxen/meeting_identifier.rb
|
|
108
124
|
- lib/edoxen/meeting_localization.rb
|
|
109
125
|
- lib/edoxen/meeting_relation.rb
|
|
126
|
+
- lib/edoxen/minutes.rb
|
|
127
|
+
- lib/edoxen/minutes_section.rb
|
|
110
128
|
- lib/edoxen/person.rb
|
|
111
129
|
- lib/edoxen/reference.rb
|
|
130
|
+
- lib/edoxen/reference_data.rb
|
|
112
131
|
- lib/edoxen/resolution.rb
|
|
113
132
|
- lib/edoxen/resolution_collection.rb
|
|
114
133
|
- lib/edoxen/resolution_date.rb
|
|
@@ -116,11 +135,13 @@ files:
|
|
|
116
135
|
- lib/edoxen/resolution_relation.rb
|
|
117
136
|
- lib/edoxen/resolution_set.rb
|
|
118
137
|
- lib/edoxen/schedule_item.rb
|
|
138
|
+
- lib/edoxen/schedule_item_localization.rb
|
|
119
139
|
- lib/edoxen/schema_validator.rb
|
|
120
140
|
- lib/edoxen/source_url.rb
|
|
121
141
|
- lib/edoxen/structured_identifier.rb
|
|
122
142
|
- lib/edoxen/url.rb
|
|
123
143
|
- lib/edoxen/version.rb
|
|
144
|
+
- lib/edoxen/vote_record.rb
|
|
124
145
|
- schema/edoxen.yaml
|
|
125
146
|
- schema/meeting.yaml
|
|
126
147
|
- sig/edoxen.rbs
|