diff --git a/configure.py b/configure.py index a752897e90aa25..abe614ee1787c0 100755 --- a/configure.py +++ b/configure.py @@ -1009,6 +1009,12 @@ default=None, help='Enable the built-in snapshot compression in V8.') +parser.add_argument('--v8-enable-temporal-support', + action='store_true', + dest='v8_enable_temporal_support', + default=None, + help='Enable Temporal support in V8.') + parser.add_argument('--node-builtin-modules-path', action='store', dest='node_builtin_modules_path', @@ -1440,8 +1446,8 @@ def host_arch_win(): return matchup.get(arch, 'x64') def set_configuration_variable(configs, name, release=None, debug=None): - configs['Release'][name] = release - configs['Debug'][name] = debug + configs['Release']['variables'][name] = release + configs['Debug']['variables'][name] = debug def configure_arm(o): if options.arm_float_abi: @@ -1522,6 +1528,7 @@ def configure_node(o): o['variables']['control_flow_guard'] = b(options.enable_cfg) o['variables']['node_use_amaro'] = b(not options.without_amaro) o['variables']['debug_node'] = b(options.debug_node) + o['variables']['build_type%'] = 'Debug' if options.debug else 'Release' o['default_configuration'] = 'Debug' if options.debug else 'Release' if options.error_on_warn and options.suppress_all_error_on_warn: raise Exception('--error_on_warn is incompatible with --suppress_all_error_on_warn.') @@ -1772,6 +1779,11 @@ def configure_library(lib, output, pkgname=None): output['libraries'] += pkg_libs.split() +def configure_rust(o, configs): + set_configuration_variable(configs, 'cargo_build_mode', release='release', debug='debug') + set_configuration_variable(configs, 'cargo_build_flags', release=['--release'], debug=[]) + + def configure_v8(o, configs): set_configuration_variable(configs, 'v8_enable_v8_checks', release=1, debug=0) @@ -1802,6 +1814,7 @@ def configure_v8(o, configs): o['variables']['v8_enable_external_code_space'] = 1 if options.enable_pointer_compression else 0 o['variables']['v8_enable_31bit_smis_on_64bit_arch'] = 1 if options.enable_pointer_compression else 0 o['variables']['v8_enable_extensible_ro_snapshot'] = 0 + o['variables']['v8_enable_temporal_support'] = 1 if options.v8_enable_temporal_support else 0 o['variables']['v8_trace_maps'] = 1 if options.trace_maps else 0 o['variables']['node_use_v8_platform'] = b(not options.without_v8_platform) o['variables']['node_use_bundled_v8'] = b(not options.without_bundled_v8) @@ -2325,6 +2338,7 @@ def make_bin_override(): 'libraries': [], 'defines': [], 'cflags': [], + 'conditions': [], } configurations = { 'Release': { 'variables': {} }, @@ -2365,6 +2379,7 @@ def make_bin_override(): configure_static(output) configure_inspector(output) configure_section_file(output) +configure_rust(output, configurations) # remove builtins that have been disabled if options.without_amaro: @@ -2387,6 +2402,17 @@ def make_bin_override(): variables = output['variables'] del output['variables'] +# move configurations[*]['variables'] to conditions variables +config_release_vars = configurations['Release']['variables'] +del configurations['Release']['variables'] +config_debug_vars = configurations['Debug']['variables'] +del configurations['Debug']['variables'] +output['conditions'].append(['build_type=="Release"', { + 'variables': config_release_vars, +}, { + 'variables': config_debug_vars, +}]) + # make_global_settings should be a root level element too if 'make_global_settings' in output: make_global_settings = output['make_global_settings'] @@ -2406,8 +2432,9 @@ def make_bin_override(): print_verbose(output) +# Dump as JSON to allow js2c.cc read it as a simple json file. write('config.gypi', do_not_edit + - pprint.pformat(output, indent=2, width=128) + '\n') + json.dumps(output, indent=2) + '\n') write('config.status', '#!/bin/sh\nset -x\nexec ./configure ' + ' '.join([shlex.quote(arg) for arg in original_argv]) + '\n') diff --git a/deps/temporal/.cargo/config.toml b/deps/temporal/.cargo/config.toml new file mode 100644 index 00000000000000..48f9d0156e7f95 --- /dev/null +++ b/deps/temporal/.cargo/config.toml @@ -0,0 +1,3 @@ +# TODO: track https://github.com/rust-lang/rust/issues/141626 for a resolution +[target.x86_64-pc-windows-msvc] +rustflags = ['-Csymbol-mangling-version=v0'] diff --git a/deps/temporal/.gitignore b/deps/temporal/.gitignore new file mode 100644 index 00000000000000..2c356aa230627a --- /dev/null +++ b/deps/temporal/.gitignore @@ -0,0 +1,23 @@ +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ +tzdata/ + +# Include the data debug view +!/provider/src/data/debug + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + +.vscode/ + +# Ignore log files +*.log + +# Ignore clangd files +.cache +compile_commands.json diff --git a/deps/temporal/CHANGELOG.md b/deps/temporal/CHANGELOG.md new file mode 100644 index 00000000000000..a56cfdfaaaf900 --- /dev/null +++ b/deps/temporal/CHANGELOG.md @@ -0,0 +1,484 @@ +## What's Changed in v0.1.0 +* Update Diplomat to 0.13.0 by @Manishearth in [#588](https://github.com/boa-dev/temporal/pull/588) +* Add TryFrom for PartialDuration to Duration by @nekevss in [#585](https://github.com/boa-dev/temporal/pull/585) +* Add missing from_epoch_nanoseconds() FFI by @linusg in [#584](https://github.com/boa-dev/temporal/pull/584) +* Add from_nanoseconds to FFI PlainDateTime by @nekevss in [#583](https://github.com/boa-dev/temporal/pull/583) +* Update diplomat to using cpp lib name by @Manishearth in [#581](https://github.com/boa-dev/temporal/pull/581) +* Fix TimeZone::get_possible_epoch_ns at date-time limits by @ptomato in [#580](https://github.com/boa-dev/temporal/pull/580) +* Rename timezone.rs to time_zone.rs by @nekevss in [#574](https://github.com/boa-dev/temporal/pull/574) +* General updates to temporal_rs's exports and docs by @nekevss in [#575](https://github.com/boa-dev/temporal/pull/575) +* Review Instant API + Duration by @nekevss in [#573](https://github.com/boa-dev/temporal/pull/573) +* Make TimeZone no longer allocate over FFI by @Manishearth in [#572](https://github.com/boa-dev/temporal/pull/572) +* Update the library introduction and README for timezone_provider by @nekevss in [#570](https://github.com/boa-dev/temporal/pull/570) +* Add a minimal README for zoneinfo_rs by @nekevss in [#569](https://github.com/boa-dev/temporal/pull/569) +* Remove passing lint allows by @Manishearth in [#571](https://github.com/boa-dev/temporal/pull/571) +* Updates to PlainYearMonth and PlainMonthDay based on review by @nekevss in [#567](https://github.com/boa-dev/temporal/pull/567) +* Update library introduction documentation and the project README.md by @nekevss in [#564](https://github.com/boa-dev/temporal/pull/564) +* Updates to PlainTime API based on review by @nekevss in [#565](https://github.com/boa-dev/temporal/pull/565) +* Make ISO getters crate private by @nekevss in [#568](https://github.com/boa-dev/temporal/pull/568) +* Handle und month codes by @Manishearth in [#563](https://github.com/boa-dev/temporal/pull/563) +* Update `ZonedDateTime` constructors by @nekevss in [#562](https://github.com/boa-dev/temporal/pull/562) +* Review and update PlainDate and PlainDateTime API by @nekevss in [#561](https://github.com/boa-dev/temporal/pull/561) +* Refactor Now to be trait based for lazy host getters by @nekevss in [#560](https://github.com/boa-dev/temporal/pull/560) +* Fix comment and organization of TimeZone::zero by @Manishearth in [#559](https://github.com/boa-dev/temporal/pull/559) +* Update ZonedDateTime module and API by @nekevss in [#557](https://github.com/boa-dev/temporal/pull/557) +* Remove yoke dep from temporal_capi by @Manishearth in [#556](https://github.com/boa-dev/temporal/pull/556) + +## New Contributors +* @ptomato made their first contribution in [#580](https://github.com/boa-dev/temporal/pull/580) + +**Full Changelog**: https://github.com/boa-dev/temporal/compare/v0.0.16...v0.1.0 + +# Changelog + +All notable changes to this project will be documented in this file. + +## What's Changed in v0.0.16 +* Bump versions to 0.0.16 +* Remove extraneous icu_time dependency +* Add TimeZone::zero() to capi by @Manishearth in [#554](https://github.com/boa-dev/temporal/pull/554) + +**Full Changelog**: https://github.com/boa-dev/temporal/compare/v0.0.15...v0.0.16 + +## What's Changed in v0.0.15 +* Bump versions +* Update zoneinfo64 by @Manishearth in [#552](https://github.com/boa-dev/temporal/pull/552) +* Remove Default impl from TimeZone; use utc() everywhere by @Manishearth in [#551](https://github.com/boa-dev/temporal/pull/551) +* Add missing header files by @Manishearth in [#550](https://github.com/boa-dev/temporal/pull/550) +* Add provider APIs to capi by @Manishearth in [#544](https://github.com/boa-dev/temporal/pull/544) +* Add new unit validation code by @Manishearth in [#542](https://github.com/boa-dev/temporal/pull/542) +* Add calendar consts for calendar construction by @nekevss in [#541](https://github.com/boa-dev/temporal/pull/541) +* Remove some unreachables by @Manishearth in [#543](https://github.com/boa-dev/temporal/pull/543) +* Move timezone tests to testing against multiple providers by @Manishearth in [#539](https://github.com/boa-dev/temporal/pull/539) +* Move TimeZone over to being Copy with TimeZoneId by @Manishearth in [#538](https://github.com/boa-dev/temporal/pull/538) +* Split TimeZoneProvider trait by @Manishearth in [#537](https://github.com/boa-dev/temporal/pull/537) +* Update compiled tzif data provider data by @nekevss in [#535](https://github.com/boa-dev/temporal/pull/535) +* Add zoneinfo64 support to temporal_provider by @Manishearth in [#533](https://github.com/boa-dev/temporal/pull/533) +* Update zoneinfo compilation in zoneinfo crate by @nekevss in [#532](https://github.com/boa-dev/temporal/pull/532) +* Complete some cleanup options module by @nekevss in [#531](https://github.com/boa-dev/temporal/pull/531) +* Make errors Copy by @Manishearth in [#528](https://github.com/boa-dev/temporal/pull/528) +* More saturating arithmetic by @Manishearth in [#527](https://github.com/boa-dev/temporal/pull/527) +* Move TimeZoneProvider to timezone_provider crate by @Manishearth in [#526](https://github.com/boa-dev/temporal/pull/526) +* Clean up TimeZoneProvider crate by @Manishearth in [#525](https://github.com/boa-dev/temporal/pull/525) + +**Full Changelog**: https://github.com/boa-dev/temporal/compare/v0.0.14...v0.0.15 + +## What's Changed in v0.0.14 +* Release 0.0.14 +* Fix validity checks by @Manishearth in [#523](https://github.com/boa-dev/temporal/pull/523) + +**Full Changelog**: https://github.com/boa-dev/temporal/compare/v0.0.13...v0.0.14 + +## What's Changed in v0.0.13 +* Bump versions to 0.13 +* Add validity checks on parse by @Manishearth in [#517](https://github.com/boa-dev/temporal/pull/517) +* Use correct cached offset when rounding ZDTs by @Manishearth in [#520](https://github.com/boa-dev/temporal/pull/520) +* Clamp unit indices before checking table by @Manishearth in [#516](https://github.com/boa-dev/temporal/pull/516) +* Check that year values are in safe arithmetical range by @Manishearth in [#513](https://github.com/boa-dev/temporal/pull/513) +* Use correct sign value in nudge code by @Manishearth in [#514](https://github.com/boa-dev/temporal/pull/514) +* Support fractional hour values in hoursInDay by @Manishearth in [#515](https://github.com/boa-dev/temporal/pull/515) +* Cache offsets on ZDT by @Manishearth in [#510](https://github.com/boa-dev/temporal/pull/510) +* Update duration to unsigned fields + specification updates by @nekevss in [#507](https://github.com/boa-dev/temporal/pull/507) +* Reduce (and lint-disallow) panics in main code by @Manishearth in [#506](https://github.com/boa-dev/temporal/pull/506) +* Further normalize MWDs, add Vancouver and Santiago tests by @Manishearth in [#504](https://github.com/boa-dev/temporal/pull/504) +* Duration rounding: is_date_unit(), not is_calendar_unit() by @Manishearth in [#503](https://github.com/boa-dev/temporal/pull/503) +* Use beyondDaySpan in NudgeToZonedDateTime by @Manishearth in [#501](https://github.com/boa-dev/temporal/pull/501) +* Remove use of unsafe from the main crate by @Manishearth in [#502](https://github.com/boa-dev/temporal/pull/502) +* Simplify calendar API over FFI by @Manishearth in [#498](https://github.com/boa-dev/temporal/pull/498) +* Handle week=5 MWD cases in posix TZ strings by @Manishearth in [#499](https://github.com/boa-dev/temporal/pull/499) +* Exclude tzif files from publish by @Manishearth in [#495](https://github.com/boa-dev/temporal/pull/495) + +**Full Changelog**: https://github.com/boa-dev/temporal/compare/v0.0.12...v0.0.13 + +## What's Changed in v0.0.12 +* Bump versions +* cleanup: Remove parsing functionality from PartialZDT by @Manishearth in [#493](https://github.com/boa-dev/temporal/pull/493) +* Various MonthDay fixes by @Manishearth in [#492](https://github.com/boa-dev/temporal/pull/492) +* Add `CalendarFields` concept and integate it with API and Partial structs by @nekevss in [#487](https://github.com/boa-dev/temporal/pull/487) +* Add support for non-ISO yearmonths and monthdays by @Manishearth in [#490](https://github.com/boa-dev/temporal/pull/490) +* Add separate parsed variants of all types by @Manishearth in [#486](https://github.com/boa-dev/temporal/pull/486) +* Update icu_calendar, fix self-consistency test by @Manishearth in [#488](https://github.com/boa-dev/temporal/pull/488) +* Add builder pattern `with_xxx` methods for PartialDuration by @nekevss in [#485](https://github.com/boa-dev/temporal/pull/485) +* Add CalendarFieldKeysToIgnore by @Manishearth in [#484](https://github.com/boa-dev/temporal/pull/484) +* Reuse ZDT parsing logic from PartialZDT by @Manishearth in [#483](https://github.com/boa-dev/temporal/pull/483) +* Fix hours in day calculation around gap transitions by @Manishearth in [#482](https://github.com/boa-dev/temporal/pull/482) +* Generate the baked zone info data for ZoneInfoProvider by @nekevss in [#264](https://github.com/boa-dev/temporal/pull/264) +* Precompute before/after offsets and use in disambiguate_possible_epoch_nanos by @Manishearth in [#479](https://github.com/boa-dev/temporal/pull/479) +* Add tzif-inspect tool for inspecting tzif data by @Manishearth in [#480](https://github.com/boa-dev/temporal/pull/480) +* Fix behavior of ns-to-seconds casting for negative values by @Manishearth in [#475](https://github.com/boa-dev/temporal/pull/475) +* Fix panics from calling abs on i64::MIN by @nekevss in [#474](https://github.com/boa-dev/temporal/pull/474) +* Implement get_named_tzdb_transition by @Manishearth in [#472](https://github.com/boa-dev/temporal/pull/472) +* Use ISO day of week unconditionally by @Manishearth in [#471](https://github.com/boa-dev/temporal/pull/471) +* Fix overflow when validating Duration by @nekevss in [#470](https://github.com/boa-dev/temporal/pull/470) +* Rewrite v2_estimate_tz_pair to compare local timestamps by @Manishearth in [#468](https://github.com/boa-dev/temporal/pull/468) +* Normalize, don't canonicalize time zones by @Manishearth in [#466](https://github.com/boa-dev/temporal/pull/466) +* Normalize UTC to UTC by @Manishearth in [#463](https://github.com/boa-dev/temporal/pull/463) +* Ensure that the correct year-month is range-checked during diff operations by @Manishearth in [#461](https://github.com/boa-dev/temporal/pull/461) +* Correctly handle matchBehavior for sub-minute offset strings by @Manishearth in [#462](https://github.com/boa-dev/temporal/pull/462) +* Correctly normalize timezones by @Manishearth in [#460](https://github.com/boa-dev/temporal/pull/460) +* Fix posix logic that was causing panics by @nekevss in [#459](https://github.com/boa-dev/temporal/pull/459) +* Fix float precision check by @Manishearth in [#457](https://github.com/boa-dev/temporal/pull/457) +* CalendarDateAdd takes DateDurations, not full Durations by @Manishearth in [#453](https://github.com/boa-dev/temporal/pull/453) +* Check validity where requested by the spec by @Manishearth in [#456](https://github.com/boa-dev/temporal/pull/456) +* Add .clone() to FFI, YearMonth::reference_day by @Manishearth in [#454](https://github.com/boa-dev/temporal/pull/454) +* Move nanoseconds-validity checking to being explicit by @Manishearth in [#452](https://github.com/boa-dev/temporal/pull/452) +* Add debug impl for error message by @Manishearth in [#451](https://github.com/boa-dev/temporal/pull/451) +* Rename ffi epoch_ns_for to epoch_ms_for by @Manishearth in [#443](https://github.com/boa-dev/temporal/pull/443) +* Fix panic in tzdb logic by @nekevss in [#441](https://github.com/boa-dev/temporal/pull/441) +* Support RoundNumberToIncrementAsIfPositive by @Manishearth in [#440](https://github.com/boa-dev/temporal/pull/440) +* Support sub-minute offsets in UTCOffset by @Manishearth in [#437](https://github.com/boa-dev/temporal/pull/437) +* Fix bug in `to_zoned_date_time_with_provider` by @nekevss in [#436](https://github.com/boa-dev/temporal/pull/436) +* Ensure dates are in limits after performing arithmetic by @Manishearth in [#435](https://github.com/boa-dev/temporal/pull/435) +* YearMonth::compare should compare ISO days by @Manishearth in [#433](https://github.com/boa-dev/temporal/pull/433) +* toPlainDate should use CONSTRAIN by @Manishearth in [#430](https://github.com/boa-dev/temporal/pull/430) + +**Full Changelog**: https://github.com/boa-dev/temporal/compare/v0.0.11...v0.0.12 + +## What's Changed in v0.0.11 +* Add PartialZonedDateTime::try_from_str by @Manishearth in [#420](https://github.com/boa-dev/temporal/pull/420) +* Add from_partial for YearMonth/MonthDay FFI by @Manishearth in [#351](https://github.com/boa-dev/temporal/pull/351) +* Throw error if given more than 9 duration digits by @Manishearth in [#425](https://github.com/boa-dev/temporal/pull/425) +* Fix up eras, correctly expose arithmetic year by @Manishearth in [#424](https://github.com/boa-dev/temporal/pull/424) +* Add time zone normalization by @Manishearth in [#415](https://github.com/boa-dev/temporal/pull/415) +* Allow adding date durations to PlainTime by @Manishearth in [#421](https://github.com/boa-dev/temporal/pull/421) +* Parse both zoned and unzoned date times in relativeTo by @Manishearth in [#422](https://github.com/boa-dev/temporal/pull/422) +* Add get_epoch_ns_for on YearMonth/MonthDay by @Manishearth in [#414](https://github.com/boa-dev/temporal/pull/414) +* Don't set None time in ZDT::from_partial by @Manishearth in [#416](https://github.com/boa-dev/temporal/pull/416) +* [capi] Add from_utf8/from_utf16 for OwnedRelativeTo by @Manishearth in [#375](https://github.com/boa-dev/temporal/pull/375) +* Forbid MonthDay/YearMonth formats for non-iso by @Manishearth in [#413](https://github.com/boa-dev/temporal/pull/413) +* Use track_caller in assertion errors by @Manishearth in [#417](https://github.com/boa-dev/temporal/pull/417) +* Properly respect overflow options when performing with_fallback_date/time by @Manishearth in [#407](https://github.com/boa-dev/temporal/pull/407) +* Add TimeZone::utc() to FFI by @Manishearth in [#358](https://github.com/boa-dev/temporal/pull/358) +* Add POSIX time zone string support to zoneinfo by @nekevss in [#265](https://github.com/boa-dev/temporal/pull/265) +* Fix duration validity check by @Manishearth in [#411](https://github.com/boa-dev/temporal/pull/411) +* Produce correct error types for invalid month/era codes by @Manishearth in [#405](https://github.com/boa-dev/temporal/pull/405) +* Add support for offsetBehavior == WALL by @Manishearth in [#404](https://github.com/boa-dev/temporal/pull/404) +* Update README.md - mention other usages of lib by @jasonwilliams in [#401](https://github.com/boa-dev/temporal/pull/401) +* Make TimeZone::identifier() infallible by @linusg in [#399](https://github.com/boa-dev/temporal/pull/399) +* Fix the bakedata provider path by @nekevss in [#398](https://github.com/boa-dev/temporal/pull/398) +* Include time duration in InternalDurationSign by @Manishearth in [#397](https://github.com/boa-dev/temporal/pull/397) +* Use rounded instant in ZDT::toString by @Manishearth in [#396](https://github.com/boa-dev/temporal/pull/396) +* Fix hoursInDay division constant by @nekevss in [#395](https://github.com/boa-dev/temporal/pull/395) +* Expose ParseTemporalCalendarString over FFI by @Manishearth in [#390](https://github.com/boa-dev/temporal/pull/390) +* Remove UTC designator check from time zone parsing by @nekevss in [#392](https://github.com/boa-dev/temporal/pull/392) +* Update ixdtf to icu4x main git branch by @robot-head in [#365](https://github.com/boa-dev/temporal/pull/365) +* Fix `9.5.8 AddDurationToYearMonth` abstract method by @HalidOdat in [#389](https://github.com/boa-dev/temporal/pull/389) +* Fix ZonedDateTime::nanosecond by @Manishearth in [#388](https://github.com/boa-dev/temporal/pull/388) +* Allow datetime strings for YearMonth/MonthDay/Time by @Manishearth in [#386](https://github.com/boa-dev/temporal/pull/386) +* Remove orgs/boa-dev/people from links by @nekevss in [#387](https://github.com/boa-dev/temporal/pull/387) +* Update maintainers in README.md by @jasonwilliams in [#384](https://github.com/boa-dev/temporal/pull/384) +* Re-add try_from_offset_str by @Manishearth in [#376](https://github.com/boa-dev/temporal/pull/376) +* Fix clippy lints for Rust 1.88 by @nekevss in [#377](https://github.com/boa-dev/temporal/pull/377) + +## New Contributors +* @linusg made their first contribution in [#399](https://github.com/boa-dev/temporal/pull/399) + +**Full Changelog**: https://github.com/boa-dev/temporal/compare/v0.0.10...v0.0.11 + +## What's Changed in v0.0.10 +* Add documentation and doctests for builtins by @blarfoon in [#360](https://github.com/boa-dev/temporal/pull/360) +* More error enums by @Manishearth in [#373](https://github.com/boa-dev/temporal/pull/373) +* [capi] Add stringifier/cloning to timezones by @Manishearth in [#344](https://github.com/boa-dev/temporal/pull/344) +* Handle unknown timezone identifiers in FsTzdbProvider by @Manishearth in [#345](https://github.com/boa-dev/temporal/pull/345) +* [capi] Fix i128Nanoseconds by @Manishearth in [#372](https://github.com/boa-dev/temporal/pull/372) +* [capi] expose error strings by @Manishearth in [#364](https://github.com/boa-dev/temporal/pull/364) +* Consolidate tools into a single `tool` directory by @nekevss in [#368](https://github.com/boa-dev/temporal/pull/368) +* Add a new PartialYearMonth to available partial structs (#288) by @robot-head in [#342](https://github.com/boa-dev/temporal/pull/342) +* Implement zoneinfo parsing/compilation and add TZif structs by @nekevss in [#257](https://github.com/boa-dev/temporal/pull/257) +* Add ErrorMessage enum, start using it by @Manishearth in [#355](https://github.com/boa-dev/temporal/pull/355) +* [capi] Add is_valid() to I128Nanoseconds by @Manishearth in [#363](https://github.com/boa-dev/temporal/pull/363) +* [capi] Add ZonedDateTime::{equals,offset} by @Manishearth in [#362](https://github.com/boa-dev/temporal/pull/362) +* Add convenience methods for constructing FFI datetime types from milliseconds by @Manishearth in [#359](https://github.com/boa-dev/temporal/pull/359) +* [capi] Add offset_nanoseconds() to ZDT FFI by @Manishearth in [#361](https://github.com/boa-dev/temporal/pull/361) +* Update diplomat by @Manishearth in [#357](https://github.com/boa-dev/temporal/pull/357) +* Stop depending on `is_dst` for calculations by @jedel1043 in [#356](https://github.com/boa-dev/temporal/pull/356) +* Add some FAQ style docs for temporal_rs by @nekevss in [#350](https://github.com/boa-dev/temporal/pull/350) +* Add try_from_offset_str ctor for TimeZone by @Manishearth in [#348](https://github.com/boa-dev/temporal/pull/348) +* Switch compiled_data APIs to new CompiledTzdbProvider by @Manishearth in [#346](https://github.com/boa-dev/temporal/pull/346) + +## New Contributors +* @blarfoon made their first contribution in [#360](https://github.com/boa-dev/temporal/pull/360) + +**Full Changelog**: https://github.com/boa-dev/temporal/compare/v0.0.9...v0.0.10 + +## What's Changed in v0.0.9 +* Cross boundary rounding fix #286 by @robot-head in [#343](https://github.com/boa-dev/temporal/pull/343) +* Implement PlainMonthDay::with functionality by @nekevss in [#335](https://github.com/boa-dev/temporal/pull/335) +* Add Writeable getters for some types, use in FFI by @Manishearth in [#340](https://github.com/boa-dev/temporal/pull/340) +* Add missing FFI APIs by @Manishearth in [#339](https://github.com/boa-dev/temporal/pull/339) +* Fill in missing Zoned APIs by @Manishearth in [#331](https://github.com/boa-dev/temporal/pull/331) +* Add stringifiers to MonthDay/YearMonth by @Manishearth in [#338](https://github.com/boa-dev/temporal/pull/338) +* Use AnyCalendarKind in PartialDate by @Manishearth in [#332](https://github.com/boa-dev/temporal/pull/332) +* Add ZonedDateTime FFI by @Manishearth in [#329](https://github.com/boa-dev/temporal/pull/329) +* Use a lock internally to FsTzdbProvider instead of externally by @Manishearth in [#327](https://github.com/boa-dev/temporal/pull/327) +* Remove create() APIs, consistently use try_new() by @Manishearth in [#326](https://github.com/boa-dev/temporal/pull/326) +* Switch FFI calendar APIs over to using AnyCalendarKind for input by @Manishearth in [#324](https://github.com/boa-dev/temporal/pull/324) +* Update abstract method `7.5.37 RoundRelativeDuration` by @HalidOdat in [#323](https://github.com/boa-dev/temporal/pull/323) +* Fix abstract method `7.5.36 BubbleRelativeDuration()` by @HalidOdat in [#322](https://github.com/boa-dev/temporal/pull/322) +* Generate FFI bindings for C by @jedel1043 in [#321](https://github.com/boa-dev/temporal/pull/321) +* Improve baked data formatting by @Manishearth in [#319](https://github.com/boa-dev/temporal/pull/319) +* Correctly validate largestUnit when constructing from DifferenceSettings by @Manishearth in [#316](https://github.com/boa-dev/temporal/pull/316) +* Align `Duration.prototype.round()` to latest specification by @HalidOdat in [#317](https://github.com/boa-dev/temporal/pull/317) + +**Full Changelog**: https://github.com/boa-dev/temporal/compare/v0.0.8...v0.0.9 + +## What's Changed in v0.0.8 +* Make duration capi getters non-optional by @Manishearth in [#314](https://github.com/boa-dev/temporal/pull/314) +* Add to_string to Duration by @Manishearth in [#312](https://github.com/boa-dev/temporal/pull/312) +* Add comparison methods to Instant by @Manishearth in [#311](https://github.com/boa-dev/temporal/pull/311) +* Add LICENSEs to timezone_provider crate by @Manishearth in [#308](https://github.com/boa-dev/temporal/pull/308) +* Prune dependencies of timezone_provider in normal mode, add depcheck by @Manishearth in [#310](https://github.com/boa-dev/temporal/pull/310) +* Add to_plain_date to PlainMonthDay and PlainYearMonth by @HenrikTennebekk in [#287](https://github.com/boa-dev/temporal/pull/287) +* Remove exclude and readme by @nekevss in [#304](https://github.com/boa-dev/temporal/pull/304) + +**Full Changelog**: https://github.com/boa-dev/temporal/compare/v0.0.7...v0.0.8 + +## What's Changed in v0.0.7 +* Bump ixdtf and complete changes for update by @nekevss in [#299](https://github.com/boa-dev/temporal/pull/299) +* A few more changes to the readme by @nekevss in [#297](https://github.com/boa-dev/temporal/pull/297) +* Implement a builder API for Now by @nekevss in [#296](https://github.com/boa-dev/temporal/pull/296) +* Some docs cleanup and updates by @nekevss in [#294](https://github.com/boa-dev/temporal/pull/294) +* Add `PlainMonthDay` method + clean up by @nekevss in [#284](https://github.com/boa-dev/temporal/pull/284) +* Add Eq, Ord impls on FiniteF64 by @sffc in [#187](https://github.com/boa-dev/temporal/pull/187) +* Allow parsers to accept unvalidated UTF8 by @HalidOdat in [#295](https://github.com/boa-dev/temporal/pull/295) +* Bump to icu_calendar 2.0 by @nekevss in [#292](https://github.com/boa-dev/temporal/pull/292) +* Add ISO specific constructors to builtins by @nekevss in [#263](https://github.com/boa-dev/temporal/pull/263) +* Rename the provider crate by @nekevss in [#289](https://github.com/boa-dev/temporal/pull/289) +* Expose equals and compare over FFI by @Magnus-Fjeldstad in [#269](https://github.com/boa-dev/temporal/pull/269) +* Impl round_with_provider for ZonedDateTIme by @sebastianjacmatt in [#278](https://github.com/boa-dev/temporal/pull/278) +* Add some compiled_data FFI APIs by @Manishearth in [#273](https://github.com/boa-dev/temporal/pull/273) +* Add string conversion functions for Temporal types by @Manishearth in [#276](https://github.com/boa-dev/temporal/pull/276) +* Make sure temporal_capi can be built no_std by @Manishearth in [#281](https://github.com/boa-dev/temporal/pull/281) +* Make iana-time-zone dep optional by @Manishearth in [#279](https://github.com/boa-dev/temporal/pull/279) +* Implementation of ZonedDateTime.prototype.with by @lockels in [#267](https://github.com/boa-dev/temporal/pull/267) +* Update Duration's inner representation from floating point to integers. by @nekevss in [#268](https://github.com/boa-dev/temporal/pull/268) +* Add all-features = true to docs.rs metadata by @Manishearth in [#271](https://github.com/boa-dev/temporal/pull/271) +* Fix instant math in capi by @Manishearth in [#270](https://github.com/boa-dev/temporal/pull/270) +* Remove the Temporal prefix from Unit, RoundingMode, and UnsignedRoundingMode by @nekevss in [#254](https://github.com/boa-dev/temporal/pull/254) +* Since until by @sebastianjacmatt in [#259](https://github.com/boa-dev/temporal/pull/259) +* Implementation of toZonedDateTimeISO for Instant by @lockels in [#258](https://github.com/boa-dev/temporal/pull/258) +* Implement toZonedDateTime in PlainDate by @JohannesHelleve in [#192](https://github.com/boa-dev/temporal/pull/192) +* Add intro documentation to ZonedDateTime and PlainDateTime by @nekevss in [#253](https://github.com/boa-dev/temporal/pull/253) +* Implement IANA normalizer baked data provider by @nekevss in [#251](https://github.com/boa-dev/temporal/pull/251) + +## New Contributors +* @HalidOdat made their first contribution in [#295](https://github.com/boa-dev/temporal/pull/295) +* @JohannesHelleve made their first contribution in [#192](https://github.com/boa-dev/temporal/pull/192) + +**Full Changelog**: https://github.com/boa-dev/temporal/compare/v0.0.6...v0.0.7 + +## What's Changed in v0.0.6 +* Rename methods on `Now` and add a test by @nekevss in [#243](https://github.com/boa-dev/temporal/pull/243) +* Add licenses to `temporal_capi` and `temporal_rs` for publish by @nekevss in [#247](https://github.com/boa-dev/temporal/pull/247) +* Add with to PlainYearMonth by @sebastianjacmatt in [#231](https://github.com/boa-dev/temporal/pull/231) +* initial implementation of ToZonedDateTime, ToPlainDate, ToPlainTime by @lockels in [#244](https://github.com/boa-dev/temporal/pull/244) +* Initial implementation of Duration.prototype.total by @lockels in [#241](https://github.com/boa-dev/temporal/pull/241) + +**Full Changelog**: https://github.com/boa-dev/temporal/compare/v0.0.5...v0.0.6 + +## What's Changed in v0.0.5 +* Prepare temporal_capi for publish by @jedel1043 in [#238](https://github.com/boa-dev/temporal/pull/238) +* Adjustments to `toPlainYearMonth` and `toPlainMonthDay` methods on PlainDate by @nekevss in [#237](https://github.com/boa-dev/temporal/pull/237) +* Missed an unwrap in the README.md example by @nekevss in [#236](https://github.com/boa-dev/temporal/pull/236) +* Clean up API ergonomics for calendar methods by @nekevss in [#235](https://github.com/boa-dev/temporal/pull/235) +* Add various updates to docs by @nekevss in [#234](https://github.com/boa-dev/temporal/pull/234) +* Reject datetime when fraction digits are too large by @nekevss in [#229](https://github.com/boa-dev/temporal/pull/229) +* Fix not adjusting fraction for duration unit by @nekevss in [#228](https://github.com/boa-dev/temporal/pull/228) +* Fixes for `EpochNanosecond`s and `Offset` parsing by @nekevss in [#223](https://github.com/boa-dev/temporal/pull/223) +* Fix bugs around validating diffing units by @nekevss in [#225](https://github.com/boa-dev/temporal/pull/225) +* Add `UtcOffset` struct for `PartialZonedDateTime` by @nekevss in [#207](https://github.com/boa-dev/temporal/pull/207) +* Check in bindings, add CI for keeping them up to date by @Manishearth in [#220](https://github.com/boa-dev/temporal/pull/220) +* Fix `Instant::epoch_milliseconds` for values before Epoch by @nekevss in [#221](https://github.com/boa-dev/temporal/pull/221) +* Update ixdtf to 0.4.0 by @Manishearth in [#219](https://github.com/boa-dev/temporal/pull/219) +* Update icu4x to 2.0.0-beta2 by @Manishearth in [#218](https://github.com/boa-dev/temporal/pull/218) +* Add `GetNamedTimeZoneTransition` method to TimeZoneProvider trait by @nekevss in [#203](https://github.com/boa-dev/temporal/pull/203) +* Implement posix resolution for month-week-day by @jedel1043 in [#214](https://github.com/boa-dev/temporal/pull/214) +* implement utility methods on partial structs by @nekevss in [#206](https://github.com/boa-dev/temporal/pull/206) +* Test all combinations of features by @jedel1043 in [#212](https://github.com/boa-dev/temporal/pull/212) +* Reject non-iso calendar in `YearMonth::from_str` and `MonthDay::from_str` by @nekevss in [#211](https://github.com/boa-dev/temporal/pull/211) +* Fix not validating `MonthCode` in ISO path by @nekevss in [#210](https://github.com/boa-dev/temporal/pull/210) +* Integrate `MonthCode` into public API and related adjustments by @nekevss in [#208](https://github.com/boa-dev/temporal/pull/208) +* Implement the remaining non-ISO calendar method calls by @nekevss in [#209](https://github.com/boa-dev/temporal/pull/209) +* PlainYearMonth parsing and Calendar field resolution cleanup/fixes by @nekevss in [#205](https://github.com/boa-dev/temporal/pull/205) +* Build out stubs for remaining unimplemented methods by @nekevss in [#202](https://github.com/boa-dev/temporal/pull/202) +* Fix clippy lints by @nekevss in [#201](https://github.com/boa-dev/temporal/pull/201) +* Temporal duration compare by @sffc, @lockels, @Neelzee, @sebastianjacmatt, @Magnus-Fjeldstad and @HenrikTennebekk. in [#186](https://github.com/boa-dev/temporal/pull/186) +* Fix issues with `from_partial` method implementations by @nekevss in [#200](https://github.com/boa-dev/temporal/pull/200) +* More FFI: Finish Calendar, add Instant by @Manishearth in [#198](https://github.com/boa-dev/temporal/pull/198) +* Fix parsing bugs related to UTC Designator usage by @nekevss in [#197](https://github.com/boa-dev/temporal/pull/197) +* Update time parsing to error on dup critical calendars by @nekevss in [#196](https://github.com/boa-dev/temporal/pull/196) +* Update unit group validation to handle rounding options by @nekevss in [#194](https://github.com/boa-dev/temporal/pull/194) +* Fix handling of leap seconds in parsing by @nekevss in [#195](https://github.com/boa-dev/temporal/pull/195) +* Update time zone parsing to include other ixdtf formats by @nekevss in [#193](https://github.com/boa-dev/temporal/pull/193) +* Fix calendar parsing on `from_str` implementation by @nekevss in [#191](https://github.com/boa-dev/temporal/pull/191) +* Cleanup `Now` API in favor of system defined implementations by @nekevss in [#182](https://github.com/boa-dev/temporal/pull/182) +* Reimplement Unit Group with different approach by @nekevss in [#183](https://github.com/boa-dev/temporal/pull/183) +* Implement `ZonedDateTime::offset` and `ZonedDateTime::offset_nanoseconds` by @nekevss in [#185](https://github.com/boa-dev/temporal/pull/185) +* Small API cleanup and a couple dev docs updates by @nekevss in [#190](https://github.com/boa-dev/temporal/pull/190) +* Add Eq and Ord for PlainYearMonth + Eq for PlainMonthDay by @nekevss in [#175](https://github.com/boa-dev/temporal/pull/175) +* More FFI APIs by @Manishearth in [#178](https://github.com/boa-dev/temporal/pull/178) +* Fix the typo that's returning milliseconds instead of microseconds by @nekevss in [#184](https://github.com/boa-dev/temporal/pull/184) +* Add some FFI tests by @Manishearth in [#179](https://github.com/boa-dev/temporal/pull/179) +* Fix Instant parsing by handling order of operations and properly balance `IsoDateTime` by @nekevss in [#174](https://github.com/boa-dev/temporal/pull/174) +* Add some testing / debugging docs by @nekevss in [#176](https://github.com/boa-dev/temporal/pull/176) +* Fix logic on asserting is_time_duration by @nekevss in [#177](https://github.com/boa-dev/temporal/pull/177) +* Rework library restructure to remove wrapper types by @nekevss in [#181](https://github.com/boa-dev/temporal/pull/181) +* Restructure project to separate core provider APIs from non-provider APIs by @nekevss in [#169](https://github.com/boa-dev/temporal/pull/169) +* Fix `Duration` parsing not returning a range error. by @nekevss in [#173](https://github.com/boa-dev/temporal/pull/173) +* Set up basic diplomat workflow by @Manishearth in [#163](https://github.com/boa-dev/temporal/pull/163) +* Implement Neri-Schneider calculations by @nekevss in [#147](https://github.com/boa-dev/temporal/pull/147) +* Remove `UnitGroup` addition by @nekevss in [#171](https://github.com/boa-dev/temporal/pull/171) +* Implement `ZonedDateTime::since` and `ZonedDateTime::until` by @nekevss in [#170](https://github.com/boa-dev/temporal/pull/170) +* Implement to_string functionality and methods for `Duration`, `PlainYearMonth`, and `PlainMonthDay` by @nekevss in [#164](https://github.com/boa-dev/temporal/pull/164) +* API cleanup, visibility updates, and tech debt cleanup by @nekevss in [#168](https://github.com/boa-dev/temporal/pull/168) +* Add to_string functionality for timezone identifer by @nekevss in [#161](https://github.com/boa-dev/temporal/pull/161) +* Bug fixes to address test failures + removing unused API by @nekevss in [#162](https://github.com/boa-dev/temporal/pull/162) +* Implement correct resolving of `getStartOfDay` by @jedel1043 in [#159](https://github.com/boa-dev/temporal/pull/159) +* Add an MSRV check to CI by @nekevss in [#158](https://github.com/boa-dev/temporal/pull/158) +* Fixing panics in test262 when running in debug mode by @nekevss in [#157](https://github.com/boa-dev/temporal/pull/157) +* Fix edge case for disambiguating `ZonedDateTime`s on DSTs skipping midnight by @jedel1043 in [#156](https://github.com/boa-dev/temporal/pull/156) +* Extend implementation of `to_ixdtf_string` to more types by @nekevss in [#155](https://github.com/boa-dev/temporal/pull/155) +* Implement support for `to_string` and implement `PlainDate::to_string` by @nekevss in [#153](https://github.com/boa-dev/temporal/pull/153) +* Fix RoundingMode::truncation to UnsignedRoundingMode mapping by @nekevss in [#146](https://github.com/boa-dev/temporal/pull/146) +* Add validation logic to `from_diff_settings` by @nekevss in [#144](https://github.com/boa-dev/temporal/pull/144) +* Build out the rest of the Now methods by @nekevss in [#145](https://github.com/boa-dev/temporal/pull/145) +* Adjust `RelativeTo` according to specification and implementation by @nekevss in [#140](https://github.com/boa-dev/temporal/pull/140) +* Complete some general cleanup of `temporal_rs` by @nekevss in [#138](https://github.com/boa-dev/temporal/pull/138) +* Add ZonedDateTime functionality to `Duration::round` by @nekevss in [#134](https://github.com/boa-dev/temporal/pull/134) +* Update try_new, new, and new_with_overflow integer type by @nekevss in [#137](https://github.com/boa-dev/temporal/pull/137) +* Fix `Calendar::from_str` to be case-insensitive by @nekevss in [#135](https://github.com/boa-dev/temporal/pull/135) +* Add ToIntegerWithTruncation, ToPositiveIntegerWithTruncation, and ToIntegerIfIntegral methods to `FiniteF64` by @nekevss in [#131](https://github.com/boa-dev/temporal/pull/131) +* Add to-x methods and with-x methods to ZonedDateTime by @nekevss in [#129](https://github.com/boa-dev/temporal/pull/129) +* Fix `epoch_time_to_epoch_year` date equation bug related to `BalanceISODate` by @nekevss in [#132](https://github.com/boa-dev/temporal/pull/132) +* Bump dependencies for `ixdtf`, `tzif`, `icu_calendar`, and `tinystr`. by @nekevss in [#133](https://github.com/boa-dev/temporal/pull/133) +* Fix bug introduced by `EpochNanoseconds` + adjust tests to catch better by @nekevss in [#128](https://github.com/boa-dev/temporal/pull/128) +* Remove epochSeconds and epochMicroseconds + adjust epochMillseconds by @nekevss in [#127](https://github.com/boa-dev/temporal/pull/127) +* Adjust compilation configuration of tzdb to target_family from target_os by @nekevss in [#125](https://github.com/boa-dev/temporal/pull/125) +* Migrate repo to workspace by @jedel1043 in [#126](https://github.com/boa-dev/temporal/pull/126) +* Add now feature flag by @nekevss in [#123](https://github.com/boa-dev/temporal/pull/123) +* Add `ZonedDateTime` calendar accessor methods by @nekevss in [#117](https://github.com/boa-dev/temporal/pull/117) +* Implement `PartialZonedDateTime` and `from_partial` and `from_str` for `ZonedDateTime` by @nekevss in [#115](https://github.com/boa-dev/temporal/pull/115) +* Update CHANGELOG for v0.0.4 release by @nekevss in [#124](https://github.com/boa-dev/temporal/pull/124) +* Patch the now test per matrix discussion by @nekevss in [#121](https://github.com/boa-dev/temporal/pull/121) + +## New Contributors +* @sffc made their first contribution in [#186](https://github.com/boa-dev/temporal/pull/186) +* @lockels made their first contribution in [#186](https://github.com/boa-dev/temporal/pull/186) +* @Neelzee made their first contribution in [#186](https://github.com/boa-dev/temporal/pull/186) +* @sebastianjacmatt made their first contribution in [#186](https://github.com/boa-dev/temporal/pull/186) +* @Magnus-Fjeldstad made their first contribution in [#186](https://github.com/boa-dev/temporal/pull/186) +* @HenrikTennebekk made their first contribution in [#186](https://github.com/boa-dev/temporal/pull/186) +* @cassioneri made their first contribution in [#147](https://github.com/boa-dev/temporal/pull/147) + +**Full Changelog**: https://github.com/boa-dev/temporal/compare/v0.0.4...v0.0.5 + +## What's Changed in v0.0.4 + +* bump release by @jasonwilliams in [#120](https://github.com/boa-dev/temporal/pull/120) +* Add an `EpochNanosecond` new type by @nekevss in [#116](https://github.com/boa-dev/temporal/pull/116) +* Migrate to `web_time::SystemTime` for `wasm32-unknown-unknown` targets by @nekevss in [#118](https://github.com/boa-dev/temporal/pull/118) +* Bug fixes and more implementation by @jasonwilliams in [#110](https://github.com/boa-dev/temporal/pull/110) +* Some `Error` optimizations by @CrazyboyQCD in [#112](https://github.com/boa-dev/temporal/pull/112) +* Add `from_partial` methods to `PlainTime`, `PlainDate`, and `PlainDateTime` by @nekevss in [#106](https://github.com/boa-dev/temporal/pull/106) +* Implement `ZonedDateTime`'s add and subtract methods by @nekevss in [#102](https://github.com/boa-dev/temporal/pull/102) +* Add matrix links to README and some layout adjustments by @nekevss in [#108](https://github.com/boa-dev/temporal/pull/108) +* Stub out `tzdb` support for Windows and POSIX tz string by @nekevss in [#100](https://github.com/boa-dev/temporal/pull/100) +* Stub out tzdb support to unblock `Now` and `ZonedDateTime` by @nekevss in [#99](https://github.com/boa-dev/temporal/pull/99) +* Remove num-bigint dependency and rely on primitives by @nekevss in [#103](https://github.com/boa-dev/temporal/pull/103) +* Move to no_std by @Manishearth in [#101](https://github.com/boa-dev/temporal/pull/101) +* General API cleanup and adjustments by @nekevss in [#97](https://github.com/boa-dev/temporal/pull/97) +* Update README.md by @jasonwilliams in [#96](https://github.com/boa-dev/temporal/pull/96) +* Refactor `TemporalFields` into `CalendarFields` by @nekevss in [#95](https://github.com/boa-dev/temporal/pull/95) +* Patch for partial records by @nekevss in [#94](https://github.com/boa-dev/temporal/pull/94) +* Add `PartialTime` and `PartialDateTime` with corresponding `with` methods. by @nekevss in [#92](https://github.com/boa-dev/temporal/pull/92) +* Implement `MonthCode`, `PartialDate`, and `Date::with` by @nekevss in [#89](https://github.com/boa-dev/temporal/pull/89) +* Add is empty for partialDuration by @jasonwilliams in [#90](https://github.com/boa-dev/temporal/pull/90) +* Fix lints for rustc 1.80.0 by @jedel1043 in [#91](https://github.com/boa-dev/temporal/pull/91) +* adding methods for yearMonth and MonthDay by @jasonwilliams in [#44](https://github.com/boa-dev/temporal/pull/44) +* Implement `DateTime` round method by @nekevss in [#88](https://github.com/boa-dev/temporal/pull/88) +* Update `Duration` types to use a `FiniteF64` instead of `f64` primitive. by @nekevss in [#86](https://github.com/boa-dev/temporal/pull/86) +* Refactor `TemporalFields` interface and add `FieldsKey` enum by @nekevss in [#87](https://github.com/boa-dev/temporal/pull/87) +* Updates to instant and its methods by @nekevss in [#85](https://github.com/boa-dev/temporal/pull/85) +* Implement compare functionality and some more traits by @nekevss in [#82](https://github.com/boa-dev/temporal/pull/82) +* Implement `DateTime` diffing methods `Until` and `Since` by @nekevss in [#83](https://github.com/boa-dev/temporal/pull/83) +* Add `with_*` methods to `Date` and `DateTime` by @nekevss in [#84](https://github.com/boa-dev/temporal/pull/84) +* Add some missing trait implementations by @nekevss in [#81](https://github.com/boa-dev/temporal/pull/81) +* chore(dependabot): bump zerovec-derive from 0.10.2 to 0.10.3 by @dependabot[bot] in [#80](https://github.com/boa-dev/temporal/pull/80) +* Add prefix option to commit-message by @nekevss in [#79](https://github.com/boa-dev/temporal/pull/79) +* Add commit-message prefix to dependabot by @nekevss in [#77](https://github.com/boa-dev/temporal/pull/77) +* Bump zerovec from 0.10.2 to 0.10.4 by @dependabot[bot] in [#78](https://github.com/boa-dev/temporal/pull/78) + +## New Contributors +* @jasonwilliams made their first contribution in [#120](https://github.com/boa-dev/temporal/pull/120) +* @CrazyboyQCD made their first contribution in [#112](https://github.com/boa-dev/temporal/pull/112) +* @Manishearth made their first contribution in [#101](https://github.com/boa-dev/temporal/pull/101) + +**Full Changelog**: https://github.com/boa-dev/temporal/compare/v0.0.3...v0.0.4 + +# CHANGELOG + +## What's Changed in v0.0.3 + +* Implement add and subtract methods for Duration by @nekevss in [#74](https://github.com/boa-dev/temporal/pull/74) +* Implement PartialEq and Eq for `Calendar`, `Date`, and `DateTime` by @nekevss in [#75](https://github.com/boa-dev/temporal/pull/75) +* Update duration validation and switch asserts to debug-asserts by @nekevss in [#73](https://github.com/boa-dev/temporal/pull/73) +* Update duration rounding to new algorithms by @nekevss in [#65](https://github.com/boa-dev/temporal/pull/65) +* Remove `CalendarProtocol` and `TimeZoneProtocol` by @jedel1043 in [#66](https://github.com/boa-dev/temporal/pull/66) +* Use groups in dependabot updates by @jedel1043 in [#69](https://github.com/boa-dev/temporal/pull/69) +* Ensure parsing throws with unknown critical annotations by @jedel1043 in [#63](https://github.com/boa-dev/temporal/pull/63) +* Reject `IsoDate` when outside the allowed range by @jedel1043 in [#62](https://github.com/boa-dev/temporal/pull/62) +* Avoid overflowing when calling `NormalizedTimeDuration::add_days` by @jedel1043 in [#61](https://github.com/boa-dev/temporal/pull/61) +* Ensure parsing throws when duplicate calendar is critical by @jedel1043 in [#58](https://github.com/boa-dev/temporal/pull/58) +* Fix rounding when the dividend is smaller than the divisor by @jedel1043 in [#57](https://github.com/boa-dev/temporal/pull/57) +* Implement the `toYearMonth`, `toMonthDay`, and `toDateTime` for `Date` component by @nekevss in [#56](https://github.com/boa-dev/temporal/pull/56) +* Update increment rounding functionality by @nekevss in [#53](https://github.com/boa-dev/temporal/pull/53) +* Patch `(un)balance_relative` to avoid panicking by @jedel1043 in [#48](https://github.com/boa-dev/temporal/pull/48) +* Cleanup rounding increment usages with new struct by @jedel1043 in [#54](https://github.com/boa-dev/temporal/pull/54) +* Add struct to encapsulate invariants of rounding increments by @jedel1043 in [#49](https://github.com/boa-dev/temporal/pull/49) +* Migrate parsing to `ixdtf` crate by @nekevss in [#50](https://github.com/boa-dev/temporal/pull/50) +* Fix method call in days_in_month by @nekevss in [#46](https://github.com/boa-dev/temporal/pull/46) +* Implement add & subtract methods for `DateTime` component by @nekevss in [#45](https://github.com/boa-dev/temporal/pull/45) +* Fix panics when no relative_to is supplied to round by @nekevss in [#40](https://github.com/boa-dev/temporal/pull/40) +* Implement Time's until and since methods by @nekevss in [#36](https://github.com/boa-dev/temporal/pull/36) +* Implements `Date`'s `add`, `subtract`, `until`, and `since` methods by @nekevss in [#35](https://github.com/boa-dev/temporal/pull/35) +* Fix clippy lints and bump bitflags version by @nekevss in [#38](https://github.com/boa-dev/temporal/pull/38) + +**Full Changelog**: https://github.com/boa-dev/temporal/compare/v0.0.2...v0.0.3 + +## What's Changed in v0.0.2 + +# [0.0.2 (2024-03-04)](https://github.com/boa-dev/temporal/compare/v0.0.1...v0.0.2) + +### Enhancements + +* Fix loop in `diff_iso_date` by @nekevss in https://github.com/boa-dev/temporal/pull/31 +* Remove unnecessary iterations by @nekevss in https://github.com/boa-dev/temporal/pull/30 + +**Full Changelog**: https://github.com/boa-dev/temporal/compare/v0.0.1...v0.0.2 + +# [0.0.1 (2024-02-25)](https://github.com/boa-dev/temporal/commits/v0.0.1) + +### Enhancements +* Add blank and negated + small adjustments by @nekevss in https://github.com/boa-dev/temporal/pull/17 +* Simplify Temporal APIs by @jedel1043 in https://github.com/boa-dev/temporal/pull/18 +* Implement `Duration` normalization - Part 1 by @nekevss in https://github.com/boa-dev/temporal/pull/20 +* Duration Normalization - Part 2 by @nekevss in https://github.com/boa-dev/temporal/pull/23 +* Add `non_exhaustive` attribute to component structs by @nekevss in https://github.com/boa-dev/temporal/pull/25 +* Implement `Duration::round` and some general updates/fixes by @nekevss in https://github.com/boa-dev/temporal/pull/24 + +### Documentation +* Adding a `docs` directory by @nekevss in https://github.com/boa-dev/temporal/pull/16 +* Build out README and CONTRIBUTING docs by @nekevss in https://github.com/boa-dev/temporal/pull/21 + +### Other Changes +* Port `boa_temporal` to new `temporal` crate by @nekevss in https://github.com/boa-dev/temporal/pull/1 +* Add CI and rename license by @jedel1043 in https://github.com/boa-dev/temporal/pull/3 +* Create LICENSE-Apache by @jedel1043 in https://github.com/boa-dev/temporal/pull/6 +* Setup publish CI by @jedel1043 in https://github.com/boa-dev/temporal/pull/26 +* Remove keywords from Cargo.toml by @jedel1043 in https://github.com/boa-dev/temporal/pull/28 + +## New Contributors +* @nekevss made their first contribution in https://github.com/boa-dev/temporal/pull/1 +* @jedel1043 made their first contribution in https://github.com/boa-dev/temporal/pull/3 + +**Full Changelog**: https://github.com/boa-dev/temporal/commits/v0.0.1 \ No newline at end of file diff --git a/deps/temporal/CONTRIBUTING.md b/deps/temporal/CONTRIBUTING.md new file mode 100644 index 00000000000000..eddeedd2700175 --- /dev/null +++ b/deps/temporal/CONTRIBUTING.md @@ -0,0 +1,51 @@ +# Contributing to Temporal in Rust + +We welcome contributions, feel free to checkout our open issues. If you +find an issue you're interested in, please feel free to ask to be assigned. + +If you're interested in helping out but don't see an issue that's for +you, please feel free to contact us on `Boa`'s Matrix server. + +## Contributor Information + +The Temporal proposal is a new date/time API that is being developed and proposed +for the ECMAScript specification. This library aims to be a Rust +implementation of that specification. + +Due to the nature of the material and this library, we would advise anyone +interested in contributing to familiarize themselves with the Temporal +specification. + +Also, always feel free to reach out for any advice or feedback as needed. + +## Testing and debugging + +For more information on testing and debugging `temporal_rs`. Please see +the [testing overview](./docs/testing.md). + +## Diplomat and `temporal_capi` + +If changes are made to `temporal_capi` that affect the public API, the +FFI bindings will need to be regenerated / updated. + +To update the bindings, run: + +```bash +cargo run -p diplomat-gen +``` + +## Baked data + +To regenerate baked data, run: + +```bash +cargo run -p bakeddata +``` + +## Dependency check + +To check the dependencies, run: + +```bash +cargo run -p depcheck +``` diff --git a/deps/temporal/Cargo.lock b/deps/temporal/Cargo.lock new file mode 100644 index 00000000000000..9db20cc27add39 --- /dev/null +++ b/deps/temporal/Cargo.lock @@ -0,0 +1,1321 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6680de5231bd6ee4c6191b8a1325daa282b415391ec9d3a37bd34f2060dc73fa" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys", +] + +[[package]] +name = "askama" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f75363874b771be265f4ffe307ca705ef6f3baa19011c149da8674a87f1b75c4" +dependencies = [ + "askama_derive", + "itoa", + "percent-encoding", + "serde", + "serde_json", +] + +[[package]] +name = "askama_derive" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "129397200fe83088e8a68407a8e2b1f826cf0086b21ccdb866a722c8bcd3a94f" +dependencies = [ + "askama_parser", + "basic-toml", + "memchr", + "proc-macro2", + "quote", + "rustc-hash", + "serde", + "serde_derive", + "syn", +] + +[[package]] +name = "askama_parser" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6ab5630b3d5eaf232620167977f95eb51f3432fc76852328774afbd242d4358" +dependencies = [ + "memchr", + "serde", + "serde_derive", + "winnow", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "bakeddata" +version = "0.1.0" +dependencies = [ + "databake", + "prettyplease", + "rustc-hash", + "serde_json", + "syn", + "timezone_provider", + "zerovec", +] + +[[package]] +name = "basic-toml" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "calendrical_calculations" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c5d386a9f2c8b97e1a036420bcf937db4e5c9df33eb0232025008ced6104c0" +dependencies = [ + "core_maths", + "displaydoc", +] + +[[package]] +name = "cc" +version = "1.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16595d3be041c03b09d08d0858631facccee9221e579704070e6e9e4915d3bc7" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "colored" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core_maths" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77745e017f5edba1a9c1d854f6f3a52dac8a12dd5af5d2f54aecf61e43d80d30" +dependencies = [ + "libm", +] + +[[package]] +name = "databake" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6ee9e2d2afb173bcdeee45934c89ec341ab26f91c9933774fc15c2b58f83ef" +dependencies = [ + "databake-derive", + "proc-macro2", + "quote", +] + +[[package]] +name = "databake-derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6834770958c7b84223607e49758ec0dde273c4df915e734aad50f62968a4c134" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "depcheck" +version = "0.1.0" + +[[package]] +name = "diplomat" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ece782ffeb426ef0d3074c5623e8f6552cc912e4bbeecfda9583cb01b02b8ba1" +dependencies = [ + "diplomat_core", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "diplomat-gen" +version = "0.1.0" +dependencies = [ + "diplomat-tool", +] + +[[package]] +name = "diplomat-runtime" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa011f69b7f99cd4c4f1545a88cfa5f303abfdd76962843a5e5c88ea7bfe81f4" + +[[package]] +name = "diplomat-tool" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f88fa2be520ed769c790accb955cc51ebc7ceb1e9d87ce4b7db24357e9378bad" +dependencies = [ + "askama", + "clap", + "colored", + "diplomat_core", + "displaydoc", + "heck", + "indenter", + "itertools", + "pulldown-cmark", + "quote", + "serde", + "syn", + "syn-inline-mod", + "toml", +] + +[[package]] +name = "diplomat_core" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb0f9322e2c506400ac3f374abfcaf9fd841fcdb729bbf008a135b600f99ede7" +dependencies = [ + "displaydoc", + "either", + "proc-macro2", + "quote", + "serde", + "smallvec", + "strck", + "syn", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "iana-time-zone" +version = "0.1.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_calendar" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e239d6422e2fdcea5d9756b48400caabac25aa4ab91b6608bd4bb6f23f0558c" +dependencies = [ + "calendrical_calculations", + "displaydoc", + "icu_calendar_data", + "icu_locale", + "icu_locale_core", + "icu_provider", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_calendar_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7219c8639ab936713a87b571eed2bc2615aa9137e8af6eb221446ee5644acc18" + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ae5921528335e91da1b6c695dbf1ec37df5ac13faa3f91e5640be93aa2fbefd" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_locale_data", + "icu_provider", + "potential_utf", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locale_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fdef0c124749d06a743c69e938350816554eb63ac979166590e2b4ee4252765" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "2.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "ixdtf" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08b741faae9005d3c809ca4b8566d75745c408171b3c6bbb54d2b00d04910c1c" +dependencies = [ + "displaydoc", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1283705eb0a21404d2bfd6eef2a7593d240bc42a0bdb39db0ad6fa2ec026524" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.172" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" + +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +dependencies = [ + "serde", +] + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "potential_utf" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +dependencies = [ + "serde", + "zerovec", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pulldown-cmark" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0" +dependencies = [ + "bitflags", + "getopts", + "memchr", + "pulldown-cmark-escape", + "unicase", +] + +[[package]] +name = "pulldown-cmark-escape" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae" + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "resb" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6572f8cee86c6a691a8a1cf8bbf7be8b3d0c02d9f8786ed1929f75e9910dbb" +dependencies = [ + "potential_utf", + "serde", +] + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "serde" +version = "1.0.225" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6c24dee235d0da097043389623fb913daddf92c76e9f5a1db88607a0bcbd1d" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.225" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "659356f9a0cb1e529b24c01e43ad2bdf520ec4ceaf83047b83ddcc2251f96383" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.225" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea936adf78b1f766949a4977b91d2f5595825bd6ec079aa9543ad2685fc4516" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "smallvec" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "strck" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42316e70da376f3d113a68d138a60d8a9883c604fe97942721ec2068dab13a9f" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn-inline-mod" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fa6dca1fdb7b2ed46dd534a326725419d4fb10f23d8c85a8b2860e5eb25d0f9" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "temporal_capi" +version = "0.1.0" +dependencies = [ + "diplomat", + "diplomat-runtime", + "icu_calendar", + "icu_locale", + "num-traits", + "temporal_rs", + "timezone_provider", + "writeable", + "zoneinfo64", +] + +[[package]] +name = "temporal_rs" +version = "0.1.0" +dependencies = [ + "core_maths", + "iana-time-zone", + "icu_calendar", + "icu_locale", + "ixdtf", + "log", + "num-traits", + "resb", + "timezone_provider", + "tinystr", + "web-time", + "writeable", + "zoneinfo64", +] + +[[package]] +name = "timezone_provider" +version = "0.1.0" +dependencies = [ + "combine", + "databake", + "jiff-tzdb", + "serde", + "serde_json", + "tinystr", + "tzif", + "yoke", + "zerotrie", + "zerovec", + "zoneinfo64", + "zoneinfo_rs", +] + +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "databake", + "displaydoc", + "serde", + "zerovec", +] + +[[package]] +name = "toml" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076" + +[[package]] +name = "tzif" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5e762ac355f0c204d09ae644b3d59423d5ddfc5603997d60c8c56f24e429a9d" +dependencies = [ + "combine", +] + +[[package]] +name = "tzif-inspect" +version = "0.1.0" +dependencies = [ + "jiff-tzdb", + "temporal_rs", + "timezone_provider", + "tzif", +] + +[[package]] +name = "unicase" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" +dependencies = [ + "memchr", +] + +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "databake", + "displaydoc", + "litemap", + "serde", + "zerovec", +] + +[[package]] +name = "zerovec" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +dependencies = [ + "databake", + "serde", + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zoneinfo-test-gen" +version = "0.1.0" +dependencies = [ + "clap", + "serde", + "serde_json", + "tzif", +] + +[[package]] +name = "zoneinfo64" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6916519e4a1cff59d49e0b902caed549d85dbbbf623a95af5c8320d5c08c6e13" +dependencies = [ + "calendrical_calculations", + "icu_locale_core", + "potential_utf", + "resb", + "serde", +] + +[[package]] +name = "zoneinfo_rs" +version = "0.0.17" +dependencies = [ + "hashbrown", + "indexmap", + "serde", + "serde_json", + "tzif", +] diff --git a/deps/temporal/Cargo.toml b/deps/temporal/Cargo.toml new file mode 100644 index 00000000000000..f12b83f4ded78c --- /dev/null +++ b/deps/temporal/Cargo.toml @@ -0,0 +1,113 @@ +[workspace] +resolver = "2" +members = [ + "provider", + "temporal_capi", + "zoneinfo", + + # Tools + "tools/*", +] + +[workspace.package] +edition = "2021" +version = "0.1.0" +rust-version = "1.82.0" +authors = ["boa-dev"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/boa-dev/temporal" +readme = "./README.md" +exclude = [ + "docs/*", + ".github/*", + "debug/", + ".gitignore", + "CONTRIBUTING.md", + "cliff.toml", + "tests/data/zoneinfo64.res", +] + +[workspace.dependencies] +# Self +temporal_rs = { version = "~0.1.0", path = ".", default-features = false } +timezone_provider = { version = "~0.1.0", path = "./provider" } +zoneinfo_rs = { version = "~0.0.17", path = "./zoneinfo" } + +# Dependencies +tinystr = "0.8.1" +icu_calendar = { version = "2.0.3", default-features = false } +icu_locale = "2.0.0" +rustc-hash = "2.1.0" +num-traits = { version = "0.2.19", default-features = false } +ixdtf = "0.6.0" +iana-time-zone = "0.1.64" +log = "0.4.28" +tzif = "0.4.0" +jiff-tzdb = "0.1.4" +combine = "4.6.7" +web-time = "1.1.0" +zerovec = "0.11.4" +zoneinfo64 = "0.2.0" + +# Diplomat +diplomat-tool = { version = "0.13.0", default-features = false } +diplomat-runtime = { version = "0.13.0", default-features = false } +diplomat = { version = "0.13.0", default-features = false } + + +[package] +name = "temporal_rs" +keywords = ["date", "time", "calendar", "timezone", "duration"] +categories = ["date-and-time", "internationalization"] +description = "Temporal in Rust is an implementation of the TC39 Temporal Builtin Proposal in Rust." +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +rust-version.workspace = true +readme.workspace = true +exclude.workspace = true + +[dependencies] + +core_maths = "0.1.1" +icu_calendar = { workspace = true, features = ["compiled_data"] } +icu_locale.workspace = true +ixdtf = { workspace = true, features = ["duration"] } +num-traits.workspace = true +tinystr.workspace = true +writeable = "0.6.1" + +# log feature +log = { workspace = true, optional = true } + +# tzdb feature +timezone_provider = { workspace = true } + +# System time feature +web-time = { workspace = true, optional = true } +iana-time-zone = { workspace = true, optional = true } + +[dev-dependencies] +timezone_provider = { workspace = true, features = ["zoneinfo64"] } +zoneinfo64 = { workspace = true } +resb = "0.1.0" + +[features] +default = ["sys"] +log = ["dep:log"] +compiled_data = ["tzdb"] +sys = ["std", "compiled_data", "dep:web-time", "dep:iana-time-zone"] +tzdb = [ + "std", + "timezone_provider/tzif", +] +std = [] + +[package.metadata.cargo-all-features] +denylist = ["default"] +max_combination_size = 4 + +[package.metadata.docs.rs] +all-features = true diff --git a/deps/temporal/LICENSE-Apache b/deps/temporal/LICENSE-Apache new file mode 100644 index 00000000000000..551045b58932a5 --- /dev/null +++ b/deps/temporal/LICENSE-Apache @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2024 Boa + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/deps/temporal/LICENSE-MIT b/deps/temporal/LICENSE-MIT new file mode 100644 index 00000000000000..d5624ad0c1fb69 --- /dev/null +++ b/deps/temporal/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Boa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/deps/temporal/README.md b/deps/temporal/README.md new file mode 100644 index 00000000000000..58b5c3315b6700 --- /dev/null +++ b/deps/temporal/README.md @@ -0,0 +1,295 @@ +# Temporal in Rust + +Temporal is a calendar and timezone aware date/time builtin currently +proposed for addition to the ECMAScript specification. + +`temporal_rs` is an implementation of Temporal in Rust that aims to be +100% test compliant. While initially developed for [Boa][boa-repo], the +crate has been externalized and is being used in other engines such as [V8](https://v8.dev) and [Kiesel](https://codeberg.org/kiesel-js/kiesel). + +For more information on `temporal_rs`'s general position in the Rust +date/time library ecoystem, see our [FAQ](./docs/FAQ.md). + + +Temporal is an API for working with date and time in a calendar +and time zone aware manner. + +temporal_rs is designed with ECMAScript implementations and general +purpose Rust usage in mind, meaning that temporal_rs can be used to implement +the Temporal built-ins in an ECMAScript implementation or generally +used as a date and time library in a Rust project. + +temporal_rs is the primary library for the Temporal API implementation in Boa, Kiesel, +and V8. Each of these engines pass the large ECMAScript conformance test suite for +the specification. + +## Why use temporal_rs? + +As previously mentioned, Temporal is an API for working with date and time in +a calendar and time zone aware manner. This means that calendar and time zone support +are first class in Temporal as well as in temporal_rs. + +For instance, converting between calendars is as simple as providing the calendar as +shown below. + +```rust +use temporal_rs::{PlainDate, Calendar}; +use tinystr::tinystr; +use core::str::FromStr; + +// Create a date with an ISO calendar +let iso8601_date = PlainDate::try_new_iso(2025, 3, 3).unwrap(); + +// Create a new date with the japanese calendar +let japanese_date = iso8601_date.with_calendar(Calendar::JAPANESE); +assert_eq!(japanese_date.era(), Some(tinystr!(16, "reiwa"))); +assert_eq!(japanese_date.era_year(), Some(7)); +assert_eq!(japanese_date.month(), 3) +``` + +Beyond the general calendar use case, temporal_rs has robust support for +time zones which can generally by applied to a `PlainDate` via [`ZonedDateTime`]. + +**Important Note:** The below API is enabled with the +`compiled_data` feature flag. + +```rust +use temporal_rs::{ZonedDateTime, TimeZone}; +use temporal_rs::options::{Disambiguation, OffsetDisambiguation}; + +let zdt = ZonedDateTime::from_utf8( +b"2025-03-01T11:16:10Z[America/Chicago][u-ca=iso8601]", +Disambiguation::Compatible, +OffsetDisambiguation::Reject +).unwrap(); +assert_eq!(zdt.year(), 2025); +assert_eq!(zdt.month(), 3); +assert_eq!(zdt.day(), 1); +// Using Z and a timezone projects a UTC datetime into the timezone. +assert_eq!(zdt.hour(), 5); +assert_eq!(zdt.minute(), 16); +assert_eq!(zdt.second(), 10); + +// You can also update a time zone easily. +let zurich_zone = TimeZone::try_from_str("Europe/Zurich").unwrap(); +let zdt_zurich = zdt.with_timezone(zurich_zone).unwrap(); +assert_eq!(zdt_zurich.year(), 2025); +assert_eq!(zdt_zurich.month(), 3); +assert_eq!(zdt_zurich.day(), 1); +assert_eq!(zdt_zurich.hour(), 12); +assert_eq!(zdt_zurich.minute(), 16); +assert_eq!(zdt_zurich.second(), 10); + +``` + +## Overview + +temporal_rs provides 8 core types for working with date and time. The core types are: + +- [PlainDate] +- [PlainTime] +- [PlainDateTime] +- [ZonedDateTime] +- [Instant] +- [Duration] +- [PlainYearMonth] +- [PlainMonthDay] + +In addition to these types, there are the [`Calendar`] and [`TimeZone`] type that +support the calendars or time zones. The specific support for calendars and time +zones per type are as follows. + +| Temporal type | Category | Calendar support | Time zone support | +|----------------|--------------------------------------|--------------------|--------------------| +| PlainDate | Calendar date | yes | no | +| PlainTime | Wall-clock time | no | no | +| PlainDateTime | Calendar date and wall-clock time | yes | no | +| ZonedDateTime | Calendar date and exact time | yes | yes | +| Instant | Exact time | no | no | +| Duration | None | no | no | +| PlainYearMonth | Calendar date | yes | no | +| PlainMonthDay | Calendar date | yes | no | + +There is also the [`Now`][now::Now], which provides access to the current host system +time. This can then be used to map to any of the above Temporal types. + +**Important Note:** the below example is only available with the `sys` and +`compiled_data` feature flag enabled. + +```rust +use core::cmp::Ordering; +use temporal_rs::{Temporal, Calendar, ZonedDateTime}; +let current_instant = Temporal::now().instant().unwrap(); +let current_zoned_date_time = Temporal::now().zoned_date_time_iso(None).unwrap(); + +/// Create a `ZonedDateTime` from the requested instant. +let zoned_date_time_from_instant = ZonedDateTime::try_new( +current_instant.as_i128(), +*current_zoned_date_time.time_zone(), +Calendar::ISO, +).unwrap(); + +// The two `ZonedDateTime` will be equal down to the second. +assert_eq!(current_zoned_date_time.year(), zoned_date_time_from_instant.year()); +assert_eq!(current_zoned_date_time.month(), zoned_date_time_from_instant.month()); +assert_eq!(current_zoned_date_time.day(), zoned_date_time_from_instant.day()); +assert_eq!(current_zoned_date_time.hour(), zoned_date_time_from_instant.hour()); +assert_eq!(current_zoned_date_time.minute(), zoned_date_time_from_instant.minute()); +assert_eq!(current_zoned_date_time.second(), zoned_date_time_from_instant.second()); + +// The `Instant` reading that occurred first will be less than the ZonedDateTime +// reading +assert_eq!( +zoned_date_time_from_instant.compare_instant(¤t_zoned_date_time), +Ordering::Less +); +``` + +## General design + +While temporal_rs can be used in native Rust programs, the library is -- first and +foremost -- designed for use in ECMAScript implementations. This is not to detract +from temporal_rs's use in a native Rust program, but it is important information to +understand in order to understand the library's architecture and general API design. + +Without default feature flags, temporal_rs does not have with access to the host +environment and it does not embed any time zone data. This is important from an +interpreter perspective, because access to the host environment and time zone data +comes from the interpreter's agent, not from a dependency. + +Instead, temporal_rs provides the [`HostHooks`][host::HostHooks] and [`TimeZoneProvider`][provider::TimeZoneProvider] +traits that can be implemented and provided as function arguments that temporal_rs will +use to access the host system or time zone data. temporal_rs also provides some baseline +implementations of the traits that can be selected from depending on application needs. + +That being said, this does not mean that everyone must implement their own trait +implementations for that functionality to exist, but the APIs are there for power +users who may need a custom host system or time zone data implementation. + +A default host system and time zone provider have been implemented and are automatically +active as default features. + +### A quick walkthrough + +For instance, the examples thus far have been using the general usage Rust API with +the `sys` and `compiled_data` feature. + +For instance, let's manually write our [`Now`][now::Now] implementation instead of using +[`Temporal::now()`] with an empty host system implementation. + +```rust +use temporal_rs::{Instant, now::Now, host::EmptyHostSystem}; + +// The empty host system is a system implementation HostHooks that always +// returns the UNIX_EPOCH and the "+00:00" time zone. +let now = Now::new(EmptyHostSystem); +let time_zone = now.time_zone().unwrap(); +assert_eq!(time_zone.identifier().unwrap(), "+00:00"); +let now = Now::new(EmptyHostSystem); +assert_eq!(now.instant(), Instant::try_new(0)); +``` + +However, even in our above example, we cheated a bit. We were still relying on the +`compiled_data` feature flag that provided time zone data for us. Let's try again, +but this time without the feature flag. + +```rust +use temporal_rs::{Instant, now::Now, host::EmptyHostSystem}; +use timezone_provider::tzif::CompiledTzdbProvider; + +let provider = CompiledTzdbProvider::default(); + +// The empty host system is a system implementation HostHooks that always +// returns the UNIX_EPOCH and the "+00:00" time zone. +let now = Now::new(EmptyHostSystem); +let time_zone = now.time_zone_with_provider(&provider).unwrap(); +assert_eq!(time_zone.identifier_with_provider(&provider).unwrap(), "+00:00"); + +let now = Now::new(EmptyHostSystem); +assert_eq!(now.instant(), Instant::try_new(0)); +``` + +Now -- pun only partially intended -- we've successfully written a no-default-features +example with temporal_rs! + +### What have we learned going over this all this? + +First, any API that has the suffix `_with_provider` is a power user API for supplying +a custom or specific time zone data provider. Furthermore, any API that has a +`_with_provider` suffix will also have a version without the suffix that automagically +provides time zone data for you. + +Finally, sourcing time zone data is a very scary (but fun!) business. If you're interested +in learning more, feel free to check out the `timezone_provider` crate! + +With any luck, this also highlights the general design of temporal_rs. It provides a +general usage API that aligns with the Temporal specification while also being +flexible enough to provide an power user to take control of their host system access +and time zone data sourcing as needed. + +## Formatting + +temporal_rs adheres to Temporal grammar, which is a strict version of +[RFC9557's IXDTF][ixdtf]. RFC9557 is an update to RFC3339 that adds +extensions to the format. + +## More information + +[`Temporal`][proposal] is the Stage 3 proposal for ECMAScript that +provides new JS objects and functions for working with dates and +times that fully supports time zones and non-gregorian calendars. + +This library's primary development source is the Temporal +Proposal [specification][spec]. + +## Temporal proposal + +Relevant links and information regarding Temporal can be found below. + +- [Temporal MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal) +- [Temporal Documentation](https://tc39.es/proposal-temporal/docs/) +- [Temporal Proposal Specification](https://tc39.es/proposal-temporal/) +- [Temporal Proposal Repository](https://github.com/tc39/proposal-temporal) + +## Core maintainers + +- [Kevin Ness](https://github.com/nekevss) +- [Manish Goregaokar](https://github.com/Manishearth) +- [José Julián Espina](https://github.com/jedel1043) +- [Jason Williams](https://github.com/jasonwilliams) +- [Haled Odat](https://github.com/HalidOdat) +- [Boa Developers](https://github.com/orgs/boa-dev/people) + +## Contributing + +This project is open source and welcomes anyone interested to +participate. Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for more +information. + +## Test262 Conformance + + + +The `temporal_rs`'s current conformance results can be viewed on Boa's +[test262 conformance page](https://boajs.dev/conformance). + +## FFI + +`temporal_rs` currently has bindings for C++, available via the +`temporal_capi` crate. + +## Communication + +Feel free to contact us on +[Matrix](https://matrix.to/#/#boa:matrix.org). + +## License + +This project is licensed under the [Apache](./LICENSE-Apache) or +[MIT](./LICENSE-MIT) licenses, at your option. + +[boa-repo]: https://github.com/boa-dev/boa +[ixdtf]: https://www.rfc-editor.org/rfc/rfc9557.txt +[proposal]: https://github.com/tc39/proposal-temporal +[spec]: https://tc39.es/proposal-temporal/ + diff --git a/deps/temporal/cliff.toml b/deps/temporal/cliff.toml new file mode 100644 index 00000000000000..9fc7f12586cf6f --- /dev/null +++ b/deps/temporal/cliff.toml @@ -0,0 +1,88 @@ +# git-cliff ~ configuration file +# https://git-cliff.org/docs/configuration + +[remote.github] +owner = "boa-dev" +repo = "temporal" + +[changelog] +body = """ +## What's Changed + +{%- if version %} in {{ version }}{%- endif -%} +{% for commit in commits %} + {% if commit.remote.pr_title -%} + {%- set commit_message = commit.remote.pr_title -%} + {%- else -%} + {%- set commit_message = commit.message -%} + {%- endif -%} + * {{ commit_message | split(pat="\n") | first | trim }}\ + {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%} + {% if commit.remote.pr_number %} in \ + [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }}) \ + {%- endif %} +{%- endfor -%} + +{% if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %} + {% raw %}\n{% endraw -%} + ## New Contributors +{%- endif %}\ +{% for contributor in github.contributors | filter(attribute="is_first_time", value=true) %} + * @{{ contributor.username }} made their first contribution + {%- if contributor.pr_number %} in \ + [#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \ + {%- endif %} +{%- endfor -%} + +{% if version %} + {% if previous.version %} + **Full Changelog**: {{ self::remote_url() }}/compare/{{ previous.version }}...{{ version }} + {% endif %} +{% else -%} + {% raw %}\n{% endraw %} +{% endif %} + +{%- macro remote_url() -%} + https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }} +{%- endmacro -%} +""" +# remove the leading and trailing whitespace from the template +trim = true +# changelog footer +footer = """ + +""" +# postprocessors +postprocessors = [] + +[git] +# parse the commits based on https://www.conventionalcommits.org +conventional_commits = false +# filter out the commits that are not conventional +filter_unconventional = false +# process each line of a commit as an individual commit +split_commits = false +# regex for preprocessing the commit messages +commit_preprocessors = [ + # remove issue numbers from commits + { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "" }, +] +# Commit grouping +commit_parsers = [ + { message = "^chore(release):", skip = true}, + { field = "author.name", pattern = "dependabot", skip = true } +] +# protect breaking changes from being skipped due to matching a skipping commit_parser +protect_breaking_commits = false +# filter out the commits that are not matched by commit parsers +filter_commits = false +# regex for matching git tags +tag_pattern = "v[0-9].*" +# regex for skipping tags +skip_tags = "beta|alpha" +# regex for ignoring tags +ignore_tags = "rc" +# sort the tags topologically +topo_order = false +# sort the commits inside sections by oldest/newest order +sort_commits = "newest" diff --git a/deps/temporal/docs/FAQ.md b/deps/temporal/docs/FAQ.md new file mode 100644 index 00000000000000..ed20345566e7e7 --- /dev/null +++ b/deps/temporal/docs/FAQ.md @@ -0,0 +1,50 @@ +# FAQ + +## Why should I use `temporal_rs`? + +`temporal_rs` implements the Temporal API in Rust. + +The Temporal API is designed to be a calendar and time zone aware +date/time API. + +`temporal_rs` may fit your use case if any of the below are true: + +- You are implementing the Temporal API in a JavaScript engine or any + other language. +- You have internationalization date/time needs for different calendars + that do not involve the ISO / proleptic Gregorian calendar. +- You really like the JavaScript Temporal built-in and would like to use + a similar API that you are familiar with. +- Idk, are you a big [ECMA402][ecma402-spec] fan? Than we might be your jam. + +## Why not use `jiff` to implement Temporal? + +There are a few reasons why `jiff` was not used for Boa's Temporal +implementation. + +Primary reasons: + +- `temporal_rs` is older than `jiff`; so, it was not an option when the + work on `temporal_rs` began +- `jiff` is inspired by Temporal, while `temporal_rs` aims to be a 100% + compliant implementation. `jiff` can break from the specification if + it would like where `temporal_rs` is bound to the specification + behavior. + +Other concerns: + +- Time zones are designed around the concept of BYOP (Bring your own + provider). This is VERY important for engines to be able to define + their own time zone providers. +- Without feature flags, `temporal_rs`'s `Now` does not ship with a + clock as this is left to JavaScript engines. +- Calendar support is first class in `temporal_rs`. The library aims to + support all ECMA402 defined calendars. `jiff` primarily implements the + ISO calendar with some support for other calendars through `jiff_icu`. + +## Why not use other date/time Rust crates `chrono`, `time` and `hifitime`? + +These crates provide fantastic APIs for their intended goal, but most +are designed for use with the proleptic Gregorian calendar. + +[ecma402-spec]: https://tc39.es/ecma402/ \ No newline at end of file diff --git a/deps/temporal/docs/README.md b/deps/temporal/docs/README.md new file mode 100644 index 00000000000000..645d85a00c7b0a --- /dev/null +++ b/deps/temporal/docs/README.md @@ -0,0 +1,3 @@ +# Temporal Documentation + +This documentation is intended to eventually serve as supplementary repo specific material and documentation. diff --git a/deps/temporal/docs/TZDB.md b/deps/temporal/docs/TZDB.md new file mode 100644 index 00000000000000..5f66f525fdceca --- /dev/null +++ b/deps/temporal/docs/TZDB.md @@ -0,0 +1,41 @@ +# General TZDB implementation notes + +Below are some logs of the logic currently at play to find the local +time records based off user provided nanoseconds (seconds). + +Important to note, that currently the logs only exist for notably +/- +time zones that observe DST. + +Further testing still needs to be done for time zones without any DST +transition / potentially historically abnormal edge cases. + +## Slim format testing + +`jiff_tzdb` and potentially others use a different compiled `tzif` +than operating systems. + +Where operating systems use the "-b fat", smaller embedded tzifs may +use "-b slim" (it's also worth noting that slim is the default setting) + +What does slim actually do? The slim formats "slims" the size of a tzif +by calculating the transition times for a smaller range. Instead of calculating +the transition times in a larger range, the tzif (and thus user) differs to +the POSIX tz string. + +So in order to support "slim" format `tzif`s, we need to be able to resolve the +[POSIX tz string](glibc-posix-docs). + +### Running tests / logging + +While using `jiff_tzdb`, the binary search will run the below: + +Running a date from 2017 using jiff: + +time array length: 175 +Returned idx: Err(175) + +This will panic, because we have gone past the supported transition times, so +we should default to parsing the POSIX tz string. + + +[glibc-posix-docs]:https://sourceware.org/glibc/manual/2.40/html_node/Proleptic-TZ.html diff --git a/deps/temporal/docs/architecture.md b/deps/temporal/docs/architecture.md new file mode 100644 index 00000000000000..17980052f92a9a --- /dev/null +++ b/deps/temporal/docs/architecture.md @@ -0,0 +1,108 @@ +# Library Architecture + +TODO: FFI docs + +This doc provides an overview of the layout of `temporal_rs`. + +We will go over the Temporal Date/Time builtins, general primitives, and +utiltity crates. + +## `temporal_rs` design considerations + +`temporal_rs` is first and foremost designed to be a fully spec +compliant implementation of ECMAScript's Temporal date/time builtins. + +As such, the main design consideration of `temporal_rs` is that it needs +to be able to service language interpreters / engines. + +Thus, `temporal_rs` aims to provide an API along with tools to implement +Temporal while minimizing issue with integrating Temporal into engines. + +## Date/Time builtins + +The primary date & time builtins/components are located in the +`builtins` directory. + +These builtins are then reexported from `lib.rs` to be available from +`temporal_rs`'s root module. + +### Core vs. Compiled + +`temporal_rs`'s builtins are split in two distinct directories `core` +and `compiled`. The core implementation contains the core implementation +of the Temporal builtins; meanwhile, the `compiled` implementation provides +method wrappers around the `core` methods that simplify some "lower" level +date/time APIs that may not be necessary for a general use case. + +### Core implementation + +The core implementation is always publicly available, but may not be +available to import from the `temporal_rs`'s root. + +The core implementation exposes the Provider API that allows the user to +supply a "provider", or any type that implements the `TimeZoneProvider` +trait, for time zone data that the library can use to complete it's +calculations. This is useful from an engine / implementor perspective +because it allows the engine to source time zone data in their preferred +manner without locking them into a library specific implementation that +may or may not have side effects. + +A `TimeZoneProvider` API on a core builtin will look like the below. + +```rust +impl ZonedDateTime { + pub fn day_with_provider(&self, provider: &impl TimeZoneProvider) -> TemporalResult { + // Code goes here. + } +} +``` + +### Compiled implementation + +The native implementation is only available via the "compiled" default +feature flag. + +For the same reason that the Provider API is useful for language +implementors, it is a deterent from a general use case perspective. Most +people using a datetime library, outside of the self-proclaimed time +zone nerds, probably won't care from where their time zone data is being +sourced. + +The native Rust wrapper of the core implementation provides a default +provider implementation to remove the need of the user to think or deal +with `TimeZoneProvider`. + +```rust +impl ZonedDateTime { + pub fn day(&self) -> TemporalResult { + // Code goes here. + } +} +``` + +This greatly simplifies the API for general use cases. + +## Primitives + + + +`temporal_rs` has a primitive number implementation `FiniteF64` along +with a few date and time primitives: `IsoDate`, `IsoTime`, +`IsoDateTime`, and `EpochNanoseconds`. + +`FiniteF64` allows an interface to translate between ECMAScript's number +type vs. `temporal_rs`'s strictly typed API. + +Meanwhile the Date and Time primitives allow certain invariants to be +enforced on their records. + +## Utiltiies + +`temporal_rs` provides one implementation of the `TimeZoneProvider` +trait: `FsTzdbProvider`. + +`FsTzdbProvider` reads from the file systems' tzdb and when not +available on the system, `FsTzdbProvider` relies on a prepackaged +`tzdb`. + + diff --git a/deps/temporal/docs/design/initial-api-concept.md b/deps/temporal/docs/design/initial-api-concept.md new file mode 100644 index 00000000000000..fc23ba0876d359 --- /dev/null +++ b/deps/temporal/docs/design/initial-api-concept.md @@ -0,0 +1,68 @@ +# Temporal API Design + +This design hopes to layout an initial concept to adapting the `Temporal` API for Rust. The layout +was broadly mentioned in a previous PR earlier in the development of `Temporal`. This write up is to +mainly overview the API, and provide context to any potential contributors. + +There are three incredibly important points to keep in mind during the design and implementation + +1. This library should empower any language engine to implement `Temporal` to a high degree of fidelity. +2. This library should be able to provide a non-engine API consumable by any potential user. + +Admittedly, as this library is being designed for use in a `JavaScript` engine. One takes priority, +but that should not completely overshadow the two. + +The largest concerns come around the implementation for both `Calendar` and `TimeZone` (aka, `CalendarSlot` +and `TimeZoneSlot`). + +Date is defined (broadly) as: + +```rust + +// In `Boa`, Date is represented as Date +struct Date { + iso: IsoDate, + calendar: CalendarSlot, +} + +``` + +In this instance, C represents any Custom Calendar implementation that is required by the `Temporal` +specification. It is also fundamental to the design of the library; however, it introduces an +interesting API concern. + +Primarily, what if someone doesn't want to implement a custom Calendar? Well, that's easy, we can just +use `Date<()>`. That's easy. We've solved the great API crisis! + +But there's a catch. To provide utility to engine implementors, `CalendarProtocol` implements a `Context` +associated type. In order to have access to that context, it needs to be passed in as an argument. + +So in an engine, like Boa, this may look like. + +```rust +// Theoretically, fetching a the year value with context. +let year_value = Date.year(context); +``` + +But this API, makes the non-engine API just that much more cumbersome. + +```rust +// A user fetching a year value. +let year_value = Date<()>.year(&mut ()); +``` + +There is also the chance that some user WANTS to implement a custom calendar, but does NOT need any `Context`. + +```rust +let year_value = Date.year(&mut ()); +``` + +The API in this instance is not necessarily bad, per se. It's just it could be better for non-engine consumers. + +In order to address this issue, this design concept would require that any function that needs a `Context` argument +clearly labels itself as such. + +```rust +let year_1 = Date<()>.year(); +let year_2 = Date<()>.year_with_context(&mut ()); +``` diff --git a/deps/temporal/docs/release.md b/deps/temporal/docs/release.md new file mode 100644 index 00000000000000..deba1eeb1d5c21 --- /dev/null +++ b/deps/temporal/docs/release.md @@ -0,0 +1,40 @@ +# Release process + +The steps for preparing and making a new release for `temporal_rs` and +its crates are as follows. + +1. Fetch the remote refs and tags (`git fetch --tags`) +2. Create and checkout release prep branch +3. Bump the version in the workspace Cargo.toml in the workspace package + and dependencies sections +4. Update the CHANGELOG with git cliff (See below for more information) +5. Commit changes to branch + - (Optional / recommended) A dry run publish could be preemptively run with + `cargo workspaces publish --dry-run` +6. Push to Github/remote, make pull request, and merge release prep. +7. Draft a new release targeting `main` with a `vx.x.x` tag +8. Publish release + +## Release post + +The release post generally includes the CHANGELOG content; however, an +introduction may be added if the individual making the release would +like to write one. + +## Git Cliff + +Updating the CHANGELOG with the below commits by running: + +```bash +git cliff $PREVIOUS_TAG.. --tag $RELEASE_TAG --prepend CHANGELOG.md +``` + +`$PREVIOUS_TAG` is the tag for the last release while `$RELEASE_TAG` is +the upcoming release tag. + +For example, in order to prep for release `v0.0.9`, the git cliff +command would be: + +```bash +git cliff v0.0.8.. --tag v0.0.9 --prepend CHANGELOG.md +``` diff --git a/deps/temporal/docs/testing.md b/deps/temporal/docs/testing.md new file mode 100644 index 00000000000000..bd04e1ec0adacc --- /dev/null +++ b/deps/temporal/docs/testing.md @@ -0,0 +1,77 @@ +## Testing `temporal_rs` + +Temporal's primary test suite is the [Temporal `test262` test +suite][test262-temporal]. There is an open issue / PR to extract +the tests from test262 into a format that `temporal_rs` can run +against in native Rust. + +In the meantime, there are two primary ways to test: + +1. Map the test into a Rust version in the `test` module in + `temporal_rs`. (Ex: [Duration's tests][duration-test-mod]) + +2. Implement the feature in a relevant ECMAScript interpreter / engine, + and run the engine through the test suite. + +### Testing with Boa + +Testing with Boa can be completed fairly easily. First and definitely +not least, implement the feature in Boa. Boa's Temporal builtin can be +found [here][boa-temporal]. + +Once implemented, the builtin Temporal test suite can be run with the +command: + +```bash +cargo run --bin boa_tester -- run -vv --console -s test/built-ins/Temporal +``` + +The `intl402` Temporal test suite can be run with: + +```bash +cargo run --bin boa_tester -- run -vv --console -s test/intl402/Temporal +``` + +#### Specify method test suites + +The test suite can be further specified by qualifying the path. In order +to run the tests for `ZonedDateTime.prototype.add`, run: + +```bash +cargo run --bin boa_tester -- run -vv --console -s test/built-ins/Temporal/ZonedDateTime/prototype/add +``` + +#### Debugging single `test262` tests + +When debugging a specific test, the test output can be viewed by running +the test in verbose mode (`-vvv`): + +```bash +cargo run --bin boa_tester -- run -vvv --console -s test/built-ins/Temporal/Instant/compare/argument-string-limits.js +``` + +Running the above command will output whether the test failed or passed, +and the test failure output if failed. + +```txt +Getting last commit on 'HEAD' branch +Loading the test suite... +Test loaded, starting... +`/home/user/Projects/boa/test262/test/built-ins/Temporal/Instant/compare/argument-string-limits.js`: starting +`/home/user/Projects/boa/test262/test/built-ins/Temporal/Instant/compare/argument-string-limits.js`: Failed +`/home/user/Projects/boa/test262/test/built-ins/Temporal/Instant/compare/argument-string-limits.js`: result text +Uncaught RangeError: Instant nanoseconds are not within a valid epoch range. +``` + +### A note on testing with ECMAScript implementations + +Any ECMAScript implementation implementing `temporal_rs` will require +some level of glue code in order to move from the implementation to +`temporal_rs`. So when debugging, it is important to determine that the +error falls in `temporal_rs`. + +[test262-temporal]: + https://github.com/tc39/test262/tree/main/test/built-ins/Temporal +[duration-test-mod]: ./src/components/duration/tests.rs +[boa-temporal]: + https://github.com/boa-dev/boa/tree/main/core/engine/src/builtins/temporal diff --git a/deps/temporal/provider/Cargo.toml b/deps/temporal/provider/Cargo.toml new file mode 100644 index 00000000000000..9e40a10233a5f2 --- /dev/null +++ b/deps/temporal/provider/Cargo.toml @@ -0,0 +1,75 @@ +[package] +name = "timezone_provider" +description = "Time zone data providers" +edition.workspace = true +version.workspace = true +rust-version.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +include = [ + "src/**/*.rs", + "src/data/*.rs.data", + "Cargo.toml", + "LICENSE-Apache", + "LICENSE-MIT", + "README.md", +] + +[features] +# Allow people to use default-features = false +default = [] +datagen = [ + "std", + "dep:serde", + "dep:databake", + "dep:yoke", + "dep:serde_json", + "tinystr/serde", + "tinystr/databake", + "zerotrie/serde", + "zerotrie/databake", + "zerovec/serde", + "zerovec/databake", + "zerovec/derive", + "dep:zoneinfo_rs", + "experimental_tzif", +] +std = [] +# Experimental tzif/tzdb compiled data +experimental_tzif = [] + +# Performing timezone resolution with the `tzif` crate +tzif = ["dep:tzif", + "dep:jiff-tzdb", + "dep:combine", + "std"] + +# Performing timezone resolution using the `zoneinfo64` crate +# (ICU4C zoneinfo64.res) +zoneinfo64 = ["dep:zoneinfo64"] + +[dependencies] + +# Provider dependency +zerotrie = "0.2.2" +zerovec = { workspace = true, features = ["derive", "alloc"] } +tinystr = { workspace = true, features = ["zerovec"] } + +# IANA dependency +zoneinfo_rs = { workspace = true, features = ["std"], optional = true } + +# tzif dependency +tzif = { workspace = true, optional = true } +jiff-tzdb = { workspace = true, optional = true } +combine = { workspace = true, optional = true } + +# zoneinfo64 dependency +zoneinfo64 = { workspace = true, optional = true } + +# Databake dependencies +serde = { version = "1.0.225", features = ["derive"], optional = true } +databake = { version = "0.2.0", features = ["derive"], optional = true } +yoke = { version = "0.8.0", features = ["derive"], optional = true } +serde_json = { version = "1.0.145", optional = true } + diff --git a/deps/temporal/provider/LICENSE-Apache b/deps/temporal/provider/LICENSE-Apache new file mode 100644 index 00000000000000..551045b58932a5 --- /dev/null +++ b/deps/temporal/provider/LICENSE-Apache @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2024 Boa + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/deps/temporal/provider/LICENSE-MIT b/deps/temporal/provider/LICENSE-MIT new file mode 100644 index 00000000000000..d5624ad0c1fb69 --- /dev/null +++ b/deps/temporal/provider/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Boa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/deps/temporal/provider/README.md b/deps/temporal/provider/README.md new file mode 100644 index 00000000000000..e1d849f4acf7d2 --- /dev/null +++ b/deps/temporal/provider/README.md @@ -0,0 +1,63 @@ +# Time zone providers + + + +Providers for time zone data + +Let's talk about time zone data everyone! + +At a high level, the `timezone_provider` crate provides a set of traits along with a few +implementations of those traits. The general intention here is to make providing time zone +data as agnostic and easy as possible. + +This crate is fairly "low level" at least as far as date and time needs are concerned. So +we'll cover the basic overview of the trait and some of the general implementations of +those traits, and then we will go on a bit further of a dive for the power users that +are interested in implementing their own provider or is just really curious about what +is going on. + +### Available providers + +Below is a list of currently available time zone providers. + +- `ZoneInfo64TzdbProvider`: a provider using ICU4C's zoneinfo64 resource bundle (enable with `zoneinfo64` features flag) +- `FsTzdbProvider`: a provider that reads and parses tzdata at runtime from the host file system's +TZif files (enable with `tzif` feature flag) +- `CompiledTzdbProvider`: a provider that reads and parses tzdata at runtime from TZif's compiled +into the application (enable with `tzif` feature flag) + +Coming soon (hopefully), a zero copy compiled tzdb provider (see `experimental_tzif` for more). + +### Time zone provider traits + +This crate provides three primary traits for working with time zone data. + +- [`TimeZoneProvider`][crate::provider::TimeZoneProvider] +- [`TimeZoneNormalizer`][crate::provider::TimeZoneNormalizer] +- [`TimeZoneResolver`][crate::provider::TimeZoneResolver] + +The first trait `TimeZoneProvider` is the primary interface for a time zone provider used by `temporal_rs`. + +Meanwhile, the two other traits, `TimeZoneNormalizer` and `TimeZoneResolver`, are secondary +traits that can be used to implement the core `TimeZoneProvider`. Once implemented, this +crate providers a default type for creating a `TimeZoneProvider` by mixing and matching objects that implement the secondary +traits, `NormalizerAndResolver`. + +#### Why two secondary traits? + +Well that's because `TimeZoneProvider` handles two different concerns: fetching and +formatting normalized and canonicalized time zone identifiers, and resolving time +zone data requests. This functionality typically requires two different sets of data, +each of which may be in a variety of formats. + +#### Why not just have the two secondary traits without `TimeZoneProvider`? + +Well while the functionality typically requires two sets of data. Those sets are not +necessarily completely unique. The time zone database updates potentially multiple times a +year so having your formatting in 2025a while your data is in 2025b could cause some +desync. So in order to better represent this `TimeZoneProvider` is used on top of them. + +**NOTE:** you CAN always just directly use `TimeZoneNormalizer` and +`TimeZoneResolver` together if you want. We just wouldn't recommemnd it. + + diff --git a/deps/temporal/provider/src/data/compiled_zoneinfo_provider.rs.data b/deps/temporal/provider/src/data/compiled_zoneinfo_provider.rs.data new file mode 100644 index 00000000000000..f1de69eaa08ffc --- /dev/null +++ b/deps/temporal/provider/src/data/compiled_zoneinfo_provider.rs.data @@ -0,0 +1,16 @@ +//@generated +// (by `bakeddata` binary in temporal_rs, using `databake`) + +#[macro_export] +macro_rules! compiled_zoneinfo_provider { + ($providername:ident) => { + pub const $providername : & 'static + timezone_provider::experimental_tzif::ZoneInfoProvider = & + timezone_provider::experimental_tzif::ZoneInfoProvider { ids : + zerotrie::ZeroAsciiIgnoreCaseTrie { store : unsafe { + zerovec::ZeroVec::from_bytes_unchecked(b"\xE1tabcefghijklmnprstuwz\x0E\x0F\x0F\x12\x12\x13\x13\x13\x13\x13\x13\x14\x14\x15\x15\x16\x16\x16\x16\xDE\x05\x9D\xEF\xF7 /\xB5\xC4\xCE\xD4\x08\x1B\xF5\xFE\x08\x0F\xA6\xB1\xE1gfmnrstu\x01\t\t\t\r\r\xF7\x05\x86\x99`\xE4rica/\xE1rabcdefghjklmnopstw\0\0\0\0\0\0\0\0\0\0\x01\x01\x01\x01\x01\x01\x01/i\x88\xAC\xB4\xBC\xC4\xCA\xDC\xFD+Z}\x88\x92\x9A\xB3\xC5bcdls\x06\n\x14\x1Aidjan\x80cra\x80dis_ababa\x8Dgiers\x81m\xC2ae\x03ra\x8Dra\x8D\xC5ailru\x12\x17\x1E(\xC2mn\x04ako\x80\xC2gj\x03ui\x8Aul\x80ssau\x82antyre\x8Bazzaville\x8Ajumbura\x8B\xC3aeo\x0F\x13\xC2is\x03ro\x83ablanca\x84uta\x85nakry\x80\xC3ajo\x12\x19\xC2kr\x03ar\x80_es_salaam\x8Dibouti\x8Duala\x8Al_aaiun\x86reetown\x80aborone\x8Barare\x8B\xC2ou\x0Bhannesburg\x87ba\x88\xC3ahi\x06\rmpala\x8Dartoum\x89\xC2gn\x04ali\x8Bshasa\x8A\xC4aiou\x04\r\x10gos\x8Abreville\x8Ame\x80\xC3abs\x04\x0Cnda\x8Aumbashi\x8Baka\x8B\xC3abo\x12\x18\xC3lps\x04\x08abo\x8Auto\x8Beru\x87abane\x87\xC2gn\x07adishu\x8Drovia\x8C\xC4adio\x06\r\x12irobi\x8Djamena\x8Eamey\x8Auakchott\x80uagadougou\x80orto-novo\x8Aao_tome\x8F\xC3iru\x07\x0Embuktu\x80ipoli\x90\0nis\x90\x01indhoek\x90\x02erica/\xE1vabcdefghijklmnoprstvwy\0\x01\x01\x02\x02\x02\x02\x02\x03\x03\x03\x03\x04\x04\x04\x05\x05\x06\x06\x06\x06\xE7F\xF4-Xv\xD1\xEEg\x7F\xB7\xEC\x92\xEC\xF4g\xB0M\x87\x9A\xB0\xC5dnrst\x04\x1F\xC7\xCFak\x90\x03\xC3cgt\x08\x0Fhorage\x90\x04uilla\x90eigua\x90e\xC3agu\x08\x9Eguaina\x90\x05entina/\xC9bcjlmrstu\r17@HUmuuenos_aires\x90\x06\xC2ao\ttamarca\x90\x07\xC2mr\rodrivadavia\x90\x07doba\x90\x08ujuy\x90\ta_rioja\x90\nendoza\x90\x0Bio_gallegos\x90\x0Ca\xC2ln\x04ta\x90\r_\xC2jl\x05uan\x90\x0Euis\x90\x0Fucuman\x90\x10shuaia\x90\x11ba\x90euncion\x90\x12\xC2ik\x07kokan\x90`a\x90\x03\xC5aelou\x1A&2I\xC2hr\x0Fia\x90\x13_banderas\x90\x14bados\x90\x15l\xC2ei\x03m\x90\x16ze\x90\x17anc-sablon\x90e\xC3agi\x08\r_vista\x90\x18ota\x90\x19se\x90\x1Aenos_aires\x90\x06\xC6ahioruCTa\x8C\x93\xC5mnrty\x19\x1E$,\xC2bp\x0Bridge_bay\x90\x1Bo_grande\x90\x1Ccun\x90\x1Dacas\x90\x1Eamarca\x90\x07\xC2em\x05nne\x90\x1Fan\x90`i\xC2ch\x05ago\x90 uahua\x90!udad_juarez\x90\"\xC3rsy\x14\x1D\xC2ad\x0Bl_harbour\x90`oba\x90\x08ta_rica\x90#haique\x90$eston\x90b\xC2ir\x05aba\x90%acao\x90e\xC3aeo\x1C+\xC2nw\x0Bmarkshavn\x90&son\x90'_creek\x90(\xC2nt\x05ver\x90)roit\x90*minica\x90e\xC4diln\x08\x10\x1Bmonton\x90+runepe\x90,_salvador\x90-senada\x90vort\xC2_a\x11\xC2nw\x07elson\x90.ayne\x909leza\x90/\xC4loru\t\x1B.ace_bay\x900\xC2do\x06thab\x90^se_bay\x901\xC2ae\tnd_turk\x902nada\x90e\xC2ay\x1C\xC3dty\x08\x0Feloupe\x90eemala\x903aquil\x904ana\x905\xC2ae\x0F\xC2lv\x06ifax\x906ana\x907rmosillo\x908\xC2nqn\xC2dueiana\xC2/pW\xC7ikmptvw\r\x12\x1A%/Andianapolis\x909nox\x90:arengo\x90;etersburg\x90ncennes\x90?inamac\x90@olis\x909vik\x90Aaluit\x90B\xC2au\x07maica\x90C\xC2jn\x04uy\x90\teau\x90D\xC3enr!(ntucky/\xC2lm\x0Bouisville\x90Eonticello\x90Fox_in\x90:alendijk\x90e\xC3aio\x06\n_paz\x90Gma\x90H\xC3suw\n\x13_angeles\x90Iisville\x90Eer_princes\x90e\xC4aeio;ks\xC5cnrtz\x05\x11\"*eio\x90Ja\xC2gu\x04ua\x90Ks\x90L\xC2it\x05got\x90einique\x90Mamoros\x90Natlan\x90O\xC4nrtx\x10\x15\x1E\xC2do\x05oza\x90\x0Bminee\x90Pida\x90Qlakatla\x90Rico_city\x90Squelon\x90Tn\xC2ct\x05ton\x90U\xC3ers\x0F\x14\xC2rv\x05rey\x90Video\x90Weal\x90werrat\x90e\xC5aeiou\x06\x0E\x15Lssau\x90ww_york\x90Xpigon\x90w\xC2mr\x03e\x90Y\xC2ot\x05nha\x90Zh_dakota/\xC3bcn\x07\x0Eeulah\x90[enter\x90\\ew_salem\x90]uk\x90^jinaga\x90_\xC4ahou\x1E%R\xC2nr\x11\xC2ag\x04ma\x90`nirtung\x90Bamaribo\x90aoenix\x90brt\xC3-_o\x0B\x15au-prince\x90cof_spain\x90e_\xC2av\x05cre\x90kelho\x90d\xC2en\nrto_rico\x90eta_arenas\x90f\xC4aeio\x190:\xC2in\nny_river\x90zkin_inlet\x90g\xC3cgs\x05\nife\x90hina\x90iolute\x90jo_branco\x90ksario\x90\x08\xC6achitw2>FK\x84\xC2no&t\xC3aio\x10\x15\xC2_r\x08isabel\x90vem\x90lago\x90m_domingo\x90n_paulo\x90ooresbysund\x90piprock\x90)tka\x90q_\xC6bjkltv\x0B\x11\x17\x1D$arthelemy\x90eohns\x90ritts\x90eucia\x90ehomas\x90eincent\x90eift_current\x90s\xC4ehio\x0B\x1C#gucigalpa\x90tu\xC2ln\x03e\x90uder_bay\x90wjuana\x90vr\xC2ot\x05nto\x90wola\x90e\xC2ai\tncouver\x90xrgin\x90e\xC2hi\nitehorse\x90ynnipeg\x90z\xC2ae\x07kutat\x90{llowknife\x90+tarctica/\xC8cdmprstv\x06\x1D9@H[aasey\x90|\xC2au\x05vis\x90}montdurville\x92@\xC2ac\x11\xC2cw\x08quarie\x90~son\x90\x7Fmurdo\x92(almer\x91\0othera\x91\x01\xC2oy\nuth_pole\x92(owa\x918roll\x91\x02ostok\x91\x03ctic/longyearbyen\x92\x01ia/\xE1uabcdfghijkmnopqrstuvy\0\0\0\0\0\0\x01\x01\x01\x01\x01\x02\x02\x02\x02\x02\x02\x03\x03\x03G\x87\xC1\xF0\xFA\xFF,?]\xD0\xFD\x1F+Miz\xC1\x0BD\\\xC7dlmnqst\x04\n\x0F\x15!3en\x918maty\x91\x04man\x91\x05adyr\x91\x06t\xC2ao\x03u\x91\x07be\x91\x08h\xC2gk\x06abat\x91\thabad\x91\tyrau\x91\n\xC4aeir%+2\xC5ghknr\x06\x0C\x0F\x15hdad\x91\x0Brain\x915u\x91\x0Cgkok\x91\rnaul\x91\x0Eirut\x91\x0Fshkek\x91\x10unei\x91)\xC3aho\x08-lcutta\x91'\xC3iou\x04\x17ta\x91\x11\xC2in\x08balsan\x91Fgqing\x91\xC5abeho\x10\x17'4\xC2is\x05pei\x91?hkent\x91@ilisi\x91A\xC2hl\x05ran\x91B_aviv\x91!im\xC2bp\x03u\x91Chu\x91C\xC2km\x04yo\x91Dsk\x91E\xC4jlrs\r#)ung_pandang\x91,a\xC2an\tnbaatar\x91F_bator\x91Fumqi\x91Gt-nera\x91H\xC2il\tentiane\x91\radivostok\x91I\xC2ae\x0F\xC2kn\x06utsk\x91Jgon\x91K\xC2kr\x0Caterinburg\x91Levan\x91Mlantic/\xC8abcfjmrs\x07\x0F\"0:BKzores\x91Nermuda\x91Oa\xC2np\x05ary\x91Pe_verde\x91Qa\xC2er\x05roe\x91Roe\x91Ran_mayen\x92\x01adeira\x91Seykjavik\x80\xC2ot\ruth_georgia\x91T\xC2_a\x07helena\x80nley\x91Ustralia/\xD0abcdehlmnpqstvwy\x0F%7>DKeo{\x81\x8C\x9B\xA4\xAD\xB2\xC2cd\x03t\x91`elaide\x91Vr\xC2io\x07sbane\x91Wken_hill\x91X\xC2au\x08nberra\x91`rrie\x91[arwin\x91Yucla\x91Zobart\x91[\xC3hio\x03\x0Bi\x91]ndeman\x91\\rd_howe\x91]elbourne\x91^\xC2os\x05rth\x91Yw\x91`erth\x91_ueensland\x91W\xC2oy\x05uth\x91Vdney\x91`asmania\x91[ictoria\x91^est\x91_ancowinna\x91Xrazil/\xC4adew\x05\x0F\x14cre\x90kenoronha\x90Zast\x90oest\x90L\xC5aehsu_b\x83\x8Anada/\xC8acemnpsy\t\x11\x19\"/7Dtlantic\x906entral\x90zastern\x90wountain\x90+ewfoundland\x90racific\x90xaskatchewan\x90iukon\x90yt\x92\x02ile/\xC2ce\x0Continental\x90masterisland\x92+t6cdt\x90 ba\x907\xE1fegistu\0\0\0\0\0\x03\x07\x0B\x14\xBEt\x91\x7Fypt\x83re\x92\x06t\x90`5edt\x90Xc/\xC3guz\x88\x9D\xC2mr{t\x91a\xC3+-04p\xCA0123456789\x02\x10\x12\x14\x16\x18\x1A\x1C\x1E\x91a\x91b\xC3012\x02\x04\x91c\x91d\x91e\x91f\x91g\x91h\x91i\x91j\x91k\x91l\x91m\xCA0123456789\x02\x18\x1A\x1C\x1E \"$&\x91a\x91n\xC501234\x02\x04\x06\x08\x91o\x91p\x91q\x91r\x91s\x91t\x91u\x91v\x91w\x91x\x91y\x91z\x91{\x91aeenwich\x91a\xC3cnt\x03\x0Ct\x91|iversal\x91|c\x91|ulu\x91|rope/\xE1uabcdghijklmnoprstuvwz\0\0\0\0\0\0\0\0\0\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x02'u\x8B\x92\xA7\xB0\xC6\xCD\xED\x14DLQkw\xC1\xDA\xEF\x1B\"\xC4mnst\t\x10\x19sterdam\x92\x02dorra\x91}trakhan\x91~hens\x91\x7F\xC3eru\x18,\xC2lr\x0F\xC2fg\x05ast\x92\x0Erade\x92\0lin\x92\x01\xC2au\ttislava\x92\x14ssels\x92\x02\xC3cds\x08\x0Fharest\x92\x03apest\x92\x04ingen\x92\"\xC2ho\x08isinau\x92\x05penhagen\x92\x01ublin\x92\x06\xC2iu\tbraltar\x92\x07ernsey\x92\x0Eelsinki\x92\x08s\xC2lt\ne_of_man\x92\x0Eanbul\x92\tersey\x92\x0E\xC3aiy\x0B\x16liningrad\x92\n\xC2er\x03v\x92\x0Cov\x92\x0Biv\x92\x0C\xC4ijou\x06\x0F\x15sbon\x92\rubljana\x92\0ndon\x92\x0Exembourg\x92\x02\xC3aio\x17\x1C\xC3dlr\x05\trid\x92\x0Fta\x92\x10iehamn\x92\x08nsk\x92\x11\xC2ns\x05aco\x92\x13cow\x92\x12icosia\x91.slo\x92\x01\xC3aor\x05\x0Eris\x92\x13dgorica\x92\0ague\x92\x14\xC2io\x04ga\x92\x15me\x92\x16\xC5aikot\",27\xC3mnr\x05\x0Eara\x92\x17_marino\x92\x16a\xC2jt\x05evo\x92\0ov\x92\x18mferopol\x92\x19opje\x92\0fia\x92\x1Aockholm\x92\x01\xC2ai\x07llinn\x92\x1Bra\xC2ns\x03e\x92\x1Cpol\x92\x05\xC2lz\tyanovsk\x92\x1Dhgorod\x92\x0C\xC3aio\x0E\x1D\xC2dt\x04uz\x92\"ican\x92\x16\xC2el\x05nna\x92\x1Enius\x92\x1Flgograd\x92 arsaw\x92!\xC2au\x12\xC2gp\x05reb\x92\0orozhye\x92\x0Crich\x92\"actory\x92#\xC3bmr\t\x1A\x92\x0E-eire\x92\x0Et\x91a\xC3+-0\x03\x060\x91a0\x91a\x91aeenwich\x91a\xC2os\x08ngkong\x91\x1Ct\x923\xC4cnrs\x06txeland\x80dian/\xC5ackmr\x0C-7Wntananarivo\x8D\xC2ho\x11\xC2ar\x05gos\x92$istmas\x91\r\xC2cm\x04os\x91Koro\x8Derguelen\x92%a\xC4hluy\x03\n\x12e\x91\x16dives\x92%ritius\x92&otte\x8Deunion\x91\x16an\x91Brael\x91!a\xC2mp\x06aica\x90Can\x91Dwajalein\x927ibya\x90\0\xC2es'\xC2tx\x02\x92\x02ico/\xC2bg\x11aja\xC2ns\x06orte\x90vur\x90Oeneral\x90St\x90b7mdt\x90)\xC2az\x06vajo\x90)\x92(-chat\x92*\xE1daors\x01\x01\x01\xB4\xC4\xC7cific/\xE1qabcefghjkmnprstwy\0\0\0\0\0\0\0\0\0\0\0\x01\x01\x01\x01\x01\x10\x1D,F_\x85\x8E\x97\xBE\xD9\xF71;Ijw\xC2pu\x04ia\x92'ckland\x92(ougainville\x92)h\xC2au\x06tham\x92*uk\x92@\xC3afn\x06\x0Bster\x92+ate\x92,derbury\x924\xC3aiu\x07\x0Bkaofo\x92-ji\x92.nafuti\x92C\xC2au\x12\xC2lm\x08apagos\x92/bier\x920a\xC2dm\talcanal\x921\x922onolulu\x923ohnston\x923\xC4aiow\x06\x10\x16nton\x924ritimati\x925srae\x926ajalein\x927\xC2ai\x11\xC2jr\x05uro\x92Cquesas\x928dway\x92=\xC3aio\x05\turu\x929ue\x92:\xC2ru\x06folk\x92;mea\x92<\xC3aio\x10\x18\xC2gl\x08o_pago\x92=au\x92>tcairn\x92?\xC3hnr\x06\x0Bnpei\x921ape\x921t_moresby\x92@arotonga\x92Aa\xC2im\x05pan\x922oa\x92=\xC3aor\x0E\x17\xC2hr\x05iti\x92Bawa\x92Cngatapu\x92Duk\x92@a\xC2kl\x03e\x92Clis\x92Cap\x92@\xC2lr\x05and\x92!tugal\x92\rc\x91Mai\xC2lr\x10\xC2ae\x05ska\x90\x04utian\x90\x03izona\x90bentral\x90 ast\xC2-e\tindiana\x909rn\x90Xawaii\x923ndiana-starke\x90:\xC2io\x08chigan\x90*untain\x90)acific\x90Iamoa\x92=c\x91|\xC2-e\x04su\x92\x12t\x92\rulu\x91|") + }, }, tzifs : unsafe { + zerovec::vecs::VarZeroVec32::from_bytes_unchecked(b"U\x01\0\0X\0\0\0\x03\x02\0\0l\x02\0\0L\x07\0\0\xE9\x0E\0\0\xE8\x10\0\0\xC8\x17\0\0T\x18\0\0\xEF\x19\0\0\x8A\x1B\0\0\r\x1C\0\0e\x1C\0\0\xD7\x1C\0\0c\x1D\0\0\xD5\x1D\0\0X\x1E\0\0\xE5\x1F\0\0R!\0\0\xC0#\0\0F'\0\0\xCC*\0\0\xEE,\0\0\x83/\0\0!2\0\0\xAD4\0\0A7\0\0\xE99\0\0\x87<\0\0&?\0\0\xB1A\0\0YD\0\0\xF7F\0\0\x9EI\0\0=L\0\0wP\0\0\xF3R\0\0\xAET\0\0\x94U\0\0\xF0V\0\0\xC1Z\0\0A\\\0\0\xBC\\\0\0\x81`\0\0\xAFc\0\0\x0Cg\0\0\x0Bi\0\0\x97i\0\0\0j\0\0\xD5p\0\0vs\0\0 v\0\0\xD1v\0\0?|\0\0\x8A\x7F\0\0\x1B\x81\0\0\xF9\x84\0\0c\x87\0\0,\x8B\0\0d\x8E\0\0\xE5\x91\0\0n\x93\0\0\xE0\x93\0\0G\x99\0\0\xFD\x9A\0\0$\x9E\0\0\xF2\xA3\0\0\x07\xA7\0\0\xAF\xA7\0\x002\xA8\0\0\xB5\xA8\0\0\xF4\xAE\0\0\x1F\xB3\0\0\xF8\xB3\0\0\xC4\xB5\0\0\x97\xB9\0\0\x8C\xBB\0\0\xFC\xBD\0\0\xC8\xBF\0\0\xF3\xC0\0\0\xDA\xC2\0\0\xF6\xC4\0\0\x0B\xC8\0\0(\xCB\0\0E\xCC\0\0\xD7\xCF\0\0\x8E\xD4\0\0\x15\xD8\0\0\x87\xD8\0\0v\xD9\0\0;\xDE\0\0\x03\xE0\0\0\0\xE1\0\0n\xE2\0\0\xE9\xE2\0\0W\xE4\0\0|\xE5\0\0\xF3\xE8\0\0\xF2\xE9\0\0\xE8\xEB\0\0X\xED\0\0L\xEF\0\0\xD6\xF4\0\0\r\xF6\0\0\x0E\xF9\0\0\x95\xFF\0\0\x01\x03\x01\0\xB7\x04\x01\0w\x08\x01\0\x18\x0C\x01\0\xAE\x0F\x01\0&\x13\x01\0\xC7\x15\x01\x000\x16\x01\0\xBB\x16\x01\0u\x17\x01\0r\x19\x01\0\xCE\x1A\x01\0I\x1B\x01\0\x1F \x01\0\x17#\x01\0\xCD$\x01\0\n'\x01\0\x03*\x01\0z+\x01\0\xE8,\x01\x0022\x01\0<3\x01\0\xA26\x01\0_:\x01\0\xE4=\x01\0\xD5D\x01\0\x04F\x01\0\x9AF\x01\0,H\x01\x006L\x01\0\xA2R\x01\0\x8BW\x01\0i[\x01\0.`\x01\0\x81c\x01\0qd\x01\0\x07e\x01\0\x9Ah\x01\0\x03i\x01\0ql\x01\0\xC9l\x01\x003m\x01\0\xAEm\x01\0\x01p\x01\0ps\x01\0tv\x01\0\xDDx\x01\0P{\x01\0\xA4|\x01\0\x19\x7F\x01\0>\x80\x01\0\xC2\x81\x01\0#\x82\x01\0\x05\x85\x01\0\xA5\x87\x01\0\xFA\x89\x01\0\xDB\x8C\x01\0\x9C\x8D\x01\0=\x92\x01\0\xEB\x92\x01\0f\x93\x01\0\xBE\x93\x01\0\xFE\x94\x01\0d\x98\x01\0\x97\xA1\x01\0\xDC\xAA\x01\0\x8C\xAB\x01\0\x81\xAE\x01\0\x90\xB0\x01\0q\xB3\x01\0(\xB4\x01\0\x9A\xB4\x01\0\x8E\xB8\x01\0\xF7\xB8\x01\0\xC6\xBB\x01\0~\xBC\x01\0\xE7\xBC\x01\0\xE3\xBF\x01\0\x89\xC0\x01\0a\xC3\x01\0j\xC4\x01\0p\xC7\x01\0Q\xCA\x01\0\xCC\xCA\x01\0\xB6\xCB\x01\0\xBD\xCD\x01\0\x8C\xD0\x01\0n\xD3\x01\0F\xD6\x01\0\xBF\xD8\x01\0n\xD9\x01\0\xF2\xD9\x01\0[\xDA\x01\0\xD8\xDC\x01\0g\xDF\x01\0\xBF\xDF\x01\0\xA9\xE2\x01\0\xFC\xE3\x01\0V\xE5\x01\0X\xE6\x01\0\x18\xE7\x01\0\xF0\xE9\x01\0\xD3\xEB\x01\0\x1D\xED\x01\0q\xEF\x01\0E\xF2\x01\0\xAE\xF2\x01\0 \xF3\x01\0\x02\xF6\x01\0\x11\xF8\x01\0i\xF8\x01\0Z\xFB\x01\x002\xFE\x01\0\n\x01\x02\0\x85\x01\x02\0n\x04\x02\0\"\x07\x02\0u\x0C\x02\x004\x10\x02\0\xD7\x11\x02\0[\x12\x02\0\xDB\x13\x02\0\xF6\x18\x02\0N\x19\x02\0Q\x1C\x02\0\xAD\x1F\x02\0\x82 \x02\0\xEF#\x02\0\x9F$\x02\0\x86%\x02\0=)\x02\0H*\x02\0\xB0,\x02\0\xFB/\x02\0\xE20\x02\0-4\x02\0t4\x02\0\xBB4\x02\0\x025\x02\0I5\x02\0\x905\x02\0\xD75\x02\0\x1E6\x02\0e6\x02\0\xAC6\x02\0\xF36\x02\0:7\x02\0\x817\x02\0\xC87\x02\0\x0F8\x02\0V8\x02\0\x9D8\x02\0\xE48\x02\0+9\x02\0r9\x02\0\xB99\x02\0\0:\x02\0G:\x02\0\x8E:\x02\0\xD5:\x02\0\x1C;\x02\0c;\x02\0\xAA;\x02\0\xF1;\x02\0:=\x02\0\r@\x02\0\x86B\x02\0*D\x02\0\xAEF\x02\0\xE3J\x02\0 M\x02\0\xE4O\x02\0\xADR\x02\0PX\x02\0\xDB\\\x02\0v^\x02\0\x13c\x02\0\x93f\x02\0\\i\x02\0@k\x02\0\xB2p\x02\0\xD3v\x02\0(z\x02\0\x8E}\x02\0\x9D\x80\x02\0\0\x84\x02\0\x16\x88\x02\0\x9A\x8A\x02\0\x06\x8D\x02\0u\x90\x02\0\\\x93\x02\x000\x96\x02\0\x8A\x99\x02\0\x9A\x9B\x02\0\xF6\x9D\x02\0\x18\xA0\x02\0\"\xA3\x02\0z\xA5\x02\0\xDB\xA7\x02\0\xB8\xAA\x02\x000\xAE\x02\0\xE5\xAF\x02\0,\xB0\x02\0\x95\xB0\x02\0\xF6\xB0\x02\0z\xB1\x02\0B\xB2\x02\0F\xB6\x02\0\xDA\xB6\x02\0\xB8\xB9\x02\0/\xBE\x02\0L\xBF\x02\0\xB5\xBF\x02\0\xAE\xC0\x02\x002\xC1\x02\0\x8A\xC1\x02\0\xE2\xC1\x02\0\x06\xC3\x02\0\xA4\xC3\x02\0\x1E\xC4\x02\0\x98\xC4\x02\0X\xC5\x02\0\xFD\xC5\x02\0U\xC6\x02\0\xD8\xC6\x02\0A\xC7\x02\0\xD5\xC7\x02\0k\xC8\x02\0\xD4\xC8\x02\0=\xC9\x02\0\xA6\xC9\x02\0\x0F\xCA\x02\0\xA3\xCA\x02\0\xFB\xCA\x02\0S\xCB\x02\0GMT\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\t\0H\x92\xE6\x92\xFF\xFF\xFF\xFF\x018\xFC\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x01<\x01$\x9B\xC9k\xFF\xFF\xFF\xFFOP`\x91\xFF\xFF\xFF\xFF\xF0xG\x9B\xFF\xFF\xFF\xFFp,\xD7\x9B\xFF\xFF\xFF\xFFp\x91\xBC\x9C\xFF\xFF\xFF\xFF\xF0H\xC0\x9D\xFF\xFF\xFF\xFFp\xFE\x89\x9E\xFF\xFF\xFF\xFF\xF0*\xA0\x9F\xFF\xFF\xFF\xFF\xF0\xA5`\xA0\xFF\xFF\xFF\xFF\xF0\x0C\x80\xA1\xFF\xFF\xFF\xFF\xF0\x12.\xA2\xFF\xFF\xFF\xFF\xF0Lz\xA3\xFF\xFF\xFF\xFF\xF0\x815\xA4\xFF\xFF\xFF\xFFp\x06\xB8\xA4\xFF\xFF\xFF\xFFp\x06\xFF\xC6\xFF\xFF\xFF\xFF\x80\xBAX\xC7\xFF\xFF\xFF\xFF\xA0\t\xDA\xC7\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF\0\0\x8A\xD0\xFF\xFF\xFF\xFF\x10\x16r\xD1\xFF\xFF\xFF\xFFp$N\xD2\xFF\xFF\xFF\xFFp\x07K\xD4\xFF\xFF\xFF\xFF\0\xD3\xCE\xE5\xFF\xFF\xFF\xFF\xF0\xB0\\\xF3\xFF\xFF\xFF\xFF\xF0\xC1x\x02\0\0\0\0\xF0\xC8C\x03\0\0\0\0\0\xD7\xCF\r\0\0\0\0\xF0D\xAD\x0E\0\0\0\0\0Zx\x0F\0\0\0\0\x10Yh\x10\0\0\0\0pCv\x12\0\0\0\0\x80Bf\x13\0\0\0\0\x10|_\x14\0\0\0\0\0_O\x15\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x04\x05\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x03\x04\x05\x03\x04\x02\x03\x04\x02\x03\x04\xDC\x02\0\0\0\0\0\x001\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0GMT\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\x12\0\x90\x9C\xE6\x92\xFF\xFF\xFF\xFF\x10ag\t\0\0\0\0\x01\x02d\xF1\xFF\xFF\xFF\xFF\xFF\xFF\xF0\xF1\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0EET\0\0 \x1C\0\0\0\0\0\0\x01EEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x04\x05\x05\0\0\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x04\x80Q\x01\0\0\0\0\0\x08\x04\x89\x04\xABM\xBD}\xFF\xFF\xFF\xFF\xE0\xB4\x93\xC8\xFF\xFF\xFF\xFF\xD0{\xFA\xC8\xFF\xFF\xFF\xFF\xE0\xEF\xFC\xC9\xFF\xFF\xFF\xFF\xD0\xE8\xC7\xCA\xFF\xFF\xFF\xFF`\xAE\xCB\xCB\xFF\xFF\xFF\xFF\xD0)\xDF\xCC\xFF\xFF\xFF\xFF\xE0\xE1\xAC\xCD\xFF\xFF\xFF\xFF\xD0\xF4\xC6\xCE\xFF\xFF\xFF\xFF\xE0f\x8F\xCF\xFF\xFF\xFF\xFF\xD0y\xA9\xD0\xFF\xFF\xFF\xFF\xE0`\x84\xD1\xFF\xFF\xFF\xFFP\xAD\x8A\xD2\xFF\xFF\xFF\xFF`c6\xE8\xFF\xFF\xFF\xFFP-\xF4\xE8\xFF\xFF\xFF\xFF`\xB9\x0B\xEA\xFF\xFF\xFF\xFF\xD0`\xD5\xEA\xFF\xFF\xFF\xFF\xF0\xFA\xEC\xEB\xFF\xFF\xFF\xFF\0m\xB5\xEC\xFF\xFF\xFF\xFF\xF0\x7F\xCF\xED\xFF\xFF\xFF\xFF\0\xF2\x97\xEE\xFF\xFF\xFF\xFFp\xB3\xB0\xEF\xFF\xFF\xFF\xFF\x80%y\xF0\xFF\xFF\xFF\xFF\xF0\xE6\x91\xF1\xFF\xFF\xFF\xFF\0YZ\xF2\xFF\xFF\xFF\xFFp\x1As\xF3\xFF\xFF\xFF\xFF\x80\x8C;\xF4\xFF\xFF\xFF\xFFp\x9FU\xF5\xFF\xFF\xFF\xFF\x80\x11\x1E\xF6\xFF\xFF\xFF\xFF\xF0\xD26\xF7\xFF\xFF\xFF\xFF\0E\xFF\xF7\xFF\xFF\xFF\xFFp\x06\x18\xF9\xFF\xFF\xFF\xFF\0\xCA\xE1\xF9\xFF\xFF\xFF\xFF\xF09\xF9\xFA\xFF\xFF\xFF\xFF\x80\xFD\xC2\xFB\xFF\xFF\xFF\xFF\xF0\xBE\xDB\xFC\xFF\xFF\xFF\xFF\x80\x82\xA5\xFD\xFF\xFF\xFF\xFFp\xF2\xBC\xFE\xFF\xFF\xFF\xFF\0\xB6\x86\xFF\xFF\xFF\xFF\xFF\xF0%\x9E\0\0\0\0\0\x80\xE9g\x01\0\0\0\0pY\x7F\x02\0\0\0\0\0\x1DI\x03\0\0\0\0p\xDEa\x04\0\0\0\0\0\xA2+\x05\0\0\0\0\xF0\x11C\x06\0\0\0\0\x80\xD5\x0C\x07\0\0\0\0pE$\x08\0\0\0\0\0\t\xEE\x08\0\0\0\0\xF0x\x05\n\0\0\0\0\x80<\xCF\n\0\0\0\0\xF0\xFD\xE7\x0B\0\0\0\0\x80\xC1\xB1\x0C\0\0\0\0p1\xC9\r\0\0\0\0\0\xF5\x92\x0E\0\0\0\0\xF0d\xAA\x0F\0\0\0\0\x80(t\x10\0\0\0\0p\x98\x8B\x11\0\0\0\0\0\\U\x12\0\0\0\0p\x1Dn\x13\0\0\0\0\0\xE17\x14\0\0\0\0\xF0PO\x15\0\0\0\0\x80\x14\x19\x16\0\0\0\0\xF0\x93\xA0\x17\0\0\0\0\0H\xFA\x17\0\0\0\0\xF0\xA3p\x19\0\0\0\0\x80{\xDB\x19\0\0\0\0\xF0<\xF4\x1A\0\0\0\0\x80\0\xBE\x1B\0\0\0\0pp\xD5\x1C\0\0\0\0\x004\x9F\x1D\0\0\0\0\xF0\xA3\xB6\x1E\0\0\0\0\x80g\x80\x1F\0\0\0\0p\xD7\x97 \0\0\0\0\0\x9Ba!\0\0\0\0p\\z\"\0\0\0\0\0 D#\0\0\0\0p'b$\0\0\0\0\x80S%%\0\0\0\0p\xC3<&\0\0\0\0\0\x87\x06'\0\0\0\0\xF0\xF6\x1D(\0\0\0\0\x80\xBA\xE7(\0\0\0\0\xF0{\0*\0\0\0\0\x80?\xCA*\0\0\0\0p\xAF\xE1+\0\0\0\0\0s\xAB,\0\0\0\0\xF0\xE2\xC2-\0\0\0\0\x80\xA6\x8C.\0\0\0\0\xE0\x13\xA0/\0\0\0\0\xD0\x0Ck0\0\0\0\0\xE0\xF5\x7F1\0\0\0\0\xD0\xEEJ2\0\0\0\0\xE0\xD7_3\0\0\0\0\xD0\xD0*4\0\0\0\0\xE0\xB9?5\0\0\0\0\xD0\xB2\n6\0\0\0\0`\xD6(7\0\0\0\0P\xCF\xF37\0\0\0\0`\xB8\x089\0\0\0\0P\xB1\xD39\0\0\0\0`\x9A\xE8:\0\0\0\0P\x93\xB3;\0\0\0\0`|\xC8<\0\0\0\0Pu\x93=\0\0\0\0`^\xA8>\0\0\0\0PWs?\0\0\0\0\xE0z\x91@\0\0\0\0\xD0s\\A\0\0\0\0\xE0\\qB\0\0\0\0\xD0UQD\0\0\0\0P\xFD\x12E\0\0\0\0\xE0 1F\0\0\0\0Pj\xE0F\0\0\0\0\xE0\x02\x11H\0\0\0\0\xD0\x11\xB7H\0\0\0\0\xE0\xE4\xF0I\0\0\0\0P\xB9\x8DJ\0\0\0\0`\x01\xDAK\0\0\0\0\xD0\xBDaL\0\0\0\0\xE0X\x89L\0\0\0\0P\xFA\xA4L\0\0\0\0\xE08uS\0\0\0\0\xD0\x89\xACS\0\0\0\0`\xBC\xDAS\0\0\0\0P\x82$T\0\0\0\0`\xF0Jd\0\0\0\0P\xD3:e\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01U\x1D\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0+01\0\0\x10\x0E\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \x06>\x07\x9C\xF9Q\x96\xFF\xFF\xFF\xFF\x80\x14\xFF\xC6\xFF\xFF\xFF\xFFp\xACX\xC7\xFF\xFF\xFF\xFF\x80\xED\xD9\xC7\xFF\xFF\xFF\xFF\xF02\xA1\xD2\xFF\xFF\xFF\xFF\0\xA45\xDB\xFF\xFF\xFF\xFF\xF0'\xEE\xDB\xFF\xFF\xFF\xFF@r%\xFB\xFF\xFF\xFF\xFFp\xEF\xC2\xFB\xFF\xFF\xFF\xFF\x80\x84k\x08\0\0\0\0\xF0m\xC6\x08\0\0\0\0\0\x0C\xE8\x0B\0\0\0\0\xF0Ga\x0C\0\0\0\0\x80?\xC9\r\0\0\0\0p\xF2\x8E\x0E\0\0\0\0\x80Q\xD3\x0F\0\0\0\0p\xA3'\x10\0\0\0\0\0\xA6\xB7\x1A\0\0\0\0\xF0o\x18\x1E\0\0\0\0\x80\xE6AH\0\0\0\0p\"\xBBH\0\0\0\0\0\x1A#J\0\0\0\0p\xD5\x8DJ\0\0\0\0\x80\xC0\xDCK\0\0\0\0p\xE5]L\0\0\0\0\x80\xB8\x97M\0\0\0\0\xF0\x8C4N\0\0\0\0\xA0\xA0\x9CO\0\0\0\0\xA0\xBB\x08P\0\0\0\0 \x9A1P\0\0\0\0\xA0\xA7gP\0\0\0\0\xA0\x82|Q\0\0\0\0\xA0\xCB\xD8Q\0\0\0\0\xA0\x9E\x05R\0\0\0\0\xA0slR\0\0\0\0\xA0z7S\0\0\0\0\xA0!\xAES\0\0\0\0 F\xDCS\0\0\0\0\xA0ULT\0\0\0\0\xA0\\\x17U\0\0\0\0 \xE0|U\0\0\0\0\xA0\x04\xABU\0\0\0\0\xA07,V\0\0\0\0\xA0>\xF7V\0\0\0\0\xA0\x87SW\0\0\0\0 \xAC\x81W\0\0\0\0 T\x15X\0\0\0\0\xA0 \xD7X\0\0\0\0\xA0\xF4 Y\0\0\0\0\xA0SXY\0\0\0\0 6\xF5Y\0\0\0\0\xA0\x02\xB7Z\0\0\0\0 \x9C\xF7Z\0\0\0\0\xA0\xC0%[\0\0\0\0\xA0C\xCE\\\0\0\0\0 h\xFC\\\0\0\0\0\xA0\xB0\x9B^\0\0\0\0\xA0\x0F\xD3^\0\0\0\0 Xr`\0\0\0\0\xA0|\xA0`\0\0\0\0 \xC5?b\0\0\0\0 $wb\0\0\0\0\xA0l\x16d\0\0\0\0 \x91Dd\0\0\0\0 \x14\xEDe\0\0\0\0\xA08\x1Bf\0\0\0\0 \x81\xBAg\0\0\0\0 \xE0\xF1g\0\0\0\0\xA0(\x91i\0\0\0\0 M\xBFi\0\0\0\0 \xD0gk\0\0\0\0\xA0\xF4\x95k\0\0\0\0 =5m\0\0\0\0 \x9Clm\0\0\0\0\xA0\xE4\x0Bo\0\0\0\0 \t:o\0\0\0\0\xA0Q\xD9p\0\0\0\0\xA0\xB0\x10q\0\0\0\0 \xF9\xAFr\0\0\0\0\xA0\x1D\xDEr\0\0\0\0\xA0\xA0\x86t\0\0\0\0 \xC5\xB4t\0\0\0\0\xA0\rTv\0\0\0\0\xA0l\x8Bv\0\0\0\0 \xB5*x\0\0\0\0\xA0\xD9Xx\0\0\0\0 \"\xF8y\0\0\0\0 \x81/z\0\0\0\0\xA0\xC9\xCE{\0\0\0\0\xA0(\x06|\0\0\0\0 q\xA5}\0\0\0\0\xA0\x95\xD3}\0\0\0\0 \xDEr\x7F\0\0\0\0 =\xAA\x7F\0\0\0\0\xA0\x85I\x81\0\0\0\0 \xAAw\x81\0\0\0\0 - \x83\0\0\0\0\xA0QN\x83\0\0\0\0 \x9A\xED\x84\0\0\0\0 \xF9$\x85\0\0\0\0\xA0A\xC4\x86\0\0\0\0 f\xF2\x86\0\0\0\0\xA0\xAE\x91\x88\0\0\0\0\xA0\r\xC9\x88\0\0\0\0 Vh\x8A\0\0\0\0 \xB5\x9F\x8A\0\0\0\0\xA0\xFD>\x8C\0\0\0\0 \"m\x8C\0\0\0\0\xA0j\x0C\x8E\0\0\0\0\xA0\xC9C\x8E\0\0\0\0 \x12\xE3\x8F\0\0\0\0\xA06\x11\x90\0\0\0\0\xA0\xB9\xB9\x91\0\0\0\0 \xDE\xE7\x91\0\0\0\0\xA0&\x87\x93\0\0\0\0\xA0\x85\xBE\x93\0\0\0\0 \xCE]\x95\0\0\0\0\xA0\xF2\x8B\x95\0\0\0\0 ;+\x97\0\0\0\0 \x9Ab\x97\0\0\0\0\xA0\xE2\x01\x99\0\0\0\0\xA0A9\x99\0\0\0\0 \x8A\xD8\x9A\0\0\0\0\xA0\xAE\x06\x9B\0\0\0\0 \xF7\xA5\x9C\0\0\0\0 V\xDD\x9C\0\0\0\0\xA0\x9E|\x9E\0\0\0\0 \xC3\xAA\x9E\0\0\0\0 FS\xA0\0\0\0\0\xA0j\x81\xA0\0\0\0\0 \xB3 \xA2\0\0\0\0 \x12X\xA2\0\0\0\0\xA0Z\xF7\xA3\0\0\0\0 \x7F%\xA4\0\0\0\0\xA0\xC7\xC4\xA5\0\0\0\0\xA0&\xFC\xA5\0\0\0\0 o\x9B\xA7\0\0\0\0 \xCE\xD2\xA7\0\0\0\0\xA0\x16r\xA9\0\0\0\0 ;\xA0\xA9\0\0\0\0\xA0\x83?\xAB\0\0\0\0\xA0\xE2v\xAB\0\0\0\0 +\x16\xAD\0\0\0\0\xA0OD\xAD\0\0\0\0\xA0\xD2\xEC\xAE\0\0\0\0 \xF7\x1A\xAF\0\0\0\0\xA0?\xBA\xB0\0\0\0\0\xA0\x9E\xF1\xB0\0\0\0\0 \xE7\x90\xB2\0\0\0\0\xA0\x0B\xBF\xB2\0\0\0\0 T^\xB4\0\0\0\0 \xB3\x95\xB4\0\0\0\0\xA0\xFB4\xB6\0\0\0\0\xA0Zl\xB6\0\0\0\0 \xA3\x0B\xB8\0\0\0\0\xA0\xC79\xB8\0\0\0\0 \x10\xD9\xB9\0\0\0\0 o\x10\xBA\0\0\0\0\xA0\xB7\xAF\xBB\0\0\0\0 \xDC\xDD\xBB\0\0\0\0 _\x86\xBD\0\0\0\0\xA0\x83\xB4\xBD\0\0\0\0 \xCCS\xBF\0\0\0\0 +\x8B\xBF\0\0\0\0\xA0s*\xC1\0\0\0\0 \x98X\xC1\0\0\0\0\xA0\xE0\xF7\xC2\0\0\0\0\xA0?/\xC3\0\0\0\0 \x88\xCE\xC4\0\0\0\0 \xE7\x05\xC5\0\0\0\0\xA0/\xA5\xC6\0\0\0\0 T\xD3\xC6\0\0\0\0\xA0\x9Cr\xC8\0\0\0\0\xA0\xFB\xA9\xC8\0\0\0\0 DI\xCA\0\0\0\0\xA0hw\xCA\0\0\0\0\xA0\xEB\x1F\xCC\0\0\0\0 \x10N\xCC\0\0\0\0\xA0X\xED\xCD\0\0\0\0\xA0\xB7$\xCE\0\0\0\0 \0\xC4\xCF\0\0\0\0\xA0$\xF2\xCF\0\0\0\0 m\x91\xD1\0\0\0\0 \xCC\xC8\xD1\0\0\0\0\xA0\x14h\xD3\0\0\0\0 9\x96\xD3\0\0\0\0 \xBC>\xD5\0\0\0\0\xA0\xE0l\xD5\0\0\0\0 )\x0C\xD7\0\0\0\0 \x88C\xD7\0\0\0\0\xA0\xD0\xE2\xD8\0\0\0\0 \xF5\x10\xD9\0\0\0\0 x\xB9\xDA\0\0\0\0\xA0\x9C\xE7\xDA\0\0\0\0 \xE5\x86\xDC\0\0\0\0 D\xBE\xDC\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\xE4\xF8\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\x01CEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\0`\x01\x98\x01\0\xB56~\xFF\xFF\xFF\xFFpu\xD6\x9E\xFF\xFF\xFF\xFF`n\xA1\x9F\xFF\xFF\xFF\xFFp\xEF\x05\xAA\xFF\xFF\xFF\xFF\0n\xE7\xAA\xFF\xFF\xFF\xFF\xF0\xA7\xC9\xAD\xFF\xFF\xFF\xFF\x002\xA7\xAE\xFF\xFF\xFF\xFFpO\xA0\xAF\xFF\xFF\xFF\xFF\0\x14\x87\xB0\xFF\xFF\xFF\xFF\0z\x89\xB1\xFF\xFF\xFF\xFF\x800p\xB2\xFF\xFF\xFF\xFF@r%\xFB\xFF\xFF\xFF\xFFp\xEF\xC2\xFB\xFF\xFF\xFF\xFF\x80\x84k\x08\0\0\0\0\xF0m\xC6\x08\0\0\0\0\0\x0C\xE8\x0B\0\0\0\0\xF0Ga\x0C\0\0\0\0\x80?\xC9\r\0\0\0\0p\xF2\x8E\x0E\0\0\0\0\x80Q\xD3\x0F\0\0\0\0p\xA3'\x10\0\0\0\0\0\xA6\xB7\x1A\0\0\0\0\xF0o\x18\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\xFB\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0+01\0\0\x10\x0E\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xC8\x05\x81\x06\xE0\xF0H\xBC\xFF\xFF\xFF\xFF\x90\xB0\xD1\x0B\0\0\0\0\0\x0C\xE8\x0B\0\0\0\0\xF0Ga\x0C\0\0\0\0\x80?\xC9\r\0\0\0\0p\xF2\x8E\x0E\0\0\0\0\x80Q\xD3\x0F\0\0\0\0p\xA3'\x10\0\0\0\0\x80\xE6AH\0\0\0\0p\"\xBBH\0\0\0\0\0\x1A#J\0\0\0\0p\xD5\x8DJ\0\0\0\0\x80\xC0\xDCK\0\0\0\0p\xE5]L\0\0\0\0\x80\xB8\x97M\0\0\0\0\xF0\x8C4N\0\0\0\0\xA0\xA0\x9CO\0\0\0\0\xA0\xBB\x08P\0\0\0\0 \x9A1P\0\0\0\0\xA0\xA7gP\0\0\0\0\xA0\x82|Q\0\0\0\0\xA0\xCB\xD8Q\0\0\0\0\xA0\x9E\x05R\0\0\0\0\xA0slR\0\0\0\0\xA0z7S\0\0\0\0\xA0!\xAES\0\0\0\0 F\xDCS\0\0\0\0\xA0ULT\0\0\0\0\xA0\\\x17U\0\0\0\0 \xE0|U\0\0\0\0\xA0\x04\xABU\0\0\0\0\xA07,V\0\0\0\0\xA0>\xF7V\0\0\0\0\xA0\x87SW\0\0\0\0 \xAC\x81W\0\0\0\0 T\x15X\0\0\0\0\xA0 \xD7X\0\0\0\0\xA0\xF4 Y\0\0\0\0\xA0SXY\0\0\0\0 6\xF5Y\0\0\0\0\xA0\x02\xB7Z\0\0\0\0 \x9C\xF7Z\0\0\0\0\xA0\xC0%[\0\0\0\0\xA0C\xCE\\\0\0\0\0 h\xFC\\\0\0\0\0\xA0\xB0\x9B^\0\0\0\0\xA0\x0F\xD3^\0\0\0\0 Xr`\0\0\0\0\xA0|\xA0`\0\0\0\0 \xC5?b\0\0\0\0 $wb\0\0\0\0\xA0l\x16d\0\0\0\0 \x91Dd\0\0\0\0 \x14\xEDe\0\0\0\0\xA08\x1Bf\0\0\0\0 \x81\xBAg\0\0\0\0 \xE0\xF1g\0\0\0\0\xA0(\x91i\0\0\0\0 M\xBFi\0\0\0\0 \xD0gk\0\0\0\0\xA0\xF4\x95k\0\0\0\0 =5m\0\0\0\0 \x9Clm\0\0\0\0\xA0\xE4\x0Bo\0\0\0\0 \t:o\0\0\0\0\xA0Q\xD9p\0\0\0\0\xA0\xB0\x10q\0\0\0\0 \xF9\xAFr\0\0\0\0\xA0\x1D\xDEr\0\0\0\0\xA0\xA0\x86t\0\0\0\0 \xC5\xB4t\0\0\0\0\xA0\rTv\0\0\0\0\xA0l\x8Bv\0\0\0\0 \xB5*x\0\0\0\0\xA0\xD9Xx\0\0\0\0 \"\xF8y\0\0\0\0 \x81/z\0\0\0\0\xA0\xC9\xCE{\0\0\0\0\xA0(\x06|\0\0\0\0 q\xA5}\0\0\0\0\xA0\x95\xD3}\0\0\0\0 \xDEr\x7F\0\0\0\0 =\xAA\x7F\0\0\0\0\xA0\x85I\x81\0\0\0\0 \xAAw\x81\0\0\0\0 - \x83\0\0\0\0\xA0QN\x83\0\0\0\0 \x9A\xED\x84\0\0\0\0 \xF9$\x85\0\0\0\0\xA0A\xC4\x86\0\0\0\0 f\xF2\x86\0\0\0\0\xA0\xAE\x91\x88\0\0\0\0\xA0\r\xC9\x88\0\0\0\0 Vh\x8A\0\0\0\0 \xB5\x9F\x8A\0\0\0\0\xA0\xFD>\x8C\0\0\0\0 \"m\x8C\0\0\0\0\xA0j\x0C\x8E\0\0\0\0\xA0\xC9C\x8E\0\0\0\0 \x12\xE3\x8F\0\0\0\0\xA06\x11\x90\0\0\0\0\xA0\xB9\xB9\x91\0\0\0\0 \xDE\xE7\x91\0\0\0\0\xA0&\x87\x93\0\0\0\0\xA0\x85\xBE\x93\0\0\0\0 \xCE]\x95\0\0\0\0\xA0\xF2\x8B\x95\0\0\0\0 ;+\x97\0\0\0\0 \x9Ab\x97\0\0\0\0\xA0\xE2\x01\x99\0\0\0\0\xA0A9\x99\0\0\0\0 \x8A\xD8\x9A\0\0\0\0\xA0\xAE\x06\x9B\0\0\0\0 \xF7\xA5\x9C\0\0\0\0 V\xDD\x9C\0\0\0\0\xA0\x9E|\x9E\0\0\0\0 \xC3\xAA\x9E\0\0\0\0 FS\xA0\0\0\0\0\xA0j\x81\xA0\0\0\0\0 \xB3 \xA2\0\0\0\0 \x12X\xA2\0\0\0\0\xA0Z\xF7\xA3\0\0\0\0 \x7F%\xA4\0\0\0\0\xA0\xC7\xC4\xA5\0\0\0\0\xA0&\xFC\xA5\0\0\0\0 o\x9B\xA7\0\0\0\0 \xCE\xD2\xA7\0\0\0\0\xA0\x16r\xA9\0\0\0\0 ;\xA0\xA9\0\0\0\0\xA0\x83?\xAB\0\0\0\0\xA0\xE2v\xAB\0\0\0\0 +\x16\xAD\0\0\0\0\xA0OD\xAD\0\0\0\0\xA0\xD2\xEC\xAE\0\0\0\0 \xF7\x1A\xAF\0\0\0\0\xA0?\xBA\xB0\0\0\0\0\xA0\x9E\xF1\xB0\0\0\0\0 \xE7\x90\xB2\0\0\0\0\xA0\x0B\xBF\xB2\0\0\0\0 T^\xB4\0\0\0\0 \xB3\x95\xB4\0\0\0\0\xA0\xFB4\xB6\0\0\0\0\xA0Zl\xB6\0\0\0\0 \xA3\x0B\xB8\0\0\0\0\xA0\xC79\xB8\0\0\0\0 \x10\xD9\xB9\0\0\0\0 o\x10\xBA\0\0\0\0\xA0\xB7\xAF\xBB\0\0\0\0 \xDC\xDD\xBB\0\0\0\0 _\x86\xBD\0\0\0\0\xA0\x83\xB4\xBD\0\0\0\0 \xCCS\xBF\0\0\0\0 +\x8B\xBF\0\0\0\0\xA0s*\xC1\0\0\0\0 \x98X\xC1\0\0\0\0\xA0\xE0\xF7\xC2\0\0\0\0\xA0?/\xC3\0\0\0\0 \x88\xCE\xC4\0\0\0\0 \xE7\x05\xC5\0\0\0\0\xA0/\xA5\xC6\0\0\0\0 T\xD3\xC6\0\0\0\0\xA0\x9Cr\xC8\0\0\0\0\xA0\xFB\xA9\xC8\0\0\0\0 DI\xCA\0\0\0\0\xA0hw\xCA\0\0\0\0\xA0\xEB\x1F\xCC\0\0\0\0 \x10N\xCC\0\0\0\0\xA0X\xED\xCD\0\0\0\0\xA0\xB7$\xCE\0\0\0\0 \0\xC4\xCF\0\0\0\0\xA0$\xF2\xCF\0\0\0\0 m\x91\xD1\0\0\0\0 \xCC\xC8\xD1\0\0\0\0\xA0\x14h\xD3\0\0\0\0 9\x96\xD3\0\0\0\0 \xBC>\xD5\0\0\0\0\xA0\xE0l\xD5\0\0\0\0 )\x0C\xD7\0\0\0\0 \x88C\xD7\0\0\0\0\xA0\xD0\xE2\xD8\0\0\0\0 \xF5\x10\xD9\0\0\0\0 x\xB9\xDA\0\0\0\0\xA0\x9C\xE7\xDA\0\0\0\0 \xE5\x86\xDC\0\0\0\0 D\xBE\xDC\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xA0\xF3\xFF\xFF\xFF\xFF\xFF\xFF\xF0\xF1\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0SAST\0 \x1C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0(\0-\0@A{m\xFF\xFF\xFF\xFFh\xCFF\x82\xFF\xFF\xFF\xFF\x80\x8C\xAE\xCC\xFF\xFF\xFF\xFFpo\x9E\xCD\xFF\xFF\xFF\xFF\x80n\x8E\xCE\xFF\xFF\xFF\xFF\x01\x02\x03\x02\x03@\x1A\0\0\0\0\0\0\x18\x15\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0CAT\0\0 \x1C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\x01<\x01\xDC\xDA\xA3\xB6\xFF\xFF\xFF\xFF\xE0\x17\x9E\0\0\0\0\0P4z\x01\0\0\0\0\xE0\xF9}\x02\0\0\0\0\xD0g[\x03\0\0\0\0\xE0~`\x04\0\0\0\0\xD0\xEC=\x05\0\0\0\0\xE0`@\x06\0\0\0\0P \x1F\x07\0\0\0\0\xE0B \x08\0\0\0\0\xD0S\0\t\0\0\0\0\xE0$\0\n\0\0\0\0P\x87\xE1\n\0\0\0\0\xE0\x06\xE0\x0B\0\0\0\0P\x0C\xC4\x0C\0\0\0\0\xE0\xE8\xBF\r\0\0\0\0\xD0?\xA5\x0E\0\0\0\0`\x05\xA9\x0F\0\0\0\0Ps\x86\x10\0\0\0\0`\xE7\x88\x11\0\0\0\0\xD0\xA6g\x12\0\0\0\0`\xC9h\x13\0\0\0\0\xD0+J\x14\0\0\0\0`\xABH\x15\0\0\0\0P_+\x16\0\0\0\0`\x8D(\x17\0\0\0\0\xD0\x92\x0C\x18\0\0\0\0`o\x08\x19\0\0\0\0P\xC6\xED\x19\0\0\0\0\xE0\x8B\xF1\x1A\0\0\0\0PK\xD0\x1B\0\0\0\0\xE0m\xD1\x1C\0\0\0\0\xD0~\xB1\x1D\0\0\0\0 E\x808\0\0\0\0P\x1A\x17`\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x01\xA4\x1D\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\x000*\0\0\0\0\0\0CAT\0\0 \x1C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\x01<\x01\0\xDA\xA3\xB6\xFF\xFF\xFF\xFF\xE0\x17\x9E\0\0\0\0\0P4z\x01\0\0\0\0\xE0\xF9}\x02\0\0\0\0\xD0g[\x03\0\0\0\0\xE0~`\x04\0\0\0\0\xD0\xEC=\x05\0\0\0\0\xE0`@\x06\0\0\0\0P \x1F\x07\0\0\0\0\xE0B \x08\0\0\0\0\xD0S\0\t\0\0\0\0\xE0$\0\n\0\0\0\0P\x87\xE1\n\0\0\0\0\xE0\x06\xE0\x0B\0\0\0\0P\x0C\xC4\x0C\0\0\0\0\xE0\xE8\xBF\r\0\0\0\0\xD0?\xA5\x0E\0\0\0\0`\x05\xA9\x0F\0\0\0\0Ps\x86\x10\0\0\0\0`\xE7\x88\x11\0\0\0\0\xD0\xA6g\x12\0\0\0\0`\xC9h\x13\0\0\0\0\xD0+J\x14\0\0\0\0`\xABH\x15\0\0\0\0P_+\x16\0\0\0\0`\x8D(\x17\0\0\0\0\xD0\x92\x0C\x18\0\0\0\0`o\x08\x19\0\0\0\0P\xC6\xED\x19\0\0\0\0\xE0\x8B\xF1\x1A\0\0\0\0PK\xD0\x1B\0\0\0\0\xE0m\xD1\x1C\0\0\0\0\xD0~\xB1\x1D\0\0\0\0 E\x808\0\0\0\0P\xE4\xF8Y\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x01\x80\x1E\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\x000*\0\0\0\0\0\0WAT\0\0\x10\x0E\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0$\0\xD1p\xAB\x86\xFF\xFF\xFF\xFF\0`P\x8C\xFF\xFF\xFF\xFF\xD1C\xAA\x96\xFF\xFF\xFF\xFFx\xEFQ\xA1\xFF\xFF\xFF\xFF\x01\0\x02\x03/\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\x07\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0CAT\0\0 \x1C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\t\0v\xD5B\x8D\xFF\xFF\xFF\xFF\x01\x8A\x1E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0GMT\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\0\x1B\0\x9C\xA6zZ\xFF\xFF\xFF\xFF\x9Cl_\xA0\xFF\xFF\xFF\xFFnZ\xCA\x03\0\0\0\0\0\x01\x02\xE4\xF5\xFF\xFF\xFF\xFF\xFF\xFF\x92\xF5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0EAT\0\x000*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0(\0-\0\xFC\xD1\xFF\x8B\xFF\xFF\xFF\xFFX\xDA\xEE\xB1\xFF\xFF\xFF\xFF\xD0\xE0\xC7\xB4\xFF\xFF\xFF\xFFX\xAD\xED\xC1\xFF\xFF\xFF\xFF\xD4zl\xCC\xFF\xFF\xFF\xFF\x01\x02\x01\x03\x02\x84\"\0\0\0\0\0\0(#\0\0\0\0\0\x000*\0\0\0\0\0\0\xAC&\0\0\0\0\0\0WAT\0\0\x10\x0E\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\0\x1B\0d\x80\xE6\x92\xFF\xFF\xFF\xFFpqf\x12\0\0\0\0`\xDE&\x13\0\0\0\0\x01\x02\x01\x1C\x0E\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0GMT\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0$\x000\xFD<^\xFF\xFF\xFF\xFF\x80\x8E\xE6\x92\xFF\xFF\xFF\xFF\x10\x88IZ\0\0\0\0\x90\xBB*\\\0\0\0\0\x01\x02\x03\x02P\x06\0\0\0\0\0\0c\xF7\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0EET\0\0 \x1C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01.\x01$\xC1\xF2\xA1\xFF\xFF\xFF\xFF\x10\xB1\xBB\xDD\xFF\xFF\xFF\xFF`\xAD#\xDE\xFF\xFF\xFF\xFF\x10\xD2x\xE1\xFF\xFF\xFF\xFF\xE0e\xE7\xE1\xFF\xFF\xFF\xFFp?/\xE5\xFF\xFF\xFF\xFF\xE0\xCC\xA9\xE5\xFF\xFF\xFF\xFF\xF0\xC6N\xEB\xFF\xFF\xFF\xFF`B\x92\x16\0\0\0\0p\xF7\x08\x17\0\0\0\0\xE0+\xFA\x17\0\0\0\0\xF0*\xEA\x18\0\0\0\0`_\xDB\x19\0\0\0\0\xF0\xAF\xCC\x1A\0\0\0\0`\xE4\xBD\x1B\0\0\0\0\xF0z\xB4\x1C\0\0\0\0\xE0\x17\x9F\x1D\0\0\0\0p\x0B\x93\x1E\0\0\0\0`\xEE\x82\x1F\0\0\0\0pJp \0\0\0\0\xE0~a!\0\0\0\0p\xCFR\"\0\0\0\0\xE0\x03D#\0\0\0\0\xF0\x024$\0\0\0\0`7%%\0\0\0\0\xF0\xB7@&\0\0\0\0`\xF1N2\0\0\0\0p6D3\0\0\0\0\xE0j54\0\0\0\0\0\x99\x9DP\0\0\0\0\x80\xD9TQ\0\0\0\0\x80\xB4iR\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x02\x03\x01\x02\x03\x02\x03\\\x0C\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0 \x1C\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xF0\0\x0E\x01\xF4\x13FY\xFF\xFF\xFF\xFFOP`\x91\xFF\xFF\xFF\xFF\xE0\x88:\xC6\xFF\xFF\xFF\xFF`\x9EX\xC7\xFF\xFF\xFF\xFF\xE0\"\xDB\xC7\xFF\xFF\xFF\xFF\xE0T\xE2\xCA\xFF\xFF\xFF\xFF\xF0i\xAD\xCB\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\0\x16\xC2\xCD\xFF\xFF\xFF\xFF\x10\xB0\xCC\xCD\xFF\xFF\xFF\xFF\x005\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF\xE0\xE3\x89\xD0\xFF\xFF\xFF\xFF\x10\x16r\xD1\xFF\xFF\xFF\xFF`\x16N\xD2\xFF\xFF\xFF\xFF\xF0\xDF\xC7\r\0\0\0\0p\xAC\x89\x0E\0\0\0\0\xF0d\xAA\x0F\0\0\0\0p\x1At\x10\0\0\0\0\xF0:\xA3\"\0\0\0\0\xF0(<#\0\0\0\0\xF0\x19,$\0\0\0\0\xF0\n\x1C%\0\0\0\0p\xC3<&\0\0\0\0p'\x05'\0\0\0\0\xF0\rtB\0\0\0\0\0\x80\0\0\0\0\x10\x83Z?\0\0\0\0\0Po@\0\0\0\0\x10e:A\0\0\0\0\x002OB\0\0\0\0\x10G\x1AC\0\0\0\0\0\x14/D\0\0\0\0\x10)\xFAD\0\0\0\0\0\xF6\x0EF\0\0\0\0\x10\x0B\xDAF\0\0\0\0\x80\x12\xF8G\0\0\0\0\x90'\xC3H\0\0\0\0\x80\xF4\xD7I\0\0\0\0\x90\t\xA3J\0\0\0\0\x80\xD6\xB7K\0\0\0\0\x90\xEB\x82L\0\0\0\0\x80\xB8\x97M\0\0\0\0\x90\xCDbN\0\0\0\0\x80\x9AwO\0\0\0\0\x90\xAFBP\0\0\0\0\0\xB7`Q\0\0\0\0\x90\x91\"R\0\0\0\0\0\x99@S\0\0\0\0\x10\xAE\x0BT\0\0\0\0\0{ U\0\0\0\0\x10\x90\xEBU\0\0\0\0\0]\0W\0\0\0\0\x10r\xCBW\0\0\0\0\0?\xE0X\0\0\0\0\x10T\xABY\0\0\0\0`f\xEEY\0\0\0\0\x01\x02\x03\x02\x02\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x02\x05\x08\x10\0\0\0\0\0\0\x18\x15\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0HST\0\0`s\xFF\xFF\xFF\xFF\xFF\xFF\x01HDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xA8\x02\x17\x03\xD1\xFD\xC2?\xFF\xFF\xFF\xFF^Z\x87}\xFF\xFF\xFF\xFF\xD0D\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF@Pa\xD2\xFF\xFF\xFF\xFF\xB0U\xD2\xFA\xFF\xFF\xFF\xFFPq\xB8\xFE\xFF\xFF\xFF\xFF@T\xA8\xFF\xFF\xFF\xFF\xFFPS\x98\0\0\0\0\0@6\x88\x01\0\0\0\0P5x\x02\0\0\0\0\xC0Rq\x03\0\0\0\0\xD0Qa\x04\0\0\0\0\xC04Q\x05\0\0\0\0\xD03A\x06\0\0\0\0\xC0\x161\x07\0\0\0\0\xD0m\x8D\x07\0\0\0\0\xC0\xF8\x10\t\0\0\0\0P\xE9\xAD\t\0\0\0\0\xC0\xDA\xF0\n\0\0\0\0\xD0\xD9\xE0\x0B\0\0\0\0@\xF7\xD9\x0C\0\0\0\0\xD0\xBB\xC0\r\0\0\0\0@\xD9\xB9\x0E\0\0\0\0P\xD8\xA9\x0F\0\0\0\0@\xBB\x99\x10\0\0\0\0P\xBA\x89\x11\0\0\0\0@\x9Dy\x12\0\0\0\0P\x9Ci\x13\0\0\0\0@\x7FY\x14\0\0\0\0P~I\x15\0\0\0\0@a9\x16\0\0\0\0P`)\x17\0\0\0\0\xC0}\"\x18\0\0\0\0PB\t\x19\0\0\0\0\xC0_\x02\x1A\0\0\0\0 \"+\x1A\0\0\0\0\xC0P\xF2\x1A\0\0\0\0\xB03\xE2\x1B\0\0\0\0\xC02\xD2\x1C\0\0\0\0\xB0\x15\xC2\x1D\0\0\0\0\xC0\x14\xB2\x1E\0\0\0\0\xB0\xF7\xA1\x1F\0\0\0\0@Gv \0\0\0\0\xB0\xD9\x81!\0\0\0\0@)V\"\0\0\0\x000\xF6j#\0\0\0\0@\x0B6$\0\0\0\x000\xD8J%\0\0\0\0@\xED\x15&\0\0\0\x000\xBA*'\0\0\0\0\xC0\t\xFF'\0\0\0\x000\x9C\n)\0\0\0\0\xC0\xEB\xDE)\0\0\0\x000~\xEA*\0\0\0\0\xC0\xCD\xBE+\0\0\0\0\xB0\x9A\xD3,\0\0\0\0\xC0\xAF\x9E-\0\0\0\0\xB0|\xB3.\0\0\0\0\xC0\x91~/\0\0\0\0\xB0^\x930\0\0\0\0@\xAEg1\0\0\0\0\xB0@s2\0\0\0\0@\x90G3\0\0\0\0\xB0\"S4\0\0\0\0@r'5\0\0\0\0\xB0\x0436\0\0\0\0@T\x077\0\0\0\x000!\x1C8\0\0\0\0@6\xE78\0\0\0\x000\x03\xFC9\0\0\0\0@\x18\xC7:\0\0\0\x000\xE5\xDB;\0\0\0\0\xC04\xB0<\0\0\0\x000\xC7\xBB=\0\0\0\0\xC0\x16\x90>\0\0\0\x000\xA9\x9B?\0\0\0\0\xC0\xF8o@\0\0\0\0\xB0\xC5\x84A\0\0\0\0\xC0\xDAOB\0\0\0\0\xB0\xA7dC\0\0\0\0\xC0\xBC/D\0\0\0\0\xB0\x89DE\0\0\0\0@\xEF\xF3E\0\0\0\x000\xA6-G\0\0\0\0\x01\x02\x03\x03\x02\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x03\x04\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\xE2\xAB\0\0\0\0\0\0bZ\xFF\xFF\xFF\xFF\xFF\xFFPe\xFF\xFF\xFF\xFF\xFF\xFF`s\xFF\xFF\xFF\xFF\xFF\xFF`s\xFF\xFF\xFF\xFF\xFF\xFFp\x81\xFF\xFF\xFF\xFF\xFF\xFFAKST\0p\x81\xFF\xFF\xFF\xFF\xFF\xFF\x01AKDT\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xA8\x02\x17\x03\xD1\xFD\xC2?\xFF\xFF\xFF\xFFHA\x87}\xFF\xFF\xFF\xFF\xC06\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF0Ba\xD2\xFF\xFF\xFF\xFF\xA0G\xD2\xFA\xFF\xFF\xFF\xFF@c\xB8\xFE\xFF\xFF\xFF\xFF0F\xA8\xFF\xFF\xFF\xFF\xFF@E\x98\0\0\0\0\x000(\x88\x01\0\0\0\0@'x\x02\0\0\0\0\xB0Dq\x03\0\0\0\0\xC0Ca\x04\0\0\0\0\xB0&Q\x05\0\0\0\0\xC0%A\x06\0\0\0\0\xB0\x081\x07\0\0\0\0\xC0_\x8D\x07\0\0\0\0\xB0\xEA\x10\t\0\0\0\0@\xDB\xAD\t\0\0\0\0\xB0\xCC\xF0\n\0\0\0\0\xC0\xCB\xE0\x0B\0\0\0\x000\xE9\xD9\x0C\0\0\0\0\xC0\xAD\xC0\r\0\0\0\x000\xCB\xB9\x0E\0\0\0\0@\xCA\xA9\x0F\0\0\0\x000\xAD\x99\x10\0\0\0\0@\xAC\x89\x11\0\0\0\x000\x8Fy\x12\0\0\0\0@\x8Ei\x13\0\0\0\x000qY\x14\0\0\0\0@pI\x15\0\0\0\x000S9\x16\0\0\0\0@R)\x17\0\0\0\0\xB0o\"\x18\0\0\0\0@4\t\x19\0\0\0\0\xB0Q\x02\x1A\0\0\0\0\x10\x14+\x1A\0\0\0\0\xB0B\xF2\x1A\0\0\0\0\xA0%\xE2\x1B\0\0\0\0\xB0$\xD2\x1C\0\0\0\0\xA0\x07\xC2\x1D\0\0\0\0\xB0\x06\xB2\x1E\0\0\0\0\xA0\xE9\xA1\x1F\0\0\0\x0009v \0\0\0\0\xA0\xCB\x81!\0\0\0\x000\x1BV\"\0\0\0\0 \xE8j#\0\0\0\x000\xFD5$\0\0\0\0 \xCAJ%\0\0\0\x000\xDF\x15&\0\0\0\0 \xAC*'\0\0\0\0\xB0\xFB\xFE'\0\0\0\0 \x8E\n)\0\0\0\0\xB0\xDD\xDE)\0\0\0\0 p\xEA*\0\0\0\0\xB0\xBF\xBE+\0\0\0\0\xA0\x8C\xD3,\0\0\0\0\xB0\xA1\x9E-\0\0\0\0\xA0n\xB3.\0\0\0\0\xB0\x83~/\0\0\0\0\xA0P\x930\0\0\0\x000\xA0g1\0\0\0\0\xA02s2\0\0\0\x000\x82G3\0\0\0\0\xA0\x14S4\0\0\0\x000d'5\0\0\0\0\xA0\xF626\0\0\0\x000F\x077\0\0\0\0 \x13\x1C8\0\0\0\x000(\xE78\0\0\0\0 \xF5\xFB9\0\0\0\x000\n\xC7:\0\0\0\0 \xD7\xDB;\0\0\0\0\xB0&\xB0<\0\0\0\0 \xB9\xBB=\0\0\0\0\xB0\x08\x90>\0\0\0\0 \x9B\x9B?\0\0\0\0\xB0\xEAo@\0\0\0\0\xA0\xB7\x84A\0\0\0\0\xB0\xCCOB\0\0\0\0\xA0\x99dC\0\0\0\0\xB0\xAE/D\0\0\0\0\xA0{DE\0\0\0\x000\xE1\xF3E\0\0\0\0 \x98-G\0\0\0\0\x01\x02\x03\x03\x02\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x03\x04\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\xF8\xC4\0\0\0\0\0\0xs\xFF\xFF\xFF\xFF\xFF\xFF`s\xFF\xFF\xFF\xFF\xFF\xFFp\x81\xFF\xFF\xFF\xFF\xFF\xFFp\x81\xFF\xFF\xFF\xFF\xFF\xFF\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x98\x01\xCB\x010t\xAA\x96\xFF\xFF\xFF\xFF\xE0I\x0F\xB8\xFF\xFF\xFF\xFF\xA0@\xFD\xB8\xFF\xFF\xFF\xFF04\xF1\xB9\xFF\xFF\xFF\xFF t\xDE\xBA\xFF\xFF\xFF\xFF0\xAE8\xDA\xFF\xFF\xFF\xFF0\xFA\xEB\xDA\xFF\xFF\xFF\xFF\xB0\xE1\x19\xDC\xFF\xFF\xFF\xFF Y\xB9\xDC\xFF\xFF\xFF\xFF0\x15\xFB\xDD\xFF\xFF\xFF\xFF \xDE\x9B\xDE\xFF\xFF\xFF\xFF0\x9A\xDD\xDF\xFF\xFF\xFF\xFF 3T\xE0\xFF\xFF\xFF\xFF\xB0\xFF\x97\xF4\xFF\xFF\xFF\xFF ^\x05\xF5\xFF\xFF\xFF\xFF0d\xC0\xF6\xFF\xFF\xFF\xFF\xA0\x1E\x0E\xF7\xFF\xFF\xFF\xFF0,Q\xF8\xFF\xFF\xFF\xFF \xC5\xC7\xF8\xFF\xFF\xFF\xFF\xB0\xD2\n\xFA\xFF\xFF\xFF\xFF\xA0\xF8\xA8\xFA\xFF\xFF\xFF\xFF0\x06\xEC\xFB\xFF\xFF\xFF\xFF\xA0}\x8B\xFC\xFF\xFF\xFF\xFF0\x8E\xC9\x1D\0\0\0\0\xA0\xD7x\x1E\0\0\0\0\xB05\xA0\x1F\0\0\0\0\xA0\xCF3 \0\0\0\x000i\x81!\0\0\0\0\xA0\xC8\x0B\"\0\0\0\0\xB0\x10X#\0\0\0\0 p\xE2#\0\0\0\0\xB0\xF27%\0\0\0\0 \xC7\xD4%\0\0\0\x000y\x800\0\0\0\0\xA0M\x1D1\0\0\0\0\xB0 W2\0\0\0\0 j\x063\0\0\0\x000T84\0\0\0\0 \xC1\xF84\0\0\0\x000\x1F 6\0\0\0\0\xA0h\xCF6\0\0\0\0\xB0\xC6\xF67\0\0\0\0 \x85\xB88\0\0\0\x000\xE3\xDF9\0\0\0\0\xA0,\x8F:\0\0\0\0\xB0\xFF\xC8;\0\0\0\0\xA0\x0Eo<\0\0\0\x000\x91\xC4=\0\0\0\0\xA0\xF0N>\0\0\0\x000e\x83P\0\0\0\0\xA09 Q\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xD0\xD2\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xE0\x01&\x02L\xA8\x9Cr\xFF\xFF\xFF\xFF0\x8F\x92\xA2\xFF\xFF\xFF\xFF@R{\xB6\xFF\xFF\xFF\xFF\xB0\xC9\x1A\xB7\xFF\xFF\xFF\xFF@\x8F\x1E\xB8\xFF\xFF\xFF\xFF0p\xD4\xB8\xFF\xFF\xFF\xFF\xC0}\x17\xBA\xFF\xFF\xFF\xFF\xB0\xA3\xB5\xBA\xFF\xFF\xFF\xFF@\xB1\xF8\xBB\xFF\xFF\xFF\xFF0\xD7\x96\xBC\xFF\xFF\xFF\xFF\xC0\xE4\xD9\xBD\xFF\xFF\xFF\xFF\xB0\nx\xBE\xFF\xFF\xFF\xFF@\x18\xBB\xBF\xFF\xFF\xFF\xFF\xB0\x8FZ\xC0\xFF\xFF\xFF\xFF@\x9D\x9D\xC1\xFF\xFF\xFF\xFF0\xC3;\xC2\xFF\xFF\xFF\xFF\xC0\xD0~\xC3\xFF\xFF\xFF\xFF\xB0\xF6\x1C\xC4\xFF\xFF\xFF\xFF@\x04`\xC5\xFF\xFF\xFF\xFF0*\xFE\xC5\xFF\xFF\xFF\xFF\xC07A\xC7\xFF\xFF\xFF\xFF0\xAF\xE0\xC7\xFF\xFF\xFF\xFF@\x94\x81\xC8\xFF\xFF\xFF\xFF\xB0\xA1M\xCA\xFF\xFF\xFF\xFF\xC0\x86\xEE\xCA\xFF\xFF\xFF\xFF0\xFFM\xCE\xFF\xFF\xFF\xFF\xC0\xED\xB0\xCE\xFF\xFF\xFF\xFF\xB05)\xD3\xFF\xFF\xFF\xFF\xC0dC\xD4\xFF\xFF\xFF\xFF0\x08=\xF4\xFF\xFF\xFF\xFF\xC0\xF6\x9F\xF4\xFF\xFF\xFF\xFF0l\x05\xF5\xFF\xFF\xFF\xFF@\x102\xF6\xFF\xFF\xFF\xFF\xB0\x9F\xE6\xF6\xFF\xFF\xFF\xFF\xC0C\x13\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF@w\xF4\xF9\xFF\xFF\xFF\xFF\xB06\xD3\xFA\xFF\xFF\xFF\xFF\xC05\xC3\xFB\xFF\xFF\xFF\xFF0S\xBC\xFC\xFF\xFF\xFF\xFF@R\xAC\xFD\xFF\xFF\xFF\xFF05\x9C\xFE\xFF\xFF\xFF\xFF@4\x8C\xFF\xFF\xFF\xFF\xFF\xB0J\xA3\x07\0\0\0\0\xA0o$\x08\0\0\0\0\xB0\xB5\x94#\0\0\0\0\xA0\x94\x10$\0\0\0\0\xB0\xF27%\0\0\0\0\xA0v\xF0%\0\0\0\x000\x0F!'\0\0\0\0\xA0X\xD0'\0\0\0\x000\xF1\0)\0\0\0\0\xA0:\xB0)\0\0\0\x000\xD3\xE0*\0\0\0\0 W\x99+\0\0\0\0\xB0\xC6\xF67\0\0\0\0\xB0*\xBF8\0\0\0\0\xB0\twG\0\0\0\0 \x7F\xDCG\0\0\0\0\xB0\xA2\xFAH\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x03\x04\x03\x04\x05\x03\x04\x054\xC9\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xC3\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xE8\x01/\x02,\xAF\x9Cr\xFF\xFF\xFF\xFF0\x8F\x92\xA2\xFF\xFF\xFF\xFF@R{\xB6\xFF\xFF\xFF\xFF\xB0\xC9\x1A\xB7\xFF\xFF\xFF\xFF@\x8F\x1E\xB8\xFF\xFF\xFF\xFF0p\xD4\xB8\xFF\xFF\xFF\xFF\xC0}\x17\xBA\xFF\xFF\xFF\xFF\xB0\xA3\xB5\xBA\xFF\xFF\xFF\xFF@\xB1\xF8\xBB\xFF\xFF\xFF\xFF0\xD7\x96\xBC\xFF\xFF\xFF\xFF\xC0\xE4\xD9\xBD\xFF\xFF\xFF\xFF\xB0\nx\xBE\xFF\xFF\xFF\xFF@\x18\xBB\xBF\xFF\xFF\xFF\xFF\xB0\x8FZ\xC0\xFF\xFF\xFF\xFF@\x9D\x9D\xC1\xFF\xFF\xFF\xFF0\xC3;\xC2\xFF\xFF\xFF\xFF\xC0\xD0~\xC3\xFF\xFF\xFF\xFF\xB0\xF6\x1C\xC4\xFF\xFF\xFF\xFF@\x04`\xC5\xFF\xFF\xFF\xFF0*\xFE\xC5\xFF\xFF\xFF\xFF\xC07A\xC7\xFF\xFF\xFF\xFF0\xAF\xE0\xC7\xFF\xFF\xFF\xFF@\x94\x81\xC8\xFF\xFF\xFF\xFF\xB0\xA1M\xCA\xFF\xFF\xFF\xFF\xC0\x86\xEE\xCA\xFF\xFF\xFF\xFF0\xFFM\xCE\xFF\xFF\xFF\xFF\xC0\xED\xB0\xCE\xFF\xFF\xFF\xFF\xB05)\xD3\xFF\xFF\xFF\xFF\xC0dC\xD4\xFF\xFF\xFF\xFF0\x08=\xF4\xFF\xFF\xFF\xFF\xC0\xF6\x9F\xF4\xFF\xFF\xFF\xFF0l\x05\xF5\xFF\xFF\xFF\xFF@\x102\xF6\xFF\xFF\xFF\xFF\xB0\x9F\xE6\xF6\xFF\xFF\xFF\xFF\xC0C\x13\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF@w\xF4\xF9\xFF\xFF\xFF\xFF\xB06\xD3\xFA\xFF\xFF\xFF\xFF\xC05\xC3\xFB\xFF\xFF\xFF\xFF0S\xBC\xFC\xFF\xFF\xFF\xFF@R\xAC\xFD\xFF\xFF\xFF\xFF05\x9C\xFE\xFF\xFF\xFF\xFF@4\x8C\xFF\xFF\xFF\xFF\xFF\xB0J\xA3\x07\0\0\0\0\xA0o$\x08\0\0\0\0\xB0\xB5\x94#\0\0\0\0\xA0\x94\x10$\0\0\0\0\xB0\xF27%\0\0\0\0\xA0v\xF0%\0\0\0\x000\x0F!'\0\0\0\0\xA0X\xD0'\0\0\0\0@\xFF\0)\0\0\0\0\xA0:\xB0)\0\0\0\x000\xD3\xE0*\0\0\0\0 W\x99+\0\0\0\0\xB0\xC6\xF67\0\0\0\0\xB0*\xBF8\0\0\0\x000\xF1\xBB@\0\0\0\0\xC0\x0B\xD5@\0\0\0\0\xB0\twG\0\0\0\0 \x7F\xDCG\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x02\x05\x03\x04\x05\x03\x04\x03\x04\x03\x04\x02\x03\x04\x05\x03\x04T\xC2\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xC3\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xE0\x01%\x02\xB0\xAD\x9Cr\xFF\xFF\xFF\xFF0\x8F\x92\xA2\xFF\xFF\xFF\xFF@R{\xB6\xFF\xFF\xFF\xFF\xB0\xC9\x1A\xB7\xFF\xFF\xFF\xFF@\x8F\x1E\xB8\xFF\xFF\xFF\xFF0p\xD4\xB8\xFF\xFF\xFF\xFF\xC0}\x17\xBA\xFF\xFF\xFF\xFF\xB0\xA3\xB5\xBA\xFF\xFF\xFF\xFF@\xB1\xF8\xBB\xFF\xFF\xFF\xFF0\xD7\x96\xBC\xFF\xFF\xFF\xFF\xC0\xE4\xD9\xBD\xFF\xFF\xFF\xFF\xB0\nx\xBE\xFF\xFF\xFF\xFF@\x18\xBB\xBF\xFF\xFF\xFF\xFF\xB0\x8FZ\xC0\xFF\xFF\xFF\xFF@\x9D\x9D\xC1\xFF\xFF\xFF\xFF0\xC3;\xC2\xFF\xFF\xFF\xFF\xC0\xD0~\xC3\xFF\xFF\xFF\xFF\xB0\xF6\x1C\xC4\xFF\xFF\xFF\xFF@\x04`\xC5\xFF\xFF\xFF\xFF0*\xFE\xC5\xFF\xFF\xFF\xFF\xC07A\xC7\xFF\xFF\xFF\xFF0\xAF\xE0\xC7\xFF\xFF\xFF\xFF@\x94\x81\xC8\xFF\xFF\xFF\xFF\xB0\xA1M\xCA\xFF\xFF\xFF\xFF\xC0\x86\xEE\xCA\xFF\xFF\xFF\xFF0\xFFM\xCE\xFF\xFF\xFF\xFF\xC0\xED\xB0\xCE\xFF\xFF\xFF\xFF\xB05)\xD3\xFF\xFF\xFF\xFF\xC0dC\xD4\xFF\xFF\xFF\xFF0\x08=\xF4\xFF\xFF\xFF\xFF\xC0\xF6\x9F\xF4\xFF\xFF\xFF\xFF0l\x05\xF5\xFF\xFF\xFF\xFF@\x102\xF6\xFF\xFF\xFF\xFF\xB0\x9F\xE6\xF6\xFF\xFF\xFF\xFF\xC0C\x13\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF@w\xF4\xF9\xFF\xFF\xFF\xFF\xB06\xD3\xFA\xFF\xFF\xFF\xFF\xC05\xC3\xFB\xFF\xFF\xFF\xFF0S\xBC\xFC\xFF\xFF\xFF\xFF@R\xAC\xFD\xFF\xFF\xFF\xFF05\x9C\xFE\xFF\xFF\xFF\xFF@4\x8C\xFF\xFF\xFF\xFF\xFF\xB0J\xA3\x07\0\0\0\0\xA0o$\x08\0\0\0\0\xB0\xB5\x94#\0\0\0\0\xA0\x94\x10$\0\0\0\0\xB0\xF27%\0\0\0\0\xA0v\xF0%\0\0\0\x000\x0F!'\0\0\0\0\xA0X\xD0'\0\0\0\0@\xFF\0)\0\0\0\0\xA0:\xB0)\0\0\0\x000\xD3\xE0*\0\0\0\0 W\x99+\0\0\0\0\xB0\xC6\xF67\0\0\0\0\xB0*\xBF8\0\0\0\0\xB0\twG\0\0\0\0 \x7F\xDCG\0\0\0\0\xB0\xA2\xFAH\0\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x01\x04\x02\x03\x04\x02\x03\x02\x03\x02\x03\x04\x02\x03\x04\xD0\xC3\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xE0\x01%\x02\xB8\xAE\x9Cr\xFF\xFF\xFF\xFF0\x8F\x92\xA2\xFF\xFF\xFF\xFF@R{\xB6\xFF\xFF\xFF\xFF\xB0\xC9\x1A\xB7\xFF\xFF\xFF\xFF@\x8F\x1E\xB8\xFF\xFF\xFF\xFF0p\xD4\xB8\xFF\xFF\xFF\xFF\xC0}\x17\xBA\xFF\xFF\xFF\xFF\xB0\xA3\xB5\xBA\xFF\xFF\xFF\xFF@\xB1\xF8\xBB\xFF\xFF\xFF\xFF0\xD7\x96\xBC\xFF\xFF\xFF\xFF\xC0\xE4\xD9\xBD\xFF\xFF\xFF\xFF\xB0\nx\xBE\xFF\xFF\xFF\xFF@\x18\xBB\xBF\xFF\xFF\xFF\xFF\xB0\x8FZ\xC0\xFF\xFF\xFF\xFF@\x9D\x9D\xC1\xFF\xFF\xFF\xFF0\xC3;\xC2\xFF\xFF\xFF\xFF\xC0\xD0~\xC3\xFF\xFF\xFF\xFF\xB0\xF6\x1C\xC4\xFF\xFF\xFF\xFF@\x04`\xC5\xFF\xFF\xFF\xFF0*\xFE\xC5\xFF\xFF\xFF\xFF\xC07A\xC7\xFF\xFF\xFF\xFF0\xAF\xE0\xC7\xFF\xFF\xFF\xFF@\x94\x81\xC8\xFF\xFF\xFF\xFF\xB0\xA1M\xCA\xFF\xFF\xFF\xFF\xC0\x86\xEE\xCA\xFF\xFF\xFF\xFF0\xFFM\xCE\xFF\xFF\xFF\xFF\xC0\xED\xB0\xCE\xFF\xFF\xFF\xFF\xB05)\xD3\xFF\xFF\xFF\xFF\xC0dC\xD4\xFF\xFF\xFF\xFF0\x08=\xF4\xFF\xFF\xFF\xFF\xC0\xF6\x9F\xF4\xFF\xFF\xFF\xFF0l\x05\xF5\xFF\xFF\xFF\xFF@\x102\xF6\xFF\xFF\xFF\xFF\xB0\x9F\xE6\xF6\xFF\xFF\xFF\xFF\xC0C\x13\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF@w\xF4\xF9\xFF\xFF\xFF\xFF\xB06\xD3\xFA\xFF\xFF\xFF\xFF\xC05\xC3\xFB\xFF\xFF\xFF\xFF0S\xBC\xFC\xFF\xFF\xFF\xFF@R\xAC\xFD\xFF\xFF\xFF\xFF05\x9C\xFE\xFF\xFF\xFF\xFF@4\x8C\xFF\xFF\xFF\xFF\xFF\xB0J\xA3\x07\0\0\0\0\xA0o$\x08\0\0\0\0\xB0\xB5\x94#\0\0\0\0\xA0\x94\x10$\0\0\0\0\xB0\xF27%\0\0\0\0\xA0v\xF0%\0\0\0\0\xC0W*'\0\0\0\0\xB0\xDB\xE2'\0\0\0\0@\x8A\xEE(\0\0\0\0\xA0 a)\0\0\0\0\xA0:\xB0)\0\0\0\x000\xD3\xE0*\0\0\0\0 W\x99+\0\0\0\0\xB0\xC6\xF67\0\0\0\0\xB0*\xBF8\0\0\0\0\xB0\twG\0\0\0\0 \x7F\xDCG\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x04\x05\x03\x04\x05\x02\x03\x04\x02\x05\x05\x03\x04\x05\x03\x04\x03\x04\x03\x04\x05\x03\x04\xC8\xC2\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xC3\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xF0\x019\x02,\xB0\x9Cr\xFF\xFF\xFF\xFF0\x8F\x92\xA2\xFF\xFF\xFF\xFF@R{\xB6\xFF\xFF\xFF\xFF\xB0\xC9\x1A\xB7\xFF\xFF\xFF\xFF@\x8F\x1E\xB8\xFF\xFF\xFF\xFF0p\xD4\xB8\xFF\xFF\xFF\xFF\xC0}\x17\xBA\xFF\xFF\xFF\xFF\xB0\xA3\xB5\xBA\xFF\xFF\xFF\xFF@\xB1\xF8\xBB\xFF\xFF\xFF\xFF0\xD7\x96\xBC\xFF\xFF\xFF\xFF\xC0\xE4\xD9\xBD\xFF\xFF\xFF\xFF\xB0\nx\xBE\xFF\xFF\xFF\xFF@\x18\xBB\xBF\xFF\xFF\xFF\xFF\xB0\x8FZ\xC0\xFF\xFF\xFF\xFF@\x9D\x9D\xC1\xFF\xFF\xFF\xFF0\xC3;\xC2\xFF\xFF\xFF\xFF\xC0\xD0~\xC3\xFF\xFF\xFF\xFF\xB0\xF6\x1C\xC4\xFF\xFF\xFF\xFF@\x04`\xC5\xFF\xFF\xFF\xFF0*\xFE\xC5\xFF\xFF\xFF\xFF\xC07A\xC7\xFF\xFF\xFF\xFF0\xAF\xE0\xC7\xFF\xFF\xFF\xFF@\x94\x81\xC8\xFF\xFF\xFF\xFF\xB0\xA1M\xCA\xFF\xFF\xFF\xFF\xC0\x86\xEE\xCA\xFF\xFF\xFF\xFF0\xFFM\xCE\xFF\xFF\xFF\xFF\xC0\xED\xB0\xCE\xFF\xFF\xFF\xFF\xB05)\xD3\xFF\xFF\xFF\xFF\xC0dC\xD4\xFF\xFF\xFF\xFF0\x08=\xF4\xFF\xFF\xFF\xFF\xC0\xF6\x9F\xF4\xFF\xFF\xFF\xFF0l\x05\xF5\xFF\xFF\xFF\xFF@\x102\xF6\xFF\xFF\xFF\xFF\xB0\x9F\xE6\xF6\xFF\xFF\xFF\xFF\xC0C\x13\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF@w\xF4\xF9\xFF\xFF\xFF\xFF\xB06\xD3\xFA\xFF\xFF\xFF\xFF\xC05\xC3\xFB\xFF\xFF\xFF\xFF0S\xBC\xFC\xFF\xFF\xFF\xFF@R\xAC\xFD\xFF\xFF\xFF\xFF05\x9C\xFE\xFF\xFF\xFF\xFF@4\x8C\xFF\xFF\xFF\xFF\xFF\xB0J\xA3\x07\0\0\0\0\xA0o$\x08\0\0\0\0\xB0\xB5\x94#\0\0\0\0\xA0\x94\x10$\0\0\0\0\xB0\xF27%\0\0\0\0\xA0v\xF0%\0\0\0\x000\x0F!'\0\0\0\0\xA0\xB5\xCD'\0\0\0\0@&&(\0\0\0\x000\xF1\0)\0\0\0\0\xA0:\xB0)\0\0\0\x000\xD3\xE0*\0\0\0\0 W\x99+\0\0\0\0\xB0\xC6\xF67\0\0\0\0\xB0*\xBF8\0\0\0\x000\xF1\xBB@\0\0\0\0\xC0\x0B\xD5@\0\0\0\0\xB0\twG\0\0\0\0 \x7F\xDCG\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x02\x03\x04\x05\x03\x04\x05\x03\x04\x03\x04\x03\x04\x02\x03\x04\x05\x03\x04T\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xC3\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xE8\x01/\x02\x04\xB2\x9Cr\xFF\xFF\xFF\xFF0\x8F\x92\xA2\xFF\xFF\xFF\xFF@R{\xB6\xFF\xFF\xFF\xFF\xB0\xC9\x1A\xB7\xFF\xFF\xFF\xFF@\x8F\x1E\xB8\xFF\xFF\xFF\xFF0p\xD4\xB8\xFF\xFF\xFF\xFF\xC0}\x17\xBA\xFF\xFF\xFF\xFF\xB0\xA3\xB5\xBA\xFF\xFF\xFF\xFF@\xB1\xF8\xBB\xFF\xFF\xFF\xFF0\xD7\x96\xBC\xFF\xFF\xFF\xFF\xC0\xE4\xD9\xBD\xFF\xFF\xFF\xFF\xB0\nx\xBE\xFF\xFF\xFF\xFF@\x18\xBB\xBF\xFF\xFF\xFF\xFF\xB0\x8FZ\xC0\xFF\xFF\xFF\xFF@\x9D\x9D\xC1\xFF\xFF\xFF\xFF0\xC3;\xC2\xFF\xFF\xFF\xFF\xC0\xD0~\xC3\xFF\xFF\xFF\xFF\xB0\xF6\x1C\xC4\xFF\xFF\xFF\xFF@\x04`\xC5\xFF\xFF\xFF\xFF0*\xFE\xC5\xFF\xFF\xFF\xFF\xC07A\xC7\xFF\xFF\xFF\xFF0\xAF\xE0\xC7\xFF\xFF\xFF\xFF@\x94\x81\xC8\xFF\xFF\xFF\xFF\xB0\xA1M\xCA\xFF\xFF\xFF\xFF\xC0\x86\xEE\xCA\xFF\xFF\xFF\xFF0\xFFM\xCE\xFF\xFF\xFF\xFF\xC0\xED\xB0\xCE\xFF\xFF\xFF\xFF\xB05)\xD3\xFF\xFF\xFF\xFF\xC0dC\xD4\xFF\xFF\xFF\xFF0\x08=\xF4\xFF\xFF\xFF\xFF\xC0\xF6\x9F\xF4\xFF\xFF\xFF\xFF0l\x05\xF5\xFF\xFF\xFF\xFF@\x102\xF6\xFF\xFF\xFF\xFF\xB0\x9F\xE6\xF6\xFF\xFF\xFF\xFF\xC0C\x13\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF@w\xF4\xF9\xFF\xFF\xFF\xFF\xB06\xD3\xFA\xFF\xFF\xFF\xFF\xC05\xC3\xFB\xFF\xFF\xFF\xFF0S\xBC\xFC\xFF\xFF\xFF\xFF@R\xAC\xFD\xFF\xFF\xFF\xFF05\x9C\xFE\xFF\xFF\xFF\xFF@4\x8C\xFF\xFF\xFF\xFF\xFF\xB0J\xA3\x07\0\0\0\0\xA0o$\x08\0\0\0\0\xB0\xB5\x94#\0\0\0\0\xA0\x94\x10$\0\0\0\0\xB0\xF27%\0\0\0\0\xA0v\xF0%\0\0\0\0@4\x19'\0\0\0\0\xB0\xC3\xCD'\0\0\0\0\xC0g\xFA(\0\0\0\0\xB0H\xB0)\0\0\0\0@\xE1\xE0*\0\0\0\0 W\x99+\0\0\0\0\xB0\xC6\xF67\0\0\0\0\xB0*\xBF8\0\0\0\0\xB0\x13\xB0@\0\0\0\0\xC0>VA\0\0\0\0\xB0\twG\0\0\0\0 \x7F\xDCG\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x04\x05\x03\x04\x05\x02\x03\x04\x02\x03\x04\x02\x05\x03\x04\x03\x04\x03\x04\x02\x03\x04\x05\x03\x04|\xBF\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xC3\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xE8\x010\x02d\xB2\x9Cr\xFF\xFF\xFF\xFF0\x8F\x92\xA2\xFF\xFF\xFF\xFF@R{\xB6\xFF\xFF\xFF\xFF\xB0\xC9\x1A\xB7\xFF\xFF\xFF\xFF@\x8F\x1E\xB8\xFF\xFF\xFF\xFF0p\xD4\xB8\xFF\xFF\xFF\xFF\xC0}\x17\xBA\xFF\xFF\xFF\xFF\xB0\xA3\xB5\xBA\xFF\xFF\xFF\xFF@\xB1\xF8\xBB\xFF\xFF\xFF\xFF0\xD7\x96\xBC\xFF\xFF\xFF\xFF\xC0\xE4\xD9\xBD\xFF\xFF\xFF\xFF\xB0\nx\xBE\xFF\xFF\xFF\xFF@\x18\xBB\xBF\xFF\xFF\xFF\xFF\xB0\x8FZ\xC0\xFF\xFF\xFF\xFF@\x9D\x9D\xC1\xFF\xFF\xFF\xFF0\xC3;\xC2\xFF\xFF\xFF\xFF\xC0\xD0~\xC3\xFF\xFF\xFF\xFF\xB0\xF6\x1C\xC4\xFF\xFF\xFF\xFF@\x04`\xC5\xFF\xFF\xFF\xFF0*\xFE\xC5\xFF\xFF\xFF\xFF\xC07A\xC7\xFF\xFF\xFF\xFF0\xAF\xE0\xC7\xFF\xFF\xFF\xFF@\x94\x81\xC8\xFF\xFF\xFF\xFF\xB0\xA1M\xCA\xFF\xFF\xFF\xFF\xC0\x86\xEE\xCA\xFF\xFF\xFF\xFF0\xFFM\xCE\xFF\xFF\xFF\xFF\xC0\xED\xB0\xCE\xFF\xFF\xFF\xFF\xB05)\xD3\xFF\xFF\xFF\xFF\xC0dC\xD4\xFF\xFF\xFF\xFF0\x08=\xF4\xFF\xFF\xFF\xFF\xC0\xF6\x9F\xF4\xFF\xFF\xFF\xFF0l\x05\xF5\xFF\xFF\xFF\xFF@\x102\xF6\xFF\xFF\xFF\xFF\xB0\x9F\xE6\xF6\xFF\xFF\xFF\xFF\xC0C\x13\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF@w\xF4\xF9\xFF\xFF\xFF\xFF\xB06\xD3\xFA\xFF\xFF\xFF\xFF\xC05\xC3\xFB\xFF\xFF\xFF\xFF0S\xBC\xFC\xFF\xFF\xFF\xFF@R\xAC\xFD\xFF\xFF\xFF\xFF05\x9C\xFE\xFF\xFF\xFF\xFF@4\x8C\xFF\xFF\xFF\xFF\xFF\xB0J\xA3\x07\0\0\0\0\xA0o$\x08\0\0\0\0\xB0\xB5\x94#\0\0\0\0\xA0\x94\x10$\0\0\0\0\xB0\xF27%\0\0\0\0\xA0v\xF0%\0\0\0\x000\x0F!'\0\0\0\0\xA0X\xD0'\0\0\0\x000\xF1\0)\0\0\0\0\xA0:\xB0)\0\0\0\x000\xD3\xE0*\0\0\0\0 W\x99+\0\0\0\0\xB0\xC6\xF67\0\0\0\0\xB0*\xBF8\0\0\0\x000\xF1\xBB@\0\0\0\0\xC0\x0B\xD5@\0\0\0\0\xB0\twG\0\0\0\0 \x7F\xDCG\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x03\x04\x03\x04\x02\x03\x04\x05\x03\x04\x1C\xBF\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xC3\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xD8\x01\x1C\x02\xD4\xAE\x9Cr\xFF\xFF\xFF\xFF0\x8F\x92\xA2\xFF\xFF\xFF\xFF@R{\xB6\xFF\xFF\xFF\xFF\xB0\xC9\x1A\xB7\xFF\xFF\xFF\xFF@\x8F\x1E\xB8\xFF\xFF\xFF\xFF0p\xD4\xB8\xFF\xFF\xFF\xFF\xC0}\x17\xBA\xFF\xFF\xFF\xFF\xB0\xA3\xB5\xBA\xFF\xFF\xFF\xFF@\xB1\xF8\xBB\xFF\xFF\xFF\xFF0\xD7\x96\xBC\xFF\xFF\xFF\xFF\xC0\xE4\xD9\xBD\xFF\xFF\xFF\xFF\xB0\nx\xBE\xFF\xFF\xFF\xFF@\x18\xBB\xBF\xFF\xFF\xFF\xFF\xB0\x8FZ\xC0\xFF\xFF\xFF\xFF@\x9D\x9D\xC1\xFF\xFF\xFF\xFF0\xC3;\xC2\xFF\xFF\xFF\xFF\xC0\xD0~\xC3\xFF\xFF\xFF\xFF\xB0\xF6\x1C\xC4\xFF\xFF\xFF\xFF@\x04`\xC5\xFF\xFF\xFF\xFF0*\xFE\xC5\xFF\xFF\xFF\xFF\xC07A\xC7\xFF\xFF\xFF\xFF0\xAF\xE0\xC7\xFF\xFF\xFF\xFF@\x94\x81\xC8\xFF\xFF\xFF\xFF\xB0\xA1M\xCA\xFF\xFF\xFF\xFF\xC0\x86\xEE\xCA\xFF\xFF\xFF\xFF0\xFFM\xCE\xFF\xFF\xFF\xFF\xC0\xED\xB0\xCE\xFF\xFF\xFF\xFF\xB05)\xD3\xFF\xFF\xFF\xFF\xC0dC\xD4\xFF\xFF\xFF\xFF0\x08=\xF4\xFF\xFF\xFF\xFF\xC0\xF6\x9F\xF4\xFF\xFF\xFF\xFF0l\x05\xF5\xFF\xFF\xFF\xFF@\x102\xF6\xFF\xFF\xFF\xFF\xB0\x9F\xE6\xF6\xFF\xFF\xFF\xFF\xC0C\x13\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF@w\xF4\xF9\xFF\xFF\xFF\xFF\xB06\xD3\xFA\xFF\xFF\xFF\xFF\xC05\xC3\xFB\xFF\xFF\xFF\xFF0S\xBC\xFC\xFF\xFF\xFF\xFF@R\xAC\xFD\xFF\xFF\xFF\xFF05\x9C\xFE\xFF\xFF\xFF\xFF@4\x8C\xFF\xFF\xFF\xFF\xFF\xB0J\xA3\x07\0\0\0\0\xA0o$\x08\0\0\0\0\xB0\xB5\x94#\0\0\0\0\xA0\x94\x10$\0\0\0\0\xB0\xF27%\0\0\0\0\xA0v\xF0%\0\0\0\x000\x0F!'\0\0\0\0\xA0X\xD0'\0\0\0\0@\xFF\0)\0\0\0\0\xA0:\xB0)\0\0\0\x000\xD3\xE0*\0\0\0\0 W\x99+\0\0\0\0\xB0\xC6\xF67\0\0\0\0\xB0*\xBF8\0\0\0\0\xB0\twG\0\0\0\0 \x7F\xDCG\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x02\x05\x03\x04\x05\x03\x04\x03\x04\x03\x04\x05\x03\x04\xAC\xC2\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xC3\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xF0\x019\x02\xBC\xB1\x9Cr\xFF\xFF\xFF\xFF0\x8F\x92\xA2\xFF\xFF\xFF\xFF@R{\xB6\xFF\xFF\xFF\xFF\xB0\xC9\x1A\xB7\xFF\xFF\xFF\xFF@\x8F\x1E\xB8\xFF\xFF\xFF\xFF0p\xD4\xB8\xFF\xFF\xFF\xFF\xC0}\x17\xBA\xFF\xFF\xFF\xFF\xB0\xA3\xB5\xBA\xFF\xFF\xFF\xFF@\xB1\xF8\xBB\xFF\xFF\xFF\xFF0\xD7\x96\xBC\xFF\xFF\xFF\xFF\xC0\xE4\xD9\xBD\xFF\xFF\xFF\xFF\xB0\nx\xBE\xFF\xFF\xFF\xFF@\x18\xBB\xBF\xFF\xFF\xFF\xFF\xB0\x8FZ\xC0\xFF\xFF\xFF\xFF@\x9D\x9D\xC1\xFF\xFF\xFF\xFF0\xC3;\xC2\xFF\xFF\xFF\xFF\xC0\xD0~\xC3\xFF\xFF\xFF\xFF\xB0\xF6\x1C\xC4\xFF\xFF\xFF\xFF@\x04`\xC5\xFF\xFF\xFF\xFF0*\xFE\xC5\xFF\xFF\xFF\xFF\xC07A\xC7\xFF\xFF\xFF\xFF0\xAF\xE0\xC7\xFF\xFF\xFF\xFF@\x94\x81\xC8\xFF\xFF\xFF\xFF\xB0\xA1M\xCA\xFF\xFF\xFF\xFF\xC0\x86\xEE\xCA\xFF\xFF\xFF\xFF0\xFFM\xCE\xFF\xFF\xFF\xFF\xC0\xED\xB0\xCE\xFF\xFF\xFF\xFF\xB05)\xD3\xFF\xFF\xFF\xFF\xC0dC\xD4\xFF\xFF\xFF\xFF0\x08=\xF4\xFF\xFF\xFF\xFF\xC0\xF6\x9F\xF4\xFF\xFF\xFF\xFF0l\x05\xF5\xFF\xFF\xFF\xFF@\x102\xF6\xFF\xFF\xFF\xFF\xB0\x9F\xE6\xF6\xFF\xFF\xFF\xFF\xC0C\x13\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF@w\xF4\xF9\xFF\xFF\xFF\xFF\xB06\xD3\xFA\xFF\xFF\xFF\xFF\xC05\xC3\xFB\xFF\xFF\xFF\xFF0S\xBC\xFC\xFF\xFF\xFF\xFF@R\xAC\xFD\xFF\xFF\xFF\xFF05\x9C\xFE\xFF\xFF\xFF\xFF@4\x8C\xFF\xFF\xFF\xFF\xFF\xB0J\xA3\x07\0\0\0\0\xA0o$\x08\0\0\0\0\xB0\xB5\x94#\0\0\0\0\xA0\x94\x10$\0\0\0\0\xB0\xF27%\0\0\0\0\xA0v\xF0%\0\0\0\x000\x0F!'\0\0\0\0\xA0\xB5\xCD'\0\0\0\0@&&(\0\0\0\x000\xF1\0)\0\0\0\0\xA0:\xB0)\0\0\0\x000\xD3\xE0*\0\0\0\0 W\x99+\0\0\0\0\xB0\xC6\xF67\0\0\0\0\xB0*\xBF8\0\0\0\0\xB0\x9F\xBA@\0\0\0\0@0\x03A\0\0\0\0\xB0\twG\0\0\0\0 \x7F\xDCG\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x02\x03\x04\x05\x03\x04\x05\x03\x04\x03\x04\x03\x04\x02\x03\x04\x05\x03\x04\xC4\xBF\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xC3\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xE8\x01/\x02\xB4\xAF\x9Cr\xFF\xFF\xFF\xFF0\x8F\x92\xA2\xFF\xFF\xFF\xFF@R{\xB6\xFF\xFF\xFF\xFF\xB0\xC9\x1A\xB7\xFF\xFF\xFF\xFF@\x8F\x1E\xB8\xFF\xFF\xFF\xFF0p\xD4\xB8\xFF\xFF\xFF\xFF\xC0}\x17\xBA\xFF\xFF\xFF\xFF\xB0\xA3\xB5\xBA\xFF\xFF\xFF\xFF@\xB1\xF8\xBB\xFF\xFF\xFF\xFF0\xD7\x96\xBC\xFF\xFF\xFF\xFF\xC0\xE4\xD9\xBD\xFF\xFF\xFF\xFF\xB0\nx\xBE\xFF\xFF\xFF\xFF@\x18\xBB\xBF\xFF\xFF\xFF\xFF\xB0\x8FZ\xC0\xFF\xFF\xFF\xFF@\x9D\x9D\xC1\xFF\xFF\xFF\xFF0\xC3;\xC2\xFF\xFF\xFF\xFF\xC0\xD0~\xC3\xFF\xFF\xFF\xFF\xB0\xF6\x1C\xC4\xFF\xFF\xFF\xFF@\x04`\xC5\xFF\xFF\xFF\xFF0*\xFE\xC5\xFF\xFF\xFF\xFF\xC07A\xC7\xFF\xFF\xFF\xFF0\xAF\xE0\xC7\xFF\xFF\xFF\xFF@\x94\x81\xC8\xFF\xFF\xFF\xFF\xB0\xA1M\xCA\xFF\xFF\xFF\xFF\xC0\x86\xEE\xCA\xFF\xFF\xFF\xFF0\xFFM\xCE\xFF\xFF\xFF\xFF\xC0\xED\xB0\xCE\xFF\xFF\xFF\xFF\xB05)\xD3\xFF\xFF\xFF\xFF\xC0dC\xD4\xFF\xFF\xFF\xFF0\x08=\xF4\xFF\xFF\xFF\xFF\xC0\xF6\x9F\xF4\xFF\xFF\xFF\xFF0l\x05\xF5\xFF\xFF\xFF\xFF@\x102\xF6\xFF\xFF\xFF\xFF\xB0\x9F\xE6\xF6\xFF\xFF\xFF\xFF\xC0C\x13\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF@w\xF4\xF9\xFF\xFF\xFF\xFF\xB06\xD3\xFA\xFF\xFF\xFF\xFF\xC05\xC3\xFB\xFF\xFF\xFF\xFF0S\xBC\xFC\xFF\xFF\xFF\xFF@R\xAC\xFD\xFF\xFF\xFF\xFF05\x9C\xFE\xFF\xFF\xFF\xFF@4\x8C\xFF\xFF\xFF\xFF\xFF\xB0J\xA3\x07\0\0\0\0\xA0o$\x08\0\0\0\0\xB0\xB5\x94#\0\0\0\0\xA0\x94\x10$\0\0\0\0\xB0\xF27%\0\0\0\0\xA0\xA5\xFD%\0\0\0\0@4\x19'\0\0\0\0\xB0\xC3\xCD'\0\0\0\0\xC0\x1BG(\0\0\0\0\xB0\xC6\xF67\0\0\0\0\xB0*\xBF8\0\0\0\0\xB0\x9F\xBA@\0\0\0\0@0\x03A\0\0\0\0\xB0\twG\0\0\0\0\xA0\xFC\x93G\0\0\0\0@v\xF1H\0\0\0\0\xB04\xB3I\0\0\0\0@X\xD1J\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x04\x05\x03\x04\x05\x02\x03\x04\x02\x03\x04\x03\x04\x03\x04\x02\x03\x04\x05\x02\x03\x04\x02\x03\x04\xCC\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xC3\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xF0\x018\x02\xA4\xAE\x9Cr\xFF\xFF\xFF\xFF0\x8F\x92\xA2\xFF\xFF\xFF\xFF@R{\xB6\xFF\xFF\xFF\xFF\xB0\xC9\x1A\xB7\xFF\xFF\xFF\xFF@\x8F\x1E\xB8\xFF\xFF\xFF\xFF0p\xD4\xB8\xFF\xFF\xFF\xFF\xC0}\x17\xBA\xFF\xFF\xFF\xFF\xB0\xA3\xB5\xBA\xFF\xFF\xFF\xFF@\xB1\xF8\xBB\xFF\xFF\xFF\xFF0\xD7\x96\xBC\xFF\xFF\xFF\xFF\xC0\xE4\xD9\xBD\xFF\xFF\xFF\xFF\xB0\nx\xBE\xFF\xFF\xFF\xFF@\x18\xBB\xBF\xFF\xFF\xFF\xFF\xB0\x8FZ\xC0\xFF\xFF\xFF\xFF@\x9D\x9D\xC1\xFF\xFF\xFF\xFF0\xC3;\xC2\xFF\xFF\xFF\xFF\xC0\xD0~\xC3\xFF\xFF\xFF\xFF\xB0\xF6\x1C\xC4\xFF\xFF\xFF\xFF@\x04`\xC5\xFF\xFF\xFF\xFF0*\xFE\xC5\xFF\xFF\xFF\xFF\xC07A\xC7\xFF\xFF\xFF\xFF0\xAF\xE0\xC7\xFF\xFF\xFF\xFF@\x94\x81\xC8\xFF\xFF\xFF\xFF\xB0\xA1M\xCA\xFF\xFF\xFF\xFF\xC0\x86\xEE\xCA\xFF\xFF\xFF\xFF0\xFFM\xCE\xFF\xFF\xFF\xFF\xC0\xED\xB0\xCE\xFF\xFF\xFF\xFF\xB05)\xD3\xFF\xFF\xFF\xFF\xC0dC\xD4\xFF\xFF\xFF\xFF0\x08=\xF4\xFF\xFF\xFF\xFF\xC0\xF6\x9F\xF4\xFF\xFF\xFF\xFF0l\x05\xF5\xFF\xFF\xFF\xFF@\x102\xF6\xFF\xFF\xFF\xFF\xB0\x9F\xE6\xF6\xFF\xFF\xFF\xFF\xC0C\x13\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF@w\xF4\xF9\xFF\xFF\xFF\xFF\xB06\xD3\xFA\xFF\xFF\xFF\xFF\xC05\xC3\xFB\xFF\xFF\xFF\xFF0S\xBC\xFC\xFF\xFF\xFF\xFF@R\xAC\xFD\xFF\xFF\xFF\xFF05\x9C\xFE\xFF\xFF\xFF\xFF@4\x8C\xFF\xFF\xFF\xFF\xFF\xB0J\xA3\x07\0\0\0\0\xA0o$\x08\0\0\0\0\xB0\xB5\x94#\0\0\0\0\xA0\x94\x10$\0\0\0\0\xB0\xF27%\0\0\0\0\xA0v\xF0%\0\0\0\x000\x0F!'\0\0\0\0\xA0X\xD0'\0\0\0\0@\xFF\0)\0\0\0\0\xA0:\xB0)\0\0\0\x000\xD3\xE0*\0\0\0\0 W\x99+\0\0\0\0\xB0\xC6\xF67\0\0\0\0\xB0*\xBF8\0\0\0\x000\xF1\xBB@\0\0\0\0@\xD1\xCB@\0\0\0\0\xB0\twG\0\0\0\0 \x7F\xDCG\0\0\0\0\xB0\xA2\xFAH\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x02\x05\x03\x04\x05\x03\x04\x03\x04\x03\x04\x02\x03\x04\x05\x03\x04\x05\xDC\xC2\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xC3\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xE8\x010\x02\x88\xB1\x9Cr\xFF\xFF\xFF\xFF0\x8F\x92\xA2\xFF\xFF\xFF\xFF@R{\xB6\xFF\xFF\xFF\xFF\xB0\xC9\x1A\xB7\xFF\xFF\xFF\xFF@\x8F\x1E\xB8\xFF\xFF\xFF\xFF0p\xD4\xB8\xFF\xFF\xFF\xFF\xC0}\x17\xBA\xFF\xFF\xFF\xFF\xB0\xA3\xB5\xBA\xFF\xFF\xFF\xFF@\xB1\xF8\xBB\xFF\xFF\xFF\xFF0\xD7\x96\xBC\xFF\xFF\xFF\xFF\xC0\xE4\xD9\xBD\xFF\xFF\xFF\xFF\xB0\nx\xBE\xFF\xFF\xFF\xFF@\x18\xBB\xBF\xFF\xFF\xFF\xFF\xB0\x8FZ\xC0\xFF\xFF\xFF\xFF@\x9D\x9D\xC1\xFF\xFF\xFF\xFF0\xC3;\xC2\xFF\xFF\xFF\xFF\xC0\xD0~\xC3\xFF\xFF\xFF\xFF\xB0\xF6\x1C\xC4\xFF\xFF\xFF\xFF@\x04`\xC5\xFF\xFF\xFF\xFF0*\xFE\xC5\xFF\xFF\xFF\xFF\xC07A\xC7\xFF\xFF\xFF\xFF0\xAF\xE0\xC7\xFF\xFF\xFF\xFF@\x94\x81\xC8\xFF\xFF\xFF\xFF\xB0\xA1M\xCA\xFF\xFF\xFF\xFF\xC0\x86\xEE\xCA\xFF\xFF\xFF\xFF0\xFFM\xCE\xFF\xFF\xFF\xFF\xC0\xED\xB0\xCE\xFF\xFF\xFF\xFF\xB05)\xD3\xFF\xFF\xFF\xFF\xC0dC\xD4\xFF\xFF\xFF\xFF0\x08=\xF4\xFF\xFF\xFF\xFF\xC0\xF6\x9F\xF4\xFF\xFF\xFF\xFF0l\x05\xF5\xFF\xFF\xFF\xFF@\x102\xF6\xFF\xFF\xFF\xFF\xB0\x9F\xE6\xF6\xFF\xFF\xFF\xFF\xC0C\x13\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF@w\xF4\xF9\xFF\xFF\xFF\xFF\xB06\xD3\xFA\xFF\xFF\xFF\xFF\xC05\xC3\xFB\xFF\xFF\xFF\xFF0S\xBC\xFC\xFF\xFF\xFF\xFF@R\xAC\xFD\xFF\xFF\xFF\xFF05\x9C\xFE\xFF\xFF\xFF\xFF@4\x8C\xFF\xFF\xFF\xFF\xFF\xB0J\xA3\x07\0\0\0\0\xA0o$\x08\0\0\0\0\xB0\xB5\x94#\0\0\0\0\xA0\x94\x10$\0\0\0\0\xB0\xF27%\0\0\0\0\xA0v\xF0%\0\0\0\x000\x0F!'\0\0\0\0\xA0X\xD0'\0\0\0\x000\xF1\0)\0\0\0\0\xA0:\xB0)\0\0\0\x000\xD3\xE0*\0\0\0\0 W\x99+\0\0\0\0\xB0\xC6\xF67\0\0\0\0\xB0*\xBF8\0\0\0\x000N\xB9@\0\0\0\0\xC0\x0B\xD5@\0\0\0\0\xB0\twG\0\0\0\0 \x7F\xDCG\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x03\x04\x03\x04\x02\x03\x04\x05\x03\x04\xF8\xBF\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xC3\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x03\xDB\x03\x90\x11\x87i\xFF\xFF\xFF\xFF\x90\xF5\x17\xB8\xFF\xFF\xFF\xFF@\xDA+\x05\0\0\0\0\xB0\xF0\xFC\x07\0\0\0\0\xC0t\xCF\n\0\0\0\0\xB0\xCA\x97\x0B\0\0\0\0\xC0\xF9\xB1\x0C\0\0\0\x000\xFEx\r\0\0\0\0@-\x93\x0E\0\0\0\0\xB01Z\x0F\0\0\0\0\xC0`t\x10\0\0\0\0\xB0Cd\x11\0\0\0\0@\x94U\x12\0\0\0\0\xB0\xC8F\x13\0\0\0\0@\x198\x14\0\0\0\x000\xFC'\x15\0\0\0\0\xC0L\x19\x16\0\0\0\0\xB0/\t\x17\0\0\0\0@\x80\xFA\x17\0\0\0\x000c\xEA\x18\0\0\0\0\xC0\xB3\xDB\x19\0\0\0\x000\xE8\xCC\x1A\0\0\0\0\xC08\xBE\x1B\0\0\0\0\xB0\x1B\xAE\x1C\0\0\0\0@l\x9F\x1D\0\0\0\x000O\x8F\x1E\0\0\0\0\xC0\x9F\x80\x1F\0\0\0\0\xB0\x82p \0\0\0\0@\xD3a!\0\0\0\0\xB0\x07S\"\0\0\0\0@XD#\0\0\0\x000;4$\0\0\0\0@;A%\0\0\0\0\xB0n\x15&\0\0\0\0@\xBF\x06'\0\0\0\x000\xA2\xF6'\0\0\0\0@\x8A\xEE(\0\0\0\0\xB0H\xB0)\0\0\0\0\xC0\xBD\xCF*\0\0\0\x000\t\xB9+\0\0\0\0@\xAB\xAB,\0\0\0\0\xB0\x0Cp-\0\0\0\0\xC0\xDE\x8C.\0\0\0\0\xB0\xEEO/\0\0\0\0@\x12n0\0\0\0\x000h61\0\0\0\0\xC0.W2\0\0\0\0\xB0\xB2\x0F3\0\0\0\0\xC0\x1074\0\0\0\x000\xCF\xF84\0\0\0\0\xC0\xF2\x166\0\0\0\0\xB0\xEB\xE16\0\0\0\0\xC0\xD4\xF67\0\0\0\0\xB0\xCD\xC18\0\0\0\0\xC0\xB6\xD69\0\0\0\0\xB0\xAF\xA1:\0\0\0\0@\xD3\xBF;\0\0\0\x000\xB6\xAF<\0\0\0\0\xC0\x90q=\0\0\0\x000\x98\x8F>\0\0\0\0@\xADZ?\0\0\0\x000zo@\0\0\0\0@\xEEqA\0\0\0\0\xB0\xAC3B\0\0\0\0@\xD0QC\0\0\0\0\xB0\x8E\x13D\0\0\0\0@\xB21E\0\0\0\0\xB0p\xF3E\0\0\0\0\xC0\xCE\x1AG\0\0\0\0\xB0R\xD3G\0\0\0\0\xC0\xB0\xFAH\0\0\0\0\xB04\xB3I\0\0\0\0\xC0\x92\xDAJ\0\0\0\x000;\xC1K\0\0\0\0\xC0\xFF\xA7L\0\0\0\x000\x1D\xA1M\0\0\0\0\xC0\xE1\x87N\0\0\0\x000\xFF\x80O\0\0\0\0@\xFEpP\0\0\0\x000lNQ\0\0\0\0@\xE0PR\0\0\0\x000N.S\0\0\0\0@\xC20T\0\0\0\x0000\x0EU\0\0\0\0@\xA4\x10V\0\0\0\0\xB0L\xF7V\0\0\0\0@\x86\xF0W\0\0\0\0\xB0.\xD7X\0\0\0\0@h\xD0Y\0\0\0\0\xB0\x10\xB7Z\0\0\0\0\xC0\x84\xB9[\0\0\0\0\xB0\xF2\x96\\\0\0\0\0\xC0f\x99]\0\0\0\0\xB0\xD4v^\0\0\0\0\xC0Hy_\0\0\0\x000\xF1_`\0\0\0\0\xC0*Ya\0\0\0\x000\xD3?b\0\0\0\0\xC0\x0C9c\0\0\0\x000\xB5\x1Fd\0\0\0\0\xC0\xEE\x18e\0\0\0\x000\x97\xFFe\0\0\0\0@\x0B\x02g\0\0\0\0\xB0\xDA\rg\0\0\0\0\0\x01\x02\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x02\x03\xF0\xC9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xE8\x01%\x02\x1Ck\xAA\x96\xFF\xFF\xFF\xFF\xE0I\x0F\xB8\xFF\xFF\xFF\xFF\xA0@\xFD\xB8\xFF\xFF\xFF\xFF04\xF1\xB9\xFF\xFF\xFF\xFF t\xDE\xBA\xFF\xFF\xFF\xFF0\xAE8\xDA\xFF\xFF\xFF\xFF0\xFA\xEB\xDA\xFF\xFF\xFF\xFF\xB0\xE1\x19\xDC\xFF\xFF\xFF\xFF Y\xB9\xDC\xFF\xFF\xFF\xFF0\x15\xFB\xDD\xFF\xFF\xFF\xFF \xDE\x9B\xDE\xFF\xFF\xFF\xFF0\x9A\xDD\xDF\xFF\xFF\xFF\xFF 3T\xE0\xFF\xFF\xFF\xFF\xB0\xFF\x97\xF4\xFF\xFF\xFF\xFF ^\x05\xF5\xFF\xFF\xFF\xFF0d\xC0\xF6\xFF\xFF\xFF\xFF\xA0\x1E\x0E\xF7\xFF\xFF\xFF\xFF0,Q\xF8\xFF\xFF\xFF\xFF \xC5\xC7\xF8\xFF\xFF\xFF\xFF\xB0\xD2\n\xFA\xFF\xFF\xFF\xFF\xA0\xF8\xA8\xFA\xFF\xFF\xFF\xFF0\x06\xEC\xFB\xFF\xFF\xFF\xFF\xA0}\x8B\xFC\xFF\xFF\xFF\xFF0\x8E\xC9\x1D\0\0\0\0\xA0\xD7x\x1E\0\0\0\0\xB05\xA0\x1F\0\0\0\0\xA0\xCF3 \0\0\0\x000i\x81!\0\0\0\0\xA0\xC8\x0B\"\0\0\0\0\xB0\x10X#\0\0\0\0 p\xE2#\0\0\0\0\xB0\xF27%\0\0\0\0 \xC7\xD4%\0\0\0\x000\x0F!'\0\0\0\0\xA0\xE3\xBD'\0\0\0\x000\xF1\0)\0\0\0\0 \x8B\x94)\0\0\0\0\xB0\r\xEA*\0\0\0\0\xA02k+\0\0\0\x000\xB5\xC0,\0\0\0\0 \xC4f-\0\0\0\x000\x97\xA0.\0\0\0\0 \xA6F/\0\0\0\x000y\x800\0\0\0\0\xA0M\x1D1\0\0\0\0\xB0 W2\0\0\0\0 j\x063\0\0\0\x000T84\0\0\0\0 \xC1\xF84\0\0\0\x000\x1F 6\0\0\0\0\xA0h\xCF6\0\0\0\0\xB0\xC6\xF67\0\0\0\0 \x85\xB88\0\0\0\x000\xE3\xDF9\0\0\0\0\xA0,\x8F:\0\0\0\0\xB0\xFF\xC8;\0\0\0\0\xA0\x0Eo<\0\0\0\x000\x91\xC4=\0\0\0\0\xA0\xF0N>\0\0\0\0\xB0H\x9AN\0\0\0\0 \x92IO\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xE4\xDB\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \x01T\x01p\xE8\xB6\xA5\xFF\xFF\xFF\xFFp+\xF1\xAF\xFF\xFF\xFF\xFF`Vf\xB6\xFF\xFF\xFF\xFFp=A\xB7\xFF\xFF\xFF\xFF`6\x0C\xB8\xFF\xFF\xFF\xFF\xF0\x86\xFD\xB8\xFF\xFF\xFF\xFF`q\xEA\xCB\xFF\xFF\xFF\xFF\x10\x84g1\0\0\0\0\x80\x16s2\0\0\0\0\x10fG3\0\0\0\0\x80\xF8R4\0\0\0\0\x10H'5\0\0\0\0\x80\xDA26\0\0\0\0\x10*\x077\0\0\0\0\0\xF7\x1B8\0\0\0\0\x10\x0C\xE78\0\0\0\0\0\xD9\xFB9\0\0\0\0\x90\x12\xF5:\0\0\0\0\0\xD1\xB6;\0\0\0\0\x90\n\xB0<\0\0\0\0\0\x9D\xBB=\0\0\0\0\x90\xEC\x8F>\0\0\0\0\0\x7F\x9B?\0\0\0\0\x90\xCEo@\0\0\0\0\x80\x9B\x84A\0\0\0\0\x90\xB0OB\0\0\0\0\x80}dC\0\0\0\0\x90\x92/D\0\0\0\0\x80_DE\0\0\0\0\x90t\x0FF\0\0\0\0\x80A$G\0\0\0\0\x10\x91\xF8G\0\0\0\0\x80#\x04I\0\0\0\0\x10s\xD8I\0\0\0\0\x80\x05\xE4J\0\0\0\0\x10U\xB8K\0\0\0\0\x01\x02\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x04T\x9D\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFFAST\0\0\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0x\0\x87\0e\xA9@\x92\xFF\xFF\xFF\xFF\xD0\xCB\xE3\xCB\xFF\xFF\xFF\xFF\xE0\x82\x94\xCC\xFF\xFF\xFF\xFF\xD0\"\xD6\xCD\xFF\xFF\xFF\xFF\xE0M|\xCE\xFF\xFF\xFF\xFF\xD0\xA6\x9B\xCF\xFF\xFF\xFF\xFF`je\xD0\xFF\xFF\xFF\xFF\xE0\xF2\0\x0E\0\0\0\0\xD0\x8C\x94\x0E\0\0\0\0\xE0\0\x97\x0F\0\0\0\0\xD0nt\x10\0\0\0\0\xE0\xE2v\x11\0\0\0\0\xD0PT\x12\0\0\0\0`\xFF_\x13\0\0\0\0P>0\x14\0\0\0\0\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x1B\xC8\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xC8\xCE\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xE8\0\x05\x01tt\xAA\x96\xFF\xFF\xFF\xFF\xE0I\x0F\xB8\xFF\xFF\xFF\xFF\xA0@\xFD\xB8\xFF\xFF\xFF\xFF04\xF1\xB9\xFF\xFF\xFF\xFF t\xDE\xBA\xFF\xFF\xFF\xFF0\xAE8\xDA\xFF\xFF\xFF\xFF0\xFA\xEB\xDA\xFF\xFF\xFF\xFF\xB0\xE1\x19\xDC\xFF\xFF\xFF\xFF Y\xB9\xDC\xFF\xFF\xFF\xFF0\x15\xFB\xDD\xFF\xFF\xFF\xFF \xDE\x9B\xDE\xFF\xFF\xFF\xFF0\x9A\xDD\xDF\xFF\xFF\xFF\xFF 3T\xE0\xFF\xFF\xFF\xFF\xB0\xFF\x97\xF4\xFF\xFF\xFF\xFF ^\x05\xF5\xFF\xFF\xFF\xFF0d\xC0\xF6\xFF\xFF\xFF\xFF\xA0\x1E\x0E\xF7\xFF\xFF\xFF\xFF0,Q\xF8\xFF\xFF\xFF\xFF \xC5\xC7\xF8\xFF\xFF\xFF\xFF\xB0\xD2\n\xFA\xFF\xFF\xFF\xFF\xA0\xF8\xA8\xFA\xFF\xFF\xFF\xFF0\x06\xEC\xFB\xFF\xFF\xFF\xFF\xA0}\x8B\xFC\xFF\xFF\xFF\xFF0\x8E\xC9\x1D\0\0\0\0\xA0\xD7x\x1E\0\0\0\0\xB05\xA0\x1F\0\0\0\0\xA0\xCF3 \0\0\0\x000i\x81!\0\0\0\0\xA0\xC8\x0B\"\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x8C\xD2\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x03r\x03\xB0\xD9^\x93\xFF\xFF\xFF\xFF\xE0;\x9F\x9F\xFF\xFF\xFF\xFF\xD8QE\xA0\xFF\xFF\xFF\xFF\xE0\x1D\x7F\xA1\xFF\xFF\xFF\xFFXn.\xA2\xFF\xFF\xFF\xFF\xE0\xFF^\xA3\xFF\xFF\xFF\xFFXP\x0E\xA4\xFF\xFF\xFF\xFF\xE0\xE1>\xA5\xFF\xFF\xFF\xFFX2\xEE\xA5\xFF\xFF\xFF\xFF`\xFE'\xA7\xFF\xFF\xFF\xFFX\x14\xCE\xA7\xFF\xFF\xFF\xFF`\xE0\x07\xA9\xFF\xFF\xFF\xFFX\xF6\xAD\xA9\xFF\xFF\xFF\xFF`\xC2\xE7\xAA\xFF\xFF\xFF\xFF\xD8\x12\x97\xAB\xFF\xFF\xFF\xFF`\xA4\xC7\xAC\xFF\xFF\xFF\xFF\xD8\xF4v\xAD\xFF\xFF\xFF\xFF`\x86\xA7\xAE\xFF\xFF\xFF\xFF\xD8\xD6V\xAF\xFF\xFF\xFF\xFF`h\x87\xB0\xFF\xFF\xFF\xFF\xD8\xB86\xB1\xFF\xFF\xFF\xFF\xE0\x84p\xB2\xFF\xFF\xFF\xFF\xD8\x9A\x16\xB3\xFF\xFF\xFF\xFF\xE0fP\xB4\xFF\xFF\xFF\xFF\xD8|\xF6\xB4\xFF\xFF\xFF\xFF\xE0H0\xB6\xFF\xFF\xFF\xFFX\x99\xDF\xB6\xFF\xFF\xFF\xFF\xE0*\x10\xB8\xFF\xFF\xFF\xFFX{\xBF\xB8\xFF\xFF\xFF\xFF\xE0\x0C\xF0\xB9\xFF\xFF\xFF\xFFX]\x9F\xBA\xFF\xFF\xFF\xFF`)\xD9\xBB\xFF\xFF\xFF\xFFX?\x7F\xBC\xFF\xFF\xFF\xFF`\x0B\xB9\xBD\xFF\xFF\xFF\xFFX!_\xBE\xFF\xFF\xFF\xFF`\xED\x98\xBF\xFF\xFF\xFF\xFFX\x03?\xC0\xFF\xFF\xFF\xFF`\xCFx\xC1\xFF\xFF\xFF\xFF\xD8\x1F(\xC2\xFF\xFF\xFF\xFF`\xB1X\xC3\xFF\xFF\xFF\xFF\xD8\x01\x08\xC4\xFF\xFF\xFF\xFF`\x938\xC5\xFF\xFF\xFF\xFF\xD8\xE3\xE7\xC5\xFF\xFF\xFF\xFF\xE0\xAF!\xC7\xFF\xFF\xFF\xFF\xD8\xC5\xC7\xC7\xFF\xFF\xFF\xFF\xE0\x91\x01\xC9\xFF\xFF\xFF\xFF\xD8\xA7\xA7\xC9\xFF\xFF\xFF\xFF\xE0s\xE1\xCA\xFF\xFF\xFF\xFFX\xC4\x90\xCB\xFF\xFF\xFF\xFF\xE0\"@\xCC\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFFPq\xC6\xD2\xFF\xFF\xFF\xFF`\xFA)\xD6\xFF\xFF\xFF\xFF\xD8J\xD9\xD6\xFF\xFF\xFF\xFF`\xDC\t\xD8\xFF\xFF\xFF\xFF\xD8,\xB9\xD8\xFF\xFF\xFF\xFF`\xBE\xE9\xD9\xFF\xFF\xFF\xFF\xD8\x0E\x99\xDA\xFF\xFF\xFF\xFF\xE0\xDA\xD2\xDB\xFF\xFF\xFF\xFF\xD8\xF0x\xDC\xFF\xFF\xFF\xFF\xE0\xBC\xB2\xDD\xFF\xFF\xFF\xFF\xD8\xD2X\xDE\xFF\xFF\xFF\xFF\xE0\x9E\x92\xDF\xFF\xFF\xFF\xFFX\xEFA\xE0\xFF\xFF\xFF\xFF\xE0\x80r\xE1\xFF\xFF\xFF\xFFX\xD1!\xE2\xFF\xFF\xFF\xFF\xE0bR\xE3\xFF\xFF\xFF\xFFX\xB3\x01\xE4\xFF\xFF\xFF\xFF\xE0D2\xE5\xFF\xFF\xFF\xFFX\x95\xE1\xE5\xFF\xFF\xFF\xFF`a\x1B\xE7\xFF\xFF\xFF\xFFXw\xC1\xE7\xFF\xFF\xFF\xFF`C\xFB\xE8\xFF\xFF\xFF\xFFXY\xA1\xE9\xFF\xFF\xFF\xFF`%\xDB\xEA\xFF\xFF\xFF\xFF\xD8u\x8A\xEB\xFF\xFF\xFF\xFF`\x07\xBB\xEC\xFF\xFF\xFF\xFF\xD8Wj\xED\xFF\xFF\xFF\xFF`\xE9\x9A\xEE\xFF\xFF\xFF\xFF\xD89J\xEF\xFF\xFF\xFF\xFF\xE0\x05\x84\xF0\xFF\xFF\xFF\xFF\xD8\x1B*\xF1\xFF\xFF\xFF\xFF\xE0\xE7c\xF2\xFF\xFF\xFF\xFF\xD8\xFD\t\xF3\xFF\xFF\xFF\xFF\xE0\xC9C\xF4\xFF\xFF\xFF\xFF\xD8\xDF\xE9\xF4\xFF\xFF\xFF\xFF\xE0\xAB#\xF6\xFF\xFF\xFF\xFFX\xFC\xD2\xF6\xFF\xFF\xFF\xFF\xE0\x8D\x03\xF8\xFF\xFF\xFF\xFFX\xDE\xB2\xF8\xFF\xFF\xFF\xFF\xE0o\xE3\xF9\xFF\xFF\xFF\xFFX\xC0\x92\xFA\xFF\xFF\xFF\xFF`\x8C\xCC\xFB\xFF\xFF\xFF\xFFX\xA2r\xFC\xFF\xFF\xFF\xFF`\xDBb\x07\0\0\0\0P\xD0\xB9\x07\0\0\0\0`qa\x18\0\0\0\0P7\xAB\x18\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01P\xAD\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xA8\xB2\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF-04\0\0\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\x01)\x01\xE0\x7F\xAA\x96\xFF\xFF\xFF\xFF\xF0W\x0F\xB8\xFF\xFF\xFF\xFF\xB0N\xFD\xB8\xFF\xFF\xFF\xFF@B\xF1\xB9\xFF\xFF\xFF\xFF0\x82\xDE\xBA\xFF\xFF\xFF\xFF@\xBC8\xDA\xFF\xFF\xFF\xFF@\x08\xEC\xDA\xFF\xFF\xFF\xFF\xC0\xEF\x19\xDC\xFF\xFF\xFF\xFF0g\xB9\xDC\xFF\xFF\xFF\xFF@#\xFB\xDD\xFF\xFF\xFF\xFF0\xEC\x9B\xDE\xFF\xFF\xFF\xFF@\xA8\xDD\xDF\xFF\xFF\xFF\xFF0AT\xE0\xFF\xFF\xFF\xFF\xC0\r\x98\xF4\xFF\xFF\xFF\xFF0l\x05\xF5\xFF\xFF\xFF\xFF@r\xC0\xF6\xFF\xFF\xFF\xFF\xB0,\x0E\xF7\xFF\xFF\xFF\xFF@:Q\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF\xC0\xE0\n\xFA\xFF\xFF\xFF\xFF\xB0\x06\xA9\xFA\xFF\xFF\xFF\xFF@\x14\xEC\xFB\xFF\xFF\xFF\xFF\xB0\x8B\x8B\xFC\xFF\xFF\xFF\xFF@\x9C\xC9\x1D\0\0\0\0\xB0\xE5x\x1E\0\0\0\0\xC0C\xA0\x1F\0\0\0\0\xB0\xDD3 \0\0\0\0@w\x81!\0\0\0\0\xB0\xD6\x0B\"\0\0\0\0\xC0\xD4\xF67\0\0\0\x000\x93\xB88\0\0\0\0@\xF1\xDF9\0\0\0\0\xB0\x1D\xE99\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01 \xC7\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF-05\0\0\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0$\0\xF04\x9C^\xFF\xFF\xFF\xFFpUX\x98\xFF\xFF\xFF\xFFPs\x03*\0\0\0\0@\x89t+\0\0\0\0\0\x01\x02\x01\x90\xBA\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFFMST\0\0\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\x01MDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xD8\x02^\x03\xC0\x1A\x04^\xFF\xFF\xFF\xFF\xA0H\xA6\x9E\xFF\xFF\xFF\xFF\x90\x15\xBB\x9F\xFF\xFF\xFF\xFF\xA0*\x86\xA0\xFF\xFF\xFF\xFF\x90\xF7\x9A\xA1\xFF\xFF\xFF\xFF LF\xA8\xFF\xFF\xFF\xFF\x90\x0C\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\0\x18a\xD2\xFF\xFF\xFF\xFF\x10u\xF8\xFA\xFF\xFF\xFF\xFF\0X\xE8\xFB\xFF\xFF\xFF\xFF\x10W\xD8\xFC\xFF\xFF\xFF\xFF\0:\xC8\xFD\xFF\xFF\xFF\xFF\x109\xB8\xFE\xFF\xFF\xFF\xFF\0\x1C\xA8\xFF\xFF\xFF\xFF\xFF\x10\x1B\x98\0\0\0\0\0\0\xFE\x87\x01\0\0\0\0\x10\xFDw\x02\0\0\0\0\x80\x1Aq\x03\0\0\0\0\x90\x19a\x04\0\0\0\0\x80\xFCP\x05\0\0\0\0\x90\xFB@\x06\0\0\0\0\x80\xDE0\x07\0\0\0\0\x90\x1F\xB2\x07\0\0\0\0\x80\xC0\x10\t\0\0\0\0\x10\xB1\xAD\t\0\0\0\0\x80\xA2\xF0\n\0\0\0\0\x90\xA1\xE0\x0B\0\0\0\0\0\xBF\xD9\x0C\0\0\0\0\x90\x83\xC0\r\0\0\0\0\0\xA1\xB9\x0E\0\0\0\0\x10\xA0\xA9\x0F\0\0\0\0\0\x83\x99\x10\0\0\0\0\x10\x82\x89\x11\0\0\0\0\0ey\x12\0\0\0\0\x10di\x13\0\0\0\0\0GY\x14\0\0\0\0\x10FI\x15\0\0\0\0\0)9\x16\0\0\0\0\x10()\x17\0\0\0\0\x80E\"\x18\0\0\0\0\x10\n\t\x19\0\0\0\0\x80'\x02\x1A\0\0\0\0\x90&\xF2\x1A\0\0\0\0\x80\t\xE2\x1B\0\0\0\0\x90\x08\xD2\x1C\0\0\0\0\x80\xEB\xC1\x1D\0\0\0\0\x90\xEA\xB1\x1E\0\0\0\0\x80\xCD\xA1\x1F\0\0\0\0\x10\x1Dv \0\0\0\0\x80\xAF\x81!\0\0\0\0\x10\xFFU\"\0\0\0\0\0\xCCj#\0\0\0\0\x10\xE15$\0\0\0\0\0\xAEJ%\0\0\0\0\x10\xC3\x15&\0\0\0\0\0\x90*'\0\0\0\0\x90\xDF\xFE'\0\0\0\0\0r\n)\0\0\0\0\x90\xC1\xDE)\0\0\0\0\0T\xEA*\0\0\0\0\x90\xA3\xBE+\0\0\0\0\x80p\xD3,\0\0\0\0\x90\x85\x9E-\0\0\0\0\x80R\xB3.\0\0\0\0\x90g~/\0\0\0\0\x804\x930\0\0\0\0\x10\x84g1\0\0\0\0\x80\x16s2\0\0\0\0\x10fG3\0\0\0\0\x80\xF8R4\0\0\0\0\x10H'5\0\0\0\0\x80\xDA26\0\0\0\0\x10*\x077\0\0\0\0\0\xF7\x1B8\0\0\0\0\x10\x0C\xE78\0\0\0\0\0\xD9\xFB9\0\0\0\0\x10\xEE\xC6:\0\0\0\0\0\xBB\xDB;\0\0\0\0\x90\n\xB0<\0\0\0\0\0\x9D\xBB=\0\0\0\0\x90\xEC\x8F>\0\0\0\0\0\x7F\x9B?\0\0\0\0\x90\xCEo@\0\0\0\0\x80\x9B\x84A\0\0\0\0\x90\xB0OB\0\0\0\0\x80}dC\0\0\0\0\x90\x92/D\0\0\0\0\x80_DE\0\0\0\0\x10\xC5\xF3E\0\0\0\0\0|-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x03\x04\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x0F\x93\xFF\xFF\xFF\xFF\xFF\xFF\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFFMST\0\0\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\x01MDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0h\x02\xBF\x02\x80\xCD\xF2\xA1\xFF\xFF\xFF\xFF\x90\x0C\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\0\x18a\xD2\xFF\xFF\xFF\xFF\x90\x19a\x04\0\0\0\0\x80\xFCP\x05\0\0\0\0\x90\xFB@\x06\0\0\0\0\x80\xDE0\x07\0\0\0\0\x90\xDD \x08\0\0\0\0\x80\xC0\x10\t\0\0\0\0\x90\xBF\0\n\0\0\0\0\x80\xA2\xF0\n\0\0\0\0\x90\xA1\xE0\x0B\0\0\0\0\0\xBF\xD9\x0C\0\0\0\0\x90\x83\xC0\r\0\0\0\0\0\xA1\xB9\x0E\0\0\0\0\x10\xA0\xA9\x0F\0\0\0\0\0\x83\x99\x10\0\0\0\0\x10\x82\x89\x11\0\0\0\0\0ey\x12\0\0\0\0\x10di\x13\0\0\0\0\0GY\x14\0\0\0\0\x10FI\x15\0\0\0\0\0)9\x16\0\0\0\0\x10()\x17\0\0\0\0\x80E\"\x18\0\0\0\0\x10\n\t\x19\0\0\0\0\x80'\x02\x1A\0\0\0\0\x90&\xF2\x1A\0\0\0\0\x80\t\xE2\x1B\0\0\0\0\x90\x08\xD2\x1C\0\0\0\0\x80\xEB\xC1\x1D\0\0\0\0\x90\xEA\xB1\x1E\0\0\0\0\x80\xCD\xA1\x1F\0\0\0\0\x10\x1Dv \0\0\0\0\x80\xAF\x81!\0\0\0\0\x10\xFFU\"\0\0\0\0\0\xCCj#\0\0\0\0\x10\xE15$\0\0\0\0\0\xAEJ%\0\0\0\0\x10\xC3\x15&\0\0\0\0\0\x90*'\0\0\0\0\x90\xDF\xFE'\0\0\0\0\0r\n)\0\0\0\0\x90\xC1\xDE)\0\0\0\0\0T\xEA*\0\0\0\0\x90\xA3\xBE+\0\0\0\0\x80p\xD3,\0\0\0\0\x90\x85\x9E-\0\0\0\0\x80R\xB3.\0\0\0\0\x90g~/\0\0\0\0\x804\x930\0\0\0\0\x10\x84g1\0\0\0\0\x80\x16s2\0\0\0\0\x10fG3\0\0\0\0\x80\xF8R4\0\0\0\0\x10H'5\0\0\0\0\x80\xDA26\0\0\0\0\x10*\x077\0\0\0\0\0\xF7\x1B8\0\0\0\0\0\xFE\xE68\0\0\0\0\xF0\xCA\xFB9\0\0\0\0P\xE9\x04:\0\0\0\0\x10\xEE\xC6:\0\0\0\0\0\xBB\xDB;\0\0\0\0\x90\n\xB0<\0\0\0\0\0\x9D\xBB=\0\0\0\0\x90\xEC\x8F>\0\0\0\0\0\x7F\x9B?\0\0\0\0\x90\xCEo@\0\0\0\0\x80\x9B\x84A\0\0\0\0\x90\xB0OB\0\0\0\0\x80}dC\0\0\0\0\x90\x92/D\0\0\0\0\x80_DE\0\0\0\0\x10\xC5\xF3E\0\0\0\0\0|-G\0\0\0\0\x01\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x03\x04\x04\x05\x02\x03\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\0\0\0\0\0\0\0\0\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF-04\0\0\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xB0\x02\x06\x034z\xAA\x96\xFF\xFF\xFF\xFF\xF0W\x0F\xB8\xFF\xFF\xFF\xFF\xB0N\xFD\xB8\xFF\xFF\xFF\xFF@B\xF1\xB9\xFF\xFF\xFF\xFF0\x82\xDE\xBA\xFF\xFF\xFF\xFF@\xBC8\xDA\xFF\xFF\xFF\xFF@\x08\xEC\xDA\xFF\xFF\xFF\xFF\xC0\xEF\x19\xDC\xFF\xFF\xFF\xFF0g\xB9\xDC\xFF\xFF\xFF\xFF@#\xFB\xDD\xFF\xFF\xFF\xFF0\xEC\x9B\xDE\xFF\xFF\xFF\xFF@\xA8\xDD\xDF\xFF\xFF\xFF\xFF0AT\xE0\xFF\xFF\xFF\xFF\xC0\r\x98\xF4\xFF\xFF\xFF\xFF0l\x05\xF5\xFF\xFF\xFF\xFF@r\xC0\xF6\xFF\xFF\xFF\xFF\xB0,\x0E\xF7\xFF\xFF\xFF\xFF@:Q\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF\xC0\xE0\n\xFA\xFF\xFF\xFF\xFF\xB0\x06\xA9\xFA\xFF\xFF\xFF\xFF@\x14\xEC\xFB\xFF\xFF\xFF\xFF\xB0\x8B\x8B\xFC\xFF\xFF\xFF\xFF@\x9C\xC9\x1D\0\0\0\0\xB0\xE5x\x1E\0\0\0\0\xC0C\xA0\x1F\0\0\0\0\xB0\xDD3 \0\0\0\0@w\x81!\0\0\0\0\xB0\xD6\x0B\"\0\0\0\0\xC0\x1EX#\0\0\0\x000~\xE2#\0\0\0\0\xC0\08%\0\0\0\x000\xD5\xD4%\0\0\0\0@\x1D!'\0\0\0\0\xB0\xF1\xBD'\0\0\0\0@\xFF\0)\0\0\0\x000\x99\x94)\0\0\0\0\xC0\x1B\xEA*\0\0\0\0\xB0@k+\0\0\0\0@\xC3\xC0,\0\0\0\x000\xD2f-\0\0\0\0@\xA5\xA0.\0\0\0\x000\xB4F/\0\0\0\0@\x87\x800\0\0\0\0\xB0[\x1D1\0\0\0\0\xC0.W2\0\0\0\x000x\x063\0\0\0\0@b84\0\0\0\x000\xCF\xF84\0\0\0\0@- 6\0\0\0\0\xB0v\xCF6\0\0\0\0\xC0\xD4\xF67\0\0\0\x000\x93\xB88\0\0\0\0@\xF1\xDF9\0\0\0\0\xB0:\x8F:\0\0\0\0\xC0\r\xC9;\0\0\0\0\xB0\x1Co<\0\0\0\0@\x9F\xC4=\0\0\0\0\xB0\xFEN>\0\0\0\0@\x0C\x92?\0\0\0\0\xB0\xE0.@\0\0\0\0@\x06\x87A\0\0\0\x000\xFD\x17B\0\0\0\0@\xD0QC\0\0\0\x000\xDF\xF7C\0\0\0\0\xC0aME\0\0\0\0\xB0\xFB\xE0E\0\0\0\0@\x94\x11G\0\0\0\x000\xA3\xB7G\0\0\0\0\xC0\xB0\xFAH\0\0\0\x000\x85\x97I\0\0\0\0\xC0\x92\xDAJ\0\0\0\0\xB0\xA1\x80K\0\0\0\0\xC0t\xBAL\0\0\0\0\xB0\x83`M\0\0\0\0\xC0V\x9AN\0\0\0\x000\xA0IO\0\0\0\0@s\x83P\0\0\0\0\xB0G Q\0\0\0\0@UcR\0\0\0\0\xB0)\0S\0\0\0\0@7CT\0\0\0\x000F\xE9T\0\0\0\0@\x19#V\0\0\0\x000(\xC9V\0\0\0\0@\xFB\x02X\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xCC\xCC\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFFEST\0\0\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0X\x01\x98\x01`\xDA\xB6\xA5\xFF\xFF\xFF\xFF\0\xE6\x8A\x16\0\0\0\0\xD0\xCCw\x18\0\0\0\0\0vg1\0\0\0\0p\x08s2\0\0\0\0\0XG3\0\0\0\0p\xEAR4\0\0\0\0\xF0+'5\0\0\0\0`\0\xC45\0\0\0\0p\xCC26\0\0\0\0\0\x1C\x077\0\0\0\0\xF0\xE8\x1B8\0\0\0\0\0\xFE\xE68\0\0\0\0\xF0\xCA\xFB9\0\0\0\0\x80\x04\xF5:\0\0\0\0\xF0\xC2\xB6;\0\0\0\0\x80\xFC\xAF<\0\0\0\0\xF0\x8E\xBB=\0\0\0\0\x80\xDE\x8F>\0\0\0\0\xF0p\x9B?\0\0\0\0\x80\xC0o@\0\0\0\0p\x8D\x84A\0\0\0\0\x80\xA2OB\0\0\0\0podC\0\0\0\0\x80\x84/D\0\0\0\0pQDE\0\0\0\0\x80f\x0FF\0\0\0\0p3$G\0\0\0\0\0\x83\xF8G\0\0\0\0p\x15\x04I\0\0\0\0\0e\xD8I\0\0\0\0p\xF7\xE3J\0\0\0\0\0G\xB8K\0\0\0\0\xF0\x13\xCDL\0\0\0\0\0)\x98M\0\0\0\0\xF0\xF5\xACN\0\0\0\0\0\x0BxO\0\0\0\0\xF0\xD7\x8CP\0\0\0\0\x80'aQ\0\0\0\0\xF0\xB9lR\0\0\0\0\x80\tAS\0\0\0\0\xF0\x9BLT\0\0\0\0\0\xDD\xCDT\0\0\0\0\x01\x02\x01\x02\x03\x01\x02\x03\x02\x03\x04\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\xA8\xAE\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF-04\0\0\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0(\0-\0@\x1A\x87i\xFF\xFF\xFF\xFF<,\x1E\x93\xFF\xFF\xFF\xFFH\xEC\x98\xF6\xFF\xFF\xFF\xFFp\x92[G\0\0\0\0p\xA9%W\0\0\0\0\x01\x02\x03\x02\x03@\xC1\xFF\xFF\xFF\xFF\xFF\xFFD\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xB8\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\x12\0\x90+\xF4\x91\xFF\xFF\xFF\xFF\xC05\xC3\xFB\xFF\xFF\xFF\xFF\x01\x02\xF0\xCE\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\x01CDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\x80\x05v\x06\xA0\xFE\x03^\xFF\xFF\xFF\xFF\x80,\xA6\x9E\xFF\xFF\xFF\xFFp\xF9\xBA\x9F\xFF\xFF\xFF\xFF\x80\x0E\x86\xA0\xFF\xFF\xFF\xFFp\xDB\x9A\xA1\xFF\xFF\xFF\xFF\0t\xCB\xA2\xFF\xFF\xFF\xFF\xF0\xF7\x83\xA3\xFF\xFF\xFF\xFF\x80\xD2E\xA4\xFF\xFF\xFF\xFF\xF0\xD9c\xA5\xFF\xFF\xFF\xFF\0\xD9S\xA6\xFF\xFF\xFF\xFFp\x97\x15\xA7\xFF\xFF\xFF\xFF\0\xBB3\xA8\xFF\xFF\xFF\xFF\xF0\xB3\xFE\xA8\xFF\xFF\xFF\xFF\0\x9D\x13\xAA\xFF\xFF\xFF\xFF\xF0\x95\xDE\xAA\xFF\xFF\xFF\xFF\0\x7F\xF3\xAB\xFF\xFF\xFF\xFF\xF0w\xBE\xAC\xFF\xFF\xFF\xFF\0a\xD3\xAD\xFF\xFF\xFF\xFF\xF0Y\x9E\xAE\xFF\xFF\xFF\xFF\0C\xB3\xAF\xFF\xFF\xFF\xFF\xF0;~\xB0\xFF\xFF\xFF\xFF\x80_\x9C\xB1\xFF\xFF\xFF\xFFpXg\xB2\xFF\xFF\xFF\xFF\x80A|\xB3\xFF\xFF\xFF\xFFp:G\xB4\xFF\xFF\xFF\xFF\x80#\\\xB5\xFF\xFF\xFF\xFFp\x1C'\xB6\xFF\xFF\xFF\xFF\x80\x05<\xB7\xFF\xFF\xFF\xFFp\xFE\x06\xB8\xFF\xFF\xFF\xFF\x80\xE7\x1B\xB9\xFF\xFF\xFF\xFFp\xE0\xE6\xB9\xFF\xFF\xFF\xFF\0\x04\x05\xBB\xFF\xFF\xFF\xFFp\xC2\xC6\xBB\xFF\xFF\xFF\xFF\0\xE6\xE4\xBC\xFF\xFF\xFF\xFF\xF0\xDE\xAF\xBD\xFF\xFF\xFF\xFF\0\xC8\xC4\xBE\xFF\xFF\xFF\xFF\xF0\xC0\x8F\xBF\xFF\xFF\xFF\xFF\0\xD6Z\xC0\xFF\xFF\xFF\xFFp<\xB0\xC1\xFF\xFF\xFF\xFF\0\x8C\x84\xC2\xFF\xFF\xFF\xFF\xF0\x84O\xC3\xFF\xFF\xFF\xFF\0nd\xC4\xFF\xFF\xFF\xFF\xF0f/\xC5\xFF\xFF\xFF\xFF\x80\x8AM\xC6\xFF\xFF\xFF\xFF\xF0H\x0F\xC7\xFF\xFF\xFF\xFF\x80l-\xC8\xFF\xFF\xFF\xFFpe\xF8\xC8\xFF\xFF\xFF\xFF\x80N\r\xCA\xFF\xFF\xFF\xFFpG\xD8\xCA\xFF\xFF\xFF\xFF\x80\xFE\x88\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\xF0\ta\xD2\xFF\xFF\xFF\xFF\0\xF3u\xD3\xFF\xFF\xFF\xFF\xF0\xEB@\xD4\xFF\xFF\xFF\xFF\0\xD5U\xD5\xFF\xFF\xFF\xFF\xF0\xCD \xD6\xFF\xFF\xFF\xFF\0\xB75\xD7\xFF\xFF\xFF\xFF\xF0\xAF\0\xD8\xFF\xFF\xFF\xFF\0\x99\x15\xD9\xFF\xFF\xFF\xFF\xF0\x91\xE0\xD9\xFF\xFF\xFF\xFF\x80\xB5\xFE\xDA\xFF\xFF\xFF\xFF\xF0s\xC0\xDB\xFF\xFF\xFF\xFF\x80\x97\xDE\xDC\xFF\xFF\xFF\xFFp\x90\xA9\xDD\xFF\xFF\xFF\xFF\x80y\xBE\xDE\xFF\xFF\xFF\xFFpr\x89\xDF\xFF\xFF\xFF\xFF\x80[\x9E\xE0\xFF\xFF\xFF\xFFpTi\xE1\xFF\xFF\xFF\xFF\x80=~\xE2\xFF\xFF\xFF\xFFp6I\xE3\xFF\xFF\xFF\xFF\x80\x1F^\xE4\xFF\xFF\xFF\xFF\xF0\0\0\0\0\xF0p\x9B?\0\0\0\0\x80\xC0o@\0\0\0\0p\x8D\x84A\0\0\0\0\x80\xA2OB\0\0\0\0podC\0\0\0\0\x80\x84/D\0\0\0\0pQDE\0\0\0\0\0\xB7\xF3E\0\0\0\0\xF0m-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\xD4\xAD\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xE0\x01:\x02p\xE8\xB6\xA5\xFF\xFF\xFF\xFFp+\xF1\xAF\xFF\xFF\xFF\xFF`Vf\xB6\xFF\xFF\xFF\xFFp=A\xB7\xFF\xFF\xFF\xFF`6\x0C\xB8\xFF\xFF\xFF\xFF\xF0\x86\xFD\xB8\xFF\xFF\xFF\xFF\0vg1\0\0\0\0p\x08s2\0\0\0\0\0XG3\0\0\0\0p\xEAR4\0\0\0\0\x10H'5\0\0\0\0\x80\xDA26\0\0\0\0\x10*\x077\0\0\0\0\0\xF7\x1B8\0\0\0\0\x10\x0C\xE78\0\0\0\0\0\xD9\xFB9\0\0\0\0\x90\x12\xF5:\0\0\0\0\0\xD1\xB6;\0\0\0\0\x90\n\xB0<\0\0\0\0\0\x9D\xBB=\0\0\0\0\x90\xEC\x8F>\0\0\0\0\0\x7F\x9B?\0\0\0\0\x90\xCEo@\0\0\0\0\x80\x9B\x84A\0\0\0\0\x90\xB0OB\0\0\0\0\x80}dC\0\0\0\0\x90\x92/D\0\0\0\0\x80_DE\0\0\0\0\x90t\x0FF\0\0\0\0\x80A$G\0\0\0\0\x10\x91\xF8G\0\0\0\0\x80#\x04I\0\0\0\0\x10s\xD8I\0\0\0\0\x80\x05\xE4J\0\0\0\0\x10U\xB8K\0\0\0\0\0\"\xCDL\0\0\0\0\x107\x98M\0\0\0\0\0\x04\xADN\0\0\0\0\x10\x19xO\0\0\0\0\0\xE6\x8CP\0\0\0\0\x905aQ\0\0\0\0\0\xC8lR\0\0\0\0\x90\x17AS\0\0\0\0\0\xAALT\0\0\0\0\x90\xF9 U\0\0\0\0\0\x8C,V\0\0\0\0\x90\xDB\0W\0\0\0\0\x80\xA8\x15X\0\0\0\0\x90\xBD\xE0X\0\0\0\0\x80\x8A\xF5Y\0\0\0\0\x90\x9F\xC0Z\0\0\0\0\x80l\xD5[\0\0\0\0\x10\xBC\xA9\\\0\0\0\0\x80N\xB5]\0\0\0\0\x10\x9E\x89^\0\0\0\0\x800\x95_\0\0\0\0\x10\x80i`\0\0\0\0\0M~a\0\0\0\0\x10bIb\0\0\0\0\0/^c\0\0\0\0\x01\x02\x01\x02\x03\x01\x02\x03\x04\x02\x03\x04\x02\x03\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x02\x03\x8C\x9C\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFFMST\0\0\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\x01MDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xE8\x01C\x02p\xE8\xB6\xA5\xFF\xFF\xFF\xFFp+\xF1\xAF\xFF\xFF\xFF\xFF`Vf\xB6\xFF\xFF\xFF\xFFp=A\xB7\xFF\xFF\xFF\xFF`6\x0C\xB8\xFF\xFF\xFF\xFF\xF0\x86\xFD\xB8\xFF\xFF\xFF\xFF\0vg1\0\0\0\0p\x08s2\0\0\0\0\0XG3\0\0\0\0p\xEAR4\0\0\0\0\x10H'5\0\0\0\0\x80\xDA26\0\0\0\0\x10*\x077\0\0\0\0\0\xF7\x1B8\0\0\0\0\x10\x0C\xE78\0\0\0\0\0\xD9\xFB9\0\0\0\0\x90\x12\xF5:\0\0\0\0\0\xD1\xB6;\0\0\0\0\x90\n\xB0<\0\0\0\0\0\x9D\xBB=\0\0\0\0\x90\xEC\x8F>\0\0\0\0\0\x7F\x9B?\0\0\0\0\x90\xCEo@\0\0\0\0\x80\x9B\x84A\0\0\0\0\x90\xB0OB\0\0\0\0\x80}dC\0\0\0\0\x90\x92/D\0\0\0\0\x80_DE\0\0\0\0\x90t\x0FF\0\0\0\0\x80A$G\0\0\0\0\x10\x91\xF8G\0\0\0\0\x80#\x04I\0\0\0\0\x10s\xD8I\0\0\0\0\x80\x05\xE4J\0\0\0\0\x90\xA5\x9CK\0\0\0\0\x80\\\xD6L\0\0\0\0\x90\x87|M\0\0\0\0\x80>\xB6N\0\0\0\0\x90i\\O\0\0\0\0\x80 \x96P\0\0\0\0\x90K\x05\0\0\0\0\xB0\r\0\x06\0\0\0\0@\xBC\x0B\x07\0\0\0\0\xB0\xEF\xDF\x07\0\0\0\0@\x13\xFE\x08\0\0\0\0\xB0\xD1\xBF\t\0\0\0\0@\xF5\xDD\n\0\0\0\x000\xEE\xA8\x0B\0\0\0\0@\xD7\xBD\x0C\0\0\0\x000\xD0\x88\r\0\0\0\0@\xB9\x9D\x0E\0\0\0\x000\xB2h\x0F\0\0\0\0\xC0\xD5\x86\x10\0\0\0\x000\x94H\x11\0\0\0\0\xC0\xB7f\x12\0\0\0\x000v(\x13\0\0\0\0\xC0\x99F\x14\0\0\0\0\xB0\x92\x11\x15\0\0\0\0\xC0{&\x16\0\0\0\0\xB0t\xF1\x16\0\0\0\0\xC0]\x06\x18\0\0\0\0\xB0V\xD1\x18\0\0\0\0\xC0?\xE6\x19\0\0\0\0\xB08\xB1\x1A\0\0\0\0@\\\xCF\x1B\0\0\0\0\xB0\x1A\x91\x1C\0\0\0\0@>\xAF\x1D\0\0\0\0\xB0\xFCp\x1E\0\0\0\0@ \x8F\x1F\0\0\0\x000\x03\x7F \0\0\0\0@\x02o!\0\0\0\x000\xFB9\"\0\0\0\0@\xE4N#\0\0\0\x000\xDD\x19$\0\0\0\0\xC0\08%\0\0\0\x000\xBF\xF9%\0\0\0\0\xC0\xF8\xF2&\0\0\0\x000\xA1\xD9'\0\0\0\0\xC0\xC4\xF7(\0\0\0\0\xB0\xBD\xC2)\0\0\0\0\xC0\xA6\xD7*\0\0\0\0\xB0\x9F\xA2+\0\0\0\0\xC0\x88\xB7,\0\0\0\0\xB0\x81\x82-\0\0\0\0\xC0j\x97.\0\0\0\0\xB0cb/\0\0\0\0@\x87\x800\0\0\0\0\xB0EB1\0\0\0\0@i`2\0\0\0\x000\xD7=3\0\0\0\0@K@4\0\0\0\x000D\x0B5\0\0\0\0@\xB8\r6\0\0\0\0\xB0\xD5\x067\0\0\0\0@\x0F\08\0\0\0\x000\x08\xCB8\0\0\0\0\xC0+\xE99\0\0\0\x000\xEA\xAA:\0\0\0\0\xC0\r\xC9;\0\0\0\x000\xCC\x8A<\0\0\0\0\xC0\xEF\xA8=\0\0\0\x000\xAEj>\0\0\0\0\xC0\xD1\x88?\0\0\0\0\xB0\xCAS@\0\0\0\0\xC0\xB3hA\0\0\0\0\xB0\xAC3B\0\0\0\0\xC0\x95HC\0\0\0\0\xB0\x8E\x13D\0\0\0\0@\xB21E\0\0\0\0\xB0p\xF3E\0\0\0\0@\x94\x11G\0\0\0\x000\x02\xEFG\0\0\0\0@v\xF1H\0\0\0\x000o\xBCI\0\0\0\0@X\xD1J\0\0\0\0\xB0\0\xB8K\0\0\0\0@:\xB1L\0\0\0\x000\x07\xC6M\0\0\0\0\xC0\x82PN\0\0\0\0\xB0\xAE\x9CO\0\0\0\0\xC0\xD9BP\0\0\0\0\xB0\x90|Q\0\0\0\0@\xF6+R\0\0\0\0\xB0r\\S\0\0\0\0@\xD8\x0BT\0\0\0\x000\xE67W\0\0\0\0\xC0\xEC\xAFW\0\0\0\x000\xC8\x17Y\0\0\0\0\xC0\xCE\x8FY\0\0\0\x000\xAA\xF7Z\0\0\0\0\xC0\xB0o[\0\0\0\0\xB0g\xA9\\\0\0\0\0\xC0|t]\0\0\0\0\xB0I\x89^\0\0\0\0\xC0^T_\0\0\0\0\xB0+i`\0\0\0\0\xC0@4a\0\0\0\0\xB0\rIb\0\0\0\0@]\x1Dc\0\0\0\0\xB0\xEF(d\0\0\0\0\xC0\x04\xF4d\0\0\0\x000\x0C\x12f\0\0\0\0@!\xDDf\0\0\0\0\xB0\x84\xDBg\0\0\0\0\x01\x02\x01\x03\x01\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x03\x04\x02\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x05\x06p\xBC\xFF\xFF\xFF\xFF\xFF\xFF\xBB\xBD\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF-04\0\0\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xA0\x02\xF4\x02\x94{\xAA\x96\xFF\xFF\xFF\xFF\xF0W\x0F\xB8\xFF\xFF\xFF\xFF\xB0N\xFD\xB8\xFF\xFF\xFF\xFF@B\xF1\xB9\xFF\xFF\xFF\xFF0\x82\xDE\xBA\xFF\xFF\xFF\xFF@\xBC8\xDA\xFF\xFF\xFF\xFF@\x08\xEC\xDA\xFF\xFF\xFF\xFF\xC0\xEF\x19\xDC\xFF\xFF\xFF\xFF0g\xB9\xDC\xFF\xFF\xFF\xFF@#\xFB\xDD\xFF\xFF\xFF\xFF0\xEC\x9B\xDE\xFF\xFF\xFF\xFF@\xA8\xDD\xDF\xFF\xFF\xFF\xFF0AT\xE0\xFF\xFF\xFF\xFF\xC0\r\x98\xF4\xFF\xFF\xFF\xFF0l\x05\xF5\xFF\xFF\xFF\xFF@r\xC0\xF6\xFF\xFF\xFF\xFF\xB0,\x0E\xF7\xFF\xFF\xFF\xFF@:Q\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF\xC0\xE0\n\xFA\xFF\xFF\xFF\xFF\xB0\x06\xA9\xFA\xFF\xFF\xFF\xFF@\x14\xEC\xFB\xFF\xFF\xFF\xFF\xB0\x8B\x8B\xFC\xFF\xFF\xFF\xFF@\x9C\xC9\x1D\0\0\0\0\xB0\xE5x\x1E\0\0\0\0\xC0C\xA0\x1F\0\0\0\0\xB0\xDD3 \0\0\0\0@w\x81!\0\0\0\0\xB0\xD6\x0B\"\0\0\0\0\xC0\x1EX#\0\0\0\x000~\xE2#\0\0\0\0\xC0\08%\0\0\0\x000\xD5\xD4%\0\0\0\0@\x1D!'\0\0\0\0\xB0\xF1\xBD'\0\0\0\0@\xFF\0)\0\0\0\x000\x99\x94)\0\0\0\0\xC0\x1B\xEA*\0\0\0\0\xB0@k+\0\0\0\0@\xC3\xC0,\0\0\0\x000\xD2f-\0\0\0\0@\xA5\xA0.\0\0\0\x000\xB4F/\0\0\0\0@\x87\x800\0\0\0\0\xB0[\x1D1\0\0\0\0\xC0.W2\0\0\0\x000x\x063\0\0\0\0@b84\0\0\0\x000\xCF\xF84\0\0\0\0@- 6\0\0\0\0\xB0v\xCF6\0\0\0\0\xC0\xD4\xF67\0\0\0\x000\x93\xB88\0\0\0\0@\xF1\xDF9\0\0\0\0\xB0:\x8F:\0\0\0\0\xC0\r\xC9;\0\0\0\0\xB0\x1Co<\0\0\0\0@\x9F\xC4=\0\0\0\0\xB0\xFEN>\0\0\0\0@\x06\x87A\0\0\0\x000\xFD\x17B\0\0\0\0@\xD0QC\0\0\0\x000\xDF\xF7C\0\0\0\0\xC0aME\0\0\0\0\xB0\xFB\xE0E\0\0\0\0@\x94\x11G\0\0\0\x000\xA3\xB7G\0\0\0\0\xC0\xB0\xFAH\0\0\0\x000\x85\x97I\0\0\0\0\xC0\x92\xDAJ\0\0\0\0\xB0\xA1\x80K\0\0\0\0\xC0t\xBAL\0\0\0\0\xB0\x83`M\0\0\0\0\xC0V\x9AN\0\0\0\x000\xA0IO\0\0\0\0@s\x83P\0\0\0\0\xB0G Q\0\0\0\0@UcR\0\0\0\0\xB0)\0S\0\0\0\0@7CT\0\0\0\x000F\xE9T\0\0\0\0@\x19#V\0\0\0\x000(\xC9V\0\0\0\0@\xFB\x02X\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02l\xCB\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFFGMT\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x012\x01\0I\x80\x9B\xFF\xFF\xFF\xFFP|M\x13\0\0\0\0\x90\xFA3\x14\0\0\0\0\x90\xEB#\x15\0\0\0\0\x90\xDC\x13\x16\0\0\0\0\x90\xCD\x03\x17\0\0\0\0\x90\xBE\xF3\x17\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\x000N\xE70\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x80\xEE\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0MST\0\0\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xE8\x02o\x03\xB4\x8E\x86}\xFF\xFF\xFF\xFF\xB0\xCB\xB8\x9E\xFF\xFF\xFF\xFF\xA0#\xBB\x9F\xFF\xFF\xFF\xFF\xB0\x0C\xD0\xA0\xFF\xFF\xFF\xFF\x80\xD2\xA2\xA1\xFF\xFF\xFF\xFF\xB0(\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF 4a\xD2\xFF\xFF\xFF\xFF\x90v/\xF7\xFF\xFF\xFF\xFF\x10\xA2(\xF8\xFF\xFF\xFF\xFF\x90\xEC0\x07\0\0\0\0 ri\x13\0\0\0\0\x10UY\x14\0\0\0\0 TI\x15\0\0\0\0\x1079\x16\0\0\0\0 6)\x17\0\0\0\0\x90S\"\x18\0\0\0\0 \x18\t\x19\0\0\0\0\x905\x02\x1A\0\0\0\0\xA04\xF2\x1A\0\0\0\0\x90\x17\xE2\x1B\0\0\0\0\xA0\x16\xD2\x1C\0\0\0\0\x90\xF9\xC1\x1D\0\0\0\0\xA0\xF8\xB1\x1E\0\0\0\0\x90\xDB\xA1\x1F\0\0\0\0 +v \0\0\0\0\x90\xBD\x81!\0\0\0\0 \rV\"\0\0\0\0\x10\xDAj#\0\0\0\0 \xEF5$\0\0\0\0\x10\xBCJ%\0\0\0\0 \xD1\x15&\0\0\0\0\x10\x9E*'\0\0\0\0\xA0\xED\xFE'\0\0\0\0\x10\x80\n)\0\0\0\0\xA0\xCF\xDE)\0\0\0\0\x10b\xEA*\0\0\0\0\xA0\xB1\xBE+\0\0\0\0\x90~\xD3,\0\0\0\0\xA0\x93\x9E-\0\0\0\0\x90`\xB3.\0\0\0\0\xA0u~/\0\0\0\0\x90B\x930\0\0\0\0 \x92g1\0\0\0\0\x90$s2\0\0\0\0 tG3\0\0\0\0\x90\x06S4\0\0\0\0 V'5\0\0\0\0\x90\xE826\0\0\0\0 8\x077\0\0\0\0\x10\x05\x1C8\0\0\0\0 \x1A\xE78\0\0\0\0\x10\xE7\xFB9\0\0\0\0 \xFC\xC6:\0\0\0\0\x10\xC9\xDB;\0\0\0\0\xA0\x18\xB0<\0\0\0\0\x10\xAB\xBB=\0\0\0\0\xA0\xFA\x8F>\0\0\0\0\x10\x8D\x9B?\0\0\0\0\xA0\xDCo@\0\0\0\0\x90\xA9\x84A\0\0\0\0\xA0\xBEOB\0\0\0\0\x90\x8BdC\0\0\0\0\xA0\xA0/D\0\0\0\0\x90mDE\0\0\0\0 \xD3\xF3E\0\0\0\0\x10\x8A-G\0\0\0\0 \xB5\xD3G\0\0\0\0\x10l\rI\0\0\0\0 \x97\xB3I\0\0\0\0\x10N\xEDJ\0\0\0\0\xA0\xB3\x9CK\0\0\0\0\x90j\xD6L\0\0\0\0\xA0\x95|M\0\0\0\0\x90L\xB6N\0\0\0\0\xA0w\\O\0\0\0\0\x90.\x96P\0\0\0\0\xA0Y\0\0\0\0\0\x7F\x9B?\0\0\0\0\x90\xCEo@\0\0\0\0\x80\x9B\x84A\0\0\0\0\x90\xB0OB\0\0\0\0\x80}dC\0\0\0\0\x90\x92/D\0\0\0\0\x80_DE\0\0\0\0\x10\xC5\xF3E\0\0\0\0\0|-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x94\x9D\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFFEST\0\0\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\x01EDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\x88\x02\xD9\x02[\"\xBD\x85\xFF\xFF\xFF\xFF\0\x94<\x99\xFF\xFF\xFF\xFFp\xF0\x88\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\xE0\xFB`\xD2\xFF\xFF\xFF\xFF\xF0\xA85\xD7\xFF\xFF\xFF\xFF\xE0\xA1\0\xD8\xFF\xFF\xFF\xFF\x8C\x903\xFB\xFF\xFF\xFF\xFF\xE0;\xE8\xFB\xFF\xFF\xFF\xFF\xF0:\xD8\xFC\xFF\xFF\xFF\xFF\xE0\x1D\xC8\xFD\xFF\xFF\xFF\xFFp\xDF@\x06\0\0\0\0`\xC20\x07\0\0\0\0p\x19\x8D\x07\0\0\0\0`\xA4\x10\t\0\0\0\0p\xA3\0\n\0\0\0\0`\x86\xF0\n\0\0\0\0p\x85\xE0\x0B\0\0\0\0\xE0\xA2\xD9\x0C\0\0\0\0pg\xC0\r\0\0\0\0\xE0\x84\xB9\x0E\0\0\0\0\xF0\x83\xA9\x0F\0\0\0\0\xE0f\x99\x10\0\0\0\0\xF0e\x89\x11\0\0\0\0\xE0Hy\x12\0\0\0\0\xF0Gi\x13\0\0\0\0\xE0*Y\x14\0\0\0\0\xF0)I\x15\0\0\0\0\xE0\x0C9\x16\0\0\0\0\xF0\x0B)\x17\0\0\0\0`)\"\x18\0\0\0\0\xF0\xED\x08\x19\0\0\0\0`\x0B\x02\x1A\0\0\0\0p\n\xF2\x1A\0\0\0\0`\xED\xE1\x1B\0\0\0\0p\xEC\xD1\x1C\0\0\0\0`\xCF\xC1\x1D\0\0\0\0p\xCE\xB1\x1E\0\0\0\0`\xB1\xA1\x1F\0\0\0\0\xF0\0v \0\0\0\0`\x93\x81!\0\0\0\0\xF0\xE2U\"\0\0\0\0\xE0\xAFj#\0\0\0\0\xF0\xC45$\0\0\0\0\xE0\x91J%\0\0\0\0\xF0\xA6\x15&\0\0\0\0\xE0s*'\0\0\0\0p\xC3\xFE'\0\0\0\0\xE0U\n)\0\0\0\0p\xA5\xDE)\0\0\0\0\xE07\xEA*\0\0\0\0p\x87\xBE+\0\0\0\0`T\xD3,\0\0\0\0pi\x9E-\0\0\0\0`6\xB3.\0\0\0\0pK~/\0\0\0\0`\x18\x930\0\0\0\0\xF0gg1\0\0\0\0`\xFAr2\0\0\0\0\xF0IG3\0\0\0\0`\xDCR4\0\0\0\0\xF0+'5\0\0\0\0`\xBE26\0\0\0\0\xF0\r\x077\0\0\0\0\xE0\xDA\x1B8\0\0\0\0\xF0\xEF\xE68\0\0\0\0\xE0\xBC\xFB9\0\0\0\0\xF0\xD1\xC6:\0\0\0\0\xE0\x9E\xDB;\0\0\0\0p\xEE\xAF<\0\0\0\0\xE0\x80\xBB=\0\0\0\0p\xD0\x8F>\0\0\0\0\xE0b\x9B?\0\0\0\0p\xB2o@\0\0\0\0`\x7F\x84A\0\0\0\0p\x94OB\0\0\0\0`adC\0\0\0\0pv/D\0\0\0\0`CDE\0\0\0\0\xF0\xA8\xF3E\0\0\0\0\xE0_-G\0\0\0\0\x01\x02\x03\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02%\xB2\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFFMST\0\0\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\x01MDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xD0\x02*\x03\xE0\xCE\xDE\x88\xFF\xFF\xFF\xFF\x90\xAF\xB8\x9E\xFF\xFF\xFF\xFF\x80\x07\xBB\x9F\xFF\xFF\xFF\xFF\x90\x91\x98\xA0\xFF\xFF\xFF\xFF\x80\x85\xD2\xA0\xFF\xFF\xFF\xFF\x90\xE8\x8A\xA2\xFF\xFF\xFF\xFF\0\x06\x84\xA3\xFF\xFF\xFF\xFF\x90\xCAj\xA4\xFF\xFF\xFF\xFF\x80\xC35\xA5\xFF\xFF\xFF\xFF\x10\xE7S\xA6\xFF\xFF\xFF\xFF\x80\xA5\x15\xA7\xFF\xFF\xFF\xFF\x10\xC93\xA8\xFF\xFF\xFF\xFF\0\xC2\xFE\xA8\xFF\xFF\xFF\xFF\x90\x0C\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\0\x18a\xD2\xFF\xFF\xFF\xFF\x10\xE3U\xD5\xFF\xFF\xFF\xFF\0\xDC \xD6\xFF\xFF\xFF\xFF\x90\x19a\x04\0\0\0\0\x80\xFCP\x05\0\0\0\0\x90\xFB@\x06\0\0\0\0\x80\xDE0\x07\0\0\0\0\x90\xDD \x08\0\0\0\0\x80\xC0\x10\t\0\0\0\0\x90\xBF\0\n\0\0\0\0\x80\xA2\xF0\n\0\0\0\0\x90\xA1\xE0\x0B\0\0\0\0\0\xBF\xD9\x0C\0\0\0\0\x90\x83\xC0\r\0\0\0\0\0\xA1\xB9\x0E\0\0\0\0\x10\xA0\xA9\x0F\0\0\0\0\0\x83\x99\x10\0\0\0\0\x10\x82\x89\x11\0\0\0\0\0ey\x12\0\0\0\0\x10di\x13\0\0\0\0\0GY\x14\0\0\0\0\x10FI\x15\0\0\0\0\0)9\x16\0\0\0\0\x10()\x17\0\0\0\0\x80E\"\x18\0\0\0\0\x10\n\t\x19\0\0\0\0\x80'\x02\x1A\0\0\0\0\x90&\xF2\x1A\0\0\0\0\x80\t\xE2\x1B\0\0\0\0\x90\x08\xD2\x1C\0\0\0\0\x80\xEB\xC1\x1D\0\0\0\0\x90\xEA\xB1\x1E\0\0\0\0\x80\xCD\xA1\x1F\0\0\0\0\xF0\x13\xFA\x1F\0\0\0\0\x80\xAF\x81!\0\0\0\0\x10\xFFU\"\0\0\0\0\0\xCCj#\0\0\0\0\x10\xE15$\0\0\0\0\0\xAEJ%\0\0\0\0\x10\xC3\x15&\0\0\0\0\0\x90*'\0\0\0\0\x90\xDF\xFE'\0\0\0\0\0r\n)\0\0\0\0\x90\xC1\xDE)\0\0\0\0\0T\xEA*\0\0\0\0\x90\xA3\xBE+\0\0\0\0\x80p\xD3,\0\0\0\0\x90\x85\x9E-\0\0\0\0\x80R\xB3.\0\0\0\0\x90g~/\0\0\0\0\x804\x930\0\0\0\0\x10\x84g1\0\0\0\0\x80\x16s2\0\0\0\0\x10fG3\0\0\0\0\x80\xF8R4\0\0\0\0\x10H'5\0\0\0\0\x80\xDA26\0\0\0\0\x10*\x077\0\0\0\0\0\xF7\x1B8\0\0\0\0\x10\x0C\xE78\0\0\0\0\0\xD9\xFB9\0\0\0\0\x10\xEE\xC6:\0\0\0\0\0\xBB\xDB;\0\0\0\0\x90\n\xB0<\0\0\0\0\0\x9D\xBB=\0\0\0\0\x90\xEC\x8F>\0\0\0\0\0\x7F\x9B?\0\0\0\0\x90\xCEo@\0\0\0\0\x80\x9B\x84A\0\0\0\0\x90\xB0OB\0\0\0\0\x80}dC\0\0\0\0\x90\x92/D\0\0\0\0\x80_DE\0\0\0\0\x10\xC5\xF3E\0\0\0\0\0|-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xA0\x95\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF-05\0\0\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\x01*\x01\x80\x88\xAA\x96\xFF\xFF\xFF\xFF\0f\x0F\xB8\xFF\xFF\xFF\xFF\xC0\\\xFD\xB8\xFF\xFF\xFF\xFFPP\xF1\xB9\xFF\xFF\xFF\xFF@\x90\xDE\xBA\xFF\xFF\xFF\xFFP\xCA8\xDA\xFF\xFF\xFF\xFFP\x16\xEC\xDA\xFF\xFF\xFF\xFF\xD0\xFD\x19\xDC\xFF\xFF\xFF\xFF@u\xB9\xDC\xFF\xFF\xFF\xFFP1\xFB\xDD\xFF\xFF\xFF\xFF@\xFA\x9B\xDE\xFF\xFF\xFF\xFFP\xB6\xDD\xDF\xFF\xFF\xFF\xFF@OT\xE0\xFF\xFF\xFF\xFF\xD0\x1B\x98\xF4\xFF\xFF\xFF\xFF@z\x05\xF5\xFF\xFF\xFF\xFFP\x80\xC0\xF6\xFF\xFF\xFF\xFF\xC0:\x0E\xF7\xFF\xFF\xFF\xFFPHQ\xF8\xFF\xFF\xFF\xFF@\xE1\xC7\xF8\xFF\xFF\xFF\xFF\xD0\xEE\n\xFA\xFF\xFF\xFF\xFF\xC0\x14\xA9\xFA\xFF\xFF\xFF\xFFP\"\xEC\xFB\xFF\xFF\xFF\xFF\xC0\x99\x8B\xFC\xFF\xFF\xFF\xFFP\xAA\xC9\x1D\0\0\0\0\xC0\xF3x\x1E\0\0\0\0\xD0Q\xA0\x1F\0\0\0\0\xC0\xEB3 \0\0\0\0P\x85\x81!\0\0\0\0\xC0\xE4\x0B\"\0\0\0\0P\xD1\xC0,\0\0\0\0@\xE0f-\0\0\0\0P\x7F`H\0\0\0\0\xC0\x04\x7FR\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x01\x80\xBE\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\0\x1B\0 \xA6\xD5\xA3\xFF\xFF\xFF\xFF\xE0\xDC\x9A \0\0\0\0P\x9B\\!\0\0\0\0\x01\x02\x01`\xAC\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFFMST\0\0\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0x\x04\x08\x05\x87v=^\xFF\xFF\xFF\xFF\xA0\xBD\xB8\x9E\xFF\xFF\xFF\xFF\x90\x15\xBB\x9F\xFF\xFF\xFF\xFF\xA0\x1A\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\x10&a\xD2\xFF\xFF\xFF\xFF \xF1U\xD5\xFF\xFF\xFF\xFF\x10\xEA \xD6\xFF\xFF\xFF\xFF \xD35\xD7\xFF\xFF\xFF\xFF\x10\xCC\0\xD8\xFF\xFF\xFF\xFF \xB5\x15\xD9\xFF\xFF\xFF\xFF\x10\xAE\xE0\xD9\xFF\xFF\xFF\xFF\xA0\xD1\xFE\xDA\xFF\xFF\xFF\xFF\x10\x90\xC0\xDB\xFF\xFF\xFF\xFF\xA0\xB3\xDE\xDC\xFF\xFF\xFF\xFF\x90\xAC\xA9\xDD\xFF\xFF\xFF\xFF\xA0\x95\xBE\xDE\xFF\xFF\xFF\xFF\x90\x8E\x89\xDF\xFF\xFF\xFF\xFF\xA0w\x9E\xE0\xFF\xFF\xFF\xFF\x90pi\xE1\xFF\xFF\xFF\xFF\xA0Y~\xE2\xFF\xFF\xFF\xFF\x90RI\xE3\xFF\xFF\xFF\xFF\xA0;^\xE4\xFF\xFF\xFF\xFF\x904)\xE5\xFF\xFF\xFF\xFF XG\xE6\xFF\xFF\xFF\xFF\x10Q\x12\xE7\xFF\xFF\xFF\xFF :'\xE8\xFF\xFF\xFF\xFF\x103\xF2\xE8\xFF\xFF\xFF\xFF \x1C\x07\xEA\xFF\xFF\xFF\xFF\x10\x15\xD2\xEA\xFF\xFF\xFF\xFF \xFE\xE6\xEB\xFF\xFF\xFF\xFF\x10\xF7\xB1\xEC\xFF\xFF\xFF\xFF \xE0\xC6\xED\xFF\xFF\xFF\xFF\x10\xD9\x91\xEE\xFF\xFF\xFF\xFF\xA0\xFC\xAF\xEF\xFF\xFF\xFF\xFF\x10\xBBq\xF0\xFF\xFF\xFF\xFF\xA0\xDE\x8F\xF1\xFF\xFF\xFF\xFF\x90\xC1\x7F\xF2\xFF\xFF\xFF\xFF\xA0\xC0o\xF3\xFF\xFF\xFF\xFF\x90\xA3_\xF4\xFF\xFF\xFF\xFF\xA0\xA2O\xF5\xFF\xFF\xFF\xFF\x90\x85?\xF6\xFF\xFF\xFF\xFF\xA0\x84/\xF7\xFF\xFF\xFF\xFF\x10\xA2(\xF8\xFF\xFF\xFF\xFF\xA0f\x0F\xF9\xFF\xFF\xFF\xFF\x10\x84\x08\xFA\xFF\xFF\xFF\xFF \x83\xF8\xFA\xFF\xFF\xFF\xFF\x10f\xE8\xFB\xFF\xFF\xFF\xFF e\xD8\xFC\xFF\xFF\xFF\xFF\x10H\xC8\xFD\xFF\xFF\xFF\xFF G\xB8\xFE\xFF\xFF\xFF\xFF\x10*\xA8\xFF\xFF\xFF\xFF\xFF )\x98\0\0\0\0\0\x10\x0C\x88\x01\0\0\0\0 \x0Bx\x02\0\0\0\0\x90(q\x03\0\0\0\0\xA0'a\x04\0\0\0\0\x90\nQ\x05\0\0\0\0\xA0\tA\x06\0\0\0\0\x90\xEC0\x07\0\0\0\0\xA0\xEB \x08\0\0\0\0\x90\xCE\x10\t\0\0\0\0\xA0\xCD\0\n\0\0\0\0\x90\xB0\xF0\n\0\0\0\0\xA0\xAF\xE0\x0B\0\0\0\0\x10\xCD\xD9\x0C\0\0\0\0\xA0\x91\xC0\r\0\0\0\0\x10\xAF\xB9\x0E\0\0\0\0 \xAE\xA9\x0F\0\0\0\0\x10\x91\x99\x10\0\0\0\0 \x90\x89\x11\0\0\0\0\x10sy\x12\0\0\0\0 ri\x13\0\0\0\0\x10UY\x14\0\0\0\0 TI\x15\0\0\0\0\x1079\x16\0\0\0\0 6)\x17\0\0\0\0\x90S\"\x18\0\0\0\0 \x18\t\x19\0\0\0\0\x905\x02\x1A\0\0\0\0\xA04\xF2\x1A\0\0\0\0\x90\x17\xE2\x1B\0\0\0\0\xA0\x16\xD2\x1C\0\0\0\0\x90\xF9\xC1\x1D\0\0\0\0\xA0\xF8\xB1\x1E\0\0\0\0\x90\xDB\xA1\x1F\0\0\0\0\0\"\xFA\x1F\0\0\0\0\x90\xBD\x81!\0\0\0\0 \rV\"\0\0\0\0\x10\xDAj#\0\0\0\0 \xEF5$\0\0\0\0\x10\xBCJ%\0\0\0\0 \xD1\x15&\0\0\0\0\x10\x9E*'\0\0\0\0\xA0\xED\xFE'\0\0\0\0\x10\x80\n)\0\0\0\0\xA0\xCF\xDE)\0\0\0\0\x10b\xEA*\0\0\0\0\xA0\xB1\xBE+\0\0\0\0\x90~\xD3,\0\0\0\0\xA0\x93\x9E-\0\0\0\0\x90`\xB3.\0\0\0\0\xA0u~/\0\0\0\0\x90B\x930\0\0\0\0 \x92g1\0\0\0\0\x90$s2\0\0\0\0 tG3\0\0\0\0\x90\x06S4\0\0\0\0 V'5\0\0\0\0\x90\xE826\0\0\0\0 8\x077\0\0\0\0\x10\x05\x1C8\0\0\0\0 \x1A\xE78\0\0\0\0\x10\xE7\xFB9\0\0\0\0 \xFC\xC6:\0\0\0\0\x10\xC9\xDB;\0\0\0\0\xA0\x18\xB0<\0\0\0\0\x10\xAB\xBB=\0\0\0\0\xA0\xFA\x8F>\0\0\0\0\x10\x8D\x9B?\0\0\0\0\xA0\xDCo@\0\0\0\0\x90\xA9\x84A\0\0\0\0\xA0\xBEOB\0\0\0\0\x90\x8BdC\0\0\0\0\xA0\xA0/D\0\0\0\0\x90mDE\0\0\0\0 \xD3\xF3E\0\0\0\0\x10\x8A-G\0\0\0\0 \xB5\xD3G\0\0\0\0\x10l\rI\0\0\0\0 \x97\xB3I\0\0\0\0\x10N\xEDJ\0\0\0\0\xA0\xB3\x9CK\0\0\0\0\x90j\xD6L\0\0\0\0\xA0\x95|M\0\0\0\0\x90L\xB6N\0\0\0\0\xA0w\\O\0\0\0\0\x90.\x96P\0\0\0\0\xA0Y\0\0\0\0\xD0T\x9B?\0\0\0\0`\xA4o@\0\0\0\0Pq\x84A\0\0\0\0`\x86OB\0\0\0\0PSdC\0\0\0\0`h/D\0\0\0\0P5DE\0\0\0\0\xE0\x9A\xF3E\0\0\0\0\xD0Q-G\0\0\0\0\x01\x02\x01\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xCC\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFFAST\0\0\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\x01ADT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xB8\x04O\x05$<=^\xFF\xFF\xFF\xFF\x8C~\xB8\x9E\xFF\xFF\xFF\xFF|\xD6\xBA\x9F\xFF\xFF\xFF\xFFlM\x9E\xBE\xFF\xFF\xFF\xFF81\xB8\xC0\xFF\xFF\xFF\xFF\xA8\xEFy\xC1\xFF\xFF\xFF\xFF8\x13\x98\xC2\xFF\xFF\xFF\xFF\xA8\xD1Y\xC3\xFF\xFF\xFF\xFF8\xF5w\xC4\xFF\xFF\xFF\xFF\xA8\xB39\xC5\xFF\xFF\xFF\xFF\xB8\x11a\xC6\xFF\xFF\xFF\xFF\xA8\x95\x19\xC7\xFF\xFF\xFF\xFF\xB8\xF3@\xC8\xFF\xFF\xFF\xFF(\xB2\x02\xC9\xFF\xFF\xFF\xFF\xB8\xD5 \xCA\xFF\xFF\xFF\xFF(\x94\xE2\xCA\xFF\xFF\xFF\xFF\xB8\xB7\0\xCC\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\xC8\xE6`\xD2\xFF\xFF\xFF\xFF\xD8D\x88\xD3\xFF\xFF\xFF\xFFH\x03J\xD4\xFF\xFF\xFF\xFF\xD8&h\xD5\xFF\xFF\xFF\xFFH\xE5)\xD6\xFF\xFF\xFF\xFF\xD8\x08H\xD7\xFF\xFF\xFF\xFFH\xC7\t\xD8\xFF\xFF\xFF\xFF\xD8\xEA'\xD9\xFF\xFF\xFF\xFFH\xA9\xE9\xD9\xFF\xFF\xFF\xFFX\x07\x11\xDB\xFF\xFF\xFF\xFF\xC8\xC5\xD2\xDB\xFF\xFF\xFF\xFFXt\xDE\xDC\xFF\xFF\xFF\xFFHm\xA9\xDD\xFF\xFF\xFF\xFFXV\xBE\xDE\xFF\xFF\xFF\xFFHO\x89\xDF\xFF\xFF\xFF\xFFX8\x9E\xE0\xFF\xFF\xFF\xFFH1i\xE1\xFF\xFF\xFF\xFFX\x1A~\xE2\xFF\xFF\xFF\xFFH\x13I\xE3\xFF\xFF\xFF\xFFX\xFC]\xE4\xFF\xFF\xFF\xFFH\xF5(\xE5\xFF\xFF\xFF\xFF\xD8\x18G\xE6\xFF\xFF\xFF\xFF\xC8\x11\x12\xE7\xFF\xFF\xFF\xFF\xD8\xFA&\xE8\xFF\xFF\xFF\xFF\xC8\xF3\xF1\xE8\xFF\xFF\xFF\xFF\xD8\xDC\x06\xEA\xFF\xFF\xFF\xFF\xC8\xD5\xD1\xEA\xFF\xFF\xFF\xFF\xD8\xBE\xE6\xEB\xFF\xFF\xFF\xFF\xC8\xB7\xB1\xEC\xFF\xFF\xFF\xFF\xD8\xA0\xC6\xED\xFF\xFF\xFF\xFFH\xBE\xBF\xEE\xFF\xFF\xFF\xFFX\xBD\xAF\xEF\xFF\xFF\xFF\xFFH\xA0\x9F\xF0\xFF\xFF\xFF\xFFX\x9F\x8F\xF1\xFF\xFF\xFF\xFFH\x82\x7F\xF2\xFF\xFF\xFF\xFFX\x81o\xF3\xFF\xFF\xFF\xFFHd_\xF4\xFF\xFF\xFF\xFFXcO\xF5\xFF\xFF\xFF\xFFHF?\xF6\xFF\xFF\xFF\xFFXE/\xF7\xFF\xFF\xFF\xFF\xC8b(\xF8\xFF\xFF\xFF\xFFXk\xDA\xF8\xFF\xFF\xFF\xFF`.\x0F\xF9\xFF\xFF\xFF\xFF\xD0K\x08\xFA\xFF\xFF\xFF\xFF\xE0J\xF8\xFA\xFF\xFF\xFF\xFF\xD0-\xE8\xFB\xFF\xFF\xFF\xFF\xE0,\xD8\xFC\xFF\xFF\xFF\xFF\xD0\x0F\xC8\xFD\xFF\xFF\xFF\xFF\xE0\x0E\xB8\xFE\xFF\xFF\xFF\xFF\xD0\xF1\xA7\xFF\xFF\xFF\xFF\xFF\xE0\xF0\x97\0\0\0\0\0\xD0\xD3\x87\x01\0\0\0\0\xE0\xD2w\x02\0\0\0\0P\xF0p\x03\0\0\0\0`\xEF`\x04\0\0\0\0P\xD2P\x05\0\0\0\0`\xD1@\x06\0\0\0\0P\xB40\x07\0\0\0\0`\xB3 \x08\0\0\0\0P\x96\x10\t\0\0\0\0`\x95\0\n\0\0\0\0Px\xF0\n\0\0\0\0`w\xE0\x0B\0\0\0\0\xD0\x94\xD9\x0C\0\0\0\0`Y\xC0\r\0\0\0\0\xD0v\xB9\x0E\0\0\0\0\xE0u\xA9\x0F\0\0\0\0\xD0X\x99\x10\0\0\0\0\xE0W\x89\x11\0\0\0\0\xD0:y\x12\0\0\0\0\xE09i\x13\0\0\0\0\xD0\x1CY\x14\0\0\0\0\xE0\x1BI\x15\0\0\0\0\xD0\xFE8\x16\0\0\0\0\xE0\xFD(\x17\0\0\0\0P\x1B\"\x18\0\0\0\0\xE0\xDF\x08\x19\0\0\0\0P\xFD\x01\x1A\0\0\0\0`\xFC\xF1\x1A\0\0\0\0P\xDF\xE1\x1B\0\0\0\0`\xDE\xD1\x1C\0\0\0\0P\xC1\xC1\x1D\0\0\0\0`\xC0\xB1\x1E\0\0\0\0P\xA3\xA1\x1F\0\0\0\0\xFC\xD6u \0\0\0\0li\x81!\0\0\0\0\xFC\xB8U\"\0\0\0\0\xDCwj#\0\0\0\0\xFC\x9A5$\0\0\0\0\xECgJ%\0\0\0\0\xFC|\x15&\0\0\0\0\xECI*'\0\0\0\0|\x99\xFE'\0\0\0\0\xEC+\n)\0\0\0\0|{\xDE)\0\0\0\0\xEC\r\xEA*\0\0\0\0|]\xBE+\0\0\0\0l*\xD3,\0\0\0\0|?\x9E-\0\0\0\0l\x0C\xB3.\0\0\0\0|!~/\0\0\0\0l\xEE\x920\0\0\0\0\xFC=g1\0\0\0\0l\xD0r2\0\0\0\0\xFC\x1FG3\0\0\0\0l\xB2R4\0\0\0\0\xFC\x01'5\0\0\0\0l\x9426\0\0\0\0\xFC\xE3\x067\0\0\0\0\xEC\xB0\x1B8\0\0\0\0\xFC\xC5\xE68\0\0\0\0\xEC\x92\xFB9\0\0\0\0\xFC\xA7\xC6:\0\0\0\0\xECt\xDB;\0\0\0\0|\xC4\xAF<\0\0\0\0\xECV\xBB=\0\0\0\0|\xA6\x8F>\0\0\0\0\xEC8\x9B?\0\0\0\0|\x88o@\0\0\0\0lU\x84A\0\0\0\0|jOB\0\0\0\0l7dC\0\0\0\0|L/D\0\0\0\0l\x19DE\0\0\0\0\xFC~\xF3E\0\0\0\0\xEC5-G\0\0\0\0\xFC`\xD3G\0\0\0\0\xEC\x17\rI\0\0\0\0\xFCB\xB3I\0\0\0\0\xEC\xF9\xECJ\0\0\0\0|_\x9CK\0\0\0\0l\x16\xD6L\0\0\0\0|A|M\0\0\0\0\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x07\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\\\xC7\xFF\xFF\xFF\xFF\xFF\xFF\x94\xCE\xFF\xFF\xFF\xFF\xFF\xFF\xA4\xDC\xFF\xFF\xFF\xFF\xFF\xFF\xC8\xCE\xFF\xFF\xFF\xFF\xFF\xFF\xD8\xDC\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFFEST\0\0\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\x01EDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0`\x02\xAE\x020\x1E\x87i\xFF\xFF\xFF\xFF\xFE\xB4\x0F\x93\xFF\xFF\xFF\xFF\xF0e\x89\x11\0\0\0\0\xE0Hy\x12\0\0\0\0\xF0Gi\x13\0\0\0\0\xE0*Y\x14\0\0\0\0\xF0)I\x15\0\0\0\0\xE0\x0C9\x16\0\0\0\0\xF0\x0B)\x17\0\0\0\0`)\"\x18\0\0\0\0\xF0\xED\x08\x19\0\0\0\0`\x0B\x02\x1A\0\0\0\0p\n\xF2\x1A\0\0\0\0`\xED\xE1\x1B\0\0\0\0p\xEC\xD1\x1C\0\0\0\0`\xCF\xC1\x1D\0\0\0\0p\xCE\xB1\x1E\0\0\0\0`\xB1\xA1\x1F\0\0\0\0\xF0\0v \0\0\0\0`\x93\x81!\0\0\0\0\xF0\xE2U\"\0\0\0\0\xE0\xAFj#\0\0\0\0\xF0\xC45$\0\0\0\0\xE0\x91J%\0\0\0\0\xF0\xA6\x15&\0\0\0\0\xE0s*'\0\0\0\0p\xC3\xFE'\0\0\0\0\xE0U\n)\0\0\0\0p\xA5\xDE)\0\0\0\0\xE07\xEA*\0\0\0\0p\x87\xBE+\0\0\0\0`T\xD3,\0\0\0\0pi\x9E-\0\0\0\0`6\xB3.\0\0\0\0pK~/\0\0\0\0`\x18\x930\0\0\0\0\xF0gg1\0\0\0\0`\xFAr2\0\0\0\0\xF0IG3\0\0\0\0`\xDCR4\0\0\0\0\xF0+'5\0\0\0\0`\xBE26\0\0\0\0\xF0\r\x077\0\0\0\0\xE0\xDA\x1B8\0\0\0\0\xF0\xEF\xE68\0\0\0\0\xE0\xBC\xFB9\0\0\0\0\xF0\xD1\xC6:\0\0\0\0\xE0\x9E\xDB;\0\0\0\0p\xEE\xAF<\0\0\0\0\xE0\x80\xBB=\0\0\0\0p\xD0\x8F>\0\0\0\0\xE0b\x9B?\0\0\0\0p\xB2o@\0\0\0\0`\x7F\x84A\0\0\0\0p\x94OB\0\0\0\0`adC\0\0\0\0pv/D\0\0\0\0`CDE\0\0\0\0\xF0\xA8\xF3E\0\0\0\0\xE0_-G\0\0\0\0\xF0\x8A\xD3G\0\0\0\0\xE0A\rI\0\0\0\0\xF0l\xB3I\0\0\0\0\xE0#\xEDJ\0\0\0\0p\x89\x9CK\0\0\0\0`@\xD6L\0\0\0\0pk|M\0\0\0\0`\"\xB6N\0\0\0\0pM\\O\0\0\0\0`\x04\x96P\0\0\0\0p/\0\0\0\0\xD0T\x9B?\0\0\0\0`\xA4o@\0\0\0\0Pq\x84A\0\0\0\0`\x86OB\0\0\0\0PSdC\0\0\0\0`h/D\0\0\0\0P5DE\0\0\0\0\xE0\x9A\xF3E\0\0\0\0\xD0Q-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01`\xC4\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\x01CDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0\0\0\0\0\0\0\0\0`\x03\xCC\x03\xB8(\x87i\xFF\xFF\xFF\xFF\x80\xC2b\xAC\xFF\xFF\xFF\xFFP\x94\xD3\xB1\xFF\xFF\xFF\xFF@]t\xB2\xFF\xFF\xFF\xFF\xD0f[\xC8\xFF\xFF\xFF\xFF@Q\xD3\xC8\xFF\xFF\xFF\xFF\xD0H;\xCA\xFF\xFF\xFF\xFF\xC0m\xBC\xCA\xFF\xFF\xFF\xFFPe$\xCC\xFF\xFF\xFF\xFF\xC0O\x9C\xCC\xFF\xFF\xFF\xFFP\x0B\xC4\xD1\xFF\xFF\xFF\xFF\xC0\xF5;\xD2\xFF\xFF\xFF\xFFP\xED\xA3\xD3\xFF\xFF\xFF\xFF\xC0\xD7\x1B\xD4\xFF\xFF\xFF\xFF\xD0\x05`\xF7\xFF\xFF\xFF\xFF@}\xFF\xF7\xFF\xFF\xFF\xFF\xD0D=\xF9\xFF\xFF\xFF\xFF\xC0S\xE3\xF9\xFF\xFF\xFF\xFF\xD0;\xDB\xFA\xFF\xFF\xFF\xFF@\x86\xA7\xFB\xFF\xFF\xFF\xFF\xD0\xA9\xC5\xFC\xFF\xFF\xFF\xFF@h\x87\xFD\xFF\xFF\xFF\xFF\xD0\0\xB8\xFE\xFF\xFF\xFF\xFF\xC0\xE3\xA7\xFF\xFF\xFF\xFF\xFF\xD0\xE2\x97\0\0\0\0\0\xC0\xC5\x87\x01\0\0\0\0\xD0\xC4w\x02\0\0\0\0@\xE2p\x03\0\0\0\0P\xE1`\x04\0\0\0\0\xC0\x145\x05\0\0\0\0P\xC3@\x06\0\0\0\0@H\x16\x07\0\0\0\0P\xA5 \x08\0\0\0\0\xC0{\xF7\x08\0\0\0\0P\x87\0\n\0\0\0\0@j\xF0\n\0\0\0\0Pi\xE0\x0B\0\0\0\0\xC0\x86\xD9\x0C\0\0\0\0PK\xC0\r\0\0\0\0\xC0h\xB9\x0E\0\0\0\0P\xA2\xB2\x0F\0\0\0\0@\x9B}\x10\0\0\0\0\xD0\xEAQ\x11\0\0\0\0\xC0\xB7f\x12\0\0\0\0\xD0\xCC1\x13\0\0\0\0\xC0\x99F\x14\0\0\0\0\xD0\x82[\x15\0\0\0\0\xC0{&\x16\0\0\0\0\xD0d;\x17\0\0\0\0\xC0]\x06\x18\0\0\0\0\xD0F\x1B\x19\0\0\0\0\xC0?\xE6\x19\0\0\0\0\xD0(\xFB\x1A\0\0\0\0@\\\xCF\x1B\0\0\0\0\xD0\n\xDB\x1C\0\0\0\0@>\xAF\x1D\0\0\0\0PSz\x1E\0\0\0\0@ \x8F\x1F\0\0\0\0P5Z \0\0\0\0@\x02o!\0\0\0\0\xD0QC\"\0\0\0\0@\xE4N#\0\0\0\0\xD03#$\0\0\0\0@\xC6.%\0\0\0\0\xD0\x8A\x15&\0\0\0\0\xC0\xE2\x17'\0\0\0\0P\xA7\xFE'\0\0\0\0\xD0\xD2\xF7(\0\0\0\0P\x89\xDE)\0\0\0\0\xD0\xB4\xD7*\0\0\0\0Pk\xBE+\0\0\0\0\xD0\x96\xB7,\0\0\0\0PM\x9E-\0\0\0\0\xD0x\x97.\0\0\0\0P/~/\0\0\0\0\xD0Zw0\0\0\0\0\xD0Kg1\0\0\0\0\xD0\0\0\0\0\xD0T\x9B?\0\0\0\0\xD0[f@\0\0\0\0P5DE\0\0\0\0\xD0\x8C\xF3E\0\0\0\0P\x17$G\0\0\0\0P\xA9\xDCG\0\0\0\0P\xF9\x03I\0\0\0\0\xD0P\xB3I\0\0\0\0P\xDB\xE3J\0\0\0\0Pm\x9CK\0\0\0\0\xD0\xF7\xCCL\0\0\0\0\xD0\x89\x85M\0\0\0\0\xD0N\xBFN\0\0\0\0\xD0\xE0wO\0\0\0\0P\xF6\x95P\0\0\0\0P\x13\0\0\0\0\0\x7F\x9B?\0\0\0\0\x90\xCEo@\0\0\0\0\x80\x9B\x84A\0\0\0\0\x90\xB0OB\0\0\0\0\x80}dC\0\0\0\0\x90\x92/D\0\0\0\0\x80_DE\0\0\0\0\x10\xC5\xF3E\0\0\0\0\0|-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\0\0\0\0\0\0\0\0\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFFEST\0\0\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\x01EDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0`\x02\xB6\x02\x80\xA1l\xCC\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\xE0\xFB`\xD2\xFF\xFF\xFF\xFFp\xFD`\x04\0\0\0\0`\xE0P\x05\0\0\0\0p\xDF@\x06\0\0\0\0`\xC20\x07\0\0\0\0p\xC1 \x08\0\0\0\0`\xA4\x10\t\0\0\0\0p\xA3\0\n\0\0\0\0`\x86\xF0\n\0\0\0\0p\x85\xE0\x0B\0\0\0\0\xE0\xA2\xD9\x0C\0\0\0\0pg\xC0\r\0\0\0\0\xE0\x84\xB9\x0E\0\0\0\0\xF0\x83\xA9\x0F\0\0\0\0\xE0f\x99\x10\0\0\0\0\xF0e\x89\x11\0\0\0\0\xE0Hy\x12\0\0\0\0\xF0Gi\x13\0\0\0\0\xE0*Y\x14\0\0\0\0\xF0)I\x15\0\0\0\0\xE0\x0C9\x16\0\0\0\0\xF0\x0B)\x17\0\0\0\0`)\"\x18\0\0\0\0\xF0\xED\x08\x19\0\0\0\0`\x0B\x02\x1A\0\0\0\0p\n\xF2\x1A\0\0\0\0`\xED\xE1\x1B\0\0\0\0p\xEC\xD1\x1C\0\0\0\0`\xCF\xC1\x1D\0\0\0\0p\xCE\xB1\x1E\0\0\0\0`\xB1\xA1\x1F\0\0\0\0\xF0\0v \0\0\0\0`\x93\x81!\0\0\0\0\xF0\xE2U\"\0\0\0\0\xE0\xAFj#\0\0\0\0\xF0\xC45$\0\0\0\0\xE0\x91J%\0\0\0\0\xF0\xA6\x15&\0\0\0\0\xE0s*'\0\0\0\0p\xC3\xFE'\0\0\0\0\xE0U\n)\0\0\0\0p\xA5\xDE)\0\0\0\0\xE07\xEA*\0\0\0\0p\x87\xBE+\0\0\0\0`T\xD3,\0\0\0\0pi\x9E-\0\0\0\0`6\xB3.\0\0\0\0pK~/\0\0\0\0`\x18\x930\0\0\0\0\xF0gg1\0\0\0\0`\xFAr2\0\0\0\0\xF0IG3\0\0\0\0`\xDCR4\0\0\0\0\xF0+'5\0\0\0\0`\xBE26\0\0\0\0\xF0\r\x077\0\0\0\0\xE0\xDA\x1B8\0\0\0\0\xF0\xE8\x1B8\0\0\0\0\0\xFE\xE68\0\0\0\0\xF0\xCA\xFB9\0\0\0\0\xF0\xD1\xC6:\0\0\0\0\xE0\x9E\xDB;\0\0\0\0p\xEE\xAF<\0\0\0\0\xE0\x80\xBB=\0\0\0\0p\xD0\x8F>\0\0\0\0\xE0b\x9B?\0\0\0\0p\xB2o@\0\0\0\0`\x7F\x84A\0\0\0\0p\x94OB\0\0\0\0`adC\0\0\0\0pv/D\0\0\0\0`CDE\0\0\0\0\xF0\xA8\xF3E\0\0\0\0\xE0_-G\0\0\0\0\x01\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x03\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\0\0\0\0\0\0\0\0\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFFEST\0\0\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xB0\0\xC6\0~#\x87i\xFF\xFF\xFF\xFF\xFE\xB4\x0F\x93\xFF\xFF\xFF\xFFp\x19\x8D\x07\0\0\0\0`\xA4\x10\t\0\0\0\0\xF0\x94\xAD\t\0\0\0\0`\x86\xF0\n\0\0\0\0p\x85\xE0\x0B\0\0\0\0\xE0\xA2\xD9\x0C\0\0\0\0pg\xC0\r\0\0\0\0\xE0\x84\xB9\x0E\0\0\0\0\xF0\x83\xA9\x0F\0\0\0\0\xE0f\x99\x10\0\0\0\0\xF0e\x89\x11\0\0\0\0\xE0Hy\x12\0\0\0\0\xF0Gi\x13\0\0\0\0\xE0*Y\x14\0\0\0\0\xF0)I\x15\0\0\0\0\xE0\x0C9\x16\0\0\0\0\xF0\x0B)\x17\0\0\0\0`)\"\x18\0\0\0\0\xF0\xED\x08\x19\0\0\0\0`\x0B\x02\x1A\0\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xB8\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFFAKST\0p\x81\xFF\xFF\xFF\xFF\xFF\xFF\x01AKDT\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xB0\x02#\x03\xD1\xFD\xC2?\xFF\xFF\xFF\xFF\xC52\x87}\xFF\xFF\xFF\xFF\xA0\x1A\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\x10&a\xD2\xFF\xFF\xFF\xFF G\xB8\xFE\xFF\xFF\xFF\xFF\x10*\xA8\xFF\xFF\xFF\xFF\xFF )\x98\0\0\0\0\0\x10\x0C\x88\x01\0\0\0\0 \x0Bx\x02\0\0\0\0\x90(q\x03\0\0\0\0\xA0'a\x04\0\0\0\0\x90\nQ\x05\0\0\0\0\xA0\tA\x06\0\0\0\0\x90\xEC0\x07\0\0\0\0\xA0C\x8D\x07\0\0\0\0\x90\xCE\x10\t\0\0\0\0 \xBF\xAD\t\0\0\0\0\x90\xB0\xF0\n\0\0\0\0\xA0\xAF\xE0\x0B\0\0\0\0\x10\xCD\xD9\x0C\0\0\0\0\xA0\x91\xC0\r\0\0\0\0\x10\xAF\xB9\x0E\0\0\0\0 \xAE\xA9\x0F\0\0\0\0\x10\x91\x99\x10\0\0\0\0 \x90\x89\x11\0\0\0\0\x10sy\x12\0\0\0\0 ri\x13\0\0\0\x000\x80i\x13\0\0\0\0 cY\x14\0\0\0\0 TI\x15\0\0\0\0\x1079\x16\0\0\0\0 6)\x17\0\0\0\0\x90S\"\x18\0\0\0\0 \x18\t\x19\0\0\0\0\x905\x02\x1A\0\0\0\0\xA0C\x02\x1A\0\0\0\0\x10\x14+\x1A\0\0\0\0\xB0B\xF2\x1A\0\0\0\0\xA0%\xE2\x1B\0\0\0\0\xB0$\xD2\x1C\0\0\0\0\xA0\x07\xC2\x1D\0\0\0\0\xB0\x06\xB2\x1E\0\0\0\0\xA0\xE9\xA1\x1F\0\0\0\x0009v \0\0\0\0\xA0\xCB\x81!\0\0\0\x000\x1BV\"\0\0\0\0 \xE8j#\0\0\0\x000\xFD5$\0\0\0\0 \xCAJ%\0\0\0\x000\xDF\x15&\0\0\0\0 \xAC*'\0\0\0\0\xB0\xFB\xFE'\0\0\0\0 \x8E\n)\0\0\0\0\xB0\xDD\xDE)\0\0\0\0 p\xEA*\0\0\0\0\xB0\xBF\xBE+\0\0\0\0\xA0\x8C\xD3,\0\0\0\0\xB0\xA1\x9E-\0\0\0\0\xA0n\xB3.\0\0\0\0\xB0\x83~/\0\0\0\0\xA0P\x930\0\0\0\x000\xA0g1\0\0\0\0\xA02s2\0\0\0\x000\x82G3\0\0\0\0\xA0\x14S4\0\0\0\x000d'5\0\0\0\0\xA0\xF626\0\0\0\x000F\x077\0\0\0\0 \x13\x1C8\0\0\0\x000(\xE78\0\0\0\0 \xF5\xFB9\0\0\0\x000\n\xC7:\0\0\0\0 \xD7\xDB;\0\0\0\0\xB0&\xB0<\0\0\0\0 \xB9\xBB=\0\0\0\0\xB0\x08\x90>\0\0\0\0 \x9B\x9B?\0\0\0\0\xB0\xEAo@\0\0\0\0\xA0\xB7\x84A\0\0\0\0\xB0\xCCOB\0\0\0\0\xA0\x99dC\0\0\0\0\xB0\xAE/D\0\0\0\0\xA0{DE\0\0\0\x000\xE1\xF3E\0\0\0\0 \x98-G\0\0\0\0\x01\x02\x03\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x05\x02\x05\x03\x02\x05\x03\x02\x05\x03\x02\x05\x04\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04\x02\x05\x04{\xD3\0\0\0\0\0\0\xFB\x81\xFF\xFF\xFF\xFF\xFF\xFF\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFFp\x81\xFF\xFF\xFF\xFF\xFF\xFF\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFFEST\0\0\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\x01EDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xB0\x03P\x04\xA0\xFE\x03^\xFF\xFF\xFF\xFF\x80,\xA6\x9E\xFF\xFF\xFF\xFFp\xF9\xBA\x9F\xFF\xFF\xFF\xFF\x80\x0E\x86\xA0\xFF\xFF\xFF\xFFp\xDB\x9A\xA1\xFF\xFF\xFF\xFF\0\xF7s\xA4\xFF\xFF\xFF\xFFp\x11\x16\xA5\xFF\xFF\xFF\xFF\x80N\r\xCA\xFF\xFF\xFF\xFFpG\xD8\xCA\xFF\xFF\xFF\xFF\x80\xFE\x88\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\xF0\ta\xD2\xFF\xFF\xFF\xFF\x1C\xD7u\xD3\xFF\xFF\xFF\xFFp\t\xA4\xD3\xFF\xFF\xFF\xFF\x80\xB5\xFE\xDA\xFF\xFF\xFF\xFF\xF0s\xC0\xDB\xFF\xFF\xFF\xFF\x80\x97\xDE\xDC\xFF\xFF\xFF\xFFp\x90\xA9\xDD\xFF\xFF\xFF\xFF\x80y\xBE\xDE\xFF\xFF\xFF\xFFpr\x89\xDF\xFF\xFF\xFF\xFF\x80[\x9E\xE0\xFF\xFF\xFF\xFFpTi\xE1\xFF\xFF\xFF\xFF\x80=~\xE2\xFF\xFF\xFF\xFFp6I\xE3\xFF\xFF\xFF\xFF\x80\x1F^\xE4\xFF\xFF\xFF\xFFp\x18)\xE5\xFF\xFF\xFF\xFF\0\0\0\0\0\xE0b\x9B?\0\0\0\0p\xB2o@\0\0\0\0`\x7F\x84A\0\0\0\0p\x94OB\0\0\0\0`adC\0\0\0\0pv/D\0\0\0\0`CDE\0\0\0\0\xF0\xA8\xF3E\0\0\0\0\xE0_-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x02\x03\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x9A\xAF\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFFEST\0\0\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\x01EDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xC0\x02 \x03\xA0\xFE\x03^\xFF\xFF\xFF\xFF\x80,\xA6\x9E\xFF\xFF\xFF\xFFp\xF9\xBA\x9F\xFF\xFF\xFF\xFF\x80\x0E\x86\xA0\xFF\xFF\xFF\xFFp\xDB\x9A\xA1\xFF\xFF\xFF\xFF\x80\xFE\x88\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\xF0\ta\xD2\xFF\xFF\xFF\xFF\0I\xD8\xFC\xFF\xFF\xFF\xFF\xF0+\xC8\xFD\xFF\xFF\xFF\xFF\0+\xB8\xFE\xFF\xFF\xFF\xFF\xF0\r\xA8\xFF\xFF\xFF\xFF\xFF\0\r\x98\0\0\0\0\0\xF0\xEF\x87\x01\0\0\0\0\0\xEFw\x02\0\0\0\0p\x0Cq\x03\0\0\0\0\x80\x0Ba\x04\0\0\0\0p\xEEP\x05\0\0\0\0\x80\xED@\x06\0\0\0\0p\xD00\x07\0\0\0\0\x80'\x8D\x07\0\0\0\0p\xB2\x10\t\0\0\0\0\0\xA3\xAD\t\0\0\0\0p\x94\xF0\n\0\0\0\0\x80\x93\xE0\x0B\0\0\0\0\xF0\xB0\xD9\x0C\0\0\0\0\x80u\xC0\r\0\0\0\0\xF0\x92\xB9\x0E\0\0\0\0\0\x92\xA9\x0F\0\0\0\0\xF0t\x99\x10\0\0\0\0\0t\x89\x11\0\0\0\0\xF0Vy\x12\0\0\0\0\0Vi\x13\0\0\0\0\xF08Y\x14\0\0\0\0\08I\x15\0\0\0\0\xF0\x1A9\x16\0\0\0\0\0\x1A)\x17\0\0\0\0p7\"\x18\0\0\0\0\0\xFC\x08\x19\0\0\0\0p\x19\x02\x1A\0\0\0\0\x80\x18\xF2\x1A\0\0\0\0p\xFB\xE1\x1B\0\0\0\0\x80\xFA\xD1\x1C\0\0\0\0p\xDD\xC1\x1D\0\0\0\0\x80\xDC\xB1\x1E\0\0\0\0p\xBF\xA1\x1F\0\0\0\0\0\x0Fv \0\0\0\0p\xA1\x81!\0\0\0\0\0\xF1U\"\0\0\0\0\xF0\xBDj#\0\0\0\0\0\xD35$\0\0\0\0\xF0\x9FJ%\0\0\0\0\0\xB5\x15&\0\0\0\0\xF0\x81*'\0\0\0\0\x80\xD1\xFE'\0\0\0\0\xF0c\n)\0\0\0\0\x80\xB3\xDE)\0\0\0\0\xF0E\xEA*\0\0\0\0\x80\x95\xBE+\0\0\0\0pb\xD3,\0\0\0\0\x80w\x9E-\0\0\0\0pD\xB3.\0\0\0\0\x80Y~/\0\0\0\0p&\x930\0\0\0\0\0vg1\0\0\0\0p\x08s2\0\0\0\0\0XG3\0\0\0\0p\xEAR4\0\0\0\0\0:'5\0\0\0\0p\xCC26\0\0\0\0\0\x1C\x077\0\0\0\0\xF0\xE8\x1B8\0\0\0\0\0\xFE\xE68\0\0\0\0\xF0\xCA\xFB9\0\0\0\0\xF0\xD1\xC6:\0\0\0\0\xE0\x9E\xDB;\0\0\0\0p\xEE\xAF<\0\0\0\0\xE0\x80\xBB=\0\0\0\0p\xD0\x8F>\0\0\0\0\xE0b\x9B?\0\0\0\0p\xB2o@\0\0\0\0`\x7F\x84A\0\0\0\0p\x94OB\0\0\0\0`adC\0\0\0\0pv/D\0\0\0\0`CDE\0\0\0\0\xF0\xA8\xF3E\0\0\0\0\xE0_-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03t\xB0\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF-04\0\0\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\0\x1B\0d\x1B\x87i\xFF\xFF\xFF\xFF\xE4\x96\x1E\xB8\xFF\xFF\xFF\xFF\xD4\xD5\xEE\xB8\xFF\xFF\xFF\xFF\0\x01\x02\x1C\xC0\xFF\xFF\xFF\xFF\xFF\xFF,\xCE\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF-05\0\0\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x80\0\x90\0\xBC#\x87i\xFF\xFF\xFF\xFF\xD4@t\x8C\xFF\xFF\xFF\xFFPJ\xCF\xC3\xFF\xFF\xFF\xFF@\xE3E\xC4\xFF\xFF\xFF\xFF\xD0J/\xC5\xFF\xFF\xFF\xFF\xC0-\x1F\xC6\xFF\xFF\xFF\xFF\xD0,\x0F\xC7\xFF\xFF\xFF\xFF\xC0\x0F\xFF\xC7\xFF\xFF\xFF\xFFP\xC4\x18\x1E\0\0\0\0@]\x8F\x1E\0\0\0\0\xD0\xF7\xF9\x1F\0\0\0\0\xC0\x90p \0\0\0\0\xD0\xE3\x9E%\0\0\0\0\xC0|\x15&\0\0\0\0P\x03%-\0\0\0\0@\x9C\x9B-\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xC4\xB7\xFF\xFF\xFF\xFF\xFF\xFF\xAC\xB7\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFFPST\0\0\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF\x01PDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xF0\x03n\x04\xC0\x1A\x04^\xFF\xFF\xFF\xFF\xA0H\xA6\x9E\xFF\xFF\xFF\xFF\x90\x15\xBB\x9F\xFF\xFF\xFF\xFF\xA0*\x86\xA0\xFF\xFF\xFF\xFF\x90\xF7\x9A\xA1\xFF\xFF\xFF\xFF\xA0\x1A\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\x10&a\xD2\xFF\xFF\xFF\xFF\\t\xFE\xD6\xFF\xFF\xFF\xFF\x90\xAD\x80\xD8\xFF\xFF\xFF\xFF\x90\xC3\xFE\xDA\xFF\xFF\xFF\xFF\x10\x90\xC0\xDB\xFF\xFF\xFF\xFF\x90\xA5\xDE\xDC\xFF\xFF\xFF\xFF\x90\xAC\xA9\xDD\xFF\xFF\xFF\xFF\x90\x87\xBE\xDE\xFF\xFF\xFF\xFF\x90\x8E\x89\xDF\xFF\xFF\xFF\xFF\x90i\x9E\xE0\xFF\xFF\xFF\xFF\x90pi\xE1\xFF\xFF\xFF\xFF\x90K~\xE2\xFF\xFF\xFF\xFF\x90RI\xE3\xFF\xFF\xFF\xFF\x90-^\xE4\xFF\xFF\xFF\xFF\x904)\xE5\xFF\xFF\xFF\xFF\x10JG\xE6\xFF\xFF\xFF\xFF\x10Q\x12\xE7\xFF\xFF\xFF\xFF\x10,'\xE8\xFF\xFF\xFF\xFF\x103\xF2\xE8\xFF\xFF\xFF\xFF\x10\x0E\x07\xEA\xFF\xFF\xFF\xFF\x10\x15\xD2\xEA\xFF\xFF\xFF\xFF\x10\xF0\xE6\xEB\xFF\xFF\xFF\xFF\x10\xF7\xB1\xEC\xFF\xFF\xFF\xFF\x10\xD2\xC6\xED\xFF\xFF\xFF\xFF\x10\xD9\x91\xEE\xFF\xFF\xFF\xFF\x90\xEE\xAF\xEF\xFF\xFF\xFF\xFF\x10\xBBq\xF0\xFF\xFF\xFF\xFF\x90\xD0\x8F\xF1\xFF\xFF\xFF\xFF\x90\xC1\x7F\xF2\xFF\xFF\xFF\xFF\x90\xB2o\xF3\xFF\xFF\xFF\xFF\x90\xA3_\xF4\xFF\xFF\xFF\xFF\x90\x94O\xF5\xFF\xFF\xFF\xFF\x90\x85?\xF6\xFF\xFF\xFF\xFF\x90v/\xF7\xFF\xFF\xFF\xFF\x10\xA2(\xF8\xFF\xFF\xFF\xFF\x90X\x0F\xF9\xFF\xFF\xFF\xFF\x10\x84\x08\xFA\xFF\xFF\xFF\xFF \x83\xF8\xFA\xFF\xFF\xFF\xFF\x10f\xE8\xFB\xFF\xFF\xFF\xFF e\xD8\xFC\xFF\xFF\xFF\xFF\x10H\xC8\xFD\xFF\xFF\xFF\xFF G\xB8\xFE\xFF\xFF\xFF\xFF\x10*\xA8\xFF\xFF\xFF\xFF\xFF )\x98\0\0\0\0\0\x10\x0C\x88\x01\0\0\0\0 \x0Bx\x02\0\0\0\0\x90(q\x03\0\0\0\0\xA0'a\x04\0\0\0\0\x90\nQ\x05\0\0\0\0\xA0\tA\x06\0\0\0\0\x90\xEC0\x07\0\0\0\0\xA0C\x8D\x07\0\0\0\0\x90\xCE\x10\t\0\0\0\0 \xBF\xAD\t\0\0\0\0\x90\xB0\xF0\n\0\0\0\0\xA0\xAF\xE0\x0B\0\0\0\0\x10\xCD\xD9\x0C\0\0\0\0\xA0\x91\xC0\r\0\0\0\0\x10\xAF\xB9\x0E\0\0\0\0 \xAE\xA9\x0F\0\0\0\0\x10\x91\x99\x10\0\0\0\0 \x90\x89\x11\0\0\0\0\x10sy\x12\0\0\0\0 ri\x13\0\0\0\0\x10UY\x14\0\0\0\0 TI\x15\0\0\0\0\x1079\x16\0\0\0\0 6)\x17\0\0\0\0\x90S\"\x18\0\0\0\0 \x18\t\x19\0\0\0\0\x905\x02\x1A\0\0\0\0\xA04\xF2\x1A\0\0\0\0\x90\x17\xE2\x1B\0\0\0\0\xA0\x16\xD2\x1C\0\0\0\0\x90\xF9\xC1\x1D\0\0\0\0\xA0\xF8\xB1\x1E\0\0\0\0\x90\xDB\xA1\x1F\0\0\0\0 +v \0\0\0\0\x90\xBD\x81!\0\0\0\0 \rV\"\0\0\0\0\x10\xDAj#\0\0\0\0 \xEF5$\0\0\0\0\x10\xBCJ%\0\0\0\0 \xD1\x15&\0\0\0\0\x10\x9E*'\0\0\0\0\xA0\xED\xFE'\0\0\0\0\x10\x80\n)\0\0\0\0\xA0\xCF\xDE)\0\0\0\0\x10b\xEA*\0\0\0\0\xA0\xB1\xBE+\0\0\0\0\x90~\xD3,\0\0\0\0\xA0\x93\x9E-\0\0\0\0\x90`\xB3.\0\0\0\0\xA0u~/\0\0\0\0\x90B\x930\0\0\0\0 \x92g1\0\0\0\0\x90$s2\0\0\0\0 tG3\0\0\0\0\x90\x06S4\0\0\0\0 V'5\0\0\0\0\x90\xE826\0\0\0\0 8\x077\0\0\0\0\x10\x05\x1C8\0\0\0\0 \x1A\xE78\0\0\0\0\x10\xE7\xFB9\0\0\0\0 \xFC\xC6:\0\0\0\0\x10\xC9\xDB;\0\0\0\0\xA0\x18\xB0<\0\0\0\0\x10\xAB\xBB=\0\0\0\0\xA0\xFA\x8F>\0\0\0\0\x10\x8D\x9B?\0\0\0\0\xA0\xDCo@\0\0\0\0\x90\xA9\x84A\0\0\0\0\xA0\xBEOB\0\0\0\0\x90\x8BdC\0\0\0\0\xA0\xA0/D\0\0\0\0\x90mDE\0\0\0\0 \xD3\xF3E\0\0\0\0\x10\x8A-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01&\x91\xFF\xFF\xFF\xFF\xFF\xFF\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0H\x01q\x01|h\xAA\x96\xFF\xFF\xFF\xFF\xE0I\x0F\xB8\xFF\xFF\xFF\xFF\xA0@\xFD\xB8\xFF\xFF\xFF\xFF04\xF1\xB9\xFF\xFF\xFF\xFF t\xDE\xBA\xFF\xFF\xFF\xFF0\xAE8\xDA\xFF\xFF\xFF\xFF0\xFA\xEB\xDA\xFF\xFF\xFF\xFF\xB0\xE1\x19\xDC\xFF\xFF\xFF\xFF Y\xB9\xDC\xFF\xFF\xFF\xFF0\x15\xFB\xDD\xFF\xFF\xFF\xFF \xDE\x9B\xDE\xFF\xFF\xFF\xFF0\x9A\xDD\xDF\xFF\xFF\xFF\xFF 3T\xE0\xFF\xFF\xFF\xFF\xB0\xFF\x97\xF4\xFF\xFF\xFF\xFF ^\x05\xF5\xFF\xFF\xFF\xFF0d\xC0\xF6\xFF\xFF\xFF\xFF\xA0\x1E\x0E\xF7\xFF\xFF\xFF\xFF0,Q\xF8\xFF\xFF\xFF\xFF \xC5\xC7\xF8\xFF\xFF\xFF\xFF\xB0\xD2\n\xFA\xFF\xFF\xFF\xFF\xA0\xF8\xA8\xFA\xFF\xFF\xFF\xFF0\x06\xEC\xFB\xFF\xFF\xFF\xFF\xA0}\x8B\xFC\xFF\xFF\xFF\xFF0\x8E\xC9\x1D\0\0\0\0\xA0\xD7x\x1E\0\0\0\0\xB05\xA0\x1F\0\0\0\0\xA0\xCF3 \0\0\0\x000i\x81!\0\0\0\0\xA0\xC8\x0B\"\0\0\0\0\xB0\x10X#\0\0\0\0 p\xE2#\0\0\0\0\xB0\xF27%\0\0\0\0 \xC7\xD4%\0\0\0\x000y\x800\0\0\0\0\xA0M\x1D1\0\0\0\0\xB0\xC6\xF67\0\0\0\0 \x85\xB88\0\0\0\x000\xE3\xDF9\0\0\0\0 J\xF29\0\0\0\0\xB0\xFF\xC8;\0\0\0\0\xA0\x0Eo<\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x84\xDE\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x80\0\x96\0d,\x87i\xFF\xFF\xFF\xFF\xE8H-\xBD\xFF\xFF\xFF\xFF`tC\x06\0\0\0\0P>\xA4\t\0\0\0\0\xE0\xF8Q\x11\0\0\0\0Po\xD4\x11\0\0\0\0\xE0\xDA1\x13\0\0\0\0PQ\xB4\x13\0\0\0\0 \x91a)\0\0\0\0PK\xC1*\0\0\0\0\xE0\xDDC+\0\0\0\0P\xEF\xC92\0\0\0\0\xE0\xC0XB\0\0\0\0Pi?C\0\0\0\0\x80nTD\0\0\0\0`Y\x1FE\0\0\0\0\x01\x02\x03\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x1C\xAF\xFF\xFF\xFF\xFF\xFF\xFF\x18\xAF\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF-04\0\0\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xF8\0\x17\x01D\x7F\xAA\x96\xFF\xFF\xFF\xFF\xF0W\x0F\xB8\xFF\xFF\xFF\xFF\xB0N\xFD\xB8\xFF\xFF\xFF\xFF@B\xF1\xB9\xFF\xFF\xFF\xFF0\x82\xDE\xBA\xFF\xFF\xFF\xFF@\xBC8\xDA\xFF\xFF\xFF\xFF@\x08\xEC\xDA\xFF\xFF\xFF\xFF\xC0\xEF\x19\xDC\xFF\xFF\xFF\xFF0g\xB9\xDC\xFF\xFF\xFF\xFF@#\xFB\xDD\xFF\xFF\xFF\xFF0\xEC\x9B\xDE\xFF\xFF\xFF\xFF@\xA8\xDD\xDF\xFF\xFF\xFF\xFF0AT\xE0\xFF\xFF\xFF\xFF\xC0\r\x98\xF4\xFF\xFF\xFF\xFF0l\x05\xF5\xFF\xFF\xFF\xFF@r\xC0\xF6\xFF\xFF\xFF\xFF\xB0,\x0E\xF7\xFF\xFF\xFF\xFF@:Q\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF\xC0\xE0\n\xFA\xFF\xFF\xFF\xFF\xB0\x06\xA9\xFA\xFF\xFF\xFF\xFF@\x14\xEC\xFB\xFF\xFF\xFF\xFF\xB0\x8B\x8B\xFC\xFF\xFF\xFF\xFF@\x9C\xC9\x1D\0\0\0\0\xB0\xE5x\x1E\0\0\0\0\xC0C\xA0\x1F\0\0\0\0\xB0\xDD3 \0\0\0\0@w\x81!\0\0\0\0\xB0\xD6\x0B\"\0\0\0\0@\xC3\xC0,\0\0\0\x000\xD2f-\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xBC\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFFAST\0\0\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0$\0\xC4\x14\x87i\xFF\xFF\xFF\xFFD\xC8\xA3\x91\xFF\xFF\xFF\xFF@nM\x13\0\0\0\0\xB0\x164\x14\0\0\0\0\0\x01\x02\x01\xBC\xC6\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\x01CDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xF8\0\x17\x01`\xDA\xB6\xA5\xFF\xFF\xFF\xFF\0\xF1U\"\0\0\0\0\xF0\xBDj#\0\0\0\0\0vg1\0\0\0\0p\x08s2\0\0\0\0\0XG3\0\0\0\0p\xEAR4\0\0\0\0\0:'5\0\0\0\0p\xCC26\0\0\0\0\0\x1C\x077\0\0\0\0\xF0\xE8\x1B8\0\0\0\0\0\xFE\xE68\0\0\0\0\xF0\xCA\xFB9\0\0\0\0\x80\x04\xF5:\0\0\0\0\xF0\xC2\xB6;\0\0\0\0\x80\xFC\xAF<\0\0\0\0\xF0\x8E\xBB=\0\0\0\0\x80\xDE\x8F>\0\0\0\0\xF0p\x9B?\0\0\0\0\x80\xC0o@\0\0\0\0p\x8D\x84A\0\0\0\0\x80\xA2OB\0\0\0\0podC\0\0\0\0\x80\x84/D\0\0\0\0pQDE\0\0\0\0\x80f\x0FF\0\0\0\0p3$G\0\0\0\0\0\x83\xF8G\0\0\0\0p\x15\x04I\0\0\0\0\0e\xD8I\0\0\0\0p\xF7\xE3J\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x98\xA4\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFFMST\0\0\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xA8\0\xC6\0p\xE8\xB6\xA5\xFF\xFF\xFF\xFFp+\xF1\xAF\xFF\xFF\xFF\xFF`Vf\xB6\xFF\xFF\xFF\xFFp=A\xB7\xFF\xFF\xFF\xFF`6\x0C\xB8\xFF\xFF\xFF\xFF\xF0\x86\xFD\xB8\xFF\xFF\xFF\xFF`q\xEA\xCB\xFF\xFF\xFF\xFF\x10\x84g1\0\0\0\0\x80\x16s2\0\0\0\0\x10fG3\0\0\0\0\x80\xF8R4\0\0\0\0\x10H'5\0\0\0\0\x80\xDA26\0\0\0\0\x10*\x077\0\0\0\0\0\xF7\x1B8\0\0\0\0\x10\x0C\xE78\0\0\0\0\0\xD9\xFB9\0\0\0\0\x90\x12\xF5:\0\0\0\0\0\xD1\xB6;\0\0\0\0\x90\n\xB0<\0\0\0\0\0\x9D\xBB=\0\0\0\0\x01\x02\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01<\x9C\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\x01CDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xA0\x02\x18\x03cIwa\xFF\xFF\xFF\xFF\x80,\xA6\x9E\xFF\xFF\xFF\xFFp\xF9\xBA\x9F\xFF\xFF\xFF\xFF\x80\x0E\x86\xA0\xFF\xFF\xFF\xFFp\xDB\x9A\xA1\xFF\xFF\xFF\xFF\x80\xFE\x88\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\xF0\ta\xD2\xFF\xFF\xFF\xFF\0\xF3u\xD3\xFF\xFF\xFF\xFF\xF0\xEB@\xD4\xFF\xFF\xFF\xFF\x80J\x0F\xF9\xFF\xFF\xFF\xFF\xF0g\x08\xFA\xFF\xFF\xFF\xFF\0+\xB8\xFE\xFF\xFF\xFF\xFFp\xDF@\x06\0\0\0\0\x80\xED@\x06\0\0\0\0p\xD00\x07\0\0\0\0\x80'\x8D\x07\0\0\0\0p\xB2\x10\t\0\0\0\0\0\xA3\xAD\t\0\0\0\0p\x94\xF0\n\0\0\0\0\x80\x93\xE0\x0B\0\0\0\0\xF0\xB0\xD9\x0C\0\0\0\0\x80u\xC0\r\0\0\0\0\xF0\x92\xB9\x0E\0\0\0\0\0\x92\xA9\x0F\0\0\0\0\xF0t\x99\x10\0\0\0\0\0t\x89\x11\0\0\0\0\xF0Vy\x12\0\0\0\0\0Vi\x13\0\0\0\0\xF08Y\x14\0\0\0\0\08I\x15\0\0\0\0\xF0\x1A9\x16\0\0\0\0\0\x1A)\x17\0\0\0\0p7\"\x18\0\0\0\0\0\xFC\x08\x19\0\0\0\0p\x19\x02\x1A\0\0\0\0\x80\x18\xF2\x1A\0\0\0\0p\xFB\xE1\x1B\0\0\0\0\x80\xFA\xD1\x1C\0\0\0\0p\xDD\xC1\x1D\0\0\0\0\x80\xDC\xB1\x1E\0\0\0\0p\xBF\xA1\x1F\0\0\0\0\0\x0Fv \0\0\0\0p\xA1\x81!\0\0\0\0\0\xF1U\"\0\0\0\0\xF0\xBDj#\0\0\0\0\0\xD35$\0\0\0\0\xF0\x9FJ%\0\0\0\0\0\xB5\x15&\0\0\0\0\xF0\x81*'\0\0\0\0\x80\xD1\xFE'\0\0\0\0\xF0c\n)\0\0\0\0\x80\xB3\xDE)\0\0\0\0\xF0E\xEA*\0\0\0\0\x80\x95\xBE+\0\0\0\0pb\xD3,\0\0\0\0\x80w\x9E-\0\0\0\0pD\xB3.\0\0\0\0\x80Y~/\0\0\0\0p&\x930\0\0\0\0\0vg1\0\0\0\0p\x08s2\0\0\0\0\0XG3\0\0\0\0p\xEAR4\0\0\0\0\0:'5\0\0\0\0p\xCC26\0\0\0\0\0\x1C\x077\0\0\0\0\xF0\xE8\x1B8\0\0\0\0\0\xFE\xE68\0\0\0\0\xF0\xCA\xFB9\0\0\0\0\0\xE0\xC6:\0\0\0\0\xF0\xAC\xDB;\0\0\0\0\x80\xFC\xAF<\0\0\0\0\xF0\x8E\xBB=\0\0\0\0\x80\xDE\x8F>\0\0\0\0\xF0p\x9B?\0\0\0\0\x80\xC0o@\0\0\0\0p\x8D\x84A\0\0\0\0\x80\xA2OB\0\0\0\0podC\0\0\0\0\x80\x84/D\0\0\0\0pQDE\0\0\0\0\0\xB7\xF3E\0\0\0\0\xF0m-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x02\x01\x02\x01\x02\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\xDD\xAD\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x88\0\xA0\0`\xDA\xB6\xA5\xFF\xFF\xFF\xFF\0\xE6\x8A\x16\0\0\0\0p\xDA$\x18\0\0\0\0\0vg1\0\0\0\0p\x08s2\0\0\0\0\0XG3\0\0\0\0p\xEAR4\0\0\0\0\0:'5\0\0\0\0p\xCC26\0\0\0\0\0\x1C\x077\0\0\0\0\xF0\xE8\x1B8\0\0\0\0\0\xFE\xE68\0\0\0\0\xF0\xCA\xFB9\0\0\0\0\x80\x04\xF5:\0\0\0\0\xF0\xC2\xB6;\0\0\0\0\x80\xFC\xAF<\0\0\0\0\xF0\x8E\xBB=\0\0\0\0\x01\x02\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\xFC\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFFAKST\0p\x81\xFF\xFF\xFF\xFF\xFF\xFF\x01AKDT\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0X\x01\x87\x01\xD1\xFD\xC2?\xFF\xFF\xFF\xFF\x1A0\x87}\xFF\xFF\xFF\xFF\xA0\x1A\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\x10&a\xD2\xFF\xFF\xFF\xFF G\xB8\xFE\xFF\xFF\xFF\xFF\x10*\xA8\xFF\xFF\xFF\xFF\xFF )\x98\0\0\0\0\0\x10\x0C\x88\x01\0\0\0\0 \x0Bx\x02\0\0\0\0\x90(q\x03\0\0\0\0\xA0'a\x04\0\0\0\0\x90\nQ\x05\0\0\0\0\xA0\tA\x06\0\0\0\0\x90\xEC0\x07\0\0\0\0\xA0C\x8D\x07\0\0\0\0\x90\xCE\x10\t\0\0\0\0 \xBF\xAD\t\0\0\0\0\x90\xB0\xF0\n\0\0\0\0\xA0\xAF\xE0\x0B\0\0\0\0\x10\xCD\xD9\x0C\0\0\0\0\xA0\x91\xC0\r\0\0\0\0\x10\xAF\xB9\x0E\0\0\0\0 \xAE\xA9\x0F\0\0\0\0\x10\x91\x99\x10\0\0\0\0 \x90\x89\x11\0\0\0\0\x10sy\x12\0\0\0\0 ri\x13\0\0\0\0\x10UY\x14\0\0\0\0 TI\x15\0\0\0\0\x1079\x16\0\0\0\0 6)\x17\0\0\0\0\x90S\"\x18\0\0\0\0 \x18\t\x19\0\0\0\0\x905\x02\x1A\0\0\0\0\xA0\xE25V\0\0\0\x000H\xE5V\0\0\0\0 \xFF\x1EX\0\0\0\x000*\xC5X\0\0\0\0 \xE1\xFEY\0\0\0\x000\x0C\xA5Z\0\0\0\0 \xC3\xDE[\0\0\0\0\xA0FD\\\0\0\0\0\x01\x02\x03\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x05\x04\x02\x05\x04\x02\x05\x02\x05\x04&\xD6\0\0\0\0\0\0\xA6\x84\xFF\xFF\xFF\xFF\xFF\xFF\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFFp\x81\xFF\xFF\xFF\xFF\xFF\xFF\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xE0\0\t\x01p\xE8\xB6\xA5\xFF\xFF\xFF\xFFp+\xF1\xAF\xFF\xFF\xFF\xFF`Vf\xB6\xFF\xFF\xFF\xFFp=A\xB7\xFF\xFF\xFF\xFF`6\x0C\xB8\xFF\xFF\xFF\xFF\xF0\x86\xFD\xB8\xFF\xFF\xFF\xFF`\xB0\xDE\xC5\xFF\xFF\xFF\xFFP4\x97\xC6\xFF\xFF\xFF\xFF\xE0\xF1U\xC9\xFF\xFF\xFF\xFFP\xDD\xEA\xC9\xFF\xFF\xFF\xFF\xE0\xC6\x02\xCF\xFF\xFF\xFF\xFFPV\xB7\xCF\xFF\xFF\xFF\xFF\xE0\x15\x99\xDA\xFF\xFF\xFF\xFF\xD0\x83v\xDB\xFF\xFF\xFF\xFF\0vg1\0\0\0\0p\x08s2\0\0\0\0\0XG3\0\0\0\0p\xEAR4\0\0\0\0\0:'5\0\0\0\0p\xCC26\0\0\0\0\0\x1C\x077\0\0\0\0\xF0\xE8\x1B8\0\0\0\0\0\xFE\xE68\0\0\0\0\xF0\xCA\xFB9\0\0\0\0\x80\x04\xF5:\0\0\0\0\xF0\xC2\xB6;\0\0\0\0\x80\xFC\xAF<\0\0\0\0\xF0\x8E\xBB=\0\0\0\0\x01\x02\x01\x02\x03\x01\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x0C\xA3\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\x01-02\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0h\x01\x95\x01(\x17\xDF\x91\xFF\xFF\xFF\xFF\xC0cn\x13\0\0\0\0\xB0\xDB\xF9\x1F\0\0\0\0\xC0\xD6u \0\0\0\0@w\x81!\0\0\0\0\xD0\xC6U\"\0\0\0\0\xC0\x93j#\0\0\0\0\xD0\xA85$\0\0\0\0\xC0uJ%\0\0\0\0\xD0\x8A\x15&\0\0\0\0\xC0W*'\0\0\0\0P\xA7\xFE'\0\0\0\0\xC09\n)\0\0\0\0P\x89\xDE)\0\0\0\0\xC0\x1B\xEA*\0\0\0\0Pk\xBE+\0\0\0\0@8\xD3,\0\0\0\0PM\x9E-\0\0\0\0@\x1A\xB3.\0\0\0\0P/~/\0\0\0\0@\xFC\x920\0\0\0\0\xD0Kg1\0\0\0\0@\xDEr2\0\0\0\0\xD0-G3\0\0\0\0@\xC0R4\0\0\0\0\xD0\x0F'5\0\0\0\0@\xA226\0\0\0\0\xD0\xF1\x067\0\0\0\0\xC0\xBE\x1B8\0\0\0\0\xD0\xD3\xE68\0\0\0\0\xC0\xA0\xFB9\0\0\0\0\xD0\xB5\xC6:\0\0\0\0\xC0\x82\xDB;\0\0\0\0P\xD2\xAF<\0\0\0\0\xC0d\xBB=\0\0\0\0P\xB4\x8F>\0\0\0\0\xC0F\x9B?\0\0\0\0P\x96o@\0\0\0\0@c\x84A\0\0\0\0PxOB\0\0\0\0@EdC\0\0\0\0PZ/D\0\0\0\0@'DE\0\0\0\0\xD0\x8C\xF3E\0\0\0\0\xC0C-G\0\0\0\0\x01\x02\x03\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02X\xCB\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFFAST\0\0\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\x01ADT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\x98\x04+\x05\xBC\xED\x1E^\xFF\xFF\xFF\xFFP\xB6\xF1\x80\xFF\xFF\xFF\xFF`\x85\xB8\x9E\xFF\xFF\xFF\xFFP\xDD\xBA\x9F\xFF\xFF\xFF\xFF\xD08<\xBB\xFF\xFF\xFF\xFF@#\xB4\xBB\xFF\xFF\xFF\xFF\xD0\x1A\x1C\xBD\xFF\xFF\xFF\xFF@\x05\x94\xBD\xFF\xFF\xFF\xFF\xD0\xFC\xFB\xBE\xFF\xFF\xFF\xFF@\xE7s\xBF\xFF\xFF\xFF\xFF\xD0\xDE\xDB\xC0\xFF\xFF\xFF\xFF@\xC9S\xC1\xFF\xFF\xFF\xFF\xD0\xC0\xBB\xC2\xFF\xFF\xFF\xFF@\xAB3\xC3\xFF\xFF\xFF\xFF\xD0\xA2\x9B\xC4\xFF\xFF\xFF\xFF@\x8D\x13\xC5\xFF\xFF\xFF\xFF\xD0\xF8p\xC6\xFF\xFF\xFF\xFF@\xCD\r\xC7\xFF\xFF\xFF\xFF\xD0\xF1H\xC8\xFF\xFF\xFF\xFF@\xAF\xED\xC8\xFF\xFF\xFF\xFF\xD0^\x16\xCA\xFF\xFF\xFF\xFF\xC0\xCB\xD6\xCA\xFF\xFF\xFF\xFF`\xE2\x88\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\xD0\xED`\xD2\xFF\xFF\xFF\xFF\xE0\xD6u\xD3\xFF\xFF\xFF\xFF\xD0\xCF@\xD4\xFF\xFF\xFF\xFF\xE0\xB8U\xD5\xFF\xFF\xFF\xFF\xD0\xB1 \xD6\xFF\xFF\xFF\xFF\xE0\x9A5\xD7\xFF\xFF\xFF\xFF\xD0\x93\0\xD8\xFF\xFF\xFF\xFF\xE0|\x15\xD9\xFF\xFF\xFF\xFF\xD0u\xE0\xD9\xFF\xFF\xFF\xFF`\x99\xFE\xDA\xFF\xFF\xFF\xFF\xD0W\xC0\xDB\xFF\xFF\xFF\xFF`{\xDE\xDC\xFF\xFF\xFF\xFFPt\xA9\xDD\xFF\xFF\xFF\xFF`]\xBE\xDE\xFF\xFF\xFF\xFFPV\x89\xDF\xFF\xFF\xFF\xFF`?\x9E\xE0\xFF\xFF\xFF\xFFP8i\xE1\xFF\xFF\xFF\xFF`!~\xE2\xFF\xFF\xFF\xFFP\x1AI\xE3\xFF\xFF\xFF\xFF`\x03^\xE4\xFF\xFF\xFF\xFFP\xFC(\xE5\xFF\xFF\xFF\xFF\xE0\x1FG\xE6\xFF\xFF\xFF\xFF\xD0\x18\x12\xE7\xFF\xFF\xFF\xFF\xE0\x01'\xE8\xFF\xFF\xFF\xFF\xD0\xE4\x16\xE9\xFF\xFF\xFF\xFF\xE0\xE3\x06\xEA\xFF\xFF\xFF\xFF\xD0\xC6\xF6\xEA\xFF\xFF\xFF\xFF\xE0\xC5\xE6\xEB\xFF\xFF\xFF\xFF\xD0\xA8\xD6\xEC\xFF\xFF\xFF\xFF\xE0\xA7\xC6\xED\xFF\xFF\xFF\xFFP\xC5\xBF\xEE\xFF\xFF\xFF\xFF`\xC4\xAF\xEF\xFF\xFF\xFF\xFFP\xA7\x9F\xF0\xFF\xFF\xFF\xFF`\xA6\x8F\xF1\xFF\xFF\xFF\xFFP\x89\x7F\xF2\xFF\xFF\xFF\xFF`\x88o\xF3\xFF\xFF\xFF\xFFPk_\xF4\xFF\xFF\xFF\xFF`jO\xF5\xFF\xFF\xFF\xFFPM?\xF6\xFF\xFF\xFF\xFF`L/\xF7\xFF\xFF\xFF\xFF\xD0i(\xF8\xFF\xFF\xFF\xFF`.\x0F\xF9\xFF\xFF\xFF\xFF\xD0K\x08\xFA\xFF\xFF\xFF\xFF\xE0J\xF8\xFA\xFF\xFF\xFF\xFF\xD0-\xE8\xFB\xFF\xFF\xFF\xFF\xE0,\xD8\xFC\xFF\xFF\xFF\xFF\xD0\x0F\xC8\xFD\xFF\xFF\xFF\xFF\xE0\x0E\xB8\xFE\xFF\xFF\xFF\xFF\xD0\xF1\xA7\xFF\xFF\xFF\xFF\xFF\xE0\xF0\x97\0\0\0\0\0\xD0\xD3\x87\x01\0\0\0\0\xE0\xD2w\x02\0\0\0\0P\xF0p\x03\0\0\0\0`\xEF`\x04\0\0\0\0P\xD2P\x05\0\0\0\0`\xB3 \x08\0\0\0\0P\x96\x10\t\0\0\0\0`\x95\0\n\0\0\0\0Px\xF0\n\0\0\0\0`w\xE0\x0B\0\0\0\0\xD0\x94\xD9\x0C\0\0\0\0`Y\xC0\r\0\0\0\0\xD0v\xB9\x0E\0\0\0\0\xE0u\xA9\x0F\0\0\0\0\xD0X\x99\x10\0\0\0\0\xE0W\x89\x11\0\0\0\0\xD0:y\x12\0\0\0\0\xE09i\x13\0\0\0\0\xD0\x1CY\x14\0\0\0\0\xE0\x1BI\x15\0\0\0\0\xD0\xFE8\x16\0\0\0\0\xE0\xFD(\x17\0\0\0\0P\x1B\"\x18\0\0\0\0\xE0\xDF\x08\x19\0\0\0\0P\xFD\x01\x1A\0\0\0\0`\xFC\xF1\x1A\0\0\0\0P\xDF\xE1\x1B\0\0\0\0`\xDE\xD1\x1C\0\0\0\0P\xC1\xC1\x1D\0\0\0\0`\xC0\xB1\x1E\0\0\0\0P\xA3\xA1\x1F\0\0\0\0\xE0\xF2u \0\0\0\0P\x85\x81!\0\0\0\0\xE0\xD4U\"\0\0\0\0\xD0\xA1j#\0\0\0\0\xE0\xB65$\0\0\0\0\xD0\x83J%\0\0\0\0\xE0\x98\x15&\0\0\0\0\xD0e*'\0\0\0\0`\xB5\xFE'\0\0\0\0\xD0G\n)\0\0\0\0`\x97\xDE)\0\0\0\0\xD0)\xEA*\0\0\0\0|]\xBE+\0\0\0\0l*\xD3,\0\0\0\0|?\x9E-\0\0\0\0l\x0C\xB3.\0\0\0\0|!~/\0\0\0\0l\xEE\x920\0\0\0\0\xFC=g1\0\0\0\0l\xD0r2\0\0\0\0\xFC\x1FG3\0\0\0\0l\xB2R4\0\0\0\0\xFC\x01'5\0\0\0\0l\x9426\0\0\0\0\xFC\xE3\x067\0\0\0\0\xEC\xB0\x1B8\0\0\0\0\xFC\xC5\xE68\0\0\0\0\xEC\x92\xFB9\0\0\0\0\xFC\xA7\xC6:\0\0\0\0\xECt\xDB;\0\0\0\0|\xC4\xAF<\0\0\0\0\xECV\xBB=\0\0\0\0|\xA6\x8F>\0\0\0\0\xEC8\x9B?\0\0\0\0|\x88o@\0\0\0\0lU\x84A\0\0\0\0|jOB\0\0\0\0l7dC\0\0\0\0|L/D\0\0\0\0l\x19DE\0\0\0\0\xE0\x9A\xF3E\0\0\0\0\xD0Q-G\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02D\xC3\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xB0\0\xD0\0`\xDA\xB6\xA5\xFF\xFF\xFF\xFFp+\xF1\xAF\xFF\xFF\xFF\xFF`Vf\xB6\xFF\xFF\xFF\xFFp=A\xB7\xFF\xFF\xFF\xFF`6\x0C\xB8\xFF\xFF\xFF\xFF\xF0\x86\xFD\xB8\xFF\xFF\xFF\xFF\0\xF1U\"\0\0\0\0\xF0\xBDj#\0\0\0\0\0vg1\0\0\0\0p\x08s2\0\0\0\0\0XG3\0\0\0\0p\xEAR4\0\0\0\0\0:'5\0\0\0\0p\xCC26\0\0\0\0\0\x1C\x077\0\0\0\0\xF0\xE8\x1B8\0\0\0\0\0\xFE\xE68\0\0\0\0\xF0\xCA\xFB9\0\0\0\0\x80\x04\xF5:\0\0\0\0\xF0\xC2\xB6;\0\0\0\0\x80\xFC\xAF<\0\0\0\0\xF0\x8E\xBB=\0\0\0\0\x01\x02\x01\x02\x03\x01\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\xF4\xA1\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0(\x02\x82\x023\xE54\x8C\xFF\xFF\xFF\xFF\xB3\x87\x92\xA2\xFF\xFF\xFF\xFF@\xDB\xFF\xA8\xFF\xFF\xFF\xFF\xB0\x0F\xF1\xA9\xFF\xFF\xFF\xFF8Y\xE2\xAA\xFF\xFF\xFF\xFF0C\xD2\xAB\xFF\xFF\xFF\xFF\xB8\x8C\xC3\xAC\xFF\xFF\xFF\xFF\xB0v\xB3\xAD\xFF\xFF\xFF\xFF\xB8\xB5\xF4\xBB\xFF\xFF\xFF\xFF\xB0\xB5\xBF\xBC\xFF\xFF\xFF\xFF\xB8\x97\xD4\xBD\xFF\xFF\xFF\xFF\xB0\x97\x9F\xBE\xFF\xFF\xFF\xFF\xB8y\xB4\xBF\xFF\xFF\xFF\xFF\xB0y\x7F\xC0\xFF\xFF\xFF\xFF\xB8[\x94\xC1\xFF\xFF\xFF\xFF\xB0[_\xC2\xFF\xFF\xFF\xFF8x}\xC3\xFF\xFF\xFF\xFF\xB0=?\xC4\xFF\xFF\xFF\xFF8Z]\xC5\xFF\xFF\xFF\xFF\xB0\x1F\x1F\xC6\xFF\xFF\xFF\xFF8R\x18\xC7\xFF\xFF\xFF\xFF0<\x08\xC8\xFF\xFF\xFF\xFF8\x1E\x1D\xC9\xFF\xFF\xFF\xFF0\x1E\xE8\xC9\xFF\xFF\xFF\xFF8\x9F\x8B\xCA\xFF\xFF\xFF\xFF0\xC6\x1E\xCD\xFF\xFF\xFF\xFF(f\x95\xCD\xFF\xFF\xFF\xFF\xB0\x85\x0B\xEC\xFF\xFF\xFF\xFF(5\xF2\xEC\xFF\xFF\xFF\xFF\xB0JE\xED\xFF\xFF\xFF\xFF \xD6\x85\xED\xFF\xFF\xFF\xFF\xB0r\x13\xF7\xFF\xFF\xFF\xFF \x1B\xFA\xF7\xFF\xFF\xFF\xFF0>\xFE\xFC\xFF\xFF\xFF\xFF(\x11\xF6\xFD\xFF\xFF\xFF\xFF0u\x96\0\0\0\0\0 R\xD8\0\0\0\0\0\xB0\x8AW\x04\0\0\0\0\xA0:\xC6\x04\0\0\0\0\xB0\x1B\x96\x07\0\0\0\0\x98\xDA\xDF\x07\0\0\0\0(\x9F\xC6\x08\0\0\0\x000NZ\t\0\0\0\0 s\xDB\t\0\0\0\x000\x12\x1A\r\0\0\0\0\xA0\x87\x7F\r\0\0\0\x000\x7F\xE7\x0E\0\0\0\0\xA0i_\x0F\0\0\0\x000\xD6\xD9\x10\0\0\0\0\xA0K?\x11\0\0\0\0\xB0-\x89\x11\0\0\0\0\xA0\xA21\x13\0\0\0\x000T\xC3!\0\0\0\0 x'\"\0\0\0\0\xB0\xE4\xA1#\0\0\0\0\xA0\x94\x10$\0\0\0\0\xB0gJ%\0\0\0\0 <\xE7%\0\0\0\x000\x0F!'\0\0\0\0\xA0X\xD0'\0\0\0\0\xB0+\n)\0\0\0\0\xA0:\xB0)\0\0\0\x000\xD3\xE0*\0\0\0\0\xA0\x1C\x90+\0\0\0\x000\xF6LA\0\0\0\0\xC0/FB\0\0\0\0\xD0\xA3HC\0\0\0\0\xC0\x9C\x13D\0\0\0\0PK\x1FE\0\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x05\x04\x02\x05\x06\x02\x05\x06\x02\x05\x04\x02\x05\x06\x02\x05\x06\x02\x05\x07\x04\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06M\xCB\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xC8\xCE\xFF\xFF\xFF\xFF\xFF\xFF\xD8\xDC\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF\xE8\xEA\xFF\xFF\xFF\xFF\xFF\xFFEST\0\0\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\x01EDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\x80\x050\x06\x90\xF0\x03^\xFF\xFF\xFF\xFFp\x1E\xA6\x9E\xFF\xFF\xFF\xFF`\xEB\xBA\x9F\xFF\xFF\xFF\xFFp\0\x86\xA0\xFF\xFF\xFF\xFF`\xCD\x9A\xA1\xFF\xFF\xFF\xFFp\xE2e\xA2\xFF\xFF\xFF\xFF\xE0\xE9\x83\xA3\xFF\xFF\xFF\xFFp\xAEj\xA4\xFF\xFF\xFF\xFF`\xA75\xA5\xFF\xFF\xFF\xFF\xF0\xCAS\xA6\xFF\xFF\xFF\xFF`\x89\x15\xA7\xFF\xFF\xFF\xFF\xF0\xAC3\xA8\xFF\xFF\xFF\xFF\xE0\xA5\xFE\xA8\xFF\xFF\xFF\xFF\xF0\x8E\x13\xAA\xFF\xFF\xFF\xFF\xE0\x87\xDE\xAA\xFF\xFF\xFF\xFF\xF0p\xF3\xAB\xFF\xFF\xFF\xFF\xE0i\xBE\xAC\xFF\xFF\xFF\xFF\xF0R\xD3\xAD\xFF\xFF\xFF\xFF\xE0K\x9E\xAE\xFF\xFF\xFF\xFF\xF04\xB3\xAF\xFF\xFF\xFF\xFF\xE0-~\xB0\xFF\xFF\xFF\xFFpQ\x9C\xB1\xFF\xFF\xFF\xFF`Jg\xB2\xFF\xFF\xFF\xFFp3|\xB3\xFF\xFF\xFF\xFF`,G\xB4\xFF\xFF\xFF\xFFp\x15\\\xB5\xFF\xFF\xFF\xFF`\x0E'\xB6\xFF\xFF\xFF\xFFp\xF7;\xB7\xFF\xFF\xFF\xFF`\xF0\x06\xB8\xFF\xFF\xFF\xFFp\xD9\x1B\xB9\xFF\xFF\xFF\xFF`\xD2\xE6\xB9\xFF\xFF\xFF\xFF\xF0\xF5\x04\xBB\xFF\xFF\xFF\xFF`\xB4\xC6\xBB\xFF\xFF\xFF\xFF\xF0\xD7\xE4\xBC\xFF\xFF\xFF\xFF\xE0\xD0\xAF\xBD\xFF\xFF\xFF\xFF\xF0\xB9\xC4\xBE\xFF\xFF\xFF\xFF\xE0\xB2\x8F\xBF\xFF\xFF\xFF\xFF\xF0\x9B\xA4\xC0\xFF\xFF\xFF\xFF\xE0\x94o\xC1\xFF\xFF\xFF\xFF\xF0}\x84\xC2\xFF\xFF\xFF\xFF\xE0vO\xC3\xFF\xFF\xFF\xFF\xF0_d\xC4\xFF\xFF\xFF\xFF\xE0X/\xC5\xFF\xFF\xFF\xFFp|M\xC6\xFF\xFF\xFF\xFF\xE0:\x0F\xC7\xFF\xFF\xFF\xFFp^-\xC8\xFF\xFF\xFF\xFF`W\xF8\xC8\xFF\xFF\xFF\xFFp@\r\xCA\xFF\xFF\xFF\xFF`9\xD8\xCA\xFF\xFF\xFF\xFFp\xF0\x88\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\xE0\xFB`\xD2\xFF\xFF\xFF\xFF\xF0\xE4u\xD3\xFF\xFF\xFF\xFF\xE0\xDD@\xD4\xFF\xFF\xFF\xFF\xF0\xC6U\xD5\xFF\xFF\xFF\xFF\xE0\xBF \xD6\xFF\xFF\xFF\xFF\xF0\xA85\xD7\xFF\xFF\xFF\xFF\xE0\xA1\0\xD8\xFF\xFF\xFF\xFF\xF0\x8A\x15\xD9\xFF\xFF\xFF\xFF\xE0\x83\xE0\xD9\xFF\xFF\xFF\xFFp\xA7\xFE\xDA\xFF\xFF\xFF\xFF\xE0e\xC0\xDB\xFF\xFF\xFF\xFFp\x89\xDE\xDC\xFF\xFF\xFF\xFF`\x82\xA9\xDD\xFF\xFF\xFF\xFFpk\xBE\xDE\xFF\xFF\xFF\xFF`d\x89\xDF\xFF\xFF\xFF\xFFpM\x9E\xE0\xFF\xFF\xFF\xFF`Fi\xE1\xFF\xFF\xFF\xFFp/~\xE2\xFF\xFF\xFF\xFF`(I\xE3\xFF\xFF\xFF\xFFp\x11^\xE4\xFF\xFF\xFF\xFF\xE0.W\xE5\xFF\xFF\xFF\xFF\xF0-G\xE6\xFF\xFF\xFF\xFF\xE0\x107\xE7\xFF\xFF\xFF\xFF\xF0\x0F'\xE8\xFF\xFF\xFF\xFF\xE0\xF2\x16\xE9\xFF\xFF\xFF\xFF\xF0\xF1\x06\xEA\xFF\xFF\xFF\xFF\xE0\xD4\xF6\xEA\xFF\xFF\xFF\xFF\xF0\xD3\xE6\xEB\xFF\xFF\xFF\xFF\xE0\xB6\xD6\xEC\xFF\xFF\xFF\xFF\xF0\xB5\xC6\xED\xFF\xFF\xFF\xFF`\xD3\xBF\xEE\xFF\xFF\xFF\xFFp\xD2\xAF\xEF\xFF\xFF\xFF\xFF`\xB5\x9F\xF0\xFF\xFF\xFF\xFFp\xB4\x8F\xF1\xFF\xFF\xFF\xFF`\x97\x7F\xF2\xFF\xFF\xFF\xFFp\x96o\xF3\xFF\xFF\xFF\xFF`y_\xF4\xFF\xFF\xFF\xFFpxO\xF5\xFF\xFF\xFF\xFF`[?\xF6\xFF\xFF\xFF\xFFpZ/\xF7\xFF\xFF\xFF\xFF\xE0w(\xF8\xFF\xFF\xFF\xFFp<\x0F\xF9\xFF\xFF\xFF\xFF\xE0Y\x08\xFA\xFF\xFF\xFF\xFF\xF0X\xF8\xFA\xFF\xFF\xFF\xFF\xE0;\xE8\xFB\xFF\xFF\xFF\xFF\xF0:\xD8\xFC\xFF\xFF\xFF\xFF\xE0\x1D\xC8\xFD\xFF\xFF\xFF\xFF\xF0\x1C\xB8\xFE\xFF\xFF\xFF\xFF\xE0\xFF\xA7\xFF\xFF\xFF\xFF\xFF\xF0\xFE\x97\0\0\0\0\0\xE0\xE1\x87\x01\0\0\0\0\xF0\xE0w\x02\0\0\0\0`\xFEp\x03\0\0\0\0p\xFD`\x04\0\0\0\0`\xE0P\x05\0\0\0\0p\xDF@\x06\0\0\0\0`\xC20\x07\0\0\0\0p\x19\x8D\x07\0\0\0\0`\xA4\x10\t\0\0\0\0\xF0\x94\xAD\t\0\0\0\0`\x86\xF0\n\0\0\0\0p\x85\xE0\x0B\0\0\0\0\xE0\xA2\xD9\x0C\0\0\0\0pg\xC0\r\0\0\0\0\xE0\x84\xB9\x0E\0\0\0\0\xF0\x83\xA9\x0F\0\0\0\0\xE0f\x99\x10\0\0\0\0\xF0e\x89\x11\0\0\0\0\xE0Hy\x12\0\0\0\0\xF0Gi\x13\0\0\0\0\xE0*Y\x14\0\0\0\0\xF0)I\x15\0\0\0\0\xE0\x0C9\x16\0\0\0\0\xF0\x0B)\x17\0\0\0\0`)\"\x18\0\0\0\0\xF0\xED\x08\x19\0\0\0\0`\x0B\x02\x1A\0\0\0\0p\n\xF2\x1A\0\0\0\0`\xED\xE1\x1B\0\0\0\0p\xEC\xD1\x1C\0\0\0\0`\xCF\xC1\x1D\0\0\0\0p\xCE\xB1\x1E\0\0\0\0`\xB1\xA1\x1F\0\0\0\0\xF0\0v \0\0\0\0`\x93\x81!\0\0\0\0\xF0\xE2U\"\0\0\0\0\xE0\xAFj#\0\0\0\0\xF0\xC45$\0\0\0\0\xE0\x91J%\0\0\0\0\xF0\xA6\x15&\0\0\0\0\xE0s*'\0\0\0\0p\xC3\xFE'\0\0\0\0\xE0U\n)\0\0\0\0p\xA5\xDE)\0\0\0\0\xE07\xEA*\0\0\0\0p\x87\xBE+\0\0\0\0`T\xD3,\0\0\0\0pi\x9E-\0\0\0\0`6\xB3.\0\0\0\0pK~/\0\0\0\0`\x18\x930\0\0\0\0\xF0gg1\0\0\0\0`\xFAr2\0\0\0\0\xF0IG3\0\0\0\0`\xDCR4\0\0\0\0\xF0+'5\0\0\0\0`\xBE26\0\0\0\0\xF0\r\x077\0\0\0\0\xE0\xDA\x1B8\0\0\0\0\xF0\xEF\xE68\0\0\0\0\xE0\xBC\xFB9\0\0\0\0\xF0\xD1\xC6:\0\0\0\0\xE0\x9E\xDB;\0\0\0\0p\xEE\xAF<\0\0\0\0\xE0\x80\xBB=\0\0\0\0p\xD0\x8F>\0\0\0\0\xE0b\x9B?\0\0\0\0p\xB2o@\0\0\0\0`\x7F\x84A\0\0\0\0p\x94OB\0\0\0\0`adC\0\0\0\0pv/D\0\0\0\0`CDE\0\0\0\0\xF0\xA8\xF3E\0\0\0\0\xE0_-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x9E\xBA\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFFAKST\0p\x81\xFF\xFF\xFF\xFF\xFF\xFF\x01AKDT\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xA8\x02\xFD\x02\xD1\xFD\xC2?\xFF\xFF\xFF\xFF\xD2O\x87}\xFF\xFF\xFF\xFF\xD0D\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF@Pa\xD2\xFF\xFF\xFF\xFF\xB0U\xD2\xFA\xFF\xFF\xFF\xFFPq\xB8\xFE\xFF\xFF\xFF\xFF@T\xA8\xFF\xFF\xFF\xFF\xFFPS\x98\0\0\0\0\0@6\x88\x01\0\0\0\0P5x\x02\0\0\0\0\xC0Rq\x03\0\0\0\0\xD0Qa\x04\0\0\0\0\xC04Q\x05\0\0\0\0\xD03A\x06\0\0\0\0\xC0\x161\x07\0\0\0\0\xD0m\x8D\x07\0\0\0\0\xC0\xF8\x10\t\0\0\0\0P\xE9\xAD\t\0\0\0\0\xC0\xDA\xF0\n\0\0\0\0\xD0\xD9\xE0\x0B\0\0\0\0@\xF7\xD9\x0C\0\0\0\0\xD0\xBB\xC0\r\0\0\0\0@\xD9\xB9\x0E\0\0\0\0P\xD8\xA9\x0F\0\0\0\0@\xBB\x99\x10\0\0\0\0P\xBA\x89\x11\0\0\0\0@\x9Dy\x12\0\0\0\0P\x9Ci\x13\0\0\0\0@\x7FY\x14\0\0\0\0P~I\x15\0\0\0\0@a9\x16\0\0\0\0P`)\x17\0\0\0\0\xC0}\"\x18\0\0\0\0PB\t\x19\0\0\0\0\xC0_\x02\x1A\0\0\0\0\x10\x14+\x1A\0\0\0\0\xB0B\xF2\x1A\0\0\0\0\xA0%\xE2\x1B\0\0\0\0\xB0$\xD2\x1C\0\0\0\0\xA0\x07\xC2\x1D\0\0\0\0\xB0\x06\xB2\x1E\0\0\0\0\xA0\xE9\xA1\x1F\0\0\0\x0009v \0\0\0\0\xA0\xCB\x81!\0\0\0\x000\x1BV\"\0\0\0\0 \xE8j#\0\0\0\x000\xFD5$\0\0\0\0 \xCAJ%\0\0\0\x000\xDF\x15&\0\0\0\0 \xAC*'\0\0\0\0\xB0\xFB\xFE'\0\0\0\0 \x8E\n)\0\0\0\0\xB0\xDD\xDE)\0\0\0\0 p\xEA*\0\0\0\0\xB0\xBF\xBE+\0\0\0\0\xA0\x8C\xD3,\0\0\0\0\xB0\xA1\x9E-\0\0\0\0\xA0n\xB3.\0\0\0\0\xB0\x83~/\0\0\0\0\xA0P\x930\0\0\0\x000\xA0g1\0\0\0\0\xA02s2\0\0\0\x000\x82G3\0\0\0\0\xA0\x14S4\0\0\0\x000d'5\0\0\0\0\xA0\xF626\0\0\0\x000F\x077\0\0\0\0 \x13\x1C8\0\0\0\x000(\xE78\0\0\0\0 \xF5\xFB9\0\0\0\x000\n\xC7:\0\0\0\0 \xD7\xDB;\0\0\0\0\xB0&\xB0<\0\0\0\0 \xB9\xBB=\0\0\0\0\xB0\x08\x90>\0\0\0\0 \x9B\x9B?\0\0\0\0\xB0\xEAo@\0\0\0\0\xA0\xB7\x84A\0\0\0\0\xB0\xCCOB\0\0\0\0\xA0\x99dC\0\0\0\0\xB0\xAE/D\0\0\0\0\xA0{DE\0\0\0\x000\xE1\xF3E\0\0\0\0 \x98-G\0\0\0\0\x01\x02\x03\x03\x02\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04n\xB6\0\0\0\0\0\0\xEEd\xFF\xFF\xFF\xFF\xFF\xFFPe\xFF\xFF\xFF\xFF\xFF\xFF`s\xFF\xFF\xFF\xFF\xFF\xFFp\x81\xFF\xFF\xFF\xFF\xFF\xFF\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF-02\0\0\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\08\x01_\x01de\xAA\x96\xFF\xFF\xFF\xFF\xD0;\x0F\xB8\xFF\xFF\xFF\xFF\x902\xFD\xB8\xFF\xFF\xFF\xFF &\xF1\xB9\xFF\xFF\xFF\xFF\x10f\xDE\xBA\xFF\xFF\xFF\xFF \xA08\xDA\xFF\xFF\xFF\xFF \xEC\xEB\xDA\xFF\xFF\xFF\xFF\xA0\xD3\x19\xDC\xFF\xFF\xFF\xFF\x10K\xB9\xDC\xFF\xFF\xFF\xFF \x07\xFB\xDD\xFF\xFF\xFF\xFF\x10\xD0\x9B\xDE\xFF\xFF\xFF\xFF \x8C\xDD\xDF\xFF\xFF\xFF\xFF\x10%T\xE0\xFF\xFF\xFF\xFF\xA0\xF1\x97\xF4\xFF\xFF\xFF\xFF\x10P\x05\xF5\xFF\xFF\xFF\xFF V\xC0\xF6\xFF\xFF\xFF\xFF\x90\x10\x0E\xF7\xFF\xFF\xFF\xFF \x1EQ\xF8\xFF\xFF\xFF\xFF\x10\xB7\xC7\xF8\xFF\xFF\xFF\xFF\xA0\xC4\n\xFA\xFF\xFF\xFF\xFF\x90\xEA\xA8\xFA\xFF\xFF\xFF\xFF \xF8\xEB\xFB\xFF\xFF\xFF\xFF\x90o\x8B\xFC\xFF\xFF\xFF\xFF \x80\xC9\x1D\0\0\0\0\x90\xC9x\x1E\0\0\0\0\xA0'\xA0\x1F\0\0\0\0\x90\xC13 \0\0\0\0 [\x81!\0\0\0\0\x90\xBA\x0B\"\0\0\0\0\xA0\x02X#\0\0\0\0\x10b\xE2#\0\0\0\0\xA0\xE47%\0\0\0\0\x10\xB9\xD4%\0\0\0\0\xA0\xB8\xF67\0\0\0\0\x10w\xB88\0\0\0\0 \xD5\xDF9\0\0\0\0\x90\x01\xE99\0\0\0\0\xA0\xF1\xC8;\0\0\0\0\x90\0o<\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x9C\xE1\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF\xF0\xF1\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\x01CDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\0\x03a\x03\xB0\x0C\x04^\xFF\xFF\xFF\xFF\x90:\xA6\x9E\xFF\xFF\xFF\xFF\x80\x07\xBB\x9F\xFF\xFF\xFF\xFF\x90\x1C\x86\xA0\xFF\xFF\xFF\xFF\x80\xE9\x9A\xA1\xFF\xFF\xFF\xFF\x90\x0C\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\0\x18a\xD2\xFF\xFF\xFF\xFF\x10u\xF8\xFA\xFF\xFF\xFF\xFF\0X\xE8\xFB\xFF\xFF\xFF\xFF\x10W\xD8\xFC\xFF\xFF\xFF\xFF\0:\xC8\xFD\xFF\xFF\xFF\xFF\x109\xB8\xFE\xFF\xFF\xFF\xFF\0\x1C\xA8\xFF\xFF\xFF\xFF\xFF\x10\x1B\x98\0\0\0\0\0\0\xFE\x87\x01\0\0\0\0\x10\xFDw\x02\0\0\0\0\x80\x1Aq\x03\0\0\0\0\x90\x19a\x04\0\0\0\0\x80\xFCP\x05\0\0\0\0\x90\xFB@\x06\0\0\0\0\x80\xDE0\x07\0\0\0\0\x905\x8D\x07\0\0\0\0\x80\xC0\x10\t\0\0\0\0\x10\xB1\xAD\t\0\0\0\0\x80\xA2\xF0\n\0\0\0\0\x90\xA1\xE0\x0B\0\0\0\0\0\xBF\xD9\x0C\0\0\0\0\x90\x83\xC0\r\0\0\0\0\0\xA1\xB9\x0E\0\0\0\0\x10\xA0\xA9\x0F\0\0\0\0\0\x83\x99\x10\0\0\0\0\x10\x82\x89\x11\0\0\0\0\0ey\x12\0\0\0\0\x10di\x13\0\0\0\0\0GY\x14\0\0\0\0\x10FI\x15\0\0\0\0\0)9\x16\0\0\0\0\x10()\x17\0\0\0\0\x80E\"\x18\0\0\0\0\x10\n\t\x19\0\0\0\0\x80'\x02\x1A\0\0\0\0\x90&\xF2\x1A\0\0\0\0\x80\t\xE2\x1B\0\0\0\0\x90\x08\xD2\x1C\0\0\0\0\x80\xEB\xC1\x1D\0\0\0\0\x90\xEA\xB1\x1E\0\0\0\0\x80\xCD\xA1\x1F\0\0\0\0\x10\x1Dv \0\0\0\0\x80\xAF\x81!\0\0\0\0\x10\xFFU\"\0\0\0\0\0\xCCj#\0\0\0\0\x10\xE15$\0\0\0\0\0\xAEJ%\0\0\0\0\x10\xC3\x15&\0\0\0\0\0\x90*'\0\0\0\0\x90\xDF\xFE'\0\0\0\0\0r\n)\0\0\0\0\x90\xC1\xDE)\0\0\0\0\0T\xEA*\0\0\0\0\x90\xA3\xBE+\0\0\0\0\x80p\xD3,\0\0\0\0\x90\x85\x9E-\0\0\0\0\x80R\xB3.\0\0\0\0\x90g~/\0\0\0\0\x804\x930\0\0\0\0\x10\x84g1\0\0\0\0\x80\x16s2\0\0\0\0\x10fG3\0\0\0\0\x80\xF8R4\0\0\0\0\x10H'5\0\0\0\0\x80\xDA26\0\0\0\0\x10*\x077\0\0\0\0\0\xF7\x1B8\0\0\0\0\x10\x0C\xE78\0\0\0\0\0\xD9\xFB9\0\0\0\0\x10\xEE\xC6:\0\0\0\0\0\xBB\xDB;\0\0\0\0\x90\n\xB0<\0\0\0\0\0\x9D\xBB=\0\0\0\0\x90\xEC\x8F>\0\0\0\0\0\x7F\x9B?\0\0\0\0\x90\xCEo@\0\0\0\0\x80\x9B\x84A\0\0\0\0\x90\xB0OB\0\0\0\0\x80}dC\0\0\0\0\x90\x92/D\0\0\0\0\x80_DE\0\0\0\0\x10\xC5\xF3E\0\0\0\0\0|-G\0\0\0\0\x10\xA7\xD3G\0\0\0\0\0^\rI\0\0\0\0\x10\x89\xB3I\0\0\0\0\0@\xEDJ\0\0\0\0\x90\xA5\x9CK\0\0\0\0\x80\\\xD6L\0\0\0\0\x01\x02\x01\x02\x01\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x03\x95\xA0\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\x01CDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xD0\x02:\x03\xB0\x0C\x04^\xFF\xFF\xFF\xFF\x90:\xA6\x9E\xFF\xFF\xFF\xFF\x80\x07\xBB\x9F\xFF\xFF\xFF\xFF\x90\x1C\x86\xA0\xFF\xFF\xFF\xFF\x80\xE9\x9A\xA1\xFF\xFF\xFF\xFF\x90\x0C\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\0\x18a\xD2\xFF\xFF\xFF\xFF\x10u\xF8\xFA\xFF\xFF\xFF\xFF\0X\xE8\xFB\xFF\xFF\xFF\xFF\x10W\xD8\xFC\xFF\xFF\xFF\xFF\0:\xC8\xFD\xFF\xFF\xFF\xFF\x109\xB8\xFE\xFF\xFF\xFF\xFF\0\x1C\xA8\xFF\xFF\xFF\xFF\xFF\x10\x1B\x98\0\0\0\0\0\0\xFE\x87\x01\0\0\0\0\x10\xFDw\x02\0\0\0\0\x80\x1Aq\x03\0\0\0\0\x90\x19a\x04\0\0\0\0\x80\xFCP\x05\0\0\0\0\x90\xFB@\x06\0\0\0\0\x80\xDE0\x07\0\0\0\0\x905\x8D\x07\0\0\0\0\x80\xC0\x10\t\0\0\0\0\x10\xB1\xAD\t\0\0\0\0\x80\xA2\xF0\n\0\0\0\0\x90\xA1\xE0\x0B\0\0\0\0\0\xBF\xD9\x0C\0\0\0\0\x90\x83\xC0\r\0\0\0\0\0\xA1\xB9\x0E\0\0\0\0\x10\xA0\xA9\x0F\0\0\0\0\0\x83\x99\x10\0\0\0\0\x10\x82\x89\x11\0\0\0\0\0ey\x12\0\0\0\0\x10di\x13\0\0\0\0\0GY\x14\0\0\0\0\x10FI\x15\0\0\0\0\0)9\x16\0\0\0\0\x10()\x17\0\0\0\0\x80E\"\x18\0\0\0\0\x10\n\t\x19\0\0\0\0\x80'\x02\x1A\0\0\0\0\x90&\xF2\x1A\0\0\0\0\x80\t\xE2\x1B\0\0\0\0\x90\x08\xD2\x1C\0\0\0\0\x80\xEB\xC1\x1D\0\0\0\0\x90\xEA\xB1\x1E\0\0\0\0\x80\xCD\xA1\x1F\0\0\0\0\x10\x1Dv \0\0\0\0\x80\xAF\x81!\0\0\0\0\x10\xFFU\"\0\0\0\0\0\xCCj#\0\0\0\0\x10\xE15$\0\0\0\0\0\xAEJ%\0\0\0\0\x10\xC3\x15&\0\0\0\0\0\x90*'\0\0\0\0\x90\xDF\xFE'\0\0\0\0\0r\n)\0\0\0\0\x90\xC1\xDE)\0\0\0\0\0T\xEA*\0\0\0\0\x80\x95\xBE+\0\0\0\0pb\xD3,\0\0\0\0\x80w\x9E-\0\0\0\0pD\xB3.\0\0\0\0\x80Y~/\0\0\0\0p&\x930\0\0\0\0\0vg1\0\0\0\0p\x08s2\0\0\0\0\0XG3\0\0\0\0p\xEAR4\0\0\0\0\0:'5\0\0\0\0p\xCC26\0\0\0\0\0\x1C\x077\0\0\0\0\xF0\xE8\x1B8\0\0\0\0\0\xFE\xE68\0\0\0\0\xF0\xCA\xFB9\0\0\0\0\0\xE0\xC6:\0\0\0\0\xF0\xAC\xDB;\0\0\0\0\x80\xFC\xAF<\0\0\0\0\xF0\x8E\xBB=\0\0\0\0\x80\xDE\x8F>\0\0\0\0\xF0p\x9B?\0\0\0\0\x80\xC0o@\0\0\0\0p\x8D\x84A\0\0\0\0\x80\xA2OB\0\0\0\0podC\0\0\0\0\x80\x84/D\0\0\0\0pQDE\0\0\0\0\0\xB7\xF3E\0\0\0\0\xF0m-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x08\xA1\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\x01CDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xD0\x02/\x03\xB0\x0C\x04^\xFF\xFF\xFF\xFF\x90:\xA6\x9E\xFF\xFF\xFF\xFF\x80\x07\xBB\x9F\xFF\xFF\xFF\xFF\x90\x1C\x86\xA0\xFF\xFF\xFF\xFF\x80\xE9\x9A\xA1\xFF\xFF\xFF\xFF\x90\x0C\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\0\x18a\xD2\xFF\xFF\xFF\xFF\x10u\xF8\xFA\xFF\xFF\xFF\xFF\0X\xE8\xFB\xFF\xFF\xFF\xFF\x10W\xD8\xFC\xFF\xFF\xFF\xFF\0:\xC8\xFD\xFF\xFF\xFF\xFF\x109\xB8\xFE\xFF\xFF\xFF\xFF\0\x1C\xA8\xFF\xFF\xFF\xFF\xFF\x10\x1B\x98\0\0\0\0\0\0\xFE\x87\x01\0\0\0\0\x10\xFDw\x02\0\0\0\0\x80\x1Aq\x03\0\0\0\0\x90\x19a\x04\0\0\0\0\x80\xFCP\x05\0\0\0\0\x90\xFB@\x06\0\0\0\0\x80\xDE0\x07\0\0\0\0\x905\x8D\x07\0\0\0\0\x80\xC0\x10\t\0\0\0\0\x10\xB1\xAD\t\0\0\0\0\x80\xA2\xF0\n\0\0\0\0\x90\xA1\xE0\x0B\0\0\0\0\0\xBF\xD9\x0C\0\0\0\0\x90\x83\xC0\r\0\0\0\0\0\xA1\xB9\x0E\0\0\0\0\x10\xA0\xA9\x0F\0\0\0\0\0\x83\x99\x10\0\0\0\0\x10\x82\x89\x11\0\0\0\0\0ey\x12\0\0\0\0\x10di\x13\0\0\0\0\0GY\x14\0\0\0\0\x10FI\x15\0\0\0\0\0)9\x16\0\0\0\0\x10()\x17\0\0\0\0\x80E\"\x18\0\0\0\0\x10\n\t\x19\0\0\0\0\x80'\x02\x1A\0\0\0\0\x90&\xF2\x1A\0\0\0\0\x80\t\xE2\x1B\0\0\0\0\x90\x08\xD2\x1C\0\0\0\0\x80\xEB\xC1\x1D\0\0\0\0\x90\xEA\xB1\x1E\0\0\0\0\x80\xCD\xA1\x1F\0\0\0\0\x10\x1Dv \0\0\0\0\x80\xAF\x81!\0\0\0\0\x10\xFFU\"\0\0\0\0\0\xCCj#\0\0\0\0\x10\xE15$\0\0\0\0\0\xAEJ%\0\0\0\0\x10\xC3\x15&\0\0\0\0\0\x90*'\0\0\0\0\x90\xDF\xFE'\0\0\0\0\0r\n)\0\0\0\0\x90\xC1\xDE)\0\0\0\0\0T\xEA*\0\0\0\0\x90\xA3\xBE+\0\0\0\0\x80p\xD3,\0\0\0\0\x90\x85\x9E-\0\0\0\0\x80R\xB3.\0\0\0\0\x90g~/\0\0\0\0\x804\x930\0\0\0\0\x10\x84g1\0\0\0\0\x80\x16s2\0\0\0\0\x10fG3\0\0\0\0\x80\xF8R4\0\0\0\0\x10H'5\0\0\0\0\x80\xDA26\0\0\0\0\x10*\x077\0\0\0\0\0\xF7\x1B8\0\0\0\0\x10\x0C\xE78\0\0\0\0\0\xD9\xFB9\0\0\0\0\x10\xEE\xC6:\0\0\0\0\0\xBB\xDB;\0\0\0\0\x90\n\xB0<\0\0\0\0\0\x9D\xBB=\0\0\0\0\x90\xEC\x8F>\0\0\0\0\0\x7F\x9B?\0\0\0\0\x80\xC0o@\0\0\0\0p\x8D\x84A\0\0\0\0\x80\xA2OB\0\0\0\0podC\0\0\0\0\x80\x84/D\0\0\0\0pQDE\0\0\0\0\0\xB7\xF3E\0\0\0\0\xF0m-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\xED\xA0\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF-02\0\0\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF\x01-01\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0\xF0\xF1\xFF\xFF\xFF\xFF\xFF\xFF\x02\0\0\0\x01\n\x05\0\0\0\0\0\0\0\0\0\xC0\x02\x19\x03\0h\x80\x9B\xFF\xFF\xFF\xFFP|M\x13\0\0\0\0\x90\xFA3\x14\0\0\0\0\x90\xEB#\x15\0\0\0\0\x90\xDC\x13\x16\0\0\0\0\x90\xCD\x03\x17\0\0\0\0\x90\xBE\xF3\x17\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x10\xBB=3\0\0\0\0\x10\x96R4\0\0\0\0\x10\x9D\x1D5\0\0\0\0\x10x26\0\0\0\0\x10\x7F\xFD6\0\0\0\0\x90\x94\x1B8\0\0\0\0\x10a\xDD8\0\0\0\0\x90v\xFB9\0\0\0\0\x10C\xBD:\0\0\0\0\x90X\xDB;\0\0\0\0\x90_\xA6<\0\0\0\0\x90:\xBB=\0\0\0\0\x90A\x86>\0\0\0\0\x90\x1C\x9B?\0\0\0\0\x90#f@\0\0\0\0\x109\x84A\0\0\0\0\x90\x05FB\0\0\0\0\x10\x1BdC\0\0\0\0\x90\xE7%D\0\0\0\0\x10\xFDCE\0\0\0\0\x90\xC9\x05F\0\0\0\0\x10\xDF#G\0\0\0\0\x10\xE6\xEEG\0\0\0\0\x10\xC1\x03I\0\0\0\0\x10\xC8\xCEI\0\0\0\0\x10\xA3\xE3J\0\0\0\0\x10\xAA\xAEK\0\0\0\0\x90\xBF\xCCL\0\0\0\0\x10\x8C\x8EM\0\0\0\0\x90\xA1\xACN\0\0\0\0\x10nnO\0\0\0\0\x90\x83\x8CP\0\0\0\0\x90\x8AWQ\0\0\0\0\x90elR\0\0\0\0\x90l7S\0\0\0\0\x90GLT\0\0\0\0\x90N\x17U\0\0\0\0\x90),V\0\0\0\0\x900\xF7V\0\0\0\0\x10F\x15X\0\0\0\0\x90\x12\xD7X\0\0\0\0\x10(\xF5Y\0\0\0\0\x90\xF4\xB6Z\0\0\0\0\x10\n\xD5[\0\0\0\0\x10\x11\xA0\\\0\0\0\0\x10\xEC\xB4]\0\0\0\0\x10\xF3\x7F^\0\0\0\0\x10\xCE\x94_\0\0\0\0\x10\xD5_`\0\0\0\0\x90\xEA}a\0\0\0\0\x10\xB7?b\0\0\0\0\x90\xCC]c\0\0\0\0\x10\x99\x1Fd\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x80\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\x01CDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xE0\x01:\x02p\xE8\xB6\xA5\xFF\xFF\xFF\xFFp+\xF1\xAF\xFF\xFF\xFF\xFF`Vf\xB6\xFF\xFF\xFF\xFFp=A\xB7\xFF\xFF\xFF\xFF`6\x0C\xB8\xFF\xFF\xFF\xFF\xF0\x86\xFD\xB8\xFF\xFF\xFF\xFF\0vg1\0\0\0\0p\x08s2\0\0\0\0\0XG3\0\0\0\0p\xEAR4\0\0\0\0\x10H'5\0\0\0\0\x80\xDA26\0\0\0\0\x10*\x077\0\0\0\0\0\xF7\x1B8\0\0\0\0\x10\x0C\xE78\0\0\0\0\0\xD9\xFB9\0\0\0\0\x90\x12\xF5:\0\0\0\0\0\xD1\xB6;\0\0\0\0\x90\n\xB0<\0\0\0\0\0\x9D\xBB=\0\0\0\0\x90\xEC\x8F>\0\0\0\0\0\x7F\x9B?\0\0\0\0\x90\xCEo@\0\0\0\0\x80\x9B\x84A\0\0\0\0\x90\xB0OB\0\0\0\0\x80}dC\0\0\0\0\x90\x92/D\0\0\0\0\x80_DE\0\0\0\0\x90t\x0FF\0\0\0\0\x80A$G\0\0\0\0\x10\x91\xF8G\0\0\0\0\x80#\x04I\0\0\0\0\x10s\xD8I\0\0\0\0\x80\x05\xE4J\0\0\0\0\x90\xA5\x9CK\0\0\0\0\x80\\\xD6L\0\0\0\0\x90\x87|M\0\0\0\0\x80>\xB6N\0\0\0\0\x90i\\O\0\0\0\0\x80 \x96P\0\0\0\0\x90K\x05\0\0\0\0\xB0\r\0\x06\0\0\0\0@\xBC\x0B\x07\0\0\0\0\xB0\xEF\xDF\x07\0\0\0\0@\x13\xFE\x08\0\0\0\0\xB0\xD1\xBF\t\0\0\0\0@\xF5\xDD\n\0\0\0\x000\xEE\xA8\x0B\0\0\0\0@\xD7\xBD\x0C\0\0\0\x000\xD0\x88\r\0\0\0\0@\xB9\x9D\x0E\0\0\0\x000\xB2h\x0F\0\0\0\0\xC0\xD5\x86\x10\0\0\0\x000\x94H\x11\0\0\0\0\xC0\xB7f\x12\0\0\0\x000v(\x13\0\0\0\0\xC0\x99F\x14\0\0\0\0\xB0\x92\x11\x15\0\0\0\0\xC0{&\x16\0\0\0\0\xB0t\xF1\x16\0\0\0\0\xC0]\x06\x18\0\0\0\0\xB0V\xD1\x18\0\0\0\0\xC0?\xE6\x19\0\0\0\0\xB08\xB1\x1A\0\0\0\0@\\\xCF\x1B\0\0\0\0\xB0\x1A\x91\x1C\0\0\0\0@>\xAF\x1D\0\0\0\0\xB0\xFCp\x1E\0\0\0\0@ \x8F\x1F\0\0\0\x000\x03\x7F \0\0\0\0@\x02o!\0\0\0\x000\xFB9\"\0\0\0\0@\xE4N#\0\0\0\x000\xDD\x19$\0\0\0\0\xC0\08%\0\0\0\x000\xBF\xF9%\0\0\0\0\xC0\xF8\xF2&\0\0\0\x000\xA1\xD9'\0\0\0\0\xC0\xC4\xF7(\0\0\0\0\xB0\xBD\xC2)\0\0\0\0\xC0\xA6\xD7*\0\0\0\0\xB0\x9F\xA2+\0\0\0\0\xC0\x88\xB7,\0\0\0\0\xB0\x81\x82-\0\0\0\0\xC0j\x97.\0\0\0\0\xB0cb/\0\0\0\0@\x87\x800\0\0\0\0\xB0EB1\0\0\0\0@i`2\0\0\0\x000\xD7=3\0\0\0\0@K@4\0\0\0\x000D\x0B5\0\0\0\0@\xB8\r6\0\0\0\0\xB0\xD5\x067\0\0\0\0@\x0F\08\0\0\0\x000\x08\xCB8\0\0\0\0\xC0+\xE99\0\0\0\x000\xEA\xAA:\0\0\0\0\xC0\r\xC9;\0\0\0\x000\xCC\x8A<\0\0\0\0\xC0\xEF\xA8=\0\0\0\x000\xAEj>\0\0\0\0\xC0\xD1\x88?\0\0\0\0\xB0\xCAS@\0\0\0\0\xC0\xB3hA\0\0\0\0\xB0\xAC3B\0\0\0\0\xC0\x95HC\0\0\0\0\xB0\x8E\x13D\0\0\0\0@\xB21E\0\0\0\0\xB0p\xF3E\0\0\0\0@\x94\x11G\0\0\0\x000\x02\xEFG\0\0\0\0@v\xF1H\0\0\0\x000o\xBCI\0\0\0\0@X\xD1J\0\0\0\0\xB0\0\xB8K\0\0\0\0@:\xB1L\0\0\0\x000\x07\xC6M\0\0\0\0\xC0\x82PN\0\0\0\0\xB0\xAE\x9CO\0\0\0\0\xC0\xD9BP\0\0\0\0\xB0\x90|Q\0\0\0\0@\xF6+R\0\0\0\0\xB0r\\S\0\0\0\0@\xD8\x0BT\0\0\0\x000\xE67W\0\0\0\0\xC0\xEC\xAFW\0\0\0\0\xB0\x86CX\0\0\0\0\x01\x02\x01\x03\x01\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x03\x04\x02\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x05\x06\x84\xBD\xFF\xFF\xFF\xFF\xFF\xFF\xBB\xBD\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\x01CDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0H\x02\x99\x02\0n\x8C\xE7\xFF\xFF\xFF\xFF\x80\x0Ba\x04\0\0\0\0p\xEEP\x05\0\0\0\0\x80\xED@\x06\0\0\0\0p\xD00\x07\0\0\0\0\x80\xCF \x08\0\0\0\0p\xB2\x10\t\0\0\0\0\x80\xB1\0\n\0\0\0\0p\x94\xF0\n\0\0\0\0\x80\x93\xE0\x0B\0\0\0\0\xF0\xB0\xD9\x0C\0\0\0\0\x80u\xC0\r\0\0\0\0\xF0\x92\xB9\x0E\0\0\0\0\0\x92\xA9\x0F\0\0\0\0\xF0t\x99\x10\0\0\0\0\0t\x89\x11\0\0\0\0\xF0Vy\x12\0\0\0\0\0Vi\x13\0\0\0\0\xF08Y\x14\0\0\0\0\08I\x15\0\0\0\0\xF0\x1A9\x16\0\0\0\0\0\x1A)\x17\0\0\0\0p7\"\x18\0\0\0\0\0\xFC\x08\x19\0\0\0\0p\x19\x02\x1A\0\0\0\0\x80\x18\xF2\x1A\0\0\0\0p\xFB\xE1\x1B\0\0\0\0\x80\xFA\xD1\x1C\0\0\0\0p\xDD\xC1\x1D\0\0\0\0\x80\xDC\xB1\x1E\0\0\0\0p\xBF\xA1\x1F\0\0\0\0\0\x0Fv \0\0\0\0p\xA1\x81!\0\0\0\0\0\xF1U\"\0\0\0\0\xF0\xBDj#\0\0\0\0\0\xD35$\0\0\0\0\xF0\x9FJ%\0\0\0\0\0\xB5\x15&\0\0\0\0\xF0\x81*'\0\0\0\0\x80\xD1\xFE'\0\0\0\0\xF0c\n)\0\0\0\0\x80\xB3\xDE)\0\0\0\0\xF0E\xEA*\0\0\0\0\x80\x95\xBE+\0\0\0\0pb\xD3,\0\0\0\0\x80w\x9E-\0\0\0\0pD\xB3.\0\0\0\0\x80Y~/\0\0\0\0p&\x930\0\0\0\0\0vg1\0\0\0\0p\x08s2\0\0\0\0\0XG3\0\0\0\0p\xEAR4\0\0\0\0\0:'5\0\0\0\0p\xCC26\0\0\0\0\0\x1C\x077\0\0\0\0\xF0\xE8\x1B8\0\0\0\0\0\xFE\xE68\0\0\0\0\xF0\xCA\xFB9\0\0\0\0\0\xE0\xC6:\0\0\0\0\xF0\xAC\xDB;\0\0\0\0\x80\xFC\xAF<\0\0\0\0\xF0\x8E\xBB=\0\0\0\0\x80\xDE\x8F>\0\0\0\0\xF0p\x9B?\0\0\0\0\x80\xC0o@\0\0\0\0p\x8D\x84A\0\0\0\0\x80\xA2OB\0\0\0\0podC\0\0\0\0\x80\x84/D\0\0\0\0pQDE\0\0\0\0\0\xB7\xF3E\0\0\0\0\xF0m-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x03\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\0\0\0\0\0\0\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\08\x01_\x01\xB8g\xAA\x96\xFF\xFF\xFF\xFF\xE0I\x0F\xB8\xFF\xFF\xFF\xFF\xA0@\xFD\xB8\xFF\xFF\xFF\xFF04\xF1\xB9\xFF\xFF\xFF\xFF t\xDE\xBA\xFF\xFF\xFF\xFF0\xAE8\xDA\xFF\xFF\xFF\xFF0\xFA\xEB\xDA\xFF\xFF\xFF\xFF\xB0\xE1\x19\xDC\xFF\xFF\xFF\xFF Y\xB9\xDC\xFF\xFF\xFF\xFF0\x15\xFB\xDD\xFF\xFF\xFF\xFF \xDE\x9B\xDE\xFF\xFF\xFF\xFF0\x9A\xDD\xDF\xFF\xFF\xFF\xFF 3T\xE0\xFF\xFF\xFF\xFF\xB0\xFF\x97\xF4\xFF\xFF\xFF\xFF ^\x05\xF5\xFF\xFF\xFF\xFF0d\xC0\xF6\xFF\xFF\xFF\xFF\xA0\x1E\x0E\xF7\xFF\xFF\xFF\xFF0,Q\xF8\xFF\xFF\xFF\xFF \xC5\xC7\xF8\xFF\xFF\xFF\xFF\xB0\xD2\n\xFA\xFF\xFF\xFF\xFF\xA0\xF8\xA8\xFA\xFF\xFF\xFF\xFF0\x06\xEC\xFB\xFF\xFF\xFF\xFF\xA0}\x8B\xFC\xFF\xFF\xFF\xFF0\x8E\xC9\x1D\0\0\0\0\xA0\xD7x\x1E\0\0\0\0\xB05\xA0\x1F\0\0\0\0\xA0\xCF3 \0\0\0\x000i\x81!\0\0\0\0\xA0\xC8\x0B\"\0\0\0\0\xB0\x10X#\0\0\0\0 p\xE2#\0\0\0\0\xB0\xF27%\0\0\0\0 \xC7\xD4%\0\0\0\0\xB0\xC6\xF67\0\0\0\0 \x85\xB88\0\0\0\x000\xE3\xDF9\0\0\0\0\xA0\x0F\xE99\0\0\0\0\xB0\xFF\xC8;\0\0\0\0\xA0\x0Eo<\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01H\xDF\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xA8\x01\xDE\x01\x1C\x93\xFD\x86\xFF\xFF\xFF\xFF\x90\xAF\xB8\x9E\xFF\xFF\xFF\xFF\x80\x07\xBB\x9F\xFF\xFF\xFF\xFF\xF0Oe\xB5\xFF\xFF\xFF\xFF\xE0H0\xB6\xFF\xFF\xFF\xFF\xF01E\xB7\xFF\xFF\xFF\xFF\xE0*\x10\xB8\xFF\xFF\xFF\xFF\xF0\x13%\xB9\xFF\xFF\xFF\xFF\xE0\x0C\xF0\xB9\xFF\xFF\xFF\xFFp0\x0E\xBB\xFF\xFF\xFF\xFF\xE0\xEE\xCF\xBB\xFF\xFF\xFF\xFFp\x12\xEE\xBC\xFF\xFF\xFF\xFF`\x0B\xB9\xBD\xFF\xFF\xFF\xFF\xF0\x08r\xC2\xFF\xFF\xFF\xFF\xE0\xEBa\xC3\xFF\xFF\xFF\xFF\xF0\xEAQ\xC4\xFF\xFF\xFF\xFF`\x938\xC5\xFF\xFF\xFF\xFF\xF0\xCC1\xC6\xFF\xFF\xFF\xFF\xE0\xAF!\xC7\xFF\xFF\xFF\xFFp\xE9\x1A\xC8\xFF\xFF\xFF\xFF`\xCC\n\xC9\xFF\xFF\xFF\xFFp\xCB\xFA\xC9\xFF\xFF\xFF\xFF`\xAE\xEA\xCA\xFF\xFF\xFF\xFF\x90\x0C\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\0\x18a\xD2\xFF\xFF\xFF\xFF\x10\x8Cc\xD3\xFF\xFF\xFF\xFF\0oS\xD4\xFF\xFF\xFF\xFF\x10\xE3U\xD5\xFF\xFF\xFF\xFF\0\xDC \xD6\xFF\xFF\xFF\xFF\x10\xC55\xD7\xFF\xFF\xFF\xFF\0\xBE\0\xD8\xFF\xFF\xFF\xFF\x10\xA7\x15\xD9\xFF\xFF\xFF\xFF\0\xA0\xE0\xD9\xFF\xFF\xFF\xFF\x90\xC3\xFE\xDA\xFF\xFF\xFF\xFF\0\x82\xC0\xDB\xFF\xFF\xFF\xFF\x90\xA5\xDE\xDC\xFF\xFF\xFF\xFF\x80\x9E\xA9\xDD\xFF\xFF\xFF\xFF\x90\x87\xBE\xDE\xFF\xFF\xFF\xFF\x80\x80\x89\xDF\xFF\xFF\xFF\xFF\x90i\x9E\xE0\xFF\xFF\xFF\xFF\x80bi\xE1\xFF\xFF\xFF\xFF\x90K~\xE2\xFF\xFF\xFF\xFF\x80DI\xE3\xFF\xFF\xFF\xFF\x90-^\xE4\xFF\xFF\xFF\xFF\x80&)\xE5\xFF\xFF\xFF\xFF\x10JG\xE6\xFF\xFF\xFF\xFF\0C\x12\xE7\xFF\xFF\xFF\xFF\x10,'\xE8\xFF\xFF\xFF\xFF\0%\xF2\xE8\xFF\xFF\xFF\xFF\x10\xF0\xE6\xEB\xFF\xFF\xFF\xFF\0\xD3\xD6\xEC\xFF\xFF\xFF\xFF\x10\xD2\xC6\xED\xFF\xFF\xFF\xFF\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\xE4\x9D\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\x01CDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0H\x02\x9A\x02\x80\x81\xFB\xD5\xFF\xFF\xFF\xFF\x80\x0Ba\x04\0\0\0\0p\xEEP\x05\0\0\0\0\x80\xED@\x06\0\0\0\0p\xD00\x07\0\0\0\0\x80\xCF \x08\0\0\0\0p\xB2\x10\t\0\0\0\0\x80\xB1\0\n\0\0\0\0p\x94\xF0\n\0\0\0\0\x80\x93\xE0\x0B\0\0\0\0\xF0\xB0\xD9\x0C\0\0\0\0\x80u\xC0\r\0\0\0\0\xF0\x92\xB9\x0E\0\0\0\0\0\x92\xA9\x0F\0\0\0\0\xF0t\x99\x10\0\0\0\0\0t\x89\x11\0\0\0\0\xF0Vy\x12\0\0\0\0\0Vi\x13\0\0\0\0\xF08Y\x14\0\0\0\0\08I\x15\0\0\0\0\xF0\x1A9\x16\0\0\0\0\0\x1A)\x17\0\0\0\0p7\"\x18\0\0\0\0\0\xFC\x08\x19\0\0\0\0p\x19\x02\x1A\0\0\0\0\x80\x18\xF2\x1A\0\0\0\0p\xFB\xE1\x1B\0\0\0\0\x80\xFA\xD1\x1C\0\0\0\0p\xDD\xC1\x1D\0\0\0\0\x80\xDC\xB1\x1E\0\0\0\0p\xBF\xA1\x1F\0\0\0\0\0\x0Fv \0\0\0\0p\xA1\x81!\0\0\0\0\0\xF1U\"\0\0\0\0\xF0\xBDj#\0\0\0\0\0\xD35$\0\0\0\0\xF0\x9FJ%\0\0\0\0\0\xB5\x15&\0\0\0\0\xF0\x81*'\0\0\0\0\x80\xD1\xFE'\0\0\0\0\xF0c\n)\0\0\0\0\x80\xB3\xDE)\0\0\0\0\xF0E\xEA*\0\0\0\0\x80\x95\xBE+\0\0\0\0pb\xD3,\0\0\0\0\x80w\x9E-\0\0\0\0pD\xB3.\0\0\0\0\x80Y~/\0\0\0\0p&\x930\0\0\0\0\0vg1\0\0\0\0p\x08s2\0\0\0\0\0XG3\0\0\0\0p\xEAR4\0\0\0\0\0:'5\0\0\0\0p\xCC26\0\0\0\0\0\x1C\x077\0\0\0\0\xF0\xE8\x1B8\0\0\0\0\0\xFE\xE68\0\0\0\0\xF0\xCA\xFB9\0\0\0\0\0\xE0\xC6:\0\0\0\0\xF0\xAC\xDB;\0\0\0\0\x80\xFC\xAF<\0\0\0\0\xF0\x8E\xBB=\0\0\0\0\x80\xDE\x8F>\0\0\0\0\xF0p\x9B?\0\0\0\0\x80\xC0o@\0\0\0\0p\x8D\x84A\0\0\0\0\x80\xA2OB\0\0\0\0podC\0\0\0\0\x80\x84/D\0\0\0\0pQDE\0\0\0\0\0\xB7\xF3E\0\0\0\0\xF0m-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x03\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x02\x03\x02\x03\x01\0\0\0\0\0\0\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF-05\0\0\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xF8\0\x18\x01\x90\x86\xAA\x96\xFF\xFF\xFF\xFF\0f\x0F\xB8\xFF\xFF\xFF\xFF\xC0\\\xFD\xB8\xFF\xFF\xFF\xFFPP\xF1\xB9\xFF\xFF\xFF\xFF@\x90\xDE\xBA\xFF\xFF\xFF\xFFP\xCA8\xDA\xFF\xFF\xFF\xFFP\x16\xEC\xDA\xFF\xFF\xFF\xFF\xD0\xFD\x19\xDC\xFF\xFF\xFF\xFF@u\xB9\xDC\xFF\xFF\xFF\xFFP1\xFB\xDD\xFF\xFF\xFF\xFF@\xFA\x9B\xDE\xFF\xFF\xFF\xFFP\xB6\xDD\xDF\xFF\xFF\xFF\xFF@OT\xE0\xFF\xFF\xFF\xFF\xD0\x1B\x98\xF4\xFF\xFF\xFF\xFF@z\x05\xF5\xFF\xFF\xFF\xFFP\x80\xC0\xF6\xFF\xFF\xFF\xFF\xC0:\x0E\xF7\xFF\xFF\xFF\xFFPHQ\xF8\xFF\xFF\xFF\xFF@\xE1\xC7\xF8\xFF\xFF\xFF\xFF\xD0\xEE\n\xFA\xFF\xFF\xFF\xFF\xC0\x14\xA9\xFA\xFF\xFF\xFF\xFFP\"\xEC\xFB\xFF\xFF\xFF\xFF\xC0\x99\x8B\xFC\xFF\xFF\xFF\xFFP\xAA\xC9\x1D\0\0\0\0\xC0\xF3x\x1E\0\0\0\0\xD0Q\xA0\x1F\0\0\0\0\xC0\xEB3 \0\0\0\0P\x85\x81!\0\0\0\0\xC0\xE4\x0B\"\0\0\0\0P\x7F`H\0\0\0\0\xC0\x04\x7FR\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x01p\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xF0\0\x0F\x01Hz\xAA\x96\xFF\xFF\xFF\xFF\xF0W\x0F\xB8\xFF\xFF\xFF\xFF\xB0N\xFD\xB8\xFF\xFF\xFF\xFF@B\xF1\xB9\xFF\xFF\xFF\xFF0\x82\xDE\xBA\xFF\xFF\xFF\xFF@\xBC8\xDA\xFF\xFF\xFF\xFF@\x08\xEC\xDA\xFF\xFF\xFF\xFF\xC0\xEF\x19\xDC\xFF\xFF\xFF\xFF0g\xB9\xDC\xFF\xFF\xFF\xFF@#\xFB\xDD\xFF\xFF\xFF\xFF0\xEC\x9B\xDE\xFF\xFF\xFF\xFF@\xA8\xDD\xDF\xFF\xFF\xFF\xFF0AT\xE0\xFF\xFF\xFF\xFF\xC0\r\x98\xF4\xFF\xFF\xFF\xFF0l\x05\xF5\xFF\xFF\xFF\xFF@r\xC0\xF6\xFF\xFF\xFF\xFF\xB0,\x0E\xF7\xFF\xFF\xFF\xFF@:Q\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF\xC0\xE0\n\xFA\xFF\xFF\xFF\xFF\xB0\x06\xA9\xFA\xFF\xFF\xFF\xFF@\x14\xEC\xFB\xFF\xFF\xFF\xFF\xB0\x8B\x8B\xFC\xFF\xFF\xFF\xFF@\x9C\xC9\x1D\0\0\0\0\xB0\xE5x\x1E\0\0\0\0\xC0C\xA0\x1F\0\0\0\0\xB0\xDD3 \0\0\0\0@w\x81!\0\0\0\0\xB0\xD6\x0B\"\0\0\0\0@q`H\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\xB8\xCC\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF-04\0\0\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\x01-03\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\t\x01\0\0\0\0\0\0\0\0\0\x02\0\0\0\x01\x04\x01\0\0\0\0\0\0\0\0\0 \x04\xE3\x04\xC5\x1D\x87i\xFF\xFF\xFF\xFFEG0\x8F\xFF\xFF\xFF\xFFP\xE5\\\x9B\xFF\xFF\xFF\xFF\xC5\xE2|\x9F\xFF\xFF\xFF\xFF\xC0q\0\xA1\xFF\xFF\xFF\xFF\xC5w^\xB0\xFF\xFF\xFF\xFF\xD0{^\xB0\xFF\xFF\xFF\xFF@=w\xB1\xFF\xFF\xFF\xFF\xD0\0A\xB2\xFF\xFF\xFF\xFF\xC0pX\xB3\xFF\xFF\xFF\xFFP4\"\xB4\xFF\xFF\xFF\xFF@\xA49\xB5\xFF\xFF\xFF\xFF\xD0g\x03\xB6\xFF\xFF\xFF\xFF\xC0\xD7\x1A\xB7\xFF\xFF\xFF\xFFP\x9B\xE4\xB7\xFF\xFF\xFF\xFF\xC0\\\xFD\xB8\xFF\xFF\xFF\xFFP \xC7\xB9\xFF\xFF\xFF\xFF@n\x1C\xCC\xFF\xFF\xFF\xFF\xD0\xE7l\xCC\xFF\xFF\xFF\xFF\xC0\x8F\xDC\xD3\xFF\xFF\xFF\xFF0\xD5\x17\xD4\xFF\xFF\xFF\xFF\xC0U3\xD5\xFF\xFF\xFF\xFF@\x92v\xD5\xFF\xFF\xFF\xFF@<\xD1\xFD\xFF\xFF\xFF\xFF\xB0\xFA\x92\xFE\xFF\xFF\xFF\xFF\xC0\xCD\xCC\xFF\xFF\xFF\xFF\xFF\xB0\xDCr\0\0\0\0\0\xC0Pu\x01\0\0\0\0\xB0I@\x02\0\0\0\0\xC02U\x03\0\0\0\0\xB0+ \x04\0\0\0\0@O>\x05\0\0\0\0\xB0\r\0\x06\0\0\0\0@\xBC\x0B\x07\0\0\0\0\xB0\xEF\xDF\x07\0\0\0\0@\x13\xFE\x08\0\0\0\0\xB0\xD1\xBF\t\0\0\0\0@\xF5\xDD\n\0\0\0\x000\xEE\xA8\x0B\0\0\0\0@\xD7\xBD\x0C\0\0\0\x000\xD0\x88\r\0\0\0\0@\xB9\x9D\x0E\0\0\0\x000\xB2h\x0F\0\0\0\0\xC0\xD5\x86\x10\0\0\0\x000\x94H\x11\0\0\0\0\xC0\xB7f\x12\0\0\0\x000v(\x13\0\0\0\0\xC0\x99F\x14\0\0\0\0\xB0\x92\x11\x15\0\0\0\0\xC0{&\x16\0\0\0\0\xB0t\xF1\x16\0\0\0\0\xC0]\x06\x18\0\0\0\0\xB0V\xD1\x18\0\0\0\0\xC0?\xE6\x19\0\0\0\0\xB08\xB1\x1A\0\0\0\0@\\\xCF\x1B\0\0\0\0\xB0\x1A\x91\x1C\0\0\0\0@>\xAF\x1D\0\0\0\0\xB0\xFCp\x1E\0\0\0\0@ \x8F\x1F\0\0\0\x000\x03\x7F \0\0\0\0@\x02o!\0\0\0\x000\xFB9\"\0\0\0\0@\xE4N#\0\0\0\x000\xDD\x19$\0\0\0\0\xC0\08%\0\0\0\x000\xBF\xF9%\0\0\0\0\xC0\xF8\xF2&\0\0\0\x000\xA1\xD9'\0\0\0\0\xC0\xC4\xF7(\0\0\0\0\xB0\xBD\xC2)\0\0\0\0\xC0\xA6\xD7*\0\0\0\0\xB0\x9F\xA2+\0\0\0\0\xC0\x88\xB7,\0\0\0\0\xB0\x81\x82-\0\0\0\0\xC0j\x97.\0\0\0\0\xB0cb/\0\0\0\0@\x87\x800\0\0\0\0\xB0EB1\0\0\0\0@i`2\0\0\0\x000\xD7=3\0\0\0\0@K@4\0\0\0\x000D\x0B5\0\0\0\0@\xB8\r6\0\0\0\0\xB0\xD5\x067\0\0\0\0@\x0F\08\0\0\0\x000\x08\xCB8\0\0\0\0\xC0+\xE99\0\0\0\x000\xEA\xAA:\0\0\0\0\xC0\r\xC9;\0\0\0\x000\xCC\x8A<\0\0\0\0\xC0\xEF\xA8=\0\0\0\x000\xAEj>\0\0\0\0\xC0\xD1\x88?\0\0\0\0\xB0\xCAS@\0\0\0\0\xC0\xB3hA\0\0\0\0\xB0\xAC3B\0\0\0\0\xC0\x95HC\0\0\0\0\xB0\x8E\x13D\0\0\0\0@\xB21E\0\0\0\0\xB0p\xF3E\0\0\0\0@\x94\x11G\0\0\0\x000\x02\xEFG\0\0\0\0@v\xF1H\0\0\0\x000o\xBCI\0\0\0\0@X\xD1J\0\0\0\0\xB0\0\xB8K\0\0\0\0@:\xB1L\0\0\0\x000\x07\xC6M\0\0\0\0\xC0\x82PN\0\0\0\0\xB0\xAE\x9CO\0\0\0\0\xC0\xD9BP\0\0\0\0\xB0\x90|Q\0\0\0\0@\xF6+R\0\0\0\0\xB0r\\S\0\0\0\0@\xD8\x0BT\0\0\0\x000\xE67W\0\0\0\0\xC0\xEC\xAFW\0\0\0\x000\xC8\x17Y\0\0\0\0\xC0\xCE\x8FY\0\0\0\x000\xAA\xF7Z\0\0\0\0\xC0\xB0o[\0\0\0\0\xB0g\xA9\\\0\0\0\0\xC0|t]\0\0\0\0\xB0I\x89^\0\0\0\0\xC0^T_\0\0\0\0\xB0+i`\0\0\0\0\xC0@4a\0\0\0\0\xB0\rIb\0\0\0\0@]\x1Dc\0\0\0\0\xB0\xEF(d\0\0\0\0\xC0\x04\xF4d\0\0\0\0\0\x01\0\x02\0\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x04\x02\x03\x01\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\xBB\xBD\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFFAST\0\0\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x88\0\x9B\0\x08\x1D\x87i\xFF\xFF\xFF\xFF`B\xDF\xBA\xFF\xFF\xFF\xFF\xD0K\x08\xFA\xFF\xFF\xFF\xFF@\xC3\xA7\xFA\xFF\xFF\xFF\xFF\xD0\xF1\xA7\xFF\xFF\xFF\xFF\xFF\xC8{C\0\0\0\0\0\xD0\xD3\x87\x01\0\0\0\0H\x7F\xFA\x01\0\0\0\0P\xF0p\x03\0\0\0\0H\x04\xDD\x03\0\0\0\0P\xD2P\x05\0\0\0\0H\x89\xBF\x05\0\0\0\0P\xB40\x07\0\0\0\0\xC8\xBC\xA0\x07\0\0\0\0P\x96\x10\t\0\0\0\0\xE0\xBC\xFB9\0\0\0\0`\xE1):\0\0\0\0\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x03\x05\x02\x03\x05x\xBE\xFF\xFF\xFF\xFF\xFF\xFF`\xBE\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xB8\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xB8\x02\x0F\x03\xB4r\xAA\x96\xFF\xFF\xFF\xFF\xE0I\x0F\xB8\xFF\xFF\xFF\xFF\xA0@\xFD\xB8\xFF\xFF\xFF\xFF04\xF1\xB9\xFF\xFF\xFF\xFF t\xDE\xBA\xFF\xFF\xFF\xFF0\xAE8\xDA\xFF\xFF\xFF\xFF0\xFA\xEB\xDA\xFF\xFF\xFF\xFF\xB0\xE1\x19\xDC\xFF\xFF\xFF\xFF Y\xB9\xDC\xFF\xFF\xFF\xFF0\x15\xFB\xDD\xFF\xFF\xFF\xFF \xDE\x9B\xDE\xFF\xFF\xFF\xFF0\x9A\xDD\xDF\xFF\xFF\xFF\xFF 3T\xE0\xFF\xFF\xFF\xFF0\tZ\xF4\xFF\xFF\xFF\xFF D\xB6\xF4\xFF\xFF\xFF\xFF ^\x05\xF5\xFF\xFF\xFF\xFF0d\xC0\xF6\xFF\xFF\xFF\xFF\xA0\x1E\x0E\xF7\xFF\xFF\xFF\xFF0,Q\xF8\xFF\xFF\xFF\xFF \xC5\xC7\xF8\xFF\xFF\xFF\xFF\xB0\xD2\n\xFA\xFF\xFF\xFF\xFF\xA0\xF8\xA8\xFA\xFF\xFF\xFF\xFF0\x06\xEC\xFB\xFF\xFF\xFF\xFF\xA0}\x8B\xFC\xFF\xFF\xFF\xFF0\x8E\xC9\x1D\0\0\0\0\xA0\xD7x\x1E\0\0\0\0\xB05\xA0\x1F\0\0\0\0\xA0\xCF3 \0\0\0\x000i\x81!\0\0\0\0\xA0\xC8\x0B\"\0\0\0\0\xB0\x10X#\0\0\0\0 p\xE2#\0\0\0\0\xB0\xF27%\0\0\0\0 \xC7\xD4%\0\0\0\x000\x0F!'\0\0\0\0\xA0\xE3\xBD'\0\0\0\x000\xF1\0)\0\0\0\0 \x8B\x94)\0\0\0\0\xB0\r\xEA*\0\0\0\0\xA02k+\0\0\0\x000\xB5\xC0,\0\0\0\0 \xC4f-\0\0\0\x000\x97\xA0.\0\0\0\0 \xA6F/\0\0\0\x000y\x800\0\0\0\0\xA0M\x1D1\0\0\0\0\xB0 W2\0\0\0\0 j\x063\0\0\0\x000T84\0\0\0\0 \xC1\xF84\0\0\0\x000\x1F 6\0\0\0\0\xA0h\xCF6\0\0\0\0\xB0\xC6\xF67\0\0\0\0 \x85\xB88\0\0\0\x000\xE3\xDF9\0\0\0\0\xA0,\x8F:\0\0\0\0\xB0\xFF\xC8;\0\0\0\0\xA0\x0Eo<\0\0\0\x000\x91\xC4=\0\0\0\0\xA0\xF0N>\0\0\0\x000\xFE\x91?\0\0\0\0\xA0\xD2.@\0\0\0\x000\xF8\x86A\0\0\0\0 \xEF\x17B\0\0\0\x000\xC2QC\0\0\0\0 \xD1\xF7C\0\0\0\0\xB0SME\0\0\0\0\xA0\xED\xE0E\0\0\0\x000\x86\x11G\0\0\0\0 \x95\xB7G\0\0\0\0\xB0\xA2\xFAH\0\0\0\0 w\x97I\0\0\0\0\xB0\x84\xDAJ\0\0\0\0\xA0\x93\x80K\0\0\0\0\xB0f\xBAL\0\0\0\0\xA0u`M\0\0\0\0\xB0H\x9AN\0\0\0\0 \x92IO\0\0\0\x000e\x83P\0\0\0\0\xA09 Q\0\0\0\x000GcR\0\0\0\0\xA0\x1B\0S\0\0\0\x000)CT\0\0\0\0 8\xE9T\0\0\0\x000\x0B#V\0\0\0\0 \x1A\xC9V\0\0\0\x000\xED\x02X\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02L\xD4\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF-02\0\0\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF\x01-01\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0\xF0\xF1\xFF\xFF\xFF\xFF\xFF\xFF\x02\0\0\0\x01\n\x05\0\0\0\0\0\0\0\0\0\xD0\x02V\x03\x18L\x80\x9B\xFF\xFF\xFF\xFF@nM\x13\0\0\0\0\xC0$4\x14\0\0\0\0\xA0\xF9#\x15\0\0\0\0\x90\xDC\x13\x16\0\0\0\0\x90\xCD\x03\x17\0\0\0\0\x90\xBE\xF3\x17\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x10\xBB=3\0\0\0\0\x10\x96R4\0\0\0\0\x10\x9D\x1D5\0\0\0\0\x10x26\0\0\0\0\x10\x7F\xFD6\0\0\0\0\x90\x94\x1B8\0\0\0\0\x10a\xDD8\0\0\0\0\x90v\xFB9\0\0\0\0\x10C\xBD:\0\0\0\0\x90X\xDB;\0\0\0\0\x90_\xA6<\0\0\0\0\x90:\xBB=\0\0\0\0\x90A\x86>\0\0\0\0\x90\x1C\x9B?\0\0\0\0\x90#f@\0\0\0\0\x109\x84A\0\0\0\0\x90\x05FB\0\0\0\0\x10\x1BdC\0\0\0\0\x90\xE7%D\0\0\0\0\x10\xFDCE\0\0\0\0\x90\xC9\x05F\0\0\0\0\x10\xDF#G\0\0\0\0\x10\xE6\xEEG\0\0\0\0\x10\xC1\x03I\0\0\0\0\x10\xC8\xCEI\0\0\0\0\x10\xA3\xE3J\0\0\0\0\x10\xAA\xAEK\0\0\0\0\x90\xBF\xCCL\0\0\0\0\x10\x8C\x8EM\0\0\0\0\x90\xA1\xACN\0\0\0\0\x10nnO\0\0\0\0\x90\x83\x8CP\0\0\0\0\x90\x8AWQ\0\0\0\0\x90elR\0\0\0\0\x90l7S\0\0\0\0\x90GLT\0\0\0\0\x90N\x17U\0\0\0\0\x90),V\0\0\0\0\x900\xF7V\0\0\0\0\x10F\x15X\0\0\0\0\x90\x12\xD7X\0\0\0\0\x10(\xF5Y\0\0\0\0\x90\xF4\xB6Z\0\0\0\0\x10\n\xD5[\0\0\0\0\x10\x11\xA0\\\0\0\0\0\x10\xEC\xB4]\0\0\0\0\x10\xF3\x7F^\0\0\0\0\x10\xCE\x94_\0\0\0\0\x10\xD5_`\0\0\0\0\x90\xEA}a\0\0\0\0\x10\xB7?b\0\0\0\0\x90\xCC]c\0\0\0\0\x10\x99\x1Fd\0\0\0\0\x90\xAE=e\0\0\0\0\x90\xB5\x08f\0\0\0\0\x01\x02\x01\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x02\x04h\xEB\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF\xF0\xF1\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\xF0\xF1\xFF\xFF\xFF\xFF\xFF\xFFAKST\0p\x81\xFF\xFF\xFF\xFF\xFF\xFF\x01AKDT\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xA8\x02\x16\x03\xD1\xFD\xC2?\xFF\xFF\xFF\xFF\x993\x87}\xFF\xFF\xFF\xFF\xA0\x1A\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\x10&a\xD2\xFF\xFF\xFF\xFF G\xB8\xFE\xFF\xFF\xFF\xFF\x10*\xA8\xFF\xFF\xFF\xFF\xFF )\x98\0\0\0\0\0\x10\x0C\x88\x01\0\0\0\0 \x0Bx\x02\0\0\0\0\x90(q\x03\0\0\0\0\xA0'a\x04\0\0\0\0\x90\nQ\x05\0\0\0\0\xA0\tA\x06\0\0\0\0\x90\xEC0\x07\0\0\0\0\xA0C\x8D\x07\0\0\0\0\x90\xCE\x10\t\0\0\0\0 \xBF\xAD\t\0\0\0\0\x90\xB0\xF0\n\0\0\0\0\xA0\xAF\xE0\x0B\0\0\0\0\x10\xCD\xD9\x0C\0\0\0\0\xA0\x91\xC0\r\0\0\0\0\x10\xAF\xB9\x0E\0\0\0\0 \xAE\xA9\x0F\0\0\0\0\x10\x91\x99\x10\0\0\0\0 \x90\x89\x11\0\0\0\0\x10sy\x12\0\0\0\0 ri\x13\0\0\0\0\x10UY\x14\0\0\0\0 TI\x15\0\0\0\0\x1079\x16\0\0\0\0 6)\x17\0\0\0\0\x90S\"\x18\0\0\0\0 \x18\t\x19\0\0\0\0\x905\x02\x1A\0\0\0\0\xA0C\x02\x1A\0\0\0\0\x10\x14+\x1A\0\0\0\0\xB0B\xF2\x1A\0\0\0\0\xA0%\xE2\x1B\0\0\0\0\xB0$\xD2\x1C\0\0\0\0\xA0\x07\xC2\x1D\0\0\0\0\xB0\x06\xB2\x1E\0\0\0\0\xA0\xE9\xA1\x1F\0\0\0\x0009v \0\0\0\0\xA0\xCB\x81!\0\0\0\x000\x1BV\"\0\0\0\0 \xE8j#\0\0\0\x000\xFD5$\0\0\0\0 \xCAJ%\0\0\0\x000\xDF\x15&\0\0\0\0 \xAC*'\0\0\0\0\xB0\xFB\xFE'\0\0\0\0 \x8E\n)\0\0\0\0\xB0\xDD\xDE)\0\0\0\0 p\xEA*\0\0\0\0\xB0\xBF\xBE+\0\0\0\0\xA0\x8C\xD3,\0\0\0\0\xB0\xA1\x9E-\0\0\0\0\xA0n\xB3.\0\0\0\0\xB0\x83~/\0\0\0\0\xA0P\x930\0\0\0\x000\xA0g1\0\0\0\0\xA02s2\0\0\0\x000\x82G3\0\0\0\0\xA0\x14S4\0\0\0\x000d'5\0\0\0\0\xA0\xF626\0\0\0\x000F\x077\0\0\0\0 \x13\x1C8\0\0\0\x000(\xE78\0\0\0\0 \xF5\xFB9\0\0\0\x000\n\xC7:\0\0\0\0 \xD7\xDB;\0\0\0\0\xB0&\xB0<\0\0\0\0 \xB9\xBB=\0\0\0\0\xB0\x08\x90>\0\0\0\0 \x9B\x9B?\0\0\0\0\xB0\xEAo@\0\0\0\0\xA0\xB7\x84A\0\0\0\0\xB0\xCCOB\0\0\0\0\xA0\x99dC\0\0\0\0\xB0\xAE/D\0\0\0\0\xA0{DE\0\0\0\x000\xE1\xF3E\0\0\0\0 \x98-G\0\0\0\0\x01\x02\x03\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\xA7\xD2\0\0\0\0\0\0'\x81\xFF\xFF\xFF\xFF\xFF\xFF\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFFp\x81\xFF\xFF\xFF\xFF\xFF\xFFNST\0\0\xC8\xCE\xFF\xFF\xFF\xFF\xFF\xFF\x01NDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xD0\x05\x8A\x06\xEC4=^\xFF\xFF\xFF\xFF\x0Cb\xCF\x9C\xFF\xFF\xFF\xFF\xFC\xE6\xA4\x9D\xFF\xFF\xFF\xFF\x8C~\xB8\x9E\xFF\xFF\xFF\xFF|\xD6\xBA\x9F\xFF\xFF\xFF\xFF\xDC\x88\xB6\xA0\xFF\xFF\xFF\xFFL\xFF8\xA1\xFF\xFF\xFF\xFF\\\x19\x95\xA2\xFF\xFF\xFF\xFFL\xFC\x84\xA3\xFF\xFF\xFF\xFF\\\xFBt\xA4\xFF\xFF\xFF\xFFL\xDEd\xA5\xFF\xFF\xFF\xFF\xDC\x17^\xA6\xFF\xFF\xFF\xFFL\xC0D\xA7\xFF\xFF\xFF\xFF\xDC\xF9=\xA8\xFF\xFF\xFF\xFFL\xA2$\xA9\xFF\xFF\xFF\xFF\xDC\xDB\x1D\xAA\xFF\xFF\xFF\xFFL\x84\x04\xAB\xFF\xFF\xFF\xFF\xDC\xBD\xFD\xAB\xFF\xFF\xFF\xFFLf\xE4\xAC\xFF\xFF\xFF\xFF\xDC\x9F\xDD\xAD\xFF\xFF\xFF\xFF\xCC\x82\xCD\xAE\xFF\xFF\xFF\xFF\xDC\x81\xBD\xAF\xFF\xFF\xFF\xFF\xCCd\xAD\xB0\xFF\xFF\xFF\xFF\\\x9E\xA6\xB1\xFF\xFF\xFF\xFF\xCCF\x8D\xB2\xFF\xFF\xFF\xFF\\\x80\x86\xB3\xFF\xFF\xFF\xFF\xCC(m\xB4\xFF\xFF\xFF\xFF\\bf\xB5\xFF\xFF\xFF\xFF\xCC\nM\xB6\xFF\xFF\xFF\xFF\\DF\xB7\xFF\xFF\xFF\xFF\xCC\xEC,\xB8\xFF\xFF\xFF\xFF\\&&\xB9\xFF\xFF\xFF\xFFL\t\x16\xBA\xFF\xFF\xFF\xFF\xDCB\x0F\xBB\xFF\xFF\xFF\xFFL\xEB\xF5\xBB\xFF\xFF\xFF\xFF\xDC$\xEF\xBC\xFF\xFF\xFF\xFFL\xCD\xD5\xBD\xFF\xFF\xFF\xFFlM\x9E\xBE\xFF\xFF\xFF\xFF\xA8\x06\xCF\xBE\xFF\xFF\xFF\xFF\x18\xAF\xB5\xBF\xFF\xFF\xFF\xFF81\xB8\xC0\xFF\xFF\xFF\xFF\xA8\xEFy\xC1\xFF\xFF\xFF\xFF8\x13\x98\xC2\xFF\xFF\xFF\xFF\xA8\xD1Y\xC3\xFF\xFF\xFF\xFF8\xF5w\xC4\xFF\xFF\xFF\xFF\xA8\xB39\xC5\xFF\xFF\xFF\xFF\xB8\x11a\xC6\xFF\xFF\xFF\xFF\xA8\x95\x19\xC7\xFF\xFF\xFF\xFF\xB8\xF3@\xC8\xFF\xFF\xFF\xFF(\xB2\x02\xC9\xFF\xFF\xFF\xFF\xB8\xD5 \xCA\xFF\xFF\xFF\xFF(\x94\xE2\xCA\xFF\xFF\xFF\xFF\xB8\xB7\0\xCC\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\xC8\xE6`\xD2\xFF\xFF\xFF\xFF\xD8D\x88\xD3\xFF\xFF\xFF\xFFH\x03J\xD4\xFF\xFF\xFF\xFF\xD8&h\xD5\xFF\xFF\xFF\xFFH\xE5)\xD6\xFF\xFF\xFF\xFF\xD8\x08H\xD7\xFF\xFF\xFF\xFFH\xC7\t\xD8\xFF\xFF\xFF\xFF\xD8\xEA'\xD9\xFF\xFF\xFF\xFFH\xA9\xE9\xD9\xFF\xFF\xFF\xFFX\x07\x11\xDB\xFF\xFF\xFF\xFF\xC8\xC5\xD2\xDB\xFF\xFF\xFF\xFFXt\xDE\xDC\xFF\xFF\xFF\xFFHm\xA9\xDD\xFF\xFF\xFF\xFFXV\xBE\xDE\xFF\xFF\xFF\xFFHO\x89\xDF\xFF\xFF\xFF\xFFX8\x9E\xE0\xFF\xFF\xFF\xFFH1i\xE1\xFF\xFF\xFF\xFFX\x1A~\xE2\xFF\xFF\xFF\xFFH\x13I\xE3\xFF\xFF\xFF\xFFX\xFC]\xE4\xFF\xFF\xFF\xFFH\xF5(\xE5\xFF\xFF\xFF\xFF\xD8\x18G\xE6\xFF\xFF\xFF\xFF\xC8\x11\x12\xE7\xFF\xFF\xFF\xFF\xD8\xFA&\xE8\xFF\xFF\xFF\xFF\xC8\xF3\xF1\xE8\xFF\xFF\xFF\xFF\xD8\xDC\x06\xEA\xFF\xFF\xFF\xFF\xC8\xD5\xD1\xEA\xFF\xFF\xFF\xFF\xD8\xBE\xE6\xEB\xFF\xFF\xFF\xFF\xC8\xB7\xB1\xEC\xFF\xFF\xFF\xFF\xD8\xA0\xC6\xED\xFF\xFF\xFF\xFFH\xBE\xBF\xEE\xFF\xFF\xFF\xFFX\xBD\xAF\xEF\xFF\xFF\xFF\xFFH\xA0\x9F\xF0\xFF\xFF\xFF\xFFX\x9F\x8F\xF1\xFF\xFF\xFF\xFFH\x82\x7F\xF2\xFF\xFF\xFF\xFFX\x81o\xF3\xFF\xFF\xFF\xFFHd_\xF4\xFF\xFF\xFF\xFFXcO\xF5\xFF\xFF\xFF\xFFHF?\xF6\xFF\xFF\xFF\xFFXE/\xF7\xFF\xFF\xFF\xFF\xC8b(\xF8\xFF\xFF\xFF\xFFX'\x0F\xF9\xFF\xFF\xFF\xFF\xC8D\x08\xFA\xFF\xFF\xFF\xFF\xD8C\xF8\xFA\xFF\xFF\xFF\xFF\xC8&\xE8\xFB\xFF\xFF\xFF\xFF\xD8%\xD8\xFC\xFF\xFF\xFF\xFF\xC8\x08\xC8\xFD\xFF\xFF\xFF\xFF\xD8\x07\xB8\xFE\xFF\xFF\xFF\xFF\xC8\xEA\xA7\xFF\xFF\xFF\xFF\xFF\xD8\xE9\x97\0\0\0\0\0\xC8\xCC\x87\x01\0\0\0\0\xD8\xCBw\x02\0\0\0\0H\xE9p\x03\0\0\0\0X\xE8`\x04\0\0\0\0H\xCBP\x05\0\0\0\0X\xCA@\x06\0\0\0\0H\xAD0\x07\0\0\0\0X\xAC \x08\0\0\0\0H\x8F\x10\t\0\0\0\0X\x8E\0\n\0\0\0\0Hq\xF0\n\0\0\0\0Xp\xE0\x0B\0\0\0\0\xC8\x8D\xD9\x0C\0\0\0\0XR\xC0\r\0\0\0\0\xC8o\xB9\x0E\0\0\0\0\xD8n\xA9\x0F\0\0\0\0\xC8Q\x99\x10\0\0\0\0\xD8P\x89\x11\0\0\0\0\xC83y\x12\0\0\0\0\xD82i\x13\0\0\0\0\xC8\x15Y\x14\0\0\0\0\xD8\x14I\x15\0\0\0\0\xC8\xF78\x16\0\0\0\0\xD8\xF6(\x17\0\0\0\0H\x14\"\x18\0\0\0\0\xD8\xD8\x08\x19\0\0\0\0H\xF6\x01\x1A\0\0\0\0X\xF5\xF1\x1A\0\0\0\0H\xD8\xE1\x1B\0\0\0\0X\xD7\xD1\x1C\0\0\0\0H\xBA\xC1\x1D\0\0\0\0X\xB9\xB1\x1E\0\0\0\0H\x9C\xA1\x1F\0\0\0\0\xF4\xCFu \0\0\0\0db\x81!\0\0\0\0\xF4\xB1U\"\0\0\0\0\xD4pj#\0\0\0\0\xF4\x935$\0\0\0\0\xE4`J%\0\0\0\0\xF4u\x15&\0\0\0\0\xE4B*'\0\0\0\0t\x92\xFE'\0\0\0\0\xE4$\n)\0\0\0\0tt\xDE)\0\0\0\0\xE4\x06\xEA*\0\0\0\0tV\xBE+\0\0\0\0d#\xD3,\0\0\0\0t8\x9E-\0\0\0\0d\x05\xB3.\0\0\0\0t\x1A~/\0\0\0\0d\xE7\x920\0\0\0\0\xF46g1\0\0\0\0d\xC9r2\0\0\0\0\xF4\x18G3\0\0\0\0d\xABR4\0\0\0\0\xF4\xFA&5\0\0\0\0d\x8D26\0\0\0\0\xF4\xDC\x067\0\0\0\0\xE4\xA9\x1B8\0\0\0\0\xF4\xBE\xE68\0\0\0\0\xE4\x8B\xFB9\0\0\0\0\xF4\xA0\xC6:\0\0\0\0\xE4m\xDB;\0\0\0\0t\xBD\xAF<\0\0\0\0\xE4O\xBB=\0\0\0\0t\x9F\x8F>\0\0\0\0\xE41\x9B?\0\0\0\0t\x81o@\0\0\0\0dN\x84A\0\0\0\0tcOB\0\0\0\0d0dC\0\0\0\0tE/D\0\0\0\0d\x12DE\0\0\0\0\xF4w\xF3E\0\0\0\0\xE4.-G\0\0\0\0\xF4Y\xD3G\0\0\0\0\xE4\x10\rI\0\0\0\0\xF4;\xB3I\0\0\0\0\xE4\xF2\xECJ\0\0\0\0tX\x9CK\0\0\0\0d\x0F\xD6L\0\0\0\0t:|M\0\0\0\0\0\x01\0\x01\0\x01\0\x01\0\x01\0\x01\0\x01\0\x01\0\x01\0\x01\0\x01\0\x01\0\x01\0\x01\0\x01\0\x01\0\x01\0\x01\0\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x94\xCE\xFF\xFF\xFF\xFF\xFF\xFF\xA4\xDC\xFF\xFF\xFF\xFF\xFF\xFF\xC8\xCE\xFF\xFF\xFF\xFF\xFF\xFF\xD8\xDC\xFF\xFF\xFF\xFF\xFF\xFF\xE8\xEA\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xB8\0\xD0\0\x18\x96\xFD\x86\xFF\xFF\xFF\xFF\x90\xAF\xB8\x9E\xFF\xFF\xFF\xFF\x80\x07\xBB\x9F\xFF\xFF\xFF\xFF\x90\x0C\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\0\x18a\xD2\xFF\xFF\xFF\xFF\x10\x01v\xD3\xFF\xFF\xFF\xFF\0oS\xD4\xFF\xFF\xFF\xFF\x10\xE3U\xD5\xFF\xFF\xFF\xFF\0\xDC \xD6\xFF\xFF\xFF\xFF\x10\xC55\xD7\xFF\xFF\xFF\xFF\0\xBE\0\xD8\xFF\xFF\xFF\xFF\x10\xA7\x15\xD9\xFF\xFF\xFF\xFF\0\xA0\xE0\xD9\xFF\xFF\xFF\xFF\x10,'\xE8\xFF\xFF\xFF\xFF\0\x0F\x17\xE9\xFF\xFF\xFF\xFF\x10\xF0\xE6\xEB\xFF\xFF\xFF\xFF\0\xD3\xD6\xEC\xFF\xFF\xFF\xFF\x10\xD2\xC6\xED\xFF\xFF\xFF\xFF\0\xCB\x91\xEE\xFF\xFF\xFF\xFF\x90\xEE\xAF\xEF\xFF\xFF\xFF\xFF\0\xADq\xF0\xFF\xFF\xFF\xFF\x90\x19a\x04\0\0\0\0\x01\x02\x01\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\xE8\x9A\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFFCST\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\08\0?\0DKL\xA4\xFF\xFF\xFF\xFF\xE0\xDC\x9A \0\0\0\0P\x9B\\!\0\0\0\0\xE0\xBEz\"\0\0\0\0P}<#\0\0\0\0\xE0\x8C]D\0\0\0\0\xD0\xC8\xD6D\0\0\0\0\x01\x02\x01\x02\x01\x02\x01<\xAE\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFFAST\0\0\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\x01ADT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\x18\x01;\x01\xFCw\x80\x9B\xFF\xFF\xFF\xFF\xE0z\xF5'\0\0\0\0\xD0]\xE5(\0\0\0\0\xE0\\\xD5)\0\0\0\0\xD0?\xC5*\0\0\0\0`y\xBE+\0\0\0\0PF\xD3,\0\0\0\0`[\x9E-\0\0\0\0P(\xB3.\0\0\0\0`=~/\0\0\0\0P\n\x930\0\0\0\0\xE0Yg1\0\0\0\0P\xECr2\0\0\0\0\xE0;G3\0\0\0\0P\xCER4\0\0\0\0\xE0\x1D'5\0\0\0\0P\xB026\0\0\0\0\xE0\xFF\x067\0\0\0\0\xD0\xCC\x1B8\0\0\0\0\xE0\xE1\xE68\0\0\0\0\xD0\xAE\xFB9\0\0\0\0\xE0\xC3\xC6:\0\0\0\0\xD0\x90\xDB;\0\0\0\0`\xE0\xAF<\0\0\0\0\xD0r\xBB=\0\0\0\0`\xC2\x8F>\0\0\0\0\xD0T\x9B?\0\0\0\0`\xA4o@\0\0\0\0Pq\x84A\0\0\0\0`\x86OB\0\0\0\0PSdC\0\0\0\0`h/D\0\0\0\0P5DE\0\0\0\0\xE0\x9A\xF3E\0\0\0\0\xD0Q-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x84\xBF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFFPST\0\0\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF\x01PDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\x18\x03\xAB\x03p\xE8\xB6\xA5\xFF\xFF\xFF\xFFpOy\xA9\xFF\xFF\xFF\xFF\x809\xF1\xAF\xFF\xFF\xFF\xFFpdf\xB6\xFF\xFF\xFF\xFF\0\x10\x1B\xB7\xFF\xFF\xFF\xFF\xF0\xF2\n\xB8\xFF\xFF\xFF\xFF\x80\x8D\xEA\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\xF0\xAE\x9D\xD2\xFF\xFF\xFF\xFF\0Y\x1B\xD7\xFF\xFF\xFF\xFF\xF0\xB4\x91\xD8\xFF\xFF\xFF\xFF\0\x07\0\xDB\xFF\xFF\xFF\xFF\xF0s\xC0\xDB\xFF\xFF\xFF\xFF\xA0\xB3\xDE\xDC\xFF\xFF\xFF\xFF\x90\xAC\xA9\xDD\xFF\xFF\xFF\xFF\xA0\x95\xBE\xDE\xFF\xFF\xFF\xFF\x90\x8E\x89\xDF\xFF\xFF\xFF\xFF\x90K~\xE2\xFF\xFF\xFF\xFF\x90RI\xE3\xFF\xFF\xFF\xFF\x90-^\xE4\xFF\xFF\xFF\xFF\x904)\xE5\xFF\xFF\xFF\xFF\x10JG\xE6\xFF\xFF\xFF\xFF\x10Q\x12\xE7\xFF\xFF\xFF\xFF\x10,'\xE8\xFF\xFF\xFF\xFF\x103\xF2\xE8\xFF\xFF\xFF\xFF\x10\x0E\x07\xEA\xFF\xFF\xFF\xFF\x10\x15\xD2\xEA\xFF\xFF\xFF\xFF\x10\xF0\xE6\xEB\xFF\xFF\xFF\xFF\x10\xF7\xB1\xEC\xFF\xFF\xFF\xFF\x10\xD2\xC6\xED\xFF\xFF\xFF\xFF\x10\xD9\x91\xEE\xFF\xFF\xFF\xFF\xA0\xAF\xE0\x0B\0\0\0\0\x10\xCD\xD9\x0C\0\0\0\0\xA0\x91\xC0\r\0\0\0\0\x10\xAF\xB9\x0E\0\0\0\0 \xAE\xA9\x0F\0\0\0\0\x10\x91\x99\x10\0\0\0\0 \x90\x89\x11\0\0\0\0\x10sy\x12\0\0\0\0 ri\x13\0\0\0\0\x10UY\x14\0\0\0\0 TI\x15\0\0\0\0\x1079\x16\0\0\0\0 6)\x17\0\0\0\0\x90S\"\x18\0\0\0\0 \x18\t\x19\0\0\0\0\x905\x02\x1A\0\0\0\0\xA04\xF2\x1A\0\0\0\0\x90\x17\xE2\x1B\0\0\0\0\xA0\x16\xD2\x1C\0\0\0\0\x90\xF9\xC1\x1D\0\0\0\0\xA0\xF8\xB1\x1E\0\0\0\0\x90\xDB\xA1\x1F\0\0\0\0 +v \0\0\0\0\x90\xBD\x81!\0\0\0\0 \rV\"\0\0\0\0\x10\xDAj#\0\0\0\0 \xEF5$\0\0\0\0\x10\xBCJ%\0\0\0\0 \xD1\x15&\0\0\0\0\x10\x9E*'\0\0\0\0\xA0\xED\xFE'\0\0\0\0\x10\x80\n)\0\0\0\0\xA0\xCF\xDE)\0\0\0\0\x10b\xEA*\0\0\0\0\xA0\xB1\xBE+\0\0\0\0\x90~\xD3,\0\0\0\0\xA0\x93\x9E-\0\0\0\0\x90`\xB3.\0\0\0\0\xA0u~/\0\0\0\0\x90B\x930\0\0\0\0 \x92g1\0\0\0\0\x90$s2\0\0\0\0 tG3\0\0\0\0\x90\x06S4\0\0\0\0 V'5\0\0\0\0\x90\xE826\0\0\0\0 8\x077\0\0\0\0\x10\x05\x1C8\0\0\0\0 \x1A\xE78\0\0\0\0\x10\xE7\xFB9\0\0\0\0 \xFC\xC6:\0\0\0\0\x10\xC9\xDB;\0\0\0\0\xA0\x18\xB0<\0\0\0\0\x10\xAB\xBB=\0\0\0\0\xA0\xFA\x8F>\0\0\0\0\x10\x8D\x9B?\0\0\0\0\xA0\xDCo@\0\0\0\0\x90\xA9\x84A\0\0\0\0\xA0\xBEOB\0\0\0\0\x90\x8BdC\0\0\0\0\xA0\xA0/D\0\0\0\0\x90mDE\0\0\0\0\xA0\x82\x0FF\0\0\0\0\x90O$G\0\0\0\0 \x9F\xF8G\0\0\0\0\x901\x04I\0\0\0\0 \x81\xD8I\0\0\0\0\x90\x13\xE4J\0\0\0\0\x01\x02\x01\x02\x01\x03\x02\x01\x03\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02L\x92\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFFEST\0\0\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\x01EDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0h\x05\x15\x06\xECx\xEEr\xFF\xFF\xFF\xFFp\x93\xB8\x9E\xFF\xFF\xFF\xFF`\xEB\xBA\x9F\xFF\xFF\xFF\xFF\xC8.\x87\xA0\xFF\xFF\xFF\xFF@\xB1\x9A\xA1\xFF\xFF\xFF\xFF\xF0\x06\x94\xA2\xFF\xFF\xFF\xFF@\xA9U\xA3\xFF\xFF\xFF\xFF\xF0]\x86\xA4\xFF\xFF\xFF\xFF`x(\xA5\xFF\xFF\xFF\xFF\xF0?f\xA6\xFF\xFF\xFF\xFF\xE0N\x0C\xA7\xFF\xFF\xFF\xFF\xF0!F\xA8\xFF\xFF\xFF\xFF\xE00\xEC\xA8\xFF\xFF\xFF\xFFp\xC9\x1C\xAA\xFF\xFF\xFF\xFF`M\xD5\xAA\xFF\xFF\xFF\xFFp\xAB\xFC\xAB\xFF\xFF\xFF\xFF`/\xB5\xAC\xFF\xFF\xFF\xFFp\x8D\xDC\xAD\xFF\xFF\xFF\xFF`\x11\x95\xAE\xFF\xFF\xFF\xFFpo\xBC\xAF\xFF\xFF\xFF\xFF\xE0-~\xB0\xFF\xFF\xFF\xFFpQ\x9C\xB1\xFF\xFF\xFF\xFF`Jg\xB2\xFF\xFF\xFF\xFFp3|\xB3\xFF\xFF\xFF\xFF`,G\xB4\xFF\xFF\xFF\xFFp\x15\\\xB5\xFF\xFF\xFF\xFF`\x0E'\xB6\xFF\xFF\xFF\xFFp\xF7;\xB7\xFF\xFF\xFF\xFF`\xF0\x06\xB8\xFF\xFF\xFF\xFF\xF0\x13%\xB9\xFF\xFF\xFF\xFF`\xD2\xE6\xB9\xFF\xFF\xFF\xFF\xF0\xF5\x04\xBB\xFF\xFF\xFF\xFF\xE0\xEE\xCF\xBB\xFF\xFF\xFF\xFF\xF0\xD7\xE4\xBC\xFF\xFF\xFF\xFF\xE0\xD0\xAF\xBD\xFF\xFF\xFF\xFF\xF0\xB9\xC4\xBE\xFF\xFF\xFF\xFF\xE0\xB2\x8F\xBF\xFF\xFF\xFF\xFF\xF0\x9B\xA4\xC0\xFF\xFF\xFF\xFF\xE0\x94o\xC1\xFF\xFF\xFF\xFF\xF0}\x84\xC2\xFF\xFF\xFF\xFF\xE0vO\xC3\xFF\xFF\xFF\xFF\xF0_d\xC4\xFF\xFF\xFF\xFF\xE0X/\xC5\xFF\xFF\xFF\xFFp|M\xC6\xFF\xFF\xFF\xFF\xE0:\x0F\xC7\xFF\xFF\xFF\xFFp^-\xC8\xFF\xFF\xFF\xFFp\xF0\x88\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\xE0\xFB`\xD2\xFF\xFF\xFF\xFFP\x89\xDB\xD2\xFF\xFF\xFF\xFF\xE0\xDD@\xD4\xFF\xFF\xFF\xFF\xF0\xC6U\xD5\xFF\xFF\xFF\xFF\xE0\xBF \xD6\xFF\xFF\xFF\xFF\xF0\xA85\xD7\xFF\xFF\xFF\xFF\xE0\xA1\0\xD8\xFF\xFF\xFF\xFF\xF0\x8A\x15\xD9\xFF\xFF\xFF\xFF`\x923\xDA\xFF\xFF\xFF\xFFp\xA7\xFE\xDA\xFF\xFF\xFF\xFF`t\x13\xDC\xFF\xFF\xFF\xFFp\x89\xDE\xDC\xFF\xFF\xFF\xFF`\x82\xA9\xDD\xFF\xFF\xFF\xFFpk\xBE\xDE\xFF\xFF\xFF\xFF`d\x89\xDF\xFF\xFF\xFF\xFFpM\x9E\xE0\xFF\xFF\xFF\xFF`Fi\xE1\xFF\xFF\xFF\xFFp/~\xE2\xFF\xFF\xFF\xFF`(I\xE3\xFF\xFF\xFF\xFFp\x11^\xE4\xFF\xFF\xFF\xFF`\n)\xE5\xFF\xFF\xFF\xFF\xF0-G\xE6\xFF\xFF\xFF\xFF\xE0&\x12\xE7\xFF\xFF\xFF\xFF\xF0\x0F'\xE8\xFF\xFF\xFF\xFF\xE0\xF2\x16\xE9\xFF\xFF\xFF\xFF\xF0\xF1\x06\xEA\xFF\xFF\xFF\xFF\xE0\xD4\xF6\xEA\xFF\xFF\xFF\xFF\xF0\xD3\xE6\xEB\xFF\xFF\xFF\xFF\xE0\xB6\xD6\xEC\xFF\xFF\xFF\xFF\xF0\xB5\xC6\xED\xFF\xFF\xFF\xFF`\xD3\xBF\xEE\xFF\xFF\xFF\xFFp\xD2\xAF\xEF\xFF\xFF\xFF\xFF`\xB5\x9F\xF0\xFF\xFF\xFF\xFFp\xB4\x8F\xF1\xFF\xFF\xFF\xFF`\x97\x7F\xF2\xFF\xFF\xFF\xFFp\x96o\xF3\xFF\xFF\xFF\xFF`y_\xF4\xFF\xFF\xFF\xFFpxO\xF5\xFF\xFF\xFF\xFF`[?\xF6\xFF\xFF\xFF\xFFpZ/\xF7\xFF\xFF\xFF\xFF\xE0w(\xF8\xFF\xFF\xFF\xFFp<\x0F\xF9\xFF\xFF\xFF\xFF\xE0Y\x08\xFA\xFF\xFF\xFF\xFF\xF0X\xF8\xFA\xFF\xFF\xFF\xFF\xE0;\xE8\xFB\xFF\xFF\xFF\xFF\xF0:\xD8\xFC\xFF\xFF\xFF\xFF\xE0\x1D\xC8\xFD\xFF\xFF\xFF\xFF\xF0\x1C\xB8\xFE\xFF\xFF\xFF\xFF\xE0\xFF\xA7\xFF\xFF\xFF\xFF\xFF\xF0\xFE\x97\0\0\0\0\0\xE0\xE1\x87\x01\0\0\0\0\xF0\xE0w\x02\0\0\0\0`\xFEp\x03\0\0\0\0p\xFD`\x04\0\0\0\0`\xE0P\x05\0\0\0\0p\xDF@\x06\0\0\0\0`\xC20\x07\0\0\0\0p\xC1 \x08\0\0\0\0`\xA4\x10\t\0\0\0\0p\xA3\0\n\0\0\0\0`\x86\xF0\n\0\0\0\0p\x85\xE0\x0B\0\0\0\0\xE0\xA2\xD9\x0C\0\0\0\0pg\xC0\r\0\0\0\0\xE0\x84\xB9\x0E\0\0\0\0\xF0\x83\xA9\x0F\0\0\0\0\xE0f\x99\x10\0\0\0\0\xF0e\x89\x11\0\0\0\0\xE0Hy\x12\0\0\0\0\xF0Gi\x13\0\0\0\0\xE0*Y\x14\0\0\0\0\xF0)I\x15\0\0\0\0\xE0\x0C9\x16\0\0\0\0\xF0\x0B)\x17\0\0\0\0`)\"\x18\0\0\0\0\xF0\xED\x08\x19\0\0\0\0`\x0B\x02\x1A\0\0\0\0p\n\xF2\x1A\0\0\0\0`\xED\xE1\x1B\0\0\0\0p\xEC\xD1\x1C\0\0\0\0`\xCF\xC1\x1D\0\0\0\0p\xCE\xB1\x1E\0\0\0\0`\xB1\xA1\x1F\0\0\0\0\xF0\0v \0\0\0\0`\x93\x81!\0\0\0\0\xF0\xE2U\"\0\0\0\0\xE0\xAFj#\0\0\0\0\xF0\xC45$\0\0\0\0\xE0\x91J%\0\0\0\0\xF0\xA6\x15&\0\0\0\0\xE0s*'\0\0\0\0p\xC3\xFE'\0\0\0\0\xE0U\n)\0\0\0\0p\xA5\xDE)\0\0\0\0\xE07\xEA*\0\0\0\0p\x87\xBE+\0\0\0\0`T\xD3,\0\0\0\0pi\x9E-\0\0\0\0`6\xB3.\0\0\0\0pK~/\0\0\0\0`\x18\x930\0\0\0\0\xF0gg1\0\0\0\0`\xFAr2\0\0\0\0\xF0IG3\0\0\0\0`\xDCR4\0\0\0\0\xF0+'5\0\0\0\0`\xBE26\0\0\0\0\xF0\r\x077\0\0\0\0\xE0\xDA\x1B8\0\0\0\0\xF0\xEF\xE68\0\0\0\0\xE0\xBC\xFB9\0\0\0\0\xF0\xD1\xC6:\0\0\0\0\xE0\x9E\xDB;\0\0\0\0p\xEE\xAF<\0\0\0\0\xE0\x80\xBB=\0\0\0\0p\xD0\x8F>\0\0\0\0\xE0b\x9B?\0\0\0\0p\xB2o@\0\0\0\0`\x7F\x84A\0\0\0\0p\x94OB\0\0\0\0`adC\0\0\0\0pv/D\0\0\0\0`CDE\0\0\0\0\xF0\xA8\xF3E\0\0\0\0\xE0_-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x94\xB5\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFFPST\0\0\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF\x01PDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\x10\x04\x92\x04\xECv=^\xFF\xFF\xFF\xFF\xA0\xBD\xB8\x9E\xFF\xFF\xFF\xFF\x90\x15\xBB\x9F\xFF\xFF\xFF\xFF\xA0\x1A\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF\x10&a\xD2\xFF\xFF\xFF\xFF \x0Fv\xD3\xFF\xFF\xFF\xFF\x10\x08A\xD4\xFF\xFF\xFF\xFF \xF1U\xD5\xFF\xFF\xFF\xFF\x10\xEA \xD6\xFF\xFF\xFF\xFF \xD35\xD7\xFF\xFF\xFF\xFF\x10\xCC\0\xD8\xFF\xFF\xFF\xFF \xB5\x15\xD9\xFF\xFF\xFF\xFF\x10\xAE\xE0\xD9\xFF\xFF\xFF\xFF\xA0\xD1\xFE\xDA\xFF\xFF\xFF\xFF\x10\x90\xC0\xDB\xFF\xFF\xFF\xFF\xA0\xB3\xDE\xDC\xFF\xFF\xFF\xFF\x90\xAC\xA9\xDD\xFF\xFF\xFF\xFF\xA0\x95\xBE\xDE\xFF\xFF\xFF\xFF\x90\x8E\x89\xDF\xFF\xFF\xFF\xFF\xA0w\x9E\xE0\xFF\xFF\xFF\xFF\x90pi\xE1\xFF\xFF\xFF\xFF\xA0Y~\xE2\xFF\xFF\xFF\xFF\x90RI\xE3\xFF\xFF\xFF\xFF\xA0;^\xE4\xFF\xFF\xFF\xFF\x904)\xE5\xFF\xFF\xFF\xFF XG\xE6\xFF\xFF\xFF\xFF\x10Q\x12\xE7\xFF\xFF\xFF\xFF :'\xE8\xFF\xFF\xFF\xFF\x103\xF2\xE8\xFF\xFF\xFF\xFF \x1C\x07\xEA\xFF\xFF\xFF\xFF\x10\x15\xD2\xEA\xFF\xFF\xFF\xFF \xFE\xE6\xEB\xFF\xFF\xFF\xFF\x10\xF7\xB1\xEC\xFF\xFF\xFF\xFF \xE0\xC6\xED\xFF\xFF\xFF\xFF\x10\xD9\x91\xEE\xFF\xFF\xFF\xFF\xA0\xFC\xAF\xEF\xFF\xFF\xFF\xFF\x10\xBBq\xF0\xFF\xFF\xFF\xFF\xA0\xDE\x8F\xF1\xFF\xFF\xFF\xFF\x90\xC1\x7F\xF2\xFF\xFF\xFF\xFF\xA0\xC0o\xF3\xFF\xFF\xFF\xFF\x90\xA3_\xF4\xFF\xFF\xFF\xFF\xA0\xA2O\xF5\xFF\xFF\xFF\xFF\x90\x85?\xF6\xFF\xFF\xFF\xFF\xA0\x84/\xF7\xFF\xFF\xFF\xFF\x10\xA2(\xF8\xFF\xFF\xFF\xFF\xA0f\x0F\xF9\xFF\xFF\xFF\xFF\x10\x84\x08\xFA\xFF\xFF\xFF\xFF \x83\xF8\xFA\xFF\xFF\xFF\xFF\x10f\xE8\xFB\xFF\xFF\xFF\xFF e\xD8\xFC\xFF\xFF\xFF\xFF\x10H\xC8\xFD\xFF\xFF\xFF\xFF G\xB8\xFE\xFF\xFF\xFF\xFF\x10*\xA8\xFF\xFF\xFF\xFF\xFF )\x98\0\0\0\0\0\x10\x0C\x88\x01\0\0\0\0 \x0Bx\x02\0\0\0\0\x90(q\x03\0\0\0\0\xA0'a\x04\0\0\0\0\x90\nQ\x05\0\0\0\0\xA0\tA\x06\0\0\0\0\x90\xEC0\x07\0\0\0\0\xA0\xEB \x08\0\0\0\0\x90\xCE\x10\t\0\0\0\0\xA0\xCD\0\n\0\0\0\0\x90\xB0\xF0\n\0\0\0\0\xA0\xAF\xE0\x0B\0\0\0\0\x10\xCD\xD9\x0C\0\0\0\0\xA0\x91\xC0\r\0\0\0\0\x10\xAF\xB9\x0E\0\0\0\0 \xAE\xA9\x0F\0\0\0\0\x10\x91\x99\x10\0\0\0\0 \x90\x89\x11\0\0\0\0\x10sy\x12\0\0\0\0 ri\x13\0\0\0\0\x10UY\x14\0\0\0\0 TI\x15\0\0\0\0\x1079\x16\0\0\0\0 6)\x17\0\0\0\0\x90S\"\x18\0\0\0\0 \x18\t\x19\0\0\0\0\x905\x02\x1A\0\0\0\0\xA04\xF2\x1A\0\0\0\0\x90\x17\xE2\x1B\0\0\0\0\xA0\x16\xD2\x1C\0\0\0\0\x90\xF9\xC1\x1D\0\0\0\0\xA0\xF8\xB1\x1E\0\0\0\0\x90\xDB\xA1\x1F\0\0\0\0\0\"\xFA\x1F\0\0\0\0\x90\xBD\x81!\0\0\0\0 \rV\"\0\0\0\0\x10\xDAj#\0\0\0\0 \xEF5$\0\0\0\0\x10\xBCJ%\0\0\0\0 \xD1\x15&\0\0\0\0\x10\x9E*'\0\0\0\0\xA0\xED\xFE'\0\0\0\0\x10\x80\n)\0\0\0\0\xA0\xCF\xDE)\0\0\0\0\x10b\xEA*\0\0\0\0\xA0\xB1\xBE+\0\0\0\0\x90~\xD3,\0\0\0\0\xA0\x93\x9E-\0\0\0\0\x90`\xB3.\0\0\0\0\xA0u~/\0\0\0\0\x90B\x930\0\0\0\0 \x92g1\0\0\0\0\x90$s2\0\0\0\0 tG3\0\0\0\0\x90\x06S4\0\0\0\0 V'5\0\0\0\0\x90\xE826\0\0\0\0 8\x077\0\0\0\0\x10\x05\x1C8\0\0\0\0 \x1A\xE78\0\0\0\0\x10\xE7\xFB9\0\0\0\0 \xFC\xC6:\0\0\0\0\x10\xC9\xDB;\0\0\0\0\xA0\x18\xB0<\0\0\0\0\x10\xAB\xBB=\0\0\0\0\xA0\xFA\x8F>\0\0\0\0\x10\x8D\x9B?\0\0\0\0\xA0\xDCo@\0\0\0\0\x90\xA9\x84A\0\0\0\0\xA0\xBEOB\0\0\0\0\x90\x8BdC\0\0\0\0\xA0\xA0/D\0\0\0\0\x90mDE\0\0\0\0 \xD3\xF3E\0\0\0\0\x10\x8A-G\0\0\0\0\x01\x02\x01\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x94\x8C\xFF\xFF\xFF\xFF\xFF\xFF\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFFMST\0\0\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xE8\x02o\x03\x9C\x8A\x86}\xFF\xFF\xFF\xFF\xB0\xCB\xB8\x9E\xFF\xFF\xFF\xFF\xA0#\xBB\x9F\xFF\xFF\xFF\xFF\xB0\x0C\xD0\xA0\xFF\xFF\xFF\xFF\x80\xD2\xA2\xA1\xFF\xFF\xFF\xFF\xB0(\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF 4a\xD2\xFF\xFF\xFF\xFF\x90v/\xF7\xFF\xFF\xFF\xFF\x10\xA2(\xF8\xFF\xFF\xFF\xFF\x90\x84\xC5\xF8\xFF\xFF\xFF\xFF ri\x13\0\0\0\0\x10UY\x14\0\0\0\0 TI\x15\0\0\0\0\x1079\x16\0\0\0\0 6)\x17\0\0\0\0\x90S\"\x18\0\0\0\0 \x18\t\x19\0\0\0\0\x905\x02\x1A\0\0\0\0\xA04\xF2\x1A\0\0\0\0\x90\x17\xE2\x1B\0\0\0\0\xA0\x16\xD2\x1C\0\0\0\0\x90\xF9\xC1\x1D\0\0\0\0\xA0\xF8\xB1\x1E\0\0\0\0\x90\xDB\xA1\x1F\0\0\0\0 +v \0\0\0\0\x90\xBD\x81!\0\0\0\0 \rV\"\0\0\0\0\x10\xDAj#\0\0\0\0 \xEF5$\0\0\0\0\x10\xBCJ%\0\0\0\0 \xD1\x15&\0\0\0\0\x10\x9E*'\0\0\0\0\xA0\xED\xFE'\0\0\0\0\x10\x80\n)\0\0\0\0\xA0\xCF\xDE)\0\0\0\0\x10b\xEA*\0\0\0\0\xA0\xB1\xBE+\0\0\0\0\x90~\xD3,\0\0\0\0\xA0\x93\x9E-\0\0\0\0\x90`\xB3.\0\0\0\0\xA0u~/\0\0\0\0\x90B\x930\0\0\0\0 \x92g1\0\0\0\0\x90$s2\0\0\0\0 tG3\0\0\0\0\x90\x06S4\0\0\0\0 V'5\0\0\0\0\x90\xE826\0\0\0\0 8\x077\0\0\0\0\x10\x05\x1C8\0\0\0\0 \x1A\xE78\0\0\0\0\x10\xE7\xFB9\0\0\0\0 \xFC\xC6:\0\0\0\0\x10\xC9\xDB;\0\0\0\0\xA0\x18\xB0<\0\0\0\0\x10\xAB\xBB=\0\0\0\0\xA0\xFA\x8F>\0\0\0\0\x10\x8D\x9B?\0\0\0\0\xA0\xDCo@\0\0\0\0\x90\xA9\x84A\0\0\0\0\xA0\xBEOB\0\0\0\0\x90\x8BdC\0\0\0\0\xA0\xA0/D\0\0\0\0\x90mDE\0\0\0\0 \xD3\xF3E\0\0\0\0\x10\x8A-G\0\0\0\0 \xB5\xD3G\0\0\0\0\x10l\rI\0\0\0\0 \x97\xB3I\0\0\0\0\x10N\xEDJ\0\0\0\0\xA0\xB3\x9CK\0\0\0\0\x90j\xD6L\0\0\0\0\xA0\x95|M\0\0\0\0\x90L\xB6N\0\0\0\0\xA0w\\O\0\0\0\0\x90.\x96P\0\0\0\0\xA0Y\0\0\0\0\0\x7F\x9B?\0\0\0\0\x80\xC0o@\0\0\0\0\x80\x9B\x84A\0\0\0\0\x80\xA2OB\0\0\0\0\x80}dC\0\0\0\0\xE0o\xB7C\0\0\0\0pQDE\0\0\0\0\0\xB7\xF3E\0\0\0\0\xF0m-G\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xEC\xA4\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFFAKST\0p\x81\xFF\xFF\xFF\xFF\xFF\xFF\x01AKDT\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\xA0\x02\xF4\x02\xD1\xFD\xC2?\xFF\xFF\xFF\xFF\xBF7\x87}\xFF\xFF\xFF\xFF\xB0(\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF 4a\xD2\xFF\xFF\xFF\xFF0U\xB8\xFE\xFF\xFF\xFF\xFF 8\xA8\xFF\xFF\xFF\xFF\xFF07\x98\0\0\0\0\0 \x1A\x88\x01\0\0\0\x000\x19x\x02\0\0\0\0\xA06q\x03\0\0\0\0\xB05a\x04\0\0\0\0\xA0\x18Q\x05\0\0\0\0\xB0\x17A\x06\0\0\0\0\xA0\xFA0\x07\0\0\0\0\xB0Q\x8D\x07\0\0\0\0\xA0\xDC\x10\t\0\0\0\x000\xCD\xAD\t\0\0\0\0\xA0\xBE\xF0\n\0\0\0\0\xB0\xBD\xE0\x0B\0\0\0\0 \xDB\xD9\x0C\0\0\0\0\xB0\x9F\xC0\r\0\0\0\0 \xBD\xB9\x0E\0\0\0\x000\xBC\xA9\x0F\0\0\0\0 \x9F\x99\x10\0\0\0\x000\x9E\x89\x11\0\0\0\0 \x81y\x12\0\0\0\x000\x80i\x13\0\0\0\0 cY\x14\0\0\0\x000bI\x15\0\0\0\0 E9\x16\0\0\0\x000D)\x17\0\0\0\0\xA0a\"\x18\0\0\0\x000&\t\x19\0\0\0\0\xA0C\x02\x1A\0\0\0\0\x10\x14+\x1A\0\0\0\0\xB0B\xF2\x1A\0\0\0\0\xA0%\xE2\x1B\0\0\0\0\xB0$\xD2\x1C\0\0\0\0\xA0\x07\xC2\x1D\0\0\0\0\xB0\x06\xB2\x1E\0\0\0\0\xA0\xE9\xA1\x1F\0\0\0\x0009v \0\0\0\0\xA0\xCB\x81!\0\0\0\x000\x1BV\"\0\0\0\0 \xE8j#\0\0\0\x000\xFD5$\0\0\0\0 \xCAJ%\0\0\0\x000\xDF\x15&\0\0\0\0 \xAC*'\0\0\0\0\xB0\xFB\xFE'\0\0\0\0 \x8E\n)\0\0\0\0\xB0\xDD\xDE)\0\0\0\0 p\xEA*\0\0\0\0\xB0\xBF\xBE+\0\0\0\0\xA0\x8C\xD3,\0\0\0\0\xB0\xA1\x9E-\0\0\0\0\xA0n\xB3.\0\0\0\0\xB0\x83~/\0\0\0\0\xA0P\x930\0\0\0\x000\xA0g1\0\0\0\0\xA02s2\0\0\0\x000\x82G3\0\0\0\0\xA0\x14S4\0\0\0\x000d'5\0\0\0\0\xA0\xF626\0\0\0\x000F\x077\0\0\0\0 \x13\x1C8\0\0\0\x000(\xE78\0\0\0\0 \xF5\xFB9\0\0\0\x000\n\xC7:\0\0\0\0 \xD7\xDB;\0\0\0\0\xB0&\xB0<\0\0\0\0 \xB9\xBB=\0\0\0\0\xB0\x08\x90>\0\0\0\0 \x9B\x9B?\0\0\0\0\xB0\xEAo@\0\0\0\0\xA0\xB7\x84A\0\0\0\0\xB0\xCCOB\0\0\0\0\xA0\x99dC\0\0\0\0\xB0\xAE/D\0\0\0\0\xA0{DE\0\0\0\x000\xE1\xF3E\0\0\0\0 \x98-G\0\0\0\0\x01\x02\x03\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x81\xCE\0\0\0\0\0\0\x01}\xFF\xFF\xFF\xFF\xFF\xFFp\x81\xFF\xFF\xFF\xFF\xFF\xFF\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF+08\0\0\x80p\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x88\0\x99\0\x80\xCC\x1E\xFE\xFF\xFF\xFF\xFF \x06\xDAJ\0\0\0\0\xF0\xCA\x8FK\0\0\0\0 \x9C\xA9N\0\0\0\0\x90\xCDCO\0\0\0\0\x80;\nX\0\0\0\0\x10\x0F\xA4Z\0\0\0\0@\x14\xB9[\0\0\0\0\x80\x1D\x8D\\\0\0\0\x000E\x96]\0\0\0\0\0\xC5c^\0\0\0\0<\xA0x_\0\0\0\0P\xB7L`\0\0\0\0<\x82Xa\0\0\0\0P\x99,b\0\0\0\0\x11\0\0\0\0\0\x84x\x12\0\0\0\0\0\xA1\x1E\x13\0\0\0\0\0fX\x14\0\0\0\0\0\x83\xFE\x14\0\0\0\0\0H8\x16\0\0\0\0\0O\x03\x17\0\0\0\0\x80d!\x18\0\0\0\0\x001\xE3\x18\0\0\0\0\x80F\x01\x1A\0\0\0\0\x80c\xA7\x1A\0\0\0\0\x80(\xE1\x1B\0\0\0\0\x80E\x87\x1C\0\0\0\0\x80\n\xC1\x1D\0\0\0\0\x80'g\x1E\0\0\0\0\0\xB2\x97\x1F\0\0\0\0\x80~Y \0\0\0\0\x80\xCE\x80!\0\0\0\0\0\x9BB\"\0\0\0\0\0\xEBi#\0\0\0\0\0}\"$\0\0\0\0\0\xCDI%\0\0\0\0\0_\x02&\0\0\0\0\0\xAF)'\0\0\0\0\0\xB6\xF4'\0\0\0\0\x80\xE1\xED(\0\0\0\0\0\x98\xD4)\0\0\0\0\x80\xC3\xCD*\0\0\0\0\0z\xB4+\0\0\0\0\x80\xA5\xAD,\0\0\0\0\0\\\x94-\0\0\0\0\x80\x87\x8D.\0\0\0\0\0>t/\0\0\0\0\x80im0\0\0\0\0\x80Z]1\0\0\0\0\0\x86V2\0\0\0\0\x80<=3\0\0\0\0\0h64\0\0\0\0\x80\x1E\x1D5\0\0\0\0\0J\x166\0\0\0\0\x80\0\xFD6\0\0\0\0\0,\xF67\0\0\0\0\x80\xE2\xDC8\0\0\0\0\x80\xE9\xA79\0\0\0\0\x80\xC4\xBC:\0\0\0\0\x80*\xBF;\0\0\0\0\0\xE1\xA5<\0\0\0\0\x80\x0C\x9F=\0\0\0\0\0\xC3\x85>\0\0\0\0\x80\xEE~?\0\0\0\0\0\xA5e@\0\0\0\0\x80\xD0^A\0\0\0\0\0\x87EB\0\0\0\0\x80\xB2>C\0\0\0\0\x80\xA3.D\0\0\0\0\x80\x94\x1EE\0\0\0\0\0K\x05F\0\0\0\0\0\xB1\x07G\0\0\0\0\0\xA2\xF7G\0\0\0\0\0\x93\xE7H\0\0\0\0\0\x84\xD7I\0\0\0\0\0u\xC7J\0\0\0\0\xD0\xD3\x1DM\0\0\0\0\x01\x02\x02\x01\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\0\0\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0+05\0\0PF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\x12\0\x802 \xE2\xFF\xFF\xFF\xFF@\"\xDAJ\0\0\0\0\x01\x02\0\0\0\0\0\0\0\0`T\0\0\0\0\0\0PF\0\0\0\0\0\0-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x90\x02\x07\x03\0\xAD\x98\xF6\xFF\xFF\xFF\xFF\xB0\x9F\xE6\xF6\xFF\xFF\xFF\xFF\xC0C\x13\xF8\xFF\xFF\xFF\xFF0\xD3\xC7\xF8\xFF\xFF\xFF\xFF@w\xF4\xF9\xFF\xFF\xFF\xFF\xB06\xD3\xFA\xFF\xFF\xFF\xFF\xC05\xC3\xFB\xFF\xFF\xFF\xFF0S\xBC\xFC\xFF\xFF\xFF\xFF@R\xAC\xFD\xFF\xFF\xFF\xFF05\x9C\xFE\xFF\xFF\xFF\xFF@4\x8C\xFF\xFF\xFF\xFF\xFF\xB0J\xA3\x07\0\0\0\0\xA0o$\x08\0\0\0\0\xB0\xBC0\x17\0\0\0\0\xC0]\x06\x18\0\0\0\0\xB0V\xD1\x18\0\0\0\0\xC0?\xE6\x19\0\0\0\0\xB08\xB1\x1A\0\0\0\0@\\\xCF\x1B\0\0\0\0\xB0\x1A\x91\x1C\0\0\0\0@>\xAF\x1D\0\0\0\0\xB0\xFCp\x1E\0\0\0\0@ \x8F\x1F\0\0\0\x000\x03\x7F \0\0\0\0@\x02o!\0\0\0\x000\xFB9\"\0\0\0\0@\xE4N#\0\0\0\x000\xDD\x19$\0\0\0\0\xC0\08%\0\0\0\x000\xBF\xF9%\0\0\0\0\xC0\xF8\xF2&\0\0\0\x000\xA1\xD9'\0\0\0\0\xC0\xC4\xF7(\0\0\0\0\xB0\xBD\xC2)\0\0\0\0\xC0\xA6\xD7*\0\0\0\0\xB0\x9F\xA2+\0\0\0\0\xC0\x88\xB7,\0\0\0\0\xB0\x81\x82-\0\0\0\0\xC0j\x97.\0\0\0\0\xB0cb/\0\0\0\0@\x87\x800\0\0\0\0\xB0EB1\0\0\0\0@i`2\0\0\0\x000\xD7=3\0\0\0\0@K@4\0\0\0\x000D\x0B5\0\0\0\0@\xB8\r6\0\0\0\0\xB0\xD5\x067\0\0\0\0@\x0F\08\0\0\0\x000\x08\xCB8\0\0\0\0\xC0+\xE99\0\0\0\x000\xEA\xAA:\0\0\0\0\xC0\r\xC9;\0\0\0\x000\xCC\x8A<\0\0\0\0\xC0\xEF\xA8=\0\0\0\x000\xAEj>\0\0\0\0\xC0\xD1\x88?\0\0\0\0\xB0\xCAS@\0\0\0\0\xC0\xB3hA\0\0\0\0\xB0\xAC3B\0\0\0\0\xC0\x95HC\0\0\0\0\xB0\x8E\x13D\0\0\0\0@\xB21E\0\0\0\0\xB0p\xF3E\0\0\0\0@\x94\x11G\0\0\0\x000\x02\xEFG\0\0\0\0@v\xF1H\0\0\0\x000o\xBCI\0\0\0\0@X\xD1J\0\0\0\0\xB0\0\xB8K\0\0\0\0@:\xB1L\0\0\0\x000\x07\xC6M\0\0\0\0\xC0\x82PN\0\0\0\0\xB0\xAE\x9CO\0\0\0\0\xC0\xD9BP\0\0\0\0\xB0\x90|Q\0\0\0\0@\xF6+R\0\0\0\0\xB0r\\S\0\0\0\0@\xD8\x0BT\0\0\0\x000\xE67W\0\0\0\0\xC0\xEC\xAFW\0\0\0\0\xB0\x86CX\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x01\x03\0\0\0\0\0\0\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\t\0\0-\x02\r\0\0\0\0\x01\0\0\0\0\0\0\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF+00\0\0\0\0\0\0\0\0\0\0\x01+02\0\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\0\x18\0\x1B\0\0G\rB\0\0\0\0\x90\x05FB\0\0\0\0\x10\x1BdC\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0 \x1C\0\0\0\0\0\0+05\0\0PF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0$\0\x80\x89X\xE9\xFF\xFF\xFF\xFF\x109M-\0\0\0\0\0\x85\xB5.\0\0\0\x000E\x7Fe\0\0\0\0\x01\0\x01\x02\0\0\0\0\0\0\0\0pb\0\0\0\0\0\0PF\0\0\0\0\0\0+05\0\0PF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xA8\x01\xEC\x01\xDC{\x19\xAA\xFF\xFF\xFF\xFF0\xEF\xA3\xB5\xFF\xFF\xFF\xFF\xA0}'\x15\0\0\0\0\x10\xB2\x18\x16\0\0\0\0 \xB1\x08\x17\0\0\0\0\x90\xE5\xF9\x17\0\0\0\0\xA0\xE4\xE9\x18\0\0\0\0\x10\x19\xDB\x19\0\0\0\0\xA0i\xCC\x1A\0\0\0\0\xC0v\xBC\x1B\0\0\0\0\xC0g\xAC\x1C\0\0\0\0\xC0X\x9C\x1D\0\0\0\0\xC0I\x8C\x1E\0\0\0\0\xC0:|\x1F\0\0\0\0\xC0+l \0\0\0\0\xC0\x1C\\!\0\0\0\0\xC0\rL\"\0\0\0\0\xC0\xFE;#\0\0\0\0\xC0\xEF+$\0\0\0\0\xC0\xE0\x1B%\0\0\0\0\xC0\xD1\x0B&\0\0\0\0@\xFD\x04'\0\0\0\0@\xEE\xF4'\0\0\0\0P\xFC\xF4'\0\0\0\0P\xED\xE4(\0\0\0\0P\x95x)\0\0\0\0@\xD0\xD4)\0\0\0\0@\xC1\xC4*\0\0\0\0@\xB2\xB4+\0\0\0\0@\xA3\xA4,\0\0\0\0@\x94\x94-\0\0\0\0@\x85\x84.\0\0\0\0@vt/\0\0\0\0@gd0\0\0\0\0\xC0\x92]1\0\0\0\0\xC0mr2\0\0\0\0\xC0t=3\0\0\0\0\xC0OR4\0\0\0\0\xC0V\x1D5\0\0\0\0\xC0126\0\0\0\0\xC08\xFD6\0\0\0\0@N\x1B8\0\0\0\0\xC0\x1A\xDD8\0\0\0\0@0\xFB9\0\0\0\0\xC0\xFC\xBC:\0\0\0\0@\x12\xDB;\0\0\0\0@\x19\xA6<\0\0\0\0@\xF4\xBA=\0\0\0\0@\xFB\x85>\0\0\0\0@\xD6\x9A?\0\0\0\0@\xDDe@\0\0\0\0\xC0\xF2\x83A\0\0\0\0 \xC6\xE0e\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x03\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x01$H\0\0\0\0\0\0PF\0\0\0\0\0\0`T\0\0\0\0\0\0pb\0\0\0\0\0\0`T\0\0\0\0\0\0+03\0\x000*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xB8\x02\x10\x03\xD0\xD6\xA3\xB6\xFF\xFF\xFF\xFF\xE0yr\x06\0\0\0\0P\xAB\x0C\x07\0\0\0\0`7$\x08\0\0\0\0\xD0\xDE\xED\x08\0\0\0\0\xE0j\x05\n\0\0\0\0P\x12\xCF\n\0\0\0\0\xE0\xEF\xE7\x0B\0\0\0\0\xD0u\xDA\x0C\0\0\0\0`#\xC9\r\0\0\0\0\xD0\xCA\x92\x0E\0\0\0\0`\x05\xA9\x0F\0\0\0\0\xD0\xACr\x10\0\0\0\0`\xD5\xAD\x1C\0\0\0\0\xD0\t\x9F\x1D\0\0\0\0`\xFD\x92\x1E\0\0\0\0P\xE0\x82\x1F\0\0\0\0`\xDFr \0\0\0\0P\xC2b!\0\0\0\0`\xC1R\"\0\0\0\0\xD0\xDEK#\0\0\0\0`\xBCd$\0\0\0\0\xD0\xC0+%\0\0\0\0`o7&\0\0\0\0\xD0\xA2\x0B'\0\0\0\0\xE0s\x0B(\0\0\0\0PJ\xE2(\0\0\0\0`\xBE\xE4)\0\0\0\0\xD0f\xCB*\0\0\0\0\xE0e\xBB+\0\0\0\0\xD0H\xAB,\0\0\0\0\xE0G\x9B-\0\0\0\0\xD0\xB5x.\0\0\0\0`d\x84/\0\0\0\0\xE0\xA5X0\0\0\0\0`Fd1\0\0\0\0`\xC2A2\0\0\0\0`(D3\0\0\0\0`\xA4!4\0\0\0\0`\n$5\0\0\0\0`\x86\x016\0\0\0\0`\x93z7\0\0\0\0\xE0\xA2\xEA7\0\0\0\0\xE0|\xE28\0\0\0\0`\xBF\xD39\0\0\0\0\xE0^\xC2:\0\0\0\0`\xA1\xB3;\0\0\0\0`\x92\xA3<\0\0\0\0`\x83\x93=\0\0\0\0`t\x83>\0\0\0\0`O\x98?\0\0\0\0`Vc@\0\0\0\0\xE0\xF6nA\0\0\0\0\xE0rLB\0\0\0\0\xE0c]1\0\0\0\0`\x19r2\0\0\0\0` =3\0\0\0\0`\xFBQ4\0\0\0\0`\x02\x1D5\0\0\0\0`\xDD16\0\0\0\0`\xE4\xFC6\0\0\0\0\xE0\xF9\x1A8\0\0\0\0`\xC6\xDC8\0\0\0\0\xE0\xDB\xFA9\0\0\0\0`\xA8\xBC:\0\0\0\0\xE0\xBD\xDA;\0\0\0\0\xE0\xC4\xA5<\0\0\0\0\xE0\x9F\xBA=\0\0\0\0\xE0\xA6\x85>\0\0\0\0\xE0\x81\x9A?\0\0\0\0\xE0\x88e@\0\0\0\0`\x9E\x83A\0\0\0\0\xE0jEB\0\0\0\0`\x80cC\0\0\0\0\xE0L%D\0\0\0\0`bCE\0\0\0\0\xE0.\x05F\0\0\0\0`D#G\0\0\0\0`K\xEEG\0\0\0\0`&\x03I\0\0\0\0`-\xCEI\0\0\0\0`\x08\xE3J\0\0\0\0`\x0F\xAEK\0\0\0\0p\x1D\xAEK\0\0\0\0\xF02\xCCL\0\0\0\0p\xFF\x8DM\0\0\0\0\x01\x02\x03\x02\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x01\x05\x01\x05\x06\x02\x04\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x06\x01\x05\x06\x01\x05d\xA6\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0\xD0\xB6\0\0\0\0\0\0\xE0\xC4\0\0\0\0\0\0\xD0\xB6\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0+05\0\0PF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xA8\x01\xFA\x01\xE0\x94\x19\xAA\xFF\xFF\xFF\xFF@\xFD\xA3\xB5\xFF\xFF\xFF\xFF0\xCE\x18\x16\0\0\0\0 \xB1\x08\x17\0\0\0\x000\xBF\x08\x17\0\0\0\0\xA0\xF3\xF9\x17\0\0\0\0\xB0\xF2\xE9\x18\0\0\0\0 '\xDB\x19\0\0\0\0\xB0w\xCC\x1A\0\0\0\0\xD0\x84\xBC\x1B\0\0\0\0\xD0u\xAC\x1C\0\0\0\0\xD0f\x9C\x1D\0\0\0\0\xD0W\x8C\x1E\0\0\0\0\xD0H|\x1F\0\0\0\0\xD09l \0\0\0\0\xD0*\\!\0\0\0\0\xD0\x1BL\"\0\0\0\0\xD0\x0C<#\0\0\0\0\xD0\xFD+$\0\0\0\0\xD0\xEE\x1B%\0\0\0\0\xD0\xDF\x0B&\0\0\0\0P\x0B\x05'\0\0\0\0P\xFC\xF4'\0\0\0\0`\n\xF5'\0\0\0\0`\xFB\xE4(\0\0\0\0`\xA3x)\0\0\0\0P\xDE\xD4)\0\0\0\0P\xCF\xC4*\0\0\0\0P\xC0\xB4+\0\0\0\0P\xB1\xA4,\0\0\0\0P\xA2\x94-\0\0\0\0P\x93\x84.\0\0\0\0`\xA1\x84.\0\0\0\0`\x92t/\0\0\0\0`\x83d0\0\0\0\0\xE0\xAE]1\0\0\0\0\xE0\x89r2\0\0\0\0\xE0\x90=3\0\0\0\0\xE0kR4\0\0\0\0\xE0r\x1D5\0\0\0\0\xE0M26\0\0\0\0\xE0T\xFD6\0\0\0\0`j\x1B8\0\0\0\0\xE06\xDD8\0\0\0\0`L\xFB9\0\0\0\0\xE0\x18\xBD:\0\0\0\0`.\xDB;\0\0\0\0`5\xA6<\0\0\0\0`\x10\xBB=\0\0\0\0`\x17\x86>\0\0\0\0`\xF2\x9A?\0\0\0\0`\xF9e@\0\0\0\0\xE0\x0E\x84A\0\0\0\0\x01\x02\x03\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x02\x05\x02\x05\x01\x03\x04\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x01\x02\x05\x01\x02\x05\x01\x02\x05\x01\x02\x05\x01\x02\x05\x01\x02\x05\x01\x02\x05\x01\x02\x05\x01\x02\x05\x01\x02\x05\x02\x05 /\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0`T\0\0\0\0\0\0`T\0\0\0\0\0\0PF\0\0\0\0\0\0+05\0\0PF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xA8\x01\x04\x02h\x8E\x19\xAA\xFF\xFF\xFF\xFF@\xFD\xA3\xB5\xFF\xFF\xFF\xFF\xB0\x8B'\x15\0\0\0\0 \xC0\x18\x16\0\0\0\0 \xB1\x08\x17\0\0\0\x000\xBF\x08\x17\0\0\0\0\xA0\xF3\xF9\x17\0\0\0\0\xB0\xF2\xE9\x18\0\0\0\0 '\xDB\x19\0\0\0\0\xB0w\xCC\x1A\0\0\0\0\xD0\x84\xBC\x1B\0\0\0\0\xD0u\xAC\x1C\0\0\0\0\xD0f\x9C\x1D\0\0\0\0\xD0W\x8C\x1E\0\0\0\0\xD0H|\x1F\0\0\0\0\xD09l \0\0\0\0\xD0*\\!\0\0\0\0\xD0\x1BL\"\0\0\0\0\xD0\x0C<#\0\0\0\0\xD0\xFD+$\0\0\0\0\xD0\xEE\x1B%\0\0\0\0\xD0\xDF\x0B&\0\0\0\0P\x0B\x05'\0\0\0\0P\xFC\xF4'\0\0\0\0`\n\xF5'\0\0\0\0`\xFB\xE4(\0\0\0\0`\xA3x)\0\0\0\0P\xDE\xD4)\0\0\0\0P\xCF\xC4*\0\0\0\0P\xC0\xB4+\0\0\0\0P\xB1\xA4,\0\0\0\0P\xA2\x94-\0\0\0\0P\x93\x84.\0\0\0\0P\x84t/\0\0\0\0Pud0\0\0\0\0\xD0\xA0]1\0\0\0\0\xD0{r2\0\0\0\0\xD0\x82=3\0\0\0\0\xD0]R4\0\0\0\0\xD0d\x1D5\0\0\0\0\xD0?26\0\0\0\0\xD0F\xFD6\0\0\0\0P\\\x1B8\0\0\0\0\xD0(\xDD8\0\0\0\0P>\xFB9\0\0\0\0\xD0\n\xBD:\0\0\0\0P \xDB;\0\0\0\0P'\xA6<\0\0\0\0P\x02\xBB=\0\0\0\0P\t\x86>\0\0\0\0P\xE4\x9A?\0\0\0\0P\xEBe@\0\0\0\0\xD0\0\x84A\0\0\0\0\x01\x02\x03\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x02\x05\x02\x05\x01\x03\x04\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x985\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0`T\0\0\0\0\0\0`T\0\0\0\0\0\0PF\0\0\0\0\0\0+05\0\0PF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xD0\0\xED\0D\x8D\x19\xAA\xFF\xFF\xFF\xFF@\xFD\xA3\xB5\xFF\xFF\xFF\xFF\xB0\x8B'\x15\0\0\0\0 \xC0\x18\x16\0\0\0\x000\xBF\x08\x17\0\0\0\0\xA0\xF3\xF9\x17\0\0\0\0\xB0\xF2\xE9\x18\0\0\0\0 '\xDB\x19\0\0\0\0\xB0w\xCC\x1A\0\0\0\0\xD0\x84\xBC\x1B\0\0\0\0\xD0u\xAC\x1C\0\0\0\0\xD0f\x9C\x1D\0\0\0\0\xD0W\x8C\x1E\0\0\0\0\xD0H|\x1F\0\0\0\0\xD09l \0\0\0\0\xD0*\\!\0\0\0\0\xD0\x1BL\"\0\0\0\0\xD0\x0C<#\0\0\0\0\xD0\xFD+$\0\0\0\0\xD0\xEE\x1B%\0\0\0\0\xD0\xDF\x0B&\0\0\0\0P\x0B\x05'\0\0\0\0P\xFC\xF4'\0\0\0\0`\n\xF5'\0\0\0\0`\xFB\xE4(\0\0\0\0`\xA3x)\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x02\x04\xBC6\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0`T\0\0\0\0\0\0PF\0\0\0\0\0\0+05\0\0PF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xA8\x01\xFE\x01P\x93\x19\xAA\xFF\xFF\xFF\xFFP\x0B\xA4\xB5\xFF\xFF\xFF\xFF0\xCE\x18\x16\0\0\0\0 \xB1\x08\x17\0\0\0\x000\xBF\x08\x17\0\0\0\0\xA0\xF3\xF9\x17\0\0\0\0\xB0\xF2\xE9\x18\0\0\0\0 '\xDB\x19\0\0\0\0\xB0w\xCC\x1A\0\0\0\0\xD0\x84\xBC\x1B\0\0\0\0\xD0u\xAC\x1C\0\0\0\0\xD0f\x9C\x1D\0\0\0\0\xD0W\x8C\x1E\0\0\0\0\xD0H|\x1F\0\0\0\0\xD09l \0\0\0\0\xD0*\\!\0\0\0\0\xD0\x1BL\"\0\0\0\0\xD0\x0C<#\0\0\0\0\xD0\xFD+$\0\0\0\0\xD0\xEE\x1B%\0\0\0\0\xD0\xDF\x0B&\0\0\0\0P\x0B\x05'\0\0\0\0P\xFC\xF4'\0\0\0\0`\n\xF5'\0\0\0\0`\xFB\xE4(\0\0\0\0`\xA3x)\0\0\0\0P\xDE\xD4)\0\0\0\0P\xCF\xC4*\0\0\0\0P\xC0\xB4+\0\0\0\0P\xB1\xA4,\0\0\0\0P\xA2\x94-\0\0\0\0P\x93\x84.\0\0\0\0P\x84t/\0\0\0\0Pud0\0\0\0\0\xD0\xA0]1\0\0\0\0\xD0{r2\0\0\0\0\xD0\x82=3\0\0\0\0\xD0]R4\0\0\0\0\xD0d\x1D5\0\0\0\0\xD0?26\0\0\0\0\xD0F\xFD6\0\0\0\0\xE0T\xFD6\0\0\0\0`j\x1B8\0\0\0\0\xE06\xDD8\0\0\0\0`L\xFB9\0\0\0\0\xE0\x18\xBD:\0\0\0\0`.\xDB;\0\0\0\0`5\xA6<\0\0\0\0`\x10\xBB=\0\0\0\0`\x17\x86>\0\0\0\0`\xF2\x9A?\0\0\0\0`\xF9e@\0\0\0\0\xE0\x0E\x84A\0\0\0\0\x01\x02\x03\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x02\x05\x02\x05\x06\x03\x04\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x02\x05\xB00\0\0\0\0\0\x000*\0\0\0\0\0\0PF\0\0\0\0\0\0`T\0\0\0\0\0\0`T\0\0\0\0\0\0PF\0\0\0\0\0\0@8\0\0\0\0\0\0+03\0\x000*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xB0\0\xC6\0\xDC\xB1\x86i\xFF\xFF\xFF\xFF\xE0<0\x9E\xFF\xFF\xFF\xFFPh0\x17\0\0\0\0\xC0\x0F\xFA\x17\0\0\0\0P\xBD\xE8\x18\0\0\0\0@C\xDB\x19\0\0\0\0\xD0\x93\xCC\x1A\0\0\0\0@\xC8\xBD\x1B\0\0\0\0P\xC7\xAD\x1C\0\0\0\0\xE0t\x9C\x1D\0\0\0\0\xE0e\x8C\x1E\0\0\0\0\xE0V|\x1F\0\0\0\0\xE0Gl \0\0\0\0\xE08\\!\0\0\0\0\xE0)L\"\0\0\0\0\xE0\x1A<#\0\0\0\0\xE0\x0B,$\0\0\0\0\xE0\xFC\x1B%\0\0\0\0\xE0\xED\x0B&\0\0\0\0`\x19\x05'\0\0\0\0\0x\xF6'\0\0\0\0\x80\xBA\xE7(\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xA4)\0\0\0\0\0\0\xA0)\0\0\0\0\0\x000*\0\0\0\0\0\0@8\0\0\0\0\0\0+04\0\0@8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xF8\0\x1D\x01D\x95\x19\xAA\xFF\xFF\xFF\xFFP\x0C\xDA\xE7\xFF\xFF\xFF\xFF\xC0\x99'\x15\0\0\0\x000\xCE\x18\x16\0\0\0\0@\xCD\x08\x17\0\0\0\0\xB0\x01\xFA\x17\0\0\0\0\xC0\0\xEA\x18\0\0\0\x0005\xDB\x19\0\0\0\0\xC0\x85\xCC\x1A\0\0\0\0\xE0\x92\xBC\x1B\0\0\0\0\xE0\x83\xAC\x1C\0\0\0\0\xE0t\x9C\x1D\0\0\0\0\xE0e\x8C\x1E\0\0\0\0\xE0V|\x1F\0\0\0\0\xE0Gl \0\0\0\0\xE08\\!\0\0\0\0\xE0)L\"\0\0\0\0\xE0\x1A<#\0\0\0\0\xE0\x0B,$\0\0\0\0\xE0\xFC\x1B%\0\0\0\0\xE0\xED\x0B&\0\0\0\0`\x19\x05'\0\0\0\0`\n\xF5'\0\0\0\0p\x18\xF5'\0\0\0\0p\t\xE5(\0\0\0\0p\xFA\xD4)\0\0\0\0p\xEB\xC4*\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\0\xAD=3\0\0\0\0\0\x88R4\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x02\x04\x02\x04\x03\x02\x04\x03\x02\x04\xBC.\0\0\0\0\0\x000*\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0@8\0\0\0\0\0\0+07\0\0pb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\x12\0\xC4\x85\xB6V\xFF\xFF\xFF\xFF\xC4gj\xA2\xFF\xFF\xFF\xFF\0\x01<^\0\0\0\0\0\0pb\0\0\0\0\0\0+07\0\0pb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \x02{\x02\xFC}\xD5\xA1\xFF\xFF\xFF\xFF \xE1\xA3\xB5\xFF\xFF\xFF\xFF\x90o'\x15\0\0\0\0\0\xA4\x18\x16\0\0\0\0\x10\xA3\x08\x17\0\0\0\0\x80\xD7\xF9\x17\0\0\0\0\x90\xD6\xE9\x18\0\0\0\0\0\x0B\xDB\x19\0\0\0\0\x90[\xCC\x1A\0\0\0\0\xB0h\xBC\x1B\0\0\0\0\xB0Y\xAC\x1C\0\0\0\0\xB0J\x9C\x1D\0\0\0\0\xB0;\x8C\x1E\0\0\0\0\xB0,|\x1F\0\0\0\0\xB0\x1Dl \0\0\0\0\xB0\x0E\\!\0\0\0\0\xB0\xFFK\"\0\0\0\0\xB0\xF0;#\0\0\0\0\xB0\xE1+$\0\0\0\0\xB0\xD2\x1B%\0\0\0\0\xB0\xC3\x0B&\0\0\0\x000\xEF\x04'\0\0\0\x000\xE0\xF4'\0\0\0\0@\xEE\xF4'\0\0\0\0@\xDF\xE4(\0\0\0\0@\x87x)\0\0\0\x000\xC2\xD4)\0\0\0\x000\xB3\xC4*\0\0\0\x000\xA4\xB4+\0\0\0\x000\x95\xA4,\0\0\0\x000\x86\x94-\0\0\0\x000w\x84.\0\0\0\x000ht/\0\0\0\0\x80L\xC7/\0\0\0\0@gd0\0\0\0\0\xC0\x92]1\0\0\0\0\xC0mr2\0\0\0\0\xC0t=3\0\0\0\0\xC0OR4\0\0\0\0\xC0V\x1D5\0\0\0\0\xC0126\0\0\0\0\xC08\xFD6\0\0\0\0@N\x1B8\0\0\0\0\xC0\x1A\xDD8\0\0\0\0@0\xFB9\0\0\0\0\xC0\xFC\xBC:\0\0\0\0@\x12\xDB;\0\0\0\0@\x19\xA6<\0\0\0\0@\xF4\xBA=\0\0\0\0@\xFB\x85>\0\0\0\0@\xD6\x9A?\0\0\0\0@\xDDe@\0\0\0\0\xC0\xF2\x83A\0\0\0\0@\xBFEB\0\0\0\0\xC0\xD4cC\0\0\0\0@\xA1%D\0\0\0\0\xC0\xB6CE\0\0\0\0@\x83\x05F\0\0\0\0\xC0\x98#G\0\0\0\0\xC0\x9F\xEEG\0\0\0\0\xC0z\x03I\0\0\0\0\xC0\x81\xCEI\0\0\0\0\xC0\\\xE3J\0\0\0\0\xC0c\xAEK\0\0\0\0@y\xCCL\0\0\0\0\xC0E\x8EM\0\0\0\x000\xF3KT\0\0\0\0@\xEA\xF6V\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x03\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x84N\0\0\0\0\0\0`T\0\0\0\0\0\0pb\0\0\0\0\0\0\x80p\0\0\0\0\0\0pb\0\0\0\0\0\0EET\0\0 \x1C\0\0\0\0\0\0\x01EEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0\0\0\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0\0\0\0\0\0\0\0\0\x08\x02I\x02\xB8\xC2\xB6V\xFF\xFF\xFF\xFF\xE0ce\xA2\xFF\xFF\xFF\xFFP\x82{\xA3\xFF\xFF\xFF\xFF`\x80N\xA4\xFF\xFF\xFF\xFF\xD0\xB4?\xA5\xFF\xFF\xFF\xFF\xE0'%\xA6\xFF\xFF\xFF\xFF\xD0\x7F'\xA7\xFF\xFF\xFF\xFF\xE0\xF3)\xA8\xFF\xFF\xFF\xFFP\xB2\xEB\xA8\xFF\xFF\xFF\xFF\xE0\x85*\xE8\xFF\xFF\xFF\xFFP-\xF4\xE8\xFF\xFF\xFF\xFF`\xB9\x0B\xEA\xFF\xFF\xFF\xFF\xD0`\xD5\xEA\xFF\xFF\xFF\xFF\xE0\xEC\xEC\xEB\xFF\xFF\xFF\xFFP\x94\xB6\xEC\xFF\xFF\xFF\xFF\xE0q\xCF\xED\xFF\xFF\xFF\xFFP\x19\x99\xEE\xFF\xFF\xFF\xFF`\xA5\xB0\xEF\xFF\xFF\xFF\xFF\xD0Lz\xF0\xFF\xFF\xFF\xFF`^\xA6\x04\0\0\0\0\xD0w+\x05\0\0\0\0\xE0\x03C\x06\0\0\0\0P\xAB\x0C\x07\0\0\0\0`7$\x08\0\0\0\0\xD0\xDE\xED\x08\0\0\0\0\xE0j\x05\n\0\0\0\0P\x12\xCF\n\0\0\0\0\xE0\xEF\xE7\x0B\0\0\0\0P\x97\xB1\x0C\0\0\0\0`#\xC9\r\0\0\0\0\xD0\xCA\x92\x0E\0\0\0\0`\x05\xA9\x0F\0\0\0\0\xD0\xACr\x10\0\0\0\0\xE0.\xF4\x1A\0\0\0\0\xD0\x9C\xD1\x1B\0\0\0\0`b\xD5\x1C\0\0\0\0P\xD0\xB2\x1D\0\0\0\0\xE0\x95\xB6\x1E\0\0\0\0\xD0\x03\x94\x1F\0\0\0\0`\xC9\x97 \0\0\0\0P7u!\0\0\0\0\xE0,\xA3\"\0\0\0\0P\xBCW#\0\0\0\0`_g$\0\0\0\0\xD0\xEF8%\0\0\0\0`\xB5<&\0\0\0\0P#\x1A'\0\0\0\0\xE0\xE8\x1D(\0\0\0\0\xD0V\xFB(\0\0\0\0\xE0m\0*\0\0\0\0\xD0\t\xCE*\0\0\0\0`\xCE\xB4+\0\0\0\0P\xB1\xA4,\0\0\0\0`\xB0\x94-\0\0\0\0P\x93\x84.\0\0\0\0`\x92t/\0\0\0\0Pud0\0\0\0\0\xE0\xAE]1\0\0\0\0\xD0\x91M2\0\0\0\0\xE0\x90=3\0\0\0\0\xD0s-4\0\0\0\0\xE0r\x1D5\0\0\0\0\xD0U\r6\0\0\0\0\xE0T\xFD6\0\0\0\0P\\\x1B8\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01H!\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0+06\0\0`T\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xA8\x01\xEE\x01\x10~\x19\xAA\xFF\xFF\xFF\xFF0\xEF\xA3\xB5\xFF\xFF\xFF\xFF\xA0}'\x15\0\0\0\0\x10\xB2\x18\x16\0\0\0\0 \xB1\x08\x17\0\0\0\0\x90\xE5\xF9\x17\0\0\0\0\xA0\xE4\xE9\x18\0\0\0\0\x10\x19\xDB\x19\0\0\0\0\xA0i\xCC\x1A\0\0\0\0\xC0v\xBC\x1B\0\0\0\0\xC0g\xAC\x1C\0\0\0\0\xC0X\x9C\x1D\0\0\0\0\xC0I\x8C\x1E\0\0\0\0\xC0:|\x1F\0\0\0\0\xC0+l \0\0\0\0\xC0\x1C\\!\0\0\0\0\xC0\rL\"\0\0\0\0\xC0\xFE;#\0\0\0\0\xC0\xEF+$\0\0\0\0\xC0\xE0\x1B%\0\0\0\0\xC0\xD1\x0B&\0\0\0\0@\xFD\x04'\0\0\0\0@\xEE\xF4'\0\0\0\0P\xFC\xF4'\0\0\0\0\xC0\xA3\xBE(\0\0\0\x0007\xE7)\0\0\0\0 \xA5\xC4*\0\0\0\x000\x19\xC7+\0\0\0\0 \x87\xA4,\0\0\0\x000\xFB\xA6-\0\0\0\0 i\x84.\0\0\0\x000\xDD\x86/\0\0\0\0 Kd0\0\0\0\x000\xBFf1\0\0\0\0\xA0gM2\0\0\0\0\xD8\x89=3\0\0\0\0\xC8VR4\0\0\0\0\xD8k\x1D5\0\0\0\0\xC8826\0\0\0\0\xD8M\xFD6\0\0\0\0HU\x1B8\0\0\0\0\xD8/\xDD8\0\0\0\0H7\xFB9\0\0\0\0\xD8\x11\xBD:\0\0\0\0H\x19\xDB;\0\0\0\0X.\xA6<\0\0\0\0H\xFB\xBA=\0\0\0\0X\x10\x86>\0\0\0\0H\xDD\x9A?\0\0\0\0X\xF2e@\0\0\0\0\xC8\xF9\x83A\0\0\0\0X\xD4EB\0\0\0\0 \x92\xFBB\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x02\x04\xF0E\0\0\0\0\0\0PF\0\0\0\0\0\0`T\0\0\0\0\0\0pb\0\0\0\0\0\0`T\0\0\0\0\0\0+09\0\0\x90~\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\x02r\x02\xA0\xF9\xDB\xA1\xFF\xFF\xFF\xFF\0\xC5\xA3\xB5\xFF\xFF\xFF\xFFpS'\x15\0\0\0\0\xE0\x87\x18\x16\0\0\0\0\xF0\x86\x08\x17\0\0\0\0`\xBB\xF9\x17\0\0\0\0p\xBA\xE9\x18\0\0\0\0\xE0\xEE\xDA\x19\0\0\0\0p?\xCC\x1A\0\0\0\0\x90L\xBC\x1B\0\0\0\0\x90=\xAC\x1C\0\0\0\0\x90.\x9C\x1D\0\0\0\0\x90\x1F\x8C\x1E\0\0\0\0\x90\x10|\x1F\0\0\0\0\x90\x01l \0\0\0\0\x90\xF2[!\0\0\0\0\x90\xE3K\"\0\0\0\0\x90\xD4;#\0\0\0\0\x90\xC5+$\0\0\0\0\x90\xB6\x1B%\0\0\0\0\x90\xA7\x0B&\0\0\0\0\x10\xD3\x04'\0\0\0\0\x10\xC4\xF4'\0\0\0\0 \xD2\xF4'\0\0\0\0 \xC3\xE4(\0\0\0\0 kx)\0\0\0\0\x10\xA6\xD4)\0\0\0\0\x10\x97\xC4*\0\0\0\0\x10\x88\xB4+\0\0\0\0\x10y\xA4,\0\0\0\0\x10j\x94-\0\0\0\0\x10[\x84.\0\0\0\0\x10Lt/\0\0\0\0\x10=d0\0\0\0\0\x90h]1\0\0\0\0\x90Cr2\0\0\0\0\x90J=3\0\0\0\0\x90%R4\0\0\0\0\x90,\x1D5\0\0\0\0\x90\x0726\0\0\0\0\x90\x0E\xFD6\0\0\0\0\x10$\x1B8\0\0\0\0\x90\xF0\xDC8\0\0\0\0\x10\x06\xFB9\0\0\0\0\x90\xD2\xBC:\0\0\0\0\x10\xE8\xDA;\0\0\0\0\x10\xEF\xA5<\0\0\0\0\x10\xCA\xBA=\0\0\0\0\x10\xD1\x85>\0\0\0\0\x10\xAC\x9A?\0\0\0\0\x10\xB3e@\0\0\0\0\x90\xC8\x83A\0\0\0\0\x10\x95EB\0\0\0\0\x90\xAAcC\0\0\0\0\x10w%D\0\0\0\0\x90\x8CCE\0\0\0\0\x10Y\x05F\0\0\0\0\x90n#G\0\0\0\0\x90u\xEEG\0\0\0\0\x90P\x03I\0\0\0\0\x90W\xCEI\0\0\0\0\x902\xE3J\0\0\0\0\x909\xAEK\0\0\0\0\x10O\xCCL\0\0\0\0\x90\x1B\x8EM\0\0\0\0\0\xC9KT\0\0\0\0 \xCE\xF6V\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x03\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x05\x01\x02\x04`j\0\0\0\0\0\0\x80p\0\0\0\0\0\0\x90~\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\x90~\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0+0530XM\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\0J\0$\x99\xB6V\xFF\xFF\xFF\xFF\x1C\xBD\x9D\x87\xFF\xFF\xFF\xFF(\x1CZ\xCB\xFF\xFF\xFF\xFF\xA0+\x95\xCC\xFF\xFF\xFF\xFF8\x80u\xD2\xFF\xFF\xFF\xFF(\0\xA61\0\0\0\0 \0q2\0\0\0\0(\xEA?D\0\0\0\0\x01\x02\x03\x04\x02\x04\x05\x03\x06\x02\xDCJ\0\0\0\0\0\0\xE4J\0\0\0\0\0\0XM\0\0\0\0\0\0`T\0\0\0\0\0\0h[\0\0\0\0\0\0h[\0\0\0\0\0\0`T\0\0\0\0\0\0+03\0\x000*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xC8\x03B\x04x\xAB\xF2\xA1\xFF\xFF\xFF\xFF\x80/\x81\xA2\xFF\xFF\xFF\xFFp\x9D^\xA3\xFF\xFF\xFF\xFF\x80\x11a\xA4\xFF\xFF\xFF\xFFp\x7F>\xA5\xFF\xFF\xFF\xFF\x80\xF3@\xA6\xFF\xFF\xFF\xFFpa\x1E\xA7\xFF\xFF\xFF\xFF\x80\xD5 \xA8\xFF\xFF\xFF\xFF\xF0}\x07\xA9\xFF\xFF\xFF\xFF\0R\x8F\xF1\xFF\xFF\xFF\xFFp\x9C[\xF2\xFF\xFF\xFF\xFF\x80(s\xF3\xFF\xFF\xFF\xFFp~;\xF4\xFF\xFF\xFF\xFF\x80\xADU\xF5\xFF\xFF\xFF\xFF\xF0T\x1F\xF6\xFF\xFF\xFF\xFF\0\xE16\xF7\xFF\xFF\xFF\xFF\xF06\xFF\xF7\xFF\xFF\xFF\xFF\0\xDA\x0E\xF9\xFF\xFF\xFF\xFF\xF0\xBB\xE1\xF9\xFF\xFF\xFF\xFF\0H\xF9\xFA\xFF\xFF\xFF\xFFp\xEF\xC2\xFB\xFF\xFF\xFF\xFF\0\xCD\xDB\xFC\xFF\xFF\xFF\xFFpt\xA5\xFD\xFF\xFF\xFF\xFF\x80\0\xBD\xFE\xFF\xFF\xFF\xFF\xF0\xA7\x86\xFF\xFF\xFF\xFF\xFF\x004\x9E\0\0\0\0\0p\xDBg\x01\0\0\0\0\x80g\x7F\x02\0\0\0\0\xF0\x0EI\x03\0\0\0\0\x80\xECa\x04\0\0\0\0\xF0\x93+\x05\0\0\0\0\0 C\x06\0\0\0\0p\xC7\x0C\x07\0\0\0\0\x80S$\x08\0\0\0\0\xF0\xFA\xED\x08\0\0\0\0\0\x87\x05\n\0\0\0\0p.\xCF\n\0\0\0\0\0\x0C\xE8\x0B\0\0\0\0p\xB3\xB1\x0C\0\0\0\0\x80?\xC9\r\0\0\0\0\xF0Yk\x0E\0\0\0\0\0s\xAA\x0F\0\0\0\0p\x8DL\x10\0\0\0\0\0\xC5\xF4\x18\0\0\0\0pm\xDB\x19\0\0\0\0\0J\xD7\x1A\0\0\0\0p\xF2\xBD\x1B\0\0\0\0\0#U\x1E\0\0\0\0p\xE5\x8A\x1F\0\0\0\0\0zG \0\0\0\0\xF0\x19\x89!\0\0\0\0\0t<\"\0\0\0\0\xF0\x9Ek#\0\0\0\0\x80\xBF2$\0\0\0\0pE%%\0\0\0\0\x80D\x15&\0\0\0\0p'\x05'\0\0\0\0\xE0[\xF6'\0\0\0\0P\x90\xE7(\0\0\0\0`\x1B\xE2)\0\0\0\0P\x15\xCA*\0\0\0\0`+\xB2+\0\0\0\0\xD0_\xA3,\0\0\0\0\xE0G\x9B-\0\0\0\0P|\x8C.\0\0\0\0`{|/\0\0\0\0\xD0\xAFm0\0\0\0\0`\0_1\0\0\0\0\xD04P2\0\0\0\0`\xE2>3\0\0\0\0Ph14\0\0\0\0`\xC4\x1E5\0\0\0\0\xD0\x9B\x126\0\0\0\0\xE0\x9A\x027\0\0\0\0P\xCF\xF37\0\0\0\0\xE0\x1F\xE58\0\0\0\0PT\xD69\0\0\0\0`S\xC6:\0\0\0\0\xD0\x87\xB7;\0\0\0\0\xE0\x86\xA7<\0\0\0\0P\xBB\x98=\0\0\0\0`\xBA\x88>\0\0\0\0\xD0\xEEy?\0\0\0\0`?k@\0\0\0\0\xD0s\\A\0\0\0\0\xE0rLB\0\0\0\0P\xA7=C\0\0\0\0`\xA6-D\0\0\0\0P\xFD\x12E\0\0\0\0\xE06\x0CF\0\0\0\0P>*G\0\0\0\0`S\xF5G\0\0\0\0\xD0q\x0BI\0\0\0\0\xE0\xFA\xCBI\0\0\0\0P\x02\xEAJ\0\0\0\0`\x17\xB5K\0\0\0\0P\xE4\xC9L\0\0\0\0`\xF9\x94M\0\0\0\0P\xC6\xA9N\0\0\0\0`\xDBtO\0\0\0\0P\xA8\x89P\0\0\0\0`\xBDTQ\0\0\0\0P\x8AiR\0\0\0\0`\x9F4S\0\0\0\0\xD0\xA6RT\0\0\0\0`\x81\x14U\0\0\0\0\xD0\x882V\0\0\0\0`c\xF4V\0\0\0\0\xD0j\x12X\0\0\0\0\xE0\x7F\xDDX\0\0\0\0\xD0L\xF2Y\0\0\0\0\xE0a\xBDZ\0\0\0\0\xD0.\xD2[\0\0\0\0\xE0C\x9D\\\0\0\0\0\xD0\x10\xB2]\0\0\0\0\xE0%}^\0\0\0\0P-\x9B_\0\0\0\0\xE0\x07]`\0\0\0\0P\x0F{a\0\0\0\0\xE0\xE9\0\0\0\0\x90\x1C\x9B?\0\0\0\0\x90#f@\0\0\0\0\x109\x84A\0\0\0\0\x90\x05FB\0\0\0\0\x10\x1BdC\0\0\0\0\x90\xE7%D\0\0\0\0\x10\xFDCE\0\0\0\0\x90\xC9\x05F\0\0\0\0\x10\xDF#G\0\0\0\0\x10\xE6\xEEG\0\0\0\0\x10\xC1\x03I\0\0\0\0\x10\xC8\xCEI\0\0\0\0\x10\xA3\xE3J\0\0\0\0\x10\xAA\xAEK\0\0\0\0\x90\xBF\xCCL\0\0\0\0\x10\x8C\x8EM\0\0\0\0\x90\xA1\xACN\0\0\0\0\x10nnO\0\0\0\0\x90\x83\x8CP\0\0\0\0\x90\x8AWQ\0\0\0\0\x90elR\0\0\0\0\x90l7S\0\0\0\0\x90GLT\0\0\0\0\x90N\x17U\0\0\0\0\x90),V\0\0\0\0\x900\xF7V\0\0\0\0\xD0\x7F\xD0W\0\0\0\0\x10(\xF5Y\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x03\x01\xD4\x1F\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\x000*\0\0\0\0\0\0EET\0\0 \x1C\0\0\0\0\0\0\x01EEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x04\x06 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x04\x06 \x1C\0\0\0\0\0\0\xE0\x07\xDC\x08\xB0J\xBD}\xFF\xFF\xFF\xFF\0\xCFY\xC8\xFF\xFF\xFF\xFF\0\xA6\xFA\xC8\xFF\xFF\xFF\xFF\x80\x9C8\xC9\xFF\xFF\xFF\xFF\x80\xEB\xE5\xCC\xFF\xFF\xFF\xFF\0\xFE\xAC\xCD\xFF\xFF\xFF\xFF\0\x1F\xC7\xCE\xFF\xFF\xFF\xFF\0\x83\x8F\xCF\xFF\xFF\xFF\xFF\0\xA4\xA9\xD0\xFF\xFF\xFF\xFF\0}\x84\xD1\xFF\xFF\xFF\xFF\x80\xD7\x8A\xD2\xFF\xFF\xFF\xFF\x80\xB0e\xD3\xFF\xFF\xFF\xFF\0\x0Bl\xD4\xFF\xFF\xFF\xFF`c6\xE8\xFF\xFF\xFF\xFFP-\xF4\xE8\xFF\xFF\xFF\xFF`\xB9\x0B\xEA\xFF\xFF\xFF\xFF\xD0`\xD5\xEA\xFF\xFF\xFF\xFF\xF0\xFA\xEC\xEB\xFF\xFF\xFF\xFF\0m\xB5\xEC\xFF\xFF\xFF\xFF\xF0\x7F\xCF\xED\xFF\xFF\xFF\xFF\0\xF2\x97\xEE\xFF\xFF\xFF\xFFp\xB3\xB0\xEF\xFF\xFF\xFF\xFF\x80%y\xF0\xFF\xFF\xFF\xFF\xF0\xE6\x91\xF1\xFF\xFF\xFF\xFF\0YZ\xF2\xFF\xFF\xFF\xFFp\x1As\xF3\xFF\xFF\xFF\xFF\x80\x8C;\xF4\xFF\xFF\xFF\xFFp\x9FU\xF5\xFF\xFF\xFF\xFF\x80\x11\x1E\xF6\xFF\xFF\xFF\xFF\xF0\xD26\xF7\xFF\xFF\xFF\xFF\0E\xFF\xF7\xFF\xFF\xFF\xFFp\x06\x18\xF9\xFF\xFF\xFF\xFF\0\xCA\xE1\xF9\xFF\xFF\xFF\xFF\xF09\xF9\xFA\xFF\xFF\xFF\xFFPB'\xFB\xFF\xFF\xFF\xFF\xE0\x8B|\x08\0\0\0\0\xD0\xB0\xFD\x08\0\0\0\0`\xEA\xF6\t\0\0\0\0\xD03\xA6\n\0\0\0\0`\xFC\xE9\x13\0\0\0\0`[!\x14\0\0\0\0`\xC6\xFA\x1A\0\0\0\0`n\x8E\x1B\0\0\0\0\xE0\xF8\xBE\x1C\0\0\0\0\xD0|w\x1D\0\0\0\0`\xFF\xCC\x1E\0\0\0\0P\x99`\x1F\0\0\0\0`\xB1\x82 \0\0\0\0\xD0\xB5I!\0\0\0\0\xE0\x9E^\"\0\0\0\0P] #\0\0\0\0`0Z$\0\0\0\0P?\0%\0\0\0\0\xE0\xED\x0B&\0\0\0\0\xD0\xE6\xD6&\0\0\0\0\xE0\xCF\xEB'\0\0\0\0P\x03\xC0(\0\0\0\0`\xEC\xD4)\0\0\0\0\xD0\x1F\xA9*\0\0\0\0\xE0e\xBB+\0\0\0\0\xD0\x01\x89,\0\0\0\0\xE0G\x9B-\0\0\0\0P\xA9_.\0\0\0\0\xE0){/\0\0\0\0\xD0\xC5H0\0\0\0\0\xE0\x07\xE70\0\0\0\0`Fd1\0\0\0\0`\xC2A2\0\0\0\0`(D3\0\0\0\0`\xA4!4\0\0\0\0`\n$5\0\0\0\0`\x86\x016\0\0\0\0`a\x167\0\0\0\0PD\x068\0\0\0\0\xE0}\xFF8\0\0\0\0\xD0`\xEF9\0\0\0\0\xE0_\xDF:\0\0\0\0\xD0B\xCF;\0\0\0\0\xE0A\xBF<\0\0\0\0\xD0$\xAF=\0\0\0\0\xE0#\x9F>\0\0\0\0\xD0\x06\x8F?\0\0\0\0\xE0\x05\x7F@\0\0\0\0\xE0\x81\\A\0\0\0\0\xE0\xE7^B\0\0\0\0\xF0\xB7AC\0\0\0\0`\xA6-D\0\0\0\0P\xFD\x12E\0\0\0\0\xE0\xD9\x0EF\0\0\0\0po\xE8F\0\0\0\0\xE0\x18\xECG\0\0\0\0\xD0\x11\xB7H\0\0\0\0\xE0\xFA\xCBI\0\0\0\0`<\xA0J\0\0\0\0\x9C.\xADK\0\0\0\0\xD0\xBDaL\0\0\0\0\x9C\xF9\x94M\0\0\0\0P\xC25N\0\0\0\0`\xDBtO\0\0\0\0\xE0\x91[P\0\0\0\0`\xBDTQ\0\0\0\0P\xA0DR\0\0\0\0`\x9F4S\0\0\0\0PlIT\0\0\0\0\xE0\xD2\x15U\0\0\0\0`\\)V\0\0\0\0\xF0\xC2\xF5V\0\0\0\0`\xCA\x13X\0\0\0\0\xF0\xA4\xD5X\0\0\0\0`\xAC\xF3Y\0\0\0\0\xF0\x86\xB5Z\0\0\0\0`\x8E\xD3[\0\0\0\0\xE0C\x9D\\\0\0\0\0Pb\xB3]\0\0\0\0`w~^\0\0\0\0`R\x93_\0\0\0\0`Y^`\0\0\0\0`\x1D{a\0\0\0\0\xE0\x8C?b\0\0\0\0\xF0^\\c\0\0\0\0\0^Ld\0\0\0\0\xF0@\"\x90\0\0\0\0\xF0x~\x90\0\0\0\0\0\x8EI\x91\0\0\0\0\xF0=\xB8\x91\0\0\0\0\0\xAB\xEF\x91\0\0\0\0\xF0Z^\x92\0\0\0\0\0p)\x93\0\0\0\0\xF0\xAA\x85\x93\0\0\0\0\x80R\xC6\x93\0\0\0\0\xF0<>\x94\0\0\0\0\0R\t\x95\0\0\0\0pR\\\x95\0\0\0\0\x80\xBF\x93\x95\0\0\0\0pY'\x96\0\0\0\0\x004\xE9\x96\0\0\0\0\xF0\xF92\x97\0\0\0\0\0gj\x97\0\0\0\0p;\x07\x98\0\0\0\0\0\x16\xC9\x98\0\0\0\0\xF0f\0\x99\0\0\0\0\x80\x0EA\x99\0\0\0\0p\x1D\xE7\x99\0\0\0\0\x802\xB2\x9A\0\0\0\0p\x0E\xD7\x9A\0\0\0\0\x80{\x0E\x9B\0\0\0\0p\xFF\xC6\x9B\0\0\0\0\x80\x14\x92\x9C\0\0\0\0p{\xA4\x9C\0\0\0\0\0#\xE5\x9C\0\0\0\0p\xE1\xA6\x9D\0\0\0\0\x80\xF6q\x9E\0\0\0\0\xF0\"{\x9E\0\0\0\0\x80\xCA\xBB\x9E\0\0\0\0p\xC3\x86\x9F\0\0\0\0\x807\x89\xA0\0\0\0\0\xF0\xDFo\xA1\0\0\0\0\0\xDF_\xA2\0\0\0\0\xF0\xC1O\xA3\0\0\0\0\0L-\xA4\0\0\0\0\xF0\xA3/\xA5\0\0\0\0\x80\xF3\x03\xA6\0\0\0\0\xF0\x85\x0F\xA7\0\0\0\0\0\x9B\xDA\xA7\0\0\0\0\xF0g\xEF\xA8\0\0\0\0\0}\xBA\xA9\0\0\0\0p\x84\xD8\xAA\0\0\0\0\0_\x9A\xAB\0\0\0\0pf\xB8\xAC\0\0\0\0\0Az\xAD\0\0\0\0pH\x98\xAE\0\0\0\0\0#Z\xAF\0\0\0\0p*x\xB0\0\0\0\0\x80?C\xB1\0\0\0\0p\x0CX\xB2\0\0\0\0\x80!#\xB3\0\0\0\0p\xEE7\xB4\0\0\0\0\x80\x03\x03\xB5\0\0\0\0\xF0\n!\xB6\0\0\0\0\x80\xE5\xE2\xB6\0\0\0\0\xF0\xEC\0\xB8\0\0\0\0\x80\xC7\xC2\xB8\0\0\0\0p\x94\xD7\xB9\0\0\0\0\0\xE4\xAB\xBA\0\0\0\0\xF0;\xAE\xBB\0\0\0\0\0\xC6\x8B\xBC\0\0\0\0p\xE3\x84\xBD\0\0\0\0\0\xA8k\xBE\0\0\0\0pPR\xBF\0\0\0\0\0\x8AK\xC0\0\0\0\0\xF0\xF7(\xC1\0\0\0\0\0e`\xC1\0\0\0\0p\x91i\xC1\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01P \0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0EET\0\0 \x1C\0\0\0\0\0\0\x01EEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x04\x06 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x04\x06 \x1C\0\0\0\0\0\0\xF0\x07\xEE\x08\x19J\xBD}\xFF\xFF\xFF\xFF\0\xCFY\xC8\xFF\xFF\xFF\xFF\0\xA6\xFA\xC8\xFF\xFF\xFF\xFF\x80\x9C8\xC9\xFF\xFF\xFF\xFF\x80\xEB\xE5\xCC\xFF\xFF\xFF\xFF\0\xFE\xAC\xCD\xFF\xFF\xFF\xFF\0\x1F\xC7\xCE\xFF\xFF\xFF\xFF\0\x83\x8F\xCF\xFF\xFF\xFF\xFF\0\xA4\xA9\xD0\xFF\xFF\xFF\xFF\0}\x84\xD1\xFF\xFF\xFF\xFF\x80\xD7\x8A\xD2\xFF\xFF\xFF\xFF\x80\xB0e\xD3\xFF\xFF\xFF\xFF\0\x0Bl\xD4\xFF\xFF\xFF\xFF`c6\xE8\xFF\xFF\xFF\xFFP-\xF4\xE8\xFF\xFF\xFF\xFF`\xB9\x0B\xEA\xFF\xFF\xFF\xFF\xD0`\xD5\xEA\xFF\xFF\xFF\xFF\xF0\xFA\xEC\xEB\xFF\xFF\xFF\xFF\0m\xB5\xEC\xFF\xFF\xFF\xFF\xF0\x7F\xCF\xED\xFF\xFF\xFF\xFF\0\xF2\x97\xEE\xFF\xFF\xFF\xFFp\xB3\xB0\xEF\xFF\xFF\xFF\xFF\x80%y\xF0\xFF\xFF\xFF\xFF\xF0\xE6\x91\xF1\xFF\xFF\xFF\xFF\0YZ\xF2\xFF\xFF\xFF\xFFp\x1As\xF3\xFF\xFF\xFF\xFF\x80\x8C;\xF4\xFF\xFF\xFF\xFFp\x9FU\xF5\xFF\xFF\xFF\xFF\x80\x11\x1E\xF6\xFF\xFF\xFF\xFF\xF0\xD26\xF7\xFF\xFF\xFF\xFF\0E\xFF\xF7\xFF\xFF\xFF\xFFp\x06\x18\xF9\xFF\xFF\xFF\xFF\0\xCA\xE1\xF9\xFF\xFF\xFF\xFF\xF09\xF9\xFA\xFF\xFF\xFF\xFFPB'\xFB\xFF\xFF\xFF\xFF\xE0\x8B|\x08\0\0\0\0\xD0\xB0\xFD\x08\0\0\0\0`\xEA\xF6\t\0\0\0\0\xD03\xA6\n\0\0\0\0`\xFC\xE9\x13\0\0\0\0`[!\x14\0\0\0\0`\xC6\xFA\x1A\0\0\0\0`n\x8E\x1B\0\0\0\0\xE0\xF8\xBE\x1C\0\0\0\0\xD0|w\x1D\0\0\0\0`\xFF\xCC\x1E\0\0\0\0P\x99`\x1F\0\0\0\0`\xB1\x82 \0\0\0\0\xD0\xB5I!\0\0\0\0\xE0\x9E^\"\0\0\0\0P] #\0\0\0\0`0Z$\0\0\0\0P?\0%\0\0\0\0\xE0\xED\x0B&\0\0\0\0\xD0\xE6\xD6&\0\0\0\0\xE0\xCF\xEB'\0\0\0\0P\x03\xC0(\0\0\0\0`\xEC\xD4)\0\0\0\0\xD0\x1F\xA9*\0\0\0\0\xE0e\xBB+\0\0\0\0\xD0\x01\x89,\0\0\0\0\xE0G\x9B-\0\0\0\0P\xA9_.\0\0\0\0\xE0){/\0\0\0\0\xD0\xC5H0\0\0\0\0\xE0\x07\xE70\0\0\0\0`Fd1\0\0\0\0`\xC2A2\0\0\0\0`(D3\0\0\0\0`\xA4!4\0\0\0\0`\n$5\0\0\0\0`\x86\x016\0\0\0\0`a\x167\0\0\0\0PD\x068\0\0\0\0\xE0}\xFF8\0\0\0\0\xD0`\xEF9\0\0\0\0\xE0_\xDF:\0\0\0\0\xD0B\xCF;\0\0\0\0\xE0A\xBF<\0\0\0\0\xD0$\xAF=\0\0\0\0\xE0#\x9F>\0\0\0\0\xD0\x06\x8F?\0\0\0\0\xE0\x05\x7F@\0\0\0\0\xE0\x81\\A\0\0\0\0\xE0\xE7^B\0\0\0\0\xF0\xB7AC\0\0\0\0`\xA6-D\0\0\0\0P\xFD\x12E\0\0\0\0\xE0\xD9\x0EF\0\0\0\0po\xE8F\0\0\0\0\xE0\x18\xECG\0\0\0\0P\x06\xBBH\0\0\0\0\xE0\xFA\xCBI\0\0\0\0`<\xA0J\0\0\0\0\xE0\xDC\xABK\0\0\0\0\xD0\xBDaL\0\0\0\0\x9C\xF9\x94M\0\0\0\0P\xC25N\0\0\0\0\xE0\x0B\\N\0\0\0\0P\xDC\x84N\0\0\0\0`\xDBtO\0\0\0\0\xE0\x91[P\0\0\0\0`\xBDTQ\0\0\0\0P\xA0DR\0\0\0\0`\x9F4S\0\0\0\0PlIT\0\0\0\0\xE0\xD2\x15U\0\0\0\0`\\)V\0\0\0\0\xF0\xC2\xF5V\0\0\0\0`\xCA\x13X\0\0\0\0\xF0\xA4\xD5X\0\0\0\0`\xAC\xF3Y\0\0\0\0\xF0\x86\xB5Z\0\0\0\0`\x8E\xD3[\0\0\0\0\xE0C\x9D\\\0\0\0\0Pb\xB3]\0\0\0\0`w~^\0\0\0\0`R\x93_\0\0\0\0`Y^`\0\0\0\0`\x1D{a\0\0\0\0\xE0\x8C?b\0\0\0\0\xF0^\\c\0\0\0\0\0^Ld\0\0\0\0\xF0@\"\x90\0\0\0\0\xF0x~\x90\0\0\0\0\0\x8EI\x91\0\0\0\0\xF0=\xB8\x91\0\0\0\0\0\xAB\xEF\x91\0\0\0\0\xF0Z^\x92\0\0\0\0\0p)\x93\0\0\0\0\xF0\xAA\x85\x93\0\0\0\0\x80R\xC6\x93\0\0\0\0\xF0<>\x94\0\0\0\0\0R\t\x95\0\0\0\0pR\\\x95\0\0\0\0\x80\xBF\x93\x95\0\0\0\0pY'\x96\0\0\0\0\x004\xE9\x96\0\0\0\0\xF0\xF92\x97\0\0\0\0\0gj\x97\0\0\0\0p;\x07\x98\0\0\0\0\0\x16\xC9\x98\0\0\0\0\xF0f\0\x99\0\0\0\0\x80\x0EA\x99\0\0\0\0p\x1D\xE7\x99\0\0\0\0\x802\xB2\x9A\0\0\0\0p\x0E\xD7\x9A\0\0\0\0\x80{\x0E\x9B\0\0\0\0p\xFF\xC6\x9B\0\0\0\0\x80\x14\x92\x9C\0\0\0\0p{\xA4\x9C\0\0\0\0\0#\xE5\x9C\0\0\0\0p\xE1\xA6\x9D\0\0\0\0\x80\xF6q\x9E\0\0\0\0\xF0\"{\x9E\0\0\0\0\x80\xCA\xBB\x9E\0\0\0\0p\xC3\x86\x9F\0\0\0\0\x807\x89\xA0\0\0\0\0\xF0\xDFo\xA1\0\0\0\0\0\xDF_\xA2\0\0\0\0\xF0\xC1O\xA3\0\0\0\0\0L-\xA4\0\0\0\0\xF0\xA3/\xA5\0\0\0\0\x80\xF3\x03\xA6\0\0\0\0\xF0\x85\x0F\xA7\0\0\0\0\0\x9B\xDA\xA7\0\0\0\0\xF0g\xEF\xA8\0\0\0\0\0}\xBA\xA9\0\0\0\0p\x84\xD8\xAA\0\0\0\0\0_\x9A\xAB\0\0\0\0pf\xB8\xAC\0\0\0\0\0Az\xAD\0\0\0\0pH\x98\xAE\0\0\0\0\0#Z\xAF\0\0\0\0p*x\xB0\0\0\0\0\x80?C\xB1\0\0\0\0p\x0CX\xB2\0\0\0\0\x80!#\xB3\0\0\0\0p\xEE7\xB4\0\0\0\0\x80\x03\x03\xB5\0\0\0\0\xF0\n!\xB6\0\0\0\0\x80\xE5\xE2\xB6\0\0\0\0\xF0\xEC\0\xB8\0\0\0\0\x80\xC7\xC2\xB8\0\0\0\0p\x94\xD7\xB9\0\0\0\0\0\xE4\xAB\xBA\0\0\0\0\xF0;\xAE\xBB\0\0\0\0\0\xC6\x8B\xBC\0\0\0\0p\xE3\x84\xBD\0\0\0\0\0\xA8k\xBE\0\0\0\0pPR\xBF\0\0\0\0\0\x8AK\xC0\0\0\0\0\xF0\xF7(\xC1\0\0\0\0\0e`\xC1\0\0\0\0p\x91i\xC1\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xE7 \0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0+07\0\0pb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0H\0Q\0\x8AC\x8C\x88\xFF\xFF\xFF\xFF\n+\xA3\x91\xFF\xFF\xFF\xFF\x80\xE65\xCD\xFF\xFF\xFF\xFFp\xCEY\xD1\xFF\xFF\xFF\xFF\xF0>;\xD2\xFF\xFF\xFF\xFF\x10\xBB2\xD5\xFF\xFF\xFF\xFF\x90\xF2\xB6\xE4\xFF\xFF\xFF\xFF\0\x98/\xED\xFF\xFF\xFF\xFF\0\xC7=\n\0\0\0\0\0\x01\x02\x03\x01\x02\x01\x02\x01\xF6c\0\0\0\0\0\0pb\0\0\0\0\0\0\x80p\0\0\0\0\0\0\x90~\0\0\0\0\0\0HKT\0\0\x80p\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0(\x02\x8E\x02\x90ci\x85\xFF\xFF\xFF\xFF01M\xCA\xFF\xFF\xFF\xFF0\x93\xDB\xCA\xFF\xFF\xFF\xFFxqK\xCB\xFF\xFF\xFF\xFF\x90\xDE\xA0\xD2\xFF\xFF\xFF\xFF\x80\xD7k\xD3\xFF\xFF\xFF\xFF\xB8X\x93\xD4\xFF\xFF\xFF\xFF8\xB0B\xD5\xFF\xFF\xFF\xFF\xB8:s\xD6\xFF\xFF\xFF\xFF\xB8A>\xD7\xFF\xFF\xFF\xFF\xB82.\xD8\xFF\xFF\xFF\xFF\xB89\xF9\xD8\xFF\xFF\xFF\xFF\xB8\x14\x0E\xDA\xFF\xFF\xFF\xFF\xB8\x1B\xD9\xDA\xFF\xFF\xFF\xFF\xB8\xF6\xED\xDB\xFF\xFF\xFF\xFF\xB8\xFD\xB8\xDC\xFF\xFF\xFF\xFF\xB8\xD8\xCD\xDD\xFF\xFF\xFF\xFF8\x1A\xA2\xDE\xFF\xFF\xFF\xFF8\xF5\xB6\xDF\xFF\xFF\xFF\xFF8\xFC\x81\xE0\xFF\xFF\xFF\xFF(\xC9\x96\xE1\xFF\xFF\xFF\xFF8iO\xE2\xFF\xFF\xFF\xFF(\xABv\xE3\xFF\xFF\xFF\xFF8K/\xE4\xFF\xFF\xFF\xFF\xA8\xC7_\xE5\xFF\xFF\xFF\xFF8-\x0F\xE6\xFF\xFF\xFF\xFF\xA8\xA9?\xE7\xFF\xFF\xFF\xFF\xB8I\xF8\xE7\xFF\xFF\xFF\xFF\xA8\x8B\x1F\xE9\xFF\xFF\xFF\xFF\xB8+\xD8\xE9\xFF\xFF\xFF\xFF\xA8m\xFF\xEA\xFF\xFF\xFF\xFF\xB8\r\xB8\xEB\xFF\xFF\xFF\xFF\xA8O\xDF\xEC\xFF\xFF\xFF\xFF\xB8\xEF\x97\xED\xFF\xFF\xFF\xFF(l\xC8\xEE\xFF\xFF\xFF\xFF\xB8\xD1w\xEF\xFF\xFF\xFF\xFF(N\xA8\xF0\xFF\xFF\xFF\xFF\xB8\xB3W\xF1\xFF\xFF\xFF\xFF(0\x88\xF2\xFF\xFF\xFF\xFF8\xD0@\xF3\xFF\xFF\xFF\xFF(\x12h\xF4\xFF\xFF\xFF\xFF8\xB2 \xF5\xFF\xFF\xFF\xFF(\xF4G\xF6\xFF\xFF\xFF\xFF8~%\xF7\xFF\xFF\xFF\xFF(a\x15\xF8\xFF\xFF\xFF\xFF8`\x05\xF9\xFF\xFF\xFF\xFF(C\xF5\xF9\xFF\xFF\xFF\xFF8B\xE5\xFA\xFF\xFF\xFF\xFF\xA8_\xDE\xFB\xFF\xFF\xFF\xFF\xB8^\xCE\xFC\xFF\xFF\xFF\xFF\xA8A\xBE\xFD\xFF\xFF\xFF\xFF\xB8@\xAE\xFE\xFF\xFF\xFF\xFF\xA8#\x9E\xFF\xFF\xFF\xFF\xFF\xB8\"\x8E\0\0\0\0\0\xA8\x05~\x01\0\0\0\0\xB8\x04n\x02\0\0\0\0\xA8\xE7]\x03\0\0\0\0\xB8\xE6M\x04\0\0\0\0(\x04G\x05\0\0\0\08\x037\x06\0\0\0\0(\xE6&\x07\0\0\0\08=\x83\x07\0\0\0\0(\xC8\x06\t\0\0\0\08\xC7\xF6\t\0\0\0\0(\xAA\xE6\n\0\0\0\08\xA9\xD6\x0B\0\0\0\0(\x8C\xC6\x0C\0\0\0\089\x9B\x11\0\0\0\0\xA8lo\x12\0\0\0\0\x01\x02\x03\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\nk\0\0\0\0\0\0\x80p\0\0\0\0\0\0\x90~\0\0\0\0\0\0\x88w\0\0\0\0\0\0\x90~\0\0\0\0\0\0+07\0\0pb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x80\x01\xB0\x01\x94\xFC\xD3\x86\xFF\xFF\xFF\xFF\xA0\xEA\x0B\x0F\0\0\0\0\x90\xD6\xE9\x18\0\0\0\0\0\x0B\xDB\x19\0\0\0\0\x90[\xCC\x1A\0\0\0\0\x80>\xBC\x1B\0\0\0\0\x90=\xAC\x1C\0\0\0\0\x80 \x9C\x1D\0\0\0\0\x90\x1F\x8C\x1E\0\0\0\0\x80\x02|\x1F\0\0\0\0\x90\x01l \0\0\0\0\x80\xE4[!\0\0\0\0\x90\xE3K\"\0\0\0\0\x80\xC6;#\0\0\0\0\x90\xC5+$\0\0\0\0\x80\xA8\x1B%\0\0\0\0\x90\xA7\x0B&\0\0\0\0\0\xC5\x04'\0\0\0\0\x10\xC4\xF4'\0\0\0\0\0\xA7\xE4(\0\0\0\0\x10\xA6\xD4)\0\0\0\0\0\x89\xC4*\0\0\0\0\x10\x88\xB4+\0\0\0\0\0k\xA4,\0\0\0\0\x10j\x94-\0\0\0\0\0M\x84.\0\0\0\0\x10Lt/\0\0\0\0\0/d0\0\0\0\0\x90h]1\0\0\0\0\x80KM2\0\0\0\0\x90J=3\0\0\0\0\x80--4\0\0\0\0\x90,\x1D5\0\0\0\0\x80\x0F\r6\0\0\0\0\xB0\xC1\xE9:\0\0\0\0\xA0\xBA\xB4;\0\0\0\0\xB0\xB9\xA4<\0\0\0\0\xA0\x9C\x94=\0\0\0\0\xB0\x9B\x84>\0\0\0\0\xA0~t?\0\0\0\0\xB0}d@\0\0\0\0\xA0`TA\0\0\0\0\xB0_DB\0\0\0\0\xA0B4C\0\0\0\0\xB0A$D\0\0\0\0 _\x1DE\0\0\0\0\xB0\xA8\x15U\0\0\0\0\x80o\x05V\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xECU\0\0\0\0\0\0`T\0\0\0\0\0\0pb\0\0\0\0\0\0\x80p\0\0\0\0\0\0+08\0\0\x80p\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\x02r\x02?\x82\xB6V\xFF\xFF\xFF\xFF\xBF\x0F\x12\xA2\xFF\xFF\xFF\xFF\x10\xD3\xA3\xB5\xFF\xFF\xFF\xFF\x80a'\x15\0\0\0\0\xF0\x95\x18\x16\0\0\0\0\0\x95\x08\x17\0\0\0\0p\xC9\xF9\x17\0\0\0\0\x80\xC8\xE9\x18\0\0\0\0\xF0\xFC\xDA\x19\0\0\0\0\x80M\xCC\x1A\0\0\0\0\xA0Z\xBC\x1B\0\0\0\0\xA0K\xAC\x1C\0\0\0\0\xA0<\x9C\x1D\0\0\0\0\xA0-\x8C\x1E\0\0\0\0\xA0\x1E|\x1F\0\0\0\0\xA0\x0Fl \0\0\0\0\xA0\0\\!\0\0\0\0\xA0\xF1K\"\0\0\0\0\xA0\xE2;#\0\0\0\0\xA0\xD3+$\0\0\0\0\xA0\xC4\x1B%\0\0\0\0\xA0\xB5\x0B&\0\0\0\0 \xE1\x04'\0\0\0\0 \xD2\xF4'\0\0\0\x000\xE0\xF4'\0\0\0\x000\xD1\xE4(\0\0\0\x000yx)\0\0\0\0 \xB4\xD4)\0\0\0\0 \xA5\xC4*\0\0\0\0 \x96\xB4+\0\0\0\0 \x87\xA4,\0\0\0\0 x\x94-\0\0\0\0 i\x84.\0\0\0\0 Zt/\0\0\0\0 Kd0\0\0\0\0\xA0v]1\0\0\0\0\xA0Qr2\0\0\0\0\xA0X=3\0\0\0\0\xA03R4\0\0\0\0\xA0:\x1D5\0\0\0\0\xA0\x1526\0\0\0\0\xA0\x1C\xFD6\0\0\0\0 2\x1B8\0\0\0\0\xA0\xFE\xDC8\0\0\0\0 \x14\xFB9\0\0\0\0\xA0\xE0\xBC:\0\0\0\0 \xF6\xDA;\0\0\0\0 \xFD\xA5<\0\0\0\0 \xD8\xBA=\0\0\0\0 \xDF\x85>\0\0\0\0 \xBA\x9A?\0\0\0\0 \xC1e@\0\0\0\0\xA0\xD6\x83A\0\0\0\0 \xA3EB\0\0\0\0\xA0\xB8cC\0\0\0\0 \x85%D\0\0\0\0\xA0\x9ACE\0\0\0\0 g\x05F\0\0\0\0\xA0|#G\0\0\0\0\xA0\x83\xEEG\0\0\0\0\xA0^\x03I\0\0\0\0\xA0e\xCEI\0\0\0\0\xA0@\xE3J\0\0\0\0\xA0G\xAEK\0\0\0\0 ]\xCCL\0\0\0\0\xA0)\x8EM\0\0\0\0\x10\xD7KT\0\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x03\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x05\x02\x04\xC1a\0\0\0\0\0\0pb\0\0\0\0\0\0\x80p\0\0\0\0\0\0\x90~\0\0\0\0\0\0\x80p\0\0\0\0\0\0\x90~\0\0\0\0\0\0WIB\0\0pb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\0H\0`If?\xFF\xFF\xFF\xFF\xE0\x85x\xA9\xFF\xFF\xFF\xFF`\xDE\x16\xBA\xFF\xFF\xFF\xFF\x88\x83\xBF\xCB\xFF\xFF\xFF\xFFp\xEEV\xD2\xFF\xFF\xFF\xFF\x08\xC6<\xD7\xFF\xFF\xFF\xFF\0&\xFF\xDA\xFF\xFF\xFF\xFF\x88\xBE\xB5\xF4\xFF\xFF\xFF\xFF\0\x01\x02\x03\x02\x04\x02\x05 d\0\0\0\0\0\0 g\0\0\0\0\0\0xi\0\0\0\0\0\0\x90~\0\0\0\0\0\0\x80p\0\0\0\0\0\0pb\0\0\0\0\0\0WIT\0\0\x90~\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\0\x1B\0\x98\xC1\x16\xBA\xFF\xFF\xFF\xFF\xF0\xB9X\xD0\xFF\xFF\xFF\xFFh\xA2\xB5\xF4\xFF\xFF\xFF\xFF\x01\x02\x01\xE8\x83\0\0\0\0\0\0\x90~\0\0\0\0\0\0\x98\x85\0\0\0\0\0\0IST\0\0 \x1C\0\0\0\0\0\0\x01IDT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x04\x05 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0 \x1C\0\0\0\0\0\0(\x03\x8D\x03\xFA\xC2\xB6V\xFF\xFF\xFF\xFF\x88E0\x9E\xFF\xFF\xFF\xFF\0\xCFY\xC8\xFF\xFF\xFF\xFF\0\xA6\xFA\xC8\xFF\xFF\xFF\xFF\x80\x9C8\xC9\xFF\xFF\xFF\xFF\x80\xEB\xE5\xCC\xFF\xFF\xFF\xFF\0\xFE\xAC\xCD\xFF\xFF\xFF\xFF\0\x1F\xC7\xCE\xFF\xFF\xFF\xFF\0\x83\x8F\xCF\xFF\xFF\xFF\xFF\0\xA4\xA9\xD0\xFF\xFF\xFF\xFF\0}\x84\xD1\xFF\xFF\xFF\xFF\x80\xD7\x8A\xD2\xFF\xFF\xFF\xFF\x80\xB0e\xD3\xFF\xFF\xFF\xFF\0\x0Bl\xD4\xFF\xFF\xFF\xFF\x800Z\xD7\xFF\xFF\xFF\xFF\0X\xDF\xD7\xFF\xFF\xFF\xFF\x80\xC3/\xD8\xFF\xFF\xFF\xFF\0c\x1E\xD9\xFF\xFF\xFF\xFF\0\xF7\x10\xDA\xFF\xFF\xFF\xFF\0\xD0\xEB\xDA\xFF\xFF\xFF\xFF\x004\xB4\xDB\xFF\xFF\xFF\xFF\0=\xB9\xDC\xFF\xFF\xFF\xFF\0\x8D\xE0\xDD\xFF\xFF\xFF\xFF\x80\xCE\xB4\xDE\xFF\xFF\xFF\xFF\x80\xBF\xA4\xDF\xFF\xFF\xFF\xFF\0v\x8B\xE0\xFF\xFF\xFF\xFF\0}V\xE1\xFF\xFF\xFF\xFF\x80f\xBE\xE2\xFF\xFF\xFF\xFF\0_6\xE3\xFF\xFF\xFF\xFF\x80H\x9E\xE4\xFF\xFF\xFF\xFF\0A\x16\xE5\xFF\xFF\xFF\xFF\0\xF0t\xE6\xFF\xFF\xFF\xFF\x80\xD2\x11\xE7\xFF\xFF\xFF\xFF\x80\xAD&\xE8\xFF\xFF\xFF\xFF\0z\xE8\xE8\xFF\xFF\xFF\xFF\xE0\x8B|\x08\0\0\0\0\xD0\xB0\xFD\x08\0\0\0\0`\xEA\xF6\t\0\0\0\0\xD03\xA6\n\0\0\0\0`\xFC\xE9\x13\0\0\0\0`[!\x14\0\0\0\0`\xC6\xFA\x1A\0\0\0\0`n\x8E\x1B\0\0\0\0\xE0\xF8\xBE\x1C\0\0\0\0\xD0|w\x1D\0\0\0\0`\xFF\xCC\x1E\0\0\0\0P\x99`\x1F\0\0\0\0`\xB1\x82 \0\0\0\0\xD0\xB5I!\0\0\0\0\xE0\x9E^\"\0\0\0\0P] #\0\0\0\0`0Z$\0\0\0\0P?\0%\0\0\0\0\xE0\xED\x0B&\0\0\0\0\xD0\xE6\xD6&\0\0\0\0\xE0\xCF\xEB'\0\0\0\0P\x03\xC0(\0\0\0\0`\xEC\xD4)\0\0\0\0\xD0\x1F\xA9*\0\0\0\0\xE0e\xBB+\0\0\0\0\xD0\x01\x89,\0\0\0\0\xE0G\x9B-\0\0\0\0P\xA9_.\0\0\0\0\xE0){/\0\0\0\0\xD0\xC5H0\0\0\0\0\xE0\x96H1\0\0\0\0Pn<2\0\0\0\0`\xB313\0\0\0\0\xD0\xFE\x1A4\0\0\0\0`\x95\x115\0\0\0\0P\xA6\xF15\0\0\0\0\x80\x08\x047\0\0\0\0p\x01\xCF7\0\0\0\0\x80_\xF68\0\0\0\0\xE0\xF9\xDC9\0\0\0\0p\xED\xD0:\0\0\0\0`[\xAE;\0\0\0\0p\xA0\xA3<\0\0\0\0`\xB2\xA0=\0\0\0\0p\x82\x83>\0\0\0\0\xE0\x9F|?\0\0\0\0p6s@\0\0\0\0`\xA4PA\0\0\0\0\0\x8FLB\0\0\0\0pOHC\0\0\0\0\0q,D\0\0\0\0\xF0\xF6\x1EE\0\0\0\0\0S\x0CF\0\0\0\0\xF0c\xECF\0\0\0\0\x005\xECG\0\0\0\0p\xF5\xE7H\0\0\0\0\0\x17\xCCI\0\0\0\0\xF0\x9C\xBEJ\0\0\0\0\0\xF9\xABK\0\0\0\0\xF0\t\x8CL\0\0\0\0\x80\x15\x95M\0\0\0\0p\x9B\x87N\0\0\0\0\x80\xF7tO\0\0\0\0\xF0B^P\0\0\0\0\x80\xD9TQ\0\0\0\0pIlR\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x06!\0\0\0\0\0\0\xF8 \0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0@8\0\0\0\0\0\0+0430H?\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\x12\0\xA0\x9A\x86i\xFF\xFF\xFF\xFF@\xD7\xF9\xD0\xFF\xFF\xFF\xFF\x01\x02\xE0@\0\0\0\0\0\0@8\0\0\0\0\0\0H?\0\0\0\0\0\0+12\0\0\xC0\xA8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x02h\x02\xC4\x96R\xA7\xFF\xFF\xFF\xFF\xD0\x9A\xA3\xB5\xFF\xFF\xFF\xFF@)'\x15\0\0\0\0\xB0]\x18\x16\0\0\0\0\xC0\\\x08\x17\0\0\0\x000\x91\xF9\x17\0\0\0\0@\x90\xE9\x18\0\0\0\0\xB0\xC4\xDA\x19\0\0\0\0@\x15\xCC\x1A\0\0\0\0`\"\xBC\x1B\0\0\0\0`\x13\xAC\x1C\0\0\0\0`\x04\x9C\x1D\0\0\0\0`\xF5\x8B\x1E\0\0\0\0`\xE6{\x1F\0\0\0\0`\xD7k \0\0\0\0`\xC8[!\0\0\0\0`\xB9K\"\0\0\0\0`\xAA;#\0\0\0\0`\x9B+$\0\0\0\0`\x8C\x1B%\0\0\0\0`}\x0B&\0\0\0\0\xE0\xA8\x04'\0\0\0\0\xE0\x99\xF4'\0\0\0\0\xF0\xA7\xF4'\0\0\0\0\xF0\x98\xE4(\0\0\0\0\xF0@x)\0\0\0\0\xE0{\xD4)\0\0\0\0\xE0l\xC4*\0\0\0\0\xE0]\xB4+\0\0\0\0\xE0N\xA4,\0\0\0\0\xE0?\x94-\0\0\0\0\xE00\x84.\0\0\0\0\xE0!t/\0\0\0\0\xE0\x12d0\0\0\0\0`>]1\0\0\0\0`\x19r2\0\0\0\0` =3\0\0\0\0`\xFBQ4\0\0\0\0`\x02\x1D5\0\0\0\0`\xDD16\0\0\0\0`\xE4\xFC6\0\0\0\0\xE0\xF9\x1A8\0\0\0\0`\xC6\xDC8\0\0\0\0\xE0\xDB\xFA9\0\0\0\0`\xA8\xBC:\0\0\0\0\xE0\xBD\xDA;\0\0\0\0\xE0\xC4\xA5<\0\0\0\0\xE0\x9F\xBA=\0\0\0\0\xE0\xA6\x85>\0\0\0\0\xE0\x81\x9A?\0\0\0\0\xE0\x88e@\0\0\0\0`\x9E\x83A\0\0\0\0\xE0jEB\0\0\0\0`\x80cC\0\0\0\0\xE0L%D\0\0\0\0`bCE\0\0\0\0\xE0.\x05F\0\0\0\0`D#G\0\0\0\0`K\xEEG\0\0\0\0`&\x03I\0\0\0\0`-\xCEI\0\0\0\0`\x08\xE3J\0\0\0\0`\x0F\xAEK\0\0\0\0p\x1D\xAEK\0\0\0\0\xF02\xCCL\0\0\0\0p\xFF\x8DM\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x03\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x01\x02\x04\x01\x02\x04\xBC\x94\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0\xD0\xB6\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0PKT\0\0PF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0H\0Q\0\xA4\xFC~\x89\xFF\xFF\xFF\xFF\xA82\x95\xCC\xFF\xFF\xFF\xFF\x98\x12t\xD2\xFF\xFF\xFF\xFF\xA8\xE0\xA8\xDD\xFF\xFF\xFF\xFF0\xABO\x02\0\0\0\0\xB0E\xAF<\0\0\0\0\xA0(\x9F=\0\0\0\x000\xA0AH\0\0\0\0\xA0G\x0BI\0\0\0\0\x01\x02\x01\x03\x03\x04\x03\x04\x03\xDC>\0\0\0\0\0\0XM\0\0\0\0\0\0h[\0\0\0\0\0\0PF\0\0\0\0\0\0`T\0\0\0\0\0\0+0545\xDCP\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\x12\0\x84}\xF2\xA1\xFF\xFF\xFF\xFF\xA80\x18\x1E\0\0\0\0\x01\x02\xFCO\0\0\0\0\0\0XM\0\0\0\0\0\0\xDCP\0\0\0\0\0\0+09\0\0\x90~\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \x02}\x02\xEB\xE4\xDB\xA1\xFF\xFF\xFF\xFF\0\xC5\xA3\xB5\xFF\xFF\xFF\xFFpS'\x15\0\0\0\0\xE0\x87\x18\x16\0\0\0\0\xF0\x86\x08\x17\0\0\0\0`\xBB\xF9\x17\0\0\0\0p\xBA\xE9\x18\0\0\0\0\xE0\xEE\xDA\x19\0\0\0\0p?\xCC\x1A\0\0\0\0\x90L\xBC\x1B\0\0\0\0\x90=\xAC\x1C\0\0\0\0\x90.\x9C\x1D\0\0\0\0\x90\x1F\x8C\x1E\0\0\0\0\x90\x10|\x1F\0\0\0\0\x90\x01l \0\0\0\0\x90\xF2[!\0\0\0\0\x90\xE3K\"\0\0\0\0\x90\xD4;#\0\0\0\0\x90\xC5+$\0\0\0\0\x90\xB6\x1B%\0\0\0\0\x90\xA7\x0B&\0\0\0\0\x10\xD3\x04'\0\0\0\0\x10\xC4\xF4'\0\0\0\0 \xD2\xF4'\0\0\0\0 \xC3\xE4(\0\0\0\0 kx)\0\0\0\0\x10\xA6\xD4)\0\0\0\0\x10\x97\xC4*\0\0\0\0\x10\x88\xB4+\0\0\0\0\x10y\xA4,\0\0\0\0\x10j\x94-\0\0\0\0\x10[\x84.\0\0\0\0\x10Lt/\0\0\0\0\x10=d0\0\0\0\0\x90h]1\0\0\0\0\x90Cr2\0\0\0\0\x90J=3\0\0\0\0\x90%R4\0\0\0\0\x90,\x1D5\0\0\0\0\x90\x0726\0\0\0\0\x90\x0E\xFD6\0\0\0\0\x10$\x1B8\0\0\0\0\x90\xF0\xDC8\0\0\0\0\x10\x06\xFB9\0\0\0\0\x90\xD2\xBC:\0\0\0\0\x10\xE8\xDA;\0\0\0\0\x10\xEF\xA5<\0\0\0\0\x10\xCA\xBA=\0\0\0\0\x10\xD1\x85>\0\0\0\0\x10\xAC\x9A?\0\0\0\0p\xE4\xF2?\0\0\0\0\0\xA5e@\0\0\0\0\x80\xBA\x83A\0\0\0\0\0\x87EB\0\0\0\0\x80\x9CcC\0\0\0\0\0i%D\0\0\0\0\x80~CE\0\0\0\0\0K\x05F\0\0\0\0\x80`#G\0\0\0\0\x80g\xEEG\0\0\0\0\x80B\x03I\0\0\0\0\x80I\xCEI\0\0\0\0\x80$\xE3J\0\0\0\0\x80+\xAEK\0\0\0\0\0A\xCCL\0\0\0\0\x80\r\x8EM\0\0\0\0P\x02nN\0\0\0\0\0\xC9KT\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x03\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x05\x06\x03\x05\x06\x03\x05\x06\x03\x05\x06\x03\x05\x06\x03\x05\x06\x03\x05\x06\x03\x05\x06\x07\x03\x05\x02\x04\x15\x7F\0\0\0\0\0\0\x80p\0\0\0\0\0\0\x90~\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\x90~\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0IST\0\0XM\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\08\0?\0(\x18\xBA&\xFF\xFF\xFF\xFF0\xEB\xE7C\xFF\xFF\xFF\xFF\xBA\xBC\x9D\x87\xFF\xFF\xFF\xFF(\x8C\xDB\xCA\xFF\xFF\xFF\xFF\x18q\x05\xCC\xFF\xFF\xFF\xFF\xA82\x95\xCC\xFF\xFF\xFF\xFF\x98\x12t\xD2\xFF\xFF\xFF\xFF\x01\x02\x03\x04\x03\x04\x03\xD8R\0\0\0\0\0\0\xD0R\0\0\0\0\0\0FK\0\0\0\0\0\0XM\0\0\0\0\0\0h[\0\0\0\0\0\0+07\0\0pb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x02i\x02\xF2\r\xF9\xA1\xFF\xFF\xFF\xFF \xE1\xA3\xB5\xFF\xFF\xFF\xFF\x90o'\x15\0\0\0\0\0\xA4\x18\x16\0\0\0\0\x10\xA3\x08\x17\0\0\0\0\x80\xD7\xF9\x17\0\0\0\0\x90\xD6\xE9\x18\0\0\0\0\0\x0B\xDB\x19\0\0\0\0\x90[\xCC\x1A\0\0\0\0\xB0h\xBC\x1B\0\0\0\0\xB0Y\xAC\x1C\0\0\0\0\xB0J\x9C\x1D\0\0\0\0\xB0;\x8C\x1E\0\0\0\0\xB0,|\x1F\0\0\0\0\xB0\x1Dl \0\0\0\0\xB0\x0E\\!\0\0\0\0\xB0\xFFK\"\0\0\0\0\xB0\xF0;#\0\0\0\0\xB0\xE1+$\0\0\0\0\xB0\xD2\x1B%\0\0\0\0\xB0\xC3\x0B&\0\0\0\x000\xEF\x04'\0\0\0\x000\xE0\xF4'\0\0\0\0@\xEE\xF4'\0\0\0\0@\xDF\xE4(\0\0\0\0@\x87x)\0\0\0\x000\xC2\xD4)\0\0\0\x000\xB3\xC4*\0\0\0\x000\xA4\xB4+\0\0\0\x000\x95\xA4,\0\0\0\x000\x86\x94-\0\0\0\x000w\x84.\0\0\0\x000ht/\0\0\0\x000Yd0\0\0\0\0\xB0\x84]1\0\0\0\0\xB0_r2\0\0\0\0\xB0f=3\0\0\0\0\xB0AR4\0\0\0\0\xB0H\x1D5\0\0\0\0\xB0#26\0\0\0\0\xB0*\xFD6\0\0\0\x000@\x1B8\0\0\0\0\xB0\x0C\xDD8\0\0\0\x000\"\xFB9\0\0\0\0\xB0\xEE\xBC:\0\0\0\x000\x04\xDB;\0\0\0\x000\x0B\xA6<\0\0\0\x000\xE6\xBA=\0\0\0\x000\xED\x85>\0\0\0\x000\xC8\x9A?\0\0\0\x000\xCFe@\0\0\0\0\xB0\xE4\x83A\0\0\0\x000\xB1EB\0\0\0\0\xB0\xC6cC\0\0\0\x000\x93%D\0\0\0\0\xB0\xA8CE\0\0\0\x000u\x05F\0\0\0\0\xB0\x8A#G\0\0\0\0\xB0\x91\xEEG\0\0\0\0\xB0l\x03I\0\0\0\0\xB0s\xCEI\0\0\0\0\xB0N\xE3J\0\0\0\0\xB0U\xAEK\0\0\0\x000k\xCCL\0\0\0\0\xB07\x8EM\0\0\0\0 \xE5KT\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x03\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x05\x02\x04\x0EW\0\0\0\0\0\0`T\0\0\0\0\0\0pb\0\0\0\0\0\0\x80p\0\0\0\0\0\0pb\0\0\0\0\0\0\x80p\0\0\0\0\0\0+08\0\0\x80p\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x90\0\xA2\0\x90\x06\x8A\xAD\xFF\xFF\xFF\xFF\x88Gg\xBA\xFF\xFF\xFF\xFF\x80'{\xBF\xFF\xFF\xFF\xFFP\x1B\xF3\xBF\xFF\xFF\xFF\xFF\x80\xAC]\xC1\xFF\xFF\xFF\xFFP\xA0\xD5\xC1\xFF\xFF\xFF\xFF\0\xE0>\xC3\xFF\xFF\xFF\xFF\xD0\xD3\xB6\xC3\xFF\xFF\xFF\xFF\x80\x13 \xC5\xFF\xFF\xFF\xFFP\x07\x98\xC5\xFF\xFF\xFF\xFF\0G\x01\xC7\xFF\xFF\xFF\xFF\xD0:y\xC7\xFF\xFF\xFF\xFF\0\xCC\xE3\xC8\xFF\xFF\xFF\xFF\xD0\xBF[\xC9\xFF\xFF\xFF\xFF\x80\xFF\xC4\xCA\xFF\xFF\xFF\xFFP\xF3<\xCB\xFF\xFF\xFF\xFF\0X\x91\xCB\xFF\xFF\xFF\xFF\xF0mH\xD2\xFF\xFF\xFF\xFF\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02pg\0\0\0\0\0\0xi\0\0\0\0\0\0\x80p\0\0\0\0\0\x000u\0\0\0\0\0\0\x90~\0\0\0\0\0\0CST\0\0\x80p\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\08\x02\x9F\x02\x8E[i\x85\xFF\xFF\xFF\xFF\xF0uG\xCB\xFF\xFF\xFF\xFF\xE0\xCA\xF2\xCB\xFF\xFF\xFF\xFFP\xBA\xFB\xCC\xFF\xFF\xFF\xFF`\xFE\xD3\xCD\xFF\xFF\xFF\xFF\xD0\xA5\x9D\xCE\xFF\xFF\xFF\xFFpza\xD2\xFF\xFF\xFF\xFFp\xF8x\xD3\xFF\xFF\xFF\xFF\xF0\xADB\xD4\xFF\xFF\xFF\xFFp\xABK\xD5\xFF\xFF\xFF\xFF\xF0Lt\xD6\xFF\xFF\xFF\xFF\xF0S?\xD7\xFF\xFF\xFF\xFF\xF0D/\xD8\xFF\xFF\xFF\xFFp\xFA\xF8\xD8\xFF\xFF\xFF\xFFp\xD5\r\xDA\xFF\xFF\xFF\xFFp\xDC\xD8\xDA\xFF\xFF\xFF\xFFp\xB7\xED\xDB\xFF\xFF\xFF\xFFp\xBE\xB8\xDC\xFF\xFF\xFF\xFF\xF0\xEA\xCE\xDD\xFF\xFF\xFF\xFF\xF0\xDA\xA1\xDE\xFF\xFF\xFF\xFF\xF0\xB5\xB6\xDF\xFF\xFF\xFF\xFF\xF0\xBC\x81\xE0\xFF\xFF\xFF\xFF\xF0\x97\x96\xE1\xFF\xFF\xFF\xFF\xF0)O\xE2\xFF\xFF\xFF\xFF\xF0yv\xE3\xFF\xFF\xFF\xFF\xF0\x0B/\xE4\xFF\xFF\xFF\xFFp\x96_\xE5\xFF\xFF\xFF\xFF\xF0\xED\x0E\xE6\xFF\xFF\xFF\xFF\xA8\xA9?\xE7\xFF\xFF\xFF\xFF\xB8I\xF8\xE7\xFF\xFF\xFF\xFF\xA8\x8B\x1F\xE9\xFF\xFF\xFF\xFF\xB8+\xD8\xE9\xFF\xFF\xFF\xFF\xA8m\xFF\xEA\xFF\xFF\xFF\xFF\xB8\r\xB8\xEB\xFF\xFF\xFF\xFF\xA8O\xDF\xEC\xFF\xFF\xFF\xFF\xB8\xEF\x97\xED\xFF\xFF\xFF\xFF(l\xC8\xEE\xFF\xFF\xFF\xFF\xB8\xD1w\xEF\xFF\xFF\xFF\xFF(N\xA8\xF0\xFF\xFF\xFF\xFF\xB8\xB3W\xF1\xFF\xFF\xFF\xFF(0\x88\xF2\xFF\xFF\xFF\xFF8\xD0@\xF3\xFF\xFF\xFF\xFF(\x12h\xF4\xFF\xFF\xFF\xFF8\xB2 \xF5\xFF\xFF\xFF\xFF(\xF4G\xF6\xFF\xFF\xFF\xFF8~%\xF7\xFF\xFF\xFF\xFF\x18S\x15\xF8\xFF\xFF\xFF\xFF8`\x05\xF9\xFF\xFF\xFF\xFF\x185\xF5\xF9\xFF\xFF\xFF\xFF8B\xE5\xFA\xFF\xFF\xFF\xFF\xA8_\xDE\xFB\xFF\xFF\xFF\xFF\xB8^\xCE\xFC\xFF\xFF\xFF\xFF\xA8A\xBE\xFD\xFF\xFF\xFF\xFF\xB8@\xAE\xFE\xFF\xFF\xFF\xFF\xA8#\x9E\xFF\xFF\xFF\xFF\xFF\xB8\"\x8E\0\0\0\0\0\xA8\x05~\x01\0\0\0\0\xB8\x04n\x02\0\0\0\0\xA8\xE7]\x03\0\0\0\0\xB8\xE6M\x04\0\0\0\0(\x04G\x05\0\0\0\08\x037\x06\0\0\0\0(\xE6&\x07\0\0\0\08=\x83\x07\0\0\0\0(\xC8\x06\t\0\0\0\08\xC7\xF6\t\0\0\0\0(\xAA\xE6\n\0\0\0\08\xA9\xD6\x0B\0\0\0\0(\x8C\xC6\x0C\0\0\0\089\x9B\x11\0\0\0\0\xA8lo\x12\0\0\0\0\x01\x02\x03\x02\x03\x02\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01rj\0\0\0\0\0\0\x80p\0\0\0\0\0\0\x90~\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\x90~\0\0\0\0\0\0+11\0\0\xB0\x9A\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\x02r\x02\xA06\x19\xAA\xFF\xFF\xFF\xFF\xE0\xA8\xA3\xB5\xFF\xFF\xFF\xFFP7'\x15\0\0\0\0\xC0k\x18\x16\0\0\0\0\xD0j\x08\x17\0\0\0\0@\x9F\xF9\x17\0\0\0\0P\x9E\xE9\x18\0\0\0\0\xC0\xD2\xDA\x19\0\0\0\0P#\xCC\x1A\0\0\0\0p0\xBC\x1B\0\0\0\0p!\xAC\x1C\0\0\0\0p\x12\x9C\x1D\0\0\0\0p\x03\x8C\x1E\0\0\0\0p\xF4{\x1F\0\0\0\0p\xE5k \0\0\0\0p\xD6[!\0\0\0\0p\xC7K\"\0\0\0\0p\xB8;#\0\0\0\0p\xA9+$\0\0\0\0p\x9A\x1B%\0\0\0\0p\x8B\x0B&\0\0\0\0\xF0\xB6\x04'\0\0\0\0\xF0\xA7\xF4'\0\0\0\0\0\xB6\xF4'\0\0\0\0\0\xA7\xE4(\0\0\0\0\0Ox)\0\0\0\0\xF0\x89\xD4)\0\0\0\0\xF0z\xC4*\0\0\0\0\xF0k\xB4+\0\0\0\0\xF0\\\xA4,\0\0\0\0\xF0M\x94-\0\0\0\0\xF0>\x84.\0\0\0\0\xF0/t/\0\0\0\0\xF0 d0\0\0\0\0pL]1\0\0\0\0p'r2\0\0\0\0p.=3\0\0\0\0p\tR4\0\0\0\0p\x10\x1D5\0\0\0\0p\xEB16\0\0\0\0p\xF2\xFC6\0\0\0\0\xF0\x07\x1B8\0\0\0\0p\xD4\xDC8\0\0\0\0\xF0\xE9\xFA9\0\0\0\0p\xB6\xBC:\0\0\0\0\xF0\xCB\xDA;\0\0\0\0\xF0\xD2\xA5<\0\0\0\0\xF0\xAD\xBA=\0\0\0\0\xF0\xB4\x85>\0\0\0\0\xF0\x8F\x9A?\0\0\0\0\xF0\x96e@\0\0\0\0p\xAC\x83A\0\0\0\0\xF0xEB\0\0\0\0p\x8EcC\0\0\0\0\xF0Z%D\0\0\0\0ppCE\0\0\0\0\xF0<\x05F\0\0\0\0pR#G\0\0\0\0pY\xEEG\0\0\0\0p4\x03I\0\0\0\0p;\xCEI\0\0\0\0p\x16\xE3J\0\0\0\0p\x1D\xAEK\0\0\0\0\xF02\xCCL\0\0\0\0p\xFF\x8DM\0\0\0\0\xE0\xACKT\0\0\0\0\0\x9C\x1BW\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x03\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x05\x01\x02\x04`\x8D\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0WITA\0\x80p\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0$\0\x90]\xF2\xA1\xFF\xFF\xFF\xFF\x90\xD5\x16\xBA\xFF\xFF\xFF\xFF\x80\x1D\x88\xCB\xFF\xFF\xFF\xFFp\xEEV\xD2\xFF\xFF\xFF\xFF\0\x01\x02\x01\xF0o\0\0\0\0\0\0\x80p\0\0\0\0\0\0\x90~\0\0\0\0\0\0PST\0\0\x80p\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0p\0\x83\0\x18\xDC\xE1\x14\xFF\xFF\xFF\xFF@z\xBB{\xFF\xFF\xFF\xFF\x80\xF4\x9C\xC1\xFF\xFF\xFF\xFFp\x18\x01\xC2\xFF\xFF\xFF\xFF\0\x9B?\xCB\xFF\xFF\xFF\xFF\xF0\x03\x8C\xCB\xFF\xFF\xFF\xFF\xF0MK\xD1\xFF\xFF\xFF\xFF\xF0\xE5\xB1\xD2\xFF\xFF\xFF\xFF\09l\xE2\xFF\xFF\xFF\xFF\xF0[\xB3\xE2\xFF\xFF\xFF\xFF\0\xFC\x9B\r\0\0\0\0\xF0\x98\x86\x0E\0\0\0\0\0\xBFV&\0\0\0\0p\xA8\xB1&\0\0\0\0\x01\x02\x03\x02\x03\x03\x04\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\xE8\x1F\xFF\xFF\xFF\xFF\xFF\xFFhq\0\0\0\0\0\0\x80p\0\0\0\0\0\0\x90~\0\0\0\0\0\0\x90~\0\0\0\0\0\0EET\0\0 \x1C\0\0\0\0\0\0\x01EEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\x000*\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0@8\0\0\0\0\0\0\x80\x01\xB0\x01\xB8\x1Ew\xA5\xFF\xFF\xFF\xFF\xE0\xAF\xED\t\0\0\0\0\xD0\x92\xDD\n\0\0\0\0\xE0d\xFA\x0B\0\0\0\0P\xC6\xBE\x0C\0\0\0\0`9\xA4\r\0\0\0\0\xD0\xE1\x8A\x0E\0\0\0\0`\x1B\x84\x0F\0\0\0\0\xD0Ou\x10\0\0\0\0`\xFDc\x11\0\0\0\0P\xE0S\x12\0\0\0\0\xE0\x19M\x13\0\0\0\0P\xC23\x14\0\0\0\0`\xC1#\x15\0\0\0\0P\xA4\x13\x16\0\0\0\0`\xA3\x03\x17\0\0\0\0P\x86\xF3\x17\0\0\0\0`\x85\xE3\x18\0\0\0\0Ph\xD3\x19\0\0\0\0`g\xC3\x1A\0\0\0\0\xD0\x84\xBC\x1B\0\0\0\0\xE0\x83\xAC\x1C\0\0\0\0\xD0f\x9C\x1D\0\0\0\0\xE0e\x8C\x1E\0\0\0\0\xD0H|\x1F\0\0\0\0\xE0Gl \0\0\0\0\xD0*\\!\0\0\0\0\xE0)L\"\0\0\0\0\xD0\x0C<#\0\0\0\0\xE0\x0B,$\0\0\0\0\xD0\xEE\x1B%\0\0\0\0\xE0\xED\x0B&\0\0\0\0P\x0B\x05'\0\0\0\0`\n\xF5'\0\0\0\0P\xED\xE4(\0\0\0\0`\xEC\xD4)\0\0\0\0P\xCF\xC4*\0\0\0\0`\xCE\xB4+\0\0\0\0P\xB1\xA4,\0\0\0\0`\xB0\x94-\0\0\0\0P\x93\x84.\0\0\0\0`\x92t/\0\0\0\0Pud0\0\0\0\0\xE0\xAE]1\0\0\0\0\xD0\x91M2\0\0\0\0\xE0\x90=3\0\0\0\0\xD0s-4\0\0\0\0\xE0r\x1D5\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02H\x1F\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0+07\0\0pb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x02h\x02\xC0 \x18\xAA\xFF\xFF\xFF\xFF \xE1\xA3\xB5\xFF\xFF\xFF\xFF\x90o'\x15\0\0\0\0\0\xA4\x18\x16\0\0\0\0\x10\xA3\x08\x17\0\0\0\0\x80\xD7\xF9\x17\0\0\0\0\x90\xD6\xE9\x18\0\0\0\0\0\x0B\xDB\x19\0\0\0\0\x90[\xCC\x1A\0\0\0\0\xB0h\xBC\x1B\0\0\0\0\xB0Y\xAC\x1C\0\0\0\0\xB0J\x9C\x1D\0\0\0\0\xB0;\x8C\x1E\0\0\0\0\xB0,|\x1F\0\0\0\0\xB0\x1Dl \0\0\0\0\xB0\x0E\\!\0\0\0\0\xB0\xFFK\"\0\0\0\0\xB0\xF0;#\0\0\0\0\xB0\xE1+$\0\0\0\0\xB0\xD2\x1B%\0\0\0\0\xB0\xC3\x0B&\0\0\0\x000\xEF\x04'\0\0\0\x000\xE0\xF4'\0\0\0\0@\xEE\xF4'\0\0\0\0@\xDF\xE4(\0\0\0\0@\x87x)\0\0\0\x000\xC2\xD4)\0\0\0\x000\xB3\xC4*\0\0\0\x000\xA4\xB4+\0\0\0\x000\x95\xA4,\0\0\0\x000\x86\x94-\0\0\0\x000w\x84.\0\0\0\x000ht/\0\0\0\x000Yd0\0\0\0\0\xB0\x84]1\0\0\0\0\xB0_r2\0\0\0\0\xB0f=3\0\0\0\0\xB0AR4\0\0\0\0\xB0H\x1D5\0\0\0\0\xB0#26\0\0\0\0\xB0*\xFD6\0\0\0\x000@\x1B8\0\0\0\0\xB0\x0C\xDD8\0\0\0\x000\"\xFB9\0\0\0\0\xB0\xEE\xBC:\0\0\0\x000\x04\xDB;\0\0\0\x000\x0B\xA6<\0\0\0\x000\xE6\xBA=\0\0\0\x000\xED\x85>\0\0\0\x000\xC8\x9A?\0\0\0\x000\xCFe@\0\0\0\0\xB0\xE4\x83A\0\0\0\x000\xB1EB\0\0\0\0\xB0\xC6cC\0\0\0\x000\x93%D\0\0\0\0\xB0\xA8CE\0\0\0\x000u\x05F\0\0\0\0\xB0\x8A#G\0\0\0\0\xB0\x91\xEEG\0\0\0\0\xB0l\x03I\0\0\0\0\xB0s\xCEI\0\0\0\0\xB0N\xE3J\0\0\0\0\xB0U\xAEK\0\0\0\0\xC0c\xAEK\0\0\0\0@y\xCCL\0\0\0\0\xC0E\x8EM\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x03\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x01\x02\x04\x01\x02\x04\xC0Q\0\0\0\0\0\0`T\0\0\0\0\0\0pb\0\0\0\0\0\0\x80p\0\0\0\0\0\0pb\0\0\0\0\0\0+07\0\0pb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \x02{\x02$\x19\xDB\xA1\xFF\xFF\xFF\xFF \xE1\xA3\xB5\xFF\xFF\xFF\xFF\x90o'\x15\0\0\0\0\0\xA4\x18\x16\0\0\0\0\x10\xA3\x08\x17\0\0\0\0\x80\xD7\xF9\x17\0\0\0\0\x90\xD6\xE9\x18\0\0\0\0\0\x0B\xDB\x19\0\0\0\0\x90[\xCC\x1A\0\0\0\0\xB0h\xBC\x1B\0\0\0\0\xB0Y\xAC\x1C\0\0\0\0\xB0J\x9C\x1D\0\0\0\0\xB0;\x8C\x1E\0\0\0\0\xB0,|\x1F\0\0\0\0\xB0\x1Dl \0\0\0\0\xB0\x0E\\!\0\0\0\0\xB0\xFFK\"\0\0\0\0\xB0\xF0;#\0\0\0\0\xB0\xE1+$\0\0\0\0\xB0\xD2\x1B%\0\0\0\0\xB0\xC3\x0B&\0\0\0\x000\xEF\x04'\0\0\0\x000\xE0\xF4'\0\0\0\0@\xEE\xF4'\0\0\0\0@\xDF\xE4(\0\0\0\0@\x87x)\0\0\0\x000\xC2\xD4)\0\0\0\x000\xB3\xC4*\0\0\0\x000\xA4\xB4+\0\0\0\0\0N\xFE+\0\0\0\0@\xA3\xA4,\0\0\0\0@\x94\x94-\0\0\0\0@\x85\x84.\0\0\0\0@vt/\0\0\0\0@gd0\0\0\0\0\xC0\x92]1\0\0\0\0\xC0mr2\0\0\0\0\xC0t=3\0\0\0\0\xC0OR4\0\0\0\0\xC0V\x1D5\0\0\0\0\xC0126\0\0\0\0\xC08\xFD6\0\0\0\0@N\x1B8\0\0\0\0\xC0\x1A\xDD8\0\0\0\0@0\xFB9\0\0\0\0\xC0\xFC\xBC:\0\0\0\0@\x12\xDB;\0\0\0\0@\x19\xA6<\0\0\0\0@\xF4\xBA=\0\0\0\0@\xFB\x85>\0\0\0\0@\xD6\x9A?\0\0\0\0@\xDDe@\0\0\0\0\xC0\xF2\x83A\0\0\0\0@\xBFEB\0\0\0\0\xC0\xD4cC\0\0\0\0@\xA1%D\0\0\0\0\xC0\xB6CE\0\0\0\0@\x83\x05F\0\0\0\0\xC0\x98#G\0\0\0\0\xC0\x9F\xEEG\0\0\0\0\xC0z\x03I\0\0\0\0\xC0\x81\xCEI\0\0\0\0\xC0\\\xE3J\0\0\0\0\xC0c\xAEK\0\0\0\0@y\xCCL\0\0\0\0\xC0E\x8EM\0\0\0\x000\xF3KT\0\0\0\0\xC0\xCC\x93W\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x03\x03\x02\x04\x03\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\xBCM\0\0\0\0\0\0`T\0\0\0\0\0\0pb\0\0\0\0\0\0\x80p\0\0\0\0\0\0pb\0\0\0\0\0\0+06\0\0`T\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x02i\x02\xB6@\xB3\xA1\xFF\xFF\xFF\xFF0\xEF\xA3\xB5\xFF\xFF\xFF\xFF\xA0}'\x15\0\0\0\0\x10\xB2\x18\x16\0\0\0\0 \xB1\x08\x17\0\0\0\0\x90\xE5\xF9\x17\0\0\0\0\xA0\xE4\xE9\x18\0\0\0\0\x10\x19\xDB\x19\0\0\0\0\xA0i\xCC\x1A\0\0\0\0\xC0v\xBC\x1B\0\0\0\0\xC0g\xAC\x1C\0\0\0\0\xC0X\x9C\x1D\0\0\0\0\xC0I\x8C\x1E\0\0\0\0\xC0:|\x1F\0\0\0\0\xC0+l \0\0\0\0\xC0\x1C\\!\0\0\0\0\xC0\rL\"\0\0\0\0\xC0\xFE;#\0\0\0\0\xC0\xEF+$\0\0\0\0\xC0\xE0\x1B%\0\0\0\0\xC0\xD1\x0B&\0\0\0\0@\xFD\x04'\0\0\0\0@\xEE\xF4'\0\0\0\0P\xFC\xF4'\0\0\0\0P\xED\xE4(\0\0\0\0P\x95x)\0\0\0\0@\xD0\xD4)\0\0\0\0@\xC1\xC4*\0\0\0\0@\xB2\xB4+\0\0\0\0@\xA3\xA4,\0\0\0\0@\x94\x94-\0\0\0\0@\x85\x84.\0\0\0\0@vt/\0\0\0\0@gd0\0\0\0\0\xC0\x92]1\0\0\0\0\xC0mr2\0\0\0\0\xC0t=3\0\0\0\0\xC0OR4\0\0\0\0\xC0V\x1D5\0\0\0\0\xC0126\0\0\0\0\xC08\xFD6\0\0\0\0@N\x1B8\0\0\0\0\xC0\x1A\xDD8\0\0\0\0@0\xFB9\0\0\0\0\xC0\xFC\xBC:\0\0\0\0@\x12\xDB;\0\0\0\0@\x19\xA6<\0\0\0\0@\xF4\xBA=\0\0\0\0@\xFB\x85>\0\0\0\0@\xD6\x9A?\0\0\0\0@\xDDe@\0\0\0\0\xC0\xF2\x83A\0\0\0\0@\xBFEB\0\0\0\0\xC0\xD4cC\0\0\0\0@\xA1%D\0\0\0\0\xC0\xB6CE\0\0\0\0@\x83\x05F\0\0\0\0\xC0\x98#G\0\0\0\0\xC0\x9F\xEEG\0\0\0\0\xC0z\x03I\0\0\0\0\xC0\x81\xCEI\0\0\0\0\xC0\\\xE3J\0\0\0\0\xC0c\xAEK\0\0\0\0@y\xCCL\0\0\0\0\xC0E\x8EM\0\0\0\x000\xF3KT\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x03\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x05\x02\x04\xCAD\0\0\0\0\0\0PF\0\0\0\0\0\0`T\0\0\0\0\0\0pb\0\0\0\0\0\0`T\0\0\0\0\0\0pb\0\0\0\0\0\0+05\0\0PF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xB0\x01\x02\x02\xDC\x93\x19\xAA\xFF\xFF\xFF\xFFP\x0B\xA4\xB5\xFF\xFF\xFF\xFF\xB0\x8B'\x15\0\0\0\0 \xC0\x18\x16\0\0\0\0 \xB1\x08\x17\0\0\0\x000\xBF\x08\x17\0\0\0\0\xA0\xF3\xF9\x17\0\0\0\0\xB0\xF2\xE9\x18\0\0\0\0 '\xDB\x19\0\0\0\0\xB0w\xCC\x1A\0\0\0\0\xD0\x84\xBC\x1B\0\0\0\0\xD0u\xAC\x1C\0\0\0\0\xD0f\x9C\x1D\0\0\0\0\xD0W\x8C\x1E\0\0\0\0\xD0H|\x1F\0\0\0\0\xD09l \0\0\0\0\xD0*\\!\0\0\0\0\xD0\x1BL\"\0\0\0\0\xD0\x0C<#\0\0\0\0\xD0\xFD+$\0\0\0\0\xE0\x0B,$\0\0\0\0\xE0\xFC\x1B%\0\0\0\0\xE0\xED\x0B&\0\0\0\0`\x19\x05'\0\0\0\0`\n\xF5'\0\0\0\0`\xFB\xE4(\0\0\0\0`\xA3x)\0\0\0\0P\xDE\xD4)\0\0\0\0`\xEC\xD4)\0\0\0\0`\xDD\xC4*\0\0\0\0`\xCE\xB4+\0\0\0\0`\xBF\xA4,\0\0\0\0`\xB0\x94-\0\0\0\0`\xA1\x84.\0\0\0\0`\x92t/\0\0\0\0`\x83d0\0\0\0\0\xE0\xAE]1\0\0\0\0\xE0\x89r2\0\0\0\0\xE0\x90=3\0\0\0\0\xE0kR4\0\0\0\0\xE0r\x1D5\0\0\0\0\xE0M26\0\0\0\0\xE0T\xFD6\0\0\0\0`j\x1B8\0\0\0\0\xE06\xDD8\0\0\0\0`L\xFB9\0\0\0\0\xE0\x18\xBD:\0\0\0\0`.\xDB;\0\0\0\0`5\xA6<\0\0\0\0`\x10\xBB=\0\0\0\0`\x17\x86>\0\0\0\0`\xF2\x9A?\0\0\0\0`\xF9e@\0\0\0\0\xE0\x0E\x84A\0\0\0\0\x01\x02\x03\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x02\x05\x02\x05\x06\x02\x05\x06\x02\x05\x06\x03\x04\x02\x05\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x06\x02\x05\x02\x05$0\0\0\0\0\0\x000*\0\0\0\0\0\0PF\0\0\0\0\0\0`T\0\0\0\0\0\0`T\0\0\0\0\0\0PF\0\0\0\0\0\0@8\0\0\0\0\0\0WIB\0\0pb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\0H\0\0\x8E\xFF\x8B\xFF\xFF\xFF\xFF\0\xDF\x16\xBA\xFF\xFF\xFF\xFF\x08\xA4y\xCB\xFF\xFF\xFF\xFFp\xEEV\xD2\xFF\xFF\xFF\xFF\x08\xC6<\xD7\xFF\xFF\xFF\xFF\0&\xFF\xDA\xFF\xFF\xFF\xFF\x88\xBE\xB5\xF4\xFF\xFF\xFF\xFF\x80t\xDA!\0\0\0\0\0\x01\x02\x01\x03\x01\x03\x04\x80f\0\0\0\0\0\0xi\0\0\0\0\0\0\x90~\0\0\0\0\0\0\x80p\0\0\0\0\0\0pb\0\0\0\0\0\0KST\0\0\x90~\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0(\0-\0\x9C\xF1\xD7\x8B\xFF\xFF\xFF\xFF\xF8\x16\xE6\x92\xFF\xFF\xFF\xFFpa/\xD2\xFF\xFF\xFF\xFFp\x02\xCEU\0\0\0\0pu\xECZ\0\0\0\0\x01\x02\x02\x01\x02\xE4u\0\0\0\0\0\0\x88w\0\0\0\0\0\0\x90~\0\0\0\0\0\0+03\0\x000*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\x12\x000\x9D\xF2\xA1\xFF\xFF\xFF\xFF\xC0\x92\x8A\x04\0\0\0\0\x01\x02P0\0\0\0\0\0\0@8\0\0\0\0\0\x000*\0\0\0\0\0\0+05\0\0PF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xB0\x01\x0E\x02\\\x88\x19\xAA\xFF\xFF\xFF\xFF@\xFD\xA3\xB5\xFF\xFF\xFF\xFF\xB0\x8B'\x15\0\0\0\0 \xC0\x18\x16\0\0\0\0 \xB1\x08\x17\0\0\0\x000\xBF\x08\x17\0\0\0\0\xA0\xF3\xF9\x17\0\0\0\0\xB0\xF2\xE9\x18\0\0\0\0 '\xDB\x19\0\0\0\0\xB0w\xCC\x1A\0\0\0\0\xD0\x84\xBC\x1B\0\0\0\0\xD0u\xAC\x1C\0\0\0\0\xD0f\x9C\x1D\0\0\0\0\xD0W\x8C\x1E\0\0\0\0\xD0H|\x1F\0\0\0\0\xD09l \0\0\0\0\xD0*\\!\0\0\0\0\xD0\x1BL\"\0\0\0\0\xD0\x0C<#\0\0\0\0\xD0\xFD+$\0\0\0\0\xD0\xEE\x1B%\0\0\0\0\xD0\xDF\x0B&\0\0\0\0P\x0B\x05'\0\0\0\0P\xFC\xF4'\0\0\0\0`\n\xF5'\0\0\0\0`\xFB\xE4(\0\0\0\0`\xA3x)\0\0\0\0P\xDE\xD4)\0\0\0\0P\xCF\xC4*\0\0\0\0P\xC0\xB4+\0\0\0\0P\xB1\xA4,\0\0\0\0P\xA2\x94-\0\0\0\0P\x93\x84.\0\0\0\0P\x84t/\0\0\0\0Pud0\0\0\0\0\xD0\xA0]1\0\0\0\0\xD0{r2\0\0\0\0\xD0\x82=3\0\0\0\0\xD0]R4\0\0\0\0\xD0d\x1D5\0\0\0\0\xD0?26\0\0\0\0\xD0F\xFD6\0\0\0\0P\\\x1B8\0\0\0\0\xD0(\xDD8\0\0\0\0P>\xFB9\0\0\0\0\xD0\n\xBD:\0\0\0\0P \xDB;\0\0\0\0P'\xA6<\0\0\0\0P\x02\xBB=\0\0\0\0P\t\x86>\0\0\0\0P\xE4\x9A?\0\0\0\0P\xEBe@\0\0\0\0\xD0\0\x84A\0\0\0\0 \xC6\xE0e\0\0\0\0\x01\x02\x03\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x02\x05\x02\x05\x01\x03\x04\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x03\x04\x02\x05\xA4;\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0`T\0\0\0\0\0\0`T\0\0\0\0\0\0PF\0\0\0\0\0\0+05\0\0PF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xB8\x01\x18\x02\xA0\x86\x19\xAA\xFF\xFF\xFF\xFF@\xFD\xA3\xB5\xFF\xFF\xFF\xFF\xB0\x8B'\x15\0\0\0\0 \xC0\x18\x16\0\0\0\0 \xB1\x08\x17\0\0\0\x000\xBF\x08\x17\0\0\0\0\xA0\xF3\xF9\x17\0\0\0\0\xB0\xF2\xE9\x18\0\0\0\0 '\xDB\x19\0\0\0\0\xB0w\xCC\x1A\0\0\0\0\xD0\x84\xBC\x1B\0\0\0\0\xD0u\xAC\x1C\0\0\0\0\xD0f\x9C\x1D\0\0\0\0\xD0W\x8C\x1E\0\0\0\0\xD0H|\x1F\0\0\0\0\xD09l \0\0\0\0\xD0*\\!\0\0\0\0\xD0\x1BL\"\0\0\0\0\xD0\x0C<#\0\0\0\0\xD0\xFD+$\0\0\0\0\xD0\xEE\x1B%\0\0\0\0\xD0\xDF\x0B&\0\0\0\0P\x0B\x05'\0\0\0\0P\xFC\xF4'\0\0\0\0`\n\xF5'\0\0\0\0`\xFB\xE4(\0\0\0\0P\x95x)\0\0\0\0@\xD0\xD4)\0\0\0\0P\xDE\xD4)\0\0\0\0P\xCF\xC4*\0\0\0\0P\xC0\xB4+\0\0\0\0P\xB1\xA4,\0\0\0\0P\xA2\x94-\0\0\0\0P\x93\x84.\0\0\0\0P\x84t/\0\0\0\0Pud0\0\0\0\0\xD0\xA0]1\0\0\0\0\xD0{r2\0\0\0\0\xD0\x82=3\0\0\0\0\xD0]R4\0\0\0\0\xD0d\x1D5\0\0\0\0\xD0?26\0\0\0\0\xD0F\xFD6\0\0\0\0P\\\x1B8\0\0\0\0\xD0(\xDD8\0\0\0\0P>\xFB9\0\0\0\0\xD0\n\xBD:\0\0\0\0P \xDB;\0\0\0\0P'\xA6<\0\0\0\0P\x02\xBB=\0\0\0\0P\t\x86>\0\0\0\0P\xE4\x9A?\0\0\0\0P\xEBe@\0\0\0\0\xD0\0\x84A\0\0\0\0\xA0\xD8\x1B\\\0\0\0\0\x01\x02\x03\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x02\x05\x02\x05\x02\x05\x06\x03\x04\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x02\x05\x03\x04\x03\x04\x02\x05`=\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0`T\0\0\0\0\0\0`T\0\0\0\0\0\0PF\0\0\0\0\0\0pb\0\0\0\0\0\0+03\0\x000*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\t\0\xB46\x1B\xD5\xFF\xFF\xFF\xFF\x01\xCC+\0\0\0\0\0\x000*\0\0\0\0\0\0+11\0\0\xB0\x9A\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \x02{\x02\xB8\xCD\xF0\x86\xFF\xFF\xFF\xFF\xF0\xB20\xD2\xFF\xFF\xFF\xFFP7'\x15\0\0\0\0\xC0k\x18\x16\0\0\0\0\xD0j\x08\x17\0\0\0\0@\x9F\xF9\x17\0\0\0\0P\x9E\xE9\x18\0\0\0\0\xC0\xD2\xDA\x19\0\0\0\0P#\xCC\x1A\0\0\0\0p0\xBC\x1B\0\0\0\0p!\xAC\x1C\0\0\0\0p\x12\x9C\x1D\0\0\0\0p\x03\x8C\x1E\0\0\0\0p\xF4{\x1F\0\0\0\0p\xE5k \0\0\0\0p\xD6[!\0\0\0\0p\xC7K\"\0\0\0\0p\xB8;#\0\0\0\0p\xA9+$\0\0\0\0p\x9A\x1B%\0\0\0\0p\x8B\x0B&\0\0\0\0\xF0\xB6\x04'\0\0\0\0\xF0\xA7\xF4'\0\0\0\0\0\xB6\xF4'\0\0\0\0\0\xA7\xE4(\0\0\0\0\0Ox)\0\0\0\0\xF0\x89\xD4)\0\0\0\0\xF0z\xC4*\0\0\0\0\xF0k\xB4+\0\0\0\0\xF0\\\xA4,\0\0\0\0\xF0M\x94-\0\0\0\0\xF0>\x84.\0\0\0\0\xF0/t/\0\0\0\0\xF0 d0\0\0\0\0pL]1\0\0\0\0p'r2\0\0\0\0p.=3\0\0\0\0\x80<=3\0\0\0\0\x80\x17R4\0\0\0\0\x80\x1E\x1D5\0\0\0\0\x80\xF916\0\0\0\0\x80\0\xFD6\0\0\0\0\0\x16\x1B8\0\0\0\0\x80\xE2\xDC8\0\0\0\0\0\xF8\xFA9\0\0\0\0\x80\xC4\xBC:\0\0\0\0\0\xDA\xDA;\0\0\0\0\0\xE1\xA5<\0\0\0\0\0\xBC\xBA=\0\0\0\0\0\xC3\x85>\0\0\0\0\0\x9E\x9A?\0\0\0\0\0\xA5e@\0\0\0\0\x80\xBA\x83A\0\0\0\0\0\x87EB\0\0\0\0\x80\x9CcC\0\0\0\0\0i%D\0\0\0\0\x80~CE\0\0\0\0\0K\x05F\0\0\0\0\x80`#G\0\0\0\0\x80g\xEEG\0\0\0\0\x80B\x03I\0\0\0\0\x80I\xCEI\0\0\0\0\x80$\xE3J\0\0\0\0\x80+\xAEK\0\0\0\0\0A\xCCL\0\0\0\0\x80\r\x8EM\0\0\0\0\xF0\xBAKT\0\0\0\0\0\xB2\xF6V\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x05\x03\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\xC8\x85\0\0\0\0\0\0\x90~\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0+05\0\0PF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xC8\0\xEC\x007\x85\x19\xAA\xFF\xFF\xFF\xFF@\xFD\xA3\xB5\xFF\xFF\xFF\xFF\xB0\x8B'\x15\0\0\0\0 \xC0\x18\x16\0\0\0\0 \xB1\x08\x17\0\0\0\x000\xBF\x08\x17\0\0\0\0\xA0\xF3\xF9\x17\0\0\0\0\xB0\xF2\xE9\x18\0\0\0\0 '\xDB\x19\0\0\0\0\xB0w\xCC\x1A\0\0\0\0\xD0\x84\xBC\x1B\0\0\0\0\xD0u\xAC\x1C\0\0\0\0\xD0f\x9C\x1D\0\0\0\0\xD0W\x8C\x1E\0\0\0\0\xD0H|\x1F\0\0\0\0\xD09l \0\0\0\0\xD0*\\!\0\0\0\0\xD0\x1BL\"\0\0\0\0\xD0\x0C<#\0\0\0\0\xD0\xFD+$\0\0\0\0\xD0\xEE\x1B%\0\0\0\0\xD0\xDF\x0B&\0\0\0\0P\x0B\x05'\0\0\0\0P\xFC\xF4'\0\0\0\0P\xED\xE4(\0\0\0\0\x01\x02\x03\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\xC9>\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0`T\0\0\0\0\0\0`T\0\0\0\0\0\0KST\0\0\x90~\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xD8\0\xF3\0x\xF0\xD7\x8B\xFF\xFF\xFF\xFF\xF8\x16\xE6\x92\xFF\xFF\xFF\xFF\xF0'C\xD2\xFF\xFF\xFF\xFFp\x8Fe\xD7\xFF\xFF\xFF\xFF`\x9D\xEE\xD7\xFF\xFF\xFF\xFFp\xFA\xF8\xD8\xFF\xFF\xFF\xFF\xE0-\xCD\xD9\xFF\xFF\xFF\xFF\xF0\x8A\xD7\xDA\xFF\xFF\xFF\xFF\xE0\x0F\xAD\xDB\xFF\xFF\xFF\xFF\xF0\xE2\xE6\xDC\xFF\xFF\xFF\xFF\xE0\xF1\x8C\xDD\xFF\xFF\xFF\xFF\xF0)O\xE2\xFF\xFF\xFF\xFF\xF8\xB7k\xE4\xFF\xFF\xFF\xFFh\x18\x13\xE5\xFF\xFF\xFF\xFFx\x03b\xE6\xFF\xFF\xFF\xFF\xE8L\x11\xE7\xFF\xFF\xFF\xFFxp/\xE8\xFF\xFF\xFF\xFFh\xF4\xE7\xE8\xFF\xFF\xFF\xFFxR\x0F\xEA\xFF\xFF\xFF\xFFh\xD6\xC7\xEA\xFF\xFF\xFF\xFFx4\xEF\xEB\xFF\xFF\xFF\xFFh\xB8\xA7\xEC\xFF\xFF\xFF\xFFx\x16\xCF\xED\xFF\xFF\xFF\xFFh\x9A\x87\xEE\xFF\xFF\xFF\xFFxq5\xF0\xFF\xFF\xFF\xFF\x90`\xA3 \0\0\0\0\x90gn!\0\0\0\0\x01\x02\x02\x03\x02\x03\x02\x03\x02\x03\x02\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x02\x03\x02\x08w\0\0\0\0\0\0\x88w\0\0\0\0\0\0\x90~\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\x98\x85\0\0\0\0\0\0CST\0\0\x80p\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x98\0\xAB\0)C6~\xFF\xFF\xFF\xFF\x80\xA2\x97\xA0\xFF\xFF\xFF\xFF\xF0\x04y\xA1\xFF\xFF\xFF\xFF\x80^Y\xC8\xFF\xFF\xFF\xFFp\xF9\t\xC9\xFF\xFF\xFF\xFF\0\xBD\xD3\xC9\xFF\xFF\xFF\xFF\xF0\x8A\x05\xCB\xFF\xFF\xFF\xFF\0@|\xCB\xFF\xFF\xFF\xFF\xF0>;\xD2\xFF\xFF\xFF\xFF\x80{\x8B\xD3\xFF\xFF\xFF\xFF\xF0\xADB\xD4\xFF\xFF\xFF\xFF\0\"E\xD5\xFF\xFF\xFF\xFF\xF0\xBFL\xD6\xFF\xFF\xFF\xFF\0\xBF<\xD7\xFF\xFF\xFF\xFFpf\x06\xD8\xFF\xFF\xFF\xFF\x80\xF2\x1D\xD9\xFF\xFF\xFF\xFF\xF0|A\xD9\xFF\xFF\xFF\xFF R\xBA\x1E\0\0\0\0\x90\x9Bi\x1F\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xD7q\0\0\0\0\0\0\x80p\0\0\0\0\0\0\x90~\0\0\0\0\0\0+08\0\0\x80p\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\0I\0\xA3S6~\xFF\xFF\xFF\xFF\xA3\x85\x83\x86\xFF\xFF\xFF\xFF\x90Ng\xBA\xFF\xFF\xFF\xFF`\xE4\n\xC0\xFF\xFF\xFF\xFF`\xE5\xB3\xCA\xFF\xFF\xFF\xFF\x08_\x91\xCB\xFF\xFF\xFF\xFF\xF0mH\xD2\xFF\xFF\xFF\xFF\0\xEE\x91\x16\0\0\0\0\0\x01\x02\x02\x03\x04\x05\x04\x06]a\0\0\0\0\0\0pb\0\0\0\0\0\0 g\0\0\0\0\0\0 g\0\0\0\0\0\0xi\0\0\0\0\0\0\x90~\0\0\0\0\0\0\x80p\0\0\0\0\0\0+11\0\0\xB0\x9A\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x02i\x02\xE43\x19\xAA\xFF\xFF\xFF\xFF\xE0\xA8\xA3\xB5\xFF\xFF\xFF\xFFP7'\x15\0\0\0\0\xC0k\x18\x16\0\0\0\0\xD0j\x08\x17\0\0\0\0@\x9F\xF9\x17\0\0\0\0P\x9E\xE9\x18\0\0\0\0\xC0\xD2\xDA\x19\0\0\0\0P#\xCC\x1A\0\0\0\0p0\xBC\x1B\0\0\0\0p!\xAC\x1C\0\0\0\0p\x12\x9C\x1D\0\0\0\0p\x03\x8C\x1E\0\0\0\0p\xF4{\x1F\0\0\0\0p\xE5k \0\0\0\0p\xD6[!\0\0\0\0p\xC7K\"\0\0\0\0p\xB8;#\0\0\0\0p\xA9+$\0\0\0\0p\x9A\x1B%\0\0\0\0p\x8B\x0B&\0\0\0\0\xF0\xB6\x04'\0\0\0\0\xF0\xA7\xF4'\0\0\0\0\0\xB6\xF4'\0\0\0\0\0\xA7\xE4(\0\0\0\0\0Ox)\0\0\0\0\xF0\x89\xD4)\0\0\0\0\xF0z\xC4*\0\0\0\0\xF0k\xB4+\0\0\0\0\xF0\\\xA4,\0\0\0\0\xF0M\x94-\0\0\0\0\xF0>\x84.\0\0\0\0\xF0/t/\0\0\0\0\xF0 d0\0\0\0\0pL]1\0\0\0\0p'r2\0\0\0\0p.=3\0\0\0\0p\tR4\0\0\0\0p\x10\x1D5\0\0\0\0p\xEB16\0\0\0\0p\xF2\xFC6\0\0\0\0\xF0\x07\x1B8\0\0\0\0p\xD4\xDC8\0\0\0\0\xF0\xE9\xFA9\0\0\0\0p\xB6\xBC:\0\0\0\0\xF0\xCB\xDA;\0\0\0\0\xF0\xD2\xA5<\0\0\0\0\xF0\xAD\xBA=\0\0\0\0\xF0\xB4\x85>\0\0\0\0\xF0\x8F\x9A?\0\0\0\0\xF0\x96e@\0\0\0\0p\xAC\x83A\0\0\0\0\xF0xEB\0\0\0\0p\x8EcC\0\0\0\0\xF0Z%D\0\0\0\0ppCE\0\0\0\0\xF0<\x05F\0\0\0\0pR#G\0\0\0\0pY\xEEG\0\0\0\0p4\x03I\0\0\0\0p;\xCEI\0\0\0\0p\x16\xE3J\0\0\0\0p\x1D\xAEK\0\0\0\0\xF02\xCCL\0\0\0\0p\xFF\x8DM\0\0\0\0\xE0\xACKT\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x03\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x05\x02\x04\x1C\x90\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0CST\0\0\x80p\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0H\x01\x84\x01\x18\xF0\xCEt\xFF\xFF\xFF\xFF\x80IU\xC3\xFF\xFF\xFF\xFF\x80YT\xD2\xFF\xFF\xFF\xFF\x80{\x8B\xD3\xFF\xFF\xFF\xFF\xF0\xADB\xD4\xFF\xFF\xFF\xFF\0\"E\xD5\xFF\xFF\xFF\xFF\xF0\xBFL\xD6\xFF\xFF\xFF\xFF\0\xBF<\xD7\xFF\xFF\xFF\xFFpf\x06\xD8\xFF\xFF\xFF\xFF\x80\xF2\x1D\xD9\xFF\xFF\xFF\xFF\xF0\x99\xE7\xD9\xFF\xFF\xFF\xFF\0&\xFF\xDA\xFF\xFF\xFF\xFFp\xCD\xC8\xDB\xFF\xFF\xFF\xFF\x80Y\xE0\xDC\xFF\xFF\xFF\xFF\xF0\0\xAA\xDD\xFF\xFF\xFF\xFF\0sr\xDE\xFF\xFF\xFF\xFFpd\xB5\xDF\xFF\xFF\xFF\xFF\0\x85|\xE0\xFF\xFF\xFF\xFF\xF0\x97\x96\xE1\xFF\xFF\xFF\xFF\x80\xB8]\xE2\xFF\xFF\xFF\xFFp\xCBw\xE3\xFF\xFF\xFF\xFF\0\xEC>\xE4\xFF\xFF\xFF\xFFp 0\xE5\xFF\xFF\xFF\xFF\0q!\xE6\xFF\xFF\xFF\xFFp\xA5\x12\xE7\xFF\xFF\xFF\xFF\x80\xA4\x02\xE8\xFF\xFF\xFF\xFF\xF0\xD8\xF3\xE8\xFF\xFF\xFF\xFF\0\xD8\xE3\xE9\xFF\xFF\xFF\xFFp\x0C\xD5\xEA\xFF\xFF\xFF\xFF\x80\x0B\xC5\xEB\xFF\xFF\xFF\xFF\xF0?\xB6\xEC\xFF\xFF\xFF\xFF\0\xFC\xF7\xED\xFF\xFF\xFF\xFF\xF0\xC4\x98\xEE\xFF\xFF\xFF\xFF\x80/\xD9\xEF\xFF\xFF\xFF\xFFp\xF8y\xF0\xFF\xFF\xFF\xFF\0V\xFC\x07\0\0\0\0p\x8A\xED\x08\0\0\0\0\x80\x89\xDD\t\0\0\0\0\xF0\xBD\xCE\n\0\0\0\0\x80\xA1\xDB\x11\0\0\0\0p\xDDT\x12\0\0\0\0\x01\x02\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\xE8q\0\0\0\0\0\0\x80p\0\0\0\0\0\0\x90~\0\0\0\0\0\0\x90~\0\0\0\0\0\0+05\0\0PF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xC8\0\xE3\0\t\x83\x19\xAA\xFF\xFF\xFF\xFF0\xEF\xA3\xB5\xFF\xFF\xFF\xFF\xA0}'\x15\0\0\0\0\x10\xB2\x18\x16\0\0\0\0 \xB1\x08\x17\0\0\0\0\x90\xE5\xF9\x17\0\0\0\0\xA0\xE4\xE9\x18\0\0\0\0\x10\x19\xDB\x19\0\0\0\0\xA0i\xCC\x1A\0\0\0\0\xC0v\xBC\x1B\0\0\0\0\xC0g\xAC\x1C\0\0\0\0\xC0X\x9C\x1D\0\0\0\0\xC0I\x8C\x1E\0\0\0\0\xC0:|\x1F\0\0\0\0\xC0+l \0\0\0\0\xC0\x1C\\!\0\0\0\0\xC0\rL\"\0\0\0\0\xC0\xFE;#\0\0\0\0\xC0\xEF+$\0\0\0\0\xC0\xE0\x1B%\0\0\0\0\xC0\xD1\x0B&\0\0\0\0@\xFD\x04'\0\0\0\0@\xEE\xF4'\0\0\0\0P\xFC\xF4'\0\0\0\0P\xED\xE4(\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\xF7@\0\0\0\0\0\0PF\0\0\0\0\0\0`T\0\0\0\0\0\0pb\0\0\0\0\0\0`T\0\0\0\0\0\0+04\0\0@8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xA8\x01\xED\x01\x01\xBA\xB6V\xFF\xFF\xFF\xFF\x01\x9A\x19\xAA\xFF\xFF\xFF\xFFP\x0C\xDA\xE7\xFF\xFF\xFF\xFF\xC0\x99'\x15\0\0\0\x000\xCE\x18\x16\0\0\0\0@\xCD\x08\x17\0\0\0\0\xB0\x01\xFA\x17\0\0\0\0\xC0\0\xEA\x18\0\0\0\x0005\xDB\x19\0\0\0\0\xC0\x85\xCC\x1A\0\0\0\0\xE0\x92\xBC\x1B\0\0\0\0\xE0\x83\xAC\x1C\0\0\0\0\xE0t\x9C\x1D\0\0\0\0\xE0e\x8C\x1E\0\0\0\0\xE0V|\x1F\0\0\0\0\xE0Gl \0\0\0\0\xE08\\!\0\0\0\0\xE0)L\"\0\0\0\0\xE0\x1A<#\0\0\0\0\xE0\x0B,$\0\0\0\0\xE0\xFC\x1B%\0\0\0\0\xE0\xED\x0B&\0\0\0\0`\x19\x05'\0\0\0\0`\n\xF5'\0\0\0\0p\x18\xF5'\0\0\0\0p\t\xE5(\0\0\0\0P\xDE\xD4)\0\0\0\0@\xC1\xC4*\0\0\0\0P\xC0\xB4+\0\0\0\0@\xA3\xA4,\0\0\0\0P\xA2\x94-\0\0\0\0@\x85\x84.\0\0\0\0@vt/\0\0\0\x000Yd0\0\0\0\0\xC0\x92]1\0\0\0\0\xB0f=3\0\0\0\0\xB0AR4\0\0\0\0\xC0V\x1D5\0\0\0\0\xB0#26\0\0\0\0\xC08\xFD6\0\0\0\x000@\x1B8\0\0\0\0\xC0\x1A\xDD8\0\0\0\x000\"\xFB9\0\0\0\0\xC0\xFC\xBC:\0\0\0\x000\x04\xDB;\0\0\0\0@\x19\xA6<\0\0\0\x000\xE6\xBA=\0\0\0\0@\xFB\x85>\0\0\0\x000\xC8\x9A?\0\0\0\0@\xDDe@\0\0\0\0\xB0\xC7\xDD@\0\0\0\0\xF0\x1C\x84A\0\0\0\0p\xE9EB\0\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x02\x04\x03\x02\x04\x03\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x01\x02\x04\xFF)\0\0\0\0\0\x000*\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0@8\0\0\0\0\0\0+033081\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0(\x02m\x02\xC8}l\x9A\xFF\xFF\xFF\xFFH\xCC\0\xBF\xFF\xFF\xFF\xFF8D\x94\r\0\0\0\0\xB8\x13\xAD\x0E\0\0\0\0@sy\x0F\0\0\0\0\xC0\xCA(\x10\0\0\0\0\xC0\xFD\xA9\x10\0\0\0\0H\xBC\xAD\x11\0\0\0\0\xB8JE\x12\0\0\0\0\xC8\xEC7\x13\0\0\0\0\xB8\x15-\x14\0\0\0\0\xC8v (\0\0\0\0\xB8\x9D\xDB(\0\0\0\0\xC8\x9C\xCB)\0\0\0\0\xB8\"\xBE*\0\0\0\0H\xD0\xAC+\0\0\0\08V\x9F,\0\0\0\0\xC8\x03\x8E-\0\0\0\0\xB8\x89\x80.\0\0\0\0H7o/\0\0\0\08\xBDa0\0\0\0\0\xC8jP1\0\0\0\0\xB8\xF0B2\0\0\0\0\xC8\xEF23\0\0\0\0\xB8u%4\0\0\0\0H#\x145\0\0\0\08\xA9\x066\0\0\0\0\xC8V\xF56\0\0\0\0\xB8\xDC\xE77\0\0\0\0H\x8A\xD68\0\0\0\08\x10\xC99\0\0\0\0H\x0F\xB9:\0\0\0\08\x95\xAB;\0\0\0\0\xC8B\x9A<\0\0\0\0\xB8\xC8\x8C=\0\0\0\0Hv{>\0\0\0\08\xFCm?\0\0\0\0\xC8\xA9\\@\0\0\0\0\xB8/OA\0\0\0\0\xC8.?B\0\0\0\0\xB8\xB41C\0\0\0\0H\xC9\xE2G\0\0\0\08O\xD5H\0\0\0\0HN\xC5I\0\0\0\08\xD4\xB7J\0\0\0\0\xC8\x81\xA6K\0\0\0\0\xB8\x07\x99L\0\0\0\0H\xB5\x87M\0\0\0\08;zN\0\0\0\0\xC8\xE8hO\0\0\0\0\xB8n[P\0\0\0\0\xC8mKQ\0\0\0\0\xB8\xF3=R\0\0\0\0H\xA1,S\0\0\0\08'\x1FT\0\0\0\0\xC8\xD4\rU\0\0\0\0\xB8Z\0V\0\0\0\0H\x08\xEFV\0\0\0\08\x8E\xE1W\0\0\0\0H\x8D\xD1X\0\0\0\08\x13\xC4Y\0\0\0\0\xC8\xC0\xB2Z\0\0\0\0\xB8F\xA5[\0\0\0\0H\xF4\x93\\\0\0\0\08z\x86]\0\0\0\0\xC8'u^\0\0\0\0\xB8\xADg_\0\0\0\0\xC8\xACW`\0\0\0\0\xB82Ja\0\0\0\0\0\x01\x02\x03\x04\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x0180\0\0\0\0\0\081\0\0\0\0\0\0H?\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0+06\0\0`T\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\x12\0t\x15\xE6\xD5\xFF\xFF\xFF\xFF\xA8Ma!\0\0\0\0\x01\x02\x0CT\0\0\0\0\0\0XM\0\0\0\0\0\0`T\0\0\0\0\0\0JST\0\0\x90~\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\0\x1B\0p\xA4\xC2e\xFF\xFF\xFF\xFFp\x02>\xD7\xFF\xFF\xFF\xFF\xF0Y\xED\xD7\xFF\xFF\xFF\xFF\x01\x02\x01\x03\x83\0\0\0\0\0\0\x90~\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0+07\0\0pb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \x02{\x02\xD9N\xE5\xA1\xFF\xFF\xFF\xFF \xE1\xA3\xB5\xFF\xFF\xFF\xFF\x90o'\x15\0\0\0\0\0\xA4\x18\x16\0\0\0\0\x10\xA3\x08\x17\0\0\0\0\x80\xD7\xF9\x17\0\0\0\0\x90\xD6\xE9\x18\0\0\0\0\0\x0B\xDB\x19\0\0\0\0\x90[\xCC\x1A\0\0\0\0\xB0h\xBC\x1B\0\0\0\0\xB0Y\xAC\x1C\0\0\0\0\xB0J\x9C\x1D\0\0\0\0\xB0;\x8C\x1E\0\0\0\0\xB0,|\x1F\0\0\0\0\xB0\x1Dl \0\0\0\0\xB0\x0E\\!\0\0\0\0\xB0\xFFK\"\0\0\0\0\xB0\xF0;#\0\0\0\0\xB0\xE1+$\0\0\0\0\xB0\xD2\x1B%\0\0\0\0\xB0\xC3\x0B&\0\0\0\x000\xEF\x04'\0\0\0\x000\xE0\xF4'\0\0\0\0@\xEE\xF4'\0\0\0\0@\xDF\xE4(\0\0\0\0@\x87x)\0\0\0\x000\xC2\xD4)\0\0\0\x000\xB3\xC4*\0\0\0\x000\xA4\xB4+\0\0\0\x000\x95\xA4,\0\0\0\x000\x86\x94-\0\0\0\x000w\x84.\0\0\0\x000ht/\0\0\0\x000Yd0\0\0\0\0\xB0\x84]1\0\0\0\0\xB0_r2\0\0\0\0\xB0f=3\0\0\0\0\xB0AR4\0\0\0\0\xB0H\x1D5\0\0\0\0\xB0#26\0\0\0\0\xB0*\xFD6\0\0\0\x000@\x1B8\0\0\0\0\xB0\x0C\xDD8\0\0\0\x000\"\xFB9\0\0\0\0\xB0\xEE\xBC:\0\0\0\x000\x04\xDB;\0\0\0\x000\x0B\xA6<\0\0\0\0\xB0\xE9\xCE<\0\0\0\0@\xF4\xBA=\0\0\0\0@\xFB\x85>\0\0\0\0@\xD6\x9A?\0\0\0\0@\xDDe@\0\0\0\0\xC0\xF2\x83A\0\0\0\0@\xBFEB\0\0\0\0\xC0\xD4cC\0\0\0\0@\xA1%D\0\0\0\0\xC0\xB6CE\0\0\0\0@\x83\x05F\0\0\0\0\xC0\x98#G\0\0\0\0\xC0\x9F\xEEG\0\0\0\0\xC0z\x03I\0\0\0\0\xC0\x81\xCEI\0\0\0\0\xC0\\\xE3J\0\0\0\0\xC0c\xAEK\0\0\0\0@y\xCCL\0\0\0\0\xC0E\x8EM\0\0\0\x000\xF3KT\0\0\0\0\xC0\xF8IW\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x03\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\xA7O\0\0\0\0\0\0`T\0\0\0\0\0\0pb\0\0\0\0\0\0\x80p\0\0\0\0\0\0pb\0\0\0\0\0\0+08\0\0\x80p\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x80\x01\xB0\x01L\xEE\xD3\x86\xFF\xFF\xFF\xFF\x90\xDC\x0B\x0F\0\0\0\0\x80\xC8\xE9\x18\0\0\0\0\xF0\xFC\xDA\x19\0\0\0\0\x80M\xCC\x1A\0\0\0\0p0\xBC\x1B\0\0\0\0\x80/\xAC\x1C\0\0\0\0p\x12\x9C\x1D\0\0\0\0\x80\x11\x8C\x1E\0\0\0\0p\xF4{\x1F\0\0\0\0\x80\xF3k \0\0\0\0p\xD6[!\0\0\0\0\x80\xD5K\"\0\0\0\0p\xB8;#\0\0\0\0\x80\xB7+$\0\0\0\0p\x9A\x1B%\0\0\0\0\x80\x99\x0B&\0\0\0\0\xF0\xB6\x04'\0\0\0\0\0\xB6\xF4'\0\0\0\0\xF0\x98\xE4(\0\0\0\0\0\x98\xD4)\0\0\0\0\xF0z\xC4*\0\0\0\0\0z\xB4+\0\0\0\0\xF0\\\xA4,\0\0\0\0\0\\\x94-\0\0\0\0\xF0>\x84.\0\0\0\0\0>t/\0\0\0\0\xF0 d0\0\0\0\0\x80Z]1\0\0\0\0p=M2\0\0\0\0\x80<=3\0\0\0\0p\x1F-4\0\0\0\0\x80\x1E\x1D5\0\0\0\0p\x01\r6\0\0\0\0\xA0\xB3\xE9:\0\0\0\0\x90\xAC\xB4;\0\0\0\0\xA0\xAB\xA4<\0\0\0\0\x90\x8E\x94=\0\0\0\0\xA0\x8D\x84>\0\0\0\0\x90pt?\0\0\0\0\xA0od@\0\0\0\0\x90RTA\0\0\0\0\xA0QDB\0\0\0\0\x9044C\0\0\0\0\xA03$D\0\0\0\0\x10Q\x1DE\0\0\0\0\xA0\x9A\x15U\0\0\0\0pa\x05V\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x024d\0\0\0\0\0\0pb\0\0\0\0\0\0\x80p\0\0\0\0\0\0\x90~\0\0\0\0\0\0+06\0\0`T\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\t\0d\xBA\xFE\xB0\xFF\xFF\xFF\xFF\x01\x1CR\0\0\0\0\0\0`T\0\0\0\0\0\0+10\0\0\xA0\x8C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\x02r\x02\xBA\xDD\xDB\xA1\xFF\xFF\xFF\xFF\0\xC5\xA3\xB5\xFF\xFF\xFF\xFFpS'\x15\0\0\0\0\xC0k\x18\x16\0\0\0\0\xD0j\x08\x17\0\0\0\0@\x9F\xF9\x17\0\0\0\0P\x9E\xE9\x18\0\0\0\0\xC0\xD2\xDA\x19\0\0\0\0P#\xCC\x1A\0\0\0\0p0\xBC\x1B\0\0\0\0p!\xAC\x1C\0\0\0\0p\x12\x9C\x1D\0\0\0\0p\x03\x8C\x1E\0\0\0\0p\xF4{\x1F\0\0\0\0p\xE5k \0\0\0\0p\xD6[!\0\0\0\0p\xC7K\"\0\0\0\0p\xB8;#\0\0\0\0p\xA9+$\0\0\0\0p\x9A\x1B%\0\0\0\0p\x8B\x0B&\0\0\0\0\xF0\xB6\x04'\0\0\0\0\xF0\xA7\xF4'\0\0\0\0\0\xB6\xF4'\0\0\0\0\0\xA7\xE4(\0\0\0\0\0Ox)\0\0\0\0\xF0\x89\xD4)\0\0\0\0\xF0z\xC4*\0\0\0\0\xF0k\xB4+\0\0\0\0\xF0\\\xA4,\0\0\0\0\xF0M\x94-\0\0\0\0\xF0>\x84.\0\0\0\0\xF0/t/\0\0\0\0\xF0 d0\0\0\0\0pL]1\0\0\0\0p'r2\0\0\0\0p.=3\0\0\0\0p\tR4\0\0\0\0p\x10\x1D5\0\0\0\0p\xEB16\0\0\0\0p\xF2\xFC6\0\0\0\0\xF0\x07\x1B8\0\0\0\0p\xD4\xDC8\0\0\0\0\xF0\xE9\xFA9\0\0\0\0p\xB6\xBC:\0\0\0\0\xF0\xCB\xDA;\0\0\0\0\xF0\xD2\xA5<\0\0\0\0\xF0\xAD\xBA=\0\0\0\0\xF0\xB4\x85>\0\0\0\0\xF0\x8F\x9A?\0\0\0\0\xF0\x96e@\0\0\0\0p\xAC\x83A\0\0\0\0\xF0xEB\0\0\0\0p\x8EcC\0\0\0\0\xF0Z%D\0\0\0\0ppCE\0\0\0\0\xF0<\x05F\0\0\0\0pR#G\0\0\0\0pY\xEEG\0\0\0\0p4\x03I\0\0\0\0p;\xCEI\0\0\0\0p\x16\xE3J\0\0\0\0p\x1D\xAEK\0\0\0\0\xF02\xCCL\0\0\0\0p\xFF\x8DM\0\0\0\0@\xF4mN\0\0\0\0\xF0\xBAKT\0\0\0\0\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x04\x05\x04\x05\x06\x03\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x07\x04\x05\x06F\x86\0\0\0\0\0\0\x80p\0\0\0\0\0\0\x90~\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0+10\0\0\xA0\x8C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x02i\x02]GY\xA7\xFF\xFF\xFF\xFF\xF0\xB6\xA3\xB5\xFF\xFF\xFF\xFF`E'\x15\0\0\0\0\xD0y\x18\x16\0\0\0\0\xE0x\x08\x17\0\0\0\0P\xAD\xF9\x17\0\0\0\0`\xAC\xE9\x18\0\0\0\0\xD0\xE0\xDA\x19\0\0\0\0`1\xCC\x1A\0\0\0\0\x80>\xBC\x1B\0\0\0\0\x80/\xAC\x1C\0\0\0\0\x80 \x9C\x1D\0\0\0\0\x80\x11\x8C\x1E\0\0\0\0\x80\x02|\x1F\0\0\0\0\x80\xF3k \0\0\0\0\x80\xE4[!\0\0\0\0\x80\xD5K\"\0\0\0\0\x80\xC6;#\0\0\0\0\x80\xB7+$\0\0\0\0\x80\xA8\x1B%\0\0\0\0\x80\x99\x0B&\0\0\0\0\0\xC5\x04'\0\0\0\0\0\xB6\xF4'\0\0\0\0\x10\xC4\xF4'\0\0\0\0\x10\xB5\xE4(\0\0\0\0\x10]x)\0\0\0\0\0\x98\xD4)\0\0\0\0\0\x89\xC4*\0\0\0\0\0z\xB4+\0\0\0\0\0k\xA4,\0\0\0\0\0\\\x94-\0\0\0\0\0M\x84.\0\0\0\0\0>t/\0\0\0\0\0/d0\0\0\0\0\x80Z]1\0\0\0\0\x805r2\0\0\0\0\x80<=3\0\0\0\0\x80\x17R4\0\0\0\0\x80\x1E\x1D5\0\0\0\0\x80\xF916\0\0\0\0\x80\0\xFD6\0\0\0\0\0\x16\x1B8\0\0\0\0\x80\xE2\xDC8\0\0\0\0\0\xF8\xFA9\0\0\0\0\x80\xC4\xBC:\0\0\0\0\0\xDA\xDA;\0\0\0\0\0\xE1\xA5<\0\0\0\0\0\xBC\xBA=\0\0\0\0\0\xC3\x85>\0\0\0\0\0\x9E\x9A?\0\0\0\0\0\xA5e@\0\0\0\0\x80\xBA\x83A\0\0\0\0\0\x87EB\0\0\0\0\x80\x9CcC\0\0\0\0\0i%D\0\0\0\0\x80~CE\0\0\0\0\0K\x05F\0\0\0\0\x80`#G\0\0\0\0\x80g\xEEG\0\0\0\0\x80B\x03I\0\0\0\0\x80I\xCEI\0\0\0\0\x80$\xE3J\0\0\0\0\x80+\xAEK\0\0\0\0\0A\xCCL\0\0\0\0\x80\r\x8EM\0\0\0\0\xF0\xBAKT\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x03\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x05\x02\x04\xA3{\0\0\0\0\0\0\x90~\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0+09\0\0\x90~\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x02i\x02^\xEA\xDB\xA1\xFF\xFF\xFF\xFF\0\xC5\xA3\xB5\xFF\xFF\xFF\xFFpS'\x15\0\0\0\0\xE0\x87\x18\x16\0\0\0\0\xF0\x86\x08\x17\0\0\0\0`\xBB\xF9\x17\0\0\0\0p\xBA\xE9\x18\0\0\0\0\xE0\xEE\xDA\x19\0\0\0\0p?\xCC\x1A\0\0\0\0\x90L\xBC\x1B\0\0\0\0\x90=\xAC\x1C\0\0\0\0\x90.\x9C\x1D\0\0\0\0\x90\x1F\x8C\x1E\0\0\0\0\x90\x10|\x1F\0\0\0\0\x90\x01l \0\0\0\0\x90\xF2[!\0\0\0\0\x90\xE3K\"\0\0\0\0\x90\xD4;#\0\0\0\0\x90\xC5+$\0\0\0\0\x90\xB6\x1B%\0\0\0\0\x90\xA7\x0B&\0\0\0\0\x10\xD3\x04'\0\0\0\0\x10\xC4\xF4'\0\0\0\0 \xD2\xF4'\0\0\0\0 \xC3\xE4(\0\0\0\0 kx)\0\0\0\0\x10\xA6\xD4)\0\0\0\0\x10\x97\xC4*\0\0\0\0\x10\x88\xB4+\0\0\0\0\x10y\xA4,\0\0\0\0\x10j\x94-\0\0\0\0\x10[\x84.\0\0\0\0\x10Lt/\0\0\0\0\x10=d0\0\0\0\0\x90h]1\0\0\0\0\x90Cr2\0\0\0\0\x90J=3\0\0\0\0\x90%R4\0\0\0\0\x90,\x1D5\0\0\0\0\x90\x0726\0\0\0\0\x90\x0E\xFD6\0\0\0\0\x10$\x1B8\0\0\0\0\x90\xF0\xDC8\0\0\0\0\x10\x06\xFB9\0\0\0\0\x90\xD2\xBC:\0\0\0\0\x10\xE8\xDA;\0\0\0\0\x10\xEF\xA5<\0\0\0\0\x10\xCA\xBA=\0\0\0\0\x10\xD1\x85>\0\0\0\0\x10\xAC\x9A?\0\0\0\0\x10\xB3e@\0\0\0\0\x90\xC8\x83A\0\0\0\0\x10\x95EB\0\0\0\0\x90\xAAcC\0\0\0\0\x10w%D\0\0\0\0\x90\x8CCE\0\0\0\0\x10Y\x05F\0\0\0\0\x90n#G\0\0\0\0\x90u\xEEG\0\0\0\0\x90P\x03I\0\0\0\0\x90W\xCEI\0\0\0\0\x902\xE3J\0\0\0\0\x909\xAEK\0\0\0\0\x10O\xCCL\0\0\0\0\x90\x1B\x8EM\0\0\0\0\0\xC9KT\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x03\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x05\x02\x04\xA2y\0\0\0\0\0\0\x80p\0\0\0\0\0\0\x90~\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\x90~\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0+0630h[\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0$\0\xD1\x89\xB6V\xFF\xFF\xFF\xFFQs\xF2\xA1\xFF\xFF\xFF\xFF\x18\xFC\xF2\xCB\xFF\xFF\xFF\xFF\xF0g\x9A\xD1\xFF\xFF\xFF\xFF\0\x01\x02\x01/Z\0\0\0\0\0\0h[\0\0\0\0\0\0\x90~\0\0\0\0\0\0+05\0\0PF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\x02r\x02'\t_\x9B\xFF\xFF\xFF\xFF\xFF\xB1\x12\xA1\xFF\xFF\xFF\xFF@\xFD\xA3\xB5\xFF\xFF\xFF\xFF\xB0\x8B'\x15\0\0\0\0 \xC0\x18\x16\0\0\0\x000\xBF\x08\x17\0\0\0\0\xA0\xF3\xF9\x17\0\0\0\0\xB0\xF2\xE9\x18\0\0\0\0 '\xDB\x19\0\0\0\0\xB0w\xCC\x1A\0\0\0\0\xD0\x84\xBC\x1B\0\0\0\0\xD0u\xAC\x1C\0\0\0\0\xD0f\x9C\x1D\0\0\0\0\xD0W\x8C\x1E\0\0\0\0\xD0H|\x1F\0\0\0\0\xD09l \0\0\0\0\xD0*\\!\0\0\0\0\xD0\x1BL\"\0\0\0\0\xD0\x0C<#\0\0\0\0\xD0\xFD+$\0\0\0\0\xD0\xEE\x1B%\0\0\0\0\xD0\xDF\x0B&\0\0\0\0P\x0B\x05'\0\0\0\0P\xFC\xF4'\0\0\0\0`\n\xF5'\0\0\0\0`\xFB\xE4(\0\0\0\0`\xA3x)\0\0\0\0P\xDE\xD4)\0\0\0\0P\xCF\xC4*\0\0\0\0P\xC0\xB4+\0\0\0\0P\xB1\xA4,\0\0\0\0P\xA2\x94-\0\0\0\0P\x93\x84.\0\0\0\0P\x84t/\0\0\0\0Pud0\0\0\0\0\xD0\xA0]1\0\0\0\0\xD0{r2\0\0\0\0\xD0\x82=3\0\0\0\0\xD0]R4\0\0\0\0\xD0d\x1D5\0\0\0\0\xD0?26\0\0\0\0\xD0F\xFD6\0\0\0\0P\\\x1B8\0\0\0\0\xD0(\xDD8\0\0\0\0P>\xFB9\0\0\0\0\xD0\n\xBD:\0\0\0\0P \xDB;\0\0\0\0P'\xA6<\0\0\0\0P\x02\xBB=\0\0\0\0P\t\x86>\0\0\0\0P\xE4\x9A?\0\0\0\0P\xEBe@\0\0\0\0\xD0\0\x84A\0\0\0\0P\xCDEB\0\0\0\0\xD0\xE2cC\0\0\0\0P\xAF%D\0\0\0\0\xD0\xC4CE\0\0\0\0P\x91\x05F\0\0\0\0\xD0\xA6#G\0\0\0\0\xD0\xAD\xEEG\0\0\0\0\xD0\x88\x03I\0\0\0\0\xD0\x8F\xCEI\0\0\0\0\xD0j\xE3J\0\0\0\0\xD0q\xAEK\0\0\0\0P\x87\xCCL\0\0\0\0\xD0S\x8EM\0\0\0\0@\x01LT\0\0\0\0\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x03\x05\x03\x05\x02\x04\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x06\x03\x05\xD98\0\0\0\0\0\0\xC14\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0`T\0\0\0\0\0\0PF\0\0\0\0\0\0`T\0\0\0\0\0\0+04\0\0@8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xF8\x01M\x02H\x9A\x19\xAA\xFF\xFF\xFF\xFFP\x0C\xDA\xE7\xFF\xFF\xFF\xFF\xC0\x99'\x15\0\0\0\x000\xCE\x18\x16\0\0\0\0@\xCD\x08\x17\0\0\0\0\xB0\x01\xFA\x17\0\0\0\0\xC0\0\xEA\x18\0\0\0\x0005\xDB\x19\0\0\0\0\xC0\x85\xCC\x1A\0\0\0\0\xE0\x92\xBC\x1B\0\0\0\0\xE0\x83\xAC\x1C\0\0\0\0\xE0t\x9C\x1D\0\0\0\0\xE0e\x8C\x1E\0\0\0\0\xE0V|\x1F\0\0\0\0\xE0Gl \0\0\0\0\xE08\\!\0\0\0\0\xE0)L\"\0\0\0\0\xE0\x1A<#\0\0\0\0\xE0\x0B,$\0\0\0\0\xE0\xFC\x1B%\0\0\0\0\xE0\xED\x0B&\0\0\0\0`\x19\x05'\0\0\0\0`\n\xF5'\0\0\0\0p\x18\xF5'\0\0\0\0p\t\xE5(\0\0\0\0p\xFA\xD4)\0\0\0\0p\xEB\xC4*\0\0\0\0p\xDC\xB4+\0\0\0\0p\xCD\xA4,\0\0\0\0p\xBE\x94-\0\0\0\0p\xAF\x84.\0\0\0\0p\xA0t/\0\0\0\0p\x91d0\0\0\0\0\xE0\x90=3\0\0\0\0\xE0kR4\0\0\0\0\xE0r\x1D5\0\0\0\0\xE0M26\0\0\0\0\xE0T\xFD6\0\0\0\0`j\x1B8\0\0\0\0\xE06\xDD8\0\0\0\0`L\xFB9\0\0\0\0\xE0\x18\xBD:\0\0\0\0`.\xDB;\0\0\0\0`5\xA6<\0\0\0\0`\x10\xBB=\0\0\0\0`\x17\x86>\0\0\0\0`\xF2\x9A?\0\0\0\0`\xF9e@\0\0\0\0\xE0\x0E\x84A\0\0\0\0`\xDBEB\0\0\0\0\xE0\xF0cC\0\0\0\0`\xBD%D\0\0\0\0\xE0\xD2CE\0\0\0\0`\x9F\x05F\0\0\0\0\xE0\xB4#G\0\0\0\0\xE0\xBB\xEEG\0\0\0\0\xE0\x96\x03I\0\0\0\0\xE0\x9D\xCEI\0\0\0\0\xE0x\xE3J\0\0\0\0\xE0\x7F\xAEK\0\0\0\0`\x95\xCCL\0\0\0\0\xE0a\x8EM\0\0\0\0`w\xACN\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\xB8)\0\0\0\0\0\x000*\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0@8\0\0\0\0\0\0-01\0\0\xF0\xF1\xFF\xFF\xFF\xFF\xFF\xFF\x01+00\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0\0\0\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0\x10\x0E\0\0\0\0\0\08\x04\xD4\x04\x90\x1B=^\xFF\xFF\xFF\xFF\xA0\xAA\xE6\x92\xFF\xFF\xFF\xFF\x90\x89K\x9B\xFF\xFF\xFF\xFF\xA0\xE3\xFE\x9B\xFF\xFF\xFF\xFF\xA0\x17\x9D\x9C\xFF\xFF\xFF\xFF\x90\x9F\xC9\x9D\xFF\xFF\xFF\xFF K~\x9E\xFF\xFF\xFF\xFF\x10\xD3\xAA\x9F\xFF\xFF\xFF\xFF\xA0~_\xA0\xFF\xFF\xFF\xFF\x90\x06\x8C\xA1\xFF\xFF\xFF\xFF\xA0\x03B\xA2\xFF\xFF\xFF\xFF\x90\x8Bn\xA3\xFF\xFF\xFF\xFF 7#\xA4\xFF\xFF\xFF\xFF\x10\xBFO\xA5\xFF\xFF\xFF\xFF\x90\x0B\x06\xAA\xFF\xFF\xFF\xFF\x10|\xE7\xAA\xFF\xFF\xFF\xFF\x10\xC4\xC9\xAD\xFF\xFF\xFF\xFF\x10@\xA7\xAE\xFF\xFF\xFF\xFF\x90k\xA0\xAF\xFF\xFF\xFF\xFF\x10\"\x87\xB0\xFF\xFF\xFF\xFF\x10\x88\x89\xB1\xFF\xFF\xFF\xFF\x90>p\xB2\xFF\xFF\xFF\xFF\x90\xA4r\xB3\xFF\xFF\xFF\xFF\x90 P\xB4\xFF\xFF\xFF\xFF\x90h2\xB7\xFF\xFF\xFF\xFF\x90\xE4\x0F\xB8\xFF\xFF\xFF\xFF\x90\xD5\xFF\xB8\xFF\xFF\xFF\xFF\x90\xC6\xEF\xB9\xFF\xFF\xFF\xFF\x10\xD4\xC8\xBC\xFF\xFF\xFF\xFF\x10\xC5\xB8\xBD\xFF\xFF\xFF\xFF\x90{\x9F\xBE\xFF\xFF\xFF\xFF\x10\xA7\x98\xBF\xFF\xFF\xFF\xFF\x10\r\x9B\xC0\xFF\xFF\xFF\xFF\x10\x89x\xC1\xFF\xFF\xFF\xFF\x10zh\xC2\xFF\xFF\xFF\xFF\x10kX\xC3\xFF\xFF\xFF\xFF\x90!?\xC4\xFF\xFF\xFF\xFF\x10M8\xC5\xFF\xFF\xFF\xFF\x10\xB3:\xC6\xFF\xFF\xFF\xFF\x90\xC8X\xC7\xFF\xFF\xFF\xFF\x90\xFB\xD9\xC7\xFF\xFF\xFF\xFF\x90\xEE\x03\xC9\xFF\xFF\xFF\xFF\x90<\xF1\xC9\xFF\xFF\xFF\xFF\x10\x7F\xE2\xCA\xFF\xFF\xFF\xFF\x10o\xB5\xCB\xFF\xFF\xFF\xFF\0\xC0\xEC\xCB\xFF\xFF\xFF\xFF\0h\x80\xCC\xFF\xFF\xFF\xFF\x10\xBF\xDC\xCC\xFF\xFF\xFF\xFF\x10Q\x95\xCD\xFF\xFF\xFF\xFF\x80g\xC3\xCD\xFF\xFF\xFF\xFF\0\xBFr\xCE\xFF\xFF\xFF\xFF\x90\xDB\xC5\xCE\xFF\xFF\xFF\xFF\x103u\xCF\xFF\xFF\xFF\xFF\0\x84\xAC\xCF\xFF\xFF\xFF\xFF\0\xA1R\xD0\xFF\xFF\xFF\xFF\x90\xBD\xA5\xD0\xFF\xFF\xFF\xFF\x10\x15U\xD1\xFF\xFF\xFF\xFF\0f\x8C\xD1\xFF\xFF\xFF\xFF\0\x832\xD2\xFF\xFF\xFF\xFF\x90\x9F\x85\xD2\xFF\xFF\xFF\xFF\x10\xE1Y\xD3\xFF\xFF\xFF\xFF\x10\xD2I\xD4\xFF\xFF\xFF\xFF@\xED9\xD5\xFF\xFF\xFF\xFF@\xDE)\xD6\xFF\xFF\xFF\xFF@\xCF\x19\xD7\xFF\xFF\xFF\xFF@\xC0\t\xD8\xFF\xFF\xFF\xFF@\xB1\xF9\xD8\xFF\xFF\xFF\xFF@\xA2\xE9\xD9\xFF\xFF\xFF\xFF@\x93\xD9\xDA\xFF\xFF\xFF\xFF@\x84\xC9\xDB\xFF\xFF\xFF\xFF@u\xB9\xDC\xFF\xFF\xFF\xFF\xC0\xA0\xB2\xDD\xFF\xFF\xFF\xFF\xC0\x91\xA2\xDE\xFF\xFF\xFF\xFF\xC0\x82\x92\xDF\xFF\xFF\xFF\xFF\xC0s\x82\xE0\xFF\xFF\xFF\xFF\xC0dr\xE1\xFF\xFF\xFF\xFF\xC0Ub\xE2\xFF\xFF\xFF\xFF\xC0FR\xE3\xFF\xFF\xFF\xFF\xC07B\xE4\xFF\xFF\xFF\xFF\xC0(2\xE5\xFF\xFF\xFF\xFF\xC0\x19\"\xE6\xFF\xFF\xFF\xFF@E\x1B\xE7\xFF\xFF\xFF\xFF@6\x0B\xE8\xFF\xFF\xFF\xFF@'\xFB\xE8\xFF\xFF\xFF\xFF@\x18\xEB\xE9\xFF\xFF\xFF\xFF@\t\xDB\xEA\xFF\xFF\xFF\xFF@\xFA\xCA\xEB\xFF\xFF\xFF\xFF@\xEB\xBA\xEC\xFF\xFF\xFF\xFF@\xDC\xAA\xED\xFF\xFF\xFF\xFF@\xCD\x9A\xEE\xFF\xFF\xFF\xFF@\xBE\x8A\xEF\xFF\xFF\xFF\xFF@\xAFz\xF0\xFF\xFF\xFF\xFF@\xA0j\xF1\xFF\xFF\xFF\xFF\xC0\xCBc\xF2\xFF\xFF\xFF\xFF\xC0\xBCS\xF3\xFF\xFF\xFF\xFF\xC0\xADC\xF4\xFF\xFF\xFF\xFF\xC0\x9E3\xF5\xFF\xFF\xFF\xFF\xC0\x8F#\xF6\xFF\xFF\xFF\xFF\xC0\x80\x13\xF7\xFF\xFF\xFF\xFF\xC0q\x03\xF8\xFF\xFF\xFF\xFF\xC0b\xF3\xF8\xFF\xFF\xFF\xFF\xC0S\xE3\xF9\xFF\xFF\xFF\xFF\x90\xCD\x03\x17\0\0\0\0\x90\xBE\xF3\x17\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x8C\x18\x1E\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0 \x0E=+\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x10\xC2\x1F,\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x02\x03\x04\x03\x02\x03\x04\x03\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x03\x05\x04\x06\x07\x04\x06\x03\x05\x04\x06\x03\x05\x04\x06\x03\x05\x04\x06\x03\x05\xF0\xE7\xFF\xFF\xFF\xFF\xFF\xFF(\xE5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF\xF0\xF1\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\xF0\xF1\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0AST\0\0\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\x01ADT\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x02\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x0B\x01\0 \x1C\0\0\0\0\0\0\0\x03`\x03F\x18\x87i\xFF\xFF\xFF\xFFF\xAE\xCC\x9C\xFF\xFF\xFF\xFF6K\xB7\x9D\xFF\xFF\xFF\xFF\xC6m\xB8\x9E\xFF\xFF\xFF\xFF6\xB8\x84\x9F\xFF\xFF\xFF\xFF\xE6\x1D\xC3\xB4\xFF\xFF\xFF\xFF\xE0\xA6b\xCB\xFF\xFF\xFF\xFF\xD0\xBC\xD3\xCC\xFF\xFF\xFF\xFF\xE0\xD1\x9E\xCD\xFF\xFF\xFF\xFF\xD0\x13\xC6\xCE\xFF\xFF\xFF\xFF`yu\xCF\xFF\xFF\xFF\xFFP0\xAF\xD0\xFF\xFF\xFF\xFF`[U\xD1\xFF\xFF\xFF\xFFP\x12\x8F\xD2\xFF\xFF\xFF\xFF`hq\xD5\xFF\xFF\xFF\xFF\xD0<\x0E\xD6\xFF\xFF\xFF\xFF\xE0\x84Z\xD7\xFF\xFF\xFF\xFFP\xE4\xE4\xD7\xFF\xFF\xFF\xFF\xE0f:\xD9\xFF\xFF\xFF\xFFP\xC6\xC4\xD9\xFF\xFF\xFF\xFF`\x83#\xDB\xFF\xFF\xFF\xFFP\xA8\xA4\xDB\xFF\xFF\xFF\xFF`e\x03\xDD\xFF\xFF\xFF\xFFP\x8A\x84\xDD\xFF\xFF\xFF\xFF`G\xE3\xDE\xFF\xFF\xFF\xFF\xD0\xA6m\xDF\xFF\xFF\xFF\xFF\xE0\tl\xE6\xFF\xFF\xFF\xFF\xD0\x027\xE7\xFF\xFF\xFF\xFF`\xB3 \x08\0\0\0\0P\x96\x10\t\0\0\0\0`\x95\0\n\0\0\0\0Px\xF0\n\0\0\0\0`w\xE0\x0B\0\0\0\0\xD0\x94\xD9\x0C\0\0\0\0`Y\xC0\r\0\0\0\0\xD0v\xB9\x0E\0\0\0\0\xE0u\xA9\x0F\0\0\0\0\xD0X\x99\x10\0\0\0\0\xE0W\x89\x11\0\0\0\0\xD0:y\x12\0\0\0\0\xE09i\x13\0\0\0\0\xD0\x1CY\x14\0\0\0\0\xE0\x1BI\x15\0\0\0\0\xD0\xFE8\x16\0\0\0\0\xE0\xFD(\x17\0\0\0\0P\x1B\"\x18\0\0\0\0\xE0\xDF\x08\x19\0\0\0\0P\xFD\x01\x1A\0\0\0\0`\xFC\xF1\x1A\0\0\0\0P\xDF\xE1\x1B\0\0\0\0`\xDE\xD1\x1C\0\0\0\0P\xC1\xC1\x1D\0\0\0\0`\xC0\xB1\x1E\0\0\0\0P\xA3\xA1\x1F\0\0\0\0\xE0\xF2u \0\0\0\0P\x85\x81!\0\0\0\0\xE0\xD4U\"\0\0\0\0\xD0\xA1j#\0\0\0\0\xE0\xB65$\0\0\0\0\xD0\x83J%\0\0\0\0\xE0\x98\x15&\0\0\0\0\xD0e*'\0\0\0\0`\xB5\xFE'\0\0\0\0\xD0G\n)\0\0\0\0`\x97\xDE)\0\0\0\0\xD0)\xEA*\0\0\0\0`y\xBE+\0\0\0\0PF\xD3,\0\0\0\0`[\x9E-\0\0\0\0P(\xB3.\0\0\0\0`=~/\0\0\0\0P\n\x930\0\0\0\0\xE0Yg1\0\0\0\0P\xECr2\0\0\0\0\xE0;G3\0\0\0\0P\xCER4\0\0\0\0\xE0\x1D'5\0\0\0\0P\xB026\0\0\0\0\xE0\xFF\x067\0\0\0\0\xD0\xCC\x1B8\0\0\0\0\xE0\xE1\xE68\0\0\0\0\xD0\xAE\xFB9\0\0\0\0\xE0\xC3\xC6:\0\0\0\0\xD0\x90\xDB;\0\0\0\0`\xE0\xAF<\0\0\0\0\xD0r\xBB=\0\0\0\0`\xC2\x8F>\0\0\0\0\xD0T\x9B?\0\0\0\0`\xA4o@\0\0\0\0Pq\x84A\0\0\0\0`\x86OB\0\0\0\0PSdC\0\0\0\0`h/D\0\0\0\0P5DE\0\0\0\0\xE0\x9A\xF3E\0\0\0\0\xD0Q-G\0\0\0\0\0\x01\0\x01\0\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02:\xC3\xFF\xFF\xFF\xFF\xFF\xFFJ\xD1\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFFWET\0\0\0\0\0\0\0\0\0\0\x01WEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0 \x1C\0\0\0\0\0\0 \x01D\x01\xF0\\\x04\xA6\xFF\xFF\xFF\xFF \xF7A\xD4\xFF\xFF\xFF\xFF\x006M\x13\0\0\0\0\x90\xFA3\x14\0\0\0\0\x90\xEB#\x15\0\0\0\0\x90\xDC\x13\x16\0\0\0\0\x90\xCD\x03\x17\0\0\0\0\x90\xBE\xF3\x17\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x90\xF1\xFF\xFF\xFF\xFF\xFF\xFF\xF0\xF1\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0-01\0\0\xF0\xF1\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0%\0\xA0\xAA\xE6\x92\xFF\xFF\xFF\xFF \x9C\x95\xCC\xFF\xFF\xFF\xFF\x10|t\xD2\xFF\xFF\xFF\xFF@\xF7\x17\x0B\0\0\0\0\x01\x02\x01\x02\x03\xF4\xE9\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF\xF0\xF1\xFF\xFF\xFF\xFF\xFF\xFF\xF0\xF1\xFF\xFF\xFF\xFF\xFF\xFFWET\0\0\0\0\0\0\0\0\0\0\x01WEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0 \x1C\0\0\0\0\0\0\x08\x01)\x01X\xA4m\x8B\xFF\xFF\xFF\xFF\0+\xB1\x14\0\0\0\0\x90\xDC\x13\x16\0\0\0\0\x90\xCD\x03\x17\0\0\0\0\x90\xBE\xF3\x17\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xA8\xF9\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0WET\0\0\0\0\0\0\0\0\0\0\x01WEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0 \x1C\0\0\0\0\0\0 \x04\xB4\x04X\x13=^\xFF\xFF\xFF\xFF\x90\x9C\xE6\x92\xFF\xFF\xFF\xFF\x80{K\x9B\xFF\xFF\xFF\xFF\x90\xD5\xFE\x9B\xFF\xFF\xFF\xFF\x90\t\x9D\x9C\xFF\xFF\xFF\xFF\x80\x91\xC9\x9D\xFF\xFF\xFF\xFF\x10=~\x9E\xFF\xFF\xFF\xFF\0\xC5\xAA\x9F\xFF\xFF\xFF\xFF\x90p_\xA0\xFF\xFF\xFF\xFF\x80\xF8\x8B\xA1\xFF\xFF\xFF\xFF\x90\xF5A\xA2\xFF\xFF\xFF\xFF\x80}n\xA3\xFF\xFF\xFF\xFF\x10)#\xA4\xFF\xFF\xFF\xFF\0\xB1O\xA5\xFF\xFF\xFF\xFF\x80\xFD\x05\xAA\xFF\xFF\xFF\xFF\0n\xE7\xAA\xFF\xFF\xFF\xFF\0\xB6\xC9\xAD\xFF\xFF\xFF\xFF\x002\xA7\xAE\xFF\xFF\xFF\xFF\x80]\xA0\xAF\xFF\xFF\xFF\xFF\0\x14\x87\xB0\xFF\xFF\xFF\xFF\0z\x89\xB1\xFF\xFF\xFF\xFF\x800p\xB2\xFF\xFF\xFF\xFF\x80\x96r\xB3\xFF\xFF\xFF\xFF\x80\x12P\xB4\xFF\xFF\xFF\xFF\x80Z2\xB7\xFF\xFF\xFF\xFF\x80\xD6\x0F\xB8\xFF\xFF\xFF\xFF\x80\xC7\xFF\xB8\xFF\xFF\xFF\xFF\x80\xB8\xEF\xB9\xFF\xFF\xFF\xFF\0\xC6\xC8\xBC\xFF\xFF\xFF\xFF\0\xB7\xB8\xBD\xFF\xFF\xFF\xFF\x80m\x9F\xBE\xFF\xFF\xFF\xFF\0\x99\x98\xBF\xFF\xFF\xFF\xFF\0\xFF\x9A\xC0\xFF\xFF\xFF\xFF\0{x\xC1\xFF\xFF\xFF\xFF\0lh\xC2\xFF\xFF\xFF\xFF\0]X\xC3\xFF\xFF\xFF\xFF\x80\x13?\xC4\xFF\xFF\xFF\xFF\0?8\xC5\xFF\xFF\xFF\xFF\0\xA5:\xC6\xFF\xFF\xFF\xFF\x80\xBAX\xC7\xFF\xFF\xFF\xFF\x80\xED\xD9\xC7\xFF\xFF\xFF\xFF\x80\xE0\x03\xC9\xFF\xFF\xFF\xFF\x80.\xF1\xC9\xFF\xFF\xFF\xFF\0q\xE2\xCA\xFF\xFF\xFF\xFF\0a\xB5\xCB\xFF\xFF\xFF\xFF\xF0\xB1\xEC\xCB\xFF\xFF\xFF\xFF\xF0Y\x80\xCC\xFF\xFF\xFF\xFF\0\xB1\xDC\xCC\xFF\xFF\xFF\xFF\0C\x95\xCD\xFF\xFF\xFF\xFFpY\xC3\xCD\xFF\xFF\xFF\xFF\xF0\xB0r\xCE\xFF\xFF\xFF\xFF\x80\xCD\xC5\xCE\xFF\xFF\xFF\xFF\0%u\xCF\xFF\xFF\xFF\xFF\xF0u\xAC\xCF\xFF\xFF\xFF\xFF\xF0\x92R\xD0\xFF\xFF\xFF\xFF\x80\xAF\xA5\xD0\xFF\xFF\xFF\xFF\0\x07U\xD1\xFF\xFF\xFF\xFF\xF0W\x8C\xD1\xFF\xFF\xFF\xFF\xF0t2\xD2\xFF\xFF\xFF\xFF\x80\x91\x85\xD2\xFF\xFF\xFF\xFF\0\xD3Y\xD3\xFF\xFF\xFF\xFF\0\xC4I\xD4\xFF\xFF\xFF\xFF0\xDF9\xD5\xFF\xFF\xFF\xFF0\xD0)\xD6\xFF\xFF\xFF\xFF0\xC1\x19\xD7\xFF\xFF\xFF\xFF0\xB2\t\xD8\xFF\xFF\xFF\xFF0\xA3\xF9\xD8\xFF\xFF\xFF\xFF0\x94\xE9\xD9\xFF\xFF\xFF\xFF0\x85\xD9\xDA\xFF\xFF\xFF\xFF0v\xC9\xDB\xFF\xFF\xFF\xFF0g\xB9\xDC\xFF\xFF\xFF\xFF\xB0\x92\xB2\xDD\xFF\xFF\xFF\xFF\xB0\x83\xA2\xDE\xFF\xFF\xFF\xFF\xB0t\x92\xDF\xFF\xFF\xFF\xFF\xB0e\x82\xE0\xFF\xFF\xFF\xFF\xB0Vr\xE1\xFF\xFF\xFF\xFF\xB0Gb\xE2\xFF\xFF\xFF\xFF\xB08R\xE3\xFF\xFF\xFF\xFF\xB0)B\xE4\xFF\xFF\xFF\xFF\xB0\x1A2\xE5\xFF\xFF\xFF\xFF\xB0\x0B\"\xE6\xFF\xFF\xFF\xFF07\x1B\xE7\xFF\xFF\xFF\xFF0(\x0B\xE8\xFF\xFF\xFF\xFF0\x19\xFB\xE8\xFF\xFF\xFF\xFF0\n\xEB\xE9\xFF\xFF\xFF\xFF0\xFB\xDA\xEA\xFF\xFF\xFF\xFF0\xEC\xCA\xEB\xFF\xFF\xFF\xFF0\xDD\xBA\xEC\xFF\xFF\xFF\xFF0\xCE\xAA\xED\xFF\xFF\xFF\xFF0\xBF\x9A\xEE\xFF\xFF\xFF\xFF0\xB0\x8A\xEF\xFF\xFF\xFF\xFF0\xA1z\xF0\xFF\xFF\xFF\xFF0\x92j\xF1\xFF\xFF\xFF\xFF\xB0\xBDc\xF2\xFF\xFF\xFF\xFF\xB0\xAES\xF3\xFF\xFF\xFF\xFF\xB0\x9FC\xF4\xFF\xFF\xFF\xFF\xB0\x903\xF5\xFF\xFF\xFF\xFF\xB0\x81#\xF6\xFF\xFF\xFF\xFF\xB0r\x13\xF7\xFF\xFF\xFF\xFF\xB0c\x03\xF8\xFF\xFF\xFF\xFF\xB0T\xF3\xF8\xFF\xFF\xFF\xFF\xB0E\xE3\xF9\xFF\xFF\xFF\xFF\0\xFA\x0C\x17\0\0\0\0\x80\xB0\xF3\x17\0\0\0\0\x80\xA1\xE3\x18\0\0\0\0\x80\x92\xD3\x19\0\0\0\0\x80\x83\xC3\x1A\0\0\0\0\0\xAF\xBC\x1B\0\0\0\0\0\xA0\xAC\x1C\0\0\0\0\0\x91\x9C\x1D\0\0\0\0\0\x82\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x03\x02\x01\x02\x03\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04(\xF0\xFF\xFF\xFF\xFF\xFF\xFF\xF0\xF1\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0\0\0\0\0\0\0\0\0-02\0\0\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\t\0\xC0\xFD\x86i\xFF\xFF\xFF\xFF\x01\xC0\xDD\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\08\x02\x9C\x02\xBC\x11\x87i\xFF\xFF\xFF\xFF<_D\x93\xFF\xFF\xFF\xFF\xC0ZO\xC3\xFF\xFF\xFF\xFF0\x036\xC4\xFF\xFF\xFF\xFF\xC0\0\0\0\0`\xC9Z?\0\0\0\0P\x0B\x82@\0\0\0\0`\xAB:A\0\0\0\0P\xEDaB\0\0\0\0`\x8D\x1AC\0\0\0\0P\xCFAD\0\0\0\0`o\xFAD\0\0\0\0P\xB1!F\0\0\0\0`Q\xDAF\0\0\0\0\xD0\xCD\nH\0\0\0\0\xE0m\xC3H\0\0\0\0\xD0\xAF\xEAI\0\0\0\0\xE0O\xA3J\0\0\0\0\xD0\x91\xCAK\0\0\0\0\xE01\x83L\0\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x03\x04\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\xC4\xC9\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFFACST\0\x98\x85\0\0\0\0\0\0\x01ACDT\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\n\x01\x000*\0\0\0\0\0\0\x02\0\0\0\x01\x04\x01\0 \x1C\0\0\0\0\0\0\xA8\x02\xFD\x02\x14\x8B\x16s\xFF\xFF\xFF\xFFp\x03\x12{\xFF\xFF\xFF\xFF\x88\xC9N\x9C\xFF\xFF\xFF\xFF\x086\xBC\x9C\xFF\xFF\xFF\xFF\x08\xBAT\xCB\xFF\xFF\xFF\xFF\x88l\xC7\xCB\xFF\xFF\xFF\xFF\x88]\xB7\xCC\xFF\xFF\xFF\xFF\x88N\xA7\xCD\xFF\xFF\xFF\xFF\x08z\xA0\xCE\xFF\xFF\xFF\xFF\x880\x87\xCF\xFF\xFF\xFF\xFF\x88@p\x03\0\0\0\0\x08#\r\x04\0\0\0\0\x88\"P\x05\0\0\0\0\x88?\xF6\x05\0\0\0\0\x88\x040\x07\0\0\0\0\x88!\xD6\x07\0\0\0\0\x88\xE6\x0F\t\0\0\0\0\x88\x03\xB6\t\0\0\0\0\x88\xC8\xEF\n\0\0\0\0\x08 \x9F\x0B\0\0\0\0\x08\xE5\xD8\x0C\0\0\0\0\x08\x02\x7F\r\0\0\0\0\x08\xC7\xB8\x0E\0\0\0\0\x08\xE4^\x0F\0\0\0\0\x08\xA9\x98\x10\0\0\0\0\x08\xC6>\x11\0\0\0\0\x08\x8Bx\x12\0\0\0\0\x08\xA8\x1E\x13\0\0\0\0\x08mX\x14\0\0\0\0\x08\x8A\xFE\x14\0\0\0\0\x08O8\x16\0\0\0\0\x88\xA6\xE7\x16\0\0\0\0\x88k!\x18\0\0\0\0\x88\x88\xC7\x18\0\0\0\0\x88M\x01\x1A\0\0\0\0\x88j\xA7\x1A\0\0\0\0\x88/\xE1\x1B\0\0\0\0\x88L\x87\x1C\0\0\0\0\x88\x11\xC1\x1D\0\0\0\0\x88\xA3y\x1E\0\0\0\0\x08\xB9\x97\x1F\0\0\0\0\x88\x85Y \0\0\0\0\x88\xD5\x80!\0\0\0\0\x08\xA2B\"\0\0\0\0\x08\xF2i#\0\0\0\0\x08\x84\"$\0\0\0\0\x08\xD4I%\0\0\0\0\x08f\x02&\0\0\0\0\x08\xB6)'\0\0\0\0\x08\xD3\xCF'\0\0\0\0\x08\x98\t)\0\0\0\0\x88d\xCB)\0\0\0\0\x08z\xE9*\0\0\0\0\x88\xD1\x98+\0\0\0\0\x88\x96\xD2,\0\0\0\0\x88(\x8B-\0\0\0\0\x88x\xB2.\0\0\0\0\x08Et/\0\0\0\0\x88Z\x920\0\0\0\0\x88a]1\0\0\0\0\x88\0\0\0\0\x08\xA5\x9A?\0\0\0\0\x08\xACe@\0\0\0\0\x88\xC1\x83A\0\0\0\0\x08\x8EEB\0\0\0\0\x88\xA3cC\0\0\0\0\x88\xAA.D\0\0\0\0\x88\x85CE\0\0\0\0\x08R\x05F\0\0\0\0\x88g#G\0\0\0\0\x08\xA9\xF7G\0\0\0\0\x08\x9A\xE7H\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xEC\x81\0\0\0\0\0\0\x90~\0\0\0\0\0\0\x98\x85\0\0\0\0\0\0\xA8\x93\0\0\0\0\0\0AEST\0\xA0\x8C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0p\0~\0\x08\x9F\xEDr\xFF\xFF\xFF\xFF\x80\xC2N\x9C\xFF\xFF\xFF\xFF\0/\xBC\x9C\xFF\xFF\xFF\xFF\0\xB3T\xCB\xFF\xFF\xFF\xFF\x80e\xC7\xCB\xFF\xFF\xFF\xFF\x80V\xB7\xCC\xFF\xFF\xFF\xFF\x80G\xA7\xCD\xFF\xFF\xFF\xFF\0s\xA0\xCE\xFF\xFF\xFF\xFF\x80)\x87\xCF\xFF\xFF\xFF\xFF\x809p\x03\0\0\0\0\0\x1C\r\x04\0\0\0\0\0\xCDI%\0\0\0\0\0\xEA\xEF%\0\0\0\0\0\xAF)'\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02x\x8F\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0ACST\0\x98\x85\0\0\0\0\0\0\x01ACDT\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\n\x01\x000*\0\0\0\0\0\0\x02\0\0\0\x01\x04\x01\0 \x1C\0\0\0\0\0\0\xB0\x02\x06\x03d\x88\x16s\xFF\xFF\xFF\xFF\xE0\xA5\x04v\xFF\xFF\xFF\xFFp\x03\x12{\xFF\xFF\xFF\xFF\x88\xC9N\x9C\xFF\xFF\xFF\xFF\x086\xBC\x9C\xFF\xFF\xFF\xFF\x08\xBAT\xCB\xFF\xFF\xFF\xFF\x88l\xC7\xCB\xFF\xFF\xFF\xFF\x88]\xB7\xCC\xFF\xFF\xFF\xFF\x88N\xA7\xCD\xFF\xFF\xFF\xFF\x08z\xA0\xCE\xFF\xFF\xFF\xFF\x880\x87\xCF\xFF\xFF\xFF\xFF\x88@p\x03\0\0\0\0\x08#\r\x04\0\0\0\0\x88\"P\x05\0\0\0\0\x88?\xF6\x05\0\0\0\0\x88\x040\x07\0\0\0\0\x88!\xD6\x07\0\0\0\0\x88\xE6\x0F\t\0\0\0\0\x88\x03\xB6\t\0\0\0\0\x88\xC8\xEF\n\0\0\0\0\x08 \x9F\x0B\0\0\0\0\x08\xE5\xD8\x0C\0\0\0\0\x08\x02\x7F\r\0\0\0\0\x08\xC7\xB8\x0E\0\0\0\0\x08\xE4^\x0F\0\0\0\0\x08\xA9\x98\x10\0\0\0\0\x08\xC6>\x11\0\0\0\0\x08\x8Bx\x12\0\0\0\0\x08\xA8\x1E\x13\0\0\0\0\x08mX\x14\0\0\0\0\x08\x8A\xFE\x14\0\0\0\0\x08O8\x16\0\0\0\0\x88\x90\x0C\x17\0\0\0\0\x88k!\x18\0\0\0\0\x88\x88\xC7\x18\0\0\0\0\x88M\x01\x1A\0\0\0\0\x88j\xA7\x1A\0\0\0\0\x88/\xE1\x1B\0\0\0\0\x88L\x87\x1C\0\0\0\0\x88\x11\xC1\x1D\0\0\0\0\x88\xA3y\x1E\0\0\0\0\x08\xB9\x97\x1F\0\0\0\0\x88\x85Y \0\0\0\0\x88\xD5\x80!\0\0\0\0\x08\xA2B\"\0\0\0\0\x08\xF2i#\0\0\0\0\x08\x84\"$\0\0\0\0\x08\xD4I%\0\0\0\0\x08\xF1\xEF%\0\0\0\0\x08\xB6)'\0\0\0\0\x08\xD3\xCF'\0\0\0\0\x08\x98\t)\0\0\0\0\x08\xB5\xAF)\0\0\0\0\x08z\xE9*\0\0\0\0\x88\xD1\x98+\0\0\0\0\x88\x96\xD2,\0\0\0\0\x88\xB3x-\0\0\0\0\x88x\xB2.\0\0\0\0\x88\x95X/\0\0\0\0\x88Z\x920\0\0\0\0\x88a]1\0\0\0\0\x88\0\0\0\0\x08\xA5\x9A?\0\0\0\0\x08\xACe@\0\0\0\0\x88\xC1\x83A\0\0\0\0\x08\x8EEB\0\0\0\0\x88\xA3cC\0\0\0\0\x88\xAA.D\0\0\0\0\x88\x85CE\0\0\0\0\x08R\x05F\0\0\0\0\x88g#G\0\0\0\0\x08\xA9\xF7G\0\0\0\0\x08\x9A\xE7H\0\0\0\0\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x9C\x84\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\x90~\0\0\0\0\0\0\x98\x85\0\0\0\0\0\0\xA8\x93\0\0\0\0\0\0ACST\0\x98\x85\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0H\0Q\0X\x92\x16s\xFF\xFF\xFF\xFFp\x03\x12{\xFF\xFF\xFF\xFF\x88\xC9N\x9C\xFF\xFF\xFF\xFF\x086\xBC\x9C\xFF\xFF\xFF\xFF\x08\xBAT\xCB\xFF\xFF\xFF\xFF\x88l\xC7\xCB\xFF\xFF\xFF\xFF\x88]\xB7\xCC\xFF\xFF\xFF\xFF\x88N\xA7\xCD\xFF\xFF\xFF\xFF\x08z\xA0\xCE\xFF\xFF\xFF\xFF\x01\x02\x03\x02\x03\x02\x03\x02\x03\xA8z\0\0\0\0\0\0\x90~\0\0\0\0\0\0\x98\x85\0\0\0\0\0\0\xA8\x93\0\0\0\0\0\0+0845\x0C{\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x80\0\x90\0\xB0\n\xA6t\xFF\xFF\xFF\xFF\x14\xD4N\x9C\xFF\xFF\xFF\xFF\x94@\xBC\x9C\xFF\xFF\xFF\xFF\x94\xC4T\xCB\xFF\xFF\xFF\xFF\x14w\xC7\xCB\xFF\xFF\xFF\xFF\x14h\xB7\xCC\xFF\xFF\xFF\xFF\x14Y\xA7\xCD\xFF\xFF\xFF\xFF\x14\xF1\x0F\t\0\0\0\0\x14\x0E\xB6\t\0\0\0\0\x14X\x01\x1A\0\0\0\0\x14u\xA7\x1A\0\0\0\0\x14R%)\0\0\0\0\x94\xBF\xAF)\0\0\0\0\x94\xB4qE\0\0\0\0\x94\\\x05F\0\0\0\0\x14r#G\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xD0x\0\0\0\0\0\0\x0C{\0\0\0\0\0\0\x1C\x89\0\0\0\0\0\0AEST\0\xA0\x8C\0\0\0\0\0\0\x01AEDT\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\n\x01\x000*\0\0\0\0\0\0\x02\0\0\0\x01\x04\x01\0 \x1C\0\0\0\0\0\0\0\x03`\x03\xE4\0.t\xFF\xFF\xFF\xFF\x80x\xD5\x9B\xFF\xFF\xFF\xFF\0/\xBC\x9C\xFF\xFF\xFF\xFF\x80D\xDA\x9D\xFF\xFF\xFF\xFF\x80a\x80\x9E\xFF\xFF\xFF\xFF\x80&\xBA\x9F\xFF\xFF\xFF\xFF\x80C`\xA0\xFF\xFF\xFF\xFF\0\xB3T\xCB\xFF\xFF\xFF\xFF\x80e\xC7\xCB\xFF\xFF\xFF\xFF\x80V\xB7\xCC\xFF\xFF\xFF\xFF\x80G\xA7\xCD\xFF\xFF\xFF\xFF\0s\xA0\xCE\xFF\xFF\xFF\xFF\x80)\x87\xCF\xFF\xFF\xFF\xFF\0\x8D\xC2\xFB\xFF\xFF\xFF\xFF\0~\xB2\xFC\xFF\xFF\xFF\xFF\0Y\xC7\xFD\xFF\xFF\xFF\xFF\x80\xB0v\xFE\xFF\xFF\xFF\xFF\0;\xA7\xFF\xFF\xFF\xFF\xFF\x80\x92V\0\0\0\0\0\0\x1D\x87\x01\0\0\0\0\0\xAF?\x02\0\0\0\0\x809p\x03\0\0\0\0\0\x1C\r\x04\0\0\0\0\x80\x1BP\x05\0\0\0\0\x808\xF6\x05\0\0\0\0\x80\xFD/\x07\0\0\0\0\x80\x1A\xD6\x07\0\0\0\0\x80\xDF\x0F\t\0\0\0\0\x80\xFC\xB5\t\0\0\0\0\x80\xC1\xEF\n\0\0\0\0\0\x19\x9F\x0B\0\0\0\0\0\xDE\xD8\x0C\0\0\0\0\0\xFB~\r\0\0\0\0\0\xC0\xB8\x0E\0\0\0\0\0\xDD^\x0F\0\0\0\0\0\xA2\x98\x10\0\0\0\0\0\xBF>\x11\0\0\0\0\0\x84x\x12\0\0\0\0\0\xA1\x1E\x13\0\0\0\0\0fX\x14\0\0\0\0\0\x83\xFE\x14\0\0\0\0\0H8\x16\0\0\0\0\0O\x03\x17\0\0\0\0\x80d!\x18\0\0\0\0\x001\xE3\x18\0\0\0\0\x80F\x01\x1A\0\0\0\0\x80c\xA7\x1A\0\0\0\0\x80(\xE1\x1B\0\0\0\0\x80E\x87\x1C\0\0\0\0\x80\n\xC1\x1D\0\0\0\0\x80'g\x1E\0\0\0\0\0\xB2\x97\x1F\0\0\0\0\x80~Y \0\0\0\0\x80\xCE\x80!\0\0\0\0\0\x9BB\"\0\0\0\0\0\xEBi#\0\0\0\0\0}\"$\0\0\0\0\0\xCDI%\0\0\0\0\0_\x02&\0\0\0\0\0\xAF)'\0\0\0\0\0\xB6\xF4'\0\0\0\0\x80\xE1\xED(\0\0\0\0\0\x98\xD4)\0\0\0\0\x80\xC3\xCD*\0\0\0\0\0z\xB4+\0\0\0\0\x80\xA5\xAD,\0\0\0\0\0\\\x94-\0\0\0\0\x80\x87\x8D.\0\0\0\0\0>t/\0\0\0\0\x80im0\0\0\0\0\x80Z]1\0\0\0\0\0\x86V2\0\0\0\0\x80<=3\0\0\0\0\0h64\0\0\0\0\x80\x1E\x1D5\0\0\0\0\0J\x166\0\0\0\0\x80\0\xFD6\0\0\0\0\0,\xF67\0\0\0\0\x80\xE2\xDC8\0\0\0\0\x80\xE9\xA79\0\0\0\0\x80\xC4\xBC:\0\0\0\0\x80*\xBF;\0\0\0\0\0\xE1\xA5<\0\0\0\0\x80\x0C\x9F=\0\0\0\0\0\xC3\x85>\0\0\0\0\x80\xEE~?\0\0\0\0\0\xA5e@\0\0\0\0\x80\xD0^A\0\0\0\0\0\x87EB\0\0\0\0\x80\xB2>C\0\0\0\0\x80\xA3.D\0\0\0\0\x80\x94\x1EE\0\0\0\0\0K\x05F\0\0\0\0\0\xB1\x07G\0\0\0\0\0\xA2\xF7G\0\0\0\0\0\x93\xE7H\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x1C\x8A\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0AEST\0\xA0\x8C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xA0\0\xB4\0\xD4\xA2\xEDr\xFF\xFF\xFF\xFF\x80\xC2N\x9C\xFF\xFF\xFF\xFF\0/\xBC\x9C\xFF\xFF\xFF\xFF\0\xB3T\xCB\xFF\xFF\xFF\xFF\x80e\xC7\xCB\xFF\xFF\xFF\xFF\x80V\xB7\xCC\xFF\xFF\xFF\xFF\x80G\xA7\xCD\xFF\xFF\xFF\xFF\0s\xA0\xCE\xFF\xFF\xFF\xFF\x80)\x87\xCF\xFF\xFF\xFF\xFF\x809p\x03\0\0\0\0\0\x1C\r\x04\0\0\0\0\0\xCDI%\0\0\0\0\0\xEA\xEF%\0\0\0\0\0\xAF)'\0\0\0\0\0\xCC\xCF'\0\0\0\0\0\x91\t)\0\0\0\0\0\xAE\xAF)\0\0\0\0\0s\xE9*\0\0\0\0\x80\xCA\x98+\0\0\0\0\x80\x8F\xD2,\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xAC\x8B\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0+1030\xA8\x93\0\0\0\0\0\0\x01+11\0\0\x08\x07\0\0\0\0\0\0\x02\0\0\0\x01\n\x01\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\x04\x01\0 \x1C\0\0\0\0\0\0\xC8\x01\x01\x02\xDCw\x16s\xFF\xFF\xFF\xFF\xE0f\xFE\x14\0\0\0\0\xF8@8\x16\0\0\0\0h\x8A\xE7\x16\0\0\0\0x]!\x18\0\0\0\0hl\xC7\x18\0\0\0\0x?\x01\x1A\0\0\0\0hN\xA7\x1A\0\0\0\0x!\xE1\x1B\0\0\0\0h0\x87\x1C\0\0\0\0x\x03\xC1\x1D\0\0\0\0p\x8Ey\x1E\0\0\0\0\xF8\xAA\x97\x1F\0\0\0\0ppY \0\0\0\0x\xC7\x80!\0\0\0\0\xF0\x8CB\"\0\0\0\0\xF8\xE3i#\0\0\0\0\xF0n\"$\0\0\0\0\xF8\xC5I%\0\0\0\0\xF0\xDB\xEF%\0\0\0\0\xF8\xA7)'\0\0\0\0\xF0\xBD\xCF'\0\0\0\0\xF8\x89\t)\0\0\0\0\xF0\x9F\xAF)\0\0\0\0\xF8k\xE9*\0\0\0\0p\xBC\x98+\0\0\0\0x\x88\xD2,\0\0\0\0p\x9Ex-\0\0\0\0xj\xB2.\0\0\0\0p\x80X/\0\0\0\0xL\x920\0\0\0\0pL]1\0\0\0\0x.r2\0\0\0\0p.=3\0\0\0\0x\x10R4\0\0\0\0p\x10\x1D5\0\0\0\0x\xF216\0\0\0\0p\xF2\xFC6\0\0\0\0\xF8\x0E\x1B8\0\0\0\0p\xD4\xDC8\0\0\0\0x\xE2\xA79\0\0\0\0p\xB6\xBC:\0\0\0\0\xF8\xD2\xDA;\0\0\0\0\xF0\xD2\xA5<\0\0\0\0\xF8\xB4\xBA=\0\0\0\0\xF0\xB4\x85>\0\0\0\0\xF8\x96\x9A?\0\0\0\0\xF0\x96e@\0\0\0\0x\xB3\x83A\0\0\0\0\xF0xEB\0\0\0\0x\x95cC\0\0\0\0p\x95.D\0\0\0\0xwCE\0\0\0\0\xF0<\x05F\0\0\0\0xY#G\0\0\0\0\xF0\x93\xF7G\0\0\0\0\xF8\x8B\xE7H\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04$\x95\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\xA8\x93\0\0\0\0\0\0\xB8\xA1\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0AEST\0\xA0\x8C\0\0\0\0\0\0\x01AEDT\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\n\x01\x000*\0\0\0\0\0\0\x02\0\0\0\x01\x04\x01\0 \x1C\0\0\0\0\0\0\xA0\x02\xF4\x02\x18\x85\x16s\xFF\xFF\xFF\xFF\x80\xC2N\x9C\xFF\xFF\xFF\xFF\0/\xBC\x9C\xFF\xFF\xFF\xFF\0\xB3T\xCB\xFF\xFF\xFF\xFF\x80e\xC7\xCB\xFF\xFF\xFF\xFF\x80V\xB7\xCC\xFF\xFF\xFF\xFF\x80G\xA7\xCD\xFF\xFF\xFF\xFF\0s\xA0\xCE\xFF\xFF\xFF\xFF\x80)\x87\xCF\xFF\xFF\xFF\xFF\x809p\x03\0\0\0\0\0\x1C\r\x04\0\0\0\0\x80\x1BP\x05\0\0\0\0\x808\xF6\x05\0\0\0\0\x80\xFD/\x07\0\0\0\0\x80\x1A\xD6\x07\0\0\0\0\x80\xDF\x0F\t\0\0\0\0\x80\xFC\xB5\t\0\0\0\0\x80\xC1\xEF\n\0\0\0\0\0\x19\x9F\x0B\0\0\0\0\0\xDE\xD8\x0C\0\0\0\0\0\xFB~\r\0\0\0\0\0\xC0\xB8\x0E\0\0\0\0\0\xDD^\x0F\0\0\0\0\0\xA2\x98\x10\0\0\0\0\0\xBF>\x11\0\0\0\0\0\x84x\x12\0\0\0\0\0\xA1\x1E\x13\0\0\0\0\0fX\x14\0\0\0\0\0\x83\xFE\x14\0\0\0\0\0H8\x16\0\0\0\0\x80\x9F\xE7\x16\0\0\0\0\x80d!\x18\0\0\0\0\x80\x81\xC7\x18\0\0\0\0\x80F\x01\x1A\0\0\0\0\x80c\xA7\x1A\0\0\0\0\x80(\xE1\x1B\0\0\0\0\x80E\x87\x1C\0\0\0\0\x80\n\xC1\x1D\0\0\0\0\x80\x9Cy\x1E\0\0\0\0\0\xB2\x97\x1F\0\0\0\0\x80~Y \0\0\0\0\0\x94w!\0\0\0\0\0\x9BB\"\0\0\0\0\0\xEBi#\0\0\0\0\0}\"$\0\0\0\0\0\xCDI%\0\0\0\0\0_\x02&\0\0\0\0\0\xAF)'\0\0\0\0\0\xCC\xCF'\0\0\0\0\0\x91\t)\0\0\0\0\0\xAE\xAF)\0\0\0\0\0s\xE9*\0\0\0\0\x80\xCA\x98+\0\0\0\0\x80\x8F\xD2,\0\0\0\0\x80\xACx-\0\0\0\0\x80q\xB2.\0\0\0\0\0>t/\0\0\0\0\x80S\x920\0\0\0\0\x80Z]1\0\0\0\0\x805r2\0\0\0\0\x80<=3\0\0\0\0\x80\x17R4\0\0\0\0\x80\x1E\x1D5\0\0\0\0\x80\xF916\0\0\0\0\x80\0\xFD6\0\0\0\0\0\x16\x1B8\0\0\0\0\x80\xE2\xDC8\0\0\0\0\x80\xE9\xA79\0\0\0\0\x80\xC4\xBC:\0\0\0\0\0\xDA\xDA;\0\0\0\0\0\xE1\xA5<\0\0\0\0\0\xBC\xBA=\0\0\0\0\0\xC3\x85>\0\0\0\0\0\x9E\x9A?\0\0\0\0\0\xA5e@\0\0\0\0\x80\xBA\x83A\0\0\0\0\0\x87EB\0\0\0\0\x80\x9CcC\0\0\0\0\x80\xA3.D\0\0\0\0\x80~CE\0\0\0\0\0K\x05F\0\0\0\0\x80`#G\0\0\0\0\0\xA2\xF7G\0\0\0\0\0\x93\xE7H\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xE8\x87\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0AWST\0\x80p\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x80\0\x90\0\xE4\x16\xA6t\xFF\xFF\xFF\xFF\xA0\xDEN\x9C\xFF\xFF\xFF\xFF K\xBC\x9C\xFF\xFF\xFF\xFF \xCFT\xCB\xFF\xFF\xFF\xFF\xA0\x81\xC7\xCB\xFF\xFF\xFF\xFF\xA0r\xB7\xCC\xFF\xFF\xFF\xFF\xA0c\xA7\xCD\xFF\xFF\xFF\xFF\xA0\xFB\x0F\t\0\0\0\0\xA0\x18\xB6\t\0\0\0\0\xA0b\x01\x1A\0\0\0\0\xA0\x7F\xA7\x1A\0\0\0\0\xA0\\%)\0\0\0\0 \xCA\xAF)\0\0\0\0 \xBFqE\0\0\0\0 g\x05F\0\0\0\0\xA0|#G\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x9Cl\0\0\0\0\0\0\x80p\0\0\0\0\0\0\x90~\0\0\0\0\0\0AEST\0\xA0\x8C\0\0\0\0\0\0\x01AEDT\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\n\x01\x000*\0\0\0\0\0\0\x02\0\0\0\x01\x04\x01\0 \x1C\0\0\0\0\0\0\xA0\x02\xF4\x02<\x7F\x16s\xFF\xFF\xFF\xFF\x80\xC2N\x9C\xFF\xFF\xFF\xFF\0/\xBC\x9C\xFF\xFF\xFF\xFF\0\xB3T\xCB\xFF\xFF\xFF\xFF\x80e\xC7\xCB\xFF\xFF\xFF\xFF\x80V\xB7\xCC\xFF\xFF\xFF\xFF\x80G\xA7\xCD\xFF\xFF\xFF\xFF\0s\xA0\xCE\xFF\xFF\xFF\xFF\x80)\x87\xCF\xFF\xFF\xFF\xFF\x809p\x03\0\0\0\0\0\x1C\r\x04\0\0\0\0\x80\x1BP\x05\0\0\0\0\x808\xF6\x05\0\0\0\0\x80\xFD/\x07\0\0\0\0\x80\x1A\xD6\x07\0\0\0\0\x80\xDF\x0F\t\0\0\0\0\x80\xFC\xB5\t\0\0\0\0\x80\xC1\xEF\n\0\0\0\0\0\x19\x9F\x0B\0\0\0\0\0\xDE\xD8\x0C\0\0\0\0\0\xFB~\r\0\0\0\0\0\xC0\xB8\x0E\0\0\0\0\0\xDD^\x0F\0\0\0\0\0\xA2\x98\x10\0\0\0\0\0\xBF>\x11\0\0\0\0\0\x84x\x12\0\0\0\0\0\xA1\x1E\x13\0\0\0\0\0fX\x14\0\0\0\0\0\x83\xFE\x14\0\0\0\0\0H8\x16\0\0\0\0\x80\x89\x0C\x17\0\0\0\0\x80d!\x18\0\0\0\0\x80\x81\xC7\x18\0\0\0\0\x80F\x01\x1A\0\0\0\0\x80c\xA7\x1A\0\0\0\0\x80(\xE1\x1B\0\0\0\0\x80E\x87\x1C\0\0\0\0\x80\n\xC1\x1D\0\0\0\0\x80\x9Cy\x1E\0\0\0\0\0\xB2\x97\x1F\0\0\0\0\x80~Y \0\0\0\0\x80\xCE\x80!\0\0\0\0\0\x9BB\"\0\0\0\0\0\xEBi#\0\0\0\0\0}\"$\0\0\0\0\0\xCDI%\0\0\0\0\0\xEA\xEF%\0\0\0\0\0\xAF)'\0\0\0\0\0\xCC\xCF'\0\0\0\0\0\x91\t)\0\0\0\0\0\xAE\xAF)\0\0\0\0\0s\xE9*\0\0\0\0\x80\xCA\x98+\0\0\0\0\x80\x8F\xD2,\0\0\0\0\x80\xACx-\0\0\0\0\x80q\xB2.\0\0\0\0\x80\x8EX/\0\0\0\0\x80S\x920\0\0\0\0\x80Z]1\0\0\0\0\x805r2\0\0\0\0\x80<=3\0\0\0\0\x80\x17R4\0\0\0\0\x80\x1E\x1D5\0\0\0\0\x80\xF916\0\0\0\0\x80\0\xFD6\0\0\0\0\0\x16\x1B8\0\0\0\0\x80\xE2\xDC8\0\0\0\0\x80\xE9\xA79\0\0\0\0\x80\xC4\xBC:\0\0\0\0\0\xDA\xDA;\0\0\0\0\0\xE1\xA5<\0\0\0\0\0\xBC\xBA=\0\0\0\0\0\xC3\x85>\0\0\0\0\0\x9E\x9A?\0\0\0\0\0\xA5e@\0\0\0\0\x80\xBA\x83A\0\0\0\0\0\x87EB\0\0\0\0\x80\x9CcC\0\0\0\0\x80\xA3.D\0\0\0\0\x80~CE\0\0\0\0\0K\x05F\0\0\0\0\x80`#G\0\0\0\0\0\xA2\xF7G\0\0\0\0\0\x93\xE7H\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xC4\x8D\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0GMT\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0-01\0\0\xF0\xF1\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xF0\xF1\xFF\xFF\xFF\xFF\xFF\xFF-10\0\0`s\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`s\xFF\xFF\xFF\xFF\xFF\xFF-11\0\0Pe\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0Pe\xFF\xFF\xFF\xFF\xFF\xFF-12\0\0@W\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@W\xFF\xFF\xFF\xFF\xFF\xFF-02\0\0\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF-03\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xD0\xD5\xFF\xFF\xFF\xFF\xFF\xFF-04\0\0\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xC0\xC7\xFF\xFF\xFF\xFF\xFF\xFF-05\0\0\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF-06\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF-07\0\0\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF-08\0\0\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF-09\0\0p\x81\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0p\x81\xFF\xFF\xFF\xFF\xFF\xFF+01\0\0\x10\x0E\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0+10\0\0\xA0\x8C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0+11\0\0\xB0\x9A\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0+12\0\0\xC0\xA8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0+13\0\0\xD0\xB6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xD0\xB6\0\0\0\0\0\0+14\0\0\xE0\xC4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xE0\xC4\0\0\0\0\0\0+02\0\0 \x1C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \x1C\0\0\0\0\0\0+03\0\x000*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x000*\0\0\0\0\0\0+04\0\0@8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@8\0\0\0\0\0\0+05\0\0PF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0PF\0\0\0\0\0\0+06\0\0`T\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`T\0\0\0\0\0\0+07\0\0pb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0pb\0\0\0\0\0\0+08\0\0\x80p\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x80p\0\0\0\0\0\0+09\0\0\x90~\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x90~\0\0\0\0\0\0UTC\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\x01CEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\0\xD0\0\xEA\0\x94\xB36~\xFF\xFF\xFF\xFF\0\xDBA\xD4\xFF\xFF\xFF\xFF\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02l\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0+04\0\0@8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x02l\x02tE\x18\xAA\xFF\xFF\xFF\xFFP\x0B\xA4\xB5\xFF\xFF\xFF\xFF\xC0\x99'\x15\0\0\0\x000\xCE\x18\x16\0\0\0\0@\xCD\x08\x17\0\0\0\0\xB0\x01\xFA\x17\0\0\0\0\xC0\0\xEA\x18\0\0\0\x0005\xDB\x19\0\0\0\0\xC0\x85\xCC\x1A\0\0\0\0\xE0\x92\xBC\x1B\0\0\0\0\xE0\x83\xAC\x1C\0\0\0\0\xE0t\x9C\x1D\0\0\0\0\xE0e\x8C\x1E\0\0\0\0\xE0V|\x1F\0\0\0\0\xE0Gl \0\0\0\0\xE08\\!\0\0\0\0\xE0)L\"\0\0\0\0\xE0\x1A<#\0\0\0\0\xE0\x0B,$\0\0\0\0\xF0\x19,$\0\0\0\0\xF0\n\x1C%\0\0\0\0\xF0\xFB\x0B&\0\0\0\0p'\x05'\0\0\0\0p\x18\xF5'\0\0\0\0`\xEC\xD4)\0\0\0\0p\xFA\xD4)\0\0\0\0p\xEB\xC4*\0\0\0\0p\xDC\xB4+\0\0\0\0p\xCD\xA4,\0\0\0\0p\xBE\x94-\0\0\0\0p\xAF\x84.\0\0\0\0p\xA0t/\0\0\0\0p\x91d0\0\0\0\0\xF0\xBC]1\0\0\0\0\xF0\x97r2\0\0\0\0\xF0\x9E=3\0\0\0\0\xF0yR4\0\0\0\0\xF0\x80\x1D5\0\0\0\0\xF0[26\0\0\0\0\xF0b\xFD6\0\0\0\0px\x1B8\0\0\0\0\xF0D\xDD8\0\0\0\0pZ\xFB9\0\0\0\0\xF0&\xBD:\0\0\0\0p<\xDB;\0\0\0\0pC\xA6<\0\0\0\0p\x1E\xBB=\0\0\0\0p%\x86>\0\0\0\0p\0\x9B?\0\0\0\0p\x07f@\0\0\0\0\xF0\x1C\x84A\0\0\0\0p\xE9EB\0\0\0\0\xF0\xFEcC\0\0\0\0p\xCB%D\0\0\0\0\xF0\xE0CE\0\0\0\0p\xAD\x05F\0\0\0\0\xF0\xC2#G\0\0\0\0\xF0\xC9\xEEG\0\0\0\0\xF0\xA4\x03I\0\0\0\0\xF0\xAB\xCEI\0\0\0\0\xF0\x86\xE3J\0\0\0\0\xF0\x8D\xAEK\0\0\0\0p\xA3\xCCL\0\0\0\0\xF0o\x8EM\0\0\0\0`\x1DLT\0\0\0\0p\x14\xF7V\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x02\x04\x01\x02\x04\x02\x04\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x0C-\0\0\0\0\0\x000*\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0@8\0\0\0\0\0\0EET\0\0 \x1C\0\0\0\0\0\0\x01EEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\x000*\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0@8\0\0\0\0\0\0\xC0\x01\x12\x02D\x98?t\xFF\xFF\xFF\xFF\x80!\x80\x9B\xFF\xFF\xFF\xFF\xE0\xE9|\xB9\xFF\xFF\xFF\xFF\xD0\xAF\xC6\xB9\xFF\xFF\xFF\xFF\xE0c\xF2\xC9\xFF\xFF\xFF\xFFP\xA8\x10\xCA\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\xF0L\xAA\xCD\xFF\xFF\xFF\xFF\xE0\x18\xA2\xCE\xFF\xFF\xFF\xFFpi\x93\xCF\xFF\xFF\xFF\xFF`\x9E\x13\xDF\xFF\xFF\xFF\xFFP\n\xB7\xDF\xFF\xFF\xFF\xFF`^\xEC\t\0\0\0\0`\xF4\x18\x0B\0\0\0\0\0\xAE\xCD\x0B\0\0\0\0\0\x9F\xBD\x0C\0\0\0\0\x80U\xA4\r\0\0\0\0\x80]\x8C\x0E\0\0\0\0\x807\x84\x0F\0\0\0\0\x10\xFCj\x10\0\0\0\0\xF0{d\x11\0\0\0\0\xF0\xAAR\x12\0\0\0\0`\x82F\x13\0\0\0\0P\xC23\x14\0\0\0\0\xE0\x0E\xB1\x14\0\0\0\0\x90\xDC\x13\x16\0\0\0\0\x90\xCD\x03\x17\0\0\0\0\x90\xBE\xF3\x17\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\0\x01\x02\x01\x02\x01\x03\x04\x01\x03\x04\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03\x02\x01\x03<\x16\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0 \x1C\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\x01CEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\0(\x01M\x01H\xF0<^\xFF\xFF\xFF\xFF\xE05\x02\xCA\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF\x10%\x82\xD0\xFF\xFF\xFF\xFF\x10\x8C\xA1\xD1\xFF\xFF\xFF\xFF\x90@N\xD2\xFF\xFF\xFF\xFF\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x018\x13\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\x01CEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\0\xE8\x01%\x02\xF8a\xA2o\xFF\xFF\xFF\xFF`\x17\x0C\x9B\xFF\xFF\xFF\xFF\xF0\xDA\xD5\x9B\xFF\xFF\xFF\xFF\x90\xAE\xD9\x9C\xFF\xFF\xFF\xFF\x90\xB5\xA4\x9D\xFF\xFF\xFF\xFF\x90\x90\xB9\x9E\xFF\xFF\xFF\xFF\x90\x97\x84\x9F\xFF\xFF\xFF\xFF\x90q\t\xC8\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF\x10%\x82\xD0\xFF\xFF\xFF\xFF\x10\x16r\xD1\xFF\xFF\xFF\xFF\0\x96\xB6\xD1\xFF\xFF\xFF\xFF\x80\xBEX\xD2\xFF\xFF\xFF\xFF\x10O\xA1\xD2\xFF\xFF\xFF\xFF\x90\x1Bc\xD3\xFF\xFF\xFF\xFF\x90#K\xD4\xFF\xFF\xFF\xFF \xD19\xD5\xFF\xFF\xFF\xFF\x90\xE7g\xD5\xFF\xFF\xFF\xFF\0s\xA8\xD5\xFF\xFF\xFF\xFF\x10\xB4)\xD6\xFF\xFF\xFF\xFF\x10\x1A,\xD7\xFF\xFF\xFF\xFF\x10\x96\t\xD8\xFF\xFF\xFF\xFF\x90\xC1\x02\xD9\xFF\xFF\xFF\xFF\x10x\xE9\xD9\xFF\xFF\xFF\xFF\x10DM\x13\0\0\0\0\x90\xFA3\x14\0\0\0\0\x90\xEB#\x15\0\0\0\0\x90\xDC\x13\x16\0\0\0\0\x90\xCD\x03\x17\0\0\0\0\x90\xBE\xF3\x17\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x88\x0C\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\x01CEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\08\x03\xCE\x03\xE6\xDF\xB6V\xFF\xFF\xFF\xFF\0\xC8\xE8m\xFF\xFF\xFF\xFF\x80ID\x98\xFF\xFF\xFF\xFFp%\x0C\x9B\xFF\xFF\xFF\xFF\xF0\xDA\xD5\x9B\xFF\xFF\xFF\xFF\x90\xAE\xD9\x9C\xFF\xFF\xFF\xFF\x90\xB5\xA4\x9D\xFF\xFF\xFF\xFF\x90\x90\xB9\x9E\xFF\xFF\xFF\xFF\x90\x97\x84\x9F\xFF\xFF\xFF\xFF0\xF8\xCE\x9F\xFF\xFF\xFF\xFF\xF0\xA5`\xA0\xFF\xFF\xFF\xFFp\xBB~\xA1\xFF\xFF\xFF\xFF\xF0\x12.\xA2\xFF\xFF\xFF\xFF\xF0Lz\xA3\xFF\xFF\xFF\xFF\xF0\x815\xA4\xFF\xFF\xFF\xFFp#^\xA5\xFF\xFF\xFF\xFF\xF05%\xA6\xFF\xFF\xFF\xFF\xF0\x9B'\xA7\xFF\xFF\xFF\xFF\xF0\x01*\xA8\xFF\xFF\xFF\xFF\xF0}\x07\xA9\xFF\xFF\xFF\xFFp4\xEE\xA9\xFF\xFF\xFF\xFF\xF0_\xE7\xAA\xFF\xFF\xFF\xFF\xF0P\xD7\xAB\xFF\xFF\xFF\xFF\xF0A\xC7\xAC\xFF\xFF\xFF\xFF\xF0\xA7\xC9\xAD\xFF\xFF\xFF\xFF\xF0#\xA7\xAE\xFF\xFF\xFF\xFFpO\xA0\xAF\xFF\xFF\xFF\xFF\xF0\x05\x87\xB0\xFF\xFF\xFF\xFF\xF0k\x89\xB1\xFF\xFF\xFF\xFF\xA0Lp\xB2\xFF\xFF\xFF\xFF\xA0\xB2r\xB3\xFF\xFF\xFF\xFF\xA0.P\xB4\xFF\xFF\xFF\xFF ZI\xB5\xFF\xFF\xFF\xFF\xA0\x100\xB6\xFF\xFF\xFF\xFF\xA0v2\xB7\xFF\xFF\xFF\xFF\xA0\xF2\x0F\xB8\xFF\xFF\xFF\xFF\xA0\xE3\xFF\xB8\xFF\xFF\xFF\xFF\xA0\xD4\xEF\xB9\xFF\xFF\xFF\xFF \x8B\xD6\xBA\xFF\xFF\xFF\xFF \xF1\xD8\xBB\xFF\xFF\xFF\xFF \xE2\xC8\xBC\xFF\xFF\xFF\xFF \xD3\xB8\xBD\xFF\xFF\xFF\xFF\xA0\x89\x9F\xBE\xFF\xFF\xFF\xFF \xB5\x98\xBF\xFF\xFF\xFF\xFF \x1B\x9B\xC0\xFF\xFF\xFF\xFF \x97x\xC1\xFF\xFF\xFF\xFF \x88h\xC2\xFF\xFF\xFF\xFF yX\xC3\xFF\xFF\xFF\xFF\xA0/?\xC4\xFF\xFF\xFF\xFF [8\xC5\xFF\xFF\xFF\xFF \xC1:\xC6\xFF\xFF\xFF\xFF\xA0\xD6X\xC7\xFF\xFF\xFF\xFF\xA0\t\xDA\xC7\xFF\xFF\xFF\xFF \x19J\xC8\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF\x90^n\xD0\xFF\xFF\xFF\xFF\x10\x16r\xD1\xFF\xFF\xFF\xFF\x90@N\xD2\xFF\xFF\xFF\xFF\x10@\x91\xD3\xFF\xFF\xFF\xFF\x90#K\xD4\xFF\xFF\xFF\xFF\x90c\xA4\r\0\0\0\0\x10\x1A\x8B\x0E\0\0\0\0\x90E\x84\x0F\0\0\0\0\x906t\x10\0\0\0\0\x90'd\x11\0\0\0\0\x90\x18T\x12\0\0\0\0\x10DM\x13\0\0\0\0\x90\xFA3\x14\0\0\0\0\x90\xEB#\x15\0\0\0\0\x90\xDC\x13\x16\0\0\0\0\x90\xCD\x03\x17\0\0\0\0\x90\xBE\xF3\x17\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x1A\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0EET\0\0 \x1C\0\0\0\0\0\0\x01EEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\x000*\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0@8\0\0\0\0\0\0\xB0\x01\xE6\x01\x08\xE0\xCFl\xFF\xFF\xFF\xFF\x08\xD2\xB0\xB7\xFF\xFF\xFF\xFF`\xF3>\xB9\xFF\xFF\xFF\xFF`\x9C\xEF\xB9\xFF\xFF\xFF\xFF`\x8D\xDF\xBA\xFF\xFF\xFF\xFF`~\xCF\xBB\xFF\xFF\xFF\xFF\xE0\xA9\xC8\xBC\xFF\xFF\xFF\xFF\xE0\x9A\xB8\xBD\xFF\xFF\xFF\xFF\xE0\x8B\xA8\xBE\xFF\xFF\xFF\xFF\xE0|\x98\xBF\xFF\xFF\xFF\xFF\xE0m\x88\xC0\xFF\xFF\xFF\xFF\xE0^x\xC1\xFF\xFF\xFF\xFF\xE0Oh\xC2\xFF\xFF\xFF\xFF\xE0@X\xC3\xFF\xFF\xFF\xFF\xE01H\xC4\xFF\xFF\xFF\xFF\xE0\"8\xC5\xFF\xFF\xFF\xFF\xE0\x13(\xC6\xFF\xFF\xFF\xFF\xE0\x04\x18\xC7\xFF\xFF\xFF\xFF`\xD1\xAD\x11\0\0\0\0P\xE0S\x12\0\0\0\0\xD0\x0BM\x13\0\0\0\0`\xD03\x14\0\0\0\0\x80\xDD#\x15\0\0\0\0\x80\xCE\x13\x16\0\0\0\0\x80\xBF\x03\x17\0\0\0\0\x80\xB0\xF3\x17\0\0\0\0\x80\xA1\xE3\x18\0\0\0\0\x80\x92\xD3\x19\0\0\0\0\x80\x83\xC3\x1A\0\0\0\0\0\xAF\xBC\x1B\0\0\0\0\0\xA0\xAC\x1C\0\0\0\0\0\x91\x9C\x1D\0\0\0\0\0\x82\x8C\x1E\0\0\0\0\0s|\x1F\0\0\0\0\0dl \0\0\0\0\0U\\!\0\0\0\0\0FL\"\0\0\0\0\x007<#\0\0\0\0\0(,$\0\0\0\0\0\x19\x1C%\0\0\0\0\0\n\x0C&\0\0\0\0\x805\x05'\0\0\0\0`\n\xF5'\0\0\0\0`\xFB\xE4(\0\0\0\0`\xEC\xD4)\0\0\0\0`\xDD\xC4*\0\0\0\0`\xCE\xB4+\0\0\0\0`\xBF\xA4,\0\0\0\0\xE0\xA0$-\0\0\0\0P\x93\x84.\0\0\0\0`\x92t/\0\0\0\0Pud0\0\0\0\0\xE0\xAE]1\0\0\0\0\xD0{r2\0\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01x\x18\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\x01CEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\0(\x02m\x02\x9C\x91\x17k\xFF\xFF\xFF\xFF`\x17\x0C\x9B\xFF\xFF\xFF\xFF\xF0\xDA\xD5\x9B\xFF\xFF\xFF\xFF\x90\xAE\xD9\x9C\xFF\xFF\xFF\xFF\x90\xB5\xA4\x9D\xFF\xFF\xFF\xFF\x90\x90\xB9\x9E\xFF\xFF\xFF\xFF\x90\x97\x84\x9F\xFF\xFF\xFF\xFF\x10\xC4\x9A\xA0\xFF\xFF\xFF\xFF\x90yd\xA1\xFF\xFF\xFF\xFF\x10\x1Ap\xA2\xFF\xFF\xFF\xFF\x10\x96M\xA3\xFF\xFF\xFF\xFF`\xB5\xF3\xC9\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF\x10%\x82\xD0\xFF\xFF\xFF\xFF\xE0x\x99\xD1\xFF\xFF\xFF\xFFp\xC9\x8A\xD2\xFF\xFF\xFF\xFF\x90\xA6P\xD3\xFF\xFF\xFF\xFF\x80\x15K\xD4\xFF\xFF\xFF\xFF\x10\xC39\xD5\xFF\xFF\xFF\xFF\x10\xB4)\xD6\xFF\xFF\xFF\xFF\x10\xA5\x19\xD7\xFF\xFF\xFF\xFF\x10\x96\t\xD8\xFF\xFF\xFF\xFF\x90\xC1\x02\xD9\xFF\xFF\xFF\xFF\x10x\xE9\xD9\xFF\xFF\xFF\xFF\xF0\xA8\xA2\xE2\xFF\xFF\xFF\xFF`\xF2Q\xE3\xFF\xFF\xFF\xFF\x10\xA7\x82\xE4\xFF\xFF\xFF\xFF\x90\xFE1\xE5\xFF\xFF\xFF\xFF\x10\xFEt\xE6\xFF\xFF\xFF\xFF\x90\xE0\x11\xE7\xFF\xFF\xFF\xFF\x10\xE0T\xE8\xFF\xFF\xFF\xFF\x90\xC2\xF1\xE8\xFF\xFF\xFF\xFF\xF0'M\x13\0\0\0\0p\xDE3\x14\0\0\0\0p\xCF#\x15\0\0\0\0p\xC0\x13\x16\0\0\0\0p\xB1\x03\x17\0\0\0\0p\xA2\xF3\x17\0\0\0\0p\x93\xE3\x18\0\0\0\0p\x84\xD3\x19\0\0\0\0p\xB7T\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xE4\x11\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0EET\0\0 \x1C\0\0\0\0\0\0\x01EEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\0\xE8\x01B\x02\xF8\xC8\xB6V\xFF\xFF\xFF\xFF\x0C\x9Fk\x9E\xFF\xFF\xFF\xFF\x08\xD2\xB0\xB7\xFF\xFF\xFF\xFF`\xF3>\xB9\xFF\xFF\xFF\xFF`\x9C\xEF\xB9\xFF\xFF\xFF\xFF`\x8D\xDF\xBA\xFF\xFF\xFF\xFF`~\xCF\xBB\xFF\xFF\xFF\xFF\xE0\xA9\xC8\xBC\xFF\xFF\xFF\xFF\xE0\x9A\xB8\xBD\xFF\xFF\xFF\xFF\xE0\x8B\xA8\xBE\xFF\xFF\xFF\xFF\xE0|\x98\xBF\xFF\xFF\xFF\xFF\xE0m\x88\xC0\xFF\xFF\xFF\xFF\xE0^x\xC1\xFF\xFF\xFF\xFF\xE0Oh\xC2\xFF\xFF\xFF\xFF\xE0@X\xC3\xFF\xFF\xFF\xFF\xE01H\xC4\xFF\xFF\xFF\xFF\xE0\"8\xC5\xFF\xFF\xFF\xFF\xE0\x13(\xC6\xFF\xFF\xFF\xFF\xE0\x04\x18\xC7\xFF\xFF\xFF\xFF`\x93\xBC\xC8\xFF\xFF\xFF\xFFP}w\xCA\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF`\x90N\xD0\xFF\xFF\xFF\xFF\xD0\xA7'\x15\0\0\0\0@\xDC\x18\x16\0\0\0\0P\xDB\x08\x17\0\0\0\0\xC0\x0F\xFA\x17\0\0\0\0\xD0\x0E\xEA\x18\0\0\0\0@C\xDB\x19\0\0\0\0\xD0\x93\xCC\x1A\0\0\0\0\xF0\xA0\xBC\x1B\0\0\0\0\xF0\x91\xAC\x1C\0\0\0\0\xF0\x82\x9C\x1D\0\0\0\0\xF0s\x8C\x1E\0\0\0\0\xF0d|\x1F\0\0\0\0\xF0Ul \0\0\0\0\xF0F\\!\0\0\0\0\xF07L\"\0\0\0\0\xF0(<#\0\0\0\0\xF0\x19,$\0\0\0\0\xF0\n\x1C%\0\0\0\0\xF0\xFB\x0B&\0\0\0\0\xE0LC&\0\0\0\0\x805\x05'\0\0\0\0\x80&\xF5'\0\0\0\0\x80\x17\xE5(\0\0\0\0`\xE8`)\0\0\0\0P\xCF\xC4*\0\0\0\0`\xCE\xB4+\0\0\0\0P\xB1\xA4,\0\0\0\0`\xB0\x94-\0\0\0\0P\x93\x84.\0\0\0\0`\x92t/\0\0\0\0Pud0\0\0\0\0\xE0\xAE]1\0\0\0\0\xD0{r2\0\0\0\0\0\xAD=3\0\0\0\0\0\x88R4\0\0\0\0\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\x03\x05\x06\x03\x05\x04\x07\x08\x04\x07\x08\x04\x07\x08\x04\x07\x08\x04\x07\x08\x04\x07\x08\x04\x07\x08\x04\x07\x08\x04\x07\x08\x04\x07\x08\x04\x07\x03\x05\x04\x07\x03\x05\x04\x07\x03\x05\x04\x07\x03\x05\x04\x07\x03\x05\x04\x07\x03\x05\x04\x07\x03\x05\x04\x07\x03\x05\x08\x1B\0\0\0\0\0\0\xF4\x1A\0\0\0\0\0\0x\x18\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0 \x1C\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\x000*\0\0\0\0\0\0@8\0\0\0\0\0\0GMT\0\0\0\0\0\0\0\0\0\0\x01IST\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0 \x1C\0\0\0\0\0\0\x90\x04<\x05\xF1\n\xD1W\xFF\xFF\xFF\xFF\x91\xB3&\x9B\xFF\xFF\xFF\xFF\x11\x0B\xD6\x9B\xFF\xFF\xFF\xFF\xA00\xCF\x9C\xFF\xFF\xFF\xFF\xA0\xC3\xA4\x9D\xFF\xFF\xFF\xFF\xA0\x9D\x9C\x9E\xFF\xFF\xFF\xFF\xA0\x1A\x97\x9F\xFF\xFF\xFF\xFF \xBA\x85\xA0\xFF\xFF\xFF\xFF\xA0\xFCv\xA1\xFF\xFF\xFF\xFF \x9Ce\xA2\xFF\xFF\xFF\xFF\xA0\xC8{\xA3\xFF\xFF\xFF\xFF\xA0\xB8N\xA4\xFF\xFF\xFF\xFF \xFB?\xA5\xFF\xFF\xFF\xFF `%\xA6\xFF\xFF\xFF\xFF \xC6'\xA7\xFF\xFF\xFF\xFF ,*\xA8\xFF\xFF\xFF\xFF\xA0\xF8\xEB\xA8\xFF\xFF\xFF\xFF\xA0\xD3\0\xAA\xFF\xFF\xFF\xFF \x15\xD5\xAA\xFF\xFF\xFF\xFF \xF0\xE9\xAB\xFF\xFF\xFF\xFF l\xC7\xAC\xFF\xFF\xFF\xFF \xD2\xC9\xAD\xFF\xFF\xFF\xFF N\xA7\xAE\xFF\xFF\xFF\xFF\xA0y\xA0\xAF\xFF\xFF\xFF\xFF 0\x87\xB0\xFF\xFF\xFF\xFF\xA0\xD0\x92\xB1\xFF\xFF\xFF\xFF\xA0Lp\xB2\xFF\xFF\xFF\xFF\xA0\xB2r\xB3\xFF\xFF\xFF\xFF\xA0.P\xB4\xFF\xFF\xFF\xFF ZI\xB5\xFF\xFF\xFF\xFF\xA0\x100\xB6\xFF\xFF\xFF\xFF\xA0v2\xB7\xFF\xFF\xFF\xFF\xA0\xF2\x0F\xB8\xFF\xFF\xFF\xFF\xA0X\x12\xB9\xFF\xFF\xFF\xFF\xA0\xD4\xEF\xB9\xFF\xFF\xFF\xFF \0\xE9\xBA\xFF\xFF\xFF\xFF \xF1\xD8\xBB\xFF\xFF\xFF\xFF W\xDB\xBC\xFF\xFF\xFF\xFF \xD3\xB8\xBD\xFF\xFF\xFF\xFF\xA0\xFE\xB1\xBE\xFF\xFF\xFF\xFF \xB5\x98\xBF\xFF\xFF\xFF\xFF \x1B\x9B\xC0\xFF\xFF\xFF\xFF \x97x\xC1\xFF\xFF\xFF\xFF \xFDz\xC2\xFF\xFF\xFF\xFF yX\xC3\xFF\xFF\xFF\xFF\xA0\xA4Q\xC4\xFF\xFF\xFF\xFF [8\xC5\xFF\xFF\xFF\xFF \xC1:\xC6\xFF\xFF\xFF\xFF\xA0\xD6X\xC7\xFF\xFF\xFF\xFF\xA0\t\xDA\xC7\xFF\xFF\xFF\xFF \xE0I\xD4\xFF\xFF\xFF\xFF\xA0!\x1E\xD5\xFF\xFF\xFF\xFF \xACN\xD6\xFF\xFF\xFF\xFF (,\xD7\xFF\xFF\xFF\xFF \x8E.\xD8\xFF\xFF\xFF\xFF \x95\xF9\xD8\xFF\xFF\xFF\xFF p\x0E\xDA\xFF\xFF\xFF\xFF \xEC\xEB\xDA\xFF\xFF\xFF\xFF\xA0\x17\xE5\xDB\xFF\xFF\xFF\xFF \xCE\xCB\xDC\xFF\xFF\xFF\xFF\xA0\xF9\xC4\xDD\xFF\xFF\xFF\xFF\xA0\xEA\xB4\xDE\xFF\xFF\xFF\xFF \x16\xAE\xDF\xFF\xFF\xFF\xFF\xA0\xCC\x94\xE0\xFF\xFF\xFF\xFF\xA0Hr\xE1\xFF\xFF\xFF\xFF tk\xE2\xFF\xFF\xFF\xFF\xA0*R\xE3\xFF\xFF\xFF\xFF\xA0\x90T\xE4\xFF\xFF\xFF\xFF\xA0\x0C2\xE5\xFF\xFF\xFF\xFF \xAD=\xE6\xFF\xFF\xFF\xFF )\x1B\xE7\xFF\xFF\xFF\xFF\xA0T\x14\xE8\xFF\xFF\xFF\xFF \x0B\xFB\xE8\xFF\xFF\xFF\xFF q\xFD\xE9\xFF\xFF\xFF\xFF \xED\xDA\xEA\xFF\xFF\xFF\xFF S\xDD\xEB\xFF\xFF\xFF\xFF \xCF\xBA\xEC\xFF\xFF\xFF\xFF\xA0\xFA\xB3\xED\xFF\xFF\xFF\xFF \xB1\x9A\xEE\xFF\xFF\xFF\xFF\xA0g\x81\xEF\xFF\xFF\xFF\xFF }\x9F\xF0\xFF\xFF\xFF\xFF\xA0Ia\xF1\xFF\xFF\xFF\xFF _\x7F\xF2\xFF\xFF\xFF\xFF fJ\xF3\xFF\xFF\xFF\xFF A_\xF4\xFF\xFF\xFF\xFF\xA0\r!\xF5\xFF\xFF\xFF\xFF #?\xF6\xFF\xFF\xFF\xFF\xA0\xEF\0\xF7\xFF\xFF\xFF\xFF \x05\x1F\xF8\xFF\xFF\xFF\xFF\xA0\xD1\xE0\xF8\xFF\xFF\xFF\xFF \xE7\xFE\xF9\xFF\xFF\xFF\xFF\xA0\xB3\xC0\xFA\xFF\xFF\xFF\xFF\xA0\x03\xE8\xFB\xFF\xFF\xFF\xFF\xA0\xAB{\xFC\xFF\xFF\xFF\xFFp\xBB\xC7\xFD\xFF\xFF\xFF\xFF \xC6p\x03\0\0\0\0 X)\x04\0\0\0\0 \xA8P\x05\0\0\0\0 :\t\x06\0\0\0\0 \x8A0\x07\0\0\0\0 \x1C\xE9\x07\0\0\0\0 l\x10\t\0\0\0\0 \xFE\xC8\t\0\0\0\0 N\xF0\n\0\0\0\0\xA0\x1A\xB2\x0B\0\0\0\0 0\xD0\x0C\0\0\0\0\xA0\xFC\x91\r\0\0\0\0 \x12\xB0\x0E\0\0\0\0\xA0\xDEq\x0F\0\0\0\0\xA0.\x99\x10\0\0\0\0\xA0\xC0Q\x11\0\0\0\0\xA0\x10y\x12\0\0\0\0\xA0\xA21\x13\0\0\0\0\xA0\xF2X\x14\0\0\0\0\x90\xEB#\x15\0\0\0\0\x90\xC68\x16\0\0\0\0\x90\xCD\x03\x17\0\0\0\0\x90\xA8\x18\x18\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\x8A\xF8\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xA7\xE1\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x89\xC1\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10k\xA1\x1F\0\0\0\0\x10rl \0\0\0\0\x10M\x81!\0\0\0\0\x10TL\"\0\0\0\0\x10/a#\0\0\0\0\x106,$\0\0\0\0\x90KJ%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90-*'\0\0\0\0\x904\xF5'\0\0\0\0\x90\x0F\n)\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\xF1\xE9*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xD3\xC9,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xB5\xA9.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\x97\x890\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x0F\xFA\xFF\xFF\xFF\xFF\xFF\xFF\x1F\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\x01CEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\0\xA0\x03$\x04\x04\n\xD1W\xFF\xFF\xFF\xFF\xA0\xAD&\x9B\xFF\xFF\xFF\xFF \x05\xD6\x9B\xFF\xFF\xFF\xFF\xA00\xCF\x9C\xFF\xFF\xFF\xFF\xA0\xC3\xA4\x9D\xFF\xFF\xFF\xFF\xA0\x9D\x9C\x9E\xFF\xFF\xFF\xFF\xA0\x1A\x97\x9F\xFF\xFF\xFF\xFF \xBA\x85\xA0\xFF\xFF\xFF\xFF\xA0\xFCv\xA1\xFF\xFF\xFF\xFF \x9Ce\xA2\xFF\xFF\xFF\xFF\xA0\xC8{\xA3\xFF\xFF\xFF\xFF\xA0\xB8N\xA4\xFF\xFF\xFF\xFF \xFB?\xA5\xFF\xFF\xFF\xFF `%\xA6\xFF\xFF\xFF\xFF \xC6'\xA7\xFF\xFF\xFF\xFF ,*\xA8\xFF\xFF\xFF\xFF\xA0\xF8\xEB\xA8\xFF\xFF\xFF\xFF\xA0\xD3\0\xAA\xFF\xFF\xFF\xFF \x15\xD5\xAA\xFF\xFF\xFF\xFF \xF0\xE9\xAB\xFF\xFF\xFF\xFF l\xC7\xAC\xFF\xFF\xFF\xFF \xD2\xC9\xAD\xFF\xFF\xFF\xFF N\xA7\xAE\xFF\xFF\xFF\xFF\xA0y\xA0\xAF\xFF\xFF\xFF\xFF 0\x87\xB0\xFF\xFF\xFF\xFF\xA0\xD0\x92\xB1\xFF\xFF\xFF\xFF\xA0Lp\xB2\xFF\xFF\xFF\xFF\xA0\xB2r\xB3\xFF\xFF\xFF\xFF\xA0.P\xB4\xFF\xFF\xFF\xFF ZI\xB5\xFF\xFF\xFF\xFF\xA0\x100\xB6\xFF\xFF\xFF\xFF\xA0v2\xB7\xFF\xFF\xFF\xFF\xA0\xF2\x0F\xB8\xFF\xFF\xFF\xFF\xA0X\x12\xB9\xFF\xFF\xFF\xFF\xA0\xD4\xEF\xB9\xFF\xFF\xFF\xFF \0\xE9\xBA\xFF\xFF\xFF\xFF \xF1\xD8\xBB\xFF\xFF\xFF\xFF W\xDB\xBC\xFF\xFF\xFF\xFF \xD3\xB8\xBD\xFF\xFF\xFF\xFF\xA0\xFE\xB1\xBE\xFF\xFF\xFF\xFF \xB5\x98\xBF\xFF\xFF\xFF\xFF \x1B\x9B\xC0\xFF\xFF\xFF\xFF \x97x\xC1\xFF\xFF\xFF\xFF \xFDz\xC2\xFF\xFF\xFF\xFF yX\xC3\xFF\xFF\xFF\xFF\xA0\xA4Q\xC4\xFF\xFF\xFF\xFF [8\xC5\xFF\xFF\xFF\xFF \xC1:\xC6\xFF\xFF\xFF\xFF\xA0\xD6X\xC7\xFF\xFF\xFF\xFF\xA0\t\xDA\xC7\xFF\xFF\xFF\xFF\x90&\x16\xCA\xFF\xFF\xFF\xFF\x90Y\x97\xCA\xFF\xFF\xFF\xFF\x90\x1E\xD1\xCB\xFF\xFF\xFF\xFF\x90;w\xCC\xFF\xFF\xFF\xFF\x90\0\xB1\xCD\xFF\xFF\xFF\xFF\x10X`\xCE\xFF\xFF\xFF\xFF\x90\xE2\x90\xCF\xFF\xFF\xFF\xFF\x90^n\xD0\xFF\xFF\xFF\xFF\x10\x16r\xD1\xFF\xFF\xFF\xFF\x102\xFB\xD1\xFF\xFF\xFF\xFF \xFEi\xD2\xFF\xFF\xFF\xFF\xA0)c\xD3\xFF\xFF\xFF\xFF \xE0I\xD4\xFF\xFF\xFF\xFF\xA0!\x1E\xD5\xFF\xFF\xFF\xFF\x90\xFDB\xD5\xFF\xFF\xFF\xFF\x10\xE0\xDF\xD5\xFF\xFF\xFF\xFF \xACN\xD6\xFF\xFF\xFF\xFF\xA0\x03\xFE\xD6\xFF\xFF\xFF\xFF \x8E.\xD8\xFF\xFF\xFF\xFF \x95\xF9\xD8\xFF\xFF\xFF\xFF p\x0E\xDA\xFF\xFF\xFF\xFF \xEC\xEB\xDA\xFF\xFF\xFF\xFF\xA0\x17\xE5\xDB\xFF\xFF\xFF\xFF \xCE\xCB\xDC\xFF\xFF\xFF\xFF\xA0\xF9\xC4\xDD\xFF\xFF\xFF\xFF\xA0\xEA\xB4\xDE\xFF\xFF\xFF\xFF \x16\xAE\xDF\xFF\xFF\xFF\xFF\xA0\xCC\x94\xE0\xFF\xFF\xFF\xFF\xA0Hr\xE1\xFF\xFF\xFF\xFF tk\xE2\xFF\xFF\xFF\xFF\xA0*R\xE3\xFF\xFF\xFF\xFF\xA0\x90T\xE4\xFF\xFF\xFF\xFF\xA0\x0C2\xE5\xFF\xFF\xFF\xFF \xAD=\xE6\xFF\xFF\xFF\xFF )\x1B\xE7\xFF\xFF\xFF\xFF\xA0T\x14\xE8\xFF\xFF\xFF\xFFpP\x92\x16\0\0\0\0\x90\xBE\xF3\x17\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\xFC\xFA\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0EET\0\0 \x1C\0\0\0\0\0\0\x01EEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\x000*\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0@8\0\0\0\0\0\0 \x01D\x01\x9B&\xBAS\xFF\xFF\xFF\xFF\x1Bos\xA4\xFF\xFF\xFF\xFF`Q\xCE\xCB\xFF\xFF\xFF\xFF`\xE5\xC0\xCC\xFF\xFF\xFF\xFF\x80\xDD#\x15\0\0\0\0\x80\xCE\x13\x16\0\0\0\0\x80\xBF\x03\x17\0\0\0\0\x80\xB0\xF3\x17\0\0\0\0\xE0us\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01e\x17\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0+03\0\x000*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x98\x03.\x04\xD8\xC8\xB6V\xFF\xFF\xFF\xFF\x98\xF5\x8B\x90\xFF\xFF\xFF\xFF`\x17\x0C\x9B\xFF\xFF\xFF\xFF\xD0\xBE\xD5\x9B\xFF\xFF\xFF\xFF\xE0ce\xA2\xFF\xFF\xFF\xFFP\x82{\xA3\xFF\xFF\xFF\xFF`\x80N\xA4\xFF\xFF\xFF\xFF\xD0\xB4?\xA5\xFF\xFF\xFF\xFF\xE0'%\xA6\xFF\xFF\xFF\xFF\xD0\x7F'\xA7\xFF\xFF\xFF\xFF`((\xAA\xFF\xFF\xFF\xFF\xD0\xFD\xE1\xAA\xFF\xFF\xFF\xFF\xE0\x89\xF9\xAB\xFF\xFF\xFF\xFFP1\xC3\xAC\xFF\xFF\xFF\xFF\xE0?\x81\xC8\xFF\xFF\xFF\xFFP\x13\x01\xC9\xFF\xFF\xFF\xFF`\xF5J\xC9\xFF\xFF\xFF\xFFP\x80\xCE\xCA\xFF\xFF\xFF\xFF`\xAE\xCB\xCB\xFF\xFF\xFF\xFFP\tk\xD2\xFF\xFF\xFF\xFF`9\xA2\xD3\xFF\xFF\xFF\xFFP\x02C\xD4\xFF\xFF\xFF\xFF\xE0\rL\xD5\xFF\xFF\xFF\xFF\xD0{)\xD6\xFF\xFF\xFF\xFF\xE0\xEF+\xD7\xFF\xFF\xFF\xFF\xD0]\t\xD8\xFF\xFF\xFF\xFF`\x97\x02\xD9\xFF\xFF\xFF\xFF\xD0?\xE9\xD9\xFF\xFF\xFF\xFF\xE0\xB3\xEB\xDA\xFF\xFF\xFF\xFFP\\\xD2\xDB\xFF\xFF\xFF\xFF`\xD0\xD4\xDC\xFF\xFF\xFF\xFFP>\xB2\xDD\xFF\xFF\xFF\xFF`\xB9\xF4\xF1\xFF\xFF\xFF\xFFP\xEFb\xF4\xFF\xFF\xFF\xFF`\x06h\xF5\xFF\xFF\xFF\xFF\xD08\x1F\xF6\xFF\xFF\xFF\xFFp\x93n\x06\0\0\0\0p\x9A9\x07\0\0\0\0\0u\xFB\x07\0\0\0\0p|\x19\t\0\0\0\0\0\xCB\xD0\t\0\0\0\0p^\xF9\n\0\0\0\0\x80\xFE\xB1\x0B\0\0\0\0p@\xD9\x0C\0\0\0\0\x80U\xA4\r\0\0\0\0p\xAD\xA6\x0E\0\0\0\0\x807\x84\x0F\0\0\0\0P\x11\xF8\x0F\0\0\0\0p\xB0\x89\x19\0\0\0\0\xE0\xB0\xDC\x19\0\0\0\0\xF0\xD0\xE6\x1B\0\0\0\0\xF0\xEF\xC6\x1C\0\0\0\0p1\x9B\x1D\0\0\0\0\xF0s\x8C\x1E\0\0\0\0\xF0d|\x1F\0\0\0\0\xF0Ul \0\0\0\0\xF0F\\!\0\0\0\0\xF07L\"\0\0\0\0\xF0(<#\0\0\0\0\xF0\x19,$\0\0\0\0\xF0\n\x1C%\0\0\0\0\xF0\xFB\x0B&\0\0\0\0p'\x05'\0\0\0\0p\x18\xF5'\0\0\0\0p\t\xE5(\0\0\0\0p\xFA\xD4)\0\0\0\0p\xEB\xC4*\0\0\0\0p\xDC\xB4+\0\0\0\0p\xCD\xA4,\0\0\0\0\xF0\x83\x8B-\0\0\0\0p\xAF\x84.\0\0\0\0p\xA0t/\0\0\0\0p\x91d0\0\0\0\0\xF0\xBC]1\0\0\0\0\xF0\x97r2\0\0\0\0\xF0\x9E=3\0\0\0\0\xF0yR4\0\0\0\0\xF0\x80\x1D5\0\0\0\0\xF0[26\0\0\0\0\xF0b\xFD6\0\0\0\0px\x1B8\0\0\0\0\xF0D\xDD8\0\0\0\0pZ\xFB9\0\0\0\0\xF0&\xBD:\0\0\0\0p<\xDB;\0\0\0\0pC\xA6<\0\0\0\0p\x1E\xBB=\0\0\0\0p%\x86>\0\0\0\0p\0\x9B?\0\0\0\0p\x07f@\0\0\0\0\xF0\x1C\x84A\0\0\0\0p\xE9EB\0\0\0\0\xF0\xFEcC\0\0\0\0p\xCB%D\0\0\0\0\xF0\xE0CE\0\0\0\0\x90\xC9\x05F\0\0\0\0\x10\xDF#G\0\0\0\0\x10\xE6\xEEG\0\0\0\0\x10\xC1\x03I\0\0\0\0\x10\xC8\xCEI\0\0\0\0\x10\xA3\xE3J\0\0\0\0\x10\xAA\xAEK\0\0\0\0\x90\xBF\xCCL\0\0\0\0\x90\xDD\x8FM\0\0\0\0\x90\xA1\xACN\0\0\0\0\x10nnO\0\0\0\0\x90\x83\x8CP\0\0\0\0\x90\x8AWQ\0\0\0\0\x90elR\0\0\0\0\x10\xBE8S\0\0\0\0\x90GLT\0\0\0\0\x90N\x17U\0\0\0\0\x90\x9E>V\0\0\0\0\x900\xF7V\0\0\0\0P.\xCFW\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x03\x04\x05\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x03\x04(\x1B\0\0\0\0\0\0h\x1B\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\x000*\0\0\0\0\0\0@8\0\0\0\0\0\0EET\0\0 \x1C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x80\x02\t\x03H[\xA2o\xFF\xFF\xFF\xFF`\x17\x0C\x9B\xFF\xFF\xFF\xFF\xF0\xDA\xD5\x9B\xFF\xFF\xFF\xFF\x90\xAE\xD9\x9C\xFF\xFF\xFF\xFF\x90\xB5\xA4\x9D\xFF\xFF\xFF\xFF\x90\x90\xB9\x9E\xFF\xFF\xFF\xFF\x90\x97\x84\x9F\xFF\xFF\xFF\xFF\x90q\t\xC8\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF\x10%\x82\xD0\xFF\xFF\xFF\xFF\x10\x16r\xD1\xFF\xFF\xFF\xFF\xE0w|\xD1\xFF\xFF\xFF\xFF`\x84\x95\xD1\xFF\xFF\xFF\xFFP\xAD\x8A\xD2\xFF\xFF\xFF\xFF\xE0\xB6Y\xD3\xFF\xFF\xFF\xFF\xD0\xA7'\x15\0\0\0\0@\xDC\x18\x16\0\0\0\0P\xDB\x08\x17\0\0\0\0\xC0\x0F\xFA\x17\0\0\0\0\xD0\x0E\xEA\x18\0\0\0\0@C\xDB\x19\0\0\0\0\xD0\x93\xCC\x1A\0\0\0\0\xF0\xA0\xBC\x1B\0\0\0\0\xF0\x91\xAC\x1C\0\0\0\0\xF0\x82\x9C\x1D\0\0\0\0\xF0s\x8C\x1E\0\0\0\0\xF0d|\x1F\0\0\0\0\xF0Ul \0\0\0\0\xF0F\\!\0\0\0\0\xF07L\"\0\0\0\0\xF0(<#\0\0\0\0\xF0\x19,$\0\0\0\0\0\x19\x1C%\0\0\0\0\0\n\x0C&\0\0\0\0\x805\x05'\0\0\0\0\x80&\xF5'\0\0\0\0\x80\x17\xE5(\0\0\0\0\x80\x08\xD5)\0\0\0\0\x80\xF9\xC4*\0\0\0\0\x80\xEA\xB4+\0\0\0\0\x80\xDB\xA4,\0\0\0\0\x80\xCC\x94-\0\0\0\0\x80\xBD\x84.\0\0\0\0\x80\xAEt/\0\0\0\0\x80\x9Fd0\0\0\0\0\0\xCB]1\0\0\0\0\0\xA6r2\0\0\0\0\0\xAD=3\0\0\0\0\0\x88R4\0\0\0\0\0\x8F\x1D5\0\0\0\0\0j26\0\0\0\0\0q\xFD6\0\0\0\0\x80\x86\x1B8\0\0\0\0\0S\xDD8\0\0\0\0\x80h\xFB9\0\0\0\0\x005\xBD:\0\0\0\0\x80J\xDB;\0\0\0\0\x80Q\xA6<\0\0\0\0\x80,\xBB=\0\0\0\0\x803\x86>\0\0\0\0\x80\x0E\x9B?\0\0\0\0\x80\x15f@\0\0\0\0\0+\x84A\0\0\0\0\x80\xF7EB\0\0\0\0\0\rdC\0\0\0\0\x80\xD9%D\0\0\0\0\0\xEFCE\0\0\0\0\x80\xBB\x05F\0\0\0\0\0\xD1#G\0\0\0\0\0\xD8\xEEG\0\0\0\0\0\xB3\x03I\0\0\0\0\0\xBA\xCEI\0\0\0\0\0\x95\xE3J\0\0\0\0\0\x9C\xAEK\0\0\0\0\x80\xB1\xCCL\0\0\0\0\0~\x8EM\0\0\0\0p+LT\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x03\x04\x02\x03\x04\x05\x06\x04\x05\x06\x04\x05\x06\x04\x05\x06\x04\x05\x06\x04\x05\x06\x04\x05\x06\x04\x05\x06\x04\x05\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x03\x04\x05\x02\x038\x13\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\x000*\0\0\0\0\0\0@8\0\0\0\0\0\0MSK\0\x000*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\x02b\x02\x809\0\xA1\xFF\xFF\xFF\xFFP\x0B\xA4\xB5\xFF\xFF\xFF\xFF\xC0\x99'\x15\0\0\0\x000\xCE\x18\x16\0\0\0\0@\xCD\x08\x17\0\0\0\0\xB0\x01\xFA\x17\0\0\0\0\xC0\0\xEA\x18\0\0\0\x0005\xDB\x19\0\0\0\0\xC0\x85\xCC\x1A\0\0\0\0\xE0\x92\xBC\x1B\0\0\0\0\xE0\x83\xAC\x1C\0\0\0\0\xE0t\x9C\x1D\0\0\0\0\xE0e\x8C\x1E\0\0\0\0\xE0V|\x1F\0\0\0\0\xE0Gl \0\0\0\0\xE08\\!\0\0\0\0\xE0)L\"\0\0\0\0\xE0\x1A<#\0\0\0\0\xE0\x0B,$\0\0\0\0\xF0\x19,$\0\0\0\0\xF0\n\x1C%\0\0\0\0\xF0\xFB\x0B&\0\0\0\0p'\x05'\0\0\0\0p\x18\xF5'\0\0\0\0`\xEC\xD4)\0\0\0\0p\xFA\xD4)\0\0\0\0p\xEB\xC4*\0\0\0\0p\xDC\xB4+\0\0\0\0p\xCD\xA4,\0\0\0\0p\xBE\x94-\0\0\0\0p\xAF\x84.\0\0\0\0p\xA0t/\0\0\0\0p\x91d0\0\0\0\0\xF0\xBC]1\0\0\0\0\xF0\x97r2\0\0\0\0\xF0\x9E=3\0\0\0\0\xF0yR4\0\0\0\0\xF0\x80\x1D5\0\0\0\0\xF0[26\0\0\0\0\xF0b\xFD6\0\0\0\0px\x1B8\0\0\0\0\xF0D\xDD8\0\0\0\0pZ\xFB9\0\0\0\0\xF0&\xBD:\0\0\0\0p<\xDB;\0\0\0\0pC\xA6<\0\0\0\0p\x1E\xBB=\0\0\0\0p%\x86>\0\0\0\0p\0\x9B?\0\0\0\0p\x07f@\0\0\0\0\xF0\x1C\x84A\0\0\0\0p\xE9EB\0\0\0\0\xF0\xFEcC\0\0\0\0p\xCB%D\0\0\0\0\xF0\xE0CE\0\0\0\0p\xAD\x05F\0\0\0\0\xF0\xC2#G\0\0\0\0\xF0\xC9\xEEG\0\0\0\0\xF0\xA4\x03I\0\0\0\0\xF0\xAB\xCEI\0\0\0\0\xF0\x86\xE3J\0\0\0\0\xF0\x8D\xAEK\0\0\0\0p\xA3\xCCL\0\0\0\0\xF0o\x8EM\0\0\0\0`\x1DLT\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x02\x04\x01\x02\x04\x02\x04\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x98.\0\0\0\0\0\x000*\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0@8\0\0\0\0\0\0EET\0\0 \x1C\0\0\0\0\0\0\x01EEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\x000*\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0@8\0\0\0\0\0\08\x01m\x01d\xC7\xB6V\xFF\xFF\xFF\xFFd\xA7\x19\xAA\xFF\xFF\xFF\xFF`\x19\xA4\xB5\xFF\xFF\xFF\xFF\xD0.\xCD\xCA\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFFp\xA8\xCD\xCE\xFF\xFF\xFF\xFF\xD0\xA7'\x15\0\0\0\0@\xDC\x18\x16\0\0\0\0P\xDB\x08\x17\0\0\0\0\xC0\x0F\xFA\x17\0\0\0\0\xD0\x0E\xEA\x18\0\0\0\0@C\xDB\x19\0\0\0\0\xD0\x93\xCC\x1A\0\0\0\0\xF0\xA0\xBC\x1B\0\0\0\0\xF0\x91\xAC\x1C\0\0\0\0\xF0\x82\x9C\x1D\0\0\0\0\xF0s\x8C\x1E\0\0\0\0\xF0d|\x1F\0\0\0\0\xF0Ul \0\0\0\0\xF0F\\!\0\0\0\0\xF07L\"\0\0\0\0\xF0(<#\0\0\0\0\xF0\x19,$\0\0\0\0\xF0\n\x1C%\0\0\0\0\xF0\xFB\x0B&\0\0\0\0\xE0 \x8D&\0\0\0\0\x80\x17\xE5(\0\0\0\0\x80\x08\xD5)\0\0\0\0\x80\xF9\xC4*\0\0\0\0\x80\xEA\xB4+\0\0\0\0\x80\xDB\xA4,\0\0\0\0\x80\xCC\x94-\0\0\0\0\x80\xBD\x84.\0\0\0\0\x80\xAEt/\0\0\0\0\x80\x9Fd0\0\0\0\0\0\xCB]1\0\0\0\0\x10\xB4r2\0\0\0\0\0\x01\x02\x01\x03\x04\x01\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x06\x01\x03\x02\x06\x01\x03\x02\x06\x01\x03\x02\x06\x01\x03\x02\x06\x01\x03\x02\x06\x01\x03\x9C\x1C\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0 \x1C\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0@8\0\0\0\0\0\x000*\0\0\0\0\0\0WET\0\0\0\0\0\0\0\0\0\0\x01WEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0 \x1C\0\0\0\0\0\0h\x04\x0B\x05\x80\x8E\xE6\x92\xFF\xFF\xFF\xFFpmK\x9B\xFF\xFF\xFF\xFF\x80\xC7\xFE\x9B\xFF\xFF\xFF\xFF\x80\xFB\x9C\x9C\xFF\xFF\xFF\xFFp\x83\xC9\x9D\xFF\xFF\xFF\xFF\0/~\x9E\xFF\xFF\xFF\xFF\xF0\xB6\xAA\x9F\xFF\xFF\xFF\xFF\x80b_\xA0\xFF\xFF\xFF\xFFp\xEA\x8B\xA1\xFF\xFF\xFF\xFF\x80\xE7A\xA2\xFF\xFF\xFF\xFFpon\xA3\xFF\xFF\xFF\xFF\0\x1B#\xA4\xFF\xFF\xFF\xFF\xF0\xA2O\xA5\xFF\xFF\xFF\xFFp\xEF\x05\xAA\xFF\xFF\xFF\xFF\xF0_\xE7\xAA\xFF\xFF\xFF\xFF\xF0\xA7\xC9\xAD\xFF\xFF\xFF\xFF\xF0#\xA7\xAE\xFF\xFF\xFF\xFFpO\xA0\xAF\xFF\xFF\xFF\xFF\xF0\x05\x87\xB0\xFF\xFF\xFF\xFF\xF0k\x89\xB1\xFF\xFF\xFF\xFFp\"p\xB2\xFF\xFF\xFF\xFFp\x88r\xB3\xFF\xFF\xFF\xFFp\x04P\xB4\xFF\xFF\xFF\xFFpL2\xB7\xFF\xFF\xFF\xFFp\xC8\x0F\xB8\xFF\xFF\xFF\xFFp\xB9\xFF\xB8\xFF\xFF\xFF\xFFp\xAA\xEF\xB9\xFF\xFF\xFF\xFF\xF0\xB7\xC8\xBC\xFF\xFF\xFF\xFF\xF0\xA8\xB8\xBD\xFF\xFF\xFF\xFFp_\x9F\xBE\xFF\xFF\xFF\xFF\xF0\x8A\x98\xBF\xFF\xFF\xFF\xFF\xF0\xF0\x9A\xC0\xFF\xFF\xFF\xFF\xF0lx\xC1\xFF\xFF\xFF\xFF\xF0]h\xC2\xFF\xFF\xFF\xFF\xF0NX\xC3\xFF\xFF\xFF\xFFp\x05?\xC4\xFF\xFF\xFF\xFF\xF008\xC5\xFF\xFF\xFF\xFF\xF0\x96:\xC6\xFF\xFF\xFF\xFFp\xACX\xC7\xFF\xFF\xFF\xFFp\xDF\xD9\xC7\xFF\xFF\xFF\xFFp\xD2\x03\xC9\xFF\xFF\xFF\xFFp \xF1\xC9\xFF\xFF\xFF\xFF\xF0b\xE2\xCA\xFF\xFF\xFF\xFF\xF0R\xB5\xCB\xFF\xFF\xFF\xFF\xE0\xA3\xEC\xCB\xFF\xFF\xFF\xFF\xE0K\x80\xCC\xFF\xFF\xFF\xFF\xF0\xA2\xDC\xCC\xFF\xFF\xFF\xFF\xF04\x95\xCD\xFF\xFF\xFF\xFF`K\xC3\xCD\xFF\xFF\xFF\xFF\xE0\xA2r\xCE\xFF\xFF\xFF\xFFp\xBF\xC5\xCE\xFF\xFF\xFF\xFF\xF0\x16u\xCF\xFF\xFF\xFF\xFF\xE0g\xAC\xCF\xFF\xFF\xFF\xFF\xE0\x84R\xD0\xFF\xFF\xFF\xFFp\xA1\xA5\xD0\xFF\xFF\xFF\xFF\xF0\xF8T\xD1\xFF\xFF\xFF\xFF\xE0I\x8C\xD1\xFF\xFF\xFF\xFF\xE0f2\xD2\xFF\xFF\xFF\xFFp\x83\x85\xD2\xFF\xFF\xFF\xFF\xF0\xC4Y\xD3\xFF\xFF\xFF\xFF\xF0\xB5I\xD4\xFF\xFF\xFF\xFF \xD19\xD5\xFF\xFF\xFF\xFF \xC2)\xD6\xFF\xFF\xFF\xFF \xB3\x19\xD7\xFF\xFF\xFF\xFF \xA4\t\xD8\xFF\xFF\xFF\xFF \x95\xF9\xD8\xFF\xFF\xFF\xFF \x86\xE9\xD9\xFF\xFF\xFF\xFF w\xD9\xDA\xFF\xFF\xFF\xFF h\xC9\xDB\xFF\xFF\xFF\xFF Y\xB9\xDC\xFF\xFF\xFF\xFF\xA0\x84\xB2\xDD\xFF\xFF\xFF\xFF\xA0u\xA2\xDE\xFF\xFF\xFF\xFF\xA0f\x92\xDF\xFF\xFF\xFF\xFF\xA0W\x82\xE0\xFF\xFF\xFF\xFF\xA0Hr\xE1\xFF\xFF\xFF\xFF\xA09b\xE2\xFF\xFF\xFF\xFF\xA0*R\xE3\xFF\xFF\xFF\xFF\xA0\x1BB\xE4\xFF\xFF\xFF\xFF\xA0\x0C2\xE5\xFF\xFF\xFF\xFF\xA0\xFD!\xE6\xFF\xFF\xFF\xFF )\x1B\xE7\xFF\xFF\xFF\xFF \x1A\x0B\xE8\xFF\xFF\xFF\xFF \x0B\xFB\xE8\xFF\xFF\xFF\xFF \xFC\xEA\xE9\xFF\xFF\xFF\xFF \xED\xDA\xEA\xFF\xFF\xFF\xFF \xDE\xCA\xEB\xFF\xFF\xFF\xFF \xCF\xBA\xEC\xFF\xFF\xFF\xFF \xC0\xAA\xED\xFF\xFF\xFF\xFF \xB1\x9A\xEE\xFF\xFF\xFF\xFF \xA2\x8A\xEF\xFF\xFF\xFF\xFF \x93z\xF0\xFF\xFF\xFF\xFF \x84j\xF1\xFF\xFF\xFF\xFF\xA0\xAFc\xF2\xFF\xFF\xFF\xFF\xA0\xA0S\xF3\xFF\xFF\xFF\xFF\xA0\x91C\xF4\xFF\xFF\xFF\xFF\xA0\x823\xF5\xFF\xFF\xFF\xFF\xA0s#\xF6\xFF\xFF\xFF\xFF\xA0d\x13\xF7\xFF\xFF\xFF\xFF\xA0U\x03\xF8\xFF\xFF\xFF\xFF\xA0F\xF3\xF8\xFF\xFF\xFF\xFF\xA07\xE3\xF9\xFF\xFF\xFF\xFF\0*\xAB\x0C\0\0\0\0\0\x0C\x8B\x0E\0\0\0\0\x90E\x84\x0F\0\0\0\0\x906t\x10\0\0\0\0\x90'd\x11\0\0\0\0\x90\x18T\x12\0\0\0\0\x10DM\x13\0\0\0\0\x90\xFA3\x14\0\0\0\0\x80\xDD#\x15\0\0\0\0\x80\xCE\x13\x16\0\0\0\0\x80\xBF\x03\x17\0\0\0\0\x80\xB0\xF3\x17\0\0\0\0\x80\xA1\xE3\x18\0\0\0\0\x80\x92\xD3\x19\0\0\0\0\x80\x83\xC3\x1A\0\0\0\0\0\xAF\xBC\x1B\0\0\0\0\0\xA0\xAC\x1C\0\0\0\0\0\x91\x9C\x1D\0\0\0\0\0~\x18\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x03\x02\x01\x02\x03\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x04\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x02\x04\x01c\xF7\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0GMT\0\0\0\0\0\0\0\0\0\0\x01BST\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0 \x1C\0\0\0\0\0\0\0\x05\xBA\x05\xCB\t]\x1A\xFF\xFF\xFF\xFF\xA0\xAD&\x9B\xFF\xFF\xFF\xFF \x05\xD6\x9B\xFF\xFF\xFF\xFF\xA00\xCF\x9C\xFF\xFF\xFF\xFF\xA0\xC3\xA4\x9D\xFF\xFF\xFF\xFF\xA0\x9D\x9C\x9E\xFF\xFF\xFF\xFF\xA0\x1A\x97\x9F\xFF\xFF\xFF\xFF \xBA\x85\xA0\xFF\xFF\xFF\xFF\xA0\xFCv\xA1\xFF\xFF\xFF\xFF \x9Ce\xA2\xFF\xFF\xFF\xFF\xA0\xC8{\xA3\xFF\xFF\xFF\xFF\xA0\xB8N\xA4\xFF\xFF\xFF\xFF \xFB?\xA5\xFF\xFF\xFF\xFF `%\xA6\xFF\xFF\xFF\xFF \xC6'\xA7\xFF\xFF\xFF\xFF ,*\xA8\xFF\xFF\xFF\xFF\xA0\xF8\xEB\xA8\xFF\xFF\xFF\xFF\xA0\xD3\0\xAA\xFF\xFF\xFF\xFF \x15\xD5\xAA\xFF\xFF\xFF\xFF \xF0\xE9\xAB\xFF\xFF\xFF\xFF l\xC7\xAC\xFF\xFF\xFF\xFF \xD2\xC9\xAD\xFF\xFF\xFF\xFF N\xA7\xAE\xFF\xFF\xFF\xFF\xA0y\xA0\xAF\xFF\xFF\xFF\xFF 0\x87\xB0\xFF\xFF\xFF\xFF\xA0\xD0\x92\xB1\xFF\xFF\xFF\xFF\xA0Lp\xB2\xFF\xFF\xFF\xFF\xA0\xB2r\xB3\xFF\xFF\xFF\xFF\xA0.P\xB4\xFF\xFF\xFF\xFF ZI\xB5\xFF\xFF\xFF\xFF\xA0\x100\xB6\xFF\xFF\xFF\xFF\xA0v2\xB7\xFF\xFF\xFF\xFF\xA0\xF2\x0F\xB8\xFF\xFF\xFF\xFF\xA0X\x12\xB9\xFF\xFF\xFF\xFF\xA0\xD4\xEF\xB9\xFF\xFF\xFF\xFF \0\xE9\xBA\xFF\xFF\xFF\xFF \xF1\xD8\xBB\xFF\xFF\xFF\xFF W\xDB\xBC\xFF\xFF\xFF\xFF \xD3\xB8\xBD\xFF\xFF\xFF\xFF\xA0\xFE\xB1\xBE\xFF\xFF\xFF\xFF \xB5\x98\xBF\xFF\xFF\xFF\xFF \x1B\x9B\xC0\xFF\xFF\xFF\xFF \x97x\xC1\xFF\xFF\xFF\xFF \xFDz\xC2\xFF\xFF\xFF\xFF yX\xC3\xFF\xFF\xFF\xFF\xA0\xA4Q\xC4\xFF\xFF\xFF\xFF [8\xC5\xFF\xFF\xFF\xFF \xC1:\xC6\xFF\xFF\xFF\xFF\xA0\xD6X\xC7\xFF\xFF\xFF\xFF\xA0\t\xDA\xC7\xFF\xFF\xFF\xFF\x90&\x16\xCA\xFF\xFF\xFF\xFF\x90Y\x97\xCA\xFF\xFF\xFF\xFF\x90\x1E\xD1\xCB\xFF\xFF\xFF\xFF\x90;w\xCC\xFF\xFF\xFF\xFF\x90\0\xB1\xCD\xFF\xFF\xFF\xFF\x10X`\xCE\xFF\xFF\xFF\xFF\x90\xE2\x90\xCF\xFF\xFF\xFF\xFF\x90^n\xD0\xFF\xFF\xFF\xFF\x10\x16r\xD1\xFF\xFF\xFF\xFF\x102\xFB\xD1\xFF\xFF\xFF\xFF \xFEi\xD2\xFF\xFF\xFF\xFF\xA0)c\xD3\xFF\xFF\xFF\xFF \xE0I\xD4\xFF\xFF\xFF\xFF\xA0!\x1E\xD5\xFF\xFF\xFF\xFF\x90\xFDB\xD5\xFF\xFF\xFF\xFF\x10\xE0\xDF\xD5\xFF\xFF\xFF\xFF \xACN\xD6\xFF\xFF\xFF\xFF\xA0\x03\xFE\xD6\xFF\xFF\xFF\xFF \x8E.\xD8\xFF\xFF\xFF\xFF \x95\xF9\xD8\xFF\xFF\xFF\xFF p\x0E\xDA\xFF\xFF\xFF\xFF \xEC\xEB\xDA\xFF\xFF\xFF\xFF\xA0\x17\xE5\xDB\xFF\xFF\xFF\xFF \xCE\xCB\xDC\xFF\xFF\xFF\xFF\xA0\xF9\xC4\xDD\xFF\xFF\xFF\xFF\xA0\xEA\xB4\xDE\xFF\xFF\xFF\xFF \x16\xAE\xDF\xFF\xFF\xFF\xFF\xA0\xCC\x94\xE0\xFF\xFF\xFF\xFF\xA0Hr\xE1\xFF\xFF\xFF\xFF tk\xE2\xFF\xFF\xFF\xFF\xA0*R\xE3\xFF\xFF\xFF\xFF\xA0\x90T\xE4\xFF\xFF\xFF\xFF\xA0\x0C2\xE5\xFF\xFF\xFF\xFF \xAD=\xE6\xFF\xFF\xFF\xFF )\x1B\xE7\xFF\xFF\xFF\xFF\xA0T\x14\xE8\xFF\xFF\xFF\xFF \x0B\xFB\xE8\xFF\xFF\xFF\xFF q\xFD\xE9\xFF\xFF\xFF\xFF \xED\xDA\xEA\xFF\xFF\xFF\xFF S\xDD\xEB\xFF\xFF\xFF\xFF \xCF\xBA\xEC\xFF\xFF\xFF\xFF\xA0\xFA\xB3\xED\xFF\xFF\xFF\xFF \xB1\x9A\xEE\xFF\xFF\xFF\xFF\xA0g\x81\xEF\xFF\xFF\xFF\xFF }\x9F\xF0\xFF\xFF\xFF\xFF\xA0Ia\xF1\xFF\xFF\xFF\xFF _\x7F\xF2\xFF\xFF\xFF\xFF fJ\xF3\xFF\xFF\xFF\xFF A_\xF4\xFF\xFF\xFF\xFF\xA0\r!\xF5\xFF\xFF\xFF\xFF #?\xF6\xFF\xFF\xFF\xFF\xA0\xEF\0\xF7\xFF\xFF\xFF\xFF \x05\x1F\xF8\xFF\xFF\xFF\xFF\xA0\xD1\xE0\xF8\xFF\xFF\xFF\xFF \xE7\xFE\xF9\xFF\xFF\xFF\xFF\xA0\xB3\xC0\xFA\xFF\xFF\xFF\xFF\xA0\x03\xE8\xFB\xFF\xFF\xFF\xFF\xA0\xAB{\xFC\xFF\xFF\xFF\xFFp\xBB\xC7\xFD\xFF\xFF\xFF\xFF \xC6p\x03\0\0\0\0 X)\x04\0\0\0\0 \xA8P\x05\0\0\0\0 :\t\x06\0\0\0\0 \x8A0\x07\0\0\0\0 \x1C\xE9\x07\0\0\0\0 l\x10\t\0\0\0\0 \xFE\xC8\t\0\0\0\0 N\xF0\n\0\0\0\0\xA0\x1A\xB2\x0B\0\0\0\0 0\xD0\x0C\0\0\0\0\xA0\xFC\x91\r\0\0\0\0 \x12\xB0\x0E\0\0\0\0\xA0\xDEq\x0F\0\0\0\0\xA0.\x99\x10\0\0\0\0\xA0\xC0Q\x11\0\0\0\0\xA0\x10y\x12\0\0\0\0\xA0\xA21\x13\0\0\0\0\xA0\xF2X\x14\0\0\0\0\x90\xEB#\x15\0\0\0\0\x90\xC68\x16\0\0\0\0\x90\xCD\x03\x17\0\0\0\0\x90\xA8\x18\x18\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\x8A\xF8\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xA7\xE1\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x89\xC1\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10k\xA1\x1F\0\0\0\0\x10rl \0\0\0\0\x10M\x81!\0\0\0\0\x10TL\"\0\0\0\0\x10/a#\0\0\0\0\x106,$\0\0\0\0\x90KJ%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90-*'\0\0\0\0\x904\xF5'\0\0\0\0\x90\x0F\n)\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\xF1\xE9*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xD3\xC9,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xB5\xA9.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\x97\x890\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\xB5\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\x01CEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\0\x80\x02\xEE\x02\0\xB56~\xFF\xFF\xFF\xFF\xF0\xC5\xBA\x9E\xFF\xFF\xFF\xFF\09\xA0\x9F\xFF\xFF\xFF\xFF\xF0\x1B\x90\xA0\xFF\xFF\xFF\xFF\x80l\x81\xA1\xFF\xFF\xFF\xFFp\xEF\x05\xAA\xFF\xFF\xFF\xFF\0n\xE7\xAA\xFF\xFF\xFF\xFF\xF0\xA7\xC9\xAD\xFF\xFF\xFF\xFF\x002\xA7\xAE\xFF\xFF\xFF\xFFpO\xA0\xAF\xFF\xFF\xFF\xFF\0\x14\x87\xB0\xFF\xFF\xFF\xFF\0z\x89\xB1\xFF\xFF\xFF\xFF\x800p\xB2\xFF\xFF\xFF\xFFp\x88r\xB3\xFF\xFF\xFF\xFF\x80\x12P\xB4\xFF\xFF\xFF\xFF\xF0\xEC\xC9\xC2\xFF\xFF\xFF\xFF\0]X\xC3\xFF\xFF\xFF\xFF\xF0?H\xC4\xFF\xFF\xFF\xFF\xE0\x1Bm\xC4\xFF\xFF\xFF\xFF`t9\xC5\xFF\xFF\xFF\xFF\x80[!\xC7\xFF\xFF\xFF\xFF\xF0\x8E\xF5\xC7\xFF\xFF\xFF\xFF`\xDE\xF5\xCB\xFF\xFF\xFF\xFF\xF0q\x95\xCC\xFF\xFF\xFF\xFF`K\xC3\xCD\xFF\xFF\xFF\xFFp\xD5\xA0\xCE\xFF\xFF\xFF\xFF`-\xA3\xCF\xFF\xFF\xFF\xFFp\xB7\x80\xD0\xFF\xFF\xFF\xFF`\x0F\x83\xD1\xFF\xFF\xFF\xFFp\x99`\xD2\xFF\xFF\xFF\xFF`\xF1b\xD3\xFF\xFF\xFF\xFFp{@\xD4\xFF\xFF\xFF\xFF\xE0F\x1E\xD9\xFF\xFF\xFF\xFF\xF0[\xE9\xD9\xFF\xFF\xFF\xFF\xE0\xCD\r\x08\0\0\0\0p\x92\xF4\x08\0\0\0\0\xE0\xAF\xED\t\0\0\0\0pt\xD4\n\0\0\0\0\xE0\x1C\xBB\x0B\0\0\0\0\xF0\x1B\xAB\x0C\0\0\0\0`9\xA4\r\0\0\0\0\xF0\xFD\x8A\x0E\0\0\0\0\x90E\x84\x0F\0\0\0\0\x906t\x10\0\0\0\0\x90'd\x11\0\0\0\0\x90\x18T\x12\0\0\0\0\x10DM\x13\0\0\0\0\x90\xFA3\x14\0\0\0\0\x90\xEB#\x15\0\0\0\0\x90\xDC\x13\x16\0\0\0\0\x90\xCD\x03\x17\0\0\0\0\x90\xBE\xF3\x17\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x8C\xFC\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\x01CEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\0\xB8\x02\x0F\x03d\xD3\xBDp\xFF\xFF\xFF\xFFp\xF88\x9B\xFF\xFF\xFF\xFF\xE0\xCC\xD5\x9B\xFF\xFF\xFF\xFF\xF0\xCB\xC5\x9C\xFF\xFF\xFF\xFF`\0\xB7\x9D\xFF\xFF\xFF\xFFp\xFE\x89\x9E\xFF\xFF\xFF\xFF\xE0\x1C\xA0\x9F\xFF\xFF\xFF\xFF\xF0\xA5`\xA0\xFF\xFF\xFF\xFF`\xAD~\xA1\xFF\xFF\xFF\xFFp7\\\xA2\xFF\xFF\xFF\xFF`\x1AL\xA3\xFF\xFF\xFF\xFF\xF05l\xC8\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x90\xE2\x90\xCF\xFF\xFF\xFF\xFF\x90^n\xD0\xFF\xFF\xFF\xFF\x10\x16r\xD1\xFF\xFF\xFF\xFF\xF0\xD2L\xD2\xFF\xFF\xFF\xFF\x901>\xD3\xFF\xFF\xFF\xFF\x10\xD2I\xD4\xFF\xFF\xFF\xFFp\xF7\x1D\xD5\xFF\xFF\xFF\xFF\xF0\x97)\xD6\xFF\xFF\xFF\xFF\x90\x80\xEB\xD6\xFF\xFF\xFF\xFF\x10\x96\t\xD8\xFF\xFF\xFF\xFF\xF0\xB53\xF9\xFF\xFF\xFF\xFF\xE0\xC4\xD9\xF9\xFF\xFF\xFF\xFFp\xD2\x1C\xFB\xFF\xFF\xFF\xFF\xF0\xB4\xB9\xFB\xFF\xFF\xFF\xFFp\xB4\xFC\xFC\xFF\xFF\xFF\xFF\xF0\x96\x99\xFD\xFF\xFF\xFF\xFF\xF0\xD0\xE5\xFE\xFF\xFF\xFF\xFFp\xB3\x82\xFF\xFF\xFF\xFF\xFF\xF0\xB2\xC5\0\0\0\0\0p\x95b\x01\0\0\0\0pZ\x9C\x02\0\0\0\0pwB\x03\0\0\0\0\xF0v\x85\x04\0\0\0\0\xF0\x93+\x05\0\0\0\0p3\x1A\x06\0\0\0\0p$\n\x07\0\0\0\0p\x16\x17\x08\0\0\0\0p4\xDA\x08\0\0\0\0\x90\x14\xF7\t\0\0\0\0\x80\r\xC2\n\0\0\0\0\x90\xF6\xD6\x0B\0\0\0\0\x80\xEF\xA1\x0C\0\0\0\0\x90\xD8\xB6\r\0\0\0\0\x80\xD1\x81\x0E\0\0\0\0\x90\xBA\x96\x0F\0\0\0\0\x80\xB3a\x10\0\0\0\0\x90\x9Cv\x11\0\0\0\0\x80\x95A\x12\0\0\0\0\x10[E\x13\0\0\0\0\0\xB2*\x14\0\0\0\0\xF0\x1C\xB1\x14\0\0\0\0\x90\xDC\x13\x16\0\0\0\0\x90\xCD\x03\x17\0\0\0\0\x90\xBE\xF3\x17\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x9C\r\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0+03\0\x000*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \x02\x90\x02(\xCA\xB6V\xFF\xFF\xFF\xFF8\xAA\x19\xAA\xFF\xFF\xFF\xFF`\x19\xA4\xB5\xFF\xFF\xFF\xFF\xD0p^\xCA\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF`\x02\n\xD0\xFF\xFF\xFF\xFF\xD0\xA7'\x15\0\0\0\0@\xDC\x18\x16\0\0\0\0P\xDB\x08\x17\0\0\0\0\xC0\x0F\xFA\x17\0\0\0\0\xD0\x0E\xEA\x18\0\0\0\0@C\xDB\x19\0\0\0\0\xD0\x93\xCC\x1A\0\0\0\0\xF0\xA0\xBC\x1B\0\0\0\0\xF0\x91\xAC\x1C\0\0\0\0\xF0\x82\x9C\x1D\0\0\0\0\xF0s\x8C\x1E\0\0\0\0\xF0d|\x1F\0\0\0\0\xF0Ul \0\0\0\0\xF0F\\!\0\0\0\0\xF07L\"\0\0\0\0\xF0(<#\0\0\0\0\xF0\x19,$\0\0\0\0\xF0\n\x1C%\0\0\0\0p\x18\xF5'\0\0\0\0\x80\x17\xE5(\0\0\0\0\x80\x08\xD5)\0\0\0\0\x80\xF9\xC4*\0\0\0\0\x80\xEA\xB4+\0\0\0\0\x80\xDB\xA4,\0\0\0\0\x80\xCC\x94-\0\0\0\0\x80\xBD\x84.\0\0\0\0\x80\xAEt/\0\0\0\0\x80\x9Fd0\0\0\0\0\0\xCB]1\0\0\0\0\0\xA6r2\0\0\0\0\0\xAD=3\0\0\0\0\0\x88R4\0\0\0\0\0\x8F\x1D5\0\0\0\0\0j26\0\0\0\0\0q\xFD6\0\0\0\0\x80\x86\x1B8\0\0\0\0\0S\xDD8\0\0\0\0\x80h\xFB9\0\0\0\0\x005\xBD:\0\0\0\0\x80J\xDB;\0\0\0\0\x80Q\xA6<\0\0\0\0\x80,\xBB=\0\0\0\0\x803\x86>\0\0\0\0\x80\x0E\x9B?\0\0\0\0\x80\x15f@\0\0\0\0\0+\x84A\0\0\0\0\x80\xF7EB\0\0\0\0\0\rdC\0\0\0\0\x80\xD9%D\0\0\0\0\0\xEFCE\0\0\0\0\x80\xBB\x05F\0\0\0\0\0\xD1#G\0\0\0\0\0\xD8\xEEG\0\0\0\0\0\xB3\x03I\0\0\0\0\0\xBA\xCEI\0\0\0\0\0\x95\xE3J\0\0\0\0\0\x9C\xAEK\0\0\0\0\x80\xB1\xCCL\0\0\0\0\0~\x8EM\0\0\0\0\x01\x02\x03\x02\x04\x05\x02\x04\x05\x02\x04\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\xD8\x19\0\0\0\0\0\0\xC8\x19\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0 \x1C\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0@8\0\0\0\0\0\x000*\0\0\0\0\0\0MSK\0\x000*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0p\x02\xD4\x02\xC7\xC0\xB6V\xFF\xFF\xFF\xFF\xC7\x1E_\x9B\xFF\xFF\xFF\xFFy\xF2>\x9D\xFF\xFF\xFF\xFF\xF9\xEE*\x9E\xFF\xFF\xFF\xFFi9\xF7\x9E\xFF\xFF\xFF\xFF\xF9W\x84\x9F\xFF\xFF\xFF\xFF\xE9l\xD8\xA0\xFF\xFF\xFF\xFF\x809\0\xA1\xFF\xFF\xFF\xFF@\xA6<\xA1\xFF\xFF\xFF\xFF\xC0m\x10\xA4\xFF\xFF\xFF\xFF\xB02=\xA4\xFF\xFF\xFF\xFF\xB0h\x15\xA5\xFF\xFF\xFF\xFF\xC0\x03=\xA5\xFF\xFF\xFF\xFFPE\x1E\xA7\xFF\xFF\xFF\xFF`\x19\xA4\xB5\xFF\xFF\xFF\xFF\xD0\xA7'\x15\0\0\0\0@\xDC\x18\x16\0\0\0\0P\xDB\x08\x17\0\0\0\0\xC0\x0F\xFA\x17\0\0\0\0\xD0\x0E\xEA\x18\0\0\0\0@C\xDB\x19\0\0\0\0\xD0\x93\xCC\x1A\0\0\0\0\xF0\xA0\xBC\x1B\0\0\0\0\xF0\x91\xAC\x1C\0\0\0\0\xF0\x82\x9C\x1D\0\0\0\0\xF0s\x8C\x1E\0\0\0\0\xF0d|\x1F\0\0\0\0\xF0Ul \0\0\0\0\xF0F\\!\0\0\0\0\xF07L\"\0\0\0\0\xF0(<#\0\0\0\0\xF0\x19,$\0\0\0\0\xF0\n\x1C%\0\0\0\0\xF0\xFB\x0B&\0\0\0\0p'\x05'\0\0\0\0p\x18\xF5'\0\0\0\0\x80\x17\xE5(\0\0\0\0\x80\xBFx)\0\0\0\0p\xFA\xD4)\0\0\0\0p\xEB\xC4*\0\0\0\0p\xDC\xB4+\0\0\0\0p\xCD\xA4,\0\0\0\0p\xBE\x94-\0\0\0\0p\xAF\x84.\0\0\0\0p\xA0t/\0\0\0\0p\x91d0\0\0\0\0\xF0\xBC]1\0\0\0\0\xF0\x97r2\0\0\0\0\xF0\x9E=3\0\0\0\0\xF0yR4\0\0\0\0\xF0\x80\x1D5\0\0\0\0\xF0[26\0\0\0\0\xF0b\xFD6\0\0\0\0px\x1B8\0\0\0\0\xF0D\xDD8\0\0\0\0pZ\xFB9\0\0\0\0\xF0&\xBD:\0\0\0\0p<\xDB;\0\0\0\0pC\xA6<\0\0\0\0p\x1E\xBB=\0\0\0\0p%\x86>\0\0\0\0p\0\x9B?\0\0\0\0p\x07f@\0\0\0\0\xF0\x1C\x84A\0\0\0\0p\xE9EB\0\0\0\0\xF0\xFEcC\0\0\0\0p\xCB%D\0\0\0\0\xF0\xE0CE\0\0\0\0p\xAD\x05F\0\0\0\0\xF0\xC2#G\0\0\0\0\xF0\xC9\xEEG\0\0\0\0\xF0\xA4\x03I\0\0\0\0\xF0\xAB\xCEI\0\0\0\0\xF0\x86\xE3J\0\0\0\0\xF0\x8D\xAEK\0\0\0\0p\xA3\xCCL\0\0\0\0\xF0o\x8EM\0\0\0\0`\x1DLT\0\0\0\0\0\x01\x02\x01\x03\x02\x03\x04\x05\x04\x06\x04\x05\x07\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x05\x08\x07\x04\x04\x05\x08\x04\x05\x08\x04\x05\x08\x04\x05\x08\x04\x05\x08\x04\x05\x08\x04\x05\x08\x04\x05\x08\x04\x05\x08\x04\x05\x08\x04\x05\x08\x04\x05\x08\x04\x05\x08\x04\x05\x08\x04\x05\x08\x04\x05\x08\x04\x05\x08\x04\x05\x08\x04\x05\x08\x04\t\x05\x089#\0\0\0\0\0\0w#\0\0\0\0\0\0\x871\0\0\0\0\0\0\x97?\0\0\0\0\0\0@8\0\0\0\0\0\x000*\0\0\0\0\0\0PF\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0@8\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\x01CEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\x000\x03\xAF\x03\xCF\x9B\xC9k\xFF\xFF\xFF\xFFOP`\x91\xFF\xFF\xFF\xFF\xF0xG\x9B\xFF\xFF\xFF\xFFp,\xD7\x9B\xFF\xFF\xFF\xFFp\x91\xBC\x9C\xFF\xFF\xFF\xFF\xF0H\xC0\x9D\xFF\xFF\xFF\xFFp\xFE\x89\x9E\xFF\xFF\xFF\xFF\xF0*\xA0\x9F\xFF\xFF\xFF\xFF\xF0\xA5`\xA0\xFF\xFF\xFF\xFF\xF0\x0C\x80\xA1\xFF\xFF\xFF\xFF\xF0\x12.\xA2\xFF\xFF\xFF\xFF\xF0Lz\xA3\xFF\xFF\xFF\xFF\xF0\x815\xA4\xFF\xFF\xFF\xFFp#^\xA5\xFF\xFF\xFF\xFF\xF05%\xA6\xFF\xFF\xFF\xFF\xF0\x9B'\xA7\xFF\xFF\xFF\xFFp&X\xA8\xFF\xFF\xFF\xFF\xF0}\x07\xA9\xFF\xFF\xFF\xFFp4\xEE\xA9\xFF\xFF\xFF\xFF\xF0_\xE7\xAA\xFF\xFF\xFF\xFF\xF0P\xD7\xAB\xFF\xFF\xFF\xFF\xF0A\xC7\xAC\xFF\xFF\xFF\xFF\xF0\xA7\xC9\xAD\xFF\xFF\xFF\xFF\xF0#\xA7\xAE\xFF\xFF\xFF\xFFpO\xA0\xAF\xFF\xFF\xFF\xFF\xF0\x05\x87\xB0\xFF\xFF\xFF\xFF\xF0k\x89\xB1\xFF\xFF\xFF\xFFp\"p\xB2\xFF\xFF\xFF\xFFp\x88r\xB3\xFF\xFF\xFF\xFFp\x04P\xB4\xFF\xFF\xFF\xFF\xF0/I\xB5\xFF\xFF\xFF\xFFp\xE6/\xB6\xFF\xFF\xFF\xFFpL2\xB7\xFF\xFF\xFF\xFFp\xC8\x0F\xB8\xFF\xFF\xFF\xFFp\xB9\xFF\xB8\xFF\xFF\xFF\xFFp\xAA\xEF\xB9\xFF\xFF\xFF\xFF\xF0`\xD6\xBA\xFF\xFF\xFF\xFF\xF0\xC6\xD8\xBB\xFF\xFF\xFF\xFF\xF0\xB7\xC8\xBC\xFF\xFF\xFF\xFF\xF0\xA8\xB8\xBD\xFF\xFF\xFF\xFFp_\x9F\xBE\xFF\xFF\xFF\xFF\xF0\x8A\x98\xBF\xFF\xFF\xFF\xFF\xF0\xF0\x9A\xC0\xFF\xFF\xFF\xFF\xF0lx\xC1\xFF\xFF\xFF\xFF\xF0]h\xC2\xFF\xFF\xFF\xFF\xF0NX\xC3\xFF\xFF\xFF\xFFp\x05?\xC4\xFF\xFF\xFF\xFF\xF008\xC5\xFF\xFF\xFF\xFF\xF0\x96:\xC6\xFF\xFF\xFF\xFFp\xACX\xC7\xFF\xFF\xFF\xFF\xA0\t\xDA\xC7\xFF\xFF\xFF\xFF\xE0'l\xC8\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF\xE0\xE1O\xD0\xFF\xFF\xFF\xFF\xF0\xF1\x89\xD0\xFF\xFF\xFF\xFF\x10\x16r\xD1\xFF\xFF\xFF\xFF\x90@N\xD2\xFF\xFF\xFF\xFF\09\xBB\x0B\0\0\0\0\xF0\x1B\xAB\x0C\0\0\0\0\x90c\xA4\r\0\0\0\0\x10\x1A\x8B\x0E\0\0\0\0\x90E\x84\x0F\0\0\0\0\x906t\x10\0\0\0\0\x90'd\x11\0\0\0\0\x90\x18T\x12\0\0\0\0\x10DM\x13\0\0\0\0\x90\xFA3\x14\0\0\0\0\x90\xEB#\x15\0\0\0\0\x90\xDC\x13\x16\0\0\0\0\x90\xCD\x03\x17\0\0\0\0\x90\xBE\xF3\x17\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x04\x03\x02\x04\x03\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x041\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\x01CEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\0\xE8\x01%\x02\xF8\x92I\x1E\xFF\xFF\xFF\xFF\xF8\xEA\xCFl\xFF\xFF\xFF\xFF`\x17\x0C\x9B\xFF\xFF\xFF\xFF\xF0\xDA\xD5\x9B\xFF\xFF\xFF\xFF\x90\xAE\xD9\x9C\xFF\xFF\xFF\xFF\x90\xB5\xA4\x9D\xFF\xFF\xFF\xFF\x90\x90\xB9\x9E\xFF\xFF\xFF\xFF\x90\x97\x84\x9F\xFF\xFF\xFF\xFF\x90q\t\xC8\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF\x10%\x82\xD0\xFF\xFF\xFF\xFF\x10\x16r\xD1\xFF\xFF\xFF\xFF\x10\x07b\xD2\xFF\xFF\xFF\xFF\x90\x1C\x80\xD3\xFF\xFF\xFF\xFF\x10\xD2I\xD4\xFF\xFF\xFF\xFF \xB4\x93\xD4\xFF\xFF\xFF\xFF r\x02\xD5\xFF\xFF\xFF\xFF\x10\xB4)\xD6\xFF\xFF\xFF\xFF\x10\x1A,\xD7\xFF\xFF\xFF\xFF\x10\x96\t\xD8\xFF\xFF\xFF\xFF\x10p\x01\xD9\xFF\xFF\xFF\xFF\x10x\xE9\xD9\xFF\xFF\xFF\xFF\x90'd\x11\0\0\0\0\x90\x18T\x12\0\0\0\0\x10DM\x13\0\0\0\0\x90\xFA3\x14\0\0\0\0\x90\xEB#\x15\0\0\0\0\x90\xDC\x13\x16\0\0\0\0\x90\xCD\x03\x17\0\0\0\0\x90\xBE\xF3\x17\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x88\r\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0\0\0\0\0\0\0\0\0EET\0\0 \x1C\0\0\0\0\0\0\x01EEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\x000*\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0@8\0\0\0\0\0\0\xA0\x01\xED\x01^\xCD\xB6V\xFF\xFF\xFF\xFF\xFE\x87\xB9\x9E\xFF\xFF\xFF\xFF\xFE\x8E\x84\x9F\xFF\xFF\xFF\xFF~F\x88\xA0\xFF\xFF\xFF\xFF\xFE\x82\xCB\xA0\xFF\xFF\xFF\xFF\xDE\xF1\xE7\xAD\xFF\xFF\xFF\xFF`d\xAF\xC8\xFF\xFF\xFF\xFFPeb\xCA\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF\x10%\x82\xD0\xFF\xFF\xFF\xFFp\x89\x90\xD0\xFF\xFF\xFF\xFF\xD0\xA7'\x15\0\0\0\0@\xDC\x18\x16\0\0\0\0P\xDB\x08\x17\0\0\0\0\xC0\x0F\xFA\x17\0\0\0\0\xD0\x0E\xEA\x18\0\0\0\0@C\xDB\x19\0\0\0\0\xD0\x93\xCC\x1A\0\0\0\0\xF0\xA0\xBC\x1B\0\0\0\0\xF0\x91\xAC\x1C\0\0\0\0\xF0\x82\x9C\x1D\0\0\0\0\xF0s\x8C\x1E\0\0\0\0\xF0d|\x1F\0\0\0\0\xF0Ul \0\0\0\0\xF0F\\!\0\0\0\0\xF07L\"\0\0\0\0\xF0(<#\0\0\0\0\xF0\x19,$\0\0\0\0\0\x19\x1C%\0\0\0\0\0\n\x0C&\0\0\0\0\x805\x05'\0\0\0\0\x80&\xF5'\0\0\0\0\x80\x17\xE5(\0\0\0\0\x80\x08\xD5)\0\0\0\0\x80\xF9\xC4*\0\0\0\0\x80\xEA\xB4+\0\0\0\0\x80\xDB\xA4,\0\0\0\0\x80\xCC\x94-\0\0\0\0\x80\xBD\x84.\0\0\0\0\x80\xAEt/\0\0\0\0\x80\x9Fd0\0\0\0\0\0\xCB]1\0\0\0\0\0\xBCM2\0\0\0\0\x10\xBB=3\0\0\0\0\x10\x96R4\0\0\0\0\x10\x9D\x1D5\0\0\0\0\x10x26\0\0\0\0\x10\x7F\xFD6\0\0\0\0\x90\x94\x1B8\0\0\0\0\0\x01\0\x01\0\x02\x03\x02\x04\x05\x02\x04\x05\x02\x04\x05\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\xA2\x16\0\0\0\0\0\0\xB2$\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0 \x1C\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0@8\0\0\0\0\0\x000*\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\x01CEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\0\xC0\x02\x18\x03L\xE8(>\xFF\xFF\xFF\xFFp\x81\xBCp\xFF\xFF\xFF\xFFp\xF88\x9B\xFF\xFF\xFF\xFF\xE0\xCC\xD5\x9B\xFF\xFF\xFF\xFF\xF0\xCB\xC5\x9C\xFF\xFF\xFF\xFF`\0\xB7\x9D\xFF\xFF\xFF\xFFp\xFE\x89\x9E\xFF\xFF\xFF\xFF\xE0\x1C\xA0\x9F\xFF\xFF\xFF\xFF\xF0\xA5`\xA0\xFF\xFF\xFF\xFF`\xAD~\xA1\xFF\xFF\xFF\xFFp7\\\xA2\xFF\xFF\xFF\xFF`\x1AL\xA3\xFF\xFF\xFF\xFF\xF05l\xC8\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF\x90^n\xD0\xFF\xFF\xFF\xFF\x10\x16r\xD1\xFF\xFF\xFF\xFF\xF0\xD2L\xD2\xFF\xFF\xFF\xFF\x901>\xD3\xFF\xFF\xFF\xFF\x10\xD2I\xD4\xFF\xFF\xFF\xFFp\xF7\x1D\xD5\xFF\xFF\xFF\xFF\xF0\x97)\xD6\xFF\xFF\xFF\xFF\x90\x80\xEB\xD6\xFF\xFF\xFF\xFF\x10\x96\t\xD8\xFF\xFF\xFF\xFF\xF0\xB53\xF9\xFF\xFF\xFF\xFF\xE0\xC4\xD9\xF9\xFF\xFF\xFF\xFFp\xD2\x1C\xFB\xFF\xFF\xFF\xFF\xF0\xB4\xB9\xFB\xFF\xFF\xFF\xFFp\xB4\xFC\xFC\xFF\xFF\xFF\xFF\xF0\x96\x99\xFD\xFF\xFF\xFF\xFF\xF0\xD0\xE5\xFE\xFF\xFF\xFF\xFFp\xB3\x82\xFF\xFF\xFF\xFF\xFF\xF0\xB2\xC5\0\0\0\0\0p\x95b\x01\0\0\0\0pZ\x9C\x02\0\0\0\0pwB\x03\0\0\0\0\xF0v\x85\x04\0\0\0\0\xF0\x93+\x05\0\0\0\0p\x93n\x06\0\0\0\0\xF0u\x0B\x07\0\0\0\0\xF0:E\x08\0\0\0\0\xF0W\xEB\x08\0\0\0\0pW.\n\0\0\0\0\xF09\xCB\n\0\0\0\0p9\x0E\x0C\0\0\0\0\xF0\x1B\xAB\x0C\0\0\0\0\xF0\xE0\xE4\r\0\0\0\0\xF0\xFD\x8A\x0E\0\0\0\0p\xFD\xCD\x0F\0\0\0\0p\x1At\x10\0\0\0\0p\xDF\xAD\x11\0\0\0\0p\xFCS\x12\0\0\0\0\x10DM\x13\0\0\0\0\x90\xFA3\x14\0\0\0\0\x90\xEB#\x15\0\0\0\0\x90\xDC\x13\x16\0\0\0\0\x90\xCD\x03\x17\0\0\0\0\x90\xBE\xF3\x17\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xB4\x0B\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0+04\0\0@8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\x02x\x02\x809\0\xA1\xFF\xFF\xFF\xFFP\x0B\xA4\xB5\xFF\xFF\xFF\xFF\xC0\x99'\x15\0\0\0\x000\xCE\x18\x16\0\0\0\0@\xCD\x08\x17\0\0\0\0\xB0\x01\xFA\x17\0\0\0\0\xC0\0\xEA\x18\0\0\0\x0005\xDB\x19\0\0\0\0\xC0\x85\xCC\x1A\0\0\0\0\xE0\x92\xBC\x1B\0\0\0\0\xE0\x83\xAC\x1C\0\0\0\0\xE0t\x9C\x1D\0\0\0\0\xE0e\x8C\x1E\0\0\0\0\xE0V|\x1F\0\0\0\0\xE0Gl \0\0\0\0\xE08\\!\0\0\0\0\xE0)L\"\0\0\0\0\xE0\x1A<#\0\0\0\0\xE0\x0B,$\0\0\0\0\xF0\x19,$\0\0\0\0\xF0\n\x1C%\0\0\0\0\xF0\xFB\x0B&\0\0\0\0p'\x05'\0\0\0\0p\x18\xF5'\0\0\0\0\x80&\xF5'\0\0\0\0\x80\x17\xE5(\0\0\0\0\0\xC7\0)\0\0\0\0`\xEC\xD4)\0\0\0\0`\xDD\xC4*\0\0\0\0`\xCE\xB4+\0\0\0\0`\xBF\xA4,\0\0\0\0`\xB0\x94-\0\0\0\0`\xA1\x84.\0\0\0\0`\x92t/\0\0\0\0`\x83d0\0\0\0\0\xE0\xAE]1\0\0\0\0\xE0\x89r2\0\0\0\0\xE0\x90=3\0\0\0\0\xE0kR4\0\0\0\0\xE0r\x1D5\0\0\0\0\xE0M26\0\0\0\0\xE0T\xFD6\0\0\0\0`j\x1B8\0\0\0\0\xE06\xDD8\0\0\0\0`L\xFB9\0\0\0\0\xE0\x18\xBD:\0\0\0\0`.\xDB;\0\0\0\0`5\xA6<\0\0\0\0`\x10\xBB=\0\0\0\0`\x17\x86>\0\0\0\0`\xF2\x9A?\0\0\0\0`\xF9e@\0\0\0\0\xE0\x0E\x84A\0\0\0\0`\xDBEB\0\0\0\0\xE0\xF0cC\0\0\0\0`\xBD%D\0\0\0\0\xE0\xD2CE\0\0\0\0`\x9F\x05F\0\0\0\0\xE0\xB4#G\0\0\0\0\xE0\xBB\xEEG\0\0\0\0\xE0\x96\x03I\0\0\0\0\xE0\x9D\xCEI\0\0\0\0\xE0x\xE3J\0\0\0\0\xE0\x7F\xAEK\0\0\0\0\xF0\x8D\xAEK\0\0\0\0p\xA3\xCCL\0\0\0\0\xF0o\x8EM\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x02\x04\x01\x01\x05\x01\x05\x01\x05\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x03\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\xF4.\0\0\0\0\0\x000*\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0@8\0\0\0\0\0\x000*\0\0\0\0\0\0+04\0\0@8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x02m\x02\x809\0\xA1\xFF\xFF\xFF\xFFP\x0B\xA4\xB5\xFF\xFF\xFF\xFF\xC0\x99'\x15\0\0\0\x000\xCE\x18\x16\0\0\0\0@\xCD\x08\x17\0\0\0\0\xB0\x01\xFA\x17\0\0\0\0\xC0\0\xEA\x18\0\0\0\x0005\xDB\x19\0\0\0\0\xC0\x85\xCC\x1A\0\0\0\0\xE0\x92\xBC\x1B\0\0\0\0\xE0\x83\xAC\x1C\0\0\0\0\xE0t\x9C\x1D\0\0\0\0\xE0e\x8C\x1E\0\0\0\0\xE0V|\x1F\0\0\0\0\xE0Gl \0\0\0\0\xE08\\!\0\0\0\0\xE0)L\"\0\0\0\0\xF07L\"\0\0\0\0\xF0(<#\0\0\0\0\xF0\x19,$\0\0\0\0\xF0\n\x1C%\0\0\0\0\xF0\xFB\x0B&\0\0\0\0p'\x05'\0\0\0\0p\x18\xF5'\0\0\0\0`\xEC\xD4)\0\0\0\0p\xFA\xD4)\0\0\0\0p\xEB\xC4*\0\0\0\0p\xDC\xB4+\0\0\0\0p\xCD\xA4,\0\0\0\0p\xBE\x94-\0\0\0\0p\xAF\x84.\0\0\0\0p\xA0t/\0\0\0\0p\x91d0\0\0\0\0\xF0\xBC]1\0\0\0\0\xF0\x97r2\0\0\0\0\xF0\x9E=3\0\0\0\0\xF0yR4\0\0\0\0\xF0\x80\x1D5\0\0\0\0\xF0[26\0\0\0\0\xF0b\xFD6\0\0\0\0px\x1B8\0\0\0\0\xF0D\xDD8\0\0\0\0pZ\xFB9\0\0\0\0\xF0&\xBD:\0\0\0\0p<\xDB;\0\0\0\0pC\xA6<\0\0\0\0p\x1E\xBB=\0\0\0\0p%\x86>\0\0\0\0p\0\x9B?\0\0\0\0p\x07f@\0\0\0\0\xF0\x1C\x84A\0\0\0\0p\xE9EB\0\0\0\0\xF0\xFEcC\0\0\0\0p\xCB%D\0\0\0\0\xF0\xE0CE\0\0\0\0p\xAD\x05F\0\0\0\0\xF0\xC2#G\0\0\0\0\xF0\xC9\xEEG\0\0\0\0\xF0\xA4\x03I\0\0\0\0\xF0\xAB\xCEI\0\0\0\0\xF0\x86\xE3J\0\0\0\0\xF0\x8D\xAEK\0\0\0\0p\xA3\xCCL\0\0\0\0\xF0o\x8EM\0\0\0\0`\x1DLT\0\0\0\0pNCX\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x02\x04\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x042+\0\0\0\0\0\x000*\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0@8\0\0\0\0\0\0MSK\0\x000*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0X\x02\xD3\x02\x08\xC4\xB6V\xFF\xFF\xFF\xFF \xA4\x19\xAA\xFF\xFF\xFF\xFF`\x19\xA4\xB5\xFF\xFF\xFF\xFF\xD0\x8D\x04\xCB\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF\xE08\x9F\xCF\xFF\xFF\xFF\xFF\xD0\xA7'\x15\0\0\0\0@\xDC\x18\x16\0\0\0\0P\xDB\x08\x17\0\0\0\0\xC0\x0F\xFA\x17\0\0\0\0\xD0\x0E\xEA\x18\0\0\0\0@C\xDB\x19\0\0\0\0\xD0\x93\xCC\x1A\0\0\0\0\xF0\xA0\xBC\x1B\0\0\0\0\xF0\x91\xAC\x1C\0\0\0\0\xF0\x82\x9C\x1D\0\0\0\0\xF0s\x8C\x1E\0\0\0\0\xF0d|\x1F\0\0\0\0\xF0Ul \0\0\0\0\xF0F\\!\0\0\0\0\xF07L\"\0\0\0\0\xF0(<#\0\0\0\0\xF0\x19,$\0\0\0\0\xF0\n\x1C%\0\0\0\0\xF0.\x8D&\0\0\0\0\xE0\x0E\xC9)\0\0\0\0\x80\xF9\xC4*\0\0\0\0\x80\xEA\xB4+\0\0\0\0\x80\xDB\xA4,\0\0\0\0\x80\xCC\x94-\0\0\0\0\xD0\xC6\xC2-\0\0\0\0p\xAF\x84.\0\0\0\0p\xA0t/\0\0\0\0p\x91d0\0\0\0\0\xD0\xA0]1\0\0\0\0\0\xA6r2\0\0\0\0\x10\xBB=3\0\0\0\0\x10\x96R4\0\0\0\0\x10\x9D\x1D5\0\0\0\0\x10x26\0\0\0\0\x10\x7F\xFD6\0\0\0\0\x90\x94\x1B8\0\0\0\0\x10a\xDD8\0\0\0\0\x90v\xFB9\0\0\0\0\x10C\xBD:\0\0\0\0\x90X\xDB;\0\0\0\0\x90_\xA6<\0\0\0\0\x90:\xBB=\0\0\0\0\x90A\x86>\0\0\0\0\x90\x1C\x9B?\0\0\0\0\x90#f@\0\0\0\0\x109\x84A\0\0\0\0\x90\x05FB\0\0\0\0\x10\x1BdC\0\0\0\0\x90\xE7%D\0\0\0\0\x10\xFDCE\0\0\0\0\x90\xC9\x05F\0\0\0\0\x10\xDF#G\0\0\0\0\x10\xE6\xEEG\0\0\0\0\x10\xC1\x03I\0\0\0\0\x10\xC8\xCEI\0\0\0\0\x10\xA3\xE3J\0\0\0\0\x10\xAA\xAEK\0\0\0\0\x90\xBF\xCCL\0\0\0\0\x10\x8C\x8EM\0\0\0\0\x90\xA1\xACN\0\0\0\0\x10nnO\0\0\0\0\x90\x83\x8CP\0\0\0\0\x90\x8AWQ\0\0\0\0\x90elR\0\0\0\0\x80^7S\0\0\0\0`\x1DLT\0\0\0\0\x01\x02\x03\x02\x04\x05\x02\x04\x05\x02\x04\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x06\x03\x07\x06\x03\x07\x06\x03\x07\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x03\x07\x02\x04\x06\x08\x03\x07\xF8\x1F\0\0\0\0\0\0\xE0\x1F\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0 \x1C\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0@8\0\0\0\0\0\x000*\0\0\0\0\0\0@8\0\0\0\0\0\0EET\0\0 \x1C\0\0\0\0\0\0\x01EEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\x000*\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0@8\0\0\0\0\0\0`\x01\xA1\x01$\xCE\xB6V\xFF\xFF\xFF\xFF\x18\xE3\xC3r\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF\x10%\x82\xD0\xFF\xFF\xFF\xFF $r\xD1\xFF\xFF\xFF\xFFP\xEFc\x11\0\0\0\0\xE0?U\x12\0\0\0\0\xD0\x0BM\x13\0\0\0\0\xE0!5\x14\0\0\0\0\xD0\xED,\x15\0\0\0\0p\xC0\x13\x16\0\0\0\0\xD0\xCF\x0C\x17\0\0\0\0\x80\xB0\xF3\x17\0\0\0\0\x80\xA1\xE3\x18\0\0\0\0\x80\x92\xD3\x19\0\0\0\0\x80\x83\xC3\x1A\0\0\0\0\0\xAF\xBC\x1B\0\0\0\0\0\xA0\xAC\x1C\0\0\0\0\0\x91\x9C\x1D\0\0\0\0\0\x82\x8C\x1E\0\0\0\0\0s|\x1F\0\0\0\0\0dl \0\0\0\0\0U\\!\0\0\0\0\0FL\"\0\0\0\0\x007<#\0\0\0\0\0(,$\0\0\0\0\0\x19\x1C%\0\0\0\0\0\n\x0C&\0\0\0\0\x805\x05'\0\0\0\0\xE0\xB4\x7F'\0\0\0\0P\xED\xE4(\0\0\0\0`\xEC\xD4)\0\0\0\0P\xCF\xC4*\0\0\0\0`\xCE\xB4+\0\0\0\0P\xB1\xA4,\0\0\0\0`\xB0\x94-\0\0\0\0P\x93\x84.\0\0\0\0`\x92t/\0\0\0\0Pud0\0\0\0\0\xE0\xAE]1\0\0\0\0\xD0{r2\0\0\0\0\x01\x02\x03\x02\x04\x03\x02\x04\x03\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\x05\x02\x04\xDC\x15\0\0\0\0\0\0h\x1B\0\0\0\0\0\0 \x1C\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0EET\0\0 \x1C\0\0\0\0\0\0\x01EEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\x000*\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0@8\0\0\0\0\0\0\x98\x01\xE5\x01\xCC\xCC\xB6V\xFF\xFF\xFF\xFF\xCC-Y\x9E\xFF\xFF\xFF\xFF\x90\x90\xB9\x9E\xFF\xFF\xFF\xFF\x90\x97\x84\x9F\xFF\xFF\xFF\xFFp+\0\xA1\xFF\xFF\xFF\xFFLos\xA4\xFF\xFF\xFF\xFF\xE0\xB5\xB0\xC8\xFF\xFF\xFF\xFFP\x97\xC6\xCA\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF\xE0\xCBt\xD0\xFF\xFF\xFF\xFF\xD0\xA7'\x15\0\0\0\0@\xDC\x18\x16\0\0\0\0P\xDB\x08\x17\0\0\0\0\xC0\x0F\xFA\x17\0\0\0\0\xD0\x0E\xEA\x18\0\0\0\0@C\xDB\x19\0\0\0\0\xD0\x93\xCC\x1A\0\0\0\0\xF0\xA0\xBC\x1B\0\0\0\0\xF0\x91\xAC\x1C\0\0\0\0\xF0\x82\x9C\x1D\0\0\0\0\xF0s\x8C\x1E\0\0\0\0\xF0d|\x1F\0\0\0\0\xF0Ul \0\0\0\0\xF0F\\!\0\0\0\0\xF07L\"\0\0\0\0\xF0(<#\0\0\0\0\xF0\x19,$\0\0\0\0\0\x19\x1C%\0\0\0\0\0\n\x0C&\0\0\0\0\x805\x05'\0\0\0\0\x80&\xF5'\0\0\0\0\x80\x17\xE5(\0\0\0\0\x80\x08\xD5)\0\0\0\0\x80\xF9\xC4*\0\0\0\0\x80\xEA\xB4+\0\0\0\0\x80\xDB\xA4,\0\0\0\0\x80\xCC\x94-\0\0\0\0\x80\xBD\x84.\0\0\0\0\x80\xAEt/\0\0\0\0\x80\x9Fd0\0\0\0\0\0\xCB]1\0\0\0\0\0\xA6r2\0\0\0\0\0\xAD=3\0\0\0\0\0\x88R4\0\0\0\0\0\x8F\x1D5\0\0\0\0\x10x26\0\0\0\0\x10\x7F\xFD6\0\0\0\0\x90\x94\x1B8\0\0\0\0\0\x01\x02\x01\0\x02\x03\x04\x02\x03\x01\x02\x03\x01\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x04\x06\x02\x03\x04\x06\x02\x03\x04\x06\x02\x03\x04\x06\x02\x03\x04\x06\x02\x03\x04\x06\x02\x03\x04\x06\x02\x03\x04\x06\x02\x03\x04\x06\x02\x03\x04\x06\x02\x03\x04\x06\x02\x034\x17\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0@8\0\0\0\0\0\x000*\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\x01CEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\0\x98\x01\xCB\x01h4\xAA\x96\xFF\xFF\xFF\xFFp\x87m\xC8\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x90\xE9\xB8\xCD\xFF\xFF\xFF\xFF\xF09(\x08\0\0\0\0`>\xEF\x08\0\0\0\0\xF0x\x05\n\0\0\0\0\xE0q\xD0\n\0\0\0\0pO\xE9\x0B\0\0\0\0`H\xB4\x0C\0\0\0\0\xF0k\xD2\r\0\0\0\0`*\x94\x0E\0\0\0\0p\xFC\xB0\x0F\0\0\0\0`\x0Ct\x10\0\0\0\0p\xDE\x90\x11\0\0\0\0`\xEES\x12\0\0\0\0p\xC0p\x13\0\0\0\0`\xB9;\x14\0\0\0\0p\xB9H\x15\0\0\0\0`\xB2\x13\x16\0\0\0\0\xF0\xD51\x17\0\0\0\0\xE0\xCE\xFC\x17\0\0\0\0p\x94\0\x19\0\0\0\0`_\xDB\x19\0\0\0\0\xF0\xAF\xCC\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x98\x12\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0+04\0\0@8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \x02\x93\x02\x809\0\xA1\xFF\xFF\xFF\xFFP\x0B\xA4\xB5\xFF\xFF\xFF\xFF\xC0\x99'\x15\0\0\0\x000\xCE\x18\x16\0\0\0\0@\xCD\x08\x17\0\0\0\0\xB0\x01\xFA\x17\0\0\0\0\xC0\0\xEA\x18\0\0\0\x0005\xDB\x19\0\0\0\0\xC0\x85\xCC\x1A\0\0\0\0\xE0\x92\xBC\x1B\0\0\0\0\xE0\x83\xAC\x1C\0\0\0\0\xE0t\x9C\x1D\0\0\0\0\xE0e\x8C\x1E\0\0\0\0\xE0V|\x1F\0\0\0\0\xE0Gl \0\0\0\0\xE08\\!\0\0\0\0\xE0)L\"\0\0\0\0\xE0\x1A<#\0\0\0\0\xE0\x0B,$\0\0\0\0\xF0\x19,$\0\0\0\0\xF0\n\x1C%\0\0\0\0\xF0\xFB\x0B&\0\0\0\0p'\x05'\0\0\0\0p\x18\xF5'\0\0\0\0\x80&\xF5'\0\0\0\0\x80\x17\xE5(\0\0\0\0\x80\xBFx)\0\0\0\0p\xFA\xD4)\0\0\0\0p\xEB\xC4*\0\0\0\0p\xDC\xB4+\0\0\0\0p\xCD\xA4,\0\0\0\0p\xBE\x94-\0\0\0\0p\xAF\x84.\0\0\0\0p\xA0t/\0\0\0\0p\x91d0\0\0\0\0\xF0\xBC]1\0\0\0\0\xF0\x97r2\0\0\0\0\xF0\x9E=3\0\0\0\0\xF0yR4\0\0\0\0\xF0\x80\x1D5\0\0\0\0\xF0[26\0\0\0\0\xF0b\xFD6\0\0\0\0px\x1B8\0\0\0\0\xF0D\xDD8\0\0\0\0pZ\xFB9\0\0\0\0\xF0&\xBD:\0\0\0\0p<\xDB;\0\0\0\0pC\xA6<\0\0\0\0p\x1E\xBB=\0\0\0\0p%\x86>\0\0\0\0p\0\x9B?\0\0\0\0p\x07f@\0\0\0\0\xF0\x1C\x84A\0\0\0\0p\xE9EB\0\0\0\0\xF0\xFEcC\0\0\0\0p\xCB%D\0\0\0\0\xF0\xE0CE\0\0\0\0p\xAD\x05F\0\0\0\0\xF0\xC2#G\0\0\0\0\xF0\xC9\xEEG\0\0\0\0\xF0\xA4\x03I\0\0\0\0\xF0\xAB\xCEI\0\0\0\0\xF0\x86\xE3J\0\0\0\0\xF0\x8D\xAEK\0\0\0\0p\xA3\xCCL\0\0\0\0\xF0o\x8EM\0\0\0\0`\x1DLT\0\0\0\0p\x14\xF7V\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x02\x04\x01\x01\x05\x01\x05\x06\x02\x04\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04\x01\x05\x02\x04`-\0\0\0\0\0\x000*\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0@8\0\0\0\0\0\x000*\0\0\0\0\0\0 \x1C\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\x01CEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\0\xC8\x01\x01\x02/_\xA2o\xFF\xFF\xFF\xFF`\x17\x0C\x9B\xFF\xFF\xFF\xFF\xF0\xDA\xD5\x9B\xFF\xFF\xFF\xFF\x90\xAE\xD9\x9C\xFF\xFF\xFF\xFF\x90\xB5\xA4\x9D\xFF\xFF\xFF\xFF\x90\x90\xB9\x9E\xFF\xFF\xFF\xFF\x90\x97\x84\x9F\xFF\xFF\xFF\xFF\x10\x1Ap\xA2\xFF\xFF\xFF\xFF\x90[D\xA3\xFF\xFF\xFF\xFF\x90q\t\xC8\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF\x10%\x82\xD0\xFF\xFF\xFF\xFF\x10\x16r\xD1\xFF\xFF\xFF\xFF\x10E\x7F\xD1\xFF\xFF\xFF\xFF\x90\x1Bc\xD3\xFF\xFF\xFF\xFF\x90#K\xD4\xFF\xFF\xFF\xFF\x10\xC39\xD5\xFF\xFF\xFF\xFF\x10\xB4)\xD6\xFF\xFF\xFF\xFF\x10\x1A,\xD7\xFF\xFF\xFF\xFF\x10\x96\t\xD8\xFF\xFF\xFF\xFF\xF0'M\x13\0\0\0\0`\xD03\x14\0\0\0\0\xF0\x1C\xB1\x14\0\0\0\0\x90\xDC\x13\x16\0\0\0\0\x90\xCD\x03\x17\0\0\0\0\x90\xBE\xF3\x17\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01Q\x0F\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0EET\0\0 \x1C\0\0\0\0\0\0\x01EEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\x000*\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\0@8\0\0\0\0\0\0\x90\x01\xDA\x01D\xCC\xB6V\xFF\xFF\xFF\xFFP\x1FO\x9C\xFF\xFF\xFF\xFF\x98J\x85\xA1\xFF\xFF\xFF\xFF\xF00\xF1\xA2\xFF\xFF\xFF\xFF`xf\xA3\xFF\xFF\xFF\xFFp\xCF\xAC\xC8\xFF\xFF\xFF\xFF\xD0*Y\xCA\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF\xE0=0\xD0\xFF\xFF\xFF\xFF\xD0\xA7'\x15\0\0\0\0@\xDC\x18\x16\0\0\0\0P\xDB\x08\x17\0\0\0\0\xC0\x0F\xFA\x17\0\0\0\0\xD0\x0E\xEA\x18\0\0\0\0@C\xDB\x19\0\0\0\0\xD0\x93\xCC\x1A\0\0\0\0\xF0\xA0\xBC\x1B\0\0\0\0\xF0\x91\xAC\x1C\0\0\0\0\xF0\x82\x9C\x1D\0\0\0\0\xF0s\x8C\x1E\0\0\0\0\xF0d|\x1F\0\0\0\0\xF0Ul \0\0\0\0\xF0F\\!\0\0\0\0\xF07L\"\0\0\0\0\xF0(<#\0\0\0\0\xF0\x19,$\0\0\0\0\0\x19\x1C%\0\0\0\0\0\n\x0C&\0\0\0\0\x805\x05'\0\0\0\0\x80&\xF5'\0\0\0\0\x80\x17\xE5(\0\0\0\0\x80\x08\xD5)\0\0\0\0\x80\xF9\xC4*\0\0\0\0\x80\xEA\xB4+\0\0\0\0\x80\xDB\xA4,\0\0\0\0\x80\xCC\x94-\0\0\0\0\x80\xBD\x84.\0\0\0\0\x80\xAEt/\0\0\0\0\x80\x9Fd0\0\0\0\0\0\xCB]1\0\0\0\0\0\xA6r2\0\0\0\0\0\xAD=3\0\0\0\0\0\x88R4\0\0\0\0\x10\x9D\x1D5\0\0\0\0\x10x26\0\0\0\0\x10\x7F\xFD6\0\0\0\0\x90\x94\x1B8\0\0\0\0\x01\x02\x03\x04\x03\x05\x04\x06\x03\x04\x06\x03\x04\x06\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x05\x08\x04\x06\x05\x08\x04\x06\x05\x08\x04\x06\x05\x08\x04\x06\x05\x08\x04\x06\x05\x08\x04\x06\x05\x08\x04\x06\x05\x08\x04\x06\x05\x08\x04\x06\x04\x06\x03\x04\x06\x04\x06\xBC\x17\0\0\0\0\0\0\xB0\x13\0\0\0\0\0\0h\x16\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0 \x1C\0\0\0\0\0\0@8\0\0\0\0\0\x000*\0\0\0\0\0\0MSK\0\x000*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\x02v\x02\xDCF\xF5\xA1\xFF\xFF\xFF\xFFP\x0B\xA4\xB5\xFF\xFF\xFF\xFF\xC0\x99'\x15\0\0\0\x000\xCE\x18\x16\0\0\0\0@\xCD\x08\x17\0\0\0\0\xB0\x01\xFA\x17\0\0\0\0\xC0\0\xEA\x18\0\0\0\x0005\xDB\x19\0\0\0\0\xC0\x85\xCC\x1A\0\0\0\0\xE0\x92\xBC\x1B\0\0\0\0\xE0\x83\xAC\x1C\0\0\0\0\xE0t\x9C\x1D\0\0\0\0\xE0e\x8C\x1E\0\0\0\0\xE0V|\x1F\0\0\0\0\xE0Gl \0\0\0\0\xE08\\!\0\0\0\0\xE0)L\"\0\0\0\0\xF07L\"\0\0\0\0\xF0(<#\0\0\0\0\xF0\x19,$\0\0\0\0\xF0\n\x1C%\0\0\0\0\xF0\xFB\x0B&\0\0\0\0p'\x05'\0\0\0\0p\x18\xF5'\0\0\0\0`\xEC\xD4)\0\0\0\0p\xFA\xD4)\0\0\0\0p\xEB\xC4*\0\0\0\0p\xDC\xB4+\0\0\0\0p\xCD\xA4,\0\0\0\0p\xBE\x94-\0\0\0\0p\xAF\x84.\0\0\0\0p\xA0t/\0\0\0\0p\x91d0\0\0\0\0\xF0\xBC]1\0\0\0\0\xF0\x97r2\0\0\0\0\xF0\x9E=3\0\0\0\0\xF0yR4\0\0\0\0\xF0\x80\x1D5\0\0\0\0\xF0[26\0\0\0\0\xF0b\xFD6\0\0\0\0px\x1B8\0\0\0\0\xF0D\xDD8\0\0\0\0pZ\xFB9\0\0\0\0\xF0&\xBD:\0\0\0\0p<\xDB;\0\0\0\0pC\xA6<\0\0\0\0p\x1E\xBB=\0\0\0\0p%\x86>\0\0\0\0p\0\x9B?\0\0\0\0p\x07f@\0\0\0\0\xF0\x1C\x84A\0\0\0\0p\xE9EB\0\0\0\0\xF0\xFEcC\0\0\0\0p\xCB%D\0\0\0\0\xF0\xE0CE\0\0\0\0p\xAD\x05F\0\0\0\0\xF0\xC2#G\0\0\0\0\xF0\xC9\xEEG\0\0\0\0\xF0\xA4\x03I\0\0\0\0\xF0\xAB\xCEI\0\0\0\0\xF0\x86\xE3J\0\0\0\0\xF0\x8D\xAEK\0\0\0\0p\xA3\xCCL\0\0\0\0\xF0o\x8EM\0\0\0\0`\x1DLT\0\0\0\0\xF0\xED\xD4[\0\0\0\0`\xB2\xE7_\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x04\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x02\x04\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\x02\x04\x01\xA4)\0\0\0\0\0\x000*\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0@8\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\x01CEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\0\x98\x02\x11\x03P\xD0\xB6V\xFF\xFF\xFF\xFF\xD0*\xA8\x99\xFF\xFF\xFF\xFF`\x17\x0C\x9B\xFF\xFF\xFF\xFF\xF0\xDA\xD5\x9B\xFF\xFF\xFF\xFF\x90\xAE\xD9\x9C\xFF\xFF\xFF\xFF\x90\xB5\xA4\x9D\xFF\xFF\xFF\xFF\x90\x90\xB9\x9E\xFF\xFF\xFF\xFF\x90\x97\x84\x9F\xFF\xFF\xFF\xFF\0\xB6\x9A\xA0\xFF\xFF\xFF\xFF\0\xBDe\xA1\xFF\xFF\xFF\xFF`|}\xA6\xFF\xFF\xFF\xFF\x10\xDEv\xC8\xFF\xFF\xFF\xFF\x10K\xE7\xCC\xFF\xFF\xFF\xFF\x90\x17\xA9\xCD\xFF\xFF\xFF\xFF\x10C\xA2\xCE\xFF\xFF\xFF\xFF\x104\x92\xCF\xFF\xFF\xFF\xFF\0\xBA\x84\xD0\xFF\xFF\xFF\xFFp\x92\x95\xD1\xFF\xFF\xFF\xFF`\xBB\x8A\xD2\xFF\xFF\xFF\xFFp\xFFb\xD3\xFF\xFF\xFF\xFF\x90#K\xD4\xFF\xFF\xFF\xFF\x10\xAD^\xD5\xFF\xFF\xFF\xFF\x10\xB4)\xD6\xFF\xFF\xFF\xFF\x10\x1A,\xD7\xFF\xFF\xFF\xFF\x10\x96\t\xD8\xFF\xFF\xFF\xFF\x90\xC1\x02\xD9\xFF\xFF\xFF\xFF\x10x\xE9\xD9\xFF\xFF\xFF\xFF\0\xD2T\xE8\xFF\xFF\xFF\xFF\x80\xB4\xF1\xE8\xFF\xFF\xFF\xFF\x80\xA5\xE1\xE9\xFF\xFF\xFF\xFF\x80\x96\xD1\xEA\xFF\xFF\xFF\xFF\0\x96\x14\xEC\xFF\xFF\xFF\xFF\0\xB3\xBA\xEC\xFF\xFF\xFF\xFF\0\xA4\xAA\xED\xFF\xFF\xFF\xFF\0\x95\x9A\xEE\xFF\xFF\xFF\xFF\0Z\xD4\xEF\xFF\xFF\xFF\xFF\0wz\xF0\xFF\xFF\xFF\xFF\0<\xB4\xF1\xFF\xFF\xFF\xFF\0YZ\xF2\xFF\xFF\xFF\xFF\0\x1E\x94\xF3\xFF\xFF\xFF\xFF\0;:\xF4\xFF\xFF\xFF\xFF\x80:}\xF5\xFF\xFF\xFF\xFF\0\x1D\x1A\xF6\xFF\xFF\xFF\xFF\x80U\xA4\r\0\0\0\0\0\x0C\x8B\x0E\0\0\0\0\x807\x84\x0F\0\0\0\0\x80(t\x10\0\0\0\0\x80\x19d\x11\0\0\0\0\x80\nT\x12\0\0\0\0\x006M\x13\0\0\0\0\x80\xEC3\x14\0\0\0\0\x80\xDD#\x15\0\0\0\0\x80\xCE\x13\x16\0\0\0\0\x80\xBF\x03\x17\0\0\0\0\x80\xB0\xF3\x17\0\0\0\0\x80\xA1\xE3\x18\0\0\0\0\x80\x92\xD3\x19\0\0\0\0\x80\x83\xC3\x1A\0\0\0\0\0\xAF\xBC\x1B\0\0\0\0\0\xA0\xAC\x1C\0\0\0\0\0\x91\x9C\x1D\0\0\0\0\0\x82\x8C\x1E\0\0\0\0\0s|\x1F\0\0\0\0\0dl \0\0\0\0\0U\\!\0\0\0\0\xF0\xD6\xDA!\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\0\x01\x02\x01\x02\x01\x02\x02\x03\x04\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\x02\x03\x01\xB0\x13\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0 \x1C\0\0\0\0\0\x000*\0\0\0\0\0\0CET\0\0\x10\x0E\0\0\0\0\0\0\x01CEST\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\x03\x05\0 \x1C\0\0\0\0\0\0\x02\0\0\0\x01\n\x05\x000*\0\0\0\0\0\x000\x01V\x01\x80\xEA\xF0$\xFF\xFF\xFF\xFF\x86\x06\xD4q\xFF\xFF\xFF\xFF\0j\x17\xCA\xFF\xFF\xFF\xFF\0q\xE2\xCA\xFF\xFF\xFF\xFF\0L\xF7\xCB\xFF\xFF\xFF\xFF\0S\xC2\xCC\xFF\xFF\xFF\xFF\xF0\x1C\xB1\x14\0\0\0\0\x90\xDC\x13\x16\0\0\0\0\x90\xCD\x03\x17\0\0\0\0\x90\xBE\xF3\x17\0\0\0\0\x90\xAF\xE3\x18\0\0\0\0\x90\xA0\xD3\x19\0\0\0\0\x90\x91\xC3\x1A\0\0\0\0\x10\xBD\xBC\x1B\0\0\0\0\x10\xAE\xAC\x1C\0\0\0\0\x10\x9F\x9C\x1D\0\0\0\0\x10\x90\x8C\x1E\0\0\0\0\x10\x81|\x1F\0\0\0\0\x10rl \0\0\0\0\x10c\\!\0\0\0\0\x10TL\"\0\0\0\0\x10E<#\0\0\0\0\x106,$\0\0\0\0\x10'\x1C%\0\0\0\0\x10\x18\x0C&\0\0\0\0\x90C\x05'\0\0\0\0\x904\xF5'\0\0\0\0\x90%\xE5(\0\0\0\0\x90\x16\xD5)\0\0\0\0\x90\x07\xC5*\0\0\0\0\x90\xF8\xB4+\0\0\0\0\x90\xE9\xA4,\0\0\0\0\x90\xDA\x94-\0\0\0\0\x90\xCB\x84.\0\0\0\0\x90\xBCt/\0\0\0\0\x90\xADd0\0\0\0\0\x10\xD9]1\0\0\0\0\x10\xB4r2\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\0\x08\0\0\0\0\0\0\xFA\x06\0\0\0\0\0\0\x10\x0E\0\0\0\0\0\0 \x1C\0\0\0\0\0\0-00\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0+06\0\0`T\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\x12\0\x9C\xF7~\x89\xFF\xFF\xFF\xFF\xB0\xDD\xE60\0\0\0\0\x01\x02\xE4C\0\0\0\0\0\0PF\0\0\0\0\0\0`T\0\0\0\0\0\0+05\0\0PF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\x12\0\x18\x9F\xB6V\xFF\xFF\xFF\xFF\x98\xC3/\xED\xFF\xFF\xFF\xFF\0\x01\xE8D\0\0\0\0\0\0PF\0\0\0\0\0\0+04\0\0@8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0(\0-\0\x98\x05\x7F\x89\xFF\xFF\xFF\xFF@\xED\x05\x18\0\0\0\x000r\xDB\x18\0\0\0\0\xE0\x96\x03I\0\0\0\0\xD0\x8F\xCEI\0\0\0\0\x01\x02\x01\x02\x01\xE85\0\0\0\0\0\0@8\0\0\0\0\0\0PF\0\0\0\0\0\0+13\0\0\xD0\xB6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0H\0Q\0\0\xC9=n\xFF\xFF\xFF\xFF\0\xFC\x05\x91\xFF\xFF\xFF\xFF8\x04b\xDA\xFF\xFF\xFF\xFF\xB0'\x9FL\0\0\0\0\xE0+\x97M\0\0\0\0`\xE2}N\0\0\0\0\xA0\x8B\xFDN\0\0\0\0\xE0\rwO\0\0\0\0\xE0\xFEfP\0\0\0\0\x01\x02\x03\x04\x03\x04\x05\x06\x05\x80\xB0\0\0\0\0\0\0\0_\xFF\xFF\xFF\xFF\xFF\xFFH^\xFF\xFF\xFF\xFF\xFF\xFFPe\xFF\xFF\xFF\xFF\xFF\xFF`s\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xC4\0\0\0\0\0\0\xD0\xB6\0\0\0\0\0\0NZST\0\xC0\xA8\0\0\0\0\0\0\x01NZDT\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\t\x05\x000*\0\0\0\0\0\0\x02\0\0\0\x01\x04\x01\0 \x1C\0\0\0\0\0\0\x10\x03\x95\x03\xA8L\xB7A\xFF\xFF\xFF\xFF\xE8\xB2\xB4\xB0\xFF\xFF\xFF\xFFX\x87Q\xB1\xFF\xFF\xFF\xFFh\xE5x\xB2\xFF\xFF\xFF\xFF`\xE5C\xB3\xFF\xFF\xFF\xFFh\xC7X\xB4\xFF\xFF\xFF\xFF`\xC7#\xB5\xFF\xFF\xFF\xFFh\xA98\xB6\xFF\xFF\xFF\xFF`\xA9\x03\xB7\xFF\xFF\xFF\xFFh\x8B\x18\xB8\xFF\xFF\xFF\xFF\xE0\xC5\xEC\xB8\xFF\xFF\xFF\xFFhm\xF8\xB9\xFF\xFF\xFF\xFF\xE0\xA7\xCC\xBA\xFF\xFF\xFF\xFFhO\xD8\xBB\xFF\xFF\xFF\xFF\xE0\xE8\xE3\xBC\xFF\xFF\xFF\xFF\xE8\xF6\xAE\xBD\xFF\xFF\xFF\xFF\xE0\xCA\xC3\xBE\xFF\xFF\xFF\xFF\xE8\xD8\x8E\xBF\xFF\xFF\xFF\xFF\xE0\xAC\xA3\xC0\xFF\xFF\xFF\xFF\xE8\xBAn\xC1\xFF\xFF\xFF\xFF\xE0\x8E\x83\xC2\xFF\xFF\xFF\xFF\xE8\x9CN\xC3\xFF\xFF\xFF\xFF\xE0pc\xC4\xFF\xFF\xFF\xFF\xE8~.\xC5\xFF\xFF\xFF\xFF`\x8DL\xC6\xFF\xFF\xFF\xFF\xE8`\x0E\xC7\xFF\xFF\xFF\xFF`o,\xC8\xFF\xFF\xFF\xFFh}\xF7\xC8\xFF\xFF\xFF\xFF@\x9A\xDA\xD2\xFF\xFF\xFF\xFF\xE0\xFD\x18\t\0\0\0\0\xE0\xA5\xAC\t\0\0\0\0`\xA5\xEF\n\0\0\0\0\xE0\xFC\x9E\x0B\0\0\0\0\xE0\xC1\xD8\x0C\0\0\0\0\xE0\xDE~\r\0\0\0\0\xE0\xA3\xB8\x0E\0\0\0\0\xE0\xC0^\x0F\0\0\0\0\xE0\x85\x98\x10\0\0\0\0\xE0\xA2>\x11\0\0\0\0\xE0gx\x12\0\0\0\0\xE0\x84\x1E\x13\0\0\0\0\xE0IX\x14\0\0\0\0\xE0f\xFE\x14\0\0\0\0\xE0+8\x16\0\0\0\0`\x83\xE7\x16\0\0\0\0`H!\x18\0\0\0\0`e\xC7\x18\0\0\0\0`*\x01\x1A\0\0\0\0`G\xA7\x1A\0\0\0\0`\x0C\xE1\x1B\0\0\0\0`)\x87\x1C\0\0\0\0`\xEE\xC0\x1D\0\0\0\0`\x0Bg\x1E\0\0\0\0`\xD0\xA0\x1F\0\0\0\0`\xEDF \0\0\0\0`\xB2\x80!\0\0\0\0\xE0\t0\"\0\0\0\0\xE0\xCEi#\0\0\0\0\xE0\xEB\x0F$\0\0\0\0`\x01.%\0\0\0\0\xE0B\x02&\0\0\0\0`\xE3\r'\0\0\0\0\xE0$\xE2'\0\0\0\0`\xC5\xED(\0\0\0\0\xE0\x06\xC2)\0\0\0\0`\xA7\xCD*\0\0\0\0`#\xAB+\0\0\0\0`\x89\xAD,\0\0\0\0`\x05\x8B-\0\0\0\0`k\x8D.\0\0\0\0`\xE7j/\0\0\0\0`Mm0\0\0\0\0`\xC9J1\0\0\0\0\xE0iV2\0\0\0\0`\xAB*3\0\0\0\0\xE0K64\0\0\0\0`\x8D\n5\0\0\0\0\xE0-\x166\0\0\0\0\xE0\xA9\xF36\0\0\0\0\xE0\x0F\xF67\0\0\0\0\xE0\x8B\xD38\0\0\0\0\xE0\xF1\xD59\0\0\0\0\xE0m\xB3:\0\0\0\0`\x0E\xBF;\0\0\0\0\xE0O\x93<\0\0\0\0`\xF0\x9E=\0\0\0\0\xE01s>\0\0\0\0`\xD2~?\0\0\0\0`N\\@\0\0\0\0`\xB4^A\0\0\0\0`0C\0\0\0\0`\x12\x1CD\0\0\0\0`x\x1EE\0\0\0\0`\xF4\xFBE\0\0\0\0`Z\xFEF\0\0\0\0\xE0\x85\xF7G\0\0\0\0`<\xDEH\0\0\0\0\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\x03\x04\x05\xD8\xA3\0\0\0\0\0\0\xB8\xA1\0\0\0\0\0\0\xC8\xAF\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0\xD0\xB6\0\0\0\0\0\0+11\0\0\xB0\x9A\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0(\0-\0(R\xB6V\xFF\xFF\xFF\xFF\x90\xA4\xEDr\xFF\xFF\xFF\xFF`6C\xCC\xFF\xFF\xFF\xFF\xF0l+\xD2\xFF\xFF\xFF\xFF\x80\xD7\x9ET\0\0\0\0\x01\x02\x03\x02\x04\xD8\x91\0\0\0\0\0\0\xF0\x89\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\x90~\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0+1245L\xB3\0\0\0\0\0\0\x01+1345\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\t\x05\0\xBC4\0\0\0\0\0\0\x02\0\0\0\x01\x04\x01\0\xAC&\0\0\0\0\0\08\x02\x7F\x02\x84D\xB7A\xFF\xFF\xFF\xFF\xBC\x96\xDA\xD2\xFF\xFF\xFF\xFF\xE0\xFD\x18\t\0\0\0\0\xE0\xA5\xAC\t\0\0\0\0`\xA5\xEF\n\0\0\0\0\xE0\xFC\x9E\x0B\0\0\0\0\xE0\xC1\xD8\x0C\0\0\0\0\xE0\xDE~\r\0\0\0\0\xE0\xA3\xB8\x0E\0\0\0\0\xE0\xC0^\x0F\0\0\0\0\xE0\x85\x98\x10\0\0\0\0\xE0\xA2>\x11\0\0\0\0\xE0gx\x12\0\0\0\0\xE0\x84\x1E\x13\0\0\0\0\xE0IX\x14\0\0\0\0\xE0f\xFE\x14\0\0\0\0\xE0+8\x16\0\0\0\0`\x83\xE7\x16\0\0\0\0`H!\x18\0\0\0\0`e\xC7\x18\0\0\0\0`*\x01\x1A\0\0\0\0`G\xA7\x1A\0\0\0\0`\x0C\xE1\x1B\0\0\0\0`)\x87\x1C\0\0\0\0`\xEE\xC0\x1D\0\0\0\0`\x0Bg\x1E\0\0\0\0`\xD0\xA0\x1F\0\0\0\0`\xEDF \0\0\0\0`\xB2\x80!\0\0\0\0\xE0\t0\"\0\0\0\0\xE0\xCEi#\0\0\0\0\xE0\xEB\x0F$\0\0\0\0`\x01.%\0\0\0\0\xE0B\x02&\0\0\0\0`\xE3\r'\0\0\0\0\xE0$\xE2'\0\0\0\0`\xC5\xED(\0\0\0\0\xE0\x06\xC2)\0\0\0\0`\xA7\xCD*\0\0\0\0`#\xAB+\0\0\0\0`\x89\xAD,\0\0\0\0`\x05\x8B-\0\0\0\0`k\x8D.\0\0\0\0`\xE7j/\0\0\0\0`Mm0\0\0\0\0`\xC9J1\0\0\0\0\xE0iV2\0\0\0\0`\xAB*3\0\0\0\0\xE0K64\0\0\0\0`\x8D\n5\0\0\0\0\xE0-\x166\0\0\0\0\xE0\xA9\xF36\0\0\0\0\xE0\x0F\xF67\0\0\0\0\xE0\x8B\xD38\0\0\0\0\xE0\xF1\xD59\0\0\0\0\xE0m\xB3:\0\0\0\0`\x0E\xBF;\0\0\0\0\xE0O\x93<\0\0\0\0`\xF0\x9E=\0\0\0\0\xE01s>\0\0\0\0`\xD2~?\0\0\0\0`N\\@\0\0\0\0`\xB4^A\0\0\0\0`0C\0\0\0\0`\x12\x1CD\0\0\0\0`x\x1EE\0\0\0\0`\xF4\xFBE\0\0\0\0`Z\xFEF\0\0\0\0\xE0\x85\xF7G\0\0\0\0`<\xDEH\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xFC\xAB\0\0\0\0\0\0D\xAC\0\0\0\0\0\0L\xB3\0\0\0\0\0\0\\\xC1\0\0\0\0\0\0-06\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\x01-05\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\t\x01\0\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFF\x02\0\0\0\x01\x04\x01\0\xE0\xE3\xFF\xFF\xFF\xFF\xFF\xFFx\x03\x10\x04\x08B\x87i\xFF\xFF\xFF\xFF\x88@\xC7\xB9\xFF\xFF\xFF\xFF@<\xD1\xFD\xFF\xFF\xFF\xFF\xB0\xFA\x92\xFE\xFF\xFF\xFF\xFF\xC0\xCD\xCC\xFF\xFF\xFF\xFF\xFF\xB0\xDCr\0\0\0\0\0\xC0Pu\x01\0\0\0\0\xB0I@\x02\0\0\0\0\xC02U\x03\0\0\0\0\xB0+ \x04\0\0\0\0@O>\x05\0\0\0\0\xB0\r\0\x06\0\0\0\0@\xBC\x0B\x07\0\0\0\0\xB0\xEF\xDF\x07\0\0\0\0@\x13\xFE\x08\0\0\0\0\xB0\xD1\xBF\t\0\0\0\0@\xF5\xDD\n\0\0\0\x000\xEE\xA8\x0B\0\0\0\0@\xD7\xBD\x0C\0\0\0\x000\xD0\x88\r\0\0\0\0@\xB9\x9D\x0E\0\0\0\x000\xB2h\x0F\0\0\0\0\xC0\xD5\x86\x10\0\0\0\x000\x94H\x11\0\0\0\0\xC0\xB7f\x12\0\0\0\x000v(\x13\0\0\0\0\xC0\x99F\x14\0\0\0\0\xB0\x92\x11\x15\0\0\0\0\xC0{&\x16\0\0\0\0\xB0t\xF1\x16\0\0\0\0\xC0]\x06\x18\0\0\0\0\xB0V\xD1\x18\0\0\0\0\xC0?\xE6\x19\0\0\0\0\xB08\xB1\x1A\0\0\0\0@\\\xCF\x1B\0\0\0\0\xB0\x1A\x91\x1C\0\0\0\0@>\xAF\x1D\0\0\0\0\xB0\xFCp\x1E\0\0\0\0@ \x8F\x1F\0\0\0\x000\x03\x7F \0\0\0\0@\x02o!\0\0\0\x000\xFB9\"\0\0\0\0@\xE4N#\0\0\0\x000\xDD\x19$\0\0\0\0\xC0\08%\0\0\0\x000\xBF\xF9%\0\0\0\0\xC0\xF8\xF2&\0\0\0\x000\xA1\xD9'\0\0\0\0\xC0\xC4\xF7(\0\0\0\0\xB0\xBD\xC2)\0\0\0\0\xC0\xA6\xD7*\0\0\0\0\xB0\x9F\xA2+\0\0\0\0\xC0\x88\xB7,\0\0\0\0\xB0\x81\x82-\0\0\0\0\xC0j\x97.\0\0\0\0\xB0cb/\0\0\0\0@\x87\x800\0\0\0\0\xB0EB1\0\0\0\0@i`2\0\0\0\x000\xD7=3\0\0\0\0@K@4\0\0\0\x000D\x0B5\0\0\0\0@\xB8\r6\0\0\0\0\xB0\xD5\x067\0\0\0\0@\x0F\08\0\0\0\x000\x08\xCB8\0\0\0\0\xC0+\xE99\0\0\0\x000\xEA\xAA:\0\0\0\0\xC0\r\xC9;\0\0\0\x000\xCC\x8A<\0\0\0\0\xC0\xEF\xA8=\0\0\0\x000\xAEj>\0\0\0\0\xC0\xD1\x88?\0\0\0\0\xB0\xCAS@\0\0\0\0\xC0\xB3hA\0\0\0\0\xB0\xAC3B\0\0\0\0\xC0\x95HC\0\0\0\0\xB0\x8E\x13D\0\0\0\0@\xB21E\0\0\0\0\xB0p\xF3E\0\0\0\0@\x94\x11G\0\0\0\x000\x02\xEFG\0\0\0\0@v\xF1H\0\0\0\x000o\xBCI\0\0\0\0@X\xD1J\0\0\0\0\xB0\0\xB8K\0\0\0\0@:\xB1L\0\0\0\x000\x07\xC6M\0\0\0\0\xC0\x82PN\0\0\0\0\xB0\xAE\x9CO\0\0\0\0\xC0\xD9BP\0\0\0\0\xB0\x90|Q\0\0\0\0@\xF6+R\0\0\0\0\xB0r\\S\0\0\0\0@\xD8\x0BT\0\0\0\x000\xE67W\0\0\0\0\xC0\xEC\xAFW\0\0\0\x000\xC8\x17Y\0\0\0\0\xC0\xCE\x8FY\0\0\0\x000\xAA\xF7Z\0\0\0\0\xC0\xB0o[\0\0\0\0\xB0g\xA9\\\0\0\0\0\xC0|t]\0\0\0\0\xB0I\x89^\0\0\0\0\xC0^T_\0\0\0\0\xB0+i`\0\0\0\0\xC0@4a\0\0\0\0\xB0\rIb\0\0\0\0@]\x1Dc\0\0\0\0\xB0\xEF(d\0\0\0\0\xC0\x04\xF4d\0\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04\x02\x03\x04x\x99\xFF\xFF\xFF\xFF\xFF\xFF\x90\x9D\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF+11\0\0\xB0\x9A\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xB0\0\xC6\0\xB4\xC2\xF5\x92\xFF\xFF\xFF\xFF@\x99y\x07\0\0\0\0@\xCC\xFA\x07\0\0\0\0\xD0\xF7\xD2\x19\0\0\0\0\xC0\xDA\xC2\x1A\0\0\0\0\xD0\xD9\xB2\x1B\0\0\0\0\xC0\xBC\xA2\x1C\0\0\0\0P\xF6\x9B\x1D\0\0\0\0\xC0\x9E\x82\x1E\0\0\0\0P\xD8{\x1F\0\0\0\0@\xBBk \0\0\0\0P\xBA[!\0\0\0\0@\x9DK\"\0\0\0\0P\x9C;#\0\0\0\0@\x7F+$\0\0\0\0P~\x1B%\0\0\0\0@a\x0B&\0\0\0\0P`\xFB&\0\0\0\0@C\xEB'\0\0\0\0\xD0|\xE4(\0\0\0\0@Q\x81)\0\0\0\0\xD0H\xE9*\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xCC\x9D\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0+13\0\0\xD0\xB6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\x12\0\x88U7~\xFF\xFF\xFF\xFF\xB0\x99\xFDN\0\0\0\0\x01\x02x_\xFF\xFF\xFF\xFF\xFF\xFFPe\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xB6\0\0\0\0\0\0+12\0\0\xC0\xA8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x90\0\xA2\0\xC0\xB1\x13\x9A\xFF\xFF\xFF\xFF\xE0\x17;6\0\0\0\0`\xFA\xD76\0\0\0\0`4$8\0\0\0\0`\xDC\xB78\0\0\0\0\xE0,\x11K\0\0\0\0`\x0F\xAEK\0\0\0\0`\xEA\xC2L\0\0\0\0\xE0ArM\0\0\0\0`\xCC\xA2N\0\0\0\0\xE0\xC4\x1AO\0\0\0\0`\xAE\x82P\0\0\0\0\xE0\xA6\xFAP\0\0\0\0\xE0\xCAkR\0\0\0\0\xD0z\xDAR\0\0\0\0`\xE7TT\0\0\0\0\xE0j\xBAT\0\0\0\0`\xC94V\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xC0\xA7\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0\xD0\xB6\0\0\0\0\0\0-06\0\0\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0%\0\x80L\xA4\xB6\xFF\xFF\xFF\xFFP\xC4\x18\x1E\0\0\0\0\xE0\n\x17+\0\0\0\0P\xF4q+\0\0\0\0\x01\x02\x01\x03\x02\0\xAC\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF\xA0\xAB\xFF\xFF\xFF\xFF\xFF\xFF\xB0\xB9\xFF\xFF\xFF\xFF\xFF\xFF-09\0\0p\x81\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\t\0\x04HP\x94\xFF\xFF\xFF\xFF\x01|\x81\xFF\xFF\xFF\xFF\xFF\xFFp\x81\xFF\xFF\xFF\xFF\xFF\xFF+11\0\0\xB0\x9A\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\t\0\x8C3O\x94\xFF\xFF\xFF\xFF\x01\xF4\x95\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0ChST\0\xA0\x8C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xA8\0\xBD\0\xCC\xC5\xE1\x14\xFF\xFF\xFF\xFFL-6~\xFF\xFF\xFF\xFF\xE0\x957\xCB\xFF\xFF\xFF\xFF\xF0\x89.\xD0\xFF\xFF\xFF\xFF\0\xBE7\xEC\xFF\xFF\xFF\xFF\xF0\xF86\xEF\xFF\xFF\xFF\xFF\0\0\x9B\xFB\xFF\xFF\xFF\xFF\x8C'?\xFE\xFF\xFF\xFF\xFF\0\x1E\x01\xFF\xFF\xFF\xFF\xFF\xF0X]\xFF\xFF\xFF\xFF\xFF\0,\x97\0\0\0\0\0puF\x01\0\0\0\0\0\x0Ew\x02\0\0\0\0pW&\x03\0\0\0\0\0\x97p\x07\0\0\0\0\xF0\xD1\xCC\x07\0\0\0\0\0\x91\x08\x0C\0\0\0\0,\x87|\x0C\0\0\0\0\x80\x94\xBF\r\0\0\0\0p\xA3e\x0E\0\0\0\0`^C:\0\0\0\0\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x0246\xFF\xFF\xFF\xFF\xFF\xFF\xB4\x87\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\x90~\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0HST\0\0`s\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\08\0?\0\xBEp\xE0t\xFF\xFF\xFF\xFFHC\x05\xBB\xFF\xFF\xFF\xFFXq!\xBB\xFF\xFF\xFF\xFF\xC8=\x89\xCB\xFF\xFF\xFF\xFFp\xF4#\xD2\xFF\xFF\xFF\xFF8Ia\xD2\xFF\xFF\xFF\xFFHs\x8D\xD5\xFF\xFF\xFF\xFF\x01\x02\x01\x02\x02\x01\x03\x02l\xFF\xFF\xFF\xFF\xFF\xFFXl\xFF\xFF\xFF\xFF\xFF\xFFhz\xFF\xFF\xFF\xFF\xFF\xFF`s\xFF\xFF\xFF\xFF\xFF\xFF+13\0\0\xD0\xB6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\0\x1B\0\x80\xDB,\xC3\xFF\xFF\xFF\xFF\xC0\x04V\x12\0\0\0\0\xB09\x05/\0\0\0\0\x01\x02\x03\0\0\0\0\0\0\0\0@W\xFF\xFF\xFF\xFF\xFF\xFFPe\xFF\xFF\xFF\xFF\xFF\xFF\xD0\xB6\0\0\0\0\0\0+14\0\0\xE0\xC4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\0\x1B\0\x80H7~\xFF\xFF\xFF\xFF\0\xF2U\x12\0\0\0\0\xA0+\x05/\0\0\0\0\x01\x02\x03\x80l\xFF\xFF\xFF\xFF\xFF\xFF\0j\xFF\xFF\xFF\xFF\xFF\xFF`s\xFF\xFF\xFF\xFF\xFF\xFF\xE0\xC4\0\0\0\0\0\0+11\0\0\xB0\x9A\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0H\0Q\0\xB4\xB4\xE1\x14\xFF\xFF\xFF\xFF4\x1C6~\xFF\xFF\xFF\xFF\xD0\x95\x11\x98\xFF\xFF\xFF\xFF\xF0\xF99\xA0\xFF\xFF\xFF\xFF\xD05\xED\xC1\xFF\xFF\xFF\xFF`\n\xEA\xC9\xFF\xFF\xFF\xFF\xF0\x0E\x11\xD2\xFF\xFF\xFF\xFFP\x1B\x86\xFF\xFF\xFF\xFF\xFF@g\x8B6\0\0\0\0\x01\x02\x03\x02\x04\x03\x02\x05\x02LG\xFF\xFF\xFF\xFF\xFF\xFF\xCC\x98\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0\x90~\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0+12\0\0\xC0\xA8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x000\x006\0 \x186~\xFF\xFF\xFF\xFF\xD05\xED\xC1\xFF\xFF\xFF\xFF`\n\xEA\xC9\xFF\xFF\xFF\xFF\xF0\x81F\xCF\xFF\xFF\xFF\xFFP\x1B\x86\xFF\xFF\xFF\xFF\xFF@\x0Ev,\0\0\0\0\x01\x02\x03\x01\x04\x05\xE0\x9C\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0\x90~\0\0\0\0\0\0@W\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xA8\0\0\0\0\0\0-0930hz\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\t\0HLP\x94\xFF\xFF\xFF\xFF\x018}\xFF\xFF\xFF\xFF\xFF\xFFhz\xFF\xFF\xFF\xFF\xFF\xFF+12\0\0\xC0\xA8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0$\0\x04+\xE7\xA3\xFF\xFF\xFF\xFF\xC8\xE9\x90\xCC\xFF\xFF\xFF\xFF\xF0'C\xD2\xFF\xFF\xFF\xFF\xE8\xA8!\x11\0\0\0\0\x01\x02\x01\x03|\x9C\0\0\0\0\0\0\xB8\xA1\0\0\0\0\0\0\x90~\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0-11\0\0Pe\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\x12\0Lj\xA1\xDF\xFF\xFF\xFF\xFF`\xB8\xA6\xF5\xFF\xFF\xFF\xFF\x01\x02\xB4`\xFF\xFF\xFF\xFF\xFF\xFF\xA0`\xFF\xFF\xFF\xFF\xFF\xFFPe\xFF\xFF\xFF\xFF\xFF\xFF+11\0\0\xB0\x9A\0\0\0\0\0\0\x01+12\0\0\x10\x0E\0\0\0\0\0\0\x02\0\0\0\x01\n\x01\x000*\0\0\0\0\0\0\x02\0\0\0\x01\x04\x01\0 \x1C\0\0\0\0\0\0(\0-\0\x88\x176~\xFF\xFF\xFF\xFF\x80\xF8A\xDC\xFF\xFF\xFF\xFFh\xCA\x0F\t\0\0\0\0h\xE7\xB5\t\0\0\0\0h\xE6\x0FV\0\0\0\0\x01\x02\x03\x02\x04x\x9D\0\0\0\0\0\0\x80\x9D\0\0\0\0\0\0\xB8\xA1\0\0\0\0\0\0\xC8\xAF\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0+11\0\0\xB0\x9A\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\08\0?\0t\xC4\xF5\x92\xFF\xFF\xFF\xFFP\xBA\xE6\x0E\0\0\0\0\xC0\xBBV\x0F\0\0\0\0P\x9C\xC6\x10\0\0\0\0@\xEF7\x11\0\0\0\0\xF0K\xA02\0\0\0\0pD\x183\0\0\0\0\x01\x02\x01\x02\x01\x02\x01\x0C\x9C\0\0\0\0\0\0\xB0\x9A\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0SST\0\0Pe\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\x12\0\x08\xC8=n\xFF\xFF\xFF\xFF\x08\xFB\x05\x91\xFF\xFF\xFF\xFF\x01\x02x\xB1\0\0\0\0\0\0\xF8_\xFF\xFF\xFF\xFF\xFF\xFFPe\xFF\xFF\xFF\xFF\xFF\xFF+09\0\0\x90~\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\x12\0l\xCF\xE1\x14\xFF\xFF\xFF\xFF\xEC66~\xFF\xFF\xFF\xFF\x01\x02\x94,\xFF\xFF\xFF\xFF\xFF\xFF\x14~\0\0\0\0\0\0\x90~\0\0\0\0\0\0-08\0\0\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\x12\0\xF4.7~\xFF\xFF\xFF\xFF\x08BD5\0\0\0\0\x01\x02\x0C\x86\xFF\xFF\xFF\xFF\xFF\xFFx\x88\xFF\xFF\xFF\xFF\xFF\xFF\x80\x8F\xFF\xFF\xFF\xFF\xFF\xFF+10\0\0\xA0\x8C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\x12\0\x08Z\xB6V\xFF\xFF\xFF\xFF\x90\xA4\xEDr\xFF\xFF\xFF\xFF\x01\x02\xF8\x89\0\0\0\0\0\0\xF0\x89\0\0\0\0\0\0\xA0\x8C\0\0\0\0\0\0-10\0\0`s\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0(\0-\0\xC8\xDCL|\xFF\xFF\xFF\xFF\xC8`\xA1\xDF\xFF\xFF\xFF\xFF(\x1B\xAC\x10\0\0\0\0\x18\xB5?\x11\0\0\0\0 \x81y\x12\0\0\0\0\x01\x02\x03\x04\x03\xB8\xBB\0\0\0\0\0\08j\xFF\xFF\xFF\xFF\xFF\xFFXl\xFF\xFF\xFF\xFF\xFF\xFFhz\xFF\xFF\xFF\xFF\xFF\xFF`s\xFF\xFF\xFF\xFF\xFF\xFF-10\0\0`s\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\t\0\xB8UP\x94\xFF\xFF\xFF\xFF\x01\xC8s\xFF\xFF\xFF\xFF\xFF\xFF`s\xFF\xFF\xFF\xFF\xFF\xFF+12\0\0\xC0\xA8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\t\0\xCC\x126~\xFF\xFF\xFF\xFF\x014\xA2\0\0\0\0\0\0\xC0\xA8\0\0\0\0\0\0+13\0\0\xD0\xB6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0P\0Z\0@\x9CE\xD2\xFF\xFF\xFF\xFF\x10\xE0\x11\xEF\xFF\xFF\xFF\xFF\xD0G\xFB7\0\0\0\0\xD0}\xD38\0\0\0\0P\x08\x04:\0\0\0\0@\xB8r:\0\0\0\0P\xEA\xE3;\0\0\0\0@\x9AR<\0\0\0\0\xD0\xD7\x1DX\0\0\0\0\xD0 zX\0\0\0\0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02@\xAD\0\0\0\0\0\0p\xAD\0\0\0\0\0\0\xD0\xB6\0\0\0\0\0\0\xE0\xC4\0\0\0\0\0\0") + }, }; + }; +} diff --git a/deps/temporal/provider/src/data/debug/iana_normalizer.json b/deps/temporal/provider/src/data/debug/iana_normalizer.json new file mode 100644 index 00000000000000..b898f3339ada83 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/iana_normalizer.json @@ -0,0 +1,2235 @@ +{ + "version": "2025b", + "available_id_index": { + "africa/abidjan": 0, + "africa/accra": 1, + "africa/addis_ababa": 2, + "africa/algiers": 3, + "africa/asmara": 4, + "africa/asmera": 5, + "africa/bamako": 6, + "africa/bangui": 7, + "africa/banjul": 8, + "africa/bissau": 9, + "africa/blantyre": 10, + "africa/brazzaville": 11, + "africa/bujumbura": 12, + "africa/cairo": 13, + "africa/casablanca": 14, + "africa/ceuta": 15, + "africa/conakry": 16, + "africa/dakar": 17, + "africa/dar_es_salaam": 18, + "africa/djibouti": 19, + "africa/douala": 20, + "africa/el_aaiun": 21, + "africa/freetown": 22, + "africa/gaborone": 23, + "africa/harare": 24, + "africa/johannesburg": 25, + "africa/juba": 26, + "africa/kampala": 27, + "africa/khartoum": 28, + "africa/kigali": 29, + "africa/kinshasa": 30, + "africa/lagos": 31, + "africa/libreville": 32, + "africa/lome": 33, + "africa/luanda": 34, + "africa/lubumbashi": 35, + "africa/lusaka": 36, + "africa/malabo": 37, + "africa/maputo": 38, + "africa/maseru": 39, + "africa/mbabane": 40, + "africa/mogadishu": 41, + "africa/monrovia": 42, + "africa/nairobi": 43, + "africa/ndjamena": 44, + "africa/niamey": 45, + "africa/nouakchott": 46, + "africa/ouagadougou": 47, + "africa/porto-novo": 48, + "africa/sao_tome": 49, + "africa/timbuktu": 50, + "africa/tripoli": 51, + "africa/tunis": 52, + "africa/windhoek": 53, + "america/adak": 54, + "america/anchorage": 55, + "america/anguilla": 56, + "america/antigua": 57, + "america/araguaina": 58, + "america/argentina/buenos_aires": 59, + "america/argentina/catamarca": 60, + "america/argentina/comodrivadavia": 61, + "america/argentina/cordoba": 62, + "america/argentina/jujuy": 63, + "america/argentina/la_rioja": 64, + "america/argentina/mendoza": 65, + "america/argentina/rio_gallegos": 66, + "america/argentina/salta": 67, + "america/argentina/san_juan": 68, + "america/argentina/san_luis": 69, + "america/argentina/tucuman": 70, + "america/argentina/ushuaia": 71, + "america/aruba": 72, + "america/asuncion": 73, + "america/atikokan": 74, + "america/atka": 75, + "america/bahia": 76, + "america/bahia_banderas": 77, + "america/barbados": 78, + "america/belem": 79, + "america/belize": 80, + "america/blanc-sablon": 81, + "america/boa_vista": 82, + "america/bogota": 83, + "america/boise": 84, + "america/buenos_aires": 85, + "america/cambridge_bay": 86, + "america/campo_grande": 87, + "america/cancun": 88, + "america/caracas": 89, + "america/catamarca": 90, + "america/cayenne": 91, + "america/cayman": 92, + "america/chicago": 93, + "america/chihuahua": 94, + "america/ciudad_juarez": 95, + "america/coral_harbour": 96, + "america/cordoba": 97, + "america/costa_rica": 98, + "america/coyhaique": 99, + "america/creston": 100, + "america/cuiaba": 101, + "america/curacao": 102, + "america/danmarkshavn": 103, + "america/dawson": 104, + "america/dawson_creek": 105, + "america/denver": 106, + "america/detroit": 107, + "america/dominica": 108, + "america/edmonton": 109, + "america/eirunepe": 110, + "america/el_salvador": 111, + "america/ensenada": 112, + "america/fort_nelson": 113, + "america/fort_wayne": 114, + "america/fortaleza": 115, + "america/glace_bay": 116, + "america/godthab": 117, + "america/goose_bay": 118, + "america/grand_turk": 119, + "america/grenada": 120, + "america/guadeloupe": 121, + "america/guatemala": 122, + "america/guayaquil": 123, + "america/guyana": 124, + "america/halifax": 125, + "america/havana": 126, + "america/hermosillo": 127, + "america/indiana/indianapolis": 128, + "america/indiana/knox": 129, + "america/indiana/marengo": 130, + "america/indiana/petersburg": 131, + "america/indiana/tell_city": 132, + "america/indiana/vevay": 133, + "america/indiana/vincennes": 134, + "america/indiana/winamac": 135, + "america/indianapolis": 136, + "america/inuvik": 137, + "america/iqaluit": 138, + "america/jamaica": 139, + "america/jujuy": 140, + "america/juneau": 141, + "america/kentucky/louisville": 142, + "america/kentucky/monticello": 143, + "america/knox_in": 144, + "america/kralendijk": 145, + "america/la_paz": 146, + "america/lima": 147, + "america/los_angeles": 148, + "america/louisville": 149, + "america/lower_princes": 150, + "america/maceio": 151, + "america/managua": 152, + "america/manaus": 153, + "america/marigot": 154, + "america/martinique": 155, + "america/matamoros": 156, + "america/mazatlan": 157, + "america/mendoza": 158, + "america/menominee": 159, + "america/merida": 160, + "america/metlakatla": 161, + "america/mexico_city": 162, + "america/miquelon": 163, + "america/moncton": 164, + "america/monterrey": 165, + "america/montevideo": 166, + "america/montreal": 167, + "america/montserrat": 168, + "america/nassau": 169, + "america/new_york": 170, + "america/nipigon": 171, + "america/nome": 172, + "america/noronha": 173, + "america/north_dakota/beulah": 174, + "america/north_dakota/center": 175, + "america/north_dakota/new_salem": 176, + "america/nuuk": 177, + "america/ojinaga": 178, + "america/panama": 179, + "america/pangnirtung": 180, + "america/paramaribo": 181, + "america/phoenix": 182, + "america/port-au-prince": 183, + "america/port_of_spain": 184, + "america/porto_acre": 185, + "america/porto_velho": 186, + "america/puerto_rico": 187, + "america/punta_arenas": 188, + "america/rainy_river": 189, + "america/rankin_inlet": 190, + "america/recife": 191, + "america/regina": 192, + "america/resolute": 193, + "america/rio_branco": 194, + "america/rosario": 195, + "america/santa_isabel": 196, + "america/santarem": 197, + "america/santiago": 198, + "america/santo_domingo": 199, + "america/sao_paulo": 200, + "america/scoresbysund": 201, + "america/shiprock": 202, + "america/sitka": 203, + "america/st_barthelemy": 204, + "america/st_johns": 205, + "america/st_kitts": 206, + "america/st_lucia": 207, + "america/st_thomas": 208, + "america/st_vincent": 209, + "america/swift_current": 210, + "america/tegucigalpa": 211, + "america/thule": 212, + "america/thunder_bay": 213, + "america/tijuana": 214, + "america/toronto": 215, + "america/tortola": 216, + "america/vancouver": 217, + "america/virgin": 218, + "america/whitehorse": 219, + "america/winnipeg": 220, + "america/yakutat": 221, + "america/yellowknife": 222, + "antarctica/casey": 223, + "antarctica/davis": 224, + "antarctica/dumontdurville": 225, + "antarctica/macquarie": 226, + "antarctica/mawson": 227, + "antarctica/mcmurdo": 228, + "antarctica/palmer": 229, + "antarctica/rothera": 230, + "antarctica/south_pole": 231, + "antarctica/syowa": 232, + "antarctica/troll": 233, + "antarctica/vostok": 234, + "arctic/longyearbyen": 235, + "asia/aden": 236, + "asia/almaty": 237, + "asia/amman": 238, + "asia/anadyr": 239, + "asia/aqtau": 240, + "asia/aqtobe": 241, + "asia/ashgabat": 242, + "asia/ashkhabad": 243, + "asia/atyrau": 244, + "asia/baghdad": 245, + "asia/bahrain": 246, + "asia/baku": 247, + "asia/bangkok": 248, + "asia/barnaul": 249, + "asia/beirut": 250, + "asia/bishkek": 251, + "asia/brunei": 252, + "asia/calcutta": 253, + "asia/chita": 254, + "asia/choibalsan": 255, + "asia/chongqing": 256, + "asia/chungking": 257, + "asia/colombo": 258, + "asia/dacca": 259, + "asia/damascus": 260, + "asia/dhaka": 261, + "asia/dili": 262, + "asia/dubai": 263, + "asia/dushanbe": 264, + "asia/famagusta": 265, + "asia/gaza": 266, + "asia/harbin": 267, + "asia/hebron": 268, + "asia/ho_chi_minh": 269, + "asia/hong_kong": 270, + "asia/hovd": 271, + "asia/irkutsk": 272, + "asia/istanbul": 273, + "asia/jakarta": 274, + "asia/jayapura": 275, + "asia/jerusalem": 276, + "asia/kabul": 277, + "asia/kamchatka": 278, + "asia/karachi": 279, + "asia/kashgar": 280, + "asia/kathmandu": 281, + "asia/katmandu": 282, + "asia/khandyga": 283, + "asia/kolkata": 284, + "asia/krasnoyarsk": 285, + "asia/kuala_lumpur": 286, + "asia/kuching": 287, + "asia/kuwait": 288, + "asia/macao": 289, + "asia/macau": 290, + "asia/magadan": 291, + "asia/makassar": 292, + "asia/manila": 293, + "asia/muscat": 294, + "asia/nicosia": 295, + "asia/novokuznetsk": 296, + "asia/novosibirsk": 297, + "asia/omsk": 298, + "asia/oral": 299, + "asia/phnom_penh": 300, + "asia/pontianak": 301, + "asia/pyongyang": 302, + "asia/qatar": 303, + "asia/qostanay": 304, + "asia/qyzylorda": 305, + "asia/rangoon": 306, + "asia/riyadh": 307, + "asia/saigon": 308, + "asia/sakhalin": 309, + "asia/samarkand": 310, + "asia/seoul": 311, + "asia/shanghai": 312, + "asia/singapore": 313, + "asia/srednekolymsk": 314, + "asia/taipei": 315, + "asia/tashkent": 316, + "asia/tbilisi": 317, + "asia/tehran": 318, + "asia/tel_aviv": 319, + "asia/thimbu": 320, + "asia/thimphu": 321, + "asia/tokyo": 322, + "asia/tomsk": 323, + "asia/ujung_pandang": 324, + "asia/ulaanbaatar": 325, + "asia/ulan_bator": 326, + "asia/urumqi": 327, + "asia/ust-nera": 328, + "asia/vientiane": 329, + "asia/vladivostok": 330, + "asia/yakutsk": 331, + "asia/yangon": 332, + "asia/yekaterinburg": 333, + "asia/yerevan": 334, + "atlantic/azores": 335, + "atlantic/bermuda": 336, + "atlantic/canary": 337, + "atlantic/cape_verde": 338, + "atlantic/faeroe": 339, + "atlantic/faroe": 340, + "atlantic/jan_mayen": 341, + "atlantic/madeira": 342, + "atlantic/reykjavik": 343, + "atlantic/south_georgia": 344, + "atlantic/st_helena": 345, + "atlantic/stanley": 346, + "australia/act": 347, + "australia/adelaide": 348, + "australia/brisbane": 349, + "australia/broken_hill": 350, + "australia/canberra": 351, + "australia/currie": 352, + "australia/darwin": 353, + "australia/eucla": 354, + "australia/hobart": 355, + "australia/lhi": 356, + "australia/lindeman": 357, + "australia/lord_howe": 358, + "australia/melbourne": 359, + "australia/north": 361, + "australia/nsw": 360, + "australia/perth": 362, + "australia/queensland": 363, + "australia/south": 364, + "australia/sydney": 365, + "australia/tasmania": 366, + "australia/victoria": 367, + "australia/west": 368, + "australia/yancowinna": 369, + "brazil/acre": 370, + "brazil/denoronha": 371, + "brazil/east": 372, + "brazil/west": 373, + "canada/atlantic": 376, + "canada/central": 377, + "canada/eastern": 378, + "canada/mountain": 379, + "canada/newfoundland": 380, + "canada/pacific": 381, + "canada/saskatchewan": 382, + "canada/yukon": 383, + "cet": 374, + "chile/continental": 384, + "chile/easterisland": 385, + "cst6cdt": 375, + "cuba": 386, + "eet": 387, + "egypt": 390, + "eire": 391, + "est": 388, + "est5edt": 389, + "etc/gmt": 392, + "etc/gmt+0": 393, + "etc/gmt+1": 394, + "etc/gmt+10": 395, + "etc/gmt+11": 396, + "etc/gmt+12": 397, + "etc/gmt+2": 398, + "etc/gmt+3": 399, + "etc/gmt+4": 400, + "etc/gmt+5": 401, + "etc/gmt+6": 402, + "etc/gmt+7": 403, + "etc/gmt+8": 404, + "etc/gmt+9": 405, + "etc/gmt-0": 406, + "etc/gmt-1": 407, + "etc/gmt-10": 408, + "etc/gmt-11": 409, + "etc/gmt-12": 410, + "etc/gmt-13": 411, + "etc/gmt-14": 412, + "etc/gmt-2": 413, + "etc/gmt-3": 414, + "etc/gmt-4": 415, + "etc/gmt-5": 416, + "etc/gmt-6": 417, + "etc/gmt-7": 418, + "etc/gmt-8": 419, + "etc/gmt-9": 420, + "etc/gmt0": 421, + "etc/greenwich": 422, + "etc/uct": 423, + "etc/universal": 425, + "etc/utc": 424, + "etc/zulu": 426, + "europe/amsterdam": 427, + "europe/andorra": 428, + "europe/astrakhan": 429, + "europe/athens": 430, + "europe/belfast": 431, + "europe/belgrade": 432, + "europe/berlin": 433, + "europe/bratislava": 434, + "europe/brussels": 435, + "europe/bucharest": 436, + "europe/budapest": 437, + "europe/busingen": 438, + "europe/chisinau": 439, + "europe/copenhagen": 440, + "europe/dublin": 441, + "europe/gibraltar": 442, + "europe/guernsey": 443, + "europe/helsinki": 444, + "europe/isle_of_man": 445, + "europe/istanbul": 446, + "europe/jersey": 447, + "europe/kaliningrad": 448, + "europe/kiev": 449, + "europe/kirov": 450, + "europe/kyiv": 451, + "europe/lisbon": 452, + "europe/ljubljana": 453, + "europe/london": 454, + "europe/luxembourg": 455, + "europe/madrid": 456, + "europe/malta": 457, + "europe/mariehamn": 458, + "europe/minsk": 459, + "europe/monaco": 460, + "europe/moscow": 461, + "europe/nicosia": 462, + "europe/oslo": 463, + "europe/paris": 464, + "europe/podgorica": 465, + "europe/prague": 466, + "europe/riga": 467, + "europe/rome": 468, + "europe/samara": 469, + "europe/san_marino": 470, + "europe/sarajevo": 471, + "europe/saratov": 472, + "europe/simferopol": 473, + "europe/skopje": 474, + "europe/sofia": 475, + "europe/stockholm": 476, + "europe/tallinn": 477, + "europe/tirane": 478, + "europe/tiraspol": 479, + "europe/ulyanovsk": 480, + "europe/uzhgorod": 481, + "europe/vaduz": 482, + "europe/vatican": 483, + "europe/vienna": 484, + "europe/vilnius": 485, + "europe/volgograd": 486, + "europe/warsaw": 487, + "europe/zagreb": 488, + "europe/zaporozhye": 489, + "europe/zurich": 490, + "gb": 491, + "gb-eire": 492, + "gmt": 493, + "gmt+0": 494, + "gmt-0": 495, + "gmt0": 496, + "greenwich": 497, + "hongkong": 499, + "hst": 498, + "iceland": 500, + "indian/antananarivo": 501, + "indian/chagos": 502, + "indian/christmas": 503, + "indian/cocos": 504, + "indian/comoro": 505, + "indian/kerguelen": 506, + "indian/mahe": 507, + "indian/maldives": 508, + "indian/mauritius": 509, + "indian/mayotte": 510, + "indian/reunion": 511, + "iran": 512, + "israel": 513, + "jamaica": 514, + "japan": 515, + "kwajalein": 516, + "libya": 517, + "met": 518, + "mexico/bajanorte": 521, + "mexico/bajasur": 522, + "mexico/general": 523, + "mst": 519, + "mst7mdt": 520, + "navajo": 526, + "nz": 524, + "nz-chat": 525, + "pacific/apia": 529, + "pacific/auckland": 530, + "pacific/bougainville": 531, + "pacific/chatham": 532, + "pacific/chuuk": 533, + "pacific/easter": 534, + "pacific/efate": 535, + "pacific/enderbury": 536, + "pacific/fakaofo": 537, + "pacific/fiji": 538, + "pacific/funafuti": 539, + "pacific/galapagos": 540, + "pacific/gambier": 541, + "pacific/guadalcanal": 542, + "pacific/guam": 543, + "pacific/honolulu": 544, + "pacific/johnston": 545, + "pacific/kanton": 546, + "pacific/kiritimati": 547, + "pacific/kosrae": 548, + "pacific/kwajalein": 549, + "pacific/majuro": 550, + "pacific/marquesas": 551, + "pacific/midway": 552, + "pacific/nauru": 553, + "pacific/niue": 554, + "pacific/norfolk": 555, + "pacific/noumea": 556, + "pacific/pago_pago": 557, + "pacific/palau": 558, + "pacific/pitcairn": 559, + "pacific/pohnpei": 560, + "pacific/ponape": 561, + "pacific/port_moresby": 562, + "pacific/rarotonga": 563, + "pacific/saipan": 564, + "pacific/samoa": 565, + "pacific/tahiti": 566, + "pacific/tarawa": 567, + "pacific/tongatapu": 568, + "pacific/truk": 569, + "pacific/wake": 570, + "pacific/wallis": 571, + "pacific/yap": 572, + "poland": 573, + "portugal": 574, + "prc": 527, + "pst8pdt": 528, + "roc": 575, + "rok": 576, + "singapore": 577, + "turkey": 578, + "uct": 579, + "universal": 593, + "us/alaska": 580, + "us/aleutian": 581, + "us/arizona": 582, + "us/central": 583, + "us/east-indiana": 584, + "us/eastern": 585, + "us/hawaii": 586, + "us/indiana-starke": 587, + "us/michigan": 588, + "us/mountain": 589, + "us/pacific": 590, + "us/samoa": 591, + "utc": 592, + "w-su": 594, + "wet": 595, + "zulu": 596 + }, + "non_canonical_identifiers": [ + [ + 1, + 0 + ], + [ + 2, + 43 + ], + [ + 4, + 43 + ], + [ + 5, + 43 + ], + [ + 6, + 0 + ], + [ + 7, + 31 + ], + [ + 8, + 0 + ], + [ + 10, + 38 + ], + [ + 11, + 31 + ], + [ + 12, + 38 + ], + [ + 16, + 0 + ], + [ + 17, + 0 + ], + [ + 18, + 43 + ], + [ + 19, + 43 + ], + [ + 20, + 31 + ], + [ + 22, + 0 + ], + [ + 23, + 38 + ], + [ + 24, + 38 + ], + [ + 27, + 43 + ], + [ + 29, + 38 + ], + [ + 30, + 31 + ], + [ + 32, + 31 + ], + [ + 33, + 0 + ], + [ + 34, + 31 + ], + [ + 35, + 38 + ], + [ + 36, + 38 + ], + [ + 37, + 31 + ], + [ + 39, + 25 + ], + [ + 40, + 25 + ], + [ + 41, + 43 + ], + [ + 45, + 31 + ], + [ + 46, + 0 + ], + [ + 47, + 0 + ], + [ + 48, + 31 + ], + [ + 50, + 0 + ], + [ + 56, + 187 + ], + [ + 57, + 187 + ], + [ + 61, + 60 + ], + [ + 72, + 187 + ], + [ + 74, + 179 + ], + [ + 75, + 54 + ], + [ + 81, + 187 + ], + [ + 85, + 59 + ], + [ + 90, + 60 + ], + [ + 92, + 179 + ], + [ + 96, + 179 + ], + [ + 97, + 62 + ], + [ + 100, + 182 + ], + [ + 102, + 187 + ], + [ + 108, + 187 + ], + [ + 112, + 214 + ], + [ + 114, + 128 + ], + [ + 117, + 177 + ], + [ + 120, + 187 + ], + [ + 121, + 187 + ], + [ + 136, + 128 + ], + [ + 140, + 63 + ], + [ + 144, + 129 + ], + [ + 145, + 187 + ], + [ + 149, + 142 + ], + [ + 150, + 187 + ], + [ + 154, + 187 + ], + [ + 158, + 65 + ], + [ + 167, + 215 + ], + [ + 168, + 187 + ], + [ + 169, + 215 + ], + [ + 171, + 215 + ], + [ + 180, + 138 + ], + [ + 184, + 187 + ], + [ + 185, + 194 + ], + [ + 189, + 220 + ], + [ + 195, + 62 + ], + [ + 196, + 214 + ], + [ + 202, + 106 + ], + [ + 204, + 187 + ], + [ + 206, + 187 + ], + [ + 207, + 187 + ], + [ + 208, + 187 + ], + [ + 209, + 187 + ], + [ + 213, + 215 + ], + [ + 216, + 187 + ], + [ + 218, + 187 + ], + [ + 222, + 109 + ], + [ + 225, + 562 + ], + [ + 228, + 530 + ], + [ + 231, + 530 + ], + [ + 232, + 307 + ], + [ + 235, + 433 + ], + [ + 236, + 307 + ], + [ + 243, + 242 + ], + [ + 246, + 303 + ], + [ + 252, + 287 + ], + [ + 253, + 284 + ], + [ + 255, + 325 + ], + [ + 256, + 312 + ], + [ + 257, + 312 + ], + [ + 259, + 261 + ], + [ + 267, + 312 + ], + [ + 273, + 446 + ], + [ + 280, + 327 + ], + [ + 282, + 281 + ], + [ + 286, + 313 + ], + [ + 288, + 307 + ], + [ + 289, + 290 + ], + [ + 294, + 263 + ], + [ + 300, + 248 + ], + [ + 306, + 332 + ], + [ + 308, + 269 + ], + [ + 319, + 276 + ], + [ + 320, + 321 + ], + [ + 324, + 292 + ], + [ + 326, + 325 + ], + [ + 329, + 248 + ], + [ + 339, + 340 + ], + [ + 341, + 433 + ], + [ + 343, + 0 + ], + [ + 345, + 0 + ], + [ + 347, + 365 + ], + [ + 351, + 365 + ], + [ + 352, + 355 + ], + [ + 356, + 358 + ], + [ + 360, + 365 + ], + [ + 361, + 353 + ], + [ + 363, + 349 + ], + [ + 364, + 348 + ], + [ + 366, + 355 + ], + [ + 367, + 359 + ], + [ + 368, + 362 + ], + [ + 369, + 350 + ], + [ + 370, + 194 + ], + [ + 371, + 173 + ], + [ + 372, + 200 + ], + [ + 373, + 153 + ], + [ + 374, + 435 + ], + [ + 375, + 93 + ], + [ + 376, + 125 + ], + [ + 377, + 220 + ], + [ + 378, + 215 + ], + [ + 379, + 109 + ], + [ + 380, + 205 + ], + [ + 381, + 217 + ], + [ + 382, + 192 + ], + [ + 383, + 219 + ], + [ + 384, + 198 + ], + [ + 385, + 534 + ], + [ + 386, + 126 + ], + [ + 387, + 430 + ], + [ + 388, + 179 + ], + [ + 389, + 170 + ], + [ + 390, + 13 + ], + [ + 391, + 441 + ], + [ + 392, + 592 + ], + [ + 393, + 592 + ], + [ + 406, + 592 + ], + [ + 421, + 592 + ], + [ + 422, + 592 + ], + [ + 423, + 592 + ], + [ + 424, + 592 + ], + [ + 425, + 592 + ], + [ + 426, + 592 + ], + [ + 427, + 435 + ], + [ + 431, + 454 + ], + [ + 434, + 466 + ], + [ + 438, + 490 + ], + [ + 440, + 433 + ], + [ + 443, + 454 + ], + [ + 445, + 454 + ], + [ + 447, + 454 + ], + [ + 449, + 451 + ], + [ + 453, + 432 + ], + [ + 455, + 435 + ], + [ + 458, + 444 + ], + [ + 460, + 464 + ], + [ + 462, + 295 + ], + [ + 463, + 433 + ], + [ + 465, + 432 + ], + [ + 470, + 468 + ], + [ + 471, + 432 + ], + [ + 474, + 432 + ], + [ + 476, + 433 + ], + [ + 479, + 439 + ], + [ + 481, + 451 + ], + [ + 482, + 490 + ], + [ + 483, + 468 + ], + [ + 488, + 432 + ], + [ + 489, + 451 + ], + [ + 491, + 454 + ], + [ + 492, + 454 + ], + [ + 493, + 592 + ], + [ + 494, + 592 + ], + [ + 495, + 592 + ], + [ + 496, + 592 + ], + [ + 497, + 592 + ], + [ + 498, + 544 + ], + [ + 499, + 270 + ], + [ + 500, + 0 + ], + [ + 501, + 43 + ], + [ + 503, + 248 + ], + [ + 504, + 332 + ], + [ + 505, + 43 + ], + [ + 506, + 508 + ], + [ + 507, + 263 + ], + [ + 510, + 43 + ], + [ + 511, + 263 + ], + [ + 512, + 318 + ], + [ + 513, + 276 + ], + [ + 514, + 139 + ], + [ + 515, + 322 + ], + [ + 516, + 549 + ], + [ + 517, + 51 + ], + [ + 518, + 435 + ], + [ + 519, + 182 + ], + [ + 520, + 106 + ], + [ + 521, + 214 + ], + [ + 522, + 157 + ], + [ + 523, + 162 + ], + [ + 524, + 530 + ], + [ + 525, + 532 + ], + [ + 526, + 106 + ], + [ + 527, + 312 + ], + [ + 528, + 148 + ], + [ + 533, + 562 + ], + [ + 536, + 546 + ], + [ + 539, + 567 + ], + [ + 545, + 544 + ], + [ + 550, + 567 + ], + [ + 552, + 557 + ], + [ + 560, + 542 + ], + [ + 561, + 542 + ], + [ + 564, + 543 + ], + [ + 565, + 557 + ], + [ + 569, + 562 + ], + [ + 570, + 567 + ], + [ + 571, + 567 + ], + [ + 572, + 562 + ], + [ + 573, + 487 + ], + [ + 574, + 452 + ], + [ + 575, + 315 + ], + [ + 576, + 311 + ], + [ + 577, + 313 + ], + [ + 578, + 446 + ], + [ + 579, + 592 + ], + [ + 580, + 55 + ], + [ + 581, + 54 + ], + [ + 582, + 182 + ], + [ + 583, + 93 + ], + [ + 584, + 128 + ], + [ + 585, + 170 + ], + [ + 586, + 544 + ], + [ + 587, + 129 + ], + [ + 588, + 107 + ], + [ + 589, + 106 + ], + [ + 590, + 148 + ], + [ + 591, + 557 + ], + [ + 593, + 592 + ], + [ + 594, + 461 + ], + [ + 595, + 452 + ], + [ + 596, + 592 + ] + ], + "normalized_identifiers": [ + "Africa/Abidjan", + "Africa/Accra", + "Africa/Addis_Ababa", + "Africa/Algiers", + "Africa/Asmara", + "Africa/Asmera", + "Africa/Bamako", + "Africa/Bangui", + "Africa/Banjul", + "Africa/Bissau", + "Africa/Blantyre", + "Africa/Brazzaville", + "Africa/Bujumbura", + "Africa/Cairo", + "Africa/Casablanca", + "Africa/Ceuta", + "Africa/Conakry", + "Africa/Dakar", + "Africa/Dar_es_Salaam", + "Africa/Djibouti", + "Africa/Douala", + "Africa/El_Aaiun", + "Africa/Freetown", + "Africa/Gaborone", + "Africa/Harare", + "Africa/Johannesburg", + "Africa/Juba", + "Africa/Kampala", + "Africa/Khartoum", + "Africa/Kigali", + "Africa/Kinshasa", + "Africa/Lagos", + "Africa/Libreville", + "Africa/Lome", + "Africa/Luanda", + "Africa/Lubumbashi", + "Africa/Lusaka", + "Africa/Malabo", + "Africa/Maputo", + "Africa/Maseru", + "Africa/Mbabane", + "Africa/Mogadishu", + "Africa/Monrovia", + "Africa/Nairobi", + "Africa/Ndjamena", + "Africa/Niamey", + "Africa/Nouakchott", + "Africa/Ouagadougou", + "Africa/Porto-Novo", + "Africa/Sao_Tome", + "Africa/Timbuktu", + "Africa/Tripoli", + "Africa/Tunis", + "Africa/Windhoek", + "America/Adak", + "America/Anchorage", + "America/Anguilla", + "America/Antigua", + "America/Araguaina", + "America/Argentina/Buenos_Aires", + "America/Argentina/Catamarca", + "America/Argentina/ComodRivadavia", + "America/Argentina/Cordoba", + "America/Argentina/Jujuy", + "America/Argentina/La_Rioja", + "America/Argentina/Mendoza", + "America/Argentina/Rio_Gallegos", + "America/Argentina/Salta", + "America/Argentina/San_Juan", + "America/Argentina/San_Luis", + "America/Argentina/Tucuman", + "America/Argentina/Ushuaia", + "America/Aruba", + "America/Asuncion", + "America/Atikokan", + "America/Atka", + "America/Bahia", + "America/Bahia_Banderas", + "America/Barbados", + "America/Belem", + "America/Belize", + "America/Blanc-Sablon", + "America/Boa_Vista", + "America/Bogota", + "America/Boise", + "America/Buenos_Aires", + "America/Cambridge_Bay", + "America/Campo_Grande", + "America/Cancun", + "America/Caracas", + "America/Catamarca", + "America/Cayenne", + "America/Cayman", + "America/Chicago", + "America/Chihuahua", + "America/Ciudad_Juarez", + "America/Coral_Harbour", + "America/Cordoba", + "America/Costa_Rica", + "America/Coyhaique", + "America/Creston", + "America/Cuiaba", + "America/Curacao", + "America/Danmarkshavn", + "America/Dawson", + "America/Dawson_Creek", + "America/Denver", + "America/Detroit", + "America/Dominica", + "America/Edmonton", + "America/Eirunepe", + "America/El_Salvador", + "America/Ensenada", + "America/Fort_Nelson", + "America/Fort_Wayne", + "America/Fortaleza", + "America/Glace_Bay", + "America/Godthab", + "America/Goose_Bay", + "America/Grand_Turk", + "America/Grenada", + "America/Guadeloupe", + "America/Guatemala", + "America/Guayaquil", + "America/Guyana", + "America/Halifax", + "America/Havana", + "America/Hermosillo", + "America/Indiana/Indianapolis", + "America/Indiana/Knox", + "America/Indiana/Marengo", + "America/Indiana/Petersburg", + "America/Indiana/Tell_City", + "America/Indiana/Vevay", + "America/Indiana/Vincennes", + "America/Indiana/Winamac", + "America/Indianapolis", + "America/Inuvik", + "America/Iqaluit", + "America/Jamaica", + "America/Jujuy", + "America/Juneau", + "America/Kentucky/Louisville", + "America/Kentucky/Monticello", + "America/Knox_IN", + "America/Kralendijk", + "America/La_Paz", + "America/Lima", + "America/Los_Angeles", + "America/Louisville", + "America/Lower_Princes", + "America/Maceio", + "America/Managua", + "America/Manaus", + "America/Marigot", + "America/Martinique", + "America/Matamoros", + "America/Mazatlan", + "America/Mendoza", + "America/Menominee", + "America/Merida", + "America/Metlakatla", + "America/Mexico_City", + "America/Miquelon", + "America/Moncton", + "America/Monterrey", + "America/Montevideo", + "America/Montreal", + "America/Montserrat", + "America/Nassau", + "America/New_York", + "America/Nipigon", + "America/Nome", + "America/Noronha", + "America/North_Dakota/Beulah", + "America/North_Dakota/Center", + "America/North_Dakota/New_Salem", + "America/Nuuk", + "America/Ojinaga", + "America/Panama", + "America/Pangnirtung", + "America/Paramaribo", + "America/Phoenix", + "America/Port-au-Prince", + "America/Port_of_Spain", + "America/Porto_Acre", + "America/Porto_Velho", + "America/Puerto_Rico", + "America/Punta_Arenas", + "America/Rainy_River", + "America/Rankin_Inlet", + "America/Recife", + "America/Regina", + "America/Resolute", + "America/Rio_Branco", + "America/Rosario", + "America/Santa_Isabel", + "America/Santarem", + "America/Santiago", + "America/Santo_Domingo", + "America/Sao_Paulo", + "America/Scoresbysund", + "America/Shiprock", + "America/Sitka", + "America/St_Barthelemy", + "America/St_Johns", + "America/St_Kitts", + "America/St_Lucia", + "America/St_Thomas", + "America/St_Vincent", + "America/Swift_Current", + "America/Tegucigalpa", + "America/Thule", + "America/Thunder_Bay", + "America/Tijuana", + "America/Toronto", + "America/Tortola", + "America/Vancouver", + "America/Virgin", + "America/Whitehorse", + "America/Winnipeg", + "America/Yakutat", + "America/Yellowknife", + "Antarctica/Casey", + "Antarctica/Davis", + "Antarctica/DumontDUrville", + "Antarctica/Macquarie", + "Antarctica/Mawson", + "Antarctica/McMurdo", + "Antarctica/Palmer", + "Antarctica/Rothera", + "Antarctica/South_Pole", + "Antarctica/Syowa", + "Antarctica/Troll", + "Antarctica/Vostok", + "Arctic/Longyearbyen", + "Asia/Aden", + "Asia/Almaty", + "Asia/Amman", + "Asia/Anadyr", + "Asia/Aqtau", + "Asia/Aqtobe", + "Asia/Ashgabat", + "Asia/Ashkhabad", + "Asia/Atyrau", + "Asia/Baghdad", + "Asia/Bahrain", + "Asia/Baku", + "Asia/Bangkok", + "Asia/Barnaul", + "Asia/Beirut", + "Asia/Bishkek", + "Asia/Brunei", + "Asia/Calcutta", + "Asia/Chita", + "Asia/Choibalsan", + "Asia/Chongqing", + "Asia/Chungking", + "Asia/Colombo", + "Asia/Dacca", + "Asia/Damascus", + "Asia/Dhaka", + "Asia/Dili", + "Asia/Dubai", + "Asia/Dushanbe", + "Asia/Famagusta", + "Asia/Gaza", + "Asia/Harbin", + "Asia/Hebron", + "Asia/Ho_Chi_Minh", + "Asia/Hong_Kong", + "Asia/Hovd", + "Asia/Irkutsk", + "Asia/Istanbul", + "Asia/Jakarta", + "Asia/Jayapura", + "Asia/Jerusalem", + "Asia/Kabul", + "Asia/Kamchatka", + "Asia/Karachi", + "Asia/Kashgar", + "Asia/Kathmandu", + "Asia/Katmandu", + "Asia/Khandyga", + "Asia/Kolkata", + "Asia/Krasnoyarsk", + "Asia/Kuala_Lumpur", + "Asia/Kuching", + "Asia/Kuwait", + "Asia/Macao", + "Asia/Macau", + "Asia/Magadan", + "Asia/Makassar", + "Asia/Manila", + "Asia/Muscat", + "Asia/Nicosia", + "Asia/Novokuznetsk", + "Asia/Novosibirsk", + "Asia/Omsk", + "Asia/Oral", + "Asia/Phnom_Penh", + "Asia/Pontianak", + "Asia/Pyongyang", + "Asia/Qatar", + "Asia/Qostanay", + "Asia/Qyzylorda", + "Asia/Rangoon", + "Asia/Riyadh", + "Asia/Saigon", + "Asia/Sakhalin", + "Asia/Samarkand", + "Asia/Seoul", + "Asia/Shanghai", + "Asia/Singapore", + "Asia/Srednekolymsk", + "Asia/Taipei", + "Asia/Tashkent", + "Asia/Tbilisi", + "Asia/Tehran", + "Asia/Tel_Aviv", + "Asia/Thimbu", + "Asia/Thimphu", + "Asia/Tokyo", + "Asia/Tomsk", + "Asia/Ujung_Pandang", + "Asia/Ulaanbaatar", + "Asia/Ulan_Bator", + "Asia/Urumqi", + "Asia/Ust-Nera", + "Asia/Vientiane", + "Asia/Vladivostok", + "Asia/Yakutsk", + "Asia/Yangon", + "Asia/Yekaterinburg", + "Asia/Yerevan", + "Atlantic/Azores", + "Atlantic/Bermuda", + "Atlantic/Canary", + "Atlantic/Cape_Verde", + "Atlantic/Faeroe", + "Atlantic/Faroe", + "Atlantic/Jan_Mayen", + "Atlantic/Madeira", + "Atlantic/Reykjavik", + "Atlantic/South_Georgia", + "Atlantic/St_Helena", + "Atlantic/Stanley", + "Australia/ACT", + "Australia/Adelaide", + "Australia/Brisbane", + "Australia/Broken_Hill", + "Australia/Canberra", + "Australia/Currie", + "Australia/Darwin", + "Australia/Eucla", + "Australia/Hobart", + "Australia/LHI", + "Australia/Lindeman", + "Australia/Lord_Howe", + "Australia/Melbourne", + "Australia/NSW", + "Australia/North", + "Australia/Perth", + "Australia/Queensland", + "Australia/South", + "Australia/Sydney", + "Australia/Tasmania", + "Australia/Victoria", + "Australia/West", + "Australia/Yancowinna", + "Brazil/Acre", + "Brazil/DeNoronha", + "Brazil/East", + "Brazil/West", + "CET", + "CST6CDT", + "Canada/Atlantic", + "Canada/Central", + "Canada/Eastern", + "Canada/Mountain", + "Canada/Newfoundland", + "Canada/Pacific", + "Canada/Saskatchewan", + "Canada/Yukon", + "Chile/Continental", + "Chile/EasterIsland", + "Cuba", + "EET", + "EST", + "EST5EDT", + "Egypt", + "Eire", + "Etc/GMT", + "Etc/GMT+0", + "Etc/GMT+1", + "Etc/GMT+10", + "Etc/GMT+11", + "Etc/GMT+12", + "Etc/GMT+2", + "Etc/GMT+3", + "Etc/GMT+4", + "Etc/GMT+5", + "Etc/GMT+6", + "Etc/GMT+7", + "Etc/GMT+8", + "Etc/GMT+9", + "Etc/GMT-0", + "Etc/GMT-1", + "Etc/GMT-10", + "Etc/GMT-11", + "Etc/GMT-12", + "Etc/GMT-13", + "Etc/GMT-14", + "Etc/GMT-2", + "Etc/GMT-3", + "Etc/GMT-4", + "Etc/GMT-5", + "Etc/GMT-6", + "Etc/GMT-7", + "Etc/GMT-8", + "Etc/GMT-9", + "Etc/GMT0", + "Etc/Greenwich", + "Etc/UCT", + "Etc/UTC", + "Etc/Universal", + "Etc/Zulu", + "Europe/Amsterdam", + "Europe/Andorra", + "Europe/Astrakhan", + "Europe/Athens", + "Europe/Belfast", + "Europe/Belgrade", + "Europe/Berlin", + "Europe/Bratislava", + "Europe/Brussels", + "Europe/Bucharest", + "Europe/Budapest", + "Europe/Busingen", + "Europe/Chisinau", + "Europe/Copenhagen", + "Europe/Dublin", + "Europe/Gibraltar", + "Europe/Guernsey", + "Europe/Helsinki", + "Europe/Isle_of_Man", + "Europe/Istanbul", + "Europe/Jersey", + "Europe/Kaliningrad", + "Europe/Kiev", + "Europe/Kirov", + "Europe/Kyiv", + "Europe/Lisbon", + "Europe/Ljubljana", + "Europe/London", + "Europe/Luxembourg", + "Europe/Madrid", + "Europe/Malta", + "Europe/Mariehamn", + "Europe/Minsk", + "Europe/Monaco", + "Europe/Moscow", + "Europe/Nicosia", + "Europe/Oslo", + "Europe/Paris", + "Europe/Podgorica", + "Europe/Prague", + "Europe/Riga", + "Europe/Rome", + "Europe/Samara", + "Europe/San_Marino", + "Europe/Sarajevo", + "Europe/Saratov", + "Europe/Simferopol", + "Europe/Skopje", + "Europe/Sofia", + "Europe/Stockholm", + "Europe/Tallinn", + "Europe/Tirane", + "Europe/Tiraspol", + "Europe/Ulyanovsk", + "Europe/Uzhgorod", + "Europe/Vaduz", + "Europe/Vatican", + "Europe/Vienna", + "Europe/Vilnius", + "Europe/Volgograd", + "Europe/Warsaw", + "Europe/Zagreb", + "Europe/Zaporozhye", + "Europe/Zurich", + "GB", + "GB-Eire", + "GMT", + "GMT+0", + "GMT-0", + "GMT0", + "Greenwich", + "HST", + "Hongkong", + "Iceland", + "Indian/Antananarivo", + "Indian/Chagos", + "Indian/Christmas", + "Indian/Cocos", + "Indian/Comoro", + "Indian/Kerguelen", + "Indian/Mahe", + "Indian/Maldives", + "Indian/Mauritius", + "Indian/Mayotte", + "Indian/Reunion", + "Iran", + "Israel", + "Jamaica", + "Japan", + "Kwajalein", + "Libya", + "MET", + "MST", + "MST7MDT", + "Mexico/BajaNorte", + "Mexico/BajaSur", + "Mexico/General", + "NZ", + "NZ-CHAT", + "Navajo", + "PRC", + "PST8PDT", + "Pacific/Apia", + "Pacific/Auckland", + "Pacific/Bougainville", + "Pacific/Chatham", + "Pacific/Chuuk", + "Pacific/Easter", + "Pacific/Efate", + "Pacific/Enderbury", + "Pacific/Fakaofo", + "Pacific/Fiji", + "Pacific/Funafuti", + "Pacific/Galapagos", + "Pacific/Gambier", + "Pacific/Guadalcanal", + "Pacific/Guam", + "Pacific/Honolulu", + "Pacific/Johnston", + "Pacific/Kanton", + "Pacific/Kiritimati", + "Pacific/Kosrae", + "Pacific/Kwajalein", + "Pacific/Majuro", + "Pacific/Marquesas", + "Pacific/Midway", + "Pacific/Nauru", + "Pacific/Niue", + "Pacific/Norfolk", + "Pacific/Noumea", + "Pacific/Pago_Pago", + "Pacific/Palau", + "Pacific/Pitcairn", + "Pacific/Pohnpei", + "Pacific/Ponape", + "Pacific/Port_Moresby", + "Pacific/Rarotonga", + "Pacific/Saipan", + "Pacific/Samoa", + "Pacific/Tahiti", + "Pacific/Tarawa", + "Pacific/Tongatapu", + "Pacific/Truk", + "Pacific/Wake", + "Pacific/Wallis", + "Pacific/Yap", + "Poland", + "Portugal", + "ROC", + "ROK", + "Singapore", + "Turkey", + "UCT", + "US/Alaska", + "US/Aleutian", + "US/Arizona", + "US/Central", + "US/East-Indiana", + "US/Eastern", + "US/Hawaii", + "US/Indiana-Starke", + "US/Michigan", + "US/Mountain", + "US/Pacific", + "US/Samoa", + "UTC", + "Universal", + "W-SU", + "WET", + "Zulu" + ] +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/map.json b/deps/temporal/provider/src/data/debug/zoneinfo/map.json new file mode 100644 index 00000000000000..2cc52f05332bcf --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/map.json @@ -0,0 +1,600 @@ +{ + "africa/abidjan": "tzif-fe8583499fe1cbb8-a7cf0ef087069495.json", + "africa/accra": "tzif-fe8583499fe1cbb8-a7cf0ef087069495.json", + "africa/addis_ababa": "tzif-486e9282debc62a3-27805d7d5dee9be4.json", + "africa/algiers": "tzif-df3a174a6f1304b9-f30768cdd2518dd1.json", + "africa/asmara": "tzif-486e9282debc62a3-27805d7d5dee9be4.json", + "africa/asmera": "tzif-486e9282debc62a3-27805d7d5dee9be4.json", + "africa/bamako": "tzif-fe8583499fe1cbb8-a7cf0ef087069495.json", + "africa/bangui": "tzif-aba73c12b2e7f46-a62a02047cf0f8be.json", + "africa/banjul": "tzif-fe8583499fe1cbb8-a7cf0ef087069495.json", + "africa/bissau": "tzif-84569b5d12891e1e-dfbd7173ea59c56d.json", + "africa/blantyre": "tzif-14cdf6863a8e2179-b18612ad8b0eacc7.json", + "africa/brazzaville": "tzif-aba73c12b2e7f46-a62a02047cf0f8be.json", + "africa/bujumbura": "tzif-14cdf6863a8e2179-b18612ad8b0eacc7.json", + "africa/cairo": "tzif-f0d38f589f1464b7-e65390d2a42c7521.json", + "africa/casablanca": "tzif-70c6eef1cba9528e-fa6fd92ebfdcf3ad.json", + "africa/ceuta": "tzif-bd05cebe8eecfa2c-408891f6d5e0c72a.json", + "africa/conakry": "tzif-fe8583499fe1cbb8-a7cf0ef087069495.json", + "africa/dakar": "tzif-fe8583499fe1cbb8-a7cf0ef087069495.json", + "africa/dar_es_salaam": "tzif-486e9282debc62a3-27805d7d5dee9be4.json", + "africa/djibouti": "tzif-486e9282debc62a3-27805d7d5dee9be4.json", + "africa/douala": "tzif-aba73c12b2e7f46-a62a02047cf0f8be.json", + "africa/el_aaiun": "tzif-2b407bee2bf8cbea-39e72d1f00f10d06.json", + "africa/freetown": "tzif-fe8583499fe1cbb8-a7cf0ef087069495.json", + "africa/gaborone": "tzif-14cdf6863a8e2179-b18612ad8b0eacc7.json", + "africa/harare": "tzif-14cdf6863a8e2179-b18612ad8b0eacc7.json", + "africa/johannesburg": "tzif-59d5e08cb19672f5-73d8fe68d8bc0b47.json", + "africa/juba": "tzif-66fc406d3b90ff90-42d7c96cbf80d3ca.json", + "africa/kampala": "tzif-486e9282debc62a3-27805d7d5dee9be4.json", + "africa/khartoum": "tzif-25763d8b26764a7a-5933d51fd56b3fdf.json", + "africa/kigali": "tzif-14cdf6863a8e2179-b18612ad8b0eacc7.json", + "africa/kinshasa": "tzif-aba73c12b2e7f46-a62a02047cf0f8be.json", + "africa/lagos": "tzif-aba73c12b2e7f46-a62a02047cf0f8be.json", + "africa/libreville": "tzif-aba73c12b2e7f46-a62a02047cf0f8be.json", + "africa/lome": "tzif-fe8583499fe1cbb8-a7cf0ef087069495.json", + "africa/luanda": "tzif-aba73c12b2e7f46-a62a02047cf0f8be.json", + "africa/lubumbashi": "tzif-14cdf6863a8e2179-b18612ad8b0eacc7.json", + "africa/lusaka": "tzif-14cdf6863a8e2179-b18612ad8b0eacc7.json", + "africa/malabo": "tzif-aba73c12b2e7f46-a62a02047cf0f8be.json", + "africa/maputo": "tzif-14cdf6863a8e2179-b18612ad8b0eacc7.json", + "africa/maseru": "tzif-59d5e08cb19672f5-73d8fe68d8bc0b47.json", + "africa/mbabane": "tzif-59d5e08cb19672f5-73d8fe68d8bc0b47.json", + "africa/mogadishu": "tzif-486e9282debc62a3-27805d7d5dee9be4.json", + "africa/monrovia": "tzif-f842f34f4c14fee1-6af6c77813d81c95.json", + "africa/nairobi": "tzif-486e9282debc62a3-27805d7d5dee9be4.json", + "africa/ndjamena": "tzif-24b250ef0928a9e9-6530a4ca5485dc31.json", + "africa/niamey": "tzif-aba73c12b2e7f46-a62a02047cf0f8be.json", + "africa/nouakchott": "tzif-fe8583499fe1cbb8-a7cf0ef087069495.json", + "africa/ouagadougou": "tzif-fe8583499fe1cbb8-a7cf0ef087069495.json", + "africa/porto-novo": "tzif-aba73c12b2e7f46-a62a02047cf0f8be.json", + "africa/sao_tome": "tzif-7aa0aebc84b44c67-973b0b87d9034391.json", + "africa/timbuktu": "tzif-fe8583499fe1cbb8-a7cf0ef087069495.json", + "africa/tripoli": "tzif-81a0c2bb7c8a41da-7b4ebb9a4aa49253.json", + "africa/tunis": "tzif-19d0e567d48830e5-20b2a6d45202416.json", + "africa/windhoek": "tzif-99cdd052561a0879-89252b18a95154e3.json", + "america/adak": "tzif-2450804cbdb4245e-fc28955e4978e50d.json", + "america/anchorage": "tzif-d4999f54d6ffa1ff-bdc2dfc5a5de1f94.json", + "america/anguilla": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/antigua": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/araguaina": "tzif-75a476630c4f3c06-6cc92a5fc490dfa3.json", + "america/argentina/buenos_aires": "tzif-24bc4f701e560e8f-fbbcb1e6855b01a1.json", + "america/argentina/catamarca": "tzif-a2c4636cb2de823b-69641876de40969.json", + "america/argentina/comodrivadavia": "tzif-a2c4636cb2de823b-69641876de40969.json", + "america/argentina/cordoba": "tzif-83ab6f3e7a54b242-140e172ea09b920.json", + "america/argentina/jujuy": "tzif-c0a7b3c45458ac17-adf27c3e51a11cf6.json", + "america/argentina/la_rioja": "tzif-c7a9617c25e2eb1a-67a9e52b4fa102af.json", + "america/argentina/mendoza": "tzif-fd03910821368f68-fa54b0ea0f2a14a7.json", + "america/argentina/rio_gallegos": "tzif-edc11c9a67454353-7a49fa82cac12758.json", + "america/argentina/salta": "tzif-26ac36da2732c840-dedd53591694d48d.json", + "america/argentina/san_juan": "tzif-f5b99738d99ddd8c-edf53ab20b57f392.json", + "america/argentina/san_luis": "tzif-a3bbf95d113466c0-366de44a51a62cbe.json", + "america/argentina/tucuman": "tzif-715448d734f9507a-f4183ed224275281.json", + "america/argentina/ushuaia": "tzif-380c01b13aae6590-113f60eeecce7355.json", + "america/aruba": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/asuncion": "tzif-9bd926151a997a3e-9909ffff90c3207.json", + "america/atikokan": "tzif-6fbdbfed85292c81-468d78f0fb8a53ac.json", + "america/atka": "tzif-2450804cbdb4245e-fc28955e4978e50d.json", + "america/bahia": "tzif-a442eead4fdb53a5-264d7185508cac7f.json", + "america/bahia_banderas": "tzif-ef074bbbac9f5764-af06bb8dad04fbb2.json", + "america/barbados": "tzif-5060a985014097b1-2e0f3c6f560795ff.json", + "america/belem": "tzif-93ba37d78a84866e-364c3b71717bb302.json", + "america/belize": "tzif-b9b18c55e2cd4d53-b3d917ee40af164d.json", + "america/blanc-sablon": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/boa_vista": "tzif-e12ae166d8468131-ee348999c2fd8345.json", + "america/bogota": "tzif-e20ebf54a807fe0e-10ef646904348bbe.json", + "america/boise": "tzif-70408e1d981309b7-da99eb025c30159.json", + "america/buenos_aires": "tzif-24bc4f701e560e8f-fbbcb1e6855b01a1.json", + "america/cambridge_bay": "tzif-3cc8439b3e85f059-8e4f59b418f8888a.json", + "america/campo_grande": "tzif-f677bd8d940386cc-6f4acf146c31eb70.json", + "america/cancun": "tzif-6fbdea510dc8bdff-a0d6c86f83720461.json", + "america/caracas": "tzif-4529e4629acf0366-8106ebfc9606aee2.json", + "america/catamarca": "tzif-a2c4636cb2de823b-69641876de40969.json", + "america/cayenne": "tzif-c3aa55f145295944-50f38632c531aab8.json", + "america/cayman": "tzif-6fbdbfed85292c81-468d78f0fb8a53ac.json", + "america/chicago": "tzif-3a5a827f28d118e9-682e0a2d838b16ae.json", + "america/chihuahua": "tzif-a685965c91f5b79b-e66cc1c813ce5bd6.json", + "america/ciudad_juarez": "tzif-2c1bb7953877feff-4c66e005cbf579fe.json", + "america/coral_harbour": "tzif-6fbdbfed85292c81-468d78f0fb8a53ac.json", + "america/cordoba": "tzif-83ab6f3e7a54b242-140e172ea09b920.json", + "america/costa_rica": "tzif-bdd491f43b0c1c85-6f9616d7048f0cf9.json", + "america/coyhaique": "tzif-eb9179abb91c8435-726489ced5139013.json", + "america/creston": "tzif-a3214de8e358efe8-33b7f8f888f95c0b.json", + "america/cuiaba": "tzif-be9bc4833f21d33b-2a54484e254d46c8.json", + "america/curacao": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/danmarkshavn": "tzif-7776a42ce751a29e-1629f5ee8a6e924e.json", + "america/dawson": "tzif-1eff85dd787ed3a1-d74f97871f7e97e8.json", + "america/dawson_creek": "tzif-1a285e17b7751f38-aefc034b499da29b.json", + "america/denver": "tzif-50fc3fea132b4f4c-5a5d88ba8de3b7c1.json", + "america/detroit": "tzif-f8baa073f0e62ab0-5c9c06226b1920d5.json", + "america/dominica": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/edmonton": "tzif-3a6fecb09c143b25-73487cfbfb37a1d6.json", + "america/eirunepe": "tzif-b785c09bc525b515-5fd6146854daeb91.json", + "america/el_salvador": "tzif-425a92f6316d948f-f81669d6e3b37009.json", + "america/ensenada": "tzif-3fc16258c94fd1bd-f5865999bedfb5cb.json", + "america/fort_nelson": "tzif-4891d41993ed3f5f-4d0c2933ef920fb1.json", + "america/fort_wayne": "tzif-754b9e4bdb20aa95-1c5b7a1b811c5ae3.json", + "america/fortaleza": "tzif-3567a65ce3b07b4a-eda38ce2d13af268.json", + "america/glace_bay": "tzif-55bb5ee9b0a529a6-dce97bdbcf437150.json", + "america/godthab": "tzif-5e245c7be541fe52-ac13030bf2bc388c.json", + "america/goose_bay": "tzif-ffd87e4e007fc8e2-442f240405f9b3e2.json", + "america/grand_turk": "tzif-cec2538008230fcd-486e4621268a0834.json", + "america/grenada": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/guadeloupe": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/guatemala": "tzif-a187ee64c8fae572-4985eb67780f1dca.json", + "america/guayaquil": "tzif-dd90c0bd2a5d5bcb-4e3fcc5e29cf94e2.json", + "america/guyana": "tzif-38d88ef47726082c-a2b861350ff9abaf.json", + "america/halifax": "tzif-ca31f6cb7d44b091-6a023a6a71d41a7.json", + "america/havana": "tzif-d28e0bb7485a8522-9d5ad01d4999d0c7.json", + "america/hermosillo": "tzif-69530af9af6cd0cb-6e2e37393c7f8e5d.json", + "america/indiana/indianapolis": "tzif-754b9e4bdb20aa95-1c5b7a1b811c5ae3.json", + "america/indiana/knox": "tzif-fc9fd017e19a24e0-530492ba8305e348.json", + "america/indiana/marengo": "tzif-1146d998a660d8a7-7083368cf5416b3.json", + "america/indiana/petersburg": "tzif-26aecc98f9d83045-d767019b239f072.json", + "america/indiana/tell_city": "tzif-bbfc9e9111217c11-69684e27be4c3e38.json", + "america/indiana/vevay": "tzif-be7c1ce9358259b9-87fdd35d13d52495.json", + "america/indiana/vincennes": "tzif-f7b886dc80987d1f-1cfc3c180fd77cd3.json", + "america/indiana/winamac": "tzif-8494d6017f05e49d-6fa1752d1f7aa8c3.json", + "america/indianapolis": "tzif-754b9e4bdb20aa95-1c5b7a1b811c5ae3.json", + "america/inuvik": "tzif-9b4491a5a7233cc3-9416dbeeb6810774.json", + "america/iqaluit": "tzif-1dd142eb22754e92-d3cee37600e3912e.json", + "america/jamaica": "tzif-98fb8731f72daeb6-4585fdc50640db42.json", + "america/jujuy": "tzif-c0a7b3c45458ac17-adf27c3e51a11cf6.json", + "america/juneau": "tzif-8fec2819cc677405-6cfb65330c2f1fa0.json", + "america/kentucky/louisville": "tzif-7599edfd11a3db64-4bf8d694826715ae.json", + "america/kentucky/monticello": "tzif-f87d2aa5dfe5efe9-6f6f56db37ced2fd.json", + "america/knox_in": "tzif-fc9fd017e19a24e0-530492ba8305e348.json", + "america/kralendijk": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/la_paz": "tzif-66a5515c6139ad2d-8cdcb912670ca415.json", + "america/lima": "tzif-fe6e0efb644eced9-f06be10a091cfb41.json", + "america/los_angeles": "tzif-effb0bd5efab2bad-76ee3ca040667987.json", + "america/louisville": "tzif-7599edfd11a3db64-4bf8d694826715ae.json", + "america/lower_princes": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/maceio": "tzif-206d649fad594120-70deb0fb976b18e.json", + "america/managua": "tzif-fbccf04b5b2fd7f2-b508b8cbe01e354b.json", + "america/manaus": "tzif-8b129baceef3898a-389e46393fa915f2.json", + "america/marigot": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/martinique": "tzif-f757031187208623-b42f12ebe4b7bfcb.json", + "america/matamoros": "tzif-be07532f1af7dccb-7a89363e76463570.json", + "america/mazatlan": "tzif-40fb52b19ef81b1d-e1ce3cc4e0a17886.json", + "america/mendoza": "tzif-fd03910821368f68-fa54b0ea0f2a14a7.json", + "america/menominee": "tzif-46dd3b15bf889536-90c51dda0af69c0c.json", + "america/merida": "tzif-3d390ef79718594a-1d54abd9de1f791b.json", + "america/metlakatla": "tzif-5d69c15d2c4f26ae-d843083a2b2d2784.json", + "america/mexico_city": "tzif-95eb641ddc74061f-5a914528a766049d.json", + "america/miquelon": "tzif-ffb42884e83683a9-7d164a9bb116efe3.json", + "america/moncton": "tzif-aa6fbecd6b3089a1-3c3e5535078a0aca.json", + "america/monterrey": "tzif-3234542952508833-776aeadf2e17fcb4.json", + "america/montevideo": "tzif-bda89ec29d33a428-f6c6f1d38129c153.json", + "america/montreal": "tzif-ed29bf9f15004c8a-f6def5db1514383c.json", + "america/montserrat": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/nassau": "tzif-ed29bf9f15004c8a-f6def5db1514383c.json", + "america/new_york": "tzif-3994d21beae7c7b6-eb145d056159d80.json", + "america/nipigon": "tzif-ed29bf9f15004c8a-f6def5db1514383c.json", + "america/nome": "tzif-480b0a55dd7bf29e-c23b37ed84c4f8f9.json", + "america/noronha": "tzif-c17291eb667fe274-81f01d3c395654a6.json", + "america/north_dakota/beulah": "tzif-f5114ea1ad21a447-657f9c7873c390b2.json", + "america/north_dakota/center": "tzif-c4897a4741bd9e82-aaea1d16ea0a4fb8.json", + "america/north_dakota/new_salem": "tzif-239c7722f428fac8-7a4c4b125895f0bd.json", + "america/nuuk": "tzif-5e245c7be541fe52-ac13030bf2bc388c.json", + "america/ojinaga": "tzif-7ba4aaa7dba09bb0-567af4b250c89d25.json", + "america/panama": "tzif-6fbdbfed85292c81-468d78f0fb8a53ac.json", + "america/pangnirtung": "tzif-1dd142eb22754e92-d3cee37600e3912e.json", + "america/paramaribo": "tzif-2a9b3a635fc27340-e824f8940a7a64f6.json", + "america/phoenix": "tzif-a3214de8e358efe8-33b7f8f888f95c0b.json", + "america/port-au-prince": "tzif-273d77751416ce66-188ad35538918cca.json", + "america/port_of_spain": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/porto_acre": "tzif-90e0499f7b80422b-16e03eeaaf192844.json", + "america/porto_velho": "tzif-609a1c759abb0f9e-a202ec7708c700d8.json", + "america/puerto_rico": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/punta_arenas": "tzif-7d7635957a94c158-89410cc4ecfceda2.json", + "america/rainy_river": "tzif-bad7f01dd3f01a92-8ed1d7da904b667d.json", + "america/rankin_inlet": "tzif-12ced9fe919d8b6-35fe81809b640977.json", + "america/recife": "tzif-7481a99701104a1c-da931bd1c7d61a9.json", + "america/regina": "tzif-f61469e5df5071ba-1d93153e2c1ef413.json", + "america/resolute": "tzif-87ef4dab5f3e3941-c43fb003c147a77.json", + "america/rio_branco": "tzif-90e0499f7b80422b-16e03eeaaf192844.json", + "america/rosario": "tzif-83ab6f3e7a54b242-140e172ea09b920.json", + "america/santa_isabel": "tzif-3fc16258c94fd1bd-f5865999bedfb5cb.json", + "america/santarem": "tzif-8e605032c3ce6342-6a27beeec5d94fef.json", + "america/santiago": "tzif-ce802c28d3beb1b-5157362aadd9dd29.json", + "america/santo_domingo": "tzif-ffd87968a303e340-9dec629c1fbdf2dc.json", + "america/sao_paulo": "tzif-dc8ea6d022a7ebec-7bdcff969a6b651c.json", + "america/scoresbysund": "tzif-806417e5a9e6e27a-d183a9f9e82d72df.json", + "america/shiprock": "tzif-50fc3fea132b4f4c-5a5d88ba8de3b7c1.json", + "america/sitka": "tzif-768158f1c3d3089e-e43bac17424df347.json", + "america/st_barthelemy": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/st_johns": "tzif-916c7f697e6af49e-cd5f0c23c53bde30.json", + "america/st_kitts": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/st_lucia": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/st_thomas": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/st_vincent": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/swift_current": "tzif-3d5473248adfd22d-72a86f7189e4c492.json", + "america/tegucigalpa": "tzif-e5822ac52a06a527-c5e561a56943464c.json", + "america/thule": "tzif-99ce61a08c1199af-56326eb4ceecfd35.json", + "america/thunder_bay": "tzif-ed29bf9f15004c8a-f6def5db1514383c.json", + "america/tijuana": "tzif-3fc16258c94fd1bd-f5865999bedfb5cb.json", + "america/toronto": "tzif-ed29bf9f15004c8a-f6def5db1514383c.json", + "america/tortola": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/vancouver": "tzif-43c01a519dcad360-c978a2de09220f3e.json", + "america/virgin": "tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json", + "america/whitehorse": "tzif-87649f3d059a10f2-a8c51b0e84c40a85.json", + "america/winnipeg": "tzif-bad7f01dd3f01a92-8ed1d7da904b667d.json", + "america/yakutat": "tzif-33db81d7f03c072e-e083980d979c0926.json", + "america/yellowknife": "tzif-3a6fecb09c143b25-73487cfbfb37a1d6.json", + "antarctica/casey": "tzif-e65fa49c7674041-51ba19ae72a3c69.json", + "antarctica/davis": "tzif-f2238fc53b0fff96-6f6aee2b55131405.json", + "antarctica/dumontdurville": "tzif-1ede513c242ae08-561006205b46a9e7.json", + "antarctica/macquarie": "tzif-f9736e8dcd3eb5de-9c17b925c6652d48.json", + "antarctica/mawson": "tzif-fd823ec71e5980ce-fb04074f1843d568.json", + "antarctica/mcmurdo": "tzif-1939cc3520b8dae8-a2fd6733973f8da2.json", + "antarctica/palmer": "tzif-f1f0b3541047bfad-8176e7d9a57a1316.json", + "antarctica/rothera": "tzif-dfcaab41c352fc41-836527ef6425759.json", + "antarctica/south_pole": "tzif-1939cc3520b8dae8-a2fd6733973f8da2.json", + "antarctica/syowa": "tzif-f58f911ab743ef1d-f57255d26abdda48.json", + "antarctica/troll": "tzif-e330917831501a06-5b1f8ec8b0ab9c4a.json", + "antarctica/vostok": "tzif-e3d5b2baffd22f2d-4e475abbb4b8264f.json", + "arctic/longyearbyen": "tzif-4a65bbe3253254a1-2a20d46c4d15c0c3.json", + "asia/aden": "tzif-f58f911ab743ef1d-f57255d26abdda48.json", + "asia/almaty": "tzif-a053c1334aeab356-645c110894da15be.json", + "asia/amman": "tzif-748e0c2c22be393e-9159f30a64f07d32.json", + "asia/anadyr": "tzif-d41aa71f743154ff-cd47b010d657ac37.json", + "asia/aqtau": "tzif-f1b7ca6dc4d0b2b0-d827a5cc52d17740.json", + "asia/aqtobe": "tzif-4f0ad1968e2955-b99def3a9c716c7f.json", + "asia/ashgabat": "tzif-f26b875165969e75-9e25992ccdfbaa1f.json", + "asia/ashkhabad": "tzif-f26b875165969e75-9e25992ccdfbaa1f.json", + "asia/atyrau": "tzif-5a8de8f20b18b43-384f712f565d0ab0.json", + "asia/baghdad": "tzif-7241c1457aae4357-3c4783fc5e291a5.json", + "asia/bahrain": "tzif-bdc0a1977c311c8d-87860ab499ecadb8.json", + "asia/baku": "tzif-fef149820a82a100-d2fff4282c3ad1f4.json", + "asia/bangkok": "tzif-2a7fc944a4c2991b-ed19eb01bbf45250.json", + "asia/barnaul": "tzif-ff54b8a04d630c85-302a593cf4d0c55a.json", + "asia/beirut": "tzif-5890af4975eb815-dbcd9d0a6fe5353.json", + "asia/bishkek": "tzif-f229cb4cd552c448-1e8f29f5b7bc6659.json", + "asia/brunei": "tzif-283cf30fce0ee58e-ee056ab931c35019.json", + "asia/calcutta": "tzif-bd9ad03026ed086f-3d5a919e98fa2787.json", + "asia/chita": "tzif-36890fddb7a9031e-81d4ff9e4c89f2e8.json", + "asia/choibalsan": "tzif-cbf2a88472b0862a-de6f37d8951e33ce.json", + "asia/chongqing": "tzif-94731e7a96e16727-b9bdd49f2158b98c.json", + "asia/chungking": "tzif-94731e7a96e16727-b9bdd49f2158b98c.json", + "asia/colombo": "tzif-996739b4c558f747-935dbc63456811c2.json", + "asia/dacca": "tzif-8bf0f826f4c6e05e-9c27d3058e34d93b.json", + "asia/damascus": "tzif-52291e736a34e36b-2ab58b9a9f408e39.json", + "asia/dhaka": "tzif-8bf0f826f4c6e05e-9c27d3058e34d93b.json", + "asia/dili": "tzif-7cca7c8a1af35285-679fdca550b074a0.json", + "asia/dubai": "tzif-7459e3ffacdde5a6-a596288a1fff51a3.json", + "asia/dushanbe": "tzif-7a158f0aed162547-27577cc8813fb4ed.json", + "asia/famagusta": "tzif-74fc38128e80b92d-871756115f3d1b05.json", + "asia/gaza": "tzif-3f61f7ebb7b0f5d7-3b9e017c8df909f8.json", + "asia/harbin": "tzif-94731e7a96e16727-b9bdd49f2158b98c.json", + "asia/hebron": "tzif-cbcf966225780b1c-8a7f4b3e40c1b2d5.json", + "asia/ho_chi_minh": "tzif-c79f46dbe8103377-6f330e5ab7f7dc8e.json", + "asia/hong_kong": "tzif-ea8173f82f8dccac-190f07fa0585582b.json", + "asia/hovd": "tzif-65badfa9c283e8d3-9bc658cd314193fd.json", + "asia/irkutsk": "tzif-6156cfed77f2a26c-d5c8e957d52b5aa1.json", + "asia/istanbul": "tzif-21007d26526b6cee-4c7defff421754b5.json", + "asia/jakarta": "tzif-e271b0f2662b1c04-20e8607792da4ec7.json", + "asia/jayapura": "tzif-b05b7d10c5ffdad-d39eb7f9fe146506.json", + "asia/jerusalem": "tzif-758d7fde6833ba8c-65256d0857a2f636.json", + "asia/kabul": "tzif-cb2104a4192b82ba-ddba0d84d8ea7d92.json", + "asia/kamchatka": "tzif-eafa00d1ad3ada02-ccfdff510d06498a.json", + "asia/karachi": "tzif-fb66f3417dbb2dfe-e13d26a5a5a0ef65.json", + "asia/kashgar": "tzif-79a67056f030a883-f33ddefe3e35e4d0.json", + "asia/kathmandu": "tzif-6d168cde30b3c19-24342dd0af895908.json", + "asia/katmandu": "tzif-6d168cde30b3c19-24342dd0af895908.json", + "asia/khandyga": "tzif-d3201ec4e70c92f3-5814e30a4cc908b9.json", + "asia/kolkata": "tzif-bd9ad03026ed086f-3d5a919e98fa2787.json", + "asia/krasnoyarsk": "tzif-b0c86e4e28bb1810-bccad26ea4f4cee2.json", + "asia/kuala_lumpur": "tzif-fc89b67bba9eff21-ed937c5b2210118e.json", + "asia/kuching": "tzif-283cf30fce0ee58e-ee056ab931c35019.json", + "asia/kuwait": "tzif-f58f911ab743ef1d-f57255d26abdda48.json", + "asia/macao": "tzif-b6ba868b587cad06-6667a264db5d890e.json", + "asia/macau": "tzif-b6ba868b587cad06-6667a264db5d890e.json", + "asia/magadan": "tzif-7be16635ecf890b5-161efc0ab3ac2299.json", + "asia/makassar": "tzif-89cd9f4224d1324a-6ddbd3de8874993f.json", + "asia/manila": "tzif-405b02408f1a7725-3c0ae0a258a25979.json", + "asia/muscat": "tzif-7459e3ffacdde5a6-a596288a1fff51a3.json", + "asia/nicosia": "tzif-37762e44a2edd792-4f1b10d181e56a5d.json", + "asia/novokuznetsk": "tzif-291cff29f8a99dfe-401473cfba65f82d.json", + "asia/novosibirsk": "tzif-98fc8236fccd3576-88ddb973d46096e3.json", + "asia/omsk": "tzif-86245dd795582456-61d8c9f7c4ad177a.json", + "asia/oral": "tzif-4c9c946292d76a04-7fbd1484596ee05e.json", + "asia/phnom_penh": "tzif-2a7fc944a4c2991b-ed19eb01bbf45250.json", + "asia/pontianak": "tzif-cb56ff55ea32bb92-c654a08c059dae2e.json", + "asia/pyongyang": "tzif-6268b48b2e959066-91294d0f7013ba84.json", + "asia/qatar": "tzif-bdc0a1977c311c8d-87860ab499ecadb8.json", + "asia/qostanay": "tzif-b9d3679a03af6191-99d89d33c8fd0b60.json", + "asia/qyzylorda": "tzif-622cbc57a076ea5d-616edf8039af4f62.json", + "asia/rangoon": "tzif-50abe32c287395c8-d2c3aa5882246ab2.json", + "asia/riyadh": "tzif-f58f911ab743ef1d-f57255d26abdda48.json", + "asia/saigon": "tzif-c79f46dbe8103377-6f330e5ab7f7dc8e.json", + "asia/sakhalin": "tzif-9a2f8cce797280e8-37784cc07103f2f3.json", + "asia/samarkand": "tzif-55ec396d83237537-39a492626467027.json", + "asia/seoul": "tzif-b89f6da72122ca01-812d173fdcfeaaa6.json", + "asia/shanghai": "tzif-94731e7a96e16727-b9bdd49f2158b98c.json", + "asia/singapore": "tzif-fc89b67bba9eff21-ed937c5b2210118e.json", + "asia/srednekolymsk": "tzif-843bd4f4a13e936f-e20d11612a15d3e6.json", + "asia/taipei": "tzif-ee42b17151e8d0d1-557c16a705ea23d1.json", + "asia/tashkent": "tzif-c841f0aca0404a73-5f8447c455db7736.json", + "asia/tbilisi": "tzif-4738bf3d72913a1b-ef164d685fcac290.json", + "asia/tehran": "tzif-650685fe5c95ce2a-2f3eb2e60291229d.json", + "asia/tel_aviv": "tzif-758d7fde6833ba8c-65256d0857a2f636.json", + "asia/thimbu": "tzif-762fa57e245bdc0d-c5a018de141b4cb3.json", + "asia/thimphu": "tzif-762fa57e245bdc0d-c5a018de141b4cb3.json", + "asia/tokyo": "tzif-7bce416a66d38e42-b58b08c4c731f7dc.json", + "asia/tomsk": "tzif-4db2cfd1785db9cd-6589edd5db80b603.json", + "asia/ujung_pandang": "tzif-89cd9f4224d1324a-6ddbd3de8874993f.json", + "asia/ulaanbaatar": "tzif-cbf2a88472b0862a-de6f37d8951e33ce.json", + "asia/ulan_bator": "tzif-cbf2a88472b0862a-de6f37d8951e33ce.json", + "asia/urumqi": "tzif-79a67056f030a883-f33ddefe3e35e4d0.json", + "asia/ust-nera": "tzif-8b944106b8f9db7e-1d2f4ecd91296f4.json", + "asia/vientiane": "tzif-2a7fc944a4c2991b-ed19eb01bbf45250.json", + "asia/vladivostok": "tzif-3fd85b535272f921-d61e3c0d217e3de2.json", + "asia/yakutsk": "tzif-3f6ff680ea89333b-f07f1041c6be937.json", + "asia/yangon": "tzif-50abe32c287395c8-d2c3aa5882246ab2.json", + "asia/yekaterinburg": "tzif-849b49f0ce1dac82-89b53710eb7d9371.json", + "asia/yerevan": "tzif-f9878deac6fa797b-63a1fb86a70f62e5.json", + "atlantic/azores": "tzif-c306ac2cd34a373c-ec50d5ecafac2084.json", + "atlantic/bermuda": "tzif-6a52098e032992a5-e1eb00358541c6a0.json", + "atlantic/canary": "tzif-a7b726e2144b8ec3-b273ddcc47da034b.json", + "atlantic/cape_verde": "tzif-55eedcdc6ff1f85-5b27bba1cde1354f.json", + "atlantic/faeroe": "tzif-67d3e39540d85c91-f13f9d0367c68c92.json", + "atlantic/faroe": "tzif-67d3e39540d85c91-f13f9d0367c68c92.json", + "atlantic/jan_mayen": "tzif-4a65bbe3253254a1-2a20d46c4d15c0c3.json", + "atlantic/madeira": "tzif-a44c115ed3d72421-692eaf79ab1934a7.json", + "atlantic/reykjavik": "tzif-fe8583499fe1cbb8-a7cf0ef087069495.json", + "atlantic/south_georgia": "tzif-9d02412abb136ce4-bfde68530f93fb26.json", + "atlantic/st_helena": "tzif-fe8583499fe1cbb8-a7cf0ef087069495.json", + "atlantic/stanley": "tzif-4eaf76405b17e0d3-64c6a9f0471d4ce9.json", + "australia/act": "tzif-ef99169dd5b3d431-ae45f4711dd0d14b.json", + "australia/adelaide": "tzif-cab5fb5bf9e7625f-4aaae2f823b6e6c9.json", + "australia/brisbane": "tzif-44b31bf3438167a2-f26149998b62ea48.json", + "australia/broken_hill": "tzif-9af11812af42f7cb-8d70b106abb9243f.json", + "australia/canberra": "tzif-ef99169dd5b3d431-ae45f4711dd0d14b.json", + "australia/currie": "tzif-9c98c8b92084c36-47e6455e977d6bb3.json", + "australia/darwin": "tzif-794b5729aca99b8f-8dcbb73848fb52db.json", + "australia/eucla": "tzif-2a2176981e284105-59c6fda81a2a226c.json", + "australia/hobart": "tzif-9c98c8b92084c36-47e6455e977d6bb3.json", + "australia/lhi": "tzif-e2789756bce07cca-d7ab71c2384db975.json", + "australia/lindeman": "tzif-eb4384db15894d16-b0aaeb08a0cbe1e0.json", + "australia/lord_howe": "tzif-e2789756bce07cca-d7ab71c2384db975.json", + "australia/melbourne": "tzif-401f78ac94f3eb66-89897df479278829.json", + "australia/north": "tzif-794b5729aca99b8f-8dcbb73848fb52db.json", + "australia/nsw": "tzif-ef99169dd5b3d431-ae45f4711dd0d14b.json", + "australia/perth": "tzif-c595527c9472a8dc-da82dc08bd3d58a0.json", + "australia/queensland": "tzif-44b31bf3438167a2-f26149998b62ea48.json", + "australia/south": "tzif-cab5fb5bf9e7625f-4aaae2f823b6e6c9.json", + "australia/sydney": "tzif-ef99169dd5b3d431-ae45f4711dd0d14b.json", + "australia/tasmania": "tzif-9c98c8b92084c36-47e6455e977d6bb3.json", + "australia/victoria": "tzif-401f78ac94f3eb66-89897df479278829.json", + "australia/west": "tzif-c595527c9472a8dc-da82dc08bd3d58a0.json", + "australia/yancowinna": "tzif-9af11812af42f7cb-8d70b106abb9243f.json", + "brazil/acre": "tzif-90e0499f7b80422b-16e03eeaaf192844.json", + "brazil/denoronha": "tzif-c17291eb667fe274-81f01d3c395654a6.json", + "brazil/east": "tzif-dc8ea6d022a7ebec-7bdcff969a6b651c.json", + "brazil/west": "tzif-8b129baceef3898a-389e46393fa915f2.json", + "canada/atlantic": "tzif-ca31f6cb7d44b091-6a023a6a71d41a7.json", + "canada/central": "tzif-bad7f01dd3f01a92-8ed1d7da904b667d.json", + "canada/eastern": "tzif-ed29bf9f15004c8a-f6def5db1514383c.json", + "canada/mountain": "tzif-3a6fecb09c143b25-73487cfbfb37a1d6.json", + "canada/newfoundland": "tzif-916c7f697e6af49e-cd5f0c23c53bde30.json", + "canada/pacific": "tzif-43c01a519dcad360-c978a2de09220f3e.json", + "canada/saskatchewan": "tzif-f61469e5df5071ba-1d93153e2c1ef413.json", + "canada/yukon": "tzif-87649f3d059a10f2-a8c51b0e84c40a85.json", + "cet": "tzif-6415eb3f74777957-6f718f12281286a3.json", + "chile/continental": "tzif-ce802c28d3beb1b-5157362aadd9dd29.json", + "chile/easterisland": "tzif-daeed2898ecd770c-894d1d81ca85ba4d.json", + "cst6cdt": "tzif-3a5a827f28d118e9-682e0a2d838b16ae.json", + "cuba": "tzif-d28e0bb7485a8522-9d5ad01d4999d0c7.json", + "eet": "tzif-f665c39691dff65-eb8beb46e71e4a05.json", + "egypt": "tzif-f0d38f589f1464b7-e65390d2a42c7521.json", + "eire": "tzif-96a7050f6c4d3e34-7cc5980522f3fef5.json", + "est": "tzif-6fbdbfed85292c81-468d78f0fb8a53ac.json", + "est5edt": "tzif-3994d21beae7c7b6-eb145d056159d80.json", + "etc/gmt": "tzif-42518274487a5d74-63fffb5b4ef7fbd9.json", + "etc/gmt+0": "tzif-42518274487a5d74-63fffb5b4ef7fbd9.json", + "etc/gmt+1": "tzif-3c8506b1fc96536c-4c88dd0e00eba4f2.json", + "etc/gmt+10": "tzif-c83537c4365f1258-7426b2a60504f417.json", + "etc/gmt+11": "tzif-bbf3217ce334c3f2-5622ec9ecf81c925.json", + "etc/gmt+12": "tzif-e2bf7ec87041f1fb-b61a215ea3b5adb3.json", + "etc/gmt+2": "tzif-2d819a70236c9f86-721e9b57fc17e8df.json", + "etc/gmt+3": "tzif-fed5f41e1701789d-daf8820af0fe9430.json", + "etc/gmt+4": "tzif-d1e4208290566f2f-8b7418c65c288188.json", + "etc/gmt+5": "tzif-a0806703e39bd41f-938b549d3f658065.json", + "etc/gmt+6": "tzif-9afb6f21d74a3dbd-d76c18d684813924.json", + "etc/gmt+7": "tzif-aeaa8db63bed649c-8a6f5505498821c5.json", + "etc/gmt+8": "tzif-f80d3a6707532038-3bae731e777368b6.json", + "etc/gmt+9": "tzif-2a554d4e97833d6e-1eb5fb8bf2c9f728.json", + "etc/gmt-0": "tzif-42518274487a5d74-63fffb5b4ef7fbd9.json", + "etc/gmt-1": "tzif-b397eb337d51aec5-9d2674bc81a95add.json", + "etc/gmt-10": "tzif-c6ecc61594d93097-34f668d36b185b09.json", + "etc/gmt-11": "tzif-170cb25ac2daddf1-c28442df6aeaf807.json", + "etc/gmt-12": "tzif-b445d8dfee87de1d-3d26ba9d3df071ac.json", + "etc/gmt-13": "tzif-186e2b651b9e98be-423bebc6a1739dc2.json", + "etc/gmt-14": "tzif-f6698c0e9f2fa661-cfcf92aaf6d6e5be.json", + "etc/gmt-2": "tzif-cd29e561a284f373-1b38f7643a89adc3.json", + "etc/gmt-3": "tzif-11b63f0f95d852ce-9769280653fbbbb1.json", + "etc/gmt-4": "tzif-c7d151e4111f596b-82465a65ac1b9a8e.json", + "etc/gmt-5": "tzif-3cc59865618b9844-e109dc95307db988.json", + "etc/gmt-6": "tzif-65401a13577707c6-bb9f9264b43c1451.json", + "etc/gmt-7": "tzif-4e52d8a7b9ecde7e-b7f50a3a0d1ac3b5.json", + "etc/gmt-8": "tzif-2bd99bb6843e89cf-932580fc9a3a0c8d.json", + "etc/gmt-9": "tzif-14ec5a4ae9e7e087-d5eb6128c4e9c616.json", + "etc/gmt0": "tzif-42518274487a5d74-63fffb5b4ef7fbd9.json", + "etc/greenwich": "tzif-42518274487a5d74-63fffb5b4ef7fbd9.json", + "etc/uct": "tzif-5eec9cd299aa076f-857603deebbce60b.json", + "etc/universal": "tzif-5eec9cd299aa076f-857603deebbce60b.json", + "etc/utc": "tzif-5eec9cd299aa076f-857603deebbce60b.json", + "etc/zulu": "tzif-5eec9cd299aa076f-857603deebbce60b.json", + "europe/amsterdam": "tzif-6415eb3f74777957-6f718f12281286a3.json", + "europe/andorra": "tzif-26bf0cacd24f77a1-a98e0c85e152f06e.json", + "europe/astrakhan": "tzif-5fd210f528e95871-c650f43dd3590090.json", + "europe/athens": "tzif-f665c39691dff65-eb8beb46e71e4a05.json", + "europe/belfast": "tzif-6bfb62f5e4b63e4a-5a7d3b172eb114d5.json", + "europe/belgrade": "tzif-a1b14d47c3da0459-9beeb6b09fc4bd85.json", + "europe/berlin": "tzif-4a65bbe3253254a1-2a20d46c4d15c0c3.json", + "europe/bratislava": "tzif-6d3285599a38ae5a-e146c246881dc5ed.json", + "europe/brussels": "tzif-6415eb3f74777957-6f718f12281286a3.json", + "europe/bucharest": "tzif-b06ac7e52f27518c-ad815076903a307.json", + "europe/budapest": "tzif-1041cd53332eeba8-60aa3eb45cf6bad9.json", + "europe/busingen": "tzif-5cb26c449b2278f2-a3a1b3aa09d53c07.json", + "europe/chisinau": "tzif-7622c5c99b380b37-74a373c9f92241c7.json", + "europe/copenhagen": "tzif-4a65bbe3253254a1-2a20d46c4d15c0c3.json", + "europe/dublin": "tzif-96a7050f6c4d3e34-7cc5980522f3fef5.json", + "europe/gibraltar": "tzif-34047004b336df3e-bbe8e4196294f00a.json", + "europe/guernsey": "tzif-6bfb62f5e4b63e4a-5a7d3b172eb114d5.json", + "europe/helsinki": "tzif-4ccce3697974db1-dd90a8482c7e02e0.json", + "europe/isle_of_man": "tzif-6bfb62f5e4b63e4a-5a7d3b172eb114d5.json", + "europe/istanbul": "tzif-21007d26526b6cee-4c7defff421754b5.json", + "europe/jersey": "tzif-6bfb62f5e4b63e4a-5a7d3b172eb114d5.json", + "europe/kaliningrad": "tzif-dc6b1be48367c4f1-5f1fbe94f0718a6a.json", + "europe/kiev": "tzif-4ab862d6d4b98ff4-7628975aa4bf631a.json", + "europe/kirov": "tzif-1735ba0bbd2e57f5-8adc7347030fce3f.json", + "europe/kyiv": "tzif-4ab862d6d4b98ff4-7628975aa4bf631a.json", + "europe/lisbon": "tzif-e953d2a73bc41375-ef97956cf6178835.json", + "europe/ljubljana": "tzif-a1b14d47c3da0459-9beeb6b09fc4bd85.json", + "europe/london": "tzif-6bfb62f5e4b63e4a-5a7d3b172eb114d5.json", + "europe/luxembourg": "tzif-6415eb3f74777957-6f718f12281286a3.json", + "europe/madrid": "tzif-7d33da447360d55c-52583d8c13b6f677.json", + "europe/malta": "tzif-638a1ae9aef4e05b-74d152a85f1741cd.json", + "europe/mariehamn": "tzif-4ccce3697974db1-dd90a8482c7e02e0.json", + "europe/minsk": "tzif-5a1de33f302092c9-7fede906b0fbc944.json", + "europe/monaco": "tzif-513821d5372dc2c3-56efcc8826fb3481.json", + "europe/moscow": "tzif-ec4f112febcbc032-a69762c688a2158f.json", + "europe/nicosia": "tzif-37762e44a2edd792-4f1b10d181e56a5d.json", + "europe/oslo": "tzif-4a65bbe3253254a1-2a20d46c4d15c0c3.json", + "europe/paris": "tzif-513821d5372dc2c3-56efcc8826fb3481.json", + "europe/podgorica": "tzif-a1b14d47c3da0459-9beeb6b09fc4bd85.json", + "europe/prague": "tzif-6d3285599a38ae5a-e146c246881dc5ed.json", + "europe/riga": "tzif-ce5eb7cf8993261f-bdd600c9c7fb16d5.json", + "europe/rome": "tzif-5473a3220fbbe20b-150c46c09db6581d.json", + "europe/samara": "tzif-2ae3e9466dbec3ec-2dfc2c7ddd060e6d.json", + "europe/san_marino": "tzif-5473a3220fbbe20b-150c46c09db6581d.json", + "europe/sarajevo": "tzif-a1b14d47c3da0459-9beeb6b09fc4bd85.json", + "europe/saratov": "tzif-6ad7cbb6af2e6144-d93cfc8ee54a6b99.json", + "europe/simferopol": "tzif-d7daa3dddb990290-2188fa690fb895b7.json", + "europe/skopje": "tzif-a1b14d47c3da0459-9beeb6b09fc4bd85.json", + "europe/sofia": "tzif-1375eb028a5068b1-c7cfa311f9a3eac8.json", + "europe/stockholm": "tzif-4a65bbe3253254a1-2a20d46c4d15c0c3.json", + "europe/tallinn": "tzif-9c7ac303ad5d20d8-9111a17e7b78de54.json", + "europe/tirane": "tzif-4fd8d72ac04d9a5d-3133c7dea65f2538.json", + "europe/tiraspol": "tzif-7622c5c99b380b37-74a373c9f92241c7.json", + "europe/ulyanovsk": "tzif-dbf1c543882cf4b7-2ee5fc1eb7933ea5.json", + "europe/uzhgorod": "tzif-4ab862d6d4b98ff4-7628975aa4bf631a.json", + "europe/vaduz": "tzif-5cb26c449b2278f2-a3a1b3aa09d53c07.json", + "europe/vatican": "tzif-5473a3220fbbe20b-150c46c09db6581d.json", + "europe/vienna": "tzif-bafb78fdc913701c-de429c1ed9e982a1.json", + "europe/vilnius": "tzif-8e1e620dda961a84-8cb519c7f5594e81.json", + "europe/volgograd": "tzif-c711f11538fdc96f-2563abbbef728ca5.json", + "europe/warsaw": "tzif-3a07d4451f21c9ef-6b2242eea52b976b.json", + "europe/zagreb": "tzif-a1b14d47c3da0459-9beeb6b09fc4bd85.json", + "europe/zaporozhye": "tzif-4ab862d6d4b98ff4-7628975aa4bf631a.json", + "europe/zurich": "tzif-5cb26c449b2278f2-a3a1b3aa09d53c07.json", + "factory": "tzif-8c010856ba3febe1-a27521eb7d78dbf6.json", + "gb": "tzif-6bfb62f5e4b63e4a-5a7d3b172eb114d5.json", + "gb-eire": "tzif-6bfb62f5e4b63e4a-5a7d3b172eb114d5.json", + "gmt": "tzif-42518274487a5d74-63fffb5b4ef7fbd9.json", + "gmt+0": "tzif-42518274487a5d74-63fffb5b4ef7fbd9.json", + "gmt-0": "tzif-42518274487a5d74-63fffb5b4ef7fbd9.json", + "gmt0": "tzif-42518274487a5d74-63fffb5b4ef7fbd9.json", + "greenwich": "tzif-42518274487a5d74-63fffb5b4ef7fbd9.json", + "hongkong": "tzif-ea8173f82f8dccac-190f07fa0585582b.json", + "hst": "tzif-6196bbf525d4d50a-c1285ce65c03319.json", + "iceland": "tzif-fe8583499fe1cbb8-a7cf0ef087069495.json", + "indian/antananarivo": "tzif-486e9282debc62a3-27805d7d5dee9be4.json", + "indian/chagos": "tzif-e713de09d9781804-3bc1517947065469.json", + "indian/christmas": "tzif-2a7fc944a4c2991b-ed19eb01bbf45250.json", + "indian/cocos": "tzif-50abe32c287395c8-d2c3aa5882246ab2.json", + "indian/comoro": "tzif-486e9282debc62a3-27805d7d5dee9be4.json", + "indian/kerguelen": "tzif-b3d9e43d648fe2bf-fa688f4eb568be69.json", + "indian/mahe": "tzif-7459e3ffacdde5a6-a596288a1fff51a3.json", + "indian/maldives": "tzif-b3d9e43d648fe2bf-fa688f4eb568be69.json", + "indian/mauritius": "tzif-dc8c7c76ac036db-6dcebe24fb293843.json", + "indian/mayotte": "tzif-486e9282debc62a3-27805d7d5dee9be4.json", + "indian/reunion": "tzif-7459e3ffacdde5a6-a596288a1fff51a3.json", + "iran": "tzif-650685fe5c95ce2a-2f3eb2e60291229d.json", + "israel": "tzif-758d7fde6833ba8c-65256d0857a2f636.json", + "jamaica": "tzif-98fb8731f72daeb6-4585fdc50640db42.json", + "japan": "tzif-7bce416a66d38e42-b58b08c4c731f7dc.json", + "kwajalein": "tzif-f104b0a7be76b68-672d15810abf76ed.json", + "libya": "tzif-81a0c2bb7c8a41da-7b4ebb9a4aa49253.json", + "met": "tzif-6415eb3f74777957-6f718f12281286a3.json", + "mexico/bajanorte": "tzif-3fc16258c94fd1bd-f5865999bedfb5cb.json", + "mexico/bajasur": "tzif-40fb52b19ef81b1d-e1ce3cc4e0a17886.json", + "mexico/general": "tzif-95eb641ddc74061f-5a914528a766049d.json", + "mst": "tzif-a3214de8e358efe8-33b7f8f888f95c0b.json", + "mst7mdt": "tzif-50fc3fea132b4f4c-5a5d88ba8de3b7c1.json", + "navajo": "tzif-50fc3fea132b4f4c-5a5d88ba8de3b7c1.json", + "nz": "tzif-1939cc3520b8dae8-a2fd6733973f8da2.json", + "nz-chat": "tzif-8a0ec5e44a49e44e-1f9e21f2398d2965.json", + "pacific/apia": "tzif-a1347b19ee040601-84e246431e54b763.json", + "pacific/auckland": "tzif-1939cc3520b8dae8-a2fd6733973f8da2.json", + "pacific/bougainville": "tzif-c0f3e562f1a83b48-46259b3efc2044b4.json", + "pacific/chatham": "tzif-8a0ec5e44a49e44e-1f9e21f2398d2965.json", + "pacific/chuuk": "tzif-1ede513c242ae08-561006205b46a9e7.json", + "pacific/easter": "tzif-daeed2898ecd770c-894d1d81ca85ba4d.json", + "pacific/efate": "tzif-bcd5d242787ff58-595e172a944e8f55.json", + "pacific/enderbury": "tzif-edc8df3b48d8f1ae-2f0fe2e55f7ceabf.json", + "pacific/fakaofo": "tzif-57ad9603575ed991-356d85cfd1d045d6.json", + "pacific/fiji": "tzif-fb562061c0f6e08b-c76bafb046d43b7.json", + "pacific/funafuti": "tzif-154d4d1d56f527ae-b4426313fdb85583.json", + "pacific/galapagos": "tzif-905f75931d73bd53-38c9d0ddc82eec2a.json", + "pacific/gambier": "tzif-e7907c2354d7f128-1222f4f18f058093.json", + "pacific/guadalcanal": "tzif-6493d17f054bfdfb-35ed6c8176f0fbed.json", + "pacific/guam": "tzif-b8b54ce37e65e37e-e9672f15a3e270a7.json", + "pacific/honolulu": "tzif-6196bbf525d4d50a-c1285ce65c03319.json", + "pacific/johnston": "tzif-6196bbf525d4d50a-c1285ce65c03319.json", + "pacific/kanton": "tzif-edc8df3b48d8f1ae-2f0fe2e55f7ceabf.json", + "pacific/kiritimati": "tzif-2be99c3dd72ebbf9-e08d147873aff81.json", + "pacific/kosrae": "tzif-cad03994b9f9755d-786401d28559cef.json", + "pacific/kwajalein": "tzif-f104b0a7be76b68-672d15810abf76ed.json", + "pacific/majuro": "tzif-154d4d1d56f527ae-b4426313fdb85583.json", + "pacific/marquesas": "tzif-6797b3dc466b8334-28780ef70fbe052e.json", + "pacific/midway": "tzif-68b74f8e8d191761-a8eaae70013bbfdf.json", + "pacific/nauru": "tzif-355a4a5906a54477-e95040f92d9fdd8d.json", + "pacific/niue": "tzif-7285bd926fe2dc70-a6ffff1cf5147cbf.json", + "pacific/norfolk": "tzif-e4c142bca3031674-44b8ea4e236ae5f5.json", + "pacific/noumea": "tzif-7238398358c87edf-bc2588b2ce94bc20.json", + "pacific/pago_pago": "tzif-68b74f8e8d191761-a8eaae70013bbfdf.json", + "pacific/palau": "tzif-b3a7b6acccb12af9-93f5a4bd9827e971.json", + "pacific/pitcairn": "tzif-f022b64b061d7846-529fb8a37afd1bc3.json", + "pacific/pohnpei": "tzif-6493d17f054bfdfb-35ed6c8176f0fbed.json", + "pacific/ponape": "tzif-6493d17f054bfdfb-35ed6c8176f0fbed.json", + "pacific/port_moresby": "tzif-1ede513c242ae08-561006205b46a9e7.json", + "pacific/rarotonga": "tzif-c0d9ca8c12b3167c-34f182f235d9fe88.json", + "pacific/saipan": "tzif-b8b54ce37e65e37e-e9672f15a3e270a7.json", + "pacific/samoa": "tzif-68b74f8e8d191761-a8eaae70013bbfdf.json", + "pacific/tahiti": "tzif-72be3d5f2c49eb87-7e9fa5340a3dee71.json", + "pacific/tarawa": "tzif-154d4d1d56f527ae-b4426313fdb85583.json", + "pacific/tongatapu": "tzif-8b312fc28eb6d503-b57cea257edd1731.json", + "pacific/truk": "tzif-1ede513c242ae08-561006205b46a9e7.json", + "pacific/wake": "tzif-154d4d1d56f527ae-b4426313fdb85583.json", + "pacific/wallis": "tzif-154d4d1d56f527ae-b4426313fdb85583.json", + "pacific/yap": "tzif-1ede513c242ae08-561006205b46a9e7.json", + "poland": "tzif-3a07d4451f21c9ef-6b2242eea52b976b.json", + "portugal": "tzif-e953d2a73bc41375-ef97956cf6178835.json", + "prc": "tzif-94731e7a96e16727-b9bdd49f2158b98c.json", + "pst8pdt": "tzif-effb0bd5efab2bad-76ee3ca040667987.json", + "roc": "tzif-ee42b17151e8d0d1-557c16a705ea23d1.json", + "rok": "tzif-b89f6da72122ca01-812d173fdcfeaaa6.json", + "singapore": "tzif-fc89b67bba9eff21-ed937c5b2210118e.json", + "turkey": "tzif-21007d26526b6cee-4c7defff421754b5.json", + "uct": "tzif-5eec9cd299aa076f-857603deebbce60b.json", + "universal": "tzif-5eec9cd299aa076f-857603deebbce60b.json", + "us/alaska": "tzif-d4999f54d6ffa1ff-bdc2dfc5a5de1f94.json", + "us/aleutian": "tzif-2450804cbdb4245e-fc28955e4978e50d.json", + "us/arizona": "tzif-a3214de8e358efe8-33b7f8f888f95c0b.json", + "us/central": "tzif-3a5a827f28d118e9-682e0a2d838b16ae.json", + "us/east-indiana": "tzif-754b9e4bdb20aa95-1c5b7a1b811c5ae3.json", + "us/eastern": "tzif-3994d21beae7c7b6-eb145d056159d80.json", + "us/hawaii": "tzif-6196bbf525d4d50a-c1285ce65c03319.json", + "us/indiana-starke": "tzif-fc9fd017e19a24e0-530492ba8305e348.json", + "us/michigan": "tzif-f8baa073f0e62ab0-5c9c06226b1920d5.json", + "us/mountain": "tzif-50fc3fea132b4f4c-5a5d88ba8de3b7c1.json", + "us/pacific": "tzif-effb0bd5efab2bad-76ee3ca040667987.json", + "us/samoa": "tzif-68b74f8e8d191761-a8eaae70013bbfdf.json", + "utc": "tzif-5eec9cd299aa076f-857603deebbce60b.json", + "w-su": "tzif-ec4f112febcbc032-a69762c688a2158f.json", + "wet": "tzif-e953d2a73bc41375-ef97956cf6178835.json", + "zulu": "tzif-5eec9cd299aa076f-857603deebbce60b.json" +} diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1041cd53332eeba8-60aa3eb45cf6bad9.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1041cd53332eeba8-60aa3eb45cf6bad9.json new file mode 100644 index 00000000000000..d3ad1712ecbe1a --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1041cd53332eeba8-60aa3eb45cf6bad9.json @@ -0,0 +1,192 @@ +{ + "ids": [ + "europe/budapest" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": { + "abbr": "CEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2498260580, + -1693706400, + -1680483600, + -1663455600, + -1650150000, + -1632006000, + -1618700400, + -1600470000, + -1587250800, + -1569711600, + -1555196400, + -906775200, + -857257200, + -844556400, + -828226800, + -812502000, + -796777200, + -778471200, + -762656400, + -749689200, + -733276800, + -717634800, + -701910000, + -686185200, + -670460400, + -654130800, + -639010800, + -492656400, + -481168800, + -461199600, + -449708400, + -428540400, + -418258800, + -397090800, + -386809200, + 323823600, + 338943600, + 354668400, + 370393200, + 386118000, + 401842800, + 417567600, + 433292400, + 441759600, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": 4580 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1146d998a660d8a7-7083368cf5416b3.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1146d998a660d8a7-7083368cf5416b3.json new file mode 100644 index 00000000000000..1b0dd650af316c --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1146d998a660d8a7-7083368cf5416b3.json @@ -0,0 +1,157 @@ +{ + "ids": [ + "america/indiana/marengo" + ], + "tzif": { + "posix": { + "abbr": "EST", + "offset": -18000, + "transition": { + "abbr": "EDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3 + ], + "transitions": [ + -2717647200, + -1633276800, + -1615136400, + -1601827200, + -1583686800, + -880214400, + -769395600, + -765392400, + -589392000, + -576090000, + -495043200, + -481741200, + -463593600, + -450291600, + -431539200, + -418237200, + -400089600, + -386787600, + -368640000, + -355338000, + -337190400, + -323888400, + -305740800, + -292438800, + -273686400, + -21488400, + -5767200, + 9961200, + 25682400, + 41410800, + 57736800, + 73465200, + 89186400, + 104914800, + 120636000, + 126687600, + 152089200, + 162370800, + 183535200, + 1143961200, + 1162101600, + 1173596400, + 1194156000 + ], + "types": [ + { + "offset": -20723 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-11b63f0f95d852ce-9769280653fbbbb1.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-11b63f0f95d852ce-9769280653fbbbb1.json new file mode 100644 index 00000000000000..1eb57361493a51 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-11b63f0f95d852ce-9769280653fbbbb1.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt-3" + ], + "tzif": { + "posix": { + "abbr": "+03", + "offset": 10800, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-12ced9fe919d8b6-35fe81809b640977.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-12ced9fe919d8b6-35fe81809b640977.json new file mode 100644 index 00000000000000..dd8376e76f5159 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-12ced9fe919d8b6-35fe81809b640977.json @@ -0,0 +1,211 @@ +{ + "ids": [ + "america/rankin_inlet" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": { + "abbr": "CDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 3, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1 + ], + "transitions": [ + -410227200, + 73468800, + 89190000, + 104918400, + 120639600, + 136368000, + 152089200, + 167817600, + 183538800, + 199267200, + 215593200, + 230716800, + 247042800, + 262771200, + 278492400, + 294220800, + 309942000, + 325670400, + 341391600, + 357120000, + 372841200, + 388569600, + 404895600, + 420019200, + 436345200, + 452073600, + 467794800, + 483523200, + 499244400, + 514972800, + 530694000, + 544608000, + 562143600, + 576057600, + 594198000, + 607507200, + 625647600, + 638956800, + 657097200, + 671011200, + 688546800, + 702460800, + 719996400, + 733910400, + 752050800, + 765360000, + 783500400, + 796809600, + 814950000, + 828864000, + 846399600, + 860313600, + 877849200, + 891763200, + 909298800, + 923212800, + 941353200, + 954662400, + 972802800, + 986112000, + 1004252400, + 1018166400, + 1035702000, + 1049616000, + 1067151600, + 1081065600, + 1099206000, + 1112515200, + 1130655600, + 1143964800, + 1162105200, + 1173600000, + 1194159600 + ], + "types": [ + { + "offset": 0 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1375eb028a5068b1-c7cfa311f9a3eac8.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1375eb028a5068b1-c7cfa311f9a3eac8.json new file mode 100644 index 00000000000000..07f1ef5da6fdef --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1375eb028a5068b1-c7cfa311f9a3eac8.json @@ -0,0 +1,172 @@ +{ + "ids": [ + "europe/sofia" + ], + "tzif": { + "posix": { + "abbr": "EET", + "offset": 7200, + "transition": { + "abbr": "EEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 14400 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4 + ], + "transitions": [ + -2840146396, + -2369527016, + -857257200, + -844556400, + -828226800, + -812502000, + -796777200, + -781048800, + 291762000, + 307576800, + 323816400, + 339026400, + 355266000, + 370393200, + 386715600, + 401846400, + 417571200, + 433296000, + 449020800, + 465350400, + 481075200, + 496800000, + 512524800, + 528249600, + 543974400, + 559699200, + 575424000, + 591148800, + 606873600, + 622598400, + 638323200, + 654652800, + 662680800, + 686091600, + 701820000, + 717541200, + 733269600, + 748990800, + 764719200, + 780440400, + 796168800, + 811890000, + 828223200, + 846363600 + ], + "types": [ + { + "offset": 5596 + }, + { + "offset": 7016 + }, + { + "offset": 7200 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-14cdf6863a8e2179-b18612ad8b0eacc7.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-14cdf6863a8e2179-b18612ad8b0eacc7.json new file mode 100644 index 00000000000000..83f92649a30756 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-14cdf6863a8e2179-b18612ad8b0eacc7.json @@ -0,0 +1,33 @@ +{ + "ids": [ + "africa/blantyre", + "africa/bujumbura", + "africa/gaborone", + "africa/harare", + "africa/kigali", + "africa/lubumbashi", + "africa/lusaka", + "africa/maputo" + ], + "tzif": { + "posix": { + "abbr": "CAT", + "offset": 7200, + "transition": null + }, + "transition_types": [ + 1 + ], + "transitions": [ + -1924999818 + ], + "types": [ + { + "offset": 7818 + }, + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-14ec5a4ae9e7e087-d5eb6128c4e9c616.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-14ec5a4ae9e7e087-d5eb6128c4e9c616.json new file mode 100644 index 00000000000000..eedae29730891c --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-14ec5a4ae9e7e087-d5eb6128c4e9c616.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt-9" + ], + "tzif": { + "posix": { + "abbr": "+09", + "offset": 32400, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": 32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-154d4d1d56f527ae-b4426313fdb85583.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-154d4d1d56f527ae-b4426313fdb85583.json new file mode 100644 index 00000000000000..bd8a666f692e0f --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-154d4d1d56f527ae-b4426313fdb85583.json @@ -0,0 +1,30 @@ +{ + "ids": [ + "pacific/funafuti", + "pacific/majuro", + "pacific/tarawa", + "pacific/wake", + "pacific/wallis" + ], + "tzif": { + "posix": { + "abbr": "+12", + "offset": 43200, + "transition": null + }, + "transition_types": [ + 1 + ], + "transitions": [ + -2177494324 + ], + "types": [ + { + "offset": 41524 + }, + { + "offset": 43200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-170cb25ac2daddf1-c28442df6aeaf807.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-170cb25ac2daddf1-c28442df6aeaf807.json new file mode 100644 index 00000000000000..592ee829b34240 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-170cb25ac2daddf1-c28442df6aeaf807.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt-11" + ], + "tzif": { + "posix": { + "abbr": "+11", + "offset": 39600, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": 39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1735ba0bbd2e57f5-8adc7347030fce3f.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1735ba0bbd2e57f5-8adc7347030fce3f.json new file mode 100644 index 00000000000000..58df87ed8dbffe --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1735ba0bbd2e57f5-8adc7347030fce3f.json @@ -0,0 +1,188 @@ +{ + "ids": [ + "europe/kirov" + ], + "tzif": { + "posix": { + "abbr": "MSK", + "offset": 10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 2, + 4, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1 + ], + "transitions": [ + -1593820800, + -1247540400, + 354916800, + 370724400, + 386452800, + 402260400, + 417988800, + 433796400, + 449611200, + 465343200, + 481068000, + 496792800, + 512517600, + 528242400, + 543967200, + 559692000, + 575416800, + 591141600, + 606866400, + 606870000, + 622594800, + 638319600, + 654649200, + 670374000, + 701820000, + 701823600, + 717548400, + 733273200, + 748998000, + 764722800, + 780447600, + 796172400, + 811897200, + 828226800, + 846370800, + 859676400, + 877820400, + 891126000, + 909270000, + 922575600, + 941324400, + 954025200, + 972774000, + 985474800, + 1004223600, + 1017529200, + 1035673200, + 1048978800, + 1067122800, + 1080428400, + 1099177200, + 1111878000, + 1130626800, + 1143327600, + 1162076400, + 1174777200, + 1193526000, + 1206831600, + 1224975600, + 1238281200, + 1256425200, + 1269730800, + 1288479600, + 1301180400, + 1414274400 + ], + "types": [ + { + "offset": 11928 + }, + { + "offset": 10800 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + }, + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-186e2b651b9e98be-423bebc6a1739dc2.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-186e2b651b9e98be-423bebc6a1739dc2.json new file mode 100644 index 00000000000000..c5d947315ccbbd --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-186e2b651b9e98be-423bebc6a1739dc2.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt-13" + ], + "tzif": { + "posix": { + "abbr": "+13", + "offset": 46800, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": 46800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1939cc3520b8dae8-a2fd6733973f8da2.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1939cc3520b8dae8-a2fd6733973f8da2.json new file mode 100644 index 00000000000000..12a5503f838e54 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1939cc3520b8dae8-a2fd6733973f8da2.json @@ -0,0 +1,297 @@ +{ + "ids": [ + "antarctica/mcmurdo", + "antarctica/south_pole", + "nz", + "pacific/auckland" + ], + "tzif": { + "posix": { + "abbr": "NZST", + "offset": 43200, + "transition": { + "abbr": "NZDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 4, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 9, + 5, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5 + ], + "transitions": [ + -3192435544, + -1330335000, + -1320057000, + -1300699800, + -1287396000, + -1269250200, + -1255946400, + -1237800600, + -1224496800, + -1206351000, + -1192442400, + -1174901400, + -1160992800, + -1143451800, + -1125914400, + -1112607000, + -1094464800, + -1081157400, + -1063015200, + -1049707800, + -1031565600, + -1018258200, + -1000116000, + -986808600, + -968061600, + -955359000, + -936612000, + -923304600, + -757425600, + 152632800, + 162309600, + 183477600, + 194968800, + 215532000, + 226418400, + 246981600, + 257868000, + 278431200, + 289317600, + 309880800, + 320767200, + 341330400, + 352216800, + 372780000, + 384271200, + 404834400, + 415720800, + 436284000, + 447170400, + 467733600, + 478620000, + 499183200, + 510069600, + 530632800, + 541519200, + 562082400, + 573573600, + 594136800, + 605023200, + 623772000, + 637682400, + 655221600, + 669132000, + 686671200, + 700581600, + 718120800, + 732636000, + 749570400, + 764085600, + 781020000, + 795535200, + 812469600, + 826984800, + 844524000, + 858434400, + 875973600, + 889884000, + 907423200, + 921938400, + 938872800, + 953388000, + 970322400, + 984837600, + 1002376800, + 1016287200, + 1033826400, + 1047736800, + 1065276000, + 1079791200, + 1096725600, + 1111240800, + 1128175200, + 1142690400, + 1159624800, + 1174140000, + 1191074400, + 1207404000, + 1222524000 + ], + "types": [ + { + "offset": 41944 + }, + { + "offset": 41400 + }, + { + "offset": 45000 + }, + { + "offset": 43200 + }, + { + "offset": 43200 + }, + { + "offset": 46800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-19d0e567d48830e5-20b2a6d45202416.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-19d0e567d48830e5-20b2a6d45202416.json new file mode 100644 index 00000000000000..9360ace55f629f --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-19d0e567d48830e5-20b2a6d45202416.json @@ -0,0 +1,90 @@ +{ + "ids": [ + "africa/tunis" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2 + ], + "transitions": [ + -2797202444, + -1855958961, + -969242400, + -950493600, + -941940000, + -891136800, + -877827600, + -857257200, + -844556400, + -842918400, + -842223600, + -828230400, + -812502000, + -796269600, + -781052400, + -766634400, + 231202800, + 243903600, + 262825200, + 276044400, + 581122800, + 591145200, + 606870000, + 622594800, + 641516400, + 654649200, + 1114902000, + 1128038400, + 1143334800, + 1162083600 + ], + "types": [ + { + "offset": 2444 + }, + { + "offset": 561 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1a285e17b7751f38-aefc034b499da29b.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1a285e17b7751f38-aefc034b499da29b.json new file mode 100644 index 00000000000000..ad440c47a25c56 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1a285e17b7751f38-aefc034b499da29b.json @@ -0,0 +1,147 @@ +{ + "ids": [ + "america/dawson_creek" + ], + "tzif": { + "posix": { + "abbr": "MST", + "offset": -25200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 3 + ], + "transitions": [ + -2713881544, + -1632060000, + -1615129200, + -880207200, + -769395600, + -765385200, + -715788000, + -702486000, + -684338400, + -671036400, + -652888800, + -639586800, + -620834400, + -608137200, + -589384800, + -576082800, + -557935200, + -544633200, + -526485600, + -513183600, + -495036000, + -481734000, + -463586400, + -450284400, + -431532000, + -418230000, + -400082400, + -386780400, + -368632800, + -355330800, + -337183200, + -323881200, + -305733600, + -292431600, + -273679200, + -260982000, + -242229600, + -226508400, + -210780000, + -195058800, + -179330400, + -163609200, + -147880800, + -131554800, + -116431200, + -100105200, + -84376800, + -68655600, + -52927200, + -37206000, + -21477600, + -5756400, + 9972000, + 25693200, + 41421600, + 57747600, + 73476000, + 84013200 + ], + "types": [ + { + "offset": -28856 + }, + { + "offset": -28800 + }, + { + "offset": -25200 + }, + { + "offset": -25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1dd142eb22754e92-d3cee37600e3912e.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1dd142eb22754e92-d3cee37600e3912e.json new file mode 100644 index 00000000000000..9cd293b6de7870 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1dd142eb22754e92-d3cee37600e3912e.json @@ -0,0 +1,223 @@ +{ + "ids": [ + "america/iqaluit", + "america/pangnirtung" + ], + "tzif": { + "posix": { + "abbr": "EST", + "offset": -18000, + "transition": { + "abbr": "EDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 4, + 2, + 3, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3 + ], + "transitions": [ + -865296000, + -769395600, + -765396000, + 73465200, + 89186400, + 104914800, + 120636000, + 136364400, + 152085600, + 167814000, + 183535200, + 199263600, + 215589600, + 230713200, + 247039200, + 262767600, + 278488800, + 294217200, + 309938400, + 325666800, + 341388000, + 357116400, + 372837600, + 388566000, + 404892000, + 420015600, + 436341600, + 452070000, + 467791200, + 483519600, + 499240800, + 514969200, + 530690400, + 544604400, + 562140000, + 576054000, + 594194400, + 607503600, + 625644000, + 638953200, + 657093600, + 671007600, + 688543200, + 702457200, + 719992800, + 733906800, + 752047200, + 765356400, + 783496800, + 796806000, + 814946400, + 828860400, + 846396000, + 860310000, + 877845600, + 891759600, + 909295200, + 923209200, + 941349600, + 941353200, + 954662400, + 972802800, + 986108400, + 1004248800, + 1018162800, + 1035698400, + 1049612400, + 1067148000, + 1081062000, + 1099202400, + 1112511600, + 1130652000, + 1143961200, + 1162101600, + 1173596400, + 1194156000 + ], + "types": [ + { + "offset": 0 + }, + { + "offset": -14400 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + }, + { + "offset": -21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1ede513c242ae08-561006205b46a9e7.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1ede513c242ae08-561006205b46a9e7.json new file mode 100644 index 00000000000000..e12048673575b5 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1ede513c242ae08-561006205b46a9e7.json @@ -0,0 +1,35 @@ +{ + "ids": [ + "antarctica/dumontdurville", + "pacific/chuuk", + "pacific/port_moresby", + "pacific/truk", + "pacific/yap" + ], + "tzif": { + "posix": { + "abbr": "+10", + "offset": 36000, + "transition": null + }, + "transition_types": [ + 1, + 2 + ], + "transitions": [ + -2840176120, + -2366790512 + ], + "types": [ + { + "offset": 35320 + }, + { + "offset": 35312 + }, + { + "offset": 36000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1eff85dd787ed3a1-d74f97871f7e97e8.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1eff85dd787ed3a1-d74f97871f7e97e8.json new file mode 100644 index 00000000000000..b70bec1a070cf6 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-1eff85dd787ed3a1-d74f97871f7e97e8.json @@ -0,0 +1,264 @@ +{ + "ids": [ + "america/dawson" + ], + "tzif": { + "posix": { + "abbr": "MST", + "offset": -25200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 3, + 1, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 3, + 5 + ], + "transitions": [ + -2188996940, + -1632056400, + -1615125600, + -1596978000, + -1583164800, + -880203600, + -769395600, + -765381600, + -147884400, + -131554800, + 120646800, + 325677600, + 341398800, + 357127200, + 372848400, + 388576800, + 404902800, + 420026400, + 436352400, + 452080800, + 467802000, + 483530400, + 499251600, + 514980000, + 530701200, + 544615200, + 562150800, + 576064800, + 594205200, + 607514400, + 625654800, + 638964000, + 657104400, + 671018400, + 688554000, + 702468000, + 720003600, + 733917600, + 752058000, + 765367200, + 783507600, + 796816800, + 814957200, + 828871200, + 846406800, + 860320800, + 877856400, + 891770400, + 909306000, + 923220000, + 941360400, + 954669600, + 972810000, + 986119200, + 1004259600, + 1018173600, + 1035709200, + 1049623200, + 1067158800, + 1081072800, + 1099213200, + 1112522400, + 1130662800, + 1143972000, + 1162112400, + 1173607200, + 1194166800, + 1205056800, + 1225616400, + 1236506400, + 1257066000, + 1268560800, + 1289120400, + 1300010400, + 1320570000, + 1331460000, + 1352019600, + 1362909600, + 1383469200, + 1394359200, + 1414918800, + 1425808800, + 1446368400, + 1457863200, + 1478422800, + 1489312800, + 1509872400, + 1520762400, + 1541322000, + 1552212000, + 1572771600, + 1583661600, + 1604214000 + ], + "types": [ + { + "offset": -33460 + }, + { + "offset": -32400 + }, + { + "offset": -28800 + }, + { + "offset": -25200 + }, + { + "offset": -28800 + }, + { + "offset": -25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-206d649fad594120-70deb0fb976b18e.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-206d649fad594120-70deb0fb976b18e.json new file mode 100644 index 00000000000000..7b82c07f97dc87 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-206d649fad594120-70deb0fb976b18e.json @@ -0,0 +1,109 @@ +{ + "ids": [ + "america/maceio" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1767217028, + -1206957600, + -1191362400, + -1175374800, + -1159826400, + -633819600, + -622069200, + -602283600, + -591832800, + -570747600, + -560210400, + -539125200, + -531352800, + -191365200, + -184197600, + -155163600, + -150069600, + -128898000, + -121125600, + -99954000, + -89589600, + -68418000, + -57967200, + 499748400, + 511236000, + 530593200, + 540266400, + 562129200, + 571197600, + 592974000, + 602042400, + 624423600, + 634701600, + 813726000, + 824004000, + 938919600, + 951616800, + 970974000, + 972180000, + 1003028400, + 1013911200 + ], + "types": [ + { + "offset": -8572 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-21007d26526b6cee-4c7defff421754b5.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-21007d26526b6cee-4c7defff421754b5.json new file mode 100644 index 00000000000000..f073b72b52a89f --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-21007d26526b6cee-4c7defff421754b5.json @@ -0,0 +1,303 @@ +{ + "ids": [ + "asia/istanbul", + "europe/istanbul", + "turkey" + ], + "tzif": { + "posix": { + "abbr": "+03", + "offset": 10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 3, + 4, + 5, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 3, + 4 + ], + "transitions": [ + -2840147752, + -1869875816, + -1693706400, + -1680490800, + -1570413600, + -1552186800, + -1538359200, + -1522551600, + -1507514400, + -1490583600, + -1440208800, + -1428030000, + -1409709600, + -1396494000, + -931053600, + -922676400, + -917834400, + -892436400, + -875844000, + -764737200, + -744343200, + -733806000, + -716436000, + -701924400, + -684986400, + -670474800, + -654141600, + -639025200, + -622087200, + -606970800, + -590032800, + -575521200, + -235620000, + -194842800, + -177732000, + -165726000, + 107910000, + 121215600, + 133920000, + 152665200, + 164678400, + 184114800, + 196214400, + 215564400, + 228873600, + 245804400, + 260323200, + 267915600, + 428454000, + 433893600, + 468111600, + 482799600, + 496710000, + 512521200, + 528246000, + 543970800, + 559695600, + 575420400, + 591145200, + 606870000, + 622594800, + 638319600, + 654649200, + 670374000, + 686098800, + 701823600, + 717548400, + 733273200, + 748998000, + 764118000, + 780447600, + 796172400, + 811897200, + 828226800, + 846370800, + 859676400, + 877820400, + 891126000, + 909270000, + 922575600, + 941324400, + 954025200, + 972774000, + 985474800, + 1004223600, + 1017529200, + 1035673200, + 1048978800, + 1067122800, + 1080428400, + 1099177200, + 1111878000, + 1130626800, + 1143327600, + 1162076400, + 1174784400, + 1193533200, + 1206838800, + 1224982800, + 1238288400, + 1256432400, + 1269738000, + 1288486800, + 1301274000, + 1319936400, + 1332637200, + 1351386000, + 1364691600, + 1382835600, + 1396227600, + 1414285200, + 1427590800, + 1446944400, + 1459040400, + 1473195600 + ], + "types": [ + { + "offset": 6952 + }, + { + "offset": 7016 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 10800 + }, + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-239c7722f428fac8-7a4c4b125895f0bd.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-239c7722f428fac8-7a4c4b125895f0bd.json new file mode 100644 index 00000000000000..2040ebc2f37af4 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-239c7722f428fac8-7a4c4b125895f0bd.json @@ -0,0 +1,245 @@ +{ + "ids": [ + "america/north_dakota/new_salem" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": { + "abbr": "CDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3 + ], + "transitions": [ + -2717643600, + -1633273200, + -1615132800, + -1601823600, + -1583683200, + -880210800, + -769395600, + -765388800, + -84380400, + -68659200, + -52930800, + -37209600, + -21481200, + -5760000, + 9968400, + 25689600, + 41418000, + 57744000, + 73472400, + 89193600, + 104922000, + 120643200, + 126694800, + 152092800, + 162378000, + 183542400, + 199270800, + 215596800, + 230720400, + 247046400, + 262774800, + 278496000, + 294224400, + 309945600, + 325674000, + 341395200, + 357123600, + 372844800, + 388573200, + 404899200, + 420022800, + 436348800, + 452077200, + 467798400, + 483526800, + 499248000, + 514976400, + 530697600, + 544611600, + 562147200, + 576061200, + 594201600, + 607510800, + 625651200, + 638960400, + 657100800, + 671014800, + 688550400, + 702464400, + 720000000, + 733914000, + 752054400, + 765363600, + 783504000, + 796813200, + 814953600, + 828867600, + 846403200, + 860317200, + 877852800, + 891766800, + 909302400, + 923216400, + 941356800, + 954666000, + 972806400, + 986115600, + 1004256000, + 1018170000, + 1035705600, + 1049619600, + 1067155200, + 1081065600, + 1099206000, + 1112515200, + 1130655600, + 1143964800, + 1162105200, + 1173600000, + 1194159600 + ], + "types": [ + { + "offset": -24339 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2450804cbdb4245e-fc28955e4978e50d.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2450804cbdb4245e-fc28955e4978e50d.json new file mode 100644 index 00000000000000..410d980cae1ae6 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2450804cbdb4245e-fc28955e4978e50d.json @@ -0,0 +1,261 @@ +{ + "ids": [ + "america/adak", + "america/atka", + "us/aleutian" + ], + "tzif": { + "posix": { + "abbr": "HST", + "offset": -36000, + "transition": { + "abbr": "HDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 3, + 2, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 3, + 4, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4 + ], + "transitions": [ + -3225223727, + -2188944802, + -880196400, + -769395600, + -765374400, + -86878800, + -21466800, + -5745600, + 9982800, + 25704000, + 41432400, + 57758400, + 73486800, + 89208000, + 104936400, + 120657600, + 126709200, + 152107200, + 162392400, + 183556800, + 199285200, + 215611200, + 230734800, + 247060800, + 262789200, + 278510400, + 294238800, + 309960000, + 325688400, + 341409600, + 357138000, + 372859200, + 388587600, + 404913600, + 420037200, + 436363200, + 439034400, + 452088000, + 467809200, + 483537600, + 499258800, + 514987200, + 530708400, + 544622400, + 562158000, + 576072000, + 594212400, + 607521600, + 625662000, + 638971200, + 657111600, + 671025600, + 688561200, + 702475200, + 720010800, + 733924800, + 752065200, + 765374400, + 783514800, + 796824000, + 814964400, + 828878400, + 846414000, + 860328000, + 877863600, + 891777600, + 909313200, + 923227200, + 941367600, + 954676800, + 972817200, + 986126400, + 1004266800, + 1018180800, + 1035716400, + 1049630400, + 1067166000, + 1081080000, + 1099220400, + 1112529600, + 1130670000, + 1143979200, + 1162119600, + 1173614400, + 1194174000 + ], + "types": [ + { + "offset": 44002 + }, + { + "offset": -42398 + }, + { + "offset": -39600 + }, + { + "offset": -36000 + }, + { + "offset": -36000 + }, + { + "offset": -32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-24b250ef0928a9e9-6530a4ca5485dc31.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-24b250ef0928a9e9-6530a4ca5485dc31.json new file mode 100644 index 00000000000000..58d5b54283ee54 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-24b250ef0928a9e9-6530a4ca5485dc31.json @@ -0,0 +1,33 @@ +{ + "ids": [ + "africa/ndjamena" + ], + "tzif": { + "posix": { + "abbr": "WAT", + "offset": 3600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1 + ], + "transitions": [ + -1830387612, + 308703600, + 321314400 + ], + "types": [ + { + "offset": 3612 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-24bc4f701e560e8f-fbbcb1e6855b01a1.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-24bc4f701e560e8f-fbbcb1e6855b01a1.json new file mode 100644 index 00000000000000..7092c8654595c0 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-24bc4f701e560e8f-fbbcb1e6855b01a1.json @@ -0,0 +1,167 @@ +{ + "ids": [ + "america/argentina/buenos_aires", + "america/buenos_aires" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 3, + 4, + 3, + 4, + 5, + 3, + 4, + 5 + ], + "transitions": [ + -2372097972, + -1567453392, + -1233432000, + -1222981200, + -1205956800, + -1194037200, + -1172865600, + -1162501200, + -1141329600, + -1130965200, + -1109793600, + -1099429200, + -1078257600, + -1067806800, + -1046635200, + -1036270800, + -1015099200, + -1004734800, + -983563200, + -973198800, + -952027200, + -941576400, + -931032000, + -900882000, + -890337600, + -833749200, + -827265600, + -752274000, + -733780800, + -197326800, + -190843200, + -184194000, + -164491200, + -152658000, + -132955200, + -121122000, + -101419200, + -86821200, + -71092800, + -54766800, + -39038400, + -23317200, + -7588800, + 128142000, + 136605600, + 596948400, + 605066400, + 624423600, + 636516000, + 656478000, + 667965600, + 687927600, + 699415200, + 719377200, + 731469600, + 938919600, + 952052400, + 1198983600, + 1205632800, + 1224385200 + ], + "types": [ + { + "offset": -14028 + }, + { + "offset": -15408 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-25763d8b26764a7a-5933d51fd56b3fdf.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-25763d8b26764a7a-5933d51fd56b3fdf.json new file mode 100644 index 00000000000000..7bcfeefaf17b33 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-25763d8b26764a7a-5933d51fd56b3fdf.json @@ -0,0 +1,101 @@ +{ + "ids": [ + "africa/khartoum" + ], + "tzif": { + "posix": { + "abbr": "CAT", + "offset": 7200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 1 + ], + "transitions": [ + -1230775808, + 10360800, + 24786000, + 41810400, + 56322000, + 73432800, + 87944400, + 104882400, + 119480400, + 136332000, + 151016400, + 167781600, + 182552400, + 199231200, + 214174800, + 230680800, + 245710800, + 262735200, + 277246800, + 294184800, + 308782800, + 325634400, + 340405200, + 357084000, + 371941200, + 388533600, + 403477200, + 419983200, + 435013200, + 452037600, + 466635600, + 483487200, + 498171600, + 947930400, + 1509483600 + ], + "types": [ + { + "offset": 7808 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-26ac36da2732c840-dedd53591694d48d.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-26ac36da2732c840-dedd53591694d48d.json new file mode 100644 index 00000000000000..f610efed9b7fa8 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-26ac36da2732c840-dedd53591694d48d.json @@ -0,0 +1,163 @@ +{ + "ids": [ + "america/argentina/salta" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 2, + 5, + 3, + 4, + 5, + 3, + 4, + 3, + 4, + 3, + 4, + 5, + 3, + 4 + ], + "transitions": [ + -2372096300, + -1567453392, + -1233432000, + -1222981200, + -1205956800, + -1194037200, + -1172865600, + -1162501200, + -1141329600, + -1130965200, + -1109793600, + -1099429200, + -1078257600, + -1067806800, + -1046635200, + -1036270800, + -1015099200, + -1004734800, + -983563200, + -973198800, + -952027200, + -941576400, + -931032000, + -900882000, + -890337600, + -833749200, + -827265600, + -752274000, + -733780800, + -197326800, + -190843200, + -184194000, + -164491200, + -152658000, + -132955200, + -121122000, + -101419200, + -86821200, + -71092800, + -54766800, + -39038400, + -23317200, + -7588800, + 128142000, + 136605600, + 596948400, + 605066400, + 624423600, + 636516000, + 656478000, + 667965600, + 687931200, + 699415200, + 719377200, + 731469600, + 938919600, + 952052400, + 1198983600, + 1205632800 + ], + "types": [ + { + "offset": -15700 + }, + { + "offset": -15408 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-26aecc98f9d83045-d767019b239f072.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-26aecc98f9d83045-d767019b239f072.json new file mode 100644 index 00000000000000..2d80a757a35eaf --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-26aecc98f9d83045-d767019b239f072.json @@ -0,0 +1,187 @@ +{ + "ids": [ + "america/indiana/petersburg" + ], + "tzif": { + "posix": { + "abbr": "EST", + "offset": -18000, + "transition": { + "abbr": "EDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 2, + 3 + ], + "transitions": [ + -2717647200, + -1633276800, + -1615136400, + -1601827200, + -1583686800, + -880214400, + -769395600, + -765392400, + -462996000, + -450291600, + -431539200, + -418237200, + -400089600, + -386787600, + -368640000, + -355338000, + -337190400, + -323888400, + -305740800, + -292438800, + -273686400, + -257965200, + -242236800, + -226515600, + -210787200, + -195066000, + -179337600, + -163616400, + -147888000, + -100112400, + -84384000, + -68662800, + -52934400, + -37213200, + -21484800, + -5763600, + 9964800, + 25686000, + 41414400, + 57740400, + 73468800, + 89190000, + 104918400, + 120639600, + 126691200, + 152089200, + 162374400, + 183538800, + 199267200, + 215593200, + 230716800, + 247042800, + 1143961200, + 1143964800, + 1162105200, + 1173600000, + 1194159600 + ], + "types": [ + { + "offset": -20947 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-26bf0cacd24f77a1-a98e0c85e152f06e.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-26bf0cacd24f77a1-a98e0c85e152f06e.json new file mode 100644 index 00000000000000..81c37cebb14d25 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-26bf0cacd24f77a1-a98e0c85e152f06e.json @@ -0,0 +1,109 @@ +{ + "ids": [ + "europe/andorra" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": { + "abbr": "CEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2 + ], + "transitions": [ + -2177453164, + -733881600, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": 364 + }, + { + "offset": 0 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-273d77751416ce66-188ad35538918cca.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-273d77751416ce66-188ad35538918cca.json new file mode 100644 index 00000000000000..ebad836a0f7d1b --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-273d77751416ce66-188ad35538918cca.json @@ -0,0 +1,149 @@ +{ + "ids": [ + "america/port-au-prince" + ], + "tzif": { + "posix": { + "abbr": "EST", + "offset": -18000, + "transition": { + "abbr": "EDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2 + ], + "transitions": [ + -2524504240, + -1670483460, + 421218000, + 436334400, + 452062800, + 467784000, + 483512400, + 499233600, + 514962000, + 530683200, + 546411600, + 562132800, + 576050400, + 594194400, + 607500000, + 625644000, + 638949600, + 657093600, + 671004000, + 688543200, + 702453600, + 719992800, + 733903200, + 752047200, + 765352800, + 783496800, + 796802400, + 814946400, + 828856800, + 846396000, + 860306400, + 877845600, + 1112504400, + 1130644800, + 1143954000, + 1162094400, + 1331449200, + 1352008800, + 1362898800, + 1383458400, + 1394348400, + 1414908000, + 1425798000, + 1446357600, + 1489302000, + 1509861600 + ], + "types": [ + { + "offset": -17360 + }, + { + "offset": -17340 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-283cf30fce0ee58e-ee056ab931c35019.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-283cf30fce0ee58e-ee056ab931c35019.json new file mode 100644 index 00000000000000..382c8e0d2b5979 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-283cf30fce0ee58e-ee056ab931c35019.json @@ -0,0 +1,70 @@ +{ + "ids": [ + "asia/brunei", + "asia/kuching" + ], + "tzif": { + "posix": { + "abbr": "+08", + "offset": 28800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 4, + 2 + ], + "transitions": [ + -1383463280, + -1167636600, + -1082448000, + -1074586800, + -1050825600, + -1042964400, + -1019289600, + -1011428400, + -987753600, + -979892400, + -956217600, + -948356400, + -924595200, + -916734000, + -893059200, + -885198000, + -879667200, + -767005200 + ], + "types": [ + { + "offset": 26480 + }, + { + "offset": 27000 + }, + { + "offset": 28800 + }, + { + "offset": 30000 + }, + { + "offset": 32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-291cff29f8a99dfe-401473cfba65f82d.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-291cff29f8a99dfe-401473cfba65f82d.json new file mode 100644 index 00000000000000..f05550ee11962f --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-291cff29f8a99dfe-401473cfba65f82d.json @@ -0,0 +1,187 @@ +{ + "ids": [ + "asia/novokuznetsk" + ], + "tzif": { + "posix": { + "abbr": "+07", + "offset": 25200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4 + ], + "transitions": [ + -1441259328, + -1247551200, + 354906000, + 370713600, + 386442000, + 402249600, + 417978000, + 433785600, + 449600400, + 465332400, + 481057200, + 496782000, + 512506800, + 528231600, + 543956400, + 559681200, + 575406000, + 591130800, + 606855600, + 622580400, + 638305200, + 654634800, + 670359600, + 670363200, + 686088000, + 695764800, + 701809200, + 717534000, + 733258800, + 748983600, + 764708400, + 780433200, + 796158000, + 811882800, + 828212400, + 846356400, + 859662000, + 877806000, + 891111600, + 909255600, + 922561200, + 941310000, + 954010800, + 972759600, + 985460400, + 1004209200, + 1017514800, + 1035658800, + 1048964400, + 1067108400, + 1080414000, + 1099162800, + 1111863600, + 1130612400, + 1143313200, + 1162062000, + 1174762800, + 1193511600, + 1206817200, + 1224961200, + 1238266800, + 1256410800, + 1269716400, + 1269720000, + 1288468800, + 1301169600 + ], + "types": [ + { + "offset": 20928 + }, + { + "offset": 21600 + }, + { + "offset": 25200 + }, + { + "offset": 28800 + }, + { + "offset": 25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2a2176981e284105-59c6fda81a2a226c.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2a2176981e284105-59c6fda81a2a226c.json new file mode 100644 index 00000000000000..99c9d868be8581 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2a2176981e284105-59c6fda81a2a226c.json @@ -0,0 +1,59 @@ +{ + "ids": [ + "australia/eucla" + ], + "tzif": { + "posix": { + "abbr": "+0845", + "offset": 31500, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2 + ], + "transitions": [ + -2337928528, + -1672555500, + -1665384300, + -883637100, + -876120300, + -860395500, + -844670700, + 152039700, + 162926100, + 436295700, + 447182100, + 690311700, + 699383700, + 1165079700, + 1174756500, + 1193505300 + ], + "types": [ + { + "offset": 30928 + }, + { + "offset": 31500 + }, + { + "offset": 35100 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2a554d4e97833d6e-1eb5fb8bf2c9f728.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2a554d4e97833d6e-1eb5fb8bf2c9f728.json new file mode 100644 index 00000000000000..67e1af22ea67c6 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2a554d4e97833d6e-1eb5fb8bf2c9f728.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt+9" + ], + "tzif": { + "posix": { + "abbr": "-09", + "offset": -32400, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": -32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2a7fc944a4c2991b-ed19eb01bbf45250.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2a7fc944a4c2991b-ed19eb01bbf45250.json new file mode 100644 index 00000000000000..cd69ddcc83060f --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2a7fc944a4c2991b-ed19eb01bbf45250.json @@ -0,0 +1,31 @@ +{ + "ids": [ + "asia/bangkok", + "asia/phnom_penh", + "asia/vientiane", + "indian/christmas" + ], + "tzif": { + "posix": { + "abbr": "+07", + "offset": 25200, + "transition": null + }, + "transition_types": [ + 0, + 1 + ], + "transitions": [ + -2840164924, + -1570084924 + ], + "types": [ + { + "offset": 24124 + }, + { + "offset": 25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2a9b3a635fc27340-e824f8940a7a64f6.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2a9b3a635fc27340-e824f8940a7a64f6.json new file mode 100644 index 00000000000000..821b7cc5122730 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2a9b3a635fc27340-e824f8940a7a64f6.json @@ -0,0 +1,41 @@ +{ + "ids": [ + "america/paramaribo" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 4 + ], + "transitions": [ + -1861906760, + -1104524348, + -765317964, + 465449400 + ], + "types": [ + { + "offset": -13240 + }, + { + "offset": -13252 + }, + { + "offset": -13236 + }, + { + "offset": -12600 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2ae3e9466dbec3ec-2dfc2c7ddd060e6d.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2ae3e9466dbec3ec-2dfc2c7ddd060e6d.json new file mode 100644 index 00000000000000..fbfbd1d89b0c92 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2ae3e9466dbec3ec-2dfc2c7ddd060e6d.json @@ -0,0 +1,199 @@ +{ + "ids": [ + "europe/samara" + ], + "tzif": { + "posix": { + "abbr": "+04", + "offset": 14400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 2, + 4, + 1, + 1, + 5, + 1, + 5, + 1, + 5, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4 + ], + "transitions": [ + -1593820800, + -1247540400, + 354916800, + 370724400, + 386452800, + 402260400, + 417988800, + 433796400, + 449611200, + 465343200, + 481068000, + 496792800, + 512517600, + 528242400, + 543967200, + 559692000, + 575416800, + 591141600, + 606866400, + 606870000, + 622594800, + 638319600, + 654649200, + 670374000, + 670377600, + 686102400, + 687916800, + 701820000, + 717544800, + 733269600, + 748994400, + 764719200, + 780444000, + 796168800, + 811893600, + 828223200, + 846367200, + 859672800, + 877816800, + 891122400, + 909266400, + 922572000, + 941320800, + 954021600, + 972770400, + 985471200, + 1004220000, + 1017525600, + 1035669600, + 1048975200, + 1067119200, + 1080424800, + 1099173600, + 1111874400, + 1130623200, + 1143324000, + 1162072800, + 1174773600, + 1193522400, + 1206828000, + 1224972000, + 1238277600, + 1256421600, + 1269727200, + 1269730800, + 1288479600, + 1301180400 + ], + "types": [ + { + "offset": 12020 + }, + { + "offset": 10800 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + }, + { + "offset": 14400 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2b407bee2bf8cbea-39e72d1f00f10d06.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2b407bee2bf8cbea-39e72d1f00f10d06.json new file mode 100644 index 00000000000000..fb22f36175653e --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2b407bee2bf8cbea-39e72d1f00f10d06.json @@ -0,0 +1,400 @@ +{ + "ids": [ + "africa/el_aaiun" + ], + "tzif": { + "posix": { + "abbr": "+01", + "offset": 3600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3 + ], + "transitions": [ + -1136070432, + 198291600, + 199756800, + 207702000, + 231292800, + 244249200, + 265507200, + 271033200, + 1212278400, + 1220223600, + 1243814400, + 1250809200, + 1272758400, + 1281222000, + 1301788800, + 1312066800, + 1335664800, + 1342749600, + 1345428000, + 1348970400, + 1367114400, + 1373162400, + 1376100000, + 1382839200, + 1396144800, + 1403920800, + 1406944800, + 1414288800, + 1427594400, + 1434247200, + 1437271200, + 1445738400, + 1459044000, + 1465092000, + 1468116000, + 1477792800, + 1490493600, + 1495332000, + 1498960800, + 1509242400, + 1521943200, + 1526176800, + 1529200800, + 1557021600, + 1560045600, + 1587261600, + 1590890400, + 1618106400, + 1621130400, + 1648346400, + 1651975200, + 1679191200, + 1682215200, + 1710036000, + 1713060000, + 1740276000, + 1743904800, + 1771120800, + 1774144800, + 1801965600, + 1804989600, + 1832205600, + 1835834400, + 1863050400, + 1866074400, + 1893290400, + 1896919200, + 1924135200, + 1927159200, + 1954980000, + 1958004000, + 1985220000, + 1988848800, + 2016064800, + 2019088800, + 2046304800, + 2049933600, + 2077149600, + 2080778400, + 2107994400, + 2111018400, + 2138234400, + 2141863200, + 2169079200, + 2172103200, + 2199924000, + 2202948000, + 2230164000, + 2233792800, + 2261008800, + 2264032800, + 2291248800, + 2294877600, + 2322093600, + 2325722400, + 2352938400, + 2355962400, + 2383178400, + 2386807200, + 2414023200, + 2417047200, + 2444868000, + 2447892000, + 2475108000, + 2478736800, + 2505952800, + 2508976800, + 2536192800, + 2539821600, + 2567037600, + 2570666400, + 2597882400, + 2600906400, + 2628122400, + 2631751200, + 2658967200, + 2661991200, + 2689812000, + 2692836000, + 2720052000, + 2723680800, + 2750896800, + 2753920800, + 2781136800, + 2784765600, + 2811981600, + 2815610400, + 2842826400, + 2845850400, + 2873066400, + 2876695200, + 2903911200, + 2906935200, + 2934756000, + 2937780000, + 2964996000, + 2968624800, + 2995840800, + 2998864800, + 3026080800, + 3029709600, + 3056925600, + 3060554400, + 3087770400, + 3090794400, + 3118010400, + 3121639200, + 3148855200, + 3151879200, + 3179700000, + 3182724000, + 3209940000, + 3213568800, + 3240784800, + 3243808800, + 3271024800, + 3274653600, + 3301869600, + 3305498400, + 3332714400, + 3335738400, + 3362954400, + 3366583200, + 3393799200, + 3396823200, + 3424644000, + 3427668000, + 3454884000, + 3458512800, + 3485728800, + 3488752800, + 3515968800, + 3519597600, + 3546813600, + 3549837600, + 3577658400, + 3580682400, + 3607898400, + 3611527200, + 3638743200, + 3641767200, + 3669588000, + 3672612000, + 3699828000, + 3703456800 + ], + "types": [ + { + "offset": -3168 + }, + { + "offset": -3600 + }, + { + "offset": 0 + }, + { + "offset": 3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2bd99bb6843e89cf-932580fc9a3a0c8d.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2bd99bb6843e89cf-932580fc9a3a0c8d.json new file mode 100644 index 00000000000000..e2fdc4ac7f09f7 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2bd99bb6843e89cf-932580fc9a3a0c8d.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt-8" + ], + "tzif": { + "posix": { + "abbr": "+08", + "offset": 28800, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": 28800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2be99c3dd72ebbf9-e08d147873aff81.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2be99c3dd72ebbf9-e08d147873aff81.json new file mode 100644 index 00000000000000..0121b65b33d6f3 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2be99c3dd72ebbf9-e08d147873aff81.json @@ -0,0 +1,36 @@ +{ + "ids": [ + "pacific/kiritimati" + ], + "tzif": { + "posix": { + "abbr": "+14", + "offset": 50400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3 + ], + "transitions": [ + -2177415040, + 307622400, + 788868000 + ], + "types": [ + { + "offset": -37760 + }, + { + "offset": -38400 + }, + { + "offset": -36000 + }, + { + "offset": 50400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2c1bb7953877feff-4c66e005cbf579fe.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2c1bb7953877feff-4c66e005cbf579fe.json new file mode 100644 index 00000000000000..a0b81cf6290dc1 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2c1bb7953877feff-4c66e005cbf579fe.json @@ -0,0 +1,212 @@ +{ + "ids": [ + "america/ciudad_juarez" + ], + "tzif": { + "posix": { + "abbr": "MST", + "offset": -25200, + "transition": { + "abbr": "MDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 2, + 3, + 1 + ], + "transitions": [ + -1514739600, + -1343149200, + -1234807200, + -1220461200, + -1207159200, + -1191344400, + 828864000, + 846399600, + 860313600, + 877849200, + 891766800, + 909302400, + 923216400, + 941356800, + 954666000, + 972806400, + 989139600, + 1001836800, + 1018170000, + 1035705600, + 1049619600, + 1067155200, + 1081069200, + 1099209600, + 1112518800, + 1130659200, + 1143968400, + 1162108800, + 1175418000, + 1193558400, + 1207472400, + 1225008000, + 1238922000, + 1256457600, + 1268557200, + 1289116800, + 1300006800, + 1320566400, + 1331456400, + 1352016000, + 1362906000, + 1383465600, + 1394355600, + 1414915200, + 1425805200, + 1446364800, + 1457859600, + 1478419200, + 1489309200, + 1509868800, + 1520758800, + 1541318400, + 1552208400, + 1572768000, + 1583658000, + 1604217600, + 1615712400, + 1636272000, + 1647162000, + 1667116800, + 1669788000 + ], + "types": [ + { + "offset": -25556 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2d819a70236c9f86-721e9b57fc17e8df.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2d819a70236c9f86-721e9b57fc17e8df.json new file mode 100644 index 00000000000000..0a9a6edf70c84a --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-2d819a70236c9f86-721e9b57fc17e8df.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt+2" + ], + "tzif": { + "posix": { + "abbr": "-02", + "offset": -7200, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3234542952508833-776aeadf2e17fcb4.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3234542952508833-776aeadf2e17fcb4.json new file mode 100644 index 00000000000000..cfaa49a044f546 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3234542952508833-776aeadf2e17fcb4.json @@ -0,0 +1,87 @@ +{ + "ids": [ + "america/monterrey" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3 + ], + "transitions": [ + -1514743200, + -1343149200, + -1234807200, + -1220461200, + -1207159200, + -1191344400, + 576057600, + 594198000, + 828864000, + 846399600, + 860313600, + 877849200, + 891763200, + 909298800, + 923212800, + 941353200, + 954662400, + 972802800, + 989136000, + 1001833200, + 1018166400, + 1035702000 + ], + "types": [ + { + "offset": -24076 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-33db81d7f03c072e-e083980d979c0926.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-33db81d7f03c072e-e083980d979c0926.json new file mode 100644 index 00000000000000..c6f248e4c19cfa --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-33db81d7f03c072e-e083980d979c0926.json @@ -0,0 +1,225 @@ +{ + "ids": [ + "america/yakutat" + ], + "tzif": { + "posix": { + "abbr": "AKST", + "offset": -32400, + "transition": { + "abbr": "AKDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2 + ], + "transitions": [ + -3225223727, + -2188953665, + -880203600, + -769395600, + -765381600, + -21474000, + -5752800, + 9975600, + 25696800, + 41425200, + 57751200, + 73479600, + 89200800, + 104929200, + 120650400, + 126702000, + 152100000, + 162385200, + 183549600, + 199278000, + 215604000, + 230727600, + 247053600, + 262782000, + 278503200, + 294231600, + 309952800, + 325681200, + 341402400, + 357130800, + 372852000, + 388580400, + 404906400, + 420030000, + 436356000, + 439030800, + 452084400, + 467805600, + 483534000, + 499255200, + 514983600, + 530704800, + 544618800, + 562154400, + 576068400, + 594208800, + 607518000, + 625658400, + 638967600, + 657108000, + 671022000, + 688557600, + 702471600, + 720007200, + 733921200, + 752061600, + 765370800, + 783511200, + 796820400, + 814960800, + 828874800, + 846410400, + 860324400, + 877860000, + 891774000, + 909309600, + 923223600, + 941364000, + 954673200, + 972813600, + 986122800, + 1004263200, + 1018177200, + 1035712800, + 1049626800, + 1067162400, + 1081076400, + 1099216800, + 1112526000, + 1130666400, + 1143975600, + 1162116000, + 1173610800, + 1194170400 + ], + "types": [ + { + "offset": 52865 + }, + { + "offset": -33535 + }, + { + "offset": -32400 + }, + { + "offset": -28800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-34047004b336df3e-bbe8e4196294f00a.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-34047004b336df3e-bbe8e4196294f00a.json new file mode 100644 index 00000000000000..db806ecb2d352d --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-34047004b336df3e-bbe8e4196294f00a.json @@ -0,0 +1,308 @@ +{ + "ids": [ + "europe/gibraltar" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": { + "abbr": "CEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 1, + 2, + 1, + 2, + 3, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4 + ], + "transitions": [ + -2821649916, + -1691964000, + -1680472800, + -1664143200, + -1650146400, + -1633903200, + -1617487200, + -1601848800, + -1586037600, + -1570399200, + -1552168800, + -1538344800, + -1522533600, + -1507500000, + -1490565600, + -1473631200, + -1460930400, + -1442786400, + -1428876000, + -1410732000, + -1396216800, + -1379282400, + -1364767200, + -1348437600, + -1333317600, + -1315778400, + -1301263200, + -1284328800, + -1269813600, + -1253484000, + -1238364000, + -1221429600, + -1206914400, + -1189980000, + -1175464800, + -1159135200, + -1143410400, + -1126476000, + -1111960800, + -1095631200, + -1080511200, + -1063576800, + -1049061600, + -1032127200, + -1017612000, + -1001282400, + -986162400, + -969228000, + -950479200, + -942012000, + -904518000, + -896050800, + -875487600, + -864601200, + -844038000, + -832546800, + -812588400, + -798073200, + -781052400, + -772066800, + -764805600, + -748476000, + -733356000, + -719445600, + -717030000, + -706748400, + -699487200, + -687996000, + -668037600, + -654732000, + -636588000, + -622072800, + -605743200, + -590623200, + -574293600, + -558568800, + -542239200, + -527119200, + -512604000, + -496274400, + -481154400, + -464220000, + -449704800, + -432165600, + -417650400, + -401320800, + 378687600, + 401850000, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": -1284 + }, + { + "offset": 0 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + }, + { + "offset": 3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-355a4a5906a54477-e95040f92d9fdd8d.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-355a4a5906a54477-e95040f92d9fdd8d.json new file mode 100644 index 00000000000000..ab0fb4881687ca --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-355a4a5906a54477-e95040f92d9fdd8d.json @@ -0,0 +1,38 @@ +{ + "ids": [ + "pacific/nauru" + ], + "tzif": { + "posix": { + "abbr": "+12", + "offset": 43200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 3 + ], + "transitions": [ + -1545131260, + -862918200, + -767350800, + 287418600 + ], + "types": [ + { + "offset": 40060 + }, + { + "offset": 41400 + }, + { + "offset": 32400 + }, + { + "offset": 43200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3567a65ce3b07b4a-eda38ce2d13af268.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3567a65ce3b07b4a-eda38ce2d13af268.json new file mode 100644 index 00000000000000..199abb8a269e02 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3567a65ce3b07b4a-eda38ce2d13af268.json @@ -0,0 +1,105 @@ +{ + "ids": [ + "america/fortaleza" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1767216360, + -1206957600, + -1191362400, + -1175374800, + -1159826400, + -633819600, + -622069200, + -602283600, + -591832800, + -570747600, + -560210400, + -539125200, + -531352800, + -191365200, + -184197600, + -155163600, + -150069600, + -128898000, + -121125600, + -99954000, + -89589600, + -68418000, + -57967200, + 499748400, + 511236000, + 530593200, + 540266400, + 562129200, + 571197600, + 592974000, + 602042400, + 624423600, + 634701600, + 938919600, + 951616800, + 970974000, + 972180000, + 1003028400, + 1013911200 + ], + "types": [ + { + "offset": -9240 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-36890fddb7a9031e-81d4ff9e4c89f2e8.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-36890fddb7a9031e-81d4ff9e4c89f2e8.json new file mode 100644 index 00000000000000..694b3d0dd1ee51 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-36890fddb7a9031e-81d4ff9e4c89f2e8.json @@ -0,0 +1,193 @@ +{ + "ids": [ + "asia/chita" + ], + "tzif": { + "posix": { + "abbr": "+09", + "offset": 32400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 5, + 1, + 2, + 4 + ], + "transitions": [ + -1579419232, + -1247558400, + 354898800, + 370706400, + 386434800, + 402242400, + 417970800, + 433778400, + 449593200, + 465325200, + 481050000, + 496774800, + 512499600, + 528224400, + 543949200, + 559674000, + 575398800, + 591123600, + 606848400, + 622573200, + 638298000, + 654627600, + 670352400, + 670356000, + 686080800, + 695757600, + 701802000, + 717526800, + 733251600, + 748976400, + 764701200, + 780426000, + 796150800, + 811875600, + 828205200, + 846349200, + 859654800, + 877798800, + 891104400, + 909248400, + 922554000, + 941302800, + 954003600, + 972752400, + 985453200, + 1004202000, + 1017507600, + 1035651600, + 1048957200, + 1067101200, + 1080406800, + 1099155600, + 1111856400, + 1130605200, + 1143306000, + 1162054800, + 1174755600, + 1193504400, + 1206810000, + 1224954000, + 1238259600, + 1256403600, + 1269709200, + 1288458000, + 1301158800, + 1414252800, + 1459015200 + ], + "types": [ + { + "offset": 27232 + }, + { + "offset": 28800 + }, + { + "offset": 32400 + }, + { + "offset": 36000 + }, + { + "offset": 32400 + }, + { + "offset": 36000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-37762e44a2edd792-4f1b10d181e56a5d.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-37762e44a2edd792-4f1b10d181e56a5d.json new file mode 100644 index 00000000000000..b7ec567d32235d --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-37762e44a2edd792-4f1b10d181e56a5d.json @@ -0,0 +1,151 @@ +{ + "ids": [ + "asia/nicosia", + "europe/nicosia" + ], + "tzif": { + "posix": { + "abbr": "EET", + "offset": 7200, + "transition": { + "abbr": "EEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 14400 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2 + ], + "transitions": [ + -1518920008, + 166572000, + 182293200, + 200959200, + 213829200, + 228866400, + 243982800, + 260316000, + 276123600, + 291765600, + 307486800, + 323820000, + 338936400, + 354664800, + 370386000, + 386114400, + 401835600, + 417564000, + 433285200, + 449013600, + 465339600, + 481068000, + 496789200, + 512517600, + 528238800, + 543967200, + 559688400, + 575416800, + 591138000, + 606866400, + 622587600, + 638316000, + 654642000, + 670370400, + 686091600, + 701820000, + 717541200, + 733269600, + 748990800, + 764719200, + 780440400, + 796168800, + 811890000, + 828223200, + 843944400, + 859672800, + 875394000, + 891122400 + ], + "types": [ + { + "offset": 8008 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-380c01b13aae6590-113f60eeecce7355.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-380c01b13aae6590-113f60eeecce7355.json new file mode 100644 index 00000000000000..b297d4d4220e13 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-380c01b13aae6590-113f60eeecce7355.json @@ -0,0 +1,169 @@ +{ + "ids": [ + "america/argentina/ushuaia" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 3, + 4, + 3, + 4, + 2, + 3, + 4, + 5, + 3, + 4 + ], + "transitions": [ + -2372095608, + -1567453392, + -1233432000, + -1222981200, + -1205956800, + -1194037200, + -1172865600, + -1162501200, + -1141329600, + -1130965200, + -1109793600, + -1099429200, + -1078257600, + -1067806800, + -1046635200, + -1036270800, + -1015099200, + -1004734800, + -983563200, + -973198800, + -952027200, + -941576400, + -931032000, + -900882000, + -890337600, + -833749200, + -827265600, + -752274000, + -733780800, + -197326800, + -190843200, + -184194000, + -164491200, + -152658000, + -132955200, + -121122000, + -101419200, + -86821200, + -71092800, + -54766800, + -39038400, + -23317200, + -7588800, + 128142000, + 136605600, + 596948400, + 605066400, + 624423600, + 636516000, + 656478000, + 667965600, + 687927600, + 699415200, + 719377200, + 731469600, + 938919600, + 952052400, + 1085886000, + 1087704000, + 1198983600, + 1205632800 + ], + "types": [ + { + "offset": -16392 + }, + { + "offset": -15408 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-38d88ef47726082c-a2b861350ff9abaf.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-38d88ef47726082c-a2b861350ff9abaf.json new file mode 100644 index 00000000000000..732b957b94c895 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-38d88ef47726082c-a2b861350ff9abaf.json @@ -0,0 +1,38 @@ +{ + "ids": [ + "america/guyana" + ], + "tzif": { + "posix": { + "abbr": "-04", + "offset": -14400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 1 + ], + "transitions": [ + -1843589241, + -1730577600, + 176096700, + 701841600 + ], + "types": [ + { + "offset": -13959 + }, + { + "offset": -14400 + }, + { + "offset": -13500 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3994d21beae7c7b6-eb145d056159d80.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3994d21beae7c7b6-eb145d056159d80.json new file mode 100644 index 00000000000000..5eda4ef05aa56a --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3994d21beae7c7b6-eb145d056159d80.json @@ -0,0 +1,408 @@ +{ + "ids": [ + "america/new_york", + "est5edt", + "us/eastern" + ], + "tzif": { + "posix": { + "abbr": "EST", + "offset": -18000, + "transition": { + "abbr": "EDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2717650800, + -1633280400, + -1615140000, + -1601830800, + -1583690400, + -1570381200, + -1551636000, + -1536512400, + -1523210400, + -1504458000, + -1491760800, + -1473008400, + -1459706400, + -1441558800, + -1428256800, + -1410109200, + -1396807200, + -1378659600, + -1365357600, + -1347210000, + -1333908000, + -1315155600, + -1301853600, + -1283706000, + -1270404000, + -1252256400, + -1238954400, + -1220806800, + -1207504800, + -1189357200, + -1176055200, + -1157302800, + -1144605600, + -1125853200, + -1112551200, + -1094403600, + -1081101600, + -1062954000, + -1049652000, + -1031504400, + -1018202400, + -1000054800, + -986752800, + -968000400, + -955303200, + -936550800, + -923248800, + -905101200, + -891799200, + -880218000, + -769395600, + -765396000, + -747248400, + -733946400, + -715798800, + -702496800, + -684349200, + -671047200, + -652899600, + -639597600, + -620845200, + -608148000, + -589395600, + -576093600, + -557946000, + -544644000, + -526496400, + -513194400, + -495046800, + -481744800, + -463597200, + -447271200, + -431542800, + -415821600, + -400093200, + -384372000, + -368643600, + -352922400, + -337194000, + -321472800, + -305744400, + -289418400, + -273690000, + -257968800, + -242240400, + -226519200, + -210790800, + -195069600, + -179341200, + -163620000, + -147891600, + -131565600, + -116442000, + -100116000, + -84387600, + -68666400, + -52938000, + -37216800, + -21488400, + -5767200, + 9961200, + 25682400, + 41410800, + 57736800, + 73465200, + 89186400, + 104914800, + 120636000, + 126687600, + 152085600, + 162370800, + 183535200, + 199263600, + 215589600, + 230713200, + 247039200, + 262767600, + 278488800, + 294217200, + 309938400, + 325666800, + 341388000, + 357116400, + 372837600, + 388566000, + 404892000, + 420015600, + 436341600, + 452070000, + 467791200, + 483519600, + 499240800, + 514969200, + 530690400, + 544604400, + 562140000, + 576054000, + 594194400, + 607503600, + 625644000, + 638953200, + 657093600, + 671007600, + 688543200, + 702457200, + 719992800, + 733906800, + 752047200, + 765356400, + 783496800, + 796806000, + 814946400, + 828860400, + 846396000, + 860310000, + 877845600, + 891759600, + 909295200, + 923209200, + 941349600, + 954658800, + 972799200, + 986108400, + 1004248800, + 1018162800, + 1035698400, + 1049612400, + 1067148000, + 1081062000, + 1099202400, + 1112511600, + 1130652000, + 1143961200, + 1162101600, + 1173596400, + 1194156000 + ], + "types": [ + { + "offset": -17762 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3a07d4451f21c9ef-6b2242eea52b976b.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3a07d4451f21c9ef-6b2242eea52b976b.json new file mode 100644 index 00000000000000..bed8302e00b057 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3a07d4451f21c9ef-6b2242eea52b976b.json @@ -0,0 +1,265 @@ +{ + "ids": [ + "europe/warsaw", + "poland" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": { + "abbr": "CEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 3, + 4, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1 + ], + "transitions": [ + -2840145840, + -1717032240, + -1693706400, + -1680483600, + -1663455600, + -1650150000, + -1632006000, + -1618700400, + -1600473600, + -1587168000, + -1501725600, + -931734000, + -857257200, + -844556400, + -828226800, + -812502000, + -796608000, + -778726800, + -762660000, + -748486800, + -733273200, + -715215600, + -701910000, + -684975600, + -670460400, + -654130800, + -639010800, + -397094400, + -386812800, + -371088000, + -355363200, + -334195200, + -323308800, + -307584000, + -291859200, + -271296000, + -260409600, + -239846400, + -228960000, + -208396800, + -197510400, + -176342400, + -166060800, + 228873600, + 243993600, + 260323200, + 276048000, + 291772800, + 307497600, + 323827200, + 338947200, + 354672000, + 370396800, + 386121600, + 401846400, + 417571200, + 433296000, + 449020800, + 465350400, + 481075200, + 496800000, + 512524800, + 528249600, + 543974400, + 559699200, + 567990000, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": 5040 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3a5a827f28d118e9-682e0a2d838b16ae.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3a5a827f28d118e9-682e0a2d838b16ae.json new file mode 100644 index 00000000000000..edbab3547764d7 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3a5a827f28d118e9-682e0a2d838b16ae.json @@ -0,0 +1,481 @@ +{ + "ids": [ + "america/chicago", + "cst6cdt", + "us/central" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": { + "abbr": "CDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1 + ], + "transitions": [ + -2717647200, + -1633276800, + -1615136400, + -1601827200, + -1583686800, + -1563724800, + -1551632400, + -1538928000, + -1520182800, + -1504454400, + -1491757200, + -1473004800, + -1459702800, + -1441555200, + -1428253200, + -1410105600, + -1396803600, + -1378656000, + -1365354000, + -1347206400, + -1333904400, + -1315152000, + -1301850000, + -1283702400, + -1270400400, + -1252252800, + -1238950800, + -1220803200, + -1207501200, + -1189353600, + -1176051600, + -1157299200, + -1144602000, + -1125849600, + -1112547600, + -1094400000, + -1081098000, + -1067788800, + -1045414800, + -1031500800, + -1018198800, + -1000051200, + -986749200, + -967996800, + -955299600, + -936547200, + -923245200, + -905097600, + -891795600, + -880214400, + -769395600, + -765392400, + -747244800, + -733942800, + -715795200, + -702493200, + -684345600, + -671043600, + -652896000, + -639594000, + -620841600, + -608144400, + -589392000, + -576090000, + -557942400, + -544640400, + -526492800, + -513190800, + -495043200, + -481741200, + -463593600, + -447267600, + -431539200, + -415818000, + -400089600, + -384368400, + -368640000, + -352918800, + -337190400, + -321469200, + -305740800, + -289414800, + -273686400, + -257965200, + -242236800, + -226515600, + -210787200, + -195066000, + -179337600, + -163616400, + -147888000, + -131562000, + -116438400, + -100112400, + -84384000, + -68662800, + -52934400, + -37213200, + -21484800, + -5763600, + 9964800, + 25686000, + 41414400, + 57740400, + 73468800, + 89190000, + 104918400, + 120639600, + 126691200, + 152089200, + 162374400, + 183538800, + 199267200, + 215593200, + 230716800, + 247042800, + 262771200, + 278492400, + 294220800, + 309942000, + 325670400, + 341391600, + 357120000, + 372841200, + 388569600, + 404895600, + 420019200, + 436345200, + 452073600, + 467794800, + 483523200, + 499244400, + 514972800, + 530694000, + 544608000, + 562143600, + 576057600, + 594198000, + 607507200, + 625647600, + 638956800, + 657097200, + 671011200, + 688546800, + 702460800, + 719996400, + 733910400, + 752050800, + 765360000, + 783500400, + 796809600, + 814950000, + 828864000, + 846399600, + 860313600, + 877849200, + 891763200, + 909298800, + 923212800, + 941353200, + 954662400, + 972802800, + 986112000, + 1004252400, + 1018166400, + 1035702000, + 1049616000, + 1067151600, + 1081065600, + 1099206000, + 1112515200, + 1130655600, + 1143964800, + 1162105200, + 1173600000, + 1194159600 + ], + "types": [ + { + "offset": -21036 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3a6fecb09c143b25-73487cfbfb37a1d6.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3a6fecb09c143b25-73487cfbfb37a1d6.json new file mode 100644 index 00000000000000..6dd3b910d77f8c --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3a6fecb09c143b25-73487cfbfb37a1d6.json @@ -0,0 +1,236 @@ +{ + "ids": [ + "america/edmonton", + "america/yellowknife", + "canada/mountain" + ], + "tzif": { + "posix": { + "abbr": "MST", + "offset": -25200, + "transition": { + "abbr": "MDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1998663968, + -1632063600, + -1615132800, + -1600614000, + -1596816000, + -1567954800, + -1551628800, + -1536505200, + -1523203200, + -1504450800, + -1491753600, + -1473001200, + -1459699200, + -880210800, + -769395600, + -765388800, + -715791600, + -702489600, + 73472400, + 89193600, + 104922000, + 120643200, + 136371600, + 152092800, + 167821200, + 183542400, + 199270800, + 215596800, + 230720400, + 247046400, + 262774800, + 278496000, + 294224400, + 309945600, + 325674000, + 341395200, + 357123600, + 372844800, + 388573200, + 404899200, + 420022800, + 436348800, + 452077200, + 467798400, + 483526800, + 499248000, + 514976400, + 530697600, + 536482800, + 562147200, + 576061200, + 594201600, + 607510800, + 625651200, + 638960400, + 657100800, + 671014800, + 688550400, + 702464400, + 720000000, + 733914000, + 752054400, + 765363600, + 783504000, + 796813200, + 814953600, + 828867600, + 846403200, + 860317200, + 877852800, + 891766800, + 909302400, + 923216400, + 941356800, + 954666000, + 972806400, + 986115600, + 1004256000, + 1018170000, + 1035705600, + 1049619600, + 1067155200, + 1081069200, + 1099209600, + 1112518800, + 1130659200, + 1143968400, + 1162108800, + 1173603600, + 1194163200 + ], + "types": [ + { + "offset": -27232 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3c8506b1fc96536c-4c88dd0e00eba4f2.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3c8506b1fc96536c-4c88dd0e00eba4f2.json new file mode 100644 index 00000000000000..75fd4000318d9c --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3c8506b1fc96536c-4c88dd0e00eba4f2.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt+1" + ], + "tzif": { + "posix": { + "abbr": "-01", + "offset": -3600, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": -3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3cc59865618b9844-e109dc95307db988.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3cc59865618b9844-e109dc95307db988.json new file mode 100644 index 00000000000000..787916aff640af --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3cc59865618b9844-e109dc95307db988.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt-5" + ], + "tzif": { + "posix": { + "abbr": "+05", + "offset": 18000, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": 18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3cc8439b3e85f059-8e4f59b418f8888a.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3cc8439b3e85f059-8e4f59b418f8888a.json new file mode 100644 index 00000000000000..ba409c58b518f2 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3cc8439b3e85f059-8e4f59b418f8888a.json @@ -0,0 +1,227 @@ +{ + "ids": [ + "america/cambridge_bay" + ], + "tzif": { + "posix": { + "abbr": "MST", + "offset": -25200, + "transition": { + "abbr": "MDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 3, + 4, + 4, + 5, + 2, + 3, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1 + ], + "transitions": [ + -1577923200, + -880210800, + -769395600, + -765388800, + 73472400, + 89193600, + 104922000, + 120643200, + 136371600, + 152092800, + 167821200, + 183542400, + 199270800, + 215596800, + 230720400, + 247046400, + 262774800, + 278496000, + 294224400, + 309945600, + 325674000, + 341395200, + 357123600, + 372844800, + 388573200, + 404899200, + 420022800, + 436348800, + 452077200, + 467798400, + 483526800, + 499248000, + 514976400, + 530697600, + 544611600, + 562147200, + 576061200, + 594201600, + 607510800, + 625651200, + 638960400, + 657100800, + 671014800, + 688550400, + 702464400, + 720000000, + 733914000, + 752054400, + 765363600, + 783504000, + 796813200, + 814953600, + 828867600, + 846403200, + 860317200, + 877852800, + 891766800, + 909302400, + 923216400, + 941356800, + 954662400, + 972802800, + 973400400, + 986115600, + 1004256000, + 1018170000, + 1035705600, + 1049619600, + 1067155200, + 1081069200, + 1099209600, + 1112518800, + 1130659200, + 1143968400, + 1162108800, + 1173603600, + 1194163200 + ], + "types": [ + { + "offset": 0 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3d390ef79718594a-1d54abd9de1f791b.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3d390ef79718594a-1d54abd9de1f791b.json new file mode 100644 index 00000000000000..600da5393ecd4c --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3d390ef79718594a-1d54abd9de1f791b.json @@ -0,0 +1,71 @@ +{ + "ids": [ + "america/merida" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1 + ], + "transitions": [ + -1514743200, + 378201600, + 405068400, + 828864000, + 846399600, + 860313600, + 877849200, + 891763200, + 909298800, + 923212800, + 941353200, + 954662400, + 972802800, + 989136000, + 1001833200, + 1018166400, + 1035702000 + ], + "types": [ + { + "offset": -21508 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3d5473248adfd22d-72a86f7189e4c492.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3d5473248adfd22d-72a86f7189e4c492.json new file mode 100644 index 00000000000000..e262510dcdafcf --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3d5473248adfd22d-72a86f7189e4c492.json @@ -0,0 +1,77 @@ +{ + "ids": [ + "america/swift_current" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3 + ], + "transitions": [ + -2030201320, + -1632063600, + -1615132800, + -880210800, + -769395600, + -765388800, + -747241200, + -732729600, + -715791600, + -702489600, + -684342000, + -671040000, + -652892400, + -639590400, + -400086000, + -384364800, + -337186800, + -321465600, + -305737200, + -292435200, + -273682800, + -260985600, + 73472400 + ], + "types": [ + { + "offset": -25880 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + }, + { + "offset": -21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3f61f7ebb7b0f5d7-3b9e017c8df909f8.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3f61f7ebb7b0f5d7-3b9e017c8df909f8.json new file mode 100644 index 00000000000000..2ce32d5c52846b --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3f61f7ebb7b0f5d7-3b9e017c8df909f8.json @@ -0,0 +1,558 @@ +{ + "ids": [ + "asia/gaza" + ], + "tzif": { + "posix": { + "abbr": "EET", + "offset": 7200, + "transition": { + "abbr": "EEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 4, + 6 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 4, + 6 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2185409872, + -933638400, + -923097600, + -919036800, + -857347200, + -844300800, + -825811200, + -812678400, + -794188800, + -779846400, + -762652800, + -748310400, + -731116800, + -399088800, + -386650800, + -368330400, + -355114800, + -336790800, + -323654400, + -305168400, + -292032000, + -273632400, + -260496000, + -242096400, + -228960000, + -210560400, + -197424000, + -178938000, + -165801600, + -147402000, + -134265600, + -115866000, + -102643200, + -84330000, + -81313200, + 142380000, + 150843600, + 167176800, + 178664400, + 334101600, + 337730400, + 452642400, + 462319200, + 482277600, + 494370000, + 516751200, + 526424400, + 545436000, + 558478800, + 576626400, + 589323600, + 609890400, + 620773200, + 638316000, + 651618000, + 669765600, + 683672400, + 701820000, + 715726800, + 733701600, + 747176400, + 765151200, + 778021200, + 796600800, + 810075600, + 820447200, + 828655200, + 843170400, + 860104800, + 874620000, + 891554400, + 906069600, + 924213600, + 939934800, + 956268000, + 971989200, + 987717600, + 1003438800, + 1019167200, + 1034888400, + 1050616800, + 1066338000, + 1082066400, + 1096581600, + 1113516000, + 1128380400, + 1143842400, + 1158872400, + 1175378400, + 1189638000, + 1206655200, + 1219957200, + 1238104800, + 1252015200, + 1269640860, + 1281474000, + 1301608860, + 1312146000, + 1333058400, + 1348178400, + 1364508000, + 1380229200, + 1395957600, + 1414098000, + 1427493600, + 1445551200, + 1458946800, + 1477692000, + 1490396400, + 1509141600, + 1521846000, + 1540591200, + 1553810400, + 1572037200, + 1585346400, + 1603490400, + 1616796000, + 1635458400, + 1648332000, + 1666998000, + 1682726400, + 1698447600, + 1713571200, + 1729897200, + 1744416000, + 1761346800, + 1774656000, + 1792796400, + 1806105600, + 1824850800, + 1837555200, + 1856300400, + 1869004800, + 1887750000, + 1901059200, + 1919199600, + 1932508800, + 1950649200, + 1963958400, + 1982703600, + 1995408000, + 2014153200, + 2026857600, + 2045602800, + 2058307200, + 2077052400, + 2090361600, + 2107897200, + 2121811200, + 2138742000, + 2153260800, + 2168982000, + 2184710400, + 2199826800, + 2216160000, + 2230066800, + 2234304000, + 2234905200, + 2248214400, + 2260911600, + 2264544000, + 2266354800, + 2279664000, + 2291756400, + 2295388800, + 2297804400, + 2311113600, + 2321996400, + 2326233600, + 2329254000, + 2342563200, + 2352841200, + 2356473600, + 2361308400, + 2374012800, + 2383686000, + 2387318400, + 2392758000, + 2405462400, + 2413926000, + 2418163200, + 2424207600, + 2437516800, + 2444770800, + 2448403200, + 2455657200, + 2468966400, + 2475010800, + 2479248000, + 2487106800, + 2500416000, + 2505855600, + 2509488000, + 2519161200, + 2531865600, + 2536700400, + 2540332800, + 2550610800, + 2563315200, + 2566940400, + 2571177600, + 2582060400, + 2595369600, + 2597785200, + 2601417600, + 2613510000, + 2626819200, + 2628025200, + 2632262400, + 2644959600, + 2658268800, + 2658870000, + 2663107200, + 2676409200, + 2693347200, + 2708463600, + 2724192000, + 2739913200, + 2754432000, + 2771362800, + 2785276800, + 2802812400, + 2816121600, + 2834262000, + 2847571200, + 2866316400, + 2879020800, + 2897766000, + 2910470400, + 2929215600, + 2941920000, + 2960665200, + 2973974400, + 2992114800, + 3005424000, + 3023564400, + 3036873600, + 3055618800, + 3068323200, + 3087068400, + 3099772800, + 3117913200, + 3131827200, + 3148758000, + 3163276800, + 3179602800, + 3194726400, + 3209842800, + 3226176000, + 3240687600, + 3244320000, + 3244921200 + ], + "types": [ + { + "offset": 8272 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3f6ff680ea89333b-f07f1041c6be937.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3f6ff680ea89333b-f07f1041c6be937.json new file mode 100644 index 00000000000000..4007c94b4cf33e --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3f6ff680ea89333b-f07f1041c6be937.json @@ -0,0 +1,191 @@ +{ + "ids": [ + "asia/yakutsk" + ], + "tzif": { + "posix": { + "abbr": "+09", + "offset": 32400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 5, + 2, + 4 + ], + "transitions": [ + -1579423138, + -1247558400, + 354898800, + 370706400, + 386434800, + 402242400, + 417970800, + 433778400, + 449593200, + 465325200, + 481050000, + 496774800, + 512499600, + 528224400, + 543949200, + 559674000, + 575398800, + 591123600, + 606848400, + 622573200, + 638298000, + 654627600, + 670352400, + 670356000, + 686080800, + 695757600, + 701802000, + 717526800, + 733251600, + 748976400, + 764701200, + 780426000, + 796150800, + 811875600, + 828205200, + 846349200, + 859654800, + 877798800, + 891104400, + 909248400, + 922554000, + 941302800, + 954003600, + 972752400, + 985453200, + 1004202000, + 1017507600, + 1035651600, + 1048957200, + 1067101200, + 1080406800, + 1099155600, + 1111856400, + 1130605200, + 1143306000, + 1162054800, + 1174755600, + 1193504400, + 1206810000, + 1224954000, + 1238259600, + 1256403600, + 1269709200, + 1288458000, + 1301158800, + 1414252800 + ], + "types": [ + { + "offset": 31138 + }, + { + "offset": 28800 + }, + { + "offset": 32400 + }, + { + "offset": 36000 + }, + { + "offset": 32400 + }, + { + "offset": 36000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3fc16258c94fd1bd-f5865999bedfb5cb.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3fc16258c94fd1bd-f5865999bedfb5cb.json new file mode 100644 index 00000000000000..a0cd891d06c297 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3fc16258c94fd1bd-f5865999bedfb5cb.json @@ -0,0 +1,306 @@ +{ + "ids": [ + "america/ensenada", + "america/santa_isabel", + "america/tijuana", + "mexico/bajanorte" + ], + "tzif": { + "posix": { + "abbr": "PST", + "offset": -28800, + "transition": { + "abbr": "PDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 3, + 2, + 1, + 3, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2 + ], + "transitions": [ + -1514739600, + -1451667600, + -1343145600, + -1234803600, + -1222963200, + -1207242000, + -873820800, + -769395600, + -761418000, + -686073600, + -661539600, + -620755200, + -608144400, + -589384800, + -576082800, + -557935200, + -544633200, + -495039600, + -481734000, + -463590000, + -450284400, + -431535600, + -418230000, + -400086000, + -386780400, + -368636400, + -355330800, + -337186800, + -323881200, + -305737200, + -292431600, + 199274400, + 215600400, + 230724000, + 247050000, + 262778400, + 278499600, + 294228000, + 309949200, + 325677600, + 341398800, + 357127200, + 372848400, + 388576800, + 404902800, + 420026400, + 436352400, + 452080800, + 467802000, + 483530400, + 499251600, + 514980000, + 530701200, + 544615200, + 562150800, + 576064800, + 594205200, + 607514400, + 625654800, + 638964000, + 657104400, + 671018400, + 688554000, + 702468000, + 720003600, + 733917600, + 752058000, + 765367200, + 783507600, + 796816800, + 814957200, + 828871200, + 846406800, + 860320800, + 877856400, + 891770400, + 909306000, + 923220000, + 941360400, + 954669600, + 972810000, + 986119200, + 1004259600, + 1018173600, + 1035709200, + 1049623200, + 1067158800, + 1081072800, + 1099213200, + 1112522400, + 1130662800, + 1143972000, + 1162112400, + 1175421600, + 1193562000, + 1207476000, + 1225011600, + 1238925600, + 1256461200 + ], + "types": [ + { + "offset": -28084 + }, + { + "offset": -25200 + }, + { + "offset": -28800 + }, + { + "offset": -25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3fd85b535272f921-d61e3c0d217e3de2.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3fd85b535272f921-d61e3c0d217e3de2.json new file mode 100644 index 00000000000000..bff57591b70e74 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-3fd85b535272f921-d61e3c0d217e3de2.json @@ -0,0 +1,191 @@ +{ + "ids": [ + "asia/vladivostok" + ], + "tzif": { + "posix": { + "abbr": "+10", + "offset": 36000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 5, + 2, + 4 + ], + "transitions": [ + -1487321251, + -1247562000, + 354895200, + 370702800, + 386431200, + 402238800, + 417967200, + 433774800, + 449589600, + 465321600, + 481046400, + 496771200, + 512496000, + 528220800, + 543945600, + 559670400, + 575395200, + 591120000, + 606844800, + 622569600, + 638294400, + 654624000, + 670348800, + 670352400, + 686077200, + 695754000, + 701798400, + 717523200, + 733248000, + 748972800, + 764697600, + 780422400, + 796147200, + 811872000, + 828201600, + 846345600, + 859651200, + 877795200, + 891100800, + 909244800, + 922550400, + 941299200, + 954000000, + 972748800, + 985449600, + 1004198400, + 1017504000, + 1035648000, + 1048953600, + 1067097600, + 1080403200, + 1099152000, + 1111852800, + 1130601600, + 1143302400, + 1162051200, + 1174752000, + 1193500800, + 1206806400, + 1224950400, + 1238256000, + 1256400000, + 1269705600, + 1288454400, + 1301155200, + 1414249200 + ], + "types": [ + { + "offset": 31651 + }, + { + "offset": 32400 + }, + { + "offset": 36000 + }, + { + "offset": 39600 + }, + { + "offset": 36000 + }, + { + "offset": 39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-401f78ac94f3eb66-89897df479278829.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-401f78ac94f3eb66-89897df479278829.json new file mode 100644 index 00000000000000..ce7840183cce49 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-401f78ac94f3eb66-89897df479278829.json @@ -0,0 +1,223 @@ +{ + "ids": [ + "australia/melbourne", + "australia/victoria" + ], + "tzif": { + "posix": { + "abbr": "AEST", + "offset": 36000, + "transition": { + "abbr": "AEDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 4, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 1, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2 + ], + "transitions": [ + -2364111592, + -1672560000, + -1665388800, + -883641600, + -876124800, + -860400000, + -844675200, + -828345600, + -813225600, + 57686400, + 67968000, + 89136000, + 100022400, + 120585600, + 131472000, + 152035200, + 162921600, + 183484800, + 194976000, + 215539200, + 226425600, + 246988800, + 257875200, + 278438400, + 289324800, + 309888000, + 320774400, + 341337600, + 352224000, + 372787200, + 384278400, + 404841600, + 415728000, + 436291200, + 447177600, + 467740800, + 478627200, + 499190400, + 511286400, + 530035200, + 542736000, + 561484800, + 574790400, + 594144000, + 606240000, + 625593600, + 637689600, + 657043200, + 667929600, + 688492800, + 699379200, + 719942400, + 731433600, + 751996800, + 762883200, + 783446400, + 796147200, + 814896000, + 828201600, + 846345600, + 859651200, + 877795200, + 891100800, + 909244800, + 922550400, + 941299200, + 954000000, + 967305600, + 985449600, + 1004198400, + 1017504000, + 1035648000, + 1048953600, + 1067097600, + 1080403200, + 1099152000, + 1111852800, + 1130601600, + 1143907200, + 1162051200, + 1174752000, + 1193500800, + 1207411200, + 1223136000 + ], + "types": [ + { + "offset": 34792 + }, + { + "offset": 36000 + }, + { + "offset": 39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-405b02408f1a7725-3c0ae0a258a25979.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-405b02408f1a7725-3c0ae0a258a25979.json new file mode 100644 index 00000000000000..211fe410dc780e --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-405b02408f1a7725-3c0ae0a258a25979.json @@ -0,0 +1,66 @@ +{ + "ids": [ + "asia/manila" + ], + "tzif": { + "posix": { + "abbr": "PST", + "offset": 28800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 3, + 4, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2 + ], + "transitions": [ + -3944621032, + -2219083200, + -1046678400, + -1040115600, + -885024000, + -880016400, + -783594000, + -760093200, + -496224000, + -491562000, + 228326400, + 243702000, + 643219200, + 649177200 + ], + "types": [ + { + "offset": -57368 + }, + { + "offset": 29032 + }, + { + "offset": 28800 + }, + { + "offset": 32400 + }, + { + "offset": 32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-40fb52b19ef81b1d-e1ce3cc4e0a17886.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-40fb52b19ef81b1d-e1ce3cc4e0a17886.json new file mode 100644 index 00000000000000..079082964c00d6 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-40fb52b19ef81b1d-e1ce3cc4e0a17886.json @@ -0,0 +1,82 @@ +{ + "ids": [ + "america/mazatlan", + "mexico/bajasur" + ], + "tzif": { + "posix": { + "abbr": "MST", + "offset": -25200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1 + ], + "transitions": [ + -1514739600, + -1343149200, + -1234807200, + -1220461200, + -1207159200, + -1191344400, + -873828000, + 828867600, + 846403200, + 860317200, + 877852800, + 891766800, + 909302400, + 923216400, + 941356800, + 954666000, + 972806400, + 989139600, + 1001836800, + 1018170000, + 1035705600 + ], + "types": [ + { + "offset": -25540 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + }, + { + "offset": -21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-42518274487a5d74-63fffb5b4ef7fbd9.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-42518274487a5d74-63fffb5b4ef7fbd9.json new file mode 100644 index 00000000000000..0692594390a83a --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-42518274487a5d74-63fffb5b4ef7fbd9.json @@ -0,0 +1,28 @@ +{ + "ids": [ + "etc/gmt", + "etc/gmt+0", + "etc/gmt-0", + "etc/gmt0", + "etc/greenwich", + "gmt", + "gmt+0", + "gmt-0", + "gmt0", + "greenwich" + ], + "tzif": { + "posix": { + "abbr": "GMT", + "offset": 0, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": 0 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-425a92f6316d948f-f81669d6e3b37009.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-425a92f6316d948f-f81669d6e3b37009.json new file mode 100644 index 00000000000000..ce7bd0e255881c --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-425a92f6316d948f-f81669d6e3b37009.json @@ -0,0 +1,33 @@ +{ + "ids": [ + "america/el_salvador" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1 + ], + "transitions": [ + -1546279392, + 547020000, + 559717200 + ], + "types": [ + { + "offset": -21408 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-43c01a519dcad360-c978a2de09220f3e.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-43c01a519dcad360-c978a2de09220f3e.json new file mode 100644 index 00000000000000..e7a2242e2633e9 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-43c01a519dcad360-c978a2de09220f3e.json @@ -0,0 +1,315 @@ +{ + "ids": [ + "america/vancouver", + "canada/pacific" + ], + "tzif": { + "posix": { + "abbr": "PST", + "offset": -28800, + "transition": { + "abbr": "PDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2713880852, + -1632060000, + -1615129200, + -880207200, + -769395600, + -765385200, + -747237600, + -733935600, + -715788000, + -702486000, + -684338400, + -671036400, + -652888800, + -639586800, + -620834400, + -608137200, + -589384800, + -576082800, + -557935200, + -544633200, + -526485600, + -513183600, + -495036000, + -481734000, + -463586400, + -450284400, + -431532000, + -418230000, + -400082400, + -386780400, + -368632800, + -355330800, + -337183200, + -323881200, + -305733600, + -292431600, + -273679200, + -260982000, + -242229600, + -226508400, + -210780000, + -195058800, + -179330400, + -163609200, + -147880800, + -131554800, + -116431200, + -100105200, + -84376800, + -68655600, + -52927200, + -37206000, + -21477600, + -5756400, + 9972000, + 25693200, + 41421600, + 57747600, + 73476000, + 89197200, + 104925600, + 120646800, + 136375200, + 152096400, + 167824800, + 183546000, + 199274400, + 215600400, + 230724000, + 247050000, + 262778400, + 278499600, + 294228000, + 309949200, + 325677600, + 341398800, + 357127200, + 372848400, + 388576800, + 404902800, + 420026400, + 436352400, + 452080800, + 467802000, + 483530400, + 499251600, + 514980000, + 530701200, + 536486400, + 562150800, + 576064800, + 594205200, + 607514400, + 625654800, + 638964000, + 657104400, + 671018400, + 688554000, + 702468000, + 720003600, + 733917600, + 752058000, + 765367200, + 783507600, + 796816800, + 814957200, + 828871200, + 846406800, + 860320800, + 877856400, + 891770400, + 909306000, + 923220000, + 941360400, + 954669600, + 972810000, + 986119200, + 1004259600, + 1018173600, + 1035709200, + 1049623200, + 1067158800, + 1081072800, + 1099213200, + 1112522400, + 1130662800, + 1143972000, + 1162112400, + 1173607200, + 1194166800 + ], + "types": [ + { + "offset": -29548 + }, + { + "offset": -28800 + }, + { + "offset": -25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-44b31bf3438167a2-f26149998b62ea48.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-44b31bf3438167a2-f26149998b62ea48.json new file mode 100644 index 00000000000000..0ca1bcca10a91f --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-44b31bf3438167a2-f26149998b62ea48.json @@ -0,0 +1,56 @@ +{ + "ids": [ + "australia/brisbane", + "australia/queensland" + ], + "tzif": { + "posix": { + "abbr": "AEST", + "offset": 36000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2 + ], + "transitions": [ + -2366791928, + -1672560000, + -1665388800, + -883641600, + -876124800, + -860400000, + -844675200, + -828345600, + -813225600, + 57686400, + 67968000, + 625593600, + 636480000, + 657043200 + ], + "types": [ + { + "offset": 36728 + }, + { + "offset": 36000 + }, + { + "offset": 39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4529e4629acf0366-8106ebfc9606aee2.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4529e4629acf0366-8106ebfc9606aee2.json new file mode 100644 index 00000000000000..cc15a1014678ba --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4529e4629acf0366-8106ebfc9606aee2.json @@ -0,0 +1,40 @@ +{ + "ids": [ + "america/caracas" + ], + "tzif": { + "posix": { + "abbr": "-04", + "offset": -14400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3 + ], + "transitions": [ + -2524505536, + -1826739140, + -157750200, + 1197183600, + 1462086000 + ], + "types": [ + { + "offset": -16064 + }, + { + "offset": -16060 + }, + { + "offset": -16200 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-46dd3b15bf889536-90c51dda0af69c0c.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-46dd3b15bf889536-90c51dda0af69c0c.json new file mode 100644 index 00000000000000..b110dd6b5396f0 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-46dd3b15bf889536-90c51dda0af69c0c.json @@ -0,0 +1,261 @@ +{ + "ids": [ + "america/menominee" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": { + "abbr": "CDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1 + ], + "transitions": [ + -2659759773, + -1633276800, + -1615136400, + -1601827200, + -1583686800, + -880214400, + -769395600, + -765392400, + -747244800, + -733942800, + -116438400, + -100112400, + -21484800, + 104914800, + 104918400, + 120639600, + 126691200, + 152089200, + 162374400, + 183538800, + 199267200, + 215593200, + 230716800, + 247042800, + 262771200, + 278492400, + 294220800, + 309942000, + 325670400, + 341391600, + 357120000, + 372841200, + 388569600, + 404895600, + 420019200, + 436345200, + 452073600, + 467794800, + 483523200, + 499244400, + 514972800, + 530694000, + 544608000, + 562143600, + 576057600, + 594198000, + 607507200, + 625647600, + 638956800, + 657097200, + 671011200, + 688546800, + 702460800, + 719996400, + 733910400, + 752050800, + 765360000, + 783500400, + 796809600, + 814950000, + 828864000, + 846399600, + 860313600, + 877849200, + 891763200, + 909298800, + 923212800, + 941353200, + 954662400, + 972802800, + 986112000, + 1004252400, + 1018166400, + 1035702000, + 1049616000, + 1067151600, + 1081065600, + 1099206000, + 1112515200, + 1130655600, + 1143964800, + 1162105200, + 1173600000, + 1194159600 + ], + "types": [ + { + "offset": -21027 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4738bf3d72913a1b-ef164d685fcac290.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4738bf3d72913a1b-ef164d685fcac290.json new file mode 100644 index 00000000000000..70bf116c36c34c --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4738bf3d72913a1b-ef164d685fcac290.json @@ -0,0 +1,155 @@ +{ + "ids": [ + "asia/tbilisi" + ], + "tzif": { + "posix": { + "abbr": "+04", + "offset": 14400, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 2, + 4, + 3, + 2, + 4, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 1, + 2, + 4 + ], + "transitions": [ + -2840151551, + -1441162751, + -405140400, + 354916800, + 370724400, + 386452800, + 402260400, + 417988800, + 433796400, + 449611200, + 465343200, + 481068000, + 496792800, + 512517600, + 528242400, + 543967200, + 559692000, + 575416800, + 591141600, + 606866400, + 622591200, + 638316000, + 654645600, + 670370400, + 670374000, + 686098800, + 701816400, + 717537600, + 733266000, + 748987200, + 764715600, + 780436800, + 796161600, + 811882800, + 828216000, + 859662000, + 877806000, + 891115200, + 909255600, + 922564800, + 941310000, + 954014400, + 972759600, + 985464000, + 1004209200, + 1017518400, + 1035658800, + 1048968000, + 1067108400, + 1080417600, + 1088276400, + 1099177200, + 1111878000 + ], + "types": [ + { + "offset": 10751 + }, + { + "offset": 10800 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + }, + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-480b0a55dd7bf29e-c23b37ed84c4f8f9.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-480b0a55dd7bf29e-c23b37ed84c4f8f9.json new file mode 100644 index 00000000000000..a625eea350ae4f --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-480b0a55dd7bf29e-c23b37ed84c4f8f9.json @@ -0,0 +1,233 @@ +{ + "ids": [ + "america/nome" + ], + "tzif": { + "posix": { + "abbr": "AKST", + "offset": -32400, + "transition": { + "abbr": "AKDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 3, + 2, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4 + ], + "transitions": [ + -3225223727, + -2188947502, + -880196400, + -769395600, + -765374400, + -86878800, + -21466800, + -5745600, + 9982800, + 25704000, + 41432400, + 57758400, + 73486800, + 89208000, + 104936400, + 120657600, + 126709200, + 152107200, + 162392400, + 183556800, + 199285200, + 215611200, + 230734800, + 247060800, + 262789200, + 278510400, + 294238800, + 309960000, + 325688400, + 341409600, + 357138000, + 372859200, + 388587600, + 404913600, + 420037200, + 436363200, + 439030800, + 452084400, + 467805600, + 483534000, + 499255200, + 514983600, + 530704800, + 544618800, + 562154400, + 576068400, + 594208800, + 607518000, + 625658400, + 638967600, + 657108000, + 671022000, + 688557600, + 702471600, + 720007200, + 733921200, + 752061600, + 765370800, + 783511200, + 796820400, + 814960800, + 828874800, + 846410400, + 860324400, + 877860000, + 891774000, + 909309600, + 923223600, + 941364000, + 954673200, + 972813600, + 986122800, + 1004263200, + 1018177200, + 1035712800, + 1049626800, + 1067162400, + 1081076400, + 1099216800, + 1112526000, + 1130666400, + 1143975600, + 1162116000, + 1173610800, + 1194170400 + ], + "types": [ + { + "offset": 46702 + }, + { + "offset": -39698 + }, + { + "offset": -39600 + }, + { + "offset": -36000 + }, + { + "offset": -32400 + }, + { + "offset": -28800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-486e9282debc62a3-27805d7d5dee9be4.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-486e9282debc62a3-27805d7d5dee9be4.json new file mode 100644 index 00000000000000..7d4bdf2ccb96b6 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-486e9282debc62a3-27805d7d5dee9be4.json @@ -0,0 +1,50 @@ +{ + "ids": [ + "africa/addis_ababa", + "africa/asmara", + "africa/asmera", + "africa/dar_es_salaam", + "africa/djibouti", + "africa/kampala", + "africa/mogadishu", + "africa/nairobi", + "indian/antananarivo", + "indian/comoro", + "indian/mayotte" + ], + "tzif": { + "posix": { + "abbr": "EAT", + "offset": 10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 3, + 2 + ], + "transitions": [ + -1946168836, + -1309746600, + -1261969200, + -1041388200, + -865305900 + ], + "types": [ + { + "offset": 8836 + }, + { + "offset": 9000 + }, + { + "offset": 10800 + }, + { + "offset": 9900 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4891d41993ed3f5f-4d0c2933ef920fb1.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4891d41993ed3f5f-4d0c2933ef920fb1.json new file mode 100644 index 00000000000000..dd9a049b68e60e --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4891d41993ed3f5f-4d0c2933ef920fb1.json @@ -0,0 +1,317 @@ +{ + "ids": [ + "america/fort_nelson" + ], + "tzif": { + "posix": { + "abbr": "MST", + "offset": -25200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3 + ], + "transitions": [ + -2713880953, + -1632060000, + -1615129200, + -880207200, + -769395600, + -765385200, + -715788000, + -702486000, + -684338400, + -671036400, + -652888800, + -639586800, + -620834400, + -608137200, + -589384800, + -576082800, + -557935200, + -544633200, + -526485600, + -513183600, + -495036000, + -481734000, + -463586400, + -450284400, + -431532000, + -418230000, + -400082400, + -386780400, + -368632800, + -355330800, + -337183200, + -323881200, + -305733600, + -292431600, + -273679200, + -260982000, + -242229600, + -226508400, + -210780000, + -195058800, + -179330400, + -163609200, + -147880800, + -131554800, + -116431200, + -100105200, + -84376800, + -68655600, + -52927200, + -37206000, + -21477600, + -5756400, + 9972000, + 25693200, + 41421600, + 57747600, + 73476000, + 89197200, + 104925600, + 120646800, + 136375200, + 152096400, + 167824800, + 183546000, + 199274400, + 215600400, + 230724000, + 247050000, + 262778400, + 278499600, + 294228000, + 309949200, + 325677600, + 341398800, + 357127200, + 372848400, + 388576800, + 404902800, + 420026400, + 436352400, + 452080800, + 467802000, + 483530400, + 499251600, + 514980000, + 530701200, + 536486400, + 562150800, + 576064800, + 594205200, + 607514400, + 625654800, + 638964000, + 657104400, + 671018400, + 688554000, + 702468000, + 720003600, + 733917600, + 752058000, + 765367200, + 783507600, + 796816800, + 814957200, + 828871200, + 846406800, + 860320800, + 877856400, + 891770400, + 909306000, + 923220000, + 941360400, + 954669600, + 972810000, + 986119200, + 1004259600, + 1018173600, + 1035709200, + 1049623200, + 1067158800, + 1081072800, + 1099213200, + 1112522400, + 1130662800, + 1143972000, + 1162112400, + 1173607200, + 1194166800, + 1205056800, + 1225616400, + 1236506400, + 1257066000, + 1268560800, + 1289120400, + 1300010400, + 1320570000, + 1331460000, + 1352019600, + 1362909600, + 1383469200, + 1394359200, + 1414918800, + 1425808800 + ], + "types": [ + { + "offset": -29447 + }, + { + "offset": -28800 + }, + { + "offset": -25200 + }, + { + "offset": -25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4a65bbe3253254a1-2a20d46c4d15c0c3.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4a65bbe3253254a1-2a20d46c4d15c0c3.json new file mode 100644 index 00000000000000..3238dcf5bf11de --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4a65bbe3253254a1-2a20d46c4d15c0c3.json @@ -0,0 +1,184 @@ +{ + "ids": [ + "arctic/longyearbyen", + "atlantic/jan_mayen", + "europe/berlin", + "europe/copenhagen", + "europe/oslo", + "europe/stockholm" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": { + "abbr": "CEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 2, + 1, + 2, + 1, + 2, + 3, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2422054408, + -1693706400, + -1680483600, + -1663455600, + -1650150000, + -1632006000, + -1618700400, + -938905200, + -857257200, + -844556400, + -828226800, + -812502000, + -796777200, + -781052400, + -776563200, + -765936000, + -761180400, + -748479600, + -733273200, + -717631200, + -714610800, + -710380800, + -701910000, + -684975600, + -670460400, + -654130800, + -639010800, + 323830800, + 338950800, + 354675600, + 370400400, + 386125200, + 401850000, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": 3208 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4ab862d6d4b98ff4-7628975aa4bf631a.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4ab862d6d4b98ff4-7628975aa4bf631a.json new file mode 100644 index 00000000000000..802200d8234c39 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4ab862d6d4b98ff4-7628975aa4bf631a.json @@ -0,0 +1,161 @@ +{ + "ids": [ + "europe/kiev", + "europe/kyiv", + "europe/uzhgorod", + "europe/zaporozhye" + ], + "tzif": { + "posix": { + "abbr": "EET", + "offset": 7200, + "transition": { + "abbr": "EEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 14400 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 3, + 4, + 1, + 3, + 4, + 2, + 5, + 2, + 5, + 2, + 5, + 2, + 5, + 2, + 5, + 2, + 5, + 2, + 5, + 2, + 5, + 2, + 5, + 2, + 5, + 2, + 6, + 1, + 3, + 2, + 6, + 1, + 3, + 2, + 6, + 1, + 3, + 2, + 6, + 1, + 3, + 2, + 6, + 1, + 3, + 2, + 6, + 1, + 3 + ], + "transitions": [ + -2840148124, + -1441159324, + -1247536800, + -892522800, + -857257200, + -844556400, + -828226800, + -825382800, + 354920400, + 370728000, + 386456400, + 402264000, + 417992400, + 433800000, + 449614800, + 465346800, + 481071600, + 496796400, + 512521200, + 528246000, + 543970800, + 559695600, + 575420400, + 591145200, + 606870000, + 622594800, + 638319600, + 646783200, + 686102400, + 701827200, + 717552000, + 733276800, + 749001600, + 764726400, + 780451200, + 796176000, + 811900800, + 828230400, + 846378000 + ], + "types": [ + { + "offset": 7324 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 7200 + }, + { + "offset": 3600 + }, + { + "offset": 14400 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4c9c946292d76a04-7fbd1484596ee05e.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4c9c946292d76a04-7fbd1484596ee05e.json new file mode 100644 index 00000000000000..e3d953fbeee511 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4c9c946292d76a04-7fbd1484596ee05e.json @@ -0,0 +1,175 @@ +{ + "ids": [ + "asia/oral" + ], + "tzif": { + "posix": { + "abbr": "+05", + "offset": 18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 2, + 5, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 3, + 4, + 2, + 5, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 2, + 5 + ], + "transitions": [ + -1441164324, + -1247540400, + 354913200, + 370720800, + 386445600, + 386449200, + 402256800, + 417985200, + 433792800, + 449607600, + 465339600, + 481064400, + 496789200, + 512514000, + 528238800, + 543963600, + 559688400, + 575413200, + 591138000, + 606862800, + 606866400, + 622591200, + 638316000, + 654645600, + 670370400, + 686095200, + 695772000, + 701816400, + 701820000, + 717544800, + 733269600, + 748994400, + 764719200, + 780444000, + 796168800, + 811893600, + 828223200, + 846367200, + 859672800, + 877816800, + 891122400, + 909266400, + 922572000, + 941320800, + 954021600, + 972770400, + 985471200, + 1004220000, + 1017525600, + 1035669600, + 1048975200, + 1067119200, + 1080424800, + 1099173600 + ], + "types": [ + { + "offset": 12324 + }, + { + "offset": 10800 + }, + { + "offset": 18000 + }, + { + "offset": 21600 + }, + { + "offset": 21600 + }, + { + "offset": 18000 + }, + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4ccce3697974db1-dd90a8482c7e02e0.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4ccce3697974db1-dd90a8482c7e02e0.json new file mode 100644 index 00000000000000..dde574d49a2ca0 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4ccce3697974db1-dd90a8482c7e02e0.json @@ -0,0 +1,127 @@ +{ + "ids": [ + "europe/helsinki", + "europe/mariehamn" + ], + "tzif": { + "posix": { + "abbr": "EET", + "offset": 7200, + "transition": { + "abbr": "EEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 14400 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2890258789, + -1535938789, + -875671200, + -859773600, + 354672000, + 370396800, + 386121600, + 401846400, + 410220000, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": 5989 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4db2cfd1785db9cd-6589edd5db80b603.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4db2cfd1785db9cd-6589edd5db80b603.json new file mode 100644 index 00000000000000..88b79a4d3c41ef --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4db2cfd1785db9cd-6589edd5db80b603.json @@ -0,0 +1,192 @@ +{ + "ids": [ + "asia/tomsk" + ], + "tzif": { + "posix": { + "abbr": "+07", + "offset": 25200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4 + ], + "transitions": [ + -1578807591, + -1247551200, + 354906000, + 370713600, + 386442000, + 402249600, + 417978000, + 433785600, + 449600400, + 465332400, + 481057200, + 496782000, + 512506800, + 528231600, + 543956400, + 559681200, + 575406000, + 591130800, + 606855600, + 622580400, + 638305200, + 654634800, + 670359600, + 670363200, + 686088000, + 695764800, + 701809200, + 717534000, + 733258800, + 748983600, + 764708400, + 780433200, + 796158000, + 811882800, + 828212400, + 846356400, + 859662000, + 877806000, + 891111600, + 909255600, + 922561200, + 941310000, + 954010800, + 972759600, + 985460400, + 1004209200, + 1017514800, + 1020193200, + 1035662400, + 1048968000, + 1067112000, + 1080417600, + 1099166400, + 1111867200, + 1130616000, + 1143316800, + 1162065600, + 1174766400, + 1193515200, + 1206820800, + 1224964800, + 1238270400, + 1256414400, + 1269720000, + 1288468800, + 1301169600, + 1414263600, + 1464465600 + ], + "types": [ + { + "offset": 20391 + }, + { + "offset": 21600 + }, + { + "offset": 25200 + }, + { + "offset": 28800 + }, + { + "offset": 25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4e52d8a7b9ecde7e-b7f50a3a0d1ac3b5.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4e52d8a7b9ecde7e-b7f50a3a0d1ac3b5.json new file mode 100644 index 00000000000000..923657a81ceb98 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4e52d8a7b9ecde7e-b7f50a3a0d1ac3b5.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt-7" + ], + "tzif": { + "posix": { + "abbr": "+07", + "offset": 25200, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": 25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4eaf76405b17e0d3-64c6a9f0471d4ce9.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4eaf76405b17e0d3-64c6a9f0471d4ce9.json new file mode 100644 index 00000000000000..d77bbee2e365c9 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4eaf76405b17e0d3-64c6a9f0471d4ce9.json @@ -0,0 +1,204 @@ +{ + "ids": [ + "atlantic/stanley" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3 + ], + "transitions": [ + -2524507716, + -1824235716, + -1018209600, + -1003093200, + -986760000, + -971643600, + -954705600, + -939589200, + -923256000, + -908139600, + -891806400, + -876690000, + -860356800, + -852066000, + 420609600, + 433306800, + 452052000, + 464151600, + 483501600, + 495601200, + 495604800, + 514350000, + 527054400, + 545799600, + 558504000, + 577249200, + 589953600, + 608698800, + 621403200, + 640753200, + 652852800, + 672202800, + 684907200, + 703652400, + 716356800, + 735102000, + 747806400, + 766551600, + 779256000, + 798001200, + 810705600, + 830055600, + 842760000, + 861505200, + 874209600, + 892954800, + 905659200, + 924404400, + 937108800, + 955854000, + 968558400, + 987310800, + 999410400, + 1019365200, + 1030860000, + 1050814800, + 1062914400, + 1082264400, + 1094364000, + 1113714000, + 1125813600, + 1145163600, + 1157263200, + 1176613200, + 1188712800, + 1208667600, + 1220767200, + 1240117200, + 1252216800, + 1271566800, + 1283666400 + ], + "types": [ + { + "offset": -13884 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4f0ad1968e2955-b99def3a9c716c7f.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4f0ad1968e2955-b99def3a9c716c7f.json new file mode 100644 index 00000000000000..a033cd1690e7af --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4f0ad1968e2955-b99def3a9c716c7f.json @@ -0,0 +1,181 @@ +{ + "ids": [ + "asia/aqtobe" + ], + "tzif": { + "posix": { + "abbr": "+05", + "offset": 18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 2, + 5, + 2, + 5, + 1, + 3, + 4, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5 + ], + "transitions": [ + -1441165720, + -1247544000, + 354913200, + 370720800, + 386445600, + 386449200, + 402256800, + 417985200, + 433792800, + 449607600, + 465339600, + 481064400, + 496789200, + 512514000, + 528238800, + 543963600, + 559688400, + 575413200, + 591138000, + 606862800, + 622587600, + 638312400, + 654642000, + 670366800, + 670370400, + 686095200, + 695772000, + 701816400, + 717541200, + 733266000, + 748990800, + 764715600, + 780440400, + 796165200, + 811890000, + 828219600, + 846363600, + 859669200, + 877813200, + 891118800, + 909262800, + 922568400, + 941317200, + 954018000, + 972766800, + 985467600, + 1004216400, + 1017522000, + 1035666000, + 1048971600, + 1067115600, + 1080421200, + 1099170000 + ], + "types": [ + { + "offset": 13720 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + }, + { + "offset": 21600 + }, + { + "offset": 21600 + }, + { + "offset": 18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4fd8d72ac04d9a5d-3133c7dea65f2538.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4fd8d72ac04d9a5d-3133c7dea65f2538.json new file mode 100644 index 00000000000000..e86789ea25167d --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-4fd8d72ac04d9a5d-3133c7dea65f2538.json @@ -0,0 +1,156 @@ +{ + "ids": [ + "europe/tirane" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": { + "abbr": "CEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1767230360, + -932346000, + -857257200, + -844556400, + -843519600, + 136854000, + 149896800, + 168130800, + 181432800, + 199839600, + 213141600, + 231894000, + 244591200, + 263257200, + 276040800, + 294706800, + 307490400, + 326156400, + 339458400, + 357087600, + 370389600, + 389142000, + 402444000, + 419468400, + 433807200, + 449622000, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": 4760 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5060a985014097b1-2e0f3c6f560795ff.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5060a985014097b1-2e0f3c6f560795ff.json new file mode 100644 index 00000000000000..61494cf8537715 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5060a985014097b1-2e0f3c6f560795ff.json @@ -0,0 +1,60 @@ +{ + "ids": [ + "america/barbados" + ], + "tzif": { + "posix": { + "abbr": "AST", + "offset": -14400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 3, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1841256091, + -874263600, + -862682400, + -841604400, + -830714400, + -811882800, + -798660000, + 234943200, + 244616400, + 261554400, + 276066000, + 293004000, + 307515600, + 325058400, + 338706000 + ], + "types": [ + { + "offset": -14309 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -12600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-50abe32c287395c8-d2c3aa5882246ab2.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-50abe32c287395c8-d2c3aa5882246ab2.json new file mode 100644 index 00000000000000..f5ef8aa144f049 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-50abe32c287395c8-d2c3aa5882246ab2.json @@ -0,0 +1,37 @@ +{ + "ids": [ + "asia/rangoon", + "asia/yangon", + "indian/cocos" + ], + "tzif": { + "posix": { + "abbr": "+0630", + "offset": 23400, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 1 + ], + "transitions": [ + -2840163887, + -1577946287, + -873268200, + -778410000 + ], + "types": [ + { + "offset": 23087 + }, + { + "offset": 23400 + }, + { + "offset": 32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-50fc3fea132b4f4c-5a5d88ba8de3b7c1.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-50fc3fea132b4f4c-5a5d88ba8de3b7c1.json new file mode 100644 index 00000000000000..036507d60d322d --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-50fc3fea132b4f4c-5a5d88ba8de3b7c1.json @@ -0,0 +1,254 @@ +{ + "ids": [ + "america/denver", + "america/shiprock", + "mst7mdt", + "navajo", + "us/mountain" + ], + "tzif": { + "posix": { + "abbr": "MST", + "offset": -25200, + "transition": { + "abbr": "MDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2717643600, + -1633273200, + -1615132800, + -1601823600, + -1583683200, + -1570374000, + -1551628800, + -1538924400, + -1534089600, + -880210800, + -769395600, + -765388800, + -147884400, + -131558400, + -116434800, + -100108800, + -84380400, + -68659200, + -52930800, + -37209600, + -21481200, + -5760000, + 9968400, + 25689600, + 41418000, + 57744000, + 73472400, + 89193600, + 104922000, + 120643200, + 126694800, + 152092800, + 162378000, + 183542400, + 199270800, + 215596800, + 230720400, + 247046400, + 262774800, + 278496000, + 294224400, + 309945600, + 325674000, + 341395200, + 357123600, + 372844800, + 388573200, + 404899200, + 420022800, + 436348800, + 452077200, + 467798400, + 483526800, + 499248000, + 514976400, + 530697600, + 544611600, + 562147200, + 576061200, + 594201600, + 607510800, + 625651200, + 638960400, + 657100800, + 671014800, + 688550400, + 702464400, + 720000000, + 733914000, + 752054400, + 765363600, + 783504000, + 796813200, + 814953600, + 828867600, + 846403200, + 860317200, + 877852800, + 891766800, + 909302400, + 923216400, + 941356800, + 954666000, + 972806400, + 986115600, + 1004256000, + 1018170000, + 1035705600, + 1049619600, + 1067155200, + 1081069200, + 1099209600, + 1112518800, + 1130659200, + 1143968400, + 1162108800, + 1173603600, + 1194163200 + ], + "types": [ + { + "offset": -25196 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-513821d5372dc2c3-56efcc8826fb3481.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-513821d5372dc2c3-56efcc8826fb3481.json new file mode 100644 index 00000000000000..5347109a6947d3 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-513821d5372dc2c3-56efcc8826fb3481.json @@ -0,0 +1,290 @@ +{ + "ids": [ + "europe/monaco", + "europe/paris" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": { + "abbr": "CEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4 + ], + "transitions": [ + -2486592561, + -1855958961, + -1689814800, + -1680397200, + -1665363600, + -1648342800, + -1635123600, + -1616893200, + -1604278800, + -1585443600, + -1574038800, + -1552266000, + -1539997200, + -1520557200, + -1507510800, + -1490576400, + -1470618000, + -1459126800, + -1444006800, + -1427677200, + -1411952400, + -1396227600, + -1379293200, + -1364778000, + -1348448400, + -1333328400, + -1316394000, + -1301274000, + -1284339600, + -1269824400, + -1253494800, + -1238374800, + -1221440400, + -1206925200, + -1191200400, + -1175475600, + -1160355600, + -1143421200, + -1127696400, + -1111971600, + -1096851600, + -1080522000, + -1063587600, + -1049072400, + -1033347600, + -1017622800, + -1002502800, + -986173200, + -969238800, + -950490000, + -942012000, + -932436000, + -857257200, + -844556400, + -828226800, + -812502000, + -800071200, + -796266000, + -781052400, + -766623600, + 196819200, + 212540400, + 228877200, + 243997200, + 260326800, + 276051600, + 291776400, + 307501200, + 323830800, + 338950800, + 354675600, + 370400400, + 386125200, + 401850000, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": 561 + }, + { + "offset": 0 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + }, + { + "offset": 3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-52291e736a34e36b-2ab58b9a9f408e39.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-52291e736a34e36b-2ab58b9a9f408e39.json new file mode 100644 index 00000000000000..e59d24012e655b --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-52291e736a34e36b-2ab58b9a9f408e39.json @@ -0,0 +1,273 @@ +{ + "ids": [ + "asia/damascus" + ], + "tzif": { + "posix": { + "abbr": "+03", + "offset": 10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 3 + ], + "transitions": [ + -1577931912, + -1568592000, + -1554080400, + -1537142400, + -1522630800, + -1505692800, + -1491181200, + -1474243200, + -1459126800, + -242265600, + -228877200, + -210556800, + -197427600, + -178934400, + -165718800, + -147398400, + -134269200, + -116467200, + -102646800, + -84326400, + -71110800, + -52704000, + -39488400, + -21168000, + -7952400, + 10368000, + 23583600, + 41904000, + 55119600, + 73526400, + 86742000, + 105062400, + 118278000, + 136598400, + 149814000, + 168134400, + 181350000, + 199756800, + 212972400, + 231292800, + 241916400, + 262828800, + 273452400, + 418694400, + 433810800, + 450316800, + 465433200, + 508896000, + 529196400, + 541555200, + 562633200, + 574387200, + 594255600, + 607305600, + 623199600, + 638928000, + 654649200, + 670456800, + 686264400, + 702684000, + 717886800, + 733096800, + 748904400, + 765151200, + 780958800, + 796687200, + 812494800, + 828309600, + 844117200, + 859759200, + 875653200, + 891208800, + 907189200, + 922917600, + 938725200, + 954540000, + 970347600, + 986076000, + 1001883600, + 1017612000, + 1033419600, + 1049148000, + 1064955600, + 1080770400, + 1096578000, + 1112306400, + 1128114000, + 1143842400, + 1158872400, + 1175205600, + 1193950800, + 1207260000, + 1225486800, + 1238104800, + 1256850000, + 1270159200, + 1288299600, + 1301608800, + 1319749200, + 1333058400, + 1351198800, + 1364508000, + 1382648400, + 1395957600, + 1414702800, + 1427407200, + 1446152400, + 1458856800, + 1477602000, + 1490911200, + 1509051600, + 1522360800, + 1540501200, + 1553810400, + 1571950800, + 1585260000, + 1604005200, + 1616709600, + 1635454800, + 1648159200, + 1666904400 + ], + "types": [ + { + "offset": 8712 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5473a3220fbbe20b-150c46c09db6581d.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5473a3220fbbe20b-150c46c09db6581d.json new file mode 100644 index 00000000000000..3c17b5dd61b95a --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5473a3220fbbe20b-150c46c09db6581d.json @@ -0,0 +1,232 @@ +{ + "ids": [ + "europe/rome", + "europe/san_marino", + "europe/vatican" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": { + "abbr": "CEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -3252098996, + -2403565200, + -1690765200, + -1680487200, + -1664758800, + -1648951200, + -1635123600, + -1616896800, + -1604278800, + -1585533600, + -1571014800, + -1555293600, + -932432400, + -857257200, + -844556400, + -828226800, + -812502000, + -798073200, + -781052400, + -766717200, + -750898800, + -733359600, + -719456400, + -701917200, + -689209200, + -670460400, + -114051600, + -103168800, + -81997200, + -71715600, + -50547600, + -40266000, + -18493200, + -8211600, + 12956400, + 23238000, + 43801200, + 54687600, + 75855600, + 86742000, + 107910000, + 118191600, + 138754800, + 149641200, + 170809200, + 181090800, + 202258800, + 212540400, + 233103600, + 243990000, + 265158000, + 276044400, + 296607600, + 307494000, + 323830800, + 338950800, + 354675600, + 370400400, + 386125200, + 401850000, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": 2996 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-55bb5ee9b0a529a6-dce97bdbcf437150.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-55bb5ee9b0a529a6-dce97bdbcf437150.json new file mode 100644 index 00000000000000..fde754caa0f764 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-55bb5ee9b0a529a6-dce97bdbcf437150.json @@ -0,0 +1,214 @@ +{ + "ids": [ + "america/glace_bay" + ], + "tzif": { + "posix": { + "abbr": "AST", + "offset": -14400, + "transition": { + "abbr": "ADT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2131646412, + -1632074400, + -1615143600, + -880221600, + -769395600, + -765399600, + -526500000, + -513198000, + 73461600, + 89182800, + 104911200, + 120632400, + 136360800, + 152082000, + 167810400, + 183531600, + 199260000, + 215586000, + 230709600, + 247035600, + 262764000, + 278485200, + 294213600, + 309934800, + 325663200, + 341384400, + 357112800, + 372834000, + 388562400, + 404888400, + 420012000, + 436338000, + 452066400, + 467787600, + 483516000, + 499237200, + 514965600, + 530686800, + 544600800, + 562136400, + 576050400, + 594190800, + 607500000, + 625640400, + 638949600, + 657090000, + 671004000, + 688539600, + 702453600, + 719989200, + 733903200, + 752043600, + 765352800, + 783493200, + 796802400, + 814942800, + 828856800, + 846392400, + 860306400, + 877842000, + 891756000, + 909291600, + 923205600, + 941346000, + 954655200, + 972795600, + 986104800, + 1004245200, + 1018159200, + 1035694800, + 1049608800, + 1067144400, + 1081058400, + 1099198800, + 1112508000, + 1130648400, + 1143957600, + 1162098000, + 1173592800, + 1194152400 + ], + "types": [ + { + "offset": -14388 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-55ec396d83237537-39a492626467027.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-55ec396d83237537-39a492626467027.json new file mode 100644 index 00000000000000..f5f89fa3395714 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-55ec396d83237537-39a492626467027.json @@ -0,0 +1,94 @@ +{ + "ids": [ + "asia/samarkand" + ], + "tzif": { + "posix": { + "abbr": "+05", + "offset": 18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2 + ], + "transitions": [ + -1441168073, + -1247544000, + 354913200, + 370720800, + 386445600, + 386449200, + 402256800, + 417985200, + 433792800, + 449607600, + 465339600, + 481064400, + 496789200, + 512514000, + 528238800, + 543963600, + 559688400, + 575413200, + 591138000, + 606862800, + 622587600, + 638312400, + 654642000, + 670366800, + 686091600 + ], + "types": [ + { + "offset": 16073 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + }, + { + "offset": 21600 + }, + { + "offset": 21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-55eedcdc6ff1f85-5b27bba1cde1354f.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-55eedcdc6ff1f85-5b27bba1cde1354f.json new file mode 100644 index 00000000000000..3b0a1fc4156ca6 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-55eedcdc6ff1f85-5b27bba1cde1354f.json @@ -0,0 +1,39 @@ +{ + "ids": [ + "atlantic/cape_verde" + ], + "tzif": { + "posix": { + "abbr": "-01", + "offset": -3600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 3 + ], + "transitions": [ + -1830376800, + -862610400, + -764118000, + 186120000 + ], + "types": [ + { + "offset": -5644 + }, + { + "offset": -7200 + }, + { + "offset": -3600 + }, + { + "offset": -3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-57ad9603575ed991-356d85cfd1d045d6.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-57ad9603575ed991-356d85cfd1d045d6.json new file mode 100644 index 00000000000000..8c668066e41d4a --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-57ad9603575ed991-356d85cfd1d045d6.json @@ -0,0 +1,31 @@ +{ + "ids": [ + "pacific/fakaofo" + ], + "tzif": { + "posix": { + "abbr": "+13", + "offset": 46800, + "transition": null + }, + "transition_types": [ + 1, + 2 + ], + "transitions": [ + -2177411704, + 1325242800 + ], + "types": [ + { + "offset": -41096 + }, + { + "offset": -39600 + }, + { + "offset": 46800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5890af4975eb815-dbcd9d0a6fe5353.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5890af4975eb815-dbcd9d0a6fe5353.json new file mode 100644 index 00000000000000..516c7c31176de3 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5890af4975eb815-dbcd9d0a6fe5353.json @@ -0,0 +1,184 @@ +{ + "ids": [ + "asia/beirut" + ], + "tzif": { + "posix": { + "abbr": "EET", + "offset": 7200, + "transition": { + "abbr": "EEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 0 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 0 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2840149320, + -1570413600, + -1552186800, + -1538359200, + -1522551600, + -1507514400, + -1490583600, + -1473645600, + -1460948400, + -399866400, + -386650800, + -368330400, + -355114800, + -336794400, + -323578800, + -305172000, + -291956400, + -273636000, + -260420400, + 78012000, + 86734800, + 105055200, + 118270800, + 136591200, + 149806800, + 168127200, + 181342800, + 199749600, + 212965200, + 231285600, + 244501200, + 262735200, + 275950800, + 452210400, + 466722000, + 483746400, + 498258000, + 515282400, + 529794000, + 546818400, + 561330000, + 581119200, + 592952400, + 610754400, + 624488400, + 641512800, + 656024400, + 673048800, + 687560400, + 704671200, + 718146000, + 733269600, + 748990800, + 764719200, + 780440400, + 796168800, + 811890000, + 828223200, + 843944400, + 859672800, + 875394000, + 891122400, + 906843600, + 922572000, + 941317200 + ], + "types": [ + { + "offset": 8520 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-59d5e08cb19672f5-73d8fe68d8bc0b47.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-59d5e08cb19672f5-73d8fe68d8bc0b47.json new file mode 100644 index 00000000000000..6c2fed3339ce46 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-59d5e08cb19672f5-73d8fe68d8bc0b47.json @@ -0,0 +1,42 @@ +{ + "ids": [ + "africa/johannesburg", + "africa/maseru", + "africa/mbabane" + ], + "tzif": { + "posix": { + "abbr": "SAST", + "offset": 7200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3 + ], + "transitions": [ + -2458173120, + -2109288600, + -860976000, + -845254800, + -829526400 + ], + "types": [ + { + "offset": 6720 + }, + { + "offset": 5400 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5a1de33f302092c9-7fede906b0fbc944.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5a1de33f302092c9-7fede906b0fbc944.json new file mode 100644 index 00000000000000..acdce38d08db61 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5a1de33f302092c9-7fede906b0fbc944.json @@ -0,0 +1,222 @@ +{ + "ids": [ + "europe/minsk" + ], + "tzif": { + "posix": { + "abbr": "+03", + "offset": 10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7 + ], + "transitions": [ + -2840147416, + -1441158600, + -1247536800, + -899780400, + -857257200, + -844556400, + -828226800, + -812502000, + -804650400, + 354920400, + 370728000, + 386456400, + 402264000, + 417992400, + 433800000, + 449614800, + 465346800, + 481071600, + 496796400, + 512521200, + 528246000, + 543970800, + 559695600, + 575420400, + 591145200, + 606870000, + 622594800, + 670374000, + 686102400, + 701827200, + 717552000, + 733276800, + 749001600, + 764726400, + 780451200, + 796176000, + 811900800, + 828230400, + 846374400, + 859680000, + 877824000, + 891129600, + 909273600, + 922579200, + 941328000, + 954028800, + 972777600, + 985478400, + 1004227200, + 1017532800, + 1035676800, + 1048982400, + 1067126400, + 1080432000, + 1099180800, + 1111881600, + 1130630400, + 1143331200, + 1162080000, + 1174780800, + 1193529600, + 1206835200, + 1224979200, + 1238284800, + 1256428800, + 1269734400, + 1288483200, + 1301184000 + ], + "types": [ + { + "offset": 6616 + }, + { + "offset": 6600 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 7200 + }, + { + "offset": 3600 + }, + { + "offset": 14400 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5a8de8f20b18b43-384f712f565d0ab0.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5a8de8f20b18b43-384f712f565d0ab0.json new file mode 100644 index 00000000000000..9e04ac7f13ad11 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5a8de8f20b18b43-384f712f565d0ab0.json @@ -0,0 +1,178 @@ +{ + "ids": [ + "asia/atyrau" + ], + "tzif": { + "posix": { + "abbr": "+05", + "offset": 18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 2, + 5, + 2, + 5, + 6, + 3, + 4, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 2, + 5 + ], + "transitions": [ + -1441164464, + -1247540400, + 370724400, + 386445600, + 386449200, + 402256800, + 417985200, + 433792800, + 449607600, + 465339600, + 481064400, + 496789200, + 512514000, + 528238800, + 543963600, + 559688400, + 575413200, + 591138000, + 606862800, + 622587600, + 638312400, + 654642000, + 670366800, + 670370400, + 686095200, + 695772000, + 701816400, + 717541200, + 733266000, + 748990800, + 764715600, + 780440400, + 796165200, + 811890000, + 828219600, + 846363600, + 859669200, + 877813200, + 891118800, + 909262800, + 922568400, + 922572000, + 941320800, + 954021600, + 972770400, + 985471200, + 1004220000, + 1017525600, + 1035669600, + 1048975200, + 1067119200, + 1080424800, + 1099173600 + ], + "types": [ + { + "offset": 12464 + }, + { + "offset": 10800 + }, + { + "offset": 18000 + }, + { + "offset": 21600 + }, + { + "offset": 21600 + }, + { + "offset": 18000 + }, + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5cb26c449b2278f2-a3a1b3aa09d53c07.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5cb26c449b2278f2-a3a1b3aa09d53c07.json new file mode 100644 index 00000000000000..b9586f684cf408 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5cb26c449b2278f2-a3a1b3aa09d53c07.json @@ -0,0 +1,135 @@ +{ + "ids": [ + "europe/busingen", + "europe/vaduz", + "europe/zurich" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": { + "abbr": "CEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2 + ], + "transitions": [ + -3675198848, + -2385246586, + -904435200, + -891129600, + -872985600, + -859680000, + 347151600, + 370400400, + 386125200, + 401850000, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": 2048 + }, + { + "offset": 1786 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5d69c15d2c4f26ae-d843083a2b2d2784.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5d69c15d2c4f26ae-d843083a2b2d2784.json new file mode 100644 index 00000000000000..b8757bffa0181e --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5d69c15d2c4f26ae-d843083a2b2d2784.json @@ -0,0 +1,153 @@ +{ + "ids": [ + "america/metlakatla" + ], + "tzif": { + "posix": { + "abbr": "AKST", + "offset": -32400, + "transition": { + "abbr": "AKDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 2, + 5, + 4 + ], + "transitions": [ + -3225223727, + -2188955622, + -880207200, + -769395600, + -765385200, + -21477600, + -5756400, + 9972000, + 25693200, + 41421600, + 57747600, + 73476000, + 89197200, + 104925600, + 120646800, + 126698400, + 152096400, + 162381600, + 183546000, + 199274400, + 215600400, + 230724000, + 247050000, + 262778400, + 278499600, + 294228000, + 309949200, + 325677600, + 341398800, + 357127200, + 372848400, + 388576800, + 404902800, + 420026400, + 436352400, + 1446372000, + 1457866800, + 1478426400, + 1489316400, + 1509876000, + 1520766000, + 1541325600, + 1547978400 + ], + "types": [ + { + "offset": 54822 + }, + { + "offset": -31578 + }, + { + "offset": -28800 + }, + { + "offset": -25200 + }, + { + "offset": -32400 + }, + { + "offset": -28800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5e245c7be541fe52-ac13030bf2bc388c.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5e245c7be541fe52-ac13030bf2bc388c.json new file mode 100644 index 00000000000000..64cb6496a95f55 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5e245c7be541fe52-ac13030bf2bc388c.json @@ -0,0 +1,235 @@ +{ + "ids": [ + "america/godthab", + "america/nuuk" + ], + "tzif": { + "posix": { + "abbr": "-02", + "offset": -7200, + "transition": { + "abbr": "-01", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 0 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": -3600 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3 + ], + "transitions": [ + -1686083584, + 323845200, + 338950800, + 354675600, + 370400400, + 386125200, + 401850000, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000, + 859683600, + 877827600, + 891133200, + 909277200, + 922582800, + 941331600, + 954032400, + 972781200, + 985482000, + 1004230800, + 1017536400, + 1035680400, + 1048986000, + 1067130000, + 1080435600, + 1099184400, + 1111885200, + 1130634000, + 1143334800, + 1162083600, + 1174784400, + 1193533200, + 1206838800, + 1224982800, + 1238288400, + 1256432400, + 1269738000, + 1288486800, + 1301187600, + 1319936400, + 1332637200, + 1351386000, + 1364691600, + 1382835600, + 1396141200, + 1414285200, + 1427590800, + 1445734800, + 1459040400, + 1477789200, + 1490490000, + 1509238800, + 1521939600, + 1540688400, + 1553994000, + 1572138000, + 1585443600, + 1603587600, + 1616893200, + 1635642000, + 1648342800, + 1667091600, + 1679792400 + ], + "types": [ + { + "offset": -12416 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5eec9cd299aa076f-857603deebbce60b.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5eec9cd299aa076f-857603deebbce60b.json new file mode 100644 index 00000000000000..8ca0a720e1c5ac --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5eec9cd299aa076f-857603deebbce60b.json @@ -0,0 +1,26 @@ +{ + "ids": [ + "etc/uct", + "etc/universal", + "etc/utc", + "etc/zulu", + "uct", + "universal", + "utc", + "zulu" + ], + "tzif": { + "posix": { + "abbr": "UTC", + "offset": 0, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": 0 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5fd210f528e95871-c650f43dd3590090.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5fd210f528e95871-c650f43dd3590090.json new file mode 100644 index 00000000000000..96d1837748181c --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-5fd210f528e95871-c650f43dd3590090.json @@ -0,0 +1,191 @@ +{ + "ids": [ + "europe/astrakhan" + ], + "tzif": { + "posix": { + "abbr": "+04", + "offset": 14400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 2, + 4, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4 + ], + "transitions": [ + -1441249932, + -1247540400, + 354916800, + 370724400, + 386452800, + 402260400, + 417988800, + 433796400, + 449611200, + 465343200, + 481068000, + 496792800, + 512517600, + 528242400, + 543967200, + 559692000, + 575416800, + 591141600, + 606866400, + 606870000, + 622594800, + 638319600, + 654649200, + 670374000, + 701820000, + 701823600, + 717548400, + 733273200, + 748998000, + 764722800, + 780447600, + 796172400, + 811897200, + 828226800, + 846370800, + 859676400, + 877820400, + 891126000, + 909270000, + 922575600, + 941324400, + 954025200, + 972774000, + 985474800, + 1004223600, + 1017529200, + 1035673200, + 1048978800, + 1067122800, + 1080428400, + 1099177200, + 1111878000, + 1130626800, + 1143327600, + 1162076400, + 1174777200, + 1193526000, + 1206831600, + 1224975600, + 1238281200, + 1256425200, + 1269730800, + 1288479600, + 1301180400, + 1414274400, + 1459033200 + ], + "types": [ + { + "offset": 11532 + }, + { + "offset": 10800 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + }, + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-609a1c759abb0f9e-a202ec7708c700d8.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-609a1c759abb0f9e-a202ec7708c700d8.json new file mode 100644 index 00000000000000..f7159b308dadbc --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-609a1c759abb0f9e-a202ec7708c700d8.json @@ -0,0 +1,85 @@ +{ + "ids": [ + "america/porto_velho" + ], + "tzif": { + "posix": { + "abbr": "-04", + "offset": -14400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1767210264, + -1206954000, + -1191358800, + -1175371200, + -1159822800, + -633816000, + -622065600, + -602280000, + -591829200, + -570744000, + -560206800, + -539121600, + -531349200, + -191361600, + -184194000, + -155160000, + -150066000, + -128894400, + -121122000, + -99950400, + -89586000, + -68414400, + -57963600, + 499752000, + 511239600, + 530596800, + 540270000, + 562132800, + 571201200 + ], + "types": [ + { + "offset": -15336 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6156cfed77f2a26c-d5c8e957d52b5aa1.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6156cfed77f2a26c-d5c8e957d52b5aa1.json new file mode 100644 index 00000000000000..beed623276a5ca --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6156cfed77f2a26c-d5c8e957d52b5aa1.json @@ -0,0 +1,193 @@ +{ + "ids": [ + "asia/irkutsk" + ], + "tzif": { + "posix": { + "abbr": "+08", + "offset": 28800, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 5, + 2, + 4 + ], + "transitions": [ + -2840165825, + -1575874625, + -1247554800, + 354902400, + 370710000, + 386438400, + 402246000, + 417974400, + 433782000, + 449596800, + 465328800, + 481053600, + 496778400, + 512503200, + 528228000, + 543952800, + 559677600, + 575402400, + 591127200, + 606852000, + 622576800, + 638301600, + 654631200, + 670356000, + 670359600, + 686084400, + 695761200, + 701805600, + 717530400, + 733255200, + 748980000, + 764704800, + 780429600, + 796154400, + 811879200, + 828208800, + 846352800, + 859658400, + 877802400, + 891108000, + 909252000, + 922557600, + 941306400, + 954007200, + 972756000, + 985456800, + 1004205600, + 1017511200, + 1035655200, + 1048960800, + 1067104800, + 1080410400, + 1099159200, + 1111860000, + 1130608800, + 1143309600, + 1162058400, + 1174759200, + 1193508000, + 1206813600, + 1224957600, + 1238263200, + 1256407200, + 1269712800, + 1288461600, + 1301162400, + 1414256400 + ], + "types": [ + { + "offset": 25025 + }, + { + "offset": 25200 + }, + { + "offset": 28800 + }, + { + "offset": 32400 + }, + { + "offset": 28800 + }, + { + "offset": 32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6196bbf525d4d50a-c1285ce65c03319.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6196bbf525d4d50a-c1285ce65c03319.json new file mode 100644 index 00000000000000..6da298bc9ba616 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6196bbf525d4d50a-c1285ce65c03319.json @@ -0,0 +1,47 @@ +{ + "ids": [ + "hst", + "pacific/honolulu", + "pacific/johnston", + "us/hawaii" + ], + "tzif": { + "posix": { + "abbr": "HST", + "offset": -36000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 2, + 1, + 3 + ], + "transitions": [ + -2334101314, + -1157283000, + -1155436200, + -880198200, + -769395600, + -765376200, + -712150200 + ], + "types": [ + { + "offset": -37886 + }, + { + "offset": -37800 + }, + { + "offset": -34200 + }, + { + "offset": -36000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-622cbc57a076ea5d-616edf8039af4f62.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-622cbc57a076ea5d-616edf8039af4f62.json new file mode 100644 index 00000000000000..d39f25e9fae739 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-622cbc57a076ea5d-616edf8039af4f62.json @@ -0,0 +1,190 @@ +{ + "ids": [ + "asia/qyzylorda" + ], + "tzif": { + "posix": { + "abbr": "+05", + "offset": 18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 2, + 5, + 2, + 5, + 2, + 5, + 6, + 3, + 4, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 3, + 4, + 2, + 5 + ], + "transitions": [ + -1441167712, + -1247544000, + 354913200, + 370720800, + 386445600, + 386449200, + 402256800, + 417985200, + 433792800, + 449607600, + 465339600, + 481064400, + 496789200, + 512514000, + 528238800, + 543963600, + 559688400, + 575413200, + 591138000, + 606862800, + 622587600, + 638312400, + 654642000, + 670366800, + 670370400, + 686095200, + 695768400, + 701812800, + 701816400, + 717541200, + 733266000, + 748990800, + 764715600, + 780440400, + 796165200, + 811890000, + 828219600, + 846363600, + 859669200, + 877813200, + 891118800, + 909262800, + 922568400, + 941317200, + 954018000, + 972766800, + 985467600, + 1004216400, + 1017522000, + 1035666000, + 1048971600, + 1067115600, + 1080421200, + 1099170000, + 1545328800 + ], + "types": [ + { + "offset": 15712 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + }, + { + "offset": 21600 + }, + { + "offset": 21600 + }, + { + "offset": 18000 + }, + { + "offset": 25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6268b48b2e959066-91294d0f7013ba84.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6268b48b2e959066-91294d0f7013ba84.json new file mode 100644 index 00000000000000..acb768b14bd852 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6268b48b2e959066-91294d0f7013ba84.json @@ -0,0 +1,37 @@ +{ + "ids": [ + "asia/pyongyang" + ], + "tzif": { + "posix": { + "abbr": "KST", + "offset": 32400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 2, + 1, + 2 + ], + "transitions": [ + -1948782180, + -1830414600, + -768646800, + 1439564400, + 1525446000 + ], + "types": [ + { + "offset": 30180 + }, + { + "offset": 30600 + }, + { + "offset": 32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-638a1ae9aef4e05b-74d152a85f1741cd.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-638a1ae9aef4e05b-74d152a85f1741cd.json new file mode 100644 index 00000000000000..b805f4a0cbcdf4 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-638a1ae9aef4e05b-74d152a85f1741cd.json @@ -0,0 +1,228 @@ +{ + "ids": [ + "europe/malta" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": { + "abbr": "CEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2403478684, + -1690765200, + -1680487200, + -1664758800, + -1648951200, + -1635123600, + -1616896800, + -1604278800, + -1585533600, + -1571014800, + -1555293600, + -932432400, + -857257200, + -844556400, + -828226800, + -812588400, + -798073200, + -781052400, + -766717200, + -750898800, + -733359600, + -719456400, + -701917200, + -689209200, + -670460400, + -114051600, + -103168800, + -81997200, + -71715600, + -50547600, + -40266000, + -18493200, + -8211600, + 12956400, + 23238000, + 43801200, + 54687600, + 75855600, + 86742000, + 102380400, + 118105200, + 135730800, + 148518000, + 167187600, + 180489600, + 198637200, + 211939200, + 230086800, + 243388800, + 261536400, + 274838400, + 292986000, + 306288000, + 323312400, + 338342400, + 347151600, + 370400400, + 386125200, + 401850000, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": 3484 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6415eb3f74777957-6f718f12281286a3.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6415eb3f74777957-6f718f12281286a3.json new file mode 100644 index 00000000000000..31cfbae1ce6028 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6415eb3f74777957-6f718f12281286a3.json @@ -0,0 +1,317 @@ +{ + "ids": [ + "cet", + "europe/amsterdam", + "europe/brussels", + "europe/luxembourg", + "met" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": { + "abbr": "CEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 0, + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4 + ], + "transitions": [ + -2840141850, + -2450995200, + -1740355200, + -1693702800, + -1680483600, + -1663455600, + -1650150000, + -1632006000, + -1618700400, + -1613826000, + -1604278800, + -1585530000, + -1574038800, + -1552266000, + -1539997200, + -1520557200, + -1507510800, + -1490576400, + -1473642000, + -1459126800, + -1444006800, + -1427677200, + -1411952400, + -1396227600, + -1379293200, + -1364778000, + -1348448400, + -1333328400, + -1316394000, + -1301263200, + -1284328800, + -1269813600, + -1253484000, + -1238364000, + -1221429600, + -1206914400, + -1191189600, + -1175464800, + -1160344800, + -1143410400, + -1127685600, + -1111960800, + -1096840800, + -1080511200, + -1063576800, + -1049061600, + -1033336800, + -1017612000, + -1002492000, + -986162400, + -969228000, + -950479200, + -942012000, + -934668000, + -857257200, + -844556400, + -828226800, + -812502000, + -798073200, + -781052400, + -766623600, + -745455600, + -733273200, + 228877200, + 243997200, + 260326800, + 276051600, + 291776400, + 307501200, + 323830800, + 338950800, + 354675600, + 370400400, + 386125200, + 401850000, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": 1050 + }, + { + "offset": 0 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + }, + { + "offset": 3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6493d17f054bfdfb-35ed6c8176f0fbed.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6493d17f054bfdfb-35ed6c8176f0fbed.json new file mode 100644 index 00000000000000..26cff7a5a7f15d --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6493d17f054bfdfb-35ed6c8176f0fbed.json @@ -0,0 +1,28 @@ +{ + "ids": [ + "pacific/guadalcanal", + "pacific/pohnpei", + "pacific/ponape" + ], + "tzif": { + "posix": { + "abbr": "+11", + "offset": 39600, + "transition": null + }, + "transition_types": [ + 1 + ], + "transitions": [ + -1806748788 + ], + "types": [ + { + "offset": 38388 + }, + { + "offset": 39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-650685fe5c95ce2a-2f3eb2e60291229d.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-650685fe5c95ce2a-2f3eb2e60291229d.json new file mode 100644 index 00000000000000..1c276e33922918 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-650685fe5c95ce2a-2f3eb2e60291229d.json @@ -0,0 +1,172 @@ +{ + "ids": [ + "asia/tehran", + "iran" + ], + "tzif": { + "posix": { + "abbr": "+0330", + "offset": 12600, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 3, + 4, + 3, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1704165944, + -1090466744, + 227820600, + 246223800, + 259617600, + 271108800, + 279576000, + 296598600, + 306531000, + 322432200, + 338499000, + 673216200, + 685481400, + 701209800, + 717103800, + 732745800, + 748639800, + 764281800, + 780175800, + 795817800, + 811711800, + 827353800, + 843247800, + 858976200, + 874870200, + 890512200, + 906406200, + 922048200, + 937942200, + 953584200, + 969478200, + 985206600, + 1001100600, + 1016742600, + 1032636600, + 1048278600, + 1064172600, + 1079814600, + 1095708600, + 1111437000, + 1127331000, + 1206045000, + 1221939000, + 1237667400, + 1253561400, + 1269203400, + 1285097400, + 1300739400, + 1316633400, + 1332275400, + 1348169400, + 1363897800, + 1379791800, + 1395433800, + 1411327800, + 1426969800, + 1442863800, + 1458505800, + 1474399800, + 1490128200, + 1506022200, + 1521664200, + 1537558200, + 1553200200, + 1569094200, + 1584736200, + 1600630200, + 1616358600, + 1632252600 + ], + "types": [ + { + "offset": 12344 + }, + { + "offset": 12600 + }, + { + "offset": 16200 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-65401a13577707c6-bb9f9264b43c1451.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-65401a13577707c6-bb9f9264b43c1451.json new file mode 100644 index 00000000000000..7735182749215f --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-65401a13577707c6-bb9f9264b43c1451.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt-6" + ], + "tzif": { + "posix": { + "abbr": "+06", + "offset": 21600, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": 21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-65badfa9c283e8d3-9bc658cd314193fd.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-65badfa9c283e8d3-9bc658cd314193fd.json new file mode 100644 index 00000000000000..403eca7a96e6ff --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-65badfa9c283e8d3-9bc658cd314193fd.json @@ -0,0 +1,126 @@ +{ + "ids": [ + "asia/hovd" + ], + "tzif": { + "posix": { + "abbr": "+07", + "offset": 25200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2 + ], + "transitions": [ + -2032927596, + 252439200, + 417978000, + 433785600, + 449600400, + 465321600, + 481050000, + 496771200, + 512499600, + 528220800, + 543949200, + 559670400, + 575398800, + 591120000, + 606848400, + 622569600, + 638298000, + 654624000, + 670352400, + 686073600, + 701802000, + 717523200, + 733251600, + 748972800, + 764701200, + 780422400, + 796150800, + 811872000, + 828205200, + 843926400, + 859654800, + 875376000, + 891104400, + 906825600, + 988398000, + 1001700000, + 1017428400, + 1033149600, + 1048878000, + 1064599200, + 1080327600, + 1096048800, + 1111777200, + 1127498400, + 1143226800, + 1159552800, + 1427482800, + 1443196800 + ], + "types": [ + { + "offset": 21996 + }, + { + "offset": 21600 + }, + { + "offset": 25200 + }, + { + "offset": 28800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-66a5515c6139ad2d-8cdcb912670ca415.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-66a5515c6139ad2d-8cdcb912670ca415.json new file mode 100644 index 00000000000000..d99868efa3569b --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-66a5515c6139ad2d-8cdcb912670ca415.json @@ -0,0 +1,33 @@ +{ + "ids": [ + "america/la_paz" + ], + "tzif": { + "posix": { + "abbr": "-04", + "offset": -14400, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2 + ], + "transitions": [ + -2524505244, + -1205954844, + -1192307244 + ], + "types": [ + { + "offset": -16356 + }, + { + "offset": -12756 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-66fc406d3b90ff90-42d7c96cbf80d3ca.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-66fc406d3b90ff90-42d7c96cbf80d3ca.json new file mode 100644 index 00000000000000..0ffdb46840ca70 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-66fc406d3b90ff90-42d7c96cbf80d3ca.json @@ -0,0 +1,101 @@ +{ + "ids": [ + "africa/juba" + ], + "tzif": { + "posix": { + "abbr": "CAT", + "offset": 7200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 1 + ], + "transitions": [ + -1230775588, + 10360800, + 24786000, + 41810400, + 56322000, + 73432800, + 87944400, + 104882400, + 119480400, + 136332000, + 151016400, + 167781600, + 182552400, + 199231200, + 214174800, + 230680800, + 245710800, + 262735200, + 277246800, + 294184800, + 308782800, + 325634400, + 340405200, + 357084000, + 371941200, + 388533600, + 403477200, + 419983200, + 435013200, + 452037600, + 466635600, + 483487200, + 498171600, + 947930400, + 1612126800 + ], + "types": [ + { + "offset": 7588 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6797b3dc466b8334-28780ef70fbe052e.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6797b3dc466b8334-28780ef70fbe052e.json new file mode 100644 index 00000000000000..7621427102d8db --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6797b3dc466b8334-28780ef70fbe052e.json @@ -0,0 +1,26 @@ +{ + "ids": [ + "pacific/marquesas" + ], + "tzif": { + "posix": { + "abbr": "-0930", + "offset": -34200, + "transition": null + }, + "transition_types": [ + 1 + ], + "transitions": [ + -1806676920 + ], + "types": [ + { + "offset": -33480 + }, + { + "offset": -34200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-67d3e39540d85c91-f13f9d0367c68c92.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-67d3e39540d85c91-f13f9d0367c68c92.json new file mode 100644 index 00000000000000..31e6c002035674 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-67d3e39540d85c91-f13f9d0367c68c92.json @@ -0,0 +1,121 @@ +{ + "ids": [ + "atlantic/faeroe", + "atlantic/faroe" + ], + "tzif": { + "posix": { + "abbr": "WET", + "offset": 0, + "transition": { + "abbr": "WEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 3600 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1955748776, + 347155200, + 370400400, + 386125200, + 401850000, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": -1624 + }, + { + "offset": 0 + }, + { + "offset": 3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-68b74f8e8d191761-a8eaae70013bbfdf.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-68b74f8e8d191761-a8eaae70013bbfdf.json new file mode 100644 index 00000000000000..4f1697e5af6bf1 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-68b74f8e8d191761-a8eaae70013bbfdf.json @@ -0,0 +1,34 @@ +{ + "ids": [ + "pacific/midway", + "pacific/pago_pago", + "pacific/samoa", + "us/samoa" + ], + "tzif": { + "posix": { + "abbr": "SST", + "offset": -39600, + "transition": null + }, + "transition_types": [ + 1, + 2 + ], + "transitions": [ + -2445424632, + -1861879032 + ], + "types": [ + { + "offset": 45432 + }, + { + "offset": -40968 + }, + { + "offset": -39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-69530af9af6cd0cb-6e2e37393c7f8e5d.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-69530af9af6cd0cb-6e2e37393c7f8e5d.json new file mode 100644 index 00000000000000..131456fd291f5c --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-69530af9af6cd0cb-6e2e37393c7f8e5d.json @@ -0,0 +1,61 @@ +{ + "ids": [ + "america/hermosillo" + ], + "tzif": { + "posix": { + "abbr": "MST", + "offset": -25200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1 + ], + "transitions": [ + -1514739600, + -1343149200, + -1234807200, + -1220461200, + -1207159200, + -1191344400, + -873828000, + 828867600, + 846403200, + 860317200, + 877852800, + 891766800, + 909302400 + ], + "types": [ + { + "offset": -26632 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + }, + { + "offset": -21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6a52098e032992a5-e1eb00358541c6a0.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6a52098e032992a5-e1eb00358541c6a0.json new file mode 100644 index 00000000000000..390fea5d856afe --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6a52098e032992a5-e1eb00358541c6a0.json @@ -0,0 +1,249 @@ +{ + "ids": [ + "atlantic/bermuda" + ], + "tzif": { + "posix": { + "abbr": "AST", + "offset": -14400, + "transition": { + "abbr": "ADT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 0, + 1, + 0, + 1, + 0, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2 + ], + "transitions": [ + -2524506042, + -1664307642, + -1648932042, + -1632080442, + -1618692042, + -1262281242, + -882727200, + -858538800, + -845229600, + -825879600, + -814384800, + -793825200, + -782935200, + -762375600, + -713988000, + -703710000, + -681933600, + -672865200, + -650484000, + -641415600, + -618429600, + -609966000, + -586980000, + -578516400, + -555530400, + -546462000, + -429127200, + -415825200, + 136360800, + 152082000, + 167810400, + 183531600, + 199260000, + 215586000, + 230709600, + 247035600, + 262764000, + 278485200, + 294213600, + 309934800, + 325663200, + 341384400, + 357112800, + 372834000, + 388562400, + 404888400, + 420012000, + 436338000, + 452066400, + 467787600, + 483516000, + 499237200, + 514965600, + 530686800, + 544600800, + 562136400, + 576050400, + 594190800, + 607500000, + 625640400, + 638949600, + 657090000, + 671004000, + 688539600, + 702453600, + 719989200, + 733903200, + 752043600, + 765352800, + 783493200, + 796802400, + 814942800, + 828856800, + 846392400, + 860306400, + 877842000, + 891756000, + 909291600, + 923205600, + 941346000, + 954655200, + 972795600, + 986104800, + 1004245200, + 1018159200, + 1035694800, + 1049608800, + 1067144400, + 1081058400, + 1099198800, + 1112508000, + 1130648400, + 1143957600, + 1162098000, + 1173592800, + 1194152400 + ], + "types": [ + { + "offset": -15558 + }, + { + "offset": -11958 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6ad7cbb6af2e6144-d93cfc8ee54a6b99.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6ad7cbb6af2e6144-d93cfc8ee54a6b99.json new file mode 100644 index 00000000000000..68164c639c125c --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6ad7cbb6af2e6144-d93cfc8ee54a6b99.json @@ -0,0 +1,192 @@ +{ + "ids": [ + "europe/saratov" + ], + "tzif": { + "posix": { + "abbr": "+04", + "offset": 14400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 2, + 4, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4 + ], + "transitions": [ + -1593820800, + -1247540400, + 354916800, + 370724400, + 386452800, + 402260400, + 417988800, + 433796400, + 449611200, + 465343200, + 481068000, + 496792800, + 512517600, + 528242400, + 543967200, + 559692000, + 575416800, + 575420400, + 591145200, + 606870000, + 622594800, + 638319600, + 654649200, + 670374000, + 701820000, + 701823600, + 717548400, + 733273200, + 748998000, + 764722800, + 780447600, + 796172400, + 811897200, + 828226800, + 846370800, + 859676400, + 877820400, + 891126000, + 909270000, + 922575600, + 941324400, + 954025200, + 972774000, + 985474800, + 1004223600, + 1017529200, + 1035673200, + 1048978800, + 1067122800, + 1080428400, + 1099177200, + 1111878000, + 1130626800, + 1143327600, + 1162076400, + 1174777200, + 1193526000, + 1206831600, + 1224975600, + 1238281200, + 1256425200, + 1269730800, + 1288479600, + 1301180400, + 1414274400, + 1480806000 + ], + "types": [ + { + "offset": 11058 + }, + { + "offset": 10800 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + }, + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6bfb62f5e4b63e4a-5a7d3b172eb114d5.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6bfb62f5e4b63e4a-5a7d3b172eb114d5.json new file mode 100644 index 00000000000000..a29182e62fd491 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6bfb62f5e4b63e4a-5a7d3b172eb114d5.json @@ -0,0 +1,412 @@ +{ + "ids": [ + "europe/belfast", + "europe/guernsey", + "europe/isle_of_man", + "europe/jersey", + "europe/london", + "gb", + "gb-eire" + ], + "tzif": { + "posix": { + "abbr": "GMT", + "offset": 0, + "transition": { + "abbr": "BST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 3600 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 1, + 2, + 1, + 2, + 3, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1 + ], + "transitions": [ + -3852662325, + -1691964000, + -1680472800, + -1664143200, + -1650146400, + -1633903200, + -1617487200, + -1601848800, + -1586037600, + -1570399200, + -1552168800, + -1538344800, + -1522533600, + -1507500000, + -1490565600, + -1473631200, + -1460930400, + -1442786400, + -1428876000, + -1410732000, + -1396216800, + -1379282400, + -1364767200, + -1348437600, + -1333317600, + -1315778400, + -1301263200, + -1284328800, + -1269813600, + -1253484000, + -1238364000, + -1221429600, + -1206914400, + -1189980000, + -1175464800, + -1159135200, + -1143410400, + -1126476000, + -1111960800, + -1095631200, + -1080511200, + -1063576800, + -1049061600, + -1032127200, + -1017612000, + -1001282400, + -986162400, + -969228000, + -950479200, + -942012000, + -904518000, + -896050800, + -875487600, + -864601200, + -844038000, + -832546800, + -812588400, + -798073200, + -781052400, + -772066800, + -764805600, + -748476000, + -733356000, + -719445600, + -717030000, + -706748400, + -699487200, + -687996000, + -668037600, + -654732000, + -636588000, + -622072800, + -605743200, + -590623200, + -574293600, + -558568800, + -542239200, + -527119200, + -512604000, + -496274400, + -481154400, + -464220000, + -449704800, + -432165600, + -417650400, + -401320800, + -386200800, + -369266400, + -354751200, + -337816800, + -323301600, + -306972000, + -291852000, + -276732000, + -257983200, + -245282400, + -226533600, + -213228000, + -195084000, + -182383200, + -163634400, + -150933600, + -132184800, + -119484000, + -100735200, + -88034400, + -68680800, + -59004000, + -37242000, + 57722400, + 69818400, + 89172000, + 101268000, + 120621600, + 132717600, + 152071200, + 164167200, + 183520800, + 196221600, + 214970400, + 227671200, + 246420000, + 259120800, + 278474400, + 290570400, + 309924000, + 322020000, + 341373600, + 354675600, + 372819600, + 386125200, + 404269200, + 417574800, + 435718800, + 449024400, + 467773200, + 481078800, + 499222800, + 512528400, + 530672400, + 543978000, + 562122000, + 575427600, + 593571600, + 606877200, + 625626000, + 638326800, + 657075600, + 670381200, + 688525200, + 701830800, + 719974800, + 733280400, + 751424400, + 764730000, + 782874000, + 796179600, + 814323600, + 828234000, + 846378000 + ], + "types": [ + { + "offset": -75 + }, + { + "offset": 0 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + }, + { + "offset": 3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6d168cde30b3c19-24342dd0af895908.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6d168cde30b3c19-24342dd0af895908.json new file mode 100644 index 00000000000000..16c7fb41dc71f1 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6d168cde30b3c19-24342dd0af895908.json @@ -0,0 +1,32 @@ +{ + "ids": [ + "asia/kathmandu", + "asia/katmandu" + ], + "tzif": { + "posix": { + "abbr": "+0545", + "offset": 20700, + "transition": null + }, + "transition_types": [ + 1, + 2 + ], + "transitions": [ + -1577943676, + 504901800 + ], + "types": [ + { + "offset": 20476 + }, + { + "offset": 19800 + }, + { + "offset": 20700 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6d3285599a38ae5a-e146c246881dc5ed.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6d3285599a38ae5a-e146c246881dc5ed.json new file mode 100644 index 00000000000000..d7e0f6a227740a --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6d3285599a38ae5a-e146c246881dc5ed.json @@ -0,0 +1,180 @@ +{ + "ids": [ + "europe/bratislava", + "europe/prague" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": { + "abbr": "CEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 3, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -3786829064, + -2469401864, + -1693706400, + -1680483600, + -1663455600, + -1650150000, + -1632006000, + -1618700400, + -938905200, + -857257200, + -844556400, + -828226800, + -812502000, + -796777200, + -781052400, + -765327600, + -746578800, + -733359600, + -728517600, + -721260000, + -701910000, + -684975600, + -670460400, + -654217200, + -639010800, + 291776400, + 307501200, + 323830800, + 338950800, + 354675600, + 370400400, + 386125200, + 401850000, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": 3464 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + }, + { + "offset": 0 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6fbdbfed85292c81-468d78f0fb8a53ac.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6fbdbfed85292c81-468d78f0fb8a53ac.json new file mode 100644 index 00000000000000..78378c54a5053b --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6fbdbfed85292c81-468d78f0fb8a53ac.json @@ -0,0 +1,35 @@ +{ + "ids": [ + "america/atikokan", + "america/cayman", + "america/coral_harbour", + "america/panama", + "est" + ], + "tzif": { + "posix": { + "abbr": "EST", + "offset": -18000, + "transition": null + }, + "transition_types": [ + 1, + 2 + ], + "transitions": [ + -2524502512, + -1946918424 + ], + "types": [ + { + "offset": -19088 + }, + { + "offset": -19176 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6fbdea510dc8bdff-a0d6c86f83720461.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6fbdea510dc8bdff-a0d6c86f83720461.json new file mode 100644 index 00000000000000..b518ed931c3a65 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-6fbdea510dc8bdff-a0d6c86f83720461.json @@ -0,0 +1,140 @@ +{ + "ids": [ + "america/cancun" + ], + "tzif": { + "posix": { + "abbr": "EST", + "offset": -18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 2, + 3, + 4, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3 + ], + "transitions": [ + -1514743200, + 378201600, + 410504400, + 828864000, + 846399600, + 860313600, + 877849200, + 891759600, + 902037600, + 909298800, + 923212800, + 941353200, + 954662400, + 972802800, + 989136000, + 1001833200, + 1018166400, + 1035702000, + 1049616000, + 1067151600, + 1081065600, + 1099206000, + 1112515200, + 1130655600, + 1143964800, + 1162105200, + 1175414400, + 1193554800, + 1207468800, + 1225004400, + 1238918400, + 1256454000, + 1270368000, + 1288508400, + 1301817600, + 1319958000, + 1333267200, + 1351407600, + 1365321600, + 1382857200, + 1396771200, + 1414306800, + 1422777600 + ], + "types": [ + { + "offset": -20824 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-70408e1d981309b7-da99eb025c30159.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-70408e1d981309b7-da99eb025c30159.json new file mode 100644 index 00000000000000..390cf37f795f28 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-70408e1d981309b7-da99eb025c30159.json @@ -0,0 +1,285 @@ +{ + "ids": [ + "america/boise" + ], + "tzif": { + "posix": { + "abbr": "MST", + "offset": -25200, + "transition": { + "abbr": "MDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 4, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3 + ], + "transitions": [ + -2717640000, + -1633269600, + -1615129200, + -1601820000, + -1583679600, + -1471788000, + -880210800, + -769395600, + -765388800, + -84380400, + -68659200, + -52930800, + -37209600, + -21481200, + -5760000, + 9968400, + 25689600, + 41418000, + 57744000, + 73472400, + 89193600, + 104922000, + 120643200, + 129114000, + 152092800, + 162378000, + 183542400, + 199270800, + 215596800, + 230720400, + 247046400, + 262774800, + 278496000, + 294224400, + 309945600, + 325674000, + 341395200, + 357123600, + 372844800, + 388573200, + 404899200, + 420022800, + 436348800, + 452077200, + 467798400, + 483526800, + 499248000, + 514976400, + 530697600, + 544611600, + 562147200, + 576061200, + 594201600, + 607510800, + 625651200, + 638960400, + 657100800, + 671014800, + 688550400, + 702464400, + 720000000, + 733914000, + 752054400, + 765363600, + 783504000, + 796813200, + 814953600, + 828867600, + 846403200, + 860317200, + 877852800, + 891766800, + 909302400, + 923216400, + 941356800, + 954666000, + 972806400, + 986115600, + 1004256000, + 1018170000, + 1035705600, + 1049619600, + 1067155200, + 1081069200, + 1099209600, + 1112518800, + 1130659200, + 1143968400, + 1162108800, + 1173603600, + 1194163200 + ], + "types": [ + { + "offset": -27889 + }, + { + "offset": -28800 + }, + { + "offset": -25200 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-70c6eef1cba9528e-fa6fd92ebfdcf3ad.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-70c6eef1cba9528e-fa6fd92ebfdcf3ad.json new file mode 100644 index 00000000000000..479dbc2a1261c2 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-70c6eef1cba9528e-fa6fd92ebfdcf3ad.json @@ -0,0 +1,512 @@ +{ + "ids": [ + "africa/casablanca" + ], + "tzif": { + "posix": { + "abbr": "+01", + "offset": 3600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3 + ], + "transitions": [ + -1773012580, + -956361600, + -950490000, + -942019200, + -761187600, + -617241600, + -605149200, + -81432000, + -71110800, + 141264000, + 147222000, + 199756800, + 207702000, + 231292800, + 244249200, + 265507200, + 271033200, + 448243200, + 504918000, + 1212278400, + 1220223600, + 1243814400, + 1250809200, + 1272758400, + 1281222000, + 1301788800, + 1312066800, + 1335664800, + 1342749600, + 1345428000, + 1348970400, + 1367114400, + 1373162400, + 1376100000, + 1382839200, + 1396144800, + 1403920800, + 1406944800, + 1414288800, + 1427594400, + 1434247200, + 1437271200, + 1445738400, + 1459044000, + 1465092000, + 1468116000, + 1477792800, + 1490493600, + 1495332000, + 1498960800, + 1509242400, + 1521943200, + 1526176800, + 1529200800, + 1557021600, + 1560045600, + 1587261600, + 1590890400, + 1618106400, + 1621130400, + 1648346400, + 1651975200, + 1679191200, + 1682215200, + 1710036000, + 1713060000, + 1740276000, + 1743904800, + 1771120800, + 1774144800, + 1801965600, + 1804989600, + 1832205600, + 1835834400, + 1863050400, + 1866074400, + 1893290400, + 1896919200, + 1924135200, + 1927159200, + 1954980000, + 1958004000, + 1985220000, + 1988848800, + 2016064800, + 2019088800, + 2046304800, + 2049933600, + 2077149600, + 2080778400, + 2107994400, + 2111018400, + 2138234400, + 2141863200, + 2169079200, + 2172103200, + 2199924000, + 2202948000, + 2230164000, + 2233792800, + 2261008800, + 2264032800, + 2291248800, + 2294877600, + 2322093600, + 2325722400, + 2352938400, + 2355962400, + 2383178400, + 2386807200, + 2414023200, + 2417047200, + 2444868000, + 2447892000, + 2475108000, + 2478736800, + 2505952800, + 2508976800, + 2536192800, + 2539821600, + 2567037600, + 2570666400, + 2597882400, + 2600906400, + 2628122400, + 2631751200, + 2658967200, + 2661991200, + 2689812000, + 2692836000, + 2720052000, + 2723680800, + 2750896800, + 2753920800, + 2781136800, + 2784765600, + 2811981600, + 2815610400, + 2842826400, + 2845850400, + 2873066400, + 2876695200, + 2903911200, + 2906935200, + 2934756000, + 2937780000, + 2964996000, + 2968624800, + 2995840800, + 2998864800, + 3026080800, + 3029709600, + 3056925600, + 3060554400, + 3087770400, + 3090794400, + 3118010400, + 3121639200, + 3148855200, + 3151879200, + 3179700000, + 3182724000, + 3209940000, + 3213568800, + 3240784800, + 3243808800, + 3271024800, + 3274653600, + 3301869600, + 3305498400, + 3332714400, + 3335738400, + 3362954400, + 3366583200, + 3393799200, + 3396823200, + 3424644000, + 3427668000, + 3454884000, + 3458512800, + 3485728800, + 3488752800, + 3515968800, + 3519597600, + 3546813600, + 3549837600, + 3577658400, + 3580682400, + 3607898400, + 3611527200, + 3638743200, + 3641767200, + 3669588000, + 3672612000, + 3699828000, + 3703456800 + ], + "types": [ + { + "offset": -1820 + }, + { + "offset": 0 + }, + { + "offset": 3600 + }, + { + "offset": 3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-715448d734f9507a-f4183ed224275281.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-715448d734f9507a-f4183ed224275281.json new file mode 100644 index 00000000000000..c3ecbed4489f94 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-715448d734f9507a-f4183ed224275281.json @@ -0,0 +1,170 @@ +{ + "ids": [ + "america/argentina/tucuman" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 2, + 5, + 3, + 4, + 5, + 3, + 4, + 3, + 4, + 3, + 4, + 2, + 3, + 4, + 5, + 3, + 4, + 5 + ], + "transitions": [ + -2372096348, + -1567453392, + -1233432000, + -1222981200, + -1205956800, + -1194037200, + -1172865600, + -1162501200, + -1141329600, + -1130965200, + -1109793600, + -1099429200, + -1078257600, + -1067806800, + -1046635200, + -1036270800, + -1015099200, + -1004734800, + -983563200, + -973198800, + -952027200, + -941576400, + -931032000, + -900882000, + -890337600, + -833749200, + -827265600, + -752274000, + -733780800, + -197326800, + -190843200, + -184194000, + -164491200, + -152658000, + -132955200, + -121122000, + -101419200, + -86821200, + -71092800, + -54766800, + -39038400, + -23317200, + -7588800, + 128142000, + 136605600, + 596948400, + 605066400, + 624423600, + 636516000, + 656478000, + 667965600, + 687931200, + 699415200, + 719377200, + 731469600, + 938919600, + 952052400, + 1086058800, + 1087099200, + 1198983600, + 1205632800, + 1224385200 + ], + "types": [ + { + "offset": -15652 + }, + { + "offset": -15408 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7238398358c87edf-bc2588b2ce94bc20.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7238398358c87edf-bc2588b2ce94bc20.json new file mode 100644 index 00000000000000..e103ef78905fe7 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7238398358c87edf-bc2588b2ce94bc20.json @@ -0,0 +1,41 @@ +{ + "ids": [ + "pacific/noumea" + ], + "tzif": { + "posix": { + "abbr": "+11", + "offset": 39600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1829387148, + 250002000, + 257342400, + 281451600, + 288878400, + 849366000, + 857228400 + ], + "types": [ + { + "offset": 39948 + }, + { + "offset": 39600 + }, + { + "offset": 43200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7241c1457aae4357-3c4783fc5e291a5.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7241c1457aae4357-3c4783fc5e291a5.json new file mode 100644 index 00000000000000..8d92255c9acba2 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7241c1457aae4357-3c4783fc5e291a5.json @@ -0,0 +1,74 @@ +{ + "ids": [ + "asia/baghdad" + ], + "tzif": { + "posix": { + "abbr": "+03", + "offset": 10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2 + ], + "transitions": [ + -2524532260, + -1641005856, + 389048400, + 402264000, + 417906000, + 433800000, + 449614800, + 465422400, + 481150800, + 496792800, + 512517600, + 528242400, + 543967200, + 559692000, + 575416800, + 591141600, + 606866400, + 622591200, + 638316000, + 654645600, + 670464000, + 686275200 + ], + "types": [ + { + "offset": 10660 + }, + { + "offset": 10656 + }, + { + "offset": 10800 + }, + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7285bd926fe2dc70-a6ffff1cf5147cbf.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7285bd926fe2dc70-a6ffff1cf5147cbf.json new file mode 100644 index 00000000000000..f32ffbd11b050e --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7285bd926fe2dc70-a6ffff1cf5147cbf.json @@ -0,0 +1,31 @@ +{ + "ids": [ + "pacific/niue" + ], + "tzif": { + "posix": { + "abbr": "-11", + "offset": -39600, + "transition": null + }, + "transition_types": [ + 1, + 2 + ], + "transitions": [ + -543069620, + -173623200 + ], + "types": [ + { + "offset": -40780 + }, + { + "offset": -40800 + }, + { + "offset": -39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-72be3d5f2c49eb87-7e9fa5340a3dee71.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-72be3d5f2c49eb87-7e9fa5340a3dee71.json new file mode 100644 index 00000000000000..f88776e5d634d2 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-72be3d5f2c49eb87-7e9fa5340a3dee71.json @@ -0,0 +1,26 @@ +{ + "ids": [ + "pacific/tahiti" + ], + "tzif": { + "posix": { + "abbr": "-10", + "offset": -36000, + "transition": null + }, + "transition_types": [ + 1 + ], + "transitions": [ + -1806674504 + ], + "types": [ + { + "offset": -35896 + }, + { + "offset": -36000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7459e3ffacdde5a6-a596288a1fff51a3.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7459e3ffacdde5a6-a596288a1fff51a3.json new file mode 100644 index 00000000000000..5e67dae5ee840a --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7459e3ffacdde5a6-a596288a1fff51a3.json @@ -0,0 +1,29 @@ +{ + "ids": [ + "asia/dubai", + "asia/muscat", + "indian/mahe", + "indian/reunion" + ], + "tzif": { + "posix": { + "abbr": "+04", + "offset": 14400, + "transition": null + }, + "transition_types": [ + 1 + ], + "transitions": [ + -1577936472 + ], + "types": [ + { + "offset": 13272 + }, + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7481a99701104a1c-da931bd1c7d61a9.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7481a99701104a1c-da931bd1c7d61a9.json new file mode 100644 index 00000000000000..9e0954bdae7a8d --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7481a99701104a1c-da931bd1c7d61a9.json @@ -0,0 +1,105 @@ +{ + "ids": [ + "america/recife" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1767217224, + -1206957600, + -1191362400, + -1175374800, + -1159826400, + -633819600, + -622069200, + -602283600, + -591832800, + -570747600, + -560210400, + -539125200, + -531352800, + -191365200, + -184197600, + -155163600, + -150069600, + -128898000, + -121125600, + -99954000, + -89589600, + -68418000, + -57967200, + 499748400, + 511236000, + 530593200, + 540266400, + 562129200, + 571197600, + 592974000, + 602042400, + 624423600, + 634701600, + 938919600, + 951616800, + 970974000, + 971575200, + 1003028400, + 1013911200 + ], + "types": [ + { + "offset": -8376 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-748e0c2c22be393e-9159f30a64f07d32.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-748e0c2c22be393e-9159f30a64f07d32.json new file mode 100644 index 00000000000000..23814008143a83 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-748e0c2c22be393e-9159f30a64f07d32.json @@ -0,0 +1,205 @@ +{ + "ids": [ + "asia/amman" + ], + "tzif": { + "posix": { + "abbr": "+03", + "offset": 10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 3 + ], + "transitions": [ + -1230776624, + 108165600, + 118270800, + 136591200, + 149806800, + 168127200, + 181342800, + 199749600, + 215643600, + 231285600, + 244501200, + 262735200, + 275950800, + 481154400, + 496962000, + 512949600, + 528670800, + 544399200, + 560120400, + 575848800, + 592174800, + 610581600, + 623624400, + 641167200, + 655074000, + 671839200, + 685918800, + 702856800, + 717973200, + 733701600, + 749422800, + 765151200, + 779662800, + 797205600, + 811116000, + 828655200, + 843170400, + 860104800, + 874620000, + 891554400, + 906069600, + 930780000, + 938124000, + 954367200, + 970178400, + 985816800, + 1001628000, + 1017352800, + 1033077600, + 1048802400, + 1066946400, + 1080252000, + 1097791200, + 1112306400, + 1128031200, + 1143756000, + 1161900000, + 1175205600, + 1193349600, + 1206655200, + 1225404000, + 1238104800, + 1256853600, + 1269554400, + 1288303200, + 1301608800, + 1319752800, + 1333058400, + 1387486800, + 1395957600, + 1414706400, + 1427407200, + 1446156000, + 1459461600, + 1477605600, + 1490911200, + 1509055200, + 1522360800, + 1540504800, + 1553810400, + 1571954400, + 1585260000, + 1604008800, + 1616709600, + 1635458400, + 1645740000, + 1666908000 + ], + "types": [ + { + "offset": 8624 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-74fc38128e80b92d-871756115f3d1b05.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-74fc38128e80b92d-871756115f3d1b05.json new file mode 100644 index 00000000000000..2e53b9b856b88a --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-74fc38128e80b92d-871756115f3d1b05.json @@ -0,0 +1,230 @@ +{ + "ids": [ + "asia/famagusta" + ], + "tzif": { + "posix": { + "abbr": "EET", + "offset": 7200, + "transition": { + "abbr": "EEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 14400 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 3, + 1 + ], + "transitions": [ + -1518920148, + 166572000, + 182293200, + 200959200, + 213829200, + 228866400, + 243982800, + 260316000, + 276123600, + 291765600, + 307486800, + 323820000, + 338936400, + 354664800, + 370386000, + 386114400, + 401835600, + 417564000, + 433285200, + 449013600, + 465339600, + 481068000, + 496789200, + 512517600, + 528238800, + 543967200, + 559688400, + 575416800, + 591138000, + 606866400, + 622587600, + 638316000, + 654642000, + 670370400, + 686091600, + 701820000, + 717541200, + 733269600, + 748990800, + 764719200, + 780440400, + 796168800, + 811890000, + 828223200, + 843944400, + 859672800, + 875394000, + 891122400, + 909277200, + 922582800, + 941331600, + 954032400, + 972781200, + 985482000, + 1004230800, + 1017536400, + 1035680400, + 1048986000, + 1067130000, + 1080435600, + 1099184400, + 1111885200, + 1130634000, + 1143334800, + 1162083600, + 1174784400, + 1193533200, + 1206838800, + 1224982800, + 1238288400, + 1256432400, + 1269738000, + 1288486800, + 1301187600, + 1319936400, + 1332637200, + 1351386000, + 1364691600, + 1382835600, + 1396141200, + 1414285200, + 1427590800, + 1445734800, + 1459040400, + 1473282000, + 1509238800 + ], + "types": [ + { + "offset": 8148 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-754b9e4bdb20aa95-1c5b7a1b811c5ae3.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-754b9e4bdb20aa95-1c5b7a1b811c5ae3.json new file mode 100644 index 00000000000000..8fd2df3513d126 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-754b9e4bdb20aa95-1c5b7a1b811c5ae3.json @@ -0,0 +1,147 @@ +{ + "ids": [ + "america/fort_wayne", + "america/indiana/indianapolis", + "america/indianapolis", + "us/east-indiana" + ], + "tzif": { + "posix": { + "abbr": "EST", + "offset": -18000, + "transition": { + "abbr": "EDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3 + ], + "transitions": [ + -2717647200, + -1633276800, + -1615136400, + -1601827200, + -1583686800, + -900259200, + -891795600, + -880214400, + -769395600, + -765392400, + -757360800, + -733942800, + -715795200, + -702493200, + -684345600, + -671043600, + -652896000, + -639594000, + -620841600, + -608144400, + -589392000, + -576090000, + -557942400, + -544640400, + -526492800, + -513190800, + -495043200, + -481741200, + -463593600, + -386787600, + -368640000, + -21488400, + -5767200, + 9961200, + 25682400, + 1143961200, + 1162101600, + 1173596400, + 1194156000 + ], + "types": [ + { + "offset": -20678 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-758d7fde6833ba8c-65256d0857a2f636.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-758d7fde6833ba8c-65256d0857a2f636.json new file mode 100644 index 00000000000000..1e68e6b7b766c6 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-758d7fde6833ba8c-65256d0857a2f636.json @@ -0,0 +1,264 @@ +{ + "ids": [ + "asia/jerusalem", + "asia/tel_aviv", + "israel" + ], + "tzif": { + "posix": { + "abbr": "IST", + "offset": 7200, + "transition": { + "abbr": "IDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 4, + 5 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 4, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2 + ], + "transitions": [ + -2840149254, + -1641003640, + -933638400, + -923097600, + -919036800, + -857347200, + -844300800, + -825811200, + -812678400, + -794188800, + -779846400, + -762652800, + -748310400, + -731116800, + -681955200, + -673228800, + -667958400, + -652320000, + -636422400, + -622080000, + -608947200, + -591840000, + -572486400, + -558576000, + -542851200, + -527731200, + -514425600, + -490838400, + -482976000, + -459388800, + -451526400, + -428544000, + -418262400, + -400118400, + -387417600, + 142380000, + 150843600, + 167176800, + 178664400, + 334101600, + 337730400, + 452642400, + 462319200, + 482277600, + 494370000, + 516751200, + 526424400, + 545436000, + 558478800, + 576626400, + 589323600, + 609890400, + 620773200, + 638316000, + 651618000, + 669765600, + 683672400, + 701820000, + 715726800, + 733701600, + 747176400, + 765151200, + 778021200, + 796600800, + 810075600, + 826840800, + 842821200, + 858895200, + 874184400, + 890344800, + 905029200, + 923011200, + 936313200, + 955670400, + 970783200, + 986770800, + 1001282400, + 1017356400, + 1033941600, + 1048806000, + 1065132000, + 1081292400, + 1095804000, + 1112313600, + 1128812400, + 1143763200, + 1159657200, + 1175212800, + 1189897200, + 1206662400, + 1223161200, + 1238112000, + 1254006000, + 1269561600, + 1284246000, + 1301616000, + 1317510000, + 1333065600, + 1348354800, + 1364515200, + 1382828400 + ], + "types": [ + { + "offset": 8454 + }, + { + "offset": 8440 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7599edfd11a3db64-4bf8d694826715ae.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7599edfd11a3db64-4bf8d694826715ae.json new file mode 100644 index 00000000000000..693b0c4c3e9053 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7599edfd11a3db64-4bf8d694826715ae.json @@ -0,0 +1,339 @@ +{ + "ids": [ + "america/kentucky/louisville", + "america/louisville" + ], + "tzif": { + "posix": { + "abbr": "EST", + "offset": -18000, + "transition": { + "abbr": "EDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3 + ], + "transitions": [ + -2717647200, + -1633276800, + -1615136400, + -1601827200, + -1583686800, + -1535904000, + -1525280400, + -905097600, + -891795600, + -880214400, + -769395600, + -765392400, + -747251940, + -744224400, + -620841600, + -608144400, + -589392000, + -576090000, + -557942400, + -544640400, + -526492800, + -513190800, + -495043200, + -481741200, + -463593600, + -450291600, + -431539200, + -415818000, + -400089600, + -384368400, + -368640000, + -352918800, + -337190400, + -321469200, + -305740800, + -289414800, + -273686400, + -266432400, + -52938000, + -37216800, + -21488400, + -5767200, + 9961200, + 25682400, + 41410800, + 57736800, + 73465200, + 89186400, + 104914800, + 120636000, + 126687600, + 152089200, + 162370800, + 183535200, + 199263600, + 215589600, + 230713200, + 247039200, + 262767600, + 278488800, + 294217200, + 309938400, + 325666800, + 341388000, + 357116400, + 372837600, + 388566000, + 404892000, + 420015600, + 436341600, + 452070000, + 467791200, + 483519600, + 499240800, + 514969200, + 530690400, + 544604400, + 562140000, + 576054000, + 594194400, + 607503600, + 625644000, + 638953200, + 657093600, + 671007600, + 688543200, + 702457200, + 719992800, + 733906800, + 752047200, + 765356400, + 783496800, + 796806000, + 814946400, + 828860400, + 846396000, + 860310000, + 877845600, + 891759600, + 909295200, + 923209200, + 941349600, + 954658800, + 972799200, + 986108400, + 1004248800, + 1018162800, + 1035698400, + 1049612400, + 1067148000, + 1081062000, + 1099202400, + 1112511600, + 1130652000, + 1143961200, + 1162101600, + 1173596400, + 1194156000 + ], + "types": [ + { + "offset": -20582 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-75a476630c4f3c06-6cc92a5fc490dfa3.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-75a476630c4f3c06-6cc92a5fc490dfa3.json new file mode 100644 index 00000000000000..18b872c8a44cca --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-75a476630c4f3c06-6cc92a5fc490dfa3.json @@ -0,0 +1,129 @@ +{ + "ids": [ + "america/araguaina" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1767214032, + -1206957600, + -1191362400, + -1175374800, + -1159826400, + -633819600, + -622069200, + -602283600, + -591832800, + -570747600, + -560210400, + -539125200, + -531352800, + -191365200, + -184197600, + -155163600, + -150069600, + -128898000, + -121125600, + -99954000, + -89589600, + -68418000, + -57967200, + 499748400, + 511236000, + 530593200, + 540266400, + 562129200, + 571197600, + 592974000, + 602042400, + 624423600, + 634701600, + 813726000, + 824004000, + 844570800, + 856058400, + 876106800, + 888717600, + 908074800, + 919562400, + 938919600, + 951616800, + 970974000, + 982461600, + 1003028400, + 1013911200, + 1036292400, + 1045360800, + 1350788400, + 1361066400 + ], + "types": [ + { + "offset": -11568 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7622c5c99b380b37-74a373c9f92241c7.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7622c5c99b380b37-74a373c9f92241c7.json new file mode 100644 index 00000000000000..4cff8fa3fe6bd6 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7622c5c99b380b37-74a373c9f92241c7.json @@ -0,0 +1,224 @@ +{ + "ids": [ + "europe/chisinau", + "europe/tiraspol" + ], + "tzif": { + "posix": { + "abbr": "EET", + "offset": 7200, + "transition": { + "abbr": "EEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 5, + 6, + 3, + 5, + 6, + 3, + 5, + 4, + 7, + 8, + 4, + 7, + 8, + 4, + 7, + 8, + 4, + 7, + 8, + 4, + 7, + 8, + 4, + 7, + 8, + 4, + 7, + 8, + 4, + 7, + 8, + 4, + 7, + 8, + 4, + 7, + 8, + 4, + 7, + 3, + 5, + 4, + 7, + 3, + 5, + 4, + 7, + 3, + 5, + 4, + 7, + 3, + 5, + 4, + 7, + 3, + 5, + 4, + 7, + 3, + 5, + 4, + 7, + 3, + 5, + 4, + 7, + 3, + 5 + ], + "transitions": [ + -2840147720, + -1637114100, + -1213148664, + -1187056800, + -1175479200, + -1159754400, + -1144029600, + -1127700000, + -1111975200, + -1096250400, + -1080525600, + -1064800800, + -1049076000, + -1033351200, + -1017626400, + -1001901600, + -986176800, + -970452000, + -954727200, + -927165600, + -898138800, + -857257200, + -844556400, + -828226800, + -812502000, + -800157600, + 354920400, + 370728000, + 386456400, + 402264000, + 417992400, + 433800000, + 449614800, + 465346800, + 481071600, + 496796400, + 512521200, + 528246000, + 543970800, + 559695600, + 575420400, + 591145200, + 606870000, + 622594800, + 638319600, + 641944800, + 654652800, + 670377600, + 686102400, + 694216800, + 717541200, + 733269600, + 748990800, + 764719200, + 780440400, + 796168800, + 811890000, + 828223200, + 846363600, + 859680000, + 877824000 + ], + "types": [ + { + "offset": 6920 + }, + { + "offset": 6900 + }, + { + "offset": 6264 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 7200 + }, + { + "offset": 3600 + }, + { + "offset": 10800 + }, + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-762fa57e245bdc0d-c5a018de141b4cb3.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-762fa57e245bdc0d-c5a018de141b4cb3.json new file mode 100644 index 00000000000000..67ea7ea99cdd55 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-762fa57e245bdc0d-c5a018de141b4cb3.json @@ -0,0 +1,32 @@ +{ + "ids": [ + "asia/thimbu", + "asia/thimphu" + ], + "tzif": { + "posix": { + "abbr": "+06", + "offset": 21600, + "transition": null + }, + "transition_types": [ + 1, + 2 + ], + "transitions": [ + -706341516, + 560025000 + ], + "types": [ + { + "offset": 21516 + }, + { + "offset": 19800 + }, + { + "offset": 21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-768158f1c3d3089e-e43bac17424df347.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-768158f1c3d3089e-e43bac17424df347.json new file mode 100644 index 00000000000000..68796ec7b64e72 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-768158f1c3d3089e-e43bac17424df347.json @@ -0,0 +1,258 @@ +{ + "ids": [ + "america/sitka" + ], + "tzif": { + "posix": { + "abbr": "AKST", + "offset": -32400, + "transition": { + "abbr": "AKDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 4, + 5, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5 + ], + "transitions": [ + -3225223727, + -2188954727, + -880207200, + -769395600, + -765385200, + -21477600, + -5756400, + 9972000, + 25693200, + 41421600, + 57747600, + 73476000, + 89197200, + 104925600, + 120646800, + 126698400, + 152096400, + 162381600, + 183546000, + 199274400, + 215600400, + 230724000, + 247050000, + 262778400, + 278499600, + 294228000, + 309949200, + 325677600, + 341398800, + 357127200, + 372848400, + 388576800, + 404902800, + 420026400, + 436352400, + 436356000, + 439030800, + 452084400, + 467805600, + 483534000, + 499255200, + 514983600, + 530704800, + 544618800, + 562154400, + 576068400, + 594208800, + 607518000, + 625658400, + 638967600, + 657108000, + 671022000, + 688557600, + 702471600, + 720007200, + 733921200, + 752061600, + 765370800, + 783511200, + 796820400, + 814960800, + 828874800, + 846410400, + 860324400, + 877860000, + 891774000, + 909309600, + 923223600, + 941364000, + 954673200, + 972813600, + 986122800, + 1004263200, + 1018177200, + 1035712800, + 1049626800, + 1067162400, + 1081076400, + 1099216800, + 1112526000, + 1130666400, + 1143975600, + 1162116000, + 1173610800, + 1194170400 + ], + "types": [ + { + "offset": 53927 + }, + { + "offset": -32473 + }, + { + "offset": -28800 + }, + { + "offset": -25200 + }, + { + "offset": -28800 + }, + { + "offset": -32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7776a42ce751a29e-1629f5ee8a6e924e.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7776a42ce751a29e-1629f5ee8a6e924e.json new file mode 100644 index 00000000000000..a0c506cd63eb2e --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7776a42ce751a29e-1629f5ee8a6e924e.json @@ -0,0 +1,98 @@ +{ + "ids": [ + "america/danmarkshavn" + ], + "tzif": { + "posix": { + "abbr": "GMT", + "offset": 0, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 3 + ], + "transitions": [ + -1686091520, + 323845200, + 338950800, + 354675600, + 370400400, + 386125200, + 401850000, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 820465200 + ], + "types": [ + { + "offset": -4480 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + }, + { + "offset": 0 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-794b5729aca99b8f-8dcbb73848fb52db.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-794b5729aca99b8f-8dcbb73848fb52db.json new file mode 100644 index 00000000000000..60e3cc9f6bff2a --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-794b5729aca99b8f-8dcbb73848fb52db.json @@ -0,0 +1,49 @@ +{ + "ids": [ + "australia/darwin", + "australia/north" + ], + "tzif": { + "posix": { + "abbr": "ACST", + "offset": 34200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3 + ], + "transitions": [ + -2364108200, + -2230189200, + -1672558200, + -1665387000, + -883639800, + -876123000, + -860398200, + -844673400, + -828343800 + ], + "types": [ + { + "offset": 31400 + }, + { + "offset": 32400 + }, + { + "offset": 34200 + }, + { + "offset": 37800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-79a67056f030a883-f33ddefe3e35e4d0.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-79a67056f030a883-f33ddefe3e35e4d0.json new file mode 100644 index 00000000000000..fa4a8618b71ff3 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-79a67056f030a883-f33ddefe3e35e4d0.json @@ -0,0 +1,27 @@ +{ + "ids": [ + "asia/kashgar", + "asia/urumqi" + ], + "tzif": { + "posix": { + "abbr": "+06", + "offset": 21600, + "transition": null + }, + "transition_types": [ + 1 + ], + "transitions": [ + -1325483420 + ], + "types": [ + { + "offset": 21020 + }, + { + "offset": 21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7a158f0aed162547-27577cc8813fb4ed.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7a158f0aed162547-27577cc8813fb4ed.json new file mode 100644 index 00000000000000..abe95e637b857f --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7a158f0aed162547-27577cc8813fb4ed.json @@ -0,0 +1,82 @@ +{ + "ids": [ + "asia/dushanbe" + ], + "tzif": { + "posix": { + "abbr": "+05", + "offset": 18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 1 + ], + "transitions": [ + -1441168512, + -1247547600, + 354909600, + 370717200, + 386445600, + 402253200, + 417981600, + 433789200, + 449604000, + 465336000, + 481060800, + 496785600, + 512510400, + 528235200, + 543960000, + 559684800, + 575409600, + 591134400, + 606859200, + 622584000, + 638308800, + 654638400, + 670363200, + 684363600 + ], + "types": [ + { + "offset": 16512 + }, + { + "offset": 18000 + }, + { + "offset": 21600 + }, + { + "offset": 25200 + }, + { + "offset": 21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7aa0aebc84b44c67-973b0b87d9034391.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7aa0aebc84b44c67-973b0b87d9034391.json new file mode 100644 index 00000000000000..298de1ce9a3048 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7aa0aebc84b44c67-973b0b87d9034391.json @@ -0,0 +1,38 @@ +{ + "ids": [ + "africa/sao_tome" + ], + "tzif": { + "posix": { + "abbr": "GMT", + "offset": 0, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2 + ], + "transitions": [ + -2713912016, + -1830384000, + 1514768400, + 1546304400 + ], + "types": [ + { + "offset": 1616 + }, + { + "offset": -2205 + }, + { + "offset": 0 + }, + { + "offset": 3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7ba4aaa7dba09bb0-567af4b250c89d25.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7ba4aaa7dba09bb0-567af4b250c89d25.json new file mode 100644 index 00000000000000..dc696146bc098e --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7ba4aaa7dba09bb0-567af4b250c89d25.json @@ -0,0 +1,210 @@ +{ + "ids": [ + "america/ojinaga" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": { + "abbr": "CDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 2, + 3 + ], + "transitions": [ + -1514739600, + -1343149200, + -1234807200, + -1220461200, + -1207159200, + -1191344400, + 828864000, + 846399600, + 860313600, + 877849200, + 891766800, + 909302400, + 923216400, + 941356800, + 954666000, + 972806400, + 989139600, + 1001836800, + 1018170000, + 1035705600, + 1049619600, + 1067155200, + 1081069200, + 1099209600, + 1112518800, + 1130659200, + 1143968400, + 1162108800, + 1175418000, + 1193558400, + 1207472400, + 1225008000, + 1238922000, + 1256457600, + 1268557200, + 1289116800, + 1300006800, + 1320566400, + 1331456400, + 1352016000, + 1362906000, + 1383465600, + 1394355600, + 1414915200, + 1425805200, + 1446364800, + 1457859600, + 1478419200, + 1489309200, + 1509868800, + 1520758800, + 1541318400, + 1552208400, + 1572768000, + 1583658000, + 1604217600, + 1615712400, + 1636272000, + 1647162000, + 1667116800 + ], + "types": [ + { + "offset": -25060 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7bce416a66d38e42-b58b08c4c731f7dc.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7bce416a66d38e42-b58b08c4c731f7dc.json new file mode 100644 index 00000000000000..99725a71edd578 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7bce416a66d38e42-b58b08c4c731f7dc.json @@ -0,0 +1,34 @@ +{ + "ids": [ + "asia/tokyo", + "japan" + ], + "tzif": { + "posix": { + "abbr": "JST", + "offset": 32400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1 + ], + "transitions": [ + -2587712400, + -683802000, + -672310800 + ], + "types": [ + { + "offset": 33539 + }, + { + "offset": 32400 + }, + { + "offset": 36000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7be16635ecf890b5-161efc0ab3ac2299.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7be16635ecf890b5-161efc0ab3ac2299.json new file mode 100644 index 00000000000000..4e6910e6c2e01f --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7be16635ecf890b5-161efc0ab3ac2299.json @@ -0,0 +1,193 @@ +{ + "ids": [ + "asia/magadan" + ], + "tzif": { + "posix": { + "abbr": "+11", + "offset": 39600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 5, + 1, + 2, + 4 + ], + "transitions": [ + -1441188192, + -1247565600, + 354891600, + 370699200, + 386427600, + 402235200, + 417963600, + 433771200, + 449586000, + 465318000, + 481042800, + 496767600, + 512492400, + 528217200, + 543942000, + 559666800, + 575391600, + 591116400, + 606841200, + 622566000, + 638290800, + 654620400, + 670345200, + 670348800, + 686073600, + 695750400, + 701794800, + 717519600, + 733244400, + 748969200, + 764694000, + 780418800, + 796143600, + 811868400, + 828198000, + 846342000, + 859647600, + 877791600, + 891097200, + 909241200, + 922546800, + 941295600, + 953996400, + 972745200, + 985446000, + 1004194800, + 1017500400, + 1035644400, + 1048950000, + 1067094000, + 1080399600, + 1099148400, + 1111849200, + 1130598000, + 1143298800, + 1162047600, + 1174748400, + 1193497200, + 1206802800, + 1224946800, + 1238252400, + 1256396400, + 1269702000, + 1288450800, + 1301151600, + 1414245600, + 1461427200 + ], + "types": [ + { + "offset": 36192 + }, + { + "offset": 36000 + }, + { + "offset": 39600 + }, + { + "offset": 43200 + }, + { + "offset": 39600 + }, + { + "offset": 43200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7cca7c8a1af35285-679fdca550b074a0.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7cca7c8a1af35285-679fdca550b074a0.json new file mode 100644 index 00000000000000..48271b49fc4192 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7cca7c8a1af35285-679fdca550b074a0.json @@ -0,0 +1,35 @@ +{ + "ids": [ + "asia/dili" + ], + "tzif": { + "posix": { + "abbr": "+09", + "offset": 32400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2 + ], + "transitions": [ + -1830412800, + -879152400, + 199897200, + 969120000 + ], + "types": [ + { + "offset": 30140 + }, + { + "offset": 28800 + }, + { + "offset": 32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7d33da447360d55c-52583d8c13b6f677.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7d33da447360d55c-52583d8c13b6f677.json new file mode 100644 index 00000000000000..f8070aa53de5c4 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7d33da447360d55c-52583d8c13b6f677.json @@ -0,0 +1,250 @@ +{ + "ids": [ + "europe/madrid" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": { + "abbr": "CEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 2, + 1, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4 + ], + "transitions": [ + -2177452800, + -1631926800, + -1616889600, + -1601168400, + -1585353600, + -1442451600, + -1427673600, + -1379293200, + -1364774400, + -1348448400, + -1333324800, + -1316390400, + -1301270400, + -1284339600, + -1269820800, + -1026954000, + -1017619200, + -1001898000, + -999482400, + -986090400, + -954115200, + -940208400, + -873079200, + -862621200, + -842839200, + -828320400, + -811389600, + -796870800, + -779940000, + -765421200, + -748490400, + -733971600, + -652327200, + -639018000, + 135122400, + 150246000, + 166572000, + 181695600, + 196812000, + 212540400, + 228866400, + 243990000, + 260326800, + 276051600, + 291776400, + 307501200, + 323830800, + 338950800, + 354675600, + 370400400, + 386125200, + 401850000, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": -884 + }, + { + "offset": 0 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + }, + { + "offset": 3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7d7635957a94c158-89410cc4ecfceda2.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7d7635957a94c158-89410cc4ecfceda2.json new file mode 100644 index 00000000000000..3ca5c1a8678149 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7d7635957a94c158-89410cc4ecfceda2.json @@ -0,0 +1,332 @@ +{ + "ids": [ + "america/punta_arenas" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 3, + 1, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 3, + 4, + 2, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 5, + 6 + ], + "transitions": [ + -2524504580, + -1892661435, + -1688410800, + -1619205435, + -1593806400, + -1335986235, + -1335985200, + -1317585600, + -1304362800, + -1286049600, + -1272826800, + -1254513600, + -1241290800, + -1222977600, + -1209754800, + -1191355200, + -1178132400, + -870552000, + -865278000, + -736632000, + -718056000, + -713649600, + -36619200, + -23922000, + -3355200, + 7527600, + 24465600, + 37767600, + 55915200, + 69217200, + 87969600, + 100666800, + 118209600, + 132116400, + 150868800, + 163566000, + 182318400, + 195620400, + 213768000, + 227070000, + 245217600, + 258519600, + 277272000, + 289969200, + 308721600, + 321418800, + 340171200, + 353473200, + 371620800, + 384922800, + 403070400, + 416372400, + 434520000, + 447822000, + 466574400, + 479271600, + 498024000, + 510721200, + 529473600, + 545194800, + 560923200, + 574225200, + 592372800, + 605674800, + 624427200, + 637124400, + 653457600, + 668574000, + 687326400, + 700628400, + 718776000, + 732078000, + 750225600, + 763527600, + 781675200, + 794977200, + 813729600, + 826426800, + 845179200, + 859690800, + 876628800, + 889930800, + 906868800, + 923194800, + 939528000, + 952830000, + 971582400, + 984279600, + 1003032000, + 1015729200, + 1034481600, + 1047178800, + 1065931200, + 1079233200, + 1097380800, + 1110682800, + 1128830400, + 1142132400, + 1160884800, + 1173582000, + 1192334400, + 1206846000, + 1223784000, + 1237086000, + 1255233600, + 1270350000, + 1286683200, + 1304823600, + 1313899200, + 1335668400, + 1346558400, + 1367118000, + 1378612800, + 1398567600, + 1410062400, + 1463281200, + 1471147200, + 1480820400 + ], + "types": [ + { + "offset": -17020 + }, + { + "offset": -16965 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json new file mode 100644 index 00000000000000..4e237e8d4114eb --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-7ec2120f35e8ce46-9f313b48e73a78c4.json @@ -0,0 +1,55 @@ +{ + "ids": [ + "america/anguilla", + "america/antigua", + "america/aruba", + "america/blanc-sablon", + "america/curacao", + "america/dominica", + "america/grenada", + "america/guadeloupe", + "america/kralendijk", + "america/lower_princes", + "america/marigot", + "america/montserrat", + "america/port_of_spain", + "america/puerto_rico", + "america/st_barthelemy", + "america/st_kitts", + "america/st_lucia", + "america/st_thomas", + "america/st_vincent", + "america/tortola", + "america/virgin" + ], + "tzif": { + "posix": { + "abbr": "AST", + "offset": -14400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 2, + 1 + ], + "transitions": [ + -2233035335, + -873057600, + -769395600, + -765399600 + ], + "types": [ + { + "offset": -15865 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-806417e5a9e6e27a-d183a9f9e82d72df.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-806417e5a9e6e27a-d183a9f9e82d72df.json new file mode 100644 index 00000000000000..0686889e5f3aa0 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-806417e5a9e6e27a-d183a9f9e82d72df.json @@ -0,0 +1,284 @@ +{ + "ids": [ + "america/scoresbysund" + ], + "tzif": { + "posix": { + "abbr": "-02", + "offset": -7200, + "transition": { + "abbr": "-01", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 0 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": -3600 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 2, + 4 + ], + "transitions": [ + -1686090728, + 323841600, + 338961600, + 354679200, + 370400400, + 386125200, + 401850000, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000, + 859683600, + 877827600, + 891133200, + 909277200, + 922582800, + 941331600, + 954032400, + 972781200, + 985482000, + 1004230800, + 1017536400, + 1035680400, + 1048986000, + 1067130000, + 1080435600, + 1099184400, + 1111885200, + 1130634000, + 1143334800, + 1162083600, + 1174784400, + 1193533200, + 1206838800, + 1224982800, + 1238288400, + 1256432400, + 1269738000, + 1288486800, + 1301187600, + 1319936400, + 1332637200, + 1351386000, + 1364691600, + 1382835600, + 1396141200, + 1414285200, + 1427590800, + 1445734800, + 1459040400, + 1477789200, + 1490490000, + 1509238800, + 1521939600, + 1540688400, + 1553994000, + 1572138000, + 1585443600, + 1603587600, + 1616893200, + 1635642000, + 1648342800, + 1667091600, + 1679792400, + 1698541200, + 1711846800 + ], + "types": [ + { + "offset": -5272 + }, + { + "offset": -7200 + }, + { + "offset": -3600 + }, + { + "offset": 0 + }, + { + "offset": -3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-81a0c2bb7c8a41da-7b4ebb9a4aa49253.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-81a0c2bb7c8a41da-7b4ebb9a4aa49253.json new file mode 100644 index 00000000000000..777730cf5e7e0d --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-81a0c2bb7c8a41da-7b4ebb9a4aa49253.json @@ -0,0 +1,109 @@ +{ + "ids": [ + "africa/tripoli", + "libya" + ], + "tzif": { + "posix": { + "abbr": "EET", + "offset": 7200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 2, + 3, + 1, + 2, + 3, + 2, + 3 + ], + "transitions": [ + -1577926364, + -574902000, + -568087200, + -512175600, + -504928800, + -449888400, + -441856800, + -347158800, + 378684000, + 386463600, + 402271200, + 417999600, + 433807200, + 449622000, + 465429600, + 481590000, + 496965600, + 512953200, + 528674400, + 544230000, + 560037600, + 575852400, + 591660000, + 607388400, + 623196000, + 641775600, + 844034400, + 860108400, + 875916000, + 1352505600, + 1364515200, + 1382659200 + ], + "types": [ + { + "offset": 3164 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + }, + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-83ab6f3e7a54b242-140e172ea09b920.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-83ab6f3e7a54b242-140e172ea09b920.json new file mode 100644 index 00000000000000..590c3ee9a6d4ec --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-83ab6f3e7a54b242-140e172ea09b920.json @@ -0,0 +1,164 @@ +{ + "ids": [ + "america/argentina/cordoba", + "america/cordoba", + "america/rosario" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 1, + 4, + 2, + 3, + 4, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 2, + 3, + 4 + ], + "transitions": [ + -2372096592, + -1567453392, + -1233432000, + -1222981200, + -1205956800, + -1194037200, + -1172865600, + -1162501200, + -1141329600, + -1130965200, + -1109793600, + -1099429200, + -1078257600, + -1067806800, + -1046635200, + -1036270800, + -1015099200, + -1004734800, + -983563200, + -973198800, + -952027200, + -941576400, + -931032000, + -900882000, + -890337600, + -833749200, + -827265600, + -752274000, + -733780800, + -197326800, + -190843200, + -184194000, + -164491200, + -152658000, + -132955200, + -121122000, + -101419200, + -86821200, + -71092800, + -54766800, + -39038400, + -23317200, + -7588800, + 128142000, + 136605600, + 596948400, + 605066400, + 624423600, + 636516000, + 656478000, + 667965600, + 687931200, + 699415200, + 719377200, + 731469600, + 938919600, + 952052400, + 1198983600, + 1205632800, + 1224385200 + ], + "types": [ + { + "offset": -15408 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-843bd4f4a13e936f-e20d11612a15d3e6.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-843bd4f4a13e936f-e20d11612a15d3e6.json new file mode 100644 index 00000000000000..82f98cd6a1c762 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-843bd4f4a13e936f-e20d11612a15d3e6.json @@ -0,0 +1,191 @@ +{ + "ids": [ + "asia/srednekolymsk" + ], + "tzif": { + "posix": { + "abbr": "+11", + "offset": 39600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 5, + 2, + 4 + ], + "transitions": [ + -1441188892, + -1247565600, + 354891600, + 370699200, + 386427600, + 402235200, + 417963600, + 433771200, + 449586000, + 465318000, + 481042800, + 496767600, + 512492400, + 528217200, + 543942000, + 559666800, + 575391600, + 591116400, + 606841200, + 622566000, + 638290800, + 654620400, + 670345200, + 670348800, + 686073600, + 695750400, + 701794800, + 717519600, + 733244400, + 748969200, + 764694000, + 780418800, + 796143600, + 811868400, + 828198000, + 846342000, + 859647600, + 877791600, + 891097200, + 909241200, + 922546800, + 941295600, + 953996400, + 972745200, + 985446000, + 1004194800, + 1017500400, + 1035644400, + 1048950000, + 1067094000, + 1080399600, + 1099148400, + 1111849200, + 1130598000, + 1143298800, + 1162047600, + 1174748400, + 1193497200, + 1206802800, + 1224946800, + 1238252400, + 1256396400, + 1269702000, + 1288450800, + 1301151600, + 1414245600 + ], + "types": [ + { + "offset": 36892 + }, + { + "offset": 36000 + }, + { + "offset": 39600 + }, + { + "offset": 43200 + }, + { + "offset": 39600 + }, + { + "offset": 43200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-84569b5d12891e1e-dfbd7173ea59c56d.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-84569b5d12891e1e-dfbd7173ea59c56d.json new file mode 100644 index 00000000000000..d4039851b9b0f9 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-84569b5d12891e1e-dfbd7173ea59c56d.json @@ -0,0 +1,31 @@ +{ + "ids": [ + "africa/bissau" + ], + "tzif": { + "posix": { + "abbr": "GMT", + "offset": 0, + "transition": null + }, + "transition_types": [ + 1, + 2 + ], + "transitions": [ + -1830380400, + 157770000 + ], + "types": [ + { + "offset": -3740 + }, + { + "offset": -3600 + }, + { + "offset": 0 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8494d6017f05e49d-6fa1752d1f7aa8c3.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8494d6017f05e49d-6fa1752d1f7aa8c3.json new file mode 100644 index 00000000000000..8d634798272261 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8494d6017f05e49d-6fa1752d1f7aa8c3.json @@ -0,0 +1,161 @@ +{ + "ids": [ + "america/indiana/winamac" + ], + "tzif": { + "posix": { + "abbr": "EST", + "offset": -18000, + "transition": { + "abbr": "EDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 1, + 2, + 3, + 1, + 4, + 2, + 3 + ], + "transitions": [ + -2717647200, + -1633276800, + -1615136400, + -1601827200, + -1583686800, + -880214400, + -769395600, + -765392400, + -747244800, + -733942800, + -715795200, + -702493200, + -684345600, + -671043600, + -652896000, + -639594000, + -620841600, + -608144400, + -589392000, + -576090000, + -557942400, + -544640400, + -526492800, + -513190800, + -495043200, + -481741200, + -463593600, + -447267600, + -431539200, + -415818000, + -400089600, + -386787600, + -368640000, + -355338000, + -337190400, + -323888400, + -305740800, + -292438800, + -273686400, + -21488400, + -5767200, + 9961200, + 25682400, + 1143961200, + 1143964800, + 1162105200, + 1173600000, + 1194156000 + ], + "types": [ + { + "offset": -20785 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-849b49f0ce1dac82-89b53710eb7d9371.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-849b49f0ce1dac82-89b53710eb7d9371.json new file mode 100644 index 00000000000000..f78d08044adf7b --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-849b49f0ce1dac82-89b53710eb7d9371.json @@ -0,0 +1,196 @@ +{ + "ids": [ + "asia/yekaterinburg" + ], + "tzif": { + "posix": { + "abbr": "+05", + "offset": 18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 3, + 5, + 3, + 5, + 2, + 4, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 6, + 3, + 5 + ], + "transitions": [ + -1688270553, + -1592610305, + -1247544000, + 354913200, + 370720800, + 386449200, + 402256800, + 417985200, + 433792800, + 449607600, + 465339600, + 481064400, + 496789200, + 512514000, + 528238800, + 543963600, + 559688400, + 575413200, + 591138000, + 606862800, + 622587600, + 638312400, + 654642000, + 670366800, + 670370400, + 686095200, + 695772000, + 701816400, + 717541200, + 733266000, + 748990800, + 764715600, + 780440400, + 796165200, + 811890000, + 828219600, + 846363600, + 859669200, + 877813200, + 891118800, + 909262800, + 922568400, + 941317200, + 954018000, + 972766800, + 985467600, + 1004216400, + 1017522000, + 1035666000, + 1048971600, + 1067115600, + 1080421200, + 1099170000, + 1111870800, + 1130619600, + 1143320400, + 1162069200, + 1174770000, + 1193518800, + 1206824400, + 1224968400, + 1238274000, + 1256418000, + 1269723600, + 1288472400, + 1301173200, + 1414267200 + ], + "types": [ + { + "offset": 14553 + }, + { + "offset": 13505 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + }, + { + "offset": 21600 + }, + { + "offset": 18000 + }, + { + "offset": 21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-86245dd795582456-61d8c9f7c4ad177a.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-86245dd795582456-61d8c9f7c4ad177a.json new file mode 100644 index 00000000000000..65a3121ee65c06 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-86245dd795582456-61d8c9f7c4ad177a.json @@ -0,0 +1,191 @@ +{ + "ids": [ + "asia/omsk" + ], + "tzif": { + "posix": { + "abbr": "+06", + "offset": 21600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 5, + 2, + 4 + ], + "transitions": [ + -1582088010, + -1247547600, + 354909600, + 370717200, + 386445600, + 402253200, + 417981600, + 433789200, + 449604000, + 465336000, + 481060800, + 496785600, + 512510400, + 528235200, + 543960000, + 559684800, + 575409600, + 591134400, + 606859200, + 622584000, + 638308800, + 654638400, + 670363200, + 670366800, + 686091600, + 695768400, + 701812800, + 717537600, + 733262400, + 748987200, + 764712000, + 780436800, + 796161600, + 811886400, + 828216000, + 846360000, + 859665600, + 877809600, + 891115200, + 909259200, + 922564800, + 941313600, + 954014400, + 972763200, + 985464000, + 1004212800, + 1017518400, + 1035662400, + 1048968000, + 1067112000, + 1080417600, + 1099166400, + 1111867200, + 1130616000, + 1143316800, + 1162065600, + 1174766400, + 1193515200, + 1206820800, + 1224964800, + 1238270400, + 1256414400, + 1269720000, + 1288468800, + 1301169600, + 1414263600 + ], + "types": [ + { + "offset": 17610 + }, + { + "offset": 18000 + }, + { + "offset": 21600 + }, + { + "offset": 25200 + }, + { + "offset": 21600 + }, + { + "offset": 25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-87649f3d059a10f2-a8c51b0e84c40a85.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-87649f3d059a10f2-a8c51b0e84c40a85.json new file mode 100644 index 00000000000000..127ea90d9ed46c --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-87649f3d059a10f2-a8c51b0e84c40a85.json @@ -0,0 +1,265 @@ +{ + "ids": [ + "america/whitehorse", + "canada/yukon" + ], + "tzif": { + "posix": { + "abbr": "MST", + "offset": -25200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 3, + 1, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 3, + 5 + ], + "transitions": [ + -2188997988, + -1632056400, + -1615125600, + -1596978000, + -1583164800, + -880203600, + -769395600, + -765381600, + -147884400, + -131554800, + -121273200, + 325677600, + 341398800, + 357127200, + 372848400, + 388576800, + 404902800, + 420026400, + 436352400, + 452080800, + 467802000, + 483530400, + 499251600, + 514980000, + 530701200, + 544615200, + 562150800, + 576064800, + 594205200, + 607514400, + 625654800, + 638964000, + 657104400, + 671018400, + 688554000, + 702468000, + 720003600, + 733917600, + 752058000, + 765367200, + 783507600, + 796816800, + 814957200, + 828871200, + 846406800, + 860320800, + 877856400, + 891770400, + 909306000, + 923220000, + 941360400, + 954669600, + 972810000, + 986119200, + 1004259600, + 1018173600, + 1035709200, + 1049623200, + 1067158800, + 1081072800, + 1099213200, + 1112522400, + 1130662800, + 1143972000, + 1162112400, + 1173607200, + 1194166800, + 1205056800, + 1225616400, + 1236506400, + 1257066000, + 1268560800, + 1289120400, + 1300010400, + 1320570000, + 1331460000, + 1352019600, + 1362909600, + 1383469200, + 1394359200, + 1414918800, + 1425808800, + 1446368400, + 1457863200, + 1478422800, + 1489312800, + 1509872400, + 1520762400, + 1541322000, + 1552212000, + 1572771600, + 1583661600, + 1604214000 + ], + "types": [ + { + "offset": -32412 + }, + { + "offset": -32400 + }, + { + "offset": -28800 + }, + { + "offset": -25200 + }, + { + "offset": -28800 + }, + { + "offset": -25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-87ef4dab5f3e3941-c43fb003c147a77.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-87ef4dab5f3e3941-c43fb003c147a77.json new file mode 100644 index 00000000000000..2d47ed00cfc64e --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-87ef4dab5f3e3941-c43fb003c147a77.json @@ -0,0 +1,212 @@ +{ + "ids": [ + "america/resolute" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": { + "abbr": "CDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 3, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 1 + ], + "transitions": [ + -704937600, + 73468800, + 89190000, + 104918400, + 120639600, + 136368000, + 152089200, + 167817600, + 183538800, + 199267200, + 215593200, + 230716800, + 247042800, + 262771200, + 278492400, + 294220800, + 309942000, + 325670400, + 341391600, + 357120000, + 372841200, + 388569600, + 404895600, + 420019200, + 436345200, + 452073600, + 467794800, + 483523200, + 499244400, + 514972800, + 530694000, + 544608000, + 562143600, + 576057600, + 594198000, + 607507200, + 625647600, + 638956800, + 657097200, + 671011200, + 688546800, + 702460800, + 719996400, + 733910400, + 752050800, + 765360000, + 783500400, + 796809600, + 814950000, + 828864000, + 846399600, + 860313600, + 877849200, + 891763200, + 909298800, + 923212800, + 941353200, + 954662400, + 972802800, + 986112000, + 1004252400, + 1018166400, + 1035702000, + 1049616000, + 1067151600, + 1081065600, + 1099206000, + 1112515200, + 1130655600, + 1143964800, + 1162105200, + 1173600000, + 1194159600 + ], + "types": [ + { + "offset": 0 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-89cd9f4224d1324a-6ddbd3de8874993f.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-89cd9f4224d1324a-6ddbd3de8874993f.json new file mode 100644 index 00000000000000..46f441957cfd4e --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-89cd9f4224d1324a-6ddbd3de8874993f.json @@ -0,0 +1,36 @@ +{ + "ids": [ + "asia/makassar", + "asia/ujung_pandang" + ], + "tzif": { + "posix": { + "abbr": "WITA", + "offset": 28800, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 1 + ], + "transitions": [ + -1577951856, + -1172908656, + -880272000, + -766054800 + ], + "types": [ + { + "offset": 28656 + }, + { + "offset": 28800 + }, + { + "offset": 32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8a0ec5e44a49e44e-1f9e21f2398d2965.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8a0ec5e44a49e44e-1f9e21f2398d2965.json new file mode 100644 index 00000000000000..c12886d95c4fc7 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8a0ec5e44a49e44e-1f9e21f2398d2965.json @@ -0,0 +1,200 @@ +{ + "ids": [ + "nz-chat", + "pacific/chatham" + ], + "tzif": { + "posix": { + "abbr": "+1245", + "offset": 45900, + "transition": { + "abbr": "+1345", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 4, + 1, + 0 + ] + }, + "time": 9900 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 9, + 5, + 0 + ] + }, + "time": 13500 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3 + ], + "transitions": [ + -3192437628, + -757426500, + 152632800, + 162309600, + 183477600, + 194968800, + 215532000, + 226418400, + 246981600, + 257868000, + 278431200, + 289317600, + 309880800, + 320767200, + 341330400, + 352216800, + 372780000, + 384271200, + 404834400, + 415720800, + 436284000, + 447170400, + 467733600, + 478620000, + 499183200, + 510069600, + 530632800, + 541519200, + 562082400, + 573573600, + 594136800, + 605023200, + 623772000, + 637682400, + 655221600, + 669132000, + 686671200, + 700581600, + 718120800, + 732636000, + 749570400, + 764085600, + 781020000, + 795535200, + 812469600, + 826984800, + 844524000, + 858434400, + 875973600, + 889884000, + 907423200, + 921938400, + 938872800, + 953388000, + 970322400, + 984837600, + 1002376800, + 1016287200, + 1033826400, + 1047736800, + 1065276000, + 1079791200, + 1096725600, + 1111240800, + 1128175200, + 1142690400, + 1159624800, + 1174140000, + 1191074400, + 1207404000, + 1222524000 + ], + "types": [ + { + "offset": 44028 + }, + { + "offset": 44100 + }, + { + "offset": 45900 + }, + { + "offset": 49500 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8b129baceef3898a-389e46393fa915f2.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8b129baceef3898a-389e46393fa915f2.json new file mode 100644 index 00000000000000..73e1c200375a69 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8b129baceef3898a-389e46393fa915f2.json @@ -0,0 +1,90 @@ +{ + "ids": [ + "america/manaus", + "brazil/west" + ], + "tzif": { + "posix": { + "abbr": "-04", + "offset": -14400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1767211196, + -1206954000, + -1191358800, + -1175371200, + -1159822800, + -633816000, + -622065600, + -602280000, + -591829200, + -570744000, + -560206800, + -539121600, + -531349200, + -191361600, + -184194000, + -155160000, + -150066000, + -128894400, + -121122000, + -99950400, + -89586000, + -68414400, + -57963600, + 499752000, + 511239600, + 530596800, + 540270000, + 562132800, + 571201200, + 750830400, + 761713200 + ], + "types": [ + { + "offset": -14404 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8b312fc28eb6d503-b57cea257edd1731.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8b312fc28eb6d503-b57cea257edd1731.json new file mode 100644 index 00000000000000..a9ce4bc9bcf3dd --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8b312fc28eb6d503-b57cea257edd1731.json @@ -0,0 +1,50 @@ +{ + "ids": [ + "pacific/tongatapu" + ], + "tzif": { + "posix": { + "abbr": "+13", + "offset": 46800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2 + ], + "transitions": [ + -767189952, + -284041200, + 939214800, + 953384400, + 973342800, + 980596800, + 1004792400, + 1012046400, + 1478350800, + 1484398800 + ], + "types": [ + { + "offset": 44352 + }, + { + "offset": 44400 + }, + { + "offset": 46800 + }, + { + "offset": 50400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8b944106b8f9db7e-1d2f4ecd91296f4.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8b944106b8f9db7e-1d2f4ecd91296f4.json new file mode 100644 index 00000000000000..f998ecc93d01fc --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8b944106b8f9db7e-1d2f4ecd91296f4.json @@ -0,0 +1,199 @@ +{ + "ids": [ + "asia/ust-nera" + ], + "tzif": { + "posix": { + "abbr": "+10", + "offset": 36000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 4, + 5, + 4, + 5, + 6, + 3, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 7, + 4, + 5, + 6 + ], + "transitions": [ + -1579426374, + -1247558400, + 354898800, + 370699200, + 386427600, + 402235200, + 417963600, + 433771200, + 449586000, + 465318000, + 481042800, + 496767600, + 512492400, + 528217200, + 543942000, + 559666800, + 575391600, + 591116400, + 606841200, + 622566000, + 638290800, + 654620400, + 670345200, + 670348800, + 686073600, + 695750400, + 701794800, + 717519600, + 733244400, + 748969200, + 764694000, + 780418800, + 796143600, + 811868400, + 828198000, + 846342000, + 859647600, + 877791600, + 891097200, + 909241200, + 922546800, + 941295600, + 953996400, + 972745200, + 985446000, + 1004194800, + 1017500400, + 1035644400, + 1048950000, + 1067094000, + 1080399600, + 1099148400, + 1111849200, + 1130598000, + 1143298800, + 1162047600, + 1174748400, + 1193497200, + 1206802800, + 1224946800, + 1238252400, + 1256396400, + 1269702000, + 1288450800, + 1301151600, + 1315828800, + 1414249200 + ], + "types": [ + { + "offset": 34374 + }, + { + "offset": 28800 + }, + { + "offset": 32400 + }, + { + "offset": 43200 + }, + { + "offset": 39600 + }, + { + "offset": 39600 + }, + { + "offset": 36000 + }, + { + "offset": 43200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8bf0f826f4c6e05e-9c27d3058e34d93b.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8bf0f826f4c6e05e-9c27d3058e34d93b.json new file mode 100644 index 00000000000000..6b6d2ef41bf993 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8bf0f826f4c6e05e-9c27d3058e34d93b.json @@ -0,0 +1,51 @@ +{ + "ids": [ + "asia/dacca", + "asia/dhaka" + ], + "tzif": { + "posix": { + "abbr": "+06", + "offset": 21600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 4, + 5, + 4 + ], + "transitions": [ + -2524543300, + -891582800, + -872058600, + -862637400, + -576138600, + 1245430800, + 1262278800 + ], + "types": [ + { + "offset": 21700 + }, + { + "offset": 21200 + }, + { + "offset": 23400 + }, + { + "offset": 19800 + }, + { + "offset": 21600 + }, + { + "offset": 25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8c010856ba3febe1-a27521eb7d78dbf6.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8c010856ba3febe1-a27521eb7d78dbf6.json new file mode 100644 index 00000000000000..a64aa68e838fe8 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8c010856ba3febe1-a27521eb7d78dbf6.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "factory" + ], + "tzif": { + "posix": { + "abbr": "-00", + "offset": 0, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": 0 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8e1e620dda961a84-8cb519c7f5594e81.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8e1e620dda961a84-8cb519c7f5594e81.json new file mode 100644 index 00000000000000..9b7167da26dbc5 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8e1e620dda961a84-8cb519c7f5594e81.json @@ -0,0 +1,196 @@ +{ + "ids": [ + "europe/vilnius" + ], + "tzif": { + "posix": { + "abbr": "EET", + "offset": 7200, + "transition": { + "abbr": "EEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 14400 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 4, + 3, + 5, + 4, + 6, + 3, + 4, + 6, + 3, + 4, + 6, + 5, + 7, + 5, + 7, + 5, + 7, + 5, + 7, + 5, + 7, + 5, + 7, + 5, + 7, + 5, + 7, + 5, + 5, + 8, + 4, + 6, + 5, + 8, + 4, + 6, + 5, + 8, + 4, + 6, + 5, + 8, + 4, + 6, + 5, + 8, + 4, + 6, + 5, + 8, + 4, + 6, + 5, + 8, + 4, + 6, + 5, + 8, + 4, + 6, + 5, + 8, + 4, + 6, + 4, + 6, + 3, + 4, + 6, + 4, + 6 + ], + "transitions": [ + -2840146876, + -1672536240, + -1585100136, + -1561251600, + -1553565600, + -928198800, + -900126000, + -857257200, + -844556400, + -828226800, + -812502000, + -802144800, + 354920400, + 370728000, + 386456400, + 402264000, + 417992400, + 433800000, + 449614800, + 465346800, + 481071600, + 496796400, + 512521200, + 528246000, + 543970800, + 559695600, + 575420400, + 591145200, + 606870000, + 622598400, + 638323200, + 654652800, + 670377600, + 686102400, + 701827200, + 717552000, + 733276800, + 749001600, + 764726400, + 780451200, + 796176000, + 811900800, + 828230400, + 846374400, + 859680000, + 877824000, + 891133200, + 909277200, + 922582800, + 941331600 + ], + "types": [ + { + "offset": 6076 + }, + { + "offset": 5040 + }, + { + "offset": 5736 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 7200 + }, + { + "offset": 14400 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8e605032c3ce6342-6a27beeec5d94fef.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8e605032c3ce6342-6a27beeec5d94fef.json new file mode 100644 index 00000000000000..6e0eec8bc5b79e --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8e605032c3ce6342-6a27beeec5d94fef.json @@ -0,0 +1,91 @@ +{ + "ids": [ + "america/santarem" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3 + ], + "transitions": [ + -1767212472, + -1206954000, + -1191358800, + -1175371200, + -1159822800, + -633816000, + -622065600, + -602280000, + -591829200, + -570744000, + -560206800, + -539121600, + -531349200, + -191361600, + -184194000, + -155160000, + -150066000, + -128894400, + -121122000, + -99950400, + -89586000, + -68414400, + -57963600, + 499752000, + 511239600, + 530596800, + 540270000, + 562132800, + 571201200, + 1214280000 + ], + "types": [ + { + "offset": -13128 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8fec2819cc677405-6cfb65330c2f1fa0.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8fec2819cc677405-6cfb65330c2f1fa0.json new file mode 100644 index 00000000000000..a9d30047317be7 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-8fec2819cc677405-6cfb65330c2f1fa0.json @@ -0,0 +1,264 @@ +{ + "ids": [ + "america/juneau" + ], + "tzif": { + "posix": { + "abbr": "AKST", + "offset": -32400, + "transition": { + "abbr": "AKDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 5, + 3, + 2, + 5, + 3, + 2, + 5, + 3, + 2, + 5, + 4, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4 + ], + "transitions": [ + -3225223727, + -2188954939, + -880207200, + -769395600, + -765385200, + -21477600, + -5756400, + 9972000, + 25693200, + 41421600, + 57747600, + 73476000, + 89197200, + 104925600, + 120646800, + 126698400, + 152096400, + 162381600, + 183546000, + 199274400, + 215600400, + 230724000, + 247050000, + 262778400, + 278499600, + 294228000, + 309949200, + 325677600, + 325681200, + 341402400, + 357127200, + 372848400, + 388576800, + 404902800, + 420026400, + 436352400, + 436356000, + 439030800, + 452084400, + 467805600, + 483534000, + 499255200, + 514983600, + 530704800, + 544618800, + 562154400, + 576068400, + 594208800, + 607518000, + 625658400, + 638967600, + 657108000, + 671022000, + 688557600, + 702471600, + 720007200, + 733921200, + 752061600, + 765370800, + 783511200, + 796820400, + 814960800, + 828874800, + 846410400, + 860324400, + 877860000, + 891774000, + 909309600, + 923223600, + 941364000, + 954673200, + 972813600, + 986122800, + 1004263200, + 1018177200, + 1035712800, + 1049626800, + 1067162400, + 1081076400, + 1099216800, + 1112526000, + 1130666400, + 1143975600, + 1162116000, + 1173610800, + 1194170400 + ], + "types": [ + { + "offset": 54139 + }, + { + "offset": -32261 + }, + { + "offset": -28800 + }, + { + "offset": -25200 + }, + { + "offset": -32400 + }, + { + "offset": -28800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-905f75931d73bd53-38c9d0ddc82eec2a.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-905f75931d73bd53-38c9d0ddc82eec2a.json new file mode 100644 index 00000000000000..0275b01d5619e9 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-905f75931d73bd53-38c9d0ddc82eec2a.json @@ -0,0 +1,39 @@ +{ + "ids": [ + "pacific/galapagos" + ], + "tzif": { + "posix": { + "abbr": "-06", + "offset": -21600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 3, + 2 + ], + "transitions": [ + -1230746496, + 504939600, + 722930400, + 728888400 + ], + "types": [ + { + "offset": -21504 + }, + { + "offset": -18000 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-90e0499f7b80422b-16e03eeaaf192844.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-90e0499f7b80422b-16e03eeaaf192844.json new file mode 100644 index 00000000000000..bae3bd72a112d6 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-90e0499f7b80422b-16e03eeaaf192844.json @@ -0,0 +1,95 @@ +{ + "ids": [ + "america/porto_acre", + "america/rio_branco", + "brazil/acre" + ], + "tzif": { + "posix": { + "abbr": "-05", + "offset": -18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 1 + ], + "transitions": [ + -1767209328, + -1206950400, + -1191355200, + -1175367600, + -1159819200, + -633812400, + -622062000, + -602276400, + -591825600, + -570740400, + -560203200, + -539118000, + -531345600, + -191358000, + -184190400, + -155156400, + -150062400, + -128890800, + -121118400, + -99946800, + -89582400, + -68410800, + -57960000, + 499755600, + 511243200, + 530600400, + 540273600, + 562136400, + 571204800, + 1214283600, + 1384056000 + ], + "types": [ + { + "offset": -16272 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-916c7f697e6af49e-cd5f0c23c53bde30.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-916c7f697e6af49e-cd5f0c23c53bde30.json new file mode 100644 index 00000000000000..6fe4d27249274f --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-916c7f697e6af49e-cd5f0c23c53bde30.json @@ -0,0 +1,433 @@ +{ + "ids": [ + "america/st_johns", + "canada/newfoundland" + ], + "tzif": { + "posix": { + "abbr": "NST", + "offset": -12600, + "transition": { + "abbr": "NDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 4, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3 + ], + "transitions": [ + -2713897748, + -1664130548, + -1650137348, + -1632076148, + -1615145348, + -1598650148, + -1590100148, + -1567286948, + -1551565748, + -1535837348, + -1520116148, + -1503782948, + -1488666548, + -1472333348, + -1457216948, + -1440883748, + -1425767348, + -1409434148, + -1394317748, + -1377984548, + -1362263348, + -1346534948, + -1330813748, + -1314480548, + -1299364148, + -1283030948, + -1267914548, + -1251581348, + -1236464948, + -1220131748, + -1205015348, + -1188682148, + -1172960948, + -1156627748, + -1141511348, + -1125178148, + -1110061748, + -1096921748, + -1093728600, + -1078612200, + -1061670600, + -1048973400, + -1030221000, + -1017523800, + -998771400, + -986074200, + -966717000, + -954624600, + -935267400, + -922570200, + -903817800, + -891120600, + -872368200, + -769395600, + -765401400, + -746044200, + -733347000, + -714594600, + -701897400, + -683145000, + -670447800, + -651695400, + -638998200, + -619641000, + -606943800, + -589401000, + -576099000, + -557951400, + -544649400, + -526501800, + -513199800, + -495052200, + -481750200, + -463602600, + -450300600, + -431548200, + -418246200, + -400098600, + -386796600, + -368649000, + -355347000, + -337199400, + -323897400, + -305749800, + -289423800, + -273695400, + -257974200, + -242245800, + -226524600, + -210796200, + -195075000, + -179346600, + -163625400, + -147897000, + -131571000, + -116447400, + -100121400, + -84393000, + -68671800, + -52943400, + -37222200, + -21493800, + -5772600, + 9955800, + 25677000, + 41405400, + 57731400, + 73459800, + 89181000, + 104909400, + 120630600, + 136359000, + 152080200, + 167808600, + 183529800, + 199258200, + 215584200, + 230707800, + 247033800, + 262762200, + 278483400, + 294211800, + 309933000, + 325661400, + 341382600, + 357111000, + 372832200, + 388560600, + 404886600, + 420010200, + 436336200, + 452064600, + 467785800, + 483514200, + 499235400, + 514963800, + 530685000, + 544591860, + 562127460, + 576041460, + 594178260, + 607491060, + 625631460, + 638940660, + 657081060, + 670995060, + 688530660, + 702444660, + 719980260, + 733894260, + 752034660, + 765343860, + 783484260, + 796793460, + 814933860, + 828847860, + 846383460, + 860297460, + 877833060, + 891747060, + 909282660, + 923196660, + 941337060, + 954646260, + 972786660, + 986095860, + 1004236260, + 1018150260, + 1035685860, + 1049599860, + 1067135460, + 1081049460, + 1099189860, + 1112499060, + 1130639460, + 1143948660, + 1162089060, + 1173583860, + 1194143460, + 1205033460, + 1225593060, + 1236483060, + 1257042660, + 1268537460, + 1289097060, + 1299987060 + ], + "types": [ + { + "offset": -12652 + }, + { + "offset": -9052 + }, + { + "offset": -12600 + }, + { + "offset": -9000 + }, + { + "offset": -5400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-93ba37d78a84866e-364c3b71717bb302.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-93ba37d78a84866e-364c3b71717bb302.json new file mode 100644 index 00000000000000..1838edfb9947c3 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-93ba37d78a84866e-364c3b71717bb302.json @@ -0,0 +1,85 @@ +{ + "ids": [ + "america/belem" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1767213964, + -1206957600, + -1191362400, + -1175374800, + -1159826400, + -633819600, + -622069200, + -602283600, + -591832800, + -570747600, + -560210400, + -539125200, + -531352800, + -191365200, + -184197600, + -155163600, + -150069600, + -128898000, + -121125600, + -99954000, + -89589600, + -68418000, + -57967200, + 499748400, + 511236000, + 530593200, + 540266400, + 562129200, + 571197600 + ], + "types": [ + { + "offset": -11636 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-94731e7a96e16727-b9bdd49f2158b98c.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-94731e7a96e16727-b9bdd49f2158b98c.json new file mode 100644 index 00000000000000..42498a53f7cb8b --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-94731e7a96e16727-b9bdd49f2158b98c.json @@ -0,0 +1,69 @@ +{ + "ids": [ + "asia/chongqing", + "asia/chungking", + "asia/harbin", + "asia/shanghai", + "prc" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": 28800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2177481943, + -1600675200, + -1585904400, + -933667200, + -922093200, + -908870400, + -888829200, + -881049600, + -767869200, + -745833600, + -733827600, + -716889600, + -699613200, + -683884800, + -670669200, + -652348800, + -650019600, + 515527200, + 527014800 + ], + "types": [ + { + "offset": 29143 + }, + { + "offset": 28800 + }, + { + "offset": 32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-95eb641ddc74061f-5a914528a766049d.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-95eb641ddc74061f-5a914528a766049d.json new file mode 100644 index 00000000000000..cce4aec02b37d9 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-95eb641ddc74061f-5a914528a766049d.json @@ -0,0 +1,103 @@ +{ + "ids": [ + "america/mexico_city", + "mexico/general" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3 + ], + "transitions": [ + -1514739600, + -1343149200, + -1234807200, + -1220461200, + -1207159200, + -1191344400, + -975261600, + -963169200, + -917114400, + -907354800, + -821901600, + -810068400, + -627501600, + -612990000, + 828864000, + 846399600, + 860313600, + 877849200, + 891763200, + 909298800, + 923212800, + 941353200, + 954662400, + 972802800, + 989136000, + 1001833200, + 1018166400, + 1035702000 + ], + "types": [ + { + "offset": -23796 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-96a7050f6c4d3e34-7cc5980522f3fef5.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-96a7050f6c4d3e34-7cc5980522f3fef5.json new file mode 100644 index 00000000000000..9e9b3e55b34cf3 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-96a7050f6c4d3e34-7cc5980522f3fef5.json @@ -0,0 +1,379 @@ +{ + "ids": [ + "eire", + "europe/dublin" + ], + "tzif": { + "posix": { + "abbr": "GMT", + "offset": 0, + "transition": { + "abbr": "IST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 3600 + } + } + }, + "transition_types": [ + 0, + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2 + ], + "transitions": [ + -2821649679, + -1691962479, + -1680471279, + -1664143200, + -1650146400, + -1633903200, + -1617487200, + -1601848800, + -1586037600, + -1570399200, + -1552168800, + -1538344800, + -1522533600, + -1507500000, + -1490565600, + -1473631200, + -1460930400, + -1442786400, + -1428876000, + -1410732000, + -1396216800, + -1379282400, + -1364767200, + -1348437600, + -1333317600, + -1315778400, + -1301263200, + -1284328800, + -1269813600, + -1253484000, + -1238364000, + -1221429600, + -1206914400, + -1189980000, + -1175464800, + -1159135200, + -1143410400, + -1126476000, + -1111960800, + -1095631200, + -1080511200, + -1063576800, + -1049061600, + -1032127200, + -1017612000, + -1001282400, + -986162400, + -969228000, + -950479200, + -942012000, + -733356000, + -719445600, + -699487200, + -684972000, + -668037600, + -654732000, + -636588000, + -622072800, + -605743200, + -590623200, + -574293600, + -558568800, + -542239200, + -527119200, + -512604000, + -496274400, + -481154400, + -464220000, + -449704800, + -432165600, + -417650400, + -401320800, + -386200800, + -369266400, + -354751200, + -337816800, + -323301600, + -306972000, + -291852000, + -276732000, + -257983200, + -245282400, + -226533600, + -213228000, + -195084000, + -182383200, + -163634400, + -150933600, + -132184800, + -119484000, + -100735200, + -88034400, + -68680800, + -59004000, + -37242000, + 57722400, + 69818400, + 89172000, + 101268000, + 120621600, + 132717600, + 152071200, + 164167200, + 183520800, + 196221600, + 214970400, + 227671200, + 246420000, + 259120800, + 278474400, + 290570400, + 309924000, + 322020000, + 341373600, + 354675600, + 372819600, + 386125200, + 404269200, + 417574800, + 435718800, + 449024400, + 467773200, + 481078800, + 499222800, + 512528400, + 530672400, + 543978000, + 562122000, + 575427600, + 593571600, + 606877200, + 625626000, + 638326800, + 657075600, + 670381200, + 688525200, + 701830800, + 719974800, + 733280400, + 751424400, + 764730000, + 782874000, + 796179600, + 814323600, + 828234000, + 846378000 + ], + "types": [ + { + "offset": -1521 + }, + { + "offset": 2079 + }, + { + "offset": 0 + }, + { + "offset": 3600 + }, + { + "offset": 3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-98fb8731f72daeb6-4585fdc50640db42.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-98fb8731f72daeb6-4585fdc50640db42.json new file mode 100644 index 00000000000000..5df843b2e10c6f --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-98fb8731f72daeb6-4585fdc50640db42.json @@ -0,0 +1,72 @@ +{ + "ids": [ + "america/jamaica", + "jamaica" + ], + "tzif": { + "posix": { + "abbr": "EST", + "offset": -18000, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2524503170, + -1827687170, + 126687600, + 152085600, + 162370800, + 183535200, + 199263600, + 215589600, + 230713200, + 247039200, + 262767600, + 278488800, + 294217200, + 309938400, + 325666800, + 341388000, + 357116400, + 372837600, + 388566000, + 404892000, + 420015600, + 436341600 + ], + "types": [ + { + "offset": -18430 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-98fc8236fccd3576-88ddb973d46096e3.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-98fc8236fccd3576-88ddb973d46096e3.json new file mode 100644 index 00000000000000..ac840f8e01103a --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-98fc8236fccd3576-88ddb973d46096e3.json @@ -0,0 +1,192 @@ +{ + "ids": [ + "asia/novosibirsk" + ], + "tzif": { + "posix": { + "abbr": "+07", + "offset": 25200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4 + ], + "transitions": [ + -1579476700, + -1247551200, + 354906000, + 370713600, + 386442000, + 402249600, + 417978000, + 433785600, + 449600400, + 465332400, + 481057200, + 496782000, + 512506800, + 528231600, + 543956400, + 559681200, + 575406000, + 591130800, + 606855600, + 622580400, + 638305200, + 654634800, + 670359600, + 670363200, + 686088000, + 695764800, + 701809200, + 717534000, + 733258800, + 738086400, + 748987200, + 764712000, + 780436800, + 796161600, + 811886400, + 828216000, + 846360000, + 859665600, + 877809600, + 891115200, + 909259200, + 922564800, + 941313600, + 954014400, + 972763200, + 985464000, + 1004212800, + 1017518400, + 1035662400, + 1048968000, + 1067112000, + 1080417600, + 1099166400, + 1111867200, + 1130616000, + 1143316800, + 1162065600, + 1174766400, + 1193515200, + 1206820800, + 1224964800, + 1238270400, + 1256414400, + 1269720000, + 1288468800, + 1301169600, + 1414263600, + 1469304000 + ], + "types": [ + { + "offset": 19900 + }, + { + "offset": 21600 + }, + { + "offset": 25200 + }, + { + "offset": 28800 + }, + { + "offset": 25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-996739b4c558f747-935dbc63456811c2.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-996739b4c558f747-935dbc63456811c2.json new file mode 100644 index 00000000000000..f05ac0a8703108 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-996739b4c558f747-935dbc63456811c2.json @@ -0,0 +1,57 @@ +{ + "ids": [ + "asia/colombo" + ], + "tzif": { + "posix": { + "abbr": "+0530", + "offset": 19800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 4, + 2, + 4, + 5, + 3, + 6, + 2 + ], + "transitions": [ + -2840159964, + -2019705572, + -883287000, + -862639200, + -764051400, + 832962600, + 846266400, + 1145039400 + ], + "types": [ + { + "offset": 19164 + }, + { + "offset": 19172 + }, + { + "offset": 19800 + }, + { + "offset": 21600 + }, + { + "offset": 23400 + }, + { + "offset": 23400 + }, + { + "offset": 21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-99cdd052561a0879-89252b18a95154e3.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-99cdd052561a0879-89252b18a95154e3.json new file mode 100644 index 00000000000000..2fc893d79b09c3 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-99cdd052561a0879-89252b18a95154e3.json @@ -0,0 +1,169 @@ +{ + "ids": [ + "africa/windhoek" + ], + "tzif": { + "posix": { + "abbr": "CAT", + "offset": 7200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 2, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 4, + 2, + 5, + 2, + 5 + ], + "transitions": [ + -2458170504, + -2109288600, + -860976000, + -845254800, + 637970400, + 764200800, + 778640400, + 796780800, + 810090000, + 828835200, + 841539600, + 860284800, + 873594000, + 891734400, + 905043600, + 923184000, + 936493200, + 954633600, + 967942800, + 986083200, + 999392400, + 1018137600, + 1030842000, + 1049587200, + 1062896400, + 1081036800, + 1094346000, + 1112486400, + 1125795600, + 1143936000, + 1157245200, + 1175385600, + 1188694800, + 1207440000, + 1220749200, + 1238889600, + 1252198800, + 1270339200, + 1283648400, + 1301788800, + 1315098000, + 1333238400, + 1346547600, + 1365292800, + 1377997200, + 1396742400, + 1410051600, + 1428192000, + 1441501200, + 1459641600, + 1472950800, + 1491091200, + 1504400400, + 1508796000 + ], + "types": [ + { + "offset": 4104 + }, + { + "offset": 5400 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-99ce61a08c1199af-56326eb4ceecfd35.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-99ce61a08c1199af-56326eb4ceecfd35.json new file mode 100644 index 00000000000000..5699c5fb1696f5 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-99ce61a08c1199af-56326eb4ceecfd35.json @@ -0,0 +1,124 @@ +{ + "ids": [ + "america/thule" + ], + "tzif": { + "posix": { + "abbr": "AST", + "offset": -14400, + "transition": { + "abbr": "ADT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1686079492, + 670399200, + 686120400, + 701848800, + 717570000, + 733903200, + 752043600, + 765352800, + 783493200, + 796802400, + 814942800, + 828856800, + 846392400, + 860306400, + 877842000, + 891756000, + 909291600, + 923205600, + 941346000, + 954655200, + 972795600, + 986104800, + 1004245200, + 1018159200, + 1035694800, + 1049608800, + 1067144400, + 1081058400, + 1099198800, + 1112508000, + 1130648400, + 1143957600, + 1162098000, + 1173592800, + 1194152400 + ], + "types": [ + { + "offset": -16508 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9a2f8cce797280e8-37784cc07103f2f3.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9a2f8cce797280e8-37784cc07103f2f3.json new file mode 100644 index 00000000000000..ea52b0d54b7d9c --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9a2f8cce797280e8-37784cc07103f2f3.json @@ -0,0 +1,195 @@ +{ + "ids": [ + "asia/sakhalin" + ], + "tzif": { + "posix": { + "abbr": "+11", + "offset": 39600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 5, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4 + ], + "transitions": [ + -2031039048, + -768560400, + 354891600, + 370699200, + 386427600, + 402235200, + 417963600, + 433771200, + 449586000, + 465318000, + 481042800, + 496767600, + 512492400, + 528217200, + 543942000, + 559666800, + 575391600, + 591116400, + 606841200, + 622566000, + 638290800, + 654620400, + 670345200, + 670348800, + 686073600, + 695750400, + 701794800, + 717519600, + 733244400, + 748969200, + 764694000, + 780418800, + 796143600, + 811868400, + 828198000, + 846342000, + 859647600, + 859651200, + 877795200, + 891100800, + 909244800, + 922550400, + 941299200, + 954000000, + 972748800, + 985449600, + 1004198400, + 1017504000, + 1035648000, + 1048953600, + 1067097600, + 1080403200, + 1099152000, + 1111852800, + 1130601600, + 1143302400, + 1162051200, + 1174752000, + 1193500800, + 1206806400, + 1224950400, + 1238256000, + 1256400000, + 1269705600, + 1288454400, + 1301155200, + 1414249200, + 1459008000 + ], + "types": [ + { + "offset": 34248 + }, + { + "offset": 32400 + }, + { + "offset": 39600 + }, + { + "offset": 43200 + }, + { + "offset": 39600 + }, + { + "offset": 36000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9af11812af42f7cb-8d70b106abb9243f.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9af11812af42f7cb-8d70b106abb9243f.json new file mode 100644 index 00000000000000..a01d5875eeb30c --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9af11812af42f7cb-8d70b106abb9243f.json @@ -0,0 +1,233 @@ +{ + "ids": [ + "australia/broken_hill", + "australia/yancowinna" + ], + "tzif": { + "posix": { + "abbr": "ACST", + "offset": 34200, + "transition": { + "abbr": "ACDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 4, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 1, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4 + ], + "transitions": [ + -2364110748, + -2314951200, + -2230189200, + -1672558200, + -1665387000, + -883639800, + -876123000, + -860398200, + -844673400, + -828343800, + -813223800, + 57688200, + 67969800, + 89137800, + 100024200, + 120587400, + 131473800, + 152037000, + 162923400, + 183486600, + 194977800, + 215541000, + 226427400, + 246990600, + 257877000, + 278440200, + 289326600, + 309889800, + 320776200, + 341339400, + 352225800, + 372789000, + 386699400, + 404843400, + 415729800, + 436293000, + 447179400, + 467742600, + 478629000, + 499192200, + 511288200, + 530037000, + 542737800, + 562091400, + 574792200, + 594145800, + 606241800, + 625595400, + 636481800, + 657045000, + 667931400, + 688494600, + 699381000, + 719944200, + 731435400, + 751998600, + 762885000, + 783448200, + 794334600, + 814897800, + 828203400, + 846347400, + 859653000, + 877797000, + 891102600, + 909246600, + 922552200, + 941301000, + 954001800, + 972750600, + 985451400, + 1004200200, + 1017505800, + 1035649800, + 1048955400, + 1067099400, + 1080405000, + 1099153800, + 1111854600, + 1130603400, + 1143909000, + 1162053000, + 1174753800, + 1193502600, + 1207413000, + 1223137800 + ], + "types": [ + { + "offset": 33948 + }, + { + "offset": 36000 + }, + { + "offset": 32400 + }, + { + "offset": 34200 + }, + { + "offset": 37800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9afb6f21d74a3dbd-d76c18d684813924.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9afb6f21d74a3dbd-d76c18d684813924.json new file mode 100644 index 00000000000000..b6b0ff5364b316 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9afb6f21d74a3dbd-d76c18d684813924.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt+6" + ], + "tzif": { + "posix": { + "abbr": "-06", + "offset": -21600, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": -21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9b4491a5a7233cc3-9416dbeeb6810774.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9b4491a5a7233cc3-9416dbeeb6810774.json new file mode 100644 index 00000000000000..200dcbe71c06b6 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9b4491a5a7233cc3-9416dbeeb6810774.json @@ -0,0 +1,235 @@ +{ + "ids": [ + "america/inuvik" + ], + "tzif": { + "posix": { + "abbr": "MST", + "offset": -25200, + "transition": { + "abbr": "MDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4 + ], + "transitions": [ + -536457600, + 73476000, + 89197200, + 104925600, + 120646800, + 136375200, + 152096400, + 167824800, + 183546000, + 199274400, + 215600400, + 230724000, + 247050000, + 262778400, + 278499600, + 294228000, + 309945600, + 325674000, + 341395200, + 357123600, + 372844800, + 388573200, + 404899200, + 420022800, + 436348800, + 452077200, + 467798400, + 483526800, + 499248000, + 514976400, + 530697600, + 544611600, + 562147200, + 576061200, + 594201600, + 607510800, + 625651200, + 638960400, + 657100800, + 671014800, + 688550400, + 702464400, + 720000000, + 733914000, + 752054400, + 765363600, + 783504000, + 796813200, + 814953600, + 828867600, + 846403200, + 860317200, + 877852800, + 891766800, + 909302400, + 923216400, + 941356800, + 954666000, + 972806400, + 986115600, + 1004256000, + 1018170000, + 1035705600, + 1049619600, + 1067155200, + 1081069200, + 1099209600, + 1112518800, + 1130659200, + 1143968400, + 1162108800, + 1173603600, + 1194163200 + ], + "types": [ + { + "offset": 0 + }, + { + "offset": -28800 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + }, + { + "offset": -25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9bd926151a997a3e-9909ffff90c3207.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9bd926151a997a3e-9909ffff90c3207.json new file mode 100644 index 00000000000000..a5a60fba00a4b7 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9bd926151a997a3e-9909ffff90c3207.json @@ -0,0 +1,289 @@ +{ + "ids": [ + "america/asuncion" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 2, + 3 + ], + "transitions": [ + -2524507760, + -1206389360, + 86760000, + 134017200, + 181368000, + 194497200, + 212990400, + 226033200, + 244526400, + 257569200, + 276062400, + 291783600, + 307598400, + 323406000, + 339220800, + 354942000, + 370756800, + 386478000, + 402292800, + 418014000, + 433828800, + 449636400, + 465451200, + 481172400, + 496987200, + 512708400, + 528523200, + 544244400, + 560059200, + 575866800, + 591681600, + 607402800, + 625032000, + 638938800, + 654753600, + 670474800, + 686721600, + 699418800, + 718257600, + 733546800, + 749448000, + 762318000, + 780984000, + 793767600, + 812520000, + 825649200, + 844574400, + 856666800, + 876024000, + 888721200, + 907473600, + 920775600, + 938923200, + 952225200, + 970372800, + 983674800, + 1002427200, + 1018148400, + 1030852800, + 1049598000, + 1062907200, + 1081047600, + 1097985600, + 1110682800, + 1129435200, + 1142132400, + 1160884800, + 1173582000, + 1192939200, + 1205031600, + 1224388800, + 1236481200, + 1255838400, + 1270954800, + 1286078400, + 1302404400, + 1317528000, + 1333854000, + 1349582400, + 1364094000, + 1381032000, + 1395543600, + 1412481600, + 1426993200, + 1443931200, + 1459047600, + 1475380800, + 1490497200, + 1506830400, + 1521946800, + 1538884800, + 1553396400, + 1570334400, + 1584846000, + 1601784000, + 1616900400, + 1633233600, + 1648350000, + 1664683200, + 1679799600, + 1696132800, + 1711249200, + 1728187200, + 1728961200 + ], + "types": [ + { + "offset": -13840 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9c7ac303ad5d20d8-9111a17e7b78de54.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9c7ac303ad5d20d8-9111a17e7b78de54.json new file mode 100644 index 00000000000000..a6cb19c4626a00 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9c7ac303ad5d20d8-9111a17e7b78de54.json @@ -0,0 +1,194 @@ +{ + "ids": [ + "europe/tallinn" + ], + "tzif": { + "posix": { + "abbr": "EET", + "offset": 7200, + "transition": { + "abbr": "EEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 14400 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 0, + 2, + 3, + 4, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 4, + 6, + 2, + 3, + 4, + 6, + 2, + 3, + 4, + 6, + 2, + 3, + 4, + 6, + 2, + 3, + 4, + 6, + 2, + 3, + 4, + 6, + 2, + 3, + 4, + 6, + 2, + 3, + 4, + 6, + 2, + 3, + 4, + 6, + 2, + 3, + 4, + 6, + 2, + 3, + 4, + 6, + 2, + 3 + ], + "transitions": [ + -2840146740, + -1638322740, + -1632006000, + -1618700400, + -1593824400, + -1535938740, + -927943200, + -892954800, + -857257200, + -844556400, + -828226800, + -812502000, + -797652000, + 354920400, + 370728000, + 386456400, + 402264000, + 417992400, + 433800000, + 449614800, + 465346800, + 481071600, + 496796400, + 512521200, + 528246000, + 543970800, + 559695600, + 575420400, + 591145200, + 606870000, + 622598400, + 638323200, + 654652800, + 670377600, + 686102400, + 701827200, + 717552000, + 733276800, + 749001600, + 764726400, + 780451200, + 796176000, + 811900800, + 828230400, + 846374400, + 859680000, + 877824000, + 891129600, + 909277200, + 922582800, + 941331600 + ], + "types": [ + { + "offset": 5940 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 14400 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9c98c8b92084c36-47e6455e977d6bb3.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9c98c8b92084c36-47e6455e977d6bb3.json new file mode 100644 index 00000000000000..1af0e6a2f982ac --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9c98c8b92084c36-47e6455e977d6bb3.json @@ -0,0 +1,248 @@ +{ + "ids": [ + "australia/currie", + "australia/hobart", + "australia/tasmania" + ], + "tzif": { + "posix": { + "abbr": "AEST", + "offset": 36000, + "transition": { + "abbr": "AEDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 4, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 1, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2 + ], + "transitions": [ + -2345795356, + -1680508800, + -1665388800, + -1646640000, + -1635753600, + -1615190400, + -1604304000, + -883641600, + -876124800, + -860400000, + -844675200, + -828345600, + -813225600, + -71136000, + -55411200, + -37267200, + -25776000, + -5817600, + 5673600, + 25632000, + 37728000, + 57686400, + 67968000, + 89136000, + 100022400, + 120585600, + 131472000, + 152035200, + 162921600, + 183484800, + 194976000, + 215539200, + 226425600, + 246988800, + 257875200, + 278438400, + 289324800, + 309888000, + 320774400, + 341337600, + 352224000, + 372787200, + 386092800, + 404841600, + 417542400, + 436291200, + 447177600, + 467740800, + 478627200, + 499190400, + 510076800, + 530035200, + 542736000, + 562089600, + 574790400, + 594144000, + 606240000, + 625593600, + 637689600, + 657043200, + 670348800, + 686678400, + 701798400, + 718128000, + 733248000, + 749577600, + 764697600, + 781027200, + 796147200, + 812476800, + 828201600, + 844531200, + 859651200, + 875980800, + 891100800, + 907430400, + 922550400, + 938880000, + 954000000, + 967305600, + 985449600, + 1002384000, + 1017504000, + 1033833600, + 1048953600, + 1065283200, + 1080403200, + 1096732800, + 1111852800, + 1128182400, + 1143907200, + 1159632000, + 1174752000, + 1191686400, + 1207411200, + 1223136000 + ], + "types": [ + { + "offset": 35356 + }, + { + "offset": 36000 + }, + { + "offset": 39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9d02412abb136ce4-bfde68530f93fb26.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9d02412abb136ce4-bfde68530f93fb26.json new file mode 100644 index 00000000000000..8ad61452233ae5 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-9d02412abb136ce4-bfde68530f93fb26.json @@ -0,0 +1,26 @@ +{ + "ids": [ + "atlantic/south_georgia" + ], + "tzif": { + "posix": { + "abbr": "-02", + "offset": -7200, + "transition": null + }, + "transition_types": [ + 1 + ], + "transitions": [ + -2524512832 + ], + "types": [ + { + "offset": -8768 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a053c1334aeab356-645c110894da15be.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a053c1334aeab356-645c110894da15be.json new file mode 100644 index 00000000000000..57cd31cb0f6ece --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a053c1334aeab356-645c110894da15be.json @@ -0,0 +1,154 @@ +{ + "ids": [ + "asia/almaty" + ], + "tzif": { + "posix": { + "abbr": "+05", + "offset": 18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 1 + ], + "transitions": [ + -1441170468, + -1247547600, + 354909600, + 370717200, + 386445600, + 402253200, + 417981600, + 433789200, + 449604000, + 465336000, + 481060800, + 496785600, + 512510400, + 528235200, + 543960000, + 559684800, + 575409600, + 591134400, + 606859200, + 622584000, + 638308800, + 654638400, + 670363200, + 670366800, + 686091600, + 695768400, + 701812800, + 717537600, + 733262400, + 748987200, + 764712000, + 780436800, + 796161600, + 811886400, + 828216000, + 846360000, + 859665600, + 877809600, + 891115200, + 909259200, + 922564800, + 941313600, + 954014400, + 972763200, + 985464000, + 1004212800, + 1017518400, + 1035662400, + 1048968000, + 1067112000, + 1080417600, + 1099166400, + 1709229600 + ], + "types": [ + { + "offset": 18468 + }, + { + "offset": 18000 + }, + { + "offset": 21600 + }, + { + "offset": 25200 + }, + { + "offset": 21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a0806703e39bd41f-938b549d3f658065.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a0806703e39bd41f-938b549d3f658065.json new file mode 100644 index 00000000000000..f7ddff0ba32474 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a0806703e39bd41f-938b549d3f658065.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt+5" + ], + "tzif": { + "posix": { + "abbr": "-05", + "offset": -18000, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a1347b19ee040601-84e246431e54b763.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a1347b19ee040601-84e246431e54b763.json new file mode 100644 index 00000000000000..0bf320a8587068 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a1347b19ee040601-84e246431e54b763.json @@ -0,0 +1,57 @@ +{ + "ids": [ + "pacific/apia" + ], + "tzif": { + "posix": { + "abbr": "+13", + "offset": 46800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 4, + 3, + 4, + 5, + 6, + 5 + ], + "transitions": [ + -2445424384, + -1861878784, + -631110600, + 1285498800, + 1301752800, + 1316872800, + 1325239200, + 1333202400, + 1348927200 + ], + "types": [ + { + "offset": 45184 + }, + { + "offset": -41216 + }, + { + "offset": -41400 + }, + { + "offset": -39600 + }, + { + "offset": -36000 + }, + { + "offset": 50400 + }, + { + "offset": 46800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a187ee64c8fae572-4985eb67780f1dca.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a187ee64c8fae572-4985eb67780f1dca.json new file mode 100644 index 00000000000000..fa7c7795c288e9 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a187ee64c8fae572-4985eb67780f1dca.json @@ -0,0 +1,45 @@ +{ + "ids": [ + "america/guatemala" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1617040676, + 123055200, + 130914000, + 422344800, + 433054800, + 669708000, + 684219600, + 1146376800, + 1159678800 + ], + "types": [ + { + "offset": -21724 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a1b14d47c3da0459-9beeb6b09fc4bd85.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a1b14d47c3da0459-9beeb6b09fc4bd85.json new file mode 100644 index 00000000000000..fd72fba6a87c29 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a1b14d47c3da0459-9beeb6b09fc4bd85.json @@ -0,0 +1,133 @@ +{ + "ids": [ + "europe/belgrade", + "europe/ljubljana", + "europe/podgorica", + "europe/sarajevo", + "europe/skopje", + "europe/zagreb" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": { + "abbr": "CEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2713915320, + -905824800, + -857257200, + -844556400, + -828226800, + -812502000, + -796777200, + -777942000, + -766623600, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": 4920 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a2c4636cb2de823b-69641876de40969.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a2c4636cb2de823b-69641876de40969.json new file mode 100644 index 00000000000000..9903aba5375d34 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a2c4636cb2de823b-69641876de40969.json @@ -0,0 +1,170 @@ +{ + "ids": [ + "america/argentina/catamarca", + "america/argentina/comodrivadavia", + "america/catamarca" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 2, + 5, + 3, + 4, + 5, + 3, + 4, + 3, + 4, + 3, + 4, + 2, + 3, + 4, + 5, + 3, + 4 + ], + "transitions": [ + -2372096212, + -1567453392, + -1233432000, + -1222981200, + -1205956800, + -1194037200, + -1172865600, + -1162501200, + -1141329600, + -1130965200, + -1109793600, + -1099429200, + -1078257600, + -1067806800, + -1046635200, + -1036270800, + -1015099200, + -1004734800, + -983563200, + -973198800, + -952027200, + -941576400, + -931032000, + -900882000, + -890337600, + -833749200, + -827265600, + -752274000, + -733780800, + -197326800, + -190843200, + -184194000, + -164491200, + -152658000, + -132955200, + -121122000, + -101419200, + -86821200, + -71092800, + -54766800, + -39038400, + -23317200, + -7588800, + 128142000, + 136605600, + 596948400, + 605066400, + 624423600, + 636516000, + 656478000, + 667965600, + 687931200, + 699415200, + 719377200, + 731469600, + 938919600, + 952052400, + 1086058800, + 1087704000, + 1198983600, + 1205632800 + ], + "types": [ + { + "offset": -15788 + }, + { + "offset": -15408 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a3214de8e358efe8-33b7f8f888f95c0b.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a3214de8e358efe8-33b7f8f888f95c0b.json new file mode 100644 index 00000000000000..ad8b4bd955f0a6 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a3214de8e358efe8-33b7f8f888f95c0b.json @@ -0,0 +1,52 @@ +{ + "ids": [ + "america/creston", + "america/phoenix", + "mst", + "us/arizona" + ], + "tzif": { + "posix": { + "abbr": "MST", + "offset": -25200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2717643600, + -1633273200, + -1615132800, + -1601823600, + -1583683200, + -880210800, + -820519140, + -812653140, + -796845540, + -84380400, + -68659200 + ], + "types": [ + { + "offset": -26898 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a3bbf95d113466c0-366de44a51a62cbe.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a3bbf95d113466c0-366de44a51a62cbe.json new file mode 100644 index 00000000000000..6882ee7884f8de --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a3bbf95d113466c0-366de44a51a62cbe.json @@ -0,0 +1,168 @@ +{ + "ids": [ + "america/argentina/san_luis" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 2, + 3, + 4, + 2, + 3, + 4, + 3, + 4, + 3, + 4, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 2, + 3, + 4 + ], + "transitions": [ + -2372096076, + -1567453392, + -1233432000, + -1222981200, + -1205956800, + -1194037200, + -1172865600, + -1162501200, + -1141329600, + -1130965200, + -1109793600, + -1099429200, + -1078257600, + -1067806800, + -1046635200, + -1036270800, + -1015099200, + -1004734800, + -983563200, + -973198800, + -952027200, + -941576400, + -931032000, + -900882000, + -890337600, + -833749200, + -827265600, + -752274000, + -733780800, + -197326800, + -190843200, + -184194000, + -164491200, + -152658000, + -132955200, + -121122000, + -101419200, + -86821200, + -71092800, + -54766800, + -39038400, + -23317200, + -7588800, + 128142000, + 136605600, + 596948400, + 605066400, + 624423600, + 637380000, + 655963200, + 667796400, + 675748800, + 938919600, + 952052400, + 1085972400, + 1090728000, + 1198983600, + 1200880800, + 1223784000, + 1236481200, + 1255233600 + ], + "types": [ + { + "offset": -15924 + }, + { + "offset": -15408 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a442eead4fdb53a5-264d7185508cac7f.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a442eead4fdb53a5-264d7185508cac7f.json new file mode 100644 index 00000000000000..8acb9929b07c41 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a442eead4fdb53a5-264d7185508cac7f.json @@ -0,0 +1,149 @@ +{ + "ids": [ + "america/bahia" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1767216356, + -1206957600, + -1191362400, + -1175374800, + -1159826400, + -633819600, + -622069200, + -602283600, + -591832800, + -570747600, + -560210400, + -539125200, + -531352800, + -191365200, + -184197600, + -155163600, + -150069600, + -128898000, + -121125600, + -99954000, + -89589600, + -68418000, + -57967200, + 499748400, + 511236000, + 530593200, + 540266400, + 562129200, + 571197600, + 592974000, + 602042400, + 624423600, + 634701600, + 656478000, + 666756000, + 687927600, + 697600800, + 719982000, + 728445600, + 750826800, + 761709600, + 782276400, + 793159200, + 813726000, + 824004000, + 844570800, + 856058400, + 876106800, + 888717600, + 908074800, + 919562400, + 938919600, + 951616800, + 970974000, + 982461600, + 1003028400, + 1013911200, + 1036292400, + 1045360800, + 1318734000, + 1330221600 + ], + "types": [ + { + "offset": -9244 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a44c115ed3d72421-692eaf79ab1934a7.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a44c115ed3d72421-692eaf79ab1934a7.json new file mode 100644 index 00000000000000..717eb27430c9f2 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a44c115ed3d72421-692eaf79ab1934a7.json @@ -0,0 +1,340 @@ +{ + "ids": [ + "atlantic/madeira" + ], + "tzif": { + "posix": { + "abbr": "WET", + "offset": 0, + "transition": { + "abbr": "WEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 3600 + } + } + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 2, + 1, + 2, + 3, + 2, + 1, + 2, + 3, + 2, + 1, + 2, + 3, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4 + ], + "transitions": [ + -2713906344, + -1830380400, + -1689552000, + -1677798000, + -1667430000, + -1647734400, + -1635894000, + -1616198400, + -1604358000, + -1584662400, + -1572735600, + -1553040000, + -1541199600, + -1521504000, + -1442448000, + -1427673600, + -1379289600, + -1364774400, + -1348444800, + -1333324800, + -1316390400, + -1301270400, + -1284336000, + -1269820800, + -1221436800, + -1206921600, + -1191196800, + -1175472000, + -1127692800, + -1111968000, + -1096848000, + -1080518400, + -1063584000, + -1049068800, + -1033344000, + -1017619200, + -1002499200, + -986169600, + -969235200, + -950486400, + -942019200, + -922492800, + -906940800, + -891129600, + -877305600, + -873680400, + -864003600, + -857952000, + -845856000, + -842835600, + -831344400, + -825897600, + -814406400, + -810781200, + -799894800, + -794448000, + -782956800, + -779331600, + -768445200, + -762998400, + -749088000, + -733363200, + -717627600, + -701902800, + -686178000, + -670453200, + -654728400, + -639003600, + -623278800, + -607554000, + -591829200, + -575499600, + -559774800, + -544050000, + -528325200, + -512600400, + -496875600, + -481150800, + -465426000, + -449701200, + -433976400, + -417646800, + -401922000, + -386197200, + -370472400, + -354747600, + -339022800, + -323298000, + -307573200, + -291848400, + -276123600, + -260398800, + -244674000, + -228344400, + -212619600, + -196894800, + -181170000, + -165445200, + -149720400, + -133995600, + -118270800, + -102546000, + 386726400, + 401846400, + 417571200, + 433296000, + 449020800, + 465350400, + 481075200, + 496800000, + 512524800, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": -4056 + }, + { + "offset": -3600 + }, + { + "offset": 0 + }, + { + "offset": 3600 + }, + { + "offset": 0 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a685965c91f5b79b-e66cc1c813ce5bd6.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a685965c91f5b79b-e66cc1c813ce5bd6.json new file mode 100644 index 00000000000000..78ad2616286876 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a685965c91f5b79b-e66cc1c813ce5bd6.json @@ -0,0 +1,183 @@ +{ + "ids": [ + "america/chihuahua" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 2, + 3 + ], + "transitions": [ + -1514739600, + -1343149200, + -1234807200, + -1220461200, + -1207159200, + -1191344400, + 828864000, + 846399600, + 860313600, + 877849200, + 891766800, + 909302400, + 923216400, + 941356800, + 954666000, + 972806400, + 989139600, + 1001836800, + 1018170000, + 1035705600, + 1049619600, + 1067155200, + 1081069200, + 1099209600, + 1112518800, + 1130659200, + 1143968400, + 1162108800, + 1175418000, + 1193558400, + 1207472400, + 1225008000, + 1238922000, + 1256457600, + 1270371600, + 1288512000, + 1301821200, + 1319961600, + 1333270800, + 1351411200, + 1365325200, + 1382860800, + 1396774800, + 1414310400, + 1428224400, + 1445760000, + 1459674000, + 1477814400, + 1491123600, + 1509264000, + 1522573200, + 1540713600, + 1554627600, + 1572163200, + 1586077200, + 1603612800, + 1617526800, + 1635667200, + 1648976400, + 1667116800 + ], + "types": [ + { + "offset": -25460 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a7b726e2144b8ec3-b273ddcc47da034b.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a7b726e2144b8ec3-b273ddcc47da034b.json new file mode 100644 index 00000000000000..87f65b1a9a06ac --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-a7b726e2144b8ec3-b273ddcc47da034b.json @@ -0,0 +1,129 @@ +{ + "ids": [ + "atlantic/canary" + ], + "tzif": { + "posix": { + "abbr": "WET", + "offset": 0, + "transition": { + "abbr": "WEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 3600 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2 + ], + "transitions": [ + -1509663504, + -733874400, + 323827200, + 338950800, + 354675600, + 370400400, + 386125200, + 401850000, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": -3696 + }, + { + "offset": -3600 + }, + { + "offset": 0 + }, + { + "offset": 3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-aa6fbecd6b3089a1-3c3e5535078a0aca.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-aa6fbecd6b3089a1-3c3e5535078a0aca.json new file mode 100644 index 00000000000000..ababf56764b506 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-aa6fbecd6b3089a1-3c3e5535078a0aca.json @@ -0,0 +1,351 @@ +{ + "ids": [ + "america/moncton" + ], + "tzif": { + "posix": { + "abbr": "AST", + "offset": -14400, + "transition": { + "abbr": "ADT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2 + ], + "transitions": [ + -2715882052, + -2131642800, + -1632074400, + -1615143600, + -1153681200, + -1145822400, + -1122231600, + -1114372800, + -1090782000, + -1082923200, + -1059332400, + -1051473600, + -1027882800, + -1020024000, + -996433200, + -988574400, + -965674800, + -955396800, + -934743600, + -923947200, + -904503600, + -891892800, + -880221600, + -769395600, + -765399600, + -747252000, + -733950000, + -715802400, + -702500400, + -684352800, + -671050800, + -652903200, + -639601200, + -620848800, + -608151600, + -589399200, + -576097200, + -557949600, + -544647600, + -526500000, + -513198000, + -495050400, + -481748400, + -463600800, + -450298800, + -431546400, + -418244400, + -400096800, + -384375600, + -368647200, + -352926000, + -337197600, + -321476400, + -305748000, + -289422000, + -273693600, + -257972400, + -242244000, + -226522800, + -210794400, + -195073200, + -179344800, + -163623600, + -147895200, + -131569200, + -116445600, + -100119600, + -84391200, + -68670000, + -52941600, + -37220400, + -21492000, + -5770800, + 9957600, + 25678800, + 41407200, + 57733200, + 73461600, + 89182800, + 136360800, + 152082000, + 167810400, + 183531600, + 199260000, + 215586000, + 230709600, + 247035600, + 262764000, + 278485200, + 294213600, + 309934800, + 325663200, + 341384400, + 357112800, + 372834000, + 388562400, + 404888400, + 420012000, + 436338000, + 452066400, + 467787600, + 483516000, + 499237200, + 514965600, + 530686800, + 544600800, + 562136400, + 576050400, + 594190800, + 607500000, + 625640400, + 638949600, + 657090000, + 671004000, + 688539600, + 702453600, + 719989200, + 733896060, + 752036460, + 765345660, + 783486060, + 796795260, + 814935660, + 828849660, + 846385260, + 860299260, + 877834860, + 891748860, + 909284460, + 923198460, + 941338860, + 954648060, + 972788460, + 986097660, + 1004238060, + 1018152060, + 1035687660, + 1049601660, + 1067137260, + 1081051260, + 1099191660, + 1112500860, + 1130641260, + 1143950460, + 1162090860, + 1173592800, + 1194152400 + ], + "types": [ + { + "offset": -15548 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-aba73c12b2e7f46-a62a02047cf0f8be.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-aba73c12b2e7f46-a62a02047cf0f8be.json new file mode 100644 index 00000000000000..edaf2a23ed7924 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-aba73c12b2e7f46-a62a02047cf0f8be.json @@ -0,0 +1,47 @@ +{ + "ids": [ + "africa/bangui", + "africa/brazzaville", + "africa/douala", + "africa/kinshasa", + "africa/lagos", + "africa/libreville", + "africa/luanda", + "africa/malabo", + "africa/niamey", + "africa/porto-novo" + ], + "tzif": { + "posix": { + "abbr": "WAT", + "offset": 3600, + "transition": null + }, + "transition_types": [ + 1, + 0, + 2, + 3 + ], + "transitions": [ + -2035584815, + -1940889600, + -1767226415, + -1588465800 + ], + "types": [ + { + "offset": 815 + }, + { + "offset": 0 + }, + { + "offset": 1800 + }, + { + "offset": 3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-aeaa8db63bed649c-8a6f5505498821c5.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-aeaa8db63bed649c-8a6f5505498821c5.json new file mode 100644 index 00000000000000..defddbdedb944f --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-aeaa8db63bed649c-8a6f5505498821c5.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt+7" + ], + "tzif": { + "posix": { + "abbr": "-07", + "offset": -25200, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": -25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b05b7d10c5ffdad-d39eb7f9fe146506.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b05b7d10c5ffdad-d39eb7f9fe146506.json new file mode 100644 index 00000000000000..91021ebecd260c --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b05b7d10c5ffdad-d39eb7f9fe146506.json @@ -0,0 +1,33 @@ +{ + "ids": [ + "asia/jayapura" + ], + "tzif": { + "posix": { + "abbr": "WIT", + "offset": 32400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1 + ], + "transitions": [ + -1172913768, + -799491600, + -189423000 + ], + "types": [ + { + "offset": 33768 + }, + { + "offset": 32400 + }, + { + "offset": 34200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b06ac7e52f27518c-ad815076903a307.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b06ac7e52f27518c-ad815076903a307.json new file mode 100644 index 00000000000000..885b5a077a942b --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b06ac7e52f27518c-ad815076903a307.json @@ -0,0 +1,162 @@ +{ + "ids": [ + "europe/bucharest" + ], + "tzif": { + "posix": { + "abbr": "EET", + "offset": 7200, + "transition": { + "abbr": "EEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 14400 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2469404664, + -1213148664, + -1187056800, + -1175479200, + -1159754400, + -1144029600, + -1127700000, + -1111975200, + -1096250400, + -1080525600, + -1064800800, + -1049076000, + -1033351200, + -1017626400, + -1001901600, + -986176800, + -970452000, + -954727200, + 296604000, + 307486800, + 323816400, + 338940000, + 354672000, + 370396800, + 386121600, + 401846400, + 417571200, + 433296000, + 449020800, + 465350400, + 481075200, + 496800000, + 512524800, + 528249600, + 543974400, + 559699200, + 575424000, + 591148800, + 606873600, + 622598400, + 638323200, + 654652800, + 670370400, + 686095200, + 701820000, + 717544800, + 733269600, + 748994400, + 757375200, + 780440400, + 796168800, + 811890000, + 828223200, + 846363600 + ], + "types": [ + { + "offset": 6264 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b0c86e4e28bb1810-bccad26ea4f4cee2.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b0c86e4e28bb1810-bccad26ea4f4cee2.json new file mode 100644 index 00000000000000..7cae47ada033bd --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b0c86e4e28bb1810-bccad26ea4f4cee2.json @@ -0,0 +1,191 @@ +{ + "ids": [ + "asia/krasnoyarsk" + ], + "tzif": { + "posix": { + "abbr": "+07", + "offset": 25200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 5, + 2, + 4 + ], + "transitions": [ + -1577513486, + -1247551200, + 354906000, + 370713600, + 386442000, + 402249600, + 417978000, + 433785600, + 449600400, + 465332400, + 481057200, + 496782000, + 512506800, + 528231600, + 543956400, + 559681200, + 575406000, + 591130800, + 606855600, + 622580400, + 638305200, + 654634800, + 670359600, + 670363200, + 686088000, + 695764800, + 701809200, + 717534000, + 733258800, + 748983600, + 764708400, + 780433200, + 796158000, + 811882800, + 828212400, + 846356400, + 859662000, + 877806000, + 891111600, + 909255600, + 922561200, + 941310000, + 954010800, + 972759600, + 985460400, + 1004209200, + 1017514800, + 1035658800, + 1048964400, + 1067108400, + 1080414000, + 1099162800, + 1111863600, + 1130612400, + 1143313200, + 1162062000, + 1174762800, + 1193511600, + 1206817200, + 1224961200, + 1238266800, + 1256410800, + 1269716400, + 1288465200, + 1301166000, + 1414260000 + ], + "types": [ + { + "offset": 22286 + }, + { + "offset": 21600 + }, + { + "offset": 25200 + }, + { + "offset": 28800 + }, + { + "offset": 25200 + }, + { + "offset": 28800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b397eb337d51aec5-9d2674bc81a95add.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b397eb337d51aec5-9d2674bc81a95add.json new file mode 100644 index 00000000000000..c3e7f81dd41fc2 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b397eb337d51aec5-9d2674bc81a95add.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt-1" + ], + "tzif": { + "posix": { + "abbr": "+01", + "offset": 3600, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": 3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b3a7b6acccb12af9-93f5a4bd9827e971.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b3a7b6acccb12af9-93f5a4bd9827e971.json new file mode 100644 index 00000000000000..20b2577cd9616b --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b3a7b6acccb12af9-93f5a4bd9827e971.json @@ -0,0 +1,31 @@ +{ + "ids": [ + "pacific/palau" + ], + "tzif": { + "posix": { + "abbr": "+09", + "offset": 32400, + "transition": null + }, + "transition_types": [ + 1, + 2 + ], + "transitions": [ + -3944624276, + -2177485076 + ], + "types": [ + { + "offset": -54124 + }, + { + "offset": 32276 + }, + { + "offset": 32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b3d9e43d648fe2bf-fa688f4eb568be69.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b3d9e43d648fe2bf-fa688f4eb568be69.json new file mode 100644 index 00000000000000..4bfcf3b1a3ee62 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b3d9e43d648fe2bf-fa688f4eb568be69.json @@ -0,0 +1,29 @@ +{ + "ids": [ + "indian/kerguelen", + "indian/maldives" + ], + "tzif": { + "posix": { + "abbr": "+05", + "offset": 18000, + "transition": null + }, + "transition_types": [ + 0, + 1 + ], + "transitions": [ + -2840158440, + -315636840 + ], + "types": [ + { + "offset": 17640 + }, + { + "offset": 18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b445d8dfee87de1d-3d26ba9d3df071ac.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b445d8dfee87de1d-3d26ba9d3df071ac.json new file mode 100644 index 00000000000000..0eed30740f1079 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b445d8dfee87de1d-3d26ba9d3df071ac.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt-12" + ], + "tzif": { + "posix": { + "abbr": "+12", + "offset": 43200, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": 43200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b6ba868b587cad06-6667a264db5d890e.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b6ba868b587cad06-6667a264db5d890e.json new file mode 100644 index 00000000000000..a2c94b4fa4c881 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b6ba868b587cad06-6667a264db5d890e.json @@ -0,0 +1,208 @@ +{ + "ids": [ + "asia/macao", + "asia/macau" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": 28800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1 + ], + "transitions": [ + -2056692850, + -884509200, + -873280800, + -855918000, + -841744800, + -828529200, + -765363600, + -747046800, + -733827600, + -716461200, + -697021200, + -683715600, + -667990800, + -654771600, + -636627600, + -623322000, + -605178000, + -591872400, + -573642000, + -559818000, + -541674000, + -528368400, + -510224400, + -498128400, + -478774800, + -466678800, + -446720400, + -435229200, + -415258200, + -403158600, + -383808600, + -371709000, + -352359000, + -340259400, + -320909400, + -308809800, + -288855000, + -277360200, + -257405400, + -245910600, + -225955800, + -213856200, + -194506200, + -182406600, + -163056600, + -148537800, + -132820200, + -117088200, + -101370600, + -85638600, + -69312600, + -53584200, + -37863000, + -22134600, + -6413400, + 9315000, + 25036200, + 40764600, + 56485800, + 72214200, + 88540200, + 104268600, + 119989800, + 126041400, + 151439400, + 167167800, + 182889000, + 198617400, + 214338600, + 295385400, + 309292200 + ], + "types": [ + { + "offset": 27250 + }, + { + "offset": 28800 + }, + { + "offset": 32400 + }, + { + "offset": 36000 + }, + { + "offset": 32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b785c09bc525b515-5fd6146854daeb91.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b785c09bc525b515-5fd6146854daeb91.json new file mode 100644 index 00000000000000..2a2e9fad08d8e9 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b785c09bc525b515-5fd6146854daeb91.json @@ -0,0 +1,97 @@ +{ + "ids": [ + "america/eirunepe" + ], + "tzif": { + "posix": { + "abbr": "-05", + "offset": -18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 1 + ], + "transitions": [ + -1767208832, + -1206950400, + -1191355200, + -1175367600, + -1159819200, + -633812400, + -622062000, + -602276400, + -591825600, + -570740400, + -560203200, + -539118000, + -531345600, + -191358000, + -184190400, + -155156400, + -150062400, + -128890800, + -121118400, + -99946800, + -89582400, + -68410800, + -57960000, + 499755600, + 511243200, + 530600400, + 540273600, + 562136400, + 571204800, + 750834000, + 761716800, + 1214283600, + 1384056000 + ], + "types": [ + { + "offset": -16768 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b89f6da72122ca01-812d173fdcfeaaa6.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b89f6da72122ca01-812d173fdcfeaaa6.json new file mode 100644 index 00000000000000..3c9b0812048233 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b89f6da72122ca01-812d173fdcfeaaa6.json @@ -0,0 +1,88 @@ +{ + "ids": [ + "asia/seoul", + "rok" + ], + "tzif": { + "posix": { + "abbr": "KST", + "offset": 32400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 1, + 4, + 1, + 4, + 1, + 4, + 1, + 4, + 1, + 4, + 1, + 4, + 1, + 2, + 3, + 2 + ], + "transitions": [ + -1948782472, + -1830414600, + -767350800, + -681210000, + -672228000, + -654771600, + -640864800, + -623408400, + -609415200, + -588848400, + -577965600, + -498128400, + -462702600, + -451733400, + -429784200, + -418296600, + -399544200, + -387451800, + -368094600, + -356002200, + -336645000, + -324552600, + -305195400, + -293103000, + -264933000, + 547578000, + 560883600 + ], + "types": [ + { + "offset": 30472 + }, + { + "offset": 30600 + }, + { + "offset": 32400 + }, + { + "offset": 36000 + }, + { + "offset": 34200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b8b54ce37e65e37e-e9672f15a3e270a7.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b8b54ce37e65e37e-e9672f15a3e270a7.json new file mode 100644 index 00000000000000..f48a5ad388b899 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b8b54ce37e65e37e-e9672f15a3e270a7.json @@ -0,0 +1,76 @@ +{ + "ids": [ + "pacific/guam", + "pacific/saipan" + ], + "tzif": { + "posix": { + "abbr": "ChST", + "offset": 36000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 2 + ], + "transitions": [ + -3944626740, + -2177487540, + -885549600, + -802256400, + -331891200, + -281610000, + -73728000, + -29415540, + -16704000, + -10659600, + 9907200, + 21394800, + 41356800, + 52844400, + 124819200, + 130863600, + 201888000, + 209487660, + 230659200, + 241542000, + 977493600 + ], + "types": [ + { + "offset": -51660 + }, + { + "offset": 34740 + }, + { + "offset": 36000 + }, + { + "offset": 32400 + }, + { + "offset": 39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b9b18c55e2cd4d53-b3d917ee40af164d.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b9b18c55e2cd4d53-b3d917ee40af164d.json new file mode 100644 index 00000000000000..715b328f90bf50 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b9b18c55e2cd4d53-b3d917ee40af164d.json @@ -0,0 +1,226 @@ +{ + "ids": [ + "america/belize" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 3, + 3, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 3, + 1, + 3, + 1 + ], + "transitions": [ + -1822500432, + -1616954400, + -1606069800, + -1585504800, + -1574015400, + -1554055200, + -1542565800, + -1522605600, + -1511116200, + -1490551200, + -1479666600, + -1459101600, + -1448217000, + -1427652000, + -1416162600, + -1396202400, + -1384713000, + -1364752800, + -1353263400, + -1333303200, + -1321813800, + -1301248800, + -1290364200, + -1269799200, + -1258914600, + -1238349600, + -1226860200, + -1206900000, + -1195410600, + -1175450400, + -1163961000, + -1143396000, + -1132511400, + -1111946400, + -1101061800, + -1080496800, + -1069612200, + -1049047200, + -1037557800, + -1017597600, + -1006108200, + -986148000, + -974658600, + -954093600, + -943209000, + -922644000, + -911759400, + -891194400, + -879705000, + -868212000, + -769395600, + -758746800, + -701892000, + -690402600, + -670442400, + -658953000, + -638992800, + -627503400, + -606938400, + -596053800, + -575488800, + -564604200, + -544039200, + -532549800, + -512589600, + -501100200, + -481140000, + -469650600, + -449690400, + -438201000, + -417636000, + -406751400, + -386186400, + -375301800, + -354736800, + -343247400, + -323287200, + -311797800, + -291837600, + -280348200, + -259783200, + -248898600, + -228333600, + -217449000, + -196884000, + -185999400, + -165434400, + -153945000, + -133984800, + -122495400, + -102535200, + -91045800, + -70480800, + -59596200, + 123919200, + 129618000, + 409039200, + 413874000 + ], + "types": [ + { + "offset": -21168 + }, + { + "offset": -21600 + }, + { + "offset": -19800 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b9d3679a03af6191-99d89d33c8fd0b60.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b9d3679a03af6191-99d89d33c8fd0b60.json new file mode 100644 index 00000000000000..54041a69497525 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-b9d3679a03af6191-99d89d33c8fd0b60.json @@ -0,0 +1,184 @@ +{ + "ids": [ + "asia/qostanay" + ], + "tzif": { + "posix": { + "abbr": "+05", + "offset": 18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 2, + 5, + 2, + 5, + 1, + 3, + 4, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 3, + 4, + 2, + 5 + ], + "transitions": [ + -1441167268, + -1247544000, + 354913200, + 370720800, + 386445600, + 386449200, + 402256800, + 417985200, + 433792800, + 449607600, + 465339600, + 481064400, + 496789200, + 512514000, + 528238800, + 543963600, + 559688400, + 575413200, + 591138000, + 606862800, + 622587600, + 638312400, + 654642000, + 670366800, + 670370400, + 686095200, + 695772000, + 701816400, + 717541200, + 733266000, + 748990800, + 764715600, + 780440400, + 796165200, + 811890000, + 828219600, + 846363600, + 859669200, + 877813200, + 891118800, + 909262800, + 922568400, + 941317200, + 954018000, + 972766800, + 985467600, + 1004216400, + 1017522000, + 1035666000, + 1048971600, + 1067115600, + 1080421200, + 1099170000, + 1709229600 + ], + "types": [ + { + "offset": 15268 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + }, + { + "offset": 21600 + }, + { + "offset": 21600 + }, + { + "offset": 18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bad7f01dd3f01a92-8ed1d7da904b667d.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bad7f01dd3f01a92-8ed1d7da904b667d.json new file mode 100644 index 00000000000000..f408a0bc99baf3 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bad7f01dd3f01a92-8ed1d7da904b667d.json @@ -0,0 +1,308 @@ +{ + "ids": [ + "america/rainy_river", + "america/winnipeg", + "canada/central" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": { + "abbr": "CDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2602258284, + -1694368800, + -1681671600, + -1632067200, + -1615136400, + -1029686400, + -1018198800, + -880214400, + -769395600, + -765392400, + -746035200, + -732733200, + -715795200, + -702493200, + -684345600, + -671043600, + -652896000, + -639594000, + -620755200, + -607626000, + -589392000, + -576090000, + -557942400, + -544640400, + -526492800, + -513190800, + -495043200, + -481741200, + -463593600, + -450291600, + -431539200, + -418237200, + -400089600, + -386787600, + -368640000, + -355338000, + -337190400, + -321469200, + -305740800, + -292438800, + -210787200, + -198090000, + -116438400, + -100108800, + -84384000, + -68659200, + -52934400, + -37209600, + -21484800, + -5760000, + 9964800, + 25689600, + 41414400, + 57744000, + 73468800, + 89193600, + 104918400, + 120643200, + 136368000, + 152092800, + 167817600, + 183542400, + 199267200, + 215596800, + 230716800, + 247046400, + 262771200, + 278496000, + 294220800, + 309945600, + 325670400, + 341395200, + 357120000, + 372844800, + 388569600, + 404899200, + 420019200, + 436348800, + 452073600, + 467798400, + 483523200, + 499248000, + 514972800, + 530697600, + 544608000, + 562147200, + 576057600, + 594201600, + 607507200, + 625651200, + 638956800, + 657100800, + 671011200, + 688550400, + 702460800, + 720000000, + 733910400, + 752054400, + 765360000, + 783504000, + 796809600, + 814953600, + 828864000, + 846403200, + 860313600, + 877852800, + 891763200, + 909302400, + 923212800, + 941356800, + 954662400, + 972806400, + 986112000, + 1004256000, + 1018166400, + 1035705600, + 1049616000, + 1067155200, + 1081065600, + 1099209600, + 1112515200, + 1130659200, + 1136095200, + 1162105200, + 1173600000, + 1194159600 + ], + "types": [ + { + "offset": -23316 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bafb78fdc913701c-de429c1ed9e982a1.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bafb78fdc913701c-de429c1ed9e982a1.json new file mode 100644 index 00000000000000..e30479fb25238e --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bafb78fdc913701c-de429c1ed9e982a1.json @@ -0,0 +1,168 @@ +{ + "ids": [ + "europe/vienna" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": { + "abbr": "CEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2422055121, + -1693706400, + -1680483600, + -1663455600, + -1650150000, + -1632006000, + -1618700400, + -1569711600, + -1555801200, + -938905200, + -857257200, + -844556400, + -828226800, + -812502000, + -796777200, + -781052400, + -780188400, + -748479600, + -733273200, + -717634800, + -701910000, + -684975600, + -670460400, + 323823600, + 338940000, + 347151600, + 370400400, + 386125200, + 401850000, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": 3921 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bbf3217ce334c3f2-5622ec9ecf81c925.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bbf3217ce334c3f2-5622ec9ecf81c925.json new file mode 100644 index 00000000000000..c17727e02fb0dc --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bbf3217ce334c3f2-5622ec9ecf81c925.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt+11" + ], + "tzif": { + "posix": { + "abbr": "-11", + "offset": -39600, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": -39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bbfc9e9111217c11-69684e27be4c3e38.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bbfc9e9111217c11-69684e27be4c3e38.json new file mode 100644 index 00000000000000..0427a357b989f4 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bbfc9e9111217c11-69684e27be4c3e38.json @@ -0,0 +1,144 @@ +{ + "ids": [ + "america/indiana/tell_city" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": { + "abbr": "CDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 4, + 2, + 3, + 4, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1 + ], + "transitions": [ + -2717647200, + -1633276800, + -1615136400, + -1601827200, + -1583686800, + -880214400, + -769395600, + -765392400, + -462996000, + -450291600, + -431539200, + -418237200, + -400089600, + -386787600, + -368640000, + -355338000, + -337190400, + -323888400, + -305740800, + -292438800, + -273686400, + -257965200, + -242236800, + -226515600, + -210787200, + -195066000, + -179337600, + -68662800, + -52934400, + -37213200, + -21484800, + -5767200, + 9961200, + 25682400, + 1143961200, + 1143964800, + 1162105200, + 1173600000, + 1194159600 + ], + "types": [ + { + "offset": -20823 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bcd5d242787ff58-595e172a944e8f55.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bcd5d242787ff58-595e172a944e8f55.json new file mode 100644 index 00000000000000..0268d3ed84c3f5 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bcd5d242787ff58-595e172a944e8f55.json @@ -0,0 +1,71 @@ +{ + "ids": [ + "pacific/efate" + ], + "tzif": { + "posix": { + "abbr": "+11", + "offset": 39600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2 + ], + "transitions": [ + -1829387596, + 125409600, + 133876800, + 433256400, + 448977600, + 464706000, + 480427200, + 496760400, + 511876800, + 528210000, + 543931200, + 559659600, + 575380800, + 591109200, + 606830400, + 622558800, + 638280000, + 654008400, + 669729600, + 686062800, + 696340800, + 719931600 + ], + "types": [ + { + "offset": 40396 + }, + { + "offset": 39600 + }, + { + "offset": 43200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bd05cebe8eecfa2c-408891f6d5e0c72a.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bd05cebe8eecfa2c-408891f6d5e0c72a.json new file mode 100644 index 00000000000000..d9fbf3da578fc1 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bd05cebe8eecfa2c-408891f6d5e0c72a.json @@ -0,0 +1,160 @@ +{ + "ids": [ + "africa/ceuta" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": { + "abbr": "CEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3 + ], + "transitions": [ + -2177452800, + -1630112400, + -1616810400, + -1442451600, + -1427673600, + -1379293200, + -1364774400, + -1348448400, + -1333324800, + -1316390400, + -1301270400, + -81432000, + -71110800, + 141264000, + 147222000, + 199756800, + 207702000, + 231292800, + 244249200, + 265507200, + 271033200, + 448243200, + 504918000, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": -1276 + }, + { + "offset": 0 + }, + { + "offset": 3600 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bd9ad03026ed086f-3d5a919e98fa2787.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bd9ad03026ed086f-3d5a919e98fa2787.json new file mode 100644 index 00000000000000..d28ce5b66fb674 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bd9ad03026ed086f-3d5a919e98fa2787.json @@ -0,0 +1,48 @@ +{ + "ids": [ + "asia/calcutta", + "asia/kolkata" + ], + "tzif": { + "posix": { + "abbr": "IST", + "offset": 19800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 4, + 3, + 4, + 3 + ], + "transitions": [ + -3645237208, + -3155694800, + -2019705670, + -891581400, + -872058600, + -862637400, + -764145000 + ], + "types": [ + { + "offset": 21208 + }, + { + "offset": 21200 + }, + { + "offset": 19270 + }, + { + "offset": 19800 + }, + { + "offset": 23400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bda89ec29d33a428-f6c6f1d38129c153.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bda89ec29d33a428-f6c6f1d38129c153.json new file mode 100644 index 00000000000000..c55b9ea8477839 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bda89ec29d33a428-f6c6f1d38129c153.json @@ -0,0 +1,201 @@ +{ + "ids": [ + "america/montevideo" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 4, + 2, + 5, + 4, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 4, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 7, + 4, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6, + 2, + 5, + 6 + ], + "transitions": [ + -1942690509, + -1567455309, + -1459627200, + -1443819600, + -1428006600, + -1412283600, + -1396470600, + -1380747600, + -1141590600, + -1128286800, + -1110141000, + -1096837200, + -1078691400, + -1065387600, + -1047241800, + -1033938000, + -1015187400, + -1002488400, + -983737800, + -971038800, + -954707400, + -938984400, + -920838600, + -907534800, + -896819400, + -853621200, + -845847000, + -334789200, + -319671000, + -314226000, + -309996000, + -149720400, + -134604000, + -50446800, + -34205400, + 9860400, + 14176800, + 72846000, + 80100000, + 127278000, + 132111000, + 147234600, + 156913200, + 165376800, + 219812400, + 226461600, + 250052400, + 257911200, + 282711600, + 289360800, + 294202800, + 322020000, + 566449200, + 573012000, + 597812400, + 605066400, + 625633200, + 635911200, + 656478000, + 667965600, + 688532400, + 699415200, + 719377200, + 730864800, + 1095562800, + 1111896000, + 1128834000, + 1142136000, + 1159678800 + ], + "types": [ + { + "offset": -13491 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -12600 + }, + { + "offset": -9000 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + }, + { + "offset": -5400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bdc0a1977c311c8d-87860ab499ecadb8.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bdc0a1977c311c8d-87860ab499ecadb8.json new file mode 100644 index 00000000000000..ed275181ee8141 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bdc0a1977c311c8d-87860ab499ecadb8.json @@ -0,0 +1,32 @@ +{ + "ids": [ + "asia/bahrain", + "asia/qatar" + ], + "tzif": { + "posix": { + "abbr": "+03", + "offset": 10800, + "transition": null + }, + "transition_types": [ + 1, + 2 + ], + "transitions": [ + -1577935568, + 76190400 + ], + "types": [ + { + "offset": 12368 + }, + { + "offset": 14400 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bdd491f43b0c1c85-6f9616d7048f0cf9.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bdd491f43b0c1c85-6f9616d7048f0cf9.json new file mode 100644 index 00000000000000..afb43838a28d6d --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-bdd491f43b0c1c85-6f9616d7048f0cf9.json @@ -0,0 +1,47 @@ +{ + "ids": [ + "america/costa_rica" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2524501427, + -1545071027, + 288770400, + 297234000, + 320220000, + 328683600, + 664264800, + 678344400, + 695714400, + 700635600 + ], + "types": [ + { + "offset": -20173 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-be07532f1af7dccb-7a89363e76463570.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-be07532f1af7dccb-7a89363e76463570.json new file mode 100644 index 00000000000000..14de2aaccd59eb --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-be07532f1af7dccb-7a89363e76463570.json @@ -0,0 +1,116 @@ +{ + "ids": [ + "america/matamoros" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": { + "abbr": "CDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1514743200, + 576057600, + 594198000, + 828864000, + 846399600, + 860313600, + 877849200, + 891763200, + 909298800, + 923212800, + 941353200, + 954662400, + 972802800, + 989136000, + 1001833200, + 1018166400, + 1035702000, + 1049616000, + 1067151600, + 1081065600, + 1099206000, + 1112515200, + 1130655600, + 1143964800, + 1162105200, + 1175414400, + 1193554800, + 1207468800, + 1225004400, + 1238918400, + 1256454000 + ], + "types": [ + { + "offset": -23400 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-be7c1ce9358259b9-87fdd35d13d52495.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-be7c1ce9358259b9-87fdd35d13d52495.json new file mode 100644 index 00000000000000..929688bb8df3c7 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-be7c1ce9358259b9-87fdd35d13d52495.json @@ -0,0 +1,109 @@ +{ + "ids": [ + "america/indiana/vevay" + ], + "tzif": { + "posix": { + "abbr": "EST", + "offset": -18000, + "transition": { + "abbr": "EDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3 + ], + "transitions": [ + -2717647200, + -1633276800, + -1615136400, + -1601827200, + -1583686800, + -880214400, + -769395600, + -765392400, + -495043200, + -21488400, + -5767200, + 9961200, + 25682400, + 41410800, + 57736800, + 73465200, + 89186400, + 1143961200, + 1162101600, + 1173596400, + 1194156000 + ], + "types": [ + { + "offset": -20416 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-be9bc4833f21d33b-2a54484e254d46c8.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-be9bc4833f21d33b-2a54484e254d46c8.json new file mode 100644 index 00000000000000..455c8d3107d2b3 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-be9bc4833f21d33b-2a54484e254d46c8.json @@ -0,0 +1,195 @@ +{ + "ids": [ + "america/cuiaba" + ], + "tzif": { + "posix": { + "abbr": "-04", + "offset": -14400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2 + ], + "transitions": [ + -1767212140, + -1206954000, + -1191358800, + -1175371200, + -1159822800, + -633816000, + -622065600, + -602280000, + -591829200, + -570744000, + -560206800, + -539121600, + -531349200, + -191361600, + -184194000, + -155160000, + -150066000, + -128894400, + -121122000, + -99950400, + -89586000, + -68414400, + -57963600, + 499752000, + 511239600, + 530596800, + 540270000, + 562132800, + 571201200, + 592977600, + 602046000, + 624427200, + 634705200, + 656481600, + 666759600, + 687931200, + 697604400, + 719985600, + 728449200, + 750830400, + 761713200, + 782280000, + 793162800, + 813729600, + 824007600, + 844574400, + 856062000, + 876110400, + 888721200, + 908078400, + 919566000, + 938923200, + 951620400, + 970977600, + 982465200, + 1003032000, + 1013914800, + 1036296000, + 1045364400, + 1099368000, + 1108868400, + 1129435200, + 1140318000, + 1162699200, + 1172372400, + 1192334400, + 1203217200, + 1224388800, + 1234666800, + 1255838400, + 1266721200, + 1287288000, + 1298170800, + 1318737600, + 1330225200, + 1350792000, + 1361070000, + 1382241600, + 1392519600, + 1413691200, + 1424574000, + 1445140800, + 1456023600, + 1476590400 + ], + "types": [ + { + "offset": -13460 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c0a7b3c45458ac17-adf27c3e51a11cf6.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c0a7b3c45458ac17-adf27c3e51a11cf6.json new file mode 100644 index 00000000000000..f72de4814b2dbd --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c0a7b3c45458ac17-adf27c3e51a11cf6.json @@ -0,0 +1,166 @@ +{ + "ids": [ + "america/argentina/jujuy", + "america/jujuy" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 2, + 3, + 4, + 2, + 5, + 5, + 3, + 4, + 5, + 3, + 4, + 3, + 4, + 3, + 4, + 5, + 3, + 4 + ], + "transitions": [ + -2372096328, + -1567453392, + -1233432000, + -1222981200, + -1205956800, + -1194037200, + -1172865600, + -1162501200, + -1141329600, + -1130965200, + -1109793600, + -1099429200, + -1078257600, + -1067806800, + -1046635200, + -1036270800, + -1015099200, + -1004734800, + -983563200, + -973198800, + -952027200, + -941576400, + -931032000, + -900882000, + -890337600, + -833749200, + -827265600, + -752274000, + -733780800, + -197326800, + -190843200, + -184194000, + -164491200, + -152658000, + -132955200, + -121122000, + -101419200, + -86821200, + -71092800, + -54766800, + -39038400, + -23317200, + -7588800, + 128142000, + 136605600, + 596948400, + 605066400, + 624423600, + 636516000, + 657086400, + 669178800, + 686721600, + 694231200, + 699415200, + 719377200, + 731469600, + 938919600, + 952052400, + 1198983600, + 1205632800 + ], + "types": [ + { + "offset": -15672 + }, + { + "offset": -15408 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c0d9ca8c12b3167c-34f182f235d9fe88.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c0d9ca8c12b3167c-34f182f235d9fe88.json new file mode 100644 index 00000000000000..636723c475117b --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c0d9ca8c12b3167c-34f182f235d9fe88.json @@ -0,0 +1,43 @@ +{ + "ids": [ + "pacific/rarotonga" + ], + "tzif": { + "posix": { + "abbr": "-10", + "offset": -36000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 4, + 3 + ], + "transitions": [ + -2209555256, + -543072056, + 279714600, + 289387800, + 309952800 + ], + "types": [ + { + "offset": 48056 + }, + { + "offset": -38344 + }, + { + "offset": -37800 + }, + { + "offset": -34200 + }, + { + "offset": -36000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c0f3e562f1a83b48-46259b3efc2044b4.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c0f3e562f1a83b48-46259b3efc2044b4.json new file mode 100644 index 00000000000000..cdb17c6226c28c --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c0f3e562f1a83b48-46259b3efc2044b4.json @@ -0,0 +1,43 @@ +{ + "ids": [ + "pacific/bougainville" + ], + "tzif": { + "posix": { + "abbr": "+11", + "offset": 39600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 4 + ], + "transitions": [ + -2840178136, + -2366790512, + -868010400, + -768906000, + 1419696000 + ], + "types": [ + { + "offset": 37336 + }, + { + "offset": 35312 + }, + { + "offset": 36000 + }, + { + "offset": 32400 + }, + { + "offset": 39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c17291eb667fe274-81f01d3c395654a6.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c17291eb667fe274-81f01d3c395654a6.json new file mode 100644 index 00000000000000..ef8ceee1cb46bf --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c17291eb667fe274-81f01d3c395654a6.json @@ -0,0 +1,106 @@ +{ + "ids": [ + "america/noronha", + "brazil/denoronha" + ], + "tzif": { + "posix": { + "abbr": "-02", + "offset": -7200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1767217820, + -1206961200, + -1191366000, + -1175378400, + -1159830000, + -633823200, + -622072800, + -602287200, + -591836400, + -570751200, + -560214000, + -539128800, + -531356400, + -191368800, + -184201200, + -155167200, + -150073200, + -128901600, + -121129200, + -99957600, + -89593200, + -68421600, + -57970800, + 499744800, + 511232400, + 530589600, + 540262800, + 562125600, + 571194000, + 592970400, + 602038800, + 624420000, + 634698000, + 938916000, + 951613200, + 970970400, + 971571600, + 1003024800, + 1013907600 + ], + "types": [ + { + "offset": -7780 + }, + { + "offset": -7200 + }, + { + "offset": -3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c306ac2cd34a373c-ec50d5ecafac2084.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c306ac2cd34a373c-ec50d5ecafac2084.json new file mode 100644 index 00000000000000..222ab4ad352216 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c306ac2cd34a373c-ec50d5ecafac2084.json @@ -0,0 +1,360 @@ +{ + "ids": [ + "atlantic/azores" + ], + "tzif": { + "posix": { + "abbr": "-01", + "offset": -3600, + "transition": { + "abbr": "+00", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 3600 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 0 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 3, + 2, + 3, + 4, + 3, + 2, + 3, + 4, + 3, + 2, + 3, + 4, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 6, + 7, + 4, + 6, + 3, + 5, + 4, + 6, + 3, + 5, + 4, + 6, + 3, + 5, + 4, + 6, + 3, + 5 + ], + "transitions": [ + -2713904240, + -1830376800, + -1689548400, + -1677794400, + -1667426400, + -1647730800, + -1635890400, + -1616194800, + -1604354400, + -1584658800, + -1572732000, + -1553036400, + -1541196000, + -1521500400, + -1442444400, + -1427670000, + -1379286000, + -1364770800, + -1348441200, + -1333321200, + -1316386800, + -1301266800, + -1284332400, + -1269817200, + -1221433200, + -1206918000, + -1191193200, + -1175468400, + -1127689200, + -1111964400, + -1096844400, + -1080514800, + -1063580400, + -1049065200, + -1033340400, + -1017615600, + -1002495600, + -986166000, + -969231600, + -950482800, + -942015600, + -922489200, + -906937200, + -891126000, + -877302000, + -873676800, + -864000000, + -857948400, + -845852400, + -842832000, + -831340800, + -825894000, + -814402800, + -810777600, + -799891200, + -794444400, + -782953200, + -779328000, + -768441600, + -762994800, + -749084400, + -733359600, + -717624000, + -701899200, + -686174400, + -670449600, + -654724800, + -639000000, + -623275200, + -607550400, + -591825600, + -575496000, + -559771200, + -544046400, + -528321600, + -512596800, + -496872000, + -481147200, + -465422400, + -449697600, + -433972800, + -417643200, + -401918400, + -386193600, + -370468800, + -354744000, + -339019200, + -323294400, + -307569600, + -291844800, + -276120000, + -260395200, + -244670400, + -228340800, + -212616000, + -196891200, + -181166400, + -165441600, + -149716800, + -133992000, + -118267200, + -102542400, + 386125200, + 401850000, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 504925200, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 725421600, + 733280400, + 740278800, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": -6160 + }, + { + "offset": -6872 + }, + { + "offset": -7200 + }, + { + "offset": -3600 + }, + { + "offset": 0 + }, + { + "offset": -3600 + }, + { + "offset": 0 + }, + { + "offset": 3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c3aa55f145295944-50f38632c531aab8.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c3aa55f145295944-50f38632c531aab8.json new file mode 100644 index 00000000000000..4322314cb2af9f --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c3aa55f145295944-50f38632c531aab8.json @@ -0,0 +1,31 @@ +{ + "ids": [ + "america/cayenne" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2 + ], + "transitions": [ + -1846269040, + -71092800 + ], + "types": [ + { + "offset": -12560 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c4897a4741bd9e82-aaea1d16ea0a4fb8.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c4897a4741bd9e82-aaea1d16ea0a4fb8.json new file mode 100644 index 00000000000000..cdb9065021843f --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c4897a4741bd9e82-aaea1d16ea0a4fb8.json @@ -0,0 +1,256 @@ +{ + "ids": [ + "america/north_dakota/center" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": { + "abbr": "CDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3 + ], + "transitions": [ + -2717643600, + -1633273200, + -1615132800, + -1601823600, + -1583683200, + -880210800, + -769395600, + -765388800, + -84380400, + -68659200, + -52930800, + -37209600, + -21481200, + -5760000, + 9968400, + 25689600, + 41418000, + 57744000, + 73472400, + 89193600, + 104922000, + 120643200, + 126694800, + 152092800, + 162378000, + 183542400, + 199270800, + 215596800, + 230720400, + 247046400, + 262774800, + 278496000, + 294224400, + 309945600, + 325674000, + 341395200, + 357123600, + 372844800, + 388573200, + 404899200, + 420022800, + 436348800, + 452077200, + 467798400, + 483526800, + 499248000, + 514976400, + 530697600, + 544611600, + 562147200, + 576061200, + 594201600, + 607510800, + 625651200, + 638960400, + 657100800, + 671014800, + 688550400, + 702464400, + 720000000, + 733910400, + 752050800, + 765360000, + 783500400, + 796809600, + 814950000, + 828864000, + 846399600, + 860313600, + 877849200, + 891763200, + 909298800, + 923212800, + 941353200, + 954662400, + 972802800, + 986112000, + 1004252400, + 1018166400, + 1035702000, + 1049616000, + 1067151600, + 1081065600, + 1099206000, + 1112515200, + 1130655600, + 1143964800, + 1162105200, + 1173600000, + 1194159600 + ], + "types": [ + { + "offset": -24312 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c595527c9472a8dc-da82dc08bd3d58a0.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c595527c9472a8dc-da82dc08bd3d58a0.json new file mode 100644 index 00000000000000..12dcab2620334d --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c595527c9472a8dc-da82dc08bd3d58a0.json @@ -0,0 +1,60 @@ +{ + "ids": [ + "australia/perth", + "australia/west" + ], + "tzif": { + "posix": { + "abbr": "AWST", + "offset": 28800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2 + ], + "transitions": [ + -2337925404, + -1672552800, + -1665381600, + -883634400, + -876117600, + -860392800, + -844668000, + 152042400, + 162928800, + 436298400, + 447184800, + 690314400, + 699386400, + 1165082400, + 1174759200, + 1193508000 + ], + "types": [ + { + "offset": 27804 + }, + { + "offset": 28800 + }, + { + "offset": 32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c6ecc61594d93097-34f668d36b185b09.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c6ecc61594d93097-34f668d36b185b09.json new file mode 100644 index 00000000000000..0cd12c4c6fe54b --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c6ecc61594d93097-34f668d36b185b09.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt-10" + ], + "tzif": { + "posix": { + "abbr": "+10", + "offset": 36000, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": 36000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c711f11538fdc96f-2563abbbef728ca5.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c711f11538fdc96f-2563abbbef728ca5.json new file mode 100644 index 00000000000000..e5680bd20b18ed --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c711f11538fdc96f-2563abbbef728ca5.json @@ -0,0 +1,194 @@ +{ + "ids": [ + "europe/volgograd" + ], + "tzif": { + "posix": { + "abbr": "MSK", + "offset": 10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 2, + 4, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1 + ], + "transitions": [ + -1577761060, + -1247540400, + 354916800, + 370724400, + 386452800, + 402260400, + 417988800, + 433796400, + 449611200, + 465343200, + 481068000, + 496792800, + 512517600, + 528242400, + 543967200, + 559692000, + 575416800, + 575420400, + 591145200, + 606870000, + 622594800, + 638319600, + 654649200, + 670374000, + 701820000, + 701823600, + 717548400, + 733273200, + 748998000, + 764722800, + 780447600, + 796172400, + 811897200, + 828226800, + 846370800, + 859676400, + 877820400, + 891126000, + 909270000, + 922575600, + 941324400, + 954025200, + 972774000, + 985474800, + 1004223600, + 1017529200, + 1035673200, + 1048978800, + 1067122800, + 1080428400, + 1099177200, + 1111878000, + 1130626800, + 1143327600, + 1162076400, + 1174777200, + 1193526000, + 1206831600, + 1224975600, + 1238281200, + 1256425200, + 1269730800, + 1288479600, + 1301180400, + 1414274400, + 1540681200, + 1609020000 + ], + "types": [ + { + "offset": 10660 + }, + { + "offset": 10800 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + }, + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c79f46dbe8103377-6f330e5ab7f7dc8e.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c79f46dbe8103377-6f330e5ab7f7dc8e.json new file mode 100644 index 00000000000000..904a9e735a71f6 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c79f46dbe8103377-6f330e5ab7f7dc8e.json @@ -0,0 +1,49 @@ +{ + "ids": [ + "asia/ho_chi_minh", + "asia/saigon" + ], + "tzif": { + "posix": { + "abbr": "+07", + "offset": 25200, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 3, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2004073590, + -1851577590, + -852105600, + -782643600, + -767869200, + -718095600, + -457772400, + -315648000, + 171820800 + ], + "types": [ + { + "offset": 25590 + }, + { + "offset": 25200 + }, + { + "offset": 28800 + }, + { + "offset": 32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c7a9617c25e2eb1a-67a9e52b4fa102af.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c7a9617c25e2eb1a-67a9e52b4fa102af.json new file mode 100644 index 00000000000000..35a6d3cb1f88e2 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c7a9617c25e2eb1a-67a9e52b4fa102af.json @@ -0,0 +1,171 @@ +{ + "ids": [ + "america/argentina/la_rioja" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 3, + 4, + 3, + 4, + 2, + 3, + 4, + 5, + 3, + 4 + ], + "transitions": [ + -2372095956, + -1567453392, + -1233432000, + -1222981200, + -1205956800, + -1194037200, + -1172865600, + -1162501200, + -1141329600, + -1130965200, + -1109793600, + -1099429200, + -1078257600, + -1067806800, + -1046635200, + -1036270800, + -1015099200, + -1004734800, + -983563200, + -973198800, + -952027200, + -941576400, + -931032000, + -900882000, + -890337600, + -833749200, + -827265600, + -752274000, + -733780800, + -197326800, + -190843200, + -184194000, + -164491200, + -152658000, + -132955200, + -121122000, + -101419200, + -86821200, + -71092800, + -54766800, + -39038400, + -23317200, + -7588800, + 128142000, + 136605600, + 596948400, + 605066400, + 624423600, + 636516000, + 656478000, + 667792800, + 673588800, + 687927600, + 699415200, + 719377200, + 731469600, + 938919600, + 952052400, + 1086058800, + 1087704000, + 1198983600, + 1205632800 + ], + "types": [ + { + "offset": -16044 + }, + { + "offset": -15408 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c7d151e4111f596b-82465a65ac1b9a8e.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c7d151e4111f596b-82465a65ac1b9a8e.json new file mode 100644 index 00000000000000..47a71c27eae291 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c7d151e4111f596b-82465a65ac1b9a8e.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt-4" + ], + "tzif": { + "posix": { + "abbr": "+04", + "offset": 14400, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c83537c4365f1258-7426b2a60504f417.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c83537c4365f1258-7426b2a60504f417.json new file mode 100644 index 00000000000000..9c3dd07bf43e5d --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c83537c4365f1258-7426b2a60504f417.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt+10" + ], + "tzif": { + "posix": { + "abbr": "-10", + "offset": -36000, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": -36000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c841f0aca0404a73-5f8447c455db7736.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c841f0aca0404a73-5f8447c455db7736.json new file mode 100644 index 00000000000000..81b4f0ee059add --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-c841f0aca0404a73-5f8447c455db7736.json @@ -0,0 +1,85 @@ +{ + "ids": [ + "asia/tashkent" + ], + "tzif": { + "posix": { + "abbr": "+05", + "offset": 18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1 + ], + "transitions": [ + -1441168631, + -1247547600, + 354909600, + 370717200, + 386445600, + 402253200, + 417981600, + 433789200, + 449604000, + 465336000, + 481060800, + 496785600, + 512510400, + 528235200, + 543960000, + 559684800, + 575409600, + 591134400, + 606859200, + 622584000, + 638308800, + 654638400, + 670363200, + 670366800, + 686091600 + ], + "types": [ + { + "offset": 16631 + }, + { + "offset": 18000 + }, + { + "offset": 21600 + }, + { + "offset": 25200 + }, + { + "offset": 21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ca31f6cb7d44b091-6a023a6a71d41a7.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ca31f6cb7d44b091-6a023a6a71d41a7.json new file mode 100644 index 00000000000000..dff38d0eb0d15d --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ca31f6cb7d44b091-6a023a6a71d41a7.json @@ -0,0 +1,391 @@ +{ + "ids": [ + "america/halifax", + "canada/atlantic" + ], + "tzif": { + "posix": { + "abbr": "AST", + "offset": -14400, + "transition": { + "abbr": "ADT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2131645536, + -1696276800, + -1680469200, + -1632074400, + -1615143600, + -1566763200, + -1557090000, + -1535486400, + -1524949200, + -1504468800, + -1493413200, + -1472414400, + -1461963600, + -1440964800, + -1429390800, + -1409515200, + -1396731600, + -1376856000, + -1366491600, + -1346616000, + -1333832400, + -1313956800, + -1303678800, + -1282507200, + -1272661200, + -1251057600, + -1240088400, + -1219608000, + -1207429200, + -1188763200, + -1175979600, + -1157313600, + -1143925200, + -1124049600, + -1113771600, + -1091390400, + -1081026000, + -1059854400, + -1050786000, + -1030910400, + -1018126800, + -999460800, + -986677200, + -965592000, + -955227600, + -935956800, + -923173200, + -904507200, + -891723600, + -880221600, + -769395600, + -765399600, + -747252000, + -733950000, + -715802400, + -702500400, + -684352800, + -671050800, + -652903200, + -639601200, + -589399200, + -576097200, + -557949600, + -544647600, + -526500000, + -513198000, + -495050400, + -481748400, + -431546400, + -418244400, + -400096800, + -386794800, + -368647200, + -355345200, + -337197600, + -323895600, + -242244000, + -226522800, + -210794400, + -195073200, + -179344800, + -163623600, + -147895200, + -131569200, + -116445600, + -100119600, + -84391200, + -68670000, + -52941600, + -37220400, + -21492000, + -5770800, + 9957600, + 25678800, + 41407200, + 57733200, + 73461600, + 89182800, + 104911200, + 120632400, + 136360800, + 152082000, + 167810400, + 183531600, + 199260000, + 215586000, + 230709600, + 247035600, + 262764000, + 278485200, + 294213600, + 309934800, + 325663200, + 341384400, + 357112800, + 372834000, + 388562400, + 404888400, + 420012000, + 436338000, + 452066400, + 467787600, + 483516000, + 499237200, + 514965600, + 530686800, + 544600800, + 562136400, + 576050400, + 594190800, + 607500000, + 625640400, + 638949600, + 657090000, + 671004000, + 688539600, + 702453600, + 719989200, + 733903200, + 752043600, + 765352800, + 783493200, + 796802400, + 814942800, + 828856800, + 846392400, + 860306400, + 877842000, + 891756000, + 909291600, + 923205600, + 941346000, + 954655200, + 972795600, + 986104800, + 1004245200, + 1018159200, + 1035694800, + 1049608800, + 1067144400, + 1081058400, + 1099198800, + 1112508000, + 1130648400, + 1143957600, + 1162098000, + 1173592800, + 1194152400 + ], + "types": [ + { + "offset": -15264 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cab5fb5bf9e7625f-4aaae2f823b6e6c9.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cab5fb5bf9e7625f-4aaae2f823b6e6c9.json new file mode 100644 index 00000000000000..6650631a048760 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cab5fb5bf9e7625f-4aaae2f823b6e6c9.json @@ -0,0 +1,228 @@ +{ + "ids": [ + "australia/adelaide", + "australia/south" + ], + "tzif": { + "posix": { + "abbr": "ACST", + "offset": 34200, + "transition": { + "abbr": "ACDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 4, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 1, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3 + ], + "transitions": [ + -2364110060, + -2230189200, + -1672558200, + -1665387000, + -883639800, + -876123000, + -860398200, + -844673400, + -828343800, + -813223800, + 57688200, + 67969800, + 89137800, + 100024200, + 120587400, + 131473800, + 152037000, + 162923400, + 183486600, + 194977800, + 215541000, + 226427400, + 246990600, + 257877000, + 278440200, + 289326600, + 309889800, + 320776200, + 341339400, + 352225800, + 372789000, + 384280200, + 404843400, + 415729800, + 436293000, + 447179400, + 467742600, + 478629000, + 499192200, + 511288200, + 530037000, + 542737800, + 562091400, + 574792200, + 594145800, + 606241800, + 625595400, + 637691400, + 657045000, + 667931400, + 688494600, + 701195400, + 719944200, + 731435400, + 751998600, + 764094600, + 783448200, + 796149000, + 814897800, + 828203400, + 846347400, + 859653000, + 877797000, + 891102600, + 909246600, + 922552200, + 941301000, + 954001800, + 972750600, + 985451400, + 1004200200, + 1017505800, + 1035649800, + 1048955400, + 1067099400, + 1080405000, + 1099153800, + 1111854600, + 1130603400, + 1143909000, + 1162053000, + 1174753800, + 1193502600, + 1207413000, + 1223137800 + ], + "types": [ + { + "offset": 33260 + }, + { + "offset": 32400 + }, + { + "offset": 34200 + }, + { + "offset": 37800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cad03994b9f9755d-786401d28559cef.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cad03994b9f9755d-786401d28559cef.json new file mode 100644 index 00000000000000..e3bec085baa6ab --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cad03994b9f9755d-786401d28559cef.json @@ -0,0 +1,54 @@ +{ + "ids": [ + "pacific/kosrae" + ], + "tzif": { + "posix": { + "abbr": "+11", + "offset": 39600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 4, + 3, + 2, + 5, + 2 + ], + "transitions": [ + -3944631116, + -2177491916, + -1743678000, + -1606813200, + -1041418800, + -907408800, + -770634000, + -7988400, + 915105600 + ], + "types": [ + { + "offset": -47284 + }, + { + "offset": 39116 + }, + { + "offset": 39600 + }, + { + "offset": 32400 + }, + { + "offset": 36000 + }, + { + "offset": 43200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cb2104a4192b82ba-ddba0d84d8ea7d92.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cb2104a4192b82ba-ddba0d84d8ea7d92.json new file mode 100644 index 00000000000000..8bb2c20f4c09b5 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cb2104a4192b82ba-ddba0d84d8ea7d92.json @@ -0,0 +1,31 @@ +{ + "ids": [ + "asia/kabul" + ], + "tzif": { + "posix": { + "abbr": "+0430", + "offset": 16200, + "transition": null + }, + "transition_types": [ + 1, + 2 + ], + "transitions": [ + -2524538208, + -788932800 + ], + "types": [ + { + "offset": 16608 + }, + { + "offset": 14400 + }, + { + "offset": 16200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cb56ff55ea32bb92-c654a08c059dae2e.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cb56ff55ea32bb92-c654a08c059dae2e.json new file mode 100644 index 00000000000000..f0d09903ef5ca1 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cb56ff55ea32bb92-c654a08c059dae2e.json @@ -0,0 +1,49 @@ +{ + "ids": [ + "asia/pontianak" + ], + "tzif": { + "posix": { + "abbr": "WIB", + "offset": 25200, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 3, + 1, + 3, + 4 + ], + "transitions": [ + -1946186240, + -1172906240, + -881220600, + -766054800, + -683883000, + -620812800, + -189415800, + 567964800 + ], + "types": [ + { + "offset": 26240 + }, + { + "offset": 27000 + }, + { + "offset": 32400 + }, + { + "offset": 28800 + }, + { + "offset": 25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cbcf966225780b1c-8a7f4b3e40c1b2d5.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cbcf966225780b1c-8a7f4b3e40c1b2d5.json new file mode 100644 index 00000000000000..37dbc6ca9cc4da --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cbcf966225780b1c-8a7f4b3e40c1b2d5.json @@ -0,0 +1,562 @@ +{ + "ids": [ + "asia/hebron" + ], + "tzif": { + "posix": { + "abbr": "EET", + "offset": 7200, + "transition": { + "abbr": "EEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 4, + 6 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 4, + 6 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2185410023, + -933638400, + -923097600, + -919036800, + -857347200, + -844300800, + -825811200, + -812678400, + -794188800, + -779846400, + -762652800, + -748310400, + -731116800, + -399088800, + -386650800, + -368330400, + -355114800, + -336790800, + -323654400, + -305168400, + -292032000, + -273632400, + -260496000, + -242096400, + -228960000, + -210560400, + -197424000, + -178938000, + -165801600, + -147402000, + -134265600, + -115866000, + -102643200, + -84330000, + -81313200, + 142380000, + 150843600, + 167176800, + 178664400, + 334101600, + 337730400, + 452642400, + 462319200, + 482277600, + 494370000, + 516751200, + 526424400, + 545436000, + 558478800, + 576626400, + 589323600, + 609890400, + 620773200, + 638316000, + 651618000, + 669765600, + 683672400, + 701820000, + 715726800, + 733701600, + 747176400, + 765151200, + 778021200, + 796600800, + 810075600, + 820447200, + 828655200, + 843170400, + 860104800, + 874620000, + 891554400, + 906069600, + 924213600, + 939934800, + 956268000, + 971989200, + 987717600, + 1003438800, + 1019167200, + 1034888400, + 1050616800, + 1066338000, + 1082066400, + 1096581600, + 1113516000, + 1128380400, + 1143842400, + 1158872400, + 1175378400, + 1189638000, + 1206655200, + 1220216400, + 1238104800, + 1252015200, + 1269554400, + 1281474000, + 1301608860, + 1312146000, + 1314655200, + 1317330000, + 1333058400, + 1348178400, + 1364508000, + 1380229200, + 1395957600, + 1414098000, + 1427493600, + 1445551200, + 1458946800, + 1477692000, + 1490396400, + 1509141600, + 1521846000, + 1540591200, + 1553810400, + 1572037200, + 1585346400, + 1603490400, + 1616796000, + 1635458400, + 1648332000, + 1666998000, + 1682726400, + 1698447600, + 1713571200, + 1729897200, + 1744416000, + 1761346800, + 1774656000, + 1792796400, + 1806105600, + 1824850800, + 1837555200, + 1856300400, + 1869004800, + 1887750000, + 1901059200, + 1919199600, + 1932508800, + 1950649200, + 1963958400, + 1982703600, + 1995408000, + 2014153200, + 2026857600, + 2045602800, + 2058307200, + 2077052400, + 2090361600, + 2107897200, + 2121811200, + 2138742000, + 2153260800, + 2168982000, + 2184710400, + 2199826800, + 2216160000, + 2230066800, + 2234304000, + 2234905200, + 2248214400, + 2260911600, + 2264544000, + 2266354800, + 2279664000, + 2291756400, + 2295388800, + 2297804400, + 2311113600, + 2321996400, + 2326233600, + 2329254000, + 2342563200, + 2352841200, + 2356473600, + 2361308400, + 2374012800, + 2383686000, + 2387318400, + 2392758000, + 2405462400, + 2413926000, + 2418163200, + 2424207600, + 2437516800, + 2444770800, + 2448403200, + 2455657200, + 2468966400, + 2475010800, + 2479248000, + 2487106800, + 2500416000, + 2505855600, + 2509488000, + 2519161200, + 2531865600, + 2536700400, + 2540332800, + 2550610800, + 2563315200, + 2566940400, + 2571177600, + 2582060400, + 2595369600, + 2597785200, + 2601417600, + 2613510000, + 2626819200, + 2628025200, + 2632262400, + 2644959600, + 2658268800, + 2658870000, + 2663107200, + 2676409200, + 2693347200, + 2708463600, + 2724192000, + 2739913200, + 2754432000, + 2771362800, + 2785276800, + 2802812400, + 2816121600, + 2834262000, + 2847571200, + 2866316400, + 2879020800, + 2897766000, + 2910470400, + 2929215600, + 2941920000, + 2960665200, + 2973974400, + 2992114800, + 3005424000, + 3023564400, + 3036873600, + 3055618800, + 3068323200, + 3087068400, + 3099772800, + 3117913200, + 3131827200, + 3148758000, + 3163276800, + 3179602800, + 3194726400, + 3209842800, + 3226176000, + 3240687600, + 3244320000, + 3244921200 + ], + "types": [ + { + "offset": 8423 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cbf2a88472b0862a-de6f37d8951e33ce.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cbf2a88472b0862a-de6f37d8951e33ce.json new file mode 100644 index 00000000000000..b4485aa08df243 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cbf2a88472b0862a-de6f37d8951e33ce.json @@ -0,0 +1,128 @@ +{ + "ids": [ + "asia/choibalsan", + "asia/ulaanbaatar", + "asia/ulan_bator" + ], + "tzif": { + "posix": { + "abbr": "+08", + "offset": 28800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2 + ], + "transitions": [ + -2032931252, + 252435600, + 417974400, + 433782000, + 449596800, + 465318000, + 481046400, + 496767600, + 512496000, + 528217200, + 543945600, + 559666800, + 575395200, + 591116400, + 606844800, + 622566000, + 638294400, + 654620400, + 670348800, + 686070000, + 701798400, + 717519600, + 733248000, + 748969200, + 764697600, + 780418800, + 796147200, + 811868400, + 828201600, + 843922800, + 859651200, + 875372400, + 891100800, + 906822000, + 988394400, + 1001696400, + 1017424800, + 1033146000, + 1048874400, + 1064595600, + 1080324000, + 1096045200, + 1111773600, + 1127494800, + 1143223200, + 1159549200, + 1427479200, + 1443193200 + ], + "types": [ + { + "offset": 25652 + }, + { + "offset": 25200 + }, + { + "offset": 28800 + }, + { + "offset": 32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cd29e561a284f373-1b38f7643a89adc3.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cd29e561a284f373-1b38f7643a89adc3.json new file mode 100644 index 00000000000000..ebe9fbb9825922 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cd29e561a284f373-1b38f7643a89adc3.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt-2" + ], + "tzif": { + "posix": { + "abbr": "+02", + "offset": 7200, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ce5eb7cf8993261f-bdd600c9c7fb16d5.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ce5eb7cf8993261f-bdd600c9c7fb16d5.json new file mode 100644 index 00000000000000..77e74376c00a3a --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ce5eb7cf8993261f-bdd600c9c7fb16d5.json @@ -0,0 +1,198 @@ +{ + "ids": [ + "europe/riga" + ], + "tzif": { + "posix": { + "abbr": "EET", + "offset": 7200, + "transition": { + "abbr": "EEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 14400 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 0, + 1, + 0, + 1, + 0, + 2, + 3, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 5, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4 + ], + "transitions": [ + -2840146594, + -1632008194, + -1618702594, + -1601681794, + -1597275394, + -1377308194, + -928029600, + -899521200, + -857257200, + -844556400, + -828226800, + -812502000, + -796777200, + -795834000, + 354920400, + 370728000, + 386456400, + 402264000, + 417992400, + 433800000, + 449614800, + 465346800, + 481071600, + 496796400, + 512521200, + 528246000, + 543970800, + 559695600, + 575420400, + 591145200, + 606870000, + 622598400, + 638323200, + 654652800, + 670377600, + 686102400, + 701827200, + 717552000, + 733276800, + 749001600, + 764726400, + 780451200, + 796176000, + 811900800, + 828230400, + 843955200, + 859683600, + 877827600, + 891133200, + 909277200, + 922582800, + 941331600 + ], + "types": [ + { + "offset": 5794 + }, + { + "offset": 9394 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 7200 + }, + { + "offset": 3600 + }, + { + "offset": 14400 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ce802c28d3beb1b-5157362aadd9dd29.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ce802c28d3beb1b-5157362aadd9dd29.json new file mode 100644 index 00000000000000..baf1c8b2a1746e --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ce802c28d3beb1b-5157362aadd9dd29.json @@ -0,0 +1,388 @@ +{ + "ids": [ + "america/santiago", + "chile/continental" + ], + "tzif": { + "posix": { + "abbr": "-04", + "offset": -14400, + "transition": { + "abbr": "-03", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 4, + 1, + 0 + ] + }, + "time": 0 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 9, + 1, + 0 + ] + }, + "time": 0 + } + } + }, + "transition_types": [ + 0, + 1, + 0, + 2, + 0, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 4, + 2, + 3, + 1, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4 + ], + "transitions": [ + -2524504635, + -1892661435, + -1688410800, + -1619205435, + -1593806400, + -1335986235, + -1335985200, + -1317585600, + -1304362800, + -1286049600, + -1272826800, + -1254513600, + -1241290800, + -1222977600, + -1209754800, + -1191355200, + -1178132400, + -870552000, + -865278000, + -740520000, + -736635600, + -718056000, + -713649600, + -36619200, + -23922000, + -3355200, + 7527600, + 24465600, + 37767600, + 55915200, + 69217200, + 87969600, + 100666800, + 118209600, + 132116400, + 150868800, + 163566000, + 182318400, + 195620400, + 213768000, + 227070000, + 245217600, + 258519600, + 277272000, + 289969200, + 308721600, + 321418800, + 340171200, + 353473200, + 371620800, + 384922800, + 403070400, + 416372400, + 434520000, + 447822000, + 466574400, + 479271600, + 498024000, + 510721200, + 529473600, + 545194800, + 560923200, + 574225200, + 592372800, + 605674800, + 624427200, + 637124400, + 653457600, + 668574000, + 687326400, + 700628400, + 718776000, + 732078000, + 750225600, + 763527600, + 781675200, + 794977200, + 813729600, + 826426800, + 845179200, + 859690800, + 876628800, + 889930800, + 906868800, + 923194800, + 939528000, + 952830000, + 971582400, + 984279600, + 1003032000, + 1015729200, + 1034481600, + 1047178800, + 1065931200, + 1079233200, + 1097380800, + 1110682800, + 1128830400, + 1142132400, + 1160884800, + 1173582000, + 1192334400, + 1206846000, + 1223784000, + 1237086000, + 1255233600, + 1270350000, + 1286683200, + 1304823600, + 1313899200, + 1335668400, + 1346558400, + 1367118000, + 1378612800, + 1398567600, + 1410062400, + 1463281200, + 1471147200, + 1494730800, + 1502596800, + 1526180400, + 1534046400, + 1554606000, + 1567915200, + 1586055600, + 1599364800, + 1617505200, + 1630814400, + 1648954800, + 1662868800, + 1680404400, + 1693713600 + ], + "types": [ + { + "offset": -16965 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cec2538008230fcd-486e4621268a0834.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cec2538008230fcd-486e4621268a0834.json new file mode 100644 index 00000000000000..fa7637e5e7d946 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-cec2538008230fcd-486e4621268a0834.json @@ -0,0 +1,214 @@ +{ + "ids": [ + "america/grand_turk" + ], + "tzif": { + "posix": { + "abbr": "EST", + "offset": -18000, + "transition": { + "abbr": "EDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 3, + 4 + ], + "transitions": [ + -2524504528, + -1827687170, + 294217200, + 309938400, + 325666800, + 341388000, + 357116400, + 372837600, + 388566000, + 404892000, + 420015600, + 436341600, + 452070000, + 467791200, + 483519600, + 499240800, + 514969200, + 530690400, + 544604400, + 562140000, + 576054000, + 594194400, + 607503600, + 625644000, + 638953200, + 657093600, + 671007600, + 688543200, + 702457200, + 719992800, + 733906800, + 752047200, + 765356400, + 783496800, + 796806000, + 814946400, + 828860400, + 846396000, + 860310000, + 877845600, + 891759600, + 909295200, + 923209200, + 941349600, + 954658800, + 972799200, + 986108400, + 1004248800, + 1018162800, + 1035698400, + 1049612400, + 1067148000, + 1081062000, + 1099202400, + 1112511600, + 1130652000, + 1143961200, + 1162101600, + 1173596400, + 1194156000, + 1205046000, + 1225605600, + 1236495600, + 1257055200, + 1268550000, + 1289109600, + 1299999600, + 1320559200, + 1331449200, + 1352008800, + 1362898800, + 1383458400, + 1394348400, + 1414908000, + 1425798000, + 1520751600 + ], + "types": [ + { + "offset": -17072 + }, + { + "offset": -18430 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d1e4208290566f2f-8b7418c65c288188.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d1e4208290566f2f-8b7418c65c288188.json new file mode 100644 index 00000000000000..8247bc06e46d45 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d1e4208290566f2f-8b7418c65c288188.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt+4" + ], + "tzif": { + "posix": { + "abbr": "-04", + "offset": -14400, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d28e0bb7485a8522-9d5ad01d4999d0c7.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d28e0bb7485a8522-9d5ad01d4999d0c7.json new file mode 100644 index 00000000000000..859b8dc2665dbb --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d28e0bb7485a8522-9d5ad01d4999d0c7.json @@ -0,0 +1,274 @@ +{ + "ids": [ + "america/havana", + "cuba" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -18000, + "transition": { + "abbr": "CDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 0 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 3600 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2 + ], + "transitions": [ + -2524501832, + -1402813824, + -1311534000, + -1300996800, + -933534000, + -925675200, + -902084400, + -893620800, + -870030000, + -862171200, + -775681200, + -767822400, + -744231600, + -736372800, + -144702000, + -134251200, + -113425200, + -102542400, + -86295600, + -72907200, + -54154800, + -41457600, + -21495600, + -5774400, + 9954000, + 25675200, + 41403600, + 57729600, + 73458000, + 87364800, + 104907600, + 118900800, + 136357200, + 150436800, + 167806800, + 183528000, + 199256400, + 215582400, + 230706000, + 247032000, + 263365200, + 276667200, + 290581200, + 308721600, + 322030800, + 340171200, + 358318800, + 371620800, + 389768400, + 403070400, + 421218000, + 434520000, + 452667600, + 466574400, + 484117200, + 498024000, + 511333200, + 529473600, + 542782800, + 560923200, + 574837200, + 592372800, + 606286800, + 623822400, + 638946000, + 655876800, + 671000400, + 687330000, + 702450000, + 718779600, + 733899600, + 750229200, + 765349200, + 781678800, + 796798800, + 813128400, + 828853200, + 844578000, + 860302800, + 876632400, + 891147600, + 909291600, + 922597200, + 941346000, + 954651600, + 972795600, + 986101200, + 1004245200, + 1018155600, + 1035694800, + 1049605200, + 1067144400, + 1080450000, + 1162098000, + 1173589200, + 1193547600, + 1205643600, + 1224997200, + 1236488400, + 1256446800, + 1268542800, + 1288501200, + 1300597200, + 1321160400, + 1333256400, + 1352005200, + 1362891600, + 1383454800 + ], + "types": [ + { + "offset": -19768 + }, + { + "offset": -19776 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d3201ec4e70c92f3-5814e30a4cc908b9.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d3201ec4e70c92f3-5814e30a4cc908b9.json new file mode 100644 index 00000000000000..83693cfce9a908 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d3201ec4e70c92f3-5814e30a4cc908b9.json @@ -0,0 +1,203 @@ +{ + "ids": [ + "asia/khandyga" + ], + "tzif": { + "posix": { + "abbr": "+09", + "offset": 32400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 5, + 6, + 3, + 5, + 6, + 3, + 5, + 6, + 3, + 5, + 6, + 3, + 5, + 6, + 3, + 5, + 6, + 3, + 5, + 6, + 3, + 5, + 6, + 7, + 3, + 5, + 2, + 4 + ], + "transitions": [ + -1579424533, + -1247558400, + 354898800, + 370706400, + 386434800, + 402242400, + 417970800, + 433778400, + 449593200, + 465325200, + 481050000, + 496774800, + 512499600, + 528224400, + 543949200, + 559674000, + 575398800, + 591123600, + 606848400, + 622573200, + 638298000, + 654627600, + 670352400, + 670356000, + 686080800, + 695757600, + 701802000, + 717526800, + 733251600, + 748976400, + 764701200, + 780426000, + 796150800, + 811875600, + 828205200, + 846349200, + 859654800, + 877798800, + 891104400, + 909248400, + 922554000, + 941302800, + 954003600, + 972752400, + 985453200, + 1004202000, + 1017507600, + 1035651600, + 1048957200, + 1067101200, + 1072882800, + 1080403200, + 1099152000, + 1111852800, + 1130601600, + 1143302400, + 1162051200, + 1174752000, + 1193500800, + 1206806400, + 1224950400, + 1238256000, + 1256400000, + 1269705600, + 1288454400, + 1301155200, + 1315832400, + 1414252800 + ], + "types": [ + { + "offset": 32533 + }, + { + "offset": 28800 + }, + { + "offset": 32400 + }, + { + "offset": 36000 + }, + { + "offset": 32400 + }, + { + "offset": 36000 + }, + { + "offset": 39600 + }, + { + "offset": 39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d41aa71f743154ff-cd47b010d657ac37.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d41aa71f743154ff-cd47b010d657ac37.json new file mode 100644 index 00000000000000..a59edb7a3e41a1 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d41aa71f743154ff-cd47b010d657ac37.json @@ -0,0 +1,223 @@ +{ + "ids": [ + "asia/anadyr" + ], + "tzif": { + "posix": { + "abbr": "+12", + "offset": 43200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 1, + 5, + 1, + 5, + 6, + 2, + 4, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 6, + 1, + 5, + 6, + 1, + 5 + ], + "transitions": [ + -1441194596, + -1247572800, + 354884400, + 370692000, + 386420400, + 386424000, + 402231600, + 417960000, + 433767600, + 449582400, + 465314400, + 481039200, + 496764000, + 512488800, + 528213600, + 543938400, + 559663200, + 575388000, + 591112800, + 606837600, + 622562400, + 638287200, + 654616800, + 670341600, + 670345200, + 686070000, + 695746800, + 701791200, + 717516000, + 733240800, + 748965600, + 764690400, + 780415200, + 796140000, + 811864800, + 828194400, + 846338400, + 859644000, + 877788000, + 891093600, + 909237600, + 922543200, + 941292000, + 953992800, + 972741600, + 985442400, + 1004191200, + 1017496800, + 1035640800, + 1048946400, + 1067090400, + 1080396000, + 1099144800, + 1111845600, + 1130594400, + 1143295200, + 1162044000, + 1174744800, + 1193493600, + 1206799200, + 1224943200, + 1238248800, + 1256392800, + 1269698400, + 1269702000, + 1288450800, + 1301151600 + ], + "types": [ + { + "offset": 42596 + }, + { + "offset": 43200 + }, + { + "offset": 46800 + }, + { + "offset": 50400 + }, + { + "offset": 46800 + }, + { + "offset": 43200 + }, + { + "offset": 39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d4999f54d6ffa1ff-bdc2dfc5a5de1f94.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d4999f54d6ffa1ff-bdc2dfc5a5de1f94.json new file mode 100644 index 00000000000000..d4108f93d6367e --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d4999f54d6ffa1ff-bdc2dfc5a5de1f94.json @@ -0,0 +1,260 @@ +{ + "ids": [ + "america/anchorage", + "us/alaska" + ], + "tzif": { + "posix": { + "abbr": "AKST", + "offset": -32400, + "transition": { + "abbr": "AKDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 3, + 2, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 3, + 4, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4 + ], + "transitions": [ + -3225223727, + -2188951224, + -880200000, + -769395600, + -765378000, + -86882400, + -21470400, + -5749200, + 9979200, + 25700400, + 41428800, + 57754800, + 73483200, + 89204400, + 104932800, + 120654000, + 126705600, + 152103600, + 162388800, + 183553200, + 199281600, + 215607600, + 230731200, + 247057200, + 262785600, + 278506800, + 294235200, + 309956400, + 325684800, + 341406000, + 357134400, + 372855600, + 388584000, + 404910000, + 420033600, + 436359600, + 439030800, + 452084400, + 467805600, + 483534000, + 499255200, + 514983600, + 530704800, + 544618800, + 562154400, + 576068400, + 594208800, + 607518000, + 625658400, + 638967600, + 657108000, + 671022000, + 688557600, + 702471600, + 720007200, + 733921200, + 752061600, + 765370800, + 783511200, + 796820400, + 814960800, + 828874800, + 846410400, + 860324400, + 877860000, + 891774000, + 909309600, + 923223600, + 941364000, + 954673200, + 972813600, + 986122800, + 1004263200, + 1018177200, + 1035712800, + 1049626800, + 1067162400, + 1081076400, + 1099216800, + 1112526000, + 1130666400, + 1143975600, + 1162116000, + 1173610800, + 1194170400 + ], + "types": [ + { + "offset": 50424 + }, + { + "offset": -35976 + }, + { + "offset": -36000 + }, + { + "offset": -32400 + }, + { + "offset": -32400 + }, + { + "offset": -28800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d7daa3dddb990290-2188fa690fb895b7.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d7daa3dddb990290-2188fa690fb895b7.json new file mode 100644 index 00000000000000..170d93d61ce040 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-d7daa3dddb990290-2188fa690fb895b7.json @@ -0,0 +1,243 @@ +{ + "ids": [ + "europe/simferopol" + ], + "tzif": { + "posix": { + "abbr": "MSK", + "offset": 10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 4, + 5, + 2, + 4, + 5, + 2, + 4, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 6, + 3, + 7, + 6, + 3, + 7, + 6, + 3, + 7, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 3, + 7, + 2, + 4, + 6, + 8, + 3, + 7 + ], + "transitions": [ + -2840148984, + -1441160160, + -1247536800, + -888894000, + -857257200, + -844556400, + -828226800, + -812502000, + -811648800, + 354920400, + 370728000, + 386456400, + 402264000, + 417992400, + 433800000, + 449614800, + 465346800, + 481071600, + 496796400, + 512521200, + 528246000, + 543970800, + 559695600, + 575420400, + 591145200, + 606870000, + 622594800, + 646786800, + 701042400, + 717552000, + 733276800, + 749001600, + 764726400, + 767739600, + 780447600, + 796172400, + 811897200, + 828219600, + 846374400, + 859683600, + 877827600, + 891133200, + 909277200, + 922582800, + 941331600, + 954032400, + 972781200, + 985482000, + 1004230800, + 1017536400, + 1035680400, + 1048986000, + 1067130000, + 1080435600, + 1099184400, + 1111885200, + 1130634000, + 1143334800, + 1162083600, + 1174784400, + 1193533200, + 1206838800, + 1224982800, + 1238288400, + 1256432400, + 1269738000, + 1288486800, + 1301187600, + 1319936400, + 1332637200, + 1351386000, + 1364691600, + 1382835600, + 1396137600, + 1414274400 + ], + "types": [ + { + "offset": 8184 + }, + { + "offset": 8160 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 7200 + }, + { + "offset": 3600 + }, + { + "offset": 14400 + }, + { + "offset": 10800 + }, + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-daeed2898ecd770c-894d1d81ca85ba4d.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-daeed2898ecd770c-894d1d81ca85ba4d.json new file mode 100644 index 00000000000000..a39e96bdd4b78d --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-daeed2898ecd770c-894d1d81ca85ba4d.json @@ -0,0 +1,324 @@ +{ + "ids": [ + "chile/easterisland", + "pacific/easter" + ], + "tzif": { + "posix": { + "abbr": "-06", + "offset": -21600, + "transition": { + "abbr": "-05", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 4, + 1, + 0 + ] + }, + "time": -7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 9, + 1, + 0 + ] + }, + "time": -7200 + } + } + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4 + ], + "transitions": [ + -2524495352, + -1178124152, + -36619200, + -23922000, + -3355200, + 7527600, + 24465600, + 37767600, + 55915200, + 69217200, + 87969600, + 100666800, + 118209600, + 132116400, + 150868800, + 163566000, + 182318400, + 195620400, + 213768000, + 227070000, + 245217600, + 258519600, + 277272000, + 289969200, + 308721600, + 321418800, + 340171200, + 353473200, + 371620800, + 384922800, + 403070400, + 416372400, + 434520000, + 447822000, + 466574400, + 479271600, + 498024000, + 510721200, + 529473600, + 545194800, + 560923200, + 574225200, + 592372800, + 605674800, + 624427200, + 637124400, + 653457600, + 668574000, + 687326400, + 700628400, + 718776000, + 732078000, + 750225600, + 763527600, + 781675200, + 794977200, + 813729600, + 826426800, + 845179200, + 859690800, + 876628800, + 889930800, + 906868800, + 923194800, + 939528000, + 952830000, + 971582400, + 984279600, + 1003032000, + 1015729200, + 1034481600, + 1047178800, + 1065931200, + 1079233200, + 1097380800, + 1110682800, + 1128830400, + 1142132400, + 1160884800, + 1173582000, + 1192334400, + 1206846000, + 1223784000, + 1237086000, + 1255233600, + 1270350000, + 1286683200, + 1304823600, + 1313899200, + 1335668400, + 1346558400, + 1367118000, + 1378612800, + 1398567600, + 1410062400, + 1463281200, + 1471147200, + 1494730800, + 1502596800, + 1526180400, + 1534046400, + 1554606000, + 1567915200, + 1586055600, + 1599364800, + 1617505200, + 1630814400, + 1648954800, + 1662868800, + 1680404400, + 1693713600 + ], + "types": [ + { + "offset": -26248 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dbf1c543882cf4b7-2ee5fc1eb7933ea5.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dbf1c543882cf4b7-2ee5fc1eb7933ea5.json new file mode 100644 index 00000000000000..b23e96d09caf46 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dbf1c543882cf4b7-2ee5fc1eb7933ea5.json @@ -0,0 +1,222 @@ +{ + "ids": [ + "europe/ulyanovsk" + ], + "tzif": { + "posix": { + "abbr": "+04", + "offset": 14400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 2, + 4, + 1, + 1, + 5, + 1, + 5, + 6, + 2, + 4, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4, + 1, + 5, + 2, + 4 + ], + "transitions": [ + -1593820800, + -1247540400, + 354916800, + 370724400, + 386452800, + 402260400, + 417988800, + 433796400, + 449611200, + 465343200, + 481068000, + 496792800, + 512517600, + 528242400, + 543967200, + 559692000, + 575416800, + 591141600, + 606866400, + 606870000, + 622594800, + 638319600, + 654649200, + 670374000, + 670377600, + 686102400, + 695779200, + 701823600, + 717548400, + 733273200, + 748998000, + 764722800, + 780447600, + 796172400, + 811897200, + 828226800, + 846370800, + 859676400, + 877820400, + 891126000, + 909270000, + 922575600, + 941324400, + 954025200, + 972774000, + 985474800, + 1004223600, + 1017529200, + 1035673200, + 1048978800, + 1067122800, + 1080428400, + 1099177200, + 1111878000, + 1130626800, + 1143327600, + 1162076400, + 1174777200, + 1193526000, + 1206831600, + 1224975600, + 1238281200, + 1256425200, + 1269730800, + 1288479600, + 1301180400, + 1414274400, + 1459033200 + ], + "types": [ + { + "offset": 11616 + }, + { + "offset": 10800 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + }, + { + "offset": 14400 + }, + { + "offset": 10800 + }, + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dc6b1be48367c4f1-5f1fbe94f0718a6a.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dc6b1be48367c4f1-5f1fbe94f0718a6a.json new file mode 100644 index 00000000000000..999a3c83fe93b9 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dc6b1be48367c4f1-5f1fbe94f0718a6a.json @@ -0,0 +1,256 @@ +{ + "ids": [ + "europe/kaliningrad" + ], + "tzif": { + "posix": { + "abbr": "EET", + "offset": 7200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 3, + 4, + 2, + 3, + 4, + 5, + 6, + 4, + 5, + 6, + 4, + 5, + 6, + 4, + 5, + 6, + 4, + 5, + 6, + 4, + 5, + 6, + 4, + 5, + 6, + 4, + 5, + 6, + 4, + 5, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 2, + 3 + ], + "transitions": [ + -2422056120, + -1693706400, + -1680483600, + -1663455600, + -1650150000, + -1632006000, + -1618700400, + -938905200, + -857257200, + -844556400, + -828226800, + -812502000, + -796777200, + -781052400, + -780372000, + -778730400, + -762663600, + -749095200, + 354920400, + 370728000, + 386456400, + 402264000, + 417992400, + 433800000, + 449614800, + 465346800, + 481071600, + 496796400, + 512521200, + 528246000, + 543970800, + 559695600, + 575420400, + 591145200, + 606870000, + 622598400, + 638323200, + 654652800, + 670377600, + 686102400, + 701827200, + 717552000, + 733276800, + 749001600, + 764726400, + 780451200, + 796176000, + 811900800, + 828230400, + 846374400, + 859680000, + 877824000, + 891129600, + 909273600, + 922579200, + 941328000, + 954028800, + 972777600, + 985478400, + 1004227200, + 1017532800, + 1035676800, + 1048982400, + 1067126400, + 1080432000, + 1099180800, + 1111881600, + 1130630400, + 1143331200, + 1162080000, + 1174780800, + 1193529600, + 1206835200, + 1224979200, + 1238284800, + 1256428800, + 1269734400, + 1288483200, + 1301184000, + 1414278000 + ], + "types": [ + { + "offset": 4920 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 10800 + }, + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dc8c7c76ac036db-6dcebe24fb293843.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dc8c7c76ac036db-6dcebe24fb293843.json new file mode 100644 index 00000000000000..938753d8cad4ad --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dc8c7c76ac036db-6dcebe24fb293843.json @@ -0,0 +1,37 @@ +{ + "ids": [ + "indian/mauritius" + ], + "tzif": { + "posix": { + "abbr": "+04", + "offset": 14400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1988164200, + 403041600, + 417034800, + 1224972000, + 1238274000 + ], + "types": [ + { + "offset": 13800 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dc8ea6d022a7ebec-7bdcff969a6b651c.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dc8ea6d022a7ebec-7bdcff969a6b651c.json new file mode 100644 index 00000000000000..cab20d7b9d07f6 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dc8ea6d022a7ebec-7bdcff969a6b651c.json @@ -0,0 +1,202 @@ +{ + "ids": [ + "america/sao_paulo", + "brazil/east" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2 + ], + "transitions": [ + -1767214412, + -1206957600, + -1191362400, + -1175374800, + -1159826400, + -633819600, + -622069200, + -602283600, + -591832800, + -570747600, + -560210400, + -539125200, + -531352800, + -195426000, + -189381600, + -184197600, + -155163600, + -150069600, + -128898000, + -121125600, + -99954000, + -89589600, + -68418000, + -57967200, + 499748400, + 511236000, + 530593200, + 540266400, + 562129200, + 571197600, + 592974000, + 602042400, + 624423600, + 634701600, + 656478000, + 666756000, + 687927600, + 697600800, + 719982000, + 728445600, + 750826800, + 761709600, + 782276400, + 793159200, + 813726000, + 824004000, + 844570800, + 856058400, + 876106800, + 888717600, + 908074800, + 919562400, + 938919600, + 951616800, + 970974000, + 982461600, + 1003028400, + 1013911200, + 1036292400, + 1045360800, + 1066532400, + 1076810400, + 1099364400, + 1108864800, + 1129431600, + 1140314400, + 1162695600, + 1172368800, + 1192330800, + 1203213600, + 1224385200, + 1234663200, + 1255834800, + 1266717600, + 1287284400, + 1298167200, + 1318734000, + 1330221600, + 1350788400, + 1361066400, + 1382238000, + 1392516000, + 1413687600, + 1424570400, + 1445137200, + 1456020000, + 1476586800 + ], + "types": [ + { + "offset": -11188 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dd90c0bd2a5d5bcb-4e3fcc5e29cf94e2.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dd90c0bd2a5d5bcb-4e3fcc5e29cf94e2.json new file mode 100644 index 00000000000000..ded8f6d0cf89db --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dd90c0bd2a5d5bcb-4e3fcc5e29cf94e2.json @@ -0,0 +1,38 @@ +{ + "ids": [ + "america/guayaquil" + ], + "tzif": { + "posix": { + "abbr": "-05", + "offset": -18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2 + ], + "transitions": [ + -2524502440, + -1230749160, + 722926800, + 728884800 + ], + "types": [ + { + "offset": -19160 + }, + { + "offset": -18840 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-df3a174a6f1304b9-f30768cdd2518dd1.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-df3a174a6f1304b9-f30768cdd2518dd1.json new file mode 100644 index 00000000000000..4688e68e5f6af0 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-df3a174a6f1304b9-f30768cdd2518dd1.json @@ -0,0 +1,114 @@ +{ + "ids": [ + "africa/algiers" + ], + "tzif": { + "posix": { + "abbr": "CET", + "offset": 3600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 3, + 4, + 5, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4 + ], + "transitions": [ + -2486592732, + -1855958961, + -1689814800, + -1680397200, + -1665363600, + -1648342800, + -1635123600, + -1616893200, + -1604278800, + -1585443600, + -1574038800, + -1552266000, + -1539997200, + -1531443600, + -956365200, + -950486400, + -942012000, + -812502000, + -796262400, + -781052400, + -766630800, + -733280400, + -439430400, + -212029200, + 41468400, + 54774000, + 231724800, + 246236400, + 259545600, + 275274000, + 309740400, + 325468800, + 341802000, + 357523200 + ], + "types": [ + { + "offset": 732 + }, + { + "offset": 561 + }, + { + "offset": 0 + }, + { + "offset": 3600 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dfcaab41c352fc41-836527ef6425759.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dfcaab41c352fc41-836527ef6425759.json new file mode 100644 index 00000000000000..b0c800cc304afa --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-dfcaab41c352fc41-836527ef6425759.json @@ -0,0 +1,26 @@ +{ + "ids": [ + "antarctica/rothera" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1 + ], + "transitions": [ + 218246400 + ], + "types": [ + { + "offset": 0 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e12ae166d8468131-ee348999c2fd8345.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e12ae166d8468131-ee348999c2fd8345.json new file mode 100644 index 00000000000000..eba53856df5a27 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e12ae166d8468131-ee348999c2fd8345.json @@ -0,0 +1,93 @@ +{ + "ids": [ + "america/boa_vista" + ], + "tzif": { + "posix": { + "abbr": "-04", + "offset": -14400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1767211040, + -1206954000, + -1191358800, + -1175371200, + -1159822800, + -633816000, + -622065600, + -602280000, + -591829200, + -570744000, + -560206800, + -539121600, + -531349200, + -191361600, + -184194000, + -155160000, + -150066000, + -128894400, + -121122000, + -99950400, + -89586000, + -68414400, + -57963600, + 499752000, + 511239600, + 530596800, + 540270000, + 562132800, + 571201200, + 938923200, + 951620400, + 970977600, + 971578800 + ], + "types": [ + { + "offset": -14560 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e20ebf54a807fe0e-10ef646904348bbe.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e20ebf54a807fe0e-10ef646904348bbe.json new file mode 100644 index 00000000000000..a176b12a77685d --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e20ebf54a807fe0e-10ef646904348bbe.json @@ -0,0 +1,35 @@ +{ + "ids": [ + "america/bogota" + ], + "tzif": { + "posix": { + "abbr": "-05", + "offset": -18000, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 1 + ], + "transitions": [ + -2707671824, + -1739041424, + 704869200, + 729057600 + ], + "types": [ + { + "offset": -17776 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e271b0f2662b1c04-20e8607792da4ec7.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e271b0f2662b1c04-20e8607792da4ec7.json new file mode 100644 index 00000000000000..ea81dbe0122400 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e271b0f2662b1c04-20e8607792da4ec7.json @@ -0,0 +1,52 @@ +{ + "ids": [ + "asia/jakarta" + ], + "tzif": { + "posix": { + "abbr": "WIB", + "offset": 25200, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 3, + 2, + 4, + 2, + 5 + ], + "transitions": [ + -3231299232, + -1451719200, + -1172906400, + -876641400, + -766054800, + -683883000, + -620812800, + -189415800 + ], + "types": [ + { + "offset": 25632 + }, + { + "offset": 26400 + }, + { + "offset": 27000 + }, + { + "offset": 32400 + }, + { + "offset": 28800 + }, + { + "offset": 25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e2789756bce07cca-d7ab71c2384db975.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e2789756bce07cca-d7ab71c2384db975.json new file mode 100644 index 00000000000000..6a5202f7b9c4c3 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e2789756bce07cca-d7ab71c2384db975.json @@ -0,0 +1,175 @@ +{ + "ids": [ + "australia/lhi", + "australia/lord_howe" + ], + "tzif": { + "posix": { + "abbr": "+1030", + "offset": 37800, + "transition": { + "abbr": "+11", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 4, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 1800, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 1, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4 + ], + "transitions": [ + -2364114980, + 352216800, + 372785400, + 384273000, + 404839800, + 415722600, + 436289400, + 447172200, + 467739000, + 478621800, + 499188600, + 511282800, + 530033400, + 542732400, + 562087800, + 574786800, + 594142200, + 606236400, + 625591800, + 636476400, + 657041400, + 667926000, + 688491000, + 699375600, + 719940600, + 731430000, + 751995000, + 762879600, + 783444600, + 794329200, + 814894200, + 828198000, + 846343800, + 859647600, + 877793400, + 891097200, + 909243000, + 922546800, + 941297400, + 953996400, + 967303800, + 985446000, + 1004196600, + 1017500400, + 1035646200, + 1048950000, + 1067095800, + 1080399600, + 1099150200, + 1111849200, + 1130599800, + 1143903600, + 1162049400, + 1174748400, + 1193499000, + 1207407600, + 1223134200 + ], + "types": [ + { + "offset": 38180 + }, + { + "offset": 36000 + }, + { + "offset": 37800 + }, + { + "offset": 41400 + }, + { + "offset": 39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e2bf7ec87041f1fb-b61a215ea3b5adb3.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e2bf7ec87041f1fb-b61a215ea3b5adb3.json new file mode 100644 index 00000000000000..be544df5635a80 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e2bf7ec87041f1fb-b61a215ea3b5adb3.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt+12" + ], + "tzif": { + "posix": { + "abbr": "-12", + "offset": -43200, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": -43200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e330917831501a06-5b1f8ec8b0ab9c4a.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e330917831501a06-5b1f8ec8b0ab9c4a.json new file mode 100644 index 00000000000000..c4d864646d1ea2 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e330917831501a06-5b1f8ec8b0ab9c4a.json @@ -0,0 +1,57 @@ +{ + "ids": [ + "antarctica/troll" + ], + "tzif": { + "posix": { + "abbr": "+00", + "offset": 0, + "transition": { + "abbr": "+02", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 10800 + }, + "savings": 7200, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 3600 + } + } + }, + "transition_types": [ + 0, + 1, + 0 + ], + "transitions": [ + 1108166400, + 1111885200, + 1130634000 + ], + "types": [ + { + "offset": 0 + }, + { + "offset": 7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e3d5b2baffd22f2d-4e475abbb4b8264f.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e3d5b2baffd22f2d-4e475abbb4b8264f.json new file mode 100644 index 00000000000000..9cd2533acd4b53 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e3d5b2baffd22f2d-4e475abbb4b8264f.json @@ -0,0 +1,35 @@ +{ + "ids": [ + "antarctica/vostok" + ], + "tzif": { + "posix": { + "abbr": "+05", + "offset": 18000, + "transition": null + }, + "transition_types": [ + 1, + 0, + 1, + 2 + ], + "transitions": [ + -380073600, + 760035600, + 783648000, + 1702839600 + ], + "types": [ + { + "offset": 0 + }, + { + "offset": 25200 + }, + { + "offset": 18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e4c142bca3031674-44b8ea4e236ae5f5.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e4c142bca3031674-44b8ea4e236ae5f5.json new file mode 100644 index 00000000000000..ef997b3c348b79 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e4c142bca3031674-44b8ea4e236ae5f5.json @@ -0,0 +1,70 @@ +{ + "ids": [ + "pacific/norfolk" + ], + "tzif": { + "posix": { + "abbr": "+11", + "offset": 39600, + "transition": { + "abbr": "+12", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 4, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 1, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 4 + ], + "transitions": [ + -2177493112, + -599656320, + 152029800, + 162916200, + 1443882600 + ], + "types": [ + { + "offset": 40312 + }, + { + "offset": 40320 + }, + { + "offset": 41400 + }, + { + "offset": 45000 + }, + { + "offset": 39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e5822ac52a06a527-c5e561a56943464c.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e5822ac52a06a527-c5e561a56943464c.json new file mode 100644 index 00000000000000..999618d3b0a152 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e5822ac52a06a527-c5e561a56943464c.json @@ -0,0 +1,41 @@ +{ + "ids": [ + "america/tegucigalpa" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -1538503868, + 547020000, + 559717200, + 578469600, + 591166800, + 1146981600, + 1154926800 + ], + "types": [ + { + "offset": -20932 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e65fa49c7674041-51ba19ae72a3c69.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e65fa49c7674041-51ba19ae72a3c69.json new file mode 100644 index 00000000000000..d501ee5144672b --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e65fa49c7674041-51ba19ae72a3c69.json @@ -0,0 +1,61 @@ +{ + "ids": [ + "antarctica/casey" + ], + "tzif": { + "posix": { + "abbr": "+08", + "offset": 28800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -31536000, + 1255802400, + 1267714800, + 1319738400, + 1329843600, + 1477065600, + 1520701200, + 1538856000, + 1552752000, + 1570129200, + 1583596800, + 1601740860, + 1615640400, + 1633190460, + 1647090000, + 1664640060, + 1678291200 + ], + "types": [ + { + "offset": 0 + }, + { + "offset": 28800 + }, + { + "offset": 39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e713de09d9781804-3bc1517947065469.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e713de09d9781804-3bc1517947065469.json new file mode 100644 index 00000000000000..68c377e400228b --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e713de09d9781804-3bc1517947065469.json @@ -0,0 +1,31 @@ +{ + "ids": [ + "indian/chagos" + ], + "tzif": { + "posix": { + "abbr": "+06", + "offset": 21600, + "transition": null + }, + "transition_types": [ + 1, + 2 + ], + "transitions": [ + -1988167780, + 820436400 + ], + "types": [ + { + "offset": 17380 + }, + { + "offset": 18000 + }, + { + "offset": 21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e7907c2354d7f128-1222f4f18f058093.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e7907c2354d7f128-1222f4f18f058093.json new file mode 100644 index 00000000000000..ea5a63deb89673 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e7907c2354d7f128-1222f4f18f058093.json @@ -0,0 +1,26 @@ +{ + "ids": [ + "pacific/gambier" + ], + "tzif": { + "posix": { + "abbr": "-09", + "offset": -32400, + "transition": null + }, + "transition_types": [ + 1 + ], + "transitions": [ + -1806678012 + ], + "types": [ + { + "offset": -32388 + }, + { + "offset": -32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e953d2a73bc41375-ef97956cf6178835.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e953d2a73bc41375-ef97956cf6178835.json new file mode 100644 index 00000000000000..ded235059b2071 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-e953d2a73bc41375-ef97956cf6178835.json @@ -0,0 +1,366 @@ +{ + "ids": [ + "europe/lisbon", + "portugal", + "wet" + ], + "tzif": { + "posix": { + "abbr": "WET", + "offset": 0, + "transition": { + "abbr": "WEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 3600 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 2, + 1, + 2, + 3, + 2, + 1, + 2, + 3, + 2, + 1, + 2, + 3, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 4, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 2, + 4, + 1 + ], + "transitions": [ + -1830384000, + -1689555600, + -1677801600, + -1667433600, + -1647738000, + -1635897600, + -1616202000, + -1604361600, + -1584666000, + -1572739200, + -1553043600, + -1541203200, + -1521507600, + -1442451600, + -1427677200, + -1379293200, + -1364778000, + -1348448400, + -1333328400, + -1316394000, + -1301274000, + -1284339600, + -1269824400, + -1221440400, + -1206925200, + -1191200400, + -1175475600, + -1127696400, + -1111971600, + -1096851600, + -1080522000, + -1063587600, + -1049072400, + -1033347600, + -1017622800, + -1002502800, + -986173200, + -969238800, + -950490000, + -942022800, + -922496400, + -906944400, + -891133200, + -877309200, + -873684000, + -864007200, + -857955600, + -845859600, + -842839200, + -831348000, + -825901200, + -814410000, + -810784800, + -799898400, + -794451600, + -782960400, + -779335200, + -768448800, + -763002000, + -749091600, + -733366800, + -717631200, + -701906400, + -686181600, + -670456800, + -654732000, + -639007200, + -623282400, + -607557600, + -591832800, + -575503200, + -559778400, + -544053600, + -528328800, + -512604000, + -496879200, + -481154400, + -465429600, + -449704800, + -433980000, + -417650400, + -401925600, + -386200800, + -370476000, + -354751200, + -339026400, + -323301600, + -307576800, + -291852000, + -276127200, + -260402400, + -244677600, + -228348000, + -212623200, + -196898400, + -181173600, + -165448800, + -149724000, + -133999200, + -118274400, + -102549600, + 212544000, + 243993600, + 260326800, + 276051600, + 291776400, + 307501200, + 323830800, + 338950800, + 354672000, + 370396800, + 386121600, + 401846400, + 417571200, + 433296000, + 449020800, + 465350400, + 481075200, + 496800000, + 504921600, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": -2205 + }, + { + "offset": 0 + }, + { + "offset": 3600 + }, + { + "offset": 7200 + }, + { + "offset": 3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ea8173f82f8dccac-190f07fa0585582b.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ea8173f82f8dccac-190f07fa0585582b.json new file mode 100644 index 00000000000000..9076a32b30e4d8 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ea8173f82f8dccac-190f07fa0585582b.json @@ -0,0 +1,205 @@ +{ + "ids": [ + "asia/hong_kong", + "hongkong" + ], + "tzif": { + "posix": { + "abbr": "HKT", + "offset": 28800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1 + ], + "transitions": [ + -2056690800, + -900910800, + -891579600, + -884248200, + -761209200, + -747907200, + -728541000, + -717049800, + -697091400, + -683785800, + -668061000, + -654755400, + -636611400, + -623305800, + -605161800, + -591856200, + -573712200, + -559801800, + -541657800, + -528352200, + -510211800, + -498112200, + -478762200, + -466662600, + -446707800, + -435213000, + -415258200, + -403158600, + -383808600, + -371709000, + -352359000, + -340259400, + -320909400, + -308809800, + -288855000, + -277360200, + -257405400, + -245910600, + -225955800, + -213856200, + -194506200, + -182406600, + -163056600, + -148537800, + -132816600, + -117088200, + -101367000, + -85638600, + -69312600, + -53584200, + -37863000, + -22134600, + -6413400, + 9315000, + 25036200, + 40764600, + 56485800, + 72214200, + 88540200, + 104268600, + 119989800, + 126041400, + 151439400, + 167167800, + 182889000, + 198617400, + 214338600, + 295385400, + 309292200 + ], + "types": [ + { + "offset": 27402 + }, + { + "offset": 28800 + }, + { + "offset": 32400 + }, + { + "offset": 30600 + }, + { + "offset": 32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-eafa00d1ad3ada02-ccfdff510d06498a.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-eafa00d1ad3ada02-ccfdff510d06498a.json new file mode 100644 index 00000000000000..731ecdac17311b --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-eafa00d1ad3ada02-ccfdff510d06498a.json @@ -0,0 +1,187 @@ +{ + "ids": [ + "asia/kamchatka" + ], + "tzif": { + "posix": { + "abbr": "+12", + "offset": 43200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4 + ], + "transitions": [ + -1487759676, + -1247569200, + 354888000, + 370695600, + 386424000, + 402231600, + 417960000, + 433767600, + 449582400, + 465314400, + 481039200, + 496764000, + 512488800, + 528213600, + 543938400, + 559663200, + 575388000, + 591112800, + 606837600, + 622562400, + 638287200, + 654616800, + 670341600, + 670345200, + 686070000, + 695746800, + 701791200, + 717516000, + 733240800, + 748965600, + 764690400, + 780415200, + 796140000, + 811864800, + 828194400, + 846338400, + 859644000, + 877788000, + 891093600, + 909237600, + 922543200, + 941292000, + 953992800, + 972741600, + 985442400, + 1004191200, + 1017496800, + 1035640800, + 1048946400, + 1067090400, + 1080396000, + 1099144800, + 1111845600, + 1130594400, + 1143295200, + 1162044000, + 1174744800, + 1193493600, + 1206799200, + 1224943200, + 1238248800, + 1256392800, + 1269698400, + 1269702000, + 1288450800, + 1301151600 + ], + "types": [ + { + "offset": 38076 + }, + { + "offset": 39600 + }, + { + "offset": 43200 + }, + { + "offset": 46800 + }, + { + "offset": 43200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-eb4384db15894d16-b0aaeb08a0cbe1e0.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-eb4384db15894d16-b0aaeb08a0cbe1e0.json new file mode 100644 index 00000000000000..c68dbf2f3afad8 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-eb4384db15894d16-b0aaeb08a0cbe1e0.json @@ -0,0 +1,67 @@ +{ + "ids": [ + "australia/lindeman" + ], + "tzif": { + "posix": { + "abbr": "AEST", + "offset": 36000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2 + ], + "transitions": [ + -2366790956, + -1672560000, + -1665388800, + -883641600, + -876124800, + -860400000, + -844675200, + -828345600, + -813225600, + 57686400, + 67968000, + 625593600, + 636480000, + 657043200, + 667929600, + 688492800, + 699379200, + 719942400, + 731433600, + 751996800 + ], + "types": [ + { + "offset": 35756 + }, + { + "offset": 36000 + }, + { + "offset": 39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-eb9179abb91c8435-726489ced5139013.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-eb9179abb91c8435-726489ced5139013.json new file mode 100644 index 00000000000000..c4365a6ea3f283 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-eb9179abb91c8435-726489ced5139013.json @@ -0,0 +1,372 @@ +{ + "ids": [ + "america/coyhaique" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 3, + 1, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 3, + 4, + 2, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 5, + 6 + ], + "transitions": [ + -2524504304, + -1892661435, + -1688410800, + -1619205435, + -1593806400, + -1335986235, + -1335985200, + -1317585600, + -1304362800, + -1286049600, + -1272826800, + -1254513600, + -1241290800, + -1222977600, + -1209754800, + -1191355200, + -1178132400, + -870552000, + -865278000, + -736632000, + -718056000, + -713649600, + -36619200, + -23922000, + -3355200, + 7527600, + 24465600, + 37767600, + 55915200, + 69217200, + 87969600, + 100666800, + 118209600, + 132116400, + 150868800, + 163566000, + 182318400, + 195620400, + 213768000, + 227070000, + 245217600, + 258519600, + 277272000, + 289969200, + 308721600, + 321418800, + 340171200, + 353473200, + 371620800, + 384922800, + 403070400, + 416372400, + 434520000, + 447822000, + 466574400, + 479271600, + 498024000, + 510721200, + 529473600, + 545194800, + 560923200, + 574225200, + 592372800, + 605674800, + 624427200, + 637124400, + 653457600, + 668574000, + 687326400, + 700628400, + 718776000, + 732078000, + 750225600, + 763527600, + 781675200, + 794977200, + 813729600, + 826426800, + 845179200, + 859690800, + 876628800, + 889930800, + 906868800, + 923194800, + 939528000, + 952830000, + 971582400, + 984279600, + 1003032000, + 1015729200, + 1034481600, + 1047178800, + 1065931200, + 1079233200, + 1097380800, + 1110682800, + 1128830400, + 1142132400, + 1160884800, + 1173582000, + 1192334400, + 1206846000, + 1223784000, + 1237086000, + 1255233600, + 1270350000, + 1286683200, + 1304823600, + 1313899200, + 1335668400, + 1346558400, + 1367118000, + 1378612800, + 1398567600, + 1410062400, + 1463281200, + 1471147200, + 1494730800, + 1502596800, + 1526180400, + 1534046400, + 1554606000, + 1567915200, + 1586055600, + 1599364800, + 1617505200, + 1630814400, + 1648954800, + 1662868800, + 1680404400, + 1693713600, + 1712458800, + 1725768000, + 1742439600 + ], + "types": [ + { + "offset": -17296 + }, + { + "offset": -16965 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ec4f112febcbc032-a69762c688a2158f.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ec4f112febcbc032-a69762c688a2158f.json new file mode 100644 index 00000000000000..6fe9c8f7460995 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ec4f112febcbc032-a69762c688a2158f.json @@ -0,0 +1,227 @@ +{ + "ids": [ + "europe/moscow", + "w-su" + ], + "tzif": { + "posix": { + "abbr": "MSK", + "offset": 10800, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 3, + 2, + 3, + 4, + 5, + 4, + 6, + 4, + 5, + 7, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 4, + 5, + 5, + 8, + 7, + 4, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 5, + 8, + 4, + 9, + 5, + 8 + ], + "transitions": [ + -2840149817, + -1688265017, + -1656819079, + -1641353479, + -1627965079, + -1618716679, + -1596429079, + -1593820800, + -1589860800, + -1542427200, + -1539493200, + -1525323600, + -1522728000, + -1491188400, + -1247536800, + 354920400, + 370728000, + 386456400, + 402264000, + 417992400, + 433800000, + 449614800, + 465346800, + 481071600, + 496796400, + 512521200, + 528246000, + 543970800, + 559695600, + 575420400, + 591145200, + 606870000, + 622594800, + 638319600, + 654649200, + 670374000, + 686102400, + 695779200, + 701823600, + 717548400, + 733273200, + 748998000, + 764722800, + 780447600, + 796172400, + 811897200, + 828226800, + 846370800, + 859676400, + 877820400, + 891126000, + 909270000, + 922575600, + 941324400, + 954025200, + 972774000, + 985474800, + 1004223600, + 1017529200, + 1035673200, + 1048978800, + 1067122800, + 1080428400, + 1099177200, + 1111878000, + 1130626800, + 1143327600, + 1162076400, + 1174777200, + 1193526000, + 1206831600, + 1224975600, + 1238281200, + 1256425200, + 1269730800, + 1288479600, + 1301180400, + 1414274400 + ], + "types": [ + { + "offset": 9017 + }, + { + "offset": 9079 + }, + { + "offset": 12679 + }, + { + "offset": 16279 + }, + { + "offset": 14400 + }, + { + "offset": 10800 + }, + { + "offset": 18000 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ed29bf9f15004c8a-f6def5db1514383c.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ed29bf9f15004c8a-f6def5db1514383c.json new file mode 100644 index 00000000000000..7fde68372da96d --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ed29bf9f15004c8a-f6def5db1514383c.json @@ -0,0 +1,405 @@ +{ + "ids": [ + "america/montreal", + "america/nassau", + "america/nipigon", + "america/thunder_bay", + "america/toronto", + "canada/eastern" + ], + "tzif": { + "posix": { + "abbr": "EST", + "offset": -18000, + "transition": { + "abbr": "EDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2366736148, + -1632070800, + -1615140000, + -1601753400, + -1583697600, + -1567357200, + -1554667200, + -1534698000, + -1524074400, + -1503248400, + -1492365600, + -1471798800, + -1460916000, + -1440954000, + -1428861600, + -1409504400, + -1397412000, + -1378054800, + -1365962400, + -1346605200, + -1333908000, + -1315155600, + -1301853600, + -1283706000, + -1270404000, + -1252256400, + -1238954400, + -1220806800, + -1207504800, + -1188752400, + -1176055200, + -1157302800, + -1144000800, + -1125853200, + -1112551200, + -1094403600, + -1081101600, + -1062954000, + -1049652000, + -1031504400, + -1018202400, + -1000054800, + -986752800, + -968000400, + -955303200, + -936550800, + -880218000, + -769395600, + -765396000, + -757364400, + -733946400, + -715798800, + -702496800, + -684349200, + -671047200, + -652899600, + -634154400, + -620845200, + -602704800, + -589395600, + -576093600, + -557946000, + -544644000, + -526496400, + -513194400, + -495046800, + -481744800, + -463597200, + -450295200, + -431542800, + -418240800, + -400093200, + -384372000, + -368643600, + -352922400, + -337194000, + -321472800, + -305744400, + -289418400, + -273690000, + -257968800, + -242240400, + -226519200, + -210790800, + -195069600, + -179341200, + -163620000, + -147891600, + -131565600, + -116442000, + -100116000, + -84387600, + -68666400, + -52938000, + -37216800, + -21488400, + -5767200, + 9961200, + 25682400, + 41410800, + 57736800, + 73465200, + 89186400, + 104914800, + 120636000, + 136364400, + 152085600, + 167814000, + 183535200, + 199263600, + 215589600, + 230713200, + 247039200, + 262767600, + 278488800, + 294217200, + 309938400, + 325666800, + 341388000, + 357116400, + 372837600, + 388566000, + 404892000, + 420015600, + 436341600, + 452070000, + 467791200, + 483519600, + 499240800, + 514969200, + 530690400, + 544604400, + 562140000, + 576054000, + 594194400, + 607503600, + 625644000, + 638953200, + 657093600, + 671007600, + 688543200, + 702457200, + 719992800, + 733906800, + 752047200, + 765356400, + 783496800, + 796806000, + 814946400, + 828860400, + 846396000, + 860310000, + 877845600, + 891759600, + 909295200, + 923209200, + 941349600, + 954658800, + 972799200, + 986108400, + 1004248800, + 1018162800, + 1035698400, + 1049612400, + 1067148000, + 1081062000, + 1099202400, + 1112511600, + 1130652000, + 1143961200, + 1162101600, + 1173596400, + 1194156000 + ], + "types": [ + { + "offset": -19052 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-edc11c9a67454353-7a49fa82cac12758.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-edc11c9a67454353-7a49fa82cac12758.json new file mode 100644 index 00000000000000..4f4106ec2ba78e --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-edc11c9a67454353-7a49fa82cac12758.json @@ -0,0 +1,169 @@ +{ + "ids": [ + "america/argentina/rio_gallegos" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 3, + 4, + 3, + 4, + 2, + 3, + 4, + 5, + 3, + 4 + ], + "transitions": [ + -2372095388, + -1567453392, + -1233432000, + -1222981200, + -1205956800, + -1194037200, + -1172865600, + -1162501200, + -1141329600, + -1130965200, + -1109793600, + -1099429200, + -1078257600, + -1067806800, + -1046635200, + -1036270800, + -1015099200, + -1004734800, + -983563200, + -973198800, + -952027200, + -941576400, + -931032000, + -900882000, + -890337600, + -833749200, + -827265600, + -752274000, + -733780800, + -197326800, + -190843200, + -184194000, + -164491200, + -152658000, + -132955200, + -121122000, + -101419200, + -86821200, + -71092800, + -54766800, + -39038400, + -23317200, + -7588800, + 128142000, + 136605600, + 596948400, + 605066400, + 624423600, + 636516000, + 656478000, + 667965600, + 687927600, + 699415200, + 719377200, + 731469600, + 938919600, + 952052400, + 1086058800, + 1087704000, + 1198983600, + 1205632800 + ], + "types": [ + { + "offset": -16612 + }, + { + "offset": -15408 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-edc8df3b48d8f1ae-2f0fe2e55f7ceabf.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-edc8df3b48d8f1ae-2f0fe2e55f7ceabf.json new file mode 100644 index 00000000000000..6baef9f36a1ef4 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-edc8df3b48d8f1ae-2f0fe2e55f7ceabf.json @@ -0,0 +1,37 @@ +{ + "ids": [ + "pacific/enderbury", + "pacific/kanton" + ], + "tzif": { + "posix": { + "abbr": "+13", + "offset": 46800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3 + ], + "transitions": [ + -1020470400, + 307627200, + 788871600 + ], + "types": [ + { + "offset": 0 + }, + { + "offset": -43200 + }, + { + "offset": -39600 + }, + { + "offset": 46800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ee42b17151e8d0d1-557c16a705ea23d1.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ee42b17151e8d0d1-557c16a705ea23d1.json new file mode 100644 index 00000000000000..a7198d18c73873 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ee42b17151e8d0d1-557c16a705ea23d1.json @@ -0,0 +1,132 @@ +{ + "ids": [ + "asia/taipei", + "roc" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": 28800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1 + ], + "transitions": [ + -2335248360, + -1017820800, + -766224000, + -745833600, + -733827600, + -716889600, + -699613200, + -683884800, + -670669200, + -652348800, + -639133200, + -620812800, + -607597200, + -589276800, + -576061200, + -562924800, + -541760400, + -528710400, + -510224400, + -497174400, + -478688400, + -465638400, + -449830800, + -434016000, + -418208400, + -402480000, + -386672400, + -370944000, + -355136400, + -339408000, + -323600400, + -302515200, + -291978000, + -270979200, + -260442000, + 133977600, + 149785200, + 165513600, + 181321200, + 299606400, + 307551600 + ], + "types": [ + { + "offset": 29160 + }, + { + "offset": 28800 + }, + { + "offset": 32400 + }, + { + "offset": 32400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ef074bbbac9f5764-af06bb8dad04fbb2.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ef074bbbac9f5764-af06bb8dad04fbb2.json new file mode 100644 index 00000000000000..8cdc8a4cf80486 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ef074bbbac9f5764-af06bb8dad04fbb2.json @@ -0,0 +1,121 @@ +{ + "ids": [ + "america/bahia_banderas" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 4 + ], + "transitions": [ + -1514739600, + -1343149200, + -1234807200, + -1220461200, + -1207159200, + -1191344400, + -873828000, + 828867600, + 846403200, + 860317200, + 877852800, + 891766800, + 909302400, + 923216400, + 941356800, + 954666000, + 972806400, + 989139600, + 1001836800, + 1018170000, + 1035705600, + 1049619600, + 1067155200, + 1081069200, + 1099209600, + 1112518800, + 1130659200, + 1143968400, + 1162108800, + 1175418000, + 1193558400, + 1207472400, + 1225008000, + 1238922000, + 1256457600, + 1270371600 + ], + "types": [ + { + "offset": -25260 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ef99169dd5b3d431-ae45f4711dd0d14b.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ef99169dd5b3d431-ae45f4711dd0d14b.json new file mode 100644 index 00000000000000..ba60ecb570eff0 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ef99169dd5b3d431-ae45f4711dd0d14b.json @@ -0,0 +1,225 @@ +{ + "ids": [ + "australia/act", + "australia/canberra", + "australia/nsw", + "australia/sydney" + ], + "tzif": { + "posix": { + "abbr": "AEST", + "offset": 36000, + "transition": { + "abbr": "AEDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 4, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 1, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2 + ], + "transitions": [ + -2364113092, + -1672560000, + -1665388800, + -883641600, + -876124800, + -860400000, + -844675200, + -828345600, + -813225600, + 57686400, + 67968000, + 89136000, + 100022400, + 120585600, + 131472000, + 152035200, + 162921600, + 183484800, + 194976000, + 215539200, + 226425600, + 246988800, + 257875200, + 278438400, + 289324800, + 309888000, + 320774400, + 341337600, + 352224000, + 372787200, + 386697600, + 404841600, + 415728000, + 436291200, + 447177600, + 467740800, + 478627200, + 499190400, + 511286400, + 530035200, + 542736000, + 562089600, + 574790400, + 594144000, + 606240000, + 625593600, + 636480000, + 657043200, + 667929600, + 688492800, + 699379200, + 719942400, + 731433600, + 751996800, + 762883200, + 783446400, + 794332800, + 814896000, + 828201600, + 846345600, + 859651200, + 877795200, + 891100800, + 909244800, + 922550400, + 941299200, + 954000000, + 967305600, + 985449600, + 1004198400, + 1017504000, + 1035648000, + 1048953600, + 1067097600, + 1080403200, + 1099152000, + 1111852800, + 1130601600, + 1143907200, + 1162051200, + 1174752000, + 1193500800, + 1207411200, + 1223136000 + ], + "types": [ + { + "offset": 36292 + }, + { + "offset": 36000 + }, + { + "offset": 39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-effb0bd5efab2bad-76ee3ca040667987.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-effb0bd5efab2bad-76ee3ca040667987.json new file mode 100644 index 00000000000000..90e7a7625d0a5e --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-effb0bd5efab2bad-76ee3ca040667987.json @@ -0,0 +1,308 @@ +{ + "ids": [ + "america/los_angeles", + "pst8pdt", + "us/pacific" + ], + "tzif": { + "posix": { + "abbr": "PST", + "offset": -28800, + "transition": { + "abbr": "PDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2717640000, + -1633269600, + -1615129200, + -1601820000, + -1583679600, + -880207200, + -769395600, + -765385200, + -687967140, + -662655600, + -620838000, + -608137200, + -589388400, + -576082800, + -557938800, + -544633200, + -526489200, + -513183600, + -495039600, + -481734000, + -463590000, + -450284400, + -431535600, + -418230000, + -400086000, + -386780400, + -368636400, + -355330800, + -337186800, + -323881200, + -305737200, + -292431600, + -273682800, + -260982000, + -242233200, + -226508400, + -210783600, + -195058800, + -179334000, + -163609200, + -147884400, + -131554800, + -116434800, + -100105200, + -84376800, + -68655600, + -52927200, + -37206000, + -21477600, + -5756400, + 9972000, + 25693200, + 41421600, + 57747600, + 73476000, + 89197200, + 104925600, + 120646800, + 126698400, + 152096400, + 162381600, + 183546000, + 199274400, + 215600400, + 230724000, + 247050000, + 262778400, + 278499600, + 294228000, + 309949200, + 325677600, + 341398800, + 357127200, + 372848400, + 388576800, + 404902800, + 420026400, + 436352400, + 452080800, + 467802000, + 483530400, + 499251600, + 514980000, + 530701200, + 544615200, + 562150800, + 576064800, + 594205200, + 607514400, + 625654800, + 638964000, + 657104400, + 671018400, + 688554000, + 702468000, + 720003600, + 733917600, + 752058000, + 765367200, + 783507600, + 796816800, + 814957200, + 828871200, + 846406800, + 860320800, + 877856400, + 891770400, + 909306000, + 923220000, + 941360400, + 954669600, + 972810000, + 986119200, + 1004259600, + 1018173600, + 1035709200, + 1049623200, + 1067158800, + 1081072800, + 1099213200, + 1112522400, + 1130662800, + 1143972000, + 1162112400, + 1173607200, + 1194166800 + ], + "types": [ + { + "offset": -28378 + }, + { + "offset": -28800 + }, + { + "offset": -25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f022b64b061d7846-529fb8a37afd1bc3.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f022b64b061d7846-529fb8a37afd1bc3.json new file mode 100644 index 00000000000000..968e0512175756 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f022b64b061d7846-529fb8a37afd1bc3.json @@ -0,0 +1,31 @@ +{ + "ids": [ + "pacific/pitcairn" + ], + "tzif": { + "posix": { + "abbr": "-08", + "offset": -28800, + "transition": null + }, + "transition_types": [ + 1, + 2 + ], + "transitions": [ + -2177421580, + 893665800 + ], + "types": [ + { + "offset": -31220 + }, + { + "offset": -30600 + }, + { + "offset": -28800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f0d38f589f1464b7-e65390d2a42c7521.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f0d38f589f1464b7-e65390d2a42c7521.json new file mode 100644 index 00000000000000..6d37ac6a3c1fda --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f0d38f589f1464b7-e65390d2a42c7521.json @@ -0,0 +1,313 @@ +{ + "ids": [ + "africa/cairo", + "egypt" + ], + "tzif": { + "posix": { + "abbr": "EET", + "offset": 7200, + "transition": { + "abbr": "EEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 4 + ] + }, + "time": 86400 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 4, + 5, + 5 + ] + }, + "time": 0 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2185409109, + -929844000, + -923108400, + -906170400, + -892868400, + -875844000, + -857790000, + -844308000, + -825822000, + -812685600, + -794199600, + -779853600, + -762663600, + -399088800, + -386650800, + -368330400, + -355114800, + -336790800, + -323654400, + -305168400, + -292032000, + -273632400, + -260496000, + -242096400, + -228960000, + -210560400, + -197424000, + -178938000, + -165801600, + -147402000, + -134265600, + -115866000, + -102643200, + -84330000, + -71107200, + -52707600, + -39484800, + -21171600, + -7948800, + 10364400, + 23587200, + 41900400, + 55123200, + 73522800, + 86745600, + 105058800, + 118281600, + 136594800, + 149817600, + 168130800, + 181353600, + 199753200, + 212976000, + 231289200, + 244512000, + 262825200, + 276048000, + 294361200, + 307584000, + 325983600, + 339206400, + 357519600, + 370742400, + 396399600, + 402278400, + 426812400, + 433814400, + 452214000, + 465436800, + 483750000, + 496972800, + 515286000, + 528508800, + 546822000, + 560044800, + 578444400, + 591667200, + 610412400, + 623203200, + 641516400, + 654739200, + 673052400, + 686275200, + 704674800, + 717897600, + 736210800, + 749433600, + 767746800, + 780969600, + 799020000, + 812322000, + 830469600, + 843771600, + 861919200, + 875221200, + 893368800, + 906670800, + 925423200, + 938725200, + 956872800, + 970174800, + 988322400, + 1001624400, + 1019772000, + 1033074000, + 1051221600, + 1064523600, + 1083276000, + 1096578000, + 1114725600, + 1128027600, + 1146175200, + 1158872400, + 1177624800, + 1189112400, + 1209074400, + 1219957200, + 1240524000, + 1250802000, + 1272578400, + 1281474000, + 1284069600, + 1285880400, + 1400191200, + 1403816400, + 1406844000, + 1411678800, + 1682632800, + 1698354000 + ], + "types": [ + { + "offset": 7509 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f104b0a7be76b68-672d15810abf76ed.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f104b0a7be76b68-672d15810abf76ed.json new file mode 100644 index 00000000000000..3c0b068a47658e --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f104b0a7be76b68-672d15810abf76ed.json @@ -0,0 +1,49 @@ +{ + "ids": [ + "kwajalein", + "pacific/kwajalein" + ], + "tzif": { + "posix": { + "abbr": "+12", + "offset": 43200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 1, + 4, + 5 + ], + "transitions": [ + -2177492960, + -1041418800, + -907408800, + -817462800, + -7988400, + 745934400 + ], + "types": [ + { + "offset": 40160 + }, + { + "offset": 39600 + }, + { + "offset": 36000 + }, + { + "offset": 32400 + }, + { + "offset": -43200 + }, + { + "offset": 43200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f1b7ca6dc4d0b2b0-d827a5cc52d17740.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f1b7ca6dc4d0b2b0-d827a5cc52d17740.json new file mode 100644 index 00000000000000..132dcf300511bf --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f1b7ca6dc4d0b2b0-d827a5cc52d17740.json @@ -0,0 +1,171 @@ +{ + "ids": [ + "asia/aqtau" + ], + "tzif": { + "posix": { + "abbr": "+05", + "offset": 18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 2, + 5, + 2, + 5, + 1, + 3, + 4, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 3, + 4, + 2, + 5, + 1, + 2, + 5, + 1, + 2, + 5, + 1, + 2, + 5, + 1, + 2, + 5, + 1, + 2, + 5, + 1, + 2, + 5, + 1, + 2, + 5, + 1, + 2, + 5, + 1, + 2, + 5, + 1, + 2, + 5, + 2, + 5 + ], + "transitions": [ + -1441164064, + -1247544000, + 370724400, + 386445600, + 386449200, + 402256800, + 417985200, + 433792800, + 449607600, + 465339600, + 481064400, + 496789200, + 512514000, + 528238800, + 543963600, + 559688400, + 575413200, + 591138000, + 606862800, + 622587600, + 638312400, + 654642000, + 670366800, + 670370400, + 686095200, + 695772000, + 701816400, + 717541200, + 733266000, + 748990800, + 764715600, + 780440400, + 780444000, + 796168800, + 811893600, + 828223200, + 846367200, + 859672800, + 877816800, + 891122400, + 909266400, + 922572000, + 941320800, + 954021600, + 972770400, + 985471200, + 1004220000, + 1017525600, + 1035669600, + 1048975200, + 1067119200, + 1080424800, + 1099173600 + ], + "types": [ + { + "offset": 12064 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + }, + { + "offset": 21600 + }, + { + "offset": 21600 + }, + { + "offset": 18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f1f0b3541047bfad-8176e7d9a57a1316.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f1f0b3541047bfad-8176e7d9a57a1316.json new file mode 100644 index 00000000000000..b59810738b165d --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f1f0b3541047bfad-8176e7d9a57a1316.json @@ -0,0 +1,234 @@ +{ + "ids": [ + "antarctica/palmer" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 3, + 4, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 1, + 3 + ], + "transitions": [ + -157766400, + -152658000, + -132955200, + -121122000, + -101419200, + -86821200, + -71092800, + -54766800, + -39038400, + -23317200, + -7588800, + 128142000, + 136605600, + 389070000, + 403070400, + 416372400, + 434520000, + 447822000, + 466574400, + 479271600, + 498024000, + 510721200, + 529473600, + 545194800, + 560923200, + 574225200, + 592372800, + 605674800, + 624427200, + 637124400, + 653457600, + 668574000, + 687326400, + 700628400, + 718776000, + 732078000, + 750225600, + 763527600, + 781675200, + 794977200, + 813729600, + 826426800, + 845179200, + 859690800, + 876628800, + 889930800, + 906868800, + 923194800, + 939528000, + 952830000, + 971582400, + 984279600, + 1003032000, + 1015729200, + 1034481600, + 1047178800, + 1065931200, + 1079233200, + 1097380800, + 1110682800, + 1128830400, + 1142132400, + 1160884800, + 1173582000, + 1192334400, + 1206846000, + 1223784000, + 1237086000, + 1255233600, + 1270350000, + 1286683200, + 1304823600, + 1313899200, + 1335668400, + 1346558400, + 1367118000, + 1378612800, + 1398567600, + 1410062400, + 1463281200, + 1471147200, + 1480820400 + ], + "types": [ + { + "offset": 0 + }, + { + "offset": -10800 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f2238fc53b0fff96-6f6aee2b55131405.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f2238fc53b0fff96-6f6aee2b55131405.json new file mode 100644 index 00000000000000..1b4bdd86171f85 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f2238fc53b0fff96-6f6aee2b55131405.json @@ -0,0 +1,41 @@ +{ + "ids": [ + "antarctica/davis" + ], + "tzif": { + "posix": { + "abbr": "+07", + "offset": 25200, + "transition": null + }, + "transition_types": [ + 1, + 0, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -409190400, + -163062000, + -28857600, + 1255806000, + 1268251200, + 1319742000, + 1329854400 + ], + "types": [ + { + "offset": 0 + }, + { + "offset": 25200 + }, + { + "offset": 18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f229cb4cd552c448-1e8f29f5b7bc6659.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f229cb4cd552c448-1e8f29f5b7bc6659.json new file mode 100644 index 00000000000000..7b39e9ac249951 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f229cb4cd552c448-1e8f29f5b7bc6659.json @@ -0,0 +1,156 @@ +{ + "ids": [ + "asia/bishkek" + ], + "tzif": { + "posix": { + "abbr": "+06", + "offset": 21600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 2, + 4 + ], + "transitions": [ + -1441169904, + -1247547600, + 354909600, + 370717200, + 386445600, + 402253200, + 417981600, + 433789200, + 449604000, + 465336000, + 481060800, + 496785600, + 512510400, + 528235200, + 543960000, + 559684800, + 575409600, + 591134400, + 606859200, + 622584000, + 638308800, + 654638400, + 670363200, + 670366800, + 683582400, + 703018800, + 717530400, + 734468400, + 748980000, + 765918000, + 780429600, + 797367600, + 811879200, + 828817200, + 843933600, + 859671000, + 877811400, + 891120600, + 909261000, + 922570200, + 941315400, + 954019800, + 972765000, + 985469400, + 1004214600, + 1017523800, + 1035664200, + 1048973400, + 1067113800, + 1080423000, + 1099168200, + 1111872600, + 1123783200 + ], + "types": [ + { + "offset": 17904 + }, + { + "offset": 18000 + }, + { + "offset": 21600 + }, + { + "offset": 25200 + }, + { + "offset": 21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f26b875165969e75-9e25992ccdfbaa1f.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f26b875165969e75-9e25992ccdfbaa1f.json new file mode 100644 index 00000000000000..c9e09d0aecd898 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f26b875165969e75-9e25992ccdfbaa1f.json @@ -0,0 +1,89 @@ +{ + "ids": [ + "asia/ashgabat", + "asia/ashkhabad" + ], + "tzif": { + "posix": { + "abbr": "+05", + "offset": 18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 2, + 4 + ], + "transitions": [ + -1441166012, + -1247544000, + 354913200, + 370720800, + 386449200, + 402256800, + 417985200, + 433792800, + 449607600, + 465339600, + 481064400, + 496789200, + 512514000, + 528238800, + 543963600, + 559688400, + 575413200, + 591138000, + 606862800, + 622587600, + 638312400, + 654642000, + 670366800, + 670370400, + 686095200, + 695772000 + ], + "types": [ + { + "offset": 14012 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + }, + { + "offset": 21600 + }, + { + "offset": 18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f5114ea1ad21a447-657f9c7873c390b2.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f5114ea1ad21a447-657f9c7873c390b2.json new file mode 100644 index 00000000000000..5c3e9b5f33aec7 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f5114ea1ad21a447-657f9c7873c390b2.json @@ -0,0 +1,250 @@ +{ + "ids": [ + "america/north_dakota/beulah" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": { + "abbr": "CDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 3 + ], + "transitions": [ + -2717643600, + -1633273200, + -1615132800, + -1601823600, + -1583683200, + -880210800, + -769395600, + -765388800, + -84380400, + -68659200, + -52930800, + -37209600, + -21481200, + -5760000, + 9968400, + 25689600, + 41418000, + 57744000, + 73472400, + 89193600, + 104922000, + 120643200, + 126694800, + 152092800, + 162378000, + 183542400, + 199270800, + 215596800, + 230720400, + 247046400, + 262774800, + 278496000, + 294224400, + 309945600, + 325674000, + 341395200, + 357123600, + 372844800, + 388573200, + 404899200, + 420022800, + 436348800, + 452077200, + 467798400, + 483526800, + 499248000, + 514976400, + 530697600, + 544611600, + 562147200, + 576061200, + 594201600, + 607510800, + 625651200, + 638960400, + 657100800, + 671014800, + 688550400, + 702464400, + 720000000, + 733914000, + 752054400, + 765363600, + 783504000, + 796813200, + 814953600, + 828867600, + 846403200, + 860317200, + 877852800, + 891766800, + 909302400, + 923216400, + 941356800, + 954666000, + 972806400, + 986115600, + 1004256000, + 1018170000, + 1035705600, + 1049619600, + 1067155200, + 1081069200, + 1099209600, + 1112518800, + 1130659200, + 1143968400, + 1162108800, + 1173603600, + 1194163200, + 1205053200, + 1225612800, + 1236502800, + 1257062400, + 1268557200, + 1289116800 + ], + "types": [ + { + "offset": -24427 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + }, + { + "offset": -21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f58f911ab743ef1d-f57255d26abdda48.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f58f911ab743ef1d-f57255d26abdda48.json new file mode 100644 index 00000000000000..59efca99579c48 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f58f911ab743ef1d-f57255d26abdda48.json @@ -0,0 +1,29 @@ +{ + "ids": [ + "antarctica/syowa", + "asia/aden", + "asia/kuwait", + "asia/riyadh" + ], + "tzif": { + "posix": { + "abbr": "+03", + "offset": 10800, + "transition": null + }, + "transition_types": [ + 1 + ], + "transitions": [ + -719636812 + ], + "types": [ + { + "offset": 11212 + }, + { + "offset": 10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f5b99738d99ddd8c-edf53ab20b57f392.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f5b99738d99ddd8c-edf53ab20b57f392.json new file mode 100644 index 00000000000000..8f2aac78f33316 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f5b99738d99ddd8c-edf53ab20b57f392.json @@ -0,0 +1,171 @@ +{ + "ids": [ + "america/argentina/san_juan" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 2, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 3, + 4, + 3, + 4, + 2, + 3, + 4, + 5, + 3, + 4 + ], + "transitions": [ + -2372095556, + -1567453392, + -1233432000, + -1222981200, + -1205956800, + -1194037200, + -1172865600, + -1162501200, + -1141329600, + -1130965200, + -1109793600, + -1099429200, + -1078257600, + -1067806800, + -1046635200, + -1036270800, + -1015099200, + -1004734800, + -983563200, + -973198800, + -952027200, + -941576400, + -931032000, + -900882000, + -890337600, + -833749200, + -827265600, + -752274000, + -733780800, + -197326800, + -190843200, + -184194000, + -164491200, + -152658000, + -132955200, + -121122000, + -101419200, + -86821200, + -71092800, + -54766800, + -39038400, + -23317200, + -7588800, + 128142000, + 136605600, + 596948400, + 605066400, + 624423600, + 636516000, + 656478000, + 667792800, + 673588800, + 687927600, + 699415200, + 719377200, + 731469600, + 938919600, + 952052400, + 1085972400, + 1090728000, + 1198983600, + 1205632800 + ], + "types": [ + { + "offset": -16444 + }, + { + "offset": -15408 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f61469e5df5071ba-1d93153e2c1ef413.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f61469e5df5071ba-1d93153e2c1ef413.json new file mode 100644 index 00000000000000..eb858b8e5f7885 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f61469e5df5071ba-1d93153e2c1ef413.json @@ -0,0 +1,138 @@ +{ + "ids": [ + "america/regina", + "canada/saskatchewan" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3 + ], + "transitions": [ + -2030202084, + -1632063600, + -1615132800, + -1251651600, + -1238349600, + -1220202000, + -1206900000, + -1188752400, + -1175450400, + -1156698000, + -1144000800, + -1125248400, + -1111946400, + -1032714000, + -1016992800, + -1001264400, + -986148000, + -969814800, + -954093600, + -937760400, + -922039200, + -906310800, + -890589600, + -880210800, + -769395600, + -765388800, + -748450800, + -732729600, + -715791600, + -702489600, + -684342000, + -671040000, + -652892400, + -639590400, + -620838000, + -608140800, + -589388400, + -576086400, + -557938800, + -544636800, + -526489200, + -513187200, + -495039600, + -481737600, + -463590000, + -450288000, + -431535600, + -418233600, + -400086000, + -386784000, + -337186800, + -321465600, + -305737200 + ], + "types": [ + { + "offset": -25116 + }, + { + "offset": -25200 + }, + { + "offset": -21600 + }, + { + "offset": -21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f665c39691dff65-eb8beb46e71e4a05.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f665c39691dff65-eb8beb46e71e4a05.json new file mode 100644 index 00000000000000..d865aaa78403d5 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f665c39691dff65-eb8beb46e71e4a05.json @@ -0,0 +1,199 @@ +{ + "ids": [ + "eet", + "europe/athens" + ], + "tzif": { + "posix": { + "abbr": "EET", + "offset": 7200, + "transition": { + "abbr": "EEST", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 5, + 0 + ] + }, + "time": 14400 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 5, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 0, + 1, + 2, + 1, + 2, + 1, + 3, + 4, + 1, + 3, + 4, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3, + 2, + 1, + 3 + ], + "transitions": [ + -2344642492, + -1686101632, + -1182996000, + -1178161200, + -906861600, + -904878000, + -857257200, + -844477200, + -828237600, + -812422800, + -552362400, + -541652400, + 166485600, + 186184800, + 198028800, + 213753600, + 228873600, + 244080000, + 260323200, + 275446800, + 291798000, + 307407600, + 323388000, + 338936400, + 347148000, + 370400400, + 386125200, + 401850000, + 417574800, + 433299600, + 449024400, + 465354000, + 481078800, + 496803600, + 512528400, + 528253200, + 543978000, + 559702800, + 575427600, + 591152400, + 606877200, + 622602000, + 638326800, + 654656400, + 670381200, + 686106000, + 701830800, + 717555600, + 733280400, + 749005200, + 764730000, + 780454800, + 796179600, + 811904400, + 828234000, + 846378000 + ], + "types": [ + { + "offset": 5692 + }, + { + "offset": 7200 + }, + { + "offset": 10800 + }, + { + "offset": 7200 + }, + { + "offset": 3600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f6698c0e9f2fa661-cfcf92aaf6d6e5be.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f6698c0e9f2fa661-cfcf92aaf6d6e5be.json new file mode 100644 index 00000000000000..b547777f8c6c72 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f6698c0e9f2fa661-cfcf92aaf6d6e5be.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt-14" + ], + "tzif": { + "posix": { + "abbr": "+14", + "offset": 50400, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": 50400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f677bd8d940386cc-6f4acf146c31eb70.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f677bd8d940386cc-6f4acf146c31eb70.json new file mode 100644 index 00000000000000..47763968465bae --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f677bd8d940386cc-6f4acf146c31eb70.json @@ -0,0 +1,199 @@ +{ + "ids": [ + "america/campo_grande" + ], + "tzif": { + "posix": { + "abbr": "-04", + "offset": -14400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2 + ], + "transitions": [ + -1767212492, + -1206954000, + -1191358800, + -1175371200, + -1159822800, + -633816000, + -622065600, + -602280000, + -591829200, + -570744000, + -560206800, + -539121600, + -531349200, + -191361600, + -184194000, + -155160000, + -150066000, + -128894400, + -121122000, + -99950400, + -89586000, + -68414400, + -57963600, + 499752000, + 511239600, + 530596800, + 540270000, + 562132800, + 571201200, + 592977600, + 602046000, + 624427200, + 634705200, + 656481600, + 666759600, + 687931200, + 697604400, + 719985600, + 728449200, + 750830400, + 761713200, + 782280000, + 793162800, + 813729600, + 824007600, + 844574400, + 856062000, + 876110400, + 888721200, + 908078400, + 919566000, + 938923200, + 951620400, + 970977600, + 982465200, + 1003032000, + 1013914800, + 1036296000, + 1045364400, + 1066536000, + 1076814000, + 1099368000, + 1108868400, + 1129435200, + 1140318000, + 1162699200, + 1172372400, + 1192334400, + 1203217200, + 1224388800, + 1234666800, + 1255838400, + 1266721200, + 1287288000, + 1298170800, + 1318737600, + 1330225200, + 1350792000, + 1361070000, + 1382241600, + 1392519600, + 1413691200, + 1424574000, + 1445140800, + 1456023600, + 1476590400 + ], + "types": [ + { + "offset": -13108 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f757031187208623-b42f12ebe4b7bfcb.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f757031187208623-b42f12ebe4b7bfcb.json new file mode 100644 index 00000000000000..bd50018f90a8e7 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f757031187208623-b42f12ebe4b7bfcb.json @@ -0,0 +1,35 @@ +{ + "ids": [ + "america/martinique" + ], + "tzif": { + "posix": { + "abbr": "AST", + "offset": -14400, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 1 + ], + "transitions": [ + -2524506940, + -1851537340, + 323841600, + 338958000 + ], + "types": [ + { + "offset": -14660 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f7b886dc80987d1f-1cfc3c180fd77cd3.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f7b886dc80987d1f-1cfc3c180fd77cd3.json new file mode 100644 index 00000000000000..b353610bde65fa --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f7b886dc80987d1f-1cfc3c180fd77cd3.json @@ -0,0 +1,150 @@ +{ + "ids": [ + "america/indiana/vincennes" + ], + "tzif": { + "posix": { + "abbr": "EST", + "offset": -18000, + "transition": { + "abbr": "EDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 2, + 3 + ], + "transitions": [ + -2717647200, + -1633276800, + -1615136400, + -1601827200, + -1583686800, + -880214400, + -769395600, + -765392400, + -747244800, + -733942800, + -526492800, + -513190800, + -495043200, + -481741200, + -462996000, + -450291600, + -431539200, + -418237200, + -400089600, + -386787600, + -368640000, + -355338000, + -337190400, + -323888400, + -305740800, + -289414800, + -273686400, + -260989200, + -242236800, + -226515600, + -210787200, + -195066000, + -179337600, + -21488400, + -5767200, + 9961200, + 25682400, + 1143961200, + 1143964800, + 1162105200, + 1173600000, + 1194159600 + ], + "types": [ + { + "offset": -21007 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f80d3a6707532038-3bae731e777368b6.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f80d3a6707532038-3bae731e777368b6.json new file mode 100644 index 00000000000000..927f2444f49d33 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f80d3a6707532038-3bae731e777368b6.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt+8" + ], + "tzif": { + "posix": { + "abbr": "-08", + "offset": -28800, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": -28800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f842f34f4c14fee1-6af6c77813d81c95.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f842f34f4c14fee1-6af6c77813d81c95.json new file mode 100644 index 00000000000000..253d5af0774355 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f842f34f4c14fee1-6af6c77813d81c95.json @@ -0,0 +1,33 @@ +{ + "ids": [ + "africa/monrovia" + ], + "tzif": { + "posix": { + "abbr": "GMT", + "offset": 0, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2 + ], + "transitions": [ + -2776979812, + -1604359012, + 63593070 + ], + "types": [ + { + "offset": -2588 + }, + { + "offset": -2670 + }, + { + "offset": 0 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f87d2aa5dfe5efe9-6f6f56db37ced2fd.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f87d2aa5dfe5efe9-6f6f56db37ced2fd.json new file mode 100644 index 00000000000000..b6920701a2982f --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f87d2aa5dfe5efe9-6f6f56db37ced2fd.json @@ -0,0 +1,244 @@ +{ + "ids": [ + "america/kentucky/monticello" + ], + "tzif": { + "posix": { + "abbr": "EST", + "offset": -18000, + "transition": { + "abbr": "EDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3 + ], + "transitions": [ + -2717647200, + -1633276800, + -1615136400, + -1601827200, + -1583686800, + -880214400, + -769395600, + -765392400, + -52934400, + -37213200, + -21484800, + -5763600, + 9964800, + 25686000, + 41414400, + 57740400, + 73468800, + 89190000, + 104918400, + 120639600, + 126691200, + 152089200, + 162374400, + 183538800, + 199267200, + 215593200, + 230716800, + 247042800, + 262771200, + 278492400, + 294220800, + 309942000, + 325670400, + 341391600, + 357120000, + 372841200, + 388569600, + 404895600, + 420019200, + 436345200, + 452073600, + 467794800, + 483523200, + 499244400, + 514972800, + 530694000, + 544608000, + 562143600, + 576057600, + 594198000, + 607507200, + 625647600, + 638956800, + 657097200, + 671011200, + 688546800, + 702460800, + 719996400, + 733910400, + 752050800, + 765360000, + 783500400, + 796809600, + 814950000, + 828864000, + 846399600, + 860313600, + 877849200, + 891763200, + 909298800, + 923212800, + 941353200, + 954662400, + 972802800, + 986108400, + 1004248800, + 1018162800, + 1035698400, + 1049612400, + 1067148000, + 1081062000, + 1099202400, + 1112511600, + 1130652000, + 1143961200, + 1162101600, + 1173596400, + 1194156000 + ], + "types": [ + { + "offset": -20364 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f8baa073f0e62ab0-5c9c06226b1920d5.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f8baa073f0e62ab0-5c9c06226b1920d5.json new file mode 100644 index 00000000000000..99c15cada043d1 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f8baa073f0e62ab0-5c9c06226b1920d5.json @@ -0,0 +1,220 @@ +{ + "ids": [ + "america/detroit", + "us/michigan" + ], + "tzif": { + "posix": { + "abbr": "EST", + "offset": -18000, + "transition": { + "abbr": "EDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2 + ], + "transitions": [ + -2051202469, + -1724083200, + -880218000, + -769395600, + -765396000, + -684349200, + -671047200, + -80506740, + -68666400, + -52938000, + -37216800, + 104914800, + 120636000, + 126687600, + 152085600, + 167814000, + 183535200, + 199263600, + 215589600, + 230713200, + 247039200, + 262767600, + 278488800, + 294217200, + 309938400, + 325666800, + 341388000, + 357116400, + 372837600, + 388566000, + 404892000, + 420015600, + 436341600, + 452070000, + 467791200, + 483519600, + 499240800, + 514969200, + 530690400, + 544604400, + 562140000, + 576054000, + 594194400, + 607503600, + 625644000, + 638953200, + 657093600, + 671007600, + 688543200, + 702457200, + 719992800, + 733906800, + 752047200, + 765356400, + 783496800, + 796806000, + 814946400, + 828860400, + 846396000, + 860310000, + 877845600, + 891759600, + 909295200, + 923209200, + 941349600, + 954658800, + 972799200, + 986108400, + 1004248800, + 1018162800, + 1035698400, + 1049612400, + 1067148000, + 1081062000, + 1099202400, + 1112511600, + 1130652000, + 1143961200, + 1162101600, + 1173596400, + 1194156000 + ], + "types": [ + { + "offset": -19931 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f9736e8dcd3eb5de-9c17b925c6652d48.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f9736e8dcd3eb5de-9c17b925c6652d48.json new file mode 100644 index 00000000000000..017b9e2cbb27c0 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f9736e8dcd3eb5de-9c17b925c6652d48.json @@ -0,0 +1,238 @@ +{ + "ids": [ + "antarctica/macquarie" + ], + "tzif": { + "posix": { + "abbr": "AEST", + "offset": 36000, + "transition": { + "abbr": "AEDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 4, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 10, + 1, + 0 + ] + }, + "time": 10800 + } + } + }, + "transition_types": [ + 1, + 2, + 2, + 1, + 0, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1 + ], + "transitions": [ + -2214259200, + -1680508800, + -1669892400, + -1665388800, + -1601719200, + -687052800, + -71136000, + -55411200, + -37267200, + -25776000, + -5817600, + 5673600, + 25632000, + 37728000, + 57686400, + 67968000, + 89136000, + 100022400, + 120585600, + 131472000, + 152035200, + 162921600, + 183484800, + 194976000, + 215539200, + 226425600, + 246988800, + 257875200, + 278438400, + 289324800, + 309888000, + 320774400, + 341337600, + 352224000, + 372787200, + 386092800, + 404841600, + 417542400, + 436291200, + 447177600, + 467740800, + 478627200, + 499190400, + 510076800, + 530035200, + 542736000, + 562089600, + 574790400, + 594144000, + 606240000, + 625593600, + 637689600, + 657043200, + 670348800, + 686678400, + 701798400, + 718128000, + 733248000, + 749577600, + 764697600, + 781027200, + 796147200, + 812476800, + 828201600, + 844531200, + 859651200, + 875980800, + 891100800, + 907430400, + 922550400, + 938880000, + 954000000, + 967305600, + 985449600, + 1002384000, + 1017504000, + 1033833600, + 1048953600, + 1065283200, + 1080403200, + 1096732800, + 1111852800, + 1128182400, + 1143907200, + 1159632000, + 1174752000, + 1191686400, + 1207411200, + 1223136000, + 1238860800, + 1254585600, + 1293800400 + ], + "types": [ + { + "offset": 0 + }, + { + "offset": 36000 + }, + { + "offset": 39600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f9878deac6fa797b-63a1fb86a70f62e5.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f9878deac6fa797b-63a1fb86a70f62e5.json new file mode 100644 index 00000000000000..65edcbca472d58 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-f9878deac6fa797b-63a1fb86a70f62e5.json @@ -0,0 +1,181 @@ +{ + "ids": [ + "asia/yerevan" + ], + "tzif": { + "posix": { + "abbr": "+04", + "offset": 14400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4 + ], + "transitions": [ + -1441162680, + -405140400, + 354916800, + 370724400, + 386452800, + 402260400, + 417988800, + 433796400, + 449611200, + 465343200, + 481068000, + 496792800, + 512517600, + 528242400, + 543967200, + 559692000, + 575416800, + 591141600, + 606866400, + 622591200, + 638316000, + 654645600, + 670370400, + 670374000, + 686098800, + 701823600, + 717548400, + 733273200, + 748998000, + 764722800, + 780447600, + 796172400, + 811897200, + 859672800, + 877816800, + 891122400, + 909266400, + 922572000, + 941320800, + 954021600, + 972770400, + 985471200, + 1004220000, + 1017525600, + 1035669600, + 1048975200, + 1067119200, + 1080424800, + 1099173600, + 1111874400, + 1130623200, + 1143324000, + 1162072800, + 1174773600, + 1193522400, + 1206828000, + 1224972000, + 1238277600, + 1256421600, + 1269727200, + 1288476000, + 1301176800, + 1319925600 + ], + "types": [ + { + "offset": 10680 + }, + { + "offset": 10800 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + }, + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fb562061c0f6e08b-c76bafb046d43b7.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fb562061c0f6e08b-c76bafb046d43b7.json new file mode 100644 index 00000000000000..793ebc2a041759 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fb562061c0f6e08b-c76bafb046d43b7.json @@ -0,0 +1,63 @@ +{ + "ids": [ + "pacific/fiji" + ], + "tzif": { + "posix": { + "abbr": "+12", + "offset": 43200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2 + ], + "transitions": [ + -1709985344, + 909842400, + 920124000, + 941896800, + 951573600, + 1259416800, + 1269698400, + 1287842400, + 1299333600, + 1319292000, + 1327154400, + 1350741600, + 1358604000, + 1382796000, + 1390050000, + 1414850400, + 1421503200, + 1446300000 + ], + "types": [ + { + "offset": 42944 + }, + { + "offset": 43200 + }, + { + "offset": 46800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fb66f3417dbb2dfe-e13d26a5a5a0ef65.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fb66f3417dbb2dfe-e13d26a5a5a0ef65.json new file mode 100644 index 00000000000000..fd844e55176c97 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fb66f3417dbb2dfe-e13d26a5a5a0ef65.json @@ -0,0 +1,51 @@ +{ + "ids": [ + "asia/karachi" + ], + "tzif": { + "posix": { + "abbr": "PKT", + "offset": 18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 1, + 3, + 3, + 4, + 3, + 4, + 3 + ], + "transitions": [ + -1988166492, + -862637400, + -764145000, + -576135000, + 38775600, + 1018119600, + 1033840800, + 1212260400, + 1225476000 + ], + "types": [ + { + "offset": 16092 + }, + { + "offset": 19800 + }, + { + "offset": 23400 + }, + { + "offset": 18000 + }, + { + "offset": 21600 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fbccf04b5b2fd7f2-b508b8cbe01e354b.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fbccf04b5b2fd7f2-b508b8cbe01e354b.json new file mode 100644 index 00000000000000..30a52d91a942b3 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fbccf04b5b2fd7f2-b508b8cbe01e354b.json @@ -0,0 +1,71 @@ +{ + "ids": [ + "america/managua" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 3, + 4, + 2 + ], + "transitions": [ + -2524500892, + -1121105688, + 105084000, + 161758800, + 290584800, + 299134800, + 322034400, + 330584400, + 694260000, + 717310800, + 725868000, + 852094800, + 1113112800, + 1128229200, + 1146384000, + 1159682400 + ], + "types": [ + { + "offset": -20708 + }, + { + "offset": -20712 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fc89b67bba9eff21-ed937c5b2210118e.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fc89b67bba9eff21-ed937c5b2210118e.json new file mode 100644 index 00000000000000..50e98b18b43d37 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fc89b67bba9eff21-ed937c5b2210118e.json @@ -0,0 +1,58 @@ +{ + "ids": [ + "asia/kuala_lumpur", + "asia/singapore", + "singapore" + ], + "tzif": { + "posix": { + "abbr": "+08", + "offset": 28800, + "transition": null + }, + "transition_types": [ + 0, + 1, + 2, + 2, + 3, + 4, + 5, + 4, + 6 + ], + "transitions": [ + -2177477725, + -2038200925, + -1167634800, + -1073028000, + -894180000, + -879665400, + -767005200, + 378662400 + ], + "types": [ + { + "offset": 24925 + }, + { + "offset": 25200 + }, + { + "offset": 26400 + }, + { + "offset": 26400 + }, + { + "offset": 27000 + }, + { + "offset": 32400 + }, + { + "offset": 28800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fc9fd017e19a24e0-530492ba8305e348.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fc9fd017e19a24e0-530492ba8305e348.json new file mode 100644 index 00000000000000..056912956ddca5 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fc9fd017e19a24e0-530492ba8305e348.json @@ -0,0 +1,278 @@ +{ + "ids": [ + "america/indiana/knox", + "america/knox_in", + "us/indiana-starke" + ], + "tzif": { + "posix": { + "abbr": "CST", + "offset": -21600, + "transition": { + "abbr": "CDT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 2, + 1, + 2, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 2, + 3, + 1, + 2, + 3, + 1, + 2, + 3, + 1 + ], + "transitions": [ + -2717647200, + -1633276800, + -1615136400, + -1601827200, + -1583686800, + -880214400, + -769395600, + -765392400, + -715795200, + -702493200, + -684345600, + -671043600, + -652896000, + -639594000, + -620841600, + -608144400, + -589392000, + -576090000, + -557942400, + -544640400, + -526492800, + -513190800, + -495043200, + -481741200, + -463593600, + -447267600, + -431539200, + -415818000, + -400089600, + -386787600, + -368640000, + -355338000, + -337190400, + -321469200, + -305740800, + -289414800, + -273686400, + -257965200, + -242236800, + -195066000, + -84384000, + -68662800, + -52934400, + -37213200, + -21484800, + -5763600, + 9964800, + 25686000, + 41414400, + 57740400, + 73468800, + 89190000, + 104918400, + 120639600, + 126691200, + 152089200, + 162374400, + 183538800, + 199267200, + 215593200, + 230716800, + 247042800, + 262771200, + 278492400, + 294220800, + 309942000, + 325670400, + 341391600, + 357120000, + 372841200, + 388569600, + 404895600, + 420019200, + 436345200, + 452073600, + 467794800, + 483523200, + 499244400, + 514972800, + 530694000, + 544608000, + 562143600, + 576057600, + 594198000, + 607507200, + 625647600, + 638956800, + 657097200, + 671011200, + 688546800, + 1143961200, + 1143964800, + 1162105200, + 1173600000, + 1194159600 + ], + "types": [ + { + "offset": -20790 + }, + { + "offset": -21600 + }, + { + "offset": -18000 + }, + { + "offset": -18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fd03910821368f68-fa54b0ea0f2a14a7.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fd03910821368f68-fa54b0ea0f2a14a7.json new file mode 100644 index 00000000000000..0519e42c2f535a --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fd03910821368f68-fa54b0ea0f2a14a7.json @@ -0,0 +1,169 @@ +{ + "ids": [ + "america/argentina/mendoza", + "america/mendoza" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 4, + 5, + 3, + 4, + 5, + 3, + 4, + 5, + 2, + 3, + 4, + 2, + 3, + 4, + 2, + 5, + 3, + 4, + 3, + 4, + 3, + 4, + 2, + 3, + 4, + 5, + 3, + 4 + ], + "transitions": [ + -2372095484, + -1567453392, + -1233432000, + -1222981200, + -1205956800, + -1194037200, + -1172865600, + -1162501200, + -1141329600, + -1130965200, + -1109793600, + -1099429200, + -1078257600, + -1067806800, + -1046635200, + -1036270800, + -1015099200, + -1004734800, + -983563200, + -973198800, + -952027200, + -941576400, + -931032000, + -900882000, + -890337600, + -833749200, + -827265600, + -752274000, + -733780800, + -197326800, + -190843200, + -184194000, + -164491200, + -152658000, + -132955200, + -121122000, + -101419200, + -86821200, + -71092800, + -54766800, + -39038400, + -23317200, + -7588800, + 128142000, + 136605600, + 596948400, + 605066400, + 624423600, + 636516000, + 655963200, + 667796400, + 687499200, + 699418800, + 719380800, + 731469600, + 938919600, + 952052400, + 1085281200, + 1096171200, + 1198983600, + 1205632800 + ], + "types": [ + { + "offset": -16516 + }, + { + "offset": -15408 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fd823ec71e5980ce-fb04074f1843d568.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fd823ec71e5980ce-fb04074f1843d568.json new file mode 100644 index 00000000000000..4b7eff6aad2787 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fd823ec71e5980ce-fb04074f1843d568.json @@ -0,0 +1,31 @@ +{ + "ids": [ + "antarctica/mawson" + ], + "tzif": { + "posix": { + "abbr": "+05", + "offset": 18000, + "transition": null + }, + "transition_types": [ + 1, + 2 + ], + "transitions": [ + -501206400, + 1255809600 + ], + "types": [ + { + "offset": 0 + }, + { + "offset": 21600 + }, + { + "offset": 18000 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fe6e0efb644eced9-f06be10a091cfb41.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fe6e0efb644eced9-f06be10a091cfb41.json new file mode 100644 index 00000000000000..aa384805d2ab72 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fe6e0efb644eced9-f06be10a091cfb41.json @@ -0,0 +1,62 @@ +{ + "ids": [ + "america/lima" + ], + "tzif": { + "posix": { + "abbr": "-05", + "offset": -18000, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2 + ], + "transitions": [ + -2524503108, + -1938538284, + -1009825200, + -1002052800, + -986756400, + -971035200, + -955306800, + -939585600, + 504939600, + 512712000, + 536475600, + 544248000, + 631170000, + 638942400, + 757400400, + 765172800 + ], + "types": [ + { + "offset": -18492 + }, + { + "offset": -18516 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fe8583499fe1cbb8-a7cf0ef087069495.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fe8583499fe1cbb8-a7cf0ef087069495.json new file mode 100644 index 00000000000000..ab775569f30b0b --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fe8583499fe1cbb8-a7cf0ef087069495.json @@ -0,0 +1,39 @@ +{ + "ids": [ + "africa/abidjan", + "africa/accra", + "africa/bamako", + "africa/banjul", + "africa/conakry", + "africa/dakar", + "africa/freetown", + "africa/lome", + "africa/nouakchott", + "africa/ouagadougou", + "africa/timbuktu", + "atlantic/reykjavik", + "atlantic/st_helena", + "iceland" + ], + "tzif": { + "posix": { + "abbr": "GMT", + "offset": 0, + "transition": null + }, + "transition_types": [ + 1 + ], + "transitions": [ + -1830383032 + ], + "types": [ + { + "offset": -968 + }, + { + "offset": 0 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fed5f41e1701789d-daf8820af0fe9430.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fed5f41e1701789d-daf8820af0fe9430.json new file mode 100644 index 00000000000000..f3fa17f6c0d9e1 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fed5f41e1701789d-daf8820af0fe9430.json @@ -0,0 +1,19 @@ +{ + "ids": [ + "etc/gmt+3" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": null + }, + "transition_types": [], + "transitions": [], + "types": [ + { + "offset": -10800 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fef149820a82a100-d2fff4282c3ad1f4.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fef149820a82a100-d2fff4282c3ad1f4.json new file mode 100644 index 00000000000000..c3dc53bee57efd --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-fef149820a82a100-d2fff4282c3ad1f4.json @@ -0,0 +1,101 @@ +{ + "ids": [ + "asia/baku" + ], + "tzif": { + "posix": { + "abbr": "+04", + "offset": 14400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 2, + 4, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4 + ], + "transitions": [ + -1441163964, + -405140400, + 354916800, + 370724400, + 386452800, + 402260400, + 417988800, + 433796400, + 449611200, + 465343200, + 481068000, + 496792800, + 512517600, + 528242400, + 543967200, + 559692000, + 575416800, + 591141600, + 606866400, + 622591200, + 638316000, + 654645600, + 670370400, + 670374000, + 686098800, + 701823600, + 717548400, + 828234000, + 846378000, + 859680000, + 877824000 + ], + "types": [ + { + "offset": 11964 + }, + { + "offset": 10800 + }, + { + "offset": 14400 + }, + { + "offset": 18000 + }, + { + "offset": 14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ff54b8a04d630c85-302a593cf4d0c55a.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ff54b8a04d630c85-302a593cf4d0c55a.json new file mode 100644 index 00000000000000..d242007bcbe260 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ff54b8a04d630c85-302a593cf4d0c55a.json @@ -0,0 +1,192 @@ +{ + "ids": [ + "asia/barnaul" + ], + "tzif": { + "posix": { + "abbr": "+07", + "offset": 25200, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 2, + 4, + 2, + 4, + 1, + 3, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 3, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4, + 1, + 2, + 4 + ], + "transitions": [ + -1579844100, + -1247551200, + 354906000, + 370713600, + 386442000, + 402249600, + 417978000, + 433785600, + 449600400, + 465332400, + 481057200, + 496782000, + 512506800, + 528231600, + 543956400, + 559681200, + 575406000, + 591130800, + 606855600, + 622580400, + 638305200, + 654634800, + 670359600, + 670363200, + 686088000, + 695764800, + 701809200, + 717534000, + 733258800, + 748983600, + 764708400, + 780433200, + 796158000, + 801590400, + 811886400, + 828216000, + 846360000, + 859665600, + 877809600, + 891115200, + 909259200, + 922564800, + 941313600, + 954014400, + 972763200, + 985464000, + 1004212800, + 1017518400, + 1035662400, + 1048968000, + 1067112000, + 1080417600, + 1099166400, + 1111867200, + 1130616000, + 1143316800, + 1162065600, + 1174766400, + 1193515200, + 1206820800, + 1224964800, + 1238270400, + 1256414400, + 1269720000, + 1288468800, + 1301169600, + 1414263600, + 1459022400 + ], + "types": [ + { + "offset": 20100 + }, + { + "offset": 21600 + }, + { + "offset": 25200 + }, + { + "offset": 28800 + }, + { + "offset": 25200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ffb42884e83683a9-7d164a9bb116efe3.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ffb42884e83683a9-7d164a9bb116efe3.json new file mode 100644 index 00000000000000..c5a59270882c14 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ffb42884e83683a9-7d164a9bb116efe3.json @@ -0,0 +1,147 @@ +{ + "ids": [ + "america/miquelon" + ], + "tzif": { + "posix": { + "abbr": "-03", + "offset": -10800, + "transition": { + "abbr": "-02", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 3, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2 + ], + "transitions": [ + -1847650520, + 326001600, + 536468400, + 544593600, + 562132800, + 576046800, + 594187200, + 607496400, + 625636800, + 638946000, + 657086400, + 671000400, + 688536000, + 702450000, + 719985600, + 733899600, + 752040000, + 765349200, + 783489600, + 796798800, + 814939200, + 828853200, + 846388800, + 860302800, + 877838400, + 891752400, + 909288000, + 923202000, + 941342400, + 954651600, + 972792000, + 986101200, + 1004241600, + 1018155600, + 1035691200, + 1049605200, + 1067140800, + 1081054800, + 1099195200, + 1112504400, + 1130644800, + 1143954000, + 1162094400, + 1173589200, + 1194148800 + ], + "types": [ + { + "offset": -13480 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ffd87968a303e340-9dec629c1fbdf2dc.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ffd87968a303e340-9dec629c1fbdf2dc.json new file mode 100644 index 00000000000000..ca1740bd142674 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ffd87968a303e340-9dec629c1fbdf2dc.json @@ -0,0 +1,72 @@ +{ + "ids": [ + "america/santo_domingo" + ], + "tzif": { + "posix": { + "abbr": "AST", + "offset": -14400, + "transition": null + }, + "transition_types": [ + 1, + 2, + 3, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 4, + 2, + 3, + 5, + 2, + 3, + 5 + ], + "transitions": [ + -2524504824, + -1159773600, + -100119600, + -89668800, + -5770800, + 4422600, + 25678800, + 33193800, + 57733200, + 64816200, + 89182800, + 96438600, + 120632400, + 127974600, + 152082000, + 972799200, + 975823200 + ], + "types": [ + { + "offset": -16776 + }, + { + "offset": -16800 + }, + { + "offset": -18000 + }, + { + "offset": -14400 + }, + { + "offset": -16200 + }, + { + "offset": -14400 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ffd87e4e007fc8e2-442f240405f9b3e2.json b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ffd87e4e007fc8e2-442f240405f9b3e2.json new file mode 100644 index 00000000000000..cb855c3f5c4047 --- /dev/null +++ b/deps/temporal/provider/src/data/debug/zoneinfo/tzifs/tzif-ffd87e4e007fc8e2-442f240405f9b3e2.json @@ -0,0 +1,371 @@ +{ + "ids": [ + "america/goose_bay" + ], + "tzif": { + "posix": { + "abbr": "AST", + "offset": -14400, + "transition": { + "abbr": "ADT", + "end": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 11, + 1, + 0 + ] + }, + "time": 7200 + }, + "savings": 3600, + "start": { + "date": { + "day": null, + "kind": "MonthWeekDay", + "mwd": [ + 3, + 2, + 0 + ] + }, + "time": 7200 + } + } + }, + "transition_types": [ + 1, + 2, + 1, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 4, + 3, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 7, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6, + 5, + 6 + ], + "transitions": [ + -2713895900, + -1632076148, + -1615145348, + -1096921748, + -1061670600, + -1048973400, + -1030221000, + -1017523800, + -998771400, + -986074200, + -966717000, + -954624600, + -935267400, + -922570200, + -903817800, + -891120600, + -872368200, + -769395600, + -765401400, + -746044200, + -733347000, + -714594600, + -701897400, + -683145000, + -670447800, + -651695400, + -638998200, + -619641000, + -606943800, + -589401000, + -576099000, + -557951400, + -544649400, + -526501800, + -513199800, + -495052200, + -481750200, + -463602600, + -450300600, + -431548200, + -418246200, + -400098600, + -386796600, + -368649000, + -355347000, + -337199400, + -323897400, + -305749800, + -289423800, + -273695400, + -257974200, + -242245800, + -226524600, + -210796200, + -195075000, + -179346600, + -163625400, + -147897000, + -131571000, + -119903400, + -116445600, + -100119600, + -84391200, + -68670000, + -52941600, + -37220400, + -21492000, + -5770800, + 9957600, + 25678800, + 41407200, + 57733200, + 73461600, + 89182800, + 104911200, + 120632400, + 136360800, + 152082000, + 167810400, + 183531600, + 199260000, + 215586000, + 230709600, + 247035600, + 262764000, + 278485200, + 294213600, + 309934800, + 325663200, + 341384400, + 357112800, + 372834000, + 388562400, + 404888400, + 420012000, + 436338000, + 452066400, + 467787600, + 483516000, + 499237200, + 514965600, + 530686800, + 544593660, + 562129260, + 576043260, + 594180060, + 607492860, + 625633260, + 638942460, + 657082860, + 670996860, + 688532460, + 702446460, + 719982060, + 733896060, + 752036460, + 765345660, + 783486060, + 796795260, + 814935660, + 828849660, + 846385260, + 860299260, + 877834860, + 891748860, + 909284460, + 923198460, + 941338860, + 954648060, + 972788460, + 986097660, + 1004238060, + 1018152060, + 1035687660, + 1049601660, + 1067137260, + 1081051260, + 1099191660, + 1112500860, + 1130641260, + 1143950460, + 1162090860, + 1173585660, + 1194145260, + 1205035260, + 1225594860, + 1236484860, + 1257044460, + 1268539260, + 1289098860, + 1299988860 + ], + "types": [ + { + "offset": -14500 + }, + { + "offset": -12652 + }, + { + "offset": -9052 + }, + { + "offset": -12600 + }, + { + "offset": -9000 + }, + { + "offset": -14400 + }, + { + "offset": -10800 + }, + { + "offset": -7200 + } + ] + } +} \ No newline at end of file diff --git a/deps/temporal/provider/src/data/iana_normalizer.rs.data b/deps/temporal/provider/src/data/iana_normalizer.rs.data new file mode 100644 index 00000000000000..40aa9cb95f588c --- /dev/null +++ b/deps/temporal/provider/src/data/iana_normalizer.rs.data @@ -0,0 +1,18 @@ +//@generated +// (by `bakeddata` binary in temporal_rs, using `databake`) + +#[macro_export] +macro_rules! iana_normalizer_singleton { + ($providername:ident) => { + pub const $providername : & 'static timezone_provider::IanaIdentifierNormalizer = + & timezone_provider::IanaIdentifierNormalizer { version : + alloc::borrow::Cow::Borrowed("2025b"), available_id_index : + zerotrie::ZeroAsciiIgnoreCaseTrie { store : unsafe { + zerovec::ZeroVec::from_bytes_unchecked(b"\xE1sabceghijklmnprstuwz\x0F\x0F\x0F\x13\x13\x13\x13\x13\x13\x13\x14\x14\x16\x16\x16\x16\x16\x16\x03*\xC2\x15>M\xD7\xE6\xF0\xF6*=\x17 *1\xC8\xD3\xE1gfmnrstu\x02\t\t\t\r\x0E\x1A(\xA9\xBC\x83\trica/\xE1rabcdefghjklmnopstw\0\0\0\0\0\0\0\0\0\x01\x01\x01\x01\x01\x01\x01\x01/i\x89\xB1\xBA\xC3\xCC\xD3\xE7\x0C@u\x9C\xA8\xB3\xBC\xD6\xC5bcdls\x06\n\x14\x1Aidjan\x80cra\x81dis_ababa\x82giers\x83m\xC2ae\x03ra\x84ra\x85\xC5ailru\x12\x17\x1E(\xC2mn\x04ako\x86\xC2gj\x03ui\x87ul\x88ssau\x89antyre\x8Aazzaville\x8Bjumbura\x8C\xC3aeo\x0F\x13\xC2is\x03ro\x8Dablanca\x8Euta\x8Fnakry\x90\0\xC3ajo\x14\x1C\xC2kr\x04ar\x90\x01_es_salaam\x90\x02ibouti\x90\x03uala\x90\x04l_aaiun\x90\x05reetown\x90\x06aborone\x90\x07arare\x90\x08\xC2ou\x0Channesburg\x90\tba\x90\n\xC3ahi\x07\x0Fmpala\x90\x0Bartoum\x90\x0C\xC2gn\x05ali\x90\rshasa\x90\x0E\xC4aiou\x05\x0F\x13gos\x90\x0Fbreville\x90\x10me\x90\x11\xC3abs\x05\x0Enda\x90\x12umbashi\x90\x13aka\x90\x14\xC3abo\x15\x1C\xC3lps\x05\nabo\x90\x15uto\x90\x16eru\x90\x17abane\x90\x18\xC2gn\x08adishu\x90\x19rovia\x90\x1A\xC4adio\x07\x0F\x15irobi\x90\x1Bjamena\x90\x1Camey\x90\x1Duakchott\x90\x1Euagadougou\x90\x1Forto-novo\x90 ao_tome\x90!\xC3iru\x08\x0Fmbuktu\x90\"ipoli\x90#nis\x90$indhoek\x90%erica/\xE1vabcdefghijklmnoprstvwy\0\x01\x01\x02\x02\x02\x02\x02\x03\x03\x03\x03\x04\x04\x04\x05\x05\x06\x06\x06\x06\xE7F\xF4-Xv\xD1\xEEg\x7F\xB7\xEC\x92\xEC\xF4g\xB0M\x87\x9A\xB0\xC5dnrst\x04\x1F\xC7\xCFak\x90&\xC3cgt\x08\x0Fhorage\x90'uilla\x90(igua\x90)\xC3agu\x08\x9Eguaina\x90*entina/\xC9bcjlmrstu\r17@HUmuuenos_aires\x90+\xC2ao\ttamarca\x90,\xC2mr\rodrivadavia\x90-doba\x90.ujuy\x90/a_rioja\x900endoza\x901io_gallegos\x902a\xC2ln\x04ta\x903_\xC2jl\x05uan\x904uis\x905ucuman\x906shuaia\x907ba\x908uncion\x909\xC2ik\x07kokan\x90:a\x90;\xC5aelou\x1A&2I\xC2hr\x0Fia\x90<_banderas\x90=bados\x90>l\xC2ei\x03m\x90?ze\x90@anc-sablon\x90A\xC3agi\x08\r_vista\x90Bota\x90Cse\x90Denos_aires\x90E\xC6ahioruCTa\x8C\x93\xC5mnrty\x19\x1E$,\xC2bp\x0Bridge_bay\x90Fo_grande\x90Gcun\x90Hacas\x90Iamarca\x90J\xC2em\x05nne\x90Kan\x90Li\xC2ch\x05ago\x90Muahua\x90Nudad_juarez\x90O\xC3rsy\x14\x1D\xC2ad\x0Bl_harbour\x90Poba\x90Qta_rica\x90Rhaique\x90Seston\x90T\xC2ir\x05aba\x90Uacao\x90V\xC3aeo\x1C+\xC2nw\x0Bmarkshavn\x90Wson\x90X_creek\x90Y\xC2nt\x05ver\x90Zroit\x90[minica\x90\\\xC4diln\x08\x10\x1Bmonton\x90]runepe\x90^_salvador\x90_senada\x90`ort\xC2_a\x11\xC2nw\x07elson\x90aayne\x90bleza\x90c\xC4loru\t\x1B.ace_bay\x90d\xC2do\x06thab\x90ese_bay\x90f\xC2ae\tnd_turk\x90gnada\x90h\xC2ay\x1C\xC3dty\x08\x0Feloupe\x90iemala\x90jaquil\x90kana\x90l\xC2ae\x0F\xC2lv\x06ifax\x90mana\x90nrmosillo\x90o\xC2nqn\xC2dueiana\xC2/pW\xC7ikmptvw\r\x12\x1A%/Andianapolis\x90pnox\x90qarengo\x90retersburg\x90sell_city\x90t\xC2ei\x05vay\x90uncennes\x90vinamac\x90wolis\x90xvik\x90yaluit\x90z\xC2au\x07maica\x90{\xC2jn\x04uy\x90|eau\x90}\xC3enr!(ntucky/\xC2lm\x0Bouisville\x90~onticello\x90\x7Fox_in\x91\0alendijk\x91\x01\xC3aio\x06\n_paz\x91\x02ma\x91\x03\xC3suw\n\x13_angeles\x91\x04isville\x91\x05er_princes\x91\x06\xC4aeio;ks\xC5cnrtz\x05\x11\"*eio\x91\x07a\xC2gu\x04ua\x91\x08s\x91\t\xC2it\x05got\x91\ninique\x91\x0Bamoros\x91\x0Catlan\x91\r\xC4nrtx\x10\x15\x1E\xC2do\x05oza\x91\x0Eminee\x91\x0Fida\x91\x10lakatla\x91\x11ico_city\x91\x12quelon\x91\x13n\xC2ct\x05ton\x91\x14\xC3ers\x0F\x14\xC2rv\x05rey\x91\x15ideo\x91\x16eal\x91\x17errat\x91\x18\xC5aeiou\x06\x0E\x15Lssau\x91\x19w_york\x91\x1Apigon\x91\x1B\xC2mr\x03e\x91\x1C\xC2ot\x05nha\x91\x1Dh_dakota/\xC3bcn\x07\x0Eeulah\x91\x1Eenter\x91\x1Few_salem\x91 uk\x91!jinaga\x91\"\xC4ahou\x1E%R\xC2nr\x11\xC2ag\x04ma\x91#nirtung\x91$amaribo\x91%oenix\x91&rt\xC3-_o\x0B\x15au-prince\x91'of_spain\x91(_\xC2av\x05cre\x91)elho\x91*\xC2en\nrto_rico\x91+ta_arenas\x91,\xC4aeio\x190:\xC2in\nny_river\x91-kin_inlet\x91.\xC3cgs\x05\nife\x91/ina\x910olute\x911o_branco\x912sario\x913\xC6achitw2>FK\x84\xC2no&t\xC3aio\x10\x15\xC2_r\x08isabel\x914em\x915ago\x916_domingo\x917_paulo\x918oresbysund\x919iprock\x91:tka\x91;_\xC6bjkltv\x0B\x11\x17\x1D$arthelemy\x91ucia\x91?homas\x91@incent\x91Aift_current\x91B\xC4ehio\x0B\x1C#gucigalpa\x91Cu\xC2ln\x03e\x91Dder_bay\x91Ejuana\x91Fr\xC2ot\x05nto\x91Gola\x91H\xC2ai\tncouver\x91Irgin\x91J\xC2hi\nitehorse\x91Knnipeg\x91L\xC2ae\x07kutat\x91Mllowknife\x91Ntarctica/\xC8cdmprstv\x06\x1D9@H[aasey\x91O\xC2au\x05vis\x91Pmontdurville\x91Q\xC2ac\x11\xC2cw\x08quarie\x91Rson\x91Smurdo\x91Talmer\x91Uothera\x91V\xC2oy\nuth_pole\x91Wowa\x91Xroll\x91Yostok\x91Zctic/longyearbyen\x91[ia/\xE1uabcdfghijkmnopqrstuvy\0\0\0\0\0\0\x01\x01\x01\x01\x01\x02\x02\x02\x02\x02\x02\x03\x03\x03G\x87\xC1\xF0\xFA\xFF,?]\xD0\xFD\x1F+Miz\xC1\x0BD\\\xC7dlmnqst\x04\n\x0F\x15!3en\x91\\maty\x91]man\x91^adyr\x91_t\xC2ao\x03u\x91`be\x91ah\xC2gk\x06abat\x91bhabad\x91cyrau\x91d\xC4aeir%+2\xC5ghknr\x06\x0C\x0F\x15hdad\x91erain\x91fu\x91ggkok\x91hnaul\x91iirut\x91jshkek\x91kunei\x91l\xC3aho\x08-lcutta\x91m\xC3iou\x04\x17ta\x91n\xC2in\x08balsan\x91ogqing\x91pngking\x91qlombo\x91r\xC4ahiu\x0F\x14\x18\xC2cm\x04ca\x91sascus\x91taka\x91uli\x91v\xC2bs\x04ai\x91whanbe\x91xamagusta\x91yaza\x91z\xC3aeo\x06\x0Crbin\x91{bron\x91|\xC3_nv\n\x12chi_minh\x91}g_kong\x91~d\x91\x7F\xC2rs\x07kutsk\x92\0tanbul\x92\x01\xC2ae\x11\xC2ky\x06arta\x92\x02apura\x92\x03rusalem\x92\x04\xC5ahoru3;BM\xC5bmrst\x04\x0C\x12\x18ul\x92\x05chatka\x92\x06achi\x92\x07hgar\x92\x08\xC2hm\x07mandu\x92\tandu\x92\nandyga\x92\x0Blkata\x92\x0Casnoyarsk\x92\r\xC3acw\x0B\x11la_lumpur\x92\x0Ehing\x92\x0Fait\x92\x10\xC2au#\xC4cgkn\t\x0F\x16a\xC2ou\x02\x92\x11\x92\x12adan\x92\x13assar\x92\x14ila\x92\x15scat\x92\x16\xC2io\x07cosia\x92\x17vo\xC2ks\tuznetsk\x92\x18ibirsk\x92\x19\xC2mr\x04sk\x92\x1Aal\x92\x1B\xC3hoy\n\x13nom_penh\x92\x1Cntianak\x92\x1Dongyang\x92\x1E\xC3aoy\x05\rtar\x92\x1Fstanay\x92 zylorda\x92!\xC2ai\x07ngoon\x92\"yadh\x92#\xC5aehir\x1A\x1F'0\xC3ikm\x05\x0Cgon\x92$halin\x92%arkand\x92&oul\x92'anghai\x92(ngapore\x92)ednekolymsk\x92*\xC5abeho\x10\x17'4\xC2is\x05pei\x92+hkent\x92,ilisi\x92-\xC2hl\x05ran\x92._aviv\x92/im\xC2bp\x03u\x920hu\x921\xC2km\x04yo\x922sk\x923\xC4jlrs\r#)ung_pandang\x924a\xC2an\tnbaatar\x925_bator\x926umqi\x927t-nera\x928\xC2il\tentiane\x929adivostok\x92:\xC2ae\x0F\xC2kn\x06utsk\x92;gon\x92<\xC2kr\x0Caterinburg\x92=evan\x92>lantic/\xC8abcfjmrs\x07\x0F\"0:BLzores\x92?ermuda\x92@a\xC2np\x05ary\x92Ae_verde\x92Ba\xC2er\x05roe\x92Coe\x92Dan_mayen\x92Eadeira\x92Feykjavik\x92G\xC2ot\ruth_georgia\x92H\xC2_a\x08helena\x92Inley\x92Jstralia/\xD0abcdehlmnpqstvwy\x0F%7>DKeo{\x81\x8C\x9B\xA4\xAD\xB2\xC2cd\x03t\x92Kelaide\x92Lr\xC2io\x07sbane\x92Mken_hill\x92N\xC2au\x08nberra\x92Orrie\x92Parwin\x92Qucla\x92Robart\x92S\xC3hio\x03\x0Bi\x92Tndeman\x92Urd_howe\x92Velbourne\x92W\xC2os\x05rth\x92Yw\x92Xerth\x92Zueensland\x92[\xC2oy\x05uth\x92\\dney\x92]asmania\x92^ictoria\x92_est\x92`ancowinna\x92arazil/\xC4adew\x05\x0F\x14cre\x92benoronha\x92cast\x92dest\x92e\xC5aehsu_b\x83\x8Anada/\xC8acemnpsy\t\x11\x19\"/7Dtlantic\x92hentral\x92iastern\x92jountain\x92kewfoundland\x92lacific\x92maskatchewan\x92nukon\x92ot\x92file/\xC2ce\x0Continental\x92pasterisland\x92qt6cdt\x92gba\x92r\xE1fegistu\0\0\0\0\0\x03\x08\x0C\x15\xBFt\x92sypt\x92vre\x92wt\x92t5edt\x92uc/\xC3guz\x88\x9D\xC2mr{t\x92x\xC3+-04p\xCA0123456789\x02\x10\x12\x14\x16\x18\x1A\x1C\x1E\x92y\x92z\xC3012\x02\x04\x92{\x92|\x92}\x92~\x92\x7F\x93\0\x93\x01\x93\x02\x93\x03\x93\x04\x93\x05\xCA0123456789\x02\x18\x1A\x1C\x1E \"$&\x93\x06\x93\x07\xC501234\x02\x04\x06\x08\x93\x08\x93\t\x93\n\x93\x0B\x93\x0C\x93\r\x93\x0E\x93\x0F\x93\x10\x93\x11\x93\x12\x93\x13\x93\x14\x93\x15eenwich\x93\x16\xC3cnt\x03\x0Ct\x93\x17iversal\x93\x19c\x93\x18ulu\x93\x1Arope/\xE1uabcdghijklmnoprstuvwz\0\0\0\0\0\0\0\0\0\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x02'u\x8B\x92\xA7\xB0\xC6\xCD\xED\x14DLQkw\xC1\xDA\xEF\x1B\"\xC4mnst\t\x10\x19sterdam\x93\x1Bdorra\x93\x1Ctrakhan\x93\x1Dhens\x93\x1E\xC3eru\x18,\xC2lr\x0F\xC2fg\x05ast\x93\x1Frade\x93 lin\x93!\xC2au\ttislava\x93\"ssels\x93#\xC3cds\x08\x0Fharest\x93$apest\x93%ingen\x93&\xC2ho\x08isinau\x93'penhagen\x93(ublin\x93)\xC2iu\tbraltar\x93*ernsey\x93+elsinki\x93,s\xC2lt\ne_of_man\x93-anbul\x93.ersey\x93/\xC3aiy\x0B\x16liningrad\x930\xC2er\x03v\x931ov\x932iv\x933\xC4ijou\x06\x0F\x15sbon\x934ubljana\x935ndon\x936xembourg\x937\xC3aio\x17\x1C\xC3dlr\x05\trid\x938ta\x939iehamn\x93:nsk\x93;\xC2ns\x05aco\x93slo\x93?\xC3aor\x05\x0Eris\x93@dgorica\x93Aague\x93B\xC2io\x04ga\x93Cme\x93D\xC5aikot\",27\xC3mnr\x05\x0Eara\x93E_marino\x93Fa\xC2jt\x05evo\x93Gov\x93Hmferopol\x93Iopje\x93Jfia\x93Kockholm\x93L\xC2ai\x07llinn\x93Mra\xC2ns\x03e\x93Npol\x93O\xC2lz\tyanovsk\x93Phgorod\x93Q\xC3aio\x0E\x1D\xC2dt\x04uz\x93Rican\x93S\xC2el\x05nna\x93Tnius\x93Ulgograd\x93Varsaw\x93W\xC2au\x12\xC2gp\x05reb\x93Xorozhye\x93Yrich\x93Z\xC3bmr\t\x1A\x93[-eire\x93\\t\x93]\xC3+-0\x03\x060\x93^0\x93_\x93`eenwich\x93a\xC2os\x08ngkong\x93ct\x93b\xC4cnrs\x07x|eland\x93ddian/\xC5ackmr\r/9Zntananarivo\x93e\xC2ho\x11\xC2ar\x05gos\x93fistmas\x93g\xC2cm\x04os\x93horo\x93ierguelen\x93ja\xC4hluy\x03\n\x12e\x93kdives\x93lritius\x93motte\x93neunion\x93oan\x93prael\x93qa\xC2mp\x06aica\x93ran\x93swajalein\x93tibya\x93u\xC2es'\xC2tx\x02\x93vico/\xC2bg\x11aja\xC2ns\x06orte\x93yur\x93zeneral\x93{t\x93w7mdt\x93x\xC2az\x06vajo\x93~\x93|-chat\x93}\xE1daors\x01\x01\x01\xB4\xC4\xC7cific/\xE1qabcefghjkmnprstwy\0\0\0\0\0\0\0\0\0\0\0\x01\x01\x01\x01\x01\x10\x1D,F_\x85\x8E\x97\xBE\xD9\xF71;Ijw\xC2pu\x04ia\x94\x01ckland\x94\x02ougainville\x94\x03h\xC2au\x06tham\x94\x04uk\x94\x05\xC3afn\x06\x0Bster\x94\x06ate\x94\x07derbury\x94\x08\xC3aiu\x07\x0Bkaofo\x94\tji\x94\nnafuti\x94\x0B\xC2au\x12\xC2lm\x08apagos\x94\x0Cbier\x94\ra\xC2dm\talcanal\x94\x0E\x94\x0Fonolulu\x94\x10ohnston\x94\x11\xC4aiow\x06\x10\x16nton\x94\x12ritimati\x94\x13srae\x94\x14ajalein\x94\x15\xC2ai\x11\xC2jr\x05uro\x94\x16quesas\x94\x17dway\x94\x18\xC3aio\x05\turu\x94\x19ue\x94\x1A\xC2ru\x06folk\x94\x1Bmea\x94\x1C\xC3aio\x10\x18\xC2gl\x08o_pago\x94\x1Dau\x94\x1Etcairn\x94\x1F\xC3hnr\x06\x0Bnpei\x94 ape\x94!t_moresby\x94\"arotonga\x94#a\xC2im\x05pan\x94$oa\x94%\xC3aor\x0E\x17\xC2hr\x05iti\x94&awa\x94'ngatapu\x94(uk\x94)a\xC2kl\x03e\x94*lis\x94+ap\x94,\xC2lr\x05and\x94-tugal\x94.c\x93\x7Ft8pdt\x94\0o\xC2ck\x02\x94/\x940ingapore\x941urkey\x942\xC4cnst\x03\x0C\x8Ct\x943iversal\x94A/\xC8acehimps\x1B#7>Mai\xC2lr\x10\xC2ae\x05ska\x944utian\x945izona\x946entral\x947ast\xC2-e\tindiana\x948rn\x949awaii\x94:ndiana-starke\x94;\xC2io\x08chigan\x94amoa\x94?c\x94@\xC2-e\x04su\x94Bt\x94Culu\x94D") + }, }, non_canonical_identifiers : unsafe { + zerovec::ZeroVec::from_bytes_unchecked(b"\x01\0\0\0\0\0\0\0\x02\0\0\0+\0\0\0\x04\0\0\0+\0\0\0\x05\0\0\0+\0\0\0\x06\0\0\0\0\0\0\0\x07\0\0\0\x1F\0\0\0\x08\0\0\0\0\0\0\0\n\0\0\0&\0\0\0\x0B\0\0\0\x1F\0\0\0\x0C\0\0\0&\0\0\0\x10\0\0\0\0\0\0\0\x11\0\0\0\0\0\0\0\x12\0\0\0+\0\0\0\x13\0\0\0+\0\0\0\x14\0\0\0\x1F\0\0\0\x16\0\0\0\0\0\0\0\x17\0\0\0&\0\0\0\x18\0\0\0&\0\0\0\x1B\0\0\0+\0\0\0\x1D\0\0\0&\0\0\0\x1E\0\0\0\x1F\0\0\0 \0\0\0\x1F\0\0\0!\0\0\0\0\0\0\0\"\0\0\0\x1F\0\0\0#\0\0\0&\0\0\0$\0\0\0&\0\0\0%\0\0\0\x1F\0\0\0'\0\0\0\x19\0\0\0(\0\0\0\x19\0\0\0)\0\0\0+\0\0\0-\0\0\0\x1F\0\0\0.\0\0\0\0\0\0\0/\0\0\0\0\0\0\x000\0\0\0\x1F\0\0\x002\0\0\0\0\0\0\08\0\0\0\xBB\0\0\09\0\0\0\xBB\0\0\0=\0\0\0<\0\0\0H\0\0\0\xBB\0\0\0J\0\0\0\xB3\0\0\0K\0\0\x006\0\0\0Q\0\0\0\xBB\0\0\0U\0\0\0;\0\0\0Z\0\0\0<\0\0\0\\\0\0\0\xB3\0\0\0`\0\0\0\xB3\0\0\0a\0\0\0>\0\0\0d\0\0\0\xB6\0\0\0f\0\0\0\xBB\0\0\0l\0\0\0\xBB\0\0\0p\0\0\0\xD6\0\0\0r\0\0\0\x80\0\0\0u\0\0\0\xB1\0\0\0x\0\0\0\xBB\0\0\0y\0\0\0\xBB\0\0\0\x88\0\0\0\x80\0\0\0\x8C\0\0\0?\0\0\0\x90\0\0\0\x81\0\0\0\x91\0\0\0\xBB\0\0\0\x95\0\0\0\x8E\0\0\0\x96\0\0\0\xBB\0\0\0\x9A\0\0\0\xBB\0\0\0\x9E\0\0\0A\0\0\0\xA7\0\0\0\xD7\0\0\0\xA8\0\0\0\xBB\0\0\0\xA9\0\0\0\xD7\0\0\0\xAB\0\0\0\xD7\0\0\0\xB4\0\0\0\x8A\0\0\0\xB8\0\0\0\xBB\0\0\0\xB9\0\0\0\xC2\0\0\0\xBD\0\0\0\xDC\0\0\0\xC3\0\0\0>\0\0\0\xC4\0\0\0\xD6\0\0\0\xCA\0\0\0j\0\0\0\xCC\0\0\0\xBB\0\0\0\xCE\0\0\0\xBB\0\0\0\xCF\0\0\0\xBB\0\0\0\xD0\0\0\0\xBB\0\0\0\xD1\0\0\0\xBB\0\0\0\xD5\0\0\0\xD7\0\0\0\xD8\0\0\0\xBB\0\0\0\xDA\0\0\0\xBB\0\0\0\xDE\0\0\0m\0\0\0\xE1\0\0\x002\x02\0\0\xE4\0\0\0\x12\x02\0\0\xE7\0\0\0\x12\x02\0\0\xE8\0\0\x003\x01\0\0\xEB\0\0\0\xB1\x01\0\0\xEC\0\0\x003\x01\0\0\xF3\0\0\0\xF2\0\0\0\xF6\0\0\0/\x01\0\0\xFC\0\0\0\x1F\x01\0\0\xFD\0\0\0\x1C\x01\0\0\xFF\0\0\0E\x01\0\0\0\x01\0\08\x01\0\0\x01\x01\0\08\x01\0\0\x03\x01\0\0\x05\x01\0\0\x0B\x01\0\08\x01\0\0\x11\x01\0\0\xBE\x01\0\0\x18\x01\0\0G\x01\0\0\x1A\x01\0\0\x19\x01\0\0\x1E\x01\0\09\x01\0\0 \x01\0\x003\x01\0\0!\x01\0\0\"\x01\0\0&\x01\0\0\x07\x01\0\0,\x01\0\0\xF8\0\0\x002\x01\0\0L\x01\0\x004\x01\0\0\r\x01\0\0?\x01\0\0\x14\x01\0\0@\x01\0\0A\x01\0\0D\x01\0\0$\x01\0\0F\x01\0\0E\x01\0\0I\x01\0\0\xF8\0\0\0S\x01\0\0T\x01\0\0U\x01\0\0\xB1\x01\0\0W\x01\0\0\0\0\0\0Y\x01\0\0\0\0\0\0[\x01\0\0m\x01\0\0_\x01\0\0m\x01\0\0`\x01\0\0c\x01\0\0d\x01\0\0f\x01\0\0h\x01\0\0m\x01\0\0i\x01\0\0a\x01\0\0k\x01\0\0]\x01\0\0l\x01\0\0\\\x01\0\0n\x01\0\0c\x01\0\0o\x01\0\0g\x01\0\0p\x01\0\0j\x01\0\0q\x01\0\0^\x01\0\0r\x01\0\0\xC2\0\0\0s\x01\0\0\xAD\0\0\0t\x01\0\0\xC8\0\0\0u\x01\0\0\x99\0\0\0v\x01\0\0\xB3\x01\0\0w\x01\0\0]\0\0\0x\x01\0\0}\0\0\0y\x01\0\0\xDC\0\0\0z\x01\0\0\xD7\0\0\0{\x01\0\0m\0\0\0|\x01\0\0\xCD\0\0\0}\x01\0\0\xD9\0\0\0~\x01\0\0\xC0\0\0\0\x7F\x01\0\0\xDB\0\0\0\x80\x01\0\0\xC6\0\0\0\x81\x01\0\0\x16\x02\0\0\x82\x01\0\0~\0\0\0\x83\x01\0\0\xAE\x01\0\0\x84\x01\0\0\xB3\0\0\0\x85\x01\0\0\xAA\0\0\0\x86\x01\0\0\r\0\0\0\x87\x01\0\0\xB9\x01\0\0\x88\x01\0\0P\x02\0\0\x89\x01\0\0P\x02\0\0\x96\x01\0\0P\x02\0\0\xA5\x01\0\0P\x02\0\0\xA6\x01\0\0P\x02\0\0\xA7\x01\0\0P\x02\0\0\xA8\x01\0\0P\x02\0\0\xA9\x01\0\0P\x02\0\0\xAA\x01\0\0P\x02\0\0\xAB\x01\0\0\xB3\x01\0\0\xAF\x01\0\0\xC6\x01\0\0\xB2\x01\0\0\xD2\x01\0\0\xB6\x01\0\0\xEA\x01\0\0\xB8\x01\0\0\xB1\x01\0\0\xBB\x01\0\0\xC6\x01\0\0\xBD\x01\0\0\xC6\x01\0\0\xBF\x01\0\0\xC6\x01\0\0\xC1\x01\0\0\xC3\x01\0\0\xC5\x01\0\0\xB0\x01\0\0\xC7\x01\0\0\xB3\x01\0\0\xCA\x01\0\0\xBC\x01\0\0\xCC\x01\0\0\xD0\x01\0\0\xCE\x01\0\0'\x01\0\0\xCF\x01\0\0\xB1\x01\0\0\xD1\x01\0\0\xB0\x01\0\0\xD6\x01\0\0\xD4\x01\0\0\xD7\x01\0\0\xB0\x01\0\0\xDA\x01\0\0\xB0\x01\0\0\xDC\x01\0\0\xB1\x01\0\0\xDF\x01\0\0\xB7\x01\0\0\xE1\x01\0\0\xC3\x01\0\0\xE2\x01\0\0\xEA\x01\0\0\xE3\x01\0\0\xD4\x01\0\0\xE8\x01\0\0\xB0\x01\0\0\xE9\x01\0\0\xC3\x01\0\0\xEB\x01\0\0\xC6\x01\0\0\xEC\x01\0\0\xC6\x01\0\0\xED\x01\0\0P\x02\0\0\xEE\x01\0\0P\x02\0\0\xEF\x01\0\0P\x02\0\0\xF0\x01\0\0P\x02\0\0\xF1\x01\0\0P\x02\0\0\xF2\x01\0\0 \x02\0\0\xF3\x01\0\0\x0E\x01\0\0\xF4\x01\0\0\0\0\0\0\xF5\x01\0\0+\0\0\0\xF7\x01\0\0\xF8\0\0\0\xF8\x01\0\0L\x01\0\0\xF9\x01\0\0+\0\0\0\xFA\x01\0\0\xFC\x01\0\0\xFB\x01\0\0\x07\x01\0\0\xFE\x01\0\0+\0\0\0\xFF\x01\0\0\x07\x01\0\0\0\x02\0\0>\x01\0\0\x01\x02\0\0\x14\x01\0\0\x02\x02\0\0\x8B\0\0\0\x03\x02\0\0B\x01\0\0\x04\x02\0\0%\x02\0\0\x05\x02\0\x003\0\0\0\x06\x02\0\0\xB3\x01\0\0\x07\x02\0\0\xB6\0\0\0\x08\x02\0\0j\0\0\0\t\x02\0\0\xD6\0\0\0\n\x02\0\0\x9D\0\0\0\x0B\x02\0\0\xA2\0\0\0\x0C\x02\0\0\x12\x02\0\0\r\x02\0\0\x14\x02\0\0\x0E\x02\0\0j\0\0\0\x0F\x02\0\08\x01\0\0\x10\x02\0\0\x94\0\0\0\x15\x02\0\x002\x02\0\0\x18\x02\0\0\"\x02\0\0\x1B\x02\0\x007\x02\0\0!\x02\0\0 \x02\0\0&\x02\0\x007\x02\0\0(\x02\0\0-\x02\0\x000\x02\0\0\x1E\x02\0\x001\x02\0\0\x1E\x02\0\x004\x02\0\0\x1F\x02\0\x005\x02\0\0-\x02\0\09\x02\0\x002\x02\0\0:\x02\0\x007\x02\0\0;\x02\0\x007\x02\0\0<\x02\0\x002\x02\0\0=\x02\0\0\xE7\x01\0\0>\x02\0\0\xC4\x01\0\0?\x02\0\0;\x01\0\0@\x02\0\x007\x01\0\0A\x02\0\09\x01\0\0B\x02\0\0\xBE\x01\0\0C\x02\0\0P\x02\0\0D\x02\0\x007\0\0\0E\x02\0\x006\0\0\0F\x02\0\0\xB6\0\0\0G\x02\0\0]\0\0\0H\x02\0\0\x80\0\0\0I\x02\0\0\xAA\0\0\0J\x02\0\0 \x02\0\0K\x02\0\0\x81\0\0\0L\x02\0\0k\0\0\0M\x02\0\0j\0\0\0N\x02\0\0\x94\0\0\0O\x02\0\0-\x02\0\0Q\x02\0\0P\x02\0\0R\x02\0\0\xCD\x01\0\0S\x02\0\0\xC4\x01\0\0T\x02\0\0P\x02\0\0") + }, normalized_identifiers : unsafe { + zerovec::vecs::VarZeroVec16::from_bytes_unchecked(b"U\x02\x0E\0\x1A\0,\0:\0G\0T\0a\0n\0{\0\x88\0\x97\0\xA9\0\xB9\0\xC5\0\xD6\0\xE2\0\xF0\0\xFC\0\x10\x01\x1F\x01,\x01;\x01J\x01Y\x01f\x01y\x01\x84\x01\x92\x01\xA1\x01\xAE\x01\xBD\x01\xC9\x01\xDA\x01\xE5\x01\xF2\x01\x03\x02\x10\x02\x1D\x02*\x027\x02E\x02U\x02d\x02r\x02\x81\x02\x8E\x02\x9F\x02\xB1\x02\xC2\x02\xD1\x02\xE0\x02\xEE\x02\xFA\x02\t\x03\x15\x03&\x036\x03E\x03V\x03t\x03\x8F\x03\xAF\x03\xC8\x03\xDF\x03\xF9\x03\x12\x040\x04G\x04a\x04{\x04\x94\x04\xAD\x04\xBA\x04\xCA\x04\xDA\x04\xE6\x04\xF3\x04\t\x05\x19\x05&\x054\x05H\x05Y\x05g\x05t\x05\x88\x05\x9D\x05\xB1\x05\xBF\x05\xCE\x05\xDF\x05\xEE\x05\xFC\x05\x0B\x06\x1C\x061\x06F\x06U\x06g\x06x\x06\x87\x06\x95\x06\xA4\x06\xB8\x06\xC6\x06\xDA\x06\xE8\x06\xF7\x06\x07\x07\x17\x07'\x07:\x07J\x07]\x07o\x07\x80\x07\x91\x07\xA0\x07\xB1\x07\xC3\x07\xD2\x07\xE4\x07\xF5\x07\x06\x08\x14\x08#\x081\x08C\x08_\x08s\x08\x8A\x08\xA4\x08\xBD\x08\xD2\x08\xEB\x08\x02\t\x16\t$\t3\tB\tO\t]\tx\t\x93\t\xA2\t\xB4\t\xC2\t\xCE\t\xE1\t\xF3\t\x08\n\x16\n%\n3\nB\nT\ne\nu\n\x84\n\x95\n\xA3\n\xB5\n\xC8\n\xD8\n\xE7\n\xF8\n\n\x0B\x1A\x0B,\x0B:\x0BJ\x0BY\x0Be\x0Bt\x0B\x8F\x0B\xAA\x0B\xC8\x0B\xD4\x0B\xE3\x0B\xF1\x0B\x04\x0C\x16\x0C%\x0C;\x0CP\x0Cb\x0Cu\x0C\x88\x0C\x9C\x0C\xAF\x0C\xC3\x0C\xD1\x0C\xDF\x0C\xEF\x0C\x01\r\x10\r$\r4\rD\rY\rj\r~\r\x8E\r\x9B\r\xB0\r\xC0\r\xD0\r\xE0\r\xF1\r\x03\x0E\x18\x0E+\x0E8\x0EK\x0EZ\x0Ei\x0Ex\x0E\x89\x0E\x97\x0E\xA9\x0E\xB9\x0E\xC8\x0E\xDB\x0E\xEB\x0E\xFB\x0E\x14\x0F(\x0F9\x0FK\x0F\\\x0Fn\x0F\x83\x0F\x93\x0F\xA3\x0F\xB4\x0F\xC7\x0F\xD0\x0F\xDB\x0F\xE5\x0F\xF0\x0F\xFA\x0F\x05\x10\x12\x10 \x10+\x107\x10C\x10L\x10X\x10d\x10o\x10{\x10\x86\x10\x93\x10\x9D\x10\xAC\x10\xBA\x10\xC8\x10\xD4\x10\xDE\x10\xEB\x10\xF5\x10\xFE\x10\x08\x11\x15\x11#\x11,\x117\x11B\x11R\x11`\x11i\x11u\x11\x82\x11\x8E\x11\x9B\x11\xA9\x11\xB3\x11\xC1\x11\xCD\x11\xD9\x11\xE7\x11\xF4\x11\x01\x12\r\x12\x1D\x12.\x12:\x12E\x12O\x12Y\x12e\x12r\x12}\x12\x88\x12\x94\x12\xA5\x12\xB5\x12\xBE\x12\xC7\x12\xD6\x12\xE4\x12\xF2\x12\xFC\x12\t\x13\x17\x13#\x13.\x139\x13F\x13T\x13^\x13k\x13y\x13\x8B\x13\x96\x13\xA3\x13\xAF\x13\xBA\x13\xC7\x13\xD2\x13\xDE\x13\xE8\x13\xF2\x13\x04\x14\x14\x14#\x14.\x14;\x14I\x14Y\x14e\x14p\x14\x82\x14\x8E\x14\x9D\x14\xAD\x14\xBC\x14\xCF\x14\xDE\x14\xEC\x14\xFE\x14\x0E\x15 \x156\x15H\x15X\x15e\x15w\x15\x89\x15\x9E\x15\xB0\x15\xC0\x15\xD0\x15\xDF\x15\xEF\x15\xFC\x15\x0E\x16!\x164\x16A\x16P\x16_\x16s\x16\x82\x16\x92\x16\xA4\x16\xB6\x16\xC4\x16\xD8\x16\xE3\x16\xF3\x16\xFE\x16\t\x17\x0C\x17\x13\x17\"\x170\x17>\x17M\x17`\x17n\x17\x81\x17\x8D\x17\x9E\x17\xB0\x17\xB4\x17\xB7\x17\xBA\x17\xC1\x17\xC6\x17\xCA\x17\xD1\x17\xDA\x17\xE3\x17\xED\x17\xF7\x17\x01\x18\n\x18\x13\x18\x1C\x18%\x18.\x187\x18@\x18I\x18R\x18[\x18e\x18o\x18y\x18\x83\x18\x8D\x18\x96\x18\x9F\x18\xA8\x18\xB1\x18\xBA\x18\xC3\x18\xCC\x18\xD5\x18\xDD\x18\xEA\x18\xF1\x18\xF8\x18\x05\x19\r\x19\x1D\x19+\x19;\x19H\x19V\x19e\x19r\x19\x83\x19\x92\x19\xA2\x19\xB1\x19\xC0\x19\xCF\x19\xE0\x19\xED\x19\xFD\x19\x0C\x1A\x1B\x1A-\x1A<\x1AI\x1A[\x1Af\x1Ar\x1A}\x1A\x8A\x1A\x9A\x1A\xA7\x1A\xB8\x1A\xC5\x1A\xD1\x1A\xE1\x1A\xED\x1A\xFA\x1A\x07\x1B\x15\x1B \x1B,\x1B<\x1BI\x1BT\x1B_\x1Bl\x1B}\x1B\x8C\x1B\x9A\x1B\xAB\x1B\xB8\x1B\xC4\x1B\xD4\x1B\xE2\x1B\xEF\x1B\xFE\x1B\x0E\x1C\x1D\x1C)\x1C7\x1CD\x1CR\x1Cb\x1Co\x1C|\x1C\x8D\x1C\x9A\x1C\x9C\x1C\xA3\x1C\xA6\x1C\xAB\x1C\xB0\x1C\xB4\x1C\xBD\x1C\xC0\x1C\xC8\x1C\xCF\x1C\xE2\x1C\xEF\x1C\xFF\x1C\x0B\x1D\x18\x1D(\x1D3\x1DB\x1DR\x1D`\x1Dn\x1Dr\x1Dx\x1D\x7F\x1D\x84\x1D\x8D\x1D\x92\x1D\x95\x1D\x98\x1D\x9F\x1D\xAF\x1D\xBD\x1D\xCB\x1D\xCD\x1D\xD4\x1D\xDA\x1D\xDD\x1D\xE4\x1D\xF0\x1D\0\x1E\x14\x1E#\x1E0\x1E>\x1EK\x1E\\\x1Ek\x1Ew\x1E\x87\x1E\x98\x1E\xA7\x1E\xBA\x1E\xC6\x1E\xD6\x1E\xE6\x1E\xF4\x1E\x06\x1F\x14\x1F%\x1F3\x1FD\x1FR\x1F_\x1Fk\x1Fz\x1F\x88\x1F\x99\x1F\xA6\x1F\xB6\x1F\xC5\x1F\xD3\x1F\xE7\x1F\xF8\x1F\x06 \x13 ! / @ L X f q w \x7F \x82 \x85 \x8E \x94 \x97 \xA0 \xAB \xB5 \xBF \xCE \xD8 \xE1 \xF2 \xFD \x08!\x12!\x1A!\x1D!&!*!-!Africa/AbidjanAfrica/AccraAfrica/Addis_AbabaAfrica/AlgiersAfrica/AsmaraAfrica/AsmeraAfrica/BamakoAfrica/BanguiAfrica/BanjulAfrica/BissauAfrica/BlantyreAfrica/BrazzavilleAfrica/BujumburaAfrica/CairoAfrica/CasablancaAfrica/CeutaAfrica/ConakryAfrica/DakarAfrica/Dar_es_SalaamAfrica/DjiboutiAfrica/DoualaAfrica/El_AaiunAfrica/FreetownAfrica/GaboroneAfrica/HarareAfrica/JohannesburgAfrica/JubaAfrica/KampalaAfrica/KhartoumAfrica/KigaliAfrica/KinshasaAfrica/LagosAfrica/LibrevilleAfrica/LomeAfrica/LuandaAfrica/LubumbashiAfrica/LusakaAfrica/MalaboAfrica/MaputoAfrica/MaseruAfrica/MbabaneAfrica/MogadishuAfrica/MonroviaAfrica/NairobiAfrica/NdjamenaAfrica/NiameyAfrica/NouakchottAfrica/OuagadougouAfrica/Porto-NovoAfrica/Sao_TomeAfrica/TimbuktuAfrica/TripoliAfrica/TunisAfrica/WindhoekAmerica/AdakAmerica/AnchorageAmerica/AnguillaAmerica/AntiguaAmerica/AraguainaAmerica/Argentina/Buenos_AiresAmerica/Argentina/CatamarcaAmerica/Argentina/ComodRivadaviaAmerica/Argentina/CordobaAmerica/Argentina/JujuyAmerica/Argentina/La_RiojaAmerica/Argentina/MendozaAmerica/Argentina/Rio_GallegosAmerica/Argentina/SaltaAmerica/Argentina/San_JuanAmerica/Argentina/San_LuisAmerica/Argentina/TucumanAmerica/Argentina/UshuaiaAmerica/ArubaAmerica/AsuncionAmerica/AtikokanAmerica/AtkaAmerica/BahiaAmerica/Bahia_BanderasAmerica/BarbadosAmerica/BelemAmerica/BelizeAmerica/Blanc-SablonAmerica/Boa_VistaAmerica/BogotaAmerica/BoiseAmerica/Buenos_AiresAmerica/Cambridge_BayAmerica/Campo_GrandeAmerica/CancunAmerica/CaracasAmerica/CatamarcaAmerica/CayenneAmerica/CaymanAmerica/ChicagoAmerica/ChihuahuaAmerica/Ciudad_JuarezAmerica/Coral_HarbourAmerica/CordobaAmerica/Costa_RicaAmerica/CoyhaiqueAmerica/CrestonAmerica/CuiabaAmerica/CuracaoAmerica/DanmarkshavnAmerica/DawsonAmerica/Dawson_CreekAmerica/DenverAmerica/DetroitAmerica/DominicaAmerica/EdmontonAmerica/EirunepeAmerica/El_SalvadorAmerica/EnsenadaAmerica/Fort_NelsonAmerica/Fort_WayneAmerica/FortalezaAmerica/Glace_BayAmerica/GodthabAmerica/Goose_BayAmerica/Grand_TurkAmerica/GrenadaAmerica/GuadeloupeAmerica/GuatemalaAmerica/GuayaquilAmerica/GuyanaAmerica/HalifaxAmerica/HavanaAmerica/HermosilloAmerica/Indiana/IndianapolisAmerica/Indiana/KnoxAmerica/Indiana/MarengoAmerica/Indiana/PetersburgAmerica/Indiana/Tell_CityAmerica/Indiana/VevayAmerica/Indiana/VincennesAmerica/Indiana/WinamacAmerica/IndianapolisAmerica/InuvikAmerica/IqaluitAmerica/JamaicaAmerica/JujuyAmerica/JuneauAmerica/Kentucky/LouisvilleAmerica/Kentucky/MonticelloAmerica/Knox_INAmerica/KralendijkAmerica/La_PazAmerica/LimaAmerica/Los_AngelesAmerica/LouisvilleAmerica/Lower_PrincesAmerica/MaceioAmerica/ManaguaAmerica/ManausAmerica/MarigotAmerica/MartiniqueAmerica/MatamorosAmerica/MazatlanAmerica/MendozaAmerica/MenomineeAmerica/MeridaAmerica/MetlakatlaAmerica/Mexico_CityAmerica/MiquelonAmerica/MonctonAmerica/MonterreyAmerica/MontevideoAmerica/MontrealAmerica/MontserratAmerica/NassauAmerica/New_YorkAmerica/NipigonAmerica/NomeAmerica/NoronhaAmerica/North_Dakota/BeulahAmerica/North_Dakota/CenterAmerica/North_Dakota/New_SalemAmerica/NuukAmerica/OjinagaAmerica/PanamaAmerica/PangnirtungAmerica/ParamariboAmerica/PhoenixAmerica/Port-au-PrinceAmerica/Port_of_SpainAmerica/Porto_AcreAmerica/Porto_VelhoAmerica/Puerto_RicoAmerica/Punta_ArenasAmerica/Rainy_RiverAmerica/Rankin_InletAmerica/RecifeAmerica/ReginaAmerica/ResoluteAmerica/Rio_BrancoAmerica/RosarioAmerica/Santa_IsabelAmerica/SantaremAmerica/SantiagoAmerica/Santo_DomingoAmerica/Sao_PauloAmerica/ScoresbysundAmerica/ShiprockAmerica/SitkaAmerica/St_BarthelemyAmerica/St_JohnsAmerica/St_KittsAmerica/St_LuciaAmerica/St_ThomasAmerica/St_VincentAmerica/Swift_CurrentAmerica/TegucigalpaAmerica/ThuleAmerica/Thunder_BayAmerica/TijuanaAmerica/TorontoAmerica/TortolaAmerica/VancouverAmerica/VirginAmerica/WhitehorseAmerica/WinnipegAmerica/YakutatAmerica/YellowknifeAntarctica/CaseyAntarctica/DavisAntarctica/DumontDUrvilleAntarctica/MacquarieAntarctica/MawsonAntarctica/McMurdoAntarctica/PalmerAntarctica/RotheraAntarctica/South_PoleAntarctica/SyowaAntarctica/TrollAntarctica/VostokArctic/LongyearbyenAsia/AdenAsia/AlmatyAsia/AmmanAsia/AnadyrAsia/AqtauAsia/AqtobeAsia/AshgabatAsia/AshkhabadAsia/AtyrauAsia/BaghdadAsia/BahrainAsia/BakuAsia/BangkokAsia/BarnaulAsia/BeirutAsia/BishkekAsia/BruneiAsia/CalcuttaAsia/ChitaAsia/ChoibalsanAsia/ChongqingAsia/ChungkingAsia/ColomboAsia/DaccaAsia/DamascusAsia/DhakaAsia/DiliAsia/DubaiAsia/DushanbeAsia/FamagustaAsia/GazaAsia/HarbinAsia/HebronAsia/Ho_Chi_MinhAsia/Hong_KongAsia/HovdAsia/IrkutskAsia/IstanbulAsia/JakartaAsia/JayapuraAsia/JerusalemAsia/KabulAsia/KamchatkaAsia/KarachiAsia/KashgarAsia/KathmanduAsia/KatmanduAsia/KhandygaAsia/KolkataAsia/KrasnoyarskAsia/Kuala_LumpurAsia/KuchingAsia/KuwaitAsia/MacaoAsia/MacauAsia/MagadanAsia/MakassarAsia/ManilaAsia/MuscatAsia/NicosiaAsia/NovokuznetskAsia/NovosibirskAsia/OmskAsia/OralAsia/Phnom_PenhAsia/PontianakAsia/PyongyangAsia/QatarAsia/QostanayAsia/QyzylordaAsia/RangoonAsia/RiyadhAsia/SaigonAsia/SakhalinAsia/SamarkandAsia/SeoulAsia/ShanghaiAsia/SingaporeAsia/SrednekolymskAsia/TaipeiAsia/TashkentAsia/TbilisiAsia/TehranAsia/Tel_AvivAsia/ThimbuAsia/ThimphuAsia/TokyoAsia/TomskAsia/Ujung_PandangAsia/UlaanbaatarAsia/Ulan_BatorAsia/UrumqiAsia/Ust-NeraAsia/VientianeAsia/VladivostokAsia/YakutskAsia/YangonAsia/YekaterinburgAsia/YerevanAtlantic/AzoresAtlantic/BermudaAtlantic/CanaryAtlantic/Cape_VerdeAtlantic/FaeroeAtlantic/FaroeAtlantic/Jan_MayenAtlantic/MadeiraAtlantic/ReykjavikAtlantic/South_GeorgiaAtlantic/St_HelenaAtlantic/StanleyAustralia/ACTAustralia/AdelaideAustralia/BrisbaneAustralia/Broken_HillAustralia/CanberraAustralia/CurrieAustralia/DarwinAustralia/EuclaAustralia/HobartAustralia/LHIAustralia/LindemanAustralia/Lord_HoweAustralia/MelbourneAustralia/NSWAustralia/NorthAustralia/PerthAustralia/QueenslandAustralia/SouthAustralia/SydneyAustralia/TasmaniaAustralia/VictoriaAustralia/WestAustralia/YancowinnaBrazil/AcreBrazil/DeNoronhaBrazil/EastBrazil/WestCETCST6CDTCanada/AtlanticCanada/CentralCanada/EasternCanada/MountainCanada/NewfoundlandCanada/PacificCanada/SaskatchewanCanada/YukonChile/ContinentalChile/EasterIslandCubaEETESTEST5EDTEgyptEireEtc/GMTEtc/GMT+0Etc/GMT+1Etc/GMT+10Etc/GMT+11Etc/GMT+12Etc/GMT+2Etc/GMT+3Etc/GMT+4Etc/GMT+5Etc/GMT+6Etc/GMT+7Etc/GMT+8Etc/GMT+9Etc/GMT-0Etc/GMT-1Etc/GMT-10Etc/GMT-11Etc/GMT-12Etc/GMT-13Etc/GMT-14Etc/GMT-2Etc/GMT-3Etc/GMT-4Etc/GMT-5Etc/GMT-6Etc/GMT-7Etc/GMT-8Etc/GMT-9Etc/GMT0Etc/GreenwichEtc/UCTEtc/UTCEtc/UniversalEtc/ZuluEurope/AmsterdamEurope/AndorraEurope/AstrakhanEurope/AthensEurope/BelfastEurope/BelgradeEurope/BerlinEurope/BratislavaEurope/BrusselsEurope/BucharestEurope/BudapestEurope/BusingenEurope/ChisinauEurope/CopenhagenEurope/DublinEurope/GibraltarEurope/GuernseyEurope/HelsinkiEurope/Isle_of_ManEurope/IstanbulEurope/JerseyEurope/KaliningradEurope/KievEurope/KirovEurope/KyivEurope/LisbonEurope/LjubljanaEurope/LondonEurope/LuxembourgEurope/MadridEurope/MaltaEurope/MariehamnEurope/MinskEurope/MonacoEurope/MoscowEurope/NicosiaEurope/OsloEurope/ParisEurope/PodgoricaEurope/PragueEurope/RigaEurope/RomeEurope/SamaraEurope/San_MarinoEurope/SarajevoEurope/SaratovEurope/SimferopolEurope/SkopjeEurope/SofiaEurope/StockholmEurope/TallinnEurope/TiraneEurope/TiraspolEurope/UlyanovskEurope/UzhgorodEurope/VaduzEurope/VaticanEurope/ViennaEurope/VilniusEurope/VolgogradEurope/WarsawEurope/ZagrebEurope/ZaporozhyeEurope/ZurichGBGB-EireGMTGMT+0GMT-0GMT0GreenwichHSTHongkongIcelandIndian/AntananarivoIndian/ChagosIndian/ChristmasIndian/CocosIndian/ComoroIndian/KerguelenIndian/MaheIndian/MaldivesIndian/MauritiusIndian/MayotteIndian/ReunionIranIsraelJamaicaJapanKwajaleinLibyaMETMSTMST7MDTMexico/BajaNorteMexico/BajaSurMexico/GeneralNZNZ-CHATNavajoPRCPST8PDTPacific/ApiaPacific/AucklandPacific/BougainvillePacific/ChathamPacific/ChuukPacific/EasterPacific/EfatePacific/EnderburyPacific/FakaofoPacific/FijiPacific/FunafutiPacific/GalapagosPacific/GambierPacific/GuadalcanalPacific/GuamPacific/HonoluluPacific/JohnstonPacific/KantonPacific/KiritimatiPacific/KosraePacific/KwajaleinPacific/MajuroPacific/MarquesasPacific/MidwayPacific/NauruPacific/NiuePacific/NorfolkPacific/NoumeaPacific/Pago_PagoPacific/PalauPacific/PitcairnPacific/PohnpeiPacific/PonapePacific/Port_MoresbyPacific/RarotongaPacific/SaipanPacific/SamoaPacific/TahitiPacific/TarawaPacific/TongatapuPacific/TrukPacific/WakePacific/WallisPacific/YapPolandPortugalROCROKSingaporeTurkeyUCTUS/AlaskaUS/AleutianUS/ArizonaUS/CentralUS/East-IndianaUS/EasternUS/HawaiiUS/Indiana-StarkeUS/MichiganUS/MountainUS/PacificUS/SamoaUTCUniversalW-SUWETZulu") + }, }; + }; +} diff --git a/deps/temporal/provider/src/data/mod.rs b/deps/temporal/provider/src/data/mod.rs new file mode 100644 index 00000000000000..f4a6c886f73a25 --- /dev/null +++ b/deps/temporal/provider/src/data/mod.rs @@ -0,0 +1,3 @@ +include!("iana_normalizer.rs.data"); + +include!("compiled_zoneinfo_provider.rs.data"); diff --git a/deps/temporal/provider/src/epoch_nanoseconds.rs b/deps/temporal/provider/src/epoch_nanoseconds.rs new file mode 100644 index 00000000000000..4dcd9fbc7dc8b8 --- /dev/null +++ b/deps/temporal/provider/src/epoch_nanoseconds.rs @@ -0,0 +1,63 @@ +use crate::TimeZoneProviderError; + +/// Number of nanoseconds in a day +#[doc(hidden)] +pub const NS_PER_DAY: u64 = MS_PER_DAY as u64 * 1_000_000; + +pub(crate) const NS_IN_S: i128 = 1_000_000_000; + +/// Milliseconds per day constant: 8.64e+7 +pub(crate) const MS_PER_DAY: u32 = 24 * 60 * 60 * 1000; +/// Max Instant nanosecond constant +#[doc(hidden)] +pub(crate) const NS_MAX_INSTANT: i128 = NS_PER_DAY as i128 * 100_000_000i128; +/// Min Instant nanosecond constant +#[doc(hidden)] +pub(crate) const NS_MIN_INSTANT: i128 = -NS_MAX_INSTANT; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] +pub struct EpochNanoseconds(pub i128); + +impl From for EpochNanoseconds { + fn from(value: i128) -> Self { + Self(value) + } +} + +// Potential TODO: Build out primitive arthmetic methods if needed. +impl EpochNanoseconds { + pub fn as_i128(&self) -> i128 { + self.0 + } + + pub fn check_validity(&self) -> Result<(), TimeZoneProviderError> { + if !is_valid_epoch_nanos(&self.0) { + return Err(TimeZoneProviderError::InstantOutOfRange); + } + Ok(()) + } + + pub fn from_seconds(seconds: i64) -> Self { + Self(seconds as i128 * NS_IN_S) + } +} + +/// Utility for determining if the nanos are within a valid range. +#[inline] +#[must_use] +pub fn is_valid_epoch_nanos(nanos: &i128) -> bool { + (NS_MIN_INSTANT..=NS_MAX_INSTANT).contains(nanos) +} + +#[cfg(feature = "tzif")] +impl From for EpochNanoseconds { + fn from(value: tzif::data::time::Seconds) -> Self { + EpochNanoseconds::from_seconds(value.0) + } +} + +#[inline] +#[cfg(any(feature = "tzif", feature = "zoneinfo64"))] +pub(crate) fn seconds_to_nanoseconds(seconds: i64) -> i128 { + seconds as i128 * NS_IN_S +} diff --git a/deps/temporal/provider/src/error.rs b/deps/temporal/provider/src/error.rs new file mode 100644 index 00000000000000..8066bfb5969185 --- /dev/null +++ b/deps/temporal/provider/src/error.rs @@ -0,0 +1,7 @@ +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[non_exhaustive] +pub enum TimeZoneProviderError { + InstantOutOfRange, + Assert(&'static str), + Range(&'static str), +} diff --git a/deps/temporal/provider/src/experimental_tzif/datagen.rs b/deps/temporal/provider/src/experimental_tzif/datagen.rs new file mode 100644 index 00000000000000..bfbc30c4e4899a --- /dev/null +++ b/deps/temporal/provider/src/experimental_tzif/datagen.rs @@ -0,0 +1,96 @@ +use super::*; +use crate::tzdb::datagen::TzdbDataSource; +use alloc::collections::BTreeMap; +use alloc::vec::Vec; +use std::path::Path; +use zerotrie::ZeroTrieBuildError; +use zoneinfo_rs::{compiler::CompiledTransitions, ZoneInfoCompiler, ZoneInfoData}; + +impl From<&zoneinfo_rs::tzif::LocalTimeRecord> for LocalTimeRecord { + fn from(value: &zoneinfo_rs::tzif::LocalTimeRecord) -> Self { + Self { + offset: value.offset, + } + } +} + +impl ZeroTzif<'_> { + fn from_transition_data(data: &CompiledTransitions) -> Self { + let tzif = data.to_v2_data_block(); + let transitions = ZeroVec::alloc_from_slice(&tzif.transition_times); + let transition_types = ZeroVec::alloc_from_slice(&tzif.transition_types); + let mapped_local_records: Vec = + tzif.local_time_types.iter().map(Into::into).collect(); + let types = ZeroVec::alloc_from_slice(&mapped_local_records); + // TODO: handle this much better. + let posix = PosixZone::from(&data.posix_time_zone); + + Self { + transitions, + transition_types, + types, + posix, + } + } +} + +#[derive(Debug)] +pub enum ZoneInfoDataError { + Build(ZeroTrieBuildError), +} + +#[allow(clippy::expect_used, clippy::unwrap_used, reason = "Datagen only")] +impl ZoneInfoProvider<'_> { + pub fn build(tzdata: &Path) -> Result { + let tzdb_source = TzdbDataSource::try_from_rearguard_zoneinfo_dir(tzdata).unwrap(); + let compiled_transitions = ZoneInfoCompiler::new(tzdb_source.data.clone()).build(); + + let mut identifiers = BTreeMap::default(); + let mut primary_zones = Vec::default(); + + // Create a Map of , this is used later to index + let ZoneInfoData { links, zones, .. } = tzdb_source.data; + + for zone_identifier in zones.into_keys() { + primary_zones.push(zone_identifier.clone()); + identifiers.insert(zone_identifier.clone(), zone_identifier); + } + for (link, zone) in links.into_iter() { + identifiers.insert(link, zone); + } + + primary_zones.sort(); + + let identifier_map: BTreeMap, usize> = identifiers + .into_iter() + .map(|(id, zoneid)| { + ( + id.to_ascii_lowercase().as_bytes().to_vec(), + primary_zones.binary_search(&zoneid).unwrap(), + ) + }) + .collect(); + + let tzifs: Vec> = primary_zones + .into_iter() + .map(|id| { + let data = compiled_transitions + .data + .get(&id) + .expect("all zones should be built"); + ZeroTzif::from_transition_data(data) + }) + .collect(); + + let tzifs_zerovec: VarZeroVec<'static, ZeroTzifULE, Index32> = tzifs.as_slice().into(); + + let ids = ZeroAsciiIgnoreCaseTrie::try_from(&identifier_map) + .map_err(ZoneInfoDataError::Build)? + .convert_store(); + + Ok(ZoneInfoProvider { + ids, + tzifs: tzifs_zerovec, + }) + } +} diff --git a/deps/temporal/provider/src/experimental_tzif/mod.rs b/deps/temporal/provider/src/experimental_tzif/mod.rs new file mode 100644 index 00000000000000..a5114243796564 --- /dev/null +++ b/deps/temporal/provider/src/experimental_tzif/mod.rs @@ -0,0 +1,66 @@ +//! A compact, zero copy TZif file. +//! +//! NOTE: This representation does not follow the TZif specification +//! to full detail, but instead attempts to compress TZif data into +//! a functional, data driven equivalent. + +#[cfg(feature = "datagen")] +mod datagen; +pub mod posix; + +use zerotrie::ZeroAsciiIgnoreCaseTrie; +use zerovec::{vecs::Index32, VarZeroVec, ZeroVec}; + +use posix::PosixZone; + +use crate as timezone_provider; +compiled_zoneinfo_provider!(COMPILED_ZONEINFO_PROVIDER); + +#[derive(Debug, Clone)] +#[cfg_attr( + feature = "datagen", + derive(yoke::Yokeable, serde::Serialize, databake::Bake) +)] +#[cfg_attr(feature = "datagen", databake(path = timezone_provider::experimental_tzif))] +pub struct ZoneInfoProvider<'data> { + // IANA identifier map to TZif index. + pub ids: ZeroAsciiIgnoreCaseTrie>, + // Vector of TZif data + pub tzifs: VarZeroVec<'data, ZeroTzifULE, Index32>, +} + +impl ZoneInfoProvider<'_> { + pub fn get(&self, identifier: &str) -> Option<&ZeroTzifULE> { + let idx = self.ids.get(identifier)?; + self.tzifs.get(idx) + } +} + +#[zerovec::make_varule(ZeroTzifULE)] +#[derive(PartialEq, Debug, Clone)] +#[zerovec::skip_derive(Ord)] +#[zerovec::derive(Debug)] +#[cfg_attr( + feature = "datagen", + derive(yoke::Yokeable, serde::Serialize, databake::Bake) +)] +#[cfg_attr(feature = "datagen", zerovec::derive(Serialize))] +#[cfg_attr(feature = "datagen", databake(path = timezone_provider::experimental_tzif))] +pub struct ZeroTzif<'data> { + pub transitions: ZeroVec<'data, i64>, + pub transition_types: ZeroVec<'data, u8>, + // NOTE: zoneinfo64 does a fun little bitmap str + pub types: ZeroVec<'data, LocalTimeRecord>, + pub posix: PosixZone, +} + +#[zerovec::make_ule(LocalTimeRecordULE)] +#[derive(PartialEq, Eq, Debug, Clone, Copy, PartialOrd, Ord)] +#[cfg_attr( + feature = "datagen", + derive(yoke::Yokeable, serde::Serialize, databake::Bake) +)] +#[cfg_attr(feature = "datagen", databake(path = timezone_provider::experimental_tzif))] +pub struct LocalTimeRecord { + pub offset: i64, +} diff --git a/deps/temporal/provider/src/experimental_tzif/posix.rs b/deps/temporal/provider/src/experimental_tzif/posix.rs new file mode 100644 index 00000000000000..1241bd174c4152 --- /dev/null +++ b/deps/temporal/provider/src/experimental_tzif/posix.rs @@ -0,0 +1,132 @@ +use tinystr::TinyAsciiStr; +#[cfg(feature = "datagen")] +use zoneinfo_rs::posix::{MonthWeekDay, PosixDate, PosixDateTime, PosixTimeZone, PosixTransition}; + +#[zerovec::make_ule(PosixZoneULE)] +#[derive(PartialEq, Eq, Debug, Clone, Copy, PartialOrd, Ord)] +#[cfg_attr( + feature = "datagen", + derive(yoke::Yokeable, serde::Serialize, databake::Bake) +)] +#[cfg_attr(feature = "datagen", databake(path = timezone_provider::experimental_tzif::posix))] +pub struct PosixZone { + pub abbr: TinyAsciiStr<5>, + pub offset: i64, + pub transition: Option, +} + +#[cfg(feature = "datagen")] +#[allow(clippy::unwrap_used, reason = "Datagen only")] +impl From<&PosixTimeZone> for PosixZone { + fn from(value: &PosixTimeZone) -> Self { + let abbr = TinyAsciiStr::<5>::try_from_str(&value.abbr.formatted).unwrap(); + let offset = value.offset.as_secs(); + let transition = value + .transition_info + .as_ref() + .map(ZeroPosixTransition::from); + + Self { + abbr, + offset, + transition, + } + } +} + +#[zerovec::make_ule(PosixTransitionULE)] +#[derive(PartialEq, Eq, Debug, Clone, Copy, PartialOrd, Ord)] +#[cfg_attr( + feature = "datagen", + derive(yoke::Yokeable, serde::Serialize, databake::Bake) +)] +#[cfg_attr(feature = "datagen", databake(path = timezone_provider::experimental_tzif::posix))] +pub struct ZeroPosixTransition { + pub abbr: TinyAsciiStr<5>, + pub savings: i64, + pub start: ZeroTransitionDateTime, + pub end: ZeroTransitionDateTime, +} + +#[cfg(feature = "datagen")] +#[allow(clippy::unwrap_used, reason = "Datagen only")] +impl From<&PosixTransition> for ZeroPosixTransition { + fn from(value: &PosixTransition) -> Self { + let abbr = TinyAsciiStr::<5>::try_from_str(&value.abbr.formatted).unwrap(); + let savings = value.savings.as_secs(); + let start = ZeroTransitionDateTime::from(&value.start); + let end = ZeroTransitionDateTime::from(&value.end); + Self { + abbr, + savings, + start, + end, + } + } +} + +#[zerovec::make_ule(TransitionDateTimeULE)] +#[derive(PartialEq, Eq, Debug, Clone, Copy, PartialOrd, Ord)] +#[cfg_attr( + feature = "datagen", + derive(yoke::Yokeable, serde::Serialize, databake::Bake) +)] +#[cfg_attr(feature = "datagen", databake(path = timezone_provider::experimental_tzif::posix))] +pub struct ZeroTransitionDateTime { + /// The date at which a transition should occur. + date: ZeroTransitionDate, + /// The time of day in seconds. + time: i64, +} + +#[cfg(feature = "datagen")] +impl From<&PosixDateTime> for ZeroTransitionDateTime { + fn from(value: &PosixDateTime) -> Self { + Self { + date: value.date.into(), + time: value.time.as_secs(), + } + } +} + +#[zerovec::make_ule(DateULE)] +#[derive(PartialEq, Eq, Debug, Clone, Copy, PartialOrd, Ord)] +#[cfg_attr( + feature = "datagen", + derive(yoke::Yokeable, serde::Serialize, databake::Bake) +)] +#[cfg_attr(feature = "datagen", databake(path = timezone_provider::experimental_tzif::posix))] +pub struct ZeroTransitionDate { + kind: DateKind, + day: Option, + mwd: Option<(u8, u8, u8)>, +} + +#[cfg(feature = "datagen")] +impl From for ZeroTransitionDate { + fn from(value: PosixDate) -> Self { + let (kind, day, mwd) = match value { + PosixDate::JulianLeap(day) => (DateKind::Julian, Some(day), None), + PosixDate::JulianNoLeap(day) => (DateKind::JulianNoLeap, Some(day), None), + PosixDate::MonthWeekDay(MonthWeekDay(month, week, day)) => ( + DateKind::MonthWeekDay, + None, + Some((month as u8, week, day as u8)), + ), + }; + Self { kind, day, mwd } + } +} +#[zerovec::make_ule(DateKindULE)] +#[derive(PartialEq, Eq, Debug, Clone, Copy, PartialOrd, Ord)] +#[cfg_attr( + feature = "datagen", + derive(yoke::Yokeable, serde::Serialize, databake::Bake) +)] +#[cfg_attr(feature = "datagen", databake(path = timezone_provider::experimental_tzif::posix))] +#[repr(u8)] +pub enum DateKind { + JulianNoLeap = 0, + Julian = 1, + MonthWeekDay = 2, +} diff --git a/deps/temporal/provider/src/lib.rs b/deps/temporal/provider/src/lib.rs new file mode 100644 index 00000000000000..a910c90e81aee3 --- /dev/null +++ b/deps/temporal/provider/src/lib.rs @@ -0,0 +1,141 @@ +//! Providers for time zone data +//! +//! Let's talk about time zone data everyone! +//! +//! At a high level, the `timezone_provider` crate provides a set of traits along with a few +//! implementations of those traits. The general intention here is to make providing time zone +//! data as agnostic and easy as possible. +//! +//! This crate is fairly "low level" at least as far as date and time needs are concerned. So +//! we'll cover the basic overview of the trait and some of the general implementations of +//! those traits, and then we will go on a bit further of a dive for the power users that +//! are interested in implementing their own provider or is just really curious about what +//! is going on. +//! +//! ## Available providers +//! +//! Below is a list of currently available time zone providers. +//! +//! - `ZoneInfo64TzdbProvider`: a provider using ICU4C's zoneinfo64 resource bundle (enable with `zoneinfo64` features flag) +//! - `FsTzdbProvider`: a provider that reads and parses tzdata at runtime from the host file system's +//! TZif files (enable with `tzif` feature flag) +//! - `CompiledTzdbProvider`: a provider that reads and parses tzdata at runtime from TZif's compiled +//! into the application (enable with `tzif` feature flag) +//! +//! Coming soon (hopefully), a zero copy compiled tzdb provider (see `experimental_tzif` for more). +//! +//! ## Time zone provider traits +//! +//! This crate provides three primary traits for working with time zone data. +//! +//! - [`TimeZoneProvider`][crate::provider::TimeZoneProvider] +//! - [`TimeZoneNormalizer`][crate::provider::TimeZoneNormalizer] +//! - [`TimeZoneResolver`][crate::provider::TimeZoneResolver] +//! +//! The first trait `TimeZoneProvider` is the primary interface for a time zone provider used by `temporal_rs`. +//! +//! Meanwhile, the two other traits, `TimeZoneNormalizer` and `TimeZoneResolver`, are secondary +//! traits that can be used to implement the core `TimeZoneProvider`. Once implemented, this +//! crate providers a default type for creating a `TimeZoneProvider` by mixing and matching objects that implement the secondary +//! traits, `NormalizerAndResolver`. +//! +//! ### Why two secondary traits? +//! +//! Well that's because `TimeZoneProvider` handles two different concerns: fetching and +//! formatting normalized and canonicalized time zone identifiers, and resolving time +//! zone data requests. This functionality typically requires two different sets of data, +//! each of which may be in a variety of formats. +//! +//! ### Why not just have the two secondary traits without `TimeZoneProvider`? +//! +//! Well while the functionality typically requires two sets of data. Those sets are not +//! necessarily completely unique. The time zone database updates potentially multiple times a +//! year so having your formatting in 2025a while your data is in 2025b could cause some +//! desync. So in order to better represent this `TimeZoneProvider` is used on top of them. +//! +//! **NOTE:** you CAN always just directly use `TimeZoneNormalizer` and +//! `TimeZoneResolver` together if you want. We just wouldn't recommemnd it. +//! + +#![no_std] +#![cfg_attr( + not(test), + warn(clippy::unwrap_used, clippy::expect_used, clippy::indexing_slicing) +)] + +extern crate alloc; + +#[cfg(feature = "std")] +extern crate std; + +#[macro_use] +mod private { + include!("./data/mod.rs"); +} + +mod tzdb; +pub use tzdb::{CompiledNormalizer, IanaIdentifierNormalizer}; + +#[cfg(feature = "tzif")] +pub mod tzif; + +#[cfg(feature = "experimental_tzif")] +pub mod experimental_tzif; + +#[cfg(feature = "zoneinfo64")] +pub mod zoneinfo64; + +pub mod epoch_nanoseconds; + +#[doc(hidden)] +pub mod utils; + +mod error; +pub mod provider; +pub use error::TimeZoneProviderError; + +use crate as timezone_provider; +iana_normalizer_singleton!(SINGLETON_IANA_NORMALIZER); + +#[cfg(test)] +mod tests { + extern crate alloc; + use super::SINGLETON_IANA_NORMALIZER; + + #[test] + fn basic_normalization() { + let index = SINGLETON_IANA_NORMALIZER + .available_id_index + .get("America/CHICAGO") + .unwrap(); + assert_eq!( + SINGLETON_IANA_NORMALIZER.normalized_identifiers.get(index), + Some("America/Chicago") + ); + + let index = SINGLETON_IANA_NORMALIZER + .available_id_index + .get("uTc") + .unwrap(); + assert_eq!( + SINGLETON_IANA_NORMALIZER.normalized_identifiers.get(index), + Some("UTC") + ); + + let index = SINGLETON_IANA_NORMALIZER + .available_id_index + .get("eTC/uTc") + .unwrap(); + assert_eq!( + SINGLETON_IANA_NORMALIZER.normalized_identifiers.get(index), + Some("Etc/UTC") + ); + } + + #[test] + #[cfg(feature = "experimental_tzif")] + fn zone_info_basic() { + let tzif = crate::experimental_tzif::COMPILED_ZONEINFO_PROVIDER.get("America/Chicago"); + assert!(tzif.is_some()) + } +} diff --git a/deps/temporal/provider/src/provider.rs b/deps/temporal/provider/src/provider.rs new file mode 100644 index 00000000000000..d1fba95f7fb6fd --- /dev/null +++ b/deps/temporal/provider/src/provider.rs @@ -0,0 +1,377 @@ +//! Traits and struct for creating time zone data providers. +//! +//! This module contains the traits needed to implement a time zone data +//! provider along with relevant structs. + +use core::str::FromStr; + +use crate::utils; +use crate::CompiledNormalizer; +use crate::{epoch_nanoseconds::EpochNanoseconds, TimeZoneProviderError}; +use alloc::borrow::Cow; + +pub(crate) type TimeZoneProviderResult = Result; + +/// `UtcOffsetSeconds` represents the amount of seconds we need to add to the UTC to reach the local time. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub struct UtcOffsetSeconds(pub i64); + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct IsoDateTime { + pub year: i32, + pub month: u8, + pub day: u8, + pub hour: u8, + pub minute: u8, + pub second: u8, + pub millisecond: u16, + pub microsecond: u16, + pub nanosecond: u16, +} + +impl IsoDateTime { + fn to_epoch_days(self) -> i64 { + utils::epoch_days_from_gregorian_date(self.year, self.month, self.day) + } + /// `IsoTimeToEpochMs` + /// + /// Note: This method is library specific and not in spec + /// + /// Functionally the same as Date's `MakeTime` + fn time_to_epoch_ms(self) -> i64 { + ((i64::from(self.hour) * utils::MS_PER_HOUR + + i64::from(self.minute) * utils::MS_PER_MINUTE) + + i64::from(self.second) * 1000i64) + + i64::from(self.millisecond) + } + + /// Convert this datetime to nanoseconds since the Unix epoch + pub fn as_nanoseconds(&self) -> EpochNanoseconds { + let time_ms = self.time_to_epoch_ms(); + let epoch_ms = utils::epoch_days_to_epoch_ms(self.to_epoch_days(), time_ms); + EpochNanoseconds( + epoch_ms as i128 * 1_000_000 + + self.microsecond as i128 * 1_000 + + self.nanosecond as i128, + ) + } +} + +#[cfg(feature = "tzif")] +use tzif::data::{posix::TimeZoneVariantInfo, tzif::LocalTimeTypeRecord}; + +#[cfg(feature = "tzif")] +impl From<&TimeZoneVariantInfo> for UtcOffsetSeconds { + fn from(value: &TimeZoneVariantInfo) -> Self { + // The POSIX tz string stores offsets as negative offsets; + // i.e. "seconds that must be added to reach UTC" + Self(-value.offset.0) + } +} + +#[cfg(feature = "tzif")] +impl From for UtcOffsetSeconds { + fn from(value: LocalTimeTypeRecord) -> Self { + Self(value.utoff.0) + } +} + +/// An EpochNanoseconds and a UTC offset +#[derive(Copy, Clone, Debug, PartialEq)] +pub struct EpochNanosecondsAndOffset { + /// The resolved nanoseconds value + pub ns: EpochNanoseconds, + /// The resolved time zone offset corresponding + /// to the nanoseconds value, in the given time zone + pub offset: UtcOffsetSeconds, +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum TransitionDirection { + Next, + Previous, +} + +#[derive(Debug, Clone, Copy)] +pub struct ParseDirectionError; + +impl core::fmt::Display for ParseDirectionError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("provided string was not a valid direction.") + } +} + +impl FromStr for TransitionDirection { + type Err = ParseDirectionError; + fn from_str(s: &str) -> Result { + match s { + "next" => Ok(Self::Next), + "previous" => Ok(Self::Previous), + _ => Err(ParseDirectionError), + } + } +} + +impl core::fmt::Display for TransitionDirection { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::Next => "next", + Self::Previous => "previous", + } + .fmt(f) + } +} + +/// Used in disambiguate_possible_epoch_nanos +/// +/// When we have a LocalTimeRecordResult::Empty, +/// it is useful to know the offsets before and after. +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] +pub struct GapEntryOffsets { + pub offset_before: UtcOffsetSeconds, + pub offset_after: UtcOffsetSeconds, + pub transition_epoch: EpochNanoseconds, +} + +/// The potential candidates for a given local datetime +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum CandidateEpochNanoseconds { + Zero(GapEntryOffsets), + One(EpochNanosecondsAndOffset), + Two([EpochNanosecondsAndOffset; 2]), +} + +impl CandidateEpochNanoseconds { + pub fn as_slice(&self) -> &[EpochNanosecondsAndOffset] { + match *self { + Self::Zero(..) => &[], + Self::One(ref one) => core::slice::from_ref(one), + Self::Two(ref multiple) => &multiple[..], + } + } + + #[allow(unused)] // Used in tests in some feature configurations + pub fn is_empty(&self) -> bool { + matches!(*self, Self::Zero(..)) + } + + #[allow(unused)] // Used in tests in some feature configurations + pub fn len(&self) -> usize { + match *self { + Self::Zero(..) => 0, + Self::One(..) => 1, + Self::Two(..) => 2, + } + } + + pub fn first(&self) -> Option { + match *self { + Self::Zero(..) => None, + Self::One(one) | Self::Two([one, _]) => Some(one), + } + } + + pub fn last(&self) -> Option { + match *self { + Self::Zero(..) => None, + Self::One(last) | Self::Two([_, last]) => Some(last), + } + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +pub struct TimeZoneId { + pub normalized: NormalizedId, + pub resolved: ResolvedId, +} + +pub trait TimeZoneProvider { + fn get(&self, ident: &[u8]) -> TimeZoneProviderResult; + fn identifier(&self, id: TimeZoneId) -> TimeZoneProviderResult>; + + fn canonicalized(&self, id: TimeZoneId) -> TimeZoneProviderResult; + + fn candidate_nanoseconds_for_local_epoch_nanoseconds( + &self, + id: TimeZoneId, + local_datetime: IsoDateTime, + ) -> TimeZoneProviderResult; + + fn transition_nanoseconds_for_utc_epoch_nanoseconds( + &self, + id: TimeZoneId, + epoch_nanoseconds: i128, + ) -> TimeZoneProviderResult; + + fn get_time_zone_transition( + &self, + id: TimeZoneId, + epoch_nanoseconds: i128, + direction: TransitionDirection, + ) -> TimeZoneProviderResult>; +} + +/// An id for a resolved timezone, for use with a [`TimeZoneNormalizer`] +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +pub struct NormalizedId(pub usize); + +/// A type capable of normalizing and canonicalizing time zones +pub trait TimeZoneNormalizer { + // Needed for temporal support + fn normalized(&self, _: &[u8]) -> TimeZoneProviderResult; + + // Support for Intl support and canonicalize-tz proposal + fn canonicalized(&self, _: NormalizedId) -> TimeZoneProviderResult; + + fn identifier(&self, _: NormalizedId) -> TimeZoneProviderResult<&str>; +} + +/// An id for a resolved timezone, for use with a [`TimeZoneResolver`] +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +pub struct ResolvedId(pub usize); + +/// A type capable of resolving time zone data +pub trait TimeZoneResolver { + fn get_id(&self, normalized_identifier: &[u8]) -> TimeZoneProviderResult; + + fn candidate_nanoseconds_for_local_epoch_nanoseconds( + &self, + identifier: ResolvedId, + local_datetime: IsoDateTime, + ) -> TimeZoneProviderResult; + + fn transition_nanoseconds_for_utc_epoch_nanoseconds( + &self, + identifier: ResolvedId, + epoch_nanoseconds: i128, + ) -> TimeZoneProviderResult; + + fn get_time_zone_transition( + &self, + identifier: ResolvedId, + epoch_nanoseconds: i128, + direction: TransitionDirection, + ) -> TimeZoneProviderResult>; +} + +/// A type that can both normalize and resolve, which implements [`TimeZoneProvider`] +#[derive(Default, Copy, Clone, Debug)] +pub struct NormalizerAndResolver { + resolver: R, + canonicalizer: C, +} + +impl NormalizerAndResolver { + /// Create a new [`NormalizerAndResolver`] with a given resolver and compiled normalizer data + pub fn new(resolver: R) -> Self { + Self { + resolver, + canonicalizer: CompiledNormalizer, + } + } +} +impl TimeZoneProvider for NormalizerAndResolver { + fn get(&self, ident: &[u8]) -> TimeZoneProviderResult { + let normalized = self.canonicalizer.normalized(ident)?; + let normalized_id = self.canonicalizer.identifier(normalized)?; + let resolved = self.resolver.get_id(normalized_id.as_bytes())?; + + Ok(TimeZoneId { + normalized, + resolved, + }) + } + + fn identifier(&self, id: TimeZoneId) -> TimeZoneProviderResult> { + self.canonicalizer.identifier(id.normalized).map(Into::into) + } + fn canonicalized(&self, id: TimeZoneId) -> TimeZoneProviderResult { + let canonical = self.canonicalizer.canonicalized(id.normalized)?; + Ok(TimeZoneId { + normalized: canonical, + resolved: id.resolved, + }) + } + fn candidate_nanoseconds_for_local_epoch_nanoseconds( + &self, + id: TimeZoneId, + local_datetime: IsoDateTime, + ) -> TimeZoneProviderResult { + self.resolver + .candidate_nanoseconds_for_local_epoch_nanoseconds(id.resolved, local_datetime) + } + + fn transition_nanoseconds_for_utc_epoch_nanoseconds( + &self, + id: TimeZoneId, + epoch_nanoseconds: i128, + ) -> TimeZoneProviderResult { + self.resolver + .transition_nanoseconds_for_utc_epoch_nanoseconds(id.resolved, epoch_nanoseconds) + } + + fn get_time_zone_transition( + &self, + id: TimeZoneId, + epoch_nanoseconds: i128, + direction: TransitionDirection, + ) -> TimeZoneProviderResult> { + self.resolver + .get_time_zone_transition(id.resolved, epoch_nanoseconds, direction) + } +} + +/// A [`TimeZoneNormalizer`] that always panics +#[derive(Copy, Clone, Debug, Default)] +pub struct NeverNormalizer; +/// A [`TimeZoneResolver`] that always panics +#[derive(Copy, Clone, Debug, Default)] +pub struct NeverResolver; + +impl TimeZoneNormalizer for NeverNormalizer { + fn normalized(&self, _: &[u8]) -> TimeZoneProviderResult { + unimplemented!() + } + + fn canonicalized(&self, _: NormalizedId) -> TimeZoneProviderResult { + unimplemented!() + } + + fn identifier(&self, _: NormalizedId) -> TimeZoneProviderResult<&str> { + unimplemented!() + } +} + +impl TimeZoneResolver for NeverResolver { + fn get_id(&self, _normalized_identifier: &[u8]) -> TimeZoneProviderResult { + unimplemented!() + } + + fn candidate_nanoseconds_for_local_epoch_nanoseconds( + &self, + _identifier: ResolvedId, + _local_datetime: IsoDateTime, + ) -> TimeZoneProviderResult { + unimplemented!() + } + + fn transition_nanoseconds_for_utc_epoch_nanoseconds( + &self, + _identifier: ResolvedId, + _epoch_nanoseconds: i128, + ) -> TimeZoneProviderResult { + unimplemented!() + } + + fn get_time_zone_transition( + &self, + _identifier: ResolvedId, + _epoch_nanoseconds: i128, + _direction: TransitionDirection, + ) -> TimeZoneProviderResult> { + unimplemented!() + } +} + +/// A [`TimeZoneProvider`] which just calls `unimplemented!()` +pub type NeverProvider = NormalizerAndResolver; diff --git a/deps/temporal/provider/src/tzdb.rs b/deps/temporal/provider/src/tzdb.rs new file mode 100644 index 00000000000000..c63c47d12298e2 --- /dev/null +++ b/deps/temporal/provider/src/tzdb.rs @@ -0,0 +1,85 @@ +//! `timezone_provider` is the core data provider implementations for `temporal_rs` + +// What are we even doing here? Why are providers needed? +// +// Two core data sources need to be accounted for: +// +// - IANA identifier normalization (hopefully, semi easy) +// - IANA TZif data (much harder) +// + +use alloc::borrow::Cow; + +use crate::provider::{NormalizedId, TimeZoneNormalizer, TimeZoneProviderResult}; +use crate::TimeZoneProviderError; +use crate::SINGLETON_IANA_NORMALIZER; +use zerotrie::ZeroAsciiIgnoreCaseTrie; +use zerovec::{VarZeroVec, ZeroVec}; + +#[cfg(feature = "datagen")] +pub(crate) mod datagen; + +/// A data struct for IANA identifier normalization +#[derive(PartialEq, Debug, Clone)] +#[cfg_attr( + feature = "datagen", + derive(serde::Serialize, yoke::Yokeable, serde::Deserialize, databake::Bake) +)] +#[cfg_attr(feature = "datagen", databake(path = timezone_provider))] +pub struct IanaIdentifierNormalizer<'data> { + /// TZDB version + pub version: Cow<'data, str>, + /// An index to the location of the normal identifier. + #[cfg_attr(feature = "datagen", serde(borrow))] + pub available_id_index: ZeroAsciiIgnoreCaseTrie>, + /// A "links" table mapping non-canonical IDs to their canonical IDs + #[cfg_attr(feature = "datagen", serde(borrow))] + pub non_canonical_identifiers: ZeroVec<'data, (u32, u32)>, + /// The normalized IANA identifier + #[cfg_attr(feature = "datagen", serde(borrow))] + pub normalized_identifiers: VarZeroVec<'data, str>, +} + +/// A simple [`TimeZoneNormalizer`] that uses compiled data. +#[derive(Default, Copy, Clone, Debug)] +pub struct CompiledNormalizer; + +impl TimeZoneNormalizer for CompiledNormalizer { + fn normalized(&self, identifier: &[u8]) -> TimeZoneProviderResult { + SINGLETON_IANA_NORMALIZER + .available_id_index + .get(identifier) + .map(NormalizedId) + .ok_or(TimeZoneProviderError::Range("Unknown time zone identifier")) + } + + fn canonicalized(&self, index: NormalizedId) -> TimeZoneProviderResult { + let Ok(u32_index) = u32::try_from(index.0) else { + return Ok(index); + }; + let Ok(canonicalized_idx) = SINGLETON_IANA_NORMALIZER + .non_canonical_identifiers + .binary_search_by(|probe| probe.0.cmp(&u32_index)) + else { + return Ok(index); + }; + + Ok(NormalizedId( + usize::try_from( + SINGLETON_IANA_NORMALIZER + .non_canonical_identifiers + .get(canonicalized_idx) + .ok_or(TimeZoneProviderError::Range("Unknown time zone identifier"))? + .1, + ) + .unwrap_or(0), + )) + } + + fn identifier(&self, index: NormalizedId) -> TimeZoneProviderResult<&str> { + SINGLETON_IANA_NORMALIZER + .normalized_identifiers + .get(index.0) + .ok_or(TimeZoneProviderError::Range("Unknown time zone identifier")) + } +} diff --git a/deps/temporal/provider/src/tzdb/datagen.rs b/deps/temporal/provider/src/tzdb/datagen.rs new file mode 100644 index 00000000000000..24479c6bef5d59 --- /dev/null +++ b/deps/temporal/provider/src/tzdb/datagen.rs @@ -0,0 +1,129 @@ +use super::*; +use alloc::string::String; +use alloc::vec::Vec; +use std::{ + borrow::ToOwned, + collections::{BTreeMap, BTreeSet}, + fs, io, + path::Path, +}; +use zoneinfo_rs::{ZoneInfoData, ZoneInfoError}; + +#[derive(Debug)] +pub enum TzdbDataSourceError { + Io(io::Error), + ZoneInfo(ZoneInfoError), +} + +impl From for TzdbDataSourceError { + fn from(value: io::Error) -> Self { + Self::Io(value) + } +} + +impl From for TzdbDataSourceError { + fn from(value: ZoneInfoError) -> Self { + Self::ZoneInfo(value) + } +} + +pub struct TzdbDataSource { + pub version: String, + pub data: ZoneInfoData, +} + +impl TzdbDataSource { + /// Try to create a tzdb source from a tzdata directory. + pub fn try_from_zoneinfo_directory(tzdata_path: &Path) -> Result { + let version_file = tzdata_path.join("version"); + let version = fs::read_to_string(version_file)?.trim().to_owned(); + let data = ZoneInfoData::from_zoneinfo_directory(tzdata_path)?; + Ok(Self { version, data }) + } + + /// Try to create a tzdb source from a tzdata rearguard.zi + /// + /// To generate a rearguard.zi, download tzdata from IANA. Run `make rearguard.zi` + pub fn try_from_rearguard_zoneinfo_dir( + tzdata_path: &Path, + ) -> Result { + let version_file = tzdata_path.join("version"); + let version = fs::read_to_string(version_file)?.trim().to_owned(); + let rearguard_zoneinfo = tzdata_path.join("rearguard.zi"); + let data = ZoneInfoData::from_filepath(rearguard_zoneinfo)?; + Ok(Self { version, data }) + } +} + +// ==== Begin DataProvider impl ==== + +#[derive(Debug)] +pub enum IanaDataError { + Io(io::Error), + Provider(TzdbDataSourceError), + Build(zerotrie::ZeroTrieBuildError), +} + +#[allow(clippy::expect_used, clippy::unwrap_used, reason = "Datagen only")] +impl IanaIdentifierNormalizer<'_> { + pub fn build(tzdata_path: &Path) -> Result { + let provider = TzdbDataSource::try_from_zoneinfo_directory(tzdata_path) + .map_err(IanaDataError::Provider)?; + let mut all_identifiers = BTreeSet::default(); + for zone_id in provider.data.zones.keys() { + // Add canonical identifiers. + let _ = all_identifiers.insert(&**zone_id); + } + + for link_from in provider.data.links.keys() { + // Add link / non-canonical identifiers + let _ = all_identifiers.insert(link_from); + } + // Make a sorted list of canonical timezones + let norm_vec: Vec<&str> = all_identifiers.iter().copied().collect(); + let norm_zerovec: VarZeroVec<'static, str> = norm_vec.as_slice().into(); + + let identifier_map: BTreeMap, usize> = all_identifiers + .iter() + .map(|id| { + let normalized_id = norm_vec.binary_search(id).unwrap(); + + (id.to_ascii_lowercase().as_bytes().to_vec(), normalized_id) + }) + .collect(); + + let mut primary_id_map: BTreeMap = BTreeMap::new(); + // ECMAScript implementations must support an available named time zone with the identifier "UTC", which must be + // the primary time zone identifier for the UTC time zone. In addition, implementations may support any number of other available named time zones. + let utc_index = norm_vec.binary_search(&"UTC").unwrap(); + primary_id_map.insert(norm_vec.binary_search(&"Etc/UTC").unwrap(), utc_index); + primary_id_map.insert(norm_vec.binary_search(&"Etc/GMT").unwrap(), utc_index); + + for (link_from, link_to) in &provider.data.links { + if link_from == "UTC" { + continue; + } + let link_from = norm_vec.binary_search(&&**link_from).unwrap(); + let index = if link_to == "Etc/UTC" || link_to == "Etc/GMT" { + utc_index + } else { + norm_vec.binary_search(&&**link_to).unwrap() + }; + primary_id_map.insert(link_from, index); + } + + Ok(IanaIdentifierNormalizer { + version: provider.version.into(), + available_id_index: ZeroAsciiIgnoreCaseTrie::try_from(&identifier_map) + .map_err(IanaDataError::Build)? + .convert_store(), + non_canonical_identifiers: primary_id_map + .iter() + .map(|(x, y)| (u32::try_from(*x).unwrap(), u32::try_from(*y).unwrap())) + .collect(), + normalized_identifiers: norm_zerovec, + }) + } +} + +// ==== End DataProvider impl ==== diff --git a/deps/temporal/provider/src/tzif.rs b/deps/temporal/provider/src/tzif.rs new file mode 100644 index 00000000000000..6bbbf0076b4a8e --- /dev/null +++ b/deps/temporal/provider/src/tzif.rs @@ -0,0 +1,2007 @@ +// Relevant operations: +// +// - Time Zone Identifiers +// - AvailableNamedTimeZoneIdentifiers +// - SystemTimeZoneIdentifier +// - IsTimeZoneOffsetString +// - GetNamedTimeZoneEpochNanoseconds +// - fn(id, isoDateTimeRecord) -> [epochNanoseconds] +// - GetNamedTimeZoneOffsetNanoseconds +// - fn(id, epochNanoseconds) -> [offset] + +// TODO: Potentially implement a IsoDateTimeRecord type to decouple +// public facing APIs from IsoDateTime + +// Could return type be something like [Option; 2] + +// NOTE: tzif data is computed in glibc's `__tzfile_compute` in `tzfile.c`. +// +// Handling the logic here may be incredibly important for full tzif support. + +// NOTES: +// +// Transitions to DST (in march) + 1. Empty list between 2:00-3:00. +// Transitions to Std (in nov) -1. Two elements 1:00-2:00 is repeated twice. + +// Transition Seconds + (offset diff) +// where +// offset diff = is_dst { dst_off - std_off } else { std_off - dst_off }, i.e. to_offset - from_offset + +use std::path::Path; +#[cfg(target_family = "unix")] +use std::path::PathBuf; + +use crate::provider::EpochNanosecondsAndOffset; +use crate::CompiledNormalizer; +use alloc::collections::BTreeMap; +use alloc::string::String; +use alloc::vec::Vec; +use core::cmp::Ordering; +use core::ops::Range; +use core::str; +use std::sync::RwLock; + +use combine::Parser; + +use tzif::{ + self, + data::{ + posix::{DstTransitionInfo, PosixTzString, TransitionDate, TransitionDay}, + time::Seconds, + tzif::{DataBlock, LocalTimeTypeRecord, TzifData, TzifHeader}, + }, +}; + +use crate::utils; + +use crate::provider::{ + CandidateEpochNanoseconds, GapEntryOffsets, IsoDateTime, NormalizerAndResolver, ResolvedId, + TimeZoneProviderResult, TimeZoneResolver, TransitionDirection, UtcOffsetSeconds, +}; +use crate::{ + epoch_nanoseconds::{seconds_to_nanoseconds, EpochNanoseconds, NS_IN_S}, + TimeZoneProviderError, +}; + +#[cfg(target_family = "unix")] +const ZONEINFO_DIR: &str = "/usr/share/zoneinfo/"; + +// TODO: Workshop record name? +/// The `LocalTimeRecord` result represents the result of searching for a +/// time zone transition without the offset seconds applied to the +/// epoch seconds. +/// +/// As a result of the search, it is possible for the resulting search to be either +/// Empty (due to an invalid time being provided that would be in the +1 tz shift) +/// or two time zones (when a time exists in the ambiguous range of a -1 shift). +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum LocalTimeRecordResult { + Empty(GapEntryOffsets), + Single(UtcOffsetSeconds), + Ambiguous { + first: UtcOffsetSeconds, + second: UtcOffsetSeconds, + }, +} + +/// `TimeZoneTransitionInfo` represents information about a timezone transition. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct TimeZoneTransitionInfo { + /// The transition time epoch at which the offset needs to be applied. + pub transition_epoch: Option, + /// The time zone offset in seconds. + pub offset: UtcOffsetSeconds, +} + +impl From for LocalTimeRecordResult { + fn from(value: UtcOffsetSeconds) -> Self { + Self::Single(value) + } +} + +impl From for LocalTimeRecordResult { + fn from(value: LocalTimeTypeRecord) -> Self { + Self::Single(value.into()) + } +} + +impl From<(LocalTimeTypeRecord, LocalTimeTypeRecord)> for LocalTimeRecordResult { + fn from(value: (LocalTimeTypeRecord, LocalTimeTypeRecord)) -> Self { + Self::Ambiguous { + first: value.0.into(), + second: value.1.into(), + } + } +} + +/// `TZif` stands for Time zone information format is laid out by [RFC 8536][rfc8536] and +/// laid out by the [tzdata manual][tzif-manual] +/// +/// To be specific, this representation of `TZif` is solely to extend functionality +/// fo the parsed type from the `tzif` [rust crate][tzif-crate], which has further detail on the +/// layout in Rust. +/// +/// `TZif` files are compiled via [`zic`][zic-manual], which offers a variety of options for changing the layout +/// and range of a `TZif`. +/// +/// [rfc8536]: https://datatracker.ietf.org/doc/html/rfc8536 +/// [tzif-manual]: https://man7.org/linux/man-pages/man5/tzfile.5.html +/// [tzif-crate]: https://docs.rs/tzif/latest/tzif/ +/// [zic-manual]: https://man7.org/linux/man-pages/man8/zic.8.html +#[derive(Debug, Clone)] +pub struct Tzif { + pub header1: TzifHeader, + pub data_block1: DataBlock, + pub header2: Option, + pub data_block2: Option, + pub footer: Option, +} + +impl From for Tzif { + fn from(value: TzifData) -> Self { + let TzifData { + header1, + data_block1, + header2, + data_block2, + footer, + } = value; + + Self { + header1, + data_block1, + header2, + data_block2, + footer, + } + } +} + +impl Tzif { + pub fn from_bytes(data: &[u8]) -> TimeZoneProviderResult { + let Ok((parse_result, _)) = tzif::parse::tzif::tzif().parse(data) else { + return Err(TimeZoneProviderError::Assert("Illformed Tzif data.")); + }; + Ok(Self::from(parse_result)) + } + + #[cfg(target_family = "unix")] + pub fn read_tzif(identifier: &str) -> TimeZoneProviderResult { + // Protect from path traversal attacks + if identifier.starts_with('/') || identifier.contains('.') { + return Err(TimeZoneProviderError::Range( + "Ill-formed timezone identifier", + )); + } + let mut path = PathBuf::from(ZONEINFO_DIR); + path.push(identifier); + Self::from_path(&path) + } + + pub fn from_path(path: &Path) -> TimeZoneProviderResult { + if !path.exists() { + return Err(TimeZoneProviderError::Range("Unknown timezone identifier")); + } + tzif::parse_tzif_file(path) + .map(Into::into) + .map_err(|_| TimeZoneProviderError::Assert("Tzif parsing error")) + } + + pub fn posix_tz_string(&self) -> Option<&PosixTzString> { + self.footer.as_ref() + } + + pub fn get_data_block2(&self) -> TimeZoneProviderResult<&DataBlock> { + self.data_block2 + .as_ref() + .ok_or(TimeZoneProviderError::Assert("Only Tzif V2+ is supported.")) + } + + pub fn get(&self, epoch_seconds: &Seconds) -> TimeZoneProviderResult { + let db = self.get_data_block2()?; + + let result = db.transition_times.binary_search(epoch_seconds); + + match result { + // The transition time was given. The transition entries *start* at their + // transition time, so we use the same index + Ok(idx) => Ok(get_timezone_offset(db, idx)), + // + // If there are no transitions, local time for all timestamps is specified by the TZ + // string in the footer if present and nonempty; otherwise, it is + // specified by time type 0. + Err(_) if db.transition_times.is_empty() => { + if let Some(posix_tz_string) = self.posix_tz_string() { + resolve_posix_tz_string_for_epoch_seconds(posix_tz_string, epoch_seconds.0) + } else { + Ok(TimeZoneTransitionInfo { + offset: db + .local_time_type_records + .first() + .copied() + .ok_or(TimeZoneProviderError::Assert("Out of transition range"))? + .into(), + transition_epoch: None, + }) + } + } + // Our time is before the first transition. + // Get the first timezone offset + Err(0) => Ok(get_first_timezone_offset(db)), + // Our time is after some transition. + Err(idx) => { + if db.transition_times.len() <= idx { + // The transition time provided is beyond the length of + // the available transition time, so the time zone is + // resolved with the POSIX tz string. + let mut offset = resolve_posix_tz_string_for_epoch_seconds( + self.posix_tz_string().ok_or(TimeZoneProviderError::Assert( + "No POSIX tz string to resolve with.", + ))?, + epoch_seconds.0, + )?; + if offset.transition_epoch.is_none() { + offset.transition_epoch = Some( + db.transition_times + .get(idx - 1) + .ok_or(TimeZoneProviderError::Assert("Out of transition range"))? + .0, + ) + } + return Ok(offset); + } + // binary_search returns the insertion index, which is one after the + // index of the closest lower bound. Fetch that bound. + Ok(get_timezone_offset(db, idx - 1)) + } + } + } + + fn transition_nanoseconds_for_utc_epoch_nanoseconds( + &self, + utc_epoch: i128, + ) -> TimeZoneProviderResult { + let mut seconds = (utc_epoch / NS_IN_S) as i64; + // The rounding is inexact. Transitions are only at second + // boundaries, so the offset at N s is the same as the offset at N.001, + // but the offset at -Ns is not the same as the offset at -N.001, + // the latter matches -N - 1 s instead. + if seconds < 0 && utc_epoch % NS_IN_S != 0 { + seconds -= 1; + } + self.get(&Seconds(seconds)).map(|t| t.offset) + } + + // Helper function to call resolve_posix_tz_string + fn resolve_posix_tz_string( + &self, + local_seconds: &Seconds, + ) -> TimeZoneProviderResult { + resolve_posix_tz_string( + self.posix_tz_string().ok_or(TimeZoneProviderError::Assert( + "Could not resolve time zone.", + ))?, + local_seconds.0, + ) + } + + pub fn get_time_zone_transition( + &self, + epoch_nanoseconds: i128, + direction: TransitionDirection, + ) -> TimeZoneProviderResult> { + // First search the tzif data + + let epoch_seconds = Seconds((epoch_nanoseconds / NS_IN_S) as i64); + // When *exactly* on a transition the spec wants you to + // get the next one, so it's important to know if we are + // actually on epoch_seconds or a couple nanoseconds before/after it + // to handle the exact match case + let seconds_is_exact = (epoch_nanoseconds % NS_IN_S) == 0; + let seconds_is_negative = epoch_nanoseconds < 0; + let db = self.get_data_block2()?; + + let b_search_result = db.transition_times.binary_search(&epoch_seconds); + + let mut transition_idx = match b_search_result { + Ok(idx) => { + match (direction, seconds_is_exact, seconds_is_negative) { + // If we are N.001 for negative N, the next transition is idx + (TransitionDirection::Next, false, true) => idx, + // If we are exactly N, or N.001 for positive N, the next transition is idx + 1 + (TransitionDirection::Next, true, _) + | (TransitionDirection::Next, false, false) => idx + 1, + // If we are N.001 for positive N, the previous transition the one at idx (= N) + (TransitionDirection::Previous, false, false) => idx, + // If we are exactly N, or N.0001 for negative N, the previous transition is idx - 1 + (TransitionDirection::Previous, true, _) + | (TransitionDirection::Previous, false, true) => { + if let Some(idx) = idx.checked_sub(1) { + idx + } else { + // If we found the first transition, there is no previous one, + // return None + return Ok(None); + } + } + } + } + // idx is insertion index here, so it is the index of the closest upper + // transition + Err(idx) => match direction { + TransitionDirection::Next => idx, + // Special case, we're after the end of the array, we want to make + // sure we hit the POSIX tz handling and we should not subtract one. + TransitionDirection::Previous if idx == db.transition_times.len() => idx, + TransitionDirection::Previous => { + // Go one previous + if let Some(idx) = idx.checked_sub(1) { + idx + } else { + // If we found the first transition, there is no previous one, + // return None + return Ok(None); + } + } + }, + }; + + while let Some(tzif_transition) = maybe_get_transition_info(db, transition_idx) { + // This is not a real transition. Skip it. + if tzif_transition.prev.utoff == tzif_transition.next.utoff { + match direction { + TransitionDirection::Next => transition_idx += 1, + TransitionDirection::Previous if transition_idx == 0 => return Ok(None), + TransitionDirection::Previous => transition_idx -= 1, + } + } else { + return Ok(Some(tzif_transition.transition_time.into())); + } + } + + // We went past the Tzif transitions. We need to handle the posix string instead. + let posix_tz_string = self.posix_tz_string().ok_or(TimeZoneProviderError::Assert( + "Could not resolve time zone.", + ))?; + + // The last transition in the tzif tables. + // We should not go back beyond this + let last_tzif_transition = db.transition_times.last().copied(); + + // We need to do a similar backwards iteration to find the last real transition. + // Do it only when needed, this case will only show up when walking Previous for a date + // just after the last tzif transition but before the first posix transition. + let last_real_tzif_transition = || { + debug_assert!(direction == TransitionDirection::Previous); + for last_transition_idx in (0..db.transition_times.len()).rev() { + if let Some(tzif_transition) = maybe_get_transition_info(db, last_transition_idx) { + if tzif_transition.prev.utoff == tzif_transition.next.utoff { + continue; + } + return Some(tzif_transition.transition_time); + } + break; + } + None + }; + + let Some(dst_variant) = &posix_tz_string.dst_info else { + // There are no further transitions. + match direction { + TransitionDirection::Next => return Ok(None), + TransitionDirection::Previous => { + // Go back to the last tzif transition + if last_tzif_transition.is_some() { + if let Some(last_real_tzif_transition) = last_real_tzif_transition() { + return Ok(Some(last_real_tzif_transition.into())); + } + } + return Ok(None); + } + } + }; + + // Calculate year, but clamp it to the last transition + // We do not want to try and apply the posix string to earlier years! + // + // Antarctica/Troll is an example of a timezone that has a posix string + // but no meaningful previous transitions. + let mut epoch_seconds_for_year_calculation = epoch_seconds; + if let Some(last_tzif_transition) = last_tzif_transition { + if epoch_seconds < last_tzif_transition { + epoch_seconds_for_year_calculation = last_tzif_transition; + } + } + let year = utils::epoch_time_to_iso_year(epoch_seconds_for_year_calculation.0 * 1000); + + let transition_info = DstTransitionInfoForYear::compute(posix_tz_string, dst_variant, year); + + let range = transition_info.transition_range(); + + let mut seconds = match direction { + TransitionDirection::Next => { + // Inexact seconds in the negative case means that (seconds == foo) is actually + // seconds < foo + // + // This code will likely not actually be hit: the current Tzif database has no + // entries with DST offset posix strings where the posix string starts + // before the unix epoch. + let seconds_is_inexact_for_negative = seconds_is_negative && !seconds_is_exact; + // We're before the first transition + if epoch_seconds < range.start + || (epoch_seconds == range.start && seconds_is_inexact_for_negative) + { + range.start + } else if epoch_seconds < range.end + || (epoch_seconds == range.end && seconds_is_inexact_for_negative) + { + // We're between the first and second transition + range.end + } else { + // We're after the second transition + let transition_info = + DstTransitionInfoForYear::compute(posix_tz_string, dst_variant, year + 1); + + transition_info.transition_range().start + } + } + TransitionDirection::Previous => { + // Inexact seconds in the positive case means that (seconds == foo) is actually + // seconds > foo + let seconds_is_ineexact_for_positive = !seconds_is_negative && !seconds_is_exact; + // We're after the second transition + // (note that seconds_is_exact means that epoch_seconds == range.end actually means equality) + if epoch_seconds > range.end + || (epoch_seconds == range.end && seconds_is_ineexact_for_positive) + { + range.end + } else if epoch_seconds > range.start + || (epoch_seconds == range.start && seconds_is_ineexact_for_positive) + { + // We're after the first transition + range.start + } else { + // We're before the first transition + let transition_info = + DstTransitionInfoForYear::compute(posix_tz_string, dst_variant, year - 1); + + transition_info.transition_range().end + } + } + }; + + if let Some(last_tzif_transition) = last_tzif_transition { + // When going Previous, we went back into the area of tzif transition + if seconds < last_tzif_transition { + if let Some(last_real_tzif_transition) = last_real_tzif_transition() { + seconds = last_real_tzif_transition; + } else { + return Ok(None); + } + } + } + + Ok(Some(seconds.into())) + } + + // For more information, see /docs/TZDB.md + /// This function determines the Time Zone output for a local epoch + /// nanoseconds value without an offset. + /// + /// Basically, if someone provides a DateTime 2017-11-05T01:30:00, + /// we have no way of knowing if this value is in DST or STD. + /// Furthermore, for the above example, this should return 2 time + /// zones due to there being two 2017-11-05T01:30:00. On the other + /// side of the transition, the DateTime 2017-03-12T02:30:00 could + /// be provided. This time does NOT exist due to the +1 jump from + /// 02:00 -> 03:00 (but of course it does as a nanosecond value). + pub fn v2_estimate_tz_pair( + &self, + local_seconds: &Seconds, + ) -> TimeZoneProviderResult { + // We need to estimate a tz pair. + // First search the ambiguous seconds. + let db = self.get_data_block2()?; + + // Note that this search is *approximate*. transition_times + // is in UTC epoch times, whereas we have a local time. + // + // An assumption we make is that this will at worst give us an off-by-one error; + // transition times should not be less than a day apart. + let b_search_result = db.transition_times.binary_search(local_seconds); + + let mut estimated_idx = match b_search_result { + Ok(idx) => idx, + Err(idx) => idx, + }; + // If we're either out of bounds or at the last + // entry, we need to check if we're after it, since if we + // are we need to use posix_tz_string instead. + // + // This includes the last entry (hence `idx + 1`) since our search was approximate. + if estimated_idx + 1 >= db.transition_times.len() { + // If we are *well past* the last transition time, we want + // to use the posix tz string + let mut use_posix = true; + if !db.transition_times.is_empty() { + // In case idx was out of bounds, bring it back in + estimated_idx = db.transition_times.len() - 1; + let transition_info = get_transition_info(db, estimated_idx); + + // I'm not fully sure if this is correct. + // Is the next_offset valid for the last transition time in its + // vicinity? Probably? It does not seem pleasant to try and do this + // math using half of the transition info and half of the posix info. + // + // TODO(manishearth, nekevss): https://github.com/boa-dev/temporal/issues/469 + if transition_info.transition_time_prev_epoch() > *local_seconds + || transition_info.transition_time_next_epoch() > *local_seconds + { + // We're before the transition fully ends; we should resolve + // with the regular transition time instead of use_posix + use_posix = false; + } + } + if use_posix { + // The transition time provided is beyond the length of + // the available transition time, so the time zone is + // resolved with the POSIX tz string. + return self.resolve_posix_tz_string(local_seconds); + } + } + + debug_assert!(estimated_idx < db.transition_times.len()); + + let transition_info = get_transition_info(db, estimated_idx); + + let range = transition_info.offset_range_local(); + + if range.contains(local_seconds) { + return Ok(transition_info.record_for_contains()); + } else if *local_seconds < range.start { + if estimated_idx == 0 { + // We're at the beginning, there are no timezones before us + // So we just return the first offset + return Ok(LocalTimeRecordResult::Single(transition_info.prev.into())); + } + // Otherwise, try the previous offset + estimated_idx -= 1; + } else { + if estimated_idx + 1 == db.transition_times.len() { + // We're at the end, return posix instead + return self.resolve_posix_tz_string(local_seconds); + } + // Otherwise, try the next offset + estimated_idx += 1; + } + + let transition_info = get_transition_info(db, estimated_idx); + let range = transition_info.offset_range_local(); + + if range.contains(local_seconds) { + Ok(transition_info.record_for_contains()) + } else if *local_seconds < range.start { + // Note that get_transition_info will correctly fetch the first offset + // into .prev when working with the first transition. + Ok(LocalTimeRecordResult::Single(transition_info.prev.into())) + } else { + // We're at the end, return posix instead + if estimated_idx + 1 == db.transition_times.len() { + return self.resolve_posix_tz_string(local_seconds); + } + Ok(LocalTimeRecordResult::Single(transition_info.next.into())) + } + } + + /// Given a *local* datetime, return all possible epoch nanosecond values for it + fn candidate_nanoseconds_for_local_epoch_nanoseconds( + &self, + local_datetime: IsoDateTime, + ) -> TimeZoneProviderResult { + let epoch_nanos = (local_datetime).as_nanoseconds(); + let mut seconds = (epoch_nanos.0 / NS_IN_S) as i64; + + // We just rounded our ns value to seconds. + // This is fine for positive ns: timezones do not transition at sub-second offsets, + // so the offset at N seconds is always the offset at N.0001 seconds. + // + // However, for negative epochs, the offset at -N seconds might be different + // from that at -N.001 seconds. Instead, we calculate the offset at (-N-1) seconds. + if seconds < 0 { + let remainder = epoch_nanos.0 % NS_IN_S; + if remainder != 0 { + seconds -= 1; + } + } + + let local_time_record_result = self.v2_estimate_tz_pair(&Seconds(seconds))?; + let result = match local_time_record_result { + LocalTimeRecordResult::Empty(bounds) => CandidateEpochNanoseconds::Zero(bounds), + LocalTimeRecordResult::Single(r) => { + let epoch_ns = EpochNanoseconds::from(epoch_nanos.0 - seconds_to_nanoseconds(r.0)); + CandidateEpochNanoseconds::One(EpochNanosecondsAndOffset { + ns: epoch_ns, + offset: r, + }) + } + LocalTimeRecordResult::Ambiguous { first, second } => { + let first_epoch_ns = + EpochNanoseconds::from(epoch_nanos.0 - seconds_to_nanoseconds(first.0)); + let second_epoch_ns = + EpochNanoseconds::from(epoch_nanos.0 - seconds_to_nanoseconds(second.0)); + CandidateEpochNanoseconds::Two([ + EpochNanosecondsAndOffset { + ns: first_epoch_ns, + offset: first, + }, + EpochNanosecondsAndOffset { + ns: second_epoch_ns, + offset: second, + }, + ]) + } + }; + Ok(result) + } +} + +#[inline] +fn get_timezone_offset(db: &DataBlock, idx: usize) -> TimeZoneTransitionInfo { + // NOTE: Transition type can be empty. If no transition_type exists, + // then use 0 as the default index of local_time_type_records. + let offset = db + .local_time_type_records + .get(db.transition_types.get(idx).copied().unwrap_or(0)); + debug_assert!(offset.is_some(), "tzif internal invariant violated"); + TimeZoneTransitionInfo { + transition_epoch: db.transition_times.get(idx).map(|s| s.0), + offset: offset.copied().unwrap_or_default().into(), + } +} + +#[inline] +fn get_first_timezone_offset(db: &DataBlock) -> TimeZoneTransitionInfo { + let offset = db.local_time_type_records.first(); + debug_assert!(offset.is_some(), "tzif internal invariant violated"); + TimeZoneTransitionInfo { + // There was no transition into the first timezone + transition_epoch: None, + offset: offset.copied().unwrap_or_default().into(), + } +} + +#[inline] +fn get_local_record(db: &DataBlock, idx: usize) -> LocalTimeTypeRecord { + // NOTE: Transition type can be empty. If no transition_type exists, + // then use 0 as the default index of local_time_type_records. + let idx = db.transition_types.get(idx).copied().unwrap_or(0); + + let get = db.local_time_type_records.get(idx); + debug_assert!(get.is_some(), "tzif internal invariant violated"); + get.copied().unwrap_or_default() +} + +#[inline] +fn get_transition_info(db: &DataBlock, idx: usize) -> TzifTransitionInfo { + let info = maybe_get_transition_info(db, idx); + debug_assert!(info.is_some(), "tzif internal invariant violated"); + info.unwrap_or_default() +} + +#[inline] +fn maybe_get_transition_info(db: &DataBlock, idx: usize) -> Option { + let next = get_local_record(db, idx); + let transition_time = *db.transition_times.get(idx)?; + let prev = if idx == 0 { + *db.local_time_type_records.first()? + } else { + get_local_record(db, idx - 1) + }; + Some(TzifTransitionInfo { + prev, + next, + transition_time, + }) +} + +/// Information obtained from the tzif file about a transition. +#[derive(Debug, Default)] +struct TzifTransitionInfo { + /// The time record from before this transition + prev: LocalTimeTypeRecord, + /// The time record corresponding to this transition and dates after it + next: LocalTimeTypeRecord, + /// The UTC epoch seconds for the transition + transition_time: Seconds, +} + +impl TzifTransitionInfo { + /// Get the previous offset as a number of seconds from + /// 1970-01-01 in local time as reckoned by the previous offset + fn transition_time_prev_epoch(&self) -> Seconds { + // You always add the UTC offset to get the local time; + // so a local time in PST (-08:00) will be `utc - 8h` + self.transition_time + self.prev.utoff + } + /// Get the previous offset as a number of seconds from + /// 1970-01-01 in local time as reckoned by the next offset + fn transition_time_next_epoch(&self) -> Seconds { + // You always add the UTC offset to get the local time; + // so a local time in PST (-08:00) will be `utc - 8h` + self.transition_time + self.next.utoff + } + + /// Gets the range of local times where this transition is active + /// + /// Note that this will always be start..end, NOT prev..next: if the next + /// offset is before prev (e.g. for a TransitionKind::Overlap) year, + /// it will be next..prev. + /// + /// You should use .kind() to understand how to interpret this + fn offset_range_local(&self) -> Range { + let prev = self.transition_time_prev_epoch(); + let next = self.transition_time_next_epoch(); + match self.kind() { + TransitionKind::Overlap => next..prev, + _ => prev..next, + } + } + + /// What is the kind of the transition? + fn kind(&self) -> TransitionKind { + match self.prev.utoff.cmp(&self.next.utoff) { + Ordering::Less => TransitionKind::Gap, + Ordering::Greater => TransitionKind::Overlap, + Ordering::Equal => TransitionKind::Smooth, + } + } + + /// If a time is found to be within self.offset_range_local(), + /// what is the corresponding LocalTimeRecordResult? + fn record_for_contains(&self) -> LocalTimeRecordResult { + match self.kind() { + TransitionKind::Gap => LocalTimeRecordResult::Empty(GapEntryOffsets { + offset_before: self.prev.into(), + offset_after: self.next.into(), + transition_epoch: self.transition_time.into(), + }), + TransitionKind::Overlap => LocalTimeRecordResult::Ambiguous { + first: self.prev.into(), + second: self.next.into(), + }, + TransitionKind::Smooth => LocalTimeRecordResult::Single(self.prev.into()), + } + } +} + +#[derive(Debug)] +enum TransitionKind { + // The offsets didn't change (happens when abbreviations/savings values change) + Smooth, + // The offsets changed in a way that leaves a gap + Gap, + // The offsets changed in a way that produces overlapping time. + Overlap, +} + +/// Stores the information about DST transitions for a given year +struct DstTransitionInfoForYear { + dst_start_seconds: Seconds, + dst_end_seconds: Seconds, + std_offset: UtcOffsetSeconds, + dst_offset: UtcOffsetSeconds, +} + +impl DstTransitionInfoForYear { + fn compute( + posix_tz_string: &PosixTzString, + dst_variant: &DstTransitionInfo, + year: i32, + ) -> Self { + let std_offset = UtcOffsetSeconds::from(&posix_tz_string.std_info); + let dst_offset = UtcOffsetSeconds::from(&dst_variant.variant_info); + let dst_start_seconds = Seconds(calculate_transition_seconds_for_year( + year, + dst_variant.start_date, + std_offset, + )); + let dst_end_seconds = Seconds(calculate_transition_seconds_for_year( + year, + dst_variant.end_date, + dst_offset, + )); + Self { + dst_start_seconds, + dst_end_seconds, + std_offset, + dst_offset, + } + } + + // Returns the range between offsets in this year + // This may cover DST or standard time, whichever starts first + pub fn transition_range(&self) -> Range { + if self.dst_start_seconds > self.dst_end_seconds { + self.dst_end_seconds..self.dst_start_seconds + } else { + self.dst_start_seconds..self.dst_end_seconds + } + } +} + +// NOTE: seconds here are epoch, so they are exact, not wall time. +#[inline] +fn resolve_posix_tz_string_for_epoch_seconds( + posix_tz_string: &PosixTzString, + seconds: i64, +) -> TimeZoneProviderResult { + let Some(dst_variant) = &posix_tz_string.dst_info else { + // Regardless of the time, there is one variant and we can return it. + return Ok(TimeZoneTransitionInfo { + transition_epoch: None, + offset: UtcOffsetSeconds::from(&posix_tz_string.std_info), + }); + }; + + let year = utils::epoch_time_to_iso_year(seconds * 1000); + + let transition_info = DstTransitionInfoForYear::compute(posix_tz_string, dst_variant, year); + let dst_start_seconds = transition_info.dst_start_seconds.0; + let dst_end_seconds = transition_info.dst_end_seconds.0; + + // Need to determine if the range being tested is standard or savings time. + let dst_is_inversed = dst_end_seconds < dst_start_seconds; + + // We have potentially to different variations of the DST start and end time. + // + // Northern hemisphere: dst_start -> dst_end + // Southern hemisphere: dst_end -> dst_start + // + // This is primarily due to the summer / winter months of those areas. + // + // For the northern hemispere, we can check if the range contains the seconds. For the + // southern hemisphere, we check if the range does no contain the value. + let should_return_dst = (!dst_is_inversed + && (dst_start_seconds..dst_end_seconds).contains(&seconds)) + || (dst_is_inversed && !(dst_end_seconds..dst_start_seconds).contains(&seconds)); + + // Expanding on the above, the state of time zones in the year are: + // + // Northern hemisphere: STD -> DST -> STD + // Southern hemisphere: DST -> STD -> DST + // + // This is simple for the returning the offsets, but if the seconds value falls into the first + // available rule. However, the northern hemisphere's first STD rule and the Southern hemisphere's + // first DST rule will have different transition times that are based in the year prior, so if the + // requested seconds falls in that range, we calculate the transition time for the prior year. + let (new_offset, transition_epoch) = if should_return_dst { + let transition_epoch = if dst_is_inversed && seconds < dst_end_seconds { + Some(calculate_transition_seconds_for_year( + year - 1, + dst_variant.start_date, + transition_info.dst_offset, + )) + } else { + Some(dst_start_seconds) + }; + (transition_info.dst_offset, transition_epoch) + } else { + let transition_epoch = if !dst_is_inversed && seconds < dst_start_seconds { + Some(calculate_transition_seconds_for_year( + year - 1, + dst_variant.end_date, + transition_info.std_offset, + )) + } else { + Some(dst_end_seconds) + }; + (transition_info.std_offset, transition_epoch) + }; + Ok(TimeZoneTransitionInfo { + offset: new_offset, + transition_epoch, + }) +} + +fn calculate_transition_seconds_for_year( + year: i32, + transition_date: TransitionDate, + offset: UtcOffsetSeconds, +) -> i64 { + // Determine the year of the requested time. + let year_epoch_seconds = i64::from(utils::epoch_days_for_year(year)) * 86400; + let is_leap = utils::is_leap(year); + + // Calculate the days in the year for the TransitionDate + // This value is zero-indexed so it can be added to the year's epoch seconds + let days = match transition_date.day { + TransitionDay::NoLeap(day) if day > 59 => day - 1 + is_leap as u16, + TransitionDay::NoLeap(day) => day - 1, + TransitionDay::WithLeap(day) => day, + TransitionDay::Mwd(month, week, day) => { + let days_to_month = utils::month_to_day((month - 1) as u8, is_leap); + let days_in_month = u16::from(utils::iso_days_in_month(year, month as u8)); + + // Month starts in the day... + let day_offset = (u16::from(utils::epoch_seconds_to_day_of_week(year_epoch_seconds)) + + days_to_month) + .rem_euclid(7); + + // EXAMPLE: + // + // 0 1 2 3 4 5 6 + // sun mon tue wed thu fri sat + // - - - 0 1 2 3 + // 4 5 6 7 8 9 10 + // 11 12 13 14 15 16 17 + // 18 19 20 21 22 23 24 + // 25 26 27 28 29 30 - + // + // The day_offset = 3, since the month starts on a wednesday. + // + // We're looking for the second friday of the month. Thus, since the month started before + // a friday, we need to start counting from week 0: + // + // day_of_month = (week - u16::from(day_offset <= day)) * 7 + day - day_offset = (2 - 1) * 7 + 5 - 3 = 9 + // + // This works if the month started on a day before the day we want (day_offset <= day). However, if that's not the + // case, we need to start counting on week 1. For example, calculate the day of the month for the third monday + // of the month: + // + // day_of_month = (week - u16::from(day_offset <= day)) * 7 + day - day_offset = (3 - 0) * 7 + 1 - 3 = 19 + + // Note: this day_of_month is zero-indexed! + let mut day_of_month = (week - u16::from(day_offset <= day)) * 7 + day - day_offset; + + // Week 5 actually means "last of month". The day_of_month calculation + // above uses `week` directly; so we might end up spilling into the next month. In that + // case, we normalize to the fourth week of the month. + // + // Note that this only needs to be done once; if a month will have at least four of each + // day of the week since all months have 28 days or greater. + // + // We add one because day_of_month is zero_indexed + if day_of_month + 1 > days_in_month { + day_of_month -= 7 + } + + days_to_month + day_of_month + } + }; + + // Transition time is on local time, so we need to add the UTC offset to get the correct UTC timestamp + // for the transition. + year_epoch_seconds + i64::from(days) * 86400 + transition_date.time.0 - offset.0 +} + +/// Resolve the footer of a tzif file. +/// +/// Seconds are epoch seconds in local time. +#[inline] +fn resolve_posix_tz_string( + posix_tz_string: &PosixTzString, + seconds: i64, +) -> TimeZoneProviderResult { + let std = &posix_tz_string.std_info; + let Some(dst) = &posix_tz_string.dst_info else { + // Regardless of the time, there is one variant and we can return it. + return Ok(UtcOffsetSeconds::from(&posix_tz_string.std_info).into()); + }; + + // TODO: Resolve safety issue around utils. + // Using f64 is a hold over from early implementation days and should + // be moved away from. + + // NOTE: + // STD -> DST == start + // DST -> STD == end + let (is_transition_day, mut is_dst) = + cmp_seconds_to_transitions(&dst.start_date.day, &dst.end_date.day, seconds)?; + if is_transition_day { + let time = utils::epoch_ms_to_ms_in_day(seconds * 1_000) as i64 / 1_000; + let transition_time = if is_dst == TransitionType::Dst { + dst.start_date.time + } else { + dst.end_date.time + }; + // Convert to UtcOffsetSeconds so that these behave like + // normal offsets + let std = UtcOffsetSeconds::from(std); + let dst = UtcOffsetSeconds::from(&dst.variant_info); + let transition_diff = if is_dst == TransitionType::Dst { + dst.0 - std.0 + } else { + std.0 - dst.0 + }; + let offset = offset_range(transition_time.0 + transition_diff, transition_time.0); + match offset.contains(&time) { + true if is_dst == TransitionType::Dst => { + return Ok(LocalTimeRecordResult::Empty(GapEntryOffsets { + offset_before: std, + offset_after: dst, + transition_epoch: transition_time.into(), + })); + } + true => { + // Note(nekevss, manishearth): We may need to more carefully + // handle inverse DST here. + return Ok(LocalTimeRecordResult::Ambiguous { + first: dst, + second: std, + }); + } + _ => {} + } + + // We were not contained in the transition above, + // AND we are before it, which means we are actually in + // the other transition! + // + // NOTE(Manishearth) do we need to do anything special + // here if we end up back at the tzif transition data? + if time < offset.start { + is_dst.invert(); + } + } + + match is_dst { + TransitionType::Dst => Ok(UtcOffsetSeconds::from(&dst.variant_info).into()), + TransitionType::Std => Ok(UtcOffsetSeconds::from(&posix_tz_string.std_info).into()), + } +} + +/// The month, week of month, and day of week value built into the POSIX tz string. +/// +/// For more information, see the [POSIX tz string docs](https://sourceware.org/glibc/manual/2.40/html_node/Proleptic-TZ.html) +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +struct Mwd { + month: u8, + week: u8, + day: u8, +} + +impl Mwd { + fn from_u16(month: u16, week: u16, day: u16) -> Self { + Self::from_u8( + u8::try_from(month).unwrap_or(0), + u8::try_from(week).unwrap_or(0), + u8::try_from(day).unwrap_or(0), + ) + } + + fn from_u8(month: u8, week: u8, day: u8) -> Self { + Self { month, week, day } + } + + /// Given the day of the week of the 0th day in this month, + /// normalize the week to being a week number (1 = first week, ...) + /// rather than a weekday ordinal (1 = first friday, etc) + fn normalize_to_week_number(&mut self, day_of_week_zeroth_day: u8) { + if self.day <= day_of_week_zeroth_day { + self.week += 1; + } + } +} + +/// Represents an MWD for a given time +#[derive(Debug)] +struct MwdForTime { + /// This will never have day = 5 + mwd: Mwd, + /// The day of the week of the 0th day (the day before the month starts) + day_of_week_zeroth_day: u8, + /// This is the day of week of the 29th and the last day of the month, + /// if the month has more than 28 days. + /// Basically, this is the start and end of the "fifth $weekday of the month" period + extra_days: Option<(u8, u8)>, +} + +impl MwdForTime { + fn from_seconds(seconds: i64) -> Self { + let (year, month, day_of_month) = utils::ymd_from_epoch_milliseconds(seconds * 1_000); + let week_of_month = day_of_month / 7 + 1; + let day_of_week = utils::epoch_seconds_to_day_of_week(seconds); + let mut mwd = Mwd::from_u8(month, week_of_month, day_of_week); + let days_in_month = utils::iso_days_in_month(year, month); + let day_of_week_zeroth_day = + (i16::from(day_of_week) - i16::from(day_of_month)).rem_euclid(7) as u8; + mwd.normalize_to_week_number(day_of_week_zeroth_day); + if day_of_month > 28 { + let day_of_week_day_29 = (day_of_week_zeroth_day + 29).rem_euclid(7); + let day_of_week_last_day = (day_of_week_zeroth_day + days_in_month).rem_euclid(7); + Self { + mwd, + day_of_week_zeroth_day, + extra_days: Some((day_of_week_day_29, day_of_week_last_day)), + } + } else { + // No day 5 + Self { + mwd, + day_of_week_zeroth_day, + extra_days: None, + } + } + } + + /// MWDs from Posix data can contain `w=5`, which means the *last* $weekday of the month, + /// not the 5th. For MWDs in the same month, this normalizes the 5 to the actual number of the + /// last weekday of the month (5 or 4) + /// + /// Furthermore, this turns the week number into a true week number: the "second friday in March" + /// will be turned into "the friday in the first week of March" or "the Friday in the second week of March" + /// depending on when March starts. + /// + /// This normalization *only* applies to MWDs in the same month. For other MWDs, such normalization is irrelevant. + fn normalize_mwd(&self, other: &mut Mwd) { + // If we're in the same month, normalization will actually have a useful effect + if self.mwd.month == other.month { + // First normalize MWDs that are like "the last $weekday in the month" + // the last $weekday in the month, we need special handling + if other.week == 5 { + if let Some((day_29, last_day)) = self.extra_days { + if day_29 < last_day { + if other.day < day_29 || other.day > last_day { + // This day isn't found in the last week. Subtract one. + other.week = 4; + } + } else { + // The extra part of the month crosses Sunday + if other.day < day_29 && other.day > last_day { + // This day isn't found in the last week. Subtract one. + other.week = 4; + } + } + } else { + // There is no week 5 in this month, normalize to 4 + other.week = 4; + } + } + + other.normalize_to_week_number(self.day_of_week_zeroth_day); + } + } +} + +fn cmp_seconds_to_transitions( + start: &TransitionDay, + end: &TransitionDay, + seconds: i64, +) -> TimeZoneProviderResult<(bool, TransitionType)> { + let cmp_result = match (start, end) { + ( + TransitionDay::Mwd(start_month, start_week, start_day), + TransitionDay::Mwd(end_month, end_week, end_day), + ) => { + let mwd = MwdForTime::from_seconds(seconds); + let mut start = Mwd::from_u16(*start_month, *start_week, *start_day); + let mut end = Mwd::from_u16(*end_month, *end_week, *end_day); + + mwd.normalize_mwd(&mut start); + mwd.normalize_mwd(&mut end); + + let is_transition = start == mwd.mwd || end == mwd.mwd; + let is_dst = if start > end { + mwd.mwd < end || start <= mwd.mwd + } else { + start <= mwd.mwd && mwd.mwd < end + }; + + (is_transition, is_dst) + } + (TransitionDay::WithLeap(start), TransitionDay::WithLeap(end)) => { + let day_in_year = utils::epoch_time_to_day_in_year(seconds * 1_000) as u16; + let is_transition = *start == day_in_year || *end == day_in_year; + let is_dst = if start > end { + day_in_year < *end || *start <= day_in_year + } else { + *start <= day_in_year && day_in_year < *end + }; + (is_transition, is_dst) + } + // TODO: do we need to modify the logic for leap years? + (TransitionDay::NoLeap(start), TransitionDay::NoLeap(end)) => { + let day_in_year = utils::epoch_time_to_day_in_year(seconds * 1_000) as u16; + let is_transition = *start == day_in_year || *end == day_in_year; + let is_dst = if start > end { + day_in_year < *end || *start <= day_in_year + } else { + *start <= day_in_year && day_in_year < *end + }; + (is_transition, is_dst) + } + // NOTE: The assumption here is that mismatched day types on + // a POSIX string is an illformed string. + _ => { + return Err(TimeZoneProviderError::Assert( + "Mismatched day types on a POSIX string.", + )) + } + }; + + match cmp_result { + (true, dst) if dst => Ok((true, TransitionType::Dst)), + (true, _) => Ok((true, TransitionType::Std)), + (false, dst) if dst => Ok((false, TransitionType::Dst)), + (false, _) => Ok((false, TransitionType::Std)), + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum TransitionType { + Dst, + Std, +} + +impl TransitionType { + fn invert(&mut self) { + *self = match *self { + Self::Dst => Self::Std, + Self::Std => Self::Dst, + } + } +} + +fn offset_range(offset_one: i64, offset_two: i64) -> core::ops::Range { + if offset_one < offset_two { + return offset_one..offset_two; + } + offset_two..offset_one +} + +/// Timezone provider that uses compiled data. +/// +/// This provider includes raw tzdata in the application binary and parses that data into +/// a TZif format, which incurs a runtime cost; however, parsed TZifs are cached, which +/// offsets the runtime cost on repeated requests. +/// +/// This will eventually use pure compiled data () +pub type CompiledTzdbProvider = + NormalizerAndResolver>; + +/// Timezone provider that uses filesystem based tzif data. +/// +/// This provider parses tzdata into a TZif format, which incurs a runtime cost; however, +/// parsed TZifs are cached, which offsets the runtime cost on repeated requests. +/// +/// Important note: the filesystem tzdb is not available on windows; as a result, this provider +/// will fallback to compiled data via `jiff_tzdb`. +/// +/// Currently uses jiff_tzdb and performs parsing; will eventually +/// use pure compiled data () +pub type FsTzdbProvider = NormalizerAndResolver>; + +/// [`TimeZoneResolver`] that uses compiled data. +/// +/// Currently uses jiff_tzdb and performs parsing; will eventually +/// use pure compiled data () +#[derive(Debug, Default)] +pub struct TzdbResolver { + id_cache: RwLock>, + cache: RwLock>, + kind: Kind, +} + +mod sealed { + pub trait Sealed {} +} +pub trait TzdbResolverBackend: sealed::Sealed { + /// The intermediate unparsed Tzif data + type IntermediateTzif<'a>; + /// Looks up a normalized timezone identifier, returning the identifier as + /// used in this timezone database and the Tzif bytes data + fn get<'a, 'b>( + &'a self, + normalized_identifier: &'b [u8], + ) -> TimeZoneProviderResult<(&'b str, Self::IntermediateTzif<'a>)>; + + fn load_tzif<'a>( + &self, + intermediate: Self::IntermediateTzif<'a>, + ) -> TimeZoneProviderResult; +} + +#[derive(Debug, Default)] +pub struct CompiledTzdbResolver; + +impl sealed::Sealed for CompiledTzdbResolver {} +impl TzdbResolverBackend for CompiledTzdbResolver { + type IntermediateTzif<'a> = &'a [u8]; + fn get<'a, 'b>( + &'a self, + normalized_identifier: &'b [u8], + ) -> TimeZoneProviderResult<(&'b str, &'a [u8])> { + let tzdb_val = + jiff_tzdb::get(str::from_utf8(normalized_identifier).map_err(|_| { + TimeZoneProviderError::Range("Time zone identifier does not exist.") + })?); + let Some((canonical_name, tzif_bytes)) = tzdb_val else { + return Err(TimeZoneProviderError::Range( + "Time zone identifier does not exist.", + )); + }; + Ok((canonical_name, tzif_bytes)) + } + + fn load_tzif<'a>( + &self, + intermediate: Self::IntermediateTzif<'a>, + ) -> TimeZoneProviderResult { + Tzif::from_bytes(intermediate) + } +} + +#[derive(Debug, Default)] +pub struct FsTzdbResolver; + +impl sealed::Sealed for FsTzdbResolver {} +impl TzdbResolverBackend for FsTzdbResolver { + #[cfg(target_family = "unix")] + type IntermediateTzif<'a> = PathBuf; + #[cfg(any(target_family = "windows", target_family = "wasm"))] + type IntermediateTzif<'a> = &'a [u8]; + fn get<'a, 'b>( + &'a self, + normalized_identifier: &'b [u8], + ) -> TimeZoneProviderResult<(&'b str, Self::IntermediateTzif<'a>)> { + let normalized_identifier = str::from_utf8(normalized_identifier) + .map_err(|_| TimeZoneProviderError::Range("Time zone identifier does not exist."))?; + #[cfg(target_family = "unix")] + { + // Protect from path traversal attacks + if normalized_identifier.starts_with('/') || normalized_identifier.contains('.') { + return Err(TimeZoneProviderError::Range( + "Ill-formed timezone identifier", + )); + } + + let mut path = PathBuf::from(ZONEINFO_DIR); + path.push(normalized_identifier); + Ok((normalized_identifier, path)) + } + + #[cfg(any(target_family = "windows", target_family = "wasm"))] + { + let Some((canonical_name, data)) = jiff_tzdb::get(normalized_identifier) else { + return Err(TimeZoneProviderError::Range( + "Time zone identifier does not exist.", + )); + }; + return Ok((canonical_name, data)); + }; + } + + fn load_tzif<'a>( + &self, + intermediate: Self::IntermediateTzif<'a>, + ) -> TimeZoneProviderResult { + #[cfg(target_family = "unix")] + let bytes = std::fs::read(intermediate) + .map_err(|_| TimeZoneProviderError::Range("Time zone identifier does not exist."))?; + #[cfg(any(target_family = "windows", target_family = "wasm"))] + let bytes = intermediate; + Tzif::from_bytes(&bytes) + } +} + +impl TzdbResolver { + /// Get timezone data for a single identifier + fn get(&self, id: ResolvedId) -> TimeZoneProviderResult { + self.cache + .read() + .map_err(|_| TimeZoneProviderError::Assert("poisoned RWLock"))? + .get(id.0) + .cloned() + .ok_or(TimeZoneProviderError::Assert( + "Time zone identifier does not exist.", + )) + } +} + +impl TimeZoneResolver for TzdbResolver { + fn get_id(&self, normalized_identifier: &[u8]) -> TimeZoneProviderResult { + let (identifier, tzif_intermediate) = self.kind.get(normalized_identifier)?; + if let Some(id) = self + .id_cache + .read() + .map_err(|_| TimeZoneProviderError::Assert("poisoned RWLock"))? + .get(identifier) + { + return Ok(*id); + } + + let mut vec = self + .cache + .write() + .map_err(|_| TimeZoneProviderError::Assert("poisoned RWLock"))?; + + let id = ResolvedId(vec.len()); + vec.push(self.kind.load_tzif(tzif_intermediate)?); + + self.id_cache + .write() + .map_err(|_| TimeZoneProviderError::Assert("poisoned RWLock"))? + .insert(identifier.into(), id); + Ok(id) + } + + fn candidate_nanoseconds_for_local_epoch_nanoseconds( + &self, + identifier: ResolvedId, + local_datetime: IsoDateTime, + ) -> TimeZoneProviderResult { + self.get(identifier)? + .candidate_nanoseconds_for_local_epoch_nanoseconds(local_datetime) + } + + fn transition_nanoseconds_for_utc_epoch_nanoseconds( + &self, + identifier: ResolvedId, + epoch_nanoseconds: i128, + ) -> TimeZoneProviderResult { + self.get(identifier)? + .transition_nanoseconds_for_utc_epoch_nanoseconds(epoch_nanoseconds) + } + + fn get_time_zone_transition( + &self, + identifier: ResolvedId, + epoch_nanoseconds: i128, + direction: TransitionDirection, + ) -> TimeZoneProviderResult> { + let tzif = self.get(identifier)?; + tzif.get_time_zone_transition(epoch_nanoseconds, direction) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::provider::TimeZoneProvider; + use crate::SINGLETON_IANA_NORMALIZER; + use tzif::data::time::Seconds; + + fn get_singleton_identifier(id: &str) -> Option<&'static str> { + let index = SINGLETON_IANA_NORMALIZER.available_id_index.get(id)?; + SINGLETON_IANA_NORMALIZER.normalized_identifiers.get(index) + } + + #[test] + fn test_singleton() { + let id = get_singleton_identifier("uTc"); + assert_eq!(id, Some("UTC")); + let id = get_singleton_identifier("EURope/BeRlIn").unwrap(); + assert_eq!(id, "Europe/Berlin"); + } + + #[test] + fn available_ids() { + let provider = FsTzdbProvider::default(); + assert!(provider.get(b"uTC").is_ok()); + assert!(provider.get(b"Etc/uTc").is_ok()); + assert!(provider.get(b"AMERIca/CHIcago").is_ok()); + } + + #[test] + fn exactly_transition_time_after_empty_edge_case() { + let provider = FsTzdbProvider::default(); + let today = IsoDateTime { + year: 2017, + month: 3, + day: 12, + hour: 3, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + }; + + let ny = provider.get(b"America/New_York").unwrap(); + let local = provider + .candidate_nanoseconds_for_local_epoch_nanoseconds(ny, today) + .unwrap(); + assert_eq!(local.len(), 1); + } + + #[test] + fn one_second_before_empty_edge_case() { + let provider = FsTzdbProvider::default(); + let today = IsoDateTime { + year: 2017, + month: 3, + day: 12, + hour: 2, + minute: 59, + second: 59, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + }; + + let ny = provider.get(b"America/New_York").unwrap(); + let local = provider + .candidate_nanoseconds_for_local_epoch_nanoseconds(ny, today) + .unwrap(); + assert!(local.is_empty()); + } + + #[test] + fn new_york_empty_test_case() { + let edge_case = IsoDateTime { + year: 2017, + month: 3, + day: 12, + hour: 2, + minute: 30, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + }; + let edge_case_seconds = ((edge_case).as_nanoseconds().0 / 1_000_000_000) as i64; + + #[cfg(not(target_os = "windows"))] + let new_york = Tzif::read_tzif("America/New_York"); + #[cfg(target_os = "windows")] + let new_york = { + let (_, data) = jiff_tzdb::get("America/New_York").unwrap(); + Tzif::from_bytes(data) + }; + + assert!(new_york.is_ok()); + let new_york = new_york.unwrap(); + + let locals = new_york + .v2_estimate_tz_pair(&Seconds(edge_case_seconds)) + .unwrap(); + assert!(matches!(locals, LocalTimeRecordResult::Empty(..))); + } + + #[test] + fn sydney_empty_test_case() { + // Australia Daylight savings day + let today = IsoDateTime { + year: 2017, + month: 10, + day: 1, + hour: 2, + minute: 30, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + }; + let seconds = ((today).as_nanoseconds().0 / 1_000_000_000) as i64; + + #[cfg(not(target_os = "windows"))] + let sydney = Tzif::read_tzif("Australia/Sydney"); + #[cfg(target_os = "windows")] + let sydney = { + let (_, data) = jiff_tzdb::get("Australia/Sydney").unwrap(); + Tzif::from_bytes(data) + }; + + assert!(sydney.is_ok()); + let sydney = sydney.unwrap(); + + let locals = sydney.v2_estimate_tz_pair(&Seconds(seconds)).unwrap(); + assert!(matches!(locals, LocalTimeRecordResult::Empty(..))); + } + + #[test] + fn new_york_duplicate_case() { + // Moves from DST to STD + let edge_case = IsoDateTime { + year: 2017, + month: 11, + day: 5, + hour: 1, + minute: 30, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + }; + let edge_case_seconds = ((edge_case).as_nanoseconds().0 / 1_000_000_000) as i64; + + #[cfg(not(target_os = "windows"))] + let new_york = Tzif::read_tzif("America/New_York"); + #[cfg(target_os = "windows")] + let new_york = { + let (_, data) = jiff_tzdb::get("America/New_York").unwrap(); + Tzif::from_bytes(data) + }; + + assert!(new_york.is_ok()); + let new_york = new_york.unwrap(); + + let locals = new_york + .v2_estimate_tz_pair(&Seconds(edge_case_seconds)) + .unwrap(); + + assert_eq!( + locals, + LocalTimeRecordResult::Ambiguous { + // DST + first: UtcOffsetSeconds(-14400), + // STD + second: UtcOffsetSeconds(-18000), + } + ); + } + + #[test] + fn sydney_duplicate_case() { + // Australia Daylight savings day + // Moves from DST to STD + let today = IsoDateTime { + year: 2017, + month: 4, + day: 2, + hour: 2, + minute: 30, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + }; + let seconds = ((today).as_nanoseconds().0 / 1_000_000_000) as i64; + + #[cfg(not(target_os = "windows"))] + let sydney = Tzif::read_tzif("Australia/Sydney"); + #[cfg(target_os = "windows")] + let sydney = { + let (_, data) = jiff_tzdb::get("Australia/Sydney").unwrap(); + Tzif::from_bytes(data) + }; + + assert!(sydney.is_ok()); + let sydney = sydney.unwrap(); + + let locals = sydney.v2_estimate_tz_pair(&Seconds(seconds)).unwrap(); + + assert_eq!( + locals, + LocalTimeRecordResult::Ambiguous { + // DST + first: UtcOffsetSeconds(39600), + // STD + second: UtcOffsetSeconds(36000), + } + ); + } + + #[test] + fn new_york_duplicate_with_slim_format() { + let (_, data) = jiff_tzdb::get("America/New_York").unwrap(); + let new_york = Tzif::from_bytes(data); + assert!(new_york.is_ok()); + let new_york = new_york.unwrap(); + + let edge_case = IsoDateTime { + year: 2017, + month: 11, + day: 5, + hour: 1, + minute: 30, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + }; + let edge_case_seconds = ((edge_case).as_nanoseconds().0 / 1_000_000_000) as i64; + + let locals = new_york + .v2_estimate_tz_pair(&Seconds(edge_case_seconds)) + .unwrap(); + + assert_eq!( + locals, + LocalTimeRecordResult::Ambiguous { + first: UtcOffsetSeconds(-14400), + second: UtcOffsetSeconds(-18000), + } + ); + } + + #[test] + fn sydney_duplicate_case_with_slim_format() { + let (_, data) = jiff_tzdb::get("Australia/Sydney").unwrap(); + let sydney = Tzif::from_bytes(data); + assert!(sydney.is_ok()); + let sydney = sydney.unwrap(); + + // Australia Daylight savings day + let today = IsoDateTime { + year: 2017, + month: 4, + day: 2, + hour: 2, + minute: 30, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + }; + let seconds = ((today).as_nanoseconds().0 / 1_000_000_000) as i64; + + let locals = sydney.v2_estimate_tz_pair(&Seconds(seconds)).unwrap(); + + assert_eq!( + locals, + LocalTimeRecordResult::Ambiguous { + first: UtcOffsetSeconds(39600), + second: UtcOffsetSeconds(36000), + } + ); + } + + // TODO: Determine the validity of this test. Primarily, this test + // goes beyond the regularly historic limit of transition_times, so + // even when on a DST boundary the first time zone is returned. The + // question is whether this behavior is consistent with what would + // be expected. + #[test] + fn before_epoch_northern_hemisphere() { + let edge_case = IsoDateTime { + year: 1880, + month: 11, + day: 5, + hour: 1, + minute: 30, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + }; + let edge_case_seconds = ((edge_case).as_nanoseconds().0 / 1_000_000_000) as i64; + + #[cfg(not(target_os = "windows"))] + let new_york = Tzif::read_tzif("America/New_York"); + #[cfg(target_os = "windows")] + let new_york = { + let (_, data) = jiff_tzdb::get("America/New_York").unwrap(); + Tzif::from_bytes(data) + }; + + assert!(new_york.is_ok()); + let new_york = new_york.unwrap(); + + let locals = new_york + .v2_estimate_tz_pair(&Seconds(edge_case_seconds)) + .unwrap(); + + assert!(matches!(locals, LocalTimeRecordResult::Single(_))); + } + + // TODO: Determine the validity of this test. Primarily, this test + // goes beyond the regularly historic limit of transition_times, so + // even when on a DST boundary the first time zone is returned. The + // question is whether this behavior is consistent with what would + // be expected. + #[test] + fn before_epoch_southern_hemisphere() { + // Australia Daylight savings day + let today = IsoDateTime { + year: 1880, + month: 4, + day: 2, + hour: 2, + minute: 30, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + }; + let seconds = ((today).as_nanoseconds().0 / 1_000_000_000) as i64; + + #[cfg(not(target_os = "windows"))] + let sydney = Tzif::read_tzif("Australia/Sydney"); + #[cfg(target_os = "windows")] + let sydney = { + let (_, data) = jiff_tzdb::get("Australia/Sydney").unwrap(); + Tzif::from_bytes(data) + }; + + assert!(sydney.is_ok()); + let sydney = sydney.unwrap(); + + let locals = sydney.v2_estimate_tz_pair(&Seconds(seconds)).unwrap(); + assert!(matches!(locals, LocalTimeRecordResult::Single(_))); + } + + #[test] + #[cfg(not(target_os = "windows"))] + fn mwd_transition_epoch() { + let tzif = Tzif::read_tzif("Europe/Berlin").unwrap(); + + let start_dt = IsoDateTime { + year: 2028, + month: 3, + day: 30, + hour: 6, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + }; + let start_dt_secs = ((start_dt).as_nanoseconds().0 / 1_000_000_000) as i64; + + let start_seconds = &Seconds(start_dt_secs); + + assert_eq!( + tzif.get(start_seconds).unwrap().transition_epoch.unwrap(), + // Sun, Mar 26 at 2:00 am + 1837645200 + ); + + let end_dt = IsoDateTime { + year: 2028, + month: 10, + day: 29, + hour: 6, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + }; + let end_dt_secs = ((end_dt).as_nanoseconds().0 / 1_000_000_000) as i64; + + let end_seconds = &Seconds(end_dt_secs); + + assert_eq!( + tzif.get(end_seconds).unwrap().transition_epoch.unwrap(), + // Sun, Oct 29 at 3:00 am + 1856394000 + ); + } + + #[test] + fn compiled_mwd_transition_epoch() { + let tzif = Tzif::from_bytes(CompiledTzdbResolver.get(b"Europe/Berlin").unwrap().1).unwrap(); + + let start_dt = IsoDateTime { + year: 2028, + month: 3, + day: 30, + hour: 6, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + }; + let start_dt_secs = ((start_dt).as_nanoseconds().0 / 1_000_000_000) as i64; + + let start_seconds = &Seconds(start_dt_secs); + + assert_eq!( + tzif.get(start_seconds).unwrap().transition_epoch.unwrap(), + // Sun, Mar 26 at 2:00 am + 1837645200 + ); + + let end_dt = IsoDateTime { + year: 2028, + month: 10, + day: 29, + hour: 6, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + }; + let end_dt_secs = ((end_dt).as_nanoseconds().0 / 1_000_000_000) as i64; + + let end_seconds = &Seconds(end_dt_secs); + + assert_eq!( + tzif.get(end_seconds).unwrap().transition_epoch.unwrap(), + // Sun, Oct 29 at 3:00 am + 1856394000 + ); + } + + // This test mimicks the operations present in `temporal_rs`'s `disambiguate_possible_epoch_nanoseconds` + #[test] + fn disambiguate_ambiguous_posix_time() { + let provider = CompiledTzdbProvider::default(); + + fn run_disambiguation_logic( + before: IsoDateTime, + after: IsoDateTime, + id: &str, + before_offset: i64, + after_offset: i64, + provider: &impl TimeZoneProvider, + ) { + let id = provider.get(id.as_bytes()).unwrap(); + let before_possible = provider + .candidate_nanoseconds_for_local_epoch_nanoseconds(id, before) + .unwrap(); + assert_eq!(before_possible.len(), 1); + + let after_possible = provider + .candidate_nanoseconds_for_local_epoch_nanoseconds(id, after) + .unwrap(); + assert_eq!(after_possible.len(), 1); + let before_seconds = before_possible.first().unwrap(); + let after_seconds = after_possible.first().unwrap(); + + let before_transition = provider + .transition_nanoseconds_for_utc_epoch_nanoseconds(id, before_seconds.ns.0) + .unwrap(); + let after_transition = provider + .transition_nanoseconds_for_utc_epoch_nanoseconds(id, after_seconds.ns.0) + .unwrap(); + assert_ne!( + before_transition, after_transition, + "Transition info must not be the same" + ); + assert_eq!(after_transition.0, after_offset); + assert_eq!(before_transition.0, before_offset); + } + + // Test Northern hemisphere + let before = IsoDateTime { + year: 2020, + month: 3, + day: 7, + hour: 23, + minute: 30, + second: 0, + microsecond: 0, + millisecond: 0, + nanosecond: 0, + }; + let after = IsoDateTime { + year: 2020, + month: 3, + day: 8, + hour: 5, + minute: 30, + second: 0, + microsecond: 0, + millisecond: 0, + nanosecond: 0, + }; + run_disambiguation_logic( + before, + after, + "America/Los_Angeles", + -28_800, + -25_200, + &provider, + ); + + // Test southern hemisphere + + let before = IsoDateTime { + year: 2020, + month: 4, + day: 4, + hour: 23, + minute: 30, + second: 0, + microsecond: 0, + millisecond: 0, + nanosecond: 0, + }; + let after = IsoDateTime { + year: 2020, + month: 4, + day: 5, + hour: 5, + minute: 30, + second: 0, + microsecond: 0, + millisecond: 0, + nanosecond: 0, + }; + run_disambiguation_logic(before, after, "Australia/Sydney", 39_600, 36_000, &provider); + } +} diff --git a/deps/temporal/provider/src/utc.rs b/deps/temporal/provider/src/utc.rs new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/deps/temporal/provider/src/utils.rs b/deps/temporal/provider/src/utils.rs new file mode 100644 index 00000000000000..7874c500567a77 --- /dev/null +++ b/deps/temporal/provider/src/utils.rs @@ -0,0 +1,132 @@ +//! Utility date and time equations for Temporal + +use crate::epoch_nanoseconds::MS_PER_DAY; + +pub mod neri_schneider; + +pub use neri_schneider::epoch_days_from_gregorian_date; + +// NOTE: Potentially add more of tests. + +// ==== Begin Date Equations ==== + +pub(crate) const MS_PER_HOUR: i64 = 3_600_000; +pub(crate) const MS_PER_MINUTE: i64 = 60_000; + +/// `EpochDaysToEpochMS` +/// +/// Functionally the same as Date's abstract operation `MakeDate` +pub fn epoch_days_to_epoch_ms(day: i64, time: i64) -> i64 { + (day * MS_PER_DAY as i64) + time +} + +/// `EpochTimeToDayNumber` +/// +/// This equation is the equivalent to `ECMAScript`'s `Date(t)` +#[cfg(feature = "tzif")] +pub(crate) fn epoch_time_to_day_number(t: i64) -> i32 { + t.div_euclid(MS_PER_DAY as i64) as i32 +} + +#[cfg(feature = "tzif")] +pub(crate) fn epoch_ms_to_ms_in_day(t: i64) -> u32 { + (t.rem_euclid(i64::from(MS_PER_DAY))) as u32 +} + +// https://tc39.es/proposal-temporal/#eqn-mathematicalinleapyear +pub(crate) fn is_leap(y: i32) -> bool { + if y % 4 != 0 { + false + } else if y % 4 == 0 && y % 100 != 0 { + true + } else if y % 100 == 0 && y % 400 != 0 { + false + } else { + // Assert that y is divisble by 400 to ensure we are returning the correct result. + assert_eq!(y % 400, 0); + true + } +} + +#[cfg(feature = "tzif")] +pub(crate) fn epoch_time_to_iso_year(t: i64) -> i32 { + let epoch_days = epoch_ms_to_epoch_days(t); + let (rata_die, shift_constant) = neri_schneider::rata_die_for_epoch_days(epoch_days); + neri_schneider::year(rata_die, shift_constant) +} + +/// Returns the epoch day number for a given year. +#[cfg(feature = "tzif")] +pub(crate) fn epoch_days_for_year(y: i32) -> i32 { + 365 * (y - 1970) + (y - 1969).div_euclid(4) - (y - 1901).div_euclid(100) + + (y - 1601).div_euclid(400) +} + +pub(crate) const fn epoch_ms_to_epoch_days(ms: i64) -> i32 { + (ms.div_euclid(MS_PER_DAY as i64)) as i32 +} + +pub fn ymd_from_epoch_milliseconds(epoch_milliseconds: i64) -> (i32, u8, u8) { + let epoch_days = epoch_ms_to_epoch_days(epoch_milliseconds); + neri_schneider::ymd_from_epoch_days(epoch_days) +} + +#[cfg(feature = "tzif")] +pub(crate) fn month_to_day(m: u8, is_leap: bool) -> u16 { + let leap_day = u16::from(is_leap); + match m { + 0 => 0, + 1 => 31, + 2 => 59 + leap_day, + 3 => 90 + leap_day, + 4 => 120 + leap_day, + 5 => 151 + leap_day, + 6 => 181 + leap_day, + 7 => 212 + leap_day, + 8 => 243 + leap_day, + 9 => 273 + leap_day, + 10 => 304 + leap_day, + 11 => 334 + leap_day, + _ => unreachable!(), + } +} + +#[cfg(feature = "tzif")] +pub(crate) fn epoch_time_to_day_in_year(t: i64) -> i32 { + epoch_time_to_day_number(t) - (epoch_days_for_year(epoch_time_to_iso_year(t))) +} + +#[cfg(feature = "tzif")] +pub(crate) fn epoch_seconds_to_day_of_week(t: i64) -> u8 { + ((t / 86_400) + 4).rem_euclid(7) as u8 +} + +// Trait implementations + +// EpochTimeTOWeekDay -> REMOVED + +// ==== End Date Equations ==== + +// ==== Begin Calendar Equations ==== + +// NOTE: below was the iso methods in temporal::calendar -> Need to be reassessed. + +/// 12.2.31 `ISODaysInMonth ( year, month )` +/// +/// NOTE: month is 1 based +pub fn iso_days_in_month(year: i32, month: u8) -> u8 { + match month { + 1 | 3 | 5 | 7 | 8 | 10 | 12 => 31, + 4 | 6 | 9 | 11 => 30, + 2 => 28 + is_leap(year) as u8, + _ => unreachable!("ISODaysInMonth panicking is an implementation error."), + } +} + +// The below calendar abstract equations/utilities were removed for being unused. +// 12.2.32 `ToISOWeekOfYear ( year, month, day )` +// 12.2.33 `ISOMonthCode ( month )` +// 12.2.39 `ToISODayOfYear ( year, month, day )` +// 12.2.40 `ToISODayOfWeek ( year, month, day )` + +// ==== End Calendar Equations ==== diff --git a/deps/temporal/provider/src/utils/neri_schneider.rs b/deps/temporal/provider/src/utils/neri_schneider.rs new file mode 100644 index 00000000000000..95fbb32b97119e --- /dev/null +++ b/deps/temporal/provider/src/utils/neri_schneider.rs @@ -0,0 +1,266 @@ +//! Gregorian Date Calculations +//! +//! This module contains the logic for Gregorian Date Calculations based +//! off Cassio Neri and Lorenz Schneider's paper, [Euclidean affine functions +//! and their application to calendar algorithms][eaf-calendar-algorithms]. +//! +//! ## General Usage Note +//! +//! Unless specified, Rata Die refers to the computational rata die as referenced +//! in the paper. +//! +//! ## Extending Neri-Schneider shift window +//! Temporal must support the year range [-271_821, 275_760] +//! +//! This means the epoch day range must be epoch_days.abs() <= 100_000_001 +//! +//! Neri-Schneider mention shifting for a range of 32_767, so the shift +//! will need to be much greater. +//! +//! (-271_821 / 400).ciel() = s // 680 +//! +//! In their paper, Neri and Schneider calculated for a Rata Die cycle +//! shift of constant of 82, but that was not sufficient in order to +//! support Temporal's date range, so below is a small addendum table +//! on extending the date range from a cyle shift of 82 to 680 in order +//! to accomodate Temporal's range. +//! +//! | Significant Date | Computational Rata Die | Rata Die Shift +//! | -----------------|------------------------|-----------------| +//! | April 19, -271_821 | -99,280,532 | 65,429 | +//! | January 1, 1970 | 719,468 | 100,065,428 | +//! | September 14, 275,760 | 100_719_469 | 200,065,429 | +//! +//! However, this shift has also been implemented by Cassio Neri, who +//! recommends using a [shift of 3670][neri-shift-context] which places the Epoch in the +//! center of the shift +//! +//! [neri-shift-context]: https://hg.mozilla.org/integration/autoland/rev/54ebf8bd2e11#l3.70 +//! [eaf-calendar-algorithms]: https://onlinelibrary.wiley.com/doi/full/10.1002/spe.3172 + +pub const EPOCH_COMPUTATIONAL_RATA_DIE: i32 = 719_468; +pub const DAYS_IN_A_400Y_CYCLE: u32 = 146_097; + +#[cfg(feature = "tzif")] +const TWO_POWER_THIRTY_NINE: u64 = 549_755_813_888; // 2^39 constant +const TWO_POWER_THIRTY_TWO: u64 = 4_294_967_296; // 2^32 constant +const TWO_POWER_SIXTEEN: u32 = 65_536; // 2^16 constant + // NOTE (nekevss): Shift constant is optimized and safe for supported date range. +const SHIFT_CONSTANT: i32 = 3670; +// NOTE (nekevss): Extended const function, because Temporal +// needs to support calculating for an arbitrarily +// large epoch day range. +const SHIFT_CONSTANT_EXTENDED: i64 = 5_368_710; + +/// Calculate Rata Die value from gregorian +pub const fn epoch_days_from_gregorian_date(year: i32, month: u8, day: u8) -> i64 { + let shift = + SHIFT_CONSTANT_EXTENDED * DAYS_IN_A_400Y_CYCLE as i64 + EPOCH_COMPUTATIONAL_RATA_DIE as i64; + let (comp_year, comp_month, comp_day, century) = rata_die_first_equations(year, month, day); + let y_star = 1461 * comp_year / 4 - century + century / 4; + let m_star = (979 * comp_month - 2919) / 32; + (y_star as i64 + m_star + comp_day) - shift +} + +// Returns Y, M, D, C +const fn rata_die_first_equations(year: i32, month: u8, day: u8) -> (u64, i64, i64, u64) { + let j = (month <= 2) as i64; + let computational_year = (year as i64 + 400 * SHIFT_CONSTANT_EXTENDED) - j; + let computation_month = month as i64 + 12 * j; + let computation_day = day as i64 - 1; + ( + computational_year as u64, + computation_month, + computation_day, + computational_year as u64 / 100, + ) +} + +// Computational days to gregorian YMD + +// Determine j +#[cfg(feature = "tzif")] +const fn j(rata_die: u32) -> u32 { + (computational_day_of_year(rata_die) >= 306) as u32 +} + +const fn n_one(rata_die: u32) -> u32 { + 4 * rata_die + 3 +} + +#[cfg(feature = "tzif")] +const fn n_two(rata_die: u32) -> u32 { + century_rem(rata_die) | 3 +} + +// Returns C, N_c AKA century number and century remainder +const fn first_equations(rata_die: u32) -> (u32, u32) { + let n_one = n_one(rata_die); + let century_rem = n_one.rem_euclid(146_097); + let century_num = n_one.div_euclid(DAYS_IN_A_400Y_CYCLE); + (century_num, century_rem) +} + +#[cfg(feature = "tzif")] +const fn century_rem(rata_die: u32) -> u32 { + n_one(rata_die).rem_euclid(DAYS_IN_A_400Y_CYCLE) +} + +#[cfg(feature = "tzif")] +pub const fn century_number(rata_die: u32) -> u32 { + n_one(rata_die).div_euclid(DAYS_IN_A_400Y_CYCLE) +} + +/// returns Y, N_y AKA, year and day_of_year +const fn second_equations(rata_die: u32) -> (u32, u32) { + let (century, rem) = first_equations(rata_die); + let n_two = rem | 3; + let p2 = 2_939_745 * n_two as u64; + let year_of_century = p2.div_euclid(TWO_POWER_THIRTY_TWO) as u32; + let day_of_year = p2 + .rem_euclid(TWO_POWER_THIRTY_TWO) + .div_euclid(2_939_745) + .div_euclid(4) as u32; + let year = 100 * century + year_of_century; + (year, day_of_year) +} + +// Returns Y, M, D, N_y, AKA year, month, day, day_of_year +const fn third_equations(rata_die: u32) -> (u32, u32, u32, u32) { + let (year, day_of_year) = second_equations(rata_die); + let n_three = 2141 * day_of_year + 197_913; + let month = n_three.div_euclid(TWO_POWER_SIXTEEN); + let day = n_three.rem_euclid(TWO_POWER_SIXTEEN).div_euclid(2141); + (year, month, day, day_of_year) +} + +// Z +#[cfg(feature = "tzif")] +pub const fn computational_year_of_century(rata_die: u32) -> u64 { + (376_287_347 * n_two(rata_die) as u64).div_euclid(TWO_POWER_THIRTY_NINE) +} + +// N_y +#[cfg(feature = "tzif")] +pub const fn computational_day_of_year(rata_die: u32) -> u32 { + (n_two(rata_die) - 1461 * computational_year_of_century(rata_die) as u32).div_euclid(4) +} + +// Y +#[cfg(feature = "tzif")] +pub const fn computational_year(rata_die: u32) -> u32 { + 100 * century_number(rata_die) + computational_year_of_century(rata_die) as u32 +} + +#[cfg(feature = "tzif")] +pub const fn year(computational_rata_die: u32, shift_constant: i32) -> i32 { + (computational_year(computational_rata_die) + j(computational_rata_die)) as i32 - shift_constant +} + +const fn gregorian_ymd(rata_die: u32) -> (i32, u8, u8) { + let (year, month, day, day_of_year) = third_equations(rata_die); + let j = (day_of_year >= 306) as u32; + let year = year + j; + let month = month - 12 * j; + let day = day + 1; + (year as i32, month as u8, day as u8) +} + +/// Get the computational Rata Die for given Epoch Days with the cycle shiftc. +/// +/// For more on `cycle_shifts`, see [`ymd_from_epoch_days`] +pub const fn rata_die_for_epoch_days(epoch_days: i32) -> (u32, i32) { + let rata_die = (epoch_days + + EPOCH_COMPUTATIONAL_RATA_DIE + + DAYS_IN_A_400Y_CYCLE as i32 * SHIFT_CONSTANT) as u32; // epoch_days + K + (rata_die, 400 * SHIFT_CONSTANT) +} + +/// Calculate a Gregorian year, month, and date for the provided epoch days. +pub const fn ymd_from_epoch_days(epoch_days: i32) -> (i32, u8, u8) { + let (rata_die, year_shift_constant) = rata_die_for_epoch_days(epoch_days); + + let (year, month, day) = gregorian_ymd(rata_die); + // Shift the year back to the proper date + (year - year_shift_constant, month, day) +} + +#[cfg(test)] +#[cfg(feature = "tzif")] +mod tests { + use super::*; + + const EPOCH_RATA_DIE: u32 = 719_468; // This is the Rata Die for 1970-01-01 + + const fn days_in_century(rata_die: u32) -> u32 { + century_rem(rata_die).div_euclid(4) + } + + #[test] + fn epoch_century_number() { + let century_number = century_number(EPOCH_RATA_DIE); + assert_eq!(century_number, 19); + let day_number_in_century = days_in_century(EPOCH_RATA_DIE); + assert_eq!(day_number_in_century, 25508); + } + + #[test] + fn epoch_year_of_century() { + let year = computational_year_of_century(EPOCH_RATA_DIE); + assert_eq!(year, 69); + } + + #[test] + fn epoch_day_of_year() { + let day = computational_day_of_year(EPOCH_RATA_DIE); + assert_eq!(day, 306); // Beginning of January in the computational calendar is day number 306 + } + + #[test] + fn epoch_year() { + let year = computational_year(EPOCH_RATA_DIE); + assert_eq!(year, 1969); + } + + #[test] + fn epoch_ymd() { + let ymd = gregorian_ymd(EPOCH_RATA_DIE); + assert_eq!(ymd, (1970, 1, 1)) + } + + #[test] + fn rata_die_from_date() { + let epoch_rata_die = epoch_days_from_gregorian_date(1970, 1, 1); + assert_eq!(epoch_rata_die, 0); + let date = ymd_from_epoch_days(epoch_rata_die as i32); + assert_eq!(date, (1970, 1, 1)); + let neri_scneider_limit_max_rata_die = epoch_days_from_gregorian_date(32767, 12, 31); + assert_eq!(neri_scneider_limit_max_rata_die, 11_248_737); + let neri_schneider_limit_min_rata_die = epoch_days_from_gregorian_date(-32767, 1, 1); + assert_eq!(neri_schneider_limit_min_rata_die, -12_687_428); + let js_max_rata_die = epoch_days_from_gregorian_date(275_760, 9, 14); + assert_eq!(js_max_rata_die, 100_000_001); + let js_min_rata_die = epoch_days_from_gregorian_date(-271_821, 4, 19); + assert_eq!(js_min_rata_die, -100_000_001); + } + + #[test] + fn epoch_days_temporal_limit_to_date() { + let max_date = ymd_from_epoch_days(100_000_001); + assert_eq!(max_date, (275_760, 9, 14)); + let min_date = ymd_from_epoch_days(-100_000_001); + assert_eq!(min_date, (-271_821, 4, 19)); + } + + #[test] + fn epoch_days_from() { + let epoch_days = epoch_days_from_gregorian_date(1970, 1, 1); + assert_eq!(epoch_days, 0); + let epoch_days = epoch_days_from_gregorian_date(275_760, 9, 14); + assert_eq!(epoch_days, 100_000_001); + let epoch_days = epoch_days_from_gregorian_date(-271_821, 4, 19); + let result = ymd_from_epoch_days(epoch_days as i32); + assert_eq!(result, (-271_821, 4, 19)); + assert_eq!(epoch_days, -100_000_001); + } +} diff --git a/deps/temporal/provider/src/zoneinfo64.rs b/deps/temporal/provider/src/zoneinfo64.rs new file mode 100644 index 00000000000000..0a439a8b9160f4 --- /dev/null +++ b/deps/temporal/provider/src/zoneinfo64.rs @@ -0,0 +1,166 @@ +use crate::CompiledNormalizer; +use core::str; +use zoneinfo64::{PossibleOffset, Zone, ZoneInfo64}; + +use crate::provider::{ + CandidateEpochNanoseconds, EpochNanosecondsAndOffset, GapEntryOffsets, IsoDateTime, + NormalizerAndResolver, ResolvedId, TimeZoneProviderResult, TimeZoneResolver, + TransitionDirection, UtcOffsetSeconds, +}; +use crate::{ + epoch_nanoseconds::{seconds_to_nanoseconds, EpochNanoseconds, NS_IN_S}, + TimeZoneProviderError, +}; +use zoneinfo64::UtcOffset; + +impl From for UtcOffsetSeconds { + fn from(other: UtcOffset) -> Self { + Self(i64::from(other.seconds())) + } +} + +pub use zoneinfo64::ZONEINFO64_RES_FOR_TESTING; + +/// A TimeZoneProvider that works using ICU4C zoneinfo64.res data +pub type ZoneInfo64TzdbProvider<'a> = NormalizerAndResolver>; + +impl ZoneInfo64TzdbProvider<'_> { + /// Produces a zoneinfo64 provider using the builtin zoneinfo64 data, + /// for testing use only. We do not provide strong guarantees for which version of zoneinfo64 + /// this will be. + pub fn zoneinfo64_provider_for_testing() -> Option { + let zi_data = zoneinfo64::ZoneInfo64::try_from_u32s(ZONEINFO64_RES_FOR_TESTING).ok()?; + Some(ZoneInfo64TzdbProvider::new(zi_data)) + } +} + +fn get<'a>(zi: &'a ZoneInfo64<'a>, id: ResolvedId) -> TimeZoneProviderResult> { + let id = u16::try_from(id.0) + .map_err(|_| TimeZoneProviderError::Range("Unknown timezone identifier"))?; + Ok(Zone::from_raw_parts((id, zi))) +} + +impl TimeZoneResolver for ZoneInfo64<'_> { + fn get_id(&self, normalized_identifier: &[u8]) -> TimeZoneProviderResult { + let utf8 = str::from_utf8(normalized_identifier) + .map_err(|_| TimeZoneProviderError::Range("Unknown timezone identifier"))?; + let zone = self + .get(utf8) + .ok_or(TimeZoneProviderError::Range("Unknown timezone identifier"))?; + let (id, _) = zone.into_raw_parts(); + Ok(ResolvedId(usize::from(id))) + } + + fn candidate_nanoseconds_for_local_epoch_nanoseconds( + &self, + identifier: ResolvedId, + local_datetime: IsoDateTime, + ) -> TimeZoneProviderResult { + let zone = get(self, identifier)?; + let epoch_nanos = (local_datetime).as_nanoseconds(); + let possible_offset = zone.for_date_time( + local_datetime.year, + local_datetime.month, + local_datetime.day, + local_datetime.hour, + local_datetime.minute, + local_datetime.second, + ); + + let result = match possible_offset { + PossibleOffset::None { + before, + after, + transition, + } => CandidateEpochNanoseconds::Zero(GapEntryOffsets { + offset_before: before.offset.into(), + offset_after: after.offset.into(), + transition_epoch: EpochNanoseconds::from(seconds_to_nanoseconds(transition)), + }), + PossibleOffset::Single(o) => { + let epoch_ns = EpochNanoseconds::from( + epoch_nanos.0 - seconds_to_nanoseconds(i64::from(o.offset.seconds())), + ); + CandidateEpochNanoseconds::One(EpochNanosecondsAndOffset { + ns: epoch_ns, + offset: o.offset.into(), + }) + } + PossibleOffset::Ambiguous { before, after, .. } => { + let first_epoch_ns = EpochNanoseconds::from( + epoch_nanos.0 - seconds_to_nanoseconds(i64::from(before.offset.seconds())), + ); + let second_epoch_ns = EpochNanoseconds::from( + epoch_nanos.0 - seconds_to_nanoseconds(i64::from(after.offset.seconds())), + ); + CandidateEpochNanoseconds::Two([ + EpochNanosecondsAndOffset { + ns: first_epoch_ns, + offset: before.offset.into(), + }, + EpochNanosecondsAndOffset { + ns: second_epoch_ns, + offset: after.offset.into(), + }, + ]) + } + }; + Ok(result) + } + + fn transition_nanoseconds_for_utc_epoch_nanoseconds( + &self, + identifier: ResolvedId, + epoch_nanoseconds: i128, + ) -> TimeZoneProviderResult { + let zone = get(self, identifier)?; + + let Ok(mut seconds) = i64::try_from(epoch_nanoseconds / NS_IN_S) else { + return Err(TimeZoneProviderError::Range( + "Epoch nanoseconds out of range", + )); + }; + // The rounding is inexact. Transitions are only at second + // boundaries, so the offset at N s is the same as the offset at N.001, + // but the offset at -Ns is not the same as the offset at -N.001, + // the latter matches -N - 1 s instead. + if seconds < 0 && epoch_nanoseconds % NS_IN_S != 0 { + seconds -= 1; + } + let offset = zone.for_timestamp(seconds); + + Ok(offset.offset.into()) + } + + fn get_time_zone_transition( + &self, + identifier: ResolvedId, + epoch_nanoseconds: i128, + direction: TransitionDirection, + ) -> TimeZoneProviderResult> { + let zone = get(self, identifier)?; + // We want div_floor behavior + let div = epoch_nanoseconds.div_euclid(NS_IN_S); + let Ok(seconds) = i64::try_from(div) else { + return Err(TimeZoneProviderError::Range( + "Epoch nanoseconds out of range", + )); + }; + + let transition = match direction { + TransitionDirection::Previous => { + let seconds_is_exact = (epoch_nanoseconds % NS_IN_S) == 0; + zone.prev_transition( + seconds, + seconds_is_exact, + /* require_offset_change */ true, + ) + } + TransitionDirection::Next => { + zone.next_transition(seconds, /* require_offset_change */ true) + } + }; + + Ok(transition.map(|transition| EpochNanoseconds::from_seconds(transition.since))) + } +} diff --git a/deps/temporal/src/builtins/compiled/duration.rs b/deps/temporal/src/builtins/compiled/duration.rs new file mode 100644 index 00000000000000..8f02933df535fa --- /dev/null +++ b/deps/temporal/src/builtins/compiled/duration.rs @@ -0,0 +1,41 @@ +use crate::{ + builtins::TZ_PROVIDER, + options::{RelativeTo, RoundingOptions, Unit}, + primitive::FiniteF64, + Duration, TemporalResult, +}; + +use core::cmp::Ordering; + +#[cfg(test)] +mod tests; + +impl Duration { + /// Rounds the current [`Duration`] according to the provided [`RoundingOptions`] and an optional + /// [`RelativeTo`] + /// + /// Enable with the `compiled_data` feature flag. + pub fn round( + &self, + options: RoundingOptions, + relative_to: Option, + ) -> TemporalResult { + self.round_with_provider(options, relative_to, &*TZ_PROVIDER) + } + + /// Returns the ordering between two [`Duration`], takes an optional + /// [`RelativeTo`] + /// + /// Enable with the `compiled_data` feature flag. + pub fn compare( + &self, + two: &Duration, + relative_to: Option, + ) -> TemporalResult { + self.compare_with_provider(two, relative_to, &*TZ_PROVIDER) + } + + pub fn total(&self, unit: Unit, relative_to: Option) -> TemporalResult { + self.total_with_provider(unit, relative_to, &*TZ_PROVIDER) + } +} diff --git a/deps/temporal/src/builtins/compiled/duration/tests.rs b/deps/temporal/src/builtins/compiled/duration/tests.rs new file mode 100644 index 00000000000000..72ae0e4a1f67b8 --- /dev/null +++ b/deps/temporal/src/builtins/compiled/duration/tests.rs @@ -0,0 +1,845 @@ +use crate::{ + duration::DateDuration, + options::{ + OffsetDisambiguation, RelativeTo, RoundingIncrement, RoundingMode, RoundingOptions, Unit, + }, + partial::PartialDuration, + Calendar, PlainDate, TimeZone, ZonedDateTime, +}; + +use core::{num::NonZeroU32, str::FromStr}; + +use super::Duration; + +fn get_round_result( + test_duration: &Duration, + relative_to: RelativeTo, + options: RoundingOptions, +) -> Duration { + test_duration.round(options, Some(relative_to)).unwrap() +} + +fn assert_duration(result: Duration, values: (i64, i64, i64, i64, i64, i64, i64, i64, i128, i128)) { + assert_eq!( + ( + result.years(), + result.months(), + result.weeks(), + result.days(), + result.hours(), + result.minutes(), + result.seconds(), + result.milliseconds(), + result.microseconds(), + result.nanoseconds() + ), + values + ) +} + +// roundingmode-floor.js +#[test] +fn basic_positive_floor_rounding_v2() { + let test_duration = Duration::new(5, 6, 7, 8, 40, 30, 20, 123, 987, 500).unwrap(); + let forward_date = PlainDate::new(2020, 4, 1, Calendar::default()).unwrap(); + + let relative_forward = RelativeTo::PlainDate(forward_date); + + let mut options = RoundingOptions { + largest_unit: None, + smallest_unit: None, + increment: None, + rounding_mode: Some(RoundingMode::Floor), + }; + + let _ = options.smallest_unit.insert(Unit::Year); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Month); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Week); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 3, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Day); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Hour); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 16, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Minute); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 16, 30, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Second); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 16, 30, 20, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Millisecond); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 16, 30, 20, 123, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Microsecond); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 16, 30, 20, 123, 987, 0)); + + let _ = options.smallest_unit.insert(Unit::Nanosecond); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 16, 30, 20, 123, 987, 500)); +} + +#[test] +fn basic_negative_floor_rounding_v2() { + // Test setup + let test_duration = Duration::new(5, 6, 7, 8, 40, 30, 20, 123, 987, 500).unwrap(); + let backward_date = PlainDate::new(2020, 12, 1, Calendar::default()).unwrap(); + + let relative_backward = RelativeTo::PlainDate(backward_date); + + let mut options = RoundingOptions { + largest_unit: None, + smallest_unit: None, + increment: None, + rounding_mode: Some(RoundingMode::Floor), + }; + + let _ = options.smallest_unit.insert(Unit::Year); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-6, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Month); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -8, 0, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Week); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, -4, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Day); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -28, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Hour); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -17, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Minute); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -16, -31, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Second); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -16, -30, -21, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Millisecond); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -16, -30, -20, -124, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Microsecond); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -16, -30, -20, -123, -988, 0)); + + let _ = options.smallest_unit.insert(Unit::Nanosecond); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -16, -30, -20, -123, -987, -500)); +} + +// roundingmode-ceil.js +#[test] +fn basic_positive_ceil_rounding() { + let test_duration = Duration::new(5, 6, 7, 8, 40, 30, 20, 123, 987, 500).unwrap(); + let forward_date = PlainDate::new(2020, 4, 1, Calendar::from_str("iso8601").unwrap()).unwrap(); + + let relative_forward = RelativeTo::PlainDate(forward_date); + + let mut options = RoundingOptions { + largest_unit: None, + smallest_unit: None, + increment: None, + rounding_mode: Some(RoundingMode::Ceil), + }; + + let _ = options.smallest_unit.insert(Unit::Year); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (6, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Month); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 8, 0, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Week); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 4, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Day); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 28, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Hour); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 17, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Minute); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 16, 31, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Second); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 16, 30, 21, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Millisecond); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 16, 30, 20, 124, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Microsecond); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 16, 30, 20, 123, 988, 0)); + + let _ = options.smallest_unit.insert(Unit::Nanosecond); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 16, 30, 20, 123, 987, 500)); +} + +#[test] +fn basic_negative_ceil_rounding() { + let test_duration = Duration::new(5, 6, 7, 8, 40, 30, 20, 123, 987, 500).unwrap(); + let backward_date = + PlainDate::new(2020, 12, 1, Calendar::from_str("iso8601").unwrap()).unwrap(); + let relative_backward = RelativeTo::PlainDate(backward_date); + + let mut options = RoundingOptions { + largest_unit: None, + smallest_unit: None, + increment: None, + rounding_mode: Some(RoundingMode::Ceil), + }; + + let _ = options.smallest_unit.insert(Unit::Year); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Month); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Week); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, -3, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Day); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Hour); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -16, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Minute); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -16, -30, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Second); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -16, -30, -20, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Millisecond); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -16, -30, -20, -123, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Microsecond); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -16, -30, -20, -123, -987, 0)); + + let _ = options.smallest_unit.insert(Unit::Nanosecond); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -16, -30, -20, -123, -987, -500)); +} + +// roundingmode-expand.js +#[test] +fn basic_positive_expand_rounding() { + let test_duration = Duration::new(5, 6, 7, 8, 40, 30, 20, 123, 987, 500).unwrap(); + let forward_date = PlainDate::new(2020, 4, 1, Calendar::from_str("iso8601").unwrap()).unwrap(); + let relative_forward = RelativeTo::PlainDate(forward_date); + + let mut options = RoundingOptions { + largest_unit: None, + smallest_unit: None, + increment: None, + rounding_mode: Some(RoundingMode::Expand), + }; + + let _ = options.smallest_unit.insert(Unit::Year); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (6, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Month); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 8, 0, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Week); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 4, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Day); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 28, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Hour); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 17, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Minute); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 16, 31, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Second); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 16, 30, 21, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Millisecond); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 16, 30, 20, 124, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Microsecond); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 16, 30, 20, 123, 988, 0)); + + let _ = options.smallest_unit.insert(Unit::Nanosecond); + let result = get_round_result(&test_duration, relative_forward.clone(), options); + assert_duration(result, (5, 7, 0, 27, 16, 30, 20, 123, 987, 500)); +} + +#[test] +fn basic_negative_expand_rounding() { + let test_duration = Duration::new(5, 6, 7, 8, 40, 30, 20, 123, 987, 500).unwrap(); + + let backward_date = + PlainDate::new(2020, 12, 1, Calendar::from_str("iso8601").unwrap()).unwrap(); + + let relative_backward = RelativeTo::PlainDate(backward_date); + + let mut options = RoundingOptions { + largest_unit: None, + smallest_unit: None, + increment: None, + rounding_mode: Some(RoundingMode::Expand), + }; + + let _ = options.smallest_unit.insert(Unit::Year); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-6, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Month); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -8, 0, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Week); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, -4, 0, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Day); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -28, 0, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Hour); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -17, 0, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Minute); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -16, -31, 0, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Second); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -16, -30, -21, 0, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Millisecond); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -16, -30, -20, -124, 0, 0)); + + let _ = options.smallest_unit.insert(Unit::Microsecond); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -16, -30, -20, -123, -988, 0)); + + let _ = options.smallest_unit.insert(Unit::Nanosecond); + let result = get_round_result(&test_duration.negated(), relative_backward.clone(), options); + assert_duration(result, (-5, -7, 0, -27, -16, -30, -20, -123, -987, -500)); +} + +#[test] +fn rounding_to_fractional_day_tests() { + let twenty_five_hours = Duration::from_hours(25); + let options = RoundingOptions { + largest_unit: Some(Unit::Day), + smallest_unit: None, + increment: None, + rounding_mode: Some(RoundingMode::Floor), + }; + let result = twenty_five_hours.round(options, None).unwrap(); + assert_duration(result, (0, 0, 0, 1, 1, 0, 0, 0, 0, 0)); + + let sixty_days = Duration::from(DateDuration::new_unchecked(0, 0, 0, 64)); + let options = RoundingOptions { + largest_unit: None, + smallest_unit: Some(Unit::Day), + increment: Some(RoundingIncrement(NonZeroU32::new(5).unwrap())), + rounding_mode: Some(RoundingMode::Floor), + }; + let result = sixty_days.round(options, None).unwrap(); + assert_duration(result, (0, 0, 0, 60, 0, 0, 0, 0, 0, 0)); + + let sixty_days = Duration::from(DateDuration::new_unchecked(0, 0, 0, 64)); + let options = RoundingOptions { + largest_unit: None, + smallest_unit: Some(Unit::Day), + increment: Some(RoundingIncrement(NonZeroU32::new(10).unwrap())), + rounding_mode: Some(RoundingMode::Floor), + }; + let result = sixty_days.round(options, None).unwrap(); + assert_duration(result, (0, 0, 0, 60, 0, 0, 0, 0, 0, 0)); + + let sixty_days = Duration::from(DateDuration::new_unchecked(0, 0, 0, 64)); + let options = RoundingOptions { + largest_unit: None, + smallest_unit: Some(Unit::Day), + increment: Some(RoundingIncrement(NonZeroU32::new(10).unwrap())), + rounding_mode: Some(RoundingMode::Ceil), + }; + let result = sixty_days.round(options, None).unwrap(); + assert_duration(result, (0, 0, 0, 70, 0, 0, 0, 0, 0, 0)); + + let sixty_days = Duration::from(DateDuration::new_unchecked(0, 0, 0, 1000)); + let options = RoundingOptions { + largest_unit: None, + smallest_unit: Some(Unit::Day), + increment: Some(RoundingIncrement(NonZeroU32::new(1_000_000_000).unwrap())), + rounding_mode: Some(RoundingMode::Expand), + }; + let result = sixty_days.round(options, None).unwrap(); + assert_duration(result, (0, 0, 0, 1_000_000_000, 0, 0, 0, 0, 0, 0)); +} + +// test262/test/built-ins/Temporal/Duration/prototype/round/roundingincrement-non-integer.js +#[test] +fn rounding_increment_non_integer() { + let test_duration = Duration::from(DateDuration::new(0, 0, 0, 1).unwrap()); + let binding = PlainDate::new(2000, 1, 1, Calendar::from_str("iso8601").unwrap()).unwrap(); + let relative_to = RelativeTo::PlainDate(binding); + + let mut options = RoundingOptions { + largest_unit: None, + smallest_unit: Some(Unit::Day), + increment: None, + rounding_mode: Some(RoundingMode::Expand), + }; + + let _ = options + .increment + .insert(RoundingIncrement::try_from(2.5).unwrap()); + let result = test_duration + .round(options, Some(relative_to.clone())) + .unwrap(); + + assert_duration(result, (0, 0, 0, 2, 0, 0, 0, 0, 0, 0)); + + let _ = options + .increment + .insert(RoundingIncrement::try_from(1e9 + 0.5).unwrap()); + let result = test_duration.round(options, Some(relative_to)).unwrap(); + assert_duration(result, (0, 0, 0, 1_000_000_000, 0, 0, 0, 0, 0, 0)); +} + +#[test] +fn basic_add_duration() { + let base = Duration::new(0, 0, 0, 1, 0, 5, 0, 0, 0, 0).unwrap(); + let other = Duration::new(0, 0, 0, 2, 0, 5, 0, 0, 0, 0).unwrap(); + let result = base.add(&other).unwrap(); + assert_eq!(result.days(), 3); + assert_eq!(result.minutes(), 10); + + let other = Duration::new(0, 0, 0, -3, 0, -15, 0, 0, 0, 0).unwrap(); + let result = base.add(&other).unwrap(); + assert_eq!(result.days(), -2); + assert_eq!(result.minutes(), -10); +} + +#[test] +fn basic_subtract_duration() { + let base = Duration::new(0, 0, 0, 3, 0, 15, 0, 0, 0, 0).unwrap(); + let other = Duration::new(0, 0, 0, 1, 0, 5, 0, 0, 0, 0).unwrap(); + let result = base.subtract(&other).unwrap(); + assert_eq!(result.days(), 2); + assert_eq!(result.minutes(), 10); + + let other = Duration::new(0, 0, 0, -3, 0, -15, 0, 0, 0, 0).unwrap(); + let result = base.subtract(&other).unwrap(); + assert_eq!(result.days(), 6); + assert_eq!(result.minutes(), 30); +} + +// days-24-hours-relative-to-zoned-date-time.js +#[test] +fn round_relative_to_zoned_datetime() { + let duration = Duration::from_hours(25); + let zdt = ZonedDateTime::try_new( + 1_000_000_000_000_000_000, + TimeZone::try_from_str("+04:30").unwrap(), + Calendar::default(), + ) + .unwrap(); + let options = RoundingOptions { + largest_unit: Some(Unit::Day), + smallest_unit: None, + rounding_mode: None, + increment: None, + }; + let result = duration + .round(options, Some(RelativeTo::ZonedDateTime(zdt))) + .unwrap(); + // Result duration should be: (0, 0, 0, 1, 1, 0, 0, 0, 0, 0) + assert_eq!(result.days(), 1); + assert_eq!(result.hours(), 1); +} + +#[test] +fn test_duration_total() { + let d1 = Duration::from_partial_duration(PartialDuration { + hours: Some(130), + minutes: Some(20), + ..Default::default() + }) + .unwrap(); + assert_eq!(d1.total(Unit::Second, None).unwrap(), 469200.0); + + // How many 24-hour days is 123456789 seconds? + let d2 = Duration::from_str("PT123456789S").unwrap(); + assert_eq!(d2.total(Unit::Day, None).unwrap(), 1428.8980208333332); + + // Find totals in months, with and without taking DST into account + let d3 = Duration::from_partial_duration(PartialDuration { + hours: Some(2756), + ..Default::default() + }) + .unwrap(); + let relative_to = ZonedDateTime::from_utf8( + b"2020-01-01T00:00+01:00[Europe/Rome]", + Default::default(), + OffsetDisambiguation::Reject, + ) + .unwrap(); + assert_eq!( + d3.total(Unit::Month, Some(RelativeTo::ZonedDateTime(relative_to))) + .unwrap(), + 3.7958333333333334 + ); + assert_eq!( + d3.total( + Unit::Month, + Some(RelativeTo::PlainDate( + PlainDate::new(2020, 1, 1, Calendar::default()).unwrap() + )) + ) + .unwrap(), + 3.7944444444444443 + ); +} + +// balance-subseconds.js +#[test] +fn balance_subseconds() { + // Test positive + let pos = Duration::from_partial_duration(PartialDuration { + milliseconds: Some(999), + microseconds: Some(999999), + nanoseconds: Some(999999999), + ..Default::default() + }) + .unwrap(); + assert_eq!(pos.total(Unit::Second, None).unwrap(), 2.998998999); + + // Test negative + let neg = Duration::from_partial_duration(PartialDuration { + milliseconds: Some(-999), + microseconds: Some(-999999), + nanoseconds: Some(-999999999), + ..Default::default() + }) + .unwrap(); + assert_eq!(neg.total(Unit::Second, None).unwrap(), -2.998998999); +} + +// balances-days-up-to-both-years-and-months.js +#[test] +fn balance_days_up_to_both_years_and_months() { + // Test positive + let two_years = Duration::from_partial_duration(PartialDuration { + months: Some(11), + days: Some(396), + ..Default::default() + }) + .unwrap(); + + let relative_to = PlainDate::new(2017, 1, 1, Calendar::default()).unwrap(); + + assert_eq!( + two_years + .total(Unit::Year, Some(RelativeTo::PlainDate(relative_to.clone()))) + .unwrap(), + 2.0 + ); + + // Test negative + let two_years_negative = Duration::from_partial_duration(PartialDuration { + months: Some(-11), + days: Some(-396), + ..Default::default() + }) + .unwrap(); + + assert_eq!( + two_years_negative + .total(Unit::Year, Some(RelativeTo::PlainDate(relative_to.clone()))) + .unwrap(), + -2.0 + ); +} + +// relativeto-plaindate-add24hourdaystoTimeDuration-out-of-range.js +#[test] +fn add_normalized_time_duration_out_of_range() { + let duration = Duration::from_partial_duration(PartialDuration { + years: Some(1), + seconds: Some(9_007_199_254_740_990_i64), + ..Default::default() + }) + .unwrap(); + + let relative_to = PlainDate::new(2000, 1, 1, Calendar::default()).unwrap(); + + let err = duration.total(Unit::Day, Some(RelativeTo::PlainDate(relative_to))); + assert!(err.is_err()) +} + +#[test] +fn test_rounding_boundaries() { + let relative_to = PlainDate::new(2000, 1, 1, Calendar::default()).unwrap(); + + // test year + let duration = Duration::from_partial_duration(PartialDuration { + years: Some((u32::MAX - 1) as i64), + ..Default::default() + }) + .unwrap(); + + let options = RoundingOptions { + smallest_unit: Some(Unit::Week), + ..Default::default() + }; + let err = duration.round(options, Some(RelativeTo::PlainDate(relative_to.clone()))); + assert!(err.is_err()); + + // test month + let duration = Duration::from_partial_duration(PartialDuration { + months: Some((u32::MAX - 1) as i64), + ..Default::default() + }) + .unwrap(); + + let options = RoundingOptions { + smallest_unit: Some(Unit::Week), + ..Default::default() + }; + let err = duration.round(options, Some(RelativeTo::PlainDate(relative_to.clone()))); + assert!(err.is_err()); + + // test week + let duration = Duration::from_partial_duration(PartialDuration { + weeks: Some((u32::MAX - 1) as i64), + ..Default::default() + }) + .unwrap(); + + let options = RoundingOptions { + smallest_unit: Some(Unit::Week), + ..Default::default() + }; + let err = duration.round(options, Some(RelativeTo::PlainDate(relative_to.clone()))); + assert!(err.is_err()); + + // test calendar max + let duration = Duration::from_partial_duration(PartialDuration { + years: Some((u32::MAX - 1) as i64), + months: Some((u32::MAX - 1) as i64), + weeks: Some((u32::MAX - 1) as i64), + ..Default::default() + }) + .unwrap(); + + let options = RoundingOptions { + smallest_unit: Some(Unit::Week), + ..Default::default() + }; + let err = duration.round(options, Some(RelativeTo::PlainDate(relative_to.clone()))); + assert!(err.is_err()); + + // test days for safety + let duration = Duration::from_partial_duration(PartialDuration { + years: Some((u32::MAX - 1) as i64), + months: Some((u32::MAX - 1) as i64), + weeks: Some((u32::MAX - 1) as i64), + days: Some(104_249_991_374), + ..Default::default() + }) + .unwrap(); + + let options = RoundingOptions { + smallest_unit: Some(Unit::Week), + ..Default::default() + }; + let err = duration.round(options, Some(RelativeTo::PlainDate(relative_to.clone()))); + assert!(err.is_err()); + + // test minimum bounds with days for safety + let min_calendar_value = -((u32::MAX - 1) as i64); + let duration = Duration::from_partial_duration(PartialDuration { + years: Some(min_calendar_value), + months: Some(min_calendar_value), + weeks: Some(min_calendar_value), + days: Some(-104_249_991_374), + ..Default::default() + }) + .unwrap(); + + let options = RoundingOptions { + smallest_unit: Some(Unit::Week), + ..Default::default() + }; + let err = duration.round(options, Some(RelativeTo::PlainDate(relative_to))); + assert!(err.is_err()); +} + +#[test] +fn test_duration_compare_boundary() { + let relative_to = PlainDate::new(2000, 1, 1, Calendar::default()).unwrap(); + let zero = Duration::default(); + + let max_days = 2i64.pow(53) / 86_400; + let max_duration = Duration::new(0, 0, 1, max_days, 0, 0, 0, 0, 0, 0).unwrap(); + let err = zero.compare( + &max_duration, + Some(RelativeTo::PlainDate(relative_to.clone())), + ); + assert!(err.is_err()); + let err = max_duration.compare(&zero, Some(RelativeTo::PlainDate(relative_to.clone()))); + assert!(err.is_err()); + + let min_days = -(2i64.pow(53) / 86_400); + let min_duration = Duration::new(0, 0, -1, min_days, 0, 0, 0, 0, 0, 0).unwrap(); + let err = zero.compare( + &min_duration, + Some(RelativeTo::PlainDate(relative_to.clone())), + ); + assert!(err.is_err()); + let err = min_duration.compare(&zero, Some(RelativeTo::PlainDate(relative_to.clone()))); + assert!(err.is_err()); +} + +#[test] +fn rounding_cross_boundary() { + let relative_to = PlainDate::new(2022, 1, 1, Calendar::default()).unwrap(); + + let duration = Duration::from(DateDuration::new(1, 11, 0, 24).unwrap()); + let options = RoundingOptions { + smallest_unit: Some(Unit::Month), + rounding_mode: Some(RoundingMode::Expand), + ..Default::default() + }; + let result = duration + .round(options, Some(RelativeTo::PlainDate(relative_to))) + .unwrap(); + assert_duration(result, (2, 0, 0, 0, 0, 0, 0, 0, 0, 0)); +} + +#[test] +fn rounding_cross_boundary_negative() { + let relative_to = PlainDate::new(2022, 1, 1, Calendar::default()).unwrap(); + + let duration = Duration::from(DateDuration::new(-1, -11, 0, -24).unwrap()); + let options = RoundingOptions { + smallest_unit: Some(Unit::Month), + rounding_mode: Some(RoundingMode::Expand), + ..Default::default() + }; + let result = duration + .round(options, Some(RelativeTo::PlainDate(relative_to))) + .unwrap(); + assert_duration(result, (-2, 0, 0, 0, 0, 0, 0, 0, 0, 0)); +} + +#[test] +fn rounding_cross_boundary_time_units() { + let duration = Duration::new(0, 0, 0, 0, 1, 59, 59, 900, 0, 0).unwrap(); + let options = RoundingOptions { + smallest_unit: Some(Unit::Second), + rounding_mode: Some(RoundingMode::Expand), + ..Default::default() + }; + let result = duration.round(options, None).unwrap(); + assert_duration(result, (0, 0, 0, 0, 2, 0, 0, 0, 0, 0)); + + let neg_duration = Duration::new(0, 0, 0, 0, -1, -59, -59, -900, 0, 0).unwrap(); + let result = neg_duration.round(options, None).unwrap(); + assert_duration(result, (0, 0, 0, 0, -2, 0, 0, 0, 0, 0)); +} + +#[test] +fn nudge_past_end() { + // built-ins/Temporal/Duration/prototype/round/next-day-out-of-range + let duration = Duration::default(); + let relative_to = ZonedDateTime::try_new( + 86_40000_00000_00000_00000, + TimeZone::try_from_str("UTC").unwrap(), + Default::default(), + ) + .unwrap(); + let options = RoundingOptions { + largest_unit: Some(Unit::Day), + smallest_unit: Some(Unit::Minute), + increment: None, + rounding_mode: None, + }; + // This constructs an endDate of MAX_DATE + 1 day (even though the sign is zero). + // This must error. + let rounded = duration.round(options, Some(relative_to.into())); + assert!( + rounded.is_err(), + "Expected rounding to fail, got {rounded:?}" + ); +} + +#[test] +fn bubble_smallest_becomes_day() { + // built-ins/Temporal/Duration/prototype/round/bubble-time-unit + let duration = Duration::new(0, 0, 0, 0, /* hours = */ 14, 0, 0, 0, 0, 0).unwrap(); + let relative_to = PlainDate::try_new(2025, 6, 14, Default::default()).unwrap(); + let options = RoundingOptions { + largest_unit: None, + smallest_unit: Some(Unit::Hour), + increment: Some(RoundingIncrement::try_new(12).unwrap()), + rounding_mode: Some(RoundingMode::Ceil), + }; + // This constructs an endDate of MAX_DATE + 1 day (even though the sign is zero). + // This must error. + let rounded = duration.round(options, Some(relative_to.into())).unwrap(); + assert_eq!( + rounded.hours(), + 24, + "Expected rounding to fail, got {rounded:?}" + ); +} diff --git a/deps/temporal/src/builtins/compiled/instant.rs b/deps/temporal/src/builtins/compiled/instant.rs new file mode 100644 index 00000000000000..fe44de70ea49d6 --- /dev/null +++ b/deps/temporal/src/builtins/compiled/instant.rs @@ -0,0 +1,35 @@ +use crate::{ + builtins::TZ_PROVIDER, options::ToStringRoundingOptions, Instant, TemporalResult, TimeZone, + ZonedDateTime, +}; +use alloc::string::String; + +impl Instant { + /// Returns the RFC9557 (IXDTF) string for this `Instant` with the + /// provided options + /// + /// Enable with the `compiled_data` feature flag. + pub fn to_ixdtf_string( + &self, + timezone: Option, + options: ToStringRoundingOptions, + ) -> TemporalResult { + self.to_ixdtf_string_with_provider(timezone, options, &*TZ_PROVIDER) + } + + /// Returns the RFC9557 (IXDTF) string for this `Instant` with the + /// provided options as a Writeable + /// + /// Enable with the `compiled_data` feature flag. + pub fn to_ixdtf_writeable( + &self, + timezone: Option, + options: ToStringRoundingOptions, + ) -> TemporalResult { + self.to_ixdtf_writeable_with_provider(timezone, options, &*TZ_PROVIDER) + } + + pub fn to_zoned_date_time_iso(&self, time_zone: TimeZone) -> TemporalResult { + self.to_zoned_date_time_iso_with_provider(time_zone, &*TZ_PROVIDER) + } +} diff --git a/deps/temporal/src/builtins/compiled/mod.rs b/deps/temporal/src/builtins/compiled/mod.rs new file mode 100644 index 00000000000000..03a843f1a6765c --- /dev/null +++ b/deps/temporal/src/builtins/compiled/mod.rs @@ -0,0 +1,20 @@ +//! This module implements native Rust wrappers for the Temporal builtins. + +mod duration; +mod instant; +mod now; +mod plain_date; +mod plain_date_time; +mod plain_month_day; +mod plain_year_month; +mod zoned_date_time; + +mod options { + use crate::{builtins::TZ_PROVIDER, options::RelativeTo, TemporalResult}; + + impl RelativeTo { + pub fn try_from_str(source: &str) -> TemporalResult { + Self::try_from_str_with_provider(source, &*TZ_PROVIDER) + } + } +} diff --git a/deps/temporal/src/builtins/compiled/now.rs b/deps/temporal/src/builtins/compiled/now.rs new file mode 100644 index 00000000000000..d3303dd9a6d864 --- /dev/null +++ b/deps/temporal/src/builtins/compiled/now.rs @@ -0,0 +1,43 @@ +use crate::{ + builtins::{ + core::{Now, PlainDate, PlainDateTime, PlainTime}, + TZ_PROVIDER, + }, + host::HostHooks, + TemporalResult, TimeZone, ZonedDateTime, +}; + +impl Now { + pub fn time_zone(self) -> TemporalResult { + self.time_zone_with_provider(&*TZ_PROVIDER) + } + + /// Returns the current system time as a [`PlainDateTime`] with an optional + /// [`TimeZone`]. + /// + /// Enable with the `compiled_data` and `sys` feature flags. + pub fn plain_date_time_iso(self, time_zone: Option) -> TemporalResult { + self.plain_date_time_iso_with_provider(time_zone, &*TZ_PROVIDER) + } + + /// Returns the current system time as a [`PlainDate`] with an optional + /// [`TimeZone`]. + /// + /// Enable with the `compiled_data` and `sys` feature flags. + pub fn plain_date_iso(self, time_zone: Option) -> TemporalResult { + self.plain_date_iso_with_provider(time_zone, &*TZ_PROVIDER) + } + + /// Returns the current system time as a [`PlainTime`] with an optional + /// [`TimeZone`]. + /// + /// Enable with the `compiled_data` and `sys` feature flags. + pub fn plain_time_iso(self, time_zone: Option) -> TemporalResult { + self.plain_time_with_provider(time_zone, &*TZ_PROVIDER) + } + + /// Converts the current [`Now`] into an [`ZonedDateTime`] with an ISO8601 calendar. + pub fn zoned_date_time_iso(self, time_zone: Option) -> TemporalResult { + self.zoned_date_time_iso_with_provider(time_zone, &*TZ_PROVIDER) + } +} diff --git a/deps/temporal/src/builtins/compiled/plain_date.rs b/deps/temporal/src/builtins/compiled/plain_date.rs new file mode 100644 index 00000000000000..da9b8b06a4ce5c --- /dev/null +++ b/deps/temporal/src/builtins/compiled/plain_date.rs @@ -0,0 +1,12 @@ +use crate::{builtins::TZ_PROVIDER, PlainDate, PlainTime, TemporalResult, TimeZone}; + +impl PlainDate { + /// Converts a `Date` to a `ZonedDateTime` in the UTC time zone. + pub fn to_zoned_date_time( + &self, + time_zone: TimeZone, + plain_time: Option, + ) -> TemporalResult { + self.to_zoned_date_time_with_provider(time_zone, plain_time, &*TZ_PROVIDER) + } +} diff --git a/deps/temporal/src/builtins/compiled/plain_date_time.rs b/deps/temporal/src/builtins/compiled/plain_date_time.rs new file mode 100644 index 00000000000000..c9d2675ef3a9ea --- /dev/null +++ b/deps/temporal/src/builtins/compiled/plain_date_time.rs @@ -0,0 +1,47 @@ +use crate::{ + builtins::core::{PlainDateTime, ZonedDateTime}, + builtins::TZ_PROVIDER, + options::Disambiguation, + TemporalResult, TimeZone, +}; + +impl PlainDateTime { + /// Returns a `ZonedDateTime` with the provided `PlainDateTime`, TimeZone` and + /// `Disambiguation`. + /// + /// # Feature gated + /// + /// Enable with the `compiled_data` feature flag. + pub fn to_zoned_date_time( + &self, + time_zone: TimeZone, + disambiguation: Disambiguation, + ) -> TemporalResult { + self.to_zoned_date_time_with_provider(time_zone, disambiguation, &*TZ_PROVIDER) + } +} + +#[cfg(test)] +mod tests { + #[cfg(feature = "tzdb")] + #[test] + fn to_zoned_date_time_edge_cases() { + use crate::{options::Disambiguation, tzdb::CompiledTzdbProvider, PlainDateTime, TimeZone}; + let provider = &CompiledTzdbProvider::default(); + + // Test that a non existent PlainDateTime is successfully disambiguated. + // + // NOTE(nekevss): POSIX time zone logic of the underlying provider if TZDB is in a "slim" format. + let pdt = PlainDateTime::try_new_iso(2020, 3, 8, 2, 30, 0, 0, 0, 0).unwrap(); + let zdt = pdt + .to_zoned_date_time_with_provider( + TimeZone::try_from_identifier_str_with_provider("America/Los_Angeles", provider) + .unwrap(), + Disambiguation::Compatible, + provider, + ) + .unwrap(); + // Should disambiguate to 2020-03-08T01:30:00-08:00[America/Los_Angeles] + assert_eq!(zdt.hour(), 3); + } +} diff --git a/deps/temporal/src/builtins/compiled/plain_month_day.rs b/deps/temporal/src/builtins/compiled/plain_month_day.rs new file mode 100644 index 00000000000000..077a2a0c6a06a5 --- /dev/null +++ b/deps/temporal/src/builtins/compiled/plain_month_day.rs @@ -0,0 +1,9 @@ +use crate::{ + builtins::TZ_PROVIDER, unix_time::EpochNanoseconds, PlainMonthDay, TemporalResult, TimeZone, +}; + +impl PlainMonthDay { + pub fn epoch_ns_for(&self, time_zone: TimeZone) -> TemporalResult { + self.epoch_ns_for_with_provider(time_zone, &*TZ_PROVIDER) + } +} diff --git a/deps/temporal/src/builtins/compiled/plain_year_month.rs b/deps/temporal/src/builtins/compiled/plain_year_month.rs new file mode 100644 index 00000000000000..ab3cebe37927dc --- /dev/null +++ b/deps/temporal/src/builtins/compiled/plain_year_month.rs @@ -0,0 +1,9 @@ +use crate::{ + builtins::TZ_PROVIDER, unix_time::EpochNanoseconds, PlainYearMonth, TemporalResult, TimeZone, +}; + +impl PlainYearMonth { + pub fn epoch_ns_for(&self, time_zone: TimeZone) -> TemporalResult { + self.epoch_ns_for_with_provider(time_zone, &*TZ_PROVIDER) + } +} diff --git a/deps/temporal/src/builtins/compiled/zoned_date_time.rs b/deps/temporal/src/builtins/compiled/zoned_date_time.rs new file mode 100644 index 00000000000000..4a8e4dd19f4a97 --- /dev/null +++ b/deps/temporal/src/builtins/compiled/zoned_date_time.rs @@ -0,0 +1,232 @@ +use crate::builtins::zoned_date_time::ZonedDateTimeFields; +use crate::builtins::TZ_PROVIDER; +use crate::partial::PartialZonedDateTime; +use crate::provider::TransitionDirection; +use crate::{ + options::{ + DifferenceSettings, Disambiguation, DisplayCalendar, DisplayOffset, DisplayTimeZone, + OffsetDisambiguation, Overflow, RoundingOptions, ToStringRoundingOptions, + }, + Calendar, Duration, PlainTime, TemporalResult, TimeZone, +}; +use crate::{Instant, ZonedDateTime}; +use alloc::string::String; + +impl core::fmt::Display for ZonedDateTime { + /// The [`core::fmt::Display`] implementation for `ZonedDateTime`. + /// + /// Enable with the `compiled_data` feature flag. + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let string = self.to_ixdtf_string( + DisplayOffset::Auto, + DisplayTimeZone::Auto, + DisplayCalendar::Auto, + ToStringRoundingOptions::default(), + ); + debug_assert!( + string.is_ok(), + "A valid ZonedDateTime string with default options." + ); + f.write_str(&string.map_err(|_| Default::default())?) + } +} + +// ==== Experimental TZ_PROVIDER calendar method implementations ==== + +/// Calendar method implementations for `ZonedDateTime`. +/// +/// The following [`ZonedDateTime`] methods are feature gated behind the +/// `compiled_data` feature flag. +impl ZonedDateTime { + // TODO: Update direction to correct option + pub fn get_time_zone_transition( + &self, + direction: TransitionDirection, + ) -> TemporalResult> { + self.get_time_zone_transition_with_provider(direction, &*TZ_PROVIDER) + } + + /// Returns the hours in the day. + /// + /// Enable with the `compiled_data` feature flag. + pub fn hours_in_day(&self) -> TemporalResult { + self.hours_in_day_with_provider(&*TZ_PROVIDER) + } +} + +// ==== Experimental TZ_PROVIDER method implementations ==== + +/// The primary `ZonedDateTime` method implementations. +/// +/// The following [`ZonedDateTime`] methods are feature gated behind the +/// `compiled_data` feature flag. +impl ZonedDateTime { + /// Creates a new valid `ZonedDateTime`. + #[inline] + pub fn try_new(nanos: i128, time_zone: TimeZone, calendar: Calendar) -> TemporalResult { + Self::try_new_with_provider(nanos, time_zone, calendar, &*TZ_PROVIDER) + } + + /// Creates a new valid `ZonedDateTime` with an ISO 8601 calendar. + #[inline] + pub fn try_new_iso(nanos: i128, time_zone: TimeZone) -> TemporalResult { + Self::try_new_iso_with_provider(nanos, time_zone, &*TZ_PROVIDER) + } + + /// Creates a new valid `ZonedDateTime` from an [`Instant`]. + #[inline] + pub fn try_new_from_instant( + instant: Instant, + time_zone: TimeZone, + calendar: Calendar, + ) -> TemporalResult { + Self::try_new_from_instant_with_provider(instant, time_zone, calendar, &*TZ_PROVIDER) + } + + /// Creates a new valid `ZonedDateTime` from an [`Instant`] with an ISO 8601 calendar. + #[inline] + pub fn try_new_iso_from_instant(instant: Instant, time_zone: TimeZone) -> TemporalResult { + Self::try_new_iso_from_instant_with_provider(instant, time_zone, &*TZ_PROVIDER) + } + + #[inline] + pub fn from_partial( + partial: PartialZonedDateTime, + overflow: Option, + disambiguation: Option, + offset_option: Option, + ) -> TemporalResult { + Self::from_partial_with_provider( + partial, + overflow, + disambiguation, + offset_option, + &*crate::builtins::TZ_PROVIDER, + ) + } + + #[inline] + pub fn with( + &self, + fields: ZonedDateTimeFields, + disambiguation: Option, + offset_option: Option, + overflow: Option, + ) -> TemporalResult { + self.with_with_provider( + fields, + disambiguation, + offset_option, + overflow, + &*TZ_PROVIDER, + ) + } + + /// Creates a new `ZonedDateTime` from the current `ZonedDateTime` with the provided `PlainTime`. + /// + /// combined with the provided `TimeZone`. + pub fn with_plain_time(&self, time: Option) -> TemporalResult { + self.with_plain_time_and_provider(time, &*TZ_PROVIDER) + } + + /// Creates a new `ZonedDateTime` from the current `ZonedDateTime` + /// combined with the provided `TimeZone`. + pub fn with_timezone(&self, timezone: TimeZone) -> TemporalResult { + self.with_time_zone_with_provider(timezone, &*TZ_PROVIDER) + } + + /// Adds a [`Duration`] to the current `ZonedDateTime`. + /// + /// Enable with the `compiled_data` feature flag. + pub fn add(&self, duration: &Duration, overflow: Option) -> TemporalResult { + self.add_with_provider(duration, overflow, &*TZ_PROVIDER) + } + + /// Subtracts a [`Duration`] to the current `ZonedDateTime`. + /// + /// Enable with the `compiled_data` feature flag. + pub fn subtract( + &self, + duration: &Duration, + overflow: Option, + ) -> TemporalResult { + self.subtract_with_provider(duration, overflow, &*TZ_PROVIDER) + } + + pub fn equals(&self, other: &Self) -> TemporalResult { + self.equals_with_provider(other, &*TZ_PROVIDER) + } + + /// Returns a [`Duration`] representing the period of time from this `ZonedDateTime` since the other `ZonedDateTime`. + /// + /// Enable with the `compiled_data` feature flag. + pub fn since(&self, other: &Self, options: DifferenceSettings) -> TemporalResult { + self.since_with_provider(other, options, &*TZ_PROVIDER) + } + + /// Returns a [`Duration`] representing the period of time from this `ZonedDateTime` since the other `ZonedDateTime`. + /// + /// Enable with the `compiled_data` feature flag. + pub fn until(&self, other: &Self, options: DifferenceSettings) -> TemporalResult { + self.until_with_provider(other, options, &*TZ_PROVIDER) + } + + /// Returns the start of day for the current `ZonedDateTime`. + /// + /// Enable with the `compiled_data` feature flag. + pub fn start_of_day(&self) -> TemporalResult { + self.start_of_day_with_provider(&*TZ_PROVIDER) + } + + /// Rounds this [`ZonedDateTime`] to the nearest value according to the given rounding options. + /// + /// Enable with the `compiled_data` feature flag. + pub fn round(&self, options: RoundingOptions) -> TemporalResult { + self.round_with_provider(options, &*TZ_PROVIDER) + } + + /// Returns a RFC9557 (IXDTF) string with the provided options. + /// + /// Enable with the `compiled_data` feature flag. + pub fn to_ixdtf_string( + &self, + display_offset: DisplayOffset, + display_timezone: DisplayTimeZone, + display_calendar: DisplayCalendar, + options: ToStringRoundingOptions, + ) -> TemporalResult { + self.to_ixdtf_string_with_provider( + display_offset, + display_timezone, + display_calendar, + options, + &*TZ_PROVIDER, + ) + } + + /// Attempts to parse and create a `ZonedDateTime` from an IXDTF formatted [`&str`]. + /// + /// Enable with the `compiled_data` feature flag. + pub fn from_utf8( + source: &[u8], + disambiguation: Disambiguation, + offset_option: OffsetDisambiguation, + ) -> TemporalResult { + ZonedDateTime::from_utf8_with_provider(source, disambiguation, offset_option, &*TZ_PROVIDER) + } + /// Attempts to parse and create a `ZonedDateTime` from an IXDTF formatted [`&str`]. + /// + /// Enable with the `compiled_data` feature flag. + pub fn from_parsed( + parsed: crate::parsed_intermediates::ParsedZonedDateTime, + disambiguation: Disambiguation, + offset_option: OffsetDisambiguation, + ) -> TemporalResult { + ZonedDateTime::from_parsed_with_provider( + parsed, + disambiguation, + offset_option, + &*TZ_PROVIDER, + ) + } +} diff --git a/deps/temporal/src/builtins/core/calendar.rs b/deps/temporal/src/builtins/core/calendar.rs new file mode 100644 index 00000000000000..e05c3f39c6867b --- /dev/null +++ b/deps/temporal/src/builtins/core/calendar.rs @@ -0,0 +1,992 @@ +//! This module implements the calendar traits and related components. +//! +//! The goal of the calendar module of `boa_temporal` is to provide +//! Temporal compatible calendar implementations. + +use crate::{ + builtins::core::{ + duration::DateDuration, Duration, PlainDate, PlainDateTime, PlainMonthDay, PlainYearMonth, + }, + iso::IsoDate, + options::{Overflow, Unit}, + parsers::parse_allowed_calendar_formats, + TemporalError, TemporalResult, +}; +use core::str::FromStr; + +use icu_calendar::{ + cal::{ + Buddhist, Chinese, Coptic, Dangi, Ethiopian, EthiopianEraStyle, Hebrew, HijriSimulated, + HijriTabular, HijriUmmAlQura, Indian, Japanese, JapaneseExtended, Persian, Roc, + }, + AnyCalendar, AnyCalendarKind, Calendar as IcuCalendar, Iso, Ref, +}; +use icu_calendar::{ + cal::{HijriTabularEpoch, HijriTabularLeapYears}, + preferences::CalendarAlgorithm, + types::MonthCode as IcuMonthCode, + Gregorian, +}; +use icu_locale::extensions::unicode::Value; +use tinystr::{tinystr, TinyAsciiStr}; + +use super::ZonedDateTime; + +mod era; +mod fields; +mod types; + +pub use fields::{CalendarFields, YearMonthCalendarFields}; +#[cfg(test)] +pub(crate) use types::month_to_month_code; +pub(crate) use types::ResolutionType; +pub use types::{MonthCode, ResolvedCalendarFields}; + +use era::EraInfo; + +/// The core `Calendar` type for `temporal_rs` +/// +/// A `Calendar` in `temporal_rs` can be any calendar that is currently +/// supported by [`icu_calendar`]. +#[derive(Debug, Clone)] +pub struct Calendar(Ref<'static, AnyCalendar>); + +impl Default for Calendar { + fn default() -> Self { + Self::ISO + } +} + +impl PartialEq for Calendar { + fn eq(&self, other: &Self) -> bool { + self.identifier() == other.identifier() + } +} + +impl Eq for Calendar {} + +impl Calendar { + /// The Buddhist calendar + pub const BUDDHIST: Self = Self::new(AnyCalendarKind::Buddhist); + /// The Chinese calendar + pub const CHINESE: Self = Self::new(AnyCalendarKind::Chinese); + /// The Coptic calendar + pub const COPTIC: Self = Self::new(AnyCalendarKind::Coptic); + /// The Dangi calendar + pub const DANGI: Self = Self::new(AnyCalendarKind::Dangi); + /// The Ethiopian calendar + pub const ETHIOPIAN: Self = Self::new(AnyCalendarKind::Ethiopian); + /// The Ethiopian Amete Alem calendar + pub const ETHIOPIAN_AMETE_ALEM: Self = Self::new(AnyCalendarKind::EthiopianAmeteAlem); + /// The Gregorian calendar + pub const GREGORIAN: Self = Self::new(AnyCalendarKind::Gregorian); + /// The Hebrew calendar + pub const HEBREW: Self = Self::new(AnyCalendarKind::Hebrew); + /// The Indian calendar + pub const INDIAN: Self = Self::new(AnyCalendarKind::Indian); + /// The Hijri Tabular calendar with a Friday epoch + pub const HIJRI_TABULAR_FRIDAY: Self = Self::new(AnyCalendarKind::HijriTabularTypeIIFriday); + /// The Hijri Tabular calendar with a Thursday epoch + pub const HIJRI_TABULAR_THURSDAY: Self = Self::new(AnyCalendarKind::HijriTabularTypeIIThursday); + /// The Hijri Umm al-Qura calendar + pub const HIJRI_UMM_AL_QURA: Self = Self::new(AnyCalendarKind::HijriUmmAlQura); + /// The Hijri simulated calendar + pub const HIJRI_SIMULATED: Self = Self::new(AnyCalendarKind::HijriSimulatedMecca); + /// The ISO 8601 calendar + pub const ISO: Self = Self::new(AnyCalendarKind::Iso); + /// The Japanese calendar + pub const JAPANESE: Self = Self::new(AnyCalendarKind::Japanese); + /// The Persian calendar + pub const PERSIAN: Self = Self::new(AnyCalendarKind::Persian); + /// The ROC calendar + pub const ROC: Self = Self::new(AnyCalendarKind::Roc); + + /// Create a `Calendar` from an ICU [`AnyCalendarKind`]. + #[warn(clippy::wildcard_enum_match_arm)] // Warns if the calendar kind gets out of sync. + pub const fn new(kind: AnyCalendarKind) -> Self { + let cal = match kind { + AnyCalendarKind::Buddhist => &AnyCalendar::Buddhist(Buddhist), + AnyCalendarKind::Chinese => const { &AnyCalendar::Chinese(Chinese::new()) }, + AnyCalendarKind::Coptic => &AnyCalendar::Coptic(Coptic), + AnyCalendarKind::Dangi => const { &AnyCalendar::Dangi(Dangi::new()) }, + AnyCalendarKind::Ethiopian => { + const { + &AnyCalendar::Ethiopian(Ethiopian::new_with_era_style( + EthiopianEraStyle::AmeteMihret, + )) + } + } + AnyCalendarKind::EthiopianAmeteAlem => { + const { + &AnyCalendar::Ethiopian(Ethiopian::new_with_era_style( + EthiopianEraStyle::AmeteAlem, + )) + } + } + AnyCalendarKind::Gregorian => &AnyCalendar::Gregorian(Gregorian), + AnyCalendarKind::Hebrew => &AnyCalendar::Hebrew(Hebrew), + AnyCalendarKind::Indian => &AnyCalendar::Indian(Indian), + AnyCalendarKind::HijriTabularTypeIIFriday => { + const { + &AnyCalendar::HijriTabular(HijriTabular::new( + HijriTabularLeapYears::TypeII, + HijriTabularEpoch::Friday, + )) + } + } + AnyCalendarKind::HijriSimulatedMecca => { + const { &AnyCalendar::HijriSimulated(HijriSimulated::new_mecca()) } + } + AnyCalendarKind::HijriTabularTypeIIThursday => { + const { + &AnyCalendar::HijriTabular(HijriTabular::new( + HijriTabularLeapYears::TypeII, + HijriTabularEpoch::Thursday, + )) + } + } + AnyCalendarKind::HijriUmmAlQura => { + const { &AnyCalendar::HijriUmmAlQura(HijriUmmAlQura::new()) } + } + AnyCalendarKind::Iso => &AnyCalendar::Iso(Iso), + AnyCalendarKind::Japanese => const { &AnyCalendar::Japanese(Japanese::new()) }, + AnyCalendarKind::JapaneseExtended => { + const { &AnyCalendar::JapaneseExtended(JapaneseExtended::new()) } + } + AnyCalendarKind::Persian => &AnyCalendar::Persian(Persian), + AnyCalendarKind::Roc => &AnyCalendar::Roc(Roc), + _ => { + debug_assert!( + false, + "Unreachable: match must handle all variants of `AnyCalendarKind`" + ); + &AnyCalendar::Iso(Iso) + } + }; + + Self(Ref(cal)) + } + + /// Returns a `Calendar` from the a slice of UTF-8 encoded bytes. + pub fn try_from_utf8(bytes: &[u8]) -> TemporalResult { + let kind = Self::try_kind_from_utf8(bytes)?; + Ok(Self::new(kind)) + } + + /// Returns a `Calendar` from the a slice of UTF-8 encoded bytes. + pub(crate) fn try_kind_from_utf8(bytes: &[u8]) -> TemporalResult { + // TODO: Determine the best way to handle "julian" here. + // Not supported by `CalendarAlgorithm` + let icu_locale_value = Value::try_from_utf8(&bytes.to_ascii_lowercase()) + .map_err(|_| TemporalError::range().with_message("unknown calendar"))?; + let algorithm = CalendarAlgorithm::try_from(&icu_locale_value) + .map_err(|_| TemporalError::range().with_message("unknown calendar"))?; + let calendar_kind = match AnyCalendarKind::try_from(algorithm) { + Ok(c) => c, + // Handle `islamic` calendar idenitifier. + // + // This should be updated depending on `icu_calendar` support and + // intl-era-monthcode. + Err(()) if algorithm == CalendarAlgorithm::Hijri(None) => { + AnyCalendarKind::HijriTabularTypeIIFriday + } + Err(()) => return Err(TemporalError::range().with_message("unknown calendar")), + }; + Ok(calendar_kind) + } +} + +impl FromStr for Calendar { + type Err = TemporalError; + + // 13.34 ParseTemporalCalendarString ( string ) + fn from_str(s: &str) -> Result { + match parse_allowed_calendar_formats(s.as_bytes()) { + Some([]) => Ok(Calendar::ISO), + Some(result) => Calendar::try_from_utf8(result), + None => Calendar::try_from_utf8(s.as_bytes()), + } + } +} + +// ==== Public `CalendarSlot` methods ==== + +impl Calendar { + /// Returns whether the current calendar is `ISO` + #[inline] + pub fn is_iso(&self) -> bool { + matches!(self.0 .0, AnyCalendar::Iso(_)) + } + + /// Returns the kind of this calendar + #[inline] + pub fn kind(&self) -> AnyCalendarKind { + self.0 .0.kind() + } + + /// `CalendarDateFromFields` + pub fn date_from_fields( + &self, + fields: CalendarFields, + overflow: Overflow, + ) -> TemporalResult { + let resolved_fields = + ResolvedCalendarFields::try_from_fields(self, &fields, overflow, ResolutionType::Date)?; + + if self.is_iso() { + // Resolve month and monthCode; + return PlainDate::new_with_overflow( + resolved_fields.era_year.arithmetic_year, + resolved_fields.month_code.to_month_integer(), + resolved_fields.day, + self.clone(), + overflow, + ); + } + + let calendar_date = self.0.from_codes( + resolved_fields.era_year.era.as_ref().map(|e| e.0.as_str()), + resolved_fields.era_year.year, + IcuMonthCode(resolved_fields.month_code.0), + resolved_fields.day, + )?; + let iso = self.0.to_iso(&calendar_date); + PlainDate::new_with_overflow( + Iso.extended_year(&iso), + Iso.month(&iso).ordinal, + Iso.day_of_month(&iso).0, + self.clone(), + overflow, + ) + } + + /// `CalendarPlainMonthDayFromFields` + pub fn month_day_from_fields( + &self, + mut fields: CalendarFields, + overflow: Overflow, + ) -> TemporalResult { + // You are allowed to specify year information, however + // it is *only* used for resolving the given month/day data. + // + // For example, constructing a PlainMonthDay for {year: 2025, month: 2, day: 29} + // with overflow: constrain will produce 02-28 since it will constrain + // the date to 2025-02-28 first, and only *then* will it construct an MD. + // + // This is specced partially in https://tc39.es/proposal-temporal/#sec-temporal-calendarmonthdaytoisoreferencedate + // notice that RegulateISODate is called with the passed-in year, but the reference year is used regardless + // of the passed in year in the final result. + // + // There may be more efficient ways to do this, but this works pretty well and doesn't require + // calendrical knowledge. + if fields.year.is_some() || (fields.era.is_some() && fields.era_year.is_some()) { + let date = self.date_from_fields(fields, overflow)?; + fields = CalendarFields::from_date(&date); + } + let resolved_fields = ResolvedCalendarFields::try_from_fields( + self, + &fields, + overflow, + ResolutionType::MonthDay, + )?; + if self.is_iso() { + return PlainMonthDay::new_with_overflow( + resolved_fields.month_code.to_month_integer(), + resolved_fields.day, + self.clone(), + overflow, + None, + ); + } + + // We trust ResolvedCalendarFields to have calculated an appropriate reference year for us + let calendar_date = self.0.from_codes( + resolved_fields.era_year.era.as_ref().map(|e| e.0.as_str()), + resolved_fields.era_year.year, + IcuMonthCode(resolved_fields.month_code.0), + resolved_fields.day, + )?; + let iso = self.0.to_iso(&calendar_date); + PlainMonthDay::new_with_overflow( + Iso.month(&iso).ordinal, + Iso.day_of_month(&iso).0, + self.clone(), + overflow, + Some(Iso.extended_year(&iso)), + ) + } + + /// `CalendarPlainYearMonthFromFields` + pub fn year_month_from_fields( + &self, + fields: YearMonthCalendarFields, + overflow: Overflow, + ) -> TemporalResult { + // TODO: add a from_partial_year_month method on ResolvedCalendarFields + let resolved_fields = ResolvedCalendarFields::try_from_fields( + self, + &CalendarFields::from(fields), + overflow, + ResolutionType::YearMonth, + )?; + if self.is_iso() { + return PlainYearMonth::new_with_overflow( + resolved_fields.era_year.arithmetic_year, + resolved_fields.month_code.to_month_integer(), + Some(resolved_fields.day), + self.clone(), + overflow, + ); + } + + // NOTE: This might preemptively throw as `ICU4X` does not support regulating. + let calendar_date = self.0.from_codes( + resolved_fields.era_year.era.as_ref().map(|e| e.0.as_str()), + resolved_fields.era_year.year, + IcuMonthCode(resolved_fields.month_code.0), + resolved_fields.day, + )?; + let iso = self.0.to_iso(&calendar_date); + PlainYearMonth::new_with_overflow( + Iso.year_info(&iso).year, + Iso.month(&iso).ordinal, + Some(Iso.day_of_month(&iso).0), + self.clone(), + overflow, + ) + } + + /// `CalendarDateAdd` + pub fn date_add( + &self, + date: &IsoDate, + duration: &DateDuration, + overflow: Overflow, + ) -> TemporalResult { + // 1. If calendar is "iso8601", then + if self.is_iso() { + let result = date.add_date_duration(duration, overflow)?; + // 11. Return ? CreateTemporalDate(result.[[Year]], result.[[Month]], result.[[Day]], "iso8601"). + return PlainDate::try_new(result.year, result.month, result.day, self.clone()); + } + + Err(TemporalError::range().with_message("Not yet implemented.")) + } + + /// `CalendarDateUntil` + pub fn date_until( + &self, + one: &IsoDate, + two: &IsoDate, + largest_unit: Unit, + ) -> TemporalResult { + if self.is_iso() { + let date_duration = one.diff_iso_date(two, largest_unit)?; + return Ok(Duration::from(date_duration)); + } + Err(TemporalError::range().with_message("Not yet implemented.")) + } + + /// `CalendarEra` + pub fn era(&self, iso_date: &IsoDate) -> Option> { + if self.is_iso() { + return None; + } + let calendar_date = self.0.from_iso(*iso_date.to_icu4x().inner()); + self.0 + .year_info(&calendar_date) + .era() + .map(|era_info| era_info.era) + } + + /// `CalendarEraYear` + pub fn era_year(&self, iso_date: &IsoDate) -> Option { + if self.is_iso() { + return None; + } + let calendar_date = self.0.from_iso(*iso_date.to_icu4x().inner()); + self.0 + .year_info(&calendar_date) + .era() + .map(|era_info| era_info.year) + } + + /// `CalendarArithmeticYear` + pub fn year(&self, iso_date: &IsoDate) -> i32 { + if self.is_iso() { + return iso_date.year; + } + let calendar_date = self.0.from_iso(*iso_date.to_icu4x().inner()); + self.0.extended_year(&calendar_date) + } + + /// `CalendarMonth` + pub fn month(&self, iso_date: &IsoDate) -> u8 { + if self.is_iso() { + return iso_date.month; + } + let calendar_date = self.0.from_iso(*iso_date.to_icu4x().inner()); + self.0.month(&calendar_date).ordinal + } + + /// `CalendarMonthCode` + pub fn month_code(&self, iso_date: &IsoDate) -> MonthCode { + if self.is_iso() { + let mc = iso_date.to_icu4x().month().standard_code.0; + return MonthCode(mc); + } + let calendar_date = self.0.from_iso(*iso_date.to_icu4x().inner()); + MonthCode(self.0.month(&calendar_date).standard_code.0) + } + + /// `CalendarDay` + pub fn day(&self, iso_date: &IsoDate) -> u8 { + if self.is_iso() { + return iso_date.day; + } + let calendar_date = self.0.from_iso(*iso_date.to_icu4x().inner()); + self.0.day_of_month(&calendar_date).0 + } + + /// `CalendarDayOfWeek` + pub fn day_of_week(&self, iso_date: &IsoDate) -> u16 { + iso_date.to_icu4x().day_of_week() as u16 + } + + /// `CalendarDayOfYear` + pub fn day_of_year(&self, iso_date: &IsoDate) -> u16 { + if self.is_iso() { + return iso_date.to_icu4x().day_of_year().0; + } + let calendar_date = self.0.from_iso(*iso_date.to_icu4x().inner()); + self.0.day_of_year(&calendar_date).0 + } + + /// `CalendarWeekOfYear` + pub fn week_of_year(&self, iso_date: &IsoDate) -> Option { + if self.is_iso() { + return Some(iso_date.to_icu4x().week_of_year().week_number); + } + // TODO: Research in ICU4X and determine best approach. + None + } + + /// `CalendarYearOfWeek` + pub fn year_of_week(&self, iso_date: &IsoDate) -> Option { + if self.is_iso() { + return Some(iso_date.to_icu4x().week_of_year().iso_year); + } + // TODO: Research in ICU4X and determine best approach. + None + } + + /// `CalendarDaysInWeek` + pub fn days_in_week(&self, _iso_date: &IsoDate) -> u16 { + 7 + } + + /// `CalendarDaysInMonth` + pub fn days_in_month(&self, iso_date: &IsoDate) -> u16 { + if self.is_iso() { + return iso_date.to_icu4x().days_in_month() as u16; + } + let calendar_date = self.0.from_iso(*iso_date.to_icu4x().inner()); + self.0.days_in_month(&calendar_date) as u16 + } + + /// `CalendarDaysInYear` + pub fn days_in_year(&self, iso_date: &IsoDate) -> u16 { + if self.is_iso() { + return iso_date.to_icu4x().days_in_year(); + } + let calendar_date = self.0.from_iso(*iso_date.to_icu4x().inner()); + self.0.days_in_year(&calendar_date) + } + + /// `CalendarMonthsInYear` + pub fn months_in_year(&self, iso_date: &IsoDate) -> u16 { + if self.is_iso() { + return 12; + } + let calendar_date = self.0.from_iso(*iso_date.to_icu4x().inner()); + self.0.months_in_year(&calendar_date) as u16 + } + + /// `CalendarInLeapYear` + pub fn in_leap_year(&self, iso_date: &IsoDate) -> bool { + if self.is_iso() { + return iso_date.to_icu4x().is_in_leap_year(); + } + let calendar_date = self.0.from_iso(*iso_date.to_icu4x().inner()); + self.0.is_in_leap_year(&calendar_date) + } + + /// Returns the identifier of this calendar slot. + pub fn identifier(&self) -> &'static str { + // icu_calendar lists iso8601 and julian as None + match self.0.calendar_algorithm() { + Some(c) => c.as_str(), + None if self.is_iso() => "iso8601", + None => "julian", + } + } +} + +impl Calendar { + pub(crate) fn get_era_info(&self, era_alias: &TinyAsciiStr<19>) -> Option { + match self.0 .0.kind() { + AnyCalendarKind::Buddhist if *era_alias == tinystr!(19, "be") => { + Some(era::BUDDHIST_ERA) + } + AnyCalendarKind::Coptic if *era_alias == tinystr!(19, "am") => Some(era::COPTIC_ERA), + AnyCalendarKind::Ethiopian if era::ETHIOPIC_ERA_IDENTIFIERS.contains(era_alias) => { + Some(era::ETHIOPIC_ERA) + } + AnyCalendarKind::Ethiopian + if era::ETHIOPIC_ETHOPICAA_ERA_IDENTIFIERS.contains(era_alias) => + { + Some(era::ETHIOPIC_ETHIOAA_ERA) + } + AnyCalendarKind::EthiopianAmeteAlem + if era::ETHIOAA_ERA_IDENTIFIERS.contains(era_alias) => + { + Some(era::ETHIOAA_ERA) + } + AnyCalendarKind::Gregorian if era::GREGORY_ERA_IDENTIFIERS.contains(era_alias) => { + Some(era::GREGORY_ERA) + } + AnyCalendarKind::Gregorian + if era::GREGORY_INVERSE_ERA_IDENTIFIERS.contains(era_alias) => + { + Some(era::GREGORY_INVERSE_ERA) + } + AnyCalendarKind::Hebrew if *era_alias == tinystr!(19, "am") => Some(era::HEBREW_ERA), + AnyCalendarKind::Indian if *era_alias == tinystr!(19, "shaka") => Some(era::INDIAN_ERA), + AnyCalendarKind::HijriTabularTypeIIFriday + | AnyCalendarKind::HijriSimulatedMecca + | AnyCalendarKind::HijriTabularTypeIIThursday + | AnyCalendarKind::HijriUmmAlQura + if *era_alias == tinystr!(19, "ah") => + { + Some(era::ISLAMIC_ERA) + } + AnyCalendarKind::HijriTabularTypeIIFriday + | AnyCalendarKind::HijriSimulatedMecca + | AnyCalendarKind::HijriTabularTypeIIThursday + | AnyCalendarKind::HijriUmmAlQura + if *era_alias == tinystr!(19, "bh") => + { + Some(era::ISLAMIC_INVERSE_ERA) + } + AnyCalendarKind::Japanese if *era_alias == tinystr!(19, "heisei") => { + Some(era::HEISEI_ERA) + } + AnyCalendarKind::Japanese if era::JAPANESE_ERA_IDENTIFIERS.contains(era_alias) => { + Some(era::JAPANESE_ERA) + } + AnyCalendarKind::Japanese + if era::JAPANESE_INVERSE_ERA_IDENTIFIERS.contains(era_alias) => + { + Some(era::JAPANESE_INVERSE_ERA) + } + AnyCalendarKind::Japanese if *era_alias == tinystr!(19, "meiji") => { + Some(era::MEIJI_ERA) + } + AnyCalendarKind::Japanese if *era_alias == tinystr!(19, "reiwa") => { + Some(era::REIWA_ERA) + } + AnyCalendarKind::Japanese if *era_alias == tinystr!(19, "showa") => { + Some(era::SHOWA_ERA) + } + AnyCalendarKind::Japanese if *era_alias == tinystr!(19, "taisho") => { + Some(era::TAISHO_ERA) + } + AnyCalendarKind::Persian if *era_alias == tinystr!(19, "ap") => Some(era::PERSIAN_ERA), + AnyCalendarKind::Roc if *era_alias == tinystr!(19, "roc") => Some(era::ROC_ERA), + AnyCalendarKind::Roc if *era_alias == tinystr!(19, "broc") => { + Some(era::ROC_INVERSE_ERA) + } + _ => None, + } + } + + pub(crate) fn get_calendar_default_era(&self) -> Option { + match self.0 .0.kind() { + AnyCalendarKind::Buddhist => Some(era::BUDDHIST_ERA), + AnyCalendarKind::Chinese => None, + AnyCalendarKind::Coptic => Some(era::COPTIC_ERA), + AnyCalendarKind::Dangi => None, + AnyCalendarKind::Ethiopian => Some(era::ETHIOPIC_ERA), + AnyCalendarKind::EthiopianAmeteAlem => Some(era::ETHIOAA_ERA), + AnyCalendarKind::Gregorian => Some(era::GREGORY_ERA), + AnyCalendarKind::Hebrew => Some(era::HEBREW_ERA), + AnyCalendarKind::Indian => Some(era::INDIAN_ERA), + AnyCalendarKind::HijriSimulatedMecca => Some(era::ISLAMIC_ERA), + AnyCalendarKind::HijriTabularTypeIIFriday => Some(era::ISLAMIC_ERA), + AnyCalendarKind::HijriTabularTypeIIThursday => Some(era::ISLAMIC_ERA), + AnyCalendarKind::HijriUmmAlQura => Some(era::ISLAMIC_ERA), + AnyCalendarKind::Iso => None, + AnyCalendarKind::Japanese => Some(era::JAPANESE_ERA), + AnyCalendarKind::Persian => Some(era::PERSIAN_ERA), + AnyCalendarKind::Roc => Some(era::ROC_ERA), + _ => None, + } + } + + pub(crate) fn calendar_has_eras(kind: AnyCalendarKind) -> bool { + match kind { + AnyCalendarKind::Buddhist + | AnyCalendarKind::Coptic + | AnyCalendarKind::Ethiopian + | AnyCalendarKind::EthiopianAmeteAlem + | AnyCalendarKind::Gregorian + | AnyCalendarKind::Hebrew + | AnyCalendarKind::Indian + | AnyCalendarKind::HijriSimulatedMecca + | AnyCalendarKind::HijriTabularTypeIIFriday + | AnyCalendarKind::HijriTabularTypeIIThursday + | AnyCalendarKind::HijriUmmAlQura + | AnyCalendarKind::Japanese + | AnyCalendarKind::Persian + | AnyCalendarKind::Roc => true, + AnyCalendarKind::Chinese | AnyCalendarKind::Dangi | AnyCalendarKind::Iso => false, + _ => false, + } + } +} + +impl From for Calendar { + fn from(value: PlainDate) -> Self { + value.calendar().clone() + } +} + +impl From for Calendar { + fn from(value: PlainDateTime) -> Self { + value.calendar().clone() + } +} + +impl From for Calendar { + fn from(value: ZonedDateTime) -> Self { + value.calendar().clone() + } +} + +impl From for Calendar { + fn from(value: PlainMonthDay) -> Self { + value.calendar().clone() + } +} + +impl From for Calendar { + fn from(value: PlainYearMonth) -> Self { + value.calendar().clone() + } +} + +#[cfg(test)] +mod tests { + use crate::{iso::IsoDate, options::Unit}; + use core::str::FromStr; + + use super::Calendar; + + #[test] + fn calendar_from_str_is_case_insensitive() { + let cal_str = "iSo8601"; + let calendar = Calendar::try_from_utf8(cal_str.as_bytes()).unwrap(); + assert_eq!(calendar, Calendar::default()); + + let cal_str = "iSO8601"; + let calendar = Calendar::try_from_utf8(cal_str.as_bytes()).unwrap(); + assert_eq!(calendar, Calendar::default()); + } + + #[test] + fn calendar_invalid_ascii_value() { + let cal_str = "İSO8601"; + let _err = Calendar::from_str(cal_str).unwrap_err(); + + let cal_str = "\u{0130}SO8601"; + let _err = Calendar::from_str(cal_str).unwrap_err(); + + // Verify that an empty calendar is an error. + let cal_str = "2025-02-07T01:24:00-06:00[u-ca=]"; + let _err = Calendar::from_str(cal_str).unwrap_err(); + } + + #[test] + fn date_until_largest_year() { + // tests format: (Date one, PlainDate two, Duration result) + let tests = [ + ((2021, 7, 16), (2021, 7, 16), (0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), + ((2021, 7, 16), (2021, 7, 17), (0, 0, 0, 1, 0, 0, 0, 0, 0, 0)), + ((2021, 7, 16), (2021, 7, 23), (0, 0, 0, 7, 0, 0, 0, 0, 0, 0)), + ((2021, 7, 16), (2021, 8, 16), (0, 1, 0, 0, 0, 0, 0, 0, 0, 0)), + ( + (2020, 12, 16), + (2021, 1, 16), + (0, 1, 0, 0, 0, 0, 0, 0, 0, 0), + ), + ((2021, 1, 5), (2021, 2, 5), (0, 1, 0, 0, 0, 0, 0, 0, 0, 0)), + ((2021, 1, 7), (2021, 3, 7), (0, 2, 0, 0, 0, 0, 0, 0, 0, 0)), + ((2021, 7, 16), (2021, 8, 17), (0, 1, 0, 1, 0, 0, 0, 0, 0, 0)), + ( + (2021, 7, 16), + (2021, 8, 13), + (0, 0, 0, 28, 0, 0, 0, 0, 0, 0), + ), + ((2021, 7, 16), (2021, 9, 16), (0, 2, 0, 0, 0, 0, 0, 0, 0, 0)), + ((2021, 7, 16), (2022, 7, 16), (1, 0, 0, 0, 0, 0, 0, 0, 0, 0)), + ( + (2021, 7, 16), + (2031, 7, 16), + (10, 0, 0, 0, 0, 0, 0, 0, 0, 0), + ), + ((2021, 7, 16), (2022, 7, 19), (1, 0, 0, 3, 0, 0, 0, 0, 0, 0)), + ((2021, 7, 16), (2022, 9, 19), (1, 2, 0, 3, 0, 0, 0, 0, 0, 0)), + ( + (2021, 7, 16), + (2031, 12, 16), + (10, 5, 0, 0, 0, 0, 0, 0, 0, 0), + ), + ( + (1997, 12, 16), + (2021, 7, 16), + (23, 7, 0, 0, 0, 0, 0, 0, 0, 0), + ), + ( + (1997, 7, 16), + (2021, 7, 16), + (24, 0, 0, 0, 0, 0, 0, 0, 0, 0), + ), + ( + (1997, 7, 16), + (2021, 7, 15), + (23, 11, 0, 29, 0, 0, 0, 0, 0, 0), + ), + ( + (1997, 6, 16), + (2021, 6, 15), + (23, 11, 0, 30, 0, 0, 0, 0, 0, 0), + ), + ( + (1960, 2, 16), + (2020, 3, 16), + (60, 1, 0, 0, 0, 0, 0, 0, 0, 0), + ), + ( + (1960, 2, 16), + (2021, 3, 15), + (61, 0, 0, 27, 0, 0, 0, 0, 0, 0), + ), + ( + (1960, 2, 16), + (2020, 3, 15), + (60, 0, 0, 28, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 3, 30), + (2021, 7, 16), + (0, 3, 0, 16, 0, 0, 0, 0, 0, 0), + ), + ( + (2020, 3, 30), + (2021, 7, 16), + (1, 3, 0, 16, 0, 0, 0, 0, 0, 0), + ), + ( + (1960, 3, 30), + (2021, 7, 16), + (61, 3, 0, 16, 0, 0, 0, 0, 0, 0), + ), + ( + (2019, 12, 30), + (2021, 7, 16), + (1, 6, 0, 16, 0, 0, 0, 0, 0, 0), + ), + ( + (2020, 12, 30), + (2021, 7, 16), + (0, 6, 0, 16, 0, 0, 0, 0, 0, 0), + ), + ( + (1997, 12, 30), + (2021, 7, 16), + (23, 6, 0, 16, 0, 0, 0, 0, 0, 0), + ), + ( + (1, 12, 25), + (2021, 7, 16), + (2019, 6, 0, 21, 0, 0, 0, 0, 0, 0), + ), + ((2019, 12, 30), (2021, 3, 5), (1, 2, 0, 5, 0, 0, 0, 0, 0, 0)), + ( + (2021, 7, 17), + (2021, 7, 16), + (0, 0, 0, -1, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 7, 23), + (2021, 7, 16), + (0, 0, 0, -7, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 8, 16), + (2021, 7, 16), + (0, -1, 0, 0, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 1, 16), + (2020, 12, 16), + (0, -1, 0, 0, 0, 0, 0, 0, 0, 0), + ), + ((2021, 2, 5), (2021, 1, 5), (0, -1, 0, 0, 0, 0, 0, 0, 0, 0)), + ((2021, 3, 7), (2021, 1, 7), (0, -2, 0, 0, 0, 0, 0, 0, 0, 0)), + ( + (2021, 8, 17), + (2021, 7, 16), + (0, -1, 0, -1, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 8, 13), + (2021, 7, 16), + (0, 0, 0, -28, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 9, 16), + (2021, 7, 16), + (0, -2, 0, 0, 0, 0, 0, 0, 0, 0), + ), + ( + (2022, 7, 16), + (2021, 7, 16), + (-1, 0, 0, 0, 0, 0, 0, 0, 0, 0), + ), + ( + (2031, 7, 16), + (2021, 7, 16), + (-10, 0, 0, 0, 0, 0, 0, 0, 0, 0), + ), + ( + (2022, 7, 19), + (2021, 7, 16), + (-1, 0, 0, -3, 0, 0, 0, 0, 0, 0), + ), + ( + (2022, 9, 19), + (2021, 7, 16), + (-1, -2, 0, -3, 0, 0, 0, 0, 0, 0), + ), + ( + (2031, 12, 16), + (2021, 7, 16), + (-10, -5, 0, 0, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 7, 16), + (1997, 12, 16), + (-23, -7, 0, 0, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 7, 16), + (1997, 7, 16), + (-24, 0, 0, 0, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 7, 15), + (1997, 7, 16), + (-23, -11, 0, -30, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 6, 15), + (1997, 6, 16), + (-23, -11, 0, -29, 0, 0, 0, 0, 0, 0), + ), + ( + (2020, 3, 16), + (1960, 2, 16), + (-60, -1, 0, 0, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 3, 15), + (1960, 2, 16), + (-61, 0, 0, -28, 0, 0, 0, 0, 0, 0), + ), + ( + (2020, 3, 15), + (1960, 2, 16), + (-60, 0, 0, -28, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 7, 16), + (2021, 3, 30), + (0, -3, 0, -17, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 7, 16), + (2020, 3, 30), + (-1, -3, 0, -17, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 7, 16), + (1960, 3, 30), + (-61, -3, 0, -17, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 7, 16), + (2019, 12, 30), + (-1, -6, 0, -17, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 7, 16), + (2020, 12, 30), + (0, -6, 0, -17, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 7, 16), + (1997, 12, 30), + (-23, -6, 0, -17, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 7, 16), + (1, 12, 25), + (-2019, -6, 0, -22, 0, 0, 0, 0, 0, 0), + ), + ( + (2021, 3, 5), + (2019, 12, 30), + (-1, -2, 0, -6, 0, 0, 0, 0, 0, 0), + ), + ]; + + let calendar = Calendar::default(); + + for test in tests { + let first = IsoDate::new_unchecked(test.0 .0, test.0 .1, test.0 .2); + let second = IsoDate::new_unchecked(test.1 .0, test.1 .1, test.1 .2); + let result = calendar.date_until(&first, &second, Unit::Year).unwrap(); + assert_eq!( + result.years() as i32, + test.2 .0, + "year failed for test \"{test:?}\"" + ); + assert_eq!( + result.months() as i32, + test.2 .1, + "months failed for test \"{test:?}\"" + ); + assert_eq!( + result.weeks() as i32, + test.2 .2, + "weeks failed for test \"{test:?}\"" + ); + assert_eq!( + result.days(), + test.2 .3, + "days failed for test \"{test:?}\"" + ); + } + } +} diff --git a/deps/temporal/src/builtins/core/calendar/era.rs b/deps/temporal/src/builtins/core/calendar/era.rs new file mode 100644 index 00000000000000..5b732abc2fd9d2 --- /dev/null +++ b/deps/temporal/src/builtins/core/calendar/era.rs @@ -0,0 +1,159 @@ +//! Calendar Eras constants + +// The general source for this implementation as of 2024-08-28 is the intl-era-monthcode proposal. +// +// As this source is currently a proposal, its content are subject to change, so full era support +// should be viewed as experimental. +// +// Source: https://tc39.es/proposal-intl-era-monthcode/ + +// TODO (0.1.0): Feature flag certain eras as experimental + +use core::ops::RangeInclusive; + +#[cfg(test)] +use icu_calendar::AnyCalendarKind; +use tinystr::{tinystr, TinyAsciiStr}; + +/// Relevant Era info. +pub(crate) struct EraInfo { + pub(crate) name: TinyAsciiStr<16>, + pub(crate) range: RangeInclusive, + pub(crate) arithmetic_year: ArithmeticYear, +} + +/// The way to map an era to an extended year +pub(crate) enum ArithmeticYear { + // This era is the default era, 1 ERA = 1 ArithmeticYear + DefaultEra, + // This era is a non-default era like reiwa, 1 ERA = offset ArithmeticYear + Offset(i32), + // This era is an inverse era like BC, 0 ERA = -1 ArithmeticYear + Inverse, +} + +impl EraInfo { + pub(crate) fn arithmetic_year_for(&self, era_year: i32) -> i32 { + match self.arithmetic_year { + ArithmeticYear::DefaultEra => era_year, + ArithmeticYear::Offset(offset) => offset + era_year - 1, + ArithmeticYear::Inverse => 1 - era_year, + } + } +} + +macro_rules! era_identifier { + ($name:literal) => { + tinystr!(19, $name) + }; +} + +macro_rules! valid_era { + ($name:literal, $range:expr, $ext:expr ) => { + EraInfo { + name: tinystr!(16, $name), + range: $range, + arithmetic_year: $ext, + } + }; + ($name:literal, $range:expr ) => { + valid_era!($name, $range, ArithmeticYear::DefaultEra) + }; +} + +pub(crate) const ETHIOPIC_ERA_IDENTIFIERS: [TinyAsciiStr<19>; 2] = + [era_identifier!("am"), era_identifier!("incar")]; + +pub(crate) const ETHIOPIC_ETHOPICAA_ERA_IDENTIFIERS: [TinyAsciiStr<19>; 2] = + [era_identifier!("aa"), era_identifier!("mundi")]; + +pub(crate) const ETHIOAA_ERA_IDENTIFIERS: [TinyAsciiStr<19>; 2] = + [era_identifier!("aa"), era_identifier!("mundi")]; + +pub(crate) const GREGORY_ERA_IDENTIFIERS: [TinyAsciiStr<19>; 2] = + [era_identifier!("ce"), era_identifier!("ad")]; + +pub(crate) const GREGORY_INVERSE_ERA_IDENTIFIERS: [TinyAsciiStr<19>; 2] = + [era_identifier!("bc"), era_identifier!("bce")]; +pub(crate) const JAPANESE_ERA_IDENTIFIERS: [TinyAsciiStr<19>; 2] = + [era_identifier!("ce"), era_identifier!("ad")]; + +pub(crate) const JAPANESE_INVERSE_ERA_IDENTIFIERS: [TinyAsciiStr<19>; 2] = + [era_identifier!("bc"), era_identifier!("bce")]; + +// NOTE: The below currently might not align 100% with ICU4X. +// TODO: Update to align with ICU4X depending on any Era updates. +pub(crate) const BUDDHIST_ERA: EraInfo = valid_era!("be", i32::MIN..=i32::MAX); +pub(crate) const COPTIC_ERA: EraInfo = valid_era!("am", 1..=i32::MAX); +pub(crate) const ETHIOPIC_ERA: EraInfo = valid_era!("am", 1..=i32::MAX); +pub(crate) const ETHIOPIC_ETHIOAA_ERA: EraInfo = + valid_era!("aa", i32::MIN..=5500, ArithmeticYear::Offset(-5499)); +pub(crate) const ETHIOAA_ERA: EraInfo = valid_era!("aa", i32::MIN..=i32::MAX); +pub(crate) const GREGORY_ERA: EraInfo = valid_era!("ce", 1..=i32::MAX); +pub(crate) const GREGORY_INVERSE_ERA: EraInfo = + valid_era!("bce", 1..=i32::MAX, ArithmeticYear::Inverse); +pub(crate) const HEBREW_ERA: EraInfo = valid_era!("am", i32::MIN..=i32::MAX); +pub(crate) const INDIAN_ERA: EraInfo = valid_era!("shaka", i32::MIN..=i32::MAX); +pub(crate) const ISLAMIC_ERA: EraInfo = valid_era!("ah", i32::MIN..=i32::MAX); +pub(crate) const ISLAMIC_INVERSE_ERA: EraInfo = + valid_era!("bh", i32::MIN..=i32::MAX, ArithmeticYear::Inverse); +pub(crate) const HEISEI_ERA: EraInfo = valid_era!("heisei", 1..=31, ArithmeticYear::Offset(1989)); +pub(crate) const JAPANESE_ERA: EraInfo = valid_era!("ce", 1..=1868); +pub(crate) const JAPANESE_INVERSE_ERA: EraInfo = + valid_era!("bce", 1..=i32::MAX, ArithmeticYear::Inverse); +pub(crate) const MEIJI_ERA: EraInfo = valid_era!("meiji", 1..=45, ArithmeticYear::Offset(1868)); +pub(crate) const REIWA_ERA: EraInfo = + valid_era!("reiwa", 1..=i32::MAX, ArithmeticYear::Offset(2019)); +pub(crate) const SHOWA_ERA: EraInfo = valid_era!("showa", 1..=64, ArithmeticYear::Offset(1926)); +pub(crate) const TAISHO_ERA: EraInfo = valid_era!("taisho", 1..=45, ArithmeticYear::Offset(1912)); +pub(crate) const PERSIAN_ERA: EraInfo = valid_era!("ap", i32::MIN..=i32::MAX); +pub(crate) const ROC_ERA: EraInfo = valid_era!("roc", 1..=i32::MAX); +pub(crate) const ROC_INVERSE_ERA: EraInfo = + valid_era!("broc", 1..=i32::MAX, ArithmeticYear::Inverse); + +#[cfg(test)] +/// https://tc39.es/proposal-intl-era-monthcode/#sec-temporal-calendarsupportsera +pub(crate) const ALL_ALLOWED_ERAS: &[(AnyCalendarKind, &[EraInfo])] = &[ + (AnyCalendarKind::Buddhist, &[BUDDHIST_ERA]), + (AnyCalendarKind::Coptic, &[COPTIC_ERA]), + ( + AnyCalendarKind::Ethiopian, + &[ETHIOPIC_ERA, ETHIOPIC_ETHIOAA_ERA], + ), + (AnyCalendarKind::EthiopianAmeteAlem, &[ETHIOAA_ERA]), + ( + AnyCalendarKind::Gregorian, + &[GREGORY_ERA, GREGORY_INVERSE_ERA], + ), + (AnyCalendarKind::Hebrew, &[HEBREW_ERA]), + (AnyCalendarKind::Indian, &[INDIAN_ERA]), + ( + AnyCalendarKind::HijriSimulatedMecca, + &[ISLAMIC_ERA, ISLAMIC_INVERSE_ERA], + ), + ( + AnyCalendarKind::HijriTabularTypeIIFriday, + &[ISLAMIC_ERA, ISLAMIC_INVERSE_ERA], + ), + ( + AnyCalendarKind::HijriTabularTypeIIThursday, + &[ISLAMIC_ERA, ISLAMIC_INVERSE_ERA], + ), + ( + AnyCalendarKind::HijriUmmAlQura, + &[ISLAMIC_ERA, ISLAMIC_INVERSE_ERA], + ), + ( + AnyCalendarKind::Japanese, + &[ + JAPANESE_ERA, + JAPANESE_INVERSE_ERA, + MEIJI_ERA, + REIWA_ERA, + SHOWA_ERA, + TAISHO_ERA, + ], + ), + (AnyCalendarKind::Persian, &[PERSIAN_ERA]), + (AnyCalendarKind::Roc, &[ROC_ERA, ROC_INVERSE_ERA]), +]; diff --git a/deps/temporal/src/builtins/core/calendar/fields.rs b/deps/temporal/src/builtins/core/calendar/fields.rs new file mode 100644 index 00000000000000..334693afff11e3 --- /dev/null +++ b/deps/temporal/src/builtins/core/calendar/fields.rs @@ -0,0 +1,389 @@ +use tinystr::TinyAsciiStr; + +use super::types::month_to_month_code; +use crate::{ + error::ErrorMessage, options::Overflow, Calendar, MonthCode, PlainDate, PlainDateTime, + PlainMonthDay, PlainYearMonth, TemporalError, TemporalResult, +}; +use core::ops::Range; + +/// The return value of CalendarFieldKeysToIgnore +#[derive(Copy, Clone, Default)] +pub(crate) struct FieldKeysToIgnore { + /// Ignore all era fields (era-year, era) + pub era: bool, + /// Ignore arithmetical year + pub arithmetical_year: bool, + /// Ignore all month fields (month, month-code) + pub month: bool, +} + +#[derive(Debug, Default, Clone, PartialEq)] +pub struct CalendarFields { + // A potentially set `year` field. + pub year: Option, + // A potentially set `month` field. + pub month: Option, + // A potentially set `month_code` field. + pub month_code: Option, + // A potentially set `day` field. + pub day: Option, + // A potentially set `era` field. + pub era: Option>, + // A potentially set `era_year` field. + pub era_year: Option, +} + +impl CalendarFields { + pub const fn new() -> Self { + Self { + year: None, + month: None, + month_code: None, + day: None, + era: None, + era_year: None, + } + } + + /// Temporal dates are valid between ISO -271821-04-20 and +275760-09-13, + /// but this may not correspond to the same thing for other calendars. + /// + /// These year values are well in range for not needing to worry about overflow/underflow, + /// but we cannot check for them without converting to the calendar first (via ISO). + /// + /// This method provides a quick and easy way to check that the years are in a safe arithmetic + /// range without necessarily needing to resolve calendar specific stuff. + /// + /// This is primarily a defense in depth mechanism; we should still use saturating/checked ops + /// where possible. This works nicely since we have an unambiguous answer for "GIGO or error" + /// since this check can always produce an error when out of range. + pub(crate) fn check_year_in_safe_arithmetical_range(&self) -> TemporalResult<()> { + // No calendars have eras offset more than 6000 years from the ISO epoch, + // and we generously round it up to ±300k + const ROUGH_YEAR_RANGE: Range = -300000..300000; + if let Some(year) = self.year { + if !ROUGH_YEAR_RANGE.contains(&year) { + return Err(TemporalError::range().with_enum(ErrorMessage::DateOutOfRange)); + } + } + if let Some(era_year) = self.era_year { + if !ROUGH_YEAR_RANGE.contains(&era_year) { + return Err(TemporalError::range().with_enum(ErrorMessage::DateOutOfRange)); + } + } + Ok(()) + } + + pub const fn with_era(mut self, era: Option>) -> Self { + self.era = era; + self + } + + pub const fn with_era_year(mut self, era_year: Option) -> Self { + self.era_year = era_year; + self + } + + pub const fn with_year(mut self, year: i32) -> Self { + self.year = Some(year); + self + } + + pub const fn with_optional_year(mut self, year: Option) -> Self { + self.year = year; + self + } + + pub const fn with_month(mut self, month: u8) -> Self { + self.month = Some(month); + self + } + + pub const fn with_optional_month(mut self, month: Option) -> Self { + self.month = month; + self + } + + pub const fn with_month_code(mut self, month_code: MonthCode) -> Self { + self.month_code = Some(month_code); + self + } + + pub const fn with_optional_month_code(mut self, month_code: Option) -> Self { + self.month_code = month_code; + self + } + + pub const fn with_day(mut self, day: u8) -> Self { + self.day = Some(day); + self + } + + pub const fn with_optional_day(mut self, day: Option) -> Self { + self.day = day; + self + } +} + +impl CalendarFields { + pub fn is_empty(&self) -> bool { + *self == Self::new() + } + + pub(crate) fn from_month_day(month_day: &PlainMonthDay) -> Self { + Self { + year: None, + month: None, + month_code: Some(month_day.month_code()), + era: None, + era_year: None, + day: Some(month_day.day()), + } + } + + pub(crate) fn from_date(date: &PlainDate) -> Self { + Self { + year: Some(date.year()), + month: Some(date.month()), + month_code: Some(date.month_code()), + era: date.era().map(TinyAsciiStr::resize), + era_year: date.era_year(), + day: Some(date.day()), + } + } + + crate::impl_with_fallback_method!(with_fallback_date, CalendarFields, (with_day: day) PlainDate); + crate::impl_with_fallback_method!(with_fallback_datetime, CalendarFields, (with_day:day) PlainDateTime); + crate::impl_field_keys_to_ignore!((with_day:day)); +} + +impl From for CalendarFields { + fn from(value: YearMonthCalendarFields) -> Self { + Self { + year: value.year, + month: value.month, + month_code: value.month_code, + day: None, + era: value.era, + era_year: value.era_year, + } + } +} + +impl From for YearMonthCalendarFields { + fn from(value: CalendarFields) -> Self { + Self { + year: value.year, + month: value.month, + month_code: value.month_code, + era: value.era, + era_year: value.era_year, + } + } +} + +#[derive(Debug, Default, Clone, PartialEq)] +pub struct YearMonthCalendarFields { + // A potentially set `year` field. + pub year: Option, + // A potentially set `month` field. + pub month: Option, + // A potentially set `month_code` field. + pub month_code: Option, + // A potentially set `era` field. + pub era: Option>, + // A potentially set `era_year` field. + pub era_year: Option, +} + +impl YearMonthCalendarFields { + pub const fn new() -> Self { + Self { + year: None, + month: None, + month_code: None, + era: None, + era_year: None, + } + } + + pub const fn with_era(mut self, era: Option>) -> Self { + self.era = era; + self + } + + pub const fn with_era_year(mut self, era_year: Option) -> Self { + self.era_year = era_year; + self + } + + pub const fn with_year(mut self, year: i32) -> Self { + self.year = Some(year); + self + } + + pub const fn with_optional_year(mut self, year: Option) -> Self { + self.year = year; + self + } + + pub const fn with_month(mut self, month: u8) -> Self { + self.month = Some(month); + self + } + + pub const fn with_optional_month(mut self, month: Option) -> Self { + self.month = month; + self + } + + pub const fn with_month_code(mut self, month_code: MonthCode) -> Self { + self.month_code = Some(month_code); + self + } + + pub const fn with_optional_month_code(mut self, month_code: Option) -> Self { + self.month_code = month_code; + self + } +} + +impl YearMonthCalendarFields { + pub(crate) fn try_from_year_month(year_month: &PlainYearMonth) -> TemporalResult { + let (year, era, era_year) = if year_month.era().is_some() { + ( + None, + year_month + .era() + .map(|t| TinyAsciiStr::<19>::try_from_utf8(t.as_bytes())) + .transpose() + .map_err(|_| TemporalError::general("Invalid era"))?, + year_month.era_year(), + ) + } else { + (Some(year_month.year()), None, None) + }; + Ok(Self { + year, + month: Some(year_month.month()), + month_code: Some(year_month.month_code()), + era, + era_year, + }) + } + + pub fn is_empty(&self) -> bool { + *self == Self::new() + } + + crate::impl_with_fallback_method!(with_fallback_year_month, CalendarFields, () PlainYearMonth); + crate::impl_field_keys_to_ignore!(()); +} + +// Use macro to impl fallback methods to avoid having a trait method. +#[doc(hidden)] +#[macro_export] +macro_rules! impl_with_fallback_method { + ($method_name:ident, $fields_type:ident, ( $(with_day: $day:ident)? ) $component_type:ty) => { + pub(crate) fn $method_name(&self, fallback: &$component_type, calendar: icu_calendar::AnyCalendarKind, overflow: Overflow) -> TemporalResult { + let keys_to_ignore = self.field_keys_to_ignore(calendar); + let mut era = self.era; + + let mut era_year = self.era_year; + let mut year = self.year; + + if !keys_to_ignore.era { + if era.is_none() { + era = + fallback.era().map(|e| { + TinyAsciiStr::<19>::try_from_utf8(e.as_bytes()) + .map_err(|_| TemporalError::assert().with_message("Produced invalid era code")) + }) + .transpose()? + } + if era_year.is_none() { + era_year = fallback.era_year(); + } + } + if !keys_to_ignore.arithmetical_year { + if year.is_none() { + year = Some(fallback.year()); + } + } + + let (month, month_code) = match (self.month, self.month_code) { + (Some(month), Some(mc)) => (Some(month), Some(mc)), + (Some(month), None) => { + let month_maybe_clamped = if overflow == Overflow::Constrain { + // TODO (manishearth) this should be managed by ICU4X + // https://github.com/unicode-org/icu4x/issues/6790 + month.clamp(1, 12) + } else { + month + }; + + (Some(month_maybe_clamped), Some(month_to_month_code(month_maybe_clamped)?)) + } + (None, Some(mc)) => (Some(mc.to_month_integer()).map(Into::into), Some(mc)), + (None, None) if !keys_to_ignore.month => ( + Some(fallback.month()).map(Into::into), + Some(fallback.month_code()), + ), + // This should currently be unreachable, but it may change as CalendarFieldKeysToIgnore + // changes + (None, None) => (None, None) + }; + #[allow(clippy::needless_update)] { + Ok(Self { + year, + month, + month_code, + $($day: Some(self.day.unwrap_or(fallback.day().into())),)? + era, + era_year, + }) + } + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! impl_field_keys_to_ignore { + (( $(with_day: $day:ident)? )) => { + /// + fn field_keys_to_ignore(&self, calendar: icu_calendar::AnyCalendarKind) -> $crate::builtins::core::calendar::fields::FieldKeysToIgnore { + let mut keys = $crate::builtins::core::calendar::fields::FieldKeysToIgnore::default(); + // All calendars have months/month codes + if self.month.is_some() || self.month_code.is_some() { + keys.month = true; + } + if Calendar::calendar_has_eras(calendar) { + // We should clear years only if the calendar has eras + if self.year.is_some() || self.era_year.is_some() || self.era.is_some() { + keys.era = true; + keys.arithmetical_year = true; + } + + // In a calendar such as "japanese" where eras do not start and end at year and/or month boundaries, note that the returned + // List should contain era and era-year if keys contains day, month, or month-code + // (not only if it contains era, era-year, or year, as in the example above) because it's possible for + // changing the day or month to cause a conflict with the era. + if calendar == icu_calendar::AnyCalendarKind::Japanese { + if self.month.is_some() || self.month_code.is_some() { + keys.era = true; + } + + $( + if self.$day.is_some() { + keys.era = true; + } + )? + } + } + + keys + } + }; +} diff --git a/deps/temporal/src/builtins/core/calendar/types.rs b/deps/temporal/src/builtins/core/calendar/types.rs new file mode 100644 index 00000000000000..b396b57230aeb8 --- /dev/null +++ b/deps/temporal/src/builtins/core/calendar/types.rs @@ -0,0 +1,790 @@ +//! Implementation of `ResolvedCalendarFields` + +use tinystr::tinystr; +use tinystr::TinyAsciiStr; + +use crate::fields::CalendarFields; +use crate::iso::{constrain_iso_day, is_valid_iso_day}; +use crate::options::Overflow; +use crate::Calendar; +use crate::{TemporalError, TemporalResult}; +use icu_calendar::AnyCalendarKind; + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum ResolutionType { + Date, + YearMonth, + MonthDay, +} + +/// `ResolvedCalendarFields` represents the resolved field values necessary for +/// creating a Date from potentially partial values. +#[derive(Debug)] +pub struct ResolvedCalendarFields { + pub(crate) era_year: EraYear, + pub(crate) month_code: MonthCode, + pub(crate) day: u8, +} + +impl ResolvedCalendarFields { + // TODO: Potentially make a method on `Calendar`. + #[inline] + pub fn try_from_fields( + calendar: &Calendar, + fields: &CalendarFields, + overflow: Overflow, + resolve_type: ResolutionType, + ) -> TemporalResult { + fields.check_year_in_safe_arithmetical_range()?; + let era_year = EraYear::try_from_fields(calendar, fields, resolve_type)?; + if calendar.is_iso() { + let month_code = resolve_iso_month(calendar, fields, overflow)?; + let day = resolve_day( + fields.day, + resolve_type == ResolutionType::YearMonth, + &era_year, + month_code, + calendar, + )?; + let day = if overflow == Overflow::Constrain { + constrain_iso_day(era_year.year, month_code.to_month_integer(), day) + } else { + if !is_valid_iso_day(era_year.year, month_code.to_month_integer(), day) { + return Err( + TemporalError::range().with_message("day value is not in a valid range.") + ); + } + day + }; + return Ok(Self { + era_year, + month_code, + day, + }); + } + + let month_code = MonthCode::try_from_fields(calendar, fields)?; + let day = resolve_day( + fields.day, + resolve_type == ResolutionType::YearMonth, + &era_year, + month_code, + calendar, + )?; + + Ok(Self { + era_year, + month_code, + day, + }) + } +} + +fn resolve_day( + day: Option, + is_year_month: bool, + year: &EraYear, + month_code: MonthCode, + calendar: &Calendar, +) -> TemporalResult { + if is_year_month { + if calendar.kind() == AnyCalendarKind::Japanese { + Ok( + match (year.arithmetic_year, month_code.to_month_integer()) { + // Meiji begins Oct 23, 1868 + (1868, 10) => 23, + // Taisho begins Jul 30, 1912 + (1912, 7) => 30, + // Showa begins Dec 12, 1926 + (1926, 12) => 25, + // Heisei begins 8 Jan 1989 + (1989, 1) => 8, + // Reiwa begins 1 May 2019 + (2019, 5) => 1, + _ => 1, + }, + ) + } else { + // PlainYearMonth construction paths all *require* setting the day to the first day of the month. + // See https://tc39.es/proposal-temporal/#sec-temporal-calendaryearmonthfromfields + Ok(1) + } + } else { + day.ok_or(TemporalError::r#type().with_message("Required day field is empty.")) + } +} + +#[derive(Debug)] +pub struct Era(pub(crate) TinyAsciiStr<16>); + +// TODO(Manishearth) We should just be using arithmetic_year unconditionally. +// so that https://github.com/boa-dev/temporal/issues/448 is handled. +// +// However, ICU4X has some bugs +// (https://github.com/unicode-org/icu4x/pull/6762/, https://github.com/unicode-org/icu4x/pull/6800) +// so for now we store both. +#[derive(Debug)] +pub struct EraYear { + pub(crate) era: Option, + pub(crate) year: i32, + pub(crate) arithmetic_year: i32, +} + +impl EraYear { + pub(crate) fn try_from_fields( + calendar: &Calendar, + partial: &CalendarFields, + resolution_type: ResolutionType, + ) -> TemporalResult { + match (partial.year, partial.era, partial.era_year) { + _ if resolution_type == ResolutionType::MonthDay => { + let day = partial + .day + .ok_or(TemporalError::r#type().with_message("MonthDay must specify day"))?; + + let arithmetic_year = Self::reference_arithmetic_year_for_month_day( + calendar, + partial.month_code, + day, + )?; + Ok(Self { + // We should just specify these as arithmetic years, no need + // to muck with eras + era: None, + arithmetic_year, + year: arithmetic_year, + }) + } + (maybe_year, Some(era), Some(era_year)) => { + let Some(era_info) = calendar.get_era_info(&era) else { + return Err(TemporalError::range().with_message("Invalid era provided.")); + }; + if !era_info.range.contains(&era_year) { + return Err(TemporalError::range() + .with_message("Year is not valid for the provided era")); + } + let calculated_arith = era_info.arithmetic_year_for(era_year); + // or a RangeError exception if the fields are sufficient but their values are internally inconsistent + // within the calendar (e.g., when fields such as [[Month]] and [[MonthCode]] have conflicting non-unset values). For example: + if let Some(arith) = maybe_year { + if calculated_arith != arith { + return Err( + TemporalError::range().with_message("Conflicting year/eraYear info") + ); + } + } + Ok(Self { + year: era_year, + era: Some(Era(era_info.name)), + arithmetic_year: calculated_arith, + }) + } + (Some(year), None, None) => Ok(Self { + era: calendar.get_calendar_default_era().map(|e| Era(e.name)), + year, + arithmetic_year: year, + }), + _ => Err(TemporalError::r#type() + .with_message("Required fields missing to determine an era and year.")), + } + } + + fn reference_arithmetic_year_for_month_day( + calendar: &Calendar, + month_code: Option, + day: u8, + ) -> TemporalResult { + // For simple calendars without leap days + // (or if leap days have already been handled) + // This needs the date of 1972-12-31 represented in that calendar + fn threshold(month: u8, day: u8, dec_31_1972: (i32, u8, u8)) -> i32 { + // If it's after the day of dec 31 in the primary reference year, + // go one year earlier + if month == dec_31_1972.1 && day > dec_31_1972.2 || month > dec_31_1972.1 { + dec_31_1972.0 - 1 + } else { + // Return the primary reference year + dec_31_1972.0 + } + } + // For simple calendars with a single leap day. + // This needs the date of 1972-12-31 represented in that calendar, the month-day of the leap day, + // and the first reference year where the leap day occurs on or before 1972-12-31 + fn threshold_with_leap_day( + month: u8, + day: u8, + dec_31_1972: (i32, u8, u8), + leap_day: (u8, u8), + leap_year: i32, + ) -> i32 { + // If it's a leap day, just return the leap year + if (month, day) == leap_day { + leap_year + } else { + threshold(month, day, dec_31_1972) + } + } + + let kind = calendar.kind(); + + // This behavior is required by tests, but is not yet specced. + // https://github.com/tc39/proposal-intl-era-monthcode/issues/60 + let Some(month_code) = month_code else { + if kind == AnyCalendarKind::Iso { + return Ok(1972); + } else { + return Err(TemporalError::r#type() + .with_message("MonthDay must be created with a monthCode for non-ISO")); + } + }; + + // The reference date is the latest ISO 8601 date corresponding to the calendar date, that is also earlier than + // or equal to the ISO 8601 date December 31, 1972. If that calendar date never occurs on or before the ISO 8601 date December 31, 1972, + // then the reference date is the earliest ISO 8601 date corresponding to that calendar date. + // The reference year is almost always 1972 (the first ISO 8601 leap year after the epoch), with exceptions + // for calendars where some dates (e.g. leap days or days in leap months) didn't occur during that ISO 8601 year. + // For example, Hebrew calendar leap month Adar I occurred in calendar years 5730 and 5733 (respectively overlapping + // ISO 8601 February/March 1970 and February/March 1973), but did not occur between them, so the reference year for days of that month is 1970. + + Ok(match calendar.kind() { + AnyCalendarKind::Iso | AnyCalendarKind::Gregorian => 1972, + // These calendars just wrap Gregorian with a different epoch + AnyCalendarKind::Buddhist => 1972 + 543, + AnyCalendarKind::Roc => 1972 - 1911, + + AnyCalendarKind::Indian => { + let month = month_code.to_month_integer(); + threshold_with_leap_day(month, day, (1894, 10, 10), (1, 30), 1984) + } + AnyCalendarKind::Persian => { + let month = month_code.to_month_integer(); + threshold_with_leap_day(month, day, (1351, 10, 10), (12, 30), 1350) + } + AnyCalendarKind::HijriTabularTypeIIFriday => { + let month = month_code.to_month_integer(); + threshold_with_leap_day(month, day, (1392, 11, 25), (12, 30), 1390) + } + AnyCalendarKind::HijriTabularTypeIIThursday => { + let month = month_code.to_month_integer(); + threshold_with_leap_day(month, day, (1392, 11, 26), (12, 30), 1390) + } + AnyCalendarKind::Coptic => { + let month = month_code.to_month_integer(); + threshold_with_leap_day(month, day, (1689, 4, 22), (13, 6), 1687) + } + AnyCalendarKind::Ethiopian => { + let month = month_code.to_month_integer(); + threshold_with_leap_day(month, day, (1965, 4, 22), (13, 6), 1963) + } + AnyCalendarKind::EthiopianAmeteAlem => { + let month = month_code.to_month_integer(); + threshold_with_leap_day(month, day, (7465, 4, 22), (13, 6), 7463) + } + AnyCalendarKind::Hebrew => { + // 1972-12-31 is y=5733 am, m=4, d=26. We must produce year 5732 or lower + if month_code.is_leap_month() { + // 5730 is a leap year + 5730 + } else { + let month = month_code.to_month_integer(); + if (month == 4 && day == 26) || month > 4 { + // 5733 will produce dates after 1972, return 5732 instead + 5732 + } else { + // All months have 29 days + if day <= 29 { + 5733 + // Ḥeshvan/Kislev only have 30 days sometimes + // Fortunately 5732 has 30 days for both + } else if month == 2 || month == 3 { + 5732 + } else { + // Some other month, we don't actually need to check + 5733 + } + } + } + } + + // TODO(Manishearth) Chinese, Dangi, waiting on https://github.com/unicode-org/icu4x/pull/6762 + + // These lunar calendars are iffier: The ones above are mathematically defined, + // the algorithm for these may change. This data may need to be updated on occasion. + AnyCalendarKind::HijriUmmAlQura => { + let month = month_code.to_month_integer(); + if day < 30 { + threshold(month, day, (1392, 11, 25)) + } else { + match month { + 1 => 1392, + 2 => 1390, + 3 => 1391, + 4 => 1392, + 5 => 1391, + 6 => 1392, + 7 => 1389, + 8 => 1392, + 9 => 1392, + 10 => 1390, + 11 => 1391, + 12 => 1390, + _ => 1392, + } + } + } + AnyCalendarKind::HijriSimulatedMecca => { + let month = month_code.to_month_integer(); + if day < 30 { + threshold(month, day, (1392, 11, 24)) + } else { + match month { + 1 => 1390, + 2 => 1391, + 3 => 1392, + 4 => 1391, + 5 => 1390, + 6 => 1392, + 7 => 1392, + 8 => 1392, + 9 => 1390, + 10 => 1392, + 11 => 1390, + 12 => 1391, + _ => 1392, + } + } + } + _ => { + return Err(TemporalError::range() + .with_message("Do not currently support MonthDay with this calendar")) + } + }) + } +} + +// MonthCode constants. +const MONTH_ONE: TinyAsciiStr<4> = tinystr!(4, "M01"); +const MONTH_ONE_LEAP: TinyAsciiStr<4> = tinystr!(4, "M01L"); +const MONTH_TWO: TinyAsciiStr<4> = tinystr!(4, "M02"); +const MONTH_TWO_LEAP: TinyAsciiStr<4> = tinystr!(4, "M02L"); +const MONTH_THREE: TinyAsciiStr<4> = tinystr!(4, "M03"); +const MONTH_THREE_LEAP: TinyAsciiStr<4> = tinystr!(4, "M03L"); +const MONTH_FOUR: TinyAsciiStr<4> = tinystr!(4, "M04"); +const MONTH_FOUR_LEAP: TinyAsciiStr<4> = tinystr!(4, "M04L"); +const MONTH_FIVE: TinyAsciiStr<4> = tinystr!(4, "M05"); +const MONTH_FIVE_LEAP: TinyAsciiStr<4> = tinystr!(4, "M05L"); +const MONTH_SIX: TinyAsciiStr<4> = tinystr!(4, "M06"); +const MONTH_SIX_LEAP: TinyAsciiStr<4> = tinystr!(4, "M06L"); +const MONTH_SEVEN: TinyAsciiStr<4> = tinystr!(4, "M07"); +const MONTH_SEVEN_LEAP: TinyAsciiStr<4> = tinystr!(4, "M07L"); +const MONTH_EIGHT: TinyAsciiStr<4> = tinystr!(4, "M08"); +const MONTH_EIGHT_LEAP: TinyAsciiStr<4> = tinystr!(4, "M08L"); +const MONTH_NINE: TinyAsciiStr<4> = tinystr!(4, "M09"); +const MONTH_NINE_LEAP: TinyAsciiStr<4> = tinystr!(4, "M09L"); +const MONTH_TEN: TinyAsciiStr<4> = tinystr!(4, "M10"); +const MONTH_TEN_LEAP: TinyAsciiStr<4> = tinystr!(4, "M10L"); +const MONTH_ELEVEN: TinyAsciiStr<4> = tinystr!(4, "M11"); +const MONTH_ELEVEN_LEAP: TinyAsciiStr<4> = tinystr!(4, "M11L"); +const MONTH_TWELVE: TinyAsciiStr<4> = tinystr!(4, "M12"); +const MONTH_TWELVE_LEAP: TinyAsciiStr<4> = tinystr!(4, "M12L"); +const MONTH_THIRTEEN: TinyAsciiStr<4> = tinystr!(4, "M13"); + +// TODO: Handle instances where month values may be outside of valid +// bounds. In other words, it is totally possible for a value to be +// passed in that is { month: 300 } with overflow::constrain. +/// A MonthCode identifier +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct MonthCode(pub(crate) TinyAsciiStr<4>); + +impl MonthCode { + pub(crate) fn validate(&self, calendar: &Calendar) -> TemporalResult<()> { + const COMMON_MONTH_CODES: [TinyAsciiStr<4>; 12] = [ + MONTH_ONE, + MONTH_TWO, + MONTH_THREE, + MONTH_FOUR, + MONTH_FIVE, + MONTH_SIX, + MONTH_SEVEN, + MONTH_EIGHT, + MONTH_NINE, + MONTH_TEN, + MONTH_ELEVEN, + MONTH_TWELVE, + ]; + + const LUNAR_LEAP_MONTHS: [TinyAsciiStr<4>; 12] = [ + MONTH_ONE_LEAP, + MONTH_TWO_LEAP, + MONTH_THREE_LEAP, + MONTH_FOUR_LEAP, + MONTH_FIVE_LEAP, + MONTH_SIX_LEAP, + MONTH_SEVEN_LEAP, + MONTH_EIGHT_LEAP, + MONTH_NINE_LEAP, + MONTH_TEN_LEAP, + MONTH_ELEVEN_LEAP, + MONTH_TWELVE_LEAP, + ]; + + if COMMON_MONTH_CODES.contains(&self.0) { + return Ok(()); + } + + match calendar.identifier() { + "chinese" | "dangi" if LUNAR_LEAP_MONTHS.contains(&self.0) => Ok(()), + "coptic" | "ethiopic" | "ethiopicaa" if MONTH_THIRTEEN == self.0 => Ok(()), + "hebrew" if MONTH_FIVE_LEAP == self.0 => Ok(()), + _ => Err(TemporalError::range() + .with_message("MonthCode was not valid for the current calendar.")), + } + } + + pub(crate) fn try_from_fields( + calendar: &Calendar, + fields: &CalendarFields, + ) -> TemporalResult { + match fields { + CalendarFields { + month: Some(month), + month_code: None, + .. + } => { + // TODO(manishearth) this is incorrect, + // see https://github.com/unicode-org/icu4x/issues/6790 + let month_code = month_to_month_code(*month)?; + month_code.validate(calendar)?; + Ok(month_code) + } + CalendarFields { + month_code: Some(month_code), + month: None, + .. + } => { + month_code.validate(calendar)?; + Ok(*month_code) + } + CalendarFields { + month: Some(month), + month_code: Some(month_code), + .. + } => { + are_month_and_month_code_resolvable(*month, month_code)?; + month_code.validate(calendar)?; + Ok(*month_code) + } + _ => Err(TemporalError::r#type() + .with_message("Month or monthCode is required to determine date.")), + } + } + + /// Returns the `MonthCode` as an integer + pub fn to_month_integer(&self) -> u8 { + // Sometimes icu_calendar returns "und" + // when the month is calculated to be out of range (usually for + // out-of-astronomic range Islamic and Chinese calendars) + // + // Normalize to something sensible, since ascii_four_to_integer + // will assert for non-digits. + if self.0 == tinystr!(4, "und") { + return 13; + } + ascii_four_to_integer(self.0) + } + + /// Returns whether the `MonthCode` is a leap month. + pub fn is_leap_month(&self) -> bool { + let bytes = self.0.all_bytes(); + bytes[3] == b'L' + } + + pub fn as_str(&self) -> &str { + self.0.as_str() + } + + pub fn as_tinystr(&self) -> TinyAsciiStr<4> { + self.0 + } + + pub fn try_from_utf8(src: &[u8]) -> TemporalResult { + if !(3..=4).contains(&src.len()) { + return Err( + TemporalError::range().with_message("Month codes must have 3 or 4 characters.") + ); + } + + let inner = TinyAsciiStr::<4>::try_from_utf8(src).map_err(|_e| TemporalError::range())?; + + let bytes = inner.all_bytes(); + if bytes[0] != b'M' { + return Err( + TemporalError::range().with_message("First month code character must be 'M'.") + ); + } + if !bytes[1].is_ascii_digit() || !bytes[2].is_ascii_digit() { + return Err(TemporalError::range().with_message("Invalid month code digit.")); + } + if src.len() == 4 && bytes[3] != b'L' { + return Err(TemporalError::range().with_message("Leap month code must end with 'L'.")); + } + + Ok(Self(inner)) + } +} + +impl core::str::FromStr for MonthCode { + type Err = TemporalError; + fn from_str(s: &str) -> Result { + Self::try_from_utf8(s.as_bytes()) + } +} + +// NOTE: This is a greedy function, should handle differently for all calendars. +#[inline] +pub(crate) fn month_to_month_code(month: u8) -> TemporalResult { + if !(1..=13).contains(&month) { + return Err(TemporalError::range().with_message("Month not in a valid range.")); + } + let first = month / 10; + let second = month % 10; + let tinystr = TinyAsciiStr::<4>::try_from_raw([b'M', first + 48, second + 48, b'\0']) + .map_err(|_| TemporalError::range().with_message("Invalid month code"))?; + Ok(MonthCode(tinystr)) +} + +#[inline] +fn are_month_and_month_code_resolvable(_month: u8, _mc: &MonthCode) -> TemporalResult<()> { + // TODO(Manishearth) month is an ordinal month, this check needs year/calendar info + // https://github.com/unicode-org/icu4x/issues/6790 + Ok(()) +} + +// Potentially greedy. Need to verify for all calendars that +// the month code integer aligns with the month integer, which +// may require calendar info +#[inline] +fn ascii_four_to_integer(mc: TinyAsciiStr<4>) -> u8 { + let bytes = mc.all_bytes(); + // Invariant: second and third character (index 1 and 2) are ascii digits. + debug_assert!(bytes[1].is_ascii_digit()); + debug_assert!(bytes[2].is_ascii_digit()); + let first = ascii_digit_to_int(bytes[1]) * 10; + first + ascii_digit_to_int(bytes[2]) +} + +#[inline] +const fn ascii_digit_to_int(ascii_digit: u8) -> u8 { + ascii_digit - 48 +} + +fn resolve_iso_month( + calendar: &Calendar, + fields: &CalendarFields, + overflow: Overflow, +) -> TemporalResult { + let month_code = match (fields.month_code, fields.month) { + (None, None) => { + return Err(TemporalError::r#type().with_message("Month or monthCode must be provided.")) + } + (None, Some(month)) => { + if overflow == Overflow::Constrain { + return month_to_month_code(month.clamp(1, 12)); + } + if !(1..=12).contains(&month) { + return Err( + TemporalError::range().with_message("month value is not in a valid range.") + ); + } + month_to_month_code(month)? + } + (Some(month_code), None) => month_code, + (Some(month_code), Some(month)) => { + if month != month_code.to_month_integer() { + return Err(TemporalError::range() + .with_message("month and monthCode could not be resolved.")); + } + month_code + } + }; + month_code.validate(calendar)?; + Ok(month_code) +} + +#[cfg(test)] +mod tests { + use core::str::FromStr; + + use tinystr::{tinystr, TinyAsciiStr}; + + use crate::{ + builtins::{ + calendar::{types::ResolutionType, CalendarFields}, + core::{calendar::Calendar, PartialDate, PlainDate}, + }, + options::Overflow, + }; + + use super::{month_to_month_code, MonthCode, ResolvedCalendarFields}; + + #[test] + fn valid_month_code() { + let month_code = MonthCode::from_str("M01").unwrap(); + assert!(!month_code.is_leap_month()); + assert_eq!(month_code.to_month_integer(), 1); + + let month_code = MonthCode::from_str("M12").unwrap(); + assert!(!month_code.is_leap_month()); + assert_eq!(month_code.to_month_integer(), 12); + + let month_code = MonthCode::from_str("M13L").unwrap(); + assert!(month_code.is_leap_month()); + assert_eq!(month_code.to_month_integer(), 13); + } + + #[test] + fn invalid_month_code() { + let _ = MonthCode::from_str("01").unwrap_err(); + let _ = MonthCode::from_str("N01").unwrap_err(); + let _ = MonthCode::from_str("M01R").unwrap_err(); + let _ = MonthCode::from_str("M1").unwrap_err(); + let _ = MonthCode::from_str("M1L").unwrap_err(); + } + + #[test] + fn month_to_mc() { + let mc = month_to_month_code(1).unwrap(); + assert_eq!(mc.as_str(), "M01"); + + let mc = month_to_month_code(13).unwrap(); + assert_eq!(mc.as_str(), "M13"); + + let _ = month_to_month_code(0).unwrap_err(); + let _ = month_to_month_code(14).unwrap_err(); + } + + #[test] + fn day_overflow_test() { + let bad_fields = CalendarFields { + year: Some(2019), + month: Some(1), + day: Some(32), + ..Default::default() + }; + + let cal = Calendar::default(); + + let err = cal.date_from_fields(bad_fields.clone(), Overflow::Reject); + assert!(err.is_err()); + let result = cal.date_from_fields(bad_fields, Overflow::Constrain); + assert!(result.is_ok()); + } + + #[test] + fn self_consistent_era_year() { + use crate::builtins::core::calendar::era::ALL_ALLOWED_ERAS; + use icu_calendar::AnyCalendarKind; + + for (cal, eras) in ALL_ALLOWED_ERAS { + for era in *eras { + let expect_str = alloc::format!("Trying {cal:?} with era {}", era.name); + let mut calendar_fields = CalendarFields::new(); + + // We want to pick some valid date. year=1 month=1, day=1 is valid for basically + // all calendars except for Japanese, which has mid-year eras. For Japanese we pick December 31 instead + if *cal == AnyCalendarKind::Japanese { + calendar_fields.month = Some(12); + calendar_fields.day = Some(31); + } else { + calendar_fields.month = Some(1); + calendar_fields.day = Some(1); + } + calendar_fields.era = Some(TinyAsciiStr::from_str(&era.name).unwrap()); + calendar_fields.era_year = Some(1); + let partial = PartialDate { + calendar_fields, + calendar: Calendar::new(*cal), + }; + + let plain_date = + PlainDate::from_partial(partial, Some(Overflow::Constrain)).expect(&expect_str); + + assert_eq!( + plain_date.year(), + era.arithmetic_year_for(1), + "Mismatched year/eraYear for {cal:?} and {}", + era.name + ); + + // Get the full partial date. + let full_partial = CalendarFields::default() + .with_fallback_date(&plain_date, *cal, Overflow::Constrain) + .expect(&expect_str); + + let era_year = super::EraYear::try_from_fields( + &Calendar::new(*cal), + &full_partial, + ResolutionType::Date, + ) + .expect(&expect_str); + + assert_eq!( + &*era_year.era.expect("only testing calendars with era").0, + &*era.name, + "Backcalculated era must match" + ); + assert_eq!(era_year.year, 1, "Backcalculated era must match"); + assert_eq!( + era_year.arithmetic_year, + plain_date.year(), + "Backcalculated arithmetic_year must match" + ); + } + } + } + + #[test] + fn unresolved_month_and_month_code() { + let bad_fields = CalendarFields { + year: Some(1976), + month: Some(11), + month_code: Some(MonthCode(tinystr!(4, "M12"))), + day: Some(18), + ..Default::default() + }; + + let err = ResolvedCalendarFields::try_from_fields( + &Calendar::ISO, + &bad_fields, + Overflow::Reject, + ResolutionType::Date, + ); + assert!(err.is_err()); + } + + #[test] + fn missing_partial_fields() { + let bad_fields = CalendarFields { + year: Some(2019), + day: Some(19), + ..Default::default() + }; + + let err = ResolvedCalendarFields::try_from_fields( + &Calendar::ISO, + &bad_fields, + Overflow::Reject, + ResolutionType::Date, + ); + assert!(err.is_err()); + + let bad_fields = CalendarFields::default(); + let err = ResolvedCalendarFields::try_from_fields( + &Calendar::ISO, + &bad_fields, + Overflow::Reject, + ResolutionType::Date, + ); + assert!(err.is_err()); + } +} diff --git a/deps/temporal/src/builtins/core/duration.rs b/deps/temporal/src/builtins/core/duration.rs new file mode 100644 index 00000000000000..fc19e7912cfb6c --- /dev/null +++ b/deps/temporal/src/builtins/core/duration.rs @@ -0,0 +1,1595 @@ +//! This module implements `Duration` along with it's methods and components. + +use crate::{ + builtins::core::{PlainDateTime, PlainTime}, + error::ErrorMessage, + iso::{IsoDateTime, IsoTime}, + options::{ + Overflow, RelativeTo, ResolvedRoundingOptions, RoundingIncrement, RoundingOptions, + ToStringRoundingOptions, Unit, UnitGroup, + }, + parsers::{FormattableDateDuration, FormattableDuration, FormattableTimeDuration, Precision}, + primitive::FiniteF64, + provider::TimeZoneProvider, + temporal_assert, Sign, TemporalError, TemporalResult, NS_PER_DAY, +}; +use alloc::string::String; +use core::{cmp::Ordering, str::FromStr}; +use ixdtf::{ + encoding::Utf8, parsers::IsoDurationParser, records::Fraction, records::TimeDurationRecord, +}; +use normalized::InternalDurationRecord; +use num_traits::Euclid; + +use self::normalized::TimeDuration; + +mod date; +pub(crate) mod normalized; + +#[cfg(test)] +mod tests; + +#[doc(inline)] +pub use date::DateDuration; + +/// A `PartialDuration` is a Duration that may have fields not set. +#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] +pub struct PartialDuration { + /// A potentially existent `years` field. + pub years: Option, + /// A potentially existent `months` field. + pub months: Option, + /// A potentially existent `weeks` field. + pub weeks: Option, + /// A potentially existent `days` field. + pub days: Option, + /// A potentially existent `hours` field. + pub hours: Option, + /// A potentially existent `minutes` field. + pub minutes: Option, + /// A potentially existent `seconds` field. + pub seconds: Option, + /// A potentially existent `milliseconds` field. + pub milliseconds: Option, + /// A potentially existent `microseconds` field. + pub microseconds: Option, + /// A potentially existent `nanoseconds` field. + pub nanoseconds: Option, +} + +impl Default for PartialDuration { + fn default() -> Self { + Self::empty() + } +} + +impl PartialDuration { + pub const fn empty() -> Self { + Self { + years: None, + months: None, + weeks: None, + days: None, + hours: None, + minutes: None, + seconds: None, + milliseconds: None, + microseconds: None, + nanoseconds: None, + } + } + + pub const fn with_years(mut self, years: i64) -> Self { + self.years = Some(years); + self + } + + pub const fn with_months(mut self, months: i64) -> Self { + self.months = Some(months); + self + } + + pub const fn with_weeks(mut self, weeks: i64) -> Self { + self.weeks = Some(weeks); + self + } + + pub const fn with_days(mut self, days: i64) -> Self { + self.days = Some(days); + self + } + + pub const fn with_hours(mut self, hours: i64) -> Self { + self.hours = Some(hours); + self + } + + pub const fn with_minutes(mut self, minutes: i64) -> Self { + self.minutes = Some(minutes); + self + } + + pub const fn with_seconds(mut self, seconds: i64) -> Self { + self.seconds = Some(seconds); + self + } + + pub const fn with_milliseconds(mut self, milliseconds: i64) -> Self { + self.milliseconds = Some(milliseconds); + self + } + + pub const fn with_microseconds(mut self, microseconds: i128) -> Self { + self.microseconds = Some(microseconds); + self + } + + pub const fn with_nanoseconds(mut self, nanoseconds: i128) -> Self { + self.nanoseconds = Some(nanoseconds); + self + } +} + +impl PartialDuration { + /// Returns whether the `PartialDuration` is empty. + #[inline] + #[must_use] + pub fn is_empty(&self) -> bool { + self == &Self::default() + } +} + +/// The native Rust implementation of `Temporal.Duration`. +/// +/// Represents a span of time such as "2 hours and 30 minutes" or "3 years, 2 months". +/// Unlike `Instant` which represents a specific moment in time, Duration represents +/// the amount of time between two moments. +/// +/// A Duration consists of two categories of components: +/// - Date components: years, months, weeks, and days +/// - Time components: hours, minutes, seconds, and subsecond units (nanosecond precision) +/// +/// Note that date arithmetic can be complex. For example, adding "1 month" to January 31st +/// could result in February 28th (non-leap year), February 29th (leap year), or March 3rd +/// (if you overflow February), depending on the calendar system and overflow handling. +/// +/// ## Examples +/// +/// ### Creating durations +/// +/// ```rust +/// use temporal_rs::Duration; +/// +/// // Create a duration with specific components +/// let vacation_duration = Duration::new( +/// 0, 0, 2, 3, // 2 weeks and 3 days +/// 0, 0, 0, // no time components +/// 0, 0, 0 // no subsecond components +/// ).unwrap(); +/// +/// assert_eq!(vacation_duration.weeks(), 2); +/// assert_eq!(vacation_duration.days(), 3); +/// ``` +/// +/// ### Parsing ISO 8601 duration strings +/// +/// ```rust +/// use temporal_rs::Duration; +/// use core::str::FromStr; +/// +/// // Complex duration with multiple components +/// let complex = Duration::from_str("P1Y2M3DT4H5M6.789S").unwrap(); +/// assert_eq!(complex.years(), 1); +/// assert_eq!(complex.months(), 2); +/// assert_eq!(complex.days(), 3); +/// assert_eq!(complex.hours(), 4); +/// assert_eq!(complex.minutes(), 5); +/// assert_eq!(complex.seconds(), 6); +/// +/// // Time-only duration +/// let movie_length = Duration::from_str("PT2H30M").unwrap(); +/// assert_eq!(movie_length.hours(), 2); +/// assert_eq!(movie_length.minutes(), 30); +/// +/// // Negative durations +/// let negative = Duration::from_str("-P1D").unwrap(); +/// assert_eq!(negative.days(), -1); +/// ``` +/// +/// ### Duration arithmetic +/// +/// ```rust +/// use temporal_rs::Duration; +/// use core::str::FromStr; +/// +/// let commute_time = Duration::from_str("PT45M").unwrap(); +/// let lunch_break = Duration::from_str("PT1H").unwrap(); +/// +/// // Add durations together +/// let total_time = commute_time.add(&lunch_break).unwrap(); +/// assert_eq!(total_time.hours(), 1); // Results in 1 hour 45 minutes +/// assert_eq!(total_time.minutes(), 45); +/// +/// // Subtract duration components +/// let shortened = lunch_break.subtract(&Duration::from_str("PT15M").unwrap()).unwrap(); +/// assert_eq!(shortened.minutes(), 45); +/// ``` +/// +/// ### Date arithmetic with durations +/// +/// ```rust +/// use temporal_rs::{PlainDate, Duration, options::Overflow}; +/// use core::str::FromStr; +/// +/// // January 31st in different years +/// let jan_31_2023 = PlainDate::try_new_iso(2023, 1, 31).unwrap(); +/// let jan_31_2024 = PlainDate::try_new_iso(2024, 1, 31).unwrap(); // leap year +/// +/// let one_month = Duration::from_str("P1M").unwrap(); +/// +/// // Adding 1 month to Jan 31st gives different results: +/// let feb_2023 = jan_31_2023.add(&one_month, Some(Overflow::Constrain)).unwrap(); +/// let feb_2024 = jan_31_2024.add(&one_month, Some(Overflow::Constrain)).unwrap(); +/// +/// // 2023: Jan 31 + 1 month = Feb 28 (no Feb 31st exists) +/// assert_eq!(feb_2023.day(), 28); +/// // 2024: Jan 31 + 1 month = Feb 29 (leap year) +/// assert_eq!(feb_2024.day(), 29); +/// ``` +/// +/// ### Working with partial durations +/// +/// ```rust +/// use temporal_rs::{Duration, partial::PartialDuration}; +/// +/// let partial = PartialDuration { +/// hours: Some(3), +/// minutes: Some(45), +/// ..Default::default() +/// }; +/// +/// let duration = Duration::from_partial_duration(partial).unwrap(); +/// assert_eq!(duration.hours(), 3); +/// assert_eq!(duration.minutes(), 45); +/// assert_eq!(duration.days(), 0); // other fields default to 0 +/// ``` +/// +/// ### Duration properties +/// +/// ```rust +/// use temporal_rs::Duration; +/// use core::str::FromStr; +/// +/// let duration = Duration::from_str("P1Y2M3D").unwrap(); +/// +/// // Check if duration is zero +/// assert!(!duration.is_zero()); +/// +/// // Get the sign of the duration +/// let sign = duration.sign(); +/// // Note: This particular duration has mixed signs which affects the overall sign +/// +/// // Get absolute value +/// let abs_duration = duration.abs(); +/// assert_eq!(abs_duration.years(), 1); +/// assert_eq!(abs_duration.months(), 2); +/// assert_eq!(abs_duration.days(), 3); +/// +/// // Negate duration +/// let negated = duration.negated(); +/// assert_eq!(negated.years(), -1); +/// assert_eq!(negated.months(), -2); +/// assert_eq!(negated.days(), -3); +/// ``` +/// +/// ## Reference +/// +/// For more information, see the [MDN documentation][mdn-duration]. +/// +/// [mdn-duration]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration +#[non_exhaustive] +#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] +pub struct Duration { + pub(crate) sign: Sign, + pub(crate) years: u32, + pub(crate) months: u32, + pub(crate) weeks: u32, + pub(crate) days: u64, + pub(crate) hours: u64, + pub(crate) minutes: u64, + pub(crate) seconds: u64, + pub(crate) milliseconds: u64, + pub(crate) microseconds: u128, + pub(crate) nanoseconds: u128, +} + +impl Default for Duration { + fn default() -> Self { + Self { + sign: Sign::Zero, + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 0, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, + } + } +} + +impl core::fmt::Display for Duration { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let string = self.as_temporal_string(ToStringRoundingOptions::default()); + + debug_assert!( + string.is_ok(), + "Duration must return a valid string with default options." + ); + f.write_str(&string.map_err(|_| Default::default())?) + } +} + +impl TryFrom for Duration { + type Error = TemporalError; + fn try_from(partial: PartialDuration) -> Result { + Duration::from_partial_duration(partial) + } +} + +// NOTE(nekevss): Structure of the below is going to be a little convoluted, +// but intended to section everything based on the below +// +// Notation - [section](sub-section(s)). +// +// Sections: +// - Creation (private/public) +// - Getters/Setters +// - Methods (private/public/feature) +// + +#[cfg(test)] +impl Duration { + pub(crate) fn from_hours(value: i64) -> Self { + Self { + sign: Sign::from(value.signum() as i8), + hours: value.saturating_abs() as u64, + ..Default::default() + } + } +} + +// ==== Private Creation methods ==== + +impl Duration { + /// Creates a new `Duration` from a `DateDuration` and `TimeDuration`. + #[allow(clippy::too_many_arguments)] + pub(crate) const fn new_unchecked( + sign: Sign, + years: u32, + months: u32, + weeks: u32, + days: u64, + hours: u64, + minutes: u64, + seconds: u64, + milliseconds: u64, + microseconds: u128, + nanoseconds: u128, + ) -> Self { + Self { + sign, + years, + months, + weeks, + days, + hours, + minutes, + seconds, + milliseconds, + microseconds, + nanoseconds, + } + } + + #[inline] + pub(crate) fn from_internal( + duration_record: InternalDurationRecord, + largest_unit: Unit, + ) -> TemporalResult { + // 1. Let days, hours, minutes, seconds, milliseconds, and microseconds be 0. + let mut days = 0; + let mut hours = 0; + let mut minutes = 0; + let mut seconds = 0; + let mut milliseconds = 0; + let mut microseconds = 0; + + // 2. Let sign be TimeDurationSign(internalDuration.[[Time]]). + let sign = duration_record + .normalized_time_duration() + .sign() + .as_sign_multiplier(); + + // 3. Let nanoseconds be abs(internalDuration.[[Time]]). + let mut nanoseconds = duration_record.normalized_time_duration().0.abs(); + match largest_unit { + // 4. If largestUnit is "year", "month", "week", or "day", then + Unit::Year | Unit::Month | Unit::Week | Unit::Day => { + // a. Set microseconds to floor(nanoseconds / 1000). + // b. Set nanoseconds to nanoseconds modulo 1000. + (microseconds, nanoseconds) = nanoseconds.div_rem_euclid(&1_000); + + // c. Set milliseconds to floor(microseconds / 1000). + // d. Set microseconds to microseconds modulo 1000. + (milliseconds, microseconds) = microseconds.div_rem_euclid(&1_000); + + // e. Set seconds to floor(milliseconds / 1000). + // f. Set milliseconds to milliseconds modulo 1000. + (seconds, milliseconds) = milliseconds.div_rem_euclid(&1_000); + + // g. Set minutes to floor(seconds / 60). + // h. Set seconds to seconds modulo 60. + (minutes, seconds) = seconds.div_rem_euclid(&60); + + // i. Set hours to floor(minutes / 60). + // j. Set minutes to minutes modulo 60. + (hours, minutes) = minutes.div_rem_euclid(&60); + + // k. Set days to floor(hours / 24). + // l. Set hours to hours modulo 24. + (days, hours) = hours.div_rem_euclid(&24); + } + // 5. Else if largestUnit is "hour", then + Unit::Hour => { + // a. Set microseconds to floor(nanoseconds / 1000). + // b. Set nanoseconds to nanoseconds modulo 1000. + (microseconds, nanoseconds) = nanoseconds.div_rem_euclid(&1_000); + + // c. Set milliseconds to floor(microseconds / 1000). + // d. Set microseconds to microseconds modulo 1000. + (milliseconds, microseconds) = microseconds.div_rem_euclid(&1_000); + + // e. Set seconds to floor(milliseconds / 1000). + // f. Set milliseconds to milliseconds modulo 1000. + (seconds, milliseconds) = milliseconds.div_rem_euclid(&1_000); + + // g. Set minutes to floor(seconds / 60). + // h. Set seconds to seconds modulo 60. + (minutes, seconds) = seconds.div_rem_euclid(&60); + + // i. Set hours to floor(minutes / 60). + // j. Set minutes to minutes modulo 60. + (hours, minutes) = minutes.div_rem_euclid(&60); + } + // 6. Else if largestUnit is "minute", then + Unit::Minute => { + // a. Set microseconds to floor(nanoseconds / 1000). + // b. Set nanoseconds to nanoseconds modulo 1000. + (microseconds, nanoseconds) = nanoseconds.div_rem_euclid(&1_000); + + // c. Set milliseconds to floor(microseconds / 1000). + // d. Set microseconds to microseconds modulo 1000. + (milliseconds, microseconds) = microseconds.div_rem_euclid(&1_000); + + // e. Set seconds to floor(milliseconds / 1000). + // f. Set milliseconds to milliseconds modulo 1000. + (seconds, milliseconds) = milliseconds.div_rem_euclid(&1_000); + + // g. Set minutes to floor(seconds / 60). + // h. Set seconds to seconds modulo 60. + (minutes, seconds) = seconds.div_rem_euclid(&60); + } + // 7. Else if largestUnit is "second", then + Unit::Second => { + // a. Set microseconds to floor(nanoseconds / 1000). + // b. Set nanoseconds to nanoseconds modulo 1000. + (microseconds, nanoseconds) = nanoseconds.div_rem_euclid(&1_000); + + // c. Set milliseconds to floor(microseconds / 1000). + // d. Set microseconds to microseconds modulo 1000. + (milliseconds, microseconds) = microseconds.div_rem_euclid(&1_000); + + // e. Set seconds to floor(milliseconds / 1000). + // f. Set milliseconds to milliseconds modulo 1000. + (seconds, milliseconds) = milliseconds.div_rem_euclid(&1_000); + } + // 8. Else if largestUnit is "millisecond", then + Unit::Millisecond => { + // a. Set microseconds to floor(nanoseconds / 1000). + // b. Set nanoseconds to nanoseconds modulo 1000. + (microseconds, nanoseconds) = nanoseconds.div_rem_euclid(&1_000); + + // c. Set milliseconds to floor(microseconds / 1000). + // d. Set microseconds to microseconds modulo 1000. + (milliseconds, microseconds) = microseconds.div_rem_euclid(&1_000); + } + // 9. Else if largestUnit is "microsecond", then + Unit::Microsecond => { + // a. Set microseconds to floor(nanoseconds / 1000). + // b. Set nanoseconds to nanoseconds modulo 1000. + (microseconds, nanoseconds) = nanoseconds.div_rem_euclid(&1_000); + } + // 10. Else, + // a. Assert: largestUnit is "nanosecond". + _ => temporal_assert!(largest_unit == Unit::Nanosecond), + } + // 11. NOTE: When largestUnit is millisecond, microsecond, or nanosecond, milliseconds, microseconds, or + // nanoseconds may be an unsafe integer. In this case, care must be taken when implementing the calculation using + // floating point arithmetic. It can be implemented in C++ using std::fma(). String manipulation will also give an + // exact result, since the multiplication is by a power of 10. + // 12. Return ? CreateTemporalDuration(internalDuration.[[Date]].[[Years]], internalDuration.[[Date]].[[Months]], + // internalDuration.[[Date]].[[Weeks]], internalDuration.[[Date]].[[Days]] + days × sign, hours × sign, minutes × sign, + // seconds × sign, milliseconds × sign, microseconds × sign, nanoseconds × sign). + Duration::new( + duration_record.date().years, + duration_record.date().months, + duration_record.date().weeks, + duration_record.date().days + days as i64 * sign as i64, + hours as i64 * sign as i64, + minutes as i64 * sign as i64, + seconds as i64 * sign as i64, + milliseconds as i64 * sign as i64, + microseconds * sign as i128, + nanoseconds * sign as i128, + ) + } + + /// Returns this `Duration` as a `TimeDuration`. + #[inline] + pub(crate) fn to_normalized(self) -> TimeDuration { + TimeDuration::from_duration(&self) + } + + /// Returns the a `Vec` of the fields values. + #[inline] + #[must_use] + pub(crate) fn fields_signum(&self) -> [i64; 10] { + [ + self.years().signum(), + self.months().signum(), + self.weeks().signum(), + self.days().signum(), + self.hours().signum(), + self.minutes().signum(), + self.seconds().signum(), + self.milliseconds().signum(), + self.microseconds().signum() as i64, + self.nanoseconds().signum() as i64, + ] + } + + /// Returns the `Unit` corresponding to the largest non-zero field. + #[inline] + pub(crate) fn default_largest_unit(&self) -> Unit { + self.fields_signum() + .iter() + .enumerate() + .find(|x| x.1 != &0) + .map(|x| Unit::from(10 - x.0)) + .unwrap_or(Unit::Nanosecond) + } + + // 7.5.5 ToInternalDurationRecord ( duration ) + pub(crate) fn to_internal_duration_record(self) -> InternalDurationRecord { + // 1. Let dateDuration be ! CreateDateDurationRecord(duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]]). + let date_duration = + DateDuration::new_unchecked(self.years(), self.months(), self.weeks(), self.days()); + // 2. Let timeDuration be TimeDurationFromComponents(duration.[[Hours]], duration.[[Minutes]], duration.[[Seconds]], duration.[[Milliseconds]], duration.[[Microseconds]], duration.[[Nanoseconds]]). + let time_duration = TimeDuration::from_components( + self.hours(), + self.minutes(), + self.seconds(), + self.milliseconds(), + self.microseconds(), + self.nanoseconds(), + ); + // 3. Return CombineDateAndTimeDuration(dateDuration, timeDuration). + InternalDurationRecord::combine(date_duration, time_duration) + } + + /// Equivalent of [`7.5.7 ToDateDurationRecordWithoutTime ( duration )`][spec] + /// + /// [spec]: + /// + // spec(2025-06-23): https://github.com/tc39/proposal-temporal/tree/ed49b0b482981119c9b5e28b0686d877d4a9bae0 + #[allow(clippy::wrong_self_convention)] + pub(crate) fn to_date_duration_record_without_time(&self) -> TemporalResult { + // 1. Let internalDuration be ToInternalDurationRecordWith24HourDays(duration). + let internal_duration = InternalDurationRecord::from_duration_with_24_hour_days(self)?; + + // 2. Let days be truncate(internalDuration.[[Time]] / nsPerDay). + // 3. Return ! CreateDateDurationRecord(internalDuration.[[Date]].[[Years]], internalDuration.[[Date]].[[Months]], internalDuration.[[Date]].[[Weeks]], days). + internal_duration.to_date_duration_record_without_time() + } +} + +// ==== Public Duration API ==== + +impl Duration { + /// Creates a new validated `Duration`. + #[allow(clippy::too_many_arguments)] + pub fn new( + years: i64, + months: i64, + weeks: i64, + days: i64, + hours: i64, + minutes: i64, + seconds: i64, + milliseconds: i64, + microseconds: i128, + nanoseconds: i128, + ) -> TemporalResult { + if !is_valid_duration( + years, + months, + weeks, + days, + hours, + minutes, + seconds, + milliseconds, + microseconds, + nanoseconds, + ) { + return Err(TemporalError::range().with_message("Duration was not valid.")); + } + let sign = duration_sign(&[ + years, + months, + weeks, + days, + hours, + minutes, + seconds, + milliseconds, + microseconds.signum() as i64, + nanoseconds.signum() as i64, + ]); + Ok(Duration::new_unchecked( + sign, + years.saturating_abs() as u32, + months.saturating_abs() as u32, + weeks.saturating_abs() as u32, + days.unsigned_abs(), + hours.unsigned_abs(), + minutes.unsigned_abs(), + seconds.unsigned_abs(), + milliseconds.unsigned_abs(), + microseconds.unsigned_abs(), + nanoseconds.unsigned_abs(), + )) + } + + /// Creates a `Duration` from a provided `PartialDuration`. + /// + /// ## Examples + /// + /// ```rust + /// use temporal_rs::{partial::PartialDuration, Duration}; + /// + /// let duration = Duration::from_partial_duration(PartialDuration { + /// seconds: Some(4), + /// ..Default::default() + /// }).unwrap(); + /// + /// assert_eq!(duration.seconds(), 4); + /// assert_eq!(duration.to_string(), "PT4S"); + /// ``` + pub fn from_partial_duration(partial: PartialDuration) -> TemporalResult { + if partial == PartialDuration::default() { + return Err(TemporalError::r#type() + .with_message("PartialDuration cannot have all empty fields.")); + } + Self::new( + partial.years.unwrap_or_default(), + partial.months.unwrap_or_default(), + partial.weeks.unwrap_or_default(), + partial.days.unwrap_or_default(), + partial.hours.unwrap_or_default(), + partial.minutes.unwrap_or_default(), + partial.seconds.unwrap_or_default(), + partial.milliseconds.unwrap_or_default(), + partial.microseconds.unwrap_or_default(), + partial.nanoseconds.unwrap_or_default(), + ) + } + + // Converts a UTF-8 encoded string into a `Duration`. + pub fn from_utf8(s: &[u8]) -> TemporalResult { + let parse_record = IsoDurationParser::::from_utf8(s).parse()?; + + fn fraction_to_unadjusted_ns(fraction: Option) -> Result { + if let Some(fraction) = fraction { + fraction.to_nanoseconds().ok_or( + TemporalError::range() + .with_enum(ErrorMessage::FractionalTimeMoreThanNineDigits), + ) + } else { + Ok(0) + } + } + + let (hours, minutes, seconds, millis, micros, nanos) = match parse_record.time { + Some(TimeDurationRecord::Hours { hours, fraction }) => { + let unadjusted_fraction = fraction_to_unadjusted_ns(fraction)? as u64; + let fractional_hours_ns = unadjusted_fraction * 3600; + let minutes = fractional_hours_ns.div_euclid(60 * 1_000_000_000); + let fractional_minutes_ns = fractional_hours_ns.rem_euclid(60 * 1_000_000_000); + + let seconds = fractional_minutes_ns.div_euclid(1_000_000_000); + let fractional_seconds = fractional_minutes_ns.rem_euclid(1_000_000_000); + + let milliseconds = fractional_seconds.div_euclid(1_000_000); + let rem = fractional_seconds.rem_euclid(1_000_000); + + let microseconds = rem.div_euclid(1_000); + let nanoseconds = rem.rem_euclid(1_000); + + ( + hours, + minutes, + seconds, + milliseconds, + microseconds, + nanoseconds, + ) + } + // Minutes variant is defined as { hours: u32, minutes: u32, fraction: u64 } + Some(TimeDurationRecord::Minutes { + hours, + minutes, + fraction, + }) => { + let unadjusted_fraction = fraction_to_unadjusted_ns(fraction)? as u64; + let fractional_minutes_ns = unadjusted_fraction * 60; + let seconds = fractional_minutes_ns.div_euclid(1_000_000_000); + let fractional_seconds = fractional_minutes_ns.rem_euclid(1_000_000_000); + + let milliseconds = fractional_seconds.div_euclid(1_000_000); + let rem = fractional_seconds.rem_euclid(1_000_000); + + let microseconds = rem.div_euclid(1_000); + let nanoseconds = rem.rem_euclid(1_000); + + ( + hours, + minutes, + seconds, + milliseconds, + microseconds, + nanoseconds, + ) + } + // Seconds variant is defined as { hours: u32, minutes: u32, seconds: u32, fraction: u32 } + Some(TimeDurationRecord::Seconds { + hours, + minutes, + seconds, + fraction, + }) => { + let ns = fraction_to_unadjusted_ns(fraction)?; + let milliseconds = ns.div_euclid(1_000_000); + let rem = ns.rem_euclid(1_000_000); + + let microseconds = rem.div_euclid(1_000); + let nanoseconds = rem.rem_euclid(1_000); + + ( + hours, + minutes, + seconds, + milliseconds as u64, + microseconds as u64, + nanoseconds as u64, + ) + } + None => (0, 0, 0, 0, 0, 0), + }; + + let (years, months, weeks, days) = if let Some(date) = parse_record.date { + (date.years, date.months, date.weeks, date.days) + } else { + (0, 0, 0, 0) + }; + + let sign = parse_record.sign as i64; + + Self::new( + years as i64 * sign, + months as i64 * sign, + weeks as i64 * sign, + days as i64 * sign, + hours as i64 * sign, + minutes as i64 * sign, + seconds as i64 * sign, + millis as i64 * sign, + micros as i128 * sign as i128, + nanos as i128 * sign as i128, + ) + } + + /// Return if the Durations values are within their valid ranges. + #[inline] + #[must_use] + pub fn is_time_within_range(&self) -> bool { + self.hours < 24 + && self.minutes < 60 + && self.seconds < 60 + && self.milliseconds < 1000 + && self.microseconds < 1000 + && self.nanoseconds < 1000 + } + + #[inline] + pub fn compare_with_provider( + &self, + other: &Duration, + relative_to: Option, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + if self == other { + return Ok(Ordering::Equal); + } + // 8. Let largestUnit1 be DefaultTemporalLargestUnit(one). + // 9. Let largestUnit2 be DefaultTemporalLargestUnit(two). + let largest_unit_1 = self.default_largest_unit(); + let largest_unit_2 = other.default_largest_unit(); + // 10. Let duration1 be ToInternalDurationRecord(one). + let duration_one = self.to_internal_duration_record(); + // 11. Let duration2 be ToInternalDurationRecord(two). + let duration_two = other.to_internal_duration_record(); + // 12. If zonedRelativeTo is not undefined, and either UnitCategory(largestUnit1) or UnitCategory(largestUnit2) is date, then + if let Some(RelativeTo::ZonedDateTime(zdt)) = relative_to.as_ref() { + if largest_unit_1.is_date_unit() || largest_unit_2.is_date_unit() { + // a. Let timeZone be zonedRelativeTo.[[TimeZone]]. + // b. Let calendar be zonedRelativeTo.[[Calendar]]. + // c. Let after1 be ? AddZonedDateTime(zonedRelativeTo.[[EpochNanoseconds]], timeZone, calendar, duration1, constrain). + // d. Let after2 be ? AddZonedDateTime(zonedRelativeTo.[[EpochNanoseconds]], timeZone, calendar, duration2, constrain). + let after1 = + zdt.add_zoned_date_time(duration_one, Overflow::Constrain, provider)?; + let after2 = + zdt.add_zoned_date_time(duration_two, Overflow::Constrain, provider)?; + // e. If after1 > after2, return 1𝔽. + // f. If after1 < after2, return -1𝔽. + // g. Return +0𝔽. + return Ok(after1.cmp(&after2)); + } + } + // 13. If IsCalendarUnit(largestUnit1) is true or IsCalendarUnit(largestUnit2) is true, then + let (days1, days2) = + if largest_unit_1.is_calendar_unit() || largest_unit_2.is_calendar_unit() { + // a. If plainRelativeTo is undefined, throw a RangeError exception. + // b. Let days1 be ? DateDurationDays(duration1.[[Date]], plainRelativeTo). + // c. Let days2 be ? DateDurationDays(duration2.[[Date]], plainRelativeTo). + let Some(RelativeTo::PlainDate(pdt)) = relative_to.as_ref() else { + return Err(TemporalError::range()); + }; + let days1 = self.date().days(pdt)?; + let days2 = other.date().days(pdt)?; + (days1, days2) + } else { + (self.date().days, other.date().days) + }; + // 15. Let timeDuration1 be ? Add24HourDaysToTimeDuration(duration1.[[Time]], days1). + let time_duration_1 = self.to_normalized().add_days(days1)?; + // 16. Let timeDuration2 be ? Add24HourDaysToTimeDuration(duration2.[[Time]], days2). + let time_duration_2 = other.to_normalized().add_days(days2)?; + // 17. Return 𝔽(CompareTimeDuration(timeDuration1, timeDuration2)). + Ok(time_duration_1.cmp(&time_duration_2)) + } +} + +// ==== Public `Duration` Getters/Setters ==== + +impl Duration { + /// Returns a reference to the inner `DateDuration` + #[inline] + #[must_use] + pub fn date(&self) -> DateDuration { + DateDuration::from(self) + } + + /// Returns the `years` field of duration. + #[inline] + #[must_use] + pub const fn years(&self) -> i64 { + self.years as i64 * self.sign.as_sign_multiplier() as i64 + } + + /// Returns the `months` field of duration. + #[inline] + #[must_use] + pub const fn months(&self) -> i64 { + self.months as i64 * self.sign.as_sign_multiplier() as i64 + } + + /// Returns the `weeks` field of duration. + #[inline] + #[must_use] + pub const fn weeks(&self) -> i64 { + self.weeks as i64 * self.sign.as_sign_multiplier() as i64 + } + + /// Returns the `days` field of duration. + #[inline] + #[must_use] + pub const fn days(&self) -> i64 { + self.days as i64 * self.sign.as_sign_multiplier() as i64 + } + + /// Returns the `hours` field of duration. + #[inline] + #[must_use] + pub const fn hours(&self) -> i64 { + self.hours as i64 * self.sign.as_sign_multiplier() as i64 + } + + /// Returns the `hours` field of duration. + #[inline] + #[must_use] + pub const fn minutes(&self) -> i64 { + self.minutes as i64 * self.sign.as_sign_multiplier() as i64 + } + + /// Returns the `seconds` field of duration. + #[inline] + #[must_use] + pub const fn seconds(&self) -> i64 { + self.seconds as i64 * self.sign.as_sign_multiplier() as i64 + } + + /// Returns the `hours` field of duration. + #[inline] + #[must_use] + pub const fn milliseconds(&self) -> i64 { + self.milliseconds as i64 * self.sign.as_sign_multiplier() as i64 + } + + /// Returns the `microseconds` field of duration. + #[inline] + #[must_use] + pub const fn microseconds(&self) -> i128 { + self.microseconds as i128 * self.sign.as_sign_multiplier() as i128 + } + + /// Returns the `nanoseconds` field of duration. + #[inline] + #[must_use] + pub const fn nanoseconds(&self) -> i128 { + self.nanoseconds as i128 * self.sign.as_sign_multiplier() as i128 + } +} + +// ==== Public Duration methods ==== + +impl Duration { + /// Determines the sign for the current self. + #[inline] + #[must_use] + pub fn sign(&self) -> Sign { + self.sign + } + + /// Returns whether the current `Duration` is zero. + /// + /// Equivalant to `Temporal.Duration.blank()`. + #[inline] + #[must_use] + pub fn is_zero(&self) -> bool { + self.sign() == Sign::Zero + } + + /// Returns a negated `Duration` + #[inline] + #[must_use] + pub fn negated(&self) -> Self { + Self { + sign: self.sign.negate(), + ..*self + } + } + + /// Returns the absolute value of `Duration`. + #[inline] + #[must_use] + pub fn abs(&self) -> Self { + Self { + sign: if self.sign == Sign::Zero { + Sign::Zero + } else { + Sign::Positive + }, + ..*self + } + } + + /// Returns the result of adding a `Duration` to the current `Duration` + #[inline] + pub fn add(&self, other: &Self) -> TemporalResult { + // 1. Set other to ? ToTemporalDuration(other). + // 2. If operation is subtract, set other to CreateNegatedTemporalDuration(other). + // 3. Let largestUnit1 be DefaultTemporalLargestUnit(duration). + let largest_unit_one = self.default_largest_unit(); + // 4. Let largestUnit2 be DefaultTemporalLargestUnit(other). + let largest_unit_two = other.default_largest_unit(); + // 5. Let largestUnit be LargerOfTwoTemporalUnits(largestUnit1, largestUnit2). + let largest_unit = largest_unit_one.max(largest_unit_two); + // 6. If IsCalendarUnit(largestUnit) is true, throw a RangeError exception. + if largest_unit.is_calendar_unit() { + return Err(TemporalError::range().with_message( + "Largest unit cannot be a calendar unit when adding two durations.", + )); + } + + // 7. Let d1 be ToInternalDurationRecordWith24HourDays(duration). + let d1 = InternalDurationRecord::from_duration_with_24_hour_days(self)?; + // 8. Let d2 be ToInternalDurationRecordWith24HourDays(other). + let d2 = InternalDurationRecord::from_duration_with_24_hour_days(other)?; + // 9. Let timeResult be ? AddTimeDuration(d1.[[Time]], d2.[[Time]]). + let time_result = (d1.normalized_time_duration() + d2.normalized_time_duration())?; + // 10. Let result be CombineDateAndTimeDuration(ZeroDateDuration(), timeResult). + let result = InternalDurationRecord::combine(DateDuration::default(), time_result); + // 11. Return ? TemporalDurationFromInternal(result, largestUnit). + Duration::from_internal(result, largest_unit) + } + + /// Returns the result of subtracting a `Duration` from the current `Duration` + #[inline] + pub fn subtract(&self, other: &Self) -> TemporalResult { + self.add(&other.negated()) + } + + /// `17.3.20 Temporal.Duration.prototype.round ( roundTo )` + /// + /// Spec: + /// + // Spec last accessed: 2025-09-08, + #[inline] + pub fn round_with_provider( + &self, + options: RoundingOptions, + relative_to: Option, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // NOTE(HalidOdat): Steps 1-12 are handled before calling the function. + // + // SKIP: 1. Let duration be the this value. + // SKIP: 2. Perform ? RequireInternalSlot(duration, [[InitializedTemporalDuration]]). + // SKIP: 3. If roundTo is undefined, then + // SKIP: a. Throw a TypeError exception. + // SKIP: 4. If roundTo is a String, then + // SKIP: a. Let paramString be roundTo. + // SKIP: b. Set roundTo to OrdinaryObjectCreate(null). + // SKIP: c. Perform ! CreateDataPropertyOrThrow(roundTo, "smallestUnit", paramString). + // SKIP: 5. Else, + // SKIP: a. Set roundTo to ? GetOptionsObject(roundTo). + // SKIP: 6. Let smallestUnitPresent be true. + // SKIP: 7. Let largestUnitPresent be true. + // SKIP: 8. NOTE: The following steps read options and perform independent validation in alphabetical order + // (GetTemporalRelativeToOption reads "relativeTo", + // GetRoundingIncrementOption reads "roundingIncrement" + // and GetRoundingModeOption reads "roundingMode"). + // SKIP: 9. Let largestUnit be ? GetTemporalUnitValuedOption(roundTo, "largestUnit", unset). + // SKIP: 10. Let relativeToRecord be ? GetTemporalRelativeToOption(roundTo). + // SKIP: 11. Let zonedRelativeTo be relativeToRecord.[[ZonedRelativeTo]]. + // SKIP: 12. Let plainRelativeTo be relativeToRecord.[[PlainRelativeTo]]. + + // 13. Let roundingIncrement be ? GetRoundingIncrementOption(roundTo). + let rounding_increment = options.increment.unwrap_or_default(); + + // 14. Let roundingMode be ? GetRoundingModeOption(roundTo, half-expand). + let rounding_mode = options.rounding_mode.unwrap_or_default(); + + // 15. Let smallestUnit be ? GetTemporalUnitValuedOption(roundTo, "smallestUnit", datetime, unset). + let smallest_unit = options.smallest_unit; + + // 16. Perform ?ValidateTemporalUnitValue(smallestUnit, datetime). + UnitGroup::DateTime.validate_unit(smallest_unit, None)?; + + // 17. If smallestUnit is unset, then + // a. Set smallestUnitPresent to false. + // b. Set smallestUnit to nanosecond. + let smallest_unit = smallest_unit.unwrap_or(Unit::Nanosecond); + + // 18. Let existingLargestUnit be DefaultTemporalLargestUnit(duration). + let existing_largest_unit = self.default_largest_unit(); + + // 19. Let defaultLargestUnit be LargerOfTwoTemporalUnits(existingLargestUnit, smallestUnit). + let default_largest_unit = Unit::larger(existing_largest_unit, smallest_unit)?; + + let largest_unit = match options.largest_unit { + // 20. If largestUnit is unset, then + // a. Set largestUnitPresent to false. + // b. Set largestUnit to defaultLargestUnit. + // 21. Else if largestUnit is auto, then + // a. Set largestUnit to defaultLargestUnit. + Some(Unit::Auto) | None => default_largest_unit, + Some(unit) => unit, + }; + + // 22. If smallestUnitPresent is false and largestUnitPresent is false, then + if options.largest_unit.is_none() && options.smallest_unit.is_none() { + // a. Throw a RangeError exception. + return Err(TemporalError::range() + .with_message("smallestUnit and largestUnit cannot both be None.")); + } + + // 23. If LargerOfTwoTemporalUnits(largestUnit, smallestUnit) is not largestUnit, throw a RangeError exception. + if Unit::larger(largest_unit, smallest_unit)? != largest_unit { + return Err( + TemporalError::range().with_message("smallestUnit is larger than largestUnit.") + ); + } + + // 24. Let maximum be MaximumTemporalDurationRoundingIncrement(smallestUnit). + let maximum = smallest_unit.to_maximum_rounding_increment(); + + // 25. If maximum is not unset, perform ? ValidateTemporalRoundingIncrement(roundingIncrement, maximum, false). + if let Some(maximum) = maximum { + rounding_increment.validate(maximum.into(), false)?; + } + + // 26. If roundingIncrement > 1, and largestUnit is not smallestUnit, and TemporalUnitCategory(smallestUnit) is date, throw a RangeError exception. + if rounding_increment > RoundingIncrement::ONE + && largest_unit != smallest_unit + && smallest_unit.is_date_unit() + { + return Err(TemporalError::range().with_message( + "roundingIncrement > 1 and largest_unit is not smallest_unit and smallest_unit is date", + )); + } + + let resolved_options = ResolvedRoundingOptions { + largest_unit, + smallest_unit, + increment: rounding_increment, + rounding_mode, + }; + + match relative_to { + // 27. If zonedRelativeTo is not undefined, then + Some(RelativeTo::ZonedDateTime(zoned_relative_to)) => { + // a. Let internalDuration be ToInternalDurationRecord(duration). + let internal_duration = self.to_internal_duration_record(); + + // b. Let timeZone be zonedRelativeTo.[[TimeZone]]. + // c. Let calendar be zonedRelativeTo.[[Calendar]]. + // (bundled in zoned_relative_to) + + // d. Let relativeEpochNs be zonedRelativeTo.[[EpochNanoseconds]]. + // let relative_epoch_ns = zoned_relative_to.epoch_nanoseconds(); + + // e. Let targetEpochNs be ? AddZonedDateTime(relativeEpochNs, timeZone, calendar, internalDuration, constrain). + let target_epoch_ns = zoned_relative_to.add_zoned_date_time( + internal_duration, + Overflow::Constrain, + provider, + )?; + + // f. Set internalDuration to ? DifferenceZonedDateTimeWithRounding(relativeEpochNs, targetEpochNs, timeZone, calendar, largestUnit, roundingIncrement, smallestUnit, roundingMode). + let internal = zoned_relative_to.diff_with_rounding( + &target_epoch_ns, + resolved_options, + provider, + )?; + + // g. If TemporalUnitCategory(largestUnit) is date, set largestUnit to hour. + let mut largest_unit = resolved_options.largest_unit; + if resolved_options.largest_unit.is_date_unit() { + largest_unit = Unit::Hour; + } + + // h. Return ? TemporalDurationFromInternal(internalDuration, largestUnit). + return Duration::from_internal(internal, largest_unit); + } + + // 28. If plainRelativeTo is not undefined, then + Some(RelativeTo::PlainDate(plain_relative_to)) => { + // a. Let internalDuration be ToInternalDurationRecordWith24HourDays(duration). + let internal_duration = + InternalDurationRecord::from_duration_with_24_hour_days(self)?; + + // b. Let targetTime be AddTime(MidnightTimeRecord(), internalDuration.[[Time]]). + let (target_time_days, target_time) = PlainTime::default() + .add_normalized_time_duration(internal_duration.normalized_time_duration()); + + // c. Let calendar be plainRelativeTo.[[Calendar]]. + let calendar = plain_relative_to.calendar(); + + // d. Let dateDuration be ! AdjustDateDurationRecord(internalDuration.[[Date]], targetTime.[[Days]]). + let date_duration = + internal_duration + .date() + .adjust(target_time_days, None, None)?; + + // e. Let targetDate be ? CalendarDateAdd(calendar, plainRelativeTo.[[ISODate]], dateDuration, constrain). + let target_date = calendar.date_add( + &plain_relative_to.iso, + &date_duration, + Overflow::Constrain, + )?; + + // f. Let isoDateTime be CombineISODateAndTimeRecord(plainRelativeTo.[[ISODate]], MidnightTimeRecord()). + let iso_date_time = + IsoDateTime::new_unchecked(plain_relative_to.iso, IsoTime::default()); + + // g. Let targetDateTime be CombineISODateAndTimeRecord(targetDate, targetTime). + let target_date_time = IsoDateTime::new_unchecked(target_date.iso, target_time.iso); + + // h. Set internalDuration to ? DifferencePlainDateTimeWithRounding(isoDateTime, targetDateTime, calendar, largestUnit, roundingIncrement, smallestUnit, roundingMode). + let internal_duration = + PlainDateTime::new_unchecked(iso_date_time, calendar.clone()) + .diff_dt_with_rounding( + &PlainDateTime::new_unchecked(target_date_time, calendar.clone()), + resolved_options, + )?; + + // i. Return ? TemporalDurationFromInternal(internalDuration, largestUnit). + return Duration::from_internal(internal_duration, resolved_options.largest_unit); + } + None => {} + } + + // 29. If IsCalendarUnit(existingLargestUnit) is true, or IsCalendarUnit(largestUnit) is true, throw a RangeError exception. + if existing_largest_unit.is_calendar_unit() + || resolved_options.largest_unit.is_calendar_unit() + { + return Err(TemporalError::range().with_message( + "largestUnit when rounding Duration was not the largest provided unit", + )); + } + + // 30. Assert: IsCalendarUnit(smallestUnit) is false. + temporal_assert!(!resolved_options.smallest_unit.is_calendar_unit()); + + // 31. Let internalDuration be ToInternalDurationRecordWith24HourDays(duration). + let internal_duration = InternalDurationRecord::from_duration_with_24_hour_days(self)?; + + // 32. If smallestUnit is day, then + let internal_duration = if resolved_options.smallest_unit == Unit::Day { + // a. Let fractionalDays be TotalTimeDuration(internalDuration.[[Time]], day). + // b. Let days be RoundNumberToIncrement(fractionalDays, roundingIncrement, roundingMode). + let days = internal_duration + .normalized_time_duration() + .round_to_fractional_days( + resolved_options.increment, + resolved_options.rounding_mode, + )?; + + // c. Let dateDuration be ? CreateDateDurationRecord(0, 0, 0, days). + let date = DateDuration::new(0, 0, 0, days)?; + + // d. Set internalDuration to CombineDateAndTimeDuration(dateDuration, 0). + InternalDurationRecord::new(date, TimeDuration::default())? + } else { + // 33. Else, + // a. Let timeDuration be ? RoundTimeDuration(internalDuration.[[Time]], roundingIncrement, smallestUnit, roundingMode). + let time_duration = internal_duration + .normalized_time_duration() + .round(resolved_options)?; + + // b. Set internalDuration to CombineDateAndTimeDuration(ZeroDateDuration(), timeDuration). + InternalDurationRecord::new(DateDuration::default(), time_duration)? + }; + + // 34. Return ? TemporalDurationFromInternal(internalDuration, largestUnit). + Duration::from_internal(internal_duration, resolved_options.largest_unit) + } + + /// Returns the total of the `Duration` + pub fn total_with_provider( + &self, + unit: Unit, + relative_to: Option, + provider: &impl TimeZoneProvider, + // Review question what is the return type of duration.prototye.total? + ) -> TemporalResult { + match relative_to { + // 11. If zonedRelativeTo is not undefined, then + Some(RelativeTo::ZonedDateTime(zoned_datetime)) => { + // a. Let internalDuration be ToInternalDurationRecord(duration). + let internal_duration = self.to_internal_duration_record(); + // b. Let timeZone be zonedRelativeTo.[[TimeZone]]. + // c. Let calendar be zonedRelativeTo.[[Calendar]]. + // d. Let relativeEpochNs be zonedRelativeTo.[[EpochNanoseconds]]. + // e. Let targetEpochNs be ? AddZonedDateTime(relativeEpochNs, timeZone, calendar, internalDuration, constrain). + let target_epoch_ns = zoned_datetime.add_zoned_date_time( + internal_duration, + Overflow::Constrain, + provider, + )?; + // f. Let total be ? DifferenceZonedDateTimeWithTotal(relativeEpochNs, targetEpochNs, timeZone, calendar, unit). + let total = zoned_datetime.diff_with_total(&target_epoch_ns, unit, provider)?; + Ok(total) + } + // 12. Else if plainRelativeTo is not undefined, then + Some(RelativeTo::PlainDate(plain_date)) => { + // a. Let internalDuration be ToInternalDurationRecordWith24HourDays(duration). + // b. Let targetTime be AddTime(MidnightTimeRecord(), internalDuration.[[Time]]). + let (balanced_days, time) = + PlainTime::default().add_normalized_time_duration(self.to_normalized()); + // c. Let calendar be plainRelativeTo.[[Calendar]]. + // d. Let dateDuration be ! AdjustDateDurationRecord(internalDuration.[[Date]], targetTime.[[Days]]). + let date_duration = DateDuration::new( + self.years(), + self.months(), + self.weeks(), + self.days() + .checked_add(balanced_days) + .ok_or(TemporalError::range())?, + )?; + // e. Let targetDate be ? CalendarDateAdd(calendar, plainRelativeTo.[[ISODate]], dateDuration, constrain). + let target_date = plain_date.calendar().date_add( + &plain_date.iso, + &date_duration, + Overflow::Constrain, + )?; + // f. Let isoDateTime be CombineISODateAndTimeRecord(plainRelativeTo.[[ISODate]], MidnightTimeRecord()). + let iso_date_time = IsoDateTime::new_unchecked(plain_date.iso, IsoTime::default()); + // g. Let targetDateTime be CombineISODateAndTimeRecord(targetDate, targetTime). + let target_date_time = IsoDateTime::new_unchecked(target_date.iso, time.iso); + // h. Let total be ? DifferencePlainDateTimeWithTotal(isoDateTime, targetDateTime, calendar, unit). + let plain_dt = + PlainDateTime::new_unchecked(iso_date_time, plain_date.calendar().clone()); + let total = plain_dt.diff_dt_with_total( + &PlainDateTime::new_unchecked(target_date_time, plain_date.calendar().clone()), + unit, + )?; + Ok(total) + } + None => { + // a. Let largestUnit be DefaultTemporalLargestUnit(duration). + let largest_unit = self.default_largest_unit(); + // b. If IsCalendarUnit(largestUnit) is true, or IsCalendarUnit(unit) is true, throw a RangeError exception. + if largest_unit.is_calendar_unit() || unit.is_calendar_unit() { + return Err(TemporalError::range()); + } + // c. Let internalDuration be ToInternalDurationRecordWith24HourDays(duration). + let internal = InternalDurationRecord::from_duration_with_24_hour_days(self)?; + // d. Let total be TotalTimeDuration(internalDuration.[[Time]], unit). + let total = internal.normalized_time_duration().total(unit)?; + Ok(total) + } + } + } + + /// Returns the `Duration` as a formatted string + pub fn as_temporal_string(&self, options: ToStringRoundingOptions) -> TemporalResult { + if options.smallest_unit == Some(Unit::Hour) || options.smallest_unit == Some(Unit::Minute) + { + return Err(TemporalError::range().with_message( + "string rounding options cannot have hour or minute smallest unit.", + )); + } + + let resolved_options = options.resolve()?; + if resolved_options.smallest_unit == Unit::Nanosecond + && resolved_options.increment == RoundingIncrement::ONE + { + let duration = duration_to_formattable(self, resolved_options.precision)?; + return Ok(duration.to_string()); + } + + let rounding_options = ResolvedRoundingOptions::from_to_string_options(&resolved_options); + + // 12. Let largestUnit be DefaultTemporalLargestUnit(duration). + let largest = self.default_largest_unit(); + // 13. Let internalDuration be ToInternalDurationRecord(duration). + let internal_duration = self.to_internal_duration_record(); + // 14. Let timeDuration be ? RoundTimeDuration(internalDuration.[[Time]], precision.[[Increment]], precision.[[Unit]], roundingMode). + let time_duration = internal_duration + .normalized_time_duration() + .round(rounding_options)?; + // 15. Set internalDuration to CombineDateAndTimeDuration(internalDuration.[[Date]], timeDuration). + let internal_duration = + InternalDurationRecord::combine(internal_duration.date(), time_duration); + // 16. Let roundedLargestUnit be LargerOfTwoTemporalUnits(largestUnit, second). + let rounded_largest_unit = largest.max(Unit::Second); + + // 17. Let roundedDuration be ? TemporalDurationFromInternal(internalDuration, roundedLargestUnit). + let rounded = Self::from_internal(internal_duration, rounded_largest_unit)?; + + // 18. Return TemporalDurationToString(roundedDuration, precision.[[Precision]]). + Ok(duration_to_formattable(&rounded, resolved_options.precision)?.to_string()) + } +} + +pub fn duration_to_formattable( + duration: &Duration, + precision: Precision, +) -> TemporalResult { + let sign = duration.sign(); + let duration = duration.abs(); + let date = duration.years() + duration.months() + duration.weeks() + duration.days(); + let date = if date != 0 { + Some(FormattableDateDuration { + years: duration.years() as u32, + months: duration.months() as u32, + weeks: duration.weeks() as u32, + days: duration.days() as u64, + }) + } else { + None + }; + + let hours = duration.hours().abs(); + let minutes = duration.minutes().abs(); + + let time = TimeDuration::from_components( + 0, + 0, + duration.seconds(), + duration.milliseconds(), + duration.microseconds(), + duration.nanoseconds(), + ); + + let seconds = time.seconds().unsigned_abs(); + let subseconds = time.subseconds().unsigned_abs(); + + let time = Some(FormattableTimeDuration::Seconds( + hours as u64, + minutes as u64, + seconds, + Some(subseconds), + )); + + Ok(FormattableDuration { + precision, + sign, + date, + time, + }) +} + +// TODO: Update, optimize, and fix the below. is_valid_duration should probably be generic over a T. + +const TWO_POWER_FIFTY_THREE: i128 = 9_007_199_254_740_992; +const MAX_SAFE_NS_PRECISION: i128 = TWO_POWER_FIFTY_THREE * 1_000_000_000; + +// NOTE: Can FiniteF64 optimize the duration_validation +/// Utility function to check whether the `Duration` fields are valid. +#[inline] +#[must_use] +#[allow(clippy::too_many_arguments)] +pub(crate) fn is_valid_duration( + years: i64, + months: i64, + weeks: i64, + days: i64, + hours: i64, + minutes: i64, + seconds: i64, + milliseconds: i64, + microseconds: i128, + nanoseconds: i128, +) -> bool { + // 1. Let sign be ! DurationSign(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds). + let set = [ + years, + months, + weeks, + days, + hours, + minutes, + seconds, + milliseconds, + microseconds.signum() as i64, + nanoseconds.signum() as i64, + ]; + let sign = duration_sign(&set); + // 2. For each value v of « years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds », do + for v in set { + // FiniteF64 must always be finite. + // a. If 𝔽(v) is not finite, return false. + // b. If v < 0 and sign > 0, return false. + if v < 0 && sign == Sign::Positive { + return false; + } + // c. If v > 0 and sign < 0, return false. + if v > 0 && sign == Sign::Negative { + return false; + } + } + // 3. If abs(years) ≥ 2**32, return false. + // n.b. u32::MAX is 2**32 - 1 + if years.saturating_abs() > u32::MAX as i64 { + return false; + }; + // 4. If abs(months) ≥ 2**32, return false. + if months.saturating_abs() > u32::MAX as i64 { + return false; + }; + // 5. If abs(weeks) ≥ 2**32, return false. + if weeks.saturating_abs() > u32::MAX as i64 { + return false; + }; + + // Work around https://github.com/boa-dev/temporal/issues/189 + // For the purpose of the validity check, we should normalize the i128 values + // to valid floating point values. This may round up! + // + // We only need to do this seconds and below, if any of the larger + // values are near MAX_SAFE_INTEGER then their seconds value will without question + // also be near MAX_SAFE_INTEGER. + let seconds = seconds as f64 as i64; + let milliseconds = milliseconds as f64 as i64; + let microseconds = microseconds as f64 as i128; + let nanoseconds = nanoseconds as f64 as i128; + + // 6. Let normalizedSeconds be days × 86,400 + hours × 3600 + minutes × 60 + seconds + // + ℝ(𝔽(milliseconds)) × 10**-3 + ℝ(𝔽(microseconds)) × 10**-6 + ℝ(𝔽(nanoseconds)) × 10**-9. + // 7. NOTE: The above step cannot be implemented directly using floating-point arithmetic. + // Multiplying by 10**-3, 10**-6, and 10**-9 respectively may be imprecise when milliseconds, + // microseconds, or nanoseconds is an unsafe integer. This multiplication can be implemented + // in C++ with an implementation of core::remquo() with sufficient bits in the quotient. + // String manipulation will also give an exact result, since the multiplication is by a power of 10. + // Seconds part + // TODO: Fix the below parts after clarification around behavior. + let normalized_nanoseconds = (days as i128 * NS_PER_DAY as i128) + + (hours as i128) * 3_600_000_000_000 + + minutes as i128 * 60_000_000_000 + + seconds as i128 * 1_000_000_000; + // Subseconds part + let normalized_subseconds_parts = (milliseconds as i128).saturating_mul(1_000_000) + + microseconds.saturating_mul(1_000) + + nanoseconds; + + let total_normalized_seconds = + normalized_nanoseconds.saturating_add(normalized_subseconds_parts); + // 8. If abs(normalizedSeconds) ≥ 2**53, return false. + if total_normalized_seconds.saturating_abs() >= MAX_SAFE_NS_PRECISION { + return false; + } + + // 9. Return true. + true +} + +/// Utility function for determining the sign for the current set of `Duration` fields. +/// +/// Equivalent: 7.5.10 `DurationSign ( years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds )` +#[inline] +#[must_use] +pub(crate) fn duration_sign(set: &[i64]) -> Sign { + // 1. For each value v of « years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds », do + for v in set { + // a. If v < 0, return -1. + // b. If v > 0, return 1. + match (*v).cmp(&0) { + Ordering::Less => return Sign::Negative, + Ordering::Greater => return Sign::Positive, + _ => {} + } + } + // 2. Return 0. + Sign::Zero +} + +impl From for Duration { + fn from(value: DateDuration) -> Self { + Self { + sign: value.sign(), + years: value.years.unsigned_abs() as u32, + months: value.months.unsigned_abs() as u32, + weeks: value.weeks.unsigned_abs() as u32, + days: value.days.unsigned_abs(), + ..Default::default() + } + } +} + +// ==== FromStr trait impl ==== + +impl FromStr for Duration { + type Err = TemporalError; + + fn from_str(s: &str) -> Result { + Self::from_utf8(s.as_bytes()) + } +} diff --git a/deps/temporal/src/builtins/core/duration/date.rs b/deps/temporal/src/builtins/core/duration/date.rs new file mode 100644 index 00000000000000..273e2c1d2ee20a --- /dev/null +++ b/deps/temporal/src/builtins/core/duration/date.rs @@ -0,0 +1,182 @@ +//! Implementation of a `DateDuration` + +use crate::{ + iso::iso_date_to_epoch_days, options::Overflow, Duration, PlainDate, Sign, TemporalError, + TemporalResult, +}; + +use super::duration_sign; + +/// `DateDuration` represents the [date duration record][spec] of the `Duration.` +/// +/// These fields are laid out in the [Temporal Proposal][field spec] as 64-bit floating point numbers. +/// +/// [spec]: https://tc39.es/proposal-temporal/#sec-temporal-date-duration-records +/// [field spec]: https://tc39.es/proposal-temporal/#sec-properties-of-temporal-duration-instances +#[non_exhaustive] +#[derive(Debug, Default, Clone, Copy, PartialEq, PartialOrd)] +pub struct DateDuration { + /// `DateDuration`'s internal year value. + pub years: i64, + /// `DateDuration`'s internal month value. + pub months: i64, + /// `DateDuration`'s internal week value. + pub weeks: i64, + /// `DateDuration`'s internal day value. + pub days: i64, +} + +impl DateDuration { + /// Creates a new, non-validated `DateDuration`. + #[inline] + #[must_use] + pub(crate) const fn new_unchecked(years: i64, months: i64, weeks: i64, days: i64) -> Self { + Self { + years, + months, + weeks, + days, + } + } +} + +impl From for DateDuration { + /// Converts a `Duration` into a `DateDuration`. + /// + /// This conversion is lossy, as `Duration` can represent time durations + /// that are not strictly date durations. + #[inline] + fn from(duration: Duration) -> Self { + Self::new_unchecked( + duration.years(), + duration.months(), + duration.weeks(), + duration.days(), + ) + } +} + +impl From<&Duration> for DateDuration { + /// Converts a `Duration` into a `DateDuration`. + /// + /// This conversion is lossy, as `Duration` can represent time durations + /// that are not strictly date durations. + #[inline] + fn from(duration: &Duration) -> Self { + Self::new_unchecked( + duration.years(), + duration.months(), + duration.weeks(), + duration.days(), + ) + } +} + +impl DateDuration { + /// Creates a new `DateDuration` with provided values. + /// + /// `7.5.9 CreateDateDurationRecord ( years, months, weeks, days )` + /// + /// Spec: + // + // spec(2025-05-28): https://github.com/tc39/proposal-temporal/tree/69001e954c70e29ba3d2e6433bc7ece2a037377a + #[inline] + pub fn new(years: i64, months: i64, weeks: i64, days: i64) -> TemporalResult { + // 1. If IsValidDuration(years, months, weeks, days, 0, 0, 0, 0, 0, 0) is false, throw a RangeError exception. + if !super::is_valid_duration(years, months, weeks, days, 0, 0, 0, 0, 0, 0) { + return Err(TemporalError::range().with_message("Invalid DateDuration.")); + } + + // 2. Return Date Duration Record { [[Years]]: ℝ(𝔽(years)), [[Months]]: ℝ(𝔽(months)), [[Weeks]]: ℝ(𝔽(weeks)), [[Days]]: ℝ(𝔽(days)) }. + Ok(Self::new_unchecked(years, months, weeks, days)) + } + + /// Returns a negated `DateDuration`. + #[inline] + #[must_use] + pub fn negated(&self) -> Self { + Self { + years: self.years.saturating_neg(), + months: self.months.saturating_neg(), + weeks: self.weeks.saturating_neg(), + days: self.days.saturating_neg(), + } + } + + /// Returns a new `DateDuration` representing the absolute value of the current. + #[inline] + #[must_use] + pub fn abs(&self) -> Self { + Self { + years: self.years.abs(), + months: self.months.abs(), + weeks: self.weeks.abs(), + days: self.days.abs(), + } + } + + /// Returns the sign for the current `DateDuration`. + #[inline] + #[must_use] + pub fn sign(&self) -> Sign { + duration_sign(&[self.years, self.months, self.weeks, self.days]) + } + + /// DateDurationDays + pub(crate) fn days(&self, relative_to: &PlainDate) -> TemporalResult { + // 1. Let yearsMonthsWeeksDuration be ! AdjustDateDurationRecord(dateDuration, 0). + let ymw_duration = self.adjust(0, None, None)?; + // 2. If DateDurationSign(yearsMonthsWeeksDuration) = 0, return dateDuration.[[Days]]. + if ymw_duration.sign() == Sign::Zero { + return Ok(self.days); + } + // 3. Let later be ? CalendarDateAdd(plainRelativeTo.[[Calendar]], plainRelativeTo.[[ISODate]], yearsMonthsWeeksDuration, constrain). + let later = relative_to.calendar().date_add( + &relative_to.iso, + &ymw_duration, + Overflow::Constrain, + )?; + // 4. Let epochDays1 be ISODateToEpochDays(plainRelativeTo.[[ISODate]].[[Year]], plainRelativeTo.[[ISODate]].[[Month]] - 1, plainRelativeTo.[[ISODate]].[[Day]]). + let epoch_days_1 = iso_date_to_epoch_days( + relative_to.iso_year(), + i32::from(relative_to.iso_month()), // this function takes 1 based month number + i32::from(relative_to.iso_day()), + ); + // 5. Let epochDays2 be ISODateToEpochDays(later.[[Year]], later.[[Month]] - 1, later.[[Day]]). + let epoch_days_2 = iso_date_to_epoch_days( + later.iso_year(), + i32::from(later.iso_month()), // this function takes 1 based month number + i32::from(later.iso_day()), + ); + // 6. Let yearsMonthsWeeksInDays be epochDays2 - epochDays1. + let ymd_in_days = epoch_days_2 - epoch_days_1; + // 7. Return dateDuration.[[Days]] + yearsMonthsWeeksInDays. + Ok(self.days + ymd_in_days) + } + + /// `7.5.10 AdjustDateDurationRecord ( dateDuration, days [ , weeks [ , months ] ] )` + /// + /// Spec: + // + // spec(2025-05-28): https://github.com/tc39/proposal-temporal/tree/69001e954c70e29ba3d2e6433bc7ece2a037377a + pub(crate) fn adjust( + &self, + days: i64, + weeks: Option, + months: Option, + ) -> TemporalResult { + // 1. If weeks is not present, set weeks to dateDuration.[[Weeks]]. + let weeks = weeks.unwrap_or(self.weeks); + + // 2. If months is not present, set months to dateDuration.[[Months]]. + let months = months.unwrap_or(self.months); + + // 3. Return ? CreateDateDurationRecord(dateDuration.[[Years]], months, weeks, days). + Ok(Self { + years: self.years, + months, + weeks, + days, + }) + } +} diff --git a/deps/temporal/src/builtins/core/duration/normalized.rs b/deps/temporal/src/builtins/core/duration/normalized.rs new file mode 100644 index 00000000000000..fcd2292425c195 --- /dev/null +++ b/deps/temporal/src/builtins/core/duration/normalized.rs @@ -0,0 +1,1058 @@ +//! This module implements the normalized `Duration` records. + +use core::{cmp, num::NonZeroU128, ops::Add}; + +use num_traits::AsPrimitive; + +use crate::{ + builtins::core::{time_zone::TimeZone, PlainDate, PlainDateTime}, + iso::{IsoDate, IsoDateTime}, + options::{ + Disambiguation, Overflow, ResolvedRoundingOptions, RoundingIncrement, RoundingMode, Unit, + UNIT_VALUE_TABLE, + }, + primitive::FiniteF64, + provider::TimeZoneProvider, + rounding::IncrementRounder, + Calendar, TemporalError, TemporalResult, TemporalUnwrap, NS_PER_DAY, NS_PER_DAY_NONZERO, +}; + +use super::{DateDuration, Duration, Sign}; + +const MAX_TIME_DURATION: i128 = 9_007_199_254_740_991_999_999_999; + +// Nanoseconds constants + +const NS_PER_DAY_128BIT: i128 = NS_PER_DAY as i128; +const NANOSECONDS_PER_MINUTE: i128 = 60 * 1_000_000_000; +const NANOSECONDS_PER_HOUR: i128 = 60 * NANOSECONDS_PER_MINUTE; + +// ==== TimeDuration ==== +// +// A time duration represented in pure nanoseconds. +// +// Invariants: +// +// nanoseconds.abs() <= MAX_TIME_DURATION + +/// A Normalized `TimeDuration` that represents the current `TimeDuration` in nanoseconds. +#[derive(Debug, Clone, Copy, Default, PartialEq, PartialOrd, Eq, Ord)] +pub(crate) struct TimeDuration(pub(crate) i128); + +impl TimeDuration { + /// Creates a `TimeDuration` from signed integer components. + /// This method preserves the sign of each component during the calculation. + pub(crate) fn from_components( + hours: i64, + minutes: i64, + seconds: i64, + milliseconds: i64, + microseconds: i128, + nanoseconds: i128, + ) -> Self { + let mut total_nanoseconds: i128 = 0; + + total_nanoseconds += i128::from(hours) * NANOSECONDS_PER_HOUR; + total_nanoseconds += i128::from(minutes) * NANOSECONDS_PER_MINUTE; + total_nanoseconds += i128::from(seconds) * 1_000_000_000; + total_nanoseconds += i128::from(milliseconds) * 1_000_000; + total_nanoseconds += microseconds * 1_000; + total_nanoseconds += nanoseconds; + + debug_assert!(total_nanoseconds.abs() <= MAX_TIME_DURATION); + Self(total_nanoseconds) + } + + /// Equivalent: 7.5.20 NormalizeTimeDuration ( hours, minutes, seconds, milliseconds, microseconds, nanoseconds ) + pub(crate) fn from_duration(duration: &Duration) -> Self { + // Note: Calculations must be done after casting to `i128` in order to preserve precision + let sign_multiplier = duration.sign().as_sign_multiplier() as i128; + let mut nanoseconds: i128 = + i128::from(duration.hours) * NANOSECONDS_PER_HOUR * sign_multiplier; + nanoseconds += i128::from(duration.minutes) * NANOSECONDS_PER_MINUTE * sign_multiplier; + nanoseconds += i128::from(duration.seconds) * 1_000_000_000 * sign_multiplier; + nanoseconds += i128::from(duration.milliseconds) * 1_000_000 * sign_multiplier; + nanoseconds += duration.microseconds as i128 * 1_000 * sign_multiplier; + nanoseconds += duration.nanoseconds as i128 * sign_multiplier; + // NOTE(nekevss): Is it worth returning a `RangeError` below. + debug_assert!(nanoseconds.abs() <= MAX_TIME_DURATION); + Self(nanoseconds) + } + + /// Equivalent to 7.5.27 TimeDurationFromEpochNanosecondsDifference ( one, two ) + pub(crate) fn from_nanosecond_difference(one: i128, two: i128) -> TemporalResult { + let result = one - two; + if result.abs() > MAX_TIME_DURATION { + return Err( + TemporalError::range().with_message("TimeDuration exceeds maxTimeDuration.") + ); + } + Ok(Self(result)) + } + + /// Equivalent: 7.5.23 Add24HourDaysToTimeDuration ( d, days ) + /// Add24HourDaysToTimeDuration?? + pub(crate) fn add_days(&self, days: i64) -> TemporalResult { + let result = self.0 + i128::from(days) * i128::from(NS_PER_DAY); + if result.abs() > MAX_TIME_DURATION { + return Err(TemporalError::range() + .with_message("SubtractTimeDuration exceeded a valid Duration range.")); + } + Ok(Self(result)) + } + + /// `Divide the NormalizedTimeDuraiton` by a divisor, truncating + /// the result + pub(crate) fn truncated_divide(&self, divisor: u64) -> i128 { + // TODO: Validate. + self.0 / i128::from(divisor) + } + + pub(crate) fn divide(&self, divisor: f64) -> f64 { + self.0 as f64 / divisor + } + + /// Equivalent: 7.5.31 TimeDurationSign ( d ) + #[inline] + #[must_use] + pub(crate) fn sign(&self) -> Sign { + Sign::from(self.0.cmp(&0) as i8) + } + + // NOTE(nekevss): non-euclid is required here for negative rounding. + /// Return the seconds value of the `TimeDuration`. + pub(crate) fn seconds(&self) -> i64 { + // SAFETY: See validate_second_cast test. + (self.0 / 1_000_000_000) as i64 + } + + // NOTE(nekevss): non-euclid is required here for negative rounding. + /// Returns the subsecond components of the `TimeDuration`. + pub(crate) fn subseconds(&self) -> i32 { + // SAFETY: Remainder is 10e9 which is in range of i32 + (self.0 % 1_000_000_000) as i32 + } + + fn negate(&self) -> Self { + Self(-self.0) + } + + pub(crate) fn checked_sub(&self, other: &Self) -> TemporalResult { + let result = self.0 - other.0; + if result.abs() > MAX_TIME_DURATION { + return Err(TemporalError::range() + .with_message("SubtractTimeDuration exceeded a valid TimeDuration range.")); + } + Ok(Self(result)) + } + + /// The equivalent of `RoundTimeDuration` abstract operation. + pub(crate) fn round(&self, options: ResolvedRoundingOptions) -> TemporalResult { + // a. Assert: The value in the "Category" column of the row of Table 22 whose "Singular" column contains unit, is time. + // b. Let divisor be the value in the "Length in Nanoseconds" column of the row of Table 22 whose "Singular" column contains unit. + let divisor = options.smallest_unit.as_nanoseconds().temporal_unwrap()?; + // c. Let total be DivideTimeDuration(norm, divisor). + let increment = options + .increment + .as_extended_increment() + .checked_mul(divisor) + .temporal_unwrap()?; + // d. Set norm to ? RoundTimeDurationToIncrement(norm, divisor × increment, roundingMode). + self.round_inner(increment, options.rounding_mode) + } + + /// Equivalent: 7.5.31 TotalTimeDuration ( timeDuration, unit ) + /// TODO Fix: Arithemtic on floating point numbers is not safe. According to NOTE 2 in the spec + pub(crate) fn total(&self, unit: Unit) -> TemporalResult { + let time_duration = self.0; + // 1. Let divisor be the value in the "Length in Nanoseconds" column of the row of Table 21 whose "Value" column contains unit. + let unit_nanoseconds = unit.as_nanoseconds().temporal_unwrap()?; + // 2. NOTE: The following step cannot be implemented directly using floating-point arithmetic when 𝔽(timeDuration) is not a safe integer. + // The division can be implemented in C++ with the __float128 type if the compiler supports it, or with software emulation such as in the SoftFP library. + // 3. Return timeDuration / divisor. + DurationTotal::new(time_duration, unit_nanoseconds.get() as u64).to_fractional_total() + } + + pub(crate) fn round_to_fractional_days( + &self, + increment: RoundingIncrement, + mode: RoundingMode, + ) -> TemporalResult { + let adjusted_increment = increment + .as_extended_increment() + .saturating_mul(NS_PER_DAY_NONZERO); + let rounded = + IncrementRounder::::from_signed_num(self.0, adjusted_increment)?.round(mode); + Ok((rounded / NS_PER_DAY_128BIT) as i64) + } + + /// Round the current `TimeDuration`. + pub(super) fn round_inner( + &self, + increment: NonZeroU128, + mode: RoundingMode, + ) -> TemporalResult { + let rounded = IncrementRounder::::from_signed_num(self.0, increment)?.round(mode); + if rounded.abs() > MAX_TIME_DURATION { + return Err( + TemporalError::range().with_message("TimeDuration exceeds maxTimeDuration.") + ); + } + Ok(Self(rounded)) + } + + pub(super) fn checked_add(&self, other: i128) -> TemporalResult { + let result = self.0 + other; + if result.abs() > MAX_TIME_DURATION { + return Err( + TemporalError::range().with_message("TimeDuration exceeds maxTimeDuration.") + ); + } + Ok(Self(result)) + } +} + +// NOTE(nekevss): As this `Add` impl is fallible. Maybe it would be best implemented as a method. +/// Equivalent: 7.5.22 AddTimeDuration ( one, two ) +impl Add for TimeDuration { + type Output = TemporalResult; + + fn add(self, rhs: Self) -> Self::Output { + let result = self.0 + rhs.0; + if result.abs() > MAX_TIME_DURATION { + return Err( + TemporalError::range().with_message("TimeDuration exceeds maxTimeDuration.") + ); + } + Ok(Self(result)) + } +} + +// Struct to handle division steps in `TotalTimeDuration` +struct DurationTotal { + quotient: i128, + remainder: i128, + unit_nanoseconds: u64, +} + +impl DurationTotal { + pub fn new(time_duration: i128, unit_nanoseconds: u64) -> Self { + let quotient = time_duration.div_euclid(unit_nanoseconds as i128); + let remainder = time_duration.rem_euclid(unit_nanoseconds as i128); + + Self { + quotient, + remainder, + unit_nanoseconds, + } + } + + pub(crate) fn to_fractional_total(&self) -> TemporalResult { + let fractional = FiniteF64::try_from(self.remainder)? + .checked_div(&FiniteF64::try_from(self.unit_nanoseconds)?)?; + FiniteF64::try_from(self.quotient)?.checked_add(&fractional) + } +} + +// ==== Internal Duration record ==== +// +// A record consisting of a DateDuration and TimeDuration +// + +/// An InternalDurationRecord is a duration record that contains +/// a `DateDuration` and `TimeDuration`. +#[derive(Debug, Default, Clone, Copy)] +pub struct InternalDurationRecord { + date: DateDuration, + norm: TimeDuration, +} + +impl InternalDurationRecord { + pub(crate) fn combine(date: DateDuration, norm: TimeDuration) -> Self { + // 1. Let dateSign be DateDurationSign(dateDuration). + // 2. Let timeSign be TimeDurationSign(timeDuration). + // 3. Assert: If dateSign ≠ 0 and timeSign ≠ 0, dateSign = timeSign. + // 4. Return Internal Duration Record { [[Date]]: dateDuration, [[Time]]: timeDuration }. + Self { date, norm } + } + + /// Creates a new `NormalizedDurationRecord`. + /// + /// Equivalent: `CreateNormalizedDurationRecord` & `CombineDateAndTimeDuration`. + pub(crate) fn new(date: DateDuration, norm: TimeDuration) -> TemporalResult { + if date.sign() != Sign::Zero && norm.sign() != Sign::Zero && date.sign() != norm.sign() { + return Err(TemporalError::range() + .with_message("DateDuration and TimeDuration must agree if both are not zero.")); + } + Ok(Self { date, norm }) + } + + /// Equivalent of `7.5.6 ToInternalDurationRecordWith24HourDays ( duration )` + /// + /// Spec: + pub(crate) fn from_duration_with_24_hour_days(duration: &Duration) -> TemporalResult { + // 1. Let timeDuration be TimeDurationFromComponents(duration.[[Hours]], duration.[[Minutes]], + // duration.[[Seconds]], duration.[[Milliseconds]], duration.[[Microseconds]], duration.[[Nanoseconds]]). + let normalized_time = TimeDuration::from_duration(duration); + // 2. Set timeDuration to ! Add24HourDaysToTimeDuration(timeDuration, duration.[[Days]]). + let normalized_time = normalized_time.add_days(duration.days())?; + // 3. Let dateDuration be ! CreateDateDurationRecord(duration.[[Years]], duration.[[Months]], duration.[[Weeks]], 0). + let date = + DateDuration::new_unchecked(duration.years(), duration.months(), duration.weeks(), 0); + // 4. Return CombineDateAndTimeDuration(dateDuration, timeDuration). + Self::new(date, normalized_time) + } + + /// Equivalent of [`7.5.7 ToDateDurationRecordWithoutTime ( duration )`][spec] + /// + /// [spec]: + /// + // spec(2025-06-23): https://github.com/tc39/proposal-temporal/tree/ed49b0b482981119c9b5e28b0686d877d4a9bae0 + #[allow(clippy::wrong_self_convention)] + pub(crate) fn to_date_duration_record_without_time(&self) -> TemporalResult { + // 1. Let internalDuration be ToInternalDurationRecordWith24HourDays(duration). + let internal_duration = self; + + // NOTE: days SHOULD be in range of an i64. + // MAX_TIME_DURATION / NS_PER_DAY <= i64::MAX + // 2. Let days be truncate(internalDuration.[[Time]] / nsPerDay). + let days = (internal_duration.normalized_time_duration().0 / i128::from(NS_PER_DAY)) as i64; + + // 3. Return ! CreateDateDurationRecord(internalDuration.[[Date]].[[Years]], internalDuration.[[Date]].[[Months]], internalDuration.[[Date]].[[Weeks]], days). + DateDuration::new( + internal_duration.date().years, + internal_duration.date().months, + internal_duration.date().weeks, + days, + ) + } + + pub(crate) fn from_date_duration(date: DateDuration) -> TemporalResult { + Self::new(date, TimeDuration::default()) + } + + pub(crate) fn date(&self) -> DateDuration { + self.date + } + + pub(crate) fn normalized_time_duration(&self) -> TimeDuration { + self.norm + } + + pub(crate) fn sign(&self) -> Sign { + let date_sign = self.date.sign(); + if date_sign == Sign::Zero { + self.norm.sign() + } else { + date_sign + } + } +} + +// ==== Nudge Duration Rounding Functions ==== + +// Below implements the nudge rounding functionality for Duration. +// +// Generally, this rounding is implemented on a NormalizedDurationRecord, +// which is the reason the functionality lives below. + +#[derive(Debug)] +struct NudgeRecord { + normalized: InternalDurationRecord, + total: Option, + nudge_epoch_ns: i128, + expanded: bool, +} + +impl InternalDurationRecord { + // TODO: Add assertion into impl. + // TODO: Add unit tests specifically for nudge_calendar_unit if possible. + fn nudge_calendar_unit( + &self, + sign: Sign, + dest_epoch_ns: i128, + dt: &PlainDateTime, + time_zone: Option<(&TimeZone, &impl TimeZoneProvider)>, // ??? + options: ResolvedRoundingOptions, + ) -> TemporalResult { + // NOTE: r2 may never be used...need to test. + let (r1, r2, start_duration, end_duration) = match options.smallest_unit { + // 1. If unit is "year", then + Unit::Year => { + // a. Let years be RoundNumberToIncrement(duration.[[Years]], increment, "trunc"). + let years = IncrementRounder::from_signed_num( + self.date().years, + options.increment.as_extended_increment(), + )? + .round(RoundingMode::Trunc); + // b. Let r1 be years. + let r1 = years; + // c. Let r2 be years + increment × sign. + let r2 = years + + i128::from(options.increment.get()) * i128::from(sign.as_sign_multiplier()); + // d. Let startDuration be ? CreateNormalizedDurationRecord(r1, 0, 0, 0, ZeroTimeDuration()). + // e. Let endDuration be ? CreateNormalizedDurationRecord(r2, 0, 0, 0, ZeroTimeDuration()). + ( + r1, + r2, + DateDuration::new( + i64::try_from(r1).map_err(|_| TemporalError::range())?, + 0, + 0, + 0, + )?, + DateDuration::new( + i64::try_from(r2).map_err(|_| TemporalError::range())?, + 0, + 0, + 0, + )?, + ) + } + // 2. Else if unit is "month", then + Unit::Month => { + // a. Let months be RoundNumberToIncrement(duration.[[Months]], increment, "trunc"). + let months = IncrementRounder::from_signed_num( + self.date().months, + options.increment.as_extended_increment(), + )? + .round(RoundingMode::Trunc); + // b. Let r1 be months. + let r1 = months; + // c. Let r2 be months + increment × sign. + let r2 = months + + i128::from(options.increment.get()) * i128::from(sign.as_sign_multiplier()); + // d. Let startDuration be ? CreateNormalizedDurationRecord(duration.[[Years]], r1, 0, 0, ZeroTimeDuration()). + // e. Let endDuration be ? CreateNormalizedDurationRecord(duration.[[Years]], r2, 0, 0, ZeroTimeDuration()). + ( + r1, + r2, + DateDuration::new( + self.date().years, + i64::try_from(r1).map_err(|_| TemporalError::range())?, + 0, + 0, + )?, + DateDuration::new( + self.date().years, + i64::try_from(r2).map_err(|_| TemporalError::range())?, + 0, + 0, + )?, + ) + } + // 3. Else if unit is "week", then + Unit::Week => { + // TODO: Reconcile potential overflow on years as i32. `ValidateDuration` + // requires years, months, weeks to be abs(x) <= 2^32. + // + // Do we even care? This needs tests, but even a truncated i32::MAX is still + // FAR TOO LARGE for adding to a duration and will throw at steps c-d. This + // is only really an issue, because we are trying to optimize out floating + // points, but it may really show that a Duration's max range is very very + // very big. Too big. To be tested and determined. + // + // In other words, our year range is roughly +/- 280_000? Let's add 2^32 to + // that. It won't overflow, right? + + // a. Let isoResult1 be BalanceISODate(dateTime.[[Year]] + duration.[[Years]], + // dateTime.[[Month]] + duration.[[Months]], dateTime.[[Day]]). + let iso_one = IsoDate::try_balance( + dt.iso_year() + self.date().years as i32, + i32::from(dt.iso_month()) + self.date().months as i32, + i64::from(dt.iso_day()), + )?; + + // b. Let isoResult2 be BalanceISODate(dateTime.[[Year]] + duration.[[Years]], dateTime.[[Month]] + + // duration.[[Months]], dateTime.[[Day]] + duration.[[Days]]). + let iso_two = IsoDate::try_balance( + dt.iso_year() + self.date().years as i32, + i32::from(dt.iso_month()) + self.date().months as i32, + i64::from(dt.iso_day()) + self.date().days, + )?; + + // c. Let weeksStart be ! CreateTemporalDate(isoResult1.[[Year]], isoResult1.[[Month]], isoResult1.[[Day]], + // calendarRec.[[Receiver]]). + let weeks_start = PlainDate::try_new( + iso_one.year, + iso_one.month, + iso_one.day, + dt.calendar().clone(), + )?; + + // d. Let weeksEnd be ! CreateTemporalDate(isoResult2.[[Year]], isoResult2.[[Month]], isoResult2.[[Day]], + // calendarRec.[[Receiver]]). + let weeks_end = PlainDate::try_new( + iso_two.year, + iso_two.month, + iso_two.day, + dt.calendar().clone(), + )?; + + // e. Let untilOptions be OrdinaryObjectCreate(null). + // f. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "week"). + // g. Let untilResult be ? DifferenceDate(calendarRec, weeksStart, weeksEnd, untilOptions). + + let until_result = weeks_start.internal_diff_date(&weeks_end, Unit::Week)?; + + // h. Let weeks be RoundNumberToIncrement(duration.[[Weeks]] + untilResult.[[Weeks]], increment, "trunc"). + let weeks = IncrementRounder::from_signed_num( + self.date().weeks + until_result.weeks(), + options.increment.as_extended_increment(), + )? + .round(RoundingMode::Trunc); + + // i. Let r1 be weeks. + let r1 = weeks; + // j. Let r2 be weeks + increment × sign. + let r2 = weeks + + i128::from(options.increment.get()) * i128::from(sign.as_sign_multiplier()); + // k. Let startDuration be ? CreateNormalizedDurationRecord(duration.[[Years]], duration.[[Months]], r1, 0, ZeroTimeDuration()). + // l. Let endDuration be ? CreateNormalizedDurationRecord(duration.[[Years]], duration.[[Months]], r2, 0, ZeroTimeDuration()). + ( + r1, + r2, + DateDuration::new( + self.date().years, + self.date().months, + i64::try_from(r1).map_err(|_| TemporalError::range())?, + 0, + )?, + DateDuration::new( + self.date().years, + self.date().months, + i64::try_from(r2).map_err(|_| TemporalError::range())?, + 0, + )?, + ) + } + Unit::Day => { + // 4. Else, + // a. Assert: unit is "day". + // b. Let days be RoundNumberToIncrement(duration.[[Days]], increment, "trunc"). + let days = IncrementRounder::from_signed_num( + self.date().days, + options.increment.as_extended_increment(), + )? + .round(RoundingMode::Trunc); + // c. Let r1 be days. + let r1 = days; + // d. Let r2 be days + increment × sign. + let r2 = days + + i128::from(options.increment.get()) * i128::from(sign.as_sign_multiplier()); + // e. Let startDuration be ? CreateNormalizedDurationRecord(duration.[[Years]], duration.[[Months]], duration.[[Weeks]], r1, ZeroTimeDuration()). + // f. Let endDuration be ? CreateNormalizedDurationRecord(duration.[[Years]], duration.[[Months]], duration.[[Weeks]], r2, ZeroTimeDuration()). + ( + r1, + r2, + DateDuration::new( + self.date().years, + self.date().months, + self.date().weeks, + i64::try_from(r1).map_err(|_| TemporalError::range())?, + )?, + DateDuration::new( + self.date().years, + self.date().months, + self.date().weeks, + i64::try_from(r2).map_err(|_| TemporalError::range())?, + )?, + ) + } + _ => { + debug_assert!( + false, + "Found unexpected unit {} in NudgeToCalendarUnit", + options.smallest_unit + ); + return Err(TemporalError::assert() + .with_message("NudgeCalendarUnit invoked with unexpected unit")); + } + }; + + // 7. Let start be ? CalendarDateAdd(calendar, isoDateTime.[[ISODate]], startDuration, constrain). + let start = dt + .calendar() + .date_add(&dt.iso.date, &start_duration, Overflow::Constrain)?; + // 8. Let end be ? CalendarDateAdd(calendar, isoDateTime.[[ISODate]], endDuration, constrain). + let end = dt + .calendar() + .date_add(&dt.iso.date, &end_duration, Overflow::Constrain)?; + // 9. Let startDateTime be CombineISODateAndTimeRecord(start, isoDateTime.[[Time]]). + let start = IsoDateTime::new_unchecked(start.iso, dt.iso.time); + // 10. Let endDateTime be CombineISODateAndTimeRecord(end, isoDateTime.[[Time]]). + let end = IsoDateTime::new_unchecked(end.iso, dt.iso.time); + + // 12. Else, + let (start_epoch_ns, end_epoch_ns) = if let Some((time_zone, provider)) = time_zone { + // a. Let startEpochNs be ? GetEpochNanosecondsFor(timeZone, startDateTime, compatible). + // b. Let endEpochNs be ? GetEpochNanosecondsFor(timeZone, endDateTime, compatible). + let start_epoch_ns = + time_zone.get_epoch_nanoseconds_for(start, Disambiguation::Compatible, provider)?; + let end_epoch_ns = + time_zone.get_epoch_nanoseconds_for(end, Disambiguation::Compatible, provider)?; + (start_epoch_ns.ns, end_epoch_ns.ns) + // 11. If timeZoneRec is unset, then + } else { + // a. Let startEpochNs be GetUTCEpochNanoseconds(start.[[Year]], start.[[Month]], start.[[Day]], start.[[Hour]], start.[[Minute]], start.[[Second]], start.[[Millisecond]], start.[[Microsecond]], start.[[Nanosecond]]). + // b. Let endEpochNs be GetUTCEpochNanoseconds(end.[[Year]], end.[[Month]], end.[[Day]], end.[[Hour]], end.[[Minute]], end.[[Second]], end.[[Millisecond]], end.[[Microsecond]], end.[[Nanosecond]]). + (start.as_nanoseconds(), end.as_nanoseconds()) + }; + + // TODO: look into handling asserts + // 13. If sign is 1, then + // a. Assert: startEpochNs ≤ destEpochNs ≤ endEpochNs. + // 14. Else, + // a. Assert: endEpochNs ≤ destEpochNs ≤ startEpochNs. + // 15. Assert: startEpochNs ≠ endEpochNs. + + // TODO: Don't use f64 below ... + // NOTE(nekevss): Step 12..13 could be problematic...need tests + // and verify, or completely change the approach involved. + // TODO(nekevss): Validate that the `f64` casts here are valid in all scenarios + // 16. Let progress be (destEpochNs - startEpochNs) / (endEpochNs - startEpochNs). + // 17. Let total be r1 + progress × increment × sign. + let progress = + (dest_epoch_ns - start_epoch_ns.0) as f64 / (end_epoch_ns.0 - start_epoch_ns.0) as f64; + let total = r1 as f64 + + progress * options.increment.get() as f64 * f64::from(sign.as_sign_multiplier()); + + // 14. NOTE: The above two steps cannot be implemented directly using floating-point arithmetic. + // This division can be implemented as if constructing Normalized Time Duration Records for the denominator + // and numerator of total and performing one division operation with a floating-point result. + // 15. Let roundedUnit be ApplyUnsignedRoundingMode(total, r1, r2, unsignedRoundingMode). + let rounded_unit = + IncrementRounder::from_signed_num(total, options.increment.as_extended_increment())? + .round(options.rounding_mode); + + // 16. If roundedUnit - total < 0, let roundedSign be -1; else let roundedSign be 1. + // 19. Return Duration Nudge Result Record { [[Duration]]: resultDuration, [[Total]]: total, [[NudgedEpochNs]]: nudgedEpochNs, [[DidExpandCalendarUnit]]: didExpandCalendarUnit }. + // 17. If roundedSign = sign, then + if rounded_unit == r2 { + // a. Let didExpandCalendarUnit be true. + // b. Let resultDuration be endDuration. + // c. Let nudgedEpochNs be endEpochNs. + Ok(NudgeRecord { + normalized: InternalDurationRecord::new(end_duration, TimeDuration::default())?, + total: Some(FiniteF64::try_from(total)?), + nudge_epoch_ns: end_epoch_ns.0, + expanded: true, + }) + // 18. Else, + } else { + // a. Let didExpandCalendarUnit be false. + // b. Let resultDuration be startDuration. + // c. Let nudgedEpochNs be startEpochNs. + Ok(NudgeRecord { + normalized: InternalDurationRecord::new(start_duration, TimeDuration::default())?, + total: Some(FiniteF64::try_from(total)?), + nudge_epoch_ns: start_epoch_ns.0, + expanded: false, + }) + } + } + + // TODO: Clean up + #[inline] + fn nudge_to_zoned_time( + &self, + sign: Sign, + dt: &PlainDateTime, + time_zone: &TimeZone, + options: ResolvedRoundingOptions, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let d = self.date(); + // 1.Let start be ? CalendarDateAdd(calendar, isoDateTime.[[ISODate]], duration.[[Date]], constrain). + let start = dt + .calendar() + .date_add(&dt.iso.date, &d, Overflow::Constrain)?; + // 2. Let startDateTime be CombineISODateAndTimeRecord(start, isoDateTime.[[Time]]). + let start_dt = IsoDateTime::new_unchecked(start.iso, dt.iso.time); + + // 3. Let endDate be BalanceISODate(start.[[Year]], start.[[Month]], start.[[Day]] + sign). + let end_date = IsoDate::balance( + start.iso_year(), + start.iso_month().into(), + // Use sign_multiplier here, not sign as i8, since spec wants sign to be nonzero (0 => +1) + start.iso_day() as i32 + i32::from(sign.as_sign_multiplier()), + ); + + // 4. Let endDateTime be CombineISODateAndTimeRecord(endDate, isoDateTime.[[Time]]). + let end_dt = IsoDateTime::new_unchecked(end_date, dt.iso.time); + // 5. Let startEpochNs be ? GetEpochNanosecondsFor(timeZone, startDateTime, compatible). + let start = + time_zone.get_epoch_nanoseconds_for(start_dt, Disambiguation::Compatible, provider)?; + // 6. Let endEpochNs be ? GetEpochNanosecondsFor(timeZone, endDateTime, compatible). + let end = + time_zone.get_epoch_nanoseconds_for(end_dt, Disambiguation::Compatible, provider)?; + // 7. Let daySpan be TimeDurationFromEpochNanosecondsDifference(endEpochNs, startEpochNs). + let day_span = TimeDuration::from_nanosecond_difference(end.ns.0, start.ns.0)?; + // 8. Assert: TimeDurationSign(daySpan) = sign. + // 9. Let unitLength be the value in the "Length in Nanoseconds" column of the row of Table 21 whose "Value" column contains unit. + let unit_length = options.smallest_unit.as_nanoseconds().temporal_unwrap()?; + // 10. Let roundedTimeDuration be ? RoundTimeDurationToIncrement(duration.[[Time]], increment × unitLength, roundingMode). + let rounded_time = self.norm.round_inner( + unit_length + .checked_mul(options.increment.as_extended_increment()) + .temporal_unwrap()?, + options.rounding_mode, + )?; + // 11. Let beyondDaySpan be ! AddTimeDuration(roundedTimeDuration, -daySpan). + let beyond_day_span = rounded_time.checked_add(day_span.negate().0)?; + // 12. If TimeDurationSign(beyondDaySpan) ≠ -sign, then + let (expanded, day_delta, rounded_time, nudge_ns) = + if beyond_day_span.sign() != sign.negate() { + // a. Let didRoundBeyondDay be true. + // b. Let dayDelta be sign. + // c. Set roundedTimeDuration to ? RoundTimeDurationToIncrement(beyondDaySpan, increment × unitLength, roundingMode). + let rounded_time = beyond_day_span.round_inner( + unit_length + .checked_mul(options.increment.as_extended_increment()) + .temporal_unwrap()?, + options.rounding_mode, + )?; + // d. Let nudgedEpochNs be AddTimeDurationToEpochNanoseconds(roundedTimeDuration, endEpochNs). + let nudged_ns = rounded_time.checked_add(end.ns.0)?; + (true, sign as i8, rounded_time, nudged_ns) + // 13. Else, + } else { + // a. Let didRoundBeyondDay be false. + // b. Let dayDelta be 0. + // c. Let nudgedEpochNs be AddTimeDurationToEpochNanoseconds(roundedTimeDuration, startEpochNs). + let nudge_ns = rounded_time.checked_add(start.ns.0)?; + (false, 0, rounded_time, nudge_ns) + }; + // 14. Let dateDuration be ! AdjustDateDurationRecord(duration.[[Date]], duration.[[Date]].[[Days]] + dayDelta). + let date = DateDuration::new( + self.date.years, + self.date.months, + self.date.weeks, + self.date + .days + .checked_add(day_delta.into()) + .ok_or(TemporalError::range())?, + )?; + // 15. Let resultDuration be CombineDateAndTimeDuration(dateDuration, roundedTimeDuration). + let normalized = InternalDurationRecord::new(date, rounded_time)?; + // 16. Return Duration Nudge Result Record { [[Duration]]: resultDuration, [[NudgedEpochNs]]: nudgedEpochNs, [[DidExpandCalendarUnit]]: didRoundBeyondDay }. + Ok(NudgeRecord { + normalized, + nudge_epoch_ns: nudge_ns.0, + total: None, + expanded, + }) + } + + #[inline] + fn nudge_to_day_or_time( + &self, + dest_epoch_ns: i128, + options: ResolvedRoundingOptions, + ) -> TemporalResult { + // 1. Let timeDuration be ! Add24HourDaysToTimeDuration(duration.[[Time]], duration.[[Date]].[[Days]]). + let time_duration = self.normalized_time_duration().add_days(self.date().days)?; + // 2. Let unitLength be the value in the "Length in Nanoseconds" column of the row of Table 21 whose "Value" column contains smallestUnit. + let unit_length = options.smallest_unit.as_nanoseconds().temporal_unwrap()?; + // 3. Let roundedTime be ? RoundTimeDurationToIncrement(timeDuration, unitLength × increment, roundingMode). + let rounded_time = time_duration.round_inner( + unit_length + .checked_mul(options.increment.as_extended_increment()) + .temporal_unwrap()?, + options.rounding_mode, + )?; + + // 4. Let diffTime be ! AddTimeDuration(roundedTime, -timeDuration). + let diff_time = rounded_time.checked_sub(&time_duration)?; + + // 5. Let wholeDays be truncate(TotalTimeDuration(timeDuration, day)). + let whole_days = time_duration.truncated_divide(NS_PER_DAY) as i64; + + // 6. Let roundedWholeDays be truncate(TotalTimeDuration(roundedTime, day)). + let rounded_whole_days = rounded_time.truncated_divide(NS_PER_DAY) as i64; + // 7. Let dayDelta be roundedWholeDays - wholeDays. + let delta = rounded_whole_days - whole_days; + // 8. If dayDelta < 0, let dayDeltaSign be -1; else if dayDelta > 0, let dayDeltaSign be 1; else let dayDeltaSign be 0. + // 9. If dayDeltaSign = TimeDurationSign(timeDuration), let didExpandDays be true; else let didExpandDays be false. + let did_expand_days = delta.signum() as i8 == time_duration.sign() as i8; + // 10. Let nudgedEpochNs be AddTimeDurationToEpochNanoseconds(diffTime, destEpochNs). + let nudged_ns = diff_time.0 + dest_epoch_ns; + + // 11. Let days be 0. + let mut days = 0; + // 12. Let remainder be roundedTime. + let mut remainder = rounded_time; + // 13. If TemporalUnitCategory(largestUnit) is date, then + if options.largest_unit.is_date_unit() { + // a. Set days to roundedWholeDays. + days = rounded_whole_days; + // b. Set remainder to ! AddTimeDuration(roundedTime, TimeDurationFromComponents(-roundedWholeDays * HoursPerDay, 0, 0, 0, 0, 0)). + remainder = rounded_time.add(TimeDuration::from_components( + -rounded_whole_days * 24, + 0, + 0, + 0, + 0, + 0, + ))?; + } + + // 14. Let dateDuration be ! AdjustDateDurationRecord(duration.[[Date]], days). + let date_duration = self.date().adjust(days, None, None)?; + // 15. Let resultDuration be CombineDateAndTimeDuration(dateDuration, remainder). + let result_duration = Self::combine(date_duration, remainder); + // 16. Return Duration Nudge Result Record { [[Duration]]: resultDuration, [[NudgedEpochNs]]: nudgedEpochNs, [[DidExpandCalendarUnit]]: didExpandDays }. + Ok(NudgeRecord { + normalized: result_duration, + total: None, + nudge_epoch_ns: nudged_ns, + expanded: did_expand_days, + }) + } + + /// `7.5.36 BubbleRelativeDuration ( sign, duration, nudgedEpochNs, isoDateTime, timeZone, calendar, largestUnit, smallestUnit )` + /// + /// Spec: + // + // spec(2025-05-28): https://github.com/tc39/proposal-temporal/tree/69001e954c70e29ba3d2e6433bc7ece2a037377a + #[inline] + #[allow(clippy::too_many_arguments)] + fn bubble_relative_duration( + &self, + sign: Sign, + nudged_epoch_ns: i128, + iso_date_time: &IsoDateTime, + time_zone: Option<(&TimeZone, &impl TimeZoneProvider)>, + calendar: &Calendar, + largest_unit: Unit, + smallest_unit: Unit, + ) -> TemporalResult { + let mut duration = *self; + + // 1. If smallestUnit is largestUnit, return duration. + if smallest_unit == largest_unit { + return Ok(duration); + } + + // 2. Let largestUnitIndex be the ordinal index of the row of Table 21 whose "Value" column contains largestUnit. + let largest_unit_index = largest_unit.table_index()?; + + // 3. Let smallestUnitIndex be the ordinal index of the row of Table 21 whose "Value" column contains smallestUnit. + let smallest_unit_index = smallest_unit.table_index()?; + + // 4. Let unitIndex be smallestUnitIndex - 1. + // 5. Let done be false. + // 6. Repeat, while unitIndex ≥ largestUnitIndex and done is false, + // a. Let unit be the value in the "Value" column of Table 21 in the row whose ordinal index is unitIndex. + // The caller is able to set smallest_unit_index to `day` here, which would result in a backwards range get + // We clamp to handle that case + let clamped_upper_bound = cmp::max(smallest_unit_index, largest_unit_index); + let unit_values = UNIT_VALUE_TABLE + .get(largest_unit_index..clamped_upper_bound) + .temporal_unwrap()?; + for unit in unit_values.iter().rev().copied() { + // b. If unit is not week, or largestUnit is week, then + if unit != Unit::Week || largest_unit == Unit::Week { + let end_duration = match unit { + // i. If unit is year, then + Unit::Year => { + // 1. Let years be duration.[[Date]].[[Years]] + sign. + let years = self + .date() + .years + .checked_add(sign.as_sign_multiplier().into()) + .ok_or(TemporalError::range())?; + + // 2. Let endDuration be ? CreateDateDurationRecord(years, 0, 0, 0). + DateDuration::new(years, 0, 0, 0)? + } + // ii. Else if unit is month, then + Unit::Month => { + // 1. Let months be duration.[[Date]].[[Months]] + sign. + let months = self + .date() + .months + .checked_add(sign.as_sign_multiplier().into()) + .ok_or(TemporalError::range())?; + + // 2. Let endDuration be ? AdjustDateDurationRecord(duration.[[Date]], 0, 0, months). + duration.date().adjust(0, Some(0), Some(months))? + } + // iii. Else, + unit => { + // 1. Assert: unit is week. + debug_assert!(unit == Unit::Week); + + // 2. Let weeks be duration.[[Date]].[[Weeks]] + sign. + let weeks = self + .date() + .weeks + .checked_add(sign.as_sign_multiplier().into()) + .ok_or(TemporalError::range())?; + + // 3. Let endDuration be ? AdjustDateDurationRecord(duration.[[Date]], 0, weeks). + duration.date().adjust(0, Some(weeks), None)? + } + }; + + // iv. Let end be ? CalendarDateAdd(calendar, isoDateTime.[[ISODate]], endDuration, constrain). + let end = + calendar.date_add(&iso_date_time.date, &end_duration, Overflow::Constrain)?; + + // v. Let endDateTime be CombineISODateAndTimeRecord(end, isoDateTime.[[Time]]). + let end_date_time = IsoDateTime::new_unchecked(end.iso, iso_date_time.time); + + let end_epoch_ns = match time_zone { + // vi. If timeZone is unset, then + None => { + // 1. Let endEpochNs be GetUTCEpochNanoseconds(endDateTime). + end_date_time.as_nanoseconds() + } + // vii. Else, + Some((time_zone, time_zone_provider)) => { + // 1. Let endEpochNs be ? GetEpochNanosecondsFor(timeZone, endDateTime, compatible). + time_zone + .get_epoch_nanoseconds_for( + end_date_time, + Disambiguation::Compatible, + time_zone_provider, + )? + .ns + } + }; + + // viii. Let beyondEnd be nudgedEpochNs - endEpochNs. + let beyond_end = nudged_epoch_ns - end_epoch_ns.as_i128(); + + // ix. If beyondEnd < 0, let beyondEndSign be -1; else if beyondEnd > 0, let beyondEndSign be 1; else let beyondEndSign be 0. + let beyound_end_sign = beyond_end.signum(); + + // x. If beyondEndSign ≠ -sign, then + if beyound_end_sign != -i128::from(sign.as_sign_multiplier()) { + // 1. Set duration to CombineDateAndTimeDuration(endDuration, 0). + duration = InternalDurationRecord::from_date_duration(end_duration)?; + } else { + // 1. Set done to true. + break; + } + } + + // c. Set unitIndex to unitIndex - 1. + } + + // 7. Return duration. + Ok(duration) + } + + /// `7.5.37 RoundRelativeDuration ( duration, destEpochNs, isoDateTime, timeZone, calendar, largestUnit, increment, smallestUnit, roundingMode )` + /// + /// Spec: + // + // spec(2025-05-29): https://github.com/tc39/proposal-temporal/tree/c150e7135c56afc9114032e93b53ac49f980d254 + // + // TODO: Potentially revisit and optimize + #[inline] + pub(crate) fn round_relative_duration( + &self, + dest_epoch_ns: i128, + dt: &PlainDateTime, + time_zone: Option<(&TimeZone, &impl TimeZoneProvider)>, + options: ResolvedRoundingOptions, + ) -> TemporalResult { + let duration = *self; + + // 1. Let irregularLengthUnit be false. + // 2. If IsCalendarUnit(smallestUnit) is true, set irregularLengthUnit to true. + // 3. If timeZone is not unset and smallestUnit is day, set irregularLengthUnit to true. + let irregular_length_unit = options.smallest_unit.is_calendar_unit() + || (time_zone.is_some() && options.smallest_unit == Unit::Day); + + // 4. If InternalDurationSign(duration) < 0, let sign be -1; else let sign be 1. + let sign = duration.sign(); + + // 5. If irregularLengthUnit is true, then + let nudge_result = if irregular_length_unit { + // a. Let record be ? NudgeToCalendarUnit(sign, duration, destEpochNs, isoDateTime, timeZone, calendar, increment, smallestUnit, roundingMode). + // b. Let nudgeResult be record.[[NudgeResult]]. + duration.nudge_calendar_unit(sign, dest_epoch_ns, dt, time_zone, options)? + } else if let Some((time_zone, time_zone_provider)) = time_zone { + // 6. Else if timeZone is not unset, then + // a. Let nudgeResult be ? NudgeToZonedTime(sign, duration, isoDateTime, timeZone, calendar, increment, smallestUnit, roundingMode). + duration.nudge_to_zoned_time(sign, dt, time_zone, options, time_zone_provider)? + } else { + // 7. Else, + // a. Let nudgeResult be ? NudgeToDayOrTime(duration, destEpochNs, largestUnit, increment, smallestUnit, roundingMode). + duration.nudge_to_day_or_time(dest_epoch_ns, options)? + }; + + // 8. Set duration to nudgeResult.[[Duration]]. + let mut duration = nudge_result.normalized; + + // 9. If nudgeResult.[[DidExpandCalendarUnit]] is true and smallestUnit is not week, then + if nudge_result.expanded && options.smallest_unit != Unit::Week { + // a. Let startUnit be LargerOfTwoTemporalUnits(smallestUnit, day). + let start_unit = Unit::larger(options.smallest_unit, Unit::Day)?; + + // b. Set duration to ? BubbleRelativeDuration(sign, duration, nudgeResult.[[NudgedEpochNs]], isoDateTime, timeZone, calendar, largestUnit, startUnit). + duration = duration.bubble_relative_duration( + sign, + nudge_result.nudge_epoch_ns, + &dt.iso, + time_zone, + dt.calendar(), + options.largest_unit, + start_unit, + )?; + } + + // 10. Return duration. + Ok(duration) + } + + // 7.5.38 TotalRelativeDuration ( duration, destEpochNs, isoDateTime, timeZone, calendar, unit ) + pub(crate) fn total_relative_duration( + &self, + dest_epoch_ns: i128, + dt: &PlainDateTime, + time_zone: Option<(&TimeZone, &impl TimeZoneProvider)>, + unit: Unit, + ) -> TemporalResult { + // 1. If IsCalendarUnit(unit) is true, or timeZone is not unset and unit is day, then + if unit.is_calendar_unit() || (time_zone.is_some() && unit == Unit::Day) { + // a. Let sign be InternalDurationSign(duration). + let sign = self.sign(); + // b. Let record be ? NudgeToCalendarUnit(sign, duration, destEpochNs, isoDateTime, timeZone, calendar, 1, unit, trunc). + let record = self.nudge_calendar_unit( + sign, + dest_epoch_ns, + dt, + time_zone, + ResolvedRoundingOptions { + largest_unit: unit, + smallest_unit: unit, + increment: RoundingIncrement::default(), + rounding_mode: RoundingMode::Trunc, + }, + )?; + + // c. Return record.[[Total]]. + return record.total.temporal_unwrap(); + } + // 2. Let timeDuration be ! Add24HourDaysToTimeDuration(duration.[[Time]], duration.[[Date]].[[Days]]). + let time_duration = self + .normalized_time_duration() + .add_days(self.date().days.as_())?; + // Return TotalTimeDuration(timeDuration, unit). + time_duration.total(unit) + } +} + +mod tests { + #[test] + fn validate_seconds_cast() { + let max_seconds = super::MAX_TIME_DURATION.div_euclid(1_000_000_000); + assert!(max_seconds <= i64::MAX.into()) + } + + // TODO: test f64 cast. +} diff --git a/deps/temporal/src/builtins/core/duration/tests.rs b/deps/temporal/src/builtins/core/duration/tests.rs new file mode 100644 index 00000000000000..6ef0453e11792f --- /dev/null +++ b/deps/temporal/src/builtins/core/duration/tests.rs @@ -0,0 +1,420 @@ +use core::str::FromStr; + +use crate::{ + options::{RoundingIncrement, RoundingOptions, ToStringRoundingOptions, Unit}, + parsers::Precision, + partial::PartialDuration, + provider::NeverProvider, +}; + +use super::Duration; + +#[test] +fn partial_duration_empty() { + let err = Duration::from_partial_duration(PartialDuration::default()); + assert!(err.is_err()) +} + +#[test] +fn partial_duration_values() { + let mut partial = PartialDuration::default(); + let _ = partial.years.insert(20); + let result = Duration::from_partial_duration(partial).unwrap(); + assert_eq!(result.years(), 20); +} + +#[test] +fn default_duration_string() { + let duration = Duration::default(); + + let options = ToStringRoundingOptions { + precision: Precision::Auto, + smallest_unit: None, + rounding_mode: None, + }; + let result = duration.as_temporal_string(options).unwrap(); + assert_eq!(&result, "PT0S"); + + let options = ToStringRoundingOptions { + precision: Precision::Digit(0), + smallest_unit: None, + rounding_mode: None, + }; + let result = duration.as_temporal_string(options).unwrap(); + assert_eq!(&result, "PT0S"); + + let options = ToStringRoundingOptions { + precision: Precision::Digit(1), + smallest_unit: None, + rounding_mode: None, + }; + let result = duration.as_temporal_string(options).unwrap(); + assert_eq!(&result, "PT0.0S"); + + let options = ToStringRoundingOptions { + precision: Precision::Digit(3), + smallest_unit: None, + rounding_mode: None, + }; + let result = duration.as_temporal_string(options).unwrap(); + assert_eq!(&result, "PT0.000S"); +} + +#[test] +fn duration_to_string_auto_precision() { + let duration = Duration::new(1, 2, 3, 4, 5, 6, 7, 0, 0, 0).unwrap(); + let result = duration + .as_temporal_string(ToStringRoundingOptions::default()) + .unwrap(); + assert_eq!(&result, "P1Y2M3W4DT5H6M7S"); + + let duration = Duration::new(1, 2, 3, 4, 5, 6, 7, 987, 650, 0).unwrap(); + let result = duration + .as_temporal_string(ToStringRoundingOptions::default()) + .unwrap(); + assert_eq!(&result, "P1Y2M3W4DT5H6M7.98765S"); +} + +#[test] +fn empty_date_duration() { + let duration = Duration::from_partial_duration(PartialDuration { + hours: Some(1.into()), + ..Default::default() + }) + .unwrap(); + let result = duration + .as_temporal_string(ToStringRoundingOptions::default()) + .unwrap(); + assert_eq!(&result, "PT1H"); +} + +#[test] +fn negative_fields_to_string() { + let duration = Duration::from_partial_duration(PartialDuration { + years: Some(-1), + months: Some(-1), + weeks: Some(-1), + days: Some(-1), + hours: Some(-1), + minutes: Some(-1), + seconds: Some(-1), + milliseconds: Some(-1), + microseconds: Some(-1), + nanoseconds: Some(-1), + }) + .unwrap(); + let result = duration + .as_temporal_string(ToStringRoundingOptions::default()) + .unwrap(); + assert_eq!(&result, "-P1Y1M1W1DT1H1M1.001001001S"); + + let duration = Duration::from_partial_duration(PartialDuration { + milliseconds: Some(-250), + ..Default::default() + }) + .unwrap(); + let result = duration + .as_temporal_string(ToStringRoundingOptions::default()) + .unwrap(); + assert_eq!(&result, "-PT0.25S"); + + let duration = Duration::from_partial_duration(PartialDuration { + milliseconds: Some(-3500), + ..Default::default() + }) + .unwrap(); + let result = duration + .as_temporal_string(ToStringRoundingOptions::default()) + .unwrap(); + assert_eq!(&result, "-PT3.5S"); + + let duration = Duration::from_partial_duration(PartialDuration { + milliseconds: Some(-3500), + ..Default::default() + }) + .unwrap(); + let result = duration + .as_temporal_string(ToStringRoundingOptions::default()) + .unwrap(); + assert_eq!(&result, "-PT3.5S"); + + let duration = Duration::from_partial_duration(PartialDuration { + weeks: Some(-1), + days: Some(-1), + ..Default::default() + }) + .unwrap(); + let result = duration + .as_temporal_string(ToStringRoundingOptions::default()) + .unwrap(); + + assert_eq!(&result, "-P1W1D"); +} + +#[test] +fn preserve_precision_loss() { + const MAX_SAFE_INT: i64 = 9_007_199_254_740_991; + let duration = Duration::from_partial_duration(PartialDuration { + milliseconds: Some(MAX_SAFE_INT), + microseconds: Some(MAX_SAFE_INT as i128), + ..Default::default() + }) + .unwrap(); + let result = duration + .as_temporal_string(ToStringRoundingOptions::default()) + .unwrap(); + + assert_eq!(&result, "PT9016206453995.731991S"); +} + +#[test] +fn duration_from_str() { + let duration = Duration::from_str("PT0.999999999H").unwrap(); + assert_eq!(duration.minutes(), 59); + assert_eq!(duration.seconds(), 59); + assert_eq!(duration.milliseconds(), 999); + assert_eq!(duration.microseconds(), 996); + assert_eq!(duration.nanoseconds(), 400); + + let duration = Duration::from_str("PT0.000000011H").unwrap(); + assert_eq!(duration.minutes(), 0); + assert_eq!(duration.seconds(), 0); + assert_eq!(duration.milliseconds(), 0); + assert_eq!(duration.microseconds(), 39); + assert_eq!(duration.nanoseconds(), 600); + + let duration = Duration::from_str("PT0.999999999M").unwrap(); + assert_eq!(duration.seconds(), 59); + assert_eq!(duration.milliseconds(), 999); + assert_eq!(duration.microseconds(), 999); + assert_eq!(duration.nanoseconds(), 940); +} + +#[test] +fn duration_max_safe() { + const MAX_SAFE_INTEGER: i64 = 9007199254740991; + + // From test262 built-ins/Temporal/Duration/prototype/subtract/result-out-of-range-3.js + assert!(Duration::new(0, 0, 0, 0, 0, 0, 0, 0, 9_007_199_254_740_991_926_258, 0).is_err()); + + // https://github.com/tc39/proposal-temporal/issues/3106#issuecomment-2849349391 + let mut options = RoundingOptions { + increment: Some(RoundingIncrement::ONE), + largest_unit: Some(Unit::Nanosecond), + ..Default::default() + }; + let d = Duration::new( + 0, + 0, + 0, + 0, + 0, + 0, + /* s = */ MAX_SAFE_INTEGER, + 0, + 0, + /* ns = */ 463_129_087, + ) + .unwrap(); + let _ = d + .round_with_provider(options, None, &NeverProvider::default()) + .expect("Must successfully round"); + let d = Duration::new( + 0, + 0, + 0, + 0, + 0, + 0, + /* s = */ MAX_SAFE_INTEGER, + 0, + 0, + /* ns = */ 463_129_088, + ) + .unwrap(); + assert!(d + .round_with_provider(options, None, &NeverProvider::default()) + .is_err()); + + options.largest_unit = Some(Unit::Microsecond); + let _ = d + .round_with_provider(options, None, &NeverProvider::default()) + .expect("Must successfully round"); + let d = Duration::new( + 0, + 0, + 0, + 0, + 0, + 0, + /* s = */ MAX_SAFE_INTEGER, + 0, + /* mis = */ 475_712, + 0, + ) + .unwrap(); + assert!(d + .round_with_provider(options, None, &NeverProvider::default()) + .is_err()); + + options.largest_unit = Some(Unit::Millisecond); + let _ = d + .round_with_provider(options, None, &NeverProvider::default()) + .expect("Must successfully round"); +} + +// Temporal/Duration/max.js +#[test] +fn duration_max() { + let cases = [ + ( + Duration::new(0, 0, 0, 104249991374, 7, 36, 31, 999, 999, 999).unwrap(), + "max days", + 9007199254740991.999999999, + ), + ( + Duration::new(0, 0, 0, 0, 2501999792983, 36, 31, 999, 999, 999).unwrap(), + "max hours", + 9007199254740991.999999999, + ), + ( + Duration::new(0, 0, 0, 0, 0, 150119987579016, 31, 999, 999, 999).unwrap(), + "max minutes", + 9007199254740991.999999999, + ), + ( + Duration::new(0, 0, 0, 0, 0, 0, 9007199254740991, 999, 999, 999).unwrap(), + "max seconds", + 9007199254740991.999999999, + ), + ( + Duration::new(0, 0, 0, -104249991374, -7, -36, -31, -999, -999, -999).unwrap(), + "min days", + -9007199254740991.999999999, + ), + ( + Duration::new(0, 0, 0, 0, -2501999792983, -36, -31, -999, -999, -999).unwrap(), + "min hours", + -9007199254740991.999999999, + ), + ( + Duration::new(0, 0, 0, 0, 0, -150119987579016, -31, -999, -999, -999).unwrap(), + "min minutes", + -9007199254740991.999999999, + ), + ( + Duration::new(0, 0, 0, 0, 0, 0, -9007199254740991, -999, -999, -999).unwrap(), + "min seconds", + -9007199254740991.999999999, + ), + ]; + + for (duration, description, result) in cases { + assert_eq!( + duration + .total_with_provider(Unit::Second, None, &NeverProvider::default()) + .unwrap() + .0, + result, + "{description}" + ); + } +} + +#[test] +fn duration_round_negative() { + let duration = Duration::new(0, 0, 0, 0, -60, 0, 0, 0, 0, 0).unwrap(); + let result = duration + .round_with_provider( + RoundingOptions { + smallest_unit: Some(Unit::Day), + ..Default::default() + }, + None, + &NeverProvider::default(), + ) + .unwrap(); + assert_eq!(result.days(), -3); +} + +#[test] +#[cfg(feature = "compiled_data")] +fn test_duration_compare() { + use crate::builtins::FS_TZ_PROVIDER; + use crate::options::{OffsetDisambiguation, RelativeTo}; + use crate::ZonedDateTime; + use alloc::string::ToString; + // TODO(#199): Make this work with Windows + // This should also ideally use the compiled data APIs and live under builtins/compiled + if cfg!(not(windows)) { + let one = Duration::from_partial_duration(PartialDuration { + hours: Some(79), + minutes: Some(10), + ..Default::default() + }) + .unwrap(); + let two = Duration::from_partial_duration(PartialDuration { + days: Some(3), + hours: Some(7), + seconds: Some(630), + ..Default::default() + }) + .unwrap(); + let three = Duration::from_partial_duration(PartialDuration { + days: Some(3), + hours: Some(6), + minutes: Some(50), + ..Default::default() + }) + .unwrap(); + + let mut arr = [&one, &two, &three]; + arr.sort_by(|a, b| Duration::compare_with_provider(a, b, None, &*FS_TZ_PROVIDER).unwrap()); + assert_eq!( + arr.map(ToString::to_string), + [&three, &one, &two].map(ToString::to_string) + ); + + // Sorting relative to a date, taking DST changes into account: + let zdt = ZonedDateTime::from_utf8_with_provider( + b"2020-11-01T00:00-07:00[America/Los_Angeles]", + Default::default(), + OffsetDisambiguation::Reject, + &*FS_TZ_PROVIDER, + ) + .unwrap(); + arr.sort_by(|a, b| { + Duration::compare_with_provider( + a, + b, + Some(RelativeTo::ZonedDateTime(zdt.clone())), + &*FS_TZ_PROVIDER, + ) + .unwrap() + }); + assert_eq!( + arr.map(ToString::to_string), + [&one, &three, &two].map(ToString::to_string) + ) + } +} +/* +TODO: Uncomment + +The below test should fail, but currently doesn't. This has to do with weird +floating point math in IsValidDuration Step 6-8 that defers to C++ std::remquo + +Needs further clarification. + +#[test] +fn duration_round_out_of_range_norm_conversion() { + const MAX_SAFE_INT: i64 = 9_007_199_254_740_991; + let duration = Duration::new(0, 0, 0, 0, 0, 0, MAX_SAFE_INT, 0, 0, 999_999_999).unwrap(); + let err = duration.round_with_provider( RoundingOptions { + largest_unit: Some(Unit::Nanosecond), + increment: Some(RoundingIncrement::ONE), + ..Default::default() + }, None, &NeverProvider::default()); + assert!(err.is_err()) +} +*/ diff --git a/deps/temporal/src/builtins/core/instant.rs b/deps/temporal/src/builtins/core/instant.rs new file mode 100644 index 00000000000000..3a6a870791ad48 --- /dev/null +++ b/deps/temporal/src/builtins/core/instant.rs @@ -0,0 +1,834 @@ +//! An implementation of the Temporal Instant. + +use alloc::string::String; +use core::{num::NonZeroU128, str::FromStr}; + +use crate::{ + builtins::core::{zoned_date_time::nanoseconds_to_formattable_offset_minutes, Duration}, + error::ErrorMessage, + iso::IsoDateTime, + options::{ + DifferenceOperation, DifferenceSettings, DisplayOffset, ResolvedRoundingOptions, + RoundingOptions, ToStringRoundingOptions, Unit, UnitGroup, + }, + parsers::{parse_instant, IxdtfStringBuilder}, + provider::TimeZoneProvider, + rounding::IncrementRounder, + unix_time::EpochNanoseconds, + Calendar, TemporalError, TemporalResult, TemporalUnwrap, TimeZone, +}; + +use ixdtf::records::UtcOffsetRecordOrZ; +use num_traits::Euclid; +use writeable::Writeable; + +use super::{ + duration::normalized::{InternalDurationRecord, TimeDuration}, + DateDuration, ZonedDateTime, +}; + +pub(crate) const NANOSECONDS_PER_SECOND: i64 = 1_000_000_000; +const NANOSECONDS_PER_MINUTE: i64 = 60 * NANOSECONDS_PER_SECOND; +const NANOSECONDS_PER_HOUR: i64 = 60 * NANOSECONDS_PER_MINUTE; + +/// The native Rust implementation of `Temporal.Instant`. +/// +/// Represents a precise moment in time measured as nanoseconds since the Unix epoch +/// (1970-01-01T00:00:00\[UTC\]). An `Instant` provides a universal timestamp +/// that represents the same moment regardless of timezone or calendar system. +/// +/// Use `Instant` when you need to record exact moments in time, measure elapsed time, +/// or work with high-precision timestamps. Unlike `PlainDateTime`, an `Instant` +/// represents an absolute point on the timeline. +/// +/// ## Examples +/// +/// ### Creating instants +/// +/// ```rust +/// use temporal_rs::Instant; +/// +/// // From epoch nanoseconds (high-precision timestamps) +/// let precise_moment = Instant::try_new(1609459200000000000).unwrap(); +/// assert_eq!(precise_moment.epoch_milliseconds(), 1609459200000); +/// +/// // From epoch milliseconds (common in web applications) +/// let web_timestamp = Instant::from_epoch_milliseconds(1609459200000).unwrap(); +/// assert_eq!(web_timestamp.epoch_nanoseconds().as_i128(), 1609459200000000000); +/// ``` +/// +/// ### Parsing ISO 8601 instant strings +/// +/// ```rust +/// use temporal_rs::Instant; +/// use core::str::FromStr; +/// +/// // Parse ISO 8601 instant strings (must include timezone info) +/// let instant = Instant::from_str("2024-03-15T14:30:45.123Z").unwrap(); +/// assert_eq!(instant.epoch_milliseconds(), 1710513045123); +/// +/// // Parse instants with different timezone notations +/// let instant2 = Instant::from_str("2024-03-15T14:30:45.123+00:00").unwrap(); +/// let instant3 = Instant::from_str("2024-03-15T14:30:45.123-00:00").unwrap(); +/// assert_eq!(instant, instant2); +/// assert_eq!(instant2, instant3); +/// ``` +/// +/// ### Instant arithmetic +/// +/// ```rust +/// use temporal_rs::{Instant, Duration}; +/// use core::str::FromStr; +/// +/// let instant = Instant::try_new(1609459200000000000).unwrap(); // 2021-01-01T00:00:00Z +/// +/// // Add time duration (only time durations, not date durations) +/// let later = instant.add(&Duration::from_str("PT1H30M").unwrap()).unwrap(); +/// let expected_ns = 1609459200000000000 + (1 * 3600 + 30 * 60) * 1_000_000_000; +/// assert_eq!(later.epoch_nanoseconds().as_i128(), expected_ns); +/// +/// // Calculate difference between instants +/// let earlier = Instant::try_new(1609459200000000000 - 3600_000_000_000).unwrap(); +/// let duration = earlier.until(&instant, Default::default()).unwrap(); +/// assert_eq!(duration.seconds(), 3600); +/// ``` +/// +/// ### Instant precision and limits +/// +/// ```rust +/// use temporal_rs::Instant; +/// +/// // Instants have well-defined limits based on approximately 100 million days before/after Unix epoch +/// let max_ns = 8_640_000_000_000_000_000_000i128; // ~100M days * 24 * 60 * 60 * 1e9 +/// let min_ns = -max_ns; +/// +/// let max_instant = Instant::try_new(max_ns).unwrap(); +/// let min_instant = Instant::try_new(min_ns).unwrap(); +/// +/// // Values outside the range will fail +/// assert!(Instant::try_new(max_ns + 1).is_err()); +/// assert!(Instant::try_new(min_ns - 1).is_err()); +/// ``` +/// +/// ### Converting to ZonedDateTime (requires provider) +/// +/// ```rust,ignore +/// use temporal_rs::{Instant, TimeZone, Calendar}; +/// +/// let instant = Instant::try_new(1609459200000000000).unwrap(); +/// let timezone = TimeZone::try_from_str("America/New_York").unwrap(); +/// +/// // Convert to a zoned date-time for display in local time +/// let zdt = instant.to_zoned_date_time_iso(timezone); +/// assert_eq!(zdt.timezone().identifier(), "America/New_York"); +/// assert_eq!(zdt.calendar().identifier(), "iso8601"); +/// ``` +/// +/// ### Rounding instants +/// +/// ```rust +/// use temporal_rs::{Instant, options::{RoundingOptions, Unit}}; +/// +/// let instant = Instant::try_new(1609459245123456789).unwrap(); // some precise moment +/// +/// let mut opts = RoundingOptions::default(); +/// opts.smallest_unit = Some(Unit::Second); +/// let rounded = instant.round(opts).unwrap(); +/// +/// // Rounded to the nearest second +/// assert_eq!(rounded.epoch_nanoseconds().as_i128() % 1_000_000_000, 0); +/// ``` +/// +/// ## Reference +/// +/// For more information, see the [MDN documentation][mdn-instant]. +/// +/// [mdn-instant]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant +#[non_exhaustive] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct Instant(EpochNanoseconds); + +impl From for Instant { + fn from(value: EpochNanoseconds) -> Self { + Self(value) + } +} + +// ==== Private API ==== + +impl Instant { + /// Adds a `TimeDuration` to the current `Instant`. + /// + /// Temporal-Proposal equivalent: `AddInstant`. + pub(crate) fn add_to_instant(&self, duration: &TimeDuration) -> TemporalResult { + // 1. Let result be AddTimeDurationToEpochNanoseconds(timeDuration, epochNanoseconds). + let result = self.epoch_nanoseconds().0 + duration.0; + let ns = EpochNanoseconds::from(result); + // 2. If IsValidEpochNanoseconds(result) is false, throw a RangeError exception. + ns.check_validity()?; + // 3. Return result. + Ok(Self::from(ns)) + } + + /// 8.5.10 AddDurationToInstant ( operation, instant, temporalDurationLike ) + pub(crate) fn add_duration_to_instant(&self, duration: &Duration) -> TemporalResult { + // 3. Let largestUnit be DefaultTemporalLargestUnit(duration). + let largest_unit = duration.default_largest_unit(); + // 4. If TemporalUnitCategory(largestUnit) is date, throw a RangeError exception. + if largest_unit.is_date_unit() { + return Err(TemporalError::range().with_enum(ErrorMessage::LargestUnitCannotBeDateUnit)); + } + // 5. Let internalDuration be ToInternalDurationRecordWith24HourDays(duration). + let internal_duration = InternalDurationRecord::from_duration_with_24_hour_days(duration)?; + // 6. Let ns be ? AddInstant(instant.[[EpochNanoseconds]], internalDuration.[[Time]]). + // 7. Return ! CreateTemporalInstant(ns). + self.add_to_instant(&internal_duration.normalized_time_duration()) + } + + /// `temporal_rs` equivalent of `DifferenceInstant` + pub(crate) fn diff_instant_internal( + &self, + other: &Self, + resolved_options: ResolvedRoundingOptions, + ) -> TemporalResult { + let diff = TimeDuration::from_nanosecond_difference(other.as_i128(), self.as_i128())?; + let normalized_time = diff.round(resolved_options)?; + InternalDurationRecord::new(DateDuration::default(), normalized_time) + } + + // TODO: Add test for `diff_instant`. + // NOTE(nekevss): As the below is internal, op will be left as a boolean + // with a `since` op being true and `until` being false. + /// Internal operation to handle `since` and `until` difference ops. + pub(crate) fn diff_instant( + &self, + op: DifferenceOperation, + other: &Self, + options: DifferenceSettings, + ) -> TemporalResult { + // 1. If operation is since, let sign be -1. Otherwise, let sign be 1. + // 2. Set other to ? ToTemporalInstant(other). + // 3. Let resolvedOptions be ? SnapshotOwnProperties(? GetOptionsObject(options), null). + // 4. Let settings be ? GetDifferenceSettings(operation, resolvedOptions, time, « », "nanosecond", "second"). + let resolved_options = ResolvedRoundingOptions::from_diff_settings( + options, + op, + UnitGroup::Time, + Unit::Second, + Unit::Nanosecond, + )?; + + // Below are the steps from Difference Instant. + // 5. Let diffRecord be DifferenceInstant(instant.[[Nanoseconds]], other.[[Nanoseconds]], + // settings.[[RoundingIncrement]], settings.[[SmallestUnit]], settings.[[RoundingMode]]). + let internal_record = self.diff_instant_internal(other, resolved_options)?; + + let result = Duration::from_internal(internal_record, resolved_options.largest_unit)?; + + // 6. Let norm be diffRecord.[[TimeDuration]]. + // 7. Let result be ! BalanceTimeDuration(norm, settings.[[LargestUnit]]). + // 8. Return ! CreateTemporalDuration(0, 0, 0, 0, sign × result.[[Hours]], sign × result.[[Minutes]], sign × result.[[Seconds]], sign × result.[[Milliseconds]], sign × result.[[Microseconds]], sign × result.[[Nanoseconds]]). + match op { + DifferenceOperation::Until => Ok(result), + DifferenceOperation::Since => Ok(result.negated()), + } + } + + /// Rounds a current `Instant` given the resolved options, returning a `BigInt` result. + pub(crate) fn round_instant( + &self, + resolved_options: ResolvedRoundingOptions, + ) -> TemporalResult { + let increment = resolved_options.increment.as_extended_increment(); + let increment = match resolved_options.smallest_unit { + Unit::Hour => increment + .checked_mul(NonZeroU128::new(NANOSECONDS_PER_HOUR as u128).temporal_unwrap()?), + Unit::Minute => increment + .checked_mul(NonZeroU128::new(NANOSECONDS_PER_MINUTE as u128).temporal_unwrap()?), + Unit::Second => increment + .checked_mul(NonZeroU128::new(NANOSECONDS_PER_SECOND as u128).temporal_unwrap()?), + Unit::Millisecond => { + increment.checked_mul(NonZeroU128::new(1_000_000).temporal_unwrap()?) + } + Unit::Microsecond => increment.checked_mul(NonZeroU128::new(1_000).temporal_unwrap()?), + Unit::Nanosecond => Some(increment), + _ => { + return Err(TemporalError::range() + .with_message("Invalid unit provided for Instant::round.")) + } + }; + + // NOTE: Potentially remove the below and just `temporal_unwrap` + let Some(increment) = increment else { + return Err(TemporalError::range().with_message("Increment exceeded a valid range.")); + }; + + let rounded = IncrementRounder::::from_signed_num(self.as_i128(), increment)? + .round_as_if_positive(resolved_options.rounding_mode); + + Ok(rounded) + } + + // Utility for converting `Instant` to `i128`. + pub fn as_i128(&self) -> i128 { + self.epoch_nanoseconds().0 + } +} + +// ==== Public API ==== + +impl Instant { + /// Create a new validated `Instant`. + #[inline] + pub fn try_new(nanoseconds: i128) -> TemporalResult { + let ns = EpochNanoseconds::from(nanoseconds); + ns.check_validity()?; + Ok(Self::from(ns)) + } + + /// Creates a new `Instant` from the provided Epoch millisecond value. + pub fn from_epoch_milliseconds(epoch_milliseconds: i64) -> TemporalResult { + // Input at most is `i64::MAX`. This means guarantees that the + // transition into nanoseconds MUST be in range of `i128` + let epoch_nanos = (epoch_milliseconds as i128) * 1_000_000; + Self::try_new(epoch_nanos) + } + + // Converts a UTF-8 encoded string into a `Instant`. + pub fn from_utf8(s: &[u8]) -> TemporalResult { + let ixdtf_record = parse_instant(s)?; + + // Find the offset + let ns_offset = match ixdtf_record.offset { + UtcOffsetRecordOrZ::Offset(offset) => { + let ns = offset + .fraction() + .and_then(|x| x.to_nanoseconds()) + .unwrap_or(0); + (offset.hour() as i64 * NANOSECONDS_PER_HOUR + + i64::from(offset.minute()) * NANOSECONDS_PER_MINUTE + + i64::from(offset.second().unwrap_or(0)) * NANOSECONDS_PER_SECOND + + i64::from(ns)) + * offset.sign() as i64 + } + UtcOffsetRecordOrZ::Z => 0, + }; + + let time_nanoseconds = ixdtf_record + .time + .fraction + .and_then(|x| x.to_nanoseconds()) + .unwrap_or(0); + let (millisecond, rem) = time_nanoseconds.div_rem_euclid(&1_000_000); + let (microsecond, nanosecond) = rem.div_rem_euclid(&1_000); + + let balanced = IsoDateTime::balance( + ixdtf_record.date.year, + ixdtf_record.date.month.into(), + ixdtf_record.date.day.into(), + ixdtf_record.time.hour.into(), + ixdtf_record.time.minute.into(), + ixdtf_record.time.second.clamp(0, 59).into(), + millisecond.into(), + microsecond.into(), + i128::from(nanosecond) - i128::from(ns_offset), + ); + + let nanoseconds = balanced.as_nanoseconds(); + + nanoseconds.check_validity()?; + + Ok(Self(nanoseconds)) + } + + /// Adds a `Duration` to the current `Instant`, returning an error if the `Duration` + /// contains a `DateDuration`. + #[inline] + pub fn add(&self, duration: &Duration) -> TemporalResult { + self.add_duration_to_instant(duration) + } + + /// Subtract a `Duration` to the current `Instant`, returning an error if the `Duration` + /// contains a `DateDuration`. + #[inline] + pub fn subtract(&self, duration: &Duration) -> TemporalResult { + self.add_duration_to_instant(&duration.negated()) + } + + /// Returns a `Duration` representing the duration since provided `Instant` + #[inline] + pub fn since(&self, other: &Self, settings: DifferenceSettings) -> TemporalResult { + self.diff_instant(DifferenceOperation::Since, other, settings) + } + + /// Returns a `Duration` representing the duration until provided `Instant` + #[inline] + pub fn until(&self, other: &Self, settings: DifferenceSettings) -> TemporalResult { + self.diff_instant(DifferenceOperation::Until, other, settings) + } + + /// Returns an `Instant` by rounding the current `Instant` according to the provided settings. + #[inline] + pub fn round(&self, options: RoundingOptions) -> TemporalResult { + let resolved_options = ResolvedRoundingOptions::from_instant_options(options)?; + + let round_result = self.round_instant(resolved_options)?; + Self::try_new(round_result) + } + + /// Returns the `epochMilliseconds` value for this `Instant`. + #[inline] + #[must_use] + pub fn epoch_milliseconds(&self) -> i64 { + self.as_i128().div_euclid(1_000_000) as i64 + } + + /// Returns the [`EpochNanoseconds`] value for this `Instant`. + #[inline] + #[must_use] + pub fn epoch_nanoseconds(&self) -> &EpochNanoseconds { + &self.0 + } + + /// Returns a [`ZonedDateTime`] for the current `Instant`. + #[inline] + pub fn to_zoned_date_time_iso_with_provider( + &self, + time_zone: TimeZone, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + ZonedDateTime::new_unchecked_with_provider(*self, time_zone, Calendar::ISO, provider) + } +} + +// ==== Instant Provider API ==== + +impl Instant { + /// Returns an RFC9557 IXDTF string representing the current `Instant`. + pub fn to_ixdtf_string_with_provider( + &self, + timezone: Option, + options: ToStringRoundingOptions, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + self.to_ixdtf_writeable_with_provider(timezone, options, provider) + .map(|x| x.write_to_string().into()) + } + + /// Returns a [`Writeable`] for formatting the current `Instant` in RFC9557's IXDTF. + pub fn to_ixdtf_writeable_with_provider( + &self, + timezone: Option, + options: ToStringRoundingOptions, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let resolved_options = options.resolve()?; + let round = self.round_instant(ResolvedRoundingOptions::from_to_string_options( + &resolved_options, + ))?; + let rounded_instant = Instant::try_new(round)?; + + let mut ixdtf = IxdtfStringBuilder::default(); + let datetime = if let Some(timezone) = timezone { + let datetime = timezone.get_iso_datetime_for(&rounded_instant, provider)?; + let nanoseconds = timezone.get_offset_nanos_for(rounded_instant.as_i128(), provider)?; + let (sign, hour, minute) = nanoseconds_to_formattable_offset_minutes(nanoseconds)?; + ixdtf = ixdtf.with_minute_offset(sign, hour, minute, DisplayOffset::Auto); + datetime + } else { + ixdtf = ixdtf.with_z(DisplayOffset::Auto); + TimeZone::utc_with_provider(provider) + .get_iso_datetime_for(&rounded_instant, provider)? + }; + let builder = ixdtf + .with_date(datetime.date) + .with_time(datetime.time, resolved_options.precision); + + Ok(builder) + } +} + +// ==== Utility Functions ==== + +impl FromStr for Instant { + type Err = TemporalError; + + fn from_str(s: &str) -> Result { + Self::from_utf8(s.as_bytes()) + } +} + +// ==== Instant Tests ==== + +#[cfg(test)] +mod tests { + + use core::str::FromStr; + + use crate::{ + builtins::{core::Instant, duration::duration_sign}, + options::{DifferenceSettings, RoundingMode, Unit}, + partial::PartialDuration, + unix_time::EpochNanoseconds, + Duration, NS_MAX_INSTANT, NS_MIN_INSTANT, + }; + + #[test] + #[allow(clippy::float_cmp)] + fn max_and_minimum_instant_bounds() { + // This test is primarily to assert that the `expect` in the epoch methods is + // valid, i.e., a valid instant is within the range of an f64. + let max = NS_MAX_INSTANT; + let min = NS_MIN_INSTANT; + let max_instant = Instant::try_new(max).unwrap(); + let min_instant = Instant::try_new(min).unwrap(); + + assert_eq!(max_instant.epoch_nanoseconds().0, max); + assert_eq!(min_instant.epoch_nanoseconds().0, min); + + let max_plus_one = NS_MAX_INSTANT + 1; + let min_minus_one = NS_MIN_INSTANT - 1; + + assert!(Instant::try_new(max_plus_one).is_err()); + assert!(Instant::try_new(min_minus_one).is_err()); + } + + #[test] + fn max_min_epoch_millseconds() { + // Assert the casting is valid. + let max = NS_MAX_INSTANT; + let min = NS_MIN_INSTANT; + let max_instant = Instant::try_new(max).unwrap(); + let min_instant = Instant::try_new(min).unwrap(); + + // Assert max and min are valid for casting. + assert_eq!( + max_instant.epoch_milliseconds(), + max.div_euclid(1_000_000) as i64 + ); + assert_eq!( + min_instant.epoch_milliseconds(), + min.div_euclid(1_000_000) as i64 + ); + // Assert the max and min are not being truncated. + assert_ne!(max_instant.epoch_milliseconds(), i64::MAX); + assert_ne!(max_instant.epoch_milliseconds(), i64::MIN); + } + + #[test] + fn instant_parsing_limits() { + // valid cases + let valid_str = "-271821-04-20T00:00Z"; + let instant = Instant::from_str(valid_str).unwrap(); + assert_eq!( + instant, + Instant::from(EpochNanoseconds(-8640000000000000000000)) + ); + + let valid_str = "-271821-04-19T23:00-01:00"; + let instant = Instant::from_str(valid_str).unwrap(); + assert_eq!( + instant, + Instant::from(EpochNanoseconds(-8640000000000000000000)) + ); + + let valid_str = "-271821-04-19T00:00:00.000000001-23:59:59.999999999"; + let instant = Instant::from_str(valid_str).unwrap(); + assert_eq!( + instant, + Instant::from(EpochNanoseconds(-8640000000000000000000)) + ); + + let valid_str = "+275760-09-13T00:00Z"; + let instant = Instant::from_str(valid_str).unwrap(); + assert_eq!( + instant, + Instant::from(EpochNanoseconds(8640000000000000000000)) + ); + + // invalid cases + let invalid_str = "-271821-04-19T00:00Z"; + let instant = Instant::from_str(invalid_str); + assert!(instant.is_err()); + + let invalid_str = "-271821-04-19T23:59:59.999999999Z"; + let instant = Instant::from_str(invalid_str); + assert!(instant.is_err()); + + let invalid_str = "-271821-04-19T23:00-00:59:59.999999999"; + let instant = Instant::from_str(invalid_str); + assert!(instant.is_err()); + } + + #[test] + fn basic_instant_until() { + let init_diff_setting = |unit: Unit| -> DifferenceSettings { + DifferenceSettings { + largest_unit: Some(Unit::Hour), + rounding_mode: Some(RoundingMode::Ceil), + increment: None, + smallest_unit: Some(unit), + } + }; + + let assert_duration = |td: Duration, expected: (i64, i64, i64, i64, i128, i128)| { + assert_eq!( + td, + Duration { + sign: duration_sign(&[ + expected.0, + expected.1, + expected.2, + expected.3, + expected.4 as i64, + expected.5 as i64 + ]), + hours: expected.0.unsigned_abs(), + minutes: expected.1.unsigned_abs(), + seconds: expected.2.unsigned_abs(), + milliseconds: expected.3.unsigned_abs(), + microseconds: expected.4.unsigned_abs(), + nanoseconds: expected.5.unsigned_abs(), + ..Default::default() + } + ) + }; + + let earlier = Instant::try_new( + 217_178_610_123_456_789, /* 1976-11-18T15:23:30.123456789Z */ + ) + .unwrap(); + let later = Instant::try_new( + 1_572_345_998_271_986_289, /* 2019-10-29T10:46:38.271986289Z */ + ) + .unwrap(); + + let positive_result = earlier + .until(&later, init_diff_setting(Unit::Hour)) + .unwrap(); + assert_duration(positive_result, (376436, 0, 0, 0, 0, 0)); + let negative_result = later + .until(&earlier, init_diff_setting(Unit::Hour)) + .unwrap(); + assert_duration(negative_result, (-376435, 0, 0, 0, 0, 0)); + + let positive_result = earlier + .until(&later, init_diff_setting(Unit::Minute)) + .unwrap(); + assert_duration(positive_result, (376435, 24, 0, 0, 0, 0)); + let negative_result = later + .until(&earlier, init_diff_setting(Unit::Minute)) + .unwrap(); + assert_duration(negative_result, (-376435, -23, 0, 0, 0, 0)); + + // ... Skip to lower units ... + + let positive_result = earlier + .until(&later, init_diff_setting(Unit::Microsecond)) + .unwrap(); + assert_duration(positive_result, (376435, 23, 8, 148, 530, 0)); + let negative_result = later + .until(&earlier, init_diff_setting(Unit::Microsecond)) + .unwrap(); + assert_duration(negative_result, (-376435, -23, -8, -148, -529, 0)); + + let positive_result = earlier + .until(&later, init_diff_setting(Unit::Nanosecond)) + .unwrap(); + assert_duration(positive_result, (376435, 23, 8, 148, 529, 500)); + let negative_result = later + .until(&earlier, init_diff_setting(Unit::Nanosecond)) + .unwrap(); + assert_duration(negative_result, (-376435, -23, -8, -148, -529, -500)); + } + + #[test] + fn basic_instant_since() { + let init_diff_setting = |unit: Unit| -> DifferenceSettings { + DifferenceSettings { + largest_unit: Some(Unit::Hour), + rounding_mode: Some(RoundingMode::Ceil), + increment: None, + smallest_unit: Some(unit), + } + }; + + let assert_duration = |td: Duration, expected: (i64, i64, i64, i64, i128, i128)| { + assert_eq!( + td, + Duration { + sign: duration_sign(&[ + expected.0, + expected.1, + expected.2, + expected.3, + expected.4 as i64, + expected.5 as i64 + ]), + hours: expected.0.unsigned_abs(), + minutes: expected.1.unsigned_abs(), + seconds: expected.2.unsigned_abs(), + milliseconds: expected.3.unsigned_abs(), + microseconds: expected.4.unsigned_abs(), + nanoseconds: expected.5.unsigned_abs(), + ..Default::default() + } + ) + }; + + let earlier = Instant::try_new( + 217_178_610_123_456_789, /* 1976-11-18T15:23:30.123456789Z */ + ) + .unwrap(); + let later = Instant::try_new( + 1_572_345_998_271_986_289, /* 2019-10-29T10:46:38.271986289Z */ + ) + .unwrap(); + + let positive_result = later + .since(&earlier, init_diff_setting(Unit::Hour)) + .unwrap(); + assert_duration(positive_result, (376436, 0, 0, 0, 0, 0)); + let negative_result = earlier + .since(&later, init_diff_setting(Unit::Hour)) + .unwrap(); + assert_duration(negative_result, (-376435, 0, 0, 0, 0, 0)); + + let positive_result = later + .since(&earlier, init_diff_setting(Unit::Minute)) + .unwrap(); + assert_duration(positive_result, (376435, 24, 0, 0, 0, 0)); + let negative_result = earlier + .since(&later, init_diff_setting(Unit::Minute)) + .unwrap(); + assert_duration(negative_result, (-376435, -23, 0, 0, 0, 0)); + + // ... Skip to lower units ... + + let positive_result = later + .since(&earlier, init_diff_setting(Unit::Microsecond)) + .unwrap(); + assert_duration(positive_result, (376435, 23, 8, 148, 530, 0)); + let negative_result = earlier + .since(&later, init_diff_setting(Unit::Microsecond)) + .unwrap(); + assert_duration(negative_result, (-376435, -23, -8, -148, -529, 0)); + + let positive_result = later + .since(&earlier, init_diff_setting(Unit::Nanosecond)) + .unwrap(); + assert_duration(positive_result, (376435, 23, 8, 148, 529, 500)); + let negative_result = earlier + .since(&later, init_diff_setting(Unit::Nanosecond)) + .unwrap(); + assert_duration(negative_result, (-376435, -23, -8, -148, -529, -500)); + } + + // /test/built-ins/Temporal/Instant/prototype/add/cross-epoch.js + #[cfg(feature = "tzdb")] + #[test] + fn instant_add_across_epoch() { + use crate::builtins::core::Duration; + use crate::{ + options::ToStringRoundingOptions, partial::PartialDuration, tzdb::FsTzdbProvider, + }; + use core::str::FromStr; + + let instant = Instant::from_str("1969-12-25T12:23:45.678901234Z").unwrap(); + let one = instant + .subtract( + &Duration::from_partial_duration(PartialDuration { + hours: Some(240.into()), + nanoseconds: Some(800.into()), + ..Default::default() + }) + .unwrap(), + ) + .unwrap(); + let two = instant + .add( + &Duration::from_partial_duration(PartialDuration { + hours: Some(240.into()), + nanoseconds: Some(800.into()), + ..Default::default() + }) + .unwrap(), + ) + .unwrap(); + let three = two + .subtract( + &Duration::from_partial_duration(PartialDuration { + hours: Some(480.into()), + nanoseconds: Some(1600.into()), + ..Default::default() + }) + .unwrap(), + ) + .unwrap(); + let four = one + .add( + &Duration::from_partial_duration(PartialDuration { + hours: Some(480.into()), + nanoseconds: Some(1600.into()), + ..Default::default() + }) + .unwrap(), + ) + .unwrap(); + + let one_comp = Instant::from_str("1969-12-15T12:23:45.678900434Z").unwrap(); + let two_comp = Instant::from_str("1970-01-04T12:23:45.678902034Z").unwrap(); + + // Assert the comparisons all hold. + assert_eq!(one, one_comp); + assert_eq!(two, two_comp); + assert_eq!(three, one); + assert_eq!(four, two); + + // Assert the to_string is valid. + let provider = &FsTzdbProvider::default(); + let inst_string = instant + .to_ixdtf_string_with_provider(None, ToStringRoundingOptions::default(), provider) + .unwrap(); + let one_string = one + .to_ixdtf_string_with_provider(None, ToStringRoundingOptions::default(), provider) + .unwrap(); + let two_string = two + .to_ixdtf_string_with_provider(None, ToStringRoundingOptions::default(), provider) + .unwrap(); + + assert_eq!(&inst_string, "1969-12-25T12:23:45.678901234Z"); + assert_eq!(&one_string, "1969-12-15T12:23:45.678900434Z"); + assert_eq!(&two_string, "1970-01-04T12:23:45.678902034Z"); + } + + // Adapted from add[subtract]/minimum-maximum-instant.js + #[test] + fn instant_add_subtract_max_min() { + let min = Instant::try_new(-86_40000_00000_00000_00000).unwrap(); + let max = Instant::try_new(86_40000_00000_00000_00000).unwrap(); + + let zero = Duration::from_partial_duration(PartialDuration::default().with_nanoseconds(0)) + .unwrap(); + let one = Duration::from_partial_duration(PartialDuration::default().with_nanoseconds(1)) + .unwrap(); + let neg_one = + Duration::from_partial_duration(PartialDuration::default().with_nanoseconds(-1)) + .unwrap(); + // Adding/subtracting zero does not cross max/min boundary. + assert_eq!(min.add(&zero).unwrap(), min); + assert_eq!(min.subtract(&zero).unwrap(), min); + + // Addition or subtraction crosses boundary. + assert!(max.add(&one).is_err()); + assert!(max.subtract(&neg_one).is_err()); + assert!(min.add(&neg_one).is_err()); + assert!(min.subtract(&one).is_err()); + + let insanely_large_partial = + PartialDuration::default().with_nanoseconds(-86_40000_00000_00000_00000 * 2); + let large_duration = Duration::from_partial_duration(insanely_large_partial).unwrap(); + assert_eq!(min.subtract(&large_duration).unwrap(), max); + assert_eq!(max.add(&large_duration).unwrap(), min); + } +} diff --git a/deps/temporal/src/builtins/core/mod.rs b/deps/temporal/src/builtins/core/mod.rs new file mode 100644 index 00000000000000..39429d41038b1a --- /dev/null +++ b/deps/temporal/src/builtins/core/mod.rs @@ -0,0 +1,41 @@ +//! The primary date-time components provided by Temporal. +//! +//! The Temporal specification, along with this implementation aims to +//! provide full support for time zones and non-gregorian calendars that +//! are compliant with standards like ISO 8601, RFC 3339, and RFC 5545. + +// TODO: Expand upon above introduction. + +pub mod calendar; +pub mod duration; +pub mod time_zone; + +mod instant; +mod plain_date; +mod plain_date_time; +mod plain_month_day; +mod plain_time; +mod plain_year_month; +pub(crate) mod zoned_date_time; + +mod now; + +#[doc(inline)] +pub use now::Now; + +#[doc(inline)] +pub use duration::{DateDuration, Duration, PartialDuration}; +#[doc(inline)] +pub use instant::Instant; +#[doc(inline)] +pub use plain_date::{PartialDate, PlainDate}; +#[doc(inline)] +pub use plain_date_time::{DateTimeFields, PartialDateTime, PlainDateTime}; +#[doc(inline)] +pub use plain_month_day::PlainMonthDay; +#[doc(inline)] +pub use plain_time::{PartialTime, PlainTime}; +#[doc(inline)] +pub use plain_year_month::{PartialYearMonth, PlainYearMonth}; +#[doc(inline)] +pub use zoned_date_time::{PartialZonedDateTime, ZonedDateTime, ZonedDateTimeFields}; diff --git a/deps/temporal/src/builtins/core/now.rs b/deps/temporal/src/builtins/core/now.rs new file mode 100644 index 00000000000000..bc640f50f165ec --- /dev/null +++ b/deps/temporal/src/builtins/core/now.rs @@ -0,0 +1,224 @@ +//! The Temporal Now component + +use crate::iso::IsoDateTime; +use crate::TemporalResult; +use crate::{host::HostHooks, provider::TimeZoneProvider}; + +use super::{ + calendar::Calendar, time_zone::TimeZone, Instant, PlainDate, PlainDateTime, PlainTime, + ZonedDateTime, +}; + +pub struct Now { + host_hooks: H, +} + +impl Now { + /// Create a new `Now` + pub const fn new(host_hooks: H) -> Self { + Self { host_hooks } + } +} + +impl Now { + pub(crate) fn system_datetime_with_provider( + self, + time_zone: Option, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let system_nanoseconds = self.host_hooks.get_system_epoch_nanoseconds()?; + let time_zone = time_zone.unwrap_or(self.host_hooks.get_system_time_zone(provider)?); + time_zone.get_iso_datetime_for(&Instant::from(system_nanoseconds), provider) + } + + /// Converts the current [`Now`] into a [`TimeZone`]. + pub fn time_zone_with_provider( + self, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + self.host_hooks.get_system_time_zone(provider) + } + + /// Converts the current [`Now`] into an [`Instant`]. + pub fn instant(self) -> TemporalResult { + Ok(Instant::from( + self.host_hooks.get_system_epoch_nanoseconds()?, + )) + } + + /// Converts the current [`Now`] into an [`ZonedDateTime`] with an ISO8601 calendar. + pub fn zoned_date_time_iso_with_provider( + self, + time_zone: Option, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let system_nanoseconds = self.host_hooks.get_system_epoch_nanoseconds()?; + let time_zone = time_zone.unwrap_or(self.host_hooks.get_system_time_zone(provider)?); + let instant = Instant::from(system_nanoseconds); + ZonedDateTime::new_unchecked_with_provider(instant, time_zone, Calendar::ISO, provider) + } +} + +impl Now { + /// Converts `Now` into the current system [`PlainDateTime`] with an ISO8601 calendar. + /// + /// When `TimeZone` is `None`, the value will default to the + /// system time zone or UTC if the system zone is unavailable. + pub fn plain_date_time_iso_with_provider( + self, + time_zone: Option, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let iso = self.system_datetime_with_provider(time_zone, provider)?; + Ok(PlainDateTime::new_unchecked(iso, Calendar::ISO)) + } + + /// Converts `Now` into the current system [`PlainDate`] with an ISO8601 calendar. + /// + /// When `TimeZone` is `None`, the value will default to the + /// system time zone or UTC if the system zone is unavailable. + pub fn plain_date_iso_with_provider( + self, + time_zone: Option, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let iso = self.system_datetime_with_provider(time_zone, provider)?; + Ok(PlainDate::new_unchecked(iso.date, Calendar::ISO)) + } + + /// Converts `Now` into the current system [`PlainTime`]. + /// + /// When `TimeZone` is `None`, the value will default to the + /// system time zone or UTC if the system zone is unavailable. + pub fn plain_time_with_provider( + self, + time_zone: Option, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let iso = self.system_datetime_with_provider(time_zone, provider)?; + Ok(PlainTime::new_unchecked(iso.time)) + } +} + +#[cfg(test)] +mod tests { + + #[cfg(feature = "tzdb")] + use crate::options::DifferenceSettings; + #[cfg(feature = "tzdb")] + use crate::unix_time::EpochNanoseconds; + + #[cfg(feature = "tzdb")] + #[test] + fn mocked_datetime() { + use timezone_provider::provider::TimeZoneProvider; + + use crate::{ + host::{HostClock, HostHooks, HostTimeZone}, + now::Now, + tzdb::FsTzdbProvider, + TemporalResult, TimeZone, + }; + let provider = FsTzdbProvider::default(); + + // Define mock test hooks + struct TestHooks { + seconds_to_add: i128, + time_zone: TimeZone, + } + + impl TestHooks { + fn new(seconds_to_add: i128, time_zone: TimeZone) -> Self { + Self { + seconds_to_add, + time_zone, + } + } + } + + impl HostHooks for TestHooks {} + + impl HostClock for TestHooks { + fn get_host_epoch_nanoseconds(&self) -> TemporalResult { + // 2025-03-11T10:47-06:00 + const TIME_BASE: i128 = 1_741_751_188_077_363_694; + let epoch_nanoseconds = TIME_BASE + (self.seconds_to_add * 1_000_000_000); + Ok(EpochNanoseconds::from(epoch_nanoseconds)) + } + } + + impl HostTimeZone for TestHooks { + fn get_host_time_zone(&self, _: &impl TimeZoneProvider) -> TemporalResult { + Ok(self.time_zone) + } + } + + // Define a UtcOffset zone + let cdt = TimeZone::try_from_identifier_str_with_provider("-05:00", &provider).unwrap(); + + // Define an IANA id zone + let uschi = + TimeZone::try_from_identifier_str_with_provider("America/Chicago", &provider).unwrap(); + + let now = Now::new(TestHooks::new(0, cdt)); + let cdt_datetime = now + .plain_date_time_iso_with_provider(None, &provider) + .unwrap(); + assert_eq!(cdt_datetime.year(), 2025); + assert_eq!(cdt_datetime.month(), 3); + assert_eq!(cdt_datetime.month_code().as_str(), "M03"); + assert_eq!(cdt_datetime.day(), 11); + assert_eq!(cdt_datetime.hour(), 22); + assert_eq!(cdt_datetime.minute(), 46); + assert_eq!(cdt_datetime.second(), 28); + assert_eq!(cdt_datetime.millisecond(), 77); + assert_eq!(cdt_datetime.microsecond(), 363); + assert_eq!(cdt_datetime.nanosecond(), 694); + + let now_cdt = Now::new(TestHooks::new(0, cdt)); + let uschi_datetime = now_cdt + .plain_date_time_iso_with_provider(Some(uschi), &provider) + .unwrap(); + assert_eq!(cdt_datetime, uschi_datetime); + + let plus_5_now = Now::new(TestHooks::new(5, cdt)); + let plus_5_pdt = plus_5_now + .plain_date_time_iso_with_provider(None, &provider) + .unwrap(); + assert_eq!(plus_5_pdt.second(), 33); + + let duration = cdt_datetime + .until(&plus_5_pdt, DifferenceSettings::default()) + .unwrap(); + assert_eq!(duration.hours(), 0); + assert_eq!(duration.minutes(), 0); + assert_eq!(duration.seconds(), 5); + assert_eq!(duration.milliseconds(), 0); + } + + #[cfg(all(feature = "tzdb", feature = "sys", feature = "compiled_data"))] + #[test] + fn now_datetime_test() { + use crate::Temporal; + use std::thread; + use std::time::Duration as StdDuration; + + let sleep = 2; + + let before = Temporal::now().plain_date_time_iso(None).unwrap(); + thread::sleep(StdDuration::from_secs(sleep)); + let after = Temporal::now().plain_date_time_iso(None).unwrap(); + + let diff = after.since(&before, DifferenceSettings::default()).unwrap(); + + let sleep_base = sleep as i64; + let tolerable_range = sleep_base..=sleep_base + 5; + + // We assert a tolerable range of sleep + 5 because std::thread::sleep + // is only guaranteed to be >= the value to sleep. So to prevent sporadic + // errors, we only assert a range. + assert!(tolerable_range.contains(&diff.seconds())); + assert_eq!(diff.hours(), 0); + assert_eq!(diff.minutes(), 0); + } +} diff --git a/deps/temporal/src/builtins/core/plain_date.rs b/deps/temporal/src/builtins/core/plain_date.rs new file mode 100644 index 00000000000000..90b5c4e4227bc1 --- /dev/null +++ b/deps/temporal/src/builtins/core/plain_date.rs @@ -0,0 +1,1044 @@ +//! This module implements `PlainDate` and any directly related algorithms. + +use crate::parsed_intermediates::ParsedDate; +use crate::{ + builtins::{ + calendar::{CalendarFields, YearMonthCalendarFields}, + core::{ + calendar::Calendar, duration::DateDuration, Duration, PlainDateTime, PlainTime, + ZonedDateTime, + }, + }, + iso::{IsoDate, IsoDateTime, IsoTime}, + options::{ + DifferenceOperation, DifferenceSettings, Disambiguation, DisplayCalendar, Overflow, + ResolvedRoundingOptions, Unit, UnitGroup, + }, + parsers::IxdtfStringBuilder, + provider::{NeverProvider, TimeZoneProvider}, + MonthCode, TemporalError, TemporalResult, TimeZone, +}; +use alloc::string::String; +use core::{cmp::Ordering, str::FromStr}; +use icu_calendar::AnyCalendarKind; +use writeable::Writeable; + +use super::{duration::normalized::InternalDurationRecord, PlainMonthDay, PlainYearMonth}; +use tinystr::TinyAsciiStr; + +// TODO (potentially): Bump era up to TinyAsciiStr<18> to accomodate +// "ethiopic-amete-alem". TODO: PrepareTemporalFields expects a type +// error to be thrown when all partial fields are None/undefined. +/// A partial PlainDate that may or may not be complete. +#[derive(Debug, Default, Clone, PartialEq)] +pub struct PartialDate { + /// The calendar fields representing a calendar date. + pub calendar_fields: CalendarFields, + /// The calendar of this `PartialDate` + pub calendar: Calendar, +} + +/// Convenience methods for building a `PartialDate` +impl PartialDate { + pub const fn new() -> Self { + Self { + calendar_fields: CalendarFields { + year: None, + month: None, + month_code: None, + day: None, + era: None, + era_year: None, + }, + calendar: Calendar::new(AnyCalendarKind::Iso), + } + } + + pub const fn with_era(mut self, era: Option>) -> Self { + self.calendar_fields.era = era; + self + } + + pub const fn with_era_year(mut self, era_year: Option) -> Self { + self.calendar_fields.era_year = era_year; + self + } + + pub const fn with_year(mut self, year: Option) -> Self { + self.calendar_fields.year = year; + self + } + + pub const fn with_month(mut self, month: Option) -> Self { + self.calendar_fields.month = month; + self + } + + pub const fn with_month_code(mut self, month_code: Option) -> Self { + self.calendar_fields.month_code = month_code; + self + } + + pub const fn with_day(mut self, day: Option) -> Self { + self.calendar_fields.day = day; + self + } + + pub const fn with_calendar(mut self, calendar: Calendar) -> Self { + self.calendar = calendar; + self + } +} + +/// The native Rust implementation of `Temporal.PlainDate`. +/// +/// Represents a calendar date without any time or timezone +/// information. Useful for dates where the specific time of day doesn't matter, +/// such as deadlines, birth dates, or historical events. +/// +/// Uses the ISO 8601 calendar (proleptic Gregorian calendar) by default, with +/// support for other calendar systems when needed. +/// +/// ## Examples +/// +/// ### Creating dates +/// +/// ```rust +/// use temporal_rs::{PlainDate, Calendar}; +/// +/// // Create a date using the ISO calendar +/// let christmas = PlainDate::try_new_iso(2024, 12, 25).unwrap(); +/// assert_eq!(christmas.year(), 2024); +/// assert_eq!(christmas.month(), 12); +/// assert_eq!(christmas.day(), 25); +/// +/// // Explicit calendar specification +/// let date = PlainDate::try_new(2024, 12, 25, Calendar::default()).unwrap(); +/// assert_eq!(date.year(), 2024); +/// assert_eq!(christmas, date); // Both represent the same date +/// ``` +/// +/// ### Date arithmetic operations +/// +/// ```rust +/// use temporal_rs::{PlainDate, Duration}; +/// use core::str::FromStr; +/// +/// let start = PlainDate::try_new_iso(2024, 1, 15).unwrap(); +/// +/// // Add one month +/// let later = start.add(&Duration::from_str("P1M").unwrap(), None).unwrap(); +/// assert_eq!(later.month(), 2); // Results in 2024-02-15 +/// assert_eq!(later.day(), 15); +/// +/// // Calculate duration between dates +/// let new_year = PlainDate::try_new_iso(2024, 1, 1).unwrap(); +/// let diff = new_year.until(&start, Default::default()).unwrap(); +/// assert_eq!(diff.days(), 14); +/// ``` +/// +/// ### Parsing ISO 8601 date strings +/// +/// ```rust +/// use temporal_rs::PlainDate; +/// use core::str::FromStr; +/// +/// // Standard ISO date format +/// let date = PlainDate::from_str("2024-03-15").unwrap(); +/// assert_eq!(date.year(), 2024); +/// assert_eq!(date.month(), 3); +/// assert_eq!(date.day(), 15); +/// +/// // With explicit calendar annotation +/// let date2 = PlainDate::from_str("2024-03-15[u-ca=iso8601]").unwrap(); +/// assert_eq!(date, date2); +/// ``` +/// +/// ## Reference +/// +/// For more information, see the [MDN documentation][mdn-plaindate]. +/// +/// [mdn-plaindate]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDate +#[non_exhaustive] +#[derive(Debug, Default, Clone, PartialEq, Eq)] +pub struct PlainDate { + pub(crate) iso: IsoDate, + calendar: Calendar, +} + +impl core::fmt::Display for PlainDate { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(&self.to_ixdtf_string(DisplayCalendar::Auto)) + } +} + +// ==== Private API ==== + +impl PlainDate { + /// Create a new `PlainDate` with the date values and calendar slot. + #[inline] + #[must_use] + pub(crate) fn new_unchecked(iso: IsoDate, calendar: Calendar) -> Self { + Self { iso, calendar } + } + + // Updated: 2025-08-03 + /// Returns the date after adding the given duration to date. + /// + /// 3.5.14 `AddDurationToDate` + /// + /// More information: + /// + /// - [AO specification](https://tc39.es/proposal-temporal/#sec-temporal-adddurationtodate) + #[inline] + pub(crate) fn add_duration_to_date( + &self, + duration: &Duration, + overflow: Option, + ) -> TemporalResult { + // 3. If operation is subtract, set duration to CreateNegatedTemporalDuration(duration). + // 4. Let dateDuration be ToDateDurationRecordWithoutTime(duration). + // TODO: Look into why this is fallible, and make some adjustments + let date_duration = duration.to_date_duration_record_without_time()?; + // 5. Let resolvedOptions be ? GetOptionsObject(options). + // 6. Let overflow be ? GetTemporalOverflowOption(resolvedOptions). + let overflow = overflow.unwrap_or(Overflow::Constrain); + // 7. Let result be ? CalendarDateAdd(calendar, temporalDate.[[ISODate]], dateDuration, overflow). + // 8. Return ! CreateTemporalDate(result, calendar). + self.calendar() + .date_add(&self.iso, &date_duration, overflow) + } + + /// Returns a duration representing the difference between the dates one and two. + /// + /// Temporal Equivalent: 3.5.6 `DifferenceDate ( calendar, one, two, options )` + #[inline] + pub(crate) fn internal_diff_date( + &self, + other: &Self, + largest_unit: Unit, + ) -> TemporalResult { + if self.iso.year == other.iso.year + && self.iso.month == other.iso.month + && self.iso.day == other.iso.day + { + return Ok(Duration::default()); + } + + if largest_unit == Unit::Day { + let days = self.days_until(other); + return Ok(Duration::from(DateDuration::new(0, 0, 0, days.into())?)); + } + + self.calendar() + .date_until(&self.iso, &other.iso, largest_unit) + } + + /// Equivalent: DifferenceTemporalPlainDate + pub(crate) fn diff_date( + &self, + op: DifferenceOperation, + other: &Self, + settings: DifferenceSettings, + ) -> TemporalResult { + // 1. If operation is SINCE, let sign be -1. Otherwise, let sign be 1. + // 2. Set other to ? ToTemporalDate(other). + + // 3. If ? CalendarEquals(temporalDate.[[Calendar]], other.[[Calendar]]) is false, throw a RangeError exception. + if self.calendar().identifier() != other.calendar().identifier() { + return Err(TemporalError::range() + .with_message("Calendars are for difference operation are not the same.")); + } + + // 4. Let resolvedOptions be ? SnapshotOwnProperties(? GetOptionsObject(options), null). + // 5. Let settings be ? GetDifferenceSettings(operation, resolvedOptions, DATE, « », "day", "day"). + let resolved = ResolvedRoundingOptions::from_diff_settings( + settings, + op, + UnitGroup::Date, + Unit::Day, + Unit::Day, + )?; + + // 6. If temporalDate.[[ISOYear]] = other.[[ISOYear]], and temporalDate.[[ISOMonth]] = other.[[ISOMonth]], + // and temporalDate.[[ISODay]] = other.[[ISODay]], then + if self.iso == other.iso { + // a. Return ! CreateTemporalDuration(0, 0, 0, 0, 0, 0, 0, 0, 0, 0). + return Ok(Duration::default()); + } + + // 7. Let calendarRec be ? CreateCalendarMethodsRecord(temporalDate.[[Calendar]], « DATE-ADD, DATE-UNTIL »). + // 8. Perform ! CreateDataPropertyOrThrow(resolvedOptions, "largestUnit", settings.[[LargestUnit]]). + // 9. Let result be ? DifferenceDate(calendarRec, temporalDate, other, resolvedOptions). + let result = self.internal_diff_date(other, resolved.largest_unit)?; + + // 10. Let duration be ! CreateNormalizedDurationRecord(result.[[Years]], result.[[Months]], result.[[Weeks]], result.[[Days]], ZeroTimeDuration()). + let mut duration = InternalDurationRecord::from_date_duration(result.date())?; + // 11. If settings.[[SmallestUnit]] is "day" and settings.[[RoundingIncrement]] = 1, let roundingGranularityIsNoop be true; else let roundingGranularityIsNoop be false. + let rounding_granularity_is_noop = + resolved.smallest_unit == Unit::Day && resolved.increment.get() == 1; + // 12. If roundingGranularityIsNoop is false, then + if !rounding_granularity_is_noop { + // a. Let destEpochNs be GetUTCEpochNanoseconds(other.[[ISOYear]], other.[[ISOMonth]], other.[[ISODay]], 0, 0, 0, 0, 0, 0). + let dest_epoch_ns = other.iso.as_nanoseconds(); + // b. Let dateTime be ISO Date-Time Record { [[Year]]: temporalDate.[[ISOYear]], [[Month]]: temporalDate.[[ISOMonth]], [[Day]]: temporalDate.[[ISODay]], [[Hour]]: 0, [[Minute]]: 0, [[Second]]: 0, [[Millisecond]]: 0, [[Microsecond]]: 0, [[Nanosecond]]: 0 }. + let dt = PlainDateTime::new_unchecked( + IsoDateTime::new_unchecked(self.iso, IsoTime::default()), + self.calendar.clone(), + ); + // c. Set duration to ? RoundRelativeDuration(duration, destEpochNs, dateTime, calendarRec, unset, settings.[[LargestUnit]], settings.[[RoundingIncrement]], settings.[[SmallestUnit]], settings.[[RoundingMode]]). + duration = duration.round_relative_duration( + dest_epoch_ns.0, + &dt, + Option::<(&TimeZone, &NeverProvider)>::None, + resolved, + )? + } + let result = Duration::from_internal(duration, Unit::Day)?; + // 13. Return ! CreateTemporalDuration(sign × duration.[[Years]], sign × duration.[[Months]], sign × duration.[[Weeks]], sign × duration.[[Days]], 0, 0, 0, 0, 0, 0). + match op { + DifferenceOperation::Until => Ok(result), + DifferenceOperation::Since => Ok(result.negated()), + } + } + + /// Abstract operation `DaysUntil` + /// + /// Calculates the epoch days between two `PlainDate`s + #[inline] + #[must_use] + fn days_until(&self, other: &Self) -> i32 { + // NOTE: cast to i32 is safe as both IsoDates must be in valid range. + debug_assert!(self.iso.check_within_limits().is_ok()); + debug_assert!(other.iso.check_within_limits().is_ok()); + (other.iso.to_epoch_days() - self.iso.to_epoch_days()) as i32 + } + + /// Returns this `PlainDate`'s ISO year value. + #[inline] + #[must_use] + pub(crate) const fn iso_year(&self) -> i32 { + self.iso.year + } + + /// Returns this `PlainDate`'s ISO month value. + #[inline] + #[must_use] + pub(crate) const fn iso_month(&self) -> u8 { + self.iso.month + } + + /// Returns this `PlainDate`'s ISO day value. + #[inline] + #[must_use] + pub(crate) const fn iso_day(&self) -> u8 { + self.iso.day + } +} + +// ==== Public API ==== + +impl PlainDate { + /// Creates a new `PlainDate` automatically constraining any values that may be invalid. + #[inline] + pub fn new(year: i32, month: u8, day: u8, calendar: Calendar) -> TemporalResult { + Self::new_with_overflow(year, month, day, calendar, Overflow::Constrain) + } + + /// Creates a new `PlainDate` with an ISO 8601 calendar automatically constraining any + /// values that may be invalid into a valid range. + #[inline] + pub fn new_iso(year: i32, month: u8, day: u8) -> TemporalResult { + Self::new(year, month, day, Calendar::default()) + } + + /// Creates a new `PlainDate` rejecting any date that may be invalid. + #[inline] + pub fn try_new(year: i32, month: u8, day: u8, calendar: Calendar) -> TemporalResult { + Self::new_with_overflow(year, month, day, calendar, Overflow::Reject) + } + + /// Creates a new `PlainDate` with an ISO 8601 calendar rejecting any date that may be invalid. + #[inline] + pub fn try_new_iso(year: i32, month: u8, day: u8) -> TemporalResult { + Self::try_new(year, month, day, Calendar::default()) + } + + /// Creates a new `PlainDate` with the specified overflow. + /// + /// This operation is the public facing API to Temporal's `RegulateIsoDate` + #[inline] + pub fn new_with_overflow( + year: i32, + month: u8, + day: u8, + calendar: Calendar, + overflow: Overflow, + ) -> TemporalResult { + let iso = IsoDate::new_with_overflow(year, month, day, overflow)?; + Ok(Self::new_unchecked(iso, calendar)) + } + + /// Create a `PlainDate` from a `PartialDate` + /// + /// ```rust + /// use temporal_rs::{PlainDate, fields::CalendarFields, Calendar, partial::PartialDate}; + /// + /// let partial = PartialDate { + /// calendar_fields: CalendarFields::new() + /// .with_year(2000) + /// .with_month(13) + /// .with_day(2), + /// calendar: Calendar::ISO, + /// }; + /// + /// let date = PlainDate::from_partial(partial, None).unwrap(); + /// + /// assert_eq!(date.year(), 2000); + /// assert_eq!(date.month(), 12); + /// assert_eq!(date.day(), 2); + /// assert_eq!(date.calendar().identifier(), "iso8601"); + /// + /// ``` + #[inline] + pub fn from_partial(partial: PartialDate, overflow: Option) -> TemporalResult { + let year_check = partial.calendar_fields.year.is_some() + || (partial.calendar_fields.era.is_some() + && partial.calendar_fields.era_year.is_some()); + let month_check = + partial.calendar_fields.month.is_some() || partial.calendar_fields.month_code.is_some(); + if !year_check || !month_check || partial.calendar_fields.day.is_none() { + return Err(TemporalError::r#type().with_message("Invalid PlainDate fields provided.")); + } + + let overflow = overflow.unwrap_or_default(); + partial + .calendar + .date_from_fields(partial.calendar_fields, overflow) + } + + /// Converts a UTF-8 encoded string into a `PlainDate`. + pub fn from_utf8(s: &[u8]) -> TemporalResult { + let parsed = ParsedDate::from_utf8(s)?; + + Self::from_parsed(parsed) + } + + /// Creates a `PlainDate` from a [`ParsedDate`]. + pub fn from_parsed(parsed: ParsedDate) -> TemporalResult { + Self::try_new( + parsed.record.year, + parsed.record.month, + parsed.record.day, + Calendar::new(parsed.calendar), + ) + } + + /// Creates a `PlainDate` with values from a [`PartialDate`]. + pub fn with(&self, fields: CalendarFields, overflow: Option) -> TemporalResult { + if fields.is_empty() { + return Err(TemporalError::r#type().with_message("CalendarFields must have a field.")); + } + // 6. Let fieldsResult be ? PrepareCalendarFieldsAndFieldNames(calendarRec, temporalDate, « "day", "month", "monthCode", "year" »). + // 7. Let partialDate be ? PrepareTemporalFields(temporalDateLike, fieldsResult.[[FieldNames]], partial). + // 8. Let fields be ? CalendarMergeFields(calendarRec, fieldsResult.[[Fields]], partialDate). + // 9. Set fields to ? PrepareTemporalFields(fields, fieldsResult.[[FieldNames]], «»). + // 10. Return ? CalendarDateFromFields(calendarRec, fields, resolvedOptions). + let overflow = overflow.unwrap_or(Overflow::Constrain); + self.calendar.date_from_fields( + fields.with_fallback_date(self, self.calendar.kind(), overflow)?, + overflow, + ) + } + + /// Creates a new `PlainDate` from the current `PlainDate` and the provided calendar. + pub fn with_calendar(&self, calendar: Calendar) -> Self { + Self::new_unchecked(self.iso, calendar) + } + + #[inline] + #[must_use] + /// Returns a reference to this `PlainDate`'s calendar slot. + pub fn calendar(&self) -> &Calendar { + &self.calendar + } + + /// 3.5.7 `IsValidISODate` + /// + /// Checks if the current date is a valid `ISODate`. + #[must_use] + pub fn is_valid(&self) -> bool { + self.iso.is_valid() + } + + /// Compares one `PlainDate` to another `PlainDate` using their + /// `IsoDate` representation. + /// + /// # Note on Ordering. + /// + /// `temporal_rs` does not implement `PartialOrd`/`Ord` as `PlainDate` does + /// not fulfill all the conditions required to implement the traits. However, + /// it is possible to compare `PlainDate`'s as their `IsoDate` representation. + #[inline] + #[must_use] + pub fn compare_iso(&self, other: &Self) -> Ordering { + self.iso.cmp(&other.iso) + } + + #[inline] + /// Adds a [`Duration`] to the current `PlainDate`. + pub fn add(&self, duration: &Duration, overflow: Option) -> TemporalResult { + self.add_duration_to_date(duration, overflow) + } + + #[inline] + /// Subtracts a [`Duration`] from the current `PlainDate`. + pub fn subtract( + &self, + duration: &Duration, + overflow: Option, + ) -> TemporalResult { + self.add_duration_to_date(&duration.negated(), overflow) + } + + #[inline] + /// Returns a [`Duration`] representing the time from this `PlainDate` until the other `PlainDate`. + pub fn until(&self, other: &Self, settings: DifferenceSettings) -> TemporalResult { + self.diff_date(DifferenceOperation::Until, other, settings) + } + + #[inline] + /// Returns a [`Duration`] representing the time passed from this `PlainDate` since the other `PlainDate`. + pub fn since(&self, other: &Self, settings: DifferenceSettings) -> TemporalResult { + self.diff_date(DifferenceOperation::Since, other, settings) + } +} + +// ==== Calendar-derived Public API ==== + +impl PlainDate { + /// Returns the calendar year value. + pub fn year(&self) -> i32 { + self.calendar.year(&self.iso) + } + + /// Returns the calendar month value. + pub fn month(&self) -> u8 { + self.calendar.month(&self.iso) + } + + /// Returns the calendar month code value. + pub fn month_code(&self) -> MonthCode { + self.calendar.month_code(&self.iso) + } + + /// Returns the calendar day value. + pub fn day(&self) -> u8 { + self.calendar.day(&self.iso) + } + + /// Returns the calendar day of week value. + pub fn day_of_week(&self) -> u16 { + self.calendar.day_of_week(&self.iso) + } + + /// Returns the calendar day of year value. + pub fn day_of_year(&self) -> u16 { + self.calendar.day_of_year(&self.iso) + } + + /// Returns the calendar week of year value. + pub fn week_of_year(&self) -> Option { + self.calendar.week_of_year(&self.iso) + } + + /// Returns the calendar year of week value. + pub fn year_of_week(&self) -> Option { + self.calendar.year_of_week(&self.iso) + } + + /// Returns the calendar days in week value. + pub fn days_in_week(&self) -> u16 { + self.calendar.days_in_week(&self.iso) + } + + /// Returns the calendar days in month value. + pub fn days_in_month(&self) -> u16 { + self.calendar.days_in_month(&self.iso) + } + + /// Returns the calendar days in year value. + pub fn days_in_year(&self) -> u16 { + self.calendar.days_in_year(&self.iso) + } + + /// Returns the calendar months in year value. + pub fn months_in_year(&self) -> u16 { + self.calendar.months_in_year(&self.iso) + } + + /// Returns whether the `PlainDate` is in a leap year for the given calendar. + pub fn in_leap_year(&self) -> bool { + self.calendar.in_leap_year(&self.iso) + } + + /// Returns the era current `PlainDate`. + pub fn era(&self) -> Option> { + self.calendar.era(&self.iso) + } + + /// Returns the era year for the current `PlainDate`. + pub fn era_year(&self) -> Option { + self.calendar.era_year(&self.iso) + } +} + +// ==== ToX Methods ==== + +impl PlainDate { + /// Converts the current `PlainDate` into a [`PlainDateTime`]. + /// + /// # Notes + /// + /// If no time is provided, then the time will default to midnight. + #[inline] + pub fn to_plain_date_time(&self, time: Option) -> TemporalResult { + let time = time.unwrap_or_default(); + let iso = IsoDateTime::new(self.iso, time.iso)?; + Ok(PlainDateTime::new_unchecked(iso, self.calendar().clone())) + } + + /// Converts the current `PlainDate` into a [`PlainYearMonth`]. + #[inline] + pub fn to_plain_year_month(&self) -> TemporalResult { + let era = self + .era() + .map(|e| { + TinyAsciiStr::<19>::try_from_utf8(e.as_bytes()) + .map_err(|_| TemporalError::general("Parsing era failed")) + }) + .transpose()?; + let fields = YearMonthCalendarFields::new() + .with_year(self.year()) + .with_era(era) + .with_era_year(self.era_year()) + .with_month(self.month()) + .with_month_code(self.month_code()); + self.calendar() + .year_month_from_fields(fields, Overflow::Constrain) + } + + /// Converts the current `PlainDate` into a [`PlainMonthDay`]. + #[inline] + pub fn to_plain_month_day(&self) -> TemporalResult { + let overflow = Overflow::Constrain; + self.calendar().month_day_from_fields( + CalendarFields::default().with_fallback_date(self, self.calendar.kind(), overflow)?, + overflow, + ) + } + + #[inline] + pub fn to_ixdtf_string(&self, display_calendar: DisplayCalendar) -> String { + self.to_ixdtf_writeable(display_calendar) + .write_to_string() + .into() + } + + #[inline] + pub fn to_ixdtf_writeable(&self, display_calendar: DisplayCalendar) -> impl Writeable + '_ { + IxdtfStringBuilder::default() + .with_date(self.iso) + .with_calendar(self.calendar.identifier(), display_calendar) + .build() + } + + /// Creates a [`ZonedDateTime`] from the current `PlainDate` with a provided [`TimeZone`] and + /// optional [`PlainTime`]. + #[inline] + pub fn to_zoned_date_time_with_provider( + &self, + time_zone: TimeZone, + plain_time: Option, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // NOTE (nekevss): Steps 1-4 are engine specific + let epoch_ns = if let Some(time) = plain_time { + // 6. Else, + // a. Set temporalTime to ? ToTemporalTime(temporalTime). + // b. Let isoDateTime be CombineISODateAndTimeRecord(temporalDate.[[ISODate]], temporalTime.[[Time]]). + // c. If ISODateTimeWithinLimits(isoDateTime) is false, throw a RangeError exception. + let result_iso = IsoDateTime::new(self.iso, time.iso)?; + // d. Let epochNs be ? GetEpochNanosecondsFor(timeZone, isoDateTime, compatible). + time_zone.get_epoch_nanoseconds_for(result_iso, Disambiguation::Compatible, provider)? + // 5. If temporalTime is undefined, then + } else { + // a. Let epochNs be ? GetStartOfDay(timeZone, temporalDate.[[ISODate]]). + time_zone.get_start_of_day(&self.iso, provider)? + }; + // 7. Return ! CreateTemporalZonedDateTime(epochNs, timeZone, temporalDate.[[Calendar]]). + ZonedDateTime::try_new_with_cached_offset( + epoch_ns.ns.0, + time_zone, + self.calendar.clone(), + epoch_ns.offset, + ) + } +} + +// ==== Trait impls ==== + +impl From for PlainDate { + fn from(pdt: PlainDateTime) -> Self { + pdt.to_plain_date() + } +} + +impl FromStr for PlainDate { + type Err = TemporalError; + + fn from_str(s: &str) -> Result { + Self::from_utf8(s.as_bytes()) + } +} + +#[cfg(test)] +mod tests { + use tinystr::tinystr; + + use super::*; + + #[test] + fn new_date_limits() { + let err = PlainDate::try_new(-271_821, 4, 18, Calendar::default()); + assert!(err.is_err()); + let err = PlainDate::try_new(275_760, 9, 14, Calendar::default()); + assert!(err.is_err()); + let ok = PlainDate::try_new(-271_821, 4, 19, Calendar::default()); + assert_eq!( + ok, + Ok(PlainDate { + iso: IsoDate { + year: -271_821, + month: 4, + day: 19, + }, + calendar: Calendar::default(), + }) + ); + + let ok = PlainDate::try_new(275_760, 9, 13, Calendar::default()); + assert_eq!( + ok, + Ok(PlainDate { + iso: IsoDate { + year: 275760, + month: 9, + day: 13, + }, + calendar: Calendar::default(), + }) + ); + } + + #[test] + fn simple_date_add() { + let base = PlainDate::from_str("1976-11-18").unwrap(); + + // Test 1 + let result = base + .add(&Duration::from_str("P43Y").unwrap(), None) + .unwrap(); + assert_eq!( + result.iso, + IsoDate { + year: 2019, + month: 11, + day: 18, + } + ); + + // Test 2 + let result = base.add(&Duration::from_str("P3M").unwrap(), None).unwrap(); + assert_eq!( + result.iso, + IsoDate { + year: 1977, + month: 2, + day: 18, + } + ); + + // Test 3 + let result = base + .add(&Duration::from_str("P20D").unwrap(), None) + .unwrap(); + assert_eq!( + result.iso, + IsoDate { + year: 1976, + month: 12, + day: 8, + } + ) + } + + #[test] + fn date_add_limits() { + let max = PlainDate::try_new(275_760, 9, 13, Calendar::default()).unwrap(); + let result = max.add(&Duration::from_str("P1D").unwrap(), None); + assert!(result.is_err()); + + let max = PlainDate::try_new(275_760, 9, 12, Calendar::default()).unwrap(); + let result = max.add(&Duration::from_str("P1D").unwrap(), None); + assert_eq!( + result, + Ok(PlainDate { + iso: IsoDate { + year: 275760, + month: 9, + day: 13 + }, + calendar: Calendar::default(), + }) + ); + + let min = PlainDate::try_new(-271_821, 4, 19, Calendar::default()).unwrap(); + let result = min.add(&Duration::from_str("-P1D").unwrap(), None); + assert!(result.is_err()); + + let min = PlainDate::try_new(-271_821, 4, 20, Calendar::default()).unwrap(); + let result = min.add(&Duration::from_str("-P1D").unwrap(), None); + assert_eq!( + result, + Ok(PlainDate { + iso: IsoDate { + year: -271_821, + month: 4, + day: 19 + }, + calendar: Calendar::default(), + }) + ); + } + + #[test] + fn simple_date_subtract() { + let base = PlainDate::from_str("2019-11-18").unwrap(); + + // Test 1 + let result = base + .subtract(&Duration::from_str("P43Y").unwrap(), None) + .unwrap(); + assert_eq!( + result.iso, + IsoDate { + year: 1976, + month: 11, + day: 18, + } + ); + + // Test 2 + let result = base + .subtract(&Duration::from_str("P11M").unwrap(), None) + .unwrap(); + assert_eq!( + result.iso, + IsoDate { + year: 2018, + month: 12, + day: 18, + } + ); + + // Test 3 + let result = base + .subtract(&Duration::from_str("P20D").unwrap(), None) + .unwrap(); + assert_eq!( + result.iso, + IsoDate { + year: 2019, + month: 10, + day: 29, + } + ) + } + + #[test] + fn simple_date_until() { + let earlier = PlainDate::from_str("1969-07-24").unwrap(); + let later = PlainDate::from_str("1969-10-05").unwrap(); + let result = earlier + .until(&later, DifferenceSettings::default()) + .unwrap(); + assert_eq!(result.days(), 73,); + + let later = PlainDate::from_str("1996-03-03").unwrap(); + let result = earlier + .until(&later, DifferenceSettings::default()) + .unwrap(); + assert_eq!(result.days(), 9719,); + } + + #[test] + fn simple_date_since() { + let earlier = PlainDate::from_str("1969-07-24").unwrap(); + let later = PlainDate::from_str("1969-10-05").unwrap(); + let result = later + .since(&earlier, DifferenceSettings::default()) + .unwrap(); + assert_eq!(result.days(), 73,); + + let later = PlainDate::from_str("1996-03-03").unwrap(); + let result = later + .since(&earlier, DifferenceSettings::default()) + .unwrap(); + assert_eq!(result.days(), 9719,); + } + + #[test] + fn date_with_empty_error() { + let base = PlainDate::new(1976, 11, 18, Calendar::default()).unwrap(); + + let err = base.with(CalendarFields::default(), None); + assert!(err.is_err()); + } + + #[test] + fn basic_date_with() { + let base = PlainDate::new(1976, 11, 18, Calendar::default()).unwrap(); + + // Year + let fields = CalendarFields::new().with_year(2019); + let with_year = base.with(fields, None).unwrap(); + assert_eq!(with_year.year(), 2019); + assert_eq!(with_year.month(), 11); + assert_eq!(with_year.month_code(), MonthCode::from_str("M11").unwrap()); + assert_eq!(with_year.day(), 18); + + // Month + let fields = CalendarFields::new().with_month(5); + let with_month = base.with(fields, None).unwrap(); + assert_eq!(with_month.year(), 1976); + assert_eq!(with_month.month(), 5); + assert_eq!(with_month.month_code(), MonthCode::from_str("M05").unwrap()); + assert_eq!(with_month.day(), 18); + + // Month Code + let fields = CalendarFields::new().with_month_code(MonthCode(tinystr!(4, "M05"))); + let with_mc = base.with(fields, None).unwrap(); + assert_eq!(with_mc.year(), 1976); + assert_eq!(with_mc.month(), 5); + assert_eq!(with_mc.month_code(), MonthCode::from_str("M05").unwrap()); + assert_eq!(with_mc.day(), 18); + + // Day + let fields = CalendarFields::new().with_day(17); + let with_day = base.with(fields, None).unwrap(); + assert_eq!(with_day.year(), 1976); + assert_eq!(with_day.month(), 11); + assert_eq!(with_day.month_code(), MonthCode::from_str("M11").unwrap()); + assert_eq!(with_day.day(), 17); + } + + // test toZonedDateTime + #[cfg(feature = "tzdb")] + #[test] + fn to_zoned_date_time() { + use timezone_provider::tzif::FsTzdbProvider; + let provider = &FsTzdbProvider::default(); + let date = PlainDate::from_str("2020-01-01").unwrap(); + let time_zone = TimeZone::try_from_str_with_provider("UTC", provider).unwrap(); + let zdt = date + .to_zoned_date_time_with_provider(time_zone, None, provider) + .unwrap(); + assert_eq!(zdt.year(), 2020); + assert_eq!(zdt.month(), 1); + assert_eq!(zdt.day(), 1); + assert_eq!(zdt.hour(), 0); + assert_eq!(zdt.minute(), 0); + assert_eq!(zdt.second(), 0); + assert_eq!(zdt.millisecond(), 0); + assert_eq!(zdt.microsecond(), 0); + assert_eq!(zdt.nanosecond(), 0); + } + + #[cfg(feature = "tzdb")] + #[test] + fn to_zoned_date_time_error() { + use timezone_provider::tzif::FsTzdbProvider; + let provider = &FsTzdbProvider::default(); + let date = PlainDate::try_new_iso(-271_821, 4, 19).unwrap(); + let time_zone = TimeZone::try_from_str_with_provider("+00", provider).unwrap(); + let zdt = date.to_zoned_date_time_with_provider(time_zone, None, provider); + assert!(zdt.is_err()) + } + + // test262/test/built-ins/Temporal/Calendar/prototype/month/argument-string-invalid.js + #[test] + fn invalid_strings() { + const INVALID_STRINGS: [&str; 35] = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00", + "2020-01-32", + "2020-02-30", + "2021-02-29", + "2020-00-01", + "2020-13-01", + "2020-01-01T", + "2020-01-01T25:00:00", + "2020-01-01T01:60:00", + "2020-01-01T01:60:61", + "2020-01-01junk", + "2020-01-01T00:00:00junk", + "2020-01-01T00:00:00+00:00junk", + "2020-01-01T00:00:00+00:00[UTC]junk", + "2020-01-01T00:00:00+00:00[UTC][u-ca=iso8601]junk", + "02020-01-01", + "2020-001-01", + "2020-01-001", + "2020-01-01T001", + "2020-01-01T01:001", + "2020-01-01T01:01:001", + // valid, but forms not supported in Temporal: + "2020-W01-1", + "2020-001", + "+0002020-01-01", + // valid, but this calendar must not exist: + "2020-01-01[u-ca=notexist]", + // may be valid in other contexts, but insufficient information for PlainDate: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + // valid, but outside the supported range: + "-999999-01-01", + "+999999-01-01", + ]; + for s in INVALID_STRINGS { + assert!(PlainDate::from_str(s).is_err()) + } + } + + // test262/test/built-ins/Temporal/Calendar/prototype/day/argument-string-critical-unknown-annotation.js + #[test] + fn argument_string_critical_unknown_annotation() { + const INVALID_STRINGS: [&str; 6] = [ + "1970-01-01[!foo=bar]", + "1970-01-01T00:00[!foo=bar]", + "1970-01-01T00:00[UTC][!foo=bar]", + "1970-01-01T00:00[u-ca=iso8601][!foo=bar]", + "1970-01-01T00:00[UTC][!foo=bar][u-ca=iso8601]", + "1970-01-01T00:00[foo=bar][!_foo-bar0=Dont-Ignore-This-99999999999]", + ]; + for s in INVALID_STRINGS { + assert!(PlainDate::from_str(s).is_err()) + } + } +} diff --git a/deps/temporal/src/builtins/core/plain_date_time.rs b/deps/temporal/src/builtins/core/plain_date_time.rs new file mode 100644 index 00000000000000..77bdf1b31fd1f5 --- /dev/null +++ b/deps/temporal/src/builtins/core/plain_date_time.rs @@ -0,0 +1,1552 @@ +//! This module implements `PlainDateTime` any directly related algorithms. + +use super::{ + duration::normalized::InternalDurationRecord, Duration, PartialTime, PlainDate, PlainTime, + ZonedDateTime, +}; +use crate::parsed_intermediates::ParsedDateTime; +use crate::{ + builtins::{ + calendar::CalendarFields, + core::{calendar::Calendar, Instant}, + }, + iso::{IsoDate, IsoDateTime, IsoTime}, + options::{ + DifferenceOperation, DifferenceSettings, Disambiguation, DisplayCalendar, Overflow, + ResolvedRoundingOptions, RoundingOptions, ToStringRoundingOptions, Unit, UnitGroup, + }, + parsers::IxdtfStringBuilder, + primitive::FiniteF64, + provider::{NeverProvider, TimeZoneProvider}, + MonthCode, TemporalError, TemporalResult, TimeZone, +}; +use alloc::string::String; +use core::{cmp::Ordering, str::FromStr}; +use tinystr::TinyAsciiStr; +use writeable::Writeable; + +/// A partial PlainDateTime record +#[derive(Debug, Default, Clone)] +pub struct PartialDateTime { + /// The `PartialDate` portion of a `PartialDateTime` + pub fields: DateTimeFields, + /// The calendar of the `PartialDateTime`. + pub calendar: Calendar, +} + +#[derive(Debug, Default, Clone)] +pub struct DateTimeFields { + pub calendar_fields: CalendarFields, + pub time: PartialTime, +} + +impl DateTimeFields { + pub fn is_empty(&self) -> bool { + self.calendar_fields.is_empty() && self.time.is_empty() + } +} + +impl DateTimeFields { + pub const fn new() -> Self { + Self { + calendar_fields: CalendarFields::new(), + time: PartialTime::new(), + } + } + + pub const fn with_partial_date(mut self, fields: CalendarFields) -> Self { + self.calendar_fields = fields; + self + } + + pub const fn with_partial_time(mut self, partial_time: PartialTime) -> Self { + self.time = partial_time; + self + } +} + +/// The native Rust implementation of a Temporal `PlainDateTime`. +/// +/// Combines a date and time into a single value representing a specific moment +/// in calendar time, such as "2024-03-15T14:30:45". Unlike `Instant`, +/// a `PlainDateTime` does not include timezone information. +/// +/// Use `PlainDateTime` when you need to represent a specific date and time but +/// timezone handling is not required, or when working with local times that +/// don't need to be converted across timezones. +/// +/// ## Examples +/// +/// ### Creating date and time values +/// +/// ```rust +/// use temporal_rs::PlainDateTime; +/// use core::str::FromStr; +/// +/// // Create a specific date and time from IXDTF string +/// let meeting = PlainDateTime::from_str("2024-03-15T14:30:45.123456789").unwrap(); +/// assert_eq!(meeting.year(), 2024); +/// assert_eq!(meeting.hour(), 14); +/// assert_eq!(meeting.minute(), 30); +/// ``` +/// +/// ### Parsing ISO 8601 datetime strings +/// +/// ```rust +/// use temporal_rs::PlainDateTime; +/// use core::str::FromStr; +/// +/// let dt = PlainDateTime::from_str("2024-03-15T14:30:45.123456789").unwrap(); +/// assert_eq!(dt.year(), 2024); +/// assert_eq!(dt.month(), 3); +/// assert_eq!(dt.day(), 15); +/// assert_eq!(dt.hour(), 14); +/// assert_eq!(dt.minute(), 30); +/// assert_eq!(dt.second(), 45); +/// assert_eq!(dt.millisecond(), 123); +/// assert_eq!(dt.microsecond(), 456); +/// assert_eq!(dt.nanosecond(), 789); +/// ``` +/// +/// ### DateTime arithmetic +/// +/// ```rust +/// use temporal_rs::{PlainDateTime, Duration}; +/// use core::str::FromStr; +/// +/// let dt = PlainDateTime::from_str("2024-01-15T12:00:00").unwrap(); +/// +/// // Add duration +/// let later = dt.add(&Duration::from_str("P1M2DT3H4M").unwrap(), None).unwrap(); +/// assert_eq!(later.month(), 2); +/// assert_eq!(later.day(), 17); +/// assert_eq!(later.hour(), 15); +/// assert_eq!(later.minute(), 4); +/// +/// // Calculate difference +/// let earlier = PlainDateTime::from_str("2024-01-10T10:30:00").unwrap(); +/// let duration = earlier.until(&dt, Default::default()).unwrap(); +/// assert_eq!(duration.days(), 5); +/// assert_eq!(duration.hours(), 1); +/// assert_eq!(duration.minutes(), 30); +/// ``` +/// +/// ### Working with partial fields +/// +/// ```rust +/// use temporal_rs::{PlainDateTime, fields::DateTimeFields, partial::PartialTime}; +/// use core::str::FromStr; +/// +/// let dt = PlainDateTime::from_str("2024-01-15T12:30:45").unwrap(); +/// +/// // Change only the hour +/// let fields = DateTimeFields::new().with_partial_time(PartialTime::new().with_hour(Some(18))); +/// let modified = dt.with(fields, None).unwrap(); +/// assert_eq!(modified.hour(), 18); +/// assert_eq!(modified.minute(), 30); // unchanged +/// assert_eq!(modified.second(), 45); // unchanged +/// ``` +/// +/// ### Converting to other types +/// +/// ```rust +/// use temporal_rs::{PlainDateTime, PlainTime}; +/// use core::str::FromStr; +/// +/// let dt = PlainDateTime::from_str("2024-03-15T14:30:45").unwrap(); +/// +/// // Extract date component +/// let date = dt.to_plain_date(); +/// assert_eq!(date.year(), 2024); +/// assert_eq!(date.month(), 3); +/// assert_eq!(date.day(), 15); +/// +/// // Extract time component +/// let time = dt.to_plain_time(); +/// assert_eq!(time.hour(), 14); +/// assert_eq!(time.minute(), 30); +/// assert_eq!(time.second(), 45); +/// ``` +/// +/// ## Reference +/// +/// For more information, see the [MDN documentation][mdn-datetime]. +/// +/// [mdn-datetime]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDateTime +#[non_exhaustive] +#[derive(Debug, Default, Clone, PartialEq, Eq)] +pub struct PlainDateTime { + pub(crate) iso: IsoDateTime, + calendar: Calendar, +} + +impl core::fmt::Display for PlainDateTime { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let string = + self.to_ixdtf_string(ToStringRoundingOptions::default(), DisplayCalendar::Auto); + + debug_assert!( + string.is_ok(), + "Duration must return a valid string with default options." + ); + + f.write_str(&string.map_err(|_| Default::default())?) + } +} + +// ==== Private PlainDateTime API ==== + +impl PlainDateTime { + /// Creates a new unchecked `PlainDateTime`. + #[inline] + #[must_use] + pub(crate) fn new_unchecked(iso: IsoDateTime, calendar: Calendar) -> Self { + Self { iso, calendar } + } + + // TODO: Potentially deprecate and remove. + /// Create a new `PlainDateTime` from an `Instant`. + #[allow(unused)] + #[inline] + pub(crate) fn from_instant(instant: &Instant, offset: i64, calendar: Calendar) -> Self { + let iso = IsoDateTime::from_epoch_nanos(instant.epoch_nanoseconds(), offset); + Self { iso, calendar } + } + + // 5.5.14 AddDurationToOrSubtractDurationFromPlainDateTime ( operation, dateTime, temporalDurationLike, options ) + fn add_or_subtract_duration( + &self, + duration: &Duration, + overflow: Option, + ) -> TemporalResult { + // SKIP: 1, 2, 3, 4 + // 5. Let internalDuration be ToInternalDurationRecordWith24HourDays(duration). + let internal_duration = InternalDurationRecord::from_duration_with_24_hour_days(duration)?; + // 6. Let timeResult be AddTime(dateTime.[[ISODateTime]].[[Time]], internalDuration.[[Time]]). + let (days, time_result) = self + .iso + .time + .add(internal_duration.normalized_time_duration()); + // 7. Let dateDuration be ? AdjustDateDurationRecord(internalDuration.[[Date]], timeResult.[[Days]]). + let date_duration = internal_duration.date().adjust(days, None, None)?; + // 8. Let addedDate be ? CalendarDateAdd(dateTime.[[Calendar]], dateTime.[[ISODateTime]].[[ISODate]], dateDuration, overflow). + let added_date = self.calendar().date_add( + &self.iso.date, + &date_duration, + overflow.unwrap_or(Overflow::Constrain), + )?; + // 9. Let result be CombineISODateAndTimeRecord(addedDate, timeResult). + let result = IsoDateTime::new(added_date.iso, time_result)?; + // 10. Return ? CreateTemporalDateTime(result, dateTime.[[Calendar]]). + Ok(Self::new_unchecked(result, self.calendar().clone())) + } + + /// Difference two `PlainDateTime`s together. + pub(crate) fn diff( + &self, + op: DifferenceOperation, + other: &Self, + settings: DifferenceSettings, + ) -> TemporalResult { + // 3. If ? CalendarEquals(dateTime.[[Calendar]], other.[[Calendar]]) is false, throw a RangeError exception. + if self.calendar != other.calendar { + return Err(TemporalError::range() + .with_message("Calendar must be the same when diffing two PlainDateTimes")); + } + + // 5. Let settings be ? GetDifferenceSettings(operation, resolvedOptions, datetime, « », "nanosecond", "day"). + let options = ResolvedRoundingOptions::from_diff_settings( + settings, + op, + UnitGroup::DateTime, + Unit::Day, + Unit::Nanosecond, + )?; + + // Step 7-8 combined. + if self.iso == other.iso { + return Ok(Duration::default()); + } + + // Step 10-11. + let norm_record = self.diff_dt_with_rounding(other, options)?; + + let result = Duration::from_internal(norm_record, options.largest_unit)?; + + // Step 12 + match op { + DifferenceOperation::Until => Ok(result), + DifferenceOperation::Since => Ok(result.negated()), + } + } + + // TODO: Figure out whether to handle resolvedOptions + // 5.5.12 DifferencePlainDateTimeWithRounding ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, d2, h2, min2, s2, ms2, + // mus2, ns2, calendarRec, largestUnit, roundingIncrement, smallestUnit, roundingMode, resolvedOptions ) + pub(crate) fn diff_dt_with_rounding( + &self, + other: &Self, + options: ResolvedRoundingOptions, + ) -> TemporalResult { + // 1. If CompareISODateTime(y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2) = 0, then + if matches!(self.iso.cmp(&other.iso), Ordering::Equal) { + // a. Let durationRecord be CreateDurationRecord(0, 0, 0, 0, 0, 0, 0, 0, 0, 0). + // b. Return the Record { [[DurationRecord]]: durationRecord, [[Total]]: 0 }. + return Ok(InternalDurationRecord::default()); + } + // 2. If ISODateTimeWithinLimits(isoDateTime1) is false or ISODateTimeWithinLimits(isoDateTime2) is false, throw a RangeError exception. + self.iso.check_within_limits()?; + other.iso.check_within_limits()?; + + // 3. Let diff be DifferenceISODateTime(isoDateTime1, isoDateTime2, calendar, largestUnit). + let diff = self + .iso + .diff(&other.iso, &self.calendar, options.largest_unit)?; + // 4. If smallestUnit is nanosecond and roundingIncrement = 1, return diff. + if options.smallest_unit == Unit::Nanosecond && options.increment.get() == 1 { + return Ok(diff); + } + + // 5. Let destEpochNs be GetUTCEpochNanoseconds(isoDateTime2). + let dest_epoch_ns = other.iso.as_nanoseconds(); + // 6. Return ? RoundRelativeDuration(diff, destEpochNs, isoDateTime1, unset, calendar, largestUnit, roundingIncrement, smallestUnit, roundingMode). + diff.round_relative_duration( + dest_epoch_ns.0, + self, + Option::<(&TimeZone, &NeverProvider)>::None, + options, + ) + } + + // 5.5.14 DifferencePlainDateTimeWithTotal ( isoDateTime1, isoDateTime2, calendar, unit ) + pub(crate) fn diff_dt_with_total(&self, other: &Self, unit: Unit) -> TemporalResult { + // 1. If CompareISODateTime(isoDateTime1, isoDateTime2) = 0, then + // a. Return 0. + if matches!(self.iso.cmp(&other.iso), Ordering::Equal) { + return FiniteF64::try_from(0.0); + } + // 2. If ISODateTimeWithinLimits(isoDateTime1) is false or ISODateTimeWithinLimits(isoDateTime2) is false, throw a RangeError exception. + if !self.iso.is_within_limits() || !other.iso.is_within_limits() { + return Err(TemporalError::range().with_message("DateTime is not within valid limits.")); + } + // 3. Let diff be DifferenceISODateTime(isoDateTime1, isoDateTime2, calendar, unit). + let diff = self.iso.diff(&other.iso, &self.calendar, unit)?; + // 4. If unit is nanosecond, return diff.[[Time]]. + if unit == Unit::Nanosecond { + return FiniteF64::try_from(diff.normalized_time_duration().0); + } + // 5. Let destEpochNs be GetUTCEpochNanoseconds(isoDateTime2). + let dest_epoch_ns = other.iso.as_nanoseconds(); + // 6. Return ? TotalRelativeDuration(diff, destEpochNs, isoDateTime1, unset, calendar, unit). + diff.total_relative_duration( + dest_epoch_ns.0, + self, + Option::<(&TimeZone, &NeverProvider)>::None, + unit, + ) + } + + /// Returns this `PlainDateTime`'s ISO year value. + #[inline] + #[must_use] + pub const fn iso_year(&self) -> i32 { + self.iso.date.year + } + + /// Returns this `PlainDateTime`'s ISO month value. + #[inline] + #[must_use] + pub const fn iso_month(&self) -> u8 { + self.iso.date.month + } + + /// Returns this `PlainDateTime`'s ISO day value. + #[inline] + #[must_use] + pub const fn iso_day(&self) -> u8 { + self.iso.date.day + } +} + +// ==== Public PlainDateTime API ==== + +impl PlainDateTime { + /// Creates a new `PlainDateTime`, constraining any arguments that are invalid + /// into a valid range. + #[inline] + #[allow(clippy::too_many_arguments)] + pub fn new( + year: i32, + month: u8, + day: u8, + hour: u8, + minute: u8, + second: u8, + millisecond: u16, + microsecond: u16, + nanosecond: u16, + calendar: Calendar, + ) -> TemporalResult { + Self::new_with_overflow( + year, + month, + day, + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + calendar, + Overflow::Constrain, + ) + } + + /// Creates a new `PlainDateTime` with an ISO 8601 calendar, constraining any + /// arguments that are invalid into a valid range. + #[inline] + #[allow(clippy::too_many_arguments)] + pub fn new_iso( + year: i32, + month: u8, + day: u8, + hour: u8, + minute: u8, + second: u8, + millisecond: u16, + microsecond: u16, + nanosecond: u16, + ) -> TemporalResult { + Self::new( + year, + month, + day, + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + Calendar::default(), + ) + } + + /// Creates a new `PlainDateTime`, rejecting any arguments that are not in a valid range. + #[inline] + #[allow(clippy::too_many_arguments)] + pub fn try_new( + year: i32, + month: u8, + day: u8, + hour: u8, + minute: u8, + second: u8, + millisecond: u16, + microsecond: u16, + nanosecond: u16, + calendar: Calendar, + ) -> TemporalResult { + Self::new_with_overflow( + year, + month, + day, + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + calendar, + Overflow::Reject, + ) + } + + /// Creates a new `PlainDateTime` with an ISO 8601 calendar, rejecting any arguments that are not in a valid range. + #[inline] + #[allow(clippy::too_many_arguments)] + pub fn try_new_iso( + year: i32, + month: u8, + day: u8, + hour: u8, + minute: u8, + second: u8, + millisecond: u16, + microsecond: u16, + nanosecond: u16, + ) -> TemporalResult { + Self::try_new( + year, + month, + day, + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + Calendar::default(), + ) + } + + /// Creates a new `PlainDateTime` with the provided [`Overflow`] option. + #[inline] + #[allow(clippy::too_many_arguments)] + pub fn new_with_overflow( + year: i32, + month: u8, + day: u8, + hour: u8, + minute: u8, + second: u8, + millisecond: u16, + microsecond: u16, + nanosecond: u16, + calendar: Calendar, + overflow: Overflow, + ) -> TemporalResult { + let iso_date = IsoDate::new_with_overflow(year, month, day, overflow)?; + let iso_time = IsoTime::new( + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + overflow, + )?; + Ok(Self::new_unchecked( + IsoDateTime::new(iso_date, iso_time)?, + calendar, + )) + } + + /// Create a `PlainDateTime` from a `Date` and a `Time`. + pub fn from_date_and_time(date: PlainDate, time: PlainTime) -> TemporalResult { + Ok(Self::new_unchecked( + IsoDateTime::new(date.iso, time.iso)?, + date.calendar().clone(), + )) + } + + /// Creates a `PlainDateTime` from a `PartialDateTime`. + /// + /// ```rust + /// use temporal_rs::{Calendar, PlainDateTime, fields::{CalendarFields, DateTimeFields}, partial::{PartialDateTime, PartialTime, PartialDate}}; + /// + /// let calendar_fields = CalendarFields::new() + /// .with_year(2000) + /// .with_month(13) + /// .with_day(2); + /// + /// let time = PartialTime { + /// hour: Some(4), + /// minute: Some(25), + /// ..Default::default() + /// }; + /// + /// let fields = PartialDateTime { + /// fields: DateTimeFields { + /// calendar_fields, + /// time, + /// }, + /// calendar: Calendar::ISO, + /// }; + /// + /// let date = PlainDateTime::from_partial(fields, None).unwrap(); + /// + /// assert_eq!(date.year(), 2000); + /// assert_eq!(date.month(), 12); + /// assert_eq!(date.day(), 2); + /// assert_eq!(date.calendar().identifier(), "iso8601"); + /// assert_eq!(date.hour(), 4); + /// assert_eq!(date.minute(), 25); + /// assert_eq!(date.second(), 0); + /// assert_eq!(date.millisecond(), 0); + /// + /// ``` + pub fn from_partial( + partial: PartialDateTime, + overflow: Option, + ) -> TemporalResult { + if partial.fields.is_empty() { + return Err(TemporalError::r#type().with_message("PartialDateTime cannot be empty.")); + } + // The steps here largely follow `InterpretTemporalDateTimeFields` + // 1. Let isoDate be ? CalendarDateFromFields(calendar, fields, overflow). + let date = partial.calendar.date_from_fields( + partial.fields.calendar_fields, + overflow.unwrap_or(Overflow::Constrain), + )?; + // 2. Let time be ? RegulateTime(fields.[[Hour]], fields.[[Minute]], fields.[[Second]], fields.[[Millisecond]], fields.[[Microsecond]], fields.[[Nanosecond]], overflow). + let iso_time = + IsoTime::default().with(partial.fields.time, overflow.unwrap_or_default())?; + // 3. Return CombineISODateAndTimeRecord(isoDate, time). + let iso = IsoDateTime::new(date.iso, iso_time)?; + Ok(Self::new_unchecked(iso, partial.calendar)) + } + + // Converts a UTF-8 encoded string into a `PlainDateTime`. + pub fn from_utf8(s: &[u8]) -> TemporalResult { + let parsed = ParsedDateTime::from_utf8(s)?; + Self::from_parsed(parsed) + } + + pub fn from_parsed(parsed: ParsedDateTime) -> TemporalResult { + let date = IsoDate::new_with_overflow( + parsed.date.record.year, + parsed.date.record.month, + parsed.date.record.day, + Overflow::Reject, + )?; + let iso = IsoDateTime::new(date, parsed.time)?; + + Ok(Self::new_unchecked( + iso, + Calendar::new(parsed.date.calendar), + )) + } + + /// Creates a new `PlainDateTime` with the fields of a `PartialDateTime`. + /// + /// ```rust + /// use temporal_rs::{Calendar, PlainDateTime, fields::{CalendarFields, DateTimeFields}, partial::{PartialDateTime, PartialTime, PartialDate}}; + /// + /// let initial = PlainDateTime::try_new(2000, 12, 2, 0,0,0,0,0,0, Calendar::default()).unwrap(); + /// + /// let calendar_fields = CalendarFields::new() + /// .with_month(5); + /// + /// let time = PartialTime { + /// hour: Some(4), + /// second: Some(30), + /// ..Default::default() + /// }; + /// + /// let fields = DateTimeFields { calendar_fields, time }; + /// + /// let date = initial.with(fields, None).unwrap(); + /// + /// assert_eq!(date.year(), 2000); + /// assert_eq!(date.month(), 5); + /// assert_eq!(date.day(), 2); + /// assert_eq!(date.calendar().identifier(), "iso8601"); + /// assert_eq!(date.hour(), 4); + /// assert_eq!(date.minute(), 0); + /// assert_eq!(date.second(), 30); + /// assert_eq!(date.millisecond(), 0); + /// + /// ``` + #[inline] + pub fn with(&self, fields: DateTimeFields, overflow: Option) -> TemporalResult { + if fields.is_empty() { + return Err( + TemporalError::r#type().with_message("A PartialDateTime must have a valid field.") + ); + } + let overflow = overflow.unwrap_or(Overflow::Constrain); + + let result_date = self.calendar.date_from_fields( + fields + .calendar_fields + .with_fallback_datetime(self, self.calendar.kind(), overflow)?, + overflow, + )?; + + // Determine the `Time` based off the partial values. + let time = self.iso.time.with(fields.time, overflow)?; + + let iso_datetime = IsoDateTime::new(result_date.iso, time)?; + + Ok(Self::new_unchecked(iso_datetime, self.calendar().clone())) + } + + /// Creates a new `PlainDateTime` from the current `PlainDateTime` and the provided `Time`. + #[inline] + pub fn with_time(&self, time: Option) -> TemporalResult { + let time = time.unwrap_or_default(); + Self::try_new( + self.iso_year(), + self.iso_month(), + self.iso_day(), + time.hour(), + time.minute(), + time.second(), + time.millisecond(), + time.microsecond(), + time.nanosecond(), + self.calendar.clone(), + ) + } + + /// Creates a new `PlainDateTime` from the current `PlainDateTime` and a provided [`Calendar`]. + #[inline] + pub fn with_calendar(&self, calendar: Calendar) -> Self { + Self::new_unchecked(self.iso, calendar) + } + + /// Returns the hour value + #[inline] + #[must_use] + pub fn hour(&self) -> u8 { + self.iso.time.hour + } + + /// Returns the minute value + #[inline] + #[must_use] + pub fn minute(&self) -> u8 { + self.iso.time.minute + } + + /// Returns the second value + #[inline] + #[must_use] + pub fn second(&self) -> u8 { + self.iso.time.second + } + + /// Returns the `millisecond` value + #[inline] + #[must_use] + pub fn millisecond(&self) -> u16 { + self.iso.time.millisecond + } + + /// Returns the `microsecond` value + #[inline] + #[must_use] + pub fn microsecond(&self) -> u16 { + self.iso.time.microsecond + } + + /// Returns the `nanosecond` value + #[inline] + #[must_use] + pub fn nanosecond(&self) -> u16 { + self.iso.time.nanosecond + } + + /// Returns the Calendar value. + #[inline] + #[must_use] + pub fn calendar(&self) -> &Calendar { + &self.calendar + } +} + +// ==== Calendar-derived public API ==== + +impl PlainDateTime { + /// Returns the calendar year value. + #[inline] + pub fn year(&self) -> i32 { + self.calendar.year(&self.iso.date) + } + + /// Returns the calendar month value. + #[inline] + pub fn month(&self) -> u8 { + self.calendar.month(&self.iso.date) + } + + /// Returns the calendar month code value. + #[inline] + pub fn month_code(&self) -> MonthCode { + self.calendar.month_code(&self.iso.date) + } + + /// Returns the calendar day value. + #[inline] + pub fn day(&self) -> u8 { + self.calendar.day(&self.iso.date) + } + + /// Returns the calendar day of week value. + #[inline] + pub fn day_of_week(&self) -> u16 { + self.calendar.day_of_week(&self.iso.date) + } + + /// Returns the calendar day of year value. + #[inline] + pub fn day_of_year(&self) -> u16 { + self.calendar.day_of_year(&self.iso.date) + } + + /// Returns the calendar week of year value. + #[inline] + pub fn week_of_year(&self) -> Option { + self.calendar.week_of_year(&self.iso.date) + } + + /// Returns the calendar year of week value. + #[inline] + pub fn year_of_week(&self) -> Option { + self.calendar.year_of_week(&self.iso.date) + } + + /// Returns the calendar days in week value. + #[inline] + pub fn days_in_week(&self) -> u16 { + self.calendar.days_in_week(&self.iso.date) + } + + /// Returns the calendar days in month value. + #[inline] + pub fn days_in_month(&self) -> u16 { + self.calendar.days_in_month(&self.iso.date) + } + + /// Returns the calendar days in year value. + #[inline] + pub fn days_in_year(&self) -> u16 { + self.calendar.days_in_year(&self.iso.date) + } + + /// Returns the calendar months in year value. + #[inline] + pub fn months_in_year(&self) -> u16 { + self.calendar.months_in_year(&self.iso.date) + } + + /// Returns whether the date in a leap year for the given calendar. + #[inline] + pub fn in_leap_year(&self) -> bool { + self.calendar.in_leap_year(&self.iso.date) + } + + /// Returns the era for the current `PlainDateTime`. + #[inline] + pub fn era(&self) -> Option> { + self.calendar.era(&self.iso.date) + } + + /// Returns the era year for the current `PlainDateTime`. + #[inline] + pub fn era_year(&self) -> Option { + self.calendar.era_year(&self.iso.date) + } +} + +impl PlainDateTime { + /// Compares one `PlainDateTime` to another `PlainDateTime` using their + /// `IsoDate` representation. + /// + /// # Note on Ordering + /// + /// `temporal_rs` does not implement `PartialOrd`/`Ord` as `PlainDateTime` does + /// not fulfill all the conditions required to implement the traits. However, + /// it is possible to compare `PlainDate`'s as their `IsoDate` representation. + #[inline] + #[must_use] + pub fn compare_iso(&self, other: &Self) -> Ordering { + self.iso.cmp(&other.iso) + } + + /// Adds a [`Duration`] to the current `PlainDateTime`. + #[inline] + pub fn add(&self, duration: &Duration, overflow: Option) -> TemporalResult { + self.add_or_subtract_duration(duration, overflow) + } + + /// Subtracts a [`Duration`] to the current `PlainDateTime`. + #[inline] + pub fn subtract( + &self, + duration: &Duration, + overflow: Option, + ) -> TemporalResult { + self.add_or_subtract_duration(&duration.negated(), overflow) + } + + /// Returns a [`Duration`] representing the period of time from this `PlainDateTime` until the other `PlainDateTime`. + #[inline] + pub fn until(&self, other: &Self, settings: DifferenceSettings) -> TemporalResult { + self.diff(DifferenceOperation::Until, other, settings) + } + + /// Returns a [`Duration`] representing the period of time from this `PlainDateTime` since the other `PlainDateTime`. + #[inline] + pub fn since(&self, other: &Self, settings: DifferenceSettings) -> TemporalResult { + self.diff(DifferenceOperation::Since, other, settings) + } + + /// Rounds the current `PlainDateTime` based on provided options. + #[inline] + pub fn round(&self, options: RoundingOptions) -> TemporalResult { + let resolved = ResolvedRoundingOptions::from_datetime_options(options)?; + + if resolved.is_noop() { + return Ok(self.clone()); + } + + let result = self.iso.round(resolved)?; + + Ok(Self::new_unchecked(result, self.calendar.clone())) + } + + /// Create a [`ZonedDateTime`] from the current `PlainDateTime` with the provided options. + #[inline] + pub fn to_zoned_date_time_with_provider( + &self, + time_zone: TimeZone, + disambiguation: Disambiguation, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // 6. Let epochNs be ? GetEpochNanosecondsFor(timeZone, dateTime.[[ISODateTime]], disambiguation). + let epoch_ns = time_zone.get_epoch_nanoseconds_for(self.iso, disambiguation, provider)?; + // 7. Return ! CreateTemporalZonedDateTime(epochNs, timeZone, dateTime.[[Calendar]]). + Ok(ZonedDateTime::new_unchecked( + Instant::from(epoch_ns.ns), + time_zone, + self.calendar.clone(), + epoch_ns.offset, + )) + } + + /// Create a [`PlainDate`] from the current `PlainDateTime`. + #[inline] + pub fn to_plain_date(&self) -> PlainDate { + // 3. Return ! CreateTemporalDate(dateTime.[[ISODateTime]].[[ISODate]], dateTime.[[Calendar]]). + PlainDate::new_unchecked(self.iso.date, self.calendar.clone()) + } + + /// Create a [`PlainTime`] from the current `PlainDateTime`. + #[inline] + pub fn to_plain_time(&self) -> PlainTime { + // 3. Return ! CreateTemporalTime(dateTime.[[ISODateTime]].[[Time]]). + PlainTime::new_unchecked(self.iso.time) + } + + /// Creates an efficient [`Writeable`] implementation for the RFC 9557 IXDTF format + /// using the current `PlainDateTime` and options. + #[inline] + pub fn to_ixdtf_writeable( + &self, + options: ToStringRoundingOptions, + display_calendar: DisplayCalendar, + ) -> TemporalResult { + let resolved_options = options.resolve()?; + let result = self + .iso + .round(ResolvedRoundingOptions::from_to_string_options( + &resolved_options, + ))?; + if !result.is_within_limits() { + return Err(TemporalError::range().with_message("DateTime is not within valid limits.")); + } + let builder = IxdtfStringBuilder::default() + .with_date(result.date) + .with_time(result.time, resolved_options.precision) + .with_calendar(self.calendar.identifier(), display_calendar); + Ok(builder) + } + + /// Returns the RFC 9557 IXDTF string for the current `PlainDateTime` with the provided + /// options. + #[inline] + pub fn to_ixdtf_string( + &self, + options: ToStringRoundingOptions, + display_calendar: DisplayCalendar, + ) -> TemporalResult { + self.to_ixdtf_writeable(options, display_calendar) + .map(|x| x.write_to_string().into()) + } +} + +// ==== Trait impls ==== + +impl FromStr for PlainDateTime { + type Err = TemporalError; + + fn from_str(s: &str) -> Result { + Self::from_utf8(s.as_bytes()) + } +} + +#[cfg(test)] +mod tests { + use tinystr::{tinystr, TinyAsciiStr}; + + use crate::{ + builtins::{ + calendar::CalendarFields, + core::{ + calendar::Calendar, duration::DateDuration, plain_date_time::DateTimeFields, + Duration, PartialTime, PlainDateTime, + }, + }, + iso::{IsoDate, IsoDateTime, IsoTime}, + options::{ + DifferenceSettings, DisplayCalendar, RoundingIncrement, RoundingMode, RoundingOptions, + ToStringRoundingOptions, Unit, + }, + parsers::Precision, + MonthCode, TemporalResult, + }; + + fn assert_datetime( + dt: PlainDateTime, + fields: (i32, u8, TinyAsciiStr<4>, u8, u8, u8, u8, u16, u16, u16), + ) { + assert_eq!(dt.year(), fields.0); + assert_eq!(dt.month(), fields.1); + assert_eq!(dt.month_code(), MonthCode(fields.2)); + assert_eq!(dt.day(), fields.3); + assert_eq!(dt.hour(), fields.4); + assert_eq!(dt.minute(), fields.5); + assert_eq!(dt.second(), fields.6); + assert_eq!(dt.millisecond(), fields.7); + assert_eq!(dt.microsecond(), fields.8); + assert_eq!(dt.nanosecond(), fields.9); + } + + fn pdt_from_date(year: i32, month: u8, day: u8) -> TemporalResult { + PlainDateTime::try_new(year, month, day, 0, 0, 0, 0, 0, 0, Calendar::default()) + } + + #[test] + #[allow(clippy::float_cmp)] + fn plain_date_time_limits() { + // This test is primarily to assert that the `expect` in the epoch methods is + // valid, i.e., a valid instant is within the range of an f64. + let negative_limit = pdt_from_date(-271_821, 4, 19); + assert!(negative_limit.is_err()); + let positive_limit = pdt_from_date(275_760, 9, 14); + assert!(positive_limit.is_err()); + let within_negative_limit = pdt_from_date(-271_821, 4, 20); + assert_eq!( + within_negative_limit, + Ok(PlainDateTime { + iso: IsoDateTime { + date: IsoDate { + year: -271_821, + month: 4, + day: 20, + }, + time: IsoTime::default(), + }, + calendar: Calendar::default(), + }) + ); + + let within_positive_limit = pdt_from_date(275_760, 9, 13); + assert_eq!( + within_positive_limit, + Ok(PlainDateTime { + iso: IsoDateTime { + date: IsoDate { + year: 275_760, + month: 9, + day: 13, + }, + time: IsoTime::default(), + }, + calendar: Calendar::default(), + }) + ); + } + + #[test] + fn basic_with_test() { + let pdt = + PlainDateTime::try_new(1976, 11, 18, 15, 23, 30, 123, 456, 789, Calendar::default()) + .unwrap(); + + // Test year + let fields = DateTimeFields { + calendar_fields: CalendarFields::new().with_year(2019), + time: PartialTime::default(), + }; + let result = pdt.with(fields, None).unwrap(); + assert_datetime( + result, + (2019, 11, tinystr!(4, "M11"), 18, 15, 23, 30, 123, 456, 789), + ); + + // Test month + let fields = DateTimeFields { + calendar_fields: CalendarFields::new().with_month(5), + time: PartialTime::default(), + }; + let result = pdt.with(fields, None).unwrap(); + assert_datetime( + result, + (1976, 5, tinystr!(4, "M05"), 18, 15, 23, 30, 123, 456, 789), + ); + + // Test monthCode + let fields = DateTimeFields { + calendar_fields: CalendarFields::new().with_month_code(MonthCode(tinystr!(4, "M05"))), + time: PartialTime::default(), + }; + let result = pdt.with(fields, None).unwrap(); + assert_datetime( + result, + (1976, 5, tinystr!(4, "M05"), 18, 15, 23, 30, 123, 456, 789), + ); + + // Test day + let fields = DateTimeFields { + calendar_fields: CalendarFields::new().with_day(5), + time: PartialTime::default(), + }; + let result = pdt.with(fields, None).unwrap(); + assert_datetime( + result, + (1976, 11, tinystr!(4, "M11"), 5, 15, 23, 30, 123, 456, 789), + ); + + // Test hour + let fields = DateTimeFields { + calendar_fields: CalendarFields::default(), + time: PartialTime { + hour: Some(5), + ..Default::default() + }, + }; + let result = pdt.with(fields, None).unwrap(); + assert_datetime( + result, + (1976, 11, tinystr!(4, "M11"), 18, 5, 23, 30, 123, 456, 789), + ); + + // Test minute + let fields = DateTimeFields { + calendar_fields: CalendarFields::default(), + time: PartialTime { + minute: Some(5), + ..Default::default() + }, + }; + let result = pdt.with(fields, None).unwrap(); + assert_datetime( + result, + (1976, 11, tinystr!(4, "M11"), 18, 15, 5, 30, 123, 456, 789), + ); + + // Test second + let fields = DateTimeFields { + calendar_fields: CalendarFields::default(), + time: PartialTime { + second: Some(5), + ..Default::default() + }, + }; + let result = pdt.with(fields, None).unwrap(); + assert_datetime( + result, + (1976, 11, tinystr!(4, "M11"), 18, 15, 23, 5, 123, 456, 789), + ); + + // Test second + let fields = DateTimeFields { + calendar_fields: CalendarFields::default(), + time: PartialTime { + millisecond: Some(5), + ..Default::default() + }, + }; + let result = pdt.with(fields, None).unwrap(); + assert_datetime( + result, + (1976, 11, tinystr!(4, "M11"), 18, 15, 23, 30, 5, 456, 789), + ); + + // Test second + let fields = DateTimeFields { + calendar_fields: CalendarFields::default(), + time: PartialTime { + microsecond: Some(5), + ..Default::default() + }, + }; + let result = pdt.with(fields, None).unwrap(); + assert_datetime( + result, + (1976, 11, tinystr!(4, "M11"), 18, 15, 23, 30, 123, 5, 789), + ); + + // Test second + let fields = DateTimeFields { + calendar_fields: CalendarFields::default(), + time: PartialTime { + nanosecond: Some(5), + ..Default::default() + }, + }; + let result = pdt.with(fields, None).unwrap(); + assert_datetime( + result, + (1976, 11, tinystr!(4, "M11"), 18, 15, 23, 30, 123, 456, 5), + ); + } + + #[test] + fn datetime_with_empty_partial() { + let pdt = + PlainDateTime::try_new(2020, 1, 31, 12, 34, 56, 987, 654, 321, Calendar::default()) + .unwrap(); + + let err = pdt.with(DateTimeFields::default(), None); + assert!(err.is_err()); + } + + // options-undefined.js + #[test] + fn datetime_add_test() { + let pdt = + PlainDateTime::try_new(2020, 1, 31, 12, 34, 56, 987, 654, 321, Calendar::default()) + .unwrap(); + + let result = pdt + .add( + &Duration::from(DateDuration::new(0, 1, 0, 0).unwrap()), + None, + ) + .unwrap(); + + assert_eq!(result.month(), 2); + assert_eq!(result.day(), 29); + } + + // options-undefined.js + #[test] + fn datetime_subtract_test() { + let pdt = + PlainDateTime::try_new(2000, 3, 31, 12, 34, 56, 987, 654, 321, Calendar::default()) + .unwrap(); + + let result = pdt + .subtract( + &Duration::from(DateDuration::new(0, 1, 0, 0).unwrap()), + None, + ) + .unwrap(); + + assert_eq!(result.month(), 2); + assert_eq!(result.day(), 29); + } + + // subtract/hour-overflow.js + #[test] + fn datetime_subtract_hour_overflows() { + let dt = + PlainDateTime::try_new(2019, 10, 29, 10, 46, 38, 271, 986, 102, Calendar::default()) + .unwrap(); + + let result = dt.subtract(&Duration::from_hours(12), None).unwrap(); + assert_datetime( + result, + (2019, 10, tinystr!(4, "M10"), 28, 22, 46, 38, 271, 986, 102), + ); + + let result = dt.add(&Duration::from_hours(-12), None).unwrap(); + assert_datetime( + result, + (2019, 10, tinystr!(4, "M10"), 28, 22, 46, 38, 271, 986, 102), + ); + } + + fn create_diff_setting( + smallest: Unit, + increment: u32, + rounding_mode: RoundingMode, + ) -> DifferenceSettings { + DifferenceSettings { + largest_unit: None, + smallest_unit: Some(smallest), + increment: Some(RoundingIncrement::try_new(increment).unwrap()), + rounding_mode: Some(rounding_mode), + } + } + + #[test] + fn dt_until_basic() { + let earlier = + PlainDateTime::try_new(2019, 1, 8, 8, 22, 36, 123, 456, 789, Calendar::default()) + .unwrap(); + let later = + PlainDateTime::try_new(2021, 9, 7, 12, 39, 40, 987, 654, 321, Calendar::default()) + .unwrap(); + + let settings = create_diff_setting(Unit::Hour, 3, RoundingMode::HalfExpand); + let result = earlier.until(&later, settings).unwrap(); + + assert_eq!(result.days(), 973); + assert_eq!(result.hours(), 3); + + let settings = create_diff_setting(Unit::Minute, 30, RoundingMode::HalfExpand); + let result = earlier.until(&later, settings).unwrap(); + + assert_eq!(result.days(), 973); + assert_eq!(result.hours(), 4); + assert_eq!(result.minutes(), 30); + } + + #[test] + fn dt_since_basic() { + let earlier = + PlainDateTime::try_new(2019, 1, 8, 8, 22, 36, 123, 456, 789, Calendar::default()) + .unwrap(); + let later = + PlainDateTime::try_new(2021, 9, 7, 12, 39, 40, 987, 654, 321, Calendar::default()) + .unwrap(); + + let settings = create_diff_setting(Unit::Hour, 3, RoundingMode::HalfExpand); + let result = later.since(&earlier, settings).unwrap(); + + assert_eq!(result.days(), 973); + assert_eq!(result.hours(), 3); + + let settings = create_diff_setting(Unit::Minute, 30, RoundingMode::HalfExpand); + let result = later.since(&earlier, settings).unwrap(); + + assert_eq!(result.days(), 973); + assert_eq!(result.hours(), 4); + assert_eq!(result.minutes(), 30); + } + + #[test] + fn dt_round_basic() { + let assert_datetime = + |dt: PlainDateTime, expected: (i32, u8, u8, u8, u8, u8, u16, u16, u16)| { + assert_eq!(dt.iso_year(), expected.0); + assert_eq!(dt.iso_month(), expected.1); + assert_eq!(dt.iso_day(), expected.2); + assert_eq!(dt.hour(), expected.3); + assert_eq!(dt.minute(), expected.4); + assert_eq!(dt.second(), expected.5); + assert_eq!(dt.millisecond(), expected.6); + assert_eq!(dt.microsecond(), expected.7); + assert_eq!(dt.nanosecond(), expected.8); + }; + + let gen_rounding_options = |smallest: Unit, increment: u32| -> RoundingOptions { + RoundingOptions { + largest_unit: None, + smallest_unit: Some(smallest), + increment: Some(RoundingIncrement::try_new(increment).unwrap()), + rounding_mode: None, + } + }; + let dt = + PlainDateTime::try_new(1976, 11, 18, 14, 23, 30, 123, 456, 789, Calendar::default()) + .unwrap(); + + let result = dt.round(gen_rounding_options(Unit::Hour, 4)).unwrap(); + assert_datetime(result, (1976, 11, 18, 16, 0, 0, 0, 0, 0)); + + let result = dt.round(gen_rounding_options(Unit::Minute, 15)).unwrap(); + assert_datetime(result, (1976, 11, 18, 14, 30, 0, 0, 0, 0)); + + let result = dt.round(gen_rounding_options(Unit::Second, 30)).unwrap(); + assert_datetime(result, (1976, 11, 18, 14, 23, 30, 0, 0, 0)); + + let result = dt + .round(gen_rounding_options(Unit::Millisecond, 10)) + .unwrap(); + assert_datetime(result, (1976, 11, 18, 14, 23, 30, 120, 0, 0)); + + let result = dt + .round(gen_rounding_options(Unit::Microsecond, 10)) + .unwrap(); + assert_datetime(result, (1976, 11, 18, 14, 23, 30, 123, 460, 0)); + + let result = dt + .round(gen_rounding_options(Unit::Nanosecond, 10)) + .unwrap(); + assert_datetime(result, (1976, 11, 18, 14, 23, 30, 123, 456, 790)); + } + + #[test] + fn datetime_round_options() { + let dt = + PlainDateTime::try_new(1976, 11, 18, 14, 23, 30, 123, 456, 789, Calendar::default()) + .unwrap(); + + let bad_options = RoundingOptions { + largest_unit: None, + smallest_unit: None, + rounding_mode: Some(RoundingMode::Ceil), + increment: Some(RoundingIncrement::ONE), + }; + + let err = dt.round(bad_options); + assert!(err.is_err()); + + let err = dt.round(RoundingOptions::default()); + assert!(err.is_err()); + } + + // Mapped from fractionaldigits-number.js + #[test] + fn to_string_precision_digits() { + let few_seconds = + PlainDateTime::try_new(1976, 2, 4, 5, 3, 1, 0, 0, 0, Calendar::default()).unwrap(); + let zero_seconds = + PlainDateTime::try_new(1976, 11, 18, 15, 23, 0, 0, 0, 0, Calendar::default()).unwrap(); + let whole_seconds = + PlainDateTime::try_new(1976, 11, 18, 15, 23, 30, 0, 0, 0, Calendar::default()).unwrap(); + let subseconds = + PlainDateTime::try_new(1976, 11, 18, 15, 23, 30, 123, 400, 0, Calendar::default()) + .unwrap(); + + let options = ToStringRoundingOptions { + precision: Precision::Digit(0), + smallest_unit: None, + rounding_mode: None, + }; + assert_eq!( + &few_seconds + .to_ixdtf_string(options, DisplayCalendar::Auto) + .unwrap(), + "1976-02-04T05:03:01", + "pads parts with 0" + ); + + let options = ToStringRoundingOptions { + precision: Precision::Digit(0), + smallest_unit: None, + rounding_mode: None, + }; + assert_eq!( + &subseconds + .to_ixdtf_string(options, DisplayCalendar::Auto) + .unwrap(), + "1976-11-18T15:23:30", + "truncates 4 decimal places to 0" + ); + + let options = ToStringRoundingOptions { + precision: Precision::Digit(2), + smallest_unit: None, + rounding_mode: None, + }; + assert_eq!( + &zero_seconds + .to_ixdtf_string(options, DisplayCalendar::Auto) + .unwrap(), + "1976-11-18T15:23:00.00", + "pads zero seconds to 2 decimal places" + ); + let options = ToStringRoundingOptions { + precision: Precision::Digit(2), + smallest_unit: None, + rounding_mode: None, + }; + + assert_eq!( + &whole_seconds + .to_ixdtf_string(options, DisplayCalendar::Auto) + .unwrap(), + "1976-11-18T15:23:30.00", + "pads whole seconds to 2 decimal places" + ); + let options = ToStringRoundingOptions { + precision: Precision::Digit(2), + smallest_unit: None, + rounding_mode: None, + }; + assert_eq!( + &subseconds + .to_ixdtf_string(options, DisplayCalendar::Auto) + .unwrap(), + "1976-11-18T15:23:30.12", + "truncates 4 decimal places to 2" + ); + + let options = ToStringRoundingOptions { + precision: Precision::Digit(3), + smallest_unit: None, + rounding_mode: None, + }; + assert_eq!( + &subseconds + .to_ixdtf_string(options, DisplayCalendar::Auto) + .unwrap(), + "1976-11-18T15:23:30.123", + "truncates 4 decimal places to 3" + ); + + let options = ToStringRoundingOptions { + precision: Precision::Digit(6), + smallest_unit: None, + rounding_mode: None, + }; + assert_eq!( + &subseconds + .to_ixdtf_string(options, DisplayCalendar::Auto) + .unwrap(), + "1976-11-18T15:23:30.123400", + "pads 4 decimal places to 6" + ); + let options = ToStringRoundingOptions { + precision: Precision::Digit(7), + smallest_unit: None, + rounding_mode: None, + }; + assert_eq!( + &zero_seconds + .to_ixdtf_string(options, DisplayCalendar::Auto) + .unwrap(), + "1976-11-18T15:23:00.0000000", + "pads zero seconds to 7 decimal places" + ); + let options = ToStringRoundingOptions { + precision: Precision::Digit(7), + smallest_unit: None, + rounding_mode: None, + }; + assert_eq!( + &whole_seconds + .to_ixdtf_string(options, DisplayCalendar::Auto) + .unwrap(), + "1976-11-18T15:23:30.0000000", + "pads whole seconds to 7 decimal places" + ); + let options = ToStringRoundingOptions { + precision: Precision::Digit(7), + smallest_unit: None, + rounding_mode: None, + }; + assert_eq!( + &subseconds + .to_ixdtf_string(options, DisplayCalendar::Auto) + .unwrap(), + "1976-11-18T15:23:30.1234000", + "pads 4 decimal places to 7" + ); + let options = ToStringRoundingOptions { + precision: Precision::Digit(9), + smallest_unit: None, + rounding_mode: None, + }; + assert_eq!( + &subseconds + .to_ixdtf_string(options, DisplayCalendar::Auto) + .unwrap(), + "1976-11-18T15:23:30.123400000", + "pads 4 decimal places to 9" + ); + } + + #[test] + fn datetime_add() { + use crate::{Duration, PlainDateTime}; + use core::str::FromStr; + + let dt = PlainDateTime::from_str("2024-01-15T12:00:00").unwrap(); + + let duration = Duration::from_str("P1M2DT3H4M").unwrap(); + + // Add duration + let later = dt.add(&duration, None).unwrap(); + assert_eq!(later.month(), 2); + assert_eq!(later.day(), 17); + assert_eq!(later.hour(), 15); + assert_eq!(later.minute(), 4); + } +} diff --git a/deps/temporal/src/builtins/core/plain_month_day.rs b/deps/temporal/src/builtins/core/plain_month_day.rs new file mode 100644 index 00000000000000..b60372bce468c6 --- /dev/null +++ b/deps/temporal/src/builtins/core/plain_month_day.rs @@ -0,0 +1,652 @@ +//! This module implements `MonthDay` and any directly related algorithms. + +use alloc::string::String; +use core::str::FromStr; + +use crate::{ + builtins::calendar::CalendarFields, + iso::{IsoDate, IsoDateTime, IsoTime}, + options::{Disambiguation, DisplayCalendar, Overflow}, + parsed_intermediates::ParsedDate, + parsers::{FormattableCalendar, FormattableDate, FormattableMonthDay}, + provider::TimeZoneProvider, + unix_time::EpochNanoseconds, + Calendar, MonthCode, TemporalError, TemporalResult, TimeZone, +}; + +use super::{PartialDate, PlainDate}; +use icu_calendar::AnyCalendarKind; +use writeable::Writeable; + +/// The native Rust implementation of `Temporal.PlainMonthDay`. +/// +/// Represents a calendar month and day without a specific year, such as +/// "December 25th" or "March 15th". Useful for representing recurring annual +/// events where the year is not specified or relevant. +/// +/// Commonly used for holidays, birthdays, anniversaries, and other events +/// that occur on the same date each year. Special handling is required for +/// February 29th when working with non-leap years. +/// +/// ## Examples +/// +/// ### Creating a PlainMonthDay +/// +/// ```rust +/// use temporal_rs::{PlainMonthDay, Calendar, MonthCode, options::Overflow}; +/// +/// // Create March 15th +/// let md = PlainMonthDay::new_with_overflow( +/// 3, 15, // month, day +/// Calendar::default(), // ISO 8601 calendar +/// Overflow::Reject, // reject invalid dates +/// None // no reference year +/// ).unwrap(); +/// +/// assert_eq!(md.month_code(), MonthCode::try_from_utf8("M03".as_bytes()).unwrap()); +/// assert_eq!(md.day(), 15); +/// assert_eq!(md.calendar().identifier(), "iso8601"); +/// ``` +/// +/// ### Parsing ISO 8601 month-day strings +/// +/// ```rust +/// use temporal_rs::{PlainMonthDay, MonthCode}; +/// use core::str::FromStr; +/// +/// // Parse month-day strings +/// let md = PlainMonthDay::from_str("03-15").unwrap(); +/// assert_eq!(md.month_code(), MonthCode::try_from_utf8("M03".as_bytes()).unwrap()); +/// assert_eq!(md.day(), 15); +/// +/// // Also supports various formats +/// let md2 = PlainMonthDay::from_str("--03-15").unwrap(); // RFC 3339 format +/// assert_eq!(md2.month_code(), MonthCode::try_from_utf8("M03".as_bytes()).unwrap()); +/// assert_eq!(md2.day(), 15); +/// assert_eq!(md, md2); // equivalent +/// ``` +/// +/// ### Working with partial fields +/// +/// ```rust +/// use temporal_rs::{PlainMonthDay, MonthCode, fields::CalendarFields}; +/// use core::str::FromStr; +/// +/// let md = PlainMonthDay::from_str("03-15").unwrap(); // March 15th +/// +/// // Change the month +/// let fields = CalendarFields::new().with_month(12); +/// let modified = md.with(fields, None).unwrap(); +/// assert_eq!(modified.month_code(), MonthCode::try_from_utf8("M12".as_bytes()).unwrap()); +/// assert_eq!(modified.day(), 15); // unchanged +/// +/// // Change the day +/// let fields = CalendarFields::new().with_day(25); +/// let modified = md.with(fields, None).unwrap(); +/// assert_eq!(modified.month_code(), MonthCode::try_from_utf8("M03".as_bytes()).unwrap()); // unchanged +/// assert_eq!(modified.day(), 25); +/// ``` +/// +/// ### Converting to PlainDate +/// +/// ```rust +/// use temporal_rs::{PlainMonthDay, fields::CalendarFields}; +/// use core::str::FromStr; +/// +/// let md = PlainMonthDay::from_str("12-25").unwrap(); // December 25th +/// +/// // Convert to a specific date by providing a year +/// let year_fields = CalendarFields::new().with_year(2024); +/// let date = md.to_plain_date(Some(year_fields)).unwrap(); +/// assert_eq!(date.year(), 2024); +/// assert_eq!(date.month(), 12); +/// assert_eq!(date.day(), 25); +/// // This represents December 25th, 2024 +/// ``` +/// +/// ### Handling leap year dates +/// +/// ```rust +/// use temporal_rs::{PlainMonthDay, MonthCode, fields::CalendarFields, Calendar, options::Overflow}; +/// +/// // February 29th (leap day) +/// let leap_day = PlainMonthDay::new_with_overflow( +/// 2, 29, +/// Calendar::default(), +/// Overflow::Reject, +/// Some(2024) // reference year 2024 (a leap year) +/// ).unwrap(); +/// +/// assert_eq!(leap_day.month_code(), MonthCode::try_from_utf8("M02".as_bytes()).unwrap()); +/// assert_eq!(leap_day.day(), 29); +/// +/// // Convert to non-leap year - this would need special handling +/// let year_fields = CalendarFields::new().with_year(2023); // non-leap year +/// let result = leap_day.to_plain_date(Some(year_fields)); +/// // This might fail or be adjusted depending on the calendar's rules +/// ``` +/// +/// ### Practical use cases +/// +/// ```rust +/// use temporal_rs::{PlainMonthDay, fields::CalendarFields}; +/// use core::str::FromStr; +/// +/// // Birthday (recurring annually) +/// let birthday = PlainMonthDay::from_str("07-15").unwrap(); // July 15th +/// +/// // Calculate this year's birthday +/// let this_year = 2024; +/// let year_fields = CalendarFields::new().with_year(this_year); +/// let birthday_2024 = birthday.to_plain_date(Some(year_fields)).unwrap(); +/// assert_eq!(birthday_2024.year(), 2024); +/// assert_eq!(birthday_2024.month(), 7); +/// assert_eq!(birthday_2024.day(), 15); +/// +/// // Holiday (Christmas) +/// let christmas = PlainMonthDay::from_str("12-25").unwrap(); +/// let year_fields = CalendarFields::new().with_year(this_year); +/// let christmas_2024 = christmas.to_plain_date(Some(year_fields)).unwrap(); +/// assert_eq!(christmas_2024.month(), 12); +/// assert_eq!(christmas_2024.day(), 25); +/// ``` +/// +/// ## Reference +/// +/// For more information, see the [MDN documentation][mdn-plainmonthday]. +/// +/// [mdn-plainmonthday]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay +#[non_exhaustive] +#[derive(Debug, Default, Clone, PartialEq, Eq)] +pub struct PlainMonthDay { + pub iso: IsoDate, + calendar: Calendar, +} + +impl core::fmt::Display for PlainMonthDay { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(&self.to_ixdtf_string(DisplayCalendar::Auto)) + } +} + +impl PlainMonthDay { + /// Creates a new unchecked `PlainMonthDay` + #[inline] + #[must_use] + pub(crate) fn new_unchecked(iso: IsoDate, calendar: Calendar) -> Self { + Self { iso, calendar } + } + + /// Returns the ISO month value of `PlainMonthDay`. + #[inline] + #[must_use] + pub(crate) fn iso_month(&self) -> u8 { + self.iso.month + } + + /// Returns the ISO year value of `PlainMonthDay`. + #[inline] + #[must_use] + pub(crate) fn iso_year(&self) -> i32 { + self.iso.year + } +} + +impl PlainMonthDay { + /// Creates a new valid `PlainMonthDay`. + #[inline] + pub fn new_with_overflow( + month: u8, + day: u8, + calendar: Calendar, + overflow: Overflow, + ref_year: Option, + ) -> TemporalResult { + let ry = ref_year.unwrap_or(1972); + // 1972 is the first leap year in the Unix epoch (needed to cover all dates) + let iso = IsoDate::new_with_overflow(ry, month, day, overflow)?; + Ok(Self::new_unchecked(iso, calendar)) + } + + // Converts a UTF-8 encoded string into a `PlainMonthDay`. + pub fn from_utf8(s: &[u8]) -> TemporalResult { + let parsed = ParsedDate::month_day_from_utf8(s)?; + Self::from_parsed(parsed) + } + + // Converts a ParsedDate into a `PlainMonthDay`. + // + // Be sure to parse this using [`ParsedDate::month_day_from_utf8()`]~ + pub fn from_parsed(parsed: ParsedDate) -> TemporalResult { + let calendar = Calendar::new(parsed.calendar); + // 10. If calendar is "iso8601", then + if parsed.calendar == AnyCalendarKind::Iso { + // a. Let referenceISOYear be 1972 (the first ISO 8601 leap year after the epoch). + // b. Let isoDate be CreateISODateRecord(referenceISOYear, result.[[Month]], result.[[Day]]). + // c. Return !CreateTemporalMonthDay(isoDate, calendar). + let iso = IsoDate::new_unchecked(1972, parsed.record.month, parsed.record.day); + debug_assert!(iso.check_validity().is_ok(), "Found invalid ParsedDate"); + return Ok(Self::new_unchecked(iso, calendar)); + } + // 11. Let isoDate be CreateISODateRecord(result.[[Year]], result.[[Month]], result.[[Day]]). + // 12. If ISODateWithinLimits(isoDate) is false, throw a RangeError exception. + // Note: parse_month_day will refuse to parse MM-DD format month-days for non-ISO, but + // it will happily parse YYYY-MM-DD[u-ca=CAL]. These will be valid ISO dates; but they + // could potentially be out of Temporal range. + let iso = + IsoDate::new_unchecked(parsed.record.year, parsed.record.month, parsed.record.day); + iso.check_within_limits()?; + debug_assert!(iso.check_validity().is_ok(), "Found invalid ParsedDate"); + + // 13. Set result to ISODateToFields(calendar, isoDate, month-day). + + let intermediate = Self::new_unchecked(iso, Calendar::new(parsed.calendar)); + let fields = CalendarFields::from_month_day(&intermediate); + // 14. NOTE: The following operation is called with constrain regardless of the value of overflow, in + // order for the calendar to store a canonical value in the [[Year]] field of the [[ISODate]] internal slot of the result. + // 15. Set isoDate to ? CalendarMonthDayFromFields(calendar, result, constrain). + intermediate + .calendar() + .month_day_from_fields(fields, Overflow::Constrain) + } + + /// Create a `PlainYearMonth` from a `PartialDate` + pub fn from_partial(partial: PartialDate, overflow: Option) -> TemporalResult { + partial + .calendar + .month_day_from_fields(partial.calendar_fields, overflow.unwrap_or_default()) + } + + /// Create a `PlainMonthDay` with the provided fields from a [`PartialDate`]. + pub fn with(&self, fields: CalendarFields, overflow: Option) -> TemporalResult { + // Steps 1-6 are engine specific. + // 5. Let fields be ISODateToFields(calendar, monthDay.[[ISODate]], month-day). + // 6. Let partialMonthDay be ? PrepareCalendarFields(calendar, temporalMonthDayLike, « year, month, month-code, day », « », partial). + // + // NOTE: We assert that partial is not empty per step 6 + if fields.is_empty() { + return Err(TemporalError::r#type().with_message("partial object must have a field.")); + } + + // NOTE: We only need to set month / month_code and day, per spec. + // 7. Set fields to CalendarMergeFields(calendar, fields, partialMonthDay). + let merged_day = fields.day.unwrap_or(self.day()); + let mut merged = fields.with_day(merged_day); + if merged.month.is_none() && merged.month_code.is_none() { + // MonthDay resolution prefers month codes + // (ordinal months work, but require year information, which + // we may not have) + // We should NOT merge over year information even though we have it. + merged = merged.with_month_code(self.month_code()); + } + // Step 8-9 already handled by engine. + // 8. Let resolvedOptions be ? GetOptionsObject(options). + // 9. Let overflow be ? GetTemporalOverflowOption(resolvedOptions). + // 10. Let isoDate be ? CalendarMonthDayFromFields(calendar, fields, overflow). + // 11. Return ! CreateTemporalMonthDay(isoDate, calendar). + self.calendar + .month_day_from_fields(merged, overflow.unwrap_or(Overflow::Constrain)) + } + + /// Returns the string identifier for the current `Calendar`. + #[inline] + #[must_use] + pub fn calendar_id(&self) -> &'static str { + self.calendar.identifier() + } + + /// Returns a reference to `PlainMonthDay`'s inner `Calendar`. + #[inline] + #[must_use] + pub fn calendar(&self) -> &Calendar { + &self.calendar + } + + /// Returns the calendar `monthCode` value of `PlainMonthDay`. + #[inline] + pub fn month_code(&self) -> MonthCode { + self.calendar.month_code(&self.iso) + } + + /// Returns the calendar day value of `PlainMonthDay`. + #[inline] + pub fn day(&self) -> u8 { + self.calendar.day(&self.iso) + } + + /// Returns the internal reference year used by this MonthDay. + #[inline] + pub fn reference_year(&self) -> i32 { + self.calendar.year(&self.iso) + } + + /// Create a [`PlainDate`] from the current `PlainMonthDay`. + pub fn to_plain_date(&self, year: Option) -> TemporalResult { + let year_partial = match &year { + Some(partial) => partial, + None => return Err(TemporalError::r#type().with_message("Year must be provided")), + }; + + // Fallback logic: prefer year, else era/era_year + let mut fields = CalendarFields::new() + .with_month_code(self.month_code()) + .with_day(self.day()); + + if let Some(year) = year_partial.year { + fields.year = Some(year); + } else if let (Some(era), Some(era_year)) = (year_partial.era, year_partial.era_year) { + fields.era = Some(era); + fields.era_year = Some(era_year); + } else { + return Err(TemporalError::r#type() + .with_message("PartialDate must contain a year or era/era_year fields")); + } + + // 8. Let isoDate be ? CalendarDateFromFields(calendar, mergedFields, constrain). + self.calendar.date_from_fields(fields, Overflow::Constrain) + } + + /// Gets the epochMilliseconds represented by this YearMonth in the given timezone + /// (using the reference year, and noon time) + /// + // Useful for implementing HandleDateTimeTemporalYearMonth + pub fn epoch_ns_for_with_provider( + &self, + time_zone: TimeZone, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // 2. Let isoDateTime be CombineISODateAndTimeRecord(temporalYearMonth.[[ISODate]], NoonTimeRecord()). + let iso = IsoDateTime::new(self.iso, IsoTime::noon())?; + // 3. Let epochNs be ? GetEpochNanosecondsFor(dateTimeFormat.[[TimeZone]], isoDateTime, compatible). + Ok(time_zone + .get_epoch_nanoseconds_for(iso, Disambiguation::Compatible, provider)? + .ns) + } + + /// Creates a RFC9557 IXDTF string from the current `PlainMonthDay`. + pub fn to_ixdtf_string(&self, display_calendar: DisplayCalendar) -> String { + self.to_ixdtf_writeable(display_calendar) + .write_to_string() + .into() + } + + /// Creates a RFC9557 IXDTF [`Writeable`]. + pub fn to_ixdtf_writeable(&self, display_calendar: DisplayCalendar) -> impl Writeable + '_ { + let ixdtf = FormattableMonthDay { + date: FormattableDate(self.iso_year(), self.iso_month(), self.iso.day), + calendar: FormattableCalendar { + show: display_calendar, + calendar: self.calendar().identifier(), + }, + }; + ixdtf + } +} + +impl FromStr for PlainMonthDay { + type Err = TemporalError; + + fn from_str(s: &str) -> Result { + Self::from_utf8(s.as_bytes()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::Calendar; + use tinystr::tinystr; + + #[test] + fn test_plain_month_day_with() { + let month_day = PlainMonthDay::from_utf8("01-15".as_bytes()).unwrap(); + + let new = month_day + .with(CalendarFields::new().with_day(22), None) + .unwrap(); + assert_eq!( + new.month_code(), + MonthCode::try_from_utf8("M01".as_bytes()).unwrap() + ); + assert_eq!(new.day(), 22,); + + let new = month_day + .with(CalendarFields::new().with_month(12), None) + .unwrap(); + assert_eq!( + new.month_code(), + MonthCode::try_from_utf8("M12".as_bytes()).unwrap() + ); + assert_eq!(new.day(), 15,); + } + + #[test] + fn test_to_plain_date_with_year() { + let month_day = + PlainMonthDay::new_with_overflow(5, 15, Calendar::default(), Overflow::Reject, None) + .unwrap(); + + let fields = CalendarFields::new().with_year(2025); + let plain_date = month_day.to_plain_date(Some(fields)).unwrap(); + assert_eq!(plain_date.iso_year(), 2025); + assert_eq!(plain_date.iso_month(), 5); + assert_eq!(plain_date.iso_day(), 15); + } + + #[test] + fn test_to_plain_date_with_era_and_era_year() { + // Use a calendar that supports era/era_year, e.g., "gregory" + let calendar = Calendar::from_str("gregory").unwrap(); + let month_day = + PlainMonthDay::new_with_overflow(3, 10, calendar.clone(), Overflow::Reject, None) + .unwrap(); + + // Era "ce" and era_year 2020 should resolve to year 2020 in Gregorian + let fields = CalendarFields::new() + .with_era(Some(tinystr!(19, "ce"))) + .with_era_year(Some(2020)); + let plain_date = month_day.to_plain_date(Some(fields)); + // Gregorian calendar in ICU4X may not resolve era/era_year unless year is also provided. + // Accept both Ok and Err, but if Ok, check the values. + match plain_date { + Ok(plain_date) => { + assert_eq!(plain_date.iso_year(), 2020); + assert_eq!(plain_date.iso_month(), 3); + assert_eq!(plain_date.iso_day(), 10); + } + Err(_) => { + // Acceptable if era/era_year fallback is not supported by the calendar impl + } + } + } + + #[test] + fn test_to_plain_date_missing_year_and_era() { + let month_day = + PlainMonthDay::new_with_overflow(7, 4, Calendar::default(), Overflow::Reject, None) + .unwrap(); + + // No year, no era/era_year + let fields = CalendarFields::new(); + let result = month_day.to_plain_date(Some(fields)); + assert!(result.is_err()); + } + + #[test] + fn test_to_plain_date_with_fallback_logic_matches_date() { + // This test ensures that the fallback logic in month_day matches the fallback logic in date.rs + let calendar = Calendar::from_str("gregory").unwrap(); + let month_day = + PlainMonthDay::new_with_overflow(12, 25, calendar.clone(), Overflow::Reject, None) + .unwrap(); + + // Provide only era/era_year, not year + let fields = CalendarFields::new() + .with_era(Some(tinystr!(19, "ce"))) + .with_era_year(Some(1999)); + let plain_date = month_day.to_plain_date(Some(fields)); + match plain_date { + Ok(plain_date) => { + assert_eq!(plain_date.iso_year(), 1999); + assert_eq!(plain_date.iso_month(), 12); + assert_eq!(plain_date.iso_day(), 25); + } + Err(_) => { + // Acceptable if era/era_year fallback is not supported by the calendar impl + } + } + } + #[test] + fn test_valid_strings() { + const TESTS: &[&str] = &[ + "02-29", + "02-28", + "2025-08-05", + "2025-08-05[u-ca=gregory]", + "2024-02-29[u-ca=gregory]", + ]; + for test in TESTS { + assert!(PlainMonthDay::from_utf8(test.as_bytes()).is_ok()); + } + } + #[test] + fn test_invalid_strings() { + const TESTS: &[&str] = &[ + // Out of range + "-99999-01-01", + "-99999-01-01[u-ca=gregory]", + // Not a leap year + "2025-02-29", + "2025-02-29[u-ca=gregory]", + // Format not allowed for non-Gregorian + "02-28[u-ca=gregory]", + ]; + for test in TESTS { + assert!(PlainMonthDay::from_utf8(test.as_bytes()).is_err()); + } + } + + #[test] + /// This test is for calendars where we don't wish to hardcode dates; but we do wish to know + /// that monthcodes can be constructed without issue + fn automated_reference_year() { + let reference_iso = IsoDate::new_unchecked(1972, 12, 31); + for cal in [ + AnyCalendarKind::HijriSimulatedMecca, + AnyCalendarKind::HijriUmmAlQura, + ] { + let calendar = Calendar::new(cal); + for month in 1..=12 { + for day in [29, 30] { + let month_code = crate::builtins::calendar::month_to_month_code(month).unwrap(); + + let calendar_fields = CalendarFields { + month_code: Some(month_code), + day: Some(day), + ..Default::default() + }; + + let md = calendar + .month_day_from_fields(calendar_fields, Overflow::Reject) + .unwrap(); + + assert!( + md.iso <= reference_iso, + "Reference ISO for {month}-{day} must be before 1972-12-31, found, {:?}", + md.iso, + ); + } + } + } + } + + #[test] + fn manual_test_reference_year() { + // monthCode, day, ISO string, expectedReferenceYear + // Some of these parsed strings are deliberately not using the reference year + // so that we can test all code paths. By default, when adding new strings, it is easier + // to just add the reference year + const TESTS: &[(&str, u8, &str, i32)] = &[ + ("M10", 30, "1868-10-30[u-ca=gregory]", 1972), + ("M08", 8, "1868-10-30[u-ca=indian]", 1894), + ("M09", 21, "2000-12-12[u-ca=indian]", 1894), + // Dates in the earlier half of the year get pushed back a year + ("M10", 22, "2000-01-12[u-ca=indian]", 1893), + ("M01", 11, "2000-03-30[u-ca=persian]", 1351), + ("M09", 22, "2000-12-12[u-ca=persian]", 1351), + ("M12", 29, "2025-03-19[u-ca=persian]", 1350), + // Leap day + ("M12", 30, "2025-03-20[u-ca=persian]", 1350), + ("M01", 1, "2025-03-21[u-ca=persian]", 1351), + ("M01", 1, "2025-03-21[u-ca=persian]", 1351), + ("M01", 1, "1972-01-01[u-ca=roc]", 61), + ("M02", 29, "2024-02-29[u-ca=roc]", 61), + ("M12", 1, "1972-12-01[u-ca=roc]", 61), + ("M01", 1, "1972-09-11[u-ca=coptic]", 1689), + ("M12", 1, "1972-08-07[u-ca=coptic]", 1688), + ("M13", 5, "1972-09-10[u-ca=coptic]", 1688), + ("M13", 6, "1971-09-11[u-ca=coptic]", 1687), + ("M01", 1, "1972-09-11[u-ca=ethiopic]", 1965), + ("M12", 1, "1972-08-07[u-ca=ethiopic]", 1964), + ("M13", 5, "1972-09-10[u-ca=ethiopic]", 1964), + ("M13", 6, "1971-09-11[u-ca=ethiopic]", 1963), + ("M01", 1, "1972-09-11[u-ca=ethioaa]", 7465), + ("M12", 1, "1972-08-07[u-ca=ethioaa]", 7464), + ("M13", 5, "1972-09-10[u-ca=ethioaa]", 7464), + ("M13", 6, "1971-09-11[u-ca=ethioaa]", 7463), + ("M01", 1, "1972-09-09[u-ca=hebrew]", 5733), + ("M02", 29, "1972-11-06[u-ca=hebrew]", 5733), + ("M03", 29, "1972-12-05[u-ca=hebrew]", 5733), + ("M03", 30, "1971-12-18[u-ca=hebrew]", 5732), + ("M05L", 29, "1970-03-07[u-ca=hebrew]", 5730), + ("M07", 1, "1972-03-16[u-ca=hebrew]", 5732), + ("M01", 1, "1972-02-16[u-ca=islamic-civil]", 1392), + ("M12", 29, "1972-02-15[u-ca=islamic-civil]", 1391), + ("M12", 30, "1971-02-26[u-ca=islamic-civil]", 1390), + ("M01", 1, "1972-02-15[u-ca=islamic-tbla]", 1392), + ("M12", 29, "1972-02-14[u-ca=islamic-tbla]", 1391), + ("M12", 30, "1971-02-25[u-ca=islamic-tbla]", 1390), + ]; + let reference_iso = IsoDate::new_unchecked(1972, 12, 31); + for (month_code, day, string, year) in TESTS { + let md = PlainMonthDay::from_str(string).expect(string); + + let calendar_fields = CalendarFields { + month_code: Some(month_code.parse().unwrap()), + day: Some(*day), + ..Default::default() + }; + + let md_from_partial = md + .calendar() + .month_day_from_fields(calendar_fields, Overflow::Reject) + .expect(string); + + assert_eq!( + md, + md_from_partial, + "Parsed {string}, compared with {}: Expected {}-{}, Found {}-{}", + md_from_partial.to_ixdtf_string(Default::default()), + md_from_partial.month_code().0, + md_from_partial.day(), + md.month_code().0, + md.day() + ); + + assert_eq!( + md_from_partial.reference_year(), + *year, + "Reference year for {string} ({month_code}-{day}) must be {year}", + ); + + assert!( + md.iso <= reference_iso && md_from_partial.iso <= reference_iso, + "Reference ISO for {string} ({}-{}) must be before 1972-12-31, found, {:?} / {:?}", + md.month_code().0, + md.day(), + md.iso, + md_from_partial.iso + ); + } + } +} diff --git a/deps/temporal/src/builtins/core/plain_time.rs b/deps/temporal/src/builtins/core/plain_time.rs new file mode 100644 index 00000000000000..0edd7ec8f25c35 --- /dev/null +++ b/deps/temporal/src/builtins/core/plain_time.rs @@ -0,0 +1,860 @@ +//! This module implements `Time` and any directly related algorithms. + +use crate::{ + builtins::{ + core::{DateDuration, Duration}, + duration::normalized::InternalDurationRecord, + }, + iso::IsoTime, + options::{ + DifferenceOperation, DifferenceSettings, Overflow, ResolvedRoundingOptions, + RoundingOptions, ToStringRoundingOptions, Unit, UnitGroup, + }, + parsers::{parse_time, IxdtfStringBuilder}, + TemporalError, TemporalResult, +}; +use alloc::string::String; +use core::str::FromStr; +use writeable::Writeable; + +use super::{duration::normalized::TimeDuration, PlainDateTime}; + +// TODO: add a PartialSignedTime + +/// A `PartialTime` represents partially filled `Time` fields. +#[derive(Debug, Default, Clone, Copy, PartialEq)] +pub struct PartialTime { + // A potentially set `hour` field. + pub hour: Option, + // A potentially set `minute` field. + pub minute: Option, + // A potentially set `second` field. + pub second: Option, + // A potentially set `millisecond` field. + pub millisecond: Option, + // A potentially set `microsecond` field. + pub microsecond: Option, + // A potentially set `nanosecond` field. + pub nanosecond: Option, +} + +impl PartialTime { + pub fn is_empty(&self) -> bool { + *self == Self::default() + } +} + +/// Convenience methods for building a `PartialTime` +impl PartialTime { + pub const fn new() -> Self { + Self { + hour: None, + minute: None, + second: None, + millisecond: None, + microsecond: None, + nanosecond: None, + } + } + + pub const fn with_hour(mut self, hour: Option) -> Self { + self.hour = hour; + self + } + + pub const fn with_minute(mut self, minute: Option) -> Self { + self.minute = minute; + self + } + + pub const fn with_second(mut self, second: Option) -> Self { + self.second = second; + self + } + + pub const fn with_millisecond(mut self, millisecond: Option) -> Self { + self.millisecond = millisecond; + self + } + + pub const fn with_microsecond(mut self, microsecond: Option) -> Self { + self.microsecond = microsecond; + self + } + + pub const fn with_nanosecond(mut self, nanosecond: Option) -> Self { + self.nanosecond = nanosecond; + self + } +} + +/// The native Rust implementation of `Temporal.PlainTime`. +/// +/// Represents a time of day such as "14:30:45.123" without any date or timezone +/// information. Contains hour, minute, second, and subsecond components with +/// nanosecond precision. +/// +/// Ideal for representing recurring daily events, schedules, or any time value +/// where the specific date is not relevant. +/// +/// ## Examples +/// +/// ### Creating time values +/// +/// ```rust +/// use temporal_rs::PlainTime; +/// +/// // High-precision time +/// let precise_time = PlainTime::try_new( +/// 14, 30, 45, // 2:30:45 PM +/// 123, 456, 789 // subsecond components +/// ).unwrap(); +/// assert_eq!(precise_time.hour(), 14); +/// assert_eq!(precise_time.millisecond(), 123); +/// +/// // Simple time without subseconds +/// let simple = PlainTime::try_new(9, 0, 0, 0, 0, 0).unwrap(); +/// assert_eq!(simple.hour(), 9); +/// ``` +/// +/// ### Parsing ISO 8601 time strings +/// +/// ```rust +/// use temporal_rs::PlainTime; +/// use core::str::FromStr; +/// +/// let time = PlainTime::from_str("14:30:45.123456789").unwrap(); +/// assert_eq!(time.hour(), 14); +/// assert_eq!(time.minute(), 30); +/// assert_eq!(time.second(), 45); +/// assert_eq!(time.millisecond(), 123); +/// assert_eq!(time.microsecond(), 456); +/// assert_eq!(time.nanosecond(), 789); +/// +/// // Also supports time-only portions of ISO 8601 strings +/// let time = PlainTime::from_str("T09:15:30").unwrap(); +/// assert_eq!(time.hour(), 9); +/// assert_eq!(time.minute(), 15); +/// assert_eq!(time.second(), 30); +/// ``` +/// +/// ### Time arithmetic +/// +/// ```rust +/// use temporal_rs::{PlainTime, Duration}; +/// use core::str::FromStr; +/// +/// let time = PlainTime::from_str("12:30:00").unwrap(); +/// +/// // Add 2 hours and 30 minutes +/// let later = time.add(&Duration::from_str("PT2H30M").unwrap()).unwrap(); +/// assert_eq!(later.hour(), 15); +/// assert_eq!(later.minute(), 0); +/// assert_eq!(later.second(), 0); +/// +/// // Calculate difference between times +/// let earlier = PlainTime::from_str("10:00:00").unwrap(); +/// let duration = earlier.until(&time, Default::default()).unwrap(); +/// assert_eq!(duration.hours(), 2); +/// assert_eq!(duration.minutes(), 30); +/// ``` +/// +/// ### Working with partial time fields +/// +/// ```rust +/// use temporal_rs::{PlainTime, partial::PartialTime}; +/// use core::str::FromStr; +/// +/// let time = PlainTime::from_str("12:30:45").unwrap(); +/// +/// // Change only the minute +/// let partial = PartialTime::new().with_minute(Some(15)); +/// let modified = time.with(partial, None).unwrap(); +/// assert_eq!(modified.hour(), 12); // unchanged +/// assert_eq!(modified.minute(), 15); // changed +/// assert_eq!(modified.second(), 45); // unchanged +/// ``` +/// +/// ### Rounding times +/// +/// ```rust +/// use temporal_rs::{PlainTime, options::{Unit, RoundingOptions}}; +/// use core::str::FromStr; +/// +/// let time = PlainTime::from_str("14:23:47.789").unwrap(); +/// +/// let mut options = RoundingOptions::default(); +/// options.smallest_unit = Some(Unit::Minute); +/// // Round to nearest minute +/// let rounded = time.round(options).unwrap(); +/// assert_eq!(rounded.hour(), 14); +/// assert_eq!(rounded.minute(), 24); +/// assert_eq!(rounded.second(), 0); +/// assert_eq!(rounded.millisecond(), 0); +/// ``` +/// +/// ## Reference +/// +/// For more information, see the [MDN documentation][mdn-plaintime]. +/// +/// [mdn-plaintime]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime +#[non_exhaustive] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct PlainTime { + pub(crate) iso: IsoTime, +} + +// ==== Private API ==== + +impl PlainTime { + #[inline] + #[must_use] + /// Creates a new unvalidated `Time`. + pub(crate) fn new_unchecked(iso: IsoTime) -> Self { + Self { iso } + } + + /// Specification equivalent to `4.5.15 AddTime ( time, timeDuration )` + /// + /// Spec: + pub(crate) fn add_normalized_time_duration(&self, norm: TimeDuration) -> (i64, Self) { + // 1. Set second to second + TimeDurationSeconds(norm). + let second = i64::from(self.second()) + norm.seconds(); + // 2. Set nanosecond to nanosecond + TimeDurationSubseconds(norm). + let nanosecond = i32::from(self.nanosecond()) + norm.subseconds(); + // 3. Return BalanceTime(hour, minute, second, millisecond, microsecond, nanosecond). + let (day, balance_result) = IsoTime::balance( + self.hour().into(), + self.minute().into(), + second, + self.millisecond().into(), + self.microsecond().into(), + nanosecond.into(), + ); + + (day, Self::new_unchecked(balance_result)) + } + + /// Adds a `Duration` to the current `Time`. + /// + /// Spec Equivalent: `AddDurationToOrSubtractDurationFromPlainTime`. + pub(crate) fn add_to_time(&self, duration: &Duration) -> TemporalResult { + let (_, result) = IsoTime::balance( + i64::from(self.hour()).saturating_add(duration.hours()), + i64::from(self.minute()).saturating_add(duration.minutes()), + i64::from(self.second()).saturating_add(duration.seconds()), + i64::from(self.millisecond()).saturating_add(duration.milliseconds()), + i128::from(self.microsecond()).saturating_add(duration.microseconds()), + i128::from(self.nanosecond()).saturating_add(duration.nanoseconds()), + ); + + // NOTE (nekevss): IsoTime::balance should never return an invalid `IsoTime` + + Ok(Self::new_unchecked(result)) + } + + // TODO: Migrate to + /// Performs a desired difference op between two `Time`'s, returning the resulting `Duration`. + pub(crate) fn diff_time( + &self, + op: DifferenceOperation, + other: &PlainTime, + settings: DifferenceSettings, + ) -> TemporalResult { + // 1. If operation is SINCE, let sign be -1. Otherwise, let sign be 1. + // 2. Set other to ? ToTemporalTime(other). + // 3. Let resolvedOptions be ? SnapshotOwnProperties(? GetOptionsObject(options), null). + // 4. Let settings be ? GetDifferenceSettings(operation, resolvedOptions, TIME, « », "nanosecond", "hour"). + let resolved = ResolvedRoundingOptions::from_diff_settings( + settings, + op, + UnitGroup::Time, + Unit::Hour, + Unit::Nanosecond, + )?; + // 4. Let timeDuration be DifferenceTime(temporalTime.[[Time]], other.[[Time]]). + let mut normalized_time = self.iso.diff(&other.iso); + // 5. Set timeDuration to ! RoundTimeDuration(timeDuration, settings.[[RoundingIncrement]], settings.[[SmallestUnit]], settings.[[RoundingMode]]). + normalized_time = normalized_time.round(resolved)?; + // 6. Let duration be CombineDateAndTimeDuration(ZeroDateDuration(), timeDuration). + let duration = InternalDurationRecord::combine(DateDuration::default(), normalized_time); + // 7. Let result be ! TemporalDurationFromInternal(duration, settings.[[LargestUnit]]). + let result = Duration::from_internal(duration, resolved.largest_unit)?; + // 8. If operation is since, set result to CreateNegatedTemporalDuration(result). + // 9. Return result. + // 8. Return ! CreateTemporalDuration(0, 0, 0, 0, sign × result.[[Hours]], sign × result.[[Minutes]], sign × result.[[Seconds]], sign × result.[[Milliseconds]], sign × result.[[Microseconds]], sign × result.[[Nanoseconds]]). + match op { + DifferenceOperation::Until => Ok(result), + DifferenceOperation::Since => Ok(result.negated()), + } + } +} + +// ==== Public API ==== + +impl PlainTime { + /// Creates a new `PlainTime`, constraining any field into a valid range. + /// + /// ```rust + /// use temporal_rs::PlainTime; + /// + /// let time = PlainTime::new(23, 59, 59, 999, 999, 999).unwrap(); + /// + /// let constrained_time = PlainTime::new(24, 59, 59, 999, 999, 999).unwrap(); + /// assert_eq!(time, constrained_time); + /// ``` + pub fn new( + hour: u8, + minute: u8, + second: u8, + millisecond: u16, + microsecond: u16, + nanosecond: u16, + ) -> TemporalResult { + Self::new_with_overflow( + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + Overflow::Constrain, + ) + } + + /// Creates a new `PlainTime`, rejecting any field that is not in a valid range. + /// + /// ```rust + /// use temporal_rs::PlainTime; + /// + /// let time = PlainTime::try_new(23, 59, 59, 999, 999, 999).unwrap(); + /// + /// let invalid_time = PlainTime::try_new(24, 59, 59, 999, 999, 999); + /// assert!(invalid_time.is_err()); + /// ``` + pub fn try_new( + hour: u8, + minute: u8, + second: u8, + millisecond: u16, + microsecond: u16, + nanosecond: u16, + ) -> TemporalResult { + Self::new_with_overflow( + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + Overflow::Reject, + ) + } + + /// Creates a new `PlainTime` with the provided [`Overflow`] option. + #[inline] + pub fn new_with_overflow( + hour: u8, + minute: u8, + second: u8, + millisecond: u16, + microsecond: u16, + nanosecond: u16, + overflow: Overflow, + ) -> TemporalResult { + let time = IsoTime::new( + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + overflow, + )?; + Ok(Self::new_unchecked(time)) + } + + /// Creates a new `PlainTime` from a `PartialTime`. + /// + /// ```rust + /// use temporal_rs::{partial::PartialTime, PlainTime}; + /// + /// let partial_time = PartialTime { + /// hour: Some(22), + /// ..Default::default() + /// }; + /// + /// let time = PlainTime::from_partial(partial_time, None).unwrap(); + /// + /// assert_eq!(time.hour(), 22); + /// assert_eq!(time.minute(), 0); + /// assert_eq!(time.second(), 0); + /// assert_eq!(time.millisecond(), 0); + /// assert_eq!(time.microsecond(), 0); + /// assert_eq!(time.nanosecond(), 0); + /// + /// ``` + pub fn from_partial(partial: PartialTime, overflow: Option) -> TemporalResult { + // NOTE: 4.5.12 ToTemporalTimeRecord requires one field to be set. + if partial.is_empty() { + return Err(TemporalError::r#type().with_message("PartialTime cannot be empty.")); + } + + let overflow = overflow.unwrap_or_default(); + let iso = IsoTime::default().with(partial, overflow)?; + Ok(Self::new_unchecked(iso)) + } + + // Converts a UTF-8 encoded string into a `PlainTime`. + pub fn from_utf8(s: &[u8]) -> TemporalResult { + let result = parse_time(s)?; + let iso = IsoTime::from_time_record(result)?; + Ok(Self::new_unchecked(iso)) + } + + /// Creates a new `PlainTime` using the current `PlainTime` fields as a fallback. + /// + /// ```rust + /// use temporal_rs::{partial::PartialTime, PlainTime}; + /// + /// let partial_time = PartialTime { + /// hour: Some(22), + /// ..Default::default() + /// }; + /// + /// let initial = PlainTime::try_new(15, 30, 12, 123, 456, 789).unwrap(); + /// + /// let time = initial.with(partial_time, None).unwrap(); + /// + /// assert_eq!(time.hour(), 22); + /// assert_eq!(time.minute(), 30); + /// assert_eq!(time.second(), 12); + /// assert_eq!(time.millisecond(), 123); + /// assert_eq!(time.microsecond(), 456); + /// assert_eq!(time.nanosecond(), 789); + /// + /// ``` + pub fn with(&self, partial: PartialTime, overflow: Option) -> TemporalResult { + // NOTE: 4.5.12 ToTemporalTimeRecord requires one field to be set. + if partial.is_empty() { + return Err(TemporalError::r#type().with_message("PartialTime cannot be empty.")); + } + + let iso = self + .iso + .with(partial, overflow.unwrap_or(Overflow::Constrain))?; + Ok(Self::new_unchecked(iso)) + } + + /// Returns the internal `hour` field. + #[inline] + #[must_use] + pub const fn hour(&self) -> u8 { + self.iso.hour + } + + /// Returns the internal `minute` field. + #[inline] + #[must_use] + pub const fn minute(&self) -> u8 { + self.iso.minute + } + + /// Returns the internal `second` field. + #[inline] + #[must_use] + pub const fn second(&self) -> u8 { + self.iso.second + } + + /// Returns the internal `millisecond` field. + #[inline] + #[must_use] + pub const fn millisecond(&self) -> u16 { + self.iso.millisecond + } + + /// Returns the internal `microsecond` field. + #[inline] + #[must_use] + pub const fn microsecond(&self) -> u16 { + self.iso.microsecond + } + + /// Returns the internal `nanosecond` field. + #[inline] + #[must_use] + pub const fn nanosecond(&self) -> u16 { + self.iso.nanosecond + } + + /// Add a `Duration` to the current `Time`. + pub fn add(&self, duration: &Duration) -> TemporalResult { + self.add_to_time(duration) + } + + /// Subtract a `Duration` to the current `Time`. + pub fn subtract(&self, duration: &Duration) -> TemporalResult { + self.add_to_time(&duration.negated()) + } + + /// Returns the `Duration` until the provided `Time` from the current `Time`. + /// + /// NOTE: `until` assumes the provided other time will occur in the future relative to the current. + #[inline] + pub fn until(&self, other: &Self, settings: DifferenceSettings) -> TemporalResult { + self.diff_time(DifferenceOperation::Until, other, settings) + } + + /// Returns the `Duration` since the provided `Time` from the current `Time`. + /// + /// NOTE: `since` assumes the provided other time is in the past relative to the current. + #[inline] + pub fn since(&self, other: &Self, settings: DifferenceSettings) -> TemporalResult { + self.diff_time(DifferenceOperation::Since, other, settings) + } + + // TODO (nekevss): optimize and test rounding_increment type (f64 vs. u64). + /// Rounds the current `Time` according to provided options. + pub fn round(&self, options: RoundingOptions) -> TemporalResult { + let resolved = ResolvedRoundingOptions::from_time_options(options)?; + let (_, result) = self.iso.round(resolved)?; + + Ok(Self::new_unchecked(result)) + } + + pub fn to_ixdtf_string(&self, options: ToStringRoundingOptions) -> TemporalResult { + self.to_ixdtf_writeable(options) + .map(|x| x.write_to_string().into()) + } + + #[inline] + pub fn to_ixdtf_writeable( + &self, + options: ToStringRoundingOptions, + ) -> TemporalResult { + let resolved = options.resolve()?; + let (_, result) = self + .iso + .round(ResolvedRoundingOptions::from_to_string_options(&resolved))?; + let builder = IxdtfStringBuilder::default().with_time(result, resolved.precision); + Ok(builder) + } +} + +impl From for PlainTime { + fn from(pdt: PlainDateTime) -> Self { + pdt.to_plain_time() + } +} + +impl FromStr for PlainTime { + type Err = TemporalError; + + fn from_str(s: &str) -> Result { + Self::from_utf8(s.as_bytes()) + } +} + +// ==== Test land ==== + +#[cfg(test)] +mod tests { + use core::str::FromStr; + + use crate::{ + builtins::core::Duration, + iso::IsoTime, + options::{DifferenceSettings, Overflow, RoundingIncrement, RoundingOptions, Unit}, + }; + use num_traits::FromPrimitive; + + use super::PlainTime; + + fn assert_time(result: PlainTime, values: (u8, u8, u8, u16, u16, u16)) { + assert_eq!( + result, + PlainTime { + iso: IsoTime { + hour: values.0, + minute: values.1, + second: values.2, + millisecond: values.3, + microsecond: values.4, + nanosecond: values.5, + } + } + ); + } + + fn assert_duration( + result: Duration, + values: (i64, i64, i64, i64, i64, i64, i64, i64, i128, i128), + ) { + assert_eq!( + ( + result.years(), + result.months(), + result.weeks(), + result.days(), + result.hours(), + result.minutes(), + result.seconds(), + result.milliseconds(), + result.microseconds(), + result.nanoseconds() + ), + values + ) + } + + fn options(unit: Unit, increment: f64) -> RoundingOptions { + RoundingOptions { + smallest_unit: Some(unit), + increment: RoundingIncrement::try_from(increment).ok(), + ..Default::default() + } + } + + #[test] + fn from_str_cast_sanity_test() { + let max = u32::MAX; + let (millisecond, rem) = (max / 1_000_000, max % 1_000_000); + let (microsecond, nanosecond) = (rem / 1_000, rem % 1_000); + + assert!(i32::from_u32(millisecond).is_some()); + assert!(i32::from_u32(microsecond).is_some()); + assert!(i32::from_u32(nanosecond).is_some()); + } + + #[test] + fn basic_parse_time() { + let result = "T12:05:24-05:00[u-ca=iso8601]".parse::(); + assert_time(result.unwrap(), (12, 5, 24, 0, 0, 0)); + + let result = "T12:05:24.123456789-05:00[u-ca=iso8601]".parse::(); + assert_time(result.unwrap(), (12, 5, 24, 123, 456, 789)); + + let result = "2024-05-04 12:05:24.123456789-05:00[u-ca=iso8601]".parse::(); + assert_time(result.unwrap(), (12, 5, 24, 123, 456, 789)); + + let result = "2024-05-04 12:05:24.123456789-05:00[u-ca=iso8601]".parse::(); + assert_time(result.unwrap(), (12, 5, 24, 123, 456, 789)); + } + + #[test] + fn time_round_millisecond() { + let base = PlainTime::new_unchecked(IsoTime::new_unchecked(3, 34, 56, 987, 654, 321)); + + let result_1 = base.round(options(Unit::Millisecond, 1.0)).unwrap(); + assert_time(result_1, (3, 34, 56, 988, 0, 0)); + + let result_2 = base.round(options(Unit::Millisecond, 2.0)).unwrap(); + assert_time(result_2, (3, 34, 56, 988, 0, 0)); + + let result_3 = base.round(options(Unit::Millisecond, 4.0)).unwrap(); + assert_time(result_3, (3, 34, 56, 988, 0, 0)); + + let result_4 = base.round(options(Unit::Millisecond, 5.0)).unwrap(); + assert_time(result_4, (3, 34, 56, 990, 0, 0)); + } + + #[test] + fn time_round_microsecond() { + let base = PlainTime::new_unchecked(IsoTime::new_unchecked(3, 34, 56, 987, 654, 321)); + + let result_1 = base.round(options(Unit::Microsecond, 1.0)).unwrap(); + assert_time(result_1, (3, 34, 56, 987, 654, 0)); + + let result_2 = base.round(options(Unit::Microsecond, 2.0)).unwrap(); + assert_time(result_2, (3, 34, 56, 987, 654, 0)); + + let result_3 = base.round(options(Unit::Microsecond, 4.0)).unwrap(); + assert_time(result_3, (3, 34, 56, 987, 656, 0)); + + let result_4 = base.round(options(Unit::Microsecond, 5.0)).unwrap(); + assert_time(result_4, (3, 34, 56, 987, 655, 0)); + } + + #[test] + fn time_round_nanoseconds() { + let base = PlainTime::new_unchecked(IsoTime::new_unchecked(3, 34, 56, 987, 654, 321)); + + let result_1 = base.round(options(Unit::Nanosecond, 1.0)).unwrap(); + assert_time(result_1, (3, 34, 56, 987, 654, 321)); + + let result_2 = base.round(options(Unit::Nanosecond, 2.0)).unwrap(); + assert_time(result_2, (3, 34, 56, 987, 654, 322)); + + let result_3 = base.round(options(Unit::Nanosecond, 4.0)).unwrap(); + assert_time(result_3, (3, 34, 56, 987, 654, 320)); + + let result_4 = base.round(options(Unit::Nanosecond, 5.0)).unwrap(); + assert_time(result_4, (3, 34, 56, 987, 654, 320)); + } + + #[test] + fn add_duration_basic() { + let base = PlainTime::new_unchecked(IsoTime::new_unchecked(15, 23, 30, 123, 456, 789)); + let result = base.add(&"PT16H".parse::().unwrap()).unwrap(); + + assert_time(result, (7, 23, 30, 123, 456, 789)); + } + + #[test] + fn since_basic() { + let one = + PlainTime::new_with_overflow(15, 23, 30, 123, 456, 789, Overflow::Constrain).unwrap(); + let two = + PlainTime::new_with_overflow(14, 23, 30, 123, 456, 789, Overflow::Constrain).unwrap(); + let three = + PlainTime::new_with_overflow(13, 30, 30, 123, 456, 789, Overflow::Constrain).unwrap(); + + let result = one.since(&two, DifferenceSettings::default()).unwrap(); + assert_eq!(result.hours(), 1); + + let result = two.since(&one, DifferenceSettings::default()).unwrap(); + assert_eq!(result.hours(), -1); + + let result = one.since(&three, DifferenceSettings::default()).unwrap(); + assert_eq!(result.hours(), 1); + assert_eq!(result.minutes(), 53); + + let result = three.since(&one, DifferenceSettings::default()).unwrap(); + assert_eq!(result.hours(), -1); + assert_eq!(result.minutes(), -53); + } + + #[test] + fn until_basic() { + let one = + PlainTime::new_with_overflow(15, 23, 30, 123, 456, 789, Overflow::Constrain).unwrap(); + let two = + PlainTime::new_with_overflow(16, 23, 30, 123, 456, 789, Overflow::Constrain).unwrap(); + let three = + PlainTime::new_with_overflow(17, 0, 30, 123, 456, 789, Overflow::Constrain).unwrap(); + + let result = one.until(&two, DifferenceSettings::default()).unwrap(); + assert_eq!(result.hours(), 1); + + let result = two.until(&one, DifferenceSettings::default()).unwrap(); + assert_eq!(result.hours(), -1); + + let result = one.until(&three, DifferenceSettings::default()).unwrap(); + assert_eq!(result.hours(), 1); + assert_eq!(result.minutes(), 37); + + let result = three.until(&one, DifferenceSettings::default()).unwrap(); + assert_eq!(result.hours(), -1); + assert_eq!(result.minutes(), -37); + } + + #[test] + fn since_rounding() { + let earlier = PlainTime::new(3, 12, 34, 123, 456, 789).unwrap(); + let later = PlainTime::new(13, 47, 57, 988, 655, 322).unwrap(); + + let settings = DifferenceSettings { + smallest_unit: Some(Unit::Second), + increment: Some(RoundingIncrement::try_new(1).unwrap()), + ..Default::default() + }; + assert_duration( + later.since(&earlier, settings).unwrap(), + (0, 0, 0, 0, 10, 35, 23, 0, 0, 0), + ); + + let settings = DifferenceSettings { + smallest_unit: Some(Unit::Second), + increment: Some(RoundingIncrement::try_new(4).unwrap()), + ..Default::default() + }; + assert_duration( + later.since(&earlier, settings).unwrap(), + (0, 0, 0, 0, 10, 35, 20, 0, 0, 0), + ); + } + + #[test] + // test262/test/built-ins/Temporal/PlainTime/prototype/round/roundingincrement-nanoseconds.js + fn rounding_increment_nanos() { + let time = + PlainTime::new_with_overflow(3, 34, 56, 987, 654, 321, Overflow::Constrain).unwrap(); + + assert_eq!( + time.round(options(Unit::Nanosecond, 1.0)).unwrap(), + PlainTime::new_with_overflow(3, 34, 56, 987, 654, 321, Overflow::Constrain).unwrap() + ); + assert_eq!( + time.round(options(Unit::Nanosecond, 2.0)).unwrap(), + PlainTime::new_with_overflow(3, 34, 56, 987, 654, 322, Overflow::Constrain).unwrap() + ); + assert_eq!( + time.round(options(Unit::Nanosecond, 4.0)).unwrap(), + PlainTime::new_with_overflow(3, 34, 56, 987, 654, 320, Overflow::Constrain).unwrap() + ); + assert_eq!( + time.round(options(Unit::Nanosecond, 5.0)).unwrap(), + PlainTime::new_with_overflow(3, 34, 56, 987, 654, 320, Overflow::Constrain).unwrap() + ); + assert_eq!( + time.round(options(Unit::Nanosecond, 8.0)).unwrap(), + PlainTime::new_with_overflow(3, 34, 56, 987, 654, 320, Overflow::Constrain).unwrap() + ); + assert_eq!( + time.round(options(Unit::Nanosecond, 10.0)).unwrap(), + PlainTime::new_with_overflow(3, 34, 56, 987, 654, 320, Overflow::Constrain).unwrap() + ); + assert_eq!( + time.round(options(Unit::Nanosecond, 20.0)).unwrap(), + PlainTime::new_with_overflow(3, 34, 56, 987, 654, 320, Overflow::Constrain).unwrap() + ); + assert_eq!( + time.round(options(Unit::Nanosecond, 25.0)).unwrap(), + PlainTime::new_with_overflow(3, 34, 56, 987, 654, 325, Overflow::Constrain).unwrap() + ); + assert_eq!( + time.round(options(Unit::Nanosecond, 40.0)).unwrap(), + PlainTime::new_with_overflow(3, 34, 56, 987, 654, 320, Overflow::Constrain).unwrap() + ); + assert_eq!( + time.round(options(Unit::Nanosecond, 50.0)).unwrap(), + PlainTime::new_with_overflow(3, 34, 56, 987, 654, 300, Overflow::Constrain).unwrap() + ); + assert_eq!( + time.round(options(Unit::Nanosecond, 100.0)).unwrap(), + PlainTime::new_with_overflow(3, 34, 56, 987, 654, 300, Overflow::Constrain).unwrap() + ); + assert_eq!( + time.round(options(Unit::Nanosecond, 125.0)).unwrap(), + PlainTime::new_with_overflow(3, 34, 56, 987, 654, 375, Overflow::Constrain).unwrap() + ); + assert_eq!( + time.round(options(Unit::Nanosecond, 200.0)).unwrap(), + PlainTime::new_with_overflow(3, 34, 56, 987, 654, 400, Overflow::Constrain).unwrap() + ); + assert_eq!( + time.round(options(Unit::Nanosecond, 250.0)).unwrap(), + PlainTime::new_with_overflow(3, 34, 56, 987, 654, 250, Overflow::Constrain).unwrap() + ); + assert_eq!( + time.round(options(Unit::Nanosecond, 500.0)).unwrap(), + PlainTime::new_with_overflow(3, 34, 56, 987, 654, 500, Overflow::Constrain).unwrap() + ); + } + + #[test] + fn invalid_time_from_strs() { + // UTC designator case + let invalid_cases = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", + "09:00:00Z[UTC]", + "09:00:00Z", + ]; + for invalid_str in invalid_cases { + let err = PlainTime::from_str(invalid_str); + assert!(err.is_err()); + } + } +} diff --git a/deps/temporal/src/builtins/core/plain_year_month.rs b/deps/temporal/src/builtins/core/plain_year_month.rs new file mode 100644 index 00000000000000..5a9047f82d6876 --- /dev/null +++ b/deps/temporal/src/builtins/core/plain_year_month.rs @@ -0,0 +1,1132 @@ +//! This module implements `YearMonth` and any directly related algorithms. + +use alloc::string::String; +use core::{cmp::Ordering, str::FromStr}; + +use tinystr::TinyAsciiStr; + +use crate::{ + builtins::calendar::{CalendarFields, YearMonthCalendarFields}, + iso::{year_month_within_limits, IsoDate, IsoDateTime, IsoTime}, + options::{ + DifferenceOperation, DifferenceSettings, Disambiguation, DisplayCalendar, Overflow, + ResolvedRoundingOptions, RoundingIncrement, Unit, UnitGroup, + }, + parsed_intermediates::ParsedDate, + parsers::{FormattableCalendar, FormattableDate, FormattableYearMonth}, + provider::{NeverProvider, TimeZoneProvider}, + temporal_assert, + unix_time::EpochNanoseconds, + Calendar, MonthCode, TemporalError, TemporalResult, TemporalUnwrap, TimeZone, +}; + +use super::{ + duration::normalized::InternalDurationRecord, DateDuration, Duration, PlainDate, PlainDateTime, +}; +use writeable::Writeable; + +/// A partial PlainYearMonth record +#[derive(Debug, Default, Clone, PartialEq)] +pub struct PartialYearMonth { + pub calendar_fields: YearMonthCalendarFields, + /// The calendar field + pub calendar: Calendar, +} + +/// The native Rust implementation of `Temporal.PlainYearMonth`. +/// +/// Represents a specific month within a specific year, such as "January 2024" +/// or "December 2023", without a specific day component. +/// +/// Useful for representing time periods at month granularity, such as billing +/// periods, reporting intervals, or any scenario where you need to work with +/// entire months rather than specific dates. +/// +/// ## Examples +/// +/// ### Creating a PlainYearMonth +/// +/// ```rust +/// use temporal_rs::{PlainYearMonth, Calendar}; +/// +/// // Create with ISO 8601 calendar +/// let ym = PlainYearMonth::try_new_iso(2024, 3, None).unwrap(); +/// assert_eq!(ym.year(), 2024); +/// assert_eq!(ym.month(), 3); +/// assert_eq!(ym.calendar().identifier(), "iso8601"); +/// +/// // Create with explicit calendar and reference day +/// let ym = PlainYearMonth::try_new(2024, 3, Some(15), Calendar::default()).unwrap(); +/// assert_eq!(ym.year(), 2024); +/// assert_eq!(ym.month(), 3); +/// // Reference day helps with calendar calculations but doesn't affect the YearMonth itself +/// ``` +/// +/// ### Parsing ISO 8601 year-month strings +/// +/// ```rust +/// use temporal_rs::PlainYearMonth; +/// use core::str::FromStr; +/// +/// // Parse year-month strings +/// let ym = PlainYearMonth::from_str("2024-03").unwrap(); +/// assert_eq!(ym.year(), 2024); +/// assert_eq!(ym.month(), 3); +/// +/// // Also accepts full date strings (day is ignored for YearMonth semantics) +/// let ym2 = PlainYearMonth::from_str("2024-03-15").unwrap(); +/// assert_eq!(ym2.year(), 2024); +/// assert_eq!(ym2.month(), 3); +/// assert_eq!(ym, ym2); // equivalent +/// ``` +/// +/// ### YearMonth arithmetic +/// +/// ```rust +/// use temporal_rs::{PlainYearMonth, options::DifferenceSettings}; +/// use core::str::FromStr; +/// +/// let ym1 = PlainYearMonth::from_str("2024-01").unwrap(); +/// let ym2 = PlainYearMonth::from_str("2024-04").unwrap(); +/// +/// // Calculate difference between year-months +/// let duration = ym1.until(&ym2, DifferenceSettings::default()).unwrap(); +/// assert_eq!(duration.months(), 3); // January to April = 3 months +/// ``` +/// +/// ### Working with partial fields +/// +/// ```rust +/// use temporal_rs::{PlainYearMonth, fields::YearMonthCalendarFields}; +/// use core::str::FromStr; +/// +/// let ym = PlainYearMonth::from_str("2024-01").unwrap(); +/// +/// // Change only the year +/// let fields = YearMonthCalendarFields::new().with_year(2025); +/// let modified = ym.with(fields, None).unwrap(); +/// assert_eq!(modified.year(), 2025); +/// assert_eq!(modified.month(), 1); // unchanged +/// +/// // Change only the month +/// let fields = YearMonthCalendarFields::new().with_month(6); +/// let modified = ym.with(fields, None).unwrap(); +/// assert_eq!(modified.year(), 2024); // unchanged +/// assert_eq!(modified.month(), 6); +/// ``` +/// +/// ### Converting to PlainDate +/// +/// ```rust +/// use temporal_rs::{PlainYearMonth, fields::CalendarFields}; +/// use core::str::FromStr; +/// +/// let ym = PlainYearMonth::from_str("2024-03").unwrap(); +/// +/// // Convert to a specific date by providing a day +/// let day_fields = CalendarFields::new().with_day(15); +/// let date = ym.to_plain_date(Some(day_fields)).unwrap(); +/// assert_eq!(date.year(), 2024); +/// assert_eq!(date.month(), 3); +/// assert_eq!(date.day(), 15); +/// ``` +/// +/// ### Calendar properties +/// +/// ```rust +/// use temporal_rs::PlainYearMonth; +/// use core::str::FromStr; +/// +/// let ym = PlainYearMonth::from_str("2024-02").unwrap(); // February 2024 +/// +/// // Get calendar-specific properties +/// assert_eq!(ym.days_in_month(), 29); // 2024 is a leap year +/// assert_eq!(ym.days_in_year(), 366); // leap year has 366 days +/// assert_eq!(ym.months_in_year(), 12); // ISO calendar has 12 months +/// assert!(ym.in_leap_year()); // 2024 is indeed a leap year +/// ``` +/// +/// ## Reference +/// +/// For more information, see the [MDN documentation][mdn-plainyearmonth]. +/// +/// [mdn-plainyearmonth]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth +#[non_exhaustive] +#[derive(Debug, Default, Clone, PartialEq, Eq)] +pub struct PlainYearMonth { + pub(crate) iso: IsoDate, + calendar: Calendar, +} + +impl core::fmt::Display for PlainYearMonth { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(&self.to_ixdtf_string(DisplayCalendar::Auto)) + } +} + +impl PlainYearMonth { + /// Creates an unvalidated `YearMonth`. + #[inline] + #[must_use] + pub(crate) fn new_unchecked(iso: IsoDate, calendar: Calendar) -> Self { + Self { iso, calendar } + } + + /// [`9.5.8 AddDurationToYearMonth(operation, yearMonth, temporalDurationLike, options)`][spec] + /// + /// Internal addition method for adding `Duration` to a `PlainYearMonth` + /// + /// [spec]: + /// + // spec(2025-06-23): https://github.com/tc39/proposal-temporal/tree/ed49b0b482981119c9b5e28b0686d877d4a9bae0 + pub(crate) fn add_duration( + &self, + duration: &Duration, + overflow: Overflow, + ) -> TemporalResult { + // NOTE: The following are engine specific: + // SKIP: 1. Let duration be ? ToTemporalDuration(temporalDurationLike). + + // NOTE: The following operation has been moved to the caller. + // MOVE: 2. If operation is subtract, set duration to CreateNegatedTemporalDuration(duration). + + // NOTE: The following are engine specific: + // SKIP: 3. Let resolvedOptions be ? GetOptionsObject(options). + // SKIP: 4. Let overflow be ? GetTemporalOverflowOption(resolvedOptions). + + // 5. Let sign be DurationSign(duration). + let sign = duration.sign(); + + // 6. Let calendar be yearMonth.[[Calendar]]. + let calendar = self.calendar(); + + // 7. Let fields be ISODateToFields(calendar, yearMonth.[[ISODate]], year-month). + let fields = CalendarFields::from(YearMonthCalendarFields::try_from_year_month(self)?); + + // 8. Set fields.[[Day]] to 1. + let fields = fields.with_day(1); + + // 9. Let intermediateDate be ? CalendarDateFromFields(calendar, fields, constrain). + let intermediate_date = calendar.date_from_fields(fields, overflow)?; + + // 10. If sign < 0, then + let date = if sign.as_sign_multiplier() < 0 { + // a. Let oneMonthDuration be ! CreateDateDurationRecord(0, 1, 0, 0). + let one_month_duration = DateDuration::new_unchecked(0, 1, 0, 0); + + // b. Let nextMonth be ? CalendarDateAdd(calendar, intermediateDate, oneMonthDuration, constrain). + let next_month = calendar.date_add( + &intermediate_date.iso, + &one_month_duration, + Overflow::Constrain, + )?; + + // c. Let date be BalanceISODate(nextMonth.[[Year]], nextMonth.[[Month]], nextMonth.[[Day]] - 1). + let date = IsoDate::balance( + next_month.year(), + i32::from(next_month.month()), + i32::from(next_month.day()) + .checked_sub(1) + .temporal_unwrap()?, + ); + + // d. Assert: ISODateWithinLimits(date) is true. + temporal_assert!(date.is_valid()); + + date + } else { + // 11. Else, + // a. Let date be intermediateDate. + intermediate_date.iso + }; + + // 12. Let durationToAdd be ToDateDurationRecordWithoutTime(duration). + let duration_to_add = duration.to_date_duration_record_without_time()?; + + // 13. Let addedDate be ? CalendarDateAdd(calendar, date, durationToAdd, overflow). + let added_date = calendar.date_add(&date, &duration_to_add, overflow)?; + + // 14. Let addedDateFields be ISODateToFields(calendar, addedDate, year-month). + let added_date_fields = YearMonthCalendarFields::new() + .with_month_code(added_date.month_code()) + .with_year(added_date.year()); + + // 15. Let isoDate be ? CalendarYearMonthFromFields(calendar, addedDateFields, overflow). + let iso_date = calendar.year_month_from_fields(added_date_fields, overflow)?; + + // 16. Return ! CreateTemporalYearMonth(isoDate, calendar). + Ok(iso_date) + } + + /// The internal difference operation of `PlainYearMonth`. + pub(crate) fn diff( + &self, + op: DifferenceOperation, + other: &Self, + settings: DifferenceSettings, + ) -> TemporalResult { + // 1. Set other to ? ToTemporalYearMonth(other). + // 2. Let calendar be yearMonth.[[Calendar]]. + // 3. If CalendarEquals(calendar, other.[[Calendar]]) is false, throw a RangeError exception. + if self.calendar().identifier() != other.calendar().identifier() { + return Err(TemporalError::range() + .with_message("Calendars for difference operation are not the same.")); + } + + // Check if weeks or days are disallowed in this operation + if matches!(settings.largest_unit, Some(Unit::Week) | Some(Unit::Day)) + || matches!(settings.smallest_unit, Some(Unit::Week) | Some(Unit::Day)) + { + return Err(TemporalError::range() + .with_message("Weeks and days are not allowed in this operation.")); + } + + // 4. Let resolvedOptions be ? GetOptionsObject(options). + // 5. Let settings be ? GetDifferenceSettings(operation, resolvedOptions, date, « week, day », month, year). + let resolved = ResolvedRoundingOptions::from_diff_settings( + settings, + op, + UnitGroup::Date, + Unit::Year, + Unit::Month, + )?; + + // 6. If CompareISODate(yearMonth.[[ISODate]], other.[[ISODate]]) = 0, then + if self.iso == other.iso { + // a. Return ! CreateTemporalDuration(0, 0, 0, 0, 0, 0, 0, 0, 0, 0). + return Ok(Duration::default()); + } + + // 7. Let thisFields be ISODateToFields(calendar, yearMonth.[[ISODate]], year-month). + // 8. Set thisFields.[[Day]] to 1. + // 9. Let thisDate be ? CalendarDateFromFields(calendar, thisFields, constrain). + let mut this_iso = self.iso; + this_iso.day = 1; + this_iso.check_within_limits()?; + // 10. Let otherFields be ISODateToFields(calendar, other.[[ISODate]], year-month). + // 11. Set otherFields.[[Day]] to 1. + // 12. Let otherDate be ? CalendarDateFromFields(calendar, otherFields, constrain). + let mut other_iso = other.iso; + other_iso.day = 1; + other_iso.check_within_limits()?; + // 13. Let dateDifference be CalendarDateUntil(calendar, thisDate, otherDate, settings.[[LargestUnit]]). + let result = self + .calendar() + .date_until(&this_iso, &other_iso, resolved.largest_unit)?; + // 14. Let yearsMonthsDifference be ! AdjustDateDurationRecord(dateDifference, 0, 0). + let result = result.date().adjust(0, Some(0), None)?; + + // 15. Let duration be CombineDateAndTimeDuration(yearsMonthsDifference, 0). + let mut duration = InternalDurationRecord::from_date_duration(result)?; + + // 16. If settings.[[SmallestUnit]] is not month or settings.[[RoundingIncrement]] ≠ 1, then + if resolved.smallest_unit != Unit::Month || resolved.increment != RoundingIncrement::ONE { + // a. Let isoDateTime be CombineISODateAndTimeRecord(thisDate, MidnightTimeRecord()). + let iso_date_time = IsoDateTime::new_unchecked(this_iso, IsoTime::default()); + // b. Let isoDateTimeOther be CombineISODateAndTimeRecord(otherDate, MidnightTimeRecord()). + let target_iso_date_time = IsoDateTime::new_unchecked(other_iso, IsoTime::default()); + // c. Let destEpochNs be GetUTCEpochNanoseconds(isoDateTimeOther). + let dest_epoch_ns = target_iso_date_time.as_nanoseconds(); + // d. Set duration to ? RoundRelativeDuration(duration, destEpochNs, isoDateTime, unset, calendar, resolved.[[LargestUnit]], resolved.[[RoundingIncrement]], resolved.[[SmallestUnit]], resolved.[[RoundingMode]]). + duration = duration.round_relative_duration( + dest_epoch_ns.as_i128(), + &PlainDateTime::new_unchecked(iso_date_time, self.calendar.clone()), + Option::<(&TimeZone, &NeverProvider)>::None, + resolved, + )?; + } + + // 17. Let result be ! TemporalDurationFromInternal(duration, day). + let result = Duration::from_internal(duration, Unit::Day)?; + + // 18. If operation is since, set result to CreateNegatedTemporalDuration(result). + // 19. Return result. + match op { + DifferenceOperation::Since => Ok(result.negated()), + DifferenceOperation::Until => Ok(result), + } + } + + /// Returns the iso month value for this `YearMonth`. + #[inline] + #[must_use] + pub(crate) fn iso_month(&self) -> u8 { + self.iso.month + } + + /// Returns the iso year value for this `YearMonth`. + #[inline] + #[must_use] + pub(crate) fn iso_year(&self) -> i32 { + self.iso.year + } +} + +// ==== Public method implementations ==== + +impl PlainYearMonth { + /// Creates a new `PlainYearMonth`, constraining any arguments that are invalid into a valid range. + #[inline] + pub fn new( + year: i32, + month: u8, + reference_day: Option, + calendar: Calendar, + ) -> TemporalResult { + Self::new_with_overflow(year, month, reference_day, calendar, Overflow::Constrain) + } + + /// Creates a new `PlainYearMonth`, rejecting any date that may be invalid. + #[inline] + pub fn try_new( + year: i32, + month: u8, + reference_day: Option, + calendar: Calendar, + ) -> TemporalResult { + Self::new_with_overflow(year, month, reference_day, calendar, Overflow::Reject) + } + + /// Creates a new `PlainYearMonth` with an ISO 8601 calendar, rejecting any date that may be invalid. + #[inline] + pub fn try_new_iso(year: i32, month: u8, reference_day: Option) -> TemporalResult { + Self::try_new(year, month, reference_day, Calendar::ISO) + } + + /// Creates a new `PlainYearMonth` with an ISO 8601 calendar, constraining any arguments + /// that are invalid into a valid range. + #[inline] + pub fn new_iso(year: i32, month: u8, reference_day: Option) -> TemporalResult { + Self::new(year, month, reference_day, Calendar::ISO) + } + + /// Creates a new valid `YearMonth` with provided [`Overflow`] option. + #[inline] + pub fn new_with_overflow( + year: i32, + month: u8, + reference_day: Option, + calendar: Calendar, + overflow: Overflow, + ) -> TemporalResult { + let day = reference_day.unwrap_or(1); + let iso = IsoDate::regulate(year, month, day, overflow)?; + if !year_month_within_limits(iso.year, iso.month) { + return Err(TemporalError::range().with_message("Exceeded valid range.")); + } + Ok(Self::new_unchecked(iso, calendar)) + } + + /// Create a `PlainYearMonth` from a `PartialYearMonth` + pub fn from_partial( + partial: PartialYearMonth, + overflow: Option, + ) -> TemporalResult { + partial + .calendar + .year_month_from_fields(partial.calendar_fields, overflow.unwrap_or_default()) + } + + // Converts a UTF-8 encoded string into a `PlainYearMonth`. + pub fn from_utf8(s: &[u8]) -> TemporalResult { + let parsed = ParsedDate::year_month_from_utf8(s)?; + Self::from_parsed(parsed) + } + + /// Converts a ParsedDate into a `PlainYearMonth`. + /// + /// Be sure to parse this using [`ParsedDate::year_month_from_utf8()`]~ + pub fn from_parsed(parsed: ParsedDate) -> TemporalResult { + let date = parsed.record; + // The below steps are from `ToTemporalYearMonth` + // 10. Let isoDate be CreateISODateRecord(result.[[Year]], result.[[Month]], result.[[Day]]). + let iso = IsoDate::new_unchecked(date.year, date.month, date.day); + + // 11. If ISOYearMonthWithinLimits(isoDate) is false, throw a RangeError exception. + if !year_month_within_limits(iso.year, iso.month) { + return Err(TemporalError::range().with_message("Exceeded valid range.")); + } + debug_assert!(iso.check_validity().is_ok(), "Found invalid ParsedDate"); + + let intermediate = Self::new_unchecked(iso, Calendar::new(parsed.calendar)); + // 12. Set result to ISODateToFields(calendar, isoDate, year-month). + let fields = YearMonthCalendarFields::try_from_year_month(&intermediate)?; + // 13. NOTE: The following operation is called with constrain regardless of the + // value of overflow, in order for the calendar to store a canonical value in the + // [[Day]] field of the [[ISODate]] internal slot of the result. + // 14. Set isoDate to ? CalendarYearMonthFromFields(calendar, result, constrain). + // 15. Return ! CreateTemporalYearMonth(isoDate, calendar). + intermediate + .calendar() + .year_month_from_fields(fields, Overflow::Constrain) + } + + /// Returns the calendar era of the current `PlainYearMonth` + pub fn era(&self) -> Option> { + self.calendar().era(&self.iso) + } + + /// Returns the calendar era year of the current `PlainYearMonth` + pub fn era_year(&self) -> Option { + self.calendar().era_year(&self.iso) + } + + /// Returns the calendar year of the current `PlainYearMonth` + pub fn year(&self) -> i32 { + self.calendar().year(&self.iso) + } + + /// Returns the calendar month of the current `PlainYearMonth` + pub fn month(&self) -> u8 { + self.calendar().month(&self.iso) + } + + /// Returns the calendar reference day of the current `PlainYearMonth` + pub fn reference_day(&self) -> u8 { + self.calendar().day(&self.iso) + } + + /// Returns the calendar month code of the current `PlainYearMonth` + pub fn month_code(&self) -> MonthCode { + self.calendar().month_code(&self.iso) + } + + /// Returns the days in the calendar year of the current `PlainYearMonth`. + pub fn days_in_year(&self) -> u16 { + self.calendar().days_in_year(&self.iso) + } + + /// Returns the days in the calendar month of the current `PlainYearMonth`. + pub fn days_in_month(&self) -> u16 { + self.calendar().days_in_month(&self.iso) + } + + /// Returns the months in the calendar year of the current `PlainYearMonth`. + pub fn months_in_year(&self) -> u16 { + self.calendar().months_in_year(&self.iso) + } + + #[inline] + #[must_use] + /// Returns a boolean representing whether the current `PlainYearMonth` is in a leap year. + pub fn in_leap_year(&self) -> bool { + self.calendar().in_leap_year(&self.iso) + } +} + +impl PlainYearMonth { + /// Returns the Calendar value. + #[inline] + #[must_use] + pub fn calendar(&self) -> &Calendar { + &self.calendar + } + + /// Returns the string identifier for the current calendar used. + #[inline] + #[must_use] + pub fn calendar_id(&self) -> &'static str { + self.calendar.identifier() + } + + /// Creates a `PlainYearMonth` using the fields provided from a [`PartialYearMonth`] + pub fn with( + &self, + fields: YearMonthCalendarFields, + overflow: Option, + ) -> TemporalResult { + // 1. Let yearMonth be the this value. + // 2. Perform ? RequireInternalSlot(yearMonth, [[InitializedTemporalYearMonth]]). + // 3. If ? IsPartialTemporalObject(temporalYearMonthLike) is false, throw a TypeError exception. + // 4. Let calendar be yearMonth.[[Calendar]]. + // 5. Let fields be ISODateToFields(calendar, yearMonth.[[ISODate]], year-month). + // 6. Let partialYearMonth be ? PrepareCalendarFields(calendar, temporalYearMonthLike, « year, month, month-code », « », partial). + // 7. Set fields to CalendarMergeFields(calendar, fields, partialYearMonth). + // 8. Let resolvedOptions be ? GetOptionsObject(options). + // 9. Let overflow be ? GetTemporalOverflowOption(resolvedOptions). + // 10. Let isoDate be ? CalendarYearMonthFromFields(calendar, fields, overflow). + // 11. Return ! CreateTemporalYearMonth(isoDate, calendar). + let overflow = overflow.unwrap_or(Overflow::Constrain); + self.calendar.year_month_from_fields( + fields.with_fallback_year_month(self, self.calendar.kind(), overflow)?, + overflow, + ) + } + + /// Compares one `PlainYearMonth` to another `PlainYearMonth` using their + /// `IsoDate` representation. + /// + /// # Note on Ordering. + /// + /// `temporal_rs` does not implement `PartialOrd`/`Ord` as `PlainYearMonth` does + /// not fulfill all the conditions required to implement the traits. However, + /// it is possible to compare `PlainDate`'s as their `IsoDate` representation. + #[inline] + #[must_use] + pub fn compare_iso(&self, other: &Self) -> Ordering { + self.iso.cmp(&other.iso) + } + + /// Adds a [`Duration`] from the current `PlainYearMonth`. + #[inline] + pub fn add(&self, duration: &Duration, overflow: Overflow) -> TemporalResult { + self.add_duration(duration, overflow) + } + + /// Subtracts a [`Duration`] from the current `PlainYearMonth`. + #[inline] + pub fn subtract(&self, duration: &Duration, overflow: Overflow) -> TemporalResult { + self.add_duration(&duration.negated(), overflow) + } + + /// Returns a `Duration` representing the period of time from this `PlainYearMonth` until the other `PlainYearMonth`. + #[inline] + pub fn until(&self, other: &Self, settings: DifferenceSettings) -> TemporalResult { + self.diff(DifferenceOperation::Until, other, settings) + } + + /// Returns a `Duration` representing the period of time from this `PlainYearMonth` since the other `PlainYearMonth`. + #[inline] + pub fn since(&self, other: &Self, settings: DifferenceSettings) -> TemporalResult { + self.diff(DifferenceOperation::Since, other, settings) + } + + pub fn to_plain_date(&self, day: Option) -> TemporalResult { + let day_value = match &day { + Some(fields) => fields.day.ok_or_else(|| { + TemporalError::r#type().with_message("CalendarFields must contain a day field") + })?, + None => return Err(TemporalError::r#type().with_message("Day must be provided")), + }; + + let fields = CalendarFields::new() + .with_year(self.year()) + .with_month_code(self.month_code()) + .with_day(day_value); + + // 8. Let isoDate be ? CalendarDateFromFields(calendar, mergedFields, constrain). + self.calendar.date_from_fields(fields, Overflow::Constrain) + } + + /// Gets the epochMilliseconds represented by this YearMonth in the given timezone + /// (using the reference year, and noon time) + /// + // Useful for implementing HandleDateTimeTemporalYearMonth + pub fn epoch_ns_for_with_provider( + &self, + time_zone: TimeZone, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // 2. Let isoDateTime be CombineISODateAndTimeRecord(temporalYearMonth.[[ISODate]], NoonTimeRecord()). + let iso = IsoDateTime::new(self.iso, IsoTime::noon())?; + // 3. Let epochNs be ? GetEpochNanosecondsFor(dateTimeFormat.[[TimeZone]], isoDateTime, compatible). + Ok(time_zone + .get_epoch_nanoseconds_for(iso, Disambiguation::Compatible, provider)? + .ns) + } + + /// Returns a RFC9557 IXDTF string for the current `PlainYearMonth` + #[inline] + pub fn to_ixdtf_string(&self, display_calendar: DisplayCalendar) -> String { + self.to_ixdtf_writeable(display_calendar) + .write_to_string() + .into() + } + + /// Returns a RFC9557 IXDTF string for the current `PlainYearMonth` as a Writeable + #[inline] + pub fn to_ixdtf_writeable(&self, display_calendar: DisplayCalendar) -> impl Writeable + '_ { + let ixdtf = FormattableYearMonth { + date: FormattableDate(self.iso_year(), self.iso_month(), self.iso.day), + calendar: FormattableCalendar { + show: display_calendar, + calendar: self.calendar().identifier(), + }, + }; + ixdtf + } +} + +impl FromStr for PlainYearMonth { + type Err = TemporalError; + + fn from_str(s: &str) -> Result { + Self::from_utf8(s.as_bytes()) + } +} + +#[cfg(test)] +mod tests { + use core::str::FromStr; + + use super::PlainYearMonth; + + use tinystr::tinystr; + + use super::*; + + #[test] + fn plain_year_month_since_until_diff_tests() { + // Equal year-months + { + let earlier = PlainYearMonth::from_str("2024-03").unwrap(); + let later = PlainYearMonth::from_str("2024-03").unwrap(); + let settings = DifferenceSettings { + smallest_unit: Some(Unit::Month), + ..Default::default() + }; + + let until = earlier.until(&later, settings).unwrap(); + let since = earlier.since(&later, settings).unwrap(); + + assert_eq!(until.days(), 0); + assert_eq!(until.months(), 0); + assert_eq!(until.years(), 0); + + assert_eq!(since.days(), 0); + assert_eq!(since.months(), 0); + assert_eq!(since.years(), 0); + } + + // One month apart + { + let earlier = PlainYearMonth::from_str("2023-01").unwrap(); + let later = PlainYearMonth::from_str("2023-02").unwrap(); + let settings = DifferenceSettings { + smallest_unit: Some(Unit::Month), + ..Default::default() + }; + + let until = earlier.until(&later, settings).unwrap(); + let since = earlier.since(&later, settings).unwrap(); + + assert_eq!(until.months(), 1); + assert_eq!(until.years(), 0); + + assert_eq!(since.months(), -1); + assert_eq!(since.years(), 0); + } + + // Crossing year boundary + { + let earlier = PlainYearMonth::from_str("2022-11").unwrap(); + let later = PlainYearMonth::from_str("2023-02").unwrap(); + let settings = DifferenceSettings { + smallest_unit: Some(Unit::Month), + ..Default::default() + }; + + let until = earlier.until(&later, settings).unwrap(); + let since = earlier.since(&later, settings).unwrap(); + + assert_eq!(until.months(), 3); + assert_eq!(until.years(), 0); + + assert_eq!(since.months(), -3); + assert_eq!(since.years(), 0); + } + + // One year and one month + { + let earlier = PlainYearMonth::from_str("2002-05").unwrap(); + let later = PlainYearMonth::from_str("2003-06").unwrap(); + let settings = DifferenceSettings { + smallest_unit: Some(Unit::Month), + ..Default::default() + }; + + let until = earlier.until(&later, settings).unwrap(); + let since = earlier.since(&later, settings).unwrap(); + + assert_eq!(until.years(), 1); + assert_eq!(until.months(), 1); + assert_eq!(until.days(), 0); + + assert_eq!(since.years(), -1); + assert_eq!(since.months(), -1); + assert_eq!(since.days(), 0); + } + + // One year apart with unit = Year + { + let earlier = PlainYearMonth::from_str("2022-06").unwrap(); + let later = PlainYearMonth::from_str("2023-06").unwrap(); + let settings = DifferenceSettings { + smallest_unit: Some(Unit::Year), + ..Default::default() + }; + + let until = earlier.until(&later, settings).unwrap(); + let since = earlier.since(&later, settings).unwrap(); + + assert_eq!(until.years(), 1); + assert_eq!(until.months(), 0); + + assert_eq!(since.years(), -1); + assert_eq!(since.months(), 0); + } + + // Large year gap + { + let earlier = PlainYearMonth::from_str("1000-01").unwrap(); + let later = PlainYearMonth::from_str("2000-01").unwrap(); + let settings = DifferenceSettings { + smallest_unit: Some(Unit::Year), + ..Default::default() + }; + + let until = earlier.until(&later, settings).unwrap(); + let since = earlier.since(&later, settings).unwrap(); + + assert_eq!(until.years(), 1000); + assert_eq!(since.years(), -1000); + } + + // Lower ISO limit plus one month + // (The lower iso limit iteslf does not work since the day is set to 1) + { + let earlier = PlainYearMonth::from_str("-271821-05").unwrap(); + let later = PlainYearMonth::from_str("-271820-05").unwrap(); + let settings = DifferenceSettings { + smallest_unit: Some(Unit::Year), + ..Default::default() + }; + + let until = earlier.until(&later, settings).unwrap(); + let since = earlier.since(&later, settings).unwrap(); + + assert_eq!(until.years(), 1); + assert_eq!(since.years(), -1); + } + } + #[test] + fn test_diff_with_different_calendars() { + let ym1 = PlainYearMonth::new_with_overflow( + 2021, + 1, + None, + Calendar::from_str("islamic").unwrap(), + Overflow::Reject, + ) + .unwrap(); + + let ym2 = PlainYearMonth::new_with_overflow( + 2021, + 1, + None, + Calendar::from_str("hebrew").unwrap(), + Overflow::Reject, + ) + .unwrap(); + + let settings = DifferenceSettings { + smallest_unit: Some(Unit::Month), + ..Default::default() + }; + + let diff = ym1.until(&ym2, settings); + assert!( + diff.is_err(), + "Expected an error when comparing dates from different calendars" + ); + } + #[test] + fn test_diff_setting() { + let ym1 = PlainYearMonth::from_str("2021-01").unwrap(); + let ym2 = PlainYearMonth::from_str("2023-02").unwrap(); + + let settings = DifferenceSettings { + smallest_unit: Some(Unit::Month), + increment: Some(RoundingIncrement::ONE), + ..Default::default() + }; + + let diff = ym1.until(&ym2, settings).unwrap(); + assert_eq!(diff.months(), 1); + assert_eq!(diff.years(), 2); + } + #[test] + fn test_diff_with_smallest_unit_year() { + let ym1 = PlainYearMonth::from_str("2021-01").unwrap(); + let ym2 = PlainYearMonth::from_str("2023-02").unwrap(); + + let settings = DifferenceSettings { + smallest_unit: Some(Unit::Year), + ..Default::default() + }; + + let diff = ym1.until(&ym2, settings).unwrap(); + assert_eq!(diff.years(), 2); // Rounded to the nearest year + assert_eq!(diff.months(), 0); // Months are ignored + } + + #[test] + fn test_diff_with_smallest_unit_day() { + let ym1 = PlainYearMonth::from_str("2021-01").unwrap(); + let ym2 = PlainYearMonth::from_str("2023-02").unwrap(); + + let settings = DifferenceSettings { + smallest_unit: Some(Unit::Day), + ..Default::default() + }; + + let diff = ym1.until(&ym2, settings); + assert!( + diff.is_err(), + "Expected an error when smallest_unit is set to Day" + ); + } + + #[test] + fn test_diff_with_smallest_unit_week() { + let ym1 = PlainYearMonth::from_str("2021-01").unwrap(); + let ym2 = PlainYearMonth::from_str("2023-02").unwrap(); + + let settings = DifferenceSettings { + smallest_unit: Some(Unit::Week), + ..Default::default() + }; + + let diff = ym1.until(&ym2, settings); + assert!( + diff.is_err(), + "Expected an error when smallest_unit is set to Week" + ); + } + + #[test] + fn test_diff_with_no_rounding_increment() { + let ym1 = PlainYearMonth::from_str("2021-01").unwrap(); + let ym2 = PlainYearMonth::from_str("2023-02").unwrap(); + + let settings = DifferenceSettings { + smallest_unit: Some(Unit::Month), + increment: None, // No rounding increment + ..Default::default() + }; + + let diff = ym1.until(&ym2, settings).unwrap(); + assert_eq!(diff.months(), 1); // Exact difference in months + assert_eq!(diff.years(), 2); // Exact difference in years + } + + #[test] + fn test_plain_year_month_with() { + let base = + PlainYearMonth::new_with_overflow(2025, 3, None, Calendar::default(), Overflow::Reject) + .unwrap(); + + // Year + let fields = YearMonthCalendarFields::new().with_year(2001); + + let with_year = base.with(fields, None).unwrap(); + assert_eq!(with_year.iso_year(), 2001); // year is changed + assert_eq!(with_year.iso_month(), 3); // month is not changed + assert_eq!(with_year.month_code(), MonthCode::from_str("M03").unwrap()); // assert month code has been initialized correctly + + // Month + let fields = YearMonthCalendarFields::new().with_month(2); + let with_month = base.with(fields, None).unwrap(); + assert_eq!(with_month.iso_year(), 2025); // year is not changed + assert_eq!(with_month.iso_month(), 2); // month is changed + assert_eq!(with_month.month_code(), MonthCode::from_str("M02").unwrap()); // assert month code has changed as well as month + + // Month Code + let fields = YearMonthCalendarFields::new().with_month_code(MonthCode(tinystr!(4, "M05"))); // change month to May (5) + let with_month_code = base.with(fields, None).unwrap(); + assert_eq!(with_month_code.iso_year(), 2025); // year is not changed + assert_eq!( + with_month_code.month_code(), + MonthCode::from_str("M05").unwrap() + ); // assert month code has changed + assert_eq!(with_month_code.iso_month(), 5); // month is changed as well + + // Day + let fields = YearMonthCalendarFields::new(); + let with_day = base.with(fields, None).unwrap(); + assert_eq!(with_day.iso_year(), 2025); // year is not changed + assert_eq!(with_day.iso_month(), 3); // month is not changed + assert_eq!(with_day.iso.day, 1); // day is ignored + + // All + let fields = YearMonthCalendarFields::new().with_year(2001).with_month(2); + let with_all = base.with(fields, None).unwrap(); + assert_eq!(with_all.iso_year(), 2001); // year is changed + assert_eq!(with_all.iso_month(), 2); // month is changed + assert_eq!(with_all.iso.day, 1); // day is ignored + } + + #[test] + fn basic_from_str() { + let valid_strings = [ + "-271821-04", + "-271821-04-01", + "-271821-04-01T00:00", + "+275760-09", + "+275760-09-30", + "+275760-09-30T23:59:59.999999999", + ]; + + for valid_case in valid_strings { + let ym = PlainYearMonth::from_str(valid_case); + assert!(ym.is_ok()); + } + } + + #[test] + fn invalid_from_str() { + let invalid_strings = [ + "-271821-03-31", + "-271821-03-31T23:59:59.999999999", + "+275760-10", + "+275760-10-01", + "+275760-10-01T00:00", + "1976-11[u-ca=hebrew]", + ]; + + for invalid_case in invalid_strings { + let err = PlainYearMonth::from_str(invalid_case); + assert!(err.is_err()); + } + + let invalid_strings = ["2019-10-01T09:00:00Z", "2019-10-01T09:00:00Z[UTC]"]; + + for invalid_case in invalid_strings { + let err = PlainYearMonth::from_str(invalid_case); + assert!(err.is_err()); + } + } + + #[test] + fn test_to_plain_date() { + let year_month = PlainYearMonth::new_with_overflow( + 2023, // year + 5, // month + None, // reference_day + Calendar::default(), + Overflow::Reject, + ) + .unwrap(); + + let fields = CalendarFields::new().with_day(3); + let plain_date = year_month.to_plain_date(Some(fields)).unwrap(); + assert_eq!(plain_date.iso_year(), 2023); + assert_eq!(plain_date.iso_month(), 5); + assert_eq!(plain_date.iso_day(), 3); + } + + #[test] + fn test_partial_year_month_try_from_plain() { + let ym = PlainYearMonth::from_str("2024-05").unwrap(); + let partial = YearMonthCalendarFields::try_from_year_month(&ym).unwrap(); + assert_eq!(partial.year, Some(2024)); + assert_eq!(partial.month, Some(5)); + assert_eq!( + partial.month_code, + Some(MonthCode::from_str("M05").unwrap()) + ); + assert_eq!(partial.era, None); + assert_eq!(partial.era_year, None); + } + + #[test] + fn test_year_month_fields_to_calendar_fields_round_trip() { + let partial = YearMonthCalendarFields::new() + .with_year(1999) + .with_month(12); + let pd: CalendarFields = partial.clone().into(); + let reconstructed: YearMonthCalendarFields = pd.into(); + assert_eq!(partial, reconstructed); + } + + #[test] + fn test_partial_year_month_builder_methods() { + let calendar = Calendar::from_str("gregory").unwrap(); + let calendar_fields = YearMonthCalendarFields::new() + .with_year(2020) + .with_month(7) + .with_month_code(MonthCode::from_str("M07").unwrap()) + .with_era(Some(tinystr!(19, "ce"))) + .with_era_year(Some(2020)); + + let partial = PartialYearMonth { + calendar_fields, + calendar: calendar.clone(), + }; + + assert_eq!(partial.calendar_fields.year, Some(2020)); + assert_eq!(partial.calendar_fields.month, Some(7)); + assert_eq!( + partial.calendar_fields.month_code, + Some(MonthCode::from_str("M07").unwrap()) + ); + assert_eq!(partial.calendar_fields.era, Some(tinystr!(19, "ce"))); + assert_eq!(partial.calendar_fields.era_year, Some(2020)); + assert_eq!(partial.calendar, calendar); + } + + #[test] + fn test_year_month_diff_range() { + // built-ins/Temporal/PlainYearMonth/prototype/since/throws-if-year-outside-valid-iso-range + + let min = PlainYearMonth::new(-271821, 4, None, Default::default()).unwrap(); + let max = PlainYearMonth::new(275760, 9, None, Default::default()).unwrap(); + let epoch = PlainYearMonth::new(1970, 1, None, Default::default()).unwrap(); + let _ = min.since(&min, Default::default()).unwrap(); + assert!(min.since(&max, Default::default()).is_err()); + assert!(min.since(&epoch, Default::default()).is_err()); + } + + #[test] + fn test_reference_day() { + assert_eq!( + PlainYearMonth::from_str("1868-10-30[u-ca=japanese]") + .unwrap() + .reference_day(), + 23 + ); + // Still happens for dates that are in the previous era but same month + assert_eq!( + PlainYearMonth::from_str("1868-10-20[u-ca=japanese]") + .unwrap() + .reference_day(), + 23 + ); + // Won't happen for dates in other months + assert_eq!( + PlainYearMonth::from_str("1868-09-30[u-ca=japanese]") + .unwrap() + .reference_day(), + 1 + ); + + // Always 1 in other calendars + assert_eq!( + PlainYearMonth::from_str("2000-09-30[u-ca=chinese]") + .unwrap() + .reference_day(), + 1 + ); + assert_eq!( + PlainYearMonth::from_str("2000-09-30[u-ca=hebrew]") + .unwrap() + .reference_day(), + 1 + ); + } + + #[test] + /// https://g-issues.chromium.org/issues/443275104 + fn test_max_rounding_increment_auto() { + let ym = PlainYearMonth::try_new_iso(1639, 11, None).unwrap(); + assert!(ym + .until( + &ym, + DifferenceSettings { + smallest_unit: Some(Unit::Auto), + ..Default::default() + } + ) + .is_err()); + } +} diff --git a/deps/temporal/src/builtins/core/time_zone.rs b/deps/temporal/src/builtins/core/time_zone.rs new file mode 100644 index 00000000000000..e791f341729261 --- /dev/null +++ b/deps/temporal/src/builtins/core/time_zone.rs @@ -0,0 +1,685 @@ +//! This module implements the Temporal `TimeZone` and components. + +use alloc::string::String; + +use ixdtf::encoding::Utf8; +use ixdtf::{ + parsers::TimeZoneParser, + records::{MinutePrecisionOffset, TimeZoneRecord, UtcOffsetRecord}, +}; +use num_traits::ToPrimitive; + +use crate::error::ErrorMessage; +use crate::parsers::{ + parse_allowed_timezone_formats, parse_identifier, FormattableOffset, FormattableTime, Precision, +}; +use crate::provider::{CandidateEpochNanoseconds, TimeZoneId, TimeZoneProvider}; +use crate::Sign; +use crate::{ + builtins::core::{duration::normalized::TimeDuration, Instant}, + iso::{IsoDate, IsoDateTime, IsoTime}, + options::Disambiguation, + TemporalError, TemporalResult, TemporalUnwrap, ZonedDateTime, +}; + +use crate::provider::EpochNanosecondsAndOffset; + +const NS_IN_S: i64 = 1_000_000_000; +const NS_IN_MIN: i64 = 60_000_000_000; + +/// A UTC time zone offset stored in nanoseconds +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub struct UtcOffset(i64); + +impl From for UtcOffset { + fn from(other: timezone_provider::provider::UtcOffsetSeconds) -> Self { + Self::from_seconds(other.0) + } +} + +impl From for timezone_provider::provider::UtcOffsetSeconds { + fn from(other: UtcOffset) -> Self { + Self(other.seconds()) + } +} + +impl UtcOffset { + pub(crate) fn from_ixdtf_minute_record(record: MinutePrecisionOffset) -> Self { + // NOTE: ixdtf parser restricts minute/second to 0..=60 + let minutes = i16::from(record.hour) * 60 + record.minute as i16; + let minutes = minutes * i16::from(record.sign as i8); + Self::from_minutes(minutes) + } + pub(crate) fn from_ixdtf_record(record: UtcOffsetRecord) -> TemporalResult { + let hours = i64::from(record.hour()); + let minutes = 60 * hours + i64::from(record.minute()); + let sign = record.sign() as i64; + + if let Some(second) = record.second() { + let seconds = 60 * minutes + i64::from(second); + + let mut ns = seconds * NS_IN_S; + + if let Some(frac) = record.fraction() { + ns += i64::from( + frac.to_nanoseconds().ok_or( + TemporalError::range() + .with_enum(ErrorMessage::FractionalTimeMoreThanNineDigits), + )?, + ); + } + + Ok(Self(ns * sign)) + } else { + Ok(Self(minutes * sign * NS_IN_MIN)) + } + } + + pub fn from_utf8(source: &[u8]) -> TemporalResult { + let record = TimeZoneParser::from_utf8(source).parse_offset()?; + Self::from_ixdtf_record(record) + } + + #[allow(clippy::inherent_to_string)] + pub fn to_string(&self) -> String { + let sign = if self.0 < 0 { + Sign::Negative + } else { + Sign::Positive + }; + let nanoseconds_total = self.0.abs(); + + let nanosecond = u32::try_from(nanoseconds_total % NS_IN_S).unwrap_or(0); + let seconds_left = nanoseconds_total / NS_IN_S; + + let second = u8::try_from(seconds_left % 60).unwrap_or(0); + let minutes_left = seconds_left / 60; + + let minute = u8::try_from(minutes_left % 60).unwrap_or(0); + let hour = u8::try_from(minutes_left / 60).unwrap_or(0); + + let precision = if nanosecond == 0 && second == 0 { + Precision::Minute + } else { + Precision::Auto + }; + let formattable_offset = FormattableOffset { + sign, + time: FormattableTime { + hour, + minute, + second, + nanosecond, + precision, + include_sep: true, + }, + }; + formattable_offset.to_string() + } + + pub fn from_minutes(minutes: i16) -> Self { + Self(i64::from(minutes) * NS_IN_MIN) + } + + pub(crate) fn from_seconds(seconds: i64) -> Self { + Self(seconds * crate::builtins::core::instant::NANOSECONDS_PER_SECOND) + } + + pub fn minutes(&self) -> i16 { + i16::try_from(self.0 / NS_IN_MIN).unwrap_or(0) + } + + pub fn seconds(&self) -> i64 { + self.0 / NS_IN_S + } + + pub fn nanoseconds(&self) -> i64 { + self.0 + } + + pub fn is_sub_minute(&self) -> bool { + self.0 % NS_IN_MIN != 0 + } + + /// Partial implementation of GetISODateTimeFor for a cached offset + pub(crate) fn get_iso_datetime_for(&self, instant: &Instant) -> IsoDateTime { + // 2. Let result be GetISOPartsFromEpoch(ℝ(epochNs)). + // 3. Return BalanceISODateTime(result.[[ISODate]].[[Year]], result.[[ISODate]].[[Month]], result.[[ISODate]].[[Day]], + // result.[[Time]].[[Hour]], result.[[Time]].[[Minute]], result.[[Time]].[[Second]], result.[[Time]].[[Millisecond]], + // result.[[Time]].[[Microsecond]], result.[[Time]].[[Nanosecond]] + offsetNanoseconds). + IsoDateTime::from_epoch_nanos(instant.epoch_nanoseconds(), self.nanoseconds()) + } +} + +impl core::str::FromStr for UtcOffset { + type Err = TemporalError; + fn from_str(s: &str) -> Result { + Self::from_utf8(s.as_bytes()) + } +} + +// TODO: Potentially migrate to Cow<'a, str> +// TODO: There may be an argument to have Offset minutes be a (Cow<'a, str>,, i16) to +// prevent allocations / writing, TBD +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum TimeZone { + IanaIdentifier(TimeZoneId), + UtcOffset(UtcOffset), +} + +impl TimeZone { + // Create a `TimeZone` from an ixdtf `TimeZoneRecord`. + #[inline] + pub(crate) fn from_time_zone_record( + record: TimeZoneRecord, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let timezone = match record { + TimeZoneRecord::Name(name) => TimeZone::IanaIdentifier(provider.get(name)?), + TimeZoneRecord::Offset(offset_record) => { + let offset = UtcOffset::from_ixdtf_minute_record(offset_record); + TimeZone::UtcOffset(offset) + } + // TimeZoneRecord is non_exhaustive, but all current branches are matching. + _ => return Err(TemporalError::assert()), + }; + + Ok(timezone) + } + + /// Parses a `TimeZone` from a provided `&str`. + pub fn try_from_identifier_str_with_provider( + identifier: &str, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + parse_identifier(identifier).map(|tz| match tz { + TimeZoneRecord::Name(name) => Ok(TimeZone::IanaIdentifier(provider.get(name)?)), + TimeZoneRecord::Offset(minute_precision_offset) => Ok(TimeZone::UtcOffset( + UtcOffset::from_ixdtf_minute_record(minute_precision_offset), + )), + _ => Err(TemporalError::range().with_message("Invalid TimeZone Identifier")), + })? + } + + #[cfg(feature = "compiled_data")] + pub fn try_from_identifier_str(src: &str) -> TemporalResult { + Self::try_from_identifier_str_with_provider(src, &*crate::builtins::TZ_PROVIDER) + } + /// Parse a `TimeZone` from a `&str` + /// + /// This is the equivalent to [`ParseTemporalTimeZoneString`](https://tc39.es/proposal-temporal/#sec-temporal-parsetemporaltimezonestring) + pub fn try_from_str_with_provider( + src: &str, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + if let Ok(timezone) = Self::try_from_identifier_str_with_provider(src, provider) { + return Ok(timezone); + } + parse_allowed_timezone_formats(src, provider) + .ok_or_else(|| TemporalError::range().with_message("Not a valid time zone string")) + } + + #[cfg(feature = "compiled_data")] + pub fn try_from_str(src: &str) -> TemporalResult { + Self::try_from_str_with_provider(src, &*crate::builtins::TZ_PROVIDER) + } + + /// Returns the current `TimeZoneSlot`'s identifier. + pub fn identifier_with_provider( + &self, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + Ok(match self { + TimeZone::IanaIdentifier(s) => provider.identifier(*s)?.into(), + TimeZone::UtcOffset(offset) => offset.to_string(), + }) + } + + /// Returns the current `TimeZoneSlot`'s identifier. + #[cfg(feature = "compiled_data")] + pub fn identifier(&self) -> TemporalResult { + self.identifier_with_provider(&*crate::builtins::TZ_PROVIDER) + } + + /// Get the primary identifier for this timezone + pub fn primary_identifier_with_provider( + &self, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + Ok(match self { + TimeZone::IanaIdentifier(s) => TimeZone::IanaIdentifier(provider.canonicalized(*s)?), + TimeZone::UtcOffset(offset) => TimeZone::UtcOffset(*offset), + }) + } + + /// Get the primary identifier for this timezone + #[cfg(feature = "compiled_data")] + pub fn primary_identifier(&self) -> TemporalResult { + self.primary_identifier_with_provider(&*crate::builtins::TZ_PROVIDER) + } + + // TimeZoneEquals, which compares primary identifiers + pub(crate) fn time_zone_equals_with_provider( + &self, + other: &Self, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + Ok(match (self, other) { + (TimeZone::IanaIdentifier(one), TimeZone::IanaIdentifier(two)) => { + let one = provider.canonicalized(*one)?; + let two = provider.canonicalized(*two)?; + one.normalized == two.normalized + } + (&TimeZone::UtcOffset(one), &TimeZone::UtcOffset(two)) => one == two, + _ => false, + }) + } + + /// Return an identifier representing `utc` + #[cfg(feature = "compiled_data")] + pub fn utc() -> Self { + Self::utc_with_provider(&*crate::builtins::TZ_PROVIDER) + } + + /// Get the primary identifier for this timezone + pub fn utc_with_provider(provider: &impl TimeZoneProvider) -> Self { + Self::IanaIdentifier(provider.get(b"UTC").unwrap_or_default()) + } +} + +impl From<&ZonedDateTime> for TimeZone { + fn from(value: &ZonedDateTime) -> Self { + *value.time_zone() + } +} + +impl From for TimeZone { + fn from(value: UtcOffset) -> Self { + Self::UtcOffset(value) + } +} + +impl TimeZone { + pub(crate) fn get_iso_datetime_for( + &self, + instant: &Instant, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // 1. Let offsetNanoseconds be GetOffsetNanosecondsFor(timeZone, epochNs). + let nanos = self.get_offset_nanos_for(instant.as_i128(), provider)?; + // 2. Let result be GetISOPartsFromEpoch(ℝ(epochNs)). + // 3. Return BalanceISODateTime(result.[[ISODate]].[[Year]], result.[[ISODate]].[[Month]], result.[[ISODate]].[[Day]], + // result.[[Time]].[[Hour]], result.[[Time]].[[Minute]], result.[[Time]].[[Second]], result.[[Time]].[[Millisecond]], + // result.[[Time]].[[Microsecond]], result.[[Time]].[[Nanosecond]] + offsetNanoseconds). + Ok(IsoDateTime::from_epoch_nanos( + instant.epoch_nanoseconds(), + nanos.to_i64().unwrap_or(0), + )) + } + + /// Get the offset for this current `TimeZoneSlot`. + pub(crate) fn get_offset_nanos_for( + &self, + utc_epoch: i128, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // 1. Let parseResult be ! ParseTimeZoneIdentifier(timeZone). + match self { + // 2. If parseResult.[[OffsetMinutes]] is not empty, return parseResult.[[OffsetMinutes]] × (60 × 10**9). + Self::UtcOffset(offset) => Ok(i128::from(offset.nanoseconds())), + // 3. Return GetNamedTimeZoneOffsetNanoseconds(parseResult.[[Name]], epochNs). + Self::IanaIdentifier(identifier) => { + let offset = provider + .transition_nanoseconds_for_utc_epoch_nanoseconds(*identifier, utc_epoch)?; + Ok(i128::from(offset.0) * 1_000_000_000) + } + } + } + + /// Get the offset for this current `TimeZoneSlot` as a `UtcOffset` + pub(crate) fn get_utc_offset_for( + &self, + utc_epoch: i128, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let offset = self.get_offset_nanos_for(utc_epoch, provider)?; + let offset = i64::try_from(offset).ok().temporal_unwrap()?; + Ok(UtcOffset(offset)) + } + + pub(crate) fn get_epoch_nanoseconds_for( + &self, + local_iso: IsoDateTime, + disambiguation: Disambiguation, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // 1. Let possibleEpochNs be ? GetPossibleEpochNanoseconds(timeZone, isoDateTime). + let possible_nanos = self.get_possible_epoch_ns_for(local_iso, provider)?; + // 2. Return ? DisambiguatePossibleEpochNanoseconds(possibleEpochNs, timeZone, isoDateTime, disambiguation). + self.disambiguate_possible_epoch_nanos(possible_nanos, local_iso, disambiguation, provider) + } + + /// Get the possible `Instant`s for this `TimeZoneSlot`. + pub(crate) fn get_possible_epoch_ns_for( + &self, + local_iso: IsoDateTime, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // 1.Let parseResult be ! ParseTimeZoneIdentifier(timeZone). + let possible_nanoseconds = match self { + // 2. If parseResult.[[OffsetMinutes]] is not empty, then + Self::UtcOffset(offset) => { + // This routine should not be hit with sub-minute offsets + // + // > ...takes arguments timeZone (an available time zone identifier) + // > + // > An available time zone identifier is either an available named time zone identifier or an + // > offset time zone identifier. + // > + // > Offset time zone identifiers are compared using the number of minutes represented (not as a String), + // > and are accepted as input in any the formats specified by UTCOffset[~SubMinutePrecision] + debug_assert!( + !offset.is_sub_minute(), + "Called get_possible_epoch_ns_for on a sub-minute-precision offset" + ); + // a. Let balanced be + // BalanceISODateTime(isoDateTime.[[ISODate]].[[Year]], + // isoDateTime.[[ISODate]].[[Month]], + // isoDateTime.[[ISODate]].[[Day]], + // isoDateTime.[[Time]].[[Hour]], + // isoDateTime.[[Time]].[[Minute]] - + // parseResult.[[OffsetMinutes]], + // isoDateTime.[[Time]].[[Second]], + // isoDateTime.[[Time]].[[Millisecond]], + // isoDateTime.[[Time]].[[Microsecond]], + // isoDateTime.[[Time]].[[Nanosecond]]). + let balanced = IsoDateTime::balance( + local_iso.date.year, + local_iso.date.month.into(), + local_iso.date.day.into(), + local_iso.time.hour.into(), + (i16::from(local_iso.time.minute) - offset.minutes()).into(), + local_iso.time.second.into(), + local_iso.time.millisecond.into(), + local_iso.time.microsecond.into(), + local_iso.time.nanosecond.into(), + ); + // b. Perform ? CheckISODaysRange(balanced.[[ISODate]]). + balanced.date.is_valid_day_range()?; + // c. Let epochNanoseconds be GetUTCEpochNanoseconds(balanced). + let epoch_ns = balanced.as_nanoseconds(); + // d. Let possibleEpochNanoseconds be « epochNanoseconds ». + CandidateEpochNanoseconds::One(EpochNanosecondsAndOffset { + offset: (*offset).into(), + ns: epoch_ns, + }) + } + // 3. Else, + Self::IanaIdentifier(identifier) => { + // a. Let possibleEpochNanoseconds be + // GetNamedTimeZoneEpochNanoseconds(parseResult.[[Name]], + // isoDateTime). + provider.candidate_nanoseconds_for_local_epoch_nanoseconds( + *identifier, + local_iso.into(), + )? + } + }; + // 4. For each value epochNanoseconds in possibleEpochNanoseconds, do + // a . If IsValidEpochNanoseconds(epochNanoseconds) is false, throw a RangeError exception. + for ns in possible_nanoseconds.as_slice() { + ns.ns.check_validity()?; + } + // 5. Return possibleEpochNanoseconds. + Ok(possible_nanoseconds) + } +} + +impl TimeZone { + // TODO: This can be optimized by just not using a vec. + pub(crate) fn disambiguate_possible_epoch_nanos( + &self, + nanos: CandidateEpochNanoseconds, + iso: IsoDateTime, + disambiguation: Disambiguation, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // 1. Let n be possibleEpochNs's length. + let valid_bounds = match nanos { + // 2. If n = 1, then + CandidateEpochNanoseconds::One(ns) => { + // a. Return possibleEpochNs[0]. + return Ok(ns); + } + // 3. If n ≠ 0, then + CandidateEpochNanoseconds::Two([one, two]) => { + match disambiguation { + // a. If disambiguation is earlier or compatible, then + // i. Return possibleEpochNs[0]. + Disambiguation::Compatible | Disambiguation::Earlier => return Ok(one), + // b. If disambiguation is later, then + // i. Return possibleEpochNs[n - 1]. + Disambiguation::Later => return Ok(two), + // c. Assert: disambiguation is reject. + // d. Throw a RangeError exception. + Disambiguation::Reject => { + return Err( + TemporalError::range().with_message("Rejecting ambiguous time zones.") + ) + } + } + } + CandidateEpochNanoseconds::Zero(vb) => vb, + }; + + // 4. Assert: n = 0. + // 5. If disambiguation is reject, then + if disambiguation == Disambiguation::Reject { + // a. Throw a RangeError exception. + return Err(TemporalError::range().with_message("Rejecting ambiguous time zones.")); + } + + // Instead of calculating the latest/earliest possible ISO datetime record, + // the GapEntryOffsets from CandidateEpochNanoseconds::Zero already has + // the offsets before and after the gap transition. We can use that directly, + // instead of doing a bunch of additional work. + // + // 6. Let before be the latest possible ISO Date-Time Record for + // which CompareISODateTime(before, isoDateTime) = -1 and ! + // GetPossibleEpochNanoseconds(timeZone, before) is not + // empty. + // 7. Let after be the earliest possible ISO Date-Time Record + // for which CompareISODateTime(after, isoDateTime) = 1 and ! + // 8. Let beforePossible be ! + // GetPossibleEpochNanoseconds(timeZone, before). + // 9. Assert: beforePossible's length is 1. + // 10. Let afterPossible be ! + // GetPossibleEpochNanoseconds(timeZone, after). + // 11. Assert: afterPossible's length is 1. + + // 12. Let offsetBefore be GetOffsetNanosecondsFor(timeZone, + // beforePossible[0]). + let offset_before = valid_bounds.offset_before; + // 13. Let offsetAfter be GetOffsetNanosecondsFor(timeZone, + // afterPossible[0]). + let offset_after = valid_bounds.offset_after; + // 14. Let nanoseconds be offsetAfter - offsetBefore. + let seconds = offset_after.0 - offset_before.0; + let nanoseconds = seconds as i128 * 1_000_000_000; + // 15. Assert: abs(nanoseconds) ≤ nsPerDay. + // 16. If disambiguation is earlier, then + if disambiguation == Disambiguation::Earlier { + // a. Let timeDuration be TimeDurationFromComponents(0, 0, 0, 0, 0, -nanoseconds). + let time_duration = TimeDuration(-nanoseconds); + // b. Let earlierTime be AddTime(isoDateTime.[[Time]], timeDuration). + let earlier_time = iso.time.add(time_duration); + // c. Let earlierDate be BalanceISODate(isoDateTime.[[ISODate]].[[Year]], + // isoDateTime.[[ISODate]].[[Month]], + // isoDateTime.[[ISODate]].[[Day]] + earlierTime.[[Days]]). + let earlier_date = IsoDate::try_balance( + iso.date.year, + iso.date.month.into(), + i64::from(iso.date.day) + earlier_time.0, + )?; + + // d. Let earlierDateTime be + // CombineISODateAndTimeRecord(earlierDate, earlierTime). + let earlier = IsoDateTime::new_unchecked(earlier_date, earlier_time.1); + // e. Set possibleEpochNs to ? GetPossibleEpochNanoseconds(timeZone, earlierDateTime). + let possible = self.get_possible_epoch_ns_for(earlier, provider)?; + // f. Assert: possibleEpochNs is not empty. + // g. Return possibleEpochNs[0]. + return possible.first().temporal_unwrap(); + } + // 17. Assert: disambiguation is compatible or later. + // 18. Let timeDuration be TimeDurationFromComponents(0, 0, 0, 0, 0, nanoseconds). + let time_duration = TimeDuration(nanoseconds); + // 19. Let laterTime be AddTime(isoDateTime.[[Time]], timeDuration). + let later_time = iso.time.add(time_duration); + // 20. Let laterDate be BalanceISODate(isoDateTime.[[ISODate]].[[Year]], + // isoDateTime.[[ISODate]].[[Month]], isoDateTime.[[ISODate]].[[Day]] + laterTime.[[Days]]). + let later_date = IsoDate::try_balance( + iso.date.year, + iso.date.month.into(), + i64::from(iso.date.day) + later_time.0, + )?; + // 21. Let laterDateTime be CombineISODateAndTimeRecord(laterDate, laterTime). + let later = IsoDateTime::new_unchecked(later_date, later_time.1); + // 22. Set possibleEpochNs to ? GetPossibleEpochNanoseconds(timeZone, laterDateTime). + let possible = self.get_possible_epoch_ns_for(later, provider)?; + // 23. Set n to possibleEpochNs's length. + // 24. Assert: n ≠ 0. + // 25. Return possibleEpochNs[n - 1]. + possible.last().temporal_unwrap() + } + + pub(crate) fn get_start_of_day( + &self, + iso_date: &IsoDate, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // 1. Let isoDateTime be CombineISODateAndTimeRecord(isoDate, MidnightTimeRecord()). + let iso = IsoDateTime::new_unchecked(*iso_date, IsoTime::default()); + // 2. Let possibleEpochNs be ? GetPossibleEpochNanoseconds(timeZone, isoDateTime). + let possible_nanos = self.get_possible_epoch_ns_for(iso, provider)?; + // 3. If possibleEpochNs is not empty, return possibleEpochNs[0]. + let gap = match possible_nanos { + CandidateEpochNanoseconds::One(first) | CandidateEpochNanoseconds::Two([first, _]) => { + return Ok(first) + } + CandidateEpochNanoseconds::Zero(gap) => gap, + }; + // 5. Let possibleEpochNsAfter be GetNamedTimeZoneEpochNanoseconds(timeZone, isoDateTimeAfter), where + // isoDateTimeAfter is the ISO Date-Time Record for which ! DifferenceISODateTime(isoDateTime, + // isoDateTimeAfter, "iso8601", hour).[[Time]] is the smallest possible value > 0 for which + // possibleEpochNsAfter is not empty (i.e., isoDateTimeAfter represents the first local time + // after the transition). + + // For a gap entry, possibleEpochNsAfter will just be the transition time. We don't + // actually need to calculate an isoDateTimeAfter and do all that rigmarole; we already + // know the transition time. + + // 6. Assert: possibleEpochNsAfter's length = 1. + // 7. Return possibleEpochNsAfter[0]. + + Ok(EpochNanosecondsAndOffset { + offset: gap.offset_after, + ns: gap.transition_epoch, + }) + } +} + +#[cfg(test)] +mod tests { + #[cfg(feature = "compiled_data")] + use super::TimeZone; + + #[test] + #[cfg(feature = "compiled_data")] + fn from_and_to_string() { + let src = "+09:30"; + let tz = TimeZone::try_from_identifier_str(src).unwrap(); + assert_eq!(tz.identifier().unwrap(), src); + + let src = "-09:30"; + let tz = TimeZone::try_from_identifier_str(src).unwrap(); + assert_eq!(tz.identifier().unwrap(), src); + + let src = "-12:30"; + let tz = TimeZone::try_from_identifier_str(src).unwrap(); + assert_eq!(tz.identifier().unwrap(), src); + + let src = "America/New_York"; + let tz = TimeZone::try_from_identifier_str(src).unwrap(); + assert_eq!(tz.identifier().unwrap(), src); + } + + #[test] + #[cfg(feature = "compiled_data")] + fn canonicalize_equals() { + let calcutta = TimeZone::try_from_identifier_str("Asia/Calcutta").unwrap(); + let kolkata = TimeZone::try_from_identifier_str("Asia/Kolkata").unwrap(); + assert!(calcutta + .time_zone_equals_with_provider(&kolkata, &*crate::builtins::TZ_PROVIDER) + .unwrap()); + } + + #[cfg(feature = "compiled_data")] + fn test_possible_epoch_ns_at_limits_helper( + time_zone_identifier: &str, + offset_sec_at_min: i64, + offset_sec_at_max: i64, + ) { + use crate::iso::IsoDateTime; + use crate::provider::{ + CandidateEpochNanoseconds, EpochNanosecondsAndOffset, UtcOffsetSeconds, + }; + use crate::unix_time::EpochNanoseconds; + use crate::{NS_MAX_INSTANT, NS_MIN_INSTANT}; + + let provider = &*crate::builtins::TZ_PROVIDER; + + let time_zone = TimeZone::try_from_identifier_str(time_zone_identifier).unwrap(); + + let min = IsoDateTime::balance(-271821, 4, 20, 0, 0, offset_sec_at_min, 0, 0, 0); + let min_result = time_zone.get_possible_epoch_ns_for(min, provider).unwrap(); + assert_eq!( + min_result, + CandidateEpochNanoseconds::One(EpochNanosecondsAndOffset { + ns: EpochNanoseconds(NS_MIN_INSTANT), + offset: UtcOffsetSeconds(offset_sec_at_min) + }) + ); + + let max = IsoDateTime::balance(275760, 9, 13, 0, 0, offset_sec_at_max, 0, 0, 0); + let max_result = time_zone.get_possible_epoch_ns_for(max, provider).unwrap(); + assert_eq!( + max_result, + CandidateEpochNanoseconds::One(EpochNanosecondsAndOffset { + ns: EpochNanoseconds(NS_MAX_INSTANT), + offset: UtcOffsetSeconds(offset_sec_at_max) + }) + ); + + let too_early = IsoDateTime::balance(-271821, 4, 20, 0, 0, offset_sec_at_min, 0, 0, -1); + assert!(time_zone + .get_possible_epoch_ns_for(too_early, provider) + .is_err()); + + let too_late = IsoDateTime::balance(275760, 9, 13, 0, 0, offset_sec_at_max, 0, 0, 1); + assert!(time_zone + .get_possible_epoch_ns_for(too_late, provider) + .is_err()); + } + + #[test] + #[cfg(feature = "compiled_data")] + fn test_possible_epoch_ns_at_limits() { + test_possible_epoch_ns_at_limits_helper("UTC", 0, 0); + test_possible_epoch_ns_at_limits_helper("+02:00", 7200, 7200); + test_possible_epoch_ns_at_limits_helper("-07:00", -25200, -25200); + test_possible_epoch_ns_at_limits_helper("Europe/Amsterdam", 1050, 7200); + test_possible_epoch_ns_at_limits_helper("America/Vancouver", -29548, -25200); + test_possible_epoch_ns_at_limits_helper("Australia/Sydney", 36292, 36000); + } +} diff --git a/deps/temporal/src/builtins/core/zoned_date_time.rs b/deps/temporal/src/builtins/core/zoned_date_time.rs new file mode 100644 index 00000000000000..38cc1fc6aa6197 --- /dev/null +++ b/deps/temporal/src/builtins/core/zoned_date_time.rs @@ -0,0 +1,1585 @@ +//! This module contains the core implementation of the `ZonedDateTime` +//! builtin type. + +use crate::provider::EpochNanosecondsAndOffset; +use alloc::string::String; +use core::{cmp::Ordering, num::NonZeroU128}; +use tinystr::TinyAsciiStr; + +use crate::{ + builtins::{ + calendar::CalendarFields, + core::{ + calendar::Calendar, + duration::normalized::{InternalDurationRecord, TimeDuration}, + time_zone::{TimeZone, UtcOffset}, + Duration, Instant, PlainDate, PlainDateTime, PlainTime, + }, + }, + error::ErrorMessage, + iso::{IsoDate, IsoDateTime, IsoTime}, + options::{ + DifferenceOperation, DifferenceSettings, Disambiguation, DisplayCalendar, DisplayOffset, + DisplayTimeZone, OffsetDisambiguation, Overflow, ResolvedRoundingOptions, + RoundingIncrement, RoundingMode, RoundingOptions, ToStringRoundingOptions, Unit, UnitGroup, + }, + parsed_intermediates::ParsedZonedDateTime, + parsers::{FormattableOffset, FormattableTime, IxdtfStringBuilder, Precision}, + partial::PartialTime, + primitive::FiniteF64, + provider::{TimeZoneProvider, TransitionDirection, UtcOffsetSeconds}, + rounding::IncrementRounder, + temporal_assert, + unix_time::EpochNanoseconds, + MonthCode, Sign, TemporalError, TemporalResult, TemporalUnwrap, +}; + +#[cfg(test)] +mod tests; + +/// A struct representing a partial `ZonedDateTime`. +#[derive(Debug, Default, Clone, PartialEq)] +pub struct PartialZonedDateTime { + /// The `ZonedDateTimeFields` portion of a `PartialZonedDateTime` + pub fields: ZonedDateTimeFields, + /// The time zone value of a partial time zone. + pub timezone: Option, + /// The calendar for the `PartialZonedDateTime`. + pub calendar: Calendar, +} + +impl PartialZonedDateTime { + pub fn is_empty(&self) -> bool { + self.fields.is_empty() && self.timezone.is_none() + } + + pub const fn new() -> Self { + Self { + fields: ZonedDateTimeFields::new(), + timezone: None, + calendar: Calendar::ISO, + } + } + + pub const fn with_calendar_fields(mut self, fields: CalendarFields) -> Self { + self.fields.calendar_fields = fields; + self + } + + pub const fn with_time(mut self, time: PartialTime) -> Self { + self.fields.time = time; + self + } + + pub const fn with_offset(mut self, offset: UtcOffset) -> Self { + self.fields.offset = Some(offset); + self + } + + pub fn with_timezone(mut self, timezone: Option) -> Self { + self.timezone = timezone; + self + } +} + +#[derive(Debug, Default, Clone, PartialEq)] +pub struct ZonedDateTimeFields { + pub calendar_fields: CalendarFields, + + pub time: PartialTime, + + /// An optional offset string + pub offset: Option, +} + +impl ZonedDateTimeFields { + pub const fn new() -> Self { + Self { + calendar_fields: CalendarFields::new(), + time: PartialTime::new(), + offset: None, + } + } + + pub fn is_empty(&self) -> bool { + self.calendar_fields.is_empty() && self.time.is_empty() && self.offset.is_none() + } +} + +/// The native Rust implementation of a Temporal `ZonedDateTime`. +/// +/// A `ZonedDateTime` represents a date and time in a specific time zone and calendar. +/// Unlike `PlainDateTime`, it represents an exact moment in time by combining a +/// `PlainDateTime` with time zone information. It is internally represented as +/// an instant (epoch nanoseconds) along with calendar and time zone data. +/// +/// Since `ZonedDateTime` includes timezone information, it can handle daylight saving time +/// transitions and timezone offset changes automatically. The type requires a timezone +/// data provider (implementing `TimeZoneProvider`) for most operations, which supplies +/// the necessary timezone rules and historical data. +/// +/// Unlike `PlainDateTime` which can be ambiguous during DST transitions, `ZonedDateTime` +/// always represents an unambiguous moment in time. +/// +/// ## Time zone provider API +/// +/// The core implementation of `ZonedDateTime` uses time zone provider APIs denoted by +/// a `*_with_provider` suffix. This means a provider that implements the `TimeZoneProvider` +/// trait must be provided for timezone-aware operations. +/// +/// Time zone providers available: +/// - **File system provider**: `FsTzdbProvider` (enabled with `tzdb` feature) +/// - **Compiled data provider**: Default implementation (enabled with `compiled_data` feature) +/// +/// ## Examples +/// +/// ### Creating a ZonedDateTime +/// +/// ```rust +/// # #[cfg(feature = "compiled_data")] { +/// use temporal_rs::{Calendar, Instant, TimeZone, ZonedDateTime}; +/// +/// // Create from epoch nanoseconds +/// let zdt = ZonedDateTime::try_new( +/// 0, // epoch nanoseconds (Unix epoch) +/// TimeZone::utc(), // UTC timezone +/// Calendar::default(), // ISO 8601 calendar +/// ).unwrap(); +/// +/// assert_eq!(zdt.epoch_milliseconds(), 0); +/// assert_eq!(zdt.epoch_nanoseconds().as_i128(), 0); +/// assert_eq!(zdt.time_zone().identifier().unwrap(), "UTC"); +/// assert_eq!(zdt.calendar().identifier(), "iso8601"); +/// # } +/// ``` +/// +/// ### Working with timezones (requires provider, or compiled data) +/// +/// ```rust +/// # #[cfg(feature = "compiled_data")] { +/// use temporal_rs::{ZonedDateTime, TimeZone, Calendar}; +/// +/// let time_zone = TimeZone::try_from_str("America/New_York").unwrap(); +/// let zoned_date_time = ZonedDateTime::try_new( +/// 1609459200000000000, // 2021-01-01T00:00:00Z +/// time_zone, +/// Calendar::default(), +/// ).unwrap(); +/// +/// // Note: This would be December 31, 2020 19:00 in New York (EST) +/// assert_eq!(zoned_date_time.year(), 2020); +/// assert_eq!(zoned_date_time.month(), 12); +/// assert_eq!(zoned_date_time.day(), 31); +/// assert_eq!(zoned_date_time.hour(), 19); +/// # } +/// ``` +/// +/// ### ZonedDateTime arithmetic (requires provider) +/// +/// ```rust +/// # #[cfg(feature = "compiled_data")] { +/// use temporal_rs::{ZonedDateTime, Duration, TimeZone, Calendar}; +/// use std::str::FromStr; +/// +/// let time_zone = TimeZone::try_from_str("Europe/London").unwrap(); +/// let zdt = ZonedDateTime::try_new( +/// 1609459200000000000, // 2021-01-01T00:00:00Z +/// time_zone, +/// Calendar::default(), +/// ).unwrap(); +/// +/// // Add 6 months +/// let later = zdt.add( +/// &Duration::from_str("P6M").unwrap(), +/// None, +/// ).unwrap(); +/// +/// assert_eq!(later.month(), 7); // July +/// # } +/// ``` +/// +/// ### Converting from PlainDateTime +/// +/// ```rust +/// # #[cfg(feature = "compiled_data")] { +/// use temporal_rs::{PlainDateTime, ZonedDateTime, TimeZone, options::Disambiguation}; +/// use std::str::FromStr; +/// +/// let plain_date_time = PlainDateTime::from_str("2024-03-15T14:30:00").unwrap(); +/// let time_zone = TimeZone::try_from_str("America/Los_Angeles").unwrap(); +/// +/// let zdt = plain_date_time.to_zoned_date_time( +/// time_zone, +/// Disambiguation::Compatible, +/// ).unwrap(); +/// +/// // Now we have an exact moment in time in the LA timezone +/// assert_eq!(zdt.time_zone().identifier().unwrap(), "America/Los_Angeles"); +/// # } +/// ``` +/// +/// ### String formatting (requires provider) +/// +/// ```rust +/// # #[cfg(feature = "compiled_data")] { +/// use temporal_rs::{ZonedDateTime, Calendar, TimeZone}; +/// use temporal_rs::options::{DisplayOffset, DisplayTimeZone, DisplayCalendar, ToStringRoundingOptions}; +/// +/// let zdt = ZonedDateTime::try_new( +/// 1609459200000000000, +/// TimeZone::try_from_str("Asia/Tokyo").unwrap(), +/// Calendar::default(), +/// ).unwrap(); +/// +/// let iso_string = zdt.to_ixdtf_string( +/// DisplayOffset::default(), +/// DisplayTimeZone::default(), +/// DisplayCalendar::default(), +/// ToStringRoundingOptions::default() +/// ).unwrap(); +/// +/// // Results in something like "2021-01-01T09:00:00+09:00[Asia/Tokyo]" +/// assert!(iso_string.contains("2021-01-01")); +/// assert!(iso_string.contains("+09:00")); +/// assert!(iso_string.contains("[Asia/Tokyo]")); +/// # } +/// ``` +/// +/// ## Reference +/// +/// For more information, see the [MDN documentation][mdn-zoneddatetime]. +/// +/// [mdn-zoneddatetime]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime +#[non_exhaustive] +#[derive(Debug, Clone)] +pub struct ZonedDateTime { + instant: Instant, + calendar: Calendar, + time_zone: TimeZone, + cached_offset: UtcOffset, +} + +// ==== Private API ==== + +impl ZonedDateTime { + /// Creates a `ZonedDateTime` without validating the input. + #[inline] + #[must_use] + pub(crate) fn new_unchecked( + instant: Instant, + time_zone: TimeZone, + calendar: Calendar, + cached_offset: UtcOffsetSeconds, + ) -> Self { + Self { + instant, + calendar, + time_zone, + cached_offset: cached_offset.into(), + } + } + + pub(crate) fn new_unchecked_with_provider( + instant: Instant, + time_zone: TimeZone, + calendar: Calendar, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let offset = time_zone + .get_utc_offset_for(instant.epoch_nanoseconds().0, provider) + .temporal_unwrap()?; + Ok(Self { + instant, + calendar, + time_zone, + cached_offset: offset, + }) + } + + /// Equivalent to self.tz.get_iso_datetime_for(&self.instant, provider) + /// + /// (which is GetISODateTimeFor(self.[[TimeZone]], self.[[EpochNanoseconds]]).) + pub(crate) fn get_iso_datetime(&self) -> IsoDateTime { + self.cached_offset.get_iso_datetime_for(&self.instant) + } + + pub(crate) fn add_zoned_date_time( + &self, + duration: InternalDurationRecord, + overflow: Overflow, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // 1. If DateDurationSign(duration.[[Date]]) = 0, then + if duration.date().sign() == Sign::Zero { + // a. Return ? AddInstant(epochNanoseconds, duration.[[Time]]). + return self + .instant + .add_to_instant(&duration.normalized_time_duration()); + } + // 2. Let isoDateTime be GetISODateTimeFor(timeZone, epochNanoseconds). + let iso_datetime = self.get_iso_datetime(); + // 3. Let addedDate be ? CalendarDateAdd(calendar, isoDateTime.[[ISODate]], duration.[[Date]], overflow). + let added_date = + self.calendar() + .date_add(&iso_datetime.date, &duration.date(), overflow)?; + // 4. Let intermediateDateTime be CombineISODateAndTimeRecord(addedDate, isoDateTime.[[Time]]). + let intermediate = IsoDateTime::new_unchecked(added_date.iso, iso_datetime.time); + // 5. If ISODateTimeWithinLimits(intermediateDateTime) is false, throw a RangeError exception. + if !intermediate.is_within_limits() { + return Err( + TemporalError::range().with_enum(ErrorMessage::IntermediateDateTimeOutOfRange) + ); + } + // 6. Let intermediateNs be ! GetEpochNanosecondsFor(timeZone, intermediateDateTime, compatible). + let intermediate_ns = self.time_zone().get_epoch_nanoseconds_for( + intermediate, + Disambiguation::Compatible, + provider, + )?; + + // 7. Return ? AddInstant(intermediateNs, duration.[[Time]]). + Instant::from(intermediate_ns.ns).add_to_instant(&duration.normalized_time_duration()) + } + + /// Adds a duration to the current `ZonedDateTime`, returning the resulting `ZonedDateTime`. + /// + /// Aligns with Abstract Operation 6.5.10 + #[inline] + pub(crate) fn add_internal( + &self, + duration: &Duration, + overflow: Overflow, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // 1. Let duration be ? ToTemporalDuration(temporalDurationLike). + // 2. If operation is subtract, set duration to CreateNegatedTemporalDuration(duration). + // 3. Let resolvedOptions be ? GetOptionsObject(options). + // 4. Let overflow be ? GetTemporalOverflowOption(resolvedOptions). + // 5. Let calendar be zonedDateTime.[[Calendar]]. + // 6. Let timeZone be zonedDateTime.[[TimeZone]]. + // 7. Let internalDuration be ToInternalDurationRecord(duration). + let internal_duration = duration.to_internal_duration_record(); + // 8. Let epochNanoseconds be ? AddZonedDateTime(zonedDateTime.[[EpochNanoseconds]], timeZone, calendar, internalDuration, overflow). + let epoch_ns = self.add_zoned_date_time(internal_duration, overflow, provider)?; + // 9. Return ! CreateTemporalZonedDateTime(epochNanoseconds, timeZone, calendar). + Self::new_unchecked_with_provider( + epoch_ns, + *self.time_zone(), + self.calendar().clone(), + provider, + ) + } + + /// Internal representation of Abstract Op 6.5.7 + pub(crate) fn diff_with_rounding( + &self, + other: &Instant, + resolved_options: ResolvedRoundingOptions, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // 1. If UnitCategory(largestUnit) is time, then + if resolved_options.largest_unit.is_time_unit() { + // a. Return DifferenceInstant(ns1, ns2, roundingIncrement, smallestUnit, roundingMode). + return self.instant.diff_instant_internal(other, resolved_options); + } + // 2. let difference be ? differencezoneddatetime(ns1, ns2, timezone, calendar, largestunit). + let diff = self.diff_zoned_datetime(other, resolved_options.largest_unit, provider)?; + // 3. if smallestunit is nanosecond and roundingincrement = 1, return difference. + if resolved_options.smallest_unit == Unit::Nanosecond + && resolved_options.increment == RoundingIncrement::ONE + { + return Ok(diff); + } + // 4. let datetime be getisodatetimefor(timezone, ns1). + let iso = self.get_iso_datetime(); + // 5. Return ? RoundRelativeDuration(difference, ns2, dateTime, timeZone, calendar, largestUnit, roundingIncrement, smallestUnit, roundingMode). + diff.round_relative_duration( + other.epoch_nanoseconds().as_i128(), + &PlainDateTime::new_unchecked(iso, self.calendar().clone()), + Some((self.time_zone(), provider)), + resolved_options, + ) + } + + /// Internal representation of Abstract Op 6.5.8 + pub(crate) fn diff_with_total( + &self, + other: &Instant, + unit: Unit, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // 1. If UnitCategory(unit) is time, then + if unit.is_time_unit() { + // a. Let difference be TimeDurationFromEpochNanosecondsDifference(ns2, ns1). + let diff = TimeDuration::from_nanosecond_difference( + other.epoch_nanoseconds().as_i128(), + self.epoch_nanoseconds().as_i128(), + )?; + // b. Return TotalTimeDuration(difference, unit). + return diff.total(unit); + } + + // 2. Let difference be ? DifferenceZonedDateTime(ns1, ns2, timeZone, calendar, unit). + let diff = self.diff_zoned_datetime(other, unit, provider)?; + // 3. Let dateTime be GetISODateTimeFor(timeZone, ns1). + let iso = self.get_iso_datetime(); + // 4. Return ? TotalRelativeDuration(difference, ns2, dateTime, timeZone, calendar, unit). + diff.total_relative_duration( + other.epoch_nanoseconds().as_i128(), + &PlainDateTime::new_unchecked(iso, self.calendar().clone()), + Some((self.time_zone(), provider)), + unit, + ) + } + + pub(crate) fn diff_zoned_datetime( + &self, + other: &Instant, + largest_unit: Unit, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // 1. If ns1 = ns2, return CombineDateAndTimeDuration(ZeroDateDuration(), 0). + if self.epoch_nanoseconds() == other.epoch_nanoseconds() { + return Ok(InternalDurationRecord::default()); + } + // 2. Let startDateTime be GetISODateTimeFor(timeZone, ns1). + let start = self.get_iso_datetime(); + // 3. Let endDateTime be GetISODateTimeFor(timeZone, ns2). + let end = self.time_zone.get_iso_datetime_for(other, provider)?; + // 4. If ns2 - ns1 < 0, let sign be -1; else let sign be 1. + let sign = if other.epoch_nanoseconds().as_i128() - self.epoch_nanoseconds().as_i128() < 0 { + Sign::Negative + } else { + Sign::Positive + }; + // 5. If sign = 1, let maxDayCorrection be 2; else let maxDayCorrection be 1. + let max_correction = if sign == Sign::Positive { 2 } else { 1 }; + // 6. Let dayCorrection be 0. + // 7. Let timeDuration be DifferenceTime(startDateTime.[[Time]], endDateTime.[[Time]]). + let time = start.time.diff(&end.time); + // 8. If TimeDurationSign(timeDuration) = -sign, set dayCorrection to dayCorrection + 1. + let mut day_correction = if time.sign() as i8 == -(sign as i8) { + 1 + } else { + 0 + }; + + // 9. Let success be false. + let mut intermediate_dt = IsoDateTime::default(); + let mut time_duration = TimeDuration::default(); + let mut is_success = false; + // 10. Repeat, while dayCorrection ≤ maxDayCorrection and success is false, + while day_correction <= max_correction && !is_success { + // a. Let intermediateDate be BalanceISODate(endDateTime.[[ISODate]].[[Year]], + // endDateTime.[[ISODate]].[[Month]], endDateTime.[[ISODate]].[[Day]] - dayCorrection × sign). + let intermediate = IsoDate::balance( + end.date.year, + end.date.month.into(), + i32::from(end.date.day) - i32::from(day_correction * sign as i8), + ); + // b. Let intermediateDateTime be CombineISODateAndTimeRecord(intermediateDate, startDateTime.[[Time]]). + intermediate_dt = IsoDateTime::new_unchecked(intermediate, start.time); + // c. Let intermediateNs be ? GetEpochNanosecondsFor(timeZone, intermediateDateTime, compatible). + let intermediate_ns = self.time_zone.get_epoch_nanoseconds_for( + intermediate_dt, + Disambiguation::Compatible, + provider, + )?; + // d. Set timeDuration to TimeDurationFromEpochNanosecondsDifference(ns2, intermediateNs). + time_duration = TimeDuration::from_nanosecond_difference( + other.epoch_nanoseconds().as_i128(), + intermediate_ns.ns.0, + )?; + // e. Let timeSign be TimeDurationSign(timeDuration). + let time_sign = time_duration.sign() as i8; + // f. If sign ≠ -timeSign, then + if sign as i8 != -time_sign { + // i. Set success to true. + is_success = true; + } + // g. Set dayCorrection to dayCorrection + 1. + day_correction += 1; + } + // 11. Assert: success is true. + // 12. Let dateLargestUnit be LargerOfTwoUnits(largestUnit, day). + let date_largest = largest_unit.max(Unit::Day); + // 13. Let dateDifference be CalendarDateUntil(calendar, startDateTime.[[ISODate]], intermediateDateTime.[[ISODate]], dateLargestUnit). + // 14. Return CombineDateAndTimeDuration(dateDifference, timeDuration). + let date_diff = + self.calendar() + .date_until(&start.date, &intermediate_dt.date, date_largest)?; + InternalDurationRecord::new(date_diff.date(), time_duration) + } + + /// `temporal_rs` equivalent to `DifferenceTemporalZonedDateTime`. + pub(crate) fn diff_internal_with_provider( + &self, + op: DifferenceOperation, + other: &Self, + options: DifferenceSettings, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // NOTE: for order of operations, this should be asserted prior to this point + // by any engine implementors, but asserting out of caution. + if self.calendar != other.calendar { + return Err(TemporalError::range().with_enum(ErrorMessage::CalendarMismatch)); + } + + // 4. Set settings be ? GetDifferenceSettings(operation, resolvedOptions, datetime, « », nanosecond, hour). + let resolved_options = ResolvedRoundingOptions::from_diff_settings( + options, + op, + UnitGroup::DateTime, + Unit::Hour, + Unit::Nanosecond, + )?; + + // 5. If UnitCategory(settings.[[LargestUnit]]) is time, then + if resolved_options.largest_unit.is_time_unit() { + // a. Let internalDuration be DifferenceInstant(zonedDateTime.[[EpochNanoseconds]], other.[[EpochNanoseconds]], settings.[[RoundingIncrement]], settings.[[SmallestUnit]], settings.[[RoundingMode]]). + let internal = self + .instant + .diff_instant_internal(&other.instant, resolved_options)?; + // b. Let result be ! TemporalDurationFromInternal(internalDuration, settings.[[LargestUnit]]). + let result = Duration::from_internal(internal, resolved_options.largest_unit)?; + // c. If operation is since, set result to CreateNegatedTemporalDuration(result). + // d. Return result. + match op { + DifferenceOperation::Since => return Ok(result.negated()), + DifferenceOperation::Until => return Ok(result), + } + } + + // 6. NOTE: To calculate differences in two different time zones, + // settings.[[LargestUnit]] must be a time unit, because day lengths + // can vary between time zones due to DST and other UTC offset shifts. + // 7. If TimeZoneEquals(zonedDateTime.[[TimeZone]], other.[[TimeZone]]) is false, then + if !self + .time_zone + .time_zone_equals_with_provider(&other.time_zone, provider)? + { + // a. Throw a RangeError exception. + return Err(TemporalError::range().with_enum(ErrorMessage::TzMismatch)); + } + + // 8. If zonedDateTime.[[EpochNanoseconds]] = other.[[EpochNanoseconds]], then + if self.instant == other.instant { + // a. Return ! CreateTemporalDuration(0, 0, 0, 0, 0, 0, 0, 0, 0, 0). + return Ok(Duration::default()); + } + + // 9. Let internalDuration be ? DifferenceZonedDateTimeWithRounding(zonedDateTime.[[EpochNanoseconds]], other.[[EpochNanoseconds]], zonedDateTime.[[TimeZone]], zonedDateTime.[[Calendar]], settings.[[LargestUnit]], settings.[[RoundingIncrement]], settings.[[SmallestUnit]], settings.[[RoundingMode]]). + let internal = self.diff_with_rounding(&other.instant, resolved_options, provider)?; + // 10. Let result be ! TemporalDurationFromInternal(internalDuration, hour). + let result = Duration::from_internal(internal, Unit::Hour)?; + // 11. If operation is since, set result to CreateNegatedTemporalDuration(result). + // 12. Return result. + match op { + DifferenceOperation::Since => Ok(result.negated()), + DifferenceOperation::Until => Ok(result), + } + } +} + +// ==== Public API ==== + +impl ZonedDateTime { + /// Creates a new valid `ZonedDateTime`. + #[inline] + pub fn try_new_with_provider( + nanos: i128, + time_zone: TimeZone, + calendar: Calendar, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let instant = Instant::try_new(nanos)?; + Self::new_unchecked_with_provider(instant, time_zone, calendar, provider) + } + + /// Creates a new valid `ZonedDateTime`. + #[inline] + pub(crate) fn try_new_with_cached_offset( + nanos: i128, + time_zone: TimeZone, + calendar: Calendar, + cached_offset: UtcOffsetSeconds, + ) -> TemporalResult { + let instant = Instant::try_new(nanos)?; + Ok(Self::new_unchecked( + instant, + time_zone, + calendar, + cached_offset, + )) + } + + /// Creates a new valid `ZonedDateTime` with an ISO 8601 calendar. + #[inline] + pub fn try_new_iso_with_provider( + nanos: i128, + time_zone: TimeZone, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let instant = Instant::try_new(nanos)?; + Self::new_unchecked_with_provider(instant, time_zone, Calendar::ISO, provider) + } + + /// Creates a new valid `ZonedDateTime` from an [`Instant`]. + #[inline] + pub fn try_new_from_instant_with_provider( + instant: Instant, + time_zone: TimeZone, + calendar: Calendar, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + Self::new_unchecked_with_provider(instant, time_zone, calendar, provider) + } + + /// Creates a new valid `ZonedDateTime` from an [`Instant`] with an ISO 8601 calendar. + #[inline] + pub fn try_new_iso_from_instant_with_provider( + instant: Instant, + time_zone: TimeZone, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + Self::new_unchecked_with_provider(instant, time_zone, Calendar::ISO, provider) + } + + /// Returns `ZonedDateTime`'s Calendar. + #[inline] + #[must_use] + pub fn calendar(&self) -> &Calendar { + &self.calendar + } + + /// Returns `ZonedDateTime`'s `TimeZone` slot. + #[inline] + #[must_use] + pub fn time_zone(&self) -> &TimeZone { + &self.time_zone + } + + /// Create a `ZonedDateTime` from a `PartialZonedDateTime`. + #[inline] + pub fn from_partial_with_provider( + partial: PartialZonedDateTime, + overflow: Option, + disambiguation: Option, + offset_option: Option, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let overflow = overflow.unwrap_or(Overflow::Constrain); + let disambiguation = disambiguation.unwrap_or(Disambiguation::Compatible); + let offset_option = offset_option.unwrap_or(OffsetDisambiguation::Reject); + + let date = partial + .calendar + .date_from_fields(partial.fields.calendar_fields, overflow)? + .iso; + + let time = Some(IsoTime::default().with(partial.fields.time, overflow)?); + + // Handle time zones + let offset_nanos = partial.fields.offset.map(|offset| offset.nanoseconds()); + + let timezone = partial + .timezone + .unwrap_or_else(|| TimeZone::utc_with_provider(provider)); + let epoch_nanos = interpret_isodatetime_offset( + date, + time, + false, + offset_nanos, + &timezone, + disambiguation, + offset_option, + false, + provider, + )?; + + Ok(Self::new_unchecked( + Instant::from(epoch_nanos.ns), + timezone, + partial.calendar, + epoch_nanos.offset, + )) + } + + /// Returns the `epochMilliseconds` value of this `ZonedDateTime`. + #[must_use] + pub fn epoch_milliseconds(&self) -> i64 { + self.instant.epoch_milliseconds() + } + + /// Returns the `epochNanoseconds` value of this `ZonedDateTime`. + #[must_use] + pub fn epoch_nanoseconds(&self) -> &EpochNanoseconds { + self.instant.epoch_nanoseconds() + } + + /// Returns the current `ZonedDateTime` as an [`Instant`]. + #[must_use] + pub fn to_instant(&self) -> Instant { + self.instant + } + + pub fn with_with_provider( + &self, + fields: ZonedDateTimeFields, + disambiguation: Option, + offset_option: Option, + overflow: Option, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let overflow = overflow.unwrap_or_default(); + let disambiguation = disambiguation.unwrap_or_default(); + let offset_option = offset_option.unwrap_or(OffsetDisambiguation::Reject); + // 8. Let isoDateTime be GetISODateTimeFor(timeZone, epochNs). + let iso_date_time = self.get_iso_datetime(); + let plain_date_time = PlainDateTime::new_unchecked(iso_date_time, self.calendar.clone()); + + // 23. Let dateTimeResult be ? InterpretTemporalDateTimeFields(calendar, fields, overflow). + let result_date = self.calendar.date_from_fields( + fields.calendar_fields.with_fallback_datetime( + &plain_date_time, + self.calendar.kind(), + overflow, + )?, + overflow, + )?; + + let time = iso_date_time.time.with(fields.time, overflow)?; + + // 7. Let offsetNanoseconds be GetOffsetNanosecondsFor(timeZone, epochNs). + let original_offset = self.offset_nanoseconds(); + // 24. Let newOffsetNanoseconds be ! ParseDateTimeUTCOffset(fields.[[OffsetString]]). + let new_offset_nanos = fields + .offset + .map(|offset| offset.nanoseconds()) + .or(Some(original_offset)); + + // 25. Let epochNanoseconds be ? InterpretISODateTimeOffset(dateTimeResult.[[ISODate]], dateTimeResult.[[Time]], option, newOffsetNanoseconds, timeZone, disambiguation, offset, match-exactly). + let epoch_nanos = interpret_isodatetime_offset( + result_date.iso, + Some(time), + // Set to Option ... we don't use an enum here, so any value will do. + true, + new_offset_nanos, + &self.time_zone, + disambiguation, + offset_option, + // match-exactly + false, + provider, + )?; + + // 26. Return ! CreateTemporalZonedDateTime(epochNanoseconds, timeZone, calendar). + Ok(Self::new_unchecked( + Instant::from(epoch_nanos.ns), + self.time_zone, + self.calendar.clone(), + epoch_nanos.offset, + )) + } + + /// Creates a new `ZonedDateTime` from the current `ZonedDateTime` + /// combined with the provided `TimeZone`. + pub fn with_time_zone_with_provider( + &self, + time_zone: TimeZone, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + Self::try_new_with_provider( + self.epoch_nanoseconds().as_i128(), + time_zone, + self.calendar.clone(), + provider, + ) + } + + /// Creates a new `ZonedDateTime` from the current `ZonedDateTime` + /// combined with the provided `Calendar`. + #[inline] + #[must_use] + pub fn with_calendar(&self, calendar: Calendar) -> Self { + Self::new_unchecked( + self.instant, + self.time_zone, + calendar, + self.cached_offset.into(), + ) + } + + /// Compares one `ZonedDateTime` to another `ZonedDateTime` using their + /// `Instant` representation. + /// + /// # Note on Ordering. + /// + /// `temporal_rs` does not implement `PartialOrd`/`Ord` as `ZonedDateTime` does + /// not fulfill all the conditions required to implement the traits. However, + /// it is possible to compare `PlainDate`'s as their `IsoDate` representation. + #[inline] + #[must_use] + pub fn compare_instant(&self, other: &Self) -> Ordering { + self.instant.cmp(&other.instant) + } +} + +// ==== HoursInDay accessor method implementation ==== + +impl ZonedDateTime { + /// Get the previous or next time zone transition for the current `ZonedDateTime`. + pub fn get_time_zone_transition_with_provider( + &self, + direction: TransitionDirection, + provider: &impl TimeZoneProvider, + ) -> TemporalResult> { + // 8. If IsOffsetTimeZoneIdentifier(timeZone) is true, return null. + let TimeZone::IanaIdentifier(identifier) = self.time_zone else { + return Ok(None); + }; + // 9. If direction is next, then + // a. Let transition be GetNamedTimeZoneNextTransition(timeZone, zonedDateTime.[[EpochNanoseconds]]). + // 10. Else, + // a. Assert: direction is previous. + // b. Let transition be GetNamedTimeZonePreviousTransition(timeZone, zonedDateTime.[[EpochNanoseconds]]). + let transition = provider.get_time_zone_transition( + identifier, + self.epoch_nanoseconds().as_i128(), + direction, + )?; + + // 11. If transition is null, return null. + let Some(transition) = transition else { + return Ok(None); + }; + + if transition.check_validity().is_err() { + // GetNamedTimeZoneNextTransition, GetNamedTimeZonePreviousTransition include a check for out-of-bounds + // instants. Instead of requiring providers handle that, we handle it here. + return Ok(None); + } + // 12. Return ! CreateTemporalZonedDateTime(transition, timeZone, zonedDateTime.[[Calendar]]). + Ok(Some( + ZonedDateTime::try_new_with_provider( + transition.0, + self.time_zone, + self.calendar().clone(), + provider, + ) + .ok() + .temporal_unwrap()?, + )) + } + + pub fn hours_in_day_with_provider( + &self, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // 1-3. Is engine specific steps + // 4. Let isoDateTime be GetISODateTimeFor(timeZone, zonedDateTime.[[EpochNanoseconds]]). + let iso = self.get_iso_datetime(); + // 5. Let today be isoDateTime.[[ISODate]]. + let today = iso.date; + // 6. Let tomorrow be BalanceISODate(today.[[Year]], today.[[Month]], today.[[Day]] + 1). + let tomorrow = IsoDate::balance(today.year, today.month.into(), i32::from(today.day + 1)); + // 7. Let todayNs be ? GetStartOfDay(timeZone, today). + let today = self.time_zone.get_start_of_day(&today, provider)?; + // 8. Let tomorrowNs be ? GetStartOfDay(timeZone, tomorrow). + let tomorrow = self.time_zone.get_start_of_day(&tomorrow, provider)?; + // 9. Let diff be TimeDurationFromEpochNanosecondsDifference(tomorrowNs, todayNs). + let diff = TimeDuration::from_nanosecond_difference(tomorrow.ns.0, today.ns.0)?; + // NOTE: The below should be safe as today_ns and tomorrow_ns should be at most 25 hours. + // TODO: Tests for the below cast. + // 10. Return 𝔽(TotalTimeDuration(diff, hour)). + Ok(diff.divide(3_600_000_000_000.)) + } +} + +// ==== Core accessor methods ==== + +impl ZonedDateTime { + /// Returns the `year` value for this `ZonedDateTime`. + #[inline] + pub fn year(&self) -> i32 { + let iso = self.get_iso_datetime(); + let dt = PlainDateTime::new_unchecked(iso, self.calendar.clone()); + self.calendar.year(&dt.iso.date) + } + + /// Returns the `month` value for this `ZonedDateTime`. + pub fn month(&self) -> u8 { + let iso = self.get_iso_datetime(); + let dt = PlainDateTime::new_unchecked(iso, self.calendar.clone()); + self.calendar.month(&dt.iso.date) + } + + /// Returns the `monthCode` value for this `ZonedDateTime`. + pub fn month_code(&self) -> MonthCode { + let iso = self.get_iso_datetime(); + let dt = PlainDateTime::new_unchecked(iso, self.calendar.clone()); + self.calendar.month_code(&dt.iso.date) + } + + /// Returns the `day` value for this `ZonedDateTime`. + pub fn day(&self) -> u8 { + let iso = self.get_iso_datetime(); + let dt = PlainDateTime::new_unchecked(iso, self.calendar.clone()); + self.calendar.day(&dt.iso.date) + } + + /// Returns the `hour` value for this `ZonedDateTime`. + pub fn hour(&self) -> u8 { + let iso = self.get_iso_datetime(); + iso.time.hour + } + + /// Returns the `minute` value for this `ZonedDateTime`. + pub fn minute(&self) -> u8 { + let iso = self.get_iso_datetime(); + iso.time.minute + } + + /// Returns the `second` value for this `ZonedDateTime`. + pub fn second(&self) -> u8 { + let iso = self.get_iso_datetime(); + iso.time.second + } + + /// Returns the `millisecond` value for this `ZonedDateTime`. + pub fn millisecond(&self) -> u16 { + let iso = self.get_iso_datetime(); + iso.time.millisecond + } + + /// Returns the `microsecond` value for this `ZonedDateTime`. + pub fn microsecond(&self) -> u16 { + let iso = self.get_iso_datetime(); + iso.time.microsecond + } + + /// Returns the `nanosecond` value for this `ZonedDateTime`. + pub fn nanosecond(&self) -> u16 { + let iso = self.get_iso_datetime(); + iso.time.nanosecond + } + + // TODO: Expose a format / writeable API + /// Returns an offset string for the current `ZonedDateTime`. + pub fn offset(&self) -> String { + let offset = self.cached_offset.nanoseconds(); + nanoseconds_to_formattable_offset(offset as i128).to_string() + } + + /// Returns the offset nanoseconds for the current `ZonedDateTime`. + pub fn offset_nanoseconds(&self) -> i64 { + self.cached_offset.nanoseconds() + } +} + +pub(crate) fn nanoseconds_to_formattable_offset(nanoseconds: i128) -> FormattableOffset { + let sign = if nanoseconds >= 0 { + Sign::Positive + } else { + Sign::Negative + }; + let nanos = nanoseconds.unsigned_abs(); + let hour = (nanos / 3_600_000_000_000) as u8; + let minute = ((nanos / 60_000_000_000) % 60) as u8; + let second = ((nanos / 1_000_000_000) % 60) as u8; + let nanosecond = (nanos % 1_000_000_000) as u32; + + let precision = if second == 0 && nanosecond == 0 { + Precision::Minute + } else { + Precision::Auto + }; + + FormattableOffset { + sign, + time: FormattableTime { + hour, + minute, + second, + nanosecond, + precision, + include_sep: true, + }, + } +} + +// ==== Core calendar method implementations ==== + +impl ZonedDateTime { + /// Returns the era for the current `ZonedDateTime`. + pub fn era(&self) -> Option> { + let iso = self.get_iso_datetime(); + let pdt = PlainDateTime::new_unchecked(iso, self.calendar.clone()); + self.calendar.era(&pdt.iso.date) + } + + /// Returns the era-specific year for the current `ZonedDateTime`. + pub fn era_year(&self) -> Option { + let iso = self.get_iso_datetime(); + let pdt = PlainDateTime::new_unchecked(iso, self.calendar.clone()); + self.calendar.era_year(&pdt.iso.date) + } + + /// Returns the calendar day of week value. + pub fn day_of_week(&self) -> u16 { + let iso = self.get_iso_datetime(); + let pdt = PlainDateTime::new_unchecked(iso, self.calendar.clone()); + self.calendar.day_of_week(&pdt.iso.date) + } + + /// Returns the calendar day of year value. + pub fn day_of_year(&self) -> u16 { + let iso = self.get_iso_datetime(); + let pdt = PlainDateTime::new_unchecked(iso, self.calendar.clone()); + self.calendar.day_of_year(&pdt.iso.date) + } + + /// Returns the calendar week of year value. + pub fn week_of_year(&self) -> Option { + let iso = self.get_iso_datetime(); + let pdt = PlainDateTime::new_unchecked(iso, self.calendar.clone()); + self.calendar.week_of_year(&pdt.iso.date) + } + + /// Returns the calendar year of week value. + pub fn year_of_week(&self) -> Option { + let iso = self.get_iso_datetime(); + let pdt = PlainDateTime::new_unchecked(iso, self.calendar.clone()); + self.calendar.year_of_week(&pdt.iso.date) + } + + /// Returns the calendar days in week value. + pub fn days_in_week(&self) -> u16 { + let iso = self.get_iso_datetime(); + let pdt = PlainDateTime::new_unchecked(iso, self.calendar.clone()); + self.calendar.days_in_week(&pdt.iso.date) + } + + /// Returns the calendar days in month value. + pub fn days_in_month(&self) -> u16 { + let iso = self.get_iso_datetime(); + let pdt = PlainDateTime::new_unchecked(iso, self.calendar.clone()); + self.calendar.days_in_month(&pdt.iso.date) + } + + /// Returns the calendar days in year value. + pub fn days_in_year(&self) -> u16 { + let iso = self.get_iso_datetime(); + let pdt = PlainDateTime::new_unchecked(iso, self.calendar.clone()); + self.calendar.days_in_year(&pdt.iso.date) + } + + /// Returns the calendar months in year value. + pub fn months_in_year(&self) -> u16 { + let iso = self.get_iso_datetime(); + let pdt = PlainDateTime::new_unchecked(iso, self.calendar.clone()); + self.calendar.months_in_year(&pdt.iso.date) + } + + /// Returns returns whether the date in a leap year for the given calendar. + pub fn in_leap_year(&self) -> bool { + let iso = self.get_iso_datetime(); + let pdt = PlainDateTime::new_unchecked(iso, self.calendar.clone()); + self.calendar.in_leap_year(&pdt.iso.date) + } +} + +// ==== Core method implementations ==== + +impl ZonedDateTime { + /// Creates a new `ZonedDateTime` from the current `ZonedDateTime` + /// combined with the provided `TimeZone`. + pub fn with_plain_time_and_provider( + &self, + time: Option, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let iso = self.get_iso_datetime(); + let epoch_ns = if let Some(time) = time { + let result_iso = IsoDateTime::new_unchecked(iso.date, time.iso); + self.time_zone.get_epoch_nanoseconds_for( + result_iso, + Disambiguation::Compatible, + provider, + )? + } else { + self.time_zone.get_start_of_day(&iso.date, provider)? + }; + Self::try_new_with_cached_offset( + epoch_ns.ns.0, + self.time_zone, + self.calendar.clone(), + epoch_ns.offset, + ) + } + + /// Add a duration to the current `ZonedDateTime` + pub fn add_with_provider( + &self, + duration: &Duration, + overflow: Option, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + self.add_internal(duration, overflow.unwrap_or(Overflow::Constrain), provider) + } + + /// Subtract a duration to the current `ZonedDateTime` + pub fn subtract_with_provider( + &self, + duration: &Duration, + overflow: Option, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + self.add_internal( + &duration.negated(), + overflow.unwrap_or(Overflow::Constrain), + provider, + ) + } + + /// Checks if the current `ZonedDateTime` is equal to another `ZonedDateTime`. + pub fn equals_with_provider( + &self, + other: &Self, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // 4. If zonedDateTime.[[EpochNanoseconds]] ≠ other.[[EpochNanoseconds]], return false. + if self.instant != other.instant { + return Ok(false); + } + + // 5. If TimeZoneEquals(zonedDateTime.[[TimeZone]], other.[[TimeZone]]) is false, return false. + if !self + .time_zone + .time_zone_equals_with_provider(&other.time_zone, provider)? + { + return Ok(false); + } + // 6. Return CalendarEquals(zonedDateTime.[[Calendar]], other.[[Calendar]]). + Ok(self.calendar == other.calendar) + } + + /// Returns a [`Duration`] representing the period of time from this `ZonedDateTime` since the other `ZonedDateTime`. + pub fn since_with_provider( + &self, + other: &Self, + options: DifferenceSettings, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + self.diff_internal_with_provider(DifferenceOperation::Since, other, options, provider) + } + + /// Returns a [`Duration`] representing the period of time from this `ZonedDateTime` since the other `ZonedDateTime`. + pub fn until_with_provider( + &self, + other: &Self, + options: DifferenceSettings, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + self.diff_internal_with_provider(DifferenceOperation::Until, other, options, provider) + } + + /// Return a `ZonedDateTime` representing the start of the day + /// for the current `ZonedDateTime`. + pub fn start_of_day_with_provider( + &self, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let iso = self.get_iso_datetime(); + let epoch_nanos = self.time_zone.get_start_of_day(&iso.date, provider)?; + Self::try_new_with_cached_offset( + epoch_nanos.ns.0, + self.time_zone, + self.calendar.clone(), + epoch_nanos.offset, + ) + } + + /// Convert the current `ZonedDateTime` to a [`PlainDate`] + pub fn to_plain_date(&self) -> PlainDate { + let iso = self.get_iso_datetime(); + PlainDate::new_unchecked(iso.date, self.calendar.clone()) + } + + /// Convert the current `ZonedDateTime` to a [`PlainTime`] + pub fn to_plain_time(&self) -> PlainTime { + let iso = self.get_iso_datetime(); + PlainTime::new_unchecked(iso.time) + } + + /// Convert the current `ZonedDateTime` to a [`PlainDateTime`] + pub fn to_plain_date_time(&self) -> PlainDateTime { + let iso = self.get_iso_datetime(); + PlainDateTime::new_unchecked(iso, self.calendar.clone()) + } + + /// Creates a default formatted IXDTF (RFC 9557) date/time string for the provided `ZonedDateTime`. + pub fn to_string_with_provider( + &self, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + self.to_ixdtf_string_with_provider( + DisplayOffset::Auto, + DisplayTimeZone::Auto, + DisplayCalendar::Auto, + ToStringRoundingOptions::default(), + provider, + ) + } + + /// 6.3.39 Temporal.ZonedDateTime.prototype.round + pub fn round_with_provider( + &self, + options: RoundingOptions, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // 1. Let zonedDateTime be the this value. + // 2. Perform ? RequireInternalSlot(zonedDateTime, [[InitializedTemporalZonedDateTime]]). + // 3. If roundTo is undefined, then + // a. Throw a TypeError exception. + // 4. If roundTo is a String, then + // a. Let paramString be roundTo. + // b. Set roundTo to OrdinaryObjectCreate(null). + // c. Perform ! CreateDataPropertyOrThrow(roundTo, "smallestUnit", paramString). + // 5. Else, + // a. Set roundTo to ? GetOptionsObject(roundTo). + // 6. NOTE: The following steps read options and perform independent validation in alphabetical order (GetRoundingIncrementOption reads "roundingIncrement" and GetRoundingModeOption reads "roundingMode"). + // 7. Let roundingIncrement be ? GetRoundingIncrementOption(roundTo). + // 8. Let roundingMode be ? GetRoundingModeOption(roundTo, half-expand). + // 9. Let smallestUnit be ? GetTemporalUnitValuedOption(roundTo, "smallestUnit", time, required, « day »). + // 10. If smallestUnit is day, then + // a. Let maximum be 1. + // b. Let inclusive be true. + // 11. Else, + // a. Let maximum be MaximumTemporalDurationRoundingIncrement(smallestUnit). + // b. Assert: maximum is not unset. + // c. Let inclusive be false. + let resolved = ResolvedRoundingOptions::from_datetime_options(options)?; + // 12. Perform ? ValidateTemporalRoundingIncrement(roundingIncrement, maximum, inclusive). + // 13. If maximum is not unset, perform ? ValidateTemporalRoundingIncrement(roundingIncrement, maximum, false). + // 13. If smallestUnit is nanosecond and roundingIncrement = 1, then + if resolved.smallest_unit == Unit::Nanosecond + && resolved.increment == RoundingIncrement::ONE + { + // a. Return ! CreateTemporalZonedDateTime(zonedDateTime.[[EpochNanoseconds]], zonedDateTime.[[TimeZone]], zonedDateTime.[[Calendar]]). + return Ok(self.clone()); + } + // 14. Let thisNs be zonedDateTime.[[EpochNanoseconds]]. + let this_ns = self.epoch_nanoseconds(); + // 15. Let timeZone be zonedDateTime.[[TimeZone]]. + // 16. Let calendar be zonedDateTime.[[Calendar]]. + // 17. Let isoDateTime be GetISODateTimeFor(timeZone, thisNs). + // 18. If smallestUnit is day, then + if resolved.smallest_unit == Unit::Day { + // a. Let dateStart be isoDateTime.[[ISODate]]. + let iso_start = self.get_iso_datetime(); + // b. Let dateEnd be BalanceISODate(dateStart.[[Year]], dateStart.[[Month]], dateStart.[[Day]] + 1). + let iso_end = IsoDate::balance( + iso_start.date.year, + iso_start.date.month.into(), + i32::from(iso_start.date.day + 1), + ); + // c. Let startNs be ? GetStartOfDay(timeZone, dateStart). + // d. Assert: thisNs ≥ startNs. + // e. Let endNs be ? GetStartOfDay(timeZone, dateEnd). + // f. Assert: thisNs < endNs. + let start = self.time_zone.get_start_of_day(&iso_start.date, provider)?; + let end = self.time_zone.get_start_of_day(&iso_end, provider)?; + if !(this_ns.0 >= start.ns.0 && this_ns.0 < end.ns.0) { + return Err(TemporalError::range().with_enum(ErrorMessage::ZDTOutOfDayBounds)); + } + // g. Let dayLengthNs be ℝ(endNs - startNs). + // h. Let dayProgressNs be TimeDurationFromEpochNanosecondsDifference(thisNs, startNs). + let day_len_ns = TimeDuration::from_nanosecond_difference(end.ns.0, start.ns.0)?; + let day_progress_ns = TimeDuration::from_nanosecond_difference(this_ns.0, start.ns.0)?; + // i. Let roundedDayNs be ! RoundTimeDurationToIncrement(dayProgressNs, dayLengthNs, roundingMode). + let rounded = if let Some(increment) = NonZeroU128::new(day_len_ns.0.unsigned_abs()) { + IncrementRounder::::from_signed_num(day_progress_ns.0, increment)? + .round(resolved.rounding_mode) + } else { + 0 // Zero-length day: round to start of day + }; + + // The cached offset will be based on which way we round + let offset = if rounded == 0 { + start.offset + } else { + end.offset + }; + + // j. Let epochNanoseconds be AddTimeDurationToEpochNanoseconds(roundedDayNs, startNs). + let candidate = start.ns.0 + rounded; + Instant::try_new(candidate)?; + // 20. Return ! CreateTemporalZonedDateTime(epochNanoseconds, timeZone, calendar). + ZonedDateTime::try_new_with_cached_offset( + candidate, + self.time_zone, + self.calendar.clone(), + offset, + ) + } else { + // 19. Else, + // a. Let roundResult be RoundISODateTime(isoDateTime, roundingIncrement, smallestUnit, roundingMode). + // b. Let offsetNanoseconds be GetOffsetNanosecondsFor(timeZone, thisNs). + // c. Let epochNanoseconds be ? InterpretISODateTimeOffset(roundResult.[[ISODate]], roundResult.[[Time]], option, offsetNanoseconds, timeZone, compatible, prefer, match-exactly). + // 20. Return ! CreateTemporalZonedDateTime(epochNanoseconds, timeZone, calendar). + let iso_dt = self.get_iso_datetime(); + let rounded_dt = iso_dt.round(resolved)?; + let offset_ns = self + .time_zone + .get_offset_nanos_for(this_ns.as_i128(), provider)?; + + let epoch_ns = interpret_isodatetime_offset( + rounded_dt.date, + Some(rounded_dt.time), + false, + Some(offset_ns as i64), + &self.time_zone, + Disambiguation::Compatible, + OffsetDisambiguation::Prefer, + // match-exactly + false, + provider, + )?; + + ZonedDateTime::try_new_with_cached_offset( + epoch_ns.ns.0, + self.time_zone, + self.calendar.clone(), + epoch_ns.offset, + ) + } + } + + /// Creates an IXDTF (RFC 9557) date/time string for the provided `ZonedDateTime` according + /// to the provided display options. + pub fn to_ixdtf_string_with_provider( + &self, + display_offset: DisplayOffset, + display_timezone: DisplayTimeZone, + display_calendar: DisplayCalendar, + options: ToStringRoundingOptions, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let resolved_options = options.resolve()?; + let result = + self.instant + .round_instant(ResolvedRoundingOptions::from_to_string_options( + &resolved_options, + ))?; + let rounded_instant = Instant::try_new(result)?; + + let offset = self.time_zone.get_offset_nanos_for(result, provider)?; + let datetime = self + .time_zone + .get_iso_datetime_for(&rounded_instant, provider)?; + let (sign, hour, minute) = nanoseconds_to_formattable_offset_minutes(offset)?; + let timezone_id = self.time_zone().identifier_with_provider(provider)?; + + let ixdtf_string = IxdtfStringBuilder::default() + .with_date(datetime.date) + .with_time(datetime.time, resolved_options.precision) + .with_minute_offset(sign, hour, minute, display_offset) + .with_timezone(&timezone_id, display_timezone) + .with_calendar(self.calendar.identifier(), display_calendar) + .build(); + + Ok(ixdtf_string) + } + + // TODO: Should IANA Identifier be prechecked or allow potentially invalid IANA Identifer values here? + pub fn from_utf8_with_provider( + source: &[u8], + disambiguation: Disambiguation, + offset_option: OffsetDisambiguation, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let parsed = ParsedZonedDateTime::from_utf8_with_provider(source, provider)?; + + Self::from_parsed_with_provider(parsed, disambiguation, offset_option, provider) + } + + pub fn from_parsed_with_provider( + parsed: ParsedZonedDateTime, + disambiguation: Disambiguation, + offset_option: OffsetDisambiguation, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + let date = IsoDate::new_with_overflow( + parsed.date.record.year, + parsed.date.record.month, + parsed.date.record.day, + Overflow::Reject, + )?; + + let epoch_nanos = interpret_isodatetime_offset( + date, + parsed.time, + parsed.has_utc_designator, + parsed.offset.map(|o| o.nanoseconds()), + &parsed.timezone, + disambiguation, + offset_option, + parsed.match_minutes, + provider, + )?; + Ok(Self::new_unchecked( + Instant::from(epoch_nanos.ns), + parsed.timezone, + Calendar::new(parsed.date.calendar), + epoch_nanos.offset, + )) + } +} + +/// InterpretISODateTimeOffset +/// +/// offsetBehavior is: +/// - OPTION if offset_nanos is Some +/// - WALL if offset_nanos is None and !is_exact +/// - EXACT if offset_nanos is None and is_exact +/// +/// When offset_nanos is None, offsetNanoseconds is 0 +#[allow(clippy::too_many_arguments)] +pub(crate) fn interpret_isodatetime_offset( + date: IsoDate, + time: Option, + is_exact: bool, + offset_nanos: Option, + timezone: &TimeZone, + disambiguation: Disambiguation, + offset_option: OffsetDisambiguation, + match_minutes: bool, + provider: &impl TimeZoneProvider, +) -> TemporalResult { + // 1. If time is start-of-day, then + let Some(time) = time else { + // a. Assert: offsetBehaviour is wall. + // b. Assert: offsetNanoseconds is 0. + temporal_assert!(offset_nanos.is_none()); + // c. Return ? GetStartOfDay(timeZone, isoDate). + return timezone.get_start_of_day(&date, provider); + }; + + // 2. Let isoDateTime be CombineISODateAndTimeRecord(isoDate, time). + let iso_datetime = IsoDateTime::new_unchecked(date, time); + match (is_exact, offset_nanos, offset_option) { + // 3. If offsetBehaviour is wall, or offsetBehaviour is option and offsetOption is ignore, then + (false, None, _) | (_, Some(_), OffsetDisambiguation::Ignore) => { + // a. Return ? GetEpochNanosecondsFor(timeZone, isoDateTime, disambiguation). + timezone.get_epoch_nanoseconds_for(iso_datetime, disambiguation, provider) + } + // 4. If offsetBehaviour is exact, or offsetBehaviour is option and offsetOption is use, then + (true, None, _) | (_, Some(_), OffsetDisambiguation::Use) => { + let offset = offset_nanos.unwrap_or(0); + // a. Let balanced be BalanceISODateTime(isoDate.[[Year]], isoDate.[[Month]], + // isoDate.[[Day]], time.[[Hour]], time.[[Minute]], time.[[Second]], time.[[Millisecond]], + // time.[[Microsecond]], time.[[Nanosecond]] - offsetNanoseconds). + let iso = IsoDateTime::balance( + date.year, + date.month.into(), + date.day.into(), + time.hour.into(), + time.minute.into(), + time.second.into(), + time.millisecond.into(), + time.microsecond.into(), + (i64::from(time.nanosecond) - offset).into(), + ); + + // b. Perform ? CheckISODaysRange(balanced.[[ISODate]]). + iso.date.is_valid_day_range()?; + + // c. Let epochNanoseconds be GetUTCEpochNanoseconds(balanced). + let ns = iso.as_nanoseconds(); + // d. If IsValidEpochNanoseconds(epochNanoseconds) is false, throw a RangeError exception. + ns.check_validity()?; + + // e. Return epochNanoseconds. + Ok(EpochNanosecondsAndOffset { + ns, + offset: timezone.get_utc_offset_for(ns.0, provider)?.into(), + }) + } + // 5. Assert: offsetBehaviour is option. + // 6. Assert: offsetOption is prefer or reject. + (_, Some(offset), OffsetDisambiguation::Prefer | OffsetDisambiguation::Reject) => { + // 7. Perform ? CheckISODaysRange(isoDate). + date.is_valid_day_range()?; + let iso = IsoDateTime::new_unchecked(date, time); + // 8. Let utcEpochNanoseconds be GetUTCEpochNanoseconds(isoDateTime). + let utc_epochs = iso.as_nanoseconds(); + // 9. Let possibleEpochNs be ? GetPossibleEpochNanoseconds(timeZone, isoDateTime). + let possible_nanos = timezone.get_possible_epoch_ns_for(iso, provider)?; + + // 10. For each element candidate of possibleEpochNs, do + for candidate in possible_nanos.as_slice() { + // a. Let candidateOffset be utcEpochNanoseconds - candidate. + let candidate_offset = utc_epochs.0 - candidate.ns.0; + // b. If candidateOffset = offsetNanoseconds, then + if candidate_offset == offset.into() { + // i. Return candidate. + return Ok(*candidate); + } + // c. If matchBehaviour is match-minutes, then + if match_minutes { + // i. Let roundedCandidateNanoseconds be RoundNumberToIncrement(candidateOffset, 60 × 10**9, half-expand). + let rounded_candidate = + IncrementRounder::from_signed_num(candidate_offset, NS_PER_MINUTE_NONZERO)? + .round(RoundingMode::HalfExpand); + // ii. If roundedCandidateNanoseconds = offsetNanoseconds, then + if rounded_candidate == offset.into() { + // 1. Return candidate. + return Ok(*candidate); + } + } + } + + // 11. If offsetOption is reject, throw a RangeError exception. + if offset_option == OffsetDisambiguation::Reject { + return Err( + TemporalError::range().with_enum(ErrorMessage::OffsetNeedsDisambiguation) + ); + } + // 12. Return ? DisambiguatePossibleEpochNanoseconds(possibleEpochNs, timeZone, isoDateTime, disambiguation). + timezone.disambiguate_possible_epoch_nanos( + possible_nanos, + iso, + disambiguation, + provider, + ) + } + } +} + +// Formatting utils +const NS_PER_MINUTE: i128 = 60_000_000_000; +// Once MSRV is 1.83 we can update this to just calling .unwrap() +const NS_PER_MINUTE_NONZERO: NonZeroU128 = if let Some(nz) = NonZeroU128::new(NS_PER_MINUTE as u128) +{ + nz +} else { + NonZeroU128::MIN +}; + +pub(crate) fn nanoseconds_to_formattable_offset_minutes( + nanoseconds: i128, +) -> TemporalResult<(Sign, u8, u8)> { + // Per 11.1.7 this should be rounding + let nanoseconds = IncrementRounder::from_signed_num(nanoseconds, NS_PER_MINUTE_NONZERO)? + .round(RoundingMode::HalfExpand); + let offset_minutes = (nanoseconds / NS_PER_MINUTE) as i32; + let sign = if offset_minutes < 0 { + Sign::Negative + } else { + Sign::Positive + }; + let hour = offset_minutes.abs() / 60; + let minute = offset_minutes.abs() % 60; + Ok((sign, hour as u8, minute as u8)) +} diff --git a/deps/temporal/src/builtins/core/zoned_date_time/tests.rs b/deps/temporal/src/builtins/core/zoned_date_time/tests.rs new file mode 100644 index 00000000000000..dcb8a3768168a5 --- /dev/null +++ b/deps/temporal/src/builtins/core/zoned_date_time/tests.rs @@ -0,0 +1,1145 @@ +use super::ZonedDateTime; +use crate::{ + builtins::{calendar::CalendarFields, zoned_date_time::ZonedDateTimeFields}, + options::{ + DifferenceSettings, Disambiguation, DisplayCalendar, DisplayOffset, DisplayTimeZone, + OffsetDisambiguation, Overflow, RoundingIncrement, RoundingMode, RoundingOptions, Unit, + }, + partial::{PartialTime, PartialZonedDateTime}, + provider::{TimeZoneProvider, TransitionDirection}, + unix_time::EpochNanoseconds, + Calendar, Duration, MonthCode, TemporalResult, TimeZone, UtcOffset, +}; +use alloc::string::ToString; +use timezone_provider::zoneinfo64::ZONEINFO64_RES_FOR_TESTING; +use tinystr::tinystr; + +macro_rules! test_all_providers { + ($(#[cfg_for_fs($cfg_fs:meta)])? $(#[cfg_for_zi64($cfg_zi:meta)])? $provider:ident: $b:block) => {{ + #[cfg(feature = "compiled_data")] + { + std::println!("Testing compiled_data:"); + let $provider = &*crate::builtins::TZ_PROVIDER; + + $b + } + + $(#[cfg($cfg_zi)])? { + std::println!("Testing ZoneInfo64Provider:"); + let zi_data = + zoneinfo64::ZoneInfo64::try_from_u32s(&ZONEINFO64_RES_FOR_TESTING).unwrap(); + let zi_provider = timezone_provider::zoneinfo64::ZoneInfo64TzdbProvider::new(zi_data); + let $provider = &zi_provider; + + $b + } + + $(#[cfg($cfg_fs)])? #[cfg(feature = "tzdb")] { + std::println!("Testing FS (note: May fail with bad local tzdb data):"); + let fs = timezone_provider::tzif::FsTzdbProvider::default(); + let $provider = &fs; + + $b + } + }}; +} + +#[test] +fn basic_zdt_test() { + test_all_providers!(provider: { + let nov_30_2023_utc = 1_701_308_952_000_000_000i128; + + let zdt = ZonedDateTime::try_new_with_provider( + nov_30_2023_utc, + TimeZone::try_from_str_with_provider("UTC", provider).unwrap(), + Calendar::ISO, + provider, + ) + .unwrap(); + + assert_eq!(zdt.year(), 2023); + assert_eq!(zdt.month(), 11); + assert_eq!(zdt.day(), 30); + assert_eq!(zdt.hour(), 1); + assert_eq!(zdt.minute(), 49); + assert_eq!(zdt.second(), 12); + + let zdt_minus_five = ZonedDateTime::try_new_with_provider( + nov_30_2023_utc, + TimeZone::try_from_str_with_provider("America/New_York", provider).unwrap(), + Calendar::ISO, + provider, + ) + .unwrap(); + + assert_eq!(zdt_minus_five.year(), 2023); + assert_eq!(zdt_minus_five.month(), 11); + assert_eq!(zdt_minus_five.day(), 29); + assert_eq!(zdt_minus_five.hour(), 20); + assert_eq!(zdt_minus_five.minute(), 49); + assert_eq!(zdt_minus_five.second(), 12); + + let zdt_plus_eleven = ZonedDateTime::try_new_with_provider( + nov_30_2023_utc, + TimeZone::try_from_str_with_provider("Australia/Sydney", provider).unwrap(), + Calendar::ISO, + provider, + ) + .unwrap(); + + assert_eq!(zdt_plus_eleven.year(), 2023); + assert_eq!(zdt_plus_eleven.month(), 11); + assert_eq!(zdt_plus_eleven.day(), 30); + assert_eq!(zdt_plus_eleven.hour(), 12); + assert_eq!(zdt_plus_eleven.minute(), 49); + assert_eq!(zdt_plus_eleven.second(), 12); + }) +} + +#[test] +// https://tc39.es/proposal-temporal/docs/zoneddatetime.html#round +fn round_with_provider_test() { + test_all_providers!(provider: { + let dt = b"1995-12-07T03:24:30.000003500-08:00[America/Los_Angeles]"; + let zdt = ZonedDateTime::from_utf8_with_provider( + dt, + Disambiguation::default(), + OffsetDisambiguation::Use, + provider, + ) + .unwrap(); + + let result = zdt + .round_with_provider( + RoundingOptions { + smallest_unit: Some(Unit::Hour), + ..Default::default() + }, + provider, + ) + .unwrap(); + assert_eq!( + result.to_string_with_provider(provider).unwrap(), + "1995-12-07T03:00:00-08:00[America/Los_Angeles]" + ); + + let result = zdt + .round_with_provider( + RoundingOptions { + smallest_unit: Some(Unit::Minute), + increment: Some((RoundingIncrement::try_new(30)).unwrap()), + ..Default::default() + }, + provider, + ) + .unwrap(); + assert_eq!( + result.to_string_with_provider(provider).unwrap(), + "1995-12-07T03:30:00-08:00[America/Los_Angeles]" + ); + + let result = zdt + .round_with_provider( + RoundingOptions { + smallest_unit: Some(Unit::Minute), + increment: Some((RoundingIncrement::try_new(30)).unwrap()), + rounding_mode: Some(RoundingMode::Floor), + ..Default::default() + }, + provider, + ) + .unwrap(); + assert_eq!( + result.to_string_with_provider(provider).unwrap(), + "1995-12-07T03:00:00-08:00[America/Los_Angeles]" + ); + }) +} + +#[test] +fn zdt_from_partial() { + test_all_providers!(provider: { + let fields = ZonedDateTimeFields { + calendar_fields: CalendarFields::new() + .with_year(1970) + .with_month_code(MonthCode(tinystr!(4, "M01"))) + .with_day(1), + time: Default::default(), + offset: None, + }; + let partial = PartialZonedDateTime { + fields, + timezone: Some(TimeZone::utc_with_provider(provider)), + calendar: Calendar::ISO, + }; + + let result = ZonedDateTime::from_partial_with_provider(partial, None, None, None, provider); + assert!(result.is_ok()); + + // This ensures that the start-of-day branch isn't hit by default time + let fields = ZonedDateTimeFields { + calendar_fields: CalendarFields::new() + .with_year(1970) + .with_month_code(MonthCode(tinystr!(4, "M01"))) + .with_day(1), + time: PartialTime::default(), + offset: Some(UtcOffset::from_minutes(30)), + }; + let partial = PartialZonedDateTime { + fields, + timezone: Some(TimeZone::utc_with_provider(provider)), + calendar: Calendar::ISO, + }; + + let result = ZonedDateTime::from_partial_with_provider( + partial, + None, + None, + Some(OffsetDisambiguation::Use), + provider, + ); + assert!(result.is_ok()); + }) +} + +#[test] +fn zdt_from_str() { + test_all_providers!(provider: { + let zdt_str = b"1970-01-01T00:00[UTC][u-ca=iso8601]"; + let result = ZonedDateTime::from_utf8_with_provider( + zdt_str, + Disambiguation::Compatible, + OffsetDisambiguation::Reject, + provider, + ); + assert!(result.is_ok()); + }) +} + +#[test] +fn zdt_hours_in_day() { + test_all_providers!(provider: { + let result = + parse_zdt_with_reject("2025-07-04T12:00[UTC][u-ca=iso8601]", provider).unwrap(); + + assert_eq!(result.hours_in_day_with_provider(provider).unwrap(), 24.) + }) +} + +#[test] +// https://github.com/tc39/test262/blob/d9b10790bc4bb5b3e1aa895f11cbd2d31a5ec743/test/intl402/Temporal/ZonedDateTime/from/dst-skipped-cross-midnight.js +fn dst_skipped_cross_midnight() { + test_all_providers!(provider: { + let start_of_day = + parse_zdt_with_compatible("1919-03-31[America/Toronto]", provider).unwrap(); + let midnight_disambiguated = + parse_zdt_with_compatible("1919-03-31T00[America/Toronto]", provider).unwrap(); + + assert_eq!( + start_of_day.epoch_nanoseconds(), + &EpochNanoseconds(-1601753400000000000) + ); + assert_eq!( + midnight_disambiguated.epoch_nanoseconds(), + &EpochNanoseconds(-1601751600000000000) + ); + let diff = start_of_day + .instant + .until( + &midnight_disambiguated.instant, + DifferenceSettings { + largest_unit: Some(Unit::Hour), + smallest_unit: Some(Unit::Nanosecond), + ..Default::default() + }, + ) + .unwrap(); + assert_eq!(diff.years(), 0); + assert_eq!(diff.months(), 0); + assert_eq!(diff.weeks(), 0); + assert_eq!(diff.days(), 0); + assert_eq!(diff.hours(), 0); + assert_eq!(diff.minutes(), 30); + assert_eq!(diff.seconds(), 0); + assert_eq!(diff.milliseconds(), 0); + assert_eq!(diff.microseconds(), 0); + assert_eq!(diff.nanoseconds(), 0); + }); +} + +#[test] +fn zdt_offset_match_minutes() { + // Cases taken from intl402/Temporal/ZonedDateTime/compare/sub-minute-offset + + test_all_providers!(provider: { + // Rounded mm accepted + let _ = parse_zdt_with_reject("1970-01-01T00:00-00:45[Africa/Monrovia]", provider).unwrap(); + // unrounded mm::ss accepted + let _ = parse_zdt_with_reject("1970-01-01T00:00:00-00:44:30[Africa/Monrovia]", provider) + .unwrap(); + assert!( + parse_zdt_with_compatible("1970-01-01T00:00:00-00:44:40[Africa/Monrovia]", provider) + .is_err(), + "Incorrect unrounded mm::ss rejected" + ); + assert!( + parse_zdt_with_compatible("1970-01-01T00:00:00-00:45:00[Africa/Monrovia]", provider) + .is_err(), + "Rounded mm::ss rejected" + ); + assert!( + parse_zdt_with_compatible("1970-01-01T00:00+00:44:30.123456789[+00:45]", provider) + .is_err(), + "Rounding not accepted between ISO offset and timezone" + ); + + assert!( + ZonedDateTime::from_partial_with_provider( + PartialZonedDateTime { + fields: ZonedDateTimeFields { + calendar_fields: CalendarFields::new() + .with_year(1970) + .with_month_code(MonthCode(tinystr!(4, "M01"))) + .with_day(1), + time: PartialTime::default(), + offset: Some(UtcOffset::from_minutes(30)), + }, + timezone: Some(TimeZone::try_from_identifier_str_with_provider("Africa/Monrovia", provider).unwrap()), + ..PartialZonedDateTime::default() + }, + None, + None, + None, + provider + ) + .is_err(), + "Rounding not accepted between ISO offset and timezone" + ); + }) +} + +// overflow-reject-throws.js +#[test] +fn overflow_reject_throws() { + test_all_providers!(provider: { + let zdt = ZonedDateTime::try_new_with_provider( + 217178610123456789, + TimeZone::utc_with_provider(provider), + Calendar::default(), + provider, + ) + .unwrap(); + + let overflow = Overflow::Reject; + + let result_1 = zdt.with_with_provider( + ZonedDateTimeFields { + calendar_fields: CalendarFields::new().with_month(29), + time: Default::default(), + offset: None, + }, + None, + None, + Some(overflow), + provider, + ); + + let result_2 = zdt.with_with_provider( + ZonedDateTimeFields { + calendar_fields: CalendarFields::new().with_day(31), + time: Default::default(), + offset: None, + }, + None, + None, + Some(overflow), + provider, + ); + + let result_3 = zdt.with_with_provider( + ZonedDateTimeFields { + calendar_fields: CalendarFields::new(), + time: PartialTime { + hour: Some(29), + ..Default::default() + }, + offset: None, + }, + None, + None, + Some(overflow), + provider, + ); + + let result_4 = zdt.with_with_provider( + ZonedDateTimeFields { + calendar_fields: CalendarFields::default(), + time: PartialTime { + nanosecond: Some(9000), + ..Default::default() + }, + offset: None, + }, + None, + None, + Some(overflow), + provider, + ); + + assert!(result_1.is_err()); + assert!(result_2.is_err()); + assert!(result_3.is_err()); + assert!(result_4.is_err()); + }) +} + +#[test] +fn static_tzdb_zdt_test() { + test_all_providers!(#[cfg_for_fs(not(target_os = "windows"))] provider: { + use crate::{Calendar, TimeZone}; + use core::str::FromStr; + + let nov_30_2023_utc = 1_701_308_952_000_000_000i128; + + let zdt = ZonedDateTime::try_new_with_provider( + nov_30_2023_utc, + TimeZone::try_from_str_with_provider("UTC", provider).unwrap(), + Calendar::from_str("iso8601").unwrap(), + provider, + ) + .unwrap(); + + assert_eq!(zdt.year(), 2023); + assert_eq!(zdt.month(), 11); + assert_eq!(zdt.day(), 30); + assert_eq!(zdt.hour(), 1); + assert_eq!(zdt.minute(), 49); + assert_eq!(zdt.second(), 12); + + let zdt_minus_five = ZonedDateTime::try_new_with_provider( + nov_30_2023_utc, + TimeZone::try_from_str_with_provider("America/New_York", provider).unwrap(), + Calendar::from_str("iso8601").unwrap(), + provider, + ) + .unwrap(); + + assert_eq!(zdt_minus_five.year(), 2023); + assert_eq!(zdt_minus_five.month(), 11); + assert_eq!(zdt_minus_five.day(), 29); + assert_eq!(zdt_minus_five.hour(), 20); + assert_eq!(zdt_minus_five.minute(), 49); + assert_eq!(zdt_minus_five.second(), 12); + + let zdt_plus_eleven = ZonedDateTime::try_new_with_provider( + nov_30_2023_utc, + TimeZone::try_from_str_with_provider("Australia/Sydney", provider).unwrap(), + Calendar::from_str("iso8601").unwrap(), + provider, + ) + .unwrap(); + + assert_eq!(zdt_plus_eleven.year(), 2023); + assert_eq!(zdt_plus_eleven.month(), 11); + assert_eq!(zdt_plus_eleven.day(), 30); + assert_eq!(zdt_plus_eleven.hour(), 12); + assert_eq!(zdt_plus_eleven.minute(), 49); + assert_eq!(zdt_plus_eleven.second(), 12); + }) +} + +#[test] +fn basic_zdt_add() { + use crate::{Calendar, Duration, TimeZone}; + test_all_providers!(#[cfg_for_fs(not(target_os = "windows"))] provider: { + let zdt = ZonedDateTime::try_new_with_provider( + -560174321098766, + TimeZone::utc_with_provider(provider), + Calendar::default(), + provider, + ) + .unwrap(); + let d = Duration::new( + 0.into(), + 0.into(), + 0.into(), + 0.into(), + 240.into(), + 0.into(), + 0.into(), + 0.into(), + 0.into(), + 800.into(), + ) + .unwrap(); + // "1970-01-04T12:23:45.678902034+00:00[UTC]" + let expected = ZonedDateTime::try_new_with_provider( + 303825678902034, + TimeZone::utc_with_provider(provider), + Calendar::default(), + provider, + ) + .unwrap(); + + let result = zdt.add_with_provider(&d, None, provider).unwrap(); + assert!(result.equals_with_provider(&expected, provider).unwrap()); + }) +} + +fn parse_zdt_with_reject( + s: &str, + provider: &impl TimeZoneProvider, +) -> TemporalResult { + ZonedDateTime::from_utf8_with_provider( + s.as_bytes(), + Disambiguation::Reject, + OffsetDisambiguation::Reject, + provider, + ) +} + +fn parse_zdt_with_compatible( + s: &str, + provider: &impl TimeZoneProvider, +) -> TemporalResult { + ZonedDateTime::from_utf8_with_provider( + s.as_bytes(), + Disambiguation::Compatible, + OffsetDisambiguation::Reject, + provider, + ) +} + +#[test] +fn test_pacific_niue() { + test_all_providers!(provider: { + // test/intl402/Temporal/ZonedDateTime/compare/sub-minute-offset.js + // Pacific/Niue on October 15, 1952, where + // the offset shifted by 20 seconds to a whole-minute boundary. + // + // The precise transition is from + // 1952-10-15T23:59:59-11:19:40[-11:19:40] to 1952-10-15T23:59:40-11:19:00[-11:19:00] + let ms_pre = -543_069_621_000; + let zdt = + parse_zdt_with_reject("1952-10-15T23:59:59-11:19:40[Pacific/Niue]", provider).unwrap(); + assert_eq!( + zdt.epoch_milliseconds(), + ms_pre, + "-11:19:40 is accepted as -11:19:40 in Pacific/Niue edge case" + ); + + let zdt = + parse_zdt_with_reject("1952-10-15T23:59:59-11:20[Pacific/Niue]", provider).unwrap(); + assert_eq!( + zdt.epoch_milliseconds(), + ms_pre, + "-11:20 matches the first candidate -11:19:40 in the Pacific/Niue edge case" + ); + + let ms_post = -543_069_601_000; + + let zdt = + parse_zdt_with_reject("1952-10-15T23:59:59-11:20:00[Pacific/Niue]", provider).unwrap(); + assert_eq!( + zdt.epoch_milliseconds(), + ms_post, + "-11:19:40 is accepted as -11:19:40 in Pacific/Niue edge case" + ); + + // Additional tests ensuring that boundary cases are handled + + let zdt = + parse_zdt_with_reject("1952-10-15T23:59:40-11:20:00[Pacific/Niue]", provider).unwrap(); + assert_eq!( + zdt.epoch_milliseconds(), + ms_post - 19_000, + "Post-transition Niue time allows up to `1952-10-15T23:59:40`" + ); + let zdt = parse_zdt_with_reject("1952-10-15T23:59:39-11:20:00[Pacific/Niue]", provider); + assert!( + zdt.is_err(), + "Post-transition Niue time does not allow times before `1952-10-15T23:59:40`" + ); + + let zdt = + parse_zdt_with_reject("1952-10-15T23:59:40-11:19:40[Pacific/Niue]", provider).unwrap(); + assert_eq!( + zdt.epoch_milliseconds(), + ms_pre - 19_000, + "Pre-transition Niue time also allows `1952-10-15T23:59:40`" + ); + + let zdt = + parse_zdt_with_reject("1952-10-15T23:59:39-11:19:40[Pacific/Niue]", provider).unwrap(); + assert_eq!( + zdt.epoch_milliseconds(), + ms_pre - 20_000, + "Pre-transition Niue time also allows `1952-10-15T23:59:39`" + ); + + // Tests without explicit offset + let zdt = parse_zdt_with_reject("1952-10-15T23:59:39[Pacific/Niue]", provider).unwrap(); + assert_eq!( + zdt.epoch_milliseconds(), + ms_pre - 20_000, + "Unambiguous before 1952-10-15T23:59:39" + ); + + let zdt = parse_zdt_with_reject("1952-10-16T00:00:00[Pacific/Niue]", provider).unwrap(); + assert_eq!( + zdt.epoch_milliseconds(), + ms_post + 1_000, + "Unambiguous after 1952-10-16T00:00:00" + ); + + let zdt = parse_zdt_with_reject("1952-10-15T23:59:40[Pacific/Niue]", provider); + assert!(zdt.is_err(), "Ambiguity starts at 1952-10-15T23:59:40"); + let zdt = parse_zdt_with_reject("1952-10-15T23:59:59[Pacific/Niue]", provider); + assert!(zdt.is_err(), "Ambiguity ends at 1952-10-15T23:59:59"); + }) +} + +fn total_seconds_for_one_day(s: &str, provider: &impl TimeZoneProvider) -> TemporalResult { + Ok(Duration::new(0, 0, 0, 1, 0, 0, 0, 0, 0, 0) + .unwrap() + .total_with_provider( + Unit::Second, + Some(parse_zdt_with_reject(s, provider).unwrap().into()), + provider, + )? + .as_inner()) +} + +#[test] +fn test_pacific_niue_duration() { + test_all_providers!(provider: { + // Also tests add_to_instant codepaths + // From intl402/Temporal/Duration/prototype/total/relativeto-sub-minute-offset + let total = + total_seconds_for_one_day("1952-10-15T23:59:59-11:19:40[Pacific/Niue]", provider) + .unwrap(); + assert_eq!( + total, 86420., + "-11:19:40 is accepted as -11:19:40 in Pacific/Niue edge case" + ); + + let total = + total_seconds_for_one_day("1952-10-15T23:59:59-11:20[Pacific/Niue]", provider).unwrap(); + assert_eq!( + total, 86420., + "-11:20 matches the first candidate -11:19:40 in the Pacific/Niue edge case" + ); + + let total = + total_seconds_for_one_day("1952-10-15T23:59:59-11:20:00[Pacific/Niue]", provider) + .unwrap(); + assert_eq!( + total, 86400., + "-11:20:00 is accepted as -11:20:00 in the Pacific/Niue edge case" + ); + }) +} + +#[track_caller] +fn assert_tr( + zdt: &ZonedDateTime, + direction: TransitionDirection, + s: &str, + provider: &impl TimeZoneProvider, +) { + assert_eq!( + zdt.get_time_zone_transition_with_provider(direction, provider) + .unwrap() + .unwrap() + .to_string_with_provider(provider) + .unwrap(), + s + ); +} + +// Modern dates + +// Transitions +const DST_2025_03_09: &str = "2025-03-09T03:00:00-07:00[America/Los_Angeles]"; +const DST_2026_03_08: &str = "2026-03-08T03:00:00-07:00[America/Los_Angeles]"; +const STD_2025_11_02: &str = "2025-11-02T01:00:00-08:00[America/Los_Angeles]"; +const STD_2024_11_03: &str = "2024-11-03T01:00:00-08:00[America/Los_Angeles]"; + +// Non transitions +const IN_DST_2025_07_31: &str = "2025-07-31T00:00:00-07:00[America/Los_Angeles]"; +const AFTER_DST_2025_12_31: &str = "2025-12-31T00:00:00-08:00[America/Los_Angeles]"; +const BEFORE_DST_2025_01_31: &str = "2025-01-31T00:00:00-08:00[America/Los_Angeles]"; + +// Transition dates ± 1 +const DST_2025_03_09_PLUS_ONE: &str = "2025-03-09T03:00:00.000000001-07:00[America/Los_Angeles]"; +const DST_2025_03_09_MINUS_ONE: &str = "2025-03-09T01:59:59.999999999-08:00[America/Los_Angeles]"; +const STD_2025_11_02_PLUS_ONE: &str = "2025-11-02T01:00:00.000000001-08:00[America/Los_Angeles]"; +const STD_2025_11_02_MINUS_ONE: &str = "2025-11-02T01:59:59.999999999-07:00[America/Los_Angeles]"; + +// Dates from the tzif data block +// Transitions +const DST_1999_04_04: &str = "1999-04-04T03:00:00-07:00[America/Los_Angeles]"; +const DST_2000_04_02: &str = "2000-04-02T03:00:00-07:00[America/Los_Angeles]"; +const STD_1999_10_31: &str = "1999-10-31T01:00:00-08:00[America/Los_Angeles]"; +const STD_1998_01_31: &str = "1998-10-25T01:00:00-08:00[America/Los_Angeles]"; + +// Non transitions +const IN_DST_1999_07_31: &str = "1999-07-31T00:00:00-07:00[America/Los_Angeles]"; +const AFTER_DST_1999_12_31: &str = "1999-12-31T00:00:00-08:00[America/Los_Angeles]"; +const BEFORE_DST_1999_01_31: &str = "1999-01-31T00:00:00-08:00[America/Los_Angeles]"; + +const LONDON_TRANSITION_1968_02_18: &str = "1968-02-18T03:00:00+01:00[Europe/London]"; +const LONDON_TRANSITION_1968_02_18_MINUS_ONE: &str = + "1968-02-18T01:59:59.999999999+00:00[Europe/London]"; + +const SAMOA_IDL_CHANGE: &str = "2011-12-31T00:00:00+14:00[Pacific/Apia]"; +const SAMOA_IDL_CHANGE_MINUS_ONE: &str = "2011-12-29T23:59:59.999999999-10:00[Pacific/Apia]"; + +// This date is a fifth Sunday +const LONDON_POSIX_TRANSITION_2019_03_31_MINUS_ONE: &str = + "2019-03-31T00:59:59.999999999+00:00[Europe/London]"; +const LONDON_POSIX_TRANSITION_2019_03_31: &str = "2019-03-31T02:00:00+01:00[Europe/London]"; + +// This date is a fourth (but last) Sunday +const LONDON_POSIX_TRANSITION_2017_03_26_MINUS_ONE: &str = + "2017-03-26T00:59:59.999999999+00:00[Europe/London]"; +const LONDON_POSIX_TRANSITION_2017_03_26: &str = "2017-03-26T02:00:00+01:00[Europe/London]"; + +const TROLL_FIRST_TRANSITION: &str = "2005-03-27T03:00:00+02:00[Antarctica/Troll]"; + +/// Vancouver transitions on the first Sunday in November, which may or may not be +/// before the first Friday in November +const VANCOUVER_FIRST_FRIDAY_IN_NOVEMBER_BEFORE_SUNDAY: &str = + "2019-11-01T00:00:00-07:00[America/Vancouver]"; +const VANCOUVER_FIRST_FRIDAY_IN_NOVEMBER_AFTER_SUNDAY: &str = + "2019-11-06T00:00:00-08:00[America/Vancouver]"; + +/// Chile tzdb has a transition on the "first saturday in april", except the transition occurs +/// at 24:00:00, which is, of course, the day after. This is not the same thing as the first Sunday in April +const SANTIAGO_DST_2024: &str = "2024-09-08T01:00:00-03:00[America/Santiago]"; +const SANTIAGO_STD_2025_APRIL: &str = "2025-04-05T23:00:00-04:00[America/Santiago]"; +const SANTIAGO_STD_2025_APRIL_PLUS_ONE: &str = + "2025-04-05T23:00:00.000000001-04:00[America/Santiago]"; +const SANTIAGO_STD_2025_APRIL_MINUS_ONE: &str = + "2025-04-05T23:59:59.999999999-03:00[America/Santiago]"; +const SANTIAGO_DST_2025_SEPT: &str = "2025-09-07T01:00:00-03:00[America/Santiago]"; +const SANTIAGO_DST_2025_SEPT_PLUS_ONE: &str = + "2025-09-07T01:00:00.000000001-03:00[America/Santiago]"; +const SANTIAGO_DST_2025_SEPT_MINUS_ONE: &str = + "2025-09-06T23:59:59.999999999-04:00[America/Santiago]"; +const SANTIAGO_STD_2026: &str = "2026-04-04T23:00:00-04:00[America/Santiago]"; + +// MUST only contain full strings +// The second boolean is whether these are unambiguous when the offset is removed +// As a rule of thumb, anything around an STD->DST transition +// will be unambiguous, but DST->STD will not +const TO_STRING_TESTCASES: &[(&str, bool)] = &[ + (DST_2025_03_09, true), + (DST_2026_03_08, true), + (STD_2025_11_02, false), + (STD_2024_11_03, false), + (IN_DST_2025_07_31, true), + (AFTER_DST_2025_12_31, true), + (BEFORE_DST_2025_01_31, true), + (DST_2025_03_09_PLUS_ONE, true), + (DST_2025_03_09_MINUS_ONE, true), + (STD_2025_11_02_PLUS_ONE, false), + (STD_2025_11_02_MINUS_ONE, false), + (DST_1999_04_04, true), + (DST_2000_04_02, true), + (STD_1999_10_31, false), + (STD_1998_01_31, false), + (IN_DST_1999_07_31, true), + (AFTER_DST_1999_12_31, true), + (BEFORE_DST_1999_01_31, true), + (LONDON_TRANSITION_1968_02_18, true), + (LONDON_TRANSITION_1968_02_18_MINUS_ONE, true), + (SAMOA_IDL_CHANGE, true), + (SAMOA_IDL_CHANGE_MINUS_ONE, true), + (LONDON_POSIX_TRANSITION_2019_03_31_MINUS_ONE, true), + (LONDON_POSIX_TRANSITION_2019_03_31, true), + (LONDON_POSIX_TRANSITION_2017_03_26_MINUS_ONE, true), + (LONDON_POSIX_TRANSITION_2017_03_26_MINUS_ONE, true), + (TROLL_FIRST_TRANSITION, true), + (VANCOUVER_FIRST_FRIDAY_IN_NOVEMBER_BEFORE_SUNDAY, true), + (VANCOUVER_FIRST_FRIDAY_IN_NOVEMBER_AFTER_SUNDAY, true), + (SANTIAGO_DST_2024, true), + (SANTIAGO_STD_2025_APRIL, false), + (SANTIAGO_STD_2025_APRIL_PLUS_ONE, false), + (SANTIAGO_STD_2025_APRIL_MINUS_ONE, false), + (SANTIAGO_DST_2025_SEPT, true), + (SANTIAGO_DST_2025_SEPT_PLUS_ONE, true), + (SANTIAGO_DST_2025_SEPT_MINUS_ONE, true), + (SANTIAGO_STD_2026, false), +]; + +#[test] +fn get_time_zone_transition() { + // This stops it from wrapping + use TransitionDirection::*; + + test_all_providers!(provider: { + // Modern dates that utilize the posix string + + // During DST + let zdt = parse_zdt_with_reject(IN_DST_2025_07_31, provider).unwrap(); + assert_tr(&zdt, Previous, DST_2025_03_09, provider); + assert_tr(&zdt, Next, STD_2025_11_02, provider); + + // After DST + let zdt = parse_zdt_with_reject(AFTER_DST_2025_12_31, provider).unwrap(); + assert_tr(&zdt, Previous, STD_2025_11_02, provider); + assert_tr(&zdt, Next, DST_2026_03_08, provider); + + // Before DST + let zdt = parse_zdt_with_reject(BEFORE_DST_2025_01_31, provider).unwrap(); + assert_tr(&zdt, Previous, STD_2024_11_03, provider); + assert_tr(&zdt, Next, DST_2025_03_09, provider); + + // Boundary test + // Modern date (On start of DST) + let zdt = parse_zdt_with_reject(DST_2025_03_09, provider).unwrap(); + assert_tr(&zdt, Previous, STD_2024_11_03, provider); + assert_tr(&zdt, Next, STD_2025_11_02, provider); + // Modern date (one ns after DST) + let zdt = parse_zdt_with_reject(DST_2025_03_09_PLUS_ONE, provider).unwrap(); + assert_tr(&zdt, Previous, DST_2025_03_09, provider); + assert_tr(&zdt, Next, STD_2025_11_02, provider); + // Modern date (one ns before DST) + let zdt = parse_zdt_with_reject(DST_2025_03_09_MINUS_ONE, provider).unwrap(); + assert_tr(&zdt, Previous, STD_2024_11_03, provider); + assert_tr(&zdt, Next, DST_2025_03_09, provider); + + // Modern date (On start of STD) + let zdt = parse_zdt_with_reject(STD_2025_11_02, provider).unwrap(); + assert_tr(&zdt, Previous, DST_2025_03_09, provider); + assert_tr(&zdt, Next, DST_2026_03_08, provider); + // Modern date (one ns after STD) + let zdt = parse_zdt_with_reject(STD_2025_11_02_PLUS_ONE, provider).unwrap(); + assert_tr(&zdt, Previous, STD_2025_11_02, provider); + assert_tr(&zdt, Next, DST_2026_03_08, provider); + // Modern date (one ns before STD) + let zdt = parse_zdt_with_reject(STD_2025_11_02_MINUS_ONE, provider).unwrap(); + assert_tr(&zdt, Previous, DST_2025_03_09, provider); + assert_tr(&zdt, Next, STD_2025_11_02, provider); + + // Old dates using the Tzif data + + // During DST + let zdt = parse_zdt_with_reject(IN_DST_1999_07_31, provider).unwrap(); + assert_tr(&zdt, Previous, DST_1999_04_04, provider); + assert_tr(&zdt, Next, STD_1999_10_31, provider); + + // After DST + let zdt = parse_zdt_with_reject(AFTER_DST_1999_12_31, provider).unwrap(); + assert_tr(&zdt, Previous, STD_1999_10_31, provider); + assert_tr(&zdt, Next, DST_2000_04_02, provider); + + // Before DST + let zdt = parse_zdt_with_reject(BEFORE_DST_1999_01_31, provider).unwrap(); + assert_tr(&zdt, Previous, STD_1998_01_31, provider); + assert_tr(&zdt, Next, DST_1999_04_04, provider); + + // Santiago tests, testing that transitions with the offset = 24:00:00 + // still work + let zdt = parse_zdt_with_reject(SANTIAGO_DST_2025_SEPT_MINUS_ONE, provider).unwrap(); + assert_tr(&zdt, Previous, SANTIAGO_STD_2025_APRIL, provider); + assert_tr(&zdt, Next, SANTIAGO_DST_2025_SEPT, provider); + let zdt = parse_zdt_with_reject(SANTIAGO_DST_2025_SEPT, provider).unwrap(); + assert_tr(&zdt, Previous, SANTIAGO_STD_2025_APRIL, provider); + assert_tr(&zdt, Next, SANTIAGO_STD_2026, provider); + let zdt = parse_zdt_with_reject(SANTIAGO_DST_2025_SEPT_PLUS_ONE, provider).unwrap(); + assert_tr(&zdt, Previous, SANTIAGO_DST_2025_SEPT, provider); + assert_tr(&zdt, Next, SANTIAGO_STD_2026, provider); + + let zdt = parse_zdt_with_reject(SANTIAGO_STD_2025_APRIL_MINUS_ONE, provider).unwrap(); + assert_tr(&zdt, Previous, SANTIAGO_DST_2024, provider); + assert_tr(&zdt, Next, SANTIAGO_STD_2025_APRIL, provider); + let zdt = parse_zdt_with_reject(SANTIAGO_STD_2025_APRIL, provider).unwrap(); + assert_tr(&zdt, Previous, SANTIAGO_DST_2024, provider); + assert_tr(&zdt, Next, SANTIAGO_DST_2025_SEPT, provider); + let zdt = parse_zdt_with_reject(SANTIAGO_STD_2025_APRIL_PLUS_ONE, provider).unwrap(); + assert_tr(&zdt, Previous, SANTIAGO_STD_2025_APRIL, provider); + assert_tr(&zdt, Next, SANTIAGO_DST_2025_SEPT, provider); + + // Test case from intl402/Temporal/ZonedDateTime/prototype/getTimeZoneTransition/rule-change-without-offset-transition + // This ensures we skip "fake" transition entries that do not actually change the offset + + let zdt = + parse_zdt_with_reject("1970-01-01T01:00:00+01:00[Europe/London]", provider).unwrap(); + assert_tr(&zdt, Previous, LONDON_TRANSITION_1968_02_18, provider); + let zdt = + parse_zdt_with_reject("1968-10-01T00:00:00+01:00[Europe/London]", provider).unwrap(); + assert_tr( + &zdt, + Next, + "1971-10-31T02:00:00+00:00[Europe/London]", + provider, + ); + let zdt = parse_zdt_with_reject("1967-05-01T00:00:00-10:00[America/Anchorage]", provider) + .unwrap(); + assert_tr( + &zdt, + Previous, + "1945-09-30T01:00:00-10:00[America/Anchorage]", + provider, + ); + let zdt = parse_zdt_with_reject("1967-01-01T00:00:00-10:00[America/Anchorage]", provider) + .unwrap(); + assert_tr( + &zdt, + Next, + "1969-04-27T03:00:00-09:00[America/Anchorage]", + provider, + ); + // These dates are one second after a "fake" transition at the end of the tzif data + // Ensure that they find a real transition, not the fake one + let zdt = parse_zdt_with_reject("2020-11-01T00:00:01-07:00[America/Whitehorse]", provider) + .unwrap(); + assert_tr( + &zdt, + Previous, + "2020-03-08T03:00:00-07:00[America/Whitehorse]", + provider, + ); + + let zdt = + parse_zdt_with_reject("1996-05-13T00:00:01+03:00[Europe/Kyiv]", provider).unwrap(); + assert_tr( + &zdt, + Previous, + "1996-03-31T03:00:00+03:00[Europe/Kyiv]", + provider, + ); + + // This ensures that nanosecond-to-second casting works correctly + let zdt = parse_zdt_with_reject(LONDON_TRANSITION_1968_02_18_MINUS_ONE, provider).unwrap(); + assert_tr(&zdt, Next, LONDON_TRANSITION_1968_02_18, provider); + assert_tr( + &zdt, + Previous, + "1967-10-29T02:00:00+00:00[Europe/London]", + provider, + ); + }) +} + +#[test] +fn test_to_string_roundtrip() { + test_all_providers!(provider: { + for (test, is_unambiguous) in TO_STRING_TESTCASES { + let zdt = parse_zdt_with_reject(test, provider).expect(test); + let string = zdt.to_string_with_provider(provider).unwrap(); + + assert_eq!( + *test, &*string, + "ZonedDateTime {test} round trips on ToString" + ); + let without_offset = zdt + .to_ixdtf_string_with_provider( + DisplayOffset::Never, + DisplayTimeZone::Auto, + DisplayCalendar::Never, + Default::default(), + provider + ) + .unwrap(); + assert_eq!( + without_offset[0..19], + test[0..19], + "Stringified object should have same date part" + ); + + // These testcases should all also parse unambiguously when the offset is removed. + if *is_unambiguous { + let zdt = parse_zdt_with_reject(&without_offset, provider).expect(test); + let string = zdt.to_string_with_provider(provider).unwrap(); + assert_eq!( + *test, &*string, + "ZonedDateTime {without_offset} round trips to {test} on ToString" + ); + } + } + }); +} + +#[test] +fn test_apia() { + test_all_providers!(provider: { + // This transition skips an entire day + // From: 2011-12-29T23:59:59.999999999-10:00[Pacific/Apia] + // To: 2011-12-31T00:00:00+14:00[Pacific/Apia] + let zdt = parse_zdt_with_reject(SAMOA_IDL_CHANGE, provider).unwrap(); + let _ = zdt + .add_with_provider(&Duration::new(0, 0, 0, 1, 1, 0, 0, 0, 0, 0).unwrap(), None, provider) + .unwrap(); + + assert_eq!(zdt.hours_in_day_with_provider(provider).unwrap(), 24.); + + let samoa_before = parse_zdt_with_reject(SAMOA_IDL_CHANGE_MINUS_ONE, provider).unwrap(); + assert_eq!(samoa_before.hours_in_day_with_provider(provider).unwrap(), 24.); + }) +} + +#[test] +fn test_london() { + test_all_providers!(provider: { + // Europe/London has an MWD transition where the transitions are on the + // last sundays of March and October. + + // Test that they correctly compute from nanoseconds + let zdt = ZonedDateTime::try_new_with_provider( + 1_553_993_999_999_999_999, + TimeZone::try_from_str_with_provider("Europe/London", provider).unwrap(), + Calendar::ISO, + provider, + ) + .unwrap(); + assert_eq!( + zdt.to_string_with_provider(provider).unwrap(), + LONDON_POSIX_TRANSITION_2019_03_31_MINUS_ONE, + ); + let zdt = ZonedDateTime::try_new_with_provider( + 1_553_994_000_000_000_000, + TimeZone::try_from_str_with_provider("Europe/London", provider).unwrap(), + Calendar::ISO, + provider, + ) + .unwrap(); + assert_eq!(zdt.to_string_with_provider(provider).unwrap(), LONDON_POSIX_TRANSITION_2019_03_31,); + + // Test that they correctly compute from ZDT strings without explicit offset + let zdt = parse_zdt_with_reject("2019-03-31T00:59:59.999999999[Europe/London]", provider) + .unwrap(); + assert_eq!( + zdt.to_string_with_provider(provider).unwrap(), + LONDON_POSIX_TRANSITION_2019_03_31_MINUS_ONE + ); + + let zdt = + parse_zdt_with_reject("2019-03-31T02:00:00+01:00[Europe/London]", provider).unwrap(); + assert_eq!(zdt.to_string_with_provider(provider).unwrap(), LONDON_POSIX_TRANSITION_2019_03_31); + + let zdt = parse_zdt_with_reject("2017-03-26T00:59:59.999999999[Europe/London]", provider) + .unwrap(); + assert_eq!( + zdt.to_string_with_provider(provider).unwrap(), + LONDON_POSIX_TRANSITION_2017_03_26_MINUS_ONE + ); + + let zdt = + parse_zdt_with_reject("2017-03-26T02:00:00+01:00[Europe/London]", provider).unwrap(); + assert_eq!(zdt.to_string_with_provider(provider).unwrap(), LONDON_POSIX_TRANSITION_2017_03_26); + }) +} + +#[test] +fn test_berlin() { + test_all_providers!(provider: { + // Need to ensure that when the transition is the last day of the month it still works + let zdt = parse_zdt_with_reject("2021-03-28T01:00:00Z[Europe/Berlin]", provider).unwrap(); + let prev = zdt + .get_time_zone_transition_with_provider(TransitionDirection::Previous, provider) + .unwrap() + .unwrap(); + + assert_eq!(prev.to_string_with_provider(provider).unwrap(), "2020-10-25T02:00:00+01:00[Europe/Berlin]"); + }) +} + +#[test] +fn test_troll() { + test_all_providers!(provider: { + // Antarctica/Troll started DST in 2005, but had no other transitions before that + let zdt = ZonedDateTime::try_new_with_provider( + 0, + TimeZone::try_from_str_with_provider("Antarctica/Troll", provider).unwrap(), + Calendar::ISO, + provider, + ) + .unwrap(); + + let next = zdt + .get_time_zone_transition_with_provider(TransitionDirection::Next, provider) + .unwrap() + .unwrap(); + assert_eq!(next.to_string_with_provider(provider).unwrap(), TROLL_FIRST_TRANSITION); + }) +} + +#[test] +fn test_zdt_until_rounding() { + test_all_providers!(provider: { + // Regression test for beyondDaySpan rounding behavior + let start = parse_zdt_with_reject("2020-01-01T00:00-08:00[-08:00]", provider).unwrap(); + let end = parse_zdt_with_reject("2020-01-03T23:59-08:00[-08:00]", provider).unwrap(); + let difference = start + .until_with_provider( + &end, + DifferenceSettings { + largest_unit: Some(Unit::Day), + smallest_unit: Some(Unit::Hour), + rounding_mode: Some(RoundingMode::HalfExpand), + ..Default::default() + }, + provider + ) + .unwrap(); + assert_eq!(difference.to_string(), "P3D"); + }) +} + +#[test] +fn test_toronto_half_hour() { + test_all_providers!(provider: { + let zdt = + parse_zdt_with_reject("1919-03-30T12:00:00-05:00[America/Toronto]", provider).unwrap(); + assert_eq!(zdt.hours_in_day_with_provider(provider).unwrap(), 23.5); + }) +} + +#[test] +fn test_round_to_start_of_day() { + test_all_providers!(provider: { + // Round up to DST + let zdt = + parse_zdt_with_reject("1919-03-30T11:45-05:00[America/Toronto]", provider).unwrap(); + let rounded = zdt + .round_with_provider(RoundingOptions { + smallest_unit: Some(Unit::Day), + ..Default::default() + }, provider) + .unwrap(); + let known_rounded = + parse_zdt_with_reject("1919-03-31T00:30:00-04:00[America/Toronto]", provider).unwrap(); + + assert!( + rounded.equals_with_provider(&known_rounded, provider).unwrap(), + "Expected {}, found {}", + known_rounded.to_string_with_provider(provider).unwrap(), + rounded.to_string_with_provider(provider).unwrap() + ); + assert_eq!(rounded.get_iso_datetime(), known_rounded.get_iso_datetime()); + + // Round down (ensure the offset picked is the correct one) + // See https://github.com/boa-dev/temporal/pull/520 + let zdt = + parse_zdt_with_reject("1919-03-30T01:45-05:00[America/Toronto]", provider).unwrap(); + let rounded = zdt + .round_with_provider(RoundingOptions { + smallest_unit: Some(Unit::Day), + ..Default::default() + }, provider) + .unwrap(); + let known_rounded = + parse_zdt_with_reject("1919-03-30T00:00:00-05:00[America/Toronto]", provider).unwrap(); + + assert!( + rounded.equals_with_provider(&known_rounded, provider).unwrap(), + "Expected {}, found {}", + known_rounded.to_string_with_provider(provider).unwrap(), + rounded.to_string_with_provider(provider).unwrap() + ); + assert_eq!(rounded.get_iso_datetime(), known_rounded.get_iso_datetime()); + }) +} diff --git a/deps/temporal/src/builtins/mod.rs b/deps/temporal/src/builtins/mod.rs new file mode 100644 index 00000000000000..97434baf2ddd1f --- /dev/null +++ b/deps/temporal/src/builtins/mod.rs @@ -0,0 +1,21 @@ +//! The builtins module contains the main implementation of the Temporal builtins + +#[cfg(feature = "compiled_data")] +pub mod compiled; +pub mod core; + +pub use core::*; + +#[cfg(feature = "compiled_data")] +use std::sync::LazyLock; +#[cfg(feature = "compiled_data")] +use timezone_provider::tzif::CompiledTzdbProvider; +#[cfg(all(test, feature = "compiled_data"))] +use timezone_provider::tzif::FsTzdbProvider; + +#[cfg(feature = "compiled_data")] +pub static TZ_PROVIDER: LazyLock = + LazyLock::new(CompiledTzdbProvider::default); + +#[cfg(all(test, feature = "compiled_data"))] +pub(crate) static FS_TZ_PROVIDER: LazyLock = LazyLock::new(FsTzdbProvider::default); diff --git a/deps/temporal/src/error.rs b/deps/temporal/src/error.rs new file mode 100644 index 00000000000000..e497f368cca262 --- /dev/null +++ b/deps/temporal/src/error.rs @@ -0,0 +1,386 @@ +//! This module implements `TemporalError`. + +use core::fmt; +use ixdtf::ParseError; +use timezone_provider::TimeZoneProviderError; + +use icu_calendar::DateError; + +/// `TemporalError`'s error type. +#[derive(Debug, Default, Clone, Copy, PartialEq)] +pub enum ErrorKind { + /// Error. + #[default] + Generic, + /// TypeError + Type, + /// RangeError + Range, + /// SyntaxError + Syntax, + /// Assert + Assert, +} + +impl fmt::Display for ErrorKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Generic => "Error", + Self::Type => "TypeError", + Self::Range => "RangeError", + Self::Syntax => "SyntaxError", + Self::Assert => "ImplementationError", + } + .fmt(f) + } +} + +/// The error type for `boa_temporal`. +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct TemporalError { + kind: ErrorKind, + msg: ErrorMessage, +} + +impl TemporalError { + #[inline] + #[must_use] + const fn new(kind: ErrorKind) -> Self { + Self { + kind, + msg: ErrorMessage::None, + } + } + + /// Create a generic error + #[inline] + #[must_use] + pub fn general(msg: &'static str) -> Self { + Self::new(ErrorKind::Generic).with_message(msg) + } + + /// Create a range error. + #[inline] + #[must_use] + pub const fn range() -> Self { + Self::new(ErrorKind::Range) + } + + /// Create a type error. + #[inline] + #[must_use] + pub const fn r#type() -> Self { + Self::new(ErrorKind::Type) + } + + /// Create a syntax error. + #[inline] + #[must_use] + pub const fn syntax() -> Self { + Self::new(ErrorKind::Syntax) + } + + /// Creates an assertion error + #[inline] + #[must_use] + #[cfg_attr(debug_assertions, track_caller)] + pub(crate) const fn assert() -> Self { + #[cfg(not(debug_assertions))] + { + Self::new(ErrorKind::Assert) + } + #[cfg(debug_assertions)] + Self { + kind: ErrorKind::Assert, + msg: ErrorMessage::String(core::panic::Location::caller().file()), + } + } + + /// Create an abrupt end error. + #[inline] + #[must_use] + pub fn abrupt_end() -> Self { + Self::syntax().with_message("Abrupt end to parsing target.") + } + + /// Add a message to the error. + #[inline] + #[must_use] + pub fn with_message(mut self, msg: &'static str) -> Self { + self.msg = ErrorMessage::String(msg); + self + } + + /// Add a message enum to the error. + #[inline] + #[must_use] + pub(crate) fn with_enum(mut self, msg: ErrorMessage) -> Self { + self.msg = msg; + self + } + + /// Returns this error's kind. + #[inline] + #[must_use] + pub const fn kind(&self) -> ErrorKind { + self.kind + } + + /// Extracts the error message. + #[inline] + #[must_use] + pub fn into_message(self) -> &'static str { + self.msg.to_string() + } +} + +impl fmt::Display for TemporalError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.kind)?; + + let msg = self.msg.to_string(); + if !msg.is_empty() { + write!(f, ": {msg}")?; + } + + Ok(()) + } +} + +impl From for TemporalError { + fn from(error: DateError) -> Self { + TemporalError::range().with_enum(ErrorMessage::Icu4xDate(error)) + } +} + +impl From for TemporalError { + fn from(error: ParseError) -> Self { + TemporalError::range().with_enum(ErrorMessage::Ixdtf(error)) + } +} + +/// The error message +#[derive(Clone, Copy, PartialEq, Debug)] +pub(crate) enum ErrorMessage { + // Range + InstantOutOfRange, + IntermediateDateTimeOutOfRange, + ZDTOutOfDayBounds, + LargestUnitCannotBeDateUnit, + DateOutOfRange, + + // Numerical errors + NumberNotFinite, + NumberNotIntegral, + NumberNotPositive, + NumberOutOfRange, + FractionalDigitsPrecisionInvalid, + + // Options validity + SmallestUnitIsRequired, + SmallestUnitNotTimeUnit, + SmallestUnitLargerThanLargestUnit, + UnitNotDate, + UnitNotTime, + UnitRequired, + UnitNoAutoDuringComparison, + RoundToUnitInvalid, + RoundingModeInvalid, + CalendarNameInvalid, + OffsetOptionInvalid, + TimeZoneNameInvalid, + + // Field mismatches + CalendarMismatch, + TzMismatch, + + // Parsing + ParserNeedsDate, + FractionalTimeMoreThanNineDigits, + + // Other + OffsetNeedsDisambiguation, + + // Typed + None, + String(&'static str), + Ixdtf(ParseError), + Icu4xDate(DateError), +} + +impl ErrorMessage { + pub fn to_string(self) -> &'static str { + match self { + Self::InstantOutOfRange => "Instant nanoseconds are not within a valid epoch range.", + Self::IntermediateDateTimeOutOfRange => { + "Intermediate ISO datetime was not within a valid range." + } + Self::ZDTOutOfDayBounds => "ZonedDateTime is outside the expected day bounds", + Self::LargestUnitCannotBeDateUnit => "Largest unit cannot be a date unit", + Self::DateOutOfRange => "Date is not within ISO date time limits.", + Self::NumberNotFinite => "number value is not a finite value.", + Self::NumberNotIntegral => "value must be integral.", + Self::NumberNotPositive => "integer must be positive.", + Self::NumberOutOfRange => "number exceeded a valid range.", + Self::FractionalDigitsPrecisionInvalid => "Invalid fractionalDigits precision value", + Self::SmallestUnitIsRequired => "smallestUnit is required", + Self::SmallestUnitNotTimeUnit => "smallestUnit must be a valid time unit.", + Self::SmallestUnitLargerThanLargestUnit => { + "smallestUnit was larger than largestunit in DifferenceeSettings" + } + Self::UnitNotDate => "Unit was not part of the date unit group.", + Self::UnitNotTime => "Unit was not part of the time unit group.", + Self::UnitRequired => "Unit is required", + Self::UnitNoAutoDuringComparison => "'auto' units are not allowed during comparison", + Self::RoundToUnitInvalid => "Invalid roundTo unit provided.", + Self::RoundingModeInvalid => "Invalid roundingMode option provided", + Self::CalendarNameInvalid => "Invalid calendarName option provided", + Self::OffsetOptionInvalid => "Invalid offsetOption option provided", + Self::TimeZoneNameInvalid => "Invalid timeZoneName option provided", + Self::CalendarMismatch => { + "Calendar must be the same for operations involving two calendared types." + } + Self::TzMismatch => "Timezones must be the same if unit is a day unit.", + + Self::ParserNeedsDate => "Could not find a valid DateRecord node during parsing.", + Self::FractionalTimeMoreThanNineDigits => "Fractional time exceeds nine digits.", + Self::OffsetNeedsDisambiguation => { + "Offsets could not be determined without disambiguation" + } + Self::None => "", + Self::String(s) => s, + Self::Ixdtf(s) => ixdtf_error_to_static_string(s), + Self::Icu4xDate(DateError::Range { field, .. }) => match field { + "year" => "Year out of range.", + "month" => "Month out of range.", + "day" => "Day out of range.", + _ => "Field out of range.", + }, + Self::Icu4xDate(DateError::UnknownEra) => "Unknown era.", + Self::Icu4xDate(DateError::UnknownMonthCode(..)) => "Unknown month code.", + Self::Icu4xDate(_) => "Date error.", + } + } +} + +impl From for TemporalError { + fn from(other: TimeZoneProviderError) -> Self { + match other { + TimeZoneProviderError::InstantOutOfRange => { + Self::range().with_enum(ErrorMessage::InstantOutOfRange) + } + TimeZoneProviderError::Assert(s) => Self::assert().with_message(s), + TimeZoneProviderError::Range(s) => Self::range().with_message(s), + _ => Self::assert().with_message("Unknown TimeZoneProviderError"), + } + } +} + +// ICU4X will get this API natively eventually +// https://github.com/unicode-org/icu4x/issues/6904 +pub fn ixdtf_error_to_static_string(error: ParseError) -> &'static str { + match error { + ParseError::ImplAssert => "Implementation error: this error must not throw.", + + ParseError::NonAsciiCodePoint => "Code point was not ASCII", + + ParseError::ParseFloat => "Invalid float while parsing fraction part.", + + ParseError::AbruptEnd { .. } => "Parsing ended abruptly.", + + ParseError::InvalidEnd => "Unexpected character found after parsing was completed.", + // Date related errors + ParseError::InvalidMonthRange => "Parsed month value not in a valid range.", + + ParseError::InvalidDayRange => "Parsed day value not in a valid range.", + + ParseError::DateYear => "Invalid chracter while parsing year value.", + + ParseError::DateExtendedYear => "Invalid character while parsing extended year value.", + + ParseError::DateMonth => "Invalid character while parsing month value.", + + ParseError::DateDay => "Invalid character while parsing day value.", + + ParseError::DateUnexpectedEnd => "Unexpected end while parsing a date value.", + + ParseError::TimeRequired => "Time is required.", + + ParseError::TimeHour => "Invalid character while parsing hour value.", + + ParseError::TimeMinuteSecond => { + "Invalid character while parsing minute/second value in (0, 59] range." + } + + ParseError::TimeSecond => "Invalid character while parsing second value in (0, 60] range.", + + ParseError::FractionPart => "Invalid character while parsing fraction part value.", + + ParseError::DateSeparator => "Invalid character while parsing date separator.", + + ParseError::TimeSeparator => "Invalid character while parsing time separator.", + + ParseError::DecimalSeparator => "Invalid character while parsing decimal separator.", + // Annotation Related Errors + ParseError::InvalidAnnotation => "Invalid annotation.", + + ParseError::AnnotationOpen => "Invalid annotation open character.", + + ParseError::AnnotationClose => "Invalid annotation close character.", + + ParseError::AnnotationChar => "Invalid annotation character.", + + ParseError::AnnotationKeyValueSeparator => { + "Invalid annotation key-value separator character." + } + + ParseError::AnnotationKeyLeadingChar => "Invalid annotation key leading character.", + + ParseError::AnnotationKeyChar => "Invalid annotation key character.", + + ParseError::AnnotationValueCharPostHyphen => { + "Expected annotation value character must exist after hyphen." + } + + ParseError::AnnotationValueChar => "Invalid annotation value character.", + + ParseError::InvalidMinutePrecisionOffset => "Offset must be minute precision", + + ParseError::CriticalDuplicateCalendar => { + "Duplicate calendars cannot be provided when one is critical." + } + + ParseError::UnrecognizedCritical => "Unrecognized annoation is marked as critical.", + + ParseError::TzLeadingChar => "Invalid time zone leading character.", + + ParseError::IanaCharPostSeparator => "Expected time zone character after '/'.", + + ParseError::IanaChar => "Invalid IANA time zone character after '/'.", + + ParseError::UtcTimeSeparator => "Invalid time zone character after '/'.", + + ParseError::OffsetNeedsSign => "UTC offset needs a sign", + + ParseError::MonthDayHyphen => "MonthDay must begin with a month or '--'", + + ParseError::DurationDisgnator => "Invalid duration designator.", + + ParseError::DurationValueExceededRange => { + "Provided Duration field value exceeds supported range." + } + + ParseError::DateDurationPartOrder => "Invalid date duration part order.", + + ParseError::TimeDurationPartOrder => "Invalid time duration part order.", + + ParseError::TimeDurationDesignator => "Invalid time duration designator.", + + ParseError::AmbiguousTimeMonthDay => "Time is ambiguous with MonthDay", + + ParseError::AmbiguousTimeYearMonth => "Time is ambiguous with YearMonth", + + ParseError::InvalidMonthDay => "MonthDay was not valid.", + _ => "General IXDTF parsing error", + } +} diff --git a/deps/temporal/src/host.rs b/deps/temporal/src/host.rs new file mode 100644 index 00000000000000..df090c570d5660 --- /dev/null +++ b/deps/temporal/src/host.rs @@ -0,0 +1,62 @@ +//! Trait definitions for accessing values from the host environment. +//! +//! NOTE: This is a power user API. + +use timezone_provider::{epoch_nanoseconds::EpochNanoseconds, provider::TimeZoneProvider}; + +use crate::{TemporalResult, TimeZone, UtcOffset}; + +/// The `HostClock` trait defines an accessor to the host's clock. +pub trait HostClock { + fn get_host_epoch_nanoseconds(&self) -> TemporalResult; +} + +/// The `HostTimeZone` trait defines the host's time zone. +pub trait HostTimeZone { + fn get_host_time_zone(&self, provider: &impl TimeZoneProvider) -> TemporalResult; +} + +/// `HostHooks` marks whether a trait implements the required host hooks with some +/// system methods. +pub trait HostHooks: HostClock + HostTimeZone { + fn get_system_epoch_nanoseconds(&self) -> TemporalResult { + self.get_host_epoch_nanoseconds() + } + + fn get_system_time_zone(&self, provider: &impl TimeZoneProvider) -> TemporalResult { + self.get_host_time_zone(provider) + } +} + +/// The empty host is a default implementation of a system host. +/// +/// This implementation will always return zero epoch nanoseconds and +/// a +00:00 time zone. +/// +/// ``` +/// # #[cfg(feature = "compiled_data")] { +/// use temporal_rs::host::EmptyHostSystem; +/// use temporal_rs::now::Now; +/// +/// let now = Now::new(EmptyHostSystem); +/// let zoned_date_time = now.zoned_date_time_iso(None).unwrap(); +/// +/// assert_eq!(zoned_date_time.to_string(), "1970-01-01T00:00:00+00:00[+00:00]"); +/// +/// # } +/// ``` +pub struct EmptyHostSystem; + +impl HostClock for EmptyHostSystem { + fn get_host_epoch_nanoseconds(&self) -> TemporalResult { + Ok(EpochNanoseconds::from_seconds(0)) + } +} + +impl HostTimeZone for EmptyHostSystem { + fn get_host_time_zone(&self, _: &impl TimeZoneProvider) -> TemporalResult { + Ok(TimeZone::from(UtcOffset::default())) + } +} + +impl HostHooks for EmptyHostSystem {} diff --git a/deps/temporal/src/iso.rs b/deps/temporal/src/iso.rs new file mode 100644 index 00000000000000..a36ca499b0248e --- /dev/null +++ b/deps/temporal/src/iso.rs @@ -0,0 +1,1097 @@ +//! This module implements the internal ISO field records. +//! +//! While these are public structs, the records are primarily +//! meant for internal Temporal calculations or calling `Calendar` +//! methods. Prefer using `PlainDateTime`, `PlainDate`, or `PlainTime` +//! +//! The three main types of records are: +//! - `IsoDateTime` +//! - `IsoDate` +//! - `IsoTime` +//! +//! ## `IsoDate` +//! +//! An `IsoDate` represents the `[[ISOYear]]`, `[[ISOMonth]]`, and `[[ISODay]]` internal slots. +//! +//! ## `IsoTime` +//! +//! An `IsoTime` represents the `[[ISOHour]]`, `[[ISOMinute]]`, `[[ISOsecond]]`, `[[ISOmillisecond]]`, +//! `[[ISOmicrosecond]]`, and `[[ISOnanosecond]]` internal slots. +//! +//! ## `IsoDateTime` +//! +//! An `IsoDateTime` has the internal slots of both an `IsoDate` and `IsoTime`. + +use core::num::NonZeroU128; +use ixdtf::records::TimeRecord; + +use crate::{ + builtins::core::{ + calendar::Calendar, + duration::{ + normalized::{InternalDurationRecord, TimeDuration}, + DateDuration, + }, + PartialTime, PlainDate, + }, + error::{ErrorMessage, TemporalError}, + options::{Overflow, ResolvedRoundingOptions, Unit}, + rounding::IncrementRounder, + unix_time::EpochNanoseconds, + utils, TemporalResult, TemporalUnwrap, NS_PER_DAY, +}; +use icu_calendar::{Date as IcuDate, Iso}; +use num_traits::{cast::FromPrimitive, Euclid}; + +/// `IsoDateTime` is the record of the `IsoDate` and `IsoTime` internal slots. +#[non_exhaustive] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct IsoDateTime { + /// The `IsoDate` fields. + pub date: IsoDate, + /// The `IsoTime` fields. + pub time: IsoTime, +} + +impl IsoDateTime { + /// Creates a new `IsoDateTime` without any validaiton. + pub(crate) fn new_unchecked(date: IsoDate, time: IsoTime) -> Self { + Self { date, time } + } + + /// Creates a new validated `IsoDateTime` that is within valid limits. + pub fn new(date: IsoDate, time: IsoTime) -> TemporalResult { + if !iso_dt_within_valid_limits(date, &time) { + return Err( + TemporalError::range().with_message("IsoDateTime not within a valid range.") + ); + } + Ok(Self::new_unchecked(date, time)) + } + + /// + pub fn check_within_limits(&self) -> TemporalResult<()> { + if !iso_dt_within_valid_limits(self.date, &self.time) { + return Err( + TemporalError::range().with_message("IsoDateTime not within a valid range.") + ); + } + Ok(()) + } + + // NOTE: The below assumes that nanos is from an `Instant` and thus in a valid range. -> Needs validation. + // + // TODO: Move away from offset use of f64 + /// Creates an `IsoDateTime` from a `BigInt` of epochNanoseconds. + #[allow(clippy::neg_cmp_op_on_partial_ord)] + pub(crate) fn from_epoch_nanos(epoch_nanoseconds: &EpochNanoseconds, offset: i64) -> Self { + // Skip the assert as nanos should be validated by Instant. + // TODO: Determine whether value needs to be validated as integral. + // Get the component ISO parts + + // 2. Let remainderNs be epochNanoseconds modulo 10^6. + let remainder_nanos = epoch_nanoseconds.0.rem_euclid(1_000_000); + + // 3. Let epochMilliseconds be 𝔽((epochNanoseconds - remainderNs) / 10^6). + let epoch_millis = (epoch_nanoseconds.0 - remainder_nanos).div_euclid(1_000_000) as i64; + + let (year, month, day) = utils::ymd_from_epoch_milliseconds(epoch_millis); + + // 7. Let hour be ℝ(! HourFromTime(epochMilliseconds)). + let hour = epoch_millis.div_euclid(3_600_000).rem_euclid(24); + // 8. Let minute be ℝ(! MinFromTime(epochMilliserhs)conds)). + let minute = epoch_millis.div_euclid(60_000).rem_euclid(60); + // 9. Let second be ℝ(! SecFromTime(epochMilliseconds)). + let second = epoch_millis.div_euclid(1000).rem_euclid(60); + // 10. Let millisecond be ℝ(! msFromTime(epochMilliseconds)). + let millis = epoch_millis.rem_euclid(1000); + + // 11. Let microsecond be floor(remainderNs / 1000). + let micros = remainder_nanos.div_euclid(1_000) as i64; + // 12. Assert: microsecond < 1000. + debug_assert!(micros < 1000); + // 13. Let nanosecond be remainderNs modulo 1000. + let nanos = remainder_nanos.rem_euclid(1000) as i64; + + Self::balance( + year, + i32::from(month), + i32::from(day), + hour, + minute, + second, + millis, + micros.into(), + (nanos + offset).into(), + ) + } + + #[allow(clippy::too_many_arguments)] + pub(crate) fn balance( + year: i32, + month: i32, + day: i32, + hour: i64, + minute: i64, + second: i64, + millisecond: i64, + microsecond: i128, + nanosecond: i128, + ) -> Self { + let (overflow_day, time) = + IsoTime::balance(hour, minute, second, millisecond, microsecond, nanosecond); + // TODO: Address truncation with `try_balance` + let date = IsoDate::balance(year, month, day + overflow_day as i32); + Self::new_unchecked(date, time) + } + + /// Returns whether the `IsoDateTime` is within valid limits. + pub(crate) fn is_within_limits(&self) -> bool { + iso_dt_within_valid_limits(self.date, &self.time) + } + + /// Returns this `IsoDateTime` in nanoseconds + pub fn as_nanoseconds(&self) -> EpochNanoseconds { + utc_epoch_nanos(self.date, &self.time) + } + + pub(crate) fn round(&self, resolved_options: ResolvedRoundingOptions) -> TemporalResult { + let (rounded_days, rounded_time) = self.time.round(resolved_options)?; + let balance_result = IsoDate::try_balance( + self.date.year, + self.date.month.into(), + i64::from(self.date.day) + rounded_days, + )?; + Self::new(balance_result, rounded_time) + } + + // TODO: UPDATE TO CURRENT SPECIFICATION + // TODO: Determine whether to provide an options object...seems duplicative. + /// 5.5.11 DifferenceISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2, calendarRec, largestUnit, options ) + pub(crate) fn diff( + &self, + other: &Self, + calendar: &Calendar, + largest_unit: Unit, + ) -> TemporalResult { + // 1. Assert: ISODateTimeWithinLimits(y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1) is true. + // 2. Assert: ISODateTimeWithinLimits(y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2) is true. + // 3. Assert: If y1 ≠ y2, and mon1 ≠ mon2, and d1 ≠ d2, and LargerOfTwoUnits(largestUnit, "day") + // is not "day", CalendarMethodsRecordHasLookedUp(calendarRec, date-until) is true. + + // 4. Let timeDuration be DifferenceTime(h1, min1, s1, ms1, mus1, ns1, h2, min2, s2, ms2, mus2, ns2). + let mut time_duration = self.time.diff(&other.time); + + // 5. Let timeSign be TimeDurationSign(timeDuration). + let time_sign = time_duration.sign() as i8; + + // 6. Let dateSign be CompareISODate(y2, mon2, d2, y1, mon1, d1). + let date_sign = other.date.cmp(&self.date) as i32; + // 7. Let adjustedDate be CreateISODateRecord(y2, mon2, d2). + let mut adjusted_date = other.date; + + // 8. If timeSign = -dateSign, then + if i32::from(time_sign) == -date_sign { + // a. Set adjustedDate to BalanceISODate(adjustedDate.[[Year]], adjustedDate.[[Month]], adjustedDate.[[Day]] + timeSign). + adjusted_date = IsoDate::balance( + adjusted_date.year, + i32::from(adjusted_date.month), + i32::from(adjusted_date.day) + i32::from(time_sign), + ); + // b. Set timeDuration to ? Add24HourDaysToTimeDuration(timeDuration, -timeSign). + time_duration = time_duration.add_days(-i64::from(time_sign))?; + } + + // 9. Let date1 be ! CreateTemporalDate(y1, mon1, d1, calendarRec.[[Receiver]]). + let date_one = PlainDate::new_unchecked(self.date, calendar.clone()); + // 10. Let date2 be ! CreateTemporalDate(adjustedDate.[[Year]], adjustedDate.[[Month]], + // adjustedDate.[[Day]], calendarRec.[[Receiver]]). + let date_two = PlainDate::try_new( + adjusted_date.year, + adjusted_date.month, + adjusted_date.day, + calendar.clone(), + )?; + + // 11. Let dateLargestUnit be LargerOfTwoUnits("day", largestUnit). + // 12. Let untilOptions be ! SnapshotOwnProperties(options, null). + let date_largest_unit = largest_unit.max(Unit::Day); + + // 13. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", dateLargestUnit). + // 14. Let dateDifference be ? DifferenceDate(calendarRec, date1, date2, untilOptions). + let date_diff = date_one.internal_diff_date(&date_two, date_largest_unit)?; + + // 16. If largestUnit is not dateLargestUnit, then + let days = if largest_unit == date_largest_unit { + // 15. Let days be dateDifference.[[Days]]. + date_diff.days() + } else { + // a. Set timeDuration to ? Add24HourDaysToTimeDuration(timeDuration, dateDifference.[[Days]]). + time_duration = time_duration.add_days(date_diff.days())?; + // b. Set days to 0. + 0 + }; + + // 17. Return ? CreateNormalizedDurationRecord(dateDifference.[[Years]], dateDifference.[[Months]], dateDifference.[[Weeks]], days, timeDuration). + InternalDurationRecord::new( + DateDuration::new_unchecked( + date_diff.years(), + date_diff.months(), + date_diff.weeks(), + days, + ), + time_duration, + ) + } +} + +// ==== `IsoDate` section ==== + +/// `IsoDate` serves as a record for the `[[ISOYear]]`, `[[ISOMonth]]`, +/// and `[[ISODay]]` internal fields. +/// +/// These fields are used for the `Temporal.PlainDate` object, the +/// `Temporal.YearMonth` object, and the `Temporal.MonthDay` object. +#[non_exhaustive] +#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)] +pub struct IsoDate { + /// An ISO year within a range -271821..=275760 + pub year: i32, + /// An ISO month within a valid range 1..=12 + pub month: u8, + /// An ISO day within a valid range of 1..=31 + pub day: u8, +} + +impl IsoDate { + /// Creates a new `IsoDate` without determining the validity. + pub(crate) const fn new_unchecked(year: i32, month: u8, day: u8) -> Self { + Self { year, month, day } + } + + pub(crate) fn regulate( + year: i32, + month: u8, + day: u8, + overflow: Overflow, + ) -> TemporalResult { + match overflow { + Overflow::Constrain => { + let month = month.clamp(1, 12); + let day = constrain_iso_day(year, month, day); + // NOTE: Values are clamped in a u8 range. + Ok(Self::new_unchecked(year, month, day)) + } + Overflow::Reject => { + if !is_valid_date(year, month, day) { + return Err(TemporalError::range().with_message("not a valid ISO date.")); + } + // NOTE: Values have been verified to be in a u8 range. + Ok(Self::new_unchecked(year, month, day)) + } + } + } + + /// + pub fn check_within_limits(self) -> TemporalResult<()> { + if !iso_dt_within_valid_limits(self, &IsoTime::noon()) { + return Err(TemporalError::range().with_message("IsoDate not within a valid range.")); + } + Ok(()) + } + + // + pub fn check_validity(&self) -> TemporalResult<()> { + if !self.is_valid() { + return Err( + TemporalError::range().with_message("IsoDateTime does not have valid fields.") + ); + } + Ok(()) + } + + pub(crate) fn new_with_overflow( + year: i32, + month: u8, + day: u8, + overflow: Overflow, + ) -> TemporalResult { + let date = Self::regulate(year, month, day, overflow)?; + if !iso_dt_within_valid_limits(date, &IsoTime::noon()) { + return Err(TemporalError::range().with_enum(ErrorMessage::DateOutOfRange)); + } + Ok(date) + } + + /// Create a balance date while rejecting invalid intermediates + pub(crate) fn try_balance(year: i32, month: i32, day: i64) -> TemporalResult { + let epoch_days = iso_date_to_epoch_days(year, month, 1) + day - 1; + if (MAX_EPOCH_DAYS) < epoch_days.abs() { + return Err(TemporalError::range().with_message("epoch days exceed maximum range.")); + } + // NOTE The cast is to i32 is safe due to MAX_EPOCH_DAYS check + let ms = utils::epoch_days_to_epoch_ms(epoch_days, 0); + let (year, month, day) = utils::ymd_from_epoch_milliseconds(ms); + Ok(Self::new_unchecked(year, month, day)) + } + + /// Create a balanced `IsoDate` + /// + /// Equivalent to `BalanceISODate`. + pub(crate) fn balance(year: i32, month: i32, day: i32) -> Self { + let epoch_days = iso_date_to_epoch_days(year, month, day); + let ms = utils::epoch_days_to_epoch_ms(epoch_days, 0); + let (year, month, day) = utils::ymd_from_epoch_milliseconds(ms); + Self::new_unchecked(year, month, day) + } + + pub(crate) fn is_valid_day_range(&self) -> TemporalResult<()> { + if self.to_epoch_days().abs() > 100_000_000 { + return Err(TemporalError::range().with_message("Not in a valid ISO day range.")); + } + Ok(()) + } + + /// Returns this `IsoDate` in nanoseconds. + #[inline] + pub(crate) fn as_nanoseconds(&self) -> EpochNanoseconds { + utc_epoch_nanos(*self, &IsoTime::default()) + } + + /// Functionally the same as Date's abstract operation `MakeDay` + /// + /// Equivalent to `IsoDateToEpochDays` + #[inline] + pub(crate) fn to_epoch_days(self) -> i64 { + utils::epoch_days_from_gregorian_date(self.year, self.month, self.day) + } + + /// Returns if the current `IsoDate` is valid. + pub(crate) fn is_valid(self) -> bool { + is_valid_date(self.year, self.month, self.day) + } + + /// Returns the resulting `IsoDate` from adding a provided `Duration` to this `IsoDate` + pub(crate) fn add_date_duration( + self, + duration: &DateDuration, + overflow: Overflow, + ) -> TemporalResult { + // 1. Assert: year, month, day, years, months, weeks, and days are integers. + // 2. Assert: overflow is either "constrain" or "reject". + // 3. Let intermediate be ! BalanceISOYearMonth(year + years, month + months). + let intermediate = balance_iso_year_month_with_clamp( + i64::from(self.year) + duration.years, + i64::from(self.month) + duration.months, + ); + + // 4. Let intermediate be ? RegulateISODate(intermediate.[[Year]], intermediate.[[Month]], day, overflow). + let intermediate = + Self::new_with_overflow(intermediate.0, intermediate.1, self.day, overflow)?; + + // 5. Set days to days + 7 × weeks. + let additional_days = duration.days + (7 * duration.weeks); + + // 6. Let d be intermediate.[[Day]] + days. + let intermediate_days = i64::from(intermediate.day) + additional_days; + + // 7. Return BalanceISODate(intermediate.[[Year]], intermediate.[[Month]], d). + Self::try_balance( + intermediate.year, + intermediate.month.into(), + intermediate_days, + ) + } + + pub(crate) fn diff_iso_date( + &self, + other: &Self, + largest_unit: Unit, + ) -> TemporalResult { + // 1. Assert: IsValidISODate(y1, m1, d1) is true. + // 2. Assert: IsValidISODate(y2, m2, d2) is true. + // 3. Let sign be -CompareISODate(y1, m1, d1, y2, m2, d2). + let sign = -(self.cmp(other) as i8); + // 4. If sign = 0, return ! CreateDateDurationRecord(0, 0, 0, 0). + if sign == 0 { + return Ok(DateDuration::default()); + }; + + // 5. Let years be 0. + let mut years = 0; + let mut months = 0; + // 6. If largestUnit is "year", then + if largest_unit == Unit::Year || largest_unit == Unit::Month { + // others.year - self.year is adopted from temporal-proposal/polyfill as it saves iterations. + // a. Let candidateYears be sign. + let mut candidate_years: i32 = other.year - self.year; + if candidate_years != 0 { + candidate_years -= i32::from(sign); + } + // b. Repeat, while ISODateSurpasses(sign, y1 + candidateYears, m1, d1, y2, m2, d2) is false, + while !iso_date_surpasses( + &IsoDate::new_unchecked(self.year + candidate_years, self.month, self.day), + other, + sign, + ) { + // i. Set years to candidateYears. + years = candidate_years; + // ii. Set candidateYears to candidateYears + sign. + candidate_years += i32::from(sign); + } + + // 7. Let months be 0. + // 8. If largestUnit is "year" or largestUnit is "month", then + // a. Let candidateMonths be sign. + let mut candidate_months: i32 = sign.into(); + // b. Let intermediate be BalanceISOYearMonth(y1 + years, m1 + candidateMonths). + let mut intermediate = + balance_iso_year_month(self.year + years, i32::from(self.month) + candidate_months); + // c. Repeat, while ISODateSurpasses(sign, intermediate.[[Year]], intermediate.[[Month]], d1, y2, m2, d2) is false, + // Safety: balance_iso_year_month should always return a month value from 1..=12 + while !iso_date_surpasses( + &IsoDate::new_unchecked(intermediate.0, intermediate.1 as u8, self.day), + other, + sign, + ) { + // i. Set months to candidateMonths. + months = candidate_months; + // ii. Set candidateMonths to candidateMonths + sign. + candidate_months += i32::from(sign); + // iii. Set intermediate to BalanceISOYearMonth(intermediate.[[Year]], intermediate.[[Month]] + sign). + intermediate = balance_iso_year_month( + intermediate.0, + i32::from(intermediate.1) + i32::from(sign), + ); + } + + if largest_unit == Unit::Month { + months += years * 12; + years = 0; + } + } + + // 9. Set intermediate to BalanceISOYearMonth(y1 + years, m1 + months). + let intermediate = + balance_iso_year_month(self.year + years, i32::from(self.month) + months); + // 10. Let constrained be ! RegulateISODate(intermediate.[[Year]], intermediate.[[Month]], d1, "constrain"). + let constrained = Self::new_with_overflow( + intermediate.0, + intermediate.1, + self.day, + Overflow::Constrain, + )?; + + // NOTE: Below is adapted from the polyfill. Preferring this as it avoids looping. + // 11. Let weeks be 0. + let days = utils::epoch_days_from_gregorian_date(other.year, other.month, other.day) + - utils::epoch_days_from_gregorian_date( + constrained.year, + constrained.month, + constrained.day, + ); + + let (weeks, days) = if largest_unit == Unit::Week { + (days / 7, days % 7) + } else { + (0, days) + }; + + // 17. Return ! CreateDateDurationRecord(years, months, weeks, days). + DateDuration::new(years as i64, months as i64, weeks, days) + } +} + +impl IsoDate { + /// Creates `[[ISOYear]]`, `[[isoMonth]]`, `[[isoDay]]` fields from `ICU4X`'s `Date` struct. + pub(crate) fn to_icu4x(self) -> IcuDate { + let d = IcuDate::try_new_iso(self.year, self.month, self.day); + debug_assert!(d.is_ok(), "ICU4X ISODate conversion must not fail"); + d.unwrap_or_else(|_| IcuDate::from_rata_die(icu_calendar::types::RataDie::new(0), Iso)) + } +} + +// ==== `IsoTime` section ==== + +/// An `IsoTime` record that contains `Temporal`'s +/// time slots. +#[non_exhaustive] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct IsoTime { + /// A valid hour value between 0..=23 + pub hour: u8, // 0..=23 + /// A valid minute value between 0..=59 + pub minute: u8, // 0..=59 + /// A valid second value between 0..=59 + pub second: u8, // 0..=59 + /// A valid millisecond value between 0..=999 + pub millisecond: u16, // 0..=999 + /// A valid microsecond value between 0..=999 + pub microsecond: u16, // 0..=999 + /// A valid nanosecond value between 0..=999 + pub nanosecond: u16, // 0..=999 +} + +impl IsoTime { + /// Creates a new `IsoTime` without any validation. + pub(crate) fn new_unchecked( + hour: u8, + minute: u8, + second: u8, + millisecond: u16, + microsecond: u16, + nanosecond: u16, + ) -> Self { + Self { + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + } + } + + /// Creates a new regulated `IsoTime`. + pub fn new( + hour: u8, + minute: u8, + second: u8, + millisecond: u16, + microsecond: u16, + nanosecond: u16, + overflow: Overflow, + ) -> TemporalResult { + match overflow { + Overflow::Constrain => { + let h = hour.clamp(0, 23); + let min = minute.clamp(0, 59); + let sec = second.clamp(0, 59); + let milli = millisecond.clamp(0, 999); + let micro = microsecond.clamp(0, 999); + let nano = nanosecond.clamp(0, 999); + Ok(Self::new_unchecked(h, min, sec, milli, micro, nano)) + } + Overflow::Reject => { + if !is_valid_time(hour, minute, second, millisecond, microsecond, nanosecond) { + return Err(TemporalError::range().with_message("IsoTime is not valid")); + }; + Ok(Self::new_unchecked( + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + )) + } + } + } + + /// Creates a new `Time` with the fields provided from a `PartialTime`. + #[inline] + pub(crate) fn with(&self, partial: PartialTime, overflow: Overflow) -> TemporalResult { + let hour = partial.hour.unwrap_or(self.hour); + let minute = partial.minute.unwrap_or(self.minute); + let second = partial.second.unwrap_or(self.second); + let millisecond = partial.millisecond.unwrap_or(self.millisecond); + let microsecond = partial.microsecond.unwrap_or(self.microsecond); + let nanosecond = partial.nanosecond.unwrap_or(self.nanosecond); + Self::new( + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + overflow, + ) + } + + /// Returns an `IsoTime` set to 12:00:00 + pub(crate) const fn noon() -> Self { + Self { + hour: 12, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + } + } + + /// Returns an `IsoTime` based off parse components. + pub(crate) fn from_time_record(time_record: TimeRecord) -> TemporalResult { + let second = time_record.second.clamp(0, 59); + let fractional_seconds = time_record + .fraction + .map(|x| { + x.to_nanoseconds().ok_or( + TemporalError::range() + .with_enum(ErrorMessage::FractionalTimeMoreThanNineDigits), + ) + }) + .transpose()? + .unwrap_or(0); + + let (millisecond, rem) = fractional_seconds.div_rem_euclid(&1_000_000); + let (micros, nanos) = rem.div_rem_euclid(&1_000); + + Self::new( + time_record.hour, + time_record.minute, + second, + millisecond as u16, + micros as u16, + nanos as u16, + Overflow::Reject, + ) + } + + /// Balances and creates a new `IsoTime` with `day` overflow from the provided values. + pub(crate) fn balance( + hour: i64, + minute: i64, + second: i64, + millisecond: i64, + microsecond: i128, + nanosecond: i128, + ) -> (i64, Self) { + // 1. Set microsecond to microsecond + floor(nanosecond / 1000). + // 2. Set nanosecond to nanosecond modulo 1000. + let (quotient, nanosecond) = (nanosecond.div_euclid(1000), nanosecond.rem_euclid(1000)); + let microsecond = microsecond + quotient; + + // 3. Set millisecond to millisecond + floor(microsecond / 1000). + // 4. Set microsecond to microsecond modulo 1000. + let (quotient, microsecond) = (microsecond.div_euclid(1000), microsecond.rem_euclid(1000)); + let millisecond = millisecond + quotient as i64; + + // 5. Set second to second + floor(millisecond / 1000). + // 6. Set millisecond to millisecond modulo 1000. + let (quotient, millisecond) = div_mod(millisecond, 1000); + let second = second + quotient; + + // 7. Set minute to minute + floor(second / 60). + // 8. Set second to second modulo 60. + let (quotient, second) = div_mod(second, 60); + let minute = minute + quotient; + + // 9. Set hour to hour + floor(minute / 60). + // 10. Set minute to minute modulo 60. + let (quotient, minute) = div_mod(minute, 60); + let hour = hour + quotient; + + // 11. Let days be floor(hour / 24). + // 12. Set hour to hour modulo 24. + let (days, hour) = div_mod(hour, 24); + + let time = Self::new_unchecked( + hour as u8, + minute as u8, + second as u8, + millisecond as u16, + microsecond as u16, + nanosecond as u16, + ); + + (days, time) + } + + /// Difference this `IsoTime` against another and returning a `TimeDuration`. + pub(crate) fn diff(&self, other: &Self) -> TimeDuration { + let h = i64::from(other.hour) - i64::from(self.hour); + let m = i64::from(other.minute) - i64::from(self.minute); + let s = i64::from(other.second) - i64::from(self.second); + let ms = i64::from(other.millisecond) - i64::from(self.millisecond); + let mis = i128::from(other.microsecond) - i128::from(self.microsecond); + let ns = i128::from(other.nanosecond) - i128::from(self.nanosecond); + + TimeDuration::from_components(h, m, s, ms, mis, ns) + } + + // NOTE (nekevss): Specification seemed to be off / not entirely working, so the below was adapted from the + // temporal-polyfill + // TODO: DayLengthNS can probably be a u64, but keep as is for now and optimize. + /// Rounds the current `IsoTime` according to the provided settings. + pub(crate) fn round( + &self, + resolved_options: ResolvedRoundingOptions, + ) -> TemporalResult<(i64, Self)> { + // 1. If unit is "day" or "hour", then + let quantity = match resolved_options.smallest_unit { + Unit::Day | Unit::Hour => { + // a. Let quantity be ((((hour × 60 + minute) × 60 + second) × 1000 + millisecond) + // × 1000 + microsecond) × 1000 + nanosecond. + let minutes = i128::from(self.hour) * 60 + i128::from(self.minute); + let seconds = minutes * 60 + i128::from(self.second); + let millis = seconds * 1000 + i128::from(self.millisecond); + let micros = millis * 1000 + i128::from(self.microsecond); + micros * 1000 + i128::from(self.nanosecond) + } + // 2. Else if unit is "minute", then + Unit::Minute => { + // a. Let quantity be (((minute × 60 + second) × 1000 + millisecond) × 1000 + microsecond) × 1000 + nanosecond. + let seconds = i128::from(self.minute) * 60 + i128::from(self.second); + let millis = seconds * 1000 + i128::from(self.millisecond); + let micros = millis * 1000 + i128::from(self.microsecond); + micros * 1000 + i128::from(self.nanosecond) + } + // 3. Else if unit is "second", then + Unit::Second => { + // a. Let quantity be ((second × 1000 + millisecond) × 1000 + microsecond) × 1000 + nanosecond. + let millis = i128::from(self.second) * 1000 + i128::from(self.millisecond); + let micros = millis * 1000 + i128::from(self.microsecond); + micros * 1000 + i128::from(self.nanosecond) + } + // 4. Else if unit is "millisecond", then + Unit::Millisecond => { + // a. Let quantity be (millisecond × 1000 + microsecond) × 1000 + nanosecond. + let micros = i128::from(self.millisecond) * 1000 + i128::from(self.microsecond); + micros * 1000 + i128::from(self.nanosecond) + } + // 5. Else if unit is "microsecond", then + Unit::Microsecond => { + // a. Let quantity be microsecond × 1000 + nanosecond. + i128::from(self.microsecond) * 1000 + i128::from(self.nanosecond) + } + // 6. Else, + Unit::Nanosecond => { + // a. Assert: unit is "nanosecond". + // b. Let quantity be nanosecond. + i128::from(self.nanosecond) + } + _ => { + return Err(TemporalError::range() + .with_message("Invalid smallestUnit value for time rounding.")) + } + }; + // 7. Let unitLength be the value in the "Length in Nanoseconds" column of the row of Table 22 whose "Singular" column contains unit. + let length = NonZeroU128::new( + resolved_options + .smallest_unit + .as_nanoseconds() + .temporal_unwrap()? + .into(), + ) + .temporal_unwrap()?; + + let increment = resolved_options + .increment + .as_extended_increment() + .checked_mul(length) + .ok_or(TemporalError::range().with_message("increment exceeded valid range."))?; + + // 8. Let result be RoundNumberToIncrement(quantity, increment × unitLength, roundingMode) / unitLength. + let result = IncrementRounder::::from_signed_num(quantity, increment)? + .round(resolved_options.rounding_mode) + / length.get() as i128; + + let result_i64 = i64::from_i128(result) + .ok_or(TemporalError::range().with_message("round result valid range."))?; + + match resolved_options.smallest_unit { + // 9. If unit is "day", then + // a. Return Time Record { [[Days]]: result, [[Hour]]: 0, [[Minute]]: 0, [[Second]]: 0, [[Millisecond]]: 0, [[Microsecond]]: 0, [[Nanosecond]]: 0 }. + Unit::Day => Ok((result_i64, Self::default())), + // 10. If unit is "hour", then + // a. Return BalanceTime(result, 0, 0, 0, 0, 0). + Unit::Hour => Ok(Self::balance(result_i64, 0, 0, 0, 0, 0)), + // 11. If unit is "minute", then + // a. Return BalanceTime(hour, result, 0.0, 0.0, 0.0, 0). + Unit::Minute => Ok(Self::balance(self.hour.into(), result_i64, 0, 0, 0, 0)), + // 12. If unit is "second", then + // a. Return BalanceTime(hour, minute, result, 0.0, 0.0, 0). + Unit::Second => Ok(Self::balance( + self.hour.into(), + self.minute.into(), + result_i64, + 0, + 0, + 0, + )), + // 13. If unit is "millisecond", then + // a. Return BalanceTime(hour, minute, second, result, 0.0, 0). + Unit::Millisecond => Ok(Self::balance( + self.hour.into(), + self.minute.into(), + self.second.into(), + result_i64, + 0, + 0, + )), + // 14. If unit is "microsecond", then + // a. Return BalanceTime(hour, minute, second, millisecond, result, 0). + Unit::Microsecond => Ok(Self::balance( + self.hour.into(), + self.minute.into(), + self.second.into(), + self.millisecond.into(), + result_i64.into(), + 0, + )), + // 15. Assert: unit is "nanosecond". + // 16. Return BalanceTime(hour, minute, second, millisecond, microsecond, result). + Unit::Nanosecond => Ok(Self::balance( + self.hour.into(), + self.minute.into(), + self.second.into(), + self.millisecond.into(), + self.microsecond.into(), + result_i64.into(), + )), + _ => Err(TemporalError::assert()), + } + } + + pub(crate) fn add(&self, norm: TimeDuration) -> (i64, Self) { + // 1. Set second to second + TimeDurationSeconds(norm). + let seconds = i64::from(self.second) + norm.seconds(); + // 2. Set nanosecond to nanosecond + TimeDurationSubseconds(norm). + let nanos = i32::from(self.nanosecond) + norm.subseconds(); + // 3. Return BalanceTime(hour, minute, second, millisecond, microsecond, nanosecond). + Self::balance( + self.hour.into(), + self.minute.into(), + seconds, + self.millisecond.into(), + self.microsecond.into(), + nanos.into(), + ) + } + + /// `IsoTimeToEpochMs` + /// + /// Note: This method is library specific and not in spec + /// + /// Functionally the same as Date's `MakeTime` + pub(crate) fn to_epoch_ms(self) -> i64 { + ((i64::from(self.hour) * utils::MS_PER_HOUR + + i64::from(self.minute) * utils::MS_PER_MINUTE) + + i64::from(self.second) * 1000i64) + + i64::from(self.millisecond) + } +} + +// ==== `IsoDateTime` specific utility functions ==== + +const MAX_EPOCH_DAYS: i64 = 10i64.pow(8) + 1; + +#[inline] +/// Utility function to determine if a `DateTime`'s components create a `DateTime` within valid limits +fn iso_dt_within_valid_limits(date: IsoDate, time: &IsoTime) -> bool { + if utils::epoch_days_from_gregorian_date(date.year, date.month, date.day).abs() > MAX_EPOCH_DAYS + { + return false; + } + + let ns = to_unchecked_epoch_nanoseconds(date, time); + let max = crate::NS_MAX_INSTANT + i128::from(NS_PER_DAY); + let min = crate::NS_MIN_INSTANT - i128::from(NS_PER_DAY); + + min < ns && max > ns +} + +#[inline] +/// Utility function to convert a `IsoDate` and `IsoTime` values into epoch nanoseconds +fn utc_epoch_nanos(date: IsoDate, time: &IsoTime) -> EpochNanoseconds { + let epoch_nanos = to_unchecked_epoch_nanoseconds(date, time); + EpochNanoseconds::from(epoch_nanos) +} + +#[inline] +fn to_unchecked_epoch_nanoseconds(date: IsoDate, time: &IsoTime) -> i128 { + let ms = time.to_epoch_ms(); + let epoch_ms = utils::epoch_days_to_epoch_ms(date.to_epoch_days(), ms); + epoch_ms as i128 * 1_000_000 + time.microsecond as i128 * 1_000 + time.nanosecond as i128 +} + +// ==== `IsoDate` specific utiltiy functions ==== + +/// Returns the Epoch days based off the given year, month, and day. +/// Note: Month should be 1 indexed +#[inline] +pub(crate) fn iso_date_to_epoch_days(year: i32, month: i32, day: i32) -> i64 { + // 1. Let resolvedYear be year + floor(month / 12). + let resolved_year = year + month.div_euclid(12); + // 2. Let resolvedMonth be month modulo 12. + let resolved_month = month.rem_euclid(12) as u8; + // 3. Find a time t such that EpochTimeToEpochYear(t) is resolvedYear, + // EpochTimeToMonthInYear(t) is resolvedMonth, and EpochTimeToDate(t) is 1. + let epoch_days = utils::epoch_days_from_gregorian_date(resolved_year, resolved_month, 1); + + // 4. Return EpochTimeToDayNumber(t) + date - 1. + epoch_days + day as i64 - 1 +} + +#[inline] +// Determines if the month and day are valid for the given year. +pub(crate) fn is_valid_date(year: i32, month: u8, day: u8) -> bool { + if !(1..=12).contains(&month) { + return false; + } + is_valid_iso_day(year, month, day) +} + +#[inline] +/// Returns with the `this` surpasses `other`. +fn iso_date_surpasses(this: &IsoDate, other: &IsoDate, sign: i8) -> bool { + this.cmp(other) as i8 * sign == 1 +} + +#[inline] +pub(crate) fn year_month_within_limits(year: i32, month: u8) -> bool { + // 1. If isoDate.[[Year]] < -271821 or isoDate.[[Year]] > 275760, then + if !(-271821..=275760).contains(&year) { + // a. Return false. + return false; + // 2. If isoDate.[[Year]] = -271821 and isoDate.[[Month]] < 4, then + } else if year == -271821 && month < 4 { + // a. Return false. + return false; + // 3. If isoDate.[[Year]] = 275760 and isoDate.[[Month]] > 9, then + } else if year == 275760 && month > 9 { + // a. Return false. + return false; + } + // 4. Return true. + true +} + +fn balance_iso_year_month_with_clamp(year: i64, month: i64) -> (i32, u8) { + // 1. Assert: year and month are integers. + // 2. Set year to year + floor((month - 1) / 12). + let y = year + (month - 1).div_euclid(12); + // 3. Set month to ((month - 1) modulo 12) + 1. + let m = (month - 1).rem_euclid(12) + 1; + // 4. Return the Record { [[Year]]: year, [[Month]]: month }. + (y.clamp(i32::MIN as i64, i32::MAX as i64) as i32, m as u8) +} + +#[inline] +fn balance_iso_year_month(year: i32, month: i32) -> (i32, u8) { + // 1. Assert: year and month are integers. + // 2. Set year to year + floor((month - 1) / 12). + let y = year + (month - 1).div_euclid(12); + // 3. Set month to ((month - 1) modulo 12) + 1. + let m = (month - 1).rem_euclid(12) + 1; + // 4. Return the Record { [[Year]]: year, [[Month]]: month }. + (y, m as u8) +} + +/// Note: month is 1 based. +#[inline] +pub(crate) fn constrain_iso_day(year: i32, month: u8, day: u8) -> u8 { + let days_in_month = utils::iso_days_in_month(year, month); + day.clamp(1, days_in_month) +} + +#[inline] +pub(crate) fn is_valid_iso_day(year: i32, month: u8, day: u8) -> bool { + let days_in_month = utils::iso_days_in_month(year, month); + (1..=days_in_month).contains(&day) +} + +// ==== `IsoTime` specific utilities ==== + +#[inline] +pub(crate) fn is_valid_time(hour: u8, minute: u8, second: u8, ms: u16, mis: u16, ns: u16) -> bool { + if !(0..=23).contains(&hour) { + return false; + } + + let min_sec = 0..=59; + if !min_sec.contains(&minute) || !min_sec.contains(&second) { + return false; + } + + let sub_second = 0..=999; + sub_second.contains(&ms) && sub_second.contains(&mis) && sub_second.contains(&ns) +} + +// NOTE(nekevss): Considering the below: Balance can probably be altered from f64. +#[inline] +fn div_mod(dividend: i64, divisor: i64) -> (i64, i64) { + (dividend.div_euclid(divisor), dividend.rem_euclid(divisor)) +} + +impl From for IsoDateTime { + fn from(other: timezone_provider::provider::IsoDateTime) -> Self { + Self::new_unchecked( + IsoDate::new_unchecked(other.year, other.month, other.day), + IsoTime::new_unchecked( + other.hour, + other.minute, + other.second, + other.millisecond, + other.microsecond, + other.nanosecond, + ), + ) + } +} + +impl From for timezone_provider::provider::IsoDateTime { + fn from(other: IsoDateTime) -> Self { + Self { + year: other.date.year, + month: other.date.month, + day: other.date.day, + hour: other.time.hour, + minute: other.time.minute, + second: other.time.second, + millisecond: other.time.millisecond, + microsecond: other.time.microsecond, + nanosecond: other.time.nanosecond, + } + } +} + +#[cfg(test)] +mod tests { + use super::{iso_date_to_epoch_days, IsoDate}; + + const MAX_DAYS_BASE: i64 = 100_000_000; + + #[test] + fn icu4x_max_conversion_test() { + // Test that the max ISO date does not panic on conversion + let _ = IsoDate::new_unchecked(275_760, 9, 13).to_icu4x(); + // Test that the min ISO date does not panic on conversion + let _ = IsoDate::new_unchecked(-271_821, 4, 20).to_icu4x(); + } + + #[test] + fn iso_date_to_epoch_days_limits() { + // Succeeds + assert_eq!(iso_date_to_epoch_days(-271_821, 4, 20).abs(), MAX_DAYS_BASE); + // Succeeds + assert_eq!( + iso_date_to_epoch_days(-271_821, 4, 19).abs(), + MAX_DAYS_BASE + 1 + ); + // Fails + assert_eq!( + iso_date_to_epoch_days(-271_821, 4, 18).abs(), + MAX_DAYS_BASE + 2 + ); + // Succeeds + assert_eq!(iso_date_to_epoch_days(275_760, 9, 13).abs(), MAX_DAYS_BASE); + // Succeeds + assert_eq!( + iso_date_to_epoch_days(275_760, 9, 14).abs(), + MAX_DAYS_BASE + 1 + ); + // Fails + assert_eq!( + iso_date_to_epoch_days(275_760, 9, 15).abs(), + MAX_DAYS_BASE + 2 + ); + } + + #[test] + fn test_month_limits() { + assert_eq!(iso_date_to_epoch_days(1970, 1, 1), 0); + assert_eq!(iso_date_to_epoch_days(1969, 12, 31), -1); + } +} diff --git a/deps/temporal/src/lib.rs b/deps/temporal/src/lib.rs new file mode 100644 index 00000000000000..28a9d59b8957ba --- /dev/null +++ b/deps/temporal/src/lib.rs @@ -0,0 +1,456 @@ +//! A native Rust implementation of ECMAScript's Temporal API. +//! +//! Temporal is an API for working with date and time in a calendar +//! and time zone aware manner. +//! +//! temporal_rs is designed with ECMAScript implementations and general +//! purpose Rust usage in mind, meaning that temporal_rs can be used to implement +//! the Temporal built-ins in an ECMAScript implementation or generally +//! used as a date and time library in a Rust project. +//! +//! temporal_rs is the primary library for the Temporal API implementation in Boa, Kiesel, +//! and V8. Each of these engines pass the large ECMAScript conformance test suite for +//! the specification. +//! +//! ## Why use temporal_rs? +//! +//! As previously mentioned, Temporal is an API for working with date and time in +//! a calendar and time zone aware manner. This means that calendar and time zone support +//! are first class in Temporal as well as in temporal_rs. +//! +//! For instance, converting between calendars is as simple as providing the calendar as +//! shown below. +//! +//! ```rust +//! use temporal_rs::{PlainDate, Calendar}; +//! use tinystr::tinystr; +//! use core::str::FromStr; +//! +//! // Create a date with an ISO calendar +//! let iso8601_date = PlainDate::try_new_iso(2025, 3, 3).unwrap(); +//! +//! // Create a new date with the japanese calendar +//! let japanese_date = iso8601_date.with_calendar(Calendar::JAPANESE); +//! assert_eq!(japanese_date.era(), Some(tinystr!(16, "reiwa"))); +//! assert_eq!(japanese_date.era_year(), Some(7)); +//! assert_eq!(japanese_date.month(), 3) +//! ``` +//! +//! Beyond the general calendar use case, temporal_rs has robust support for +//! time zones which can generally by applied to a `PlainDate` via [`ZonedDateTime`]. +//! +//! **Important Note:** The below API is enabled with the +//! `compiled_data` feature flag. +//! +//! ```rust +//! # #[cfg(feature = "compiled_data")] { +//! use temporal_rs::{ZonedDateTime, TimeZone}; +//! use temporal_rs::options::{Disambiguation, OffsetDisambiguation}; +//! +//! let zdt = ZonedDateTime::from_utf8( +//! b"2025-03-01T11:16:10Z[America/Chicago][u-ca=iso8601]", +//! Disambiguation::Compatible, +//! OffsetDisambiguation::Reject +//! ).unwrap(); +//! assert_eq!(zdt.year(), 2025); +//! assert_eq!(zdt.month(), 3); +//! assert_eq!(zdt.day(), 1); +//! // Using Z and a timezone projects a UTC datetime into the timezone. +//! assert_eq!(zdt.hour(), 5); +//! assert_eq!(zdt.minute(), 16); +//! assert_eq!(zdt.second(), 10); +//! +//! // You can also update a time zone easily. +//! let zurich_zone = TimeZone::try_from_str("Europe/Zurich").unwrap(); +//! let zdt_zurich = zdt.with_timezone(zurich_zone).unwrap(); +//! assert_eq!(zdt_zurich.year(), 2025); +//! assert_eq!(zdt_zurich.month(), 3); +//! assert_eq!(zdt_zurich.day(), 1); +//! assert_eq!(zdt_zurich.hour(), 12); +//! assert_eq!(zdt_zurich.minute(), 16); +//! assert_eq!(zdt_zurich.second(), 10); +//! +//! # } +//! ``` +//! +//! ## Overview +//! +//! temporal_rs provides 8 core types for working with date and time. The core types are: +//! +//! - [PlainDate] +//! - [PlainTime] +//! - [PlainDateTime] +//! - [ZonedDateTime] +//! - [Instant] +//! - [Duration] +//! - [PlainYearMonth] +//! - [PlainMonthDay] +//! +//! In addition to these types, there are the [`Calendar`] and [`TimeZone`] type that +//! support the calendars or time zones. The specific support for calendars and time +//! zones per type are as follows. +//! +//! | Temporal type | Category | Calendar support | Time zone support | +//! |----------------|--------------------------------------|--------------------|--------------------| +//! | PlainDate | Calendar date | yes | no | +//! | PlainTime | Wall-clock time | no | no | +//! | PlainDateTime | Calendar date and wall-clock time | yes | no | +//! | ZonedDateTime | Calendar date and exact time | yes | yes | +//! | Instant | Exact time | no | no | +//! | Duration | None | no | no | +//! | PlainYearMonth | Calendar date | yes | no | +//! | PlainMonthDay | Calendar date | yes | no | +//! +//! There is also the [`Now`][now::Now], which provides access to the current host system +//! time. This can then be used to map to any of the above Temporal types. +//! +//! **Important Note:** the below example is only available with the `sys` and +//! `compiled_data` feature flag enabled. +//! +//! ```rust +//! # #[cfg(all(feature = "sys", feature = "compiled_data"))] { +//! use core::cmp::Ordering; +//! use temporal_rs::{Temporal, Calendar, ZonedDateTime}; +//! let current_instant = Temporal::now().instant().unwrap(); +//! let current_zoned_date_time = Temporal::now().zoned_date_time_iso(None).unwrap(); +//! +//! /// Create a `ZonedDateTime` from the requested instant. +//! let zoned_date_time_from_instant = ZonedDateTime::try_new( +//! current_instant.as_i128(), +//! *current_zoned_date_time.time_zone(), +//! Calendar::ISO, +//! ).unwrap(); +//! +//! // The two `ZonedDateTime` will be equal down to the second. +//! assert_eq!(current_zoned_date_time.year(), zoned_date_time_from_instant.year()); +//! assert_eq!(current_zoned_date_time.month(), zoned_date_time_from_instant.month()); +//! assert_eq!(current_zoned_date_time.day(), zoned_date_time_from_instant.day()); +//! assert_eq!(current_zoned_date_time.hour(), zoned_date_time_from_instant.hour()); +//! assert_eq!(current_zoned_date_time.minute(), zoned_date_time_from_instant.minute()); +//! assert_eq!(current_zoned_date_time.second(), zoned_date_time_from_instant.second()); +//! +//! // The `Instant` reading that occurred first will be less than the ZonedDateTime +//! // reading +//! assert_eq!( +//! zoned_date_time_from_instant.compare_instant(¤t_zoned_date_time), +//! Ordering::Less +//! ); +//! # } +//! ``` +//! +//! ## General design +//! +//! While temporal_rs can be used in native Rust programs, the library is -- first and +//! foremost -- designed for use in ECMAScript implementations. This is not to detract +//! from temporal_rs's use in a native Rust program, but it is important information to +//! understand in order to understand the library's architecture and general API design. +//! +//! Without default feature flags, temporal_rs does not have with access to the host +//! environment and it does not embed any time zone data. This is important from an +//! interpreter perspective, because access to the host environment and time zone data +//! comes from the interpreter's agent, not from a dependency. +//! +//! Instead, temporal_rs provides the [`HostHooks`][host::HostHooks] and [`TimeZoneProvider`][provider::TimeZoneProvider] +//! traits that can be implemented and provided as function arguments that temporal_rs will +//! use to access the host system or time zone data. temporal_rs also provides some baseline +//! implementations of the traits that can be selected from depending on application needs. +//! +//! That being said, this does not mean that everyone must implement their own trait +//! implementations for that functionality to exist, but the APIs are there for power +//! users who may need a custom host system or time zone data implementation. +//! +//! A default host system and time zone provider have been implemented and are automatically +//! active as default features. +//! +//! ### A quick walkthrough +//! +//! For instance, the examples thus far have been using the general usage Rust API with +//! the `sys` and `compiled_data` feature. +//! +//! For instance, let's manually write our [`Now`][now::Now] implementation instead of using +//! [`Temporal::now()`] with an empty host system implementation. +//! +//! ```rust +//! # #[cfg(feature = "compiled_data")] { +//! use temporal_rs::{Instant, now::Now, host::EmptyHostSystem}; +//! +//! // The empty host system is a system implementation HostHooks that always +//! // returns the UNIX_EPOCH and the "+00:00" time zone. +//! let now = Now::new(EmptyHostSystem); +//! let time_zone = now.time_zone().unwrap(); +//! assert_eq!(time_zone.identifier().unwrap(), "+00:00"); +//! let now = Now::new(EmptyHostSystem); +//! assert_eq!(now.instant(), Instant::try_new(0)); +//! # } +//! ``` +//! +//! However, even in our above example, we cheated a bit. We were still relying on the +//! `compiled_data` feature flag that provided time zone data for us. Let's try again, +//! but this time without the feature flag. +//! +//! ```rust +//! # #[cfg(feature = "tzdb")] { +//! use temporal_rs::{Instant, now::Now, host::EmptyHostSystem}; +//! use timezone_provider::tzif::CompiledTzdbProvider; +//! +//! let provider = CompiledTzdbProvider::default(); +//! +//! // The empty host system is a system implementation HostHooks that always +//! // returns the UNIX_EPOCH and the "+00:00" time zone. +//! let now = Now::new(EmptyHostSystem); +//! let time_zone = now.time_zone_with_provider(&provider).unwrap(); +//! assert_eq!(time_zone.identifier_with_provider(&provider).unwrap(), "+00:00"); +//! +//! let now = Now::new(EmptyHostSystem); +//! assert_eq!(now.instant(), Instant::try_new(0)); +//! # } +//! ``` +//! +//! Now -- pun only partially intended -- we've successfully written a no-default-features +//! example with temporal_rs! +//! +//! ### What have we learned going over this all this? +//! +//! First, any API that has the suffix `_with_provider` is a power user API for supplying +//! a custom or specific time zone data provider. Furthermore, any API that has a +//! `_with_provider` suffix will also have a version without the suffix that automagically +//! provides time zone data for you. +//! +//! Finally, sourcing time zone data is a very scary (but fun!) business. If you're interested +//! in learning more, feel free to check out the `timezone_provider` crate! +//! +//! With any luck, this also highlights the general design of temporal_rs. It provides a +//! general usage API that aligns with the Temporal specification while also being +//! flexible enough to provide an power user to take control of their host system access +//! and time zone data sourcing as needed. +//! +//! ## Formatting +//! +//! temporal_rs adheres to Temporal grammar, which is a strict version of +//! [RFC9557's IXDTF][ixdtf]. RFC9557 is an update to RFC3339 that adds +//! extensions to the format. +//! +//! ## More information +//! +//! [`Temporal`][proposal] is the Stage 3 proposal for ECMAScript that +//! provides new JS objects and functions for working with dates and +//! times that fully supports time zones and non-gregorian calendars. +//! +//! This library's primary development source is the Temporal +//! Proposal [specification][spec]. +//! +//! [ixdtf]: https://www.rfc-editor.org/rfc/rfc9557.txt +//! [proposal]: https://github.com/tc39/proposal-temporal +//! [spec]: https://tc39.es/proposal-temporal/ +#![doc( + html_logo_url = "https://raw.githubusercontent.com/boa-dev/boa/main/assets/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/boa-dev/boa/main/assets/logo.svg" +)] +#![no_std] +#![cfg_attr(not(test), forbid(clippy::unwrap_used))] +// We wish to reduce the number of panics, .expect() must be justified +// to never occur. Opt to have GIGO or .temporal_unwrap() behavior where possible. +#![cfg_attr(not(test), warn(clippy::expect_used, clippy::indexing_slicing))] +#![allow( + // Currently throws a false positive regarding dependencies that are only used in benchmarks. + unused_crate_dependencies, + clippy::module_name_repetitions, + clippy::redundant_pub_crate, + clippy::too_many_lines, + clippy::cognitive_complexity, + clippy::missing_errors_doc, + clippy::let_unit_value, + clippy::option_if_let_else, +)] +#![forbid(unsafe_code)] + +extern crate alloc; +extern crate core; + +#[cfg(any(test, feature = "std"))] +extern crate std; + +pub mod error; +pub mod host; +pub mod iso; +pub mod options; +pub mod parsers; +pub mod primitive; +pub mod provider; + +#[cfg(feature = "sys")] +pub(crate) mod sys; + +mod builtins; + +#[cfg(feature = "tzdb")] +pub(crate) mod tzdb; + +#[doc(hidden)] +pub(crate) mod rounding; +#[doc(hidden)] +pub(crate) mod utils; + +use core::cmp::Ordering; + +// TODO: evaluate positives and negatives of using tinystr. Re-exporting +// tinystr as a convenience, as it is currently tied into the API. +/// Re-export of `TinyAsciiStr` from `tinystr`. +pub use tinystr::TinyAsciiStr; + +/// The `Temporal` result type +pub type TemporalResult = Result; + +#[doc(inline)] +pub use error::TemporalError; + +#[cfg(feature = "sys")] +#[doc(inline)] +pub use sys::Temporal; + +pub mod partial { + //! Partial date and time component records + //! + //! The partial records are `temporal_rs`'s method of addressing + //! `TemporalFields` in the specification. + pub use crate::builtins::core::{ + PartialDate, PartialDateTime, PartialDuration, PartialTime, PartialYearMonth, + PartialZonedDateTime, + }; +} + +pub mod parsed_intermediates; + +// TODO: Potentially bikeshed how `EpochNanoseconds` should be exported. +/// A module for structs related to the UNIX epoch +pub mod unix_time { + pub use timezone_provider::epoch_nanoseconds::EpochNanoseconds; +} + +/// The `Now` module includes type for building a Now +pub mod now { + pub use crate::builtins::Now; +} + +/// Duration related types +pub mod duration { + pub use crate::builtins::DateDuration; +} + +/// Calendar field records +pub mod fields { + pub use crate::builtins::{ + calendar::{CalendarFields, YearMonthCalendarFields}, + DateTimeFields, ZonedDateTimeFields, + }; +} + +// TODO: Should we be exporting MonthCode and UtcOffset here. +pub use crate::builtins::{ + calendar::{Calendar, MonthCode}, + core::time_zone::{TimeZone, UtcOffset}, + Duration, Instant, PlainDate, PlainDateTime, PlainMonthDay, PlainTime, PlainYearMonth, + ZonedDateTime, +}; + +/// A library specific trait for unwrapping assertions. +pub(crate) trait TemporalUnwrap { + type Output; + + /// `temporal_rs` based assertion for unwrapping. This will panic in + /// debug builds, but throws error during runtime. + fn temporal_unwrap(self) -> TemporalResult; +} + +impl TemporalUnwrap for Option { + type Output = T; + + fn temporal_unwrap(self) -> TemporalResult { + debug_assert!(self.is_some()); + self.ok_or(TemporalError::assert()) + } +} + +impl TemporalUnwrap for TemporalResult { + type Output = T; + + fn temporal_unwrap(self) -> Self { + debug_assert!(self.is_ok(), "Assertion failed: {:?}", self.err()); + self.map_err(|e| TemporalError::assert().with_message(e.into_message())) + } +} + +#[doc(hidden)] +#[macro_export] +macro_rules! temporal_assert { + ($condition:expr $(,)*) => { + if !$condition { + return Err(TemporalError::assert()); + } + }; + ($condition:expr, $($args:tt)+) => { + if !$condition { + #[cfg(feature = "log")] + log::error!($($args)+); + return Err(TemporalError::assert()); + } + }; +} + +// TODO: Determine final home or leave in the top level? ops::Sign, +// types::Sign, etc. +/// A general Sign type. +#[repr(i8)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum Sign { + #[default] + Positive = 1, + Zero = 0, + Negative = -1, +} + +impl From for Sign { + fn from(value: i8) -> Self { + match value.cmp(&0) { + Ordering::Greater => Self::Positive, + Ordering::Equal => Self::Zero, + Ordering::Less => Self::Negative, + } + } +} + +impl Sign { + /// Coerces the current `Sign` to be either negative or positive. + pub(crate) const fn as_sign_multiplier(&self) -> i8 { + if matches!(self, Self::Zero) { + return 1; + } + *self as i8 + } + + pub(crate) fn negate(&self) -> Sign { + Sign::from(-(*self as i8)) + } +} + +// Relevant numeric constants + +/// Nanoseconds per day constant: 8.64e+13 +#[doc(hidden)] +pub const NS_PER_DAY: u64 = MS_PER_DAY as u64 * 1_000_000; +#[doc(hidden)] +pub const NS_PER_DAY_NONZERO: core::num::NonZeroU128 = + if let Some(nz) = core::num::NonZeroU128::new(NS_PER_DAY as u128) { + nz + } else { + unreachable!() + }; +/// Milliseconds per day constant: 8.64e+7 +#[doc(hidden)] +pub const MS_PER_DAY: u32 = 24 * 60 * 60 * 1000; +/// Max Instant nanosecond constant +#[doc(hidden)] +pub(crate) const NS_MAX_INSTANT: i128 = NS_PER_DAY as i128 * 100_000_000i128; +/// Min Instant nanosecond constant +#[doc(hidden)] +pub(crate) const NS_MIN_INSTANT: i128 = -NS_MAX_INSTANT; diff --git a/deps/temporal/src/options.rs b/deps/temporal/src/options.rs new file mode 100644 index 00000000000000..c7f6c025a1789c --- /dev/null +++ b/deps/temporal/src/options.rs @@ -0,0 +1,989 @@ +//! Native implementation of the `Temporal` options. +//! +//! Temporal has various instances where user's can define options for how an +//! operation may be completed. + +use crate::parsers::Precision; +use crate::TemporalUnwrap; +use crate::{error::ErrorMessage, TemporalError, TemporalResult, MS_PER_DAY, NS_PER_DAY}; +use core::num::NonZeroU128; +use core::ops::Add; +use core::{fmt, str::FromStr}; + +mod increment; +mod relative_to; + +pub use increment::RoundingIncrement; +pub use relative_to::RelativeTo; + +// ==== RoundingOptions / DifferenceSettings ==== + +#[derive(Debug, Clone, Copy)] +pub(crate) enum DifferenceOperation { + Until, + Since, +} + +#[derive(Debug, Default)] +pub struct ToStringRoundingOptions { + pub precision: Precision, + pub smallest_unit: Option, + pub rounding_mode: Option, +} + +#[derive(Debug)] +pub(crate) struct ResolvedToStringRoundingOptions { + pub(crate) precision: Precision, + pub(crate) smallest_unit: Unit, + pub(crate) rounding_mode: RoundingMode, + pub(crate) increment: RoundingIncrement, +} + +impl ToStringRoundingOptions { + pub(crate) fn resolve(&self) -> TemporalResult { + let rounding_mode = self.rounding_mode.unwrap_or(RoundingMode::Trunc); + match self.smallest_unit { + Some(Unit::Minute) => Ok(ResolvedToStringRoundingOptions { + precision: Precision::Minute, + smallest_unit: Unit::Minute, + rounding_mode, + increment: RoundingIncrement::ONE, + }), + Some(Unit::Second) => Ok(ResolvedToStringRoundingOptions { + precision: Precision::Digit(0), + smallest_unit: Unit::Second, + rounding_mode, + increment: RoundingIncrement::ONE, + }), + Some(Unit::Millisecond) => Ok(ResolvedToStringRoundingOptions { + precision: Precision::Digit(3), + smallest_unit: Unit::Millisecond, + rounding_mode, + increment: RoundingIncrement::ONE, + }), + Some(Unit::Microsecond) => Ok(ResolvedToStringRoundingOptions { + precision: Precision::Digit(6), + smallest_unit: Unit::Microsecond, + rounding_mode, + increment: RoundingIncrement::ONE, + }), + Some(Unit::Nanosecond) => Ok(ResolvedToStringRoundingOptions { + precision: Precision::Digit(9), + smallest_unit: Unit::Nanosecond, + rounding_mode, + increment: RoundingIncrement::ONE, + }), + None => match self.precision { + Precision::Auto => Ok(ResolvedToStringRoundingOptions { + precision: Precision::Auto, + smallest_unit: Unit::Nanosecond, + rounding_mode, + increment: RoundingIncrement::ONE, + }), + Precision::Digit(0) => Ok(ResolvedToStringRoundingOptions { + precision: Precision::Digit(0), + smallest_unit: Unit::Second, + rounding_mode, + increment: RoundingIncrement::ONE, + }), + Precision::Digit(d) if (1..=3).contains(&d) => { + Ok(ResolvedToStringRoundingOptions { + precision: Precision::Digit(d), + smallest_unit: Unit::Millisecond, + rounding_mode, + increment: RoundingIncrement::try_new(10_u32.pow(3 - d as u32)) + .temporal_unwrap()?, + }) + } + Precision::Digit(d) if (4..=6).contains(&d) => { + Ok(ResolvedToStringRoundingOptions { + precision: Precision::Digit(d), + smallest_unit: Unit::Microsecond, + rounding_mode, + increment: RoundingIncrement::try_new(10_u32.pow(6 - d as u32)) + .temporal_unwrap()?, + }) + } + Precision::Digit(d) if (7..=9).contains(&d) => { + Ok(ResolvedToStringRoundingOptions { + precision: Precision::Digit(d), + smallest_unit: Unit::Nanosecond, + rounding_mode, + increment: RoundingIncrement::try_new(10_u32.pow(9 - d as u32)) + .temporal_unwrap()?, + }) + } + _ => Err(TemporalError::range() + .with_enum(ErrorMessage::FractionalDigitsPrecisionInvalid)), + }, + _ => Err(TemporalError::range().with_enum(ErrorMessage::SmallestUnitNotTimeUnit)), + } + } +} + +#[non_exhaustive] +#[derive(Debug, Default, Clone, Copy)] +pub struct DifferenceSettings { + pub largest_unit: Option, + pub smallest_unit: Option, + pub rounding_mode: Option, + pub increment: Option, +} + +#[non_exhaustive] +#[derive(Debug, Clone, Copy)] +pub struct RoundingOptions { + pub largest_unit: Option, + pub smallest_unit: Option, + pub rounding_mode: Option, + pub increment: Option, +} + +// Note: Specification does not clearly state a default, but +// having both largest and smallest unit None would auto throw. + +impl Default for RoundingOptions { + fn default() -> Self { + Self { + largest_unit: Some(Unit::Auto), + smallest_unit: None, + rounding_mode: None, + increment: None, + } + } +} + +/// Internal options object that represents the resolved rounding options. +#[derive(Debug, Clone, Copy)] +pub(crate) struct ResolvedRoundingOptions { + pub(crate) largest_unit: Unit, + pub(crate) smallest_unit: Unit, + pub(crate) increment: RoundingIncrement, + pub(crate) rounding_mode: RoundingMode, +} + +impl ResolvedRoundingOptions { + pub(crate) fn from_to_string_options(options: &ResolvedToStringRoundingOptions) -> Self { + Self { + largest_unit: Unit::Auto, + smallest_unit: options.smallest_unit, + increment: options.increment, + rounding_mode: options.rounding_mode, + } + } + + pub(crate) fn from_diff_settings( + options: DifferenceSettings, + operation: DifferenceOperation, + unit_group: UnitGroup, + fallback_largest: Unit, + fallback_smallest: Unit, + ) -> TemporalResult { + // 1. NOTE: The following steps read options and perform independent validation in alphabetical order. + // 2. Let largestUnit be ? GetUnitValuedOption(options, "largestUnit", unitGroup, auto). + unit_group.validate_unit(options.largest_unit, Some(Unit::Auto))?; + + // 4. Let resolvedOptions be ? SnapshotOwnProperties(? GetOptionsObject(options), null). + // 5. Let settings be ? GetDifferenceSettings(operation, resolvedOptions, DATE, « », "day", "day"). + + // 3. If disallowedUnits contains largestUnit, throw a RangeError exception. + // 4. Let roundingIncrement be ? GetRoundingIncrementOption(options). + let increment = options.increment.unwrap_or_default(); + // 5. Let roundingMode be ? GetRoundingModeOption(options, trunc). + // 6. If operation is since, then + // a. Set roundingMode to NegateRoundingMode(roundingMode). + let rounding_mode = match operation { + DifferenceOperation::Since => options + .rounding_mode + .unwrap_or(RoundingMode::Trunc) + .negate(), + DifferenceOperation::Until => options.rounding_mode.unwrap_or(RoundingMode::Trunc), + }; + // 7. Let smallestUnit be ? GetUnitValuedOption(options, "smallestUnit", unitGroup, fallbackSmallestUnit). + let smallest_unit = options.smallest_unit.unwrap_or(fallback_smallest); + // 8. If disallowedUnits contains smallestUnit, throw a RangeError exception. + unit_group.validate_unit(options.smallest_unit, None)?; + // 9. Let defaultLargestUnit be LargerOfTwoUnits(smallestLargestDefaultUnit, smallestUnit). + let default_largest_unit = smallest_unit.max(fallback_largest); + // 10. If largestUnit is auto, set largestUnit to defaultLargestUnit. + let mut largest_unit = options.largest_unit.unwrap_unit_or(default_largest_unit); + if largest_unit == Unit::Auto { + largest_unit = default_largest_unit; + } + // 11. If LargerOfTwoUnits(largestUnit, smallestUnit) is not largestUnit, throw a RangeError exception. + if largest_unit < smallest_unit { + return Err( + TemporalError::range().with_enum(ErrorMessage::SmallestUnitLargerThanLargestUnit) + ); + } + + // 12. Let maximum be MaximumTemporalDurationRoundingIncrement(smallestUnit). + let maximum = smallest_unit.to_maximum_rounding_increment(); + // 13. If maximum is not unset, perform ? ValidateTemporalRoundingIncrement(roundingIncrement, maximum, false). + if let Some(max) = maximum { + increment.validate(max.into(), false)?; + } + // 14. Return the Record { [[SmallestUnit]]: smallestUnit, [[LargestUnit]]: largestUnit, [[RoundingMode]]: + // roundingMode, [[RoundingIncrement]]: roundingIncrement, }. + Ok(ResolvedRoundingOptions { + largest_unit, + smallest_unit, + increment, + rounding_mode, + }) + } + + // NOTE: Should the GetUnitValuedOption check be integrated into these validations. + pub(crate) fn from_datetime_options(options: RoundingOptions) -> TemporalResult { + let increment = options.increment.unwrap_or_default(); + let rounding_mode = options.rounding_mode.unwrap_or_default(); + let smallest_unit = + UnitGroup::Time.validate_required_unit(options.smallest_unit, Some(Unit::Day))?; + let (maximum, inclusive) = if smallest_unit == Unit::Day { + (1, true) + } else { + let maximum = smallest_unit + .to_maximum_rounding_increment() + .ok_or(TemporalError::range().with_enum(ErrorMessage::SmallestUnitNotTimeUnit))?; + (maximum, false) + }; + + increment.validate(maximum.into(), inclusive)?; + + Ok(Self { + largest_unit: Unit::Auto, + smallest_unit, + increment, + rounding_mode, + }) + } + + pub(crate) fn from_time_options(options: RoundingOptions) -> TemporalResult { + let Some(smallest_unit) = options.smallest_unit else { + return Err(TemporalError::range().with_enum(ErrorMessage::SmallestUnitIsRequired)); + }; + let increment = options.increment.unwrap_or(RoundingIncrement::ONE); + let rounding_mode = options.rounding_mode.unwrap_or(RoundingMode::HalfExpand); + + let max = smallest_unit + .to_maximum_rounding_increment() + .ok_or_else(|| { + TemporalError::range().with_enum(ErrorMessage::SmallestUnitNotTimeUnit) + })?; + + // Safety (nekevss): to_rounding_increment returns a value in the range of a u32. + increment.validate(u64::from(max), false)?; + + Ok(ResolvedRoundingOptions { + largest_unit: Unit::Auto, + increment, + smallest_unit, + rounding_mode, + }) + } + + pub(crate) fn from_instant_options(options: RoundingOptions) -> TemporalResult { + let increment = options.increment.unwrap_or_default(); + let rounding_mode = options.rounding_mode.unwrap_or_default(); + let smallest_unit = UnitGroup::Time.validate_required_unit(options.smallest_unit, None)?; + let maximum = match smallest_unit { + Unit::Hour => 24u64, + Unit::Minute => 24 * 60, + Unit::Second => 24 * 3600, + Unit::Millisecond => MS_PER_DAY as u64, + Unit::Microsecond => MS_PER_DAY as u64 * 1000, + Unit::Nanosecond => NS_PER_DAY, + _ => return Err(TemporalError::range().with_enum(ErrorMessage::RoundToUnitInvalid)), + }; + + increment.validate(maximum, true)?; + + Ok(Self { + largest_unit: Unit::Auto, + smallest_unit, + increment, + rounding_mode, + }) + } + + pub(crate) fn is_noop(&self) -> bool { + self.smallest_unit == Unit::Nanosecond && self.increment == RoundingIncrement::ONE + } +} + +// ==== Options enums and methods ==== + +#[derive(Debug, Clone, Copy)] +pub enum UnitGroup { + Date, + Time, + DateTime, +} + +impl UnitGroup { + pub fn validate_required_unit( + self, + unit: Option, + extra_unit: Option, + ) -> TemporalResult { + let Some(unit) = unit else { + return Err(TemporalError::range().with_enum(ErrorMessage::UnitRequired)); + }; + self.validate_unit(Some(unit), extra_unit)?; + Ok(unit) + } + + /// Note: this always rejects Auto unless extra_unit is specified + /// + /// + pub fn validate_unit(self, unit: Option, extra_unit: Option) -> TemporalResult<()> { + match self { + _ if unit == extra_unit => Ok(()), + UnitGroup::Date => match unit { + Some(unit) if unit.is_date_unit() => Ok(()), + None => Ok(()), + _ => Err(TemporalError::range().with_enum(ErrorMessage::UnitNotDate)), + }, + UnitGroup::Time => match unit { + Some(unit) if unit.is_time_unit() => Ok(()), + None => Ok(()), + _ => Err(TemporalError::range().with_enum(ErrorMessage::UnitNotTime)), + }, + UnitGroup::DateTime if unit != Some(Unit::Auto) => Ok(()), + _ => Err(TemporalError::range().with_enum(ErrorMessage::UnitNoAutoDuringComparison)), + } + } +} + +/// `Table 21: Temporal units by descending magnitude` +/// +/// Subset of the spec table containing only the value column. +/// +/// Spec: +// +// Spec last accessed: 2025-05-16, +pub(crate) const UNIT_VALUE_TABLE: [Unit; 10] = [ + Unit::Year, + Unit::Month, + Unit::Week, + Unit::Day, + Unit::Hour, + Unit::Minute, + Unit::Second, + Unit::Millisecond, + Unit::Microsecond, + Unit::Nanosecond, +]; + +// TODO: Need to decide whether to make auto default or remove. Blocker was one +// of Duration::round / Duration::total +/// The relevant unit that should be used for the operation that +/// this option is provided as a value. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum Unit { + /// The `Auto` unit + Auto = 0, + /// The `Nanosecond` unit + Nanosecond, + /// The `Microsecond` unit + Microsecond, + /// The `Millisecond` unit + Millisecond, + /// The `Second` unit + Second, + /// The `Minute` unit + Minute, + /// The `Hour` unit + Hour, + /// The `Day` unit + Day, + /// The `Week` unit + Week, + /// The `Month` unit + Month, + /// The `Year` unit + Year, +} + +impl Unit { + #[inline] + #[must_use] + /// Returns the `MaximumRoundingIncrement` for the current `Unit`. + pub fn to_maximum_rounding_increment(self) -> Option { + use Unit::{ + Auto, Day, Hour, Microsecond, Millisecond, Minute, Month, Nanosecond, Second, Week, + Year, + }; + // 1. If unit is "year", "month", "week", or "day", then + // a. Return undefined. + // 2. If unit is "hour", then + // a. Return 24. + // 3. If unit is "minute" or "second", then + // a. Return 60. + // 4. Assert: unit is one of "millisecond", "microsecond", or "nanosecond". + // 5. Return 1000. + let max = match self { + Year | Month | Week | Day => return None, + Hour => 24, + Minute | Second => 60, + Millisecond | Microsecond | Nanosecond => 1000, + Auto => { + debug_assert!(false, "Auto units should be resolved by this point"); + return None; + } + }; + + Some(max) + } + + // TODO: potentiall use a u64 + /// Returns the `Nanosecond amount for any given value.` + #[must_use] + pub const fn as_nanoseconds(&self) -> Option { + use Unit::{ + Auto, Day, Hour, Microsecond, Millisecond, Minute, Month, Nanosecond, Second, Week, + Year, + }; + match self { + Year | Month | Week | Auto => None, + Day => NonZeroU128::new(NS_PER_DAY as u128), + Hour => NonZeroU128::new(3_600_000_000_000), + Minute => NonZeroU128::new(60_000_000_000), + Second => NonZeroU128::new(1_000_000_000), + Millisecond => NonZeroU128::new(1_000_000), + Microsecond => NonZeroU128::new(1_000), + Nanosecond => NonZeroU128::new(1), + } + } + + #[inline] + #[must_use] + pub fn is_calendar_unit(&self) -> bool { + use Unit::{Month, Week, Year}; + matches!(self, Year | Month | Week) + } + + #[inline] + #[must_use] + pub fn is_date_unit(&self) -> bool { + use Unit::{Day, Month, Week, Year}; + matches!(self, Day | Year | Month | Week) + } + + #[inline] + #[must_use] + pub fn is_time_unit(&self) -> bool { + use Unit::{Hour, Microsecond, Millisecond, Minute, Nanosecond, Second}; + matches!( + self, + Hour | Minute | Second | Millisecond | Microsecond | Nanosecond + ) + } + + /// `13.19 LargerOfTwoTemporalUnits ( u1, u2 )` + /// + /// Spec: + // + // Spec last accessed: 2025-05-16, + #[inline] + pub fn larger(u1: Unit, u2: Unit) -> TemporalResult { + // 1. For each row of Table 21, except the header row, in table order, do + // a. Let unit be the value in the "Value" column of the row. + for unit in UNIT_VALUE_TABLE { + // b. If u1 is unit, return unit. + if u1 == unit { + return Ok(unit); + } + // c. If u2 is unit, return unit. + if u2 == unit { + return Ok(unit); + } + } + + // NOTE(HalidOdat): deviation from specification. + Err(TemporalError::assert().with_enum(ErrorMessage::UnitNoAutoDuringComparison)) + } + + /// Helper method for getting the index into the [`UNIT_VALUE_TABLE`]. + /// + /// # Error + /// + /// If the given [`Unit`] is [`Unit::Auto`]. + pub(crate) fn table_index(&self) -> TemporalResult { + // Taken from: + // + // spec(2025-05-28): https://github.com/tc39/proposal-temporal/tree/69001e954c70e29ba3d2e6433bc7ece2a037377a + // + // 2. Let largestUnitIndex be the ordinal index of the row of Table 21 whose "Value" column contains largestUnit. + // 3. Let smallestUnitIndex be the ordinal index of the row of Table 21 whose "Value" column contains smallestUnit. + for (i, unit) in UNIT_VALUE_TABLE.iter().enumerate() { + if self == unit { + return Ok(i); + } + } + + Err(TemporalError::assert().with_enum(ErrorMessage::UnitNoAutoDuringComparison)) + } +} + +trait UnwrapUnit { + type Result; + fn unwrap_unit_or(self, unit: Unit) -> Self::Result; +} + +impl UnwrapUnit for Option { + type Result = Unit; + fn unwrap_unit_or(self, unit: Unit) -> Self::Result { + if self == Some(Unit::Auto) { + return unit; + } + self.unwrap_or(unit) + } +} + +impl From for Unit { + fn from(value: usize) -> Self { + match value { + 10 => Self::Year, + 9 => Self::Month, + 8 => Self::Week, + 7 => Self::Day, + 6 => Self::Hour, + 5 => Self::Minute, + 4 => Self::Second, + 3 => Self::Millisecond, + 2 => Self::Microsecond, + 1 => Self::Nanosecond, + _ => Self::Auto, + } + } +} + +impl Add for Unit { + type Output = Unit; + + fn add(self, rhs: usize) -> Self::Output { + Unit::from(self as usize + rhs) + } +} + +/// A parsing error for `Unit` +#[derive(Debug, Clone, Copy)] +pub struct ParseUnitError; + +impl fmt::Display for ParseUnitError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("provided string was not a valid Unit") + } +} + +impl FromStr for Unit { + type Err = ParseUnitError; + + fn from_str(s: &str) -> Result { + match s { + "auto" => Ok(Self::Auto), + "year" | "years" => Ok(Self::Year), + "month" | "months" => Ok(Self::Month), + "week" | "weeks" => Ok(Self::Week), + "day" | "days" => Ok(Self::Day), + "hour" | "hours" => Ok(Self::Hour), + "minute" | "minutes" => Ok(Self::Minute), + "second" | "seconds" => Ok(Self::Second), + "millisecond" | "milliseconds" => Ok(Self::Millisecond), + "microsecond" | "microseconds" => Ok(Self::Microsecond), + "nanosecond" | "nanoseconds" => Ok(Self::Nanosecond), + _ => Err(ParseUnitError), + } + } +} + +impl fmt::Display for Unit { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::Auto => "auto", + Self::Year => "year", + Self::Month => "month", + Self::Week => "week", + Self::Day => "day", + Self::Hour => "hour", + Self::Minute => "minute", + Self::Second => "second", + Self::Millisecond => "millsecond", + Self::Microsecond => "microsecond", + Self::Nanosecond => "nanosecond", + } + .fmt(f) + } +} + +/// `Overflow` can also be used as an +/// assignment overflow and consists of the "constrain" +/// and "reject" options. +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] +pub enum Overflow { + /// Constrain option + #[default] + Constrain, + /// Constrain option + Reject, +} + +/// A parsing error for `ArithemeticOverflow` +#[derive(Debug, Clone, Copy)] +pub struct ParseOverflowError; + +impl fmt::Display for ParseOverflowError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("provided string was not a valid overflow value") + } +} + +impl FromStr for Overflow { + type Err = ParseOverflowError; + + fn from_str(s: &str) -> Result { + match s { + "constrain" => Ok(Self::Constrain), + "reject" => Ok(Self::Reject), + _ => Err(ParseOverflowError), + } + } +} + +impl fmt::Display for Overflow { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::Constrain => "constrain", + Self::Reject => "reject", + } + .fmt(f) + } +} + +/// The disambiguation options for an instant. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub enum Disambiguation { + /// Compatible option + /// + /// This is the default according to GetTemporalDisambiguationOption + #[default] + Compatible, + /// Earlier option + Earlier, + /// Later option + Later, + /// Reject option + Reject, +} + +/// A parsing error on `InstantDisambiguation` options. +#[derive(Debug, Clone, Copy)] +pub struct ParseDisambiguationError; + +impl fmt::Display for ParseDisambiguationError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("provided string was not a valid instant disambiguation value") + } +} + +impl FromStr for Disambiguation { + type Err = ParseDisambiguationError; + + fn from_str(s: &str) -> Result { + match s { + "compatible" => Ok(Self::Compatible), + "earlier" => Ok(Self::Earlier), + "later" => Ok(Self::Later), + "reject" => Ok(Self::Reject), + _ => Err(ParseDisambiguationError), + } + } +} + +impl fmt::Display for Disambiguation { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::Compatible => "compatible", + Self::Earlier => "earlier", + Self::Later => "later", + Self::Reject => "reject", + } + .fmt(f) + } +} + +/// Offset disambiguation options. +#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] +pub enum OffsetDisambiguation { + /// Use option + Use, + /// Prefer option + Prefer, + /// Ignore option + Ignore, + /// Reject option + Reject, +} + +/// A parsing error for `OffsetDisambiguation` parsing. +#[derive(Debug, Clone, Copy)] +pub struct ParseOffsetDisambiguationError; + +impl fmt::Display for ParseOffsetDisambiguationError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("provided string was not a valid offset disambiguation value") + } +} + +impl FromStr for OffsetDisambiguation { + type Err = ParseOffsetDisambiguationError; + + fn from_str(s: &str) -> Result { + match s { + "use" => Ok(Self::Use), + "prefer" => Ok(Self::Prefer), + "ignore" => Ok(Self::Ignore), + "reject" => Ok(Self::Reject), + _ => Err(ParseOffsetDisambiguationError), + } + } +} + +impl fmt::Display for OffsetDisambiguation { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::Use => "use", + Self::Prefer => "prefer", + Self::Ignore => "ignore", + Self::Reject => "reject", + } + .fmt(f) + } +} + +// TODO: Figure out what to do with intl's RoundingMode + +/// Declares the specified `RoundingMode` for the operation. +#[derive(Debug, Copy, Clone, Default)] +pub enum RoundingMode { + /// Ceil RoundingMode + Ceil, + /// Floor RoundingMode + Floor, + /// Expand RoundingMode + Expand, + /// Truncate RoundingMode + Trunc, + /// HalfCeil RoundingMode + HalfCeil, + /// HalfFloor RoundingMode + HalfFloor, + /// HalfExpand RoundingMode - Default + #[default] + HalfExpand, + /// HalfTruncate RoundingMode + HalfTrunc, + /// HalfEven RoundingMode + HalfEven, +} + +/// The `UnsignedRoundingMode` +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum UnsignedRoundingMode { + /// `Infinity` `RoundingMode` + Infinity, + /// `Zero` `RoundingMode` + Zero, + /// `HalfInfinity` `RoundingMode` + HalfInfinity, + /// `HalfZero` `RoundingMode` + HalfZero, + /// `HalfEven` `RoundingMode` + HalfEven, +} + +impl RoundingMode { + #[inline] + #[must_use] + /// Negates the current `RoundingMode`. + pub const fn negate(self) -> Self { + use RoundingMode::{ + Ceil, Expand, Floor, HalfCeil, HalfEven, HalfExpand, HalfFloor, HalfTrunc, Trunc, + }; + + match self { + Ceil => Self::Floor, + Floor => Self::Ceil, + HalfCeil => Self::HalfFloor, + HalfFloor => Self::HalfCeil, + Trunc => Self::Trunc, + Expand => Self::Expand, + HalfTrunc => Self::HalfTrunc, + HalfExpand => Self::HalfExpand, + HalfEven => Self::HalfEven, + } + } + + #[inline] + #[must_use] + /// Returns the `UnsignedRoundingMode` + pub const fn get_unsigned_round_mode(self, is_positive: bool) -> UnsignedRoundingMode { + use RoundingMode::{ + Ceil, Expand, Floor, HalfCeil, HalfEven, HalfExpand, HalfFloor, HalfTrunc, Trunc, + }; + + match self { + Ceil if is_positive => UnsignedRoundingMode::Infinity, + Ceil | Trunc => UnsignedRoundingMode::Zero, + Floor if is_positive => UnsignedRoundingMode::Zero, + Floor | Expand => UnsignedRoundingMode::Infinity, + HalfCeil if is_positive => UnsignedRoundingMode::HalfInfinity, + HalfCeil | HalfTrunc => UnsignedRoundingMode::HalfZero, + HalfFloor if is_positive => UnsignedRoundingMode::HalfZero, + HalfFloor | HalfExpand => UnsignedRoundingMode::HalfInfinity, + HalfEven => UnsignedRoundingMode::HalfEven, + } + } +} + +impl FromStr for RoundingMode { + type Err = TemporalError; + + fn from_str(s: &str) -> Result { + match s { + "ceil" => Ok(Self::Ceil), + "floor" => Ok(Self::Floor), + "expand" => Ok(Self::Expand), + "trunc" => Ok(Self::Trunc), + "halfCeil" => Ok(Self::HalfCeil), + "halfFloor" => Ok(Self::HalfFloor), + "halfExpand" => Ok(Self::HalfExpand), + "halfTrunc" => Ok(Self::HalfTrunc), + "halfEven" => Ok(Self::HalfEven), + _ => Err(TemporalError::range().with_enum(ErrorMessage::RoundingModeInvalid)), + } + } +} + +impl fmt::Display for RoundingMode { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::Ceil => "ceil", + Self::Floor => "floor", + Self::Expand => "expand", + Self::Trunc => "trunc", + Self::HalfCeil => "halfCeil", + Self::HalfFloor => "halfFloor", + Self::HalfExpand => "halfExpand", + Self::HalfTrunc => "halfTrunc", + Self::HalfEven => "halfEven", + } + .fmt(f) + } +} + +/// values for `CalendarName`, whether to show the calendar in toString() methods +/// +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum DisplayCalendar { + #[default] + /// `Auto` option + Auto, + /// `Always` option + Always, + /// `Never` option + Never, + // `Critical` option + Critical, +} + +impl fmt::Display for DisplayCalendar { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + DisplayCalendar::Auto => "auto", + DisplayCalendar::Always => "always", + DisplayCalendar::Never => "never", + DisplayCalendar::Critical => "critical", + } + .fmt(f) + } +} + +impl FromStr for DisplayCalendar { + type Err = TemporalError; + + fn from_str(s: &str) -> Result { + match s { + "auto" => Ok(Self::Auto), + "always" => Ok(Self::Always), + "never" => Ok(Self::Never), + "critical" => Ok(Self::Critical), + _ => Err(TemporalError::range().with_enum(ErrorMessage::CalendarNameInvalid)), + } + } +} + +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum DisplayOffset { + #[default] + Auto, + Never, +} + +impl fmt::Display for DisplayOffset { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + DisplayOffset::Auto => "auto", + DisplayOffset::Never => "never", + } + .fmt(f) + } +} + +impl FromStr for DisplayOffset { + type Err = TemporalError; + + fn from_str(s: &str) -> Result { + match s { + "auto" => Ok(Self::Auto), + "never" => Ok(Self::Never), + _ => Err(TemporalError::range().with_enum(ErrorMessage::OffsetOptionInvalid)), + } + } +} + +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum DisplayTimeZone { + #[default] + /// `Auto` option + Auto, + /// `Never` option + Never, + // `Critical` option + Critical, +} + +impl fmt::Display for DisplayTimeZone { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + DisplayTimeZone::Auto => "auto", + DisplayTimeZone::Never => "never", + DisplayTimeZone::Critical => "critical", + } + .fmt(f) + } +} + +impl FromStr for DisplayTimeZone { + type Err = TemporalError; + + fn from_str(s: &str) -> Result { + match s { + "auto" => Ok(Self::Auto), + "never" => Ok(Self::Never), + "critical" => Ok(Self::Critical), + _ => Err(TemporalError::range().with_enum(ErrorMessage::TimeZoneNameInvalid)), + } + } +} diff --git a/deps/temporal/src/options/increment.rs b/deps/temporal/src/options/increment.rs new file mode 100644 index 00000000000000..f229e85a7825ff --- /dev/null +++ b/deps/temporal/src/options/increment.rs @@ -0,0 +1,117 @@ +use core::num::{NonZeroU128, NonZeroU32}; + +use crate::{TemporalError, TemporalResult}; +use num_traits::float::FloatCore; + +// ==== RoundingIncrement option ==== + +// Invariants: +// RoundingIncrement(n): 1 <= n < 10^9 +// TODO: Add explanation on what exactly are rounding increments. + +/// A numeric rounding increment. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct RoundingIncrement(pub(crate) NonZeroU32); + +impl Default for RoundingIncrement { + fn default() -> Self { + Self::ONE + } +} + +impl TryFrom for RoundingIncrement { + type Error = TemporalError; + + fn try_from(value: f64) -> Result { + // GetRoundingIncrementOption ( options ) + // https://tc39.es/proposal-temporal/#sec-temporal-getroundingincrementoption + + // 4. If increment is not finite, throw a RangeError exception. + if !value.is_finite() { + return Err(TemporalError::range().with_message("roundingIncrement must be finite")); + } + + // 5. Let integerIncrement be truncate(ℝ(increment)). + let integer_increment = FloatCore::trunc(value); + // 6. If integerIncrement < 1 or integerIncrement > 10**9, throw a RangeError exception. + // 7. Return integerIncrement. + if !(1.0..=1_000_000_000.0).contains(&integer_increment) { + Err(TemporalError::range() + .with_message("roundingIncrement cannot be less that 1 or bigger than 10**9")) + } else { + // We already range-checked, so we can just unwrap_or and expect it to never be reached + Ok(Self( + NonZeroU32::new(integer_increment as u32).unwrap_or(NonZeroU32::MIN), + )) + } + } +} + +impl RoundingIncrement { + // Using `MIN` avoids either a panic or using NonZeroU32::new_unchecked + /// A rounding increment of 1 (normal rounding). + pub const ONE: Self = Self(NonZeroU32::MIN); + + /// Create a new `RoundingIncrement`. + /// + /// # Errors + /// + /// - If `increment` is less than 1 or bigger than 10**9. + pub fn try_new(increment: u32) -> TemporalResult { + if !(1..=1_000_000_000).contains(&increment) { + Err(TemporalError::range() + .with_message("roundingIncrement cannot be less that 1 or bigger than 10**9")) + } else { + // We already range-checked, so we can just unwrap_or and expect it to never be reached + Ok(Self(NonZeroU32::new(increment).unwrap_or(NonZeroU32::MIN))) + } + } + + /// Create a new `RoundingIncrement` without checking the validity of the + /// increment. + /// + /// The increment is expected to be in `1..=10⁹` + /// + /// This is safe to invoke (and will result in incorrect but not unsafe behavior if + /// invoked with an out-of-range `increment`). + pub const fn new_unchecked(increment: NonZeroU32) -> Self { + Self(increment) + } + + /// Gets the numeric value of this `RoundingIncrement`. + pub const fn get(self) -> u32 { + self.0.get() + } + + // ValidateTemporalRoundingIncrement ( increment, dividend, inclusive ) + // https://tc39.es/proposal-temporal/#sec-validatetemporalroundingincrement + pub(crate) fn validate(self, dividend: u64, inclusive: bool) -> TemporalResult<()> { + // 1. If inclusive is true, then + // a. Let maximum be dividend. + // 2. Else, + // a. Assert: dividend > 1. + // b. Let maximum be dividend - 1. + let max = dividend - u64::from(!inclusive); + + let increment = u64::from(self.get()); + + // 3. If increment > maximum, throw a RangeError exception. + if increment > max { + return Err(TemporalError::range().with_message("roundingIncrement exceeds maximum")); + } + + // 4. If dividend modulo increment ≠ 0, then + if dividend.rem_euclid(increment) != 0 { + // a. Throw a RangeError exception. + return Err(TemporalError::range() + .with_message("dividend is not divisible by roundingIncrement")); + } + + // 5. Return unused. + Ok(()) + } + + pub(crate) fn as_extended_increment(&self) -> NonZeroU128 { + NonZeroU128::from(self.0) + } +} diff --git a/deps/temporal/src/options/relative_to.rs b/deps/temporal/src/options/relative_to.rs new file mode 100644 index 00000000000000..2f65fbbf5f0067 --- /dev/null +++ b/deps/temporal/src/options/relative_to.rs @@ -0,0 +1,181 @@ +//! RelativeTo rounding option + +use crate::builtins::core::zoned_date_time::interpret_isodatetime_offset; +use crate::builtins::core::{calendar::Calendar, time_zone::TimeZone, PlainDate, ZonedDateTime}; +use crate::iso::{IsoDate, IsoTime}; +use crate::options::{Disambiguation, OffsetDisambiguation, Overflow}; +use crate::parsers::{parse_date_time, parse_zoned_date_time}; +use crate::provider::TimeZoneProvider; +use crate::{TemporalResult, TemporalUnwrap}; + +use ixdtf::records::UtcOffsetRecordOrZ; + +// ==== RelativeTo Object ==== + +#[derive(Debug, Clone)] +pub enum RelativeTo { + PlainDate(PlainDate), + ZonedDateTime(ZonedDateTime), +} + +impl From for RelativeTo { + fn from(value: PlainDate) -> Self { + Self::PlainDate(value) + } +} + +impl From for RelativeTo { + fn from(value: ZonedDateTime) -> Self { + Self::ZonedDateTime(value) + } +} + +impl RelativeTo { + /// Attempts to parse a `ZonedDateTime` string falling back to a `PlainDate` + /// if possible. + /// + /// If the fallback fails or either the `ZonedDateTime` or `PlainDate` + /// is invalid, then an error is returned. + pub fn try_from_str_with_provider( + source: &str, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // b. Let result be ? ParseISODateTime(value, « TemporalDateTimeString[+Zoned], TemporalDateTimeString[~Zoned] »). + let bytes = source.as_bytes(); + let result = parse_date_time(bytes).or_else(|_| parse_zoned_date_time(bytes))?; + + let Some(annotation) = result.tz else { + let date_record = result.date.temporal_unwrap()?; + + let calendar = result + .calendar + .map(Calendar::try_from_utf8) + .transpose()? + .unwrap_or_default(); + + return Ok(PlainDate::try_new( + date_record.year, + date_record.month, + date_record.day, + calendar, + )? + .into()); + }; + + // iv. Set matchBehaviour to match-minutes. + let mut match_minutes = true; + + let time_zone = TimeZone::from_time_zone_record(annotation.tz, provider)?; + + let (offset_nanos, is_exact) = result + .offset + .map(|record| { + let UtcOffsetRecordOrZ::Offset(offset) = record else { + return (None, true); + }; + let hours_in_ns = i64::from(offset.hour()) * 3_600_000_000_000_i64; + let minutes_in_ns = i64::from(offset.minute()) * 60_000_000_000_i64; + let seconds_in_ns = i64::from(offset.second().unwrap_or(0)) * 1_000_000_000_i64; + // 3. If offsetParseResult contains more than one MinuteSecond Parse Node, set matchBehaviour to match-exactly. + if offset.second().is_some() { + match_minutes = false; + } + + let ns = offset + .fraction() + .and_then(|x| x.to_nanoseconds()) + .unwrap_or(0); + ( + Some( + (hours_in_ns + minutes_in_ns + seconds_in_ns + i64::from(ns)) + * i64::from(offset.sign() as i8), + ), + false, + ) + }) + .unwrap_or((None, false)); + + let calendar = result + .calendar + .map(Calendar::try_from_utf8) + .transpose()? + .unwrap_or_default(); + + let time = result.time.map(IsoTime::from_time_record).transpose()?; + + let date = result.date.temporal_unwrap()?; + let iso = IsoDate::new_with_overflow(date.year, date.month, date.day, Overflow::Constrain)?; + + let epoch_ns = interpret_isodatetime_offset( + iso, + time, + is_exact, + offset_nanos, + &time_zone, + Disambiguation::Compatible, + OffsetDisambiguation::Reject, + match_minutes, + provider, + )?; + + Ok(ZonedDateTime::try_new_with_cached_offset( + epoch_ns.ns.0, + time_zone, + calendar, + epoch_ns.offset, + )? + .into()) + } +} + +#[cfg(test)] +mod tests { + #[cfg(feature = "compiled_data")] + use super::*; + #[cfg(feature = "compiled_data")] + #[test] + fn relativeto_offset_parse() { + // Cases taken from intl402/Temporal/Duration/prototype/total/relativeto-sub-minute-offset + + let provider = &*crate::builtins::TZ_PROVIDER; + let _ = + RelativeTo::try_from_str_with_provider("1970-01-01T00:00-00:45:00[-00:45]", provider) + .unwrap(); + // Rounded mm accepted + let _ = RelativeTo::try_from_str_with_provider( + "1970-01-01T00:00:00-00:45[Africa/Monrovia]", + provider, + ) + .unwrap(); + // unrounded mm::ss accepted + let _ = RelativeTo::try_from_str_with_provider( + "1970-01-01T00:00:00-00:44:30[Africa/Monrovia]", + provider, + ) + .unwrap(); + assert!( + RelativeTo::try_from_str_with_provider( + "1970-01-01T00:00:00-00:44:40[Africa/Monrovia]", + provider + ) + .is_err(), + "Incorrect unrounded mm::ss rejected" + ); + assert!( + RelativeTo::try_from_str_with_provider( + "1970-01-01T00:00:00-00:45:00[Africa/Monrovia]", + provider + ) + .is_err(), + "Rounded mm::ss rejected" + ); + assert!( + RelativeTo::try_from_str_with_provider( + "1970-01-01T00:00+00:44:30.123456789[+00:45]", + provider + ) + .is_err(), + "Rounding not accepted between ISO offset and timezone" + ); + } +} diff --git a/deps/temporal/src/parsed_intermediates.rs b/deps/temporal/src/parsed_intermediates.rs new file mode 100644 index 00000000000000..c4ff2cc0d98fd4 --- /dev/null +++ b/deps/temporal/src/parsed_intermediates.rs @@ -0,0 +1,210 @@ +//! Parsed intermediate types +//! +//! These are types which have been *parsed* from an IXDTF string, extracting +//! calendar/time zone/etc information, but have not yet been validated. +//! +//! They are primarily useful for clients implementing the Temporal specification +//! since the specification performs observable operations +//! between the parse and validate steps. + +use crate::error::ErrorMessage; +use crate::error::TemporalError; +use crate::iso::IsoTime; +use crate::parsers; +use crate::provider::TimeZoneProvider; +use crate::Calendar; +use crate::TemporalResult; +use crate::TemporalUnwrap; +use crate::TimeZone; +use crate::UtcOffset; +use icu_calendar::AnyCalendarKind; +use ixdtf::records::DateRecord; +use ixdtf::records::UtcOffsetRecordOrZ; + +fn extract_kind(calendar: Option<&[u8]>) -> TemporalResult { + Ok(calendar + .map(Calendar::try_kind_from_utf8) + .transpose()? + .unwrap_or(AnyCalendarKind::Iso)) +} + +/// A parsed-but-not-validated date +#[derive(Copy, Clone, Debug)] +pub struct ParsedDate { + pub(crate) record: DateRecord, + pub(crate) calendar: AnyCalendarKind, +} + +impl ParsedDate { + /// Converts a UTF-8 encoded string into a `ParsedDate`. + pub fn from_utf8(s: &[u8]) -> TemporalResult { + let parse_record = parsers::parse_date_time(s)?; + + let calendar = extract_kind(parse_record.calendar)?; + + // Assertion: PlainDate must exist on a DateTime parse. + let record = parse_record.date.temporal_unwrap()?; + + Ok(Self { record, calendar }) + } + /// Converts a UTF-8 encoded YearMonth string into a `ParsedDate`. + pub fn year_month_from_utf8(s: &[u8]) -> TemporalResult { + let parse_record = parsers::parse_year_month(s)?; + + let calendar = extract_kind(parse_record.calendar)?; + + // Assertion: PlainDate must exist on a DateTime parse. + let record = parse_record.date.temporal_unwrap()?; + + Ok(Self { record, calendar }) + } + /// Converts a UTF-8 encoded MonthDay string into a `ParsedDate`. + pub fn month_day_from_utf8(s: &[u8]) -> TemporalResult { + let parse_record = parsers::parse_month_day(s)?; + + let calendar = extract_kind(parse_record.calendar)?; + + // Assertion: PlainDate must exist on a DateTime parse. + let record = parse_record.date.temporal_unwrap()?; + + Ok(Self { record, calendar }) + } +} + +/// A parsed-but-not-validated datetime +#[derive(Copy, Clone, Debug)] +pub struct ParsedDateTime { + pub(crate) date: ParsedDate, + pub(crate) time: IsoTime, +} + +impl ParsedDateTime { + /// Converts a UTF-8 encoded string into a `ParsedDateTime`. + pub fn from_utf8(s: &[u8]) -> TemporalResult { + let parse_record = parsers::parse_date_time(s)?; + + let calendar = extract_kind(parse_record.calendar)?; + + let time = parse_record + .time + .map(IsoTime::from_time_record) + .transpose()? + .unwrap_or_default(); + + let record = parse_record.date.temporal_unwrap()?; + Ok(Self { + date: ParsedDate { record, calendar }, + time, + }) + } +} + +/// A parsed-but-not-validated zoned datetime +#[derive(Clone, Debug)] +pub struct ParsedZonedDateTime { + pub(crate) date: ParsedDate, + /// None time is START-OF-DAY + pub(crate) time: Option, + /// Whether or not the string has a UTC designator (`Z`) + /// + /// Incompatible with having an offset (you can still have a offset-format timezone) + pub(crate) has_utc_designator: bool, + /// Whether or not to allow offsets rounded to the minute + /// + /// (Typically only needs to be set when parsing, can be false otherwise) + pub(crate) match_minutes: bool, + /// An optional offset string + pub(crate) offset: Option, + /// The time zone + pub(crate) timezone: TimeZone, +} + +impl ParsedZonedDateTime { + /// Converts a UTF-8 encoded string into a `ParsedZonedDateTime`, using compiled data + #[cfg(feature = "compiled_data")] + pub fn from_utf8(source: &[u8]) -> TemporalResult { + Self::from_utf8_with_provider(source, &*crate::builtins::TZ_PROVIDER) + } + + /// Converts a UTF-8 encoded string into a `ParsedZonedDateTime`. + pub fn from_utf8_with_provider( + source: &[u8], + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + // Steps from the parse bits of of ToZonedDateTime + + // 3. Let matchBehaviour be match-minutes. + let mut match_minutes = true; + + // b. Let result be ? ParseISODateTime(item, « TemporalDateTimeString[+Zoned] »). + let parse_result = parsers::parse_zoned_date_time(source)?; + + // c. Let annotation be result.[[TimeZone]].[[TimeZoneAnnotation]]. + // d. Assert: annotation is not empty. + // NOTE (nekevss): `parse_zoned_date_time` guarantees that this value exists. + let annotation = parse_result.tz.temporal_unwrap()?; + + // e. Let timeZone be ? ToTemporalTimeZoneIdentifier(annotation). + let time_zone = TimeZone::from_time_zone_record(annotation.tz, provider)?; + + // f. Let offsetString be result.[[TimeZone]].[[OffsetString]]. + let (offset, has_utc_designator) = match parse_result.offset { + // g. If result.[[TimeZone]].[[Z]] is true, then + // i. Set hasUTCDesignator to true. + Some(UtcOffsetRecordOrZ::Z) => (None, true), + Some(UtcOffsetRecordOrZ::Offset(offset)) => { + if offset.second().is_some() { + // iii. If offsetParseResult contains more than one MinuteSecond Parse Node, set matchBehaviour to match-exactly. + match_minutes = false; + } + (Some(UtcOffset::from_ixdtf_record(offset)?), false) + } + None => (None, false), + }; + + // h. Let calendar be result.[[Calendar]]. + // i. If calendar is empty, set calendar to "iso8601". + // j. Set calendar to ? CanonicalizeCalendar(calendar). + let calendar = extract_kind(parse_result.calendar)?; + + let Some(date) = parse_result.date else { + return Err(TemporalError::range().with_enum(ErrorMessage::ParserNeedsDate)); + }; + + let time = parse_result + .time + .map(IsoTime::from_time_record) + .transpose()?; + + Ok(Self { + date: ParsedDate { + record: date, + calendar, + }, + time, + has_utc_designator, + match_minutes, + offset, + timezone: time_zone, + }) + } +} + +#[test] +fn test_parsed_intermediate_invalid_dates() { + // https://tc39.es/proposal-temporal/#sec-temporal-iso8601grammar-static-semantics-early-errors + // + // We need to error on invalid date/times *before* producing a ParsedFoo, since this is observable + assert!(ParsedDate::from_utf8(b"2025-02-29").is_err()); + assert!(ParsedDate::from_utf8(b"2025-02-28").is_ok()); + assert!(ParsedDate::year_month_from_utf8(b"202513").is_err()); + assert!(ParsedDate::year_month_from_utf8(b"202512").is_ok()); + assert!(ParsedDate::month_day_from_utf8(b"1000").is_err()); + assert!(ParsedDate::month_day_from_utf8(b"1001").is_ok()); + assert!(ParsedDateTime::from_utf8(b"2025-02-28T25:69:69").is_err()); + assert!(ParsedDateTime::from_utf8(b"2025-02-28T23:59:59").is_ok()); + #[cfg(feature = "compiled_data")] + assert!(ParsedZonedDateTime::from_utf8(b"2025-02-29T00:00:00Z[utc]").is_err()); + #[cfg(feature = "compiled_data")] + assert!(ParsedZonedDateTime::from_utf8(b"2025-02-28T00:00:00Z[utc]").is_ok()); +} diff --git a/deps/temporal/src/parsers.rs b/deps/temporal/src/parsers.rs new file mode 100644 index 00000000000000..43a7d778802a5b --- /dev/null +++ b/deps/temporal/src/parsers.rs @@ -0,0 +1,1025 @@ +//! This module implements Temporal Date/Time parsing functionality. + +use crate::{ + iso::{IsoDate, IsoTime}, + options::{DisplayCalendar, DisplayOffset, DisplayTimeZone}, + Sign, TemporalError, TemporalResult, +}; +use ixdtf::{ + encoding::Utf8, + parsers::IxdtfParser, + records::{Annotation, DateRecord, IxdtfParseRecord, TimeRecord, UtcOffsetRecordOrZ}, +}; +use writeable::{impl_display_with_writeable, LengthHint, Writeable}; + +mod time_zone; + +pub(crate) use time_zone::{parse_allowed_timezone_formats, parse_identifier}; + +// TODO: Move `Writeable` functionality to `ixdtf` crate + +#[derive(Debug, Default)] +pub struct IxdtfStringBuilder<'a> { + inner: FormattableIxdtf<'a>, +} + +impl<'a> IxdtfStringBuilder<'a> { + pub fn with_date(mut self, iso: IsoDate) -> Self { + self.inner.date = Some(FormattableDate(iso.year, iso.month, iso.day)); + self + } + + pub fn with_time(mut self, time: IsoTime, precision: Precision) -> Self { + let nanosecond = (time.millisecond as u32 * 1_000_000) + + (time.microsecond as u32 * 1000) + + time.nanosecond as u32; + + self.inner.time = Some(FormattableTime { + hour: time.hour, + minute: time.minute, + second: time.second, + nanosecond, + precision, + include_sep: true, + }); + self + } + + pub fn with_minute_offset( + mut self, + sign: Sign, + hour: u8, + minute: u8, + show: DisplayOffset, + ) -> Self { + let time = FormattableTime { + hour, + minute, + second: 9, + nanosecond: 0, + precision: Precision::Minute, + include_sep: true, + }; + + self.inner.utc_offset = Some(FormattableUtcOffset { + show, + offset: UtcOffset::Offset(FormattableOffset { sign, time }), + }); + self + } + + pub fn with_z(mut self, show: DisplayOffset) -> Self { + self.inner.utc_offset = Some(FormattableUtcOffset { + show, + offset: UtcOffset::Z, + }); + self + } + + pub fn with_timezone(mut self, timezone: &'a str, show: DisplayTimeZone) -> Self { + self.inner.timezone = Some(FormattableTimeZone { show, timezone }); + self + } + + pub fn with_calendar(mut self, calendar: &'static str, show: DisplayCalendar) -> Self { + self.inner.calendar = Some(FormattableCalendar { show, calendar }); + self + } + + pub fn build(self) -> alloc::string::String { + self.inner.to_string() + } +} + +impl Writeable for IxdtfStringBuilder<'_> { + fn write_to(&self, sink: &mut W) -> core::fmt::Result { + self.inner.write_to(sink) + } + + fn writeable_length_hint(&self) -> LengthHint { + self.inner.writeable_length_hint() + } +} + +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum Precision { + #[default] + Auto, + Minute, + Digit(u8), +} + +#[derive(Debug)] +pub struct FormattableTime { + pub hour: u8, + pub minute: u8, + pub second: u8, + pub nanosecond: u32, + pub precision: Precision, + pub include_sep: bool, +} + +impl Writeable for FormattableTime { + fn write_to(&self, sink: &mut W) -> core::fmt::Result { + write_padded_u8(self.hour, sink)?; + if self.include_sep { + sink.write_char(':')?; + } + write_padded_u8(self.minute, sink)?; + if self.precision == Precision::Minute { + return Ok(()); + } + if self.include_sep { + sink.write_char(':')?; + } + write_padded_u8(self.second, sink)?; + if (self.nanosecond == 0 && self.precision == Precision::Auto) + || self.precision == Precision::Digit(0) + { + return Ok(()); + } + sink.write_char('.')?; + write_nanosecond(self.nanosecond, self.precision, sink) + } + + fn writeable_length_hint(&self) -> LengthHint { + let sep = self.include_sep as usize; + if self.precision == Precision::Minute { + return LengthHint::exact(4 + sep); + } + let time_base = 6 + (sep * 2); + if self.nanosecond == 0 || self.precision == Precision::Digit(0) { + return LengthHint::exact(time_base); + } + if let Precision::Digit(d) = self.precision { + return LengthHint::exact(time_base + 1 + d as usize); + } + LengthHint::between(time_base + 2, time_base + 10) + } +} + +#[derive(Debug)] +pub struct FormattableUtcOffset { + pub show: DisplayOffset, + pub offset: UtcOffset, +} + +#[derive(Debug)] +pub enum UtcOffset { + Z, + Offset(FormattableOffset), +} + +impl Writeable for FormattableUtcOffset { + fn write_to(&self, sink: &mut W) -> core::fmt::Result { + if self.show == DisplayOffset::Never { + return Ok(()); + } + match &self.offset { + UtcOffset::Z => sink.write_char('Z'), + UtcOffset::Offset(offset) => offset.write_to(sink), + } + } + + fn writeable_length_hint(&self) -> LengthHint { + match &self.offset { + UtcOffset::Z => LengthHint::exact(1), + UtcOffset::Offset(o) => o.writeable_length_hint(), + } + } +} + +fn write_padded_u8(num: u8, sink: &mut W) -> core::fmt::Result { + if num < 10 { + sink.write_char('0')?; + } + num.write_to(sink) +} + +fn write_nanosecond( + nanoseconds: u32, + precision: Precision, + sink: &mut W, +) -> core::fmt::Result { + let (digits, index) = u32_to_digits(nanoseconds); + let precision = match precision { + Precision::Digit(digit) if digit <= 9 => digit as usize, + _ => index, + }; + write_digit_slice_to_precision(digits, 0, precision, sink) +} + +pub fn u32_to_digits(mut value: u32) -> ([u8; 9], usize) { + let mut output = [0; 9]; + let mut precision = 0; + for (i, out) in output.iter_mut().enumerate().rev() { + let v = (value % 10) as u8; + value /= 10; + if precision == 0 && v != 0 { + // i is 0-indexed, but we want a 1-indexed precision + precision = i + 1; + } + *out = v; + } + + (output, precision) +} + +pub fn write_digit_slice_to_precision( + digits: [u8; 9], + base: usize, + precision: usize, + sink: &mut W, +) -> core::fmt::Result { + for digit in digits.iter().take(precision).skip(base) { + digit.write_to(sink)?; + } + Ok(()) +} + +#[derive(Debug)] +pub struct FormattableOffset { + pub sign: Sign, + pub time: FormattableTime, +} + +impl Writeable for FormattableOffset { + fn write_to(&self, sink: &mut W) -> core::fmt::Result { + match self.sign { + Sign::Negative => sink.write_char('-')?, + _ => sink.write_char('+')?, + } + self.time.write_to(sink) + } + + fn writeable_length_hint(&self) -> LengthHint { + self.time.writeable_length_hint() + 1 + } +} + +impl_display_with_writeable!(FormattableIxdtf<'_>); +impl_display_with_writeable!(FormattableMonthDay<'_>); +impl_display_with_writeable!(FormattableYearMonth<'_>); +impl_display_with_writeable!(FormattableDuration); +impl_display_with_writeable!(FormattableDate); +impl_display_with_writeable!(FormattableTime); +impl_display_with_writeable!(FormattableUtcOffset); +impl_display_with_writeable!(FormattableOffset); +impl_display_with_writeable!(FormattableTimeZone<'_>); +impl_display_with_writeable!(FormattableCalendar<'_>); + +#[derive(Debug)] +pub struct FormattableDate(pub i32, pub u8, pub u8); + +impl Writeable for FormattableDate { + fn write_to(&self, sink: &mut W) -> core::fmt::Result { + write_year(self.0, sink)?; + sink.write_char('-')?; + write_padded_u8(self.1, sink)?; + sink.write_char('-')?; + write_padded_u8(self.2, sink) + } + + fn writeable_length_hint(&self) -> LengthHint { + let year_length = if (0..=9999).contains(&self.0) { 4 } else { 7 }; + + LengthHint::exact(6 + year_length) + } +} + +fn write_year(year: i32, sink: &mut W) -> core::fmt::Result { + if (0..=9999).contains(&year) { + write_four_digit_year(year, sink) + } else { + write_extended_year(year, sink) + } +} + +fn write_four_digit_year( + mut y: i32, + sink: &mut W, +) -> core::fmt::Result { + (y / 1_000).write_to(sink)?; + y %= 1_000; + (y / 100).write_to(sink)?; + y %= 100; + (y / 10).write_to(sink)?; + y %= 10; + y.write_to(sink) +} + +fn write_extended_year(y: i32, sink: &mut W) -> core::fmt::Result { + let sign = if y < 0 { '-' } else { '+' }; + sink.write_char(sign)?; + let (digits, _) = u32_to_digits(y.unsigned_abs()); + // SAFETY: digits slice is made up up valid ASCII digits. + write_digit_slice_to_precision(digits, 3, 9, sink) +} + +#[derive(Debug)] +pub struct FormattableTimeZone<'a> { + pub show: DisplayTimeZone, + pub timezone: &'a str, +} + +impl Writeable for FormattableTimeZone<'_> { + fn write_to(&self, sink: &mut W) -> core::fmt::Result { + if self.show == DisplayTimeZone::Never { + return Ok(()); + } + sink.write_char('[')?; + if self.show == DisplayTimeZone::Critical { + sink.write_char('!')?; + } + sink.write_str(self.timezone)?; + sink.write_char(']') + } + + fn writeable_length_hint(&self) -> writeable::LengthHint { + if self.show == DisplayTimeZone::Never { + return LengthHint::exact(0); + } + let critical = (self.show == DisplayTimeZone::Critical) as usize; + LengthHint::exact(2 + critical + self.timezone.len()) + } +} + +#[derive(Debug)] +pub struct FormattableCalendar<'a> { + pub show: DisplayCalendar, + pub calendar: &'a str, +} + +impl Writeable for FormattableCalendar<'_> { + fn write_to(&self, sink: &mut W) -> core::fmt::Result { + if self.show == DisplayCalendar::Never + || self.show == DisplayCalendar::Auto && self.calendar == "iso8601" + { + return Ok(()); + } + sink.write_char('[')?; + if self.show == DisplayCalendar::Critical { + sink.write_char('!')?; + } + sink.write_str("u-ca=")?; + sink.write_str(self.calendar)?; + sink.write_char(']') + } + + fn writeable_length_hint(&self) -> LengthHint { + if self.show == DisplayCalendar::Never + || self.show == DisplayCalendar::Auto && self.calendar == "iso8601" + { + return LengthHint::exact(0); + } + let critical = (self.show == DisplayCalendar::Critical) as usize; + LengthHint::exact(7 + critical + self.calendar.len()) + } +} + +#[derive(Debug)] +pub struct FormattableMonthDay<'a> { + pub date: FormattableDate, + pub calendar: FormattableCalendar<'a>, +} + +impl Writeable for FormattableMonthDay<'_> { + fn write_to(&self, sink: &mut W) -> core::fmt::Result { + if self.calendar.show == DisplayCalendar::Always + || self.calendar.show == DisplayCalendar::Critical + || self.calendar.calendar != "iso8601" + { + write_year(self.date.0, sink)?; + sink.write_char('-')?; + } + write_padded_u8(self.date.1, sink)?; + sink.write_char('-')?; + write_padded_u8(self.date.2, sink)?; + self.calendar.write_to(sink) + } + + fn writeable_length_hint(&self) -> LengthHint { + let base_length = self.calendar.writeable_length_hint() + LengthHint::exact(5); + if self.calendar.show == DisplayCalendar::Always + || self.calendar.show == DisplayCalendar::Critical + || self.calendar.calendar != "iso8601" + { + let year_length = if (0..=9999).contains(&self.date.0) { + 4 + } else { + 7 + }; + return base_length + LengthHint::exact(year_length); + } + base_length + } +} + +#[derive(Debug)] +pub struct FormattableYearMonth<'a> { + pub date: FormattableDate, + pub calendar: FormattableCalendar<'a>, +} + +impl Writeable for FormattableYearMonth<'_> { + fn write_to(&self, sink: &mut W) -> core::fmt::Result { + write_year(self.date.0, sink)?; + sink.write_char('-')?; + write_padded_u8(self.date.1, sink)?; + if self.calendar.show == DisplayCalendar::Always + || self.calendar.show == DisplayCalendar::Critical + || self.calendar.calendar != "iso8601" + { + sink.write_char('-')?; + write_padded_u8(self.date.2, sink)?; + } + + self.calendar.write_to(sink) + } + + fn writeable_length_hint(&self) -> LengthHint { + let year_length = if (0..=9999).contains(&self.date.0) { + 4 + } else { + 7 + }; + let base_length = + self.calendar.writeable_length_hint() + LengthHint::exact(year_length + 3); + if self.calendar.show == DisplayCalendar::Always + || self.calendar.show == DisplayCalendar::Critical + || self.calendar.calendar != "iso8601" + { + return base_length + LengthHint::exact(3); + } + base_length + } +} + +#[derive(Debug, Default)] +pub struct FormattableIxdtf<'a> { + pub date: Option, + pub time: Option, + pub utc_offset: Option, + pub timezone: Option>, + pub calendar: Option>, +} + +impl Writeable for FormattableIxdtf<'_> { + fn write_to(&self, sink: &mut W) -> core::fmt::Result { + if let Some(date) = &self.date { + date.write_to(sink)?; + } + if let Some(time) = &self.time { + if self.date.is_some() { + sink.write_char('T')?; + } + time.write_to(sink)?; + } + if let Some(offset) = &self.utc_offset { + offset.write_to(sink)?; + } + if let Some(timezone) = &self.timezone { + timezone.write_to(sink)?; + } + if let Some(calendar) = &self.calendar { + calendar.write_to(sink)?; + } + + Ok(()) + } + + fn writeable_length_hint(&self) -> LengthHint { + let date_length = self + .date + .as_ref() + .map(|d| d.writeable_length_hint()) + .unwrap_or(LengthHint::exact(0)); + let time_length = self + .time + .as_ref() + .map(|t| { + let t_present = self.date.is_some() as usize; + t.writeable_length_hint() + t_present + }) + .unwrap_or(LengthHint::exact(0)); + let utc_length = self + .utc_offset + .as_ref() + .map(|utc| utc.writeable_length_hint()) + .unwrap_or(LengthHint::exact(0)); + let timezone_length = self + .timezone + .as_ref() + .map(|tz| tz.writeable_length_hint()) + .unwrap_or(LengthHint::exact(0)); + let cal_length = self + .calendar + .as_ref() + .map(|cal| cal.writeable_length_hint()) + .unwrap_or(LengthHint::exact(0)); + + date_length + time_length + utc_length + timezone_length + cal_length + } +} + +#[derive(Debug, Clone, Copy)] +pub struct FormattableDateDuration { + pub years: u32, + pub months: u32, + pub weeks: u32, + pub days: u64, +} + +#[derive(Debug, Clone, Copy)] +pub enum FormattableTimeDuration { + Hours(u64, Option), + Minutes(u64, u64, Option), + Seconds(u64, u64, u64, Option), +} + +pub struct FormattableDuration { + pub precision: Precision, + pub sign: Sign, + pub date: Option, + pub time: Option, +} + +impl Writeable for FormattableDuration { + fn write_to(&self, sink: &mut W) -> core::fmt::Result { + if self.sign == Sign::Negative { + sink.write_char('-')?; + } + sink.write_char('P')?; + if let Some(date) = self.date { + checked_write_u32_with_suffix(date.years, 'Y', sink)?; + checked_write_u32_with_suffix(date.months, 'M', sink)?; + checked_write_u32_with_suffix(date.weeks, 'W', sink)?; + checked_write_u64_with_suffix(date.days, 'D', sink)?; + } + if let Some(time) = self.time { + match time { + FormattableTimeDuration::Hours(hours, fraction) => { + let ns = fraction.unwrap_or(0); + if hours + u64::from(ns) != 0 { + sink.write_char('T')?; + } + if hours == 0 { + return Ok(()); + } + hours.write_to(sink)?; + if ns != 0 { + sink.write_char('.')?; + ns.write_to(sink)?; + } + sink.write_char('H')?; + } + FormattableTimeDuration::Minutes(hours, minutes, fraction) => { + let ns = fraction.unwrap_or(0); + if hours + minutes + u64::from(ns) != 0 { + sink.write_char('T')?; + } + checked_write_u64_with_suffix(hours, 'H', sink)?; + if minutes == 0 { + return Ok(()); + } + minutes.write_to(sink)?; + if ns != 0 { + sink.write_char('.')?; + ns.write_to(sink)?; + } + sink.write_char('M')?; + } + FormattableTimeDuration::Seconds(hours, minutes, seconds, fraction) => { + let ns = fraction.unwrap_or(0); + let unit_below_minute = self.date.is_none() && hours == 0 && minutes == 0; + + let write_second = seconds != 0 + || unit_below_minute + || matches!(self.precision, Precision::Digit(_)); + + if hours != 0 || minutes != 0 || write_second { + sink.write_char('T')?; + } + + checked_write_u64_with_suffix(hours, 'H', sink)?; + checked_write_u64_with_suffix(minutes, 'M', sink)?; + if write_second { + seconds.write_to(sink)?; + if self.precision == Precision::Digit(0) + || (self.precision == Precision::Auto && ns == 0) + { + sink.write_char('S')?; + return Ok(()); + } + sink.write_char('.')?; + write_nanosecond(ns, self.precision, sink)?; + sink.write_char('S')?; + } + } + } + } + Ok(()) + } +} + +fn checked_write_u32_with_suffix( + val: u32, + suffix: char, + sink: &mut W, +) -> core::fmt::Result { + if val == 0 { + return Ok(()); + } + val.write_to(sink)?; + sink.write_char(suffix) +} + +fn checked_write_u64_with_suffix( + val: u64, + suffix: char, + sink: &mut W, +) -> core::fmt::Result { + if val == 0 { + return Ok(()); + } + val.write_to(sink)?; + sink.write_char(suffix) +} + +// TODO: Determine if these should be separate structs, i.e. TemporalDateTimeParser/TemporalInstantParser, or +// maybe on global `TemporalParser` around `IxdtfParser` that handles the Temporal idiosyncracies. +#[derive(PartialEq)] +enum ParseVariant { + YearMonth, + MonthDay, + DateTime, + Time, +} + +#[inline] +fn parse_ixdtf(source: &[u8], variant: ParseVariant) -> TemporalResult> { + fn cast_handler<'a>( + _: &mut IxdtfParser<'a, Utf8>, + handler: impl FnMut(Annotation<'a, Utf8>) -> Option>, + ) -> impl FnMut(Annotation<'a, Utf8>) -> Option> { + handler + } + + let mut first_calendar: Option> = None; + let mut critical_duplicate_calendar = false; + let mut parser = IxdtfParser::from_utf8(source); + + let handler = cast_handler(&mut parser, |annotation: Annotation| { + if annotation.key == "u-ca".as_bytes() { + match first_calendar { + Some(ref cal) => { + if cal.critical || annotation.critical { + critical_duplicate_calendar = true + } + } + None => first_calendar = Some(annotation), + } + return None; + } + + // Make the parser handle any unknown annotation. + Some(annotation) + }); + + let mut record = match variant { + ParseVariant::YearMonth => parser.parse_year_month_with_annotation_handler(handler), + ParseVariant::MonthDay => parser.parse_month_day_with_annotation_handler(handler), + ParseVariant::DateTime => parser.parse_with_annotation_handler(handler), + ParseVariant::Time => parser.parse_time_with_annotation_handler(handler), + }?; + + record.calendar = first_calendar.map(|v| v.value); + + // Note: this method only handles the specific AnnotatedFoo nonterminals; + // so if we are parsing MonthDay/YearMonth we will never have a DateDay/DateYear parse node. + // + // 3. If goal is TemporalYearMonthString, and parseResult does not contain a DateDay Parse Node, then + // a. If calendar is not empty, and the ASCII-lowercase of calendar is not "iso8601", throw a RangeError exception. + // 4. If goal is TemporalMonthDayString and parseResult does not contain a DateYear Parse Node, then + // a. If calendar is not empty, and the ASCII-lowercase of calendar is not "iso8601", throw a RangeError exception. + // b. Set yearAbsent to true. + if variant == ParseVariant::MonthDay || variant == ParseVariant::YearMonth { + if let Some(cal) = record.calendar { + if !cal.eq_ignore_ascii_case(b"iso8601") { + return Err(TemporalError::range() + .with_message("YearMonth/MonthDay formats only allowed for ISO calendar.")); + } + } + } + + if critical_duplicate_calendar { + // TODO: Add tests for the below. + // Parser handles non-matching calendar, so the value thrown here should only be duplicates. + return Err(TemporalError::range() + .with_message("Duplicate calendar value with critical flag found.")); + } + + // Validate that the DateRecord exists. + if variant != ParseVariant::Time && record.date.is_none() { + return Err( + TemporalError::range().with_message("DateTime strings must contain a Date value.") + ); + } + + // Temporal requires parsed dates to be checked for validity at parse time + // https://tc39.es/proposal-temporal/#sec-temporal-iso8601grammar-static-semantics-early-errors + // https://tc39.es/proposal-temporal/#sec-temporal-iso8601grammar-static-semantics-isvaliddate + // https://tc39.es/proposal-temporal/#sec-temporal-iso8601grammar-static-semantics-isvalidmonthday + if let Some(date) = record.date { + // ixdtf currently returns always-valid reference years/days + // in these cases (year = 0, day = 1), but we should set our own + // for robustness. + let year = if variant == ParseVariant::MonthDay { + 1972 + } else { + date.year + }; + let day = if variant == ParseVariant::YearMonth { + 1 + } else { + date.day + }; + if !crate::iso::is_valid_date(year, date.month, day) { + return Err(TemporalError::range() + .with_message("DateTime strings must contain a valid ISO date.")); + } + } + + Ok(record) +} + +/// A utility function for parsing a `DateTime` string +#[inline] +pub(crate) fn parse_date_time(source: &[u8]) -> TemporalResult> { + let record = parse_ixdtf(source, ParseVariant::DateTime)?; + + if record.offset == Some(UtcOffsetRecordOrZ::Z) { + return Err(TemporalError::range() + .with_message("UTC designator is not valid for DateTime parsing.")); + } + + Ok(record) +} + +#[inline] +pub(crate) fn parse_zoned_date_time(source: &[u8]) -> TemporalResult> { + let record = parse_ixdtf(source, ParseVariant::DateTime)?; + + // TODO: Support rejecting subminute precision in time zone annootations + if record.tz.is_none() { + return Err(TemporalError::range() + .with_message("Time zone annotation is required for parsing a zoned date time.")); + } + + Ok(record) +} + +pub(crate) struct IxdtfParseInstantRecord { + pub(crate) date: DateRecord, + pub(crate) time: TimeRecord, + pub(crate) offset: UtcOffsetRecordOrZ, +} + +/// A utility function for parsing an `Instant` string +#[inline] +pub(crate) fn parse_instant(source: &[u8]) -> TemporalResult { + let record = parse_ixdtf(source, ParseVariant::DateTime)?; + + let IxdtfParseRecord { + date: Some(date), + time: Some(time), + offset: Some(offset), + .. + } = record + else { + return Err( + TemporalError::range().with_message("Required fields missing from Instant string.") + ); + }; + + Ok(IxdtfParseInstantRecord { date, time, offset }) +} + +// Ensure that the record does not have an offset element. +// +// This handles the [~Zoned] in TemporalFooString productions +fn check_offset(record: IxdtfParseRecord<'_, Utf8>) -> TemporalResult> { + if record.offset == Some(UtcOffsetRecordOrZ::Z) { + return Err(TemporalError::range() + .with_message("UTC designator is not valid for plain date/time parsing.")); + } + Ok(record) +} + +/// A utility function for parsing a `YearMonth` string +#[inline] +pub(crate) fn parse_year_month(source: &[u8]) -> TemporalResult> { + let ym_record = parse_ixdtf(source, ParseVariant::YearMonth); + + let Err(e) = ym_record else { + return ym_record.and_then(check_offset); + }; + + let dt_parse = parse_date_time(source); + + match dt_parse { + Ok(dt) => check_offset(dt), + // Format and return the error from parsing YearMonth. + _ => Err(e), + } +} + +/// A utilty function for parsing a `MonthDay` String. +pub(crate) fn parse_month_day(source: &[u8]) -> TemporalResult> { + let md_record = parse_ixdtf(source, ParseVariant::MonthDay); + let Err(e) = md_record else { + return md_record.and_then(check_offset); + }; + + let dt_parse = parse_date_time(source); + + match dt_parse { + Ok(dt) => check_offset(dt), + // Format and return the error from parsing MonthDay. + _ => Err(e), + } +} + +// Ensures that an IxdtfParseRecord was parsed with [~Zoned][+TimeRequired] +fn check_time_record(record: IxdtfParseRecord) -> TemporalResult { + // Handle [~Zoned] + let record = check_offset(record)?; + // Handle [+TimeRequired] + let Some(time) = record.time else { + return Err(TemporalError::range() + .with_message("PlainTime can only be parsed from strings with a time component.")); + }; + Ok(time) +} + +#[inline] +pub(crate) fn parse_time(source: &[u8]) -> TemporalResult { + let time_record = parse_ixdtf(source, ParseVariant::Time); + + let Err(e) = time_record else { + return time_record.and_then(check_time_record); + }; + + let dt_parse = parse_date_time(source); + + match dt_parse { + Ok(dt) => check_time_record(dt), + // Format and return the error from parsing MonthDay. + _ => Err(e), + } +} + +/// Consider this API to be unstable: it is used internally by temporal_capi but +/// will likely be replaced with a proper TemporalParser API at some point. +#[inline] +pub fn parse_allowed_calendar_formats(s: &[u8]) -> Option<&[u8]> { + if let Ok(r) = parse_ixdtf(s, ParseVariant::DateTime).map(|r| r.calendar) { + return Some(r.unwrap_or(&[])); + } else if let Ok(r) = IxdtfParser::from_utf8(s).parse_time().map(|r| r.calendar) { + return Some(r.unwrap_or(&[])); + } else if let Ok(r) = parse_ixdtf(s, ParseVariant::YearMonth).map(|r| r.calendar) { + return Some(r.unwrap_or(&[])); + } else if let Ok(r) = parse_ixdtf(s, ParseVariant::MonthDay).map(|r| r.calendar) { + return Some(r.unwrap_or(&[])); + } + None +} + +// TODO: ParseTimeZoneString, ParseZonedDateTimeString + +#[cfg(test)] +mod tests { + use super::{FormattableDate, FormattableOffset}; + use crate::parsers::{FormattableTime, Precision}; + use alloc::format; + use writeable::assert_writeable_eq; + + #[test] + fn offset_string() { + let offset = FormattableOffset { + sign: crate::Sign::Positive, + time: FormattableTime { + hour: 4, + minute: 0, + second: 0, + nanosecond: 0, + precision: Precision::Minute, + include_sep: true, + }, + }; + assert_writeable_eq!(offset, "+04:00"); + + let offset = FormattableOffset { + sign: crate::Sign::Negative, + time: FormattableTime { + hour: 5, + minute: 0, + second: 30, + nanosecond: 0, + precision: Precision::Minute, + include_sep: true, + }, + }; + assert_writeable_eq!(offset, "-05:00"); + + let offset = FormattableOffset { + sign: crate::Sign::Negative, + time: FormattableTime { + hour: 5, + minute: 0, + second: 30, + nanosecond: 0, + precision: Precision::Auto, + include_sep: true, + }, + }; + assert_writeable_eq!(offset, "-05:00:30"); + + let offset = FormattableOffset { + sign: crate::Sign::Negative, + time: FormattableTime { + hour: 5, + minute: 0, + second: 00, + nanosecond: 123050000, + precision: Precision::Auto, + include_sep: true, + }, + }; + assert_writeable_eq!(offset, "-05:00:00.12305"); + } + + #[test] + fn time_to_precision() { + let time = FormattableTime { + hour: 5, + minute: 0, + second: 00, + nanosecond: 123050000, + precision: Precision::Digit(8), + include_sep: true, + }; + assert_writeable_eq!(time, "05:00:00.12305000"); + + let time = FormattableTime { + hour: 5, + minute: 0, + second: 00, + nanosecond: 123050002, + precision: Precision::Digit(9), + include_sep: true, + }; + assert_writeable_eq!(time, "05:00:00.123050002"); + + let time = FormattableTime { + hour: 5, + minute: 0, + second: 00, + nanosecond: 123050000, + precision: Precision::Digit(1), + include_sep: true, + }; + assert_writeable_eq!(time, "05:00:00.1"); + + let time = FormattableTime { + hour: 5, + minute: 0, + second: 00, + nanosecond: 123050000, + precision: Precision::Digit(0), + include_sep: true, + }; + assert_writeable_eq!(time, "05:00:00"); + } + + #[test] + fn date_string() { + let date = FormattableDate(2024, 12, 8); + assert_writeable_eq!(date, "2024-12-08"); + + let date = FormattableDate(987654, 12, 8); + assert_writeable_eq!(date, "+987654-12-08"); + + let date = FormattableDate(-987654, 12, 8); + assert_writeable_eq!(date, "-987654-12-08"); + + let date = FormattableDate(0, 12, 8); + assert_writeable_eq!(date, "0000-12-08"); + + let date = FormattableDate(10_000, 12, 8); + assert_writeable_eq!(date, "+010000-12-08"); + + let date = FormattableDate(-10_000, 12, 8); + assert_writeable_eq!(date, "-010000-12-08"); + } +} diff --git a/deps/temporal/src/parsers/time_zone.rs b/deps/temporal/src/parsers/time_zone.rs new file mode 100644 index 00000000000000..51b9d10c434161 --- /dev/null +++ b/deps/temporal/src/parsers/time_zone.rs @@ -0,0 +1,66 @@ +use ixdtf::{ + encoding::Utf8, + parsers::{IxdtfParser, TimeZoneParser}, + records::{TimeZoneRecord, UtcOffsetRecord, UtcOffsetRecordOrZ}, +}; + +use crate::provider::TimeZoneProvider; +use crate::{builtins::time_zone::UtcOffset, TemporalError, TemporalResult, TimeZone}; + +use super::{parse_ixdtf, ParseVariant}; + +#[inline] +pub(crate) fn parse_allowed_timezone_formats( + s: &str, + provider: &impl TimeZoneProvider, +) -> Option { + let (offset, annotation) = if let Ok((offset, annotation)) = + parse_ixdtf(s.as_bytes(), ParseVariant::DateTime).map(|r| (r.offset, r.tz)) + { + (offset, annotation) + } else if let Ok((offset, annotation)) = IxdtfParser::from_str(s) + .parse_time() + .map(|r| (r.offset, r.tz)) + { + (offset, annotation) + } else if let Ok((offset, annotation)) = + parse_ixdtf(s.as_bytes(), ParseVariant::YearMonth).map(|r| (r.offset, r.tz)) + { + (offset, annotation) + } else if let Ok((offset, annotation)) = + parse_ixdtf(s.as_bytes(), ParseVariant::MonthDay).map(|r| (r.offset, r.tz)) + { + (offset, annotation) + } else { + return None; + }; + + if let Some(annotation) = annotation { + return TimeZone::from_time_zone_record(annotation.tz, provider).ok(); + }; + + if let Some(offset) = offset { + match offset { + UtcOffsetRecordOrZ::Z => return Some(TimeZone::utc_with_provider(provider)), + UtcOffsetRecordOrZ::Offset(offset) => { + let offset = match offset { + UtcOffsetRecord::MinutePrecision(offset) => offset, + _ => return None, + }; + return Some(TimeZone::UtcOffset(UtcOffset::from_ixdtf_minute_record( + offset, + ))); + } + } + } + + None +} + +#[inline] +pub(crate) fn parse_identifier(source: &str) -> TemporalResult> { + let mut parser = TimeZoneParser::from_str(source); + parser.parse_identifier().or(Err( + TemporalError::range().with_message("Invalid TimeZone Identifier") + )) +} diff --git a/deps/temporal/src/primitive.rs b/deps/temporal/src/primitive.rs new file mode 100644 index 00000000000000..bc7cfe302379df --- /dev/null +++ b/deps/temporal/src/primitive.rs @@ -0,0 +1,378 @@ +//! Implementation of the FiniteF64 primitive + +use core::cmp::Ordering; + +use crate::{error::ErrorMessage, TemporalError, TemporalResult}; +use num_traits::float::FloatCore; +use num_traits::{AsPrimitive, FromPrimitive, PrimInt}; + +#[derive(Debug, Default, Clone, Copy, PartialEq, PartialOrd)] +pub struct FiniteF64(pub(crate) f64); + +impl core::fmt::Display for FiniteF64 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_fmt(format_args!("{}", self.0)) + } +} + +impl FiniteF64 { + #[inline] + pub fn as_inner(&self) -> f64 { + self.0 + } + + #[inline] + pub fn is_zero(&self) -> bool { + self.0 == 0.0 + } + + #[inline] + pub fn negate(&self) -> Self { + if !self.is_zero() { + Self(-self.0) + } else { + *self + } + } + + #[inline] + pub fn abs(&self) -> Self { + Self(self.0.abs()) + } + + #[inline] + pub fn checked_add(&self, other: &Self) -> TemporalResult { + let result = Self(self.0 + other.0); + if !result.0.is_finite() { + return Err(TemporalError::range().with_enum(ErrorMessage::NumberNotFinite)); + } + Ok(result) + } + + #[inline] + pub fn checked_mul_add(&self, a: FiniteF64, b: FiniteF64) -> TemporalResult { + let result = Self(core_maths::CoreFloat::mul_add(self.0, a.0, b.0)); + if !result.0.is_finite() { + return Err(TemporalError::range().with_enum(ErrorMessage::NumberNotFinite)); + } + Ok(result) + } + + #[inline] + pub fn checked_div(&self, other: &Self) -> TemporalResult { + let result = Self(self.0 / other.0); + if !result.0.is_finite() { + return Err(TemporalError::range().with_enum(ErrorMessage::NumberNotFinite)); + } + Ok(result) + } + + pub fn copysign(&self, other: f64) -> Self { + if !self.is_zero() { + Self(self.0.copysign(other)) + } else { + *self + } + } + + /// Returns an integer of type `T` if if value is integral + pub fn as_integer_if_integral>(&self) -> TemporalResult + where + f64: AsPrimitive, + { + if self.0 != FloatCore::trunc(self.0) { + return Err(TemporalError::range().with_enum(ErrorMessage::NumberNotIntegral)); + } + Ok(self.0.as_()) + } + + /// Truncate the current `FiniteF64` to an integer `T` + pub fn as_integer_with_truncation>(&self) -> T + where + f64: AsPrimitive, + { + let clamped = + num_traits::clamp(self.as_inner(), T::min_value().as_(), T::max_value().as_()); + clamped.as_() + } + + /// Truncate the current `FiniteF64` to an integer `T`, throwing an error if the value is not positive. + pub fn as_positive_integer_with_truncation>( + &self, + ) -> TemporalResult + where + f64: AsPrimitive, + i8: AsPrimitive, + { + let truncated_value = self.as_integer_with_truncation::(); + if truncated_value <= 0i8.as_() { + return Err(TemporalError::range().with_enum(ErrorMessage::NumberNotPositive)); + } + Ok(truncated_value) + } +} + +impl AsPrimitive for FiniteF64 { + fn as_(self) -> i64 { + self.0 as i64 + } +} + +impl AsPrimitive for FiniteF64 { + fn as_(self) -> i128 { + self.0 as i128 + } +} + +impl TryFrom for FiniteF64 { + type Error = TemporalError; + fn try_from(value: f64) -> Result { + if !value.is_finite() { + return Err(TemporalError::range().with_enum(ErrorMessage::NumberNotFinite)); + } + Ok(Self(value)) + } +} + +impl TryFrom for FiniteF64 { + type Error = TemporalError; + fn try_from(value: i64) -> Result { + let result = f64::from_i64(value) + .ok_or(TemporalError::range().with_enum(ErrorMessage::NumberOutOfRange))?; + Ok(Self(result)) + } +} + +impl TryFrom for FiniteF64 { + type Error = TemporalError; + fn try_from(value: u64) -> Result { + let result = f64::from_u64(value) + .ok_or(TemporalError::range().with_enum(ErrorMessage::NumberOutOfRange))?; + Ok(Self(result)) + } +} + +impl TryFrom for FiniteF64 { + type Error = TemporalError; + fn try_from(value: i128) -> Result { + let result = f64::from_i128(value) + .ok_or(TemporalError::range().with_enum(ErrorMessage::NumberOutOfRange))?; + debug_assert!(result.is_finite()); + Ok(Self(result)) + } +} + +impl TryFrom for FiniteF64 { + type Error = TemporalError; + fn try_from(value: u128) -> Result { + let result = f64::from_u128(value) + .ok_or(TemporalError::range().with_enum(ErrorMessage::NumberOutOfRange))?; + debug_assert!(result.is_finite()); + Ok(Self(result)) + } +} + +impl From for FiniteF64 { + fn from(value: i8) -> Self { + Self(f64::from(value)) + } +} + +impl From for FiniteF64 { + fn from(value: i16) -> Self { + Self(f64::from(value)) + } +} + +impl From for FiniteF64 { + fn from(value: i32) -> Self { + Self(f64::from(value)) + } +} + +impl From for FiniteF64 { + fn from(value: u8) -> Self { + Self(f64::from(value)) + } +} + +impl From for FiniteF64 { + fn from(value: u16) -> Self { + Self(f64::from(value)) + } +} + +impl From for FiniteF64 { + fn from(value: u32) -> Self { + Self(f64::from(value)) + } +} + +impl PartialEq for FiniteF64 { + fn eq(&self, other: &f64) -> bool { + self.0 == *other + } +} + +impl PartialOrd for FiniteF64 { + fn partial_cmp(&self, other: &f64) -> Option { + self.0.partial_cmp(other) + } +} + +impl Eq for FiniteF64 {} + +#[allow(clippy::derive_ord_xor_partial_ord)] +impl Ord for FiniteF64 { + fn cmp(&self, other: &Self) -> Ordering { + match self.0.partial_cmp(&other.0) { + Some(ordering) => ordering, + None => { + debug_assert!(false, "could not compare finite f64: {self} {other}"); + Ordering::Equal + } + } + } +} + +#[cfg(test)] +mod tests { + use super::FiniteF64; + + use num_traits::FromPrimitive; + + #[test] + fn finitef64_i128_limits() { + let max = f64::from_i128(i128::MAX).unwrap(); + assert_eq!(max, 170_141_183_460_469_231_731_687_303_715_884_105_727.0); + let min = f64::from_i128(i128::MIN).unwrap(); + assert_eq!(min, -170_141_183_460_469_231_731_687_303_715_884_105_728.0); + } + + #[test] + fn finitef64_u128_limits() { + let max = f64::from_u128(u128::MAX).unwrap(); + assert_eq!(max, 340_282_366_920_938_463_463_374_607_431_768_211_455.0); + let min = f64::from_u128(u128::MIN).unwrap(); + assert_eq!(min, 0.0); + } + + #[test] + fn finitef64_truncate() { + let value = 8_640_000_000_000_000i64; + let finite = FiniteF64::try_from(value).unwrap(); + + let num_usize = finite.as_integer_with_truncation::(); + #[cfg(target_pointer_width = "64")] + assert_eq!(num_usize, 8_640_000_000_000_000); + #[cfg(target_pointer_width = "32")] + assert_eq!(num_usize, usize::MAX); + let num_u8 = finite.as_integer_with_truncation::(); + assert_eq!(num_u8, u8::MAX); + let num_u16 = finite.as_integer_with_truncation::(); + assert_eq!(num_u16, u16::MAX); + let num_u32 = finite.as_integer_with_truncation::(); + assert_eq!(num_u32, u32::MAX); + let num_u64 = finite.as_integer_with_truncation::(); + assert_eq!(num_u64, 8_640_000_000_000_000); + let num_u128 = finite.as_integer_with_truncation::(); + assert_eq!(num_u128, 8_640_000_000_000_000); + + let num_isize = finite.as_integer_with_truncation::(); + #[cfg(target_pointer_width = "64")] + assert_eq!(num_isize, 8_640_000_000_000_000); + #[cfg(target_pointer_width = "32")] + assert_eq!(num_isize, isize::MAX); + let num_i8 = finite.as_integer_with_truncation::(); + assert_eq!(num_i8, i8::MAX); + let num_i16 = finite.as_integer_with_truncation::(); + assert_eq!(num_i16, i16::MAX); + let num_i32 = finite.as_integer_with_truncation::(); + assert_eq!(num_i32, i32::MAX); + let num_i64 = finite.as_integer_with_truncation::(); + assert_eq!(num_i64, 8_640_000_000_000_000); + let num_i128 = finite.as_integer_with_truncation::(); + assert_eq!(num_i128, 8_640_000_000_000_000); + } + + #[test] + fn finitef64_as_positive_integer_with_truncation_int() { + let positive = FiniteF64::from(5); + let truncated = positive + .as_positive_integer_with_truncation::() + .unwrap(); + assert_eq!(truncated, 5); + + let negative = FiniteF64::from(-4); + let truncated = negative.as_positive_integer_with_truncation::(); + assert!(truncated.is_err()); + } + + #[test] + fn finitef64_as_positive_integer_with_truncation_correct_floor() { + let floors_to_zero = FiniteF64::try_from(0.5).unwrap(); + let truncated = floors_to_zero.as_positive_integer_with_truncation::(); + assert!(truncated.is_err()); + + let floors_to_zero = FiniteF64::try_from(-0.5).unwrap(); + let truncated = floors_to_zero.as_positive_integer_with_truncation::(); + assert!(truncated.is_err()); + + let floors_to_zero = FiniteF64::try_from(0.9).unwrap(); + let truncated = floors_to_zero.as_positive_integer_with_truncation::(); + assert!(truncated.is_err()); + + let floors_to_one = FiniteF64::try_from(1.1).unwrap(); + let truncated = floors_to_one + .as_positive_integer_with_truncation::() + .unwrap(); + assert_eq!(truncated, 1); + + let floors_to_one = FiniteF64::try_from(1.9).unwrap(); + let truncated = floors_to_one + .as_positive_integer_with_truncation::() + .unwrap(); + assert_eq!(truncated, 1); + } + + #[test] + fn finitef64_truncate_correct_floor() { + let floors_to_zero = FiniteF64::try_from(0.5).unwrap(); + let truncated = floors_to_zero.as_integer_with_truncation::(); + assert_eq!(truncated, 0); + + let floors_to_zero = FiniteF64::try_from(-0.5).unwrap(); + let truncated = floors_to_zero.as_integer_with_truncation::(); + assert_eq!(truncated, 0); + + let floors_to_one = FiniteF64::try_from(-1.2).unwrap(); + let truncated = floors_to_one.as_integer_with_truncation::(); + assert_eq!(truncated, -1); + + let floors_to_one = FiniteF64::try_from(1.9).unwrap(); + let truncated = floors_to_one.as_integer_with_truncation::(); + assert_eq!(truncated, 1); + } + + #[test] + fn finitef64_integer_if_integral_returns_err() { + let test_value = FiniteF64::try_from(0.999).unwrap(); + let integer = test_value.as_integer_if_integral::(); + assert!(integer.is_err()); + + let test_value = FiniteF64::try_from(1.5).unwrap(); + let integer = test_value.as_integer_if_integral::(); + assert!(integer.is_err()); + } + + #[test] + fn finitef64_integer_if_integral_returns_int() { + let test_value = FiniteF64::from(0); + let integer = test_value.as_integer_if_integral::(); + assert_eq!(integer, Ok(0)); + + let test_value = FiniteF64::from(1); + let integer = test_value.as_integer_if_integral::(); + assert_eq!(integer, Ok(1)); + } +} diff --git a/deps/temporal/src/provider.rs b/deps/temporal/src/provider.rs new file mode 100644 index 00000000000000..2b18bbc0658b8b --- /dev/null +++ b/deps/temporal/src/provider.rs @@ -0,0 +1,9 @@ +//! The `TimeZoneProvider` trait. + +pub use timezone_provider::provider::{ + CandidateEpochNanoseconds, EpochNanosecondsAndOffset, GapEntryOffsets, NeverProvider, + ParseDirectionError, TimeZoneId, TimeZoneProvider, TransitionDirection, UtcOffsetSeconds, +}; + +#[cfg(feature = "compiled_data")] +pub use crate::builtins::TZ_PROVIDER as COMPILED_TZ_PROVIDER; diff --git a/deps/temporal/src/rounding.rs b/deps/temporal/src/rounding.rs new file mode 100644 index 00000000000000..217bc66cebf8ab --- /dev/null +++ b/deps/temporal/src/rounding.rs @@ -0,0 +1,626 @@ +//! Implementation of increment rounding functionality + +use crate::{ + options::{RoundingMode, UnsignedRoundingMode}, + TemporalResult, TemporalUnwrap, +}; + +use core::{ + cmp::Ordering, + num::NonZeroU128, + ops::{Div, Neg}, +}; + +use num_traits::float::FloatCore; +use num_traits::{ConstZero, Euclid, FromPrimitive, NumCast, Signed, ToPrimitive}; + +pub(crate) trait Roundable: + Euclid + Div + PartialOrd + Signed + FromPrimitive + ToPrimitive + NumCast + ConstZero + Copy +{ + /// Is dividend an exact multiple of divisor? + fn is_exact(dividend: Self, divisor: Self) -> bool; + /// Compare dividend/divisor with the midpoint of result_floor/result_ceil. + fn compare_remainder(dividend: Self, divisor: Self) -> Ordering; + fn is_even_cardinal(dividend: Self, divisor: Self) -> bool; + /// Return dividend/divisor rounded down (floor) + fn result_floor(dividend: Self, divisor: Self) -> i128; + /// Return dividend/divisor rounded up (ceil) + fn result_ceil(dividend: Self, divisor: Self) -> i128 { + Self::result_floor(dividend, divisor) + 1 + } +} + +#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] +pub(crate) struct IncrementRounder { + sign: bool, + dividend: T, + divisor: T, +} + +impl IncrementRounder { + #[inline] + pub(crate) fn from_signed_num(number: T, increment: NonZeroU128) -> TemporalResult { + let increment = ::from(increment.get()).temporal_unwrap()?; + Ok(Self { + sign: number >= T::ZERO, + dividend: number, + divisor: increment, + }) + } +} + +impl IncrementRounder { + #[inline] + /// https://tc39.es/proposal-temporal/#sec-temporal-roundnumbertoincrement + pub fn round(&self, mode: RoundingMode) -> i128 { + let unsigned_rounding_mode = mode.get_unsigned_round_mode(self.sign); + + let dividend = if self.sign { + self.dividend + } else { + -self.dividend + }; + + let mut rounded = + apply_unsigned_rounding_mode(dividend, self.divisor, unsigned_rounding_mode); + if !self.sign { + rounded = rounded.neg(); + } + // TODO: Add unit tests for the below + let divisor = ::from(self.divisor); + debug_assert!(divisor.is_some(), "increment is representable by a u64"); + rounded.saturating_mul(divisor.unwrap_or_default()) + } + #[inline] + /// https://tc39.es/proposal-temporal/#sec-temporal-roundnumbertoincrementasifpositive + pub fn round_as_if_positive(&self, mode: RoundingMode) -> i128 { + // 2. Let unsignedRoundingMode be GetUnsignedRoundingMode(roundingMode, positive). + let unsigned_rounding_mode = mode.get_unsigned_round_mode(true); + + // 5. Let rounded be ApplyUnsignedRoundingMode(quotient, r1, r2, unsignedRoundingMode). + let rounded = + apply_unsigned_rounding_mode(self.dividend, self.divisor, unsigned_rounding_mode); + + // TODO: Add unit tests for the below + let divisor = ::from(self.divisor); + debug_assert!(divisor.is_some(), "increment is representable by a u64"); + rounded.saturating_mul(divisor.unwrap_or_default()) + } +} + +impl Roundable for i128 { + fn is_exact(dividend: Self, divisor: Self) -> bool { + dividend.rem_euclid(divisor) == 0 + } + + fn compare_remainder(dividend: Self, divisor: Self) -> Ordering { + let midway = divisor.div_euclid(2); + let cmp = dividend.rem_euclid(divisor).cmp(&midway); + if cmp == Ordering::Equal && divisor.rem_euclid(2) != 0 { + Ordering::Less + } else { + cmp + } + } + + fn is_even_cardinal(dividend: Self, divisor: Self) -> bool { + Roundable::result_floor(dividend, divisor).rem_euclid(2) == 0 + } + + fn result_floor(dividend: Self, divisor: Self) -> i128 { + dividend.div_euclid(divisor) + } +} + +impl Roundable for f64 { + fn is_exact(dividend: Self, divisor: Self) -> bool { + let quotient_abs = (dividend / divisor).abs(); + quotient_abs == quotient_abs.floor() + } + + fn compare_remainder(dividend: Self, divisor: Self) -> Ordering { + let quotient = dividend / divisor; + let d1 = quotient - FloatCore::floor(quotient); + let d2 = FloatCore::ceil(quotient) - quotient; + let result = d1.partial_cmp(&d2); + debug_assert!( + result.is_some(), + "Should never have non-finite floats in rounding code" + ); + result.unwrap_or(Ordering::Equal) + } + + fn is_even_cardinal(dividend: Self, divisor: Self) -> bool { + let quotient = dividend / divisor; + (FloatCore::floor(quotient) / (FloatCore::ceil(quotient) - FloatCore::floor(quotient)) + % 2.0) + == 0.0 + } + + fn result_floor(dividend: Self, divisor: Self) -> i128 { + Euclid::div_euclid(÷nd, &divisor) as i128 + } +} + +impl Roundable for i64 { + fn is_exact(dividend: Self, divisor: Self) -> bool { + dividend.rem_euclid(divisor) == 0 + } + + fn compare_remainder(dividend: Self, divisor: Self) -> Ordering { + let midway = divisor.div_euclid(2); + let cmp = dividend.rem_euclid(divisor).cmp(&midway); + if cmp == Ordering::Equal && divisor.rem_euclid(2) != 0 { + Ordering::Less + } else { + cmp + } + } + + fn is_even_cardinal(dividend: Self, divisor: Self) -> bool { + Roundable::result_floor(dividend, divisor).rem_euclid(2) == 0 + } + + fn result_floor(dividend: Self, divisor: Self) -> i128 { + dividend.div_euclid(divisor).into() + } +} + +/// Applies the unsigned rounding mode. +fn apply_unsigned_rounding_mode( + dividend: T, + divisor: T, + unsigned_rounding_mode: UnsignedRoundingMode, +) -> i128 { + // (x is dividend / divisor) + + // (from RoundNumberToIncrement, RoundNumberToIncrementAsIfPositive) + // 5. Let r1 be the largest integer such that r1 ≤ quotient. + // 6. Let r2 be the smallest integer such that r2 > quotient. + let r1 = Roundable::result_floor(dividend, divisor); + let r2 = Roundable::result_ceil(dividend, divisor); + + // is_floor + // 1. If x is equal to r1, return r1. + if Roundable::is_exact(dividend, divisor) { + return r1; + } + // 2. Assert: r1 < x < r2. + // 3. Assert: unsignedRoundingMode is not undefined. + + // 4. If unsignedRoundingMode is zero, return r1. + if unsigned_rounding_mode == UnsignedRoundingMode::Zero { + return r1; + }; + // 5. If unsignedRoundingMode is infinity, return r2. + if unsigned_rounding_mode == UnsignedRoundingMode::Infinity { + return r2; + }; + + // 6. Let d1 be x – r1. + // 7. Let d2 be r2 – x. + // 8. If d1 < d2, return r1. + // 9. If d2 < d1, return r2. + match Roundable::compare_remainder(dividend, divisor) { + Ordering::Less => r1, + Ordering::Greater => r2, + Ordering::Equal => { + // 10. Assert: d1 is equal to d2. + // 11. If unsignedRoundingMode is half-zero, return r1. + if unsigned_rounding_mode == UnsignedRoundingMode::HalfZero { + return r1; + }; + // 12. If unsignedRoundingMode is half-infinity, return r2. + if unsigned_rounding_mode == UnsignedRoundingMode::HalfInfinity { + return r2; + }; + // 13. Assert: unsignedRoundingMode is half-even. + debug_assert!(unsigned_rounding_mode == UnsignedRoundingMode::HalfEven); + // 14. Let cardinality be (r1 / (r2 – r1)) modulo 2. + // 15. If cardinality is 0, return r1. + if Roundable::is_even_cardinal(dividend, divisor) { + return r1; + } + // 16. Return r2. + r2 + } + } +} + +#[cfg(test)] +mod tests { + use core::num::NonZeroU128; + + use super::{IncrementRounder, Roundable, RoundingMode}; + use core::fmt::Debug; + + #[derive(Debug)] + struct TestCase { + x: T, + increment: u128, + ceil: i128, + floor: i128, + expand: i128, + trunc: i128, + half_ceil: i128, + half_floor: i128, + half_expand: i128, + half_trunc: i128, + half_even: i128, + } + + impl TestCase { + fn run(&self) { + let rounder = IncrementRounder::from_signed_num( + self.x, + TryFrom::try_from(self.increment).unwrap(), + ) + .unwrap(); + + assert_eq!( + self.ceil, + rounder.round(RoundingMode::Ceil), + "Rounding {:?}/{:?} with mode Ceil", + self.x, + self.increment + ); + assert_eq!( + self.floor, + rounder.round(RoundingMode::Floor), + "Rounding {:?}/{:?} with mode Floor", + self.x, + self.increment + ); + assert_eq!( + self.trunc, + rounder.round(RoundingMode::Trunc), + "Rounding {:?}/{:?} with mode Trunc", + self.x, + self.increment + ); + assert_eq!( + self.floor, + rounder.round_as_if_positive(RoundingMode::Trunc), + "Rounding (as if positive) {:?}/{:?} with mode Trunc", + self.x, + self.increment + ); + + assert_eq!( + self.half_ceil, + rounder.round(RoundingMode::HalfCeil), + "Rounding {:?}/{:?} with mode HalfCeil", + self.x, + self.increment + ); + assert_eq!( + self.half_floor, + rounder.round(RoundingMode::HalfFloor), + "Rounding {:?}/{:?} with mode HalfFloor", + self.x, + self.increment + ); + assert_eq!( + self.half_expand, + rounder.round(RoundingMode::HalfExpand), + "Rounding {:?}/{:?} with mode HalfExpand", + self.x, + self.increment + ); + assert_eq!( + self.half_trunc, + rounder.round(RoundingMode::HalfTrunc), + "Rounding {:?}/{:?} with mode HalfTrunc", + self.x, + self.increment + ); + assert_eq!( + self.half_even, + rounder.round(RoundingMode::HalfEven), + "Rounding {:?}/{:?} with mode HalfEven", + self.x, + self.increment + ); + + // Ceil and floor are the same for as_if_positive + assert_eq!( + self.ceil, + rounder.round_as_if_positive(RoundingMode::Ceil), + "Rounding (as if positive) {:?}/{:?} with mode Ceil", + self.x, + self.increment + ); + assert_eq!( + self.floor, + rounder.round_as_if_positive(RoundingMode::Floor), + "Rounding (as if positive) {:?}/{:?} with mode Floor", + self.x, + self.increment + ); + // Expand and Trunc are equivalent to Ceil and Floor for as_if_positive + assert_eq!( + self.expand, + rounder.round(RoundingMode::Expand), + "Rounding {:?}/{:?} with mode Expand", + self.x, + self.increment + ); + assert_eq!( + self.ceil, + rounder.round_as_if_positive(RoundingMode::Expand), + "Rounding (as if positive) {:?}/{:?} with mode Expand", + self.x, + self.increment + ); + // Same goes for the half ones + assert_eq!( + self.half_ceil, + rounder.round_as_if_positive(RoundingMode::HalfCeil), + "Rounding (as if positive) {:?}/{:?} with mode HalfCeil", + self.x, + self.increment + ); + assert_eq!( + self.half_floor, + rounder.round_as_if_positive(RoundingMode::HalfFloor), + "Rounding (as if positive) {:?}/{:?} with mode HalfFloor", + self.x, + self.increment + ); + assert_eq!( + self.half_ceil, + rounder.round_as_if_positive(RoundingMode::HalfExpand), + "Rounding (as if positive) {:?}/{:?} with mode HalfExpand", + self.x, + self.increment + ); + assert_eq!( + self.half_floor, + rounder.round_as_if_positive(RoundingMode::HalfTrunc), + "Rounding (as if positive) {:?}/{:?} with mode HalfTrunc", + self.x, + self.increment + ); + // HalfEven is just HalfEven + assert_eq!( + self.half_even, + rounder.round_as_if_positive(RoundingMode::HalfEven), + "Rounding (as if positive) {:?}/{:?} with mode HalfEven", + self.x, + self.increment + ); + } + } + + #[test] + fn test_basic_rounding_cases() { + const CASES: &[TestCase] = &[ + TestCase { + x: 100, + increment: 10, + ceil: 100, + floor: 100, + expand: 100, + trunc: 100, + half_ceil: 100, + half_floor: 100, + half_expand: 100, + half_trunc: 100, + half_even: 100, + }, + TestCase { + x: 101, + increment: 10, + ceil: 110, + floor: 100, + expand: 110, + trunc: 100, + half_ceil: 100, + half_floor: 100, + half_expand: 100, + half_trunc: 100, + half_even: 100, + }, + TestCase { + x: 105, + increment: 10, + ceil: 110, + floor: 100, + expand: 110, + trunc: 100, + half_ceil: 110, + half_floor: 100, + half_expand: 110, + half_trunc: 100, + half_even: 100, + }, + TestCase { + x: 107, + increment: 10, + ceil: 110, + floor: 100, + expand: 110, + trunc: 100, + half_ceil: 110, + half_floor: 110, + half_expand: 110, + half_trunc: 110, + half_even: 110, + }, + TestCase { + x: -100, + increment: 10, + ceil: -100, + floor: -100, + expand: -100, + trunc: -100, + half_ceil: -100, + half_floor: -100, + half_expand: -100, + half_trunc: -100, + half_even: -100, + }, + TestCase { + x: -101, + increment: 10, + ceil: -100, + floor: -110, + expand: -110, + trunc: -100, + half_ceil: -100, + half_floor: -100, + half_expand: -100, + half_trunc: -100, + half_even: -100, + }, + TestCase { + x: -105, + increment: 10, + ceil: -100, + floor: -110, + expand: -110, + trunc: -100, + half_ceil: -100, + half_floor: -110, + half_expand: -110, + half_trunc: -100, + half_even: -100, + }, + TestCase { + x: -107, + increment: 10, + ceil: -100, + floor: -110, + expand: -110, + trunc: -100, + half_ceil: -110, + half_floor: -110, + half_expand: -110, + half_trunc: -110, + half_even: -110, + }, + // More negative number tests + TestCase { + x: -9i128, + increment: 2, + ceil: -8, + floor: -10, + expand: -10, + trunc: -8, + half_ceil: -8, + half_floor: -10, + half_expand: -10, + half_trunc: -8, + half_even: -8, + }, + TestCase { + x: -14i128, + increment: 3, + ceil: -12, + floor: -15, + expand: -15, + trunc: -12, + half_ceil: -15, + half_floor: -15, + half_expand: -15, + half_trunc: -15, + half_even: -15, + }, + ]; + + for case in CASES { + case.run(); + + TestCase { + x: case.x as f64, + increment: case.increment, + ceil: case.ceil, + floor: case.floor, + expand: case.expand, + trunc: case.trunc, + half_ceil: case.half_ceil, + half_floor: case.half_floor, + half_expand: case.half_expand, + half_trunc: case.half_trunc, + half_even: case.half_even, + } + .run(); + + TestCase { + x: case.x as i64, + increment: case.increment, + ceil: case.ceil, + floor: case.floor, + expand: case.expand, + trunc: case.trunc, + half_ceil: case.half_ceil, + half_floor: case.half_floor, + half_expand: case.half_expand, + half_trunc: case.half_trunc, + half_even: case.half_even, + } + .run(); + } + } + + #[test] + fn test_float_rounding_cases() { + const CASES: &[TestCase] = &[ + TestCase { + x: -8.5f64, + increment: 1, + ceil: -8, + floor: -9, + expand: -9, + trunc: -8, + half_ceil: -8, + half_floor: -9, + half_expand: -9, + half_trunc: -8, + half_even: -8, + }, + TestCase { + x: -8.5f64, + increment: 2, + ceil: -8, + floor: -10, + expand: -10, + trunc: -8, + half_ceil: -8, + half_floor: -8, + half_expand: -8, + half_trunc: -8, + half_even: -8, + }, + TestCase { + x: -9.5f64, + increment: 2, + ceil: -8, + floor: -10, + expand: -10, + trunc: -8, + half_ceil: -10, + half_floor: -10, + half_expand: -10, + half_trunc: -10, + half_even: -10, + }, + ]; + + for case in CASES { + case.run() + } + } + + #[test] + fn dt_since_basic_rounding() { + let result = IncrementRounder::::from_signed_num( + -84082624864197532, + NonZeroU128::new(1800000000000).unwrap(), + ) + .unwrap() + .round(RoundingMode::HalfExpand); + + assert_eq!(result, -84083400000000000); + } +} diff --git a/deps/temporal/src/sys.rs b/deps/temporal/src/sys.rs new file mode 100644 index 00000000000000..a530dc88358fcc --- /dev/null +++ b/deps/temporal/src/sys.rs @@ -0,0 +1,79 @@ +use crate::builtins::Now; +use crate::host::HostClock; +use crate::host::HostHooks; +use crate::host::HostTimeZone; +use crate::TemporalResult; + +use crate::unix_time::EpochNanoseconds; +use crate::TemporalError; +use crate::TimeZone; +#[cfg(feature = "sys")] +use timezone_provider::provider::TimeZoneProvider; +use web_time::{SystemTime, UNIX_EPOCH}; + +// TODO: Look into and potentially implement a `SystemTime` struct allows +// providing closures or trait implementations that can then +// be used to construct [`Now`]. Basically `Temporal` but with +// traits or closures. +// +// Temporal could then be something like: +// +// pub struct Temporal(SystemTime) +// + +/// The Temporal object for accessing current system time +#[cfg(feature = "sys")] +pub struct Temporal; + +#[cfg(feature = "sys")] +impl Temporal { + /// Get a `Now` object for the default host system. + pub fn now() -> Now { + Now::new(DefaultHostSystem) + } +} + +/// A default host system implementation +/// +/// This implementation is backed by [`SystemTime`] and [`iana_time_zone`] +#[cfg(feature = "sys")] +pub struct DefaultHostSystem; + +#[cfg(feature = "sys")] +impl HostHooks for DefaultHostSystem {} + +#[cfg(feature = "sys")] +impl HostClock for DefaultHostSystem { + fn get_host_epoch_nanoseconds(&self) -> TemporalResult { + get_system_nanoseconds() + } +} + +#[cfg(feature = "sys")] +impl HostTimeZone for DefaultHostSystem { + fn get_host_time_zone( + &self, + provider: &impl timezone_provider::provider::TimeZoneProvider, + ) -> TemporalResult { + get_system_timezone(provider) + } +} + +#[cfg(feature = "sys")] +#[inline] +pub(crate) fn get_system_timezone(provider: &impl TimeZoneProvider) -> TemporalResult { + iana_time_zone::get_timezone() + .map(|s| TimeZone::try_from_identifier_str_with_provider(&s, provider)) + .map_err(|_| TemporalError::general("Error fetching system time"))? +} + +/// Returns the system time in nanoseconds. +#[cfg(feature = "sys")] +pub(crate) fn get_system_nanoseconds() -> TemporalResult { + use crate::unix_time::EpochNanoseconds; + + SystemTime::now() + .duration_since(UNIX_EPOCH) + .map_err(|_| TemporalError::general("Error fetching system time")) + .map(|d| EpochNanoseconds::from(d.as_nanos() as i128)) +} diff --git a/deps/temporal/src/tzdb.rs b/deps/temporal/src/tzdb.rs new file mode 100644 index 00000000000000..4f2026381fdb91 --- /dev/null +++ b/deps/temporal/src/tzdb.rs @@ -0,0 +1,68 @@ +// We can clean these imports up eventually + +#[cfg(feature = "compiled_data")] +#[cfg(test)] +pub use timezone_provider::tzif::CompiledTzdbProvider; +#[cfg(test)] +pub use timezone_provider::tzif::FsTzdbProvider; + +#[cfg(test)] +mod tests { + use crate::{ + builtins::calendar::CalendarFields, partial::PartialZonedDateTime, TimeZone, ZonedDateTime, + }; + + use super::FsTzdbProvider; + + #[test] + fn canonical_time_zone() { + let provider = FsTzdbProvider::default(); + let valid_iana_identifiers = [ + ("AFRICA/Bissau", "Africa/Bissau", "-01:00"), + ("America/Belem", "America/Belem", "-03:00"), + ("Europe/Vienna", "Europe/Vienna", "+01:00"), + ("America/New_York", "America/New_York", "-05:00"), + ("Africa/CAIRO", "Africa/Cairo", "+02:00"), + ("Asia/Ulan_Bator", "Asia/Ulan_Bator", "+07:00"), + ("GMT", "GMT", "+00:00"), + ("etc/gmt", "Etc/GMT", "+00:00"), + ( + "1994-11-05T08:15:30-05:00[America/New_York]", + "America/New_York", + "-05:00", + ), + ( + "1994-11-05T08:15:30-05[America/Chicago]", + "America/Chicago", + "-06:00", + ), + ("EuROpe/DUBLIn", "Europe/Dublin", "+01:00"), + ]; + + for (valid_iana_identifier, canonical, offset) in valid_iana_identifiers { + let time_zone = + TimeZone::try_from_str_with_provider(valid_iana_identifier, &provider).unwrap(); + + assert_eq!( + time_zone.identifier_with_provider(&provider).unwrap(), + canonical + ); + let result = ZonedDateTime::from_partial_with_provider( + PartialZonedDateTime::default() + .with_calendar_fields( + CalendarFields::new() + .with_year(1970) + .with_month(1) + .with_day(1), + ) + .with_timezone(Some(time_zone)), + None, + None, + None, + &provider, + ) + .unwrap(); + assert_eq!(result.offset(), offset); + } + } +} diff --git a/deps/temporal/src/utils.rs b/deps/temporal/src/utils.rs new file mode 100644 index 00000000000000..bb85c67cc99515 --- /dev/null +++ b/deps/temporal/src/utils.rs @@ -0,0 +1,16 @@ +//! Utility date and time equations for Temporal + +pub(crate) use timezone_provider::utils::epoch_days_from_gregorian_date; + +// NOTE: Potentially add more of tests. + +// ==== Begin Date Equations ==== + +pub(crate) const MS_PER_HOUR: i64 = 3_600_000; +pub(crate) const MS_PER_MINUTE: i64 = 60_000; + +pub(crate) use timezone_provider::utils::{ + epoch_days_to_epoch_ms, iso_days_in_month, ymd_from_epoch_milliseconds, +}; + +// ==== End Calendar Equations ==== diff --git a/deps/temporal/temporal_capi/.gitattributes b/deps/temporal/temporal_capi/.gitattributes new file mode 100644 index 00000000000000..49065d790bda1e --- /dev/null +++ b/deps/temporal/temporal_capi/.gitattributes @@ -0,0 +1 @@ +bindings/** linguist-generated=true diff --git a/deps/temporal/temporal_capi/.gitignore b/deps/temporal/temporal_capi/.gitignore new file mode 100644 index 00000000000000..fa929750c2d889 --- /dev/null +++ b/deps/temporal/temporal_capi/.gitignore @@ -0,0 +1 @@ +*.out \ No newline at end of file diff --git a/deps/temporal/temporal_capi/Cargo.toml b/deps/temporal/temporal_capi/Cargo.toml new file mode 100644 index 00000000000000..c6201edbf1137d --- /dev/null +++ b/deps/temporal/temporal_capi/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "temporal_capi" +description = "C interface to temporal_rs" +edition.workspace = true +version.workspace = true +rust-version.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +include = [ + "bindings/**/*", + "src/**/*", + "tests/**/*", + "Cargo.toml", + "LICENSE-Apache", + "LICENSE-MIT", + "README.md", +] + +[dependencies] +diplomat.workspace = true +diplomat-runtime.workspace = true +num-traits.workspace = true +temporal_rs = { workspace = true, default-features = false } +timezone_provider = { workspace = true, default-features = false } +icu_calendar = { version = "2.0.2", default-features = false } +icu_locale = { version = "2.0.0" } +writeable = "0.6.1" +zoneinfo64 = { workspace = true, optional = true } + +[features] +compiled_data = ["temporal_rs/compiled_data"] +zoneinfo64 = ["dep:zoneinfo64", "timezone_provider/zoneinfo64"] + +[package.metadata.docs.rs] +all-features = true diff --git a/deps/temporal/temporal_capi/LICENSE-Apache b/deps/temporal/temporal_capi/LICENSE-Apache new file mode 100644 index 00000000000000..551045b58932a5 --- /dev/null +++ b/deps/temporal/temporal_capi/LICENSE-Apache @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2024 Boa + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/deps/temporal/temporal_capi/LICENSE-MIT b/deps/temporal/temporal_capi/LICENSE-MIT new file mode 100644 index 00000000000000..d5624ad0c1fb69 --- /dev/null +++ b/deps/temporal/temporal_capi/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Boa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/deps/temporal/temporal_capi/README.md b/deps/temporal/temporal_capi/README.md new file mode 100644 index 00000000000000..284b0e2e1ab274 --- /dev/null +++ b/deps/temporal/temporal_capi/README.md @@ -0,0 +1,14 @@ +# temporal_capi [![crates.io](https://img.shields.io/crates/v/temporal_capi)](https://crates.io/crates/temporal_capi) + + + +This crate contains the original definitions of [`temporal_rs`] APIs consumed by [Diplomat](https://github.com/rust-diplomat/diplomat) +to generate FFI bindings. We currently generate bindings for C++ and `extern "C"` APIs. + +The APIs exposed by this crate are *not intended to be used from Rust* and as such this crate may change its Rust API +across compatible semver versions. In contrast, the `extern "C"` APIs and all the language bindings are stable within +the same major semver version. + +[`temporal_rs`]: http://crates.io/crates/temporal_rs + + diff --git a/deps/temporal/temporal_capi/bindings/c/AnyCalendarKind.d.h b/deps/temporal/temporal_capi/bindings/c/AnyCalendarKind.d.h new file mode 100644 index 00000000000000..44bed28e18cb5a --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/AnyCalendarKind.d.h @@ -0,0 +1,39 @@ +#ifndef AnyCalendarKind_D_H +#define AnyCalendarKind_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef enum AnyCalendarKind { + AnyCalendarKind_Buddhist = 0, + AnyCalendarKind_Chinese = 1, + AnyCalendarKind_Coptic = 2, + AnyCalendarKind_Dangi = 3, + AnyCalendarKind_Ethiopian = 4, + AnyCalendarKind_EthiopianAmeteAlem = 5, + AnyCalendarKind_Gregorian = 6, + AnyCalendarKind_Hebrew = 7, + AnyCalendarKind_Indian = 8, + AnyCalendarKind_HijriTabularTypeIIFriday = 9, + AnyCalendarKind_HijriSimulatedMecca = 10, + AnyCalendarKind_HijriTabularTypeIIThursday = 11, + AnyCalendarKind_HijriUmmAlQura = 12, + AnyCalendarKind_Iso = 13, + AnyCalendarKind_Japanese = 14, + AnyCalendarKind_JapaneseExtended = 15, + AnyCalendarKind_Persian = 16, + AnyCalendarKind_Roc = 17, +} AnyCalendarKind; + +typedef struct AnyCalendarKind_option {union { AnyCalendarKind ok; }; bool is_ok; } AnyCalendarKind_option; + + + +#endif // AnyCalendarKind_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/AnyCalendarKind.h b/deps/temporal/temporal_capi/bindings/c/AnyCalendarKind.h new file mode 100644 index 00000000000000..7422307c618a61 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/AnyCalendarKind.h @@ -0,0 +1,28 @@ +#ifndef AnyCalendarKind_H +#define AnyCalendarKind_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "AnyCalendarKind.d.h" + + + + + + +typedef struct temporal_rs_AnyCalendarKind_get_for_str_result {union {AnyCalendarKind ok; }; bool is_ok;} temporal_rs_AnyCalendarKind_get_for_str_result; +temporal_rs_AnyCalendarKind_get_for_str_result temporal_rs_AnyCalendarKind_get_for_str(DiplomatStringView s); + +typedef struct temporal_rs_AnyCalendarKind_parse_temporal_calendar_string_result {union {AnyCalendarKind ok; }; bool is_ok;} temporal_rs_AnyCalendarKind_parse_temporal_calendar_string_result; +temporal_rs_AnyCalendarKind_parse_temporal_calendar_string_result temporal_rs_AnyCalendarKind_parse_temporal_calendar_string(DiplomatStringView s); + + + + + +#endif // AnyCalendarKind_H diff --git a/deps/temporal/temporal_capi/bindings/c/ArithmeticOverflow.d.h b/deps/temporal/temporal_capi/bindings/c/ArithmeticOverflow.d.h new file mode 100644 index 00000000000000..47d8f551a2bac7 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/ArithmeticOverflow.d.h @@ -0,0 +1,23 @@ +#ifndef ArithmeticOverflow_D_H +#define ArithmeticOverflow_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef enum ArithmeticOverflow { + ArithmeticOverflow_Constrain = 0, + ArithmeticOverflow_Reject = 1, +} ArithmeticOverflow; + +typedef struct ArithmeticOverflow_option {union { ArithmeticOverflow ok; }; bool is_ok; } ArithmeticOverflow_option; + + + +#endif // ArithmeticOverflow_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/ArithmeticOverflow.h b/deps/temporal/temporal_capi/bindings/c/ArithmeticOverflow.h new file mode 100644 index 00000000000000..4406c69ff59356 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/ArithmeticOverflow.h @@ -0,0 +1,22 @@ +#ifndef ArithmeticOverflow_H +#define ArithmeticOverflow_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "ArithmeticOverflow.d.h" + + + + + + + + + + +#endif // ArithmeticOverflow_H diff --git a/deps/temporal/temporal_capi/bindings/c/Calendar.d.h b/deps/temporal/temporal_capi/bindings/c/Calendar.d.h new file mode 100644 index 00000000000000..d748ff0cb9d933 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/Calendar.d.h @@ -0,0 +1,19 @@ +#ifndef Calendar_D_H +#define Calendar_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct Calendar Calendar; + + + + +#endif // Calendar_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/Calendar.h b/deps/temporal/temporal_capi/bindings/c/Calendar.h new file mode 100644 index 00000000000000..6393eac71a49a3 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/Calendar.h @@ -0,0 +1,37 @@ +#ifndef Calendar_H +#define Calendar_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "AnyCalendarKind.d.h" +#include "TemporalError.d.h" + +#include "Calendar.d.h" + + + + + + +Calendar* temporal_rs_Calendar_try_new_constrain(AnyCalendarKind kind); + +typedef struct temporal_rs_Calendar_from_utf8_result {union {Calendar* ok; TemporalError err;}; bool is_ok;} temporal_rs_Calendar_from_utf8_result; +temporal_rs_Calendar_from_utf8_result temporal_rs_Calendar_from_utf8(DiplomatStringView s); + +bool temporal_rs_Calendar_is_iso(const Calendar* self); + +DiplomatStringView temporal_rs_Calendar_identifier(const Calendar* self); + +AnyCalendarKind temporal_rs_Calendar_kind(const Calendar* self); + +void temporal_rs_Calendar_destroy(Calendar* self); + + + + + +#endif // Calendar_H diff --git a/deps/temporal/temporal_capi/bindings/c/DateDuration.d.h b/deps/temporal/temporal_capi/bindings/c/DateDuration.d.h new file mode 100644 index 00000000000000..b92c029df696b7 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/DateDuration.d.h @@ -0,0 +1,19 @@ +#ifndef DateDuration_D_H +#define DateDuration_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct DateDuration DateDuration; + + + + +#endif // DateDuration_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/DateDuration.h b/deps/temporal/temporal_capi/bindings/c/DateDuration.h new file mode 100644 index 00000000000000..56b8aadcab7b8e --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/DateDuration.h @@ -0,0 +1,35 @@ +#ifndef DateDuration_H +#define DateDuration_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "Sign.d.h" +#include "TemporalError.d.h" + +#include "DateDuration.d.h" + + + + + + +typedef struct temporal_rs_DateDuration_try_new_result {union {DateDuration* ok; TemporalError err;}; bool is_ok;} temporal_rs_DateDuration_try_new_result; +temporal_rs_DateDuration_try_new_result temporal_rs_DateDuration_try_new(int64_t years, int64_t months, int64_t weeks, int64_t days); + +DateDuration* temporal_rs_DateDuration_abs(const DateDuration* self); + +DateDuration* temporal_rs_DateDuration_negated(const DateDuration* self); + +Sign temporal_rs_DateDuration_sign(const DateDuration* self); + +void temporal_rs_DateDuration_destroy(DateDuration* self); + + + + + +#endif // DateDuration_H diff --git a/deps/temporal/temporal_capi/bindings/c/DifferenceSettings.d.h b/deps/temporal/temporal_capi/bindings/c/DifferenceSettings.d.h new file mode 100644 index 00000000000000..f738a609387a2b --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/DifferenceSettings.d.h @@ -0,0 +1,27 @@ +#ifndef DifferenceSettings_D_H +#define DifferenceSettings_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "RoundingMode.d.h" +#include "Unit.d.h" + + + + +typedef struct DifferenceSettings { + Unit_option largest_unit; + Unit_option smallest_unit; + RoundingMode_option rounding_mode; + OptionU32 increment; +} DifferenceSettings; + +typedef struct DifferenceSettings_option {union { DifferenceSettings ok; }; bool is_ok; } DifferenceSettings_option; + + + +#endif // DifferenceSettings_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/DifferenceSettings.h b/deps/temporal/temporal_capi/bindings/c/DifferenceSettings.h new file mode 100644 index 00000000000000..c43fa6b9d84658 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/DifferenceSettings.h @@ -0,0 +1,22 @@ +#ifndef DifferenceSettings_H +#define DifferenceSettings_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "DifferenceSettings.d.h" + + + + + + + + + + +#endif // DifferenceSettings_H diff --git a/deps/temporal/temporal_capi/bindings/c/Disambiguation.d.h b/deps/temporal/temporal_capi/bindings/c/Disambiguation.d.h new file mode 100644 index 00000000000000..cfe99859b04344 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/Disambiguation.d.h @@ -0,0 +1,25 @@ +#ifndef Disambiguation_D_H +#define Disambiguation_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef enum Disambiguation { + Disambiguation_Compatible = 0, + Disambiguation_Earlier = 1, + Disambiguation_Later = 2, + Disambiguation_Reject = 3, +} Disambiguation; + +typedef struct Disambiguation_option {union { Disambiguation ok; }; bool is_ok; } Disambiguation_option; + + + +#endif // Disambiguation_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/Disambiguation.h b/deps/temporal/temporal_capi/bindings/c/Disambiguation.h new file mode 100644 index 00000000000000..f4aeaa7d58e29d --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/Disambiguation.h @@ -0,0 +1,22 @@ +#ifndef Disambiguation_H +#define Disambiguation_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "Disambiguation.d.h" + + + + + + + + + + +#endif // Disambiguation_H diff --git a/deps/temporal/temporal_capi/bindings/c/DisplayCalendar.d.h b/deps/temporal/temporal_capi/bindings/c/DisplayCalendar.d.h new file mode 100644 index 00000000000000..5aca25e6db57d4 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/DisplayCalendar.d.h @@ -0,0 +1,25 @@ +#ifndef DisplayCalendar_D_H +#define DisplayCalendar_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef enum DisplayCalendar { + DisplayCalendar_Auto = 0, + DisplayCalendar_Always = 1, + DisplayCalendar_Never = 2, + DisplayCalendar_Critical = 3, +} DisplayCalendar; + +typedef struct DisplayCalendar_option {union { DisplayCalendar ok; }; bool is_ok; } DisplayCalendar_option; + + + +#endif // DisplayCalendar_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/DisplayCalendar.h b/deps/temporal/temporal_capi/bindings/c/DisplayCalendar.h new file mode 100644 index 00000000000000..1d80f822b2f213 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/DisplayCalendar.h @@ -0,0 +1,22 @@ +#ifndef DisplayCalendar_H +#define DisplayCalendar_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "DisplayCalendar.d.h" + + + + + + + + + + +#endif // DisplayCalendar_H diff --git a/deps/temporal/temporal_capi/bindings/c/DisplayOffset.d.h b/deps/temporal/temporal_capi/bindings/c/DisplayOffset.d.h new file mode 100644 index 00000000000000..668e20d36e4c3d --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/DisplayOffset.d.h @@ -0,0 +1,23 @@ +#ifndef DisplayOffset_D_H +#define DisplayOffset_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef enum DisplayOffset { + DisplayOffset_Auto = 0, + DisplayOffset_Never = 1, +} DisplayOffset; + +typedef struct DisplayOffset_option {union { DisplayOffset ok; }; bool is_ok; } DisplayOffset_option; + + + +#endif // DisplayOffset_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/DisplayOffset.h b/deps/temporal/temporal_capi/bindings/c/DisplayOffset.h new file mode 100644 index 00000000000000..e59ccac16c725d --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/DisplayOffset.h @@ -0,0 +1,22 @@ +#ifndef DisplayOffset_H +#define DisplayOffset_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "DisplayOffset.d.h" + + + + + + + + + + +#endif // DisplayOffset_H diff --git a/deps/temporal/temporal_capi/bindings/c/DisplayTimeZone.d.h b/deps/temporal/temporal_capi/bindings/c/DisplayTimeZone.d.h new file mode 100644 index 00000000000000..f9b743749abedb --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/DisplayTimeZone.d.h @@ -0,0 +1,24 @@ +#ifndef DisplayTimeZone_D_H +#define DisplayTimeZone_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef enum DisplayTimeZone { + DisplayTimeZone_Auto = 0, + DisplayTimeZone_Never = 1, + DisplayTimeZone_Critical = 2, +} DisplayTimeZone; + +typedef struct DisplayTimeZone_option {union { DisplayTimeZone ok; }; bool is_ok; } DisplayTimeZone_option; + + + +#endif // DisplayTimeZone_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/DisplayTimeZone.h b/deps/temporal/temporal_capi/bindings/c/DisplayTimeZone.h new file mode 100644 index 00000000000000..736cd05c44d302 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/DisplayTimeZone.h @@ -0,0 +1,22 @@ +#ifndef DisplayTimeZone_H +#define DisplayTimeZone_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "DisplayTimeZone.d.h" + + + + + + + + + + +#endif // DisplayTimeZone_H diff --git a/deps/temporal/temporal_capi/bindings/c/Duration.d.h b/deps/temporal/temporal_capi/bindings/c/Duration.d.h new file mode 100644 index 00000000000000..b44d572600b98a --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/Duration.d.h @@ -0,0 +1,19 @@ +#ifndef Duration_D_H +#define Duration_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct Duration Duration; + + + + +#endif // Duration_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/Duration.h b/deps/temporal/temporal_capi/bindings/c/Duration.h new file mode 100644 index 00000000000000..08ef9952ccdf70 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/Duration.h @@ -0,0 +1,106 @@ +#ifndef Duration_H +#define Duration_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "PartialDuration.d.h" +#include "Provider.d.h" +#include "RelativeTo.d.h" +#include "RoundingOptions.d.h" +#include "Sign.d.h" +#include "TemporalError.d.h" +#include "ToStringRoundingOptions.d.h" +#include "Unit.d.h" + +#include "Duration.d.h" + + + + + + +typedef struct temporal_rs_Duration_create_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_Duration_create_result; +temporal_rs_Duration_create_result temporal_rs_Duration_create(int64_t years, int64_t months, int64_t weeks, int64_t days, int64_t hours, int64_t minutes, int64_t seconds, int64_t milliseconds, double microseconds, double nanoseconds); + +typedef struct temporal_rs_Duration_try_new_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_Duration_try_new_result; +temporal_rs_Duration_try_new_result temporal_rs_Duration_try_new(int64_t years, int64_t months, int64_t weeks, int64_t days, int64_t hours, int64_t minutes, int64_t seconds, int64_t milliseconds, double microseconds, double nanoseconds); + +typedef struct temporal_rs_Duration_from_partial_duration_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_Duration_from_partial_duration_result; +temporal_rs_Duration_from_partial_duration_result temporal_rs_Duration_from_partial_duration(PartialDuration partial); + +typedef struct temporal_rs_Duration_from_utf8_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_Duration_from_utf8_result; +temporal_rs_Duration_from_utf8_result temporal_rs_Duration_from_utf8(DiplomatStringView s); + +typedef struct temporal_rs_Duration_from_utf16_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_Duration_from_utf16_result; +temporal_rs_Duration_from_utf16_result temporal_rs_Duration_from_utf16(DiplomatString16View s); + +bool temporal_rs_Duration_is_time_within_range(const Duration* self); + +int64_t temporal_rs_Duration_years(const Duration* self); + +int64_t temporal_rs_Duration_months(const Duration* self); + +int64_t temporal_rs_Duration_weeks(const Duration* self); + +int64_t temporal_rs_Duration_days(const Duration* self); + +int64_t temporal_rs_Duration_hours(const Duration* self); + +int64_t temporal_rs_Duration_minutes(const Duration* self); + +int64_t temporal_rs_Duration_seconds(const Duration* self); + +int64_t temporal_rs_Duration_milliseconds(const Duration* self); + +double temporal_rs_Duration_microseconds(const Duration* self); + +double temporal_rs_Duration_nanoseconds(const Duration* self); + +Sign temporal_rs_Duration_sign(const Duration* self); + +bool temporal_rs_Duration_is_zero(const Duration* self); + +Duration* temporal_rs_Duration_abs(const Duration* self); + +Duration* temporal_rs_Duration_negated(const Duration* self); + +typedef struct temporal_rs_Duration_add_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_Duration_add_result; +temporal_rs_Duration_add_result temporal_rs_Duration_add(const Duration* self, const Duration* other); + +typedef struct temporal_rs_Duration_subtract_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_Duration_subtract_result; +temporal_rs_Duration_subtract_result temporal_rs_Duration_subtract(const Duration* self, const Duration* other); + +typedef struct temporal_rs_Duration_to_string_result {union { TemporalError err;}; bool is_ok;} temporal_rs_Duration_to_string_result; +temporal_rs_Duration_to_string_result temporal_rs_Duration_to_string(const Duration* self, ToStringRoundingOptions options, DiplomatWrite* write); + +typedef struct temporal_rs_Duration_round_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_Duration_round_result; +temporal_rs_Duration_round_result temporal_rs_Duration_round(const Duration* self, RoundingOptions options, RelativeTo relative_to); + +typedef struct temporal_rs_Duration_round_with_provider_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_Duration_round_with_provider_result; +temporal_rs_Duration_round_with_provider_result temporal_rs_Duration_round_with_provider(const Duration* self, RoundingOptions options, RelativeTo relative_to, const Provider* p); + +typedef struct temporal_rs_Duration_compare_result {union {int8_t ok; TemporalError err;}; bool is_ok;} temporal_rs_Duration_compare_result; +temporal_rs_Duration_compare_result temporal_rs_Duration_compare(const Duration* self, const Duration* other, RelativeTo relative_to); + +typedef struct temporal_rs_Duration_compare_with_provider_result {union {int8_t ok; TemporalError err;}; bool is_ok;} temporal_rs_Duration_compare_with_provider_result; +temporal_rs_Duration_compare_with_provider_result temporal_rs_Duration_compare_with_provider(const Duration* self, const Duration* other, RelativeTo relative_to, const Provider* p); + +typedef struct temporal_rs_Duration_total_result {union {double ok; TemporalError err;}; bool is_ok;} temporal_rs_Duration_total_result; +temporal_rs_Duration_total_result temporal_rs_Duration_total(const Duration* self, Unit unit, RelativeTo relative_to); + +typedef struct temporal_rs_Duration_total_with_provider_result {union {double ok; TemporalError err;}; bool is_ok;} temporal_rs_Duration_total_with_provider_result; +temporal_rs_Duration_total_with_provider_result temporal_rs_Duration_total_with_provider(const Duration* self, Unit unit, RelativeTo relative_to, const Provider* p); + +Duration* temporal_rs_Duration_clone(const Duration* self); + +void temporal_rs_Duration_destroy(Duration* self); + + + + + +#endif // Duration_H diff --git a/deps/temporal/temporal_capi/bindings/c/ErrorKind.d.h b/deps/temporal/temporal_capi/bindings/c/ErrorKind.d.h new file mode 100644 index 00000000000000..94619441568b57 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/ErrorKind.d.h @@ -0,0 +1,26 @@ +#ifndef ErrorKind_D_H +#define ErrorKind_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef enum ErrorKind { + ErrorKind_Generic = 0, + ErrorKind_Type = 1, + ErrorKind_Range = 2, + ErrorKind_Syntax = 3, + ErrorKind_Assert = 4, +} ErrorKind; + +typedef struct ErrorKind_option {union { ErrorKind ok; }; bool is_ok; } ErrorKind_option; + + + +#endif // ErrorKind_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/ErrorKind.h b/deps/temporal/temporal_capi/bindings/c/ErrorKind.h new file mode 100644 index 00000000000000..113613977f13ba --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/ErrorKind.h @@ -0,0 +1,22 @@ +#ifndef ErrorKind_H +#define ErrorKind_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "ErrorKind.d.h" + + + + + + + + + + +#endif // ErrorKind_H diff --git a/deps/temporal/temporal_capi/bindings/c/I128Nanoseconds.d.h b/deps/temporal/temporal_capi/bindings/c/I128Nanoseconds.d.h new file mode 100644 index 00000000000000..268a534e550948 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/I128Nanoseconds.d.h @@ -0,0 +1,23 @@ +#ifndef I128Nanoseconds_D_H +#define I128Nanoseconds_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct I128Nanoseconds { + uint64_t high; + uint64_t low; +} I128Nanoseconds; + +typedef struct I128Nanoseconds_option {union { I128Nanoseconds ok; }; bool is_ok; } I128Nanoseconds_option; + + + +#endif // I128Nanoseconds_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/I128Nanoseconds.h b/deps/temporal/temporal_capi/bindings/c/I128Nanoseconds.h new file mode 100644 index 00000000000000..b026864d65f2f2 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/I128Nanoseconds.h @@ -0,0 +1,24 @@ +#ifndef I128Nanoseconds_H +#define I128Nanoseconds_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "I128Nanoseconds.d.h" + + + + + + +bool temporal_rs_I128Nanoseconds_is_valid(I128Nanoseconds self); + + + + + +#endif // I128Nanoseconds_H diff --git a/deps/temporal/temporal_capi/bindings/c/Instant.d.h b/deps/temporal/temporal_capi/bindings/c/Instant.d.h new file mode 100644 index 00000000000000..77d95421e5f17e --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/Instant.d.h @@ -0,0 +1,19 @@ +#ifndef Instant_D_H +#define Instant_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct Instant Instant; + + + + +#endif // Instant_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/Instant.h b/deps/temporal/temporal_capi/bindings/c/Instant.h new file mode 100644 index 00000000000000..3f82c47c2dd207 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/Instant.h @@ -0,0 +1,82 @@ +#ifndef Instant_H +#define Instant_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "DifferenceSettings.d.h" +#include "Duration.d.h" +#include "I128Nanoseconds.d.h" +#include "Provider.d.h" +#include "RoundingOptions.d.h" +#include "TemporalError.d.h" +#include "TimeZone.d.h" +#include "ToStringRoundingOptions.d.h" +#include "ZonedDateTime.d.h" + +#include "Instant.d.h" + + + + + + +typedef struct temporal_rs_Instant_try_new_result {union {Instant* ok; TemporalError err;}; bool is_ok;} temporal_rs_Instant_try_new_result; +temporal_rs_Instant_try_new_result temporal_rs_Instant_try_new(I128Nanoseconds ns); + +typedef struct temporal_rs_Instant_from_epoch_milliseconds_result {union {Instant* ok; TemporalError err;}; bool is_ok;} temporal_rs_Instant_from_epoch_milliseconds_result; +temporal_rs_Instant_from_epoch_milliseconds_result temporal_rs_Instant_from_epoch_milliseconds(int64_t epoch_milliseconds); + +typedef struct temporal_rs_Instant_from_utf8_result {union {Instant* ok; TemporalError err;}; bool is_ok;} temporal_rs_Instant_from_utf8_result; +temporal_rs_Instant_from_utf8_result temporal_rs_Instant_from_utf8(DiplomatStringView s); + +typedef struct temporal_rs_Instant_from_utf16_result {union {Instant* ok; TemporalError err;}; bool is_ok;} temporal_rs_Instant_from_utf16_result; +temporal_rs_Instant_from_utf16_result temporal_rs_Instant_from_utf16(DiplomatString16View s); + +typedef struct temporal_rs_Instant_add_result {union {Instant* ok; TemporalError err;}; bool is_ok;} temporal_rs_Instant_add_result; +temporal_rs_Instant_add_result temporal_rs_Instant_add(const Instant* self, const Duration* duration); + +typedef struct temporal_rs_Instant_subtract_result {union {Instant* ok; TemporalError err;}; bool is_ok;} temporal_rs_Instant_subtract_result; +temporal_rs_Instant_subtract_result temporal_rs_Instant_subtract(const Instant* self, const Duration* duration); + +typedef struct temporal_rs_Instant_since_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_Instant_since_result; +temporal_rs_Instant_since_result temporal_rs_Instant_since(const Instant* self, const Instant* other, DifferenceSettings settings); + +typedef struct temporal_rs_Instant_until_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_Instant_until_result; +temporal_rs_Instant_until_result temporal_rs_Instant_until(const Instant* self, const Instant* other, DifferenceSettings settings); + +typedef struct temporal_rs_Instant_round_result {union {Instant* ok; TemporalError err;}; bool is_ok;} temporal_rs_Instant_round_result; +temporal_rs_Instant_round_result temporal_rs_Instant_round(const Instant* self, RoundingOptions options); + +int8_t temporal_rs_Instant_compare(const Instant* self, const Instant* other); + +bool temporal_rs_Instant_equals(const Instant* self, const Instant* other); + +int64_t temporal_rs_Instant_epoch_milliseconds(const Instant* self); + +I128Nanoseconds temporal_rs_Instant_epoch_nanoseconds(const Instant* self); + +typedef struct temporal_rs_Instant_to_ixdtf_string_with_compiled_data_result {union { TemporalError err;}; bool is_ok;} temporal_rs_Instant_to_ixdtf_string_with_compiled_data_result; +temporal_rs_Instant_to_ixdtf_string_with_compiled_data_result temporal_rs_Instant_to_ixdtf_string_with_compiled_data(const Instant* self, TimeZone_option zone, ToStringRoundingOptions options, DiplomatWrite* write); + +typedef struct temporal_rs_Instant_to_ixdtf_string_with_provider_result {union { TemporalError err;}; bool is_ok;} temporal_rs_Instant_to_ixdtf_string_with_provider_result; +temporal_rs_Instant_to_ixdtf_string_with_provider_result temporal_rs_Instant_to_ixdtf_string_with_provider(const Instant* self, TimeZone_option zone, ToStringRoundingOptions options, const Provider* p, DiplomatWrite* write); + +typedef struct temporal_rs_Instant_to_zoned_date_time_iso_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_Instant_to_zoned_date_time_iso_result; +temporal_rs_Instant_to_zoned_date_time_iso_result temporal_rs_Instant_to_zoned_date_time_iso(const Instant* self, TimeZone zone); + +typedef struct temporal_rs_Instant_to_zoned_date_time_iso_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_Instant_to_zoned_date_time_iso_with_provider_result; +temporal_rs_Instant_to_zoned_date_time_iso_with_provider_result temporal_rs_Instant_to_zoned_date_time_iso_with_provider(const Instant* self, TimeZone zone, const Provider* p); + +Instant* temporal_rs_Instant_clone(const Instant* self); + +void temporal_rs_Instant_destroy(Instant* self); + + + + + +#endif // Instant_H diff --git a/deps/temporal/temporal_capi/bindings/c/OffsetDisambiguation.d.h b/deps/temporal/temporal_capi/bindings/c/OffsetDisambiguation.d.h new file mode 100644 index 00000000000000..aa46cf3de918ff --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/OffsetDisambiguation.d.h @@ -0,0 +1,25 @@ +#ifndef OffsetDisambiguation_D_H +#define OffsetDisambiguation_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef enum OffsetDisambiguation { + OffsetDisambiguation_Use = 0, + OffsetDisambiguation_Prefer = 1, + OffsetDisambiguation_Ignore = 2, + OffsetDisambiguation_Reject = 3, +} OffsetDisambiguation; + +typedef struct OffsetDisambiguation_option {union { OffsetDisambiguation ok; }; bool is_ok; } OffsetDisambiguation_option; + + + +#endif // OffsetDisambiguation_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/OffsetDisambiguation.h b/deps/temporal/temporal_capi/bindings/c/OffsetDisambiguation.h new file mode 100644 index 00000000000000..8227ec084b5d52 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/OffsetDisambiguation.h @@ -0,0 +1,22 @@ +#ifndef OffsetDisambiguation_H +#define OffsetDisambiguation_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "OffsetDisambiguation.d.h" + + + + + + + + + + +#endif // OffsetDisambiguation_H diff --git a/deps/temporal/temporal_capi/bindings/c/OwnedRelativeTo.d.h b/deps/temporal/temporal_capi/bindings/c/OwnedRelativeTo.d.h new file mode 100644 index 00000000000000..297922d5207af7 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/OwnedRelativeTo.d.h @@ -0,0 +1,25 @@ +#ifndef OwnedRelativeTo_D_H +#define OwnedRelativeTo_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "PlainDate.d.h" +#include "ZonedDateTime.d.h" + + + + +typedef struct OwnedRelativeTo { + PlainDate* date; + ZonedDateTime* zoned; +} OwnedRelativeTo; + +typedef struct OwnedRelativeTo_option {union { OwnedRelativeTo ok; }; bool is_ok; } OwnedRelativeTo_option; + + + +#endif // OwnedRelativeTo_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/OwnedRelativeTo.h b/deps/temporal/temporal_capi/bindings/c/OwnedRelativeTo.h new file mode 100644 index 00000000000000..cfe0587720b353 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/OwnedRelativeTo.h @@ -0,0 +1,38 @@ +#ifndef OwnedRelativeTo_H +#define OwnedRelativeTo_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "Provider.d.h" +#include "TemporalError.d.h" + +#include "OwnedRelativeTo.d.h" + + + + + + +typedef struct temporal_rs_OwnedRelativeTo_from_utf8_result {union {OwnedRelativeTo ok; TemporalError err;}; bool is_ok;} temporal_rs_OwnedRelativeTo_from_utf8_result; +temporal_rs_OwnedRelativeTo_from_utf8_result temporal_rs_OwnedRelativeTo_from_utf8(DiplomatStringView s); + +typedef struct temporal_rs_OwnedRelativeTo_from_utf8_with_provider_result {union {OwnedRelativeTo ok; TemporalError err;}; bool is_ok;} temporal_rs_OwnedRelativeTo_from_utf8_with_provider_result; +temporal_rs_OwnedRelativeTo_from_utf8_with_provider_result temporal_rs_OwnedRelativeTo_from_utf8_with_provider(DiplomatStringView s, const Provider* p); + +typedef struct temporal_rs_OwnedRelativeTo_from_utf16_result {union {OwnedRelativeTo ok; TemporalError err;}; bool is_ok;} temporal_rs_OwnedRelativeTo_from_utf16_result; +temporal_rs_OwnedRelativeTo_from_utf16_result temporal_rs_OwnedRelativeTo_from_utf16(DiplomatString16View s); + +typedef struct temporal_rs_OwnedRelativeTo_from_utf16_with_provider_result {union {OwnedRelativeTo ok; TemporalError err;}; bool is_ok;} temporal_rs_OwnedRelativeTo_from_utf16_with_provider_result; +temporal_rs_OwnedRelativeTo_from_utf16_with_provider_result temporal_rs_OwnedRelativeTo_from_utf16_with_provider(DiplomatString16View s, const Provider* p); + +OwnedRelativeTo temporal_rs_OwnedRelativeTo_empty(void); + + + + + +#endif // OwnedRelativeTo_H diff --git a/deps/temporal/temporal_capi/bindings/c/ParsedDate.d.h b/deps/temporal/temporal_capi/bindings/c/ParsedDate.d.h new file mode 100644 index 00000000000000..ae75840aabae68 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/ParsedDate.d.h @@ -0,0 +1,19 @@ +#ifndef ParsedDate_D_H +#define ParsedDate_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct ParsedDate ParsedDate; + + + + +#endif // ParsedDate_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/ParsedDate.h b/deps/temporal/temporal_capi/bindings/c/ParsedDate.h new file mode 100644 index 00000000000000..d92f3a0d78a29c --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/ParsedDate.h @@ -0,0 +1,43 @@ +#ifndef ParsedDate_H +#define ParsedDate_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "TemporalError.d.h" + +#include "ParsedDate.d.h" + + + + + + +typedef struct temporal_rs_ParsedDate_from_utf8_result {union {ParsedDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_ParsedDate_from_utf8_result; +temporal_rs_ParsedDate_from_utf8_result temporal_rs_ParsedDate_from_utf8(DiplomatStringView s); + +typedef struct temporal_rs_ParsedDate_from_utf16_result {union {ParsedDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_ParsedDate_from_utf16_result; +temporal_rs_ParsedDate_from_utf16_result temporal_rs_ParsedDate_from_utf16(DiplomatString16View s); + +typedef struct temporal_rs_ParsedDate_year_month_from_utf8_result {union {ParsedDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_ParsedDate_year_month_from_utf8_result; +temporal_rs_ParsedDate_year_month_from_utf8_result temporal_rs_ParsedDate_year_month_from_utf8(DiplomatStringView s); + +typedef struct temporal_rs_ParsedDate_year_month_from_utf16_result {union {ParsedDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_ParsedDate_year_month_from_utf16_result; +temporal_rs_ParsedDate_year_month_from_utf16_result temporal_rs_ParsedDate_year_month_from_utf16(DiplomatString16View s); + +typedef struct temporal_rs_ParsedDate_month_day_from_utf8_result {union {ParsedDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_ParsedDate_month_day_from_utf8_result; +temporal_rs_ParsedDate_month_day_from_utf8_result temporal_rs_ParsedDate_month_day_from_utf8(DiplomatStringView s); + +typedef struct temporal_rs_ParsedDate_month_day_from_utf16_result {union {ParsedDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_ParsedDate_month_day_from_utf16_result; +temporal_rs_ParsedDate_month_day_from_utf16_result temporal_rs_ParsedDate_month_day_from_utf16(DiplomatString16View s); + +void temporal_rs_ParsedDate_destroy(ParsedDate* self); + + + + + +#endif // ParsedDate_H diff --git a/deps/temporal/temporal_capi/bindings/c/ParsedDateTime.d.h b/deps/temporal/temporal_capi/bindings/c/ParsedDateTime.d.h new file mode 100644 index 00000000000000..96bbbe4cc84998 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/ParsedDateTime.d.h @@ -0,0 +1,19 @@ +#ifndef ParsedDateTime_D_H +#define ParsedDateTime_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct ParsedDateTime ParsedDateTime; + + + + +#endif // ParsedDateTime_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/ParsedDateTime.h b/deps/temporal/temporal_capi/bindings/c/ParsedDateTime.h new file mode 100644 index 00000000000000..cdb6a54e66a33b --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/ParsedDateTime.h @@ -0,0 +1,31 @@ +#ifndef ParsedDateTime_H +#define ParsedDateTime_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "TemporalError.d.h" + +#include "ParsedDateTime.d.h" + + + + + + +typedef struct temporal_rs_ParsedDateTime_from_utf8_result {union {ParsedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ParsedDateTime_from_utf8_result; +temporal_rs_ParsedDateTime_from_utf8_result temporal_rs_ParsedDateTime_from_utf8(DiplomatStringView s); + +typedef struct temporal_rs_ParsedDateTime_from_utf16_result {union {ParsedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ParsedDateTime_from_utf16_result; +temporal_rs_ParsedDateTime_from_utf16_result temporal_rs_ParsedDateTime_from_utf16(DiplomatString16View s); + +void temporal_rs_ParsedDateTime_destroy(ParsedDateTime* self); + + + + + +#endif // ParsedDateTime_H diff --git a/deps/temporal/temporal_capi/bindings/c/ParsedZonedDateTime.d.h b/deps/temporal/temporal_capi/bindings/c/ParsedZonedDateTime.d.h new file mode 100644 index 00000000000000..48c89d3e175d2d --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/ParsedZonedDateTime.d.h @@ -0,0 +1,19 @@ +#ifndef ParsedZonedDateTime_D_H +#define ParsedZonedDateTime_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct ParsedZonedDateTime ParsedZonedDateTime; + + + + +#endif // ParsedZonedDateTime_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/ParsedZonedDateTime.h b/deps/temporal/temporal_capi/bindings/c/ParsedZonedDateTime.h new file mode 100644 index 00000000000000..3663529ef4d6a9 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/ParsedZonedDateTime.h @@ -0,0 +1,38 @@ +#ifndef ParsedZonedDateTime_H +#define ParsedZonedDateTime_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "Provider.d.h" +#include "TemporalError.d.h" + +#include "ParsedZonedDateTime.d.h" + + + + + + +typedef struct temporal_rs_ParsedZonedDateTime_from_utf8_result {union {ParsedZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ParsedZonedDateTime_from_utf8_result; +temporal_rs_ParsedZonedDateTime_from_utf8_result temporal_rs_ParsedZonedDateTime_from_utf8(DiplomatStringView s); + +typedef struct temporal_rs_ParsedZonedDateTime_from_utf8_with_provider_result {union {ParsedZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ParsedZonedDateTime_from_utf8_with_provider_result; +temporal_rs_ParsedZonedDateTime_from_utf8_with_provider_result temporal_rs_ParsedZonedDateTime_from_utf8_with_provider(DiplomatStringView s, const Provider* p); + +typedef struct temporal_rs_ParsedZonedDateTime_from_utf16_result {union {ParsedZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ParsedZonedDateTime_from_utf16_result; +temporal_rs_ParsedZonedDateTime_from_utf16_result temporal_rs_ParsedZonedDateTime_from_utf16(DiplomatString16View s); + +typedef struct temporal_rs_ParsedZonedDateTime_from_utf16_with_provider_result {union {ParsedZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ParsedZonedDateTime_from_utf16_with_provider_result; +temporal_rs_ParsedZonedDateTime_from_utf16_with_provider_result temporal_rs_ParsedZonedDateTime_from_utf16_with_provider(DiplomatString16View s, const Provider* p); + +void temporal_rs_ParsedZonedDateTime_destroy(ParsedZonedDateTime* self); + + + + + +#endif // ParsedZonedDateTime_H diff --git a/deps/temporal/temporal_capi/bindings/c/PartialDate.d.h b/deps/temporal/temporal_capi/bindings/c/PartialDate.d.h new file mode 100644 index 00000000000000..b4157fcccdb157 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PartialDate.d.h @@ -0,0 +1,29 @@ +#ifndef PartialDate_D_H +#define PartialDate_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "AnyCalendarKind.d.h" + + + + +typedef struct PartialDate { + OptionI32 year; + OptionU8 month; + DiplomatStringView month_code; + OptionU8 day; + DiplomatStringView era; + OptionI32 era_year; + AnyCalendarKind calendar; +} PartialDate; + +typedef struct PartialDate_option {union { PartialDate ok; }; bool is_ok; } PartialDate_option; + + + +#endif // PartialDate_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/PartialDate.h b/deps/temporal/temporal_capi/bindings/c/PartialDate.h new file mode 100644 index 00000000000000..824a8e03422bf1 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PartialDate.h @@ -0,0 +1,22 @@ +#ifndef PartialDate_H +#define PartialDate_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "PartialDate.d.h" + + + + + + + + + + +#endif // PartialDate_H diff --git a/deps/temporal/temporal_capi/bindings/c/PartialDateTime.d.h b/deps/temporal/temporal_capi/bindings/c/PartialDateTime.d.h new file mode 100644 index 00000000000000..735baf3fc10397 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PartialDateTime.d.h @@ -0,0 +1,25 @@ +#ifndef PartialDateTime_D_H +#define PartialDateTime_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "PartialDate.d.h" +#include "PartialTime.d.h" + + + + +typedef struct PartialDateTime { + PartialDate date; + PartialTime time; +} PartialDateTime; + +typedef struct PartialDateTime_option {union { PartialDateTime ok; }; bool is_ok; } PartialDateTime_option; + + + +#endif // PartialDateTime_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/PartialDateTime.h b/deps/temporal/temporal_capi/bindings/c/PartialDateTime.h new file mode 100644 index 00000000000000..11efc7104cfb3c --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PartialDateTime.h @@ -0,0 +1,22 @@ +#ifndef PartialDateTime_H +#define PartialDateTime_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "PartialDateTime.d.h" + + + + + + + + + + +#endif // PartialDateTime_H diff --git a/deps/temporal/temporal_capi/bindings/c/PartialDuration.d.h b/deps/temporal/temporal_capi/bindings/c/PartialDuration.d.h new file mode 100644 index 00000000000000..f0189fc9ae56c7 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PartialDuration.d.h @@ -0,0 +1,31 @@ +#ifndef PartialDuration_D_H +#define PartialDuration_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct PartialDuration { + OptionI64 years; + OptionI64 months; + OptionI64 weeks; + OptionI64 days; + OptionI64 hours; + OptionI64 minutes; + OptionI64 seconds; + OptionI64 milliseconds; + OptionF64 microseconds; + OptionF64 nanoseconds; +} PartialDuration; + +typedef struct PartialDuration_option {union { PartialDuration ok; }; bool is_ok; } PartialDuration_option; + + + +#endif // PartialDuration_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/PartialDuration.h b/deps/temporal/temporal_capi/bindings/c/PartialDuration.h new file mode 100644 index 00000000000000..afe0bfb00be7e6 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PartialDuration.h @@ -0,0 +1,24 @@ +#ifndef PartialDuration_H +#define PartialDuration_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "PartialDuration.d.h" + + + + + + +bool temporal_rs_PartialDuration_is_empty(PartialDuration self); + + + + + +#endif // PartialDuration_H diff --git a/deps/temporal/temporal_capi/bindings/c/PartialTime.d.h b/deps/temporal/temporal_capi/bindings/c/PartialTime.d.h new file mode 100644 index 00000000000000..6dd1fe9be90fcf --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PartialTime.d.h @@ -0,0 +1,27 @@ +#ifndef PartialTime_D_H +#define PartialTime_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct PartialTime { + OptionU8 hour; + OptionU8 minute; + OptionU8 second; + OptionU16 millisecond; + OptionU16 microsecond; + OptionU16 nanosecond; +} PartialTime; + +typedef struct PartialTime_option {union { PartialTime ok; }; bool is_ok; } PartialTime_option; + + + +#endif // PartialTime_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/PartialTime.h b/deps/temporal/temporal_capi/bindings/c/PartialTime.h new file mode 100644 index 00000000000000..8662bb27a60ee8 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PartialTime.h @@ -0,0 +1,22 @@ +#ifndef PartialTime_H +#define PartialTime_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "PartialTime.d.h" + + + + + + + + + + +#endif // PartialTime_H diff --git a/deps/temporal/temporal_capi/bindings/c/PartialZonedDateTime.d.h b/deps/temporal/temporal_capi/bindings/c/PartialZonedDateTime.d.h new file mode 100644 index 00000000000000..eec6a876a69ed4 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PartialZonedDateTime.d.h @@ -0,0 +1,28 @@ +#ifndef PartialZonedDateTime_D_H +#define PartialZonedDateTime_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "PartialDate.d.h" +#include "PartialTime.d.h" +#include "TimeZone.d.h" + + + + +typedef struct PartialZonedDateTime { + PartialDate date; + PartialTime time; + OptionStringView offset; + TimeZone_option timezone; +} PartialZonedDateTime; + +typedef struct PartialZonedDateTime_option {union { PartialZonedDateTime ok; }; bool is_ok; } PartialZonedDateTime_option; + + + +#endif // PartialZonedDateTime_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/PartialZonedDateTime.h b/deps/temporal/temporal_capi/bindings/c/PartialZonedDateTime.h new file mode 100644 index 00000000000000..2f8305ae3d18c8 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PartialZonedDateTime.h @@ -0,0 +1,22 @@ +#ifndef PartialZonedDateTime_H +#define PartialZonedDateTime_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "PartialZonedDateTime.d.h" + + + + + + + + + + +#endif // PartialZonedDateTime_H diff --git a/deps/temporal/temporal_capi/bindings/c/PlainDate.d.h b/deps/temporal/temporal_capi/bindings/c/PlainDate.d.h new file mode 100644 index 00000000000000..680fa1e8370f5b --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PlainDate.d.h @@ -0,0 +1,19 @@ +#ifndef PlainDate_D_H +#define PlainDate_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct PlainDate PlainDate; + + + + +#endif // PlainDate_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/PlainDate.h b/deps/temporal/temporal_capi/bindings/c/PlainDate.h new file mode 100644 index 00000000000000..d196dc30ab7a83 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PlainDate.h @@ -0,0 +1,151 @@ +#ifndef PlainDate_H +#define PlainDate_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "AnyCalendarKind.d.h" +#include "ArithmeticOverflow.d.h" +#include "Calendar.d.h" +#include "DifferenceSettings.d.h" +#include "DisplayCalendar.d.h" +#include "Duration.d.h" +#include "I128Nanoseconds.d.h" +#include "ParsedDate.d.h" +#include "PartialDate.d.h" +#include "PlainDateTime.d.h" +#include "PlainMonthDay.d.h" +#include "PlainTime.d.h" +#include "PlainYearMonth.d.h" +#include "Provider.d.h" +#include "TemporalError.d.h" +#include "TimeZone.d.h" +#include "ZonedDateTime.d.h" + +#include "PlainDate.d.h" + + + + + + +typedef struct temporal_rs_PlainDate_try_new_constrain_result {union {PlainDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_try_new_constrain_result; +temporal_rs_PlainDate_try_new_constrain_result temporal_rs_PlainDate_try_new_constrain(int32_t year, uint8_t month, uint8_t day, AnyCalendarKind calendar); + +typedef struct temporal_rs_PlainDate_try_new_result {union {PlainDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_try_new_result; +temporal_rs_PlainDate_try_new_result temporal_rs_PlainDate_try_new(int32_t year, uint8_t month, uint8_t day, AnyCalendarKind calendar); + +typedef struct temporal_rs_PlainDate_try_new_with_overflow_result {union {PlainDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_try_new_with_overflow_result; +temporal_rs_PlainDate_try_new_with_overflow_result temporal_rs_PlainDate_try_new_with_overflow(int32_t year, uint8_t month, uint8_t day, AnyCalendarKind calendar, ArithmeticOverflow overflow); + +typedef struct temporal_rs_PlainDate_from_partial_result {union {PlainDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_from_partial_result; +temporal_rs_PlainDate_from_partial_result temporal_rs_PlainDate_from_partial(PartialDate partial, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_PlainDate_from_parsed_result {union {PlainDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_from_parsed_result; +temporal_rs_PlainDate_from_parsed_result temporal_rs_PlainDate_from_parsed(const ParsedDate* parsed); + +typedef struct temporal_rs_PlainDate_from_epoch_milliseconds_result {union {PlainDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_from_epoch_milliseconds_result; +temporal_rs_PlainDate_from_epoch_milliseconds_result temporal_rs_PlainDate_from_epoch_milliseconds(int64_t ms, TimeZone tz); + +typedef struct temporal_rs_PlainDate_from_epoch_milliseconds_with_provider_result {union {PlainDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_from_epoch_milliseconds_with_provider_result; +temporal_rs_PlainDate_from_epoch_milliseconds_with_provider_result temporal_rs_PlainDate_from_epoch_milliseconds_with_provider(int64_t ms, TimeZone tz, const Provider* p); + +typedef struct temporal_rs_PlainDate_from_epoch_nanoseconds_result {union {PlainDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_from_epoch_nanoseconds_result; +temporal_rs_PlainDate_from_epoch_nanoseconds_result temporal_rs_PlainDate_from_epoch_nanoseconds(I128Nanoseconds ns, TimeZone tz); + +typedef struct temporal_rs_PlainDate_from_epoch_nanoseconds_with_provider_result {union {PlainDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_from_epoch_nanoseconds_with_provider_result; +temporal_rs_PlainDate_from_epoch_nanoseconds_with_provider_result temporal_rs_PlainDate_from_epoch_nanoseconds_with_provider(I128Nanoseconds ns, TimeZone tz, const Provider* p); + +typedef struct temporal_rs_PlainDate_with_result {union {PlainDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_with_result; +temporal_rs_PlainDate_with_result temporal_rs_PlainDate_with(const PlainDate* self, PartialDate partial, ArithmeticOverflow_option overflow); + +PlainDate* temporal_rs_PlainDate_with_calendar(const PlainDate* self, AnyCalendarKind calendar); + +typedef struct temporal_rs_PlainDate_from_utf8_result {union {PlainDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_from_utf8_result; +temporal_rs_PlainDate_from_utf8_result temporal_rs_PlainDate_from_utf8(DiplomatStringView s); + +typedef struct temporal_rs_PlainDate_from_utf16_result {union {PlainDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_from_utf16_result; +temporal_rs_PlainDate_from_utf16_result temporal_rs_PlainDate_from_utf16(DiplomatString16View s); + +const Calendar* temporal_rs_PlainDate_calendar(const PlainDate* self); + +bool temporal_rs_PlainDate_is_valid(const PlainDate* self); + +typedef struct temporal_rs_PlainDate_add_result {union {PlainDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_add_result; +temporal_rs_PlainDate_add_result temporal_rs_PlainDate_add(const PlainDate* self, const Duration* duration, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_PlainDate_subtract_result {union {PlainDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_subtract_result; +temporal_rs_PlainDate_subtract_result temporal_rs_PlainDate_subtract(const PlainDate* self, const Duration* duration, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_PlainDate_until_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_until_result; +temporal_rs_PlainDate_until_result temporal_rs_PlainDate_until(const PlainDate* self, const PlainDate* other, DifferenceSettings settings); + +typedef struct temporal_rs_PlainDate_since_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_since_result; +temporal_rs_PlainDate_since_result temporal_rs_PlainDate_since(const PlainDate* self, const PlainDate* other, DifferenceSettings settings); + +bool temporal_rs_PlainDate_equals(const PlainDate* self, const PlainDate* other); + +int8_t temporal_rs_PlainDate_compare(const PlainDate* one, const PlainDate* two); + +int32_t temporal_rs_PlainDate_year(const PlainDate* self); + +uint8_t temporal_rs_PlainDate_month(const PlainDate* self); + +void temporal_rs_PlainDate_month_code(const PlainDate* self, DiplomatWrite* write); + +uint8_t temporal_rs_PlainDate_day(const PlainDate* self); + +uint16_t temporal_rs_PlainDate_day_of_week(const PlainDate* self); + +uint16_t temporal_rs_PlainDate_day_of_year(const PlainDate* self); + +typedef struct temporal_rs_PlainDate_week_of_year_result {union {uint8_t ok; }; bool is_ok;} temporal_rs_PlainDate_week_of_year_result; +temporal_rs_PlainDate_week_of_year_result temporal_rs_PlainDate_week_of_year(const PlainDate* self); + +typedef struct temporal_rs_PlainDate_year_of_week_result {union {int32_t ok; }; bool is_ok;} temporal_rs_PlainDate_year_of_week_result; +temporal_rs_PlainDate_year_of_week_result temporal_rs_PlainDate_year_of_week(const PlainDate* self); + +uint16_t temporal_rs_PlainDate_days_in_week(const PlainDate* self); + +uint16_t temporal_rs_PlainDate_days_in_month(const PlainDate* self); + +uint16_t temporal_rs_PlainDate_days_in_year(const PlainDate* self); + +uint16_t temporal_rs_PlainDate_months_in_year(const PlainDate* self); + +bool temporal_rs_PlainDate_in_leap_year(const PlainDate* self); + +void temporal_rs_PlainDate_era(const PlainDate* self, DiplomatWrite* write); + +typedef struct temporal_rs_PlainDate_era_year_result {union {int32_t ok; }; bool is_ok;} temporal_rs_PlainDate_era_year_result; +temporal_rs_PlainDate_era_year_result temporal_rs_PlainDate_era_year(const PlainDate* self); + +typedef struct temporal_rs_PlainDate_to_plain_date_time_result {union {PlainDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_to_plain_date_time_result; +temporal_rs_PlainDate_to_plain_date_time_result temporal_rs_PlainDate_to_plain_date_time(const PlainDate* self, const PlainTime* time); + +typedef struct temporal_rs_PlainDate_to_plain_month_day_result {union {PlainMonthDay* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_to_plain_month_day_result; +temporal_rs_PlainDate_to_plain_month_day_result temporal_rs_PlainDate_to_plain_month_day(const PlainDate* self); + +typedef struct temporal_rs_PlainDate_to_plain_year_month_result {union {PlainYearMonth* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_to_plain_year_month_result; +temporal_rs_PlainDate_to_plain_year_month_result temporal_rs_PlainDate_to_plain_year_month(const PlainDate* self); + +typedef struct temporal_rs_PlainDate_to_zoned_date_time_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_to_zoned_date_time_result; +temporal_rs_PlainDate_to_zoned_date_time_result temporal_rs_PlainDate_to_zoned_date_time(const PlainDate* self, TimeZone time_zone, const PlainTime* time); + +typedef struct temporal_rs_PlainDate_to_zoned_date_time_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_to_zoned_date_time_with_provider_result; +temporal_rs_PlainDate_to_zoned_date_time_with_provider_result temporal_rs_PlainDate_to_zoned_date_time_with_provider(const PlainDate* self, TimeZone time_zone, const PlainTime* time, const Provider* p); + +void temporal_rs_PlainDate_to_ixdtf_string(const PlainDate* self, DisplayCalendar display_calendar, DiplomatWrite* write); + +PlainDate* temporal_rs_PlainDate_clone(const PlainDate* self); + +void temporal_rs_PlainDate_destroy(PlainDate* self); + + + + + +#endif // PlainDate_H diff --git a/deps/temporal/temporal_capi/bindings/c/PlainDateTime.d.h b/deps/temporal/temporal_capi/bindings/c/PlainDateTime.d.h new file mode 100644 index 00000000000000..83eafb5e8b90d5 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PlainDateTime.d.h @@ -0,0 +1,19 @@ +#ifndef PlainDateTime_D_H +#define PlainDateTime_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct PlainDateTime PlainDateTime; + + + + +#endif // PlainDateTime_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/PlainDateTime.h b/deps/temporal/temporal_capi/bindings/c/PlainDateTime.h new file mode 100644 index 00000000000000..32b5e35b80467d --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PlainDateTime.h @@ -0,0 +1,161 @@ +#ifndef PlainDateTime_H +#define PlainDateTime_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "AnyCalendarKind.d.h" +#include "ArithmeticOverflow.d.h" +#include "Calendar.d.h" +#include "DifferenceSettings.d.h" +#include "Disambiguation.d.h" +#include "DisplayCalendar.d.h" +#include "Duration.d.h" +#include "I128Nanoseconds.d.h" +#include "ParsedDateTime.d.h" +#include "PartialDateTime.d.h" +#include "PlainDate.d.h" +#include "PlainTime.d.h" +#include "Provider.d.h" +#include "RoundingOptions.d.h" +#include "TemporalError.d.h" +#include "TimeZone.d.h" +#include "ToStringRoundingOptions.d.h" +#include "ZonedDateTime.d.h" + +#include "PlainDateTime.d.h" + + + + + + +typedef struct temporal_rs_PlainDateTime_try_new_constrain_result {union {PlainDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_try_new_constrain_result; +temporal_rs_PlainDateTime_try_new_constrain_result temporal_rs_PlainDateTime_try_new_constrain(int32_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint16_t millisecond, uint16_t microsecond, uint16_t nanosecond, AnyCalendarKind calendar); + +typedef struct temporal_rs_PlainDateTime_try_new_result {union {PlainDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_try_new_result; +temporal_rs_PlainDateTime_try_new_result temporal_rs_PlainDateTime_try_new(int32_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint16_t millisecond, uint16_t microsecond, uint16_t nanosecond, AnyCalendarKind calendar); + +typedef struct temporal_rs_PlainDateTime_from_partial_result {union {PlainDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_from_partial_result; +temporal_rs_PlainDateTime_from_partial_result temporal_rs_PlainDateTime_from_partial(PartialDateTime partial, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_PlainDateTime_from_parsed_result {union {PlainDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_from_parsed_result; +temporal_rs_PlainDateTime_from_parsed_result temporal_rs_PlainDateTime_from_parsed(const ParsedDateTime* parsed); + +typedef struct temporal_rs_PlainDateTime_from_epoch_milliseconds_result {union {PlainDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_from_epoch_milliseconds_result; +temporal_rs_PlainDateTime_from_epoch_milliseconds_result temporal_rs_PlainDateTime_from_epoch_milliseconds(int64_t ms, TimeZone tz); + +typedef struct temporal_rs_PlainDateTime_from_epoch_milliseconds_with_provider_result {union {PlainDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_from_epoch_milliseconds_with_provider_result; +temporal_rs_PlainDateTime_from_epoch_milliseconds_with_provider_result temporal_rs_PlainDateTime_from_epoch_milliseconds_with_provider(int64_t ms, TimeZone tz, const Provider* p); + +typedef struct temporal_rs_PlainDateTime_from_epoch_nanoseconds_result {union {PlainDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_from_epoch_nanoseconds_result; +temporal_rs_PlainDateTime_from_epoch_nanoseconds_result temporal_rs_PlainDateTime_from_epoch_nanoseconds(I128Nanoseconds ns, TimeZone tz); + +typedef struct temporal_rs_PlainDateTime_from_epoch_nanoseconds_with_provider_result {union {PlainDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_from_epoch_nanoseconds_with_provider_result; +temporal_rs_PlainDateTime_from_epoch_nanoseconds_with_provider_result temporal_rs_PlainDateTime_from_epoch_nanoseconds_with_provider(I128Nanoseconds ns, TimeZone tz, const Provider* p); + +typedef struct temporal_rs_PlainDateTime_with_result {union {PlainDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_with_result; +temporal_rs_PlainDateTime_with_result temporal_rs_PlainDateTime_with(const PlainDateTime* self, PartialDateTime partial, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_PlainDateTime_with_time_result {union {PlainDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_with_time_result; +temporal_rs_PlainDateTime_with_time_result temporal_rs_PlainDateTime_with_time(const PlainDateTime* self, const PlainTime* time); + +PlainDateTime* temporal_rs_PlainDateTime_with_calendar(const PlainDateTime* self, AnyCalendarKind calendar); + +typedef struct temporal_rs_PlainDateTime_from_utf8_result {union {PlainDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_from_utf8_result; +temporal_rs_PlainDateTime_from_utf8_result temporal_rs_PlainDateTime_from_utf8(DiplomatStringView s); + +typedef struct temporal_rs_PlainDateTime_from_utf16_result {union {PlainDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_from_utf16_result; +temporal_rs_PlainDateTime_from_utf16_result temporal_rs_PlainDateTime_from_utf16(DiplomatString16View s); + +uint8_t temporal_rs_PlainDateTime_hour(const PlainDateTime* self); + +uint8_t temporal_rs_PlainDateTime_minute(const PlainDateTime* self); + +uint8_t temporal_rs_PlainDateTime_second(const PlainDateTime* self); + +uint16_t temporal_rs_PlainDateTime_millisecond(const PlainDateTime* self); + +uint16_t temporal_rs_PlainDateTime_microsecond(const PlainDateTime* self); + +uint16_t temporal_rs_PlainDateTime_nanosecond(const PlainDateTime* self); + +const Calendar* temporal_rs_PlainDateTime_calendar(const PlainDateTime* self); + +int32_t temporal_rs_PlainDateTime_year(const PlainDateTime* self); + +uint8_t temporal_rs_PlainDateTime_month(const PlainDateTime* self); + +void temporal_rs_PlainDateTime_month_code(const PlainDateTime* self, DiplomatWrite* write); + +uint8_t temporal_rs_PlainDateTime_day(const PlainDateTime* self); + +uint16_t temporal_rs_PlainDateTime_day_of_week(const PlainDateTime* self); + +uint16_t temporal_rs_PlainDateTime_day_of_year(const PlainDateTime* self); + +typedef struct temporal_rs_PlainDateTime_week_of_year_result {union {uint8_t ok; }; bool is_ok;} temporal_rs_PlainDateTime_week_of_year_result; +temporal_rs_PlainDateTime_week_of_year_result temporal_rs_PlainDateTime_week_of_year(const PlainDateTime* self); + +typedef struct temporal_rs_PlainDateTime_year_of_week_result {union {int32_t ok; }; bool is_ok;} temporal_rs_PlainDateTime_year_of_week_result; +temporal_rs_PlainDateTime_year_of_week_result temporal_rs_PlainDateTime_year_of_week(const PlainDateTime* self); + +uint16_t temporal_rs_PlainDateTime_days_in_week(const PlainDateTime* self); + +uint16_t temporal_rs_PlainDateTime_days_in_month(const PlainDateTime* self); + +uint16_t temporal_rs_PlainDateTime_days_in_year(const PlainDateTime* self); + +uint16_t temporal_rs_PlainDateTime_months_in_year(const PlainDateTime* self); + +bool temporal_rs_PlainDateTime_in_leap_year(const PlainDateTime* self); + +void temporal_rs_PlainDateTime_era(const PlainDateTime* self, DiplomatWrite* write); + +typedef struct temporal_rs_PlainDateTime_era_year_result {union {int32_t ok; }; bool is_ok;} temporal_rs_PlainDateTime_era_year_result; +temporal_rs_PlainDateTime_era_year_result temporal_rs_PlainDateTime_era_year(const PlainDateTime* self); + +typedef struct temporal_rs_PlainDateTime_add_result {union {PlainDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_add_result; +temporal_rs_PlainDateTime_add_result temporal_rs_PlainDateTime_add(const PlainDateTime* self, const Duration* duration, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_PlainDateTime_subtract_result {union {PlainDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_subtract_result; +temporal_rs_PlainDateTime_subtract_result temporal_rs_PlainDateTime_subtract(const PlainDateTime* self, const Duration* duration, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_PlainDateTime_until_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_until_result; +temporal_rs_PlainDateTime_until_result temporal_rs_PlainDateTime_until(const PlainDateTime* self, const PlainDateTime* other, DifferenceSettings settings); + +typedef struct temporal_rs_PlainDateTime_since_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_since_result; +temporal_rs_PlainDateTime_since_result temporal_rs_PlainDateTime_since(const PlainDateTime* self, const PlainDateTime* other, DifferenceSettings settings); + +bool temporal_rs_PlainDateTime_equals(const PlainDateTime* self, const PlainDateTime* other); + +int8_t temporal_rs_PlainDateTime_compare(const PlainDateTime* one, const PlainDateTime* two); + +typedef struct temporal_rs_PlainDateTime_round_result {union {PlainDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_round_result; +temporal_rs_PlainDateTime_round_result temporal_rs_PlainDateTime_round(const PlainDateTime* self, RoundingOptions options); + +PlainDate* temporal_rs_PlainDateTime_to_plain_date(const PlainDateTime* self); + +PlainTime* temporal_rs_PlainDateTime_to_plain_time(const PlainDateTime* self); + +typedef struct temporal_rs_PlainDateTime_to_zoned_date_time_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_to_zoned_date_time_result; +temporal_rs_PlainDateTime_to_zoned_date_time_result temporal_rs_PlainDateTime_to_zoned_date_time(const PlainDateTime* self, TimeZone time_zone, Disambiguation disambiguation); + +typedef struct temporal_rs_PlainDateTime_to_zoned_date_time_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_to_zoned_date_time_with_provider_result; +temporal_rs_PlainDateTime_to_zoned_date_time_with_provider_result temporal_rs_PlainDateTime_to_zoned_date_time_with_provider(const PlainDateTime* self, TimeZone time_zone, Disambiguation disambiguation, const Provider* p); + +typedef struct temporal_rs_PlainDateTime_to_ixdtf_string_result {union { TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_to_ixdtf_string_result; +temporal_rs_PlainDateTime_to_ixdtf_string_result temporal_rs_PlainDateTime_to_ixdtf_string(const PlainDateTime* self, ToStringRoundingOptions options, DisplayCalendar display_calendar, DiplomatWrite* write); + +PlainDateTime* temporal_rs_PlainDateTime_clone(const PlainDateTime* self); + +void temporal_rs_PlainDateTime_destroy(PlainDateTime* self); + + + + + +#endif // PlainDateTime_H diff --git a/deps/temporal/temporal_capi/bindings/c/PlainMonthDay.d.h b/deps/temporal/temporal_capi/bindings/c/PlainMonthDay.d.h new file mode 100644 index 00000000000000..12d40c36d1d27a --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PlainMonthDay.d.h @@ -0,0 +1,19 @@ +#ifndef PlainMonthDay_D_H +#define PlainMonthDay_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct PlainMonthDay PlainMonthDay; + + + + +#endif // PlainMonthDay_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/PlainMonthDay.h b/deps/temporal/temporal_capi/bindings/c/PlainMonthDay.h new file mode 100644 index 00000000000000..64c5dfd732af12 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PlainMonthDay.h @@ -0,0 +1,73 @@ +#ifndef PlainMonthDay_H +#define PlainMonthDay_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "AnyCalendarKind.d.h" +#include "ArithmeticOverflow.d.h" +#include "Calendar.d.h" +#include "DisplayCalendar.d.h" +#include "ParsedDate.d.h" +#include "PartialDate.d.h" +#include "PlainDate.d.h" +#include "Provider.d.h" +#include "TemporalError.d.h" +#include "TimeZone.d.h" + +#include "PlainMonthDay.d.h" + + + + + + +typedef struct temporal_rs_PlainMonthDay_try_new_with_overflow_result {union {PlainMonthDay* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_try_new_with_overflow_result; +temporal_rs_PlainMonthDay_try_new_with_overflow_result temporal_rs_PlainMonthDay_try_new_with_overflow(uint8_t month, uint8_t day, AnyCalendarKind calendar, ArithmeticOverflow overflow, OptionI32 ref_year); + +typedef struct temporal_rs_PlainMonthDay_from_partial_result {union {PlainMonthDay* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_from_partial_result; +temporal_rs_PlainMonthDay_from_partial_result temporal_rs_PlainMonthDay_from_partial(PartialDate partial, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_PlainMonthDay_from_parsed_result {union {PlainMonthDay* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_from_parsed_result; +temporal_rs_PlainMonthDay_from_parsed_result temporal_rs_PlainMonthDay_from_parsed(const ParsedDate* parsed); + +typedef struct temporal_rs_PlainMonthDay_with_result {union {PlainMonthDay* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_with_result; +temporal_rs_PlainMonthDay_with_result temporal_rs_PlainMonthDay_with(const PlainMonthDay* self, PartialDate partial, ArithmeticOverflow_option overflow); + +bool temporal_rs_PlainMonthDay_equals(const PlainMonthDay* self, const PlainMonthDay* other); + +typedef struct temporal_rs_PlainMonthDay_from_utf8_result {union {PlainMonthDay* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_from_utf8_result; +temporal_rs_PlainMonthDay_from_utf8_result temporal_rs_PlainMonthDay_from_utf8(DiplomatStringView s); + +typedef struct temporal_rs_PlainMonthDay_from_utf16_result {union {PlainMonthDay* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_from_utf16_result; +temporal_rs_PlainMonthDay_from_utf16_result temporal_rs_PlainMonthDay_from_utf16(DiplomatString16View s); + +uint8_t temporal_rs_PlainMonthDay_day(const PlainMonthDay* self); + +const Calendar* temporal_rs_PlainMonthDay_calendar(const PlainMonthDay* self); + +void temporal_rs_PlainMonthDay_month_code(const PlainMonthDay* self, DiplomatWrite* write); + +typedef struct temporal_rs_PlainMonthDay_to_plain_date_result {union {PlainDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_to_plain_date_result; +temporal_rs_PlainMonthDay_to_plain_date_result temporal_rs_PlainMonthDay_to_plain_date(const PlainMonthDay* self, PartialDate_option year); + +typedef struct temporal_rs_PlainMonthDay_epoch_ms_for_result {union {int64_t ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_epoch_ms_for_result; +temporal_rs_PlainMonthDay_epoch_ms_for_result temporal_rs_PlainMonthDay_epoch_ms_for(const PlainMonthDay* self, TimeZone time_zone); + +typedef struct temporal_rs_PlainMonthDay_epoch_ms_for_with_provider_result {union {int64_t ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_epoch_ms_for_with_provider_result; +temporal_rs_PlainMonthDay_epoch_ms_for_with_provider_result temporal_rs_PlainMonthDay_epoch_ms_for_with_provider(const PlainMonthDay* self, TimeZone time_zone, const Provider* p); + +void temporal_rs_PlainMonthDay_to_ixdtf_string(const PlainMonthDay* self, DisplayCalendar display_calendar, DiplomatWrite* write); + +PlainMonthDay* temporal_rs_PlainMonthDay_clone(const PlainMonthDay* self); + +void temporal_rs_PlainMonthDay_destroy(PlainMonthDay* self); + + + + + +#endif // PlainMonthDay_H diff --git a/deps/temporal/temporal_capi/bindings/c/PlainTime.d.h b/deps/temporal/temporal_capi/bindings/c/PlainTime.d.h new file mode 100644 index 00000000000000..0d3ca8e327bb46 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PlainTime.d.h @@ -0,0 +1,19 @@ +#ifndef PlainTime_D_H +#define PlainTime_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct PlainTime PlainTime; + + + + +#endif // PlainTime_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/PlainTime.h b/deps/temporal/temporal_capi/bindings/c/PlainTime.h new file mode 100644 index 00000000000000..0d897da90a9f49 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PlainTime.h @@ -0,0 +1,100 @@ +#ifndef PlainTime_H +#define PlainTime_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "ArithmeticOverflow.d.h" +#include "DifferenceSettings.d.h" +#include "Duration.d.h" +#include "I128Nanoseconds.d.h" +#include "PartialTime.d.h" +#include "Provider.d.h" +#include "RoundingOptions.d.h" +#include "TemporalError.d.h" +#include "TimeZone.d.h" +#include "ToStringRoundingOptions.d.h" + +#include "PlainTime.d.h" + + + + + + +typedef struct temporal_rs_PlainTime_try_new_constrain_result {union {PlainTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_try_new_constrain_result; +temporal_rs_PlainTime_try_new_constrain_result temporal_rs_PlainTime_try_new_constrain(uint8_t hour, uint8_t minute, uint8_t second, uint16_t millisecond, uint16_t microsecond, uint16_t nanosecond); + +typedef struct temporal_rs_PlainTime_try_new_result {union {PlainTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_try_new_result; +temporal_rs_PlainTime_try_new_result temporal_rs_PlainTime_try_new(uint8_t hour, uint8_t minute, uint8_t second, uint16_t millisecond, uint16_t microsecond, uint16_t nanosecond); + +typedef struct temporal_rs_PlainTime_from_partial_result {union {PlainTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_from_partial_result; +temporal_rs_PlainTime_from_partial_result temporal_rs_PlainTime_from_partial(PartialTime partial, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_PlainTime_from_epoch_milliseconds_result {union {PlainTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_from_epoch_milliseconds_result; +temporal_rs_PlainTime_from_epoch_milliseconds_result temporal_rs_PlainTime_from_epoch_milliseconds(int64_t ms, TimeZone tz); + +typedef struct temporal_rs_PlainTime_from_epoch_milliseconds_with_provider_result {union {PlainTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_from_epoch_milliseconds_with_provider_result; +temporal_rs_PlainTime_from_epoch_milliseconds_with_provider_result temporal_rs_PlainTime_from_epoch_milliseconds_with_provider(int64_t ms, TimeZone tz, const Provider* p); + +typedef struct temporal_rs_PlainTime_from_epoch_nanoseconds_result {union {PlainTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_from_epoch_nanoseconds_result; +temporal_rs_PlainTime_from_epoch_nanoseconds_result temporal_rs_PlainTime_from_epoch_nanoseconds(I128Nanoseconds ns, TimeZone tz); + +typedef struct temporal_rs_PlainTime_from_epoch_nanoseconds_with_provider_result {union {PlainTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_from_epoch_nanoseconds_with_provider_result; +temporal_rs_PlainTime_from_epoch_nanoseconds_with_provider_result temporal_rs_PlainTime_from_epoch_nanoseconds_with_provider(I128Nanoseconds ns, TimeZone tz, const Provider* p); + +typedef struct temporal_rs_PlainTime_with_result {union {PlainTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_with_result; +temporal_rs_PlainTime_with_result temporal_rs_PlainTime_with(const PlainTime* self, PartialTime partial, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_PlainTime_from_utf8_result {union {PlainTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_from_utf8_result; +temporal_rs_PlainTime_from_utf8_result temporal_rs_PlainTime_from_utf8(DiplomatStringView s); + +typedef struct temporal_rs_PlainTime_from_utf16_result {union {PlainTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_from_utf16_result; +temporal_rs_PlainTime_from_utf16_result temporal_rs_PlainTime_from_utf16(DiplomatString16View s); + +uint8_t temporal_rs_PlainTime_hour(const PlainTime* self); + +uint8_t temporal_rs_PlainTime_minute(const PlainTime* self); + +uint8_t temporal_rs_PlainTime_second(const PlainTime* self); + +uint16_t temporal_rs_PlainTime_millisecond(const PlainTime* self); + +uint16_t temporal_rs_PlainTime_microsecond(const PlainTime* self); + +uint16_t temporal_rs_PlainTime_nanosecond(const PlainTime* self); + +typedef struct temporal_rs_PlainTime_add_result {union {PlainTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_add_result; +temporal_rs_PlainTime_add_result temporal_rs_PlainTime_add(const PlainTime* self, const Duration* duration); + +typedef struct temporal_rs_PlainTime_subtract_result {union {PlainTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_subtract_result; +temporal_rs_PlainTime_subtract_result temporal_rs_PlainTime_subtract(const PlainTime* self, const Duration* duration); + +typedef struct temporal_rs_PlainTime_until_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_until_result; +temporal_rs_PlainTime_until_result temporal_rs_PlainTime_until(const PlainTime* self, const PlainTime* other, DifferenceSettings settings); + +typedef struct temporal_rs_PlainTime_since_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_since_result; +temporal_rs_PlainTime_since_result temporal_rs_PlainTime_since(const PlainTime* self, const PlainTime* other, DifferenceSettings settings); + +bool temporal_rs_PlainTime_equals(const PlainTime* self, const PlainTime* other); + +int8_t temporal_rs_PlainTime_compare(const PlainTime* one, const PlainTime* two); + +typedef struct temporal_rs_PlainTime_round_result {union {PlainTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_round_result; +temporal_rs_PlainTime_round_result temporal_rs_PlainTime_round(const PlainTime* self, RoundingOptions options); + +typedef struct temporal_rs_PlainTime_to_ixdtf_string_result {union { TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_to_ixdtf_string_result; +temporal_rs_PlainTime_to_ixdtf_string_result temporal_rs_PlainTime_to_ixdtf_string(const PlainTime* self, ToStringRoundingOptions options, DiplomatWrite* write); + +PlainTime* temporal_rs_PlainTime_clone(const PlainTime* self); + +void temporal_rs_PlainTime_destroy(PlainTime* self); + + + + + +#endif // PlainTime_H diff --git a/deps/temporal/temporal_capi/bindings/c/PlainYearMonth.d.h b/deps/temporal/temporal_capi/bindings/c/PlainYearMonth.d.h new file mode 100644 index 00000000000000..beff08754ac718 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PlainYearMonth.d.h @@ -0,0 +1,19 @@ +#ifndef PlainYearMonth_D_H +#define PlainYearMonth_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct PlainYearMonth PlainYearMonth; + + + + +#endif // PlainYearMonth_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/PlainYearMonth.h b/deps/temporal/temporal_capi/bindings/c/PlainYearMonth.h new file mode 100644 index 00000000000000..2283264e3ea980 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/PlainYearMonth.h @@ -0,0 +1,104 @@ +#ifndef PlainYearMonth_H +#define PlainYearMonth_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "AnyCalendarKind.d.h" +#include "ArithmeticOverflow.d.h" +#include "Calendar.d.h" +#include "DifferenceSettings.d.h" +#include "DisplayCalendar.d.h" +#include "Duration.d.h" +#include "ParsedDate.d.h" +#include "PartialDate.d.h" +#include "PlainDate.d.h" +#include "Provider.d.h" +#include "TemporalError.d.h" +#include "TimeZone.d.h" + +#include "PlainYearMonth.d.h" + + + + + + +typedef struct temporal_rs_PlainYearMonth_try_new_with_overflow_result {union {PlainYearMonth* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_try_new_with_overflow_result; +temporal_rs_PlainYearMonth_try_new_with_overflow_result temporal_rs_PlainYearMonth_try_new_with_overflow(int32_t year, uint8_t month, OptionU8 reference_day, AnyCalendarKind calendar, ArithmeticOverflow overflow); + +typedef struct temporal_rs_PlainYearMonth_from_partial_result {union {PlainYearMonth* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_from_partial_result; +temporal_rs_PlainYearMonth_from_partial_result temporal_rs_PlainYearMonth_from_partial(PartialDate partial, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_PlainYearMonth_from_parsed_result {union {PlainYearMonth* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_from_parsed_result; +temporal_rs_PlainYearMonth_from_parsed_result temporal_rs_PlainYearMonth_from_parsed(const ParsedDate* parsed); + +typedef struct temporal_rs_PlainYearMonth_with_result {union {PlainYearMonth* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_with_result; +temporal_rs_PlainYearMonth_with_result temporal_rs_PlainYearMonth_with(const PlainYearMonth* self, PartialDate partial, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_PlainYearMonth_from_utf8_result {union {PlainYearMonth* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_from_utf8_result; +temporal_rs_PlainYearMonth_from_utf8_result temporal_rs_PlainYearMonth_from_utf8(DiplomatStringView s); + +typedef struct temporal_rs_PlainYearMonth_from_utf16_result {union {PlainYearMonth* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_from_utf16_result; +temporal_rs_PlainYearMonth_from_utf16_result temporal_rs_PlainYearMonth_from_utf16(DiplomatString16View s); + +int32_t temporal_rs_PlainYearMonth_year(const PlainYearMonth* self); + +uint8_t temporal_rs_PlainYearMonth_month(const PlainYearMonth* self); + +void temporal_rs_PlainYearMonth_month_code(const PlainYearMonth* self, DiplomatWrite* write); + +bool temporal_rs_PlainYearMonth_in_leap_year(const PlainYearMonth* self); + +uint16_t temporal_rs_PlainYearMonth_days_in_month(const PlainYearMonth* self); + +uint16_t temporal_rs_PlainYearMonth_days_in_year(const PlainYearMonth* self); + +uint16_t temporal_rs_PlainYearMonth_months_in_year(const PlainYearMonth* self); + +void temporal_rs_PlainYearMonth_era(const PlainYearMonth* self, DiplomatWrite* write); + +typedef struct temporal_rs_PlainYearMonth_era_year_result {union {int32_t ok; }; bool is_ok;} temporal_rs_PlainYearMonth_era_year_result; +temporal_rs_PlainYearMonth_era_year_result temporal_rs_PlainYearMonth_era_year(const PlainYearMonth* self); + +const Calendar* temporal_rs_PlainYearMonth_calendar(const PlainYearMonth* self); + +typedef struct temporal_rs_PlainYearMonth_add_result {union {PlainYearMonth* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_add_result; +temporal_rs_PlainYearMonth_add_result temporal_rs_PlainYearMonth_add(const PlainYearMonth* self, const Duration* duration, ArithmeticOverflow overflow); + +typedef struct temporal_rs_PlainYearMonth_subtract_result {union {PlainYearMonth* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_subtract_result; +temporal_rs_PlainYearMonth_subtract_result temporal_rs_PlainYearMonth_subtract(const PlainYearMonth* self, const Duration* duration, ArithmeticOverflow overflow); + +typedef struct temporal_rs_PlainYearMonth_until_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_until_result; +temporal_rs_PlainYearMonth_until_result temporal_rs_PlainYearMonth_until(const PlainYearMonth* self, const PlainYearMonth* other, DifferenceSettings settings); + +typedef struct temporal_rs_PlainYearMonth_since_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_since_result; +temporal_rs_PlainYearMonth_since_result temporal_rs_PlainYearMonth_since(const PlainYearMonth* self, const PlainYearMonth* other, DifferenceSettings settings); + +bool temporal_rs_PlainYearMonth_equals(const PlainYearMonth* self, const PlainYearMonth* other); + +int8_t temporal_rs_PlainYearMonth_compare(const PlainYearMonth* one, const PlainYearMonth* two); + +typedef struct temporal_rs_PlainYearMonth_to_plain_date_result {union {PlainDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_to_plain_date_result; +temporal_rs_PlainYearMonth_to_plain_date_result temporal_rs_PlainYearMonth_to_plain_date(const PlainYearMonth* self, PartialDate_option day); + +typedef struct temporal_rs_PlainYearMonth_epoch_ms_for_result {union {int64_t ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_epoch_ms_for_result; +temporal_rs_PlainYearMonth_epoch_ms_for_result temporal_rs_PlainYearMonth_epoch_ms_for(const PlainYearMonth* self, TimeZone time_zone); + +typedef struct temporal_rs_PlainYearMonth_epoch_ms_for_with_provider_result {union {int64_t ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_epoch_ms_for_with_provider_result; +temporal_rs_PlainYearMonth_epoch_ms_for_with_provider_result temporal_rs_PlainYearMonth_epoch_ms_for_with_provider(const PlainYearMonth* self, TimeZone time_zone, const Provider* p); + +void temporal_rs_PlainYearMonth_to_ixdtf_string(const PlainYearMonth* self, DisplayCalendar display_calendar, DiplomatWrite* write); + +PlainYearMonth* temporal_rs_PlainYearMonth_clone(const PlainYearMonth* self); + +void temporal_rs_PlainYearMonth_destroy(PlainYearMonth* self); + + + + + +#endif // PlainYearMonth_H diff --git a/deps/temporal/temporal_capi/bindings/c/Precision.d.h b/deps/temporal/temporal_capi/bindings/c/Precision.d.h new file mode 100644 index 00000000000000..858901bc4ef254 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/Precision.d.h @@ -0,0 +1,23 @@ +#ifndef Precision_D_H +#define Precision_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct Precision { + bool is_minute; + OptionU8 precision; +} Precision; + +typedef struct Precision_option {union { Precision ok; }; bool is_ok; } Precision_option; + + + +#endif // Precision_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/Precision.h b/deps/temporal/temporal_capi/bindings/c/Precision.h new file mode 100644 index 00000000000000..b184fe14192c7c --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/Precision.h @@ -0,0 +1,22 @@ +#ifndef Precision_H +#define Precision_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "Precision.d.h" + + + + + + + + + + +#endif // Precision_H diff --git a/deps/temporal/temporal_capi/bindings/c/Provider.d.h b/deps/temporal/temporal_capi/bindings/c/Provider.d.h new file mode 100644 index 00000000000000..f55779116fdf38 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/Provider.d.h @@ -0,0 +1,19 @@ +#ifndef Provider_D_H +#define Provider_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct Provider Provider; + + + + +#endif // Provider_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/Provider.h b/deps/temporal/temporal_capi/bindings/c/Provider.h new file mode 100644 index 00000000000000..3a60b153eee086 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/Provider.h @@ -0,0 +1,31 @@ +#ifndef Provider_H +#define Provider_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "Provider.d.h" + + + + + + +typedef struct temporal_rs_Provider_new_zoneinfo64_result {union {Provider* ok; }; bool is_ok;} temporal_rs_Provider_new_zoneinfo64_result; +temporal_rs_Provider_new_zoneinfo64_result temporal_rs_Provider_new_zoneinfo64(DiplomatU32View data); + +Provider* temporal_rs_Provider_new_compiled(void); + +Provider* temporal_rs_Provider_empty(void); + +void temporal_rs_Provider_destroy(Provider* self); + + + + + +#endif // Provider_H diff --git a/deps/temporal/temporal_capi/bindings/c/RelativeTo.d.h b/deps/temporal/temporal_capi/bindings/c/RelativeTo.d.h new file mode 100644 index 00000000000000..fde7f3c6c1b870 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/RelativeTo.d.h @@ -0,0 +1,25 @@ +#ifndef RelativeTo_D_H +#define RelativeTo_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "PlainDate.d.h" +#include "ZonedDateTime.d.h" + + + + +typedef struct RelativeTo { + const PlainDate* date; + const ZonedDateTime* zoned; +} RelativeTo; + +typedef struct RelativeTo_option {union { RelativeTo ok; }; bool is_ok; } RelativeTo_option; + + + +#endif // RelativeTo_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/RelativeTo.h b/deps/temporal/temporal_capi/bindings/c/RelativeTo.h new file mode 100644 index 00000000000000..d40bc871f08922 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/RelativeTo.h @@ -0,0 +1,22 @@ +#ifndef RelativeTo_H +#define RelativeTo_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "RelativeTo.d.h" + + + + + + + + + + +#endif // RelativeTo_H diff --git a/deps/temporal/temporal_capi/bindings/c/RoundingMode.d.h b/deps/temporal/temporal_capi/bindings/c/RoundingMode.d.h new file mode 100644 index 00000000000000..b6bdd3aa0f1662 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/RoundingMode.d.h @@ -0,0 +1,30 @@ +#ifndef RoundingMode_D_H +#define RoundingMode_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef enum RoundingMode { + RoundingMode_Ceil = 0, + RoundingMode_Floor = 1, + RoundingMode_Expand = 2, + RoundingMode_Trunc = 3, + RoundingMode_HalfCeil = 4, + RoundingMode_HalfFloor = 5, + RoundingMode_HalfExpand = 6, + RoundingMode_HalfTrunc = 7, + RoundingMode_HalfEven = 8, +} RoundingMode; + +typedef struct RoundingMode_option {union { RoundingMode ok; }; bool is_ok; } RoundingMode_option; + + + +#endif // RoundingMode_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/RoundingMode.h b/deps/temporal/temporal_capi/bindings/c/RoundingMode.h new file mode 100644 index 00000000000000..5c028595f86548 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/RoundingMode.h @@ -0,0 +1,22 @@ +#ifndef RoundingMode_H +#define RoundingMode_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "RoundingMode.d.h" + + + + + + + + + + +#endif // RoundingMode_H diff --git a/deps/temporal/temporal_capi/bindings/c/RoundingOptions.d.h b/deps/temporal/temporal_capi/bindings/c/RoundingOptions.d.h new file mode 100644 index 00000000000000..37c2bc25a60cfc --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/RoundingOptions.d.h @@ -0,0 +1,27 @@ +#ifndef RoundingOptions_D_H +#define RoundingOptions_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "RoundingMode.d.h" +#include "Unit.d.h" + + + + +typedef struct RoundingOptions { + Unit_option largest_unit; + Unit_option smallest_unit; + RoundingMode_option rounding_mode; + OptionU32 increment; +} RoundingOptions; + +typedef struct RoundingOptions_option {union { RoundingOptions ok; }; bool is_ok; } RoundingOptions_option; + + + +#endif // RoundingOptions_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/RoundingOptions.h b/deps/temporal/temporal_capi/bindings/c/RoundingOptions.h new file mode 100644 index 00000000000000..0d0c4f6cbee25d --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/RoundingOptions.h @@ -0,0 +1,22 @@ +#ifndef RoundingOptions_H +#define RoundingOptions_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "RoundingOptions.d.h" + + + + + + + + + + +#endif // RoundingOptions_H diff --git a/deps/temporal/temporal_capi/bindings/c/Sign.d.h b/deps/temporal/temporal_capi/bindings/c/Sign.d.h new file mode 100644 index 00000000000000..787837d280e5f7 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/Sign.d.h @@ -0,0 +1,24 @@ +#ifndef Sign_D_H +#define Sign_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef enum Sign { + Sign_Positive = 1, + Sign_Zero = 0, + Sign_Negative = -1, +} Sign; + +typedef struct Sign_option {union { Sign ok; }; bool is_ok; } Sign_option; + + + +#endif // Sign_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/Sign.h b/deps/temporal/temporal_capi/bindings/c/Sign.h new file mode 100644 index 00000000000000..10f470c3427db4 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/Sign.h @@ -0,0 +1,22 @@ +#ifndef Sign_H +#define Sign_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "Sign.d.h" + + + + + + + + + + +#endif // Sign_H diff --git a/deps/temporal/temporal_capi/bindings/c/TemporalError.d.h b/deps/temporal/temporal_capi/bindings/c/TemporalError.d.h new file mode 100644 index 00000000000000..3c37cf5f339b16 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/TemporalError.d.h @@ -0,0 +1,24 @@ +#ifndef TemporalError_D_H +#define TemporalError_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "ErrorKind.d.h" + + + + +typedef struct TemporalError { + ErrorKind kind; + OptionStringView msg; +} TemporalError; + +typedef struct TemporalError_option {union { TemporalError ok; }; bool is_ok; } TemporalError_option; + + + +#endif // TemporalError_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/TemporalError.h b/deps/temporal/temporal_capi/bindings/c/TemporalError.h new file mode 100644 index 00000000000000..5386db88391af0 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/TemporalError.h @@ -0,0 +1,22 @@ +#ifndef TemporalError_H +#define TemporalError_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "TemporalError.d.h" + + + + + + + + + + +#endif // TemporalError_H diff --git a/deps/temporal/temporal_capi/bindings/c/TimeZone.d.h b/deps/temporal/temporal_capi/bindings/c/TimeZone.d.h new file mode 100644 index 00000000000000..892eea11c2796a --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/TimeZone.d.h @@ -0,0 +1,25 @@ +#ifndef TimeZone_D_H +#define TimeZone_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct TimeZone { + int16_t offset_minutes; + size_t resolved_id; + size_t normalized_id; + bool is_iana_id; +} TimeZone; + +typedef struct TimeZone_option {union { TimeZone ok; }; bool is_ok; } TimeZone_option; + + + +#endif // TimeZone_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/TimeZone.h b/deps/temporal/temporal_capi/bindings/c/TimeZone.h new file mode 100644 index 00000000000000..152aa5b7054152 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/TimeZone.h @@ -0,0 +1,57 @@ +#ifndef TimeZone_H +#define TimeZone_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "Provider.d.h" +#include "TemporalError.d.h" + +#include "TimeZone.d.h" + + + + + + +typedef struct temporal_rs_TimeZone_try_from_identifier_str_result {union {TimeZone ok; TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_try_from_identifier_str_result; +temporal_rs_TimeZone_try_from_identifier_str_result temporal_rs_TimeZone_try_from_identifier_str(DiplomatStringView ident); + +typedef struct temporal_rs_TimeZone_try_from_identifier_str_with_provider_result {union {TimeZone ok; TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_try_from_identifier_str_with_provider_result; +temporal_rs_TimeZone_try_from_identifier_str_with_provider_result temporal_rs_TimeZone_try_from_identifier_str_with_provider(DiplomatStringView ident, const Provider* p); + +typedef struct temporal_rs_TimeZone_try_from_offset_str_result {union {TimeZone ok; TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_try_from_offset_str_result; +temporal_rs_TimeZone_try_from_offset_str_result temporal_rs_TimeZone_try_from_offset_str(DiplomatStringView ident); + +typedef struct temporal_rs_TimeZone_try_from_str_result {union {TimeZone ok; TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_try_from_str_result; +temporal_rs_TimeZone_try_from_str_result temporal_rs_TimeZone_try_from_str(DiplomatStringView ident); + +typedef struct temporal_rs_TimeZone_try_from_str_with_provider_result {union {TimeZone ok; TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_try_from_str_with_provider_result; +temporal_rs_TimeZone_try_from_str_with_provider_result temporal_rs_TimeZone_try_from_str_with_provider(DiplomatStringView ident, const Provider* p); + +void temporal_rs_TimeZone_identifier(TimeZone self, DiplomatWrite* write); + +typedef struct temporal_rs_TimeZone_identifier_with_provider_result {union { TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_identifier_with_provider_result; +temporal_rs_TimeZone_identifier_with_provider_result temporal_rs_TimeZone_identifier_with_provider(TimeZone self, const Provider* p, DiplomatWrite* write); + +TimeZone temporal_rs_TimeZone_utc(void); + +typedef struct temporal_rs_TimeZone_utc_with_provider_result {union {TimeZone ok; TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_utc_with_provider_result; +temporal_rs_TimeZone_utc_with_provider_result temporal_rs_TimeZone_utc_with_provider(const Provider* p); + +TimeZone temporal_rs_TimeZone_zero(void); + +typedef struct temporal_rs_TimeZone_primary_identifier_result {union {TimeZone ok; TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_primary_identifier_result; +temporal_rs_TimeZone_primary_identifier_result temporal_rs_TimeZone_primary_identifier(TimeZone self); + +typedef struct temporal_rs_TimeZone_primary_identifier_with_provider_result {union {TimeZone ok; TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_primary_identifier_with_provider_result; +temporal_rs_TimeZone_primary_identifier_with_provider_result temporal_rs_TimeZone_primary_identifier_with_provider(TimeZone self, const Provider* p); + + + + + +#endif // TimeZone_H diff --git a/deps/temporal/temporal_capi/bindings/c/ToStringRoundingOptions.d.h b/deps/temporal/temporal_capi/bindings/c/ToStringRoundingOptions.d.h new file mode 100644 index 00000000000000..7cb50707916f95 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/ToStringRoundingOptions.d.h @@ -0,0 +1,27 @@ +#ifndef ToStringRoundingOptions_D_H +#define ToStringRoundingOptions_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "Precision.d.h" +#include "RoundingMode.d.h" +#include "Unit.d.h" + + + + +typedef struct ToStringRoundingOptions { + Precision precision; + Unit_option smallest_unit; + RoundingMode_option rounding_mode; +} ToStringRoundingOptions; + +typedef struct ToStringRoundingOptions_option {union { ToStringRoundingOptions ok; }; bool is_ok; } ToStringRoundingOptions_option; + + + +#endif // ToStringRoundingOptions_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/ToStringRoundingOptions.h b/deps/temporal/temporal_capi/bindings/c/ToStringRoundingOptions.h new file mode 100644 index 00000000000000..cc43e6f5efc0fc --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/ToStringRoundingOptions.h @@ -0,0 +1,22 @@ +#ifndef ToStringRoundingOptions_H +#define ToStringRoundingOptions_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "ToStringRoundingOptions.d.h" + + + + + + + + + + +#endif // ToStringRoundingOptions_H diff --git a/deps/temporal/temporal_capi/bindings/c/TransitionDirection.d.h b/deps/temporal/temporal_capi/bindings/c/TransitionDirection.d.h new file mode 100644 index 00000000000000..0976c3ee6e28f0 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/TransitionDirection.d.h @@ -0,0 +1,23 @@ +#ifndef TransitionDirection_D_H +#define TransitionDirection_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef enum TransitionDirection { + TransitionDirection_Next = 0, + TransitionDirection_Previous = 1, +} TransitionDirection; + +typedef struct TransitionDirection_option {union { TransitionDirection ok; }; bool is_ok; } TransitionDirection_option; + + + +#endif // TransitionDirection_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/TransitionDirection.h b/deps/temporal/temporal_capi/bindings/c/TransitionDirection.h new file mode 100644 index 00000000000000..2bc20dd00d8a4a --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/TransitionDirection.h @@ -0,0 +1,22 @@ +#ifndef TransitionDirection_H +#define TransitionDirection_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "TransitionDirection.d.h" + + + + + + + + + + +#endif // TransitionDirection_H diff --git a/deps/temporal/temporal_capi/bindings/c/Unit.d.h b/deps/temporal/temporal_capi/bindings/c/Unit.d.h new file mode 100644 index 00000000000000..00d816ee88dbd6 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/Unit.d.h @@ -0,0 +1,32 @@ +#ifndef Unit_D_H +#define Unit_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef enum Unit { + Unit_Auto = 0, + Unit_Nanosecond = 1, + Unit_Microsecond = 2, + Unit_Millisecond = 3, + Unit_Second = 4, + Unit_Minute = 5, + Unit_Hour = 6, + Unit_Day = 7, + Unit_Week = 8, + Unit_Month = 9, + Unit_Year = 10, +} Unit; + +typedef struct Unit_option {union { Unit ok; }; bool is_ok; } Unit_option; + + + +#endif // Unit_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/Unit.h b/deps/temporal/temporal_capi/bindings/c/Unit.h new file mode 100644 index 00000000000000..7ad63612212d6e --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/Unit.h @@ -0,0 +1,22 @@ +#ifndef Unit_H +#define Unit_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "Unit.d.h" + + + + + + + + + + +#endif // Unit_H diff --git a/deps/temporal/temporal_capi/bindings/c/UnsignedRoundingMode.d.h b/deps/temporal/temporal_capi/bindings/c/UnsignedRoundingMode.d.h new file mode 100644 index 00000000000000..c0f18ebb43e175 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/UnsignedRoundingMode.d.h @@ -0,0 +1,26 @@ +#ifndef UnsignedRoundingMode_D_H +#define UnsignedRoundingMode_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef enum UnsignedRoundingMode { + UnsignedRoundingMode_Infinity = 0, + UnsignedRoundingMode_Zero = 1, + UnsignedRoundingMode_HalfInfinity = 2, + UnsignedRoundingMode_HalfZero = 3, + UnsignedRoundingMode_HalfEven = 4, +} UnsignedRoundingMode; + +typedef struct UnsignedRoundingMode_option {union { UnsignedRoundingMode ok; }; bool is_ok; } UnsignedRoundingMode_option; + + + +#endif // UnsignedRoundingMode_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/UnsignedRoundingMode.h b/deps/temporal/temporal_capi/bindings/c/UnsignedRoundingMode.h new file mode 100644 index 00000000000000..4e68a3ba351f69 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/UnsignedRoundingMode.h @@ -0,0 +1,22 @@ +#ifndef UnsignedRoundingMode_H +#define UnsignedRoundingMode_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "UnsignedRoundingMode.d.h" + + + + + + + + + + +#endif // UnsignedRoundingMode_H diff --git a/deps/temporal/temporal_capi/bindings/c/ZonedDateTime.d.h b/deps/temporal/temporal_capi/bindings/c/ZonedDateTime.d.h new file mode 100644 index 00000000000000..f1380f58043c71 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/ZonedDateTime.d.h @@ -0,0 +1,19 @@ +#ifndef ZonedDateTime_D_H +#define ZonedDateTime_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct ZonedDateTime ZonedDateTime; + + + + +#endif // ZonedDateTime_D_H diff --git a/deps/temporal/temporal_capi/bindings/c/ZonedDateTime.h b/deps/temporal/temporal_capi/bindings/c/ZonedDateTime.h new file mode 100644 index 00000000000000..b2faad335ea200 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/ZonedDateTime.h @@ -0,0 +1,238 @@ +#ifndef ZonedDateTime_H +#define ZonedDateTime_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "AnyCalendarKind.d.h" +#include "ArithmeticOverflow.d.h" +#include "Calendar.d.h" +#include "DifferenceSettings.d.h" +#include "Disambiguation.d.h" +#include "DisplayCalendar.d.h" +#include "DisplayOffset.d.h" +#include "DisplayTimeZone.d.h" +#include "Duration.d.h" +#include "I128Nanoseconds.d.h" +#include "Instant.d.h" +#include "OffsetDisambiguation.d.h" +#include "ParsedZonedDateTime.d.h" +#include "PartialZonedDateTime.d.h" +#include "PlainDate.d.h" +#include "PlainDateTime.d.h" +#include "PlainTime.d.h" +#include "Provider.d.h" +#include "RoundingOptions.d.h" +#include "TemporalError.d.h" +#include "TimeZone.d.h" +#include "ToStringRoundingOptions.d.h" +#include "TransitionDirection.d.h" + +#include "ZonedDateTime.d.h" + + + + + + +typedef struct temporal_rs_ZonedDateTime_try_new_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_try_new_result; +temporal_rs_ZonedDateTime_try_new_result temporal_rs_ZonedDateTime_try_new(I128Nanoseconds nanosecond, AnyCalendarKind calendar, TimeZone time_zone); + +typedef struct temporal_rs_ZonedDateTime_try_new_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_try_new_with_provider_result; +temporal_rs_ZonedDateTime_try_new_with_provider_result temporal_rs_ZonedDateTime_try_new_with_provider(I128Nanoseconds nanosecond, AnyCalendarKind calendar, TimeZone time_zone, const Provider* p); + +typedef struct temporal_rs_ZonedDateTime_from_partial_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_partial_result; +temporal_rs_ZonedDateTime_from_partial_result temporal_rs_ZonedDateTime_from_partial(PartialZonedDateTime partial, ArithmeticOverflow_option overflow, Disambiguation_option disambiguation, OffsetDisambiguation_option offset_option); + +typedef struct temporal_rs_ZonedDateTime_from_partial_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_partial_with_provider_result; +temporal_rs_ZonedDateTime_from_partial_with_provider_result temporal_rs_ZonedDateTime_from_partial_with_provider(PartialZonedDateTime partial, ArithmeticOverflow_option overflow, Disambiguation_option disambiguation, OffsetDisambiguation_option offset_option, const Provider* p); + +typedef struct temporal_rs_ZonedDateTime_from_parsed_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_parsed_result; +temporal_rs_ZonedDateTime_from_parsed_result temporal_rs_ZonedDateTime_from_parsed(const ParsedZonedDateTime* parsed, Disambiguation disambiguation, OffsetDisambiguation offset_option); + +typedef struct temporal_rs_ZonedDateTime_from_parsed_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_parsed_with_provider_result; +temporal_rs_ZonedDateTime_from_parsed_with_provider_result temporal_rs_ZonedDateTime_from_parsed_with_provider(const ParsedZonedDateTime* parsed, Disambiguation disambiguation, OffsetDisambiguation offset_option, const Provider* p); + +typedef struct temporal_rs_ZonedDateTime_from_utf8_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_utf8_result; +temporal_rs_ZonedDateTime_from_utf8_result temporal_rs_ZonedDateTime_from_utf8(DiplomatStringView s, Disambiguation disambiguation, OffsetDisambiguation offset_disambiguation); + +typedef struct temporal_rs_ZonedDateTime_from_utf8_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_utf8_with_provider_result; +temporal_rs_ZonedDateTime_from_utf8_with_provider_result temporal_rs_ZonedDateTime_from_utf8_with_provider(DiplomatStringView s, Disambiguation disambiguation, OffsetDisambiguation offset_disambiguation, const Provider* p); + +typedef struct temporal_rs_ZonedDateTime_from_utf16_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_utf16_result; +temporal_rs_ZonedDateTime_from_utf16_result temporal_rs_ZonedDateTime_from_utf16(DiplomatString16View s, Disambiguation disambiguation, OffsetDisambiguation offset_disambiguation); + +typedef struct temporal_rs_ZonedDateTime_from_utf16_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_utf16_with_provider_result; +temporal_rs_ZonedDateTime_from_utf16_with_provider_result temporal_rs_ZonedDateTime_from_utf16_with_provider(DiplomatString16View s, Disambiguation disambiguation, OffsetDisambiguation offset_disambiguation, const Provider* p); + +int64_t temporal_rs_ZonedDateTime_epoch_milliseconds(const ZonedDateTime* self); + +typedef struct temporal_rs_ZonedDateTime_from_epoch_milliseconds_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_epoch_milliseconds_result; +temporal_rs_ZonedDateTime_from_epoch_milliseconds_result temporal_rs_ZonedDateTime_from_epoch_milliseconds(int64_t ms, TimeZone tz); + +typedef struct temporal_rs_ZonedDateTime_from_epoch_milliseconds_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_epoch_milliseconds_with_provider_result; +temporal_rs_ZonedDateTime_from_epoch_milliseconds_with_provider_result temporal_rs_ZonedDateTime_from_epoch_milliseconds_with_provider(int64_t ms, TimeZone tz, const Provider* p); + +typedef struct temporal_rs_ZonedDateTime_from_epoch_nanoseconds_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_epoch_nanoseconds_result; +temporal_rs_ZonedDateTime_from_epoch_nanoseconds_result temporal_rs_ZonedDateTime_from_epoch_nanoseconds(I128Nanoseconds ns, TimeZone tz); + +typedef struct temporal_rs_ZonedDateTime_from_epoch_nanoseconds_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_epoch_nanoseconds_with_provider_result; +temporal_rs_ZonedDateTime_from_epoch_nanoseconds_with_provider_result temporal_rs_ZonedDateTime_from_epoch_nanoseconds_with_provider(I128Nanoseconds ns, TimeZone tz, const Provider* p); + +I128Nanoseconds temporal_rs_ZonedDateTime_epoch_nanoseconds(const ZonedDateTime* self); + +int64_t temporal_rs_ZonedDateTime_offset_nanoseconds(const ZonedDateTime* self); + +Instant* temporal_rs_ZonedDateTime_to_instant(const ZonedDateTime* self); + +typedef struct temporal_rs_ZonedDateTime_with_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_result; +temporal_rs_ZonedDateTime_with_result temporal_rs_ZonedDateTime_with(const ZonedDateTime* self, PartialZonedDateTime partial, Disambiguation_option disambiguation, OffsetDisambiguation_option offset_option, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_ZonedDateTime_with_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_with_provider_result; +temporal_rs_ZonedDateTime_with_with_provider_result temporal_rs_ZonedDateTime_with_with_provider(const ZonedDateTime* self, PartialZonedDateTime partial, Disambiguation_option disambiguation, OffsetDisambiguation_option offset_option, ArithmeticOverflow_option overflow, const Provider* p); + +typedef struct temporal_rs_ZonedDateTime_with_timezone_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_timezone_result; +temporal_rs_ZonedDateTime_with_timezone_result temporal_rs_ZonedDateTime_with_timezone(const ZonedDateTime* self, TimeZone zone); + +typedef struct temporal_rs_ZonedDateTime_with_timezone_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_timezone_with_provider_result; +temporal_rs_ZonedDateTime_with_timezone_with_provider_result temporal_rs_ZonedDateTime_with_timezone_with_provider(const ZonedDateTime* self, TimeZone zone, const Provider* p); + +TimeZone temporal_rs_ZonedDateTime_timezone(const ZonedDateTime* self); + +int8_t temporal_rs_ZonedDateTime_compare_instant(const ZonedDateTime* self, const ZonedDateTime* other); + +bool temporal_rs_ZonedDateTime_equals(const ZonedDateTime* self, const ZonedDateTime* other); + +typedef struct temporal_rs_ZonedDateTime_equals_with_provider_result {union {bool ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_equals_with_provider_result; +temporal_rs_ZonedDateTime_equals_with_provider_result temporal_rs_ZonedDateTime_equals_with_provider(const ZonedDateTime* self, const ZonedDateTime* other, const Provider* p); + +typedef struct temporal_rs_ZonedDateTime_offset_result {union { TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_offset_result; +temporal_rs_ZonedDateTime_offset_result temporal_rs_ZonedDateTime_offset(const ZonedDateTime* self, DiplomatWrite* write); + +typedef struct temporal_rs_ZonedDateTime_start_of_day_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_start_of_day_result; +temporal_rs_ZonedDateTime_start_of_day_result temporal_rs_ZonedDateTime_start_of_day(const ZonedDateTime* self); + +typedef struct temporal_rs_ZonedDateTime_start_of_day_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_start_of_day_with_provider_result; +temporal_rs_ZonedDateTime_start_of_day_with_provider_result temporal_rs_ZonedDateTime_start_of_day_with_provider(const ZonedDateTime* self, const Provider* p); + +typedef struct temporal_rs_ZonedDateTime_get_time_zone_transition_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_get_time_zone_transition_result; +temporal_rs_ZonedDateTime_get_time_zone_transition_result temporal_rs_ZonedDateTime_get_time_zone_transition(const ZonedDateTime* self, TransitionDirection direction); + +typedef struct temporal_rs_ZonedDateTime_get_time_zone_transition_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_get_time_zone_transition_with_provider_result; +temporal_rs_ZonedDateTime_get_time_zone_transition_with_provider_result temporal_rs_ZonedDateTime_get_time_zone_transition_with_provider(const ZonedDateTime* self, TransitionDirection direction, const Provider* p); + +typedef struct temporal_rs_ZonedDateTime_hours_in_day_result {union {double ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_hours_in_day_result; +temporal_rs_ZonedDateTime_hours_in_day_result temporal_rs_ZonedDateTime_hours_in_day(const ZonedDateTime* self); + +typedef struct temporal_rs_ZonedDateTime_hours_in_day_with_provider_result {union {double ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_hours_in_day_with_provider_result; +temporal_rs_ZonedDateTime_hours_in_day_with_provider_result temporal_rs_ZonedDateTime_hours_in_day_with_provider(const ZonedDateTime* self, const Provider* p); + +PlainDateTime* temporal_rs_ZonedDateTime_to_plain_datetime(const ZonedDateTime* self); + +PlainDate* temporal_rs_ZonedDateTime_to_plain_date(const ZonedDateTime* self); + +PlainTime* temporal_rs_ZonedDateTime_to_plain_time(const ZonedDateTime* self); + +typedef struct temporal_rs_ZonedDateTime_to_ixdtf_string_result {union { TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_to_ixdtf_string_result; +temporal_rs_ZonedDateTime_to_ixdtf_string_result temporal_rs_ZonedDateTime_to_ixdtf_string(const ZonedDateTime* self, DisplayOffset display_offset, DisplayTimeZone display_timezone, DisplayCalendar display_calendar, ToStringRoundingOptions options, DiplomatWrite* write); + +typedef struct temporal_rs_ZonedDateTime_to_ixdtf_string_with_provider_result {union { TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_to_ixdtf_string_with_provider_result; +temporal_rs_ZonedDateTime_to_ixdtf_string_with_provider_result temporal_rs_ZonedDateTime_to_ixdtf_string_with_provider(const ZonedDateTime* self, DisplayOffset display_offset, DisplayTimeZone display_timezone, DisplayCalendar display_calendar, ToStringRoundingOptions options, const Provider* p, DiplomatWrite* write); + +ZonedDateTime* temporal_rs_ZonedDateTime_with_calendar(const ZonedDateTime* self, AnyCalendarKind calendar); + +typedef struct temporal_rs_ZonedDateTime_with_plain_time_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_plain_time_result; +temporal_rs_ZonedDateTime_with_plain_time_result temporal_rs_ZonedDateTime_with_plain_time(const ZonedDateTime* self, const PlainTime* time); + +typedef struct temporal_rs_ZonedDateTime_with_plain_time_and_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_plain_time_and_provider_result; +temporal_rs_ZonedDateTime_with_plain_time_and_provider_result temporal_rs_ZonedDateTime_with_plain_time_and_provider(const ZonedDateTime* self, const PlainTime* time, const Provider* p); + +typedef struct temporal_rs_ZonedDateTime_add_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_add_result; +temporal_rs_ZonedDateTime_add_result temporal_rs_ZonedDateTime_add(const ZonedDateTime* self, const Duration* duration, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_ZonedDateTime_add_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_add_with_provider_result; +temporal_rs_ZonedDateTime_add_with_provider_result temporal_rs_ZonedDateTime_add_with_provider(const ZonedDateTime* self, const Duration* duration, ArithmeticOverflow_option overflow, const Provider* p); + +typedef struct temporal_rs_ZonedDateTime_subtract_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_subtract_result; +temporal_rs_ZonedDateTime_subtract_result temporal_rs_ZonedDateTime_subtract(const ZonedDateTime* self, const Duration* duration, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_ZonedDateTime_subtract_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_subtract_with_provider_result; +temporal_rs_ZonedDateTime_subtract_with_provider_result temporal_rs_ZonedDateTime_subtract_with_provider(const ZonedDateTime* self, const Duration* duration, ArithmeticOverflow_option overflow, const Provider* p); + +typedef struct temporal_rs_ZonedDateTime_until_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_until_result; +temporal_rs_ZonedDateTime_until_result temporal_rs_ZonedDateTime_until(const ZonedDateTime* self, const ZonedDateTime* other, DifferenceSettings settings); + +typedef struct temporal_rs_ZonedDateTime_until_with_provider_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_until_with_provider_result; +temporal_rs_ZonedDateTime_until_with_provider_result temporal_rs_ZonedDateTime_until_with_provider(const ZonedDateTime* self, const ZonedDateTime* other, DifferenceSettings settings, const Provider* p); + +typedef struct temporal_rs_ZonedDateTime_since_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_since_result; +temporal_rs_ZonedDateTime_since_result temporal_rs_ZonedDateTime_since(const ZonedDateTime* self, const ZonedDateTime* other, DifferenceSettings settings); + +typedef struct temporal_rs_ZonedDateTime_since_with_provider_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_since_with_provider_result; +temporal_rs_ZonedDateTime_since_with_provider_result temporal_rs_ZonedDateTime_since_with_provider(const ZonedDateTime* self, const ZonedDateTime* other, DifferenceSettings settings, const Provider* p); + +typedef struct temporal_rs_ZonedDateTime_round_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_round_result; +temporal_rs_ZonedDateTime_round_result temporal_rs_ZonedDateTime_round(const ZonedDateTime* self, RoundingOptions options); + +typedef struct temporal_rs_ZonedDateTime_round_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_round_with_provider_result; +temporal_rs_ZonedDateTime_round_with_provider_result temporal_rs_ZonedDateTime_round_with_provider(const ZonedDateTime* self, RoundingOptions options, const Provider* p); + +uint8_t temporal_rs_ZonedDateTime_hour(const ZonedDateTime* self); + +uint8_t temporal_rs_ZonedDateTime_minute(const ZonedDateTime* self); + +uint8_t temporal_rs_ZonedDateTime_second(const ZonedDateTime* self); + +uint16_t temporal_rs_ZonedDateTime_millisecond(const ZonedDateTime* self); + +uint16_t temporal_rs_ZonedDateTime_microsecond(const ZonedDateTime* self); + +uint16_t temporal_rs_ZonedDateTime_nanosecond(const ZonedDateTime* self); + +const Calendar* temporal_rs_ZonedDateTime_calendar(const ZonedDateTime* self); + +int32_t temporal_rs_ZonedDateTime_year(const ZonedDateTime* self); + +uint8_t temporal_rs_ZonedDateTime_month(const ZonedDateTime* self); + +void temporal_rs_ZonedDateTime_month_code(const ZonedDateTime* self, DiplomatWrite* write); + +uint8_t temporal_rs_ZonedDateTime_day(const ZonedDateTime* self); + +uint16_t temporal_rs_ZonedDateTime_day_of_week(const ZonedDateTime* self); + +uint16_t temporal_rs_ZonedDateTime_day_of_year(const ZonedDateTime* self); + +typedef struct temporal_rs_ZonedDateTime_week_of_year_result {union {uint8_t ok; }; bool is_ok;} temporal_rs_ZonedDateTime_week_of_year_result; +temporal_rs_ZonedDateTime_week_of_year_result temporal_rs_ZonedDateTime_week_of_year(const ZonedDateTime* self); + +typedef struct temporal_rs_ZonedDateTime_year_of_week_result {union {int32_t ok; }; bool is_ok;} temporal_rs_ZonedDateTime_year_of_week_result; +temporal_rs_ZonedDateTime_year_of_week_result temporal_rs_ZonedDateTime_year_of_week(const ZonedDateTime* self); + +uint16_t temporal_rs_ZonedDateTime_days_in_week(const ZonedDateTime* self); + +uint16_t temporal_rs_ZonedDateTime_days_in_month(const ZonedDateTime* self); + +uint16_t temporal_rs_ZonedDateTime_days_in_year(const ZonedDateTime* self); + +uint16_t temporal_rs_ZonedDateTime_months_in_year(const ZonedDateTime* self); + +bool temporal_rs_ZonedDateTime_in_leap_year(const ZonedDateTime* self); + +void temporal_rs_ZonedDateTime_era(const ZonedDateTime* self, DiplomatWrite* write); + +typedef struct temporal_rs_ZonedDateTime_era_year_result {union {int32_t ok; }; bool is_ok;} temporal_rs_ZonedDateTime_era_year_result; +temporal_rs_ZonedDateTime_era_year_result temporal_rs_ZonedDateTime_era_year(const ZonedDateTime* self); + +ZonedDateTime* temporal_rs_ZonedDateTime_clone(const ZonedDateTime* self); + +void temporal_rs_ZonedDateTime_destroy(ZonedDateTime* self); + + + + + +#endif // ZonedDateTime_H diff --git a/deps/temporal/temporal_capi/bindings/c/diplomat_runtime.h b/deps/temporal/temporal_capi/bindings/c/diplomat_runtime.h new file mode 100644 index 00000000000000..e5d6b298d73c5b --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/c/diplomat_runtime.h @@ -0,0 +1,82 @@ +#ifndef DIPLOMAT_RUNTIME_C_H +#define DIPLOMAT_RUNTIME_C_H + +#include +#include +#include +#include + +// These come from `uchar.h`, which is not available on all platforms. +// Redefining them in C is no problem, however in >C++11 they are fundamental +// types, which don't like being redefined. +#if !(__cplusplus >= 201100) +// https://en.cppreference.com/w/c/string/multibyte/char16_t +typedef uint_least16_t char16_t; +// https://en.cppreference.com/w/c/string/multibyte/char32_t +typedef uint_least32_t char32_t; +#endif + +static_assert(sizeof(char) == sizeof(uint8_t), "your architecture's `char` is not 8 bits"); +static_assert(sizeof(char16_t) == sizeof(uint16_t), "your architecture's `char16_t` is not 16 bits"); +static_assert(sizeof(char32_t) == sizeof(uint32_t), "your architecture's `char32_t` is not 32 bits"); + +typedef struct DiplomatWrite { + void* context; + char* buf; + size_t len; + size_t cap; + bool grow_failed; + void (*flush)(struct DiplomatWrite*); + bool (*grow)(struct DiplomatWrite*, size_t); +} DiplomatWrite; + +bool diplomat_is_str(const char* buf, size_t len); + +#define MAKE_SLICES(name, c_ty) \ + typedef struct Diplomat##name##View { \ + const c_ty* data; \ + size_t len; \ + } Diplomat##name##View; \ + typedef struct Diplomat##name##ViewMut { \ + c_ty* data; \ + size_t len; \ + } Diplomat##name##ViewMut; \ + typedef struct Diplomat##name##Array { \ + const c_ty* data; \ + size_t len; \ + } Diplomat##name##Array; + +#define MAKE_SLICES_AND_OPTIONS(name, c_ty) \ + MAKE_SLICES(name, c_ty) \ + typedef struct Option##name {union { c_ty ok; }; bool is_ok; } Option##name; \ + typedef struct Option##name##View {union { Diplomat##name##View ok; }; bool is_ok; } Option##name##View; \ + typedef struct Option##name##ViewMut {union { Diplomat##name##ViewMut ok; }; bool is_ok; } Option##name##ViewMut; \ + typedef struct Option##name##Array {union { Diplomat##name##Array ok; }; bool is_ok; } Option##name##Array; \ + +MAKE_SLICES_AND_OPTIONS(I8, int8_t) +MAKE_SLICES_AND_OPTIONS(U8, uint8_t) +MAKE_SLICES_AND_OPTIONS(I16, int16_t) +MAKE_SLICES_AND_OPTIONS(U16, uint16_t) +MAKE_SLICES_AND_OPTIONS(I32, int32_t) +MAKE_SLICES_AND_OPTIONS(U32, uint32_t) +MAKE_SLICES_AND_OPTIONS(I64, int64_t) +MAKE_SLICES_AND_OPTIONS(U64, uint64_t) +MAKE_SLICES_AND_OPTIONS(Isize, intptr_t) +MAKE_SLICES_AND_OPTIONS(Usize, size_t) +MAKE_SLICES_AND_OPTIONS(F32, float) +MAKE_SLICES_AND_OPTIONS(F64, double) +MAKE_SLICES_AND_OPTIONS(Bool, bool) +MAKE_SLICES_AND_OPTIONS(Char, char32_t) +MAKE_SLICES_AND_OPTIONS(String, char) +MAKE_SLICES_AND_OPTIONS(String16, char16_t) +MAKE_SLICES_AND_OPTIONS(Strings, DiplomatStringView) +MAKE_SLICES_AND_OPTIONS(Strings16, DiplomatString16View) + +DiplomatWrite diplomat_simple_write(char* buf, size_t buf_size); + +DiplomatWrite* diplomat_buffer_write_create(size_t cap); +char* diplomat_buffer_write_get_bytes(DiplomatWrite* t); +size_t diplomat_buffer_write_len(DiplomatWrite* t); +void diplomat_buffer_write_destroy(DiplomatWrite* t); + +#endif diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/AnyCalendarKind.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/AnyCalendarKind.d.hpp new file mode 100644 index 00000000000000..d7d93fd3386c8d --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/AnyCalendarKind.d.hpp @@ -0,0 +1,89 @@ +#ifndef TEMPORAL_RS_AnyCalendarKind_D_HPP +#define TEMPORAL_RS_AnyCalendarKind_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +class AnyCalendarKind; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + enum AnyCalendarKind { + AnyCalendarKind_Buddhist = 0, + AnyCalendarKind_Chinese = 1, + AnyCalendarKind_Coptic = 2, + AnyCalendarKind_Dangi = 3, + AnyCalendarKind_Ethiopian = 4, + AnyCalendarKind_EthiopianAmeteAlem = 5, + AnyCalendarKind_Gregorian = 6, + AnyCalendarKind_Hebrew = 7, + AnyCalendarKind_Indian = 8, + AnyCalendarKind_HijriTabularTypeIIFriday = 9, + AnyCalendarKind_HijriSimulatedMecca = 10, + AnyCalendarKind_HijriTabularTypeIIThursday = 11, + AnyCalendarKind_HijriUmmAlQura = 12, + AnyCalendarKind_Iso = 13, + AnyCalendarKind_Japanese = 14, + AnyCalendarKind_JapaneseExtended = 15, + AnyCalendarKind_Persian = 16, + AnyCalendarKind_Roc = 17, + }; + + typedef struct AnyCalendarKind_option {union { AnyCalendarKind ok; }; bool is_ok; } AnyCalendarKind_option; +} // namespace capi +} // namespace + +namespace temporal_rs { +class AnyCalendarKind { +public: + enum Value { + Buddhist = 0, + Chinese = 1, + Coptic = 2, + Dangi = 3, + Ethiopian = 4, + EthiopianAmeteAlem = 5, + Gregorian = 6, + Hebrew = 7, + Indian = 8, + HijriTabularTypeIIFriday = 9, + HijriSimulatedMecca = 10, + HijriTabularTypeIIThursday = 11, + HijriUmmAlQura = 12, + Iso = 13, + Japanese = 14, + JapaneseExtended = 15, + Persian = 16, + Roc = 17, + }; + + AnyCalendarKind(): value(Value::Buddhist) {} + + // Implicit conversions between enum and ::Value + constexpr AnyCalendarKind(Value v) : value(v) {} + constexpr operator Value() const { return value; } + // Prevent usage as boolean value + explicit operator bool() const = delete; + + inline static std::optional get_for_str(std::string_view s); + + inline static std::optional parse_temporal_calendar_string(std::string_view s); + + inline temporal_rs::capi::AnyCalendarKind AsFFI() const; + inline static temporal_rs::AnyCalendarKind FromFFI(temporal_rs::capi::AnyCalendarKind c_enum); +private: + Value value; +}; + +} // namespace +#endif // TEMPORAL_RS_AnyCalendarKind_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/AnyCalendarKind.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/AnyCalendarKind.hpp new file mode 100644 index 00000000000000..810aae25a504f3 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/AnyCalendarKind.hpp @@ -0,0 +1,70 @@ +#ifndef TEMPORAL_RS_AnyCalendarKind_HPP +#define TEMPORAL_RS_AnyCalendarKind_HPP + +#include "AnyCalendarKind.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + typedef struct temporal_rs_AnyCalendarKind_get_for_str_result {union {temporal_rs::capi::AnyCalendarKind ok; }; bool is_ok;} temporal_rs_AnyCalendarKind_get_for_str_result; + temporal_rs_AnyCalendarKind_get_for_str_result temporal_rs_AnyCalendarKind_get_for_str(temporal_rs::diplomat::capi::DiplomatStringView s); + + typedef struct temporal_rs_AnyCalendarKind_parse_temporal_calendar_string_result {union {temporal_rs::capi::AnyCalendarKind ok; }; bool is_ok;} temporal_rs_AnyCalendarKind_parse_temporal_calendar_string_result; + temporal_rs_AnyCalendarKind_parse_temporal_calendar_string_result temporal_rs_AnyCalendarKind_parse_temporal_calendar_string(temporal_rs::diplomat::capi::DiplomatStringView s); + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::capi::AnyCalendarKind temporal_rs::AnyCalendarKind::AsFFI() const { + return static_cast(value); +} + +inline temporal_rs::AnyCalendarKind temporal_rs::AnyCalendarKind::FromFFI(temporal_rs::capi::AnyCalendarKind c_enum) { + switch (c_enum) { + case temporal_rs::capi::AnyCalendarKind_Buddhist: + case temporal_rs::capi::AnyCalendarKind_Chinese: + case temporal_rs::capi::AnyCalendarKind_Coptic: + case temporal_rs::capi::AnyCalendarKind_Dangi: + case temporal_rs::capi::AnyCalendarKind_Ethiopian: + case temporal_rs::capi::AnyCalendarKind_EthiopianAmeteAlem: + case temporal_rs::capi::AnyCalendarKind_Gregorian: + case temporal_rs::capi::AnyCalendarKind_Hebrew: + case temporal_rs::capi::AnyCalendarKind_Indian: + case temporal_rs::capi::AnyCalendarKind_HijriTabularTypeIIFriday: + case temporal_rs::capi::AnyCalendarKind_HijriSimulatedMecca: + case temporal_rs::capi::AnyCalendarKind_HijriTabularTypeIIThursday: + case temporal_rs::capi::AnyCalendarKind_HijriUmmAlQura: + case temporal_rs::capi::AnyCalendarKind_Iso: + case temporal_rs::capi::AnyCalendarKind_Japanese: + case temporal_rs::capi::AnyCalendarKind_JapaneseExtended: + case temporal_rs::capi::AnyCalendarKind_Persian: + case temporal_rs::capi::AnyCalendarKind_Roc: + return static_cast(c_enum); + default: + std::abort(); + } +} + +inline std::optional temporal_rs::AnyCalendarKind::get_for_str(std::string_view s) { + auto result = temporal_rs::capi::temporal_rs_AnyCalendarKind_get_for_str({s.data(), s.size()}); + return result.is_ok ? std::optional(temporal_rs::AnyCalendarKind::FromFFI(result.ok)) : std::nullopt; +} + +inline std::optional temporal_rs::AnyCalendarKind::parse_temporal_calendar_string(std::string_view s) { + auto result = temporal_rs::capi::temporal_rs_AnyCalendarKind_parse_temporal_calendar_string({s.data(), s.size()}); + return result.is_ok ? std::optional(temporal_rs::AnyCalendarKind::FromFFI(result.ok)) : std::nullopt; +} +#endif // TEMPORAL_RS_AnyCalendarKind_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ArithmeticOverflow.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ArithmeticOverflow.d.hpp new file mode 100644 index 00000000000000..0e912957885a68 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ArithmeticOverflow.d.hpp @@ -0,0 +1,49 @@ +#ifndef TEMPORAL_RS_ArithmeticOverflow_D_HPP +#define TEMPORAL_RS_ArithmeticOverflow_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + enum ArithmeticOverflow { + ArithmeticOverflow_Constrain = 0, + ArithmeticOverflow_Reject = 1, + }; + + typedef struct ArithmeticOverflow_option {union { ArithmeticOverflow ok; }; bool is_ok; } ArithmeticOverflow_option; +} // namespace capi +} // namespace + +namespace temporal_rs { +class ArithmeticOverflow { +public: + enum Value { + Constrain = 0, + Reject = 1, + }; + + ArithmeticOverflow(): value(Value::Constrain) {} + + // Implicit conversions between enum and ::Value + constexpr ArithmeticOverflow(Value v) : value(v) {} + constexpr operator Value() const { return value; } + // Prevent usage as boolean value + explicit operator bool() const = delete; + + inline temporal_rs::capi::ArithmeticOverflow AsFFI() const; + inline static temporal_rs::ArithmeticOverflow FromFFI(temporal_rs::capi::ArithmeticOverflow c_enum); +private: + Value value; +}; + +} // namespace +#endif // TEMPORAL_RS_ArithmeticOverflow_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ArithmeticOverflow.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ArithmeticOverflow.hpp new file mode 100644 index 00000000000000..10a1773866e934 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ArithmeticOverflow.hpp @@ -0,0 +1,38 @@ +#ifndef TEMPORAL_RS_ArithmeticOverflow_HPP +#define TEMPORAL_RS_ArithmeticOverflow_HPP + +#include "ArithmeticOverflow.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::capi::ArithmeticOverflow temporal_rs::ArithmeticOverflow::AsFFI() const { + return static_cast(value); +} + +inline temporal_rs::ArithmeticOverflow temporal_rs::ArithmeticOverflow::FromFFI(temporal_rs::capi::ArithmeticOverflow c_enum) { + switch (c_enum) { + case temporal_rs::capi::ArithmeticOverflow_Constrain: + case temporal_rs::capi::ArithmeticOverflow_Reject: + return static_cast(c_enum); + default: + std::abort(); + } +} +#endif // TEMPORAL_RS_ArithmeticOverflow_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Calendar.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Calendar.d.hpp new file mode 100644 index 00000000000000..fe042ea08e224f --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Calendar.d.hpp @@ -0,0 +1,64 @@ +#ifndef TEMPORAL_RS_Calendar_D_HPP +#define TEMPORAL_RS_Calendar_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +namespace capi { struct Calendar; } +class Calendar; +struct TemporalError; +class AnyCalendarKind; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct Calendar; +} // namespace capi +} // namespace + +namespace temporal_rs { +/** + * By and large one should not need to construct this type; it mostly exists + * to represent calendar data found on other Temporal types, obtained via `.calendar()`. + */ +class Calendar { +public: + + inline static std::unique_ptr try_new_constrain(temporal_rs::AnyCalendarKind kind); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf8(std::string_view s); + + inline bool is_iso() const; + + inline std::string_view identifier() const; + + /** + * Returns the kind of this calendar + */ + inline temporal_rs::AnyCalendarKind kind() const; + + inline const temporal_rs::capi::Calendar* AsFFI() const; + inline temporal_rs::capi::Calendar* AsFFI(); + inline static const temporal_rs::Calendar* FromFFI(const temporal_rs::capi::Calendar* ptr); + inline static temporal_rs::Calendar* FromFFI(temporal_rs::capi::Calendar* ptr); + inline static void operator delete(void* ptr); +private: + Calendar() = delete; + Calendar(const temporal_rs::Calendar&) = delete; + Calendar(temporal_rs::Calendar&&) noexcept = delete; + Calendar operator=(const temporal_rs::Calendar&) = delete; + Calendar operator=(temporal_rs::Calendar&&) noexcept = delete; + static void operator delete[](void*, size_t) = delete; +}; + +} // namespace +#endif // TEMPORAL_RS_Calendar_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Calendar.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Calendar.hpp new file mode 100644 index 00000000000000..06509ab1a3f078 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Calendar.hpp @@ -0,0 +1,86 @@ +#ifndef TEMPORAL_RS_Calendar_HPP +#define TEMPORAL_RS_Calendar_HPP + +#include "Calendar.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "AnyCalendarKind.hpp" +#include "TemporalError.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + temporal_rs::capi::Calendar* temporal_rs_Calendar_try_new_constrain(temporal_rs::capi::AnyCalendarKind kind); + + typedef struct temporal_rs_Calendar_from_utf8_result {union {temporal_rs::capi::Calendar* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Calendar_from_utf8_result; + temporal_rs_Calendar_from_utf8_result temporal_rs_Calendar_from_utf8(temporal_rs::diplomat::capi::DiplomatStringView s); + + bool temporal_rs_Calendar_is_iso(const temporal_rs::capi::Calendar* self); + + temporal_rs::diplomat::capi::DiplomatStringView temporal_rs_Calendar_identifier(const temporal_rs::capi::Calendar* self); + + temporal_rs::capi::AnyCalendarKind temporal_rs_Calendar_kind(const temporal_rs::capi::Calendar* self); + + void temporal_rs_Calendar_destroy(Calendar* self); + + } // extern "C" +} // namespace capi +} // namespace + +inline std::unique_ptr temporal_rs::Calendar::try_new_constrain(temporal_rs::AnyCalendarKind kind) { + auto result = temporal_rs::capi::temporal_rs_Calendar_try_new_constrain(kind.AsFFI()); + return std::unique_ptr(temporal_rs::Calendar::FromFFI(result)); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Calendar::from_utf8(std::string_view s) { + auto result = temporal_rs::capi::temporal_rs_Calendar_from_utf8({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Calendar::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline bool temporal_rs::Calendar::is_iso() const { + auto result = temporal_rs::capi::temporal_rs_Calendar_is_iso(this->AsFFI()); + return result; +} + +inline std::string_view temporal_rs::Calendar::identifier() const { + auto result = temporal_rs::capi::temporal_rs_Calendar_identifier(this->AsFFI()); + return std::string_view(result.data, result.len); +} + +inline temporal_rs::AnyCalendarKind temporal_rs::Calendar::kind() const { + auto result = temporal_rs::capi::temporal_rs_Calendar_kind(this->AsFFI()); + return temporal_rs::AnyCalendarKind::FromFFI(result); +} + +inline const temporal_rs::capi::Calendar* temporal_rs::Calendar::AsFFI() const { + return reinterpret_cast(this); +} + +inline temporal_rs::capi::Calendar* temporal_rs::Calendar::AsFFI() { + return reinterpret_cast(this); +} + +inline const temporal_rs::Calendar* temporal_rs::Calendar::FromFFI(const temporal_rs::capi::Calendar* ptr) { + return reinterpret_cast(ptr); +} + +inline temporal_rs::Calendar* temporal_rs::Calendar::FromFFI(temporal_rs::capi::Calendar* ptr) { + return reinterpret_cast(ptr); +} + +inline void temporal_rs::Calendar::operator delete(void* ptr) { + temporal_rs::capi::temporal_rs_Calendar_destroy(reinterpret_cast(ptr)); +} + + +#endif // TEMPORAL_RS_Calendar_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DateDuration.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DateDuration.d.hpp new file mode 100644 index 00000000000000..f677dcfe065563 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DateDuration.d.hpp @@ -0,0 +1,55 @@ +#ifndef TEMPORAL_RS_DateDuration_D_HPP +#define TEMPORAL_RS_DateDuration_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +namespace capi { struct DateDuration; } +class DateDuration; +struct TemporalError; +class Sign; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct DateDuration; +} // namespace capi +} // namespace + +namespace temporal_rs { +class DateDuration { +public: + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> try_new(int64_t years, int64_t months, int64_t weeks, int64_t days); + + inline std::unique_ptr abs() const; + + inline std::unique_ptr negated() const; + + inline temporal_rs::Sign sign() const; + + inline const temporal_rs::capi::DateDuration* AsFFI() const; + inline temporal_rs::capi::DateDuration* AsFFI(); + inline static const temporal_rs::DateDuration* FromFFI(const temporal_rs::capi::DateDuration* ptr); + inline static temporal_rs::DateDuration* FromFFI(temporal_rs::capi::DateDuration* ptr); + inline static void operator delete(void* ptr); +private: + DateDuration() = delete; + DateDuration(const temporal_rs::DateDuration&) = delete; + DateDuration(temporal_rs::DateDuration&&) noexcept = delete; + DateDuration operator=(const temporal_rs::DateDuration&) = delete; + DateDuration operator=(temporal_rs::DateDuration&&) noexcept = delete; + static void operator delete[](void*, size_t) = delete; +}; + +} // namespace +#endif // TEMPORAL_RS_DateDuration_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DateDuration.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DateDuration.hpp new file mode 100644 index 00000000000000..b41b4610e25779 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DateDuration.hpp @@ -0,0 +1,82 @@ +#ifndef TEMPORAL_RS_DateDuration_HPP +#define TEMPORAL_RS_DateDuration_HPP + +#include "DateDuration.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "Sign.hpp" +#include "TemporalError.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + typedef struct temporal_rs_DateDuration_try_new_result {union {temporal_rs::capi::DateDuration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_DateDuration_try_new_result; + temporal_rs_DateDuration_try_new_result temporal_rs_DateDuration_try_new(int64_t years, int64_t months, int64_t weeks, int64_t days); + + temporal_rs::capi::DateDuration* temporal_rs_DateDuration_abs(const temporal_rs::capi::DateDuration* self); + + temporal_rs::capi::DateDuration* temporal_rs_DateDuration_negated(const temporal_rs::capi::DateDuration* self); + + temporal_rs::capi::Sign temporal_rs_DateDuration_sign(const temporal_rs::capi::DateDuration* self); + + void temporal_rs_DateDuration_destroy(DateDuration* self); + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::DateDuration::try_new(int64_t years, int64_t months, int64_t weeks, int64_t days) { + auto result = temporal_rs::capi::temporal_rs_DateDuration_try_new(years, + months, + weeks, + days); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::DateDuration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline std::unique_ptr temporal_rs::DateDuration::abs() const { + auto result = temporal_rs::capi::temporal_rs_DateDuration_abs(this->AsFFI()); + return std::unique_ptr(temporal_rs::DateDuration::FromFFI(result)); +} + +inline std::unique_ptr temporal_rs::DateDuration::negated() const { + auto result = temporal_rs::capi::temporal_rs_DateDuration_negated(this->AsFFI()); + return std::unique_ptr(temporal_rs::DateDuration::FromFFI(result)); +} + +inline temporal_rs::Sign temporal_rs::DateDuration::sign() const { + auto result = temporal_rs::capi::temporal_rs_DateDuration_sign(this->AsFFI()); + return temporal_rs::Sign::FromFFI(result); +} + +inline const temporal_rs::capi::DateDuration* temporal_rs::DateDuration::AsFFI() const { + return reinterpret_cast(this); +} + +inline temporal_rs::capi::DateDuration* temporal_rs::DateDuration::AsFFI() { + return reinterpret_cast(this); +} + +inline const temporal_rs::DateDuration* temporal_rs::DateDuration::FromFFI(const temporal_rs::capi::DateDuration* ptr) { + return reinterpret_cast(ptr); +} + +inline temporal_rs::DateDuration* temporal_rs::DateDuration::FromFFI(temporal_rs::capi::DateDuration* ptr) { + return reinterpret_cast(ptr); +} + +inline void temporal_rs::DateDuration::operator delete(void* ptr) { + temporal_rs::capi::temporal_rs_DateDuration_destroy(reinterpret_cast(ptr)); +} + + +#endif // TEMPORAL_RS_DateDuration_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DifferenceSettings.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DifferenceSettings.d.hpp new file mode 100644 index 00000000000000..e87224fe4289ab --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DifferenceSettings.d.hpp @@ -0,0 +1,48 @@ +#ifndef TEMPORAL_RS_DifferenceSettings_D_HPP +#define TEMPORAL_RS_DifferenceSettings_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "RoundingMode.d.hpp" +#include "Unit.d.hpp" +#include "diplomat_runtime.hpp" +namespace temporal_rs { +class RoundingMode; +class Unit; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct DifferenceSettings { + temporal_rs::capi::Unit_option largest_unit; + temporal_rs::capi::Unit_option smallest_unit; + temporal_rs::capi::RoundingMode_option rounding_mode; + temporal_rs::diplomat::capi::OptionU32 increment; + }; + + typedef struct DifferenceSettings_option {union { DifferenceSettings ok; }; bool is_ok; } DifferenceSettings_option; +} // namespace capi +} // namespace + + +namespace temporal_rs { +struct DifferenceSettings { + std::optional largest_unit; + std::optional smallest_unit; + std::optional rounding_mode; + std::optional increment; + + inline temporal_rs::capi::DifferenceSettings AsFFI() const; + inline static temporal_rs::DifferenceSettings FromFFI(temporal_rs::capi::DifferenceSettings c_struct); +}; + +} // namespace +#endif // TEMPORAL_RS_DifferenceSettings_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DifferenceSettings.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DifferenceSettings.hpp new file mode 100644 index 00000000000000..d00ab0e5b7590c --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DifferenceSettings.hpp @@ -0,0 +1,47 @@ +#ifndef TEMPORAL_RS_DifferenceSettings_HPP +#define TEMPORAL_RS_DifferenceSettings_HPP + +#include "DifferenceSettings.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "RoundingMode.hpp" +#include "Unit.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + + +inline temporal_rs::capi::DifferenceSettings temporal_rs::DifferenceSettings::AsFFI() const { + return temporal_rs::capi::DifferenceSettings { + /* .largest_unit = */ largest_unit.has_value() ? (temporal_rs::capi::Unit_option{ { largest_unit.value().AsFFI() }, true }) : (temporal_rs::capi::Unit_option{ {}, false }), + /* .smallest_unit = */ smallest_unit.has_value() ? (temporal_rs::capi::Unit_option{ { smallest_unit.value().AsFFI() }, true }) : (temporal_rs::capi::Unit_option{ {}, false }), + /* .rounding_mode = */ rounding_mode.has_value() ? (temporal_rs::capi::RoundingMode_option{ { rounding_mode.value().AsFFI() }, true }) : (temporal_rs::capi::RoundingMode_option{ {}, false }), + /* .increment = */ increment.has_value() ? (temporal_rs::diplomat::capi::OptionU32{ { increment.value() }, true }) : (temporal_rs::diplomat::capi::OptionU32{ {}, false }), + }; +} + +inline temporal_rs::DifferenceSettings temporal_rs::DifferenceSettings::FromFFI(temporal_rs::capi::DifferenceSettings c_struct) { + return temporal_rs::DifferenceSettings { + /* .largest_unit = */ c_struct.largest_unit.is_ok ? std::optional(temporal_rs::Unit::FromFFI(c_struct.largest_unit.ok)) : std::nullopt, + /* .smallest_unit = */ c_struct.smallest_unit.is_ok ? std::optional(temporal_rs::Unit::FromFFI(c_struct.smallest_unit.ok)) : std::nullopt, + /* .rounding_mode = */ c_struct.rounding_mode.is_ok ? std::optional(temporal_rs::RoundingMode::FromFFI(c_struct.rounding_mode.ok)) : std::nullopt, + /* .increment = */ c_struct.increment.is_ok ? std::optional(c_struct.increment.ok) : std::nullopt, + }; +} + + +#endif // TEMPORAL_RS_DifferenceSettings_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Disambiguation.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Disambiguation.d.hpp new file mode 100644 index 00000000000000..648cdc6e67bd81 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Disambiguation.d.hpp @@ -0,0 +1,53 @@ +#ifndef TEMPORAL_RS_Disambiguation_D_HPP +#define TEMPORAL_RS_Disambiguation_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + enum Disambiguation { + Disambiguation_Compatible = 0, + Disambiguation_Earlier = 1, + Disambiguation_Later = 2, + Disambiguation_Reject = 3, + }; + + typedef struct Disambiguation_option {union { Disambiguation ok; }; bool is_ok; } Disambiguation_option; +} // namespace capi +} // namespace + +namespace temporal_rs { +class Disambiguation { +public: + enum Value { + Compatible = 0, + Earlier = 1, + Later = 2, + Reject = 3, + }; + + Disambiguation(): value(Value::Compatible) {} + + // Implicit conversions between enum and ::Value + constexpr Disambiguation(Value v) : value(v) {} + constexpr operator Value() const { return value; } + // Prevent usage as boolean value + explicit operator bool() const = delete; + + inline temporal_rs::capi::Disambiguation AsFFI() const; + inline static temporal_rs::Disambiguation FromFFI(temporal_rs::capi::Disambiguation c_enum); +private: + Value value; +}; + +} // namespace +#endif // TEMPORAL_RS_Disambiguation_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Disambiguation.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Disambiguation.hpp new file mode 100644 index 00000000000000..15476c9ed7512d --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Disambiguation.hpp @@ -0,0 +1,40 @@ +#ifndef TEMPORAL_RS_Disambiguation_HPP +#define TEMPORAL_RS_Disambiguation_HPP + +#include "Disambiguation.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::capi::Disambiguation temporal_rs::Disambiguation::AsFFI() const { + return static_cast(value); +} + +inline temporal_rs::Disambiguation temporal_rs::Disambiguation::FromFFI(temporal_rs::capi::Disambiguation c_enum) { + switch (c_enum) { + case temporal_rs::capi::Disambiguation_Compatible: + case temporal_rs::capi::Disambiguation_Earlier: + case temporal_rs::capi::Disambiguation_Later: + case temporal_rs::capi::Disambiguation_Reject: + return static_cast(c_enum); + default: + std::abort(); + } +} +#endif // TEMPORAL_RS_Disambiguation_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayCalendar.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayCalendar.d.hpp new file mode 100644 index 00000000000000..272ccb3e6afc75 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayCalendar.d.hpp @@ -0,0 +1,53 @@ +#ifndef TEMPORAL_RS_DisplayCalendar_D_HPP +#define TEMPORAL_RS_DisplayCalendar_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + enum DisplayCalendar { + DisplayCalendar_Auto = 0, + DisplayCalendar_Always = 1, + DisplayCalendar_Never = 2, + DisplayCalendar_Critical = 3, + }; + + typedef struct DisplayCalendar_option {union { DisplayCalendar ok; }; bool is_ok; } DisplayCalendar_option; +} // namespace capi +} // namespace + +namespace temporal_rs { +class DisplayCalendar { +public: + enum Value { + Auto = 0, + Always = 1, + Never = 2, + Critical = 3, + }; + + DisplayCalendar(): value(Value::Auto) {} + + // Implicit conversions between enum and ::Value + constexpr DisplayCalendar(Value v) : value(v) {} + constexpr operator Value() const { return value; } + // Prevent usage as boolean value + explicit operator bool() const = delete; + + inline temporal_rs::capi::DisplayCalendar AsFFI() const; + inline static temporal_rs::DisplayCalendar FromFFI(temporal_rs::capi::DisplayCalendar c_enum); +private: + Value value; +}; + +} // namespace +#endif // TEMPORAL_RS_DisplayCalendar_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayCalendar.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayCalendar.hpp new file mode 100644 index 00000000000000..4225d477d4510a --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayCalendar.hpp @@ -0,0 +1,40 @@ +#ifndef TEMPORAL_RS_DisplayCalendar_HPP +#define TEMPORAL_RS_DisplayCalendar_HPP + +#include "DisplayCalendar.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::capi::DisplayCalendar temporal_rs::DisplayCalendar::AsFFI() const { + return static_cast(value); +} + +inline temporal_rs::DisplayCalendar temporal_rs::DisplayCalendar::FromFFI(temporal_rs::capi::DisplayCalendar c_enum) { + switch (c_enum) { + case temporal_rs::capi::DisplayCalendar_Auto: + case temporal_rs::capi::DisplayCalendar_Always: + case temporal_rs::capi::DisplayCalendar_Never: + case temporal_rs::capi::DisplayCalendar_Critical: + return static_cast(c_enum); + default: + std::abort(); + } +} +#endif // TEMPORAL_RS_DisplayCalendar_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayOffset.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayOffset.d.hpp new file mode 100644 index 00000000000000..da19e959cd4f0f --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayOffset.d.hpp @@ -0,0 +1,49 @@ +#ifndef TEMPORAL_RS_DisplayOffset_D_HPP +#define TEMPORAL_RS_DisplayOffset_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + enum DisplayOffset { + DisplayOffset_Auto = 0, + DisplayOffset_Never = 1, + }; + + typedef struct DisplayOffset_option {union { DisplayOffset ok; }; bool is_ok; } DisplayOffset_option; +} // namespace capi +} // namespace + +namespace temporal_rs { +class DisplayOffset { +public: + enum Value { + Auto = 0, + Never = 1, + }; + + DisplayOffset(): value(Value::Auto) {} + + // Implicit conversions between enum and ::Value + constexpr DisplayOffset(Value v) : value(v) {} + constexpr operator Value() const { return value; } + // Prevent usage as boolean value + explicit operator bool() const = delete; + + inline temporal_rs::capi::DisplayOffset AsFFI() const; + inline static temporal_rs::DisplayOffset FromFFI(temporal_rs::capi::DisplayOffset c_enum); +private: + Value value; +}; + +} // namespace +#endif // TEMPORAL_RS_DisplayOffset_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayOffset.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayOffset.hpp new file mode 100644 index 00000000000000..ab63e3fe1d7d27 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayOffset.hpp @@ -0,0 +1,38 @@ +#ifndef TEMPORAL_RS_DisplayOffset_HPP +#define TEMPORAL_RS_DisplayOffset_HPP + +#include "DisplayOffset.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::capi::DisplayOffset temporal_rs::DisplayOffset::AsFFI() const { + return static_cast(value); +} + +inline temporal_rs::DisplayOffset temporal_rs::DisplayOffset::FromFFI(temporal_rs::capi::DisplayOffset c_enum) { + switch (c_enum) { + case temporal_rs::capi::DisplayOffset_Auto: + case temporal_rs::capi::DisplayOffset_Never: + return static_cast(c_enum); + default: + std::abort(); + } +} +#endif // TEMPORAL_RS_DisplayOffset_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayTimeZone.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayTimeZone.d.hpp new file mode 100644 index 00000000000000..3e2ec215506047 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayTimeZone.d.hpp @@ -0,0 +1,51 @@ +#ifndef TEMPORAL_RS_DisplayTimeZone_D_HPP +#define TEMPORAL_RS_DisplayTimeZone_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + enum DisplayTimeZone { + DisplayTimeZone_Auto = 0, + DisplayTimeZone_Never = 1, + DisplayTimeZone_Critical = 2, + }; + + typedef struct DisplayTimeZone_option {union { DisplayTimeZone ok; }; bool is_ok; } DisplayTimeZone_option; +} // namespace capi +} // namespace + +namespace temporal_rs { +class DisplayTimeZone { +public: + enum Value { + Auto = 0, + Never = 1, + Critical = 2, + }; + + DisplayTimeZone(): value(Value::Auto) {} + + // Implicit conversions between enum and ::Value + constexpr DisplayTimeZone(Value v) : value(v) {} + constexpr operator Value() const { return value; } + // Prevent usage as boolean value + explicit operator bool() const = delete; + + inline temporal_rs::capi::DisplayTimeZone AsFFI() const; + inline static temporal_rs::DisplayTimeZone FromFFI(temporal_rs::capi::DisplayTimeZone c_enum); +private: + Value value; +}; + +} // namespace +#endif // TEMPORAL_RS_DisplayTimeZone_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayTimeZone.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayTimeZone.hpp new file mode 100644 index 00000000000000..3341bd73be3c61 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/DisplayTimeZone.hpp @@ -0,0 +1,39 @@ +#ifndef TEMPORAL_RS_DisplayTimeZone_HPP +#define TEMPORAL_RS_DisplayTimeZone_HPP + +#include "DisplayTimeZone.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::capi::DisplayTimeZone temporal_rs::DisplayTimeZone::AsFFI() const { + return static_cast(value); +} + +inline temporal_rs::DisplayTimeZone temporal_rs::DisplayTimeZone::FromFFI(temporal_rs::capi::DisplayTimeZone c_enum) { + switch (c_enum) { + case temporal_rs::capi::DisplayTimeZone_Auto: + case temporal_rs::capi::DisplayTimeZone_Never: + case temporal_rs::capi::DisplayTimeZone_Critical: + return static_cast(c_enum); + default: + std::abort(); + } +} +#endif // TEMPORAL_RS_DisplayTimeZone_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Duration.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Duration.d.hpp new file mode 100644 index 00000000000000..8357d229f8e36e --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Duration.d.hpp @@ -0,0 +1,119 @@ +#ifndef TEMPORAL_RS_Duration_D_HPP +#define TEMPORAL_RS_Duration_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +namespace capi { struct Duration; } +class Duration; +namespace capi { struct Provider; } +class Provider; +struct PartialDuration; +struct RelativeTo; +struct RoundingOptions; +struct TemporalError; +struct ToStringRoundingOptions; +class Sign; +class Unit; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct Duration; +} // namespace capi +} // namespace + +namespace temporal_rs { +class Duration { +public: + + /** + * Temporary API until v8 can move off of it + */ + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> create(int64_t years, int64_t months, int64_t weeks, int64_t days, int64_t hours, int64_t minutes, int64_t seconds, int64_t milliseconds, double microseconds, double nanoseconds); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> try_new(int64_t years, int64_t months, int64_t weeks, int64_t days, int64_t hours, int64_t minutes, int64_t seconds, int64_t milliseconds, double microseconds, double nanoseconds); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_partial_duration(temporal_rs::PartialDuration partial); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf8(std::string_view s); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf16(std::u16string_view s); + + inline bool is_time_within_range() const; + + inline int64_t years() const; + + inline int64_t months() const; + + inline int64_t weeks() const; + + inline int64_t days() const; + + inline int64_t hours() const; + + inline int64_t minutes() const; + + inline int64_t seconds() const; + + inline int64_t milliseconds() const; + + inline double microseconds() const; + + inline double nanoseconds() const; + + inline temporal_rs::Sign sign() const; + + inline bool is_zero() const; + + inline std::unique_ptr abs() const; + + inline std::unique_ptr negated() const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> add(const temporal_rs::Duration& other) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> subtract(const temporal_rs::Duration& other) const; + + inline temporal_rs::diplomat::result to_string(temporal_rs::ToStringRoundingOptions options) const; + template + inline temporal_rs::diplomat::result to_string_write(temporal_rs::ToStringRoundingOptions options, W& writeable_output) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> round(temporal_rs::RoundingOptions options, temporal_rs::RelativeTo relative_to) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> round_with_provider(temporal_rs::RoundingOptions options, temporal_rs::RelativeTo relative_to, const temporal_rs::Provider& p) const; + + inline temporal_rs::diplomat::result compare(const temporal_rs::Duration& other, temporal_rs::RelativeTo relative_to) const; + + inline temporal_rs::diplomat::result compare_with_provider(const temporal_rs::Duration& other, temporal_rs::RelativeTo relative_to, const temporal_rs::Provider& p) const; + + inline temporal_rs::diplomat::result total(temporal_rs::Unit unit, temporal_rs::RelativeTo relative_to) const; + + inline temporal_rs::diplomat::result total_with_provider(temporal_rs::Unit unit, temporal_rs::RelativeTo relative_to, const temporal_rs::Provider& p) const; + + inline std::unique_ptr clone() const; + + inline const temporal_rs::capi::Duration* AsFFI() const; + inline temporal_rs::capi::Duration* AsFFI(); + inline static const temporal_rs::Duration* FromFFI(const temporal_rs::capi::Duration* ptr); + inline static temporal_rs::Duration* FromFFI(temporal_rs::capi::Duration* ptr); + inline static void operator delete(void* ptr); +private: + Duration() = delete; + Duration(const temporal_rs::Duration&) = delete; + Duration(temporal_rs::Duration&&) noexcept = delete; + Duration operator=(const temporal_rs::Duration&) = delete; + Duration operator=(temporal_rs::Duration&&) noexcept = delete; + static void operator delete[](void*, size_t) = delete; +}; + +} // namespace +#endif // TEMPORAL_RS_Duration_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Duration.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Duration.hpp new file mode 100644 index 00000000000000..af3f0cd449d42d --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Duration.hpp @@ -0,0 +1,327 @@ +#ifndef TEMPORAL_RS_Duration_HPP +#define TEMPORAL_RS_Duration_HPP + +#include "Duration.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "PartialDuration.hpp" +#include "Provider.hpp" +#include "RelativeTo.hpp" +#include "RoundingOptions.hpp" +#include "Sign.hpp" +#include "TemporalError.hpp" +#include "ToStringRoundingOptions.hpp" +#include "Unit.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + typedef struct temporal_rs_Duration_create_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Duration_create_result; + temporal_rs_Duration_create_result temporal_rs_Duration_create(int64_t years, int64_t months, int64_t weeks, int64_t days, int64_t hours, int64_t minutes, int64_t seconds, int64_t milliseconds, double microseconds, double nanoseconds); + + typedef struct temporal_rs_Duration_try_new_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Duration_try_new_result; + temporal_rs_Duration_try_new_result temporal_rs_Duration_try_new(int64_t years, int64_t months, int64_t weeks, int64_t days, int64_t hours, int64_t minutes, int64_t seconds, int64_t milliseconds, double microseconds, double nanoseconds); + + typedef struct temporal_rs_Duration_from_partial_duration_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Duration_from_partial_duration_result; + temporal_rs_Duration_from_partial_duration_result temporal_rs_Duration_from_partial_duration(temporal_rs::capi::PartialDuration partial); + + typedef struct temporal_rs_Duration_from_utf8_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Duration_from_utf8_result; + temporal_rs_Duration_from_utf8_result temporal_rs_Duration_from_utf8(temporal_rs::diplomat::capi::DiplomatStringView s); + + typedef struct temporal_rs_Duration_from_utf16_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Duration_from_utf16_result; + temporal_rs_Duration_from_utf16_result temporal_rs_Duration_from_utf16(temporal_rs::diplomat::capi::DiplomatString16View s); + + bool temporal_rs_Duration_is_time_within_range(const temporal_rs::capi::Duration* self); + + int64_t temporal_rs_Duration_years(const temporal_rs::capi::Duration* self); + + int64_t temporal_rs_Duration_months(const temporal_rs::capi::Duration* self); + + int64_t temporal_rs_Duration_weeks(const temporal_rs::capi::Duration* self); + + int64_t temporal_rs_Duration_days(const temporal_rs::capi::Duration* self); + + int64_t temporal_rs_Duration_hours(const temporal_rs::capi::Duration* self); + + int64_t temporal_rs_Duration_minutes(const temporal_rs::capi::Duration* self); + + int64_t temporal_rs_Duration_seconds(const temporal_rs::capi::Duration* self); + + int64_t temporal_rs_Duration_milliseconds(const temporal_rs::capi::Duration* self); + + double temporal_rs_Duration_microseconds(const temporal_rs::capi::Duration* self); + + double temporal_rs_Duration_nanoseconds(const temporal_rs::capi::Duration* self); + + temporal_rs::capi::Sign temporal_rs_Duration_sign(const temporal_rs::capi::Duration* self); + + bool temporal_rs_Duration_is_zero(const temporal_rs::capi::Duration* self); + + temporal_rs::capi::Duration* temporal_rs_Duration_abs(const temporal_rs::capi::Duration* self); + + temporal_rs::capi::Duration* temporal_rs_Duration_negated(const temporal_rs::capi::Duration* self); + + typedef struct temporal_rs_Duration_add_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Duration_add_result; + temporal_rs_Duration_add_result temporal_rs_Duration_add(const temporal_rs::capi::Duration* self, const temporal_rs::capi::Duration* other); + + typedef struct temporal_rs_Duration_subtract_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Duration_subtract_result; + temporal_rs_Duration_subtract_result temporal_rs_Duration_subtract(const temporal_rs::capi::Duration* self, const temporal_rs::capi::Duration* other); + + typedef struct temporal_rs_Duration_to_string_result {union { temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Duration_to_string_result; + temporal_rs_Duration_to_string_result temporal_rs_Duration_to_string(const temporal_rs::capi::Duration* self, temporal_rs::capi::ToStringRoundingOptions options, temporal_rs::diplomat::capi::DiplomatWrite* write); + + typedef struct temporal_rs_Duration_round_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Duration_round_result; + temporal_rs_Duration_round_result temporal_rs_Duration_round(const temporal_rs::capi::Duration* self, temporal_rs::capi::RoundingOptions options, temporal_rs::capi::RelativeTo relative_to); + + typedef struct temporal_rs_Duration_round_with_provider_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Duration_round_with_provider_result; + temporal_rs_Duration_round_with_provider_result temporal_rs_Duration_round_with_provider(const temporal_rs::capi::Duration* self, temporal_rs::capi::RoundingOptions options, temporal_rs::capi::RelativeTo relative_to, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_Duration_compare_result {union {int8_t ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Duration_compare_result; + temporal_rs_Duration_compare_result temporal_rs_Duration_compare(const temporal_rs::capi::Duration* self, const temporal_rs::capi::Duration* other, temporal_rs::capi::RelativeTo relative_to); + + typedef struct temporal_rs_Duration_compare_with_provider_result {union {int8_t ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Duration_compare_with_provider_result; + temporal_rs_Duration_compare_with_provider_result temporal_rs_Duration_compare_with_provider(const temporal_rs::capi::Duration* self, const temporal_rs::capi::Duration* other, temporal_rs::capi::RelativeTo relative_to, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_Duration_total_result {union {double ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Duration_total_result; + temporal_rs_Duration_total_result temporal_rs_Duration_total(const temporal_rs::capi::Duration* self, temporal_rs::capi::Unit unit, temporal_rs::capi::RelativeTo relative_to); + + typedef struct temporal_rs_Duration_total_with_provider_result {union {double ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Duration_total_with_provider_result; + temporal_rs_Duration_total_with_provider_result temporal_rs_Duration_total_with_provider(const temporal_rs::capi::Duration* self, temporal_rs::capi::Unit unit, temporal_rs::capi::RelativeTo relative_to, const temporal_rs::capi::Provider* p); + + temporal_rs::capi::Duration* temporal_rs_Duration_clone(const temporal_rs::capi::Duration* self); + + void temporal_rs_Duration_destroy(Duration* self); + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Duration::create(int64_t years, int64_t months, int64_t weeks, int64_t days, int64_t hours, int64_t minutes, int64_t seconds, int64_t milliseconds, double microseconds, double nanoseconds) { + auto result = temporal_rs::capi::temporal_rs_Duration_create(years, + months, + weeks, + days, + hours, + minutes, + seconds, + milliseconds, + microseconds, + nanoseconds); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Duration::try_new(int64_t years, int64_t months, int64_t weeks, int64_t days, int64_t hours, int64_t minutes, int64_t seconds, int64_t milliseconds, double microseconds, double nanoseconds) { + auto result = temporal_rs::capi::temporal_rs_Duration_try_new(years, + months, + weeks, + days, + hours, + minutes, + seconds, + milliseconds, + microseconds, + nanoseconds); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Duration::from_partial_duration(temporal_rs::PartialDuration partial) { + auto result = temporal_rs::capi::temporal_rs_Duration_from_partial_duration(partial.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Duration::from_utf8(std::string_view s) { + auto result = temporal_rs::capi::temporal_rs_Duration_from_utf8({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Duration::from_utf16(std::u16string_view s) { + auto result = temporal_rs::capi::temporal_rs_Duration_from_utf16({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline bool temporal_rs::Duration::is_time_within_range() const { + auto result = temporal_rs::capi::temporal_rs_Duration_is_time_within_range(this->AsFFI()); + return result; +} + +inline int64_t temporal_rs::Duration::years() const { + auto result = temporal_rs::capi::temporal_rs_Duration_years(this->AsFFI()); + return result; +} + +inline int64_t temporal_rs::Duration::months() const { + auto result = temporal_rs::capi::temporal_rs_Duration_months(this->AsFFI()); + return result; +} + +inline int64_t temporal_rs::Duration::weeks() const { + auto result = temporal_rs::capi::temporal_rs_Duration_weeks(this->AsFFI()); + return result; +} + +inline int64_t temporal_rs::Duration::days() const { + auto result = temporal_rs::capi::temporal_rs_Duration_days(this->AsFFI()); + return result; +} + +inline int64_t temporal_rs::Duration::hours() const { + auto result = temporal_rs::capi::temporal_rs_Duration_hours(this->AsFFI()); + return result; +} + +inline int64_t temporal_rs::Duration::minutes() const { + auto result = temporal_rs::capi::temporal_rs_Duration_minutes(this->AsFFI()); + return result; +} + +inline int64_t temporal_rs::Duration::seconds() const { + auto result = temporal_rs::capi::temporal_rs_Duration_seconds(this->AsFFI()); + return result; +} + +inline int64_t temporal_rs::Duration::milliseconds() const { + auto result = temporal_rs::capi::temporal_rs_Duration_milliseconds(this->AsFFI()); + return result; +} + +inline double temporal_rs::Duration::microseconds() const { + auto result = temporal_rs::capi::temporal_rs_Duration_microseconds(this->AsFFI()); + return result; +} + +inline double temporal_rs::Duration::nanoseconds() const { + auto result = temporal_rs::capi::temporal_rs_Duration_nanoseconds(this->AsFFI()); + return result; +} + +inline temporal_rs::Sign temporal_rs::Duration::sign() const { + auto result = temporal_rs::capi::temporal_rs_Duration_sign(this->AsFFI()); + return temporal_rs::Sign::FromFFI(result); +} + +inline bool temporal_rs::Duration::is_zero() const { + auto result = temporal_rs::capi::temporal_rs_Duration_is_zero(this->AsFFI()); + return result; +} + +inline std::unique_ptr temporal_rs::Duration::abs() const { + auto result = temporal_rs::capi::temporal_rs_Duration_abs(this->AsFFI()); + return std::unique_ptr(temporal_rs::Duration::FromFFI(result)); +} + +inline std::unique_ptr temporal_rs::Duration::negated() const { + auto result = temporal_rs::capi::temporal_rs_Duration_negated(this->AsFFI()); + return std::unique_ptr(temporal_rs::Duration::FromFFI(result)); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Duration::add(const temporal_rs::Duration& other) const { + auto result = temporal_rs::capi::temporal_rs_Duration_add(this->AsFFI(), + other.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Duration::subtract(const temporal_rs::Duration& other) const { + auto result = temporal_rs::capi::temporal_rs_Duration_subtract(this->AsFFI(), + other.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::Duration::to_string(temporal_rs::ToStringRoundingOptions options) const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + auto result = temporal_rs::capi::temporal_rs_Duration_to_string(this->AsFFI(), + options.AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(std::move(output))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} +template +inline temporal_rs::diplomat::result temporal_rs::Duration::to_string_write(temporal_rs::ToStringRoundingOptions options, W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + auto result = temporal_rs::capi::temporal_rs_Duration_to_string(this->AsFFI(), + options.AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok()) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Duration::round(temporal_rs::RoundingOptions options, temporal_rs::RelativeTo relative_to) const { + auto result = temporal_rs::capi::temporal_rs_Duration_round(this->AsFFI(), + options.AsFFI(), + relative_to.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Duration::round_with_provider(temporal_rs::RoundingOptions options, temporal_rs::RelativeTo relative_to, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_Duration_round_with_provider(this->AsFFI(), + options.AsFFI(), + relative_to.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::Duration::compare(const temporal_rs::Duration& other, temporal_rs::RelativeTo relative_to) const { + auto result = temporal_rs::capi::temporal_rs_Duration_compare(this->AsFFI(), + other.AsFFI(), + relative_to.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(result.ok)) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::Duration::compare_with_provider(const temporal_rs::Duration& other, temporal_rs::RelativeTo relative_to, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_Duration_compare_with_provider(this->AsFFI(), + other.AsFFI(), + relative_to.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(result.ok)) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::Duration::total(temporal_rs::Unit unit, temporal_rs::RelativeTo relative_to) const { + auto result = temporal_rs::capi::temporal_rs_Duration_total(this->AsFFI(), + unit.AsFFI(), + relative_to.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(result.ok)) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::Duration::total_with_provider(temporal_rs::Unit unit, temporal_rs::RelativeTo relative_to, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_Duration_total_with_provider(this->AsFFI(), + unit.AsFFI(), + relative_to.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(result.ok)) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline std::unique_ptr temporal_rs::Duration::clone() const { + auto result = temporal_rs::capi::temporal_rs_Duration_clone(this->AsFFI()); + return std::unique_ptr(temporal_rs::Duration::FromFFI(result)); +} + +inline const temporal_rs::capi::Duration* temporal_rs::Duration::AsFFI() const { + return reinterpret_cast(this); +} + +inline temporal_rs::capi::Duration* temporal_rs::Duration::AsFFI() { + return reinterpret_cast(this); +} + +inline const temporal_rs::Duration* temporal_rs::Duration::FromFFI(const temporal_rs::capi::Duration* ptr) { + return reinterpret_cast(ptr); +} + +inline temporal_rs::Duration* temporal_rs::Duration::FromFFI(temporal_rs::capi::Duration* ptr) { + return reinterpret_cast(ptr); +} + +inline void temporal_rs::Duration::operator delete(void* ptr) { + temporal_rs::capi::temporal_rs_Duration_destroy(reinterpret_cast(ptr)); +} + + +#endif // TEMPORAL_RS_Duration_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ErrorKind.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ErrorKind.d.hpp new file mode 100644 index 00000000000000..f6506bdec1cae8 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ErrorKind.d.hpp @@ -0,0 +1,55 @@ +#ifndef TEMPORAL_RS_ErrorKind_D_HPP +#define TEMPORAL_RS_ErrorKind_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + enum ErrorKind { + ErrorKind_Generic = 0, + ErrorKind_Type = 1, + ErrorKind_Range = 2, + ErrorKind_Syntax = 3, + ErrorKind_Assert = 4, + }; + + typedef struct ErrorKind_option {union { ErrorKind ok; }; bool is_ok; } ErrorKind_option; +} // namespace capi +} // namespace + +namespace temporal_rs { +class ErrorKind { +public: + enum Value { + Generic = 0, + Type = 1, + Range = 2, + Syntax = 3, + Assert = 4, + }; + + ErrorKind(): value(Value::Generic) {} + + // Implicit conversions between enum and ::Value + constexpr ErrorKind(Value v) : value(v) {} + constexpr operator Value() const { return value; } + // Prevent usage as boolean value + explicit operator bool() const = delete; + + inline temporal_rs::capi::ErrorKind AsFFI() const; + inline static temporal_rs::ErrorKind FromFFI(temporal_rs::capi::ErrorKind c_enum); +private: + Value value; +}; + +} // namespace +#endif // TEMPORAL_RS_ErrorKind_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ErrorKind.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ErrorKind.hpp new file mode 100644 index 00000000000000..bb6ff87a377f78 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ErrorKind.hpp @@ -0,0 +1,41 @@ +#ifndef TEMPORAL_RS_ErrorKind_HPP +#define TEMPORAL_RS_ErrorKind_HPP + +#include "ErrorKind.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::capi::ErrorKind temporal_rs::ErrorKind::AsFFI() const { + return static_cast(value); +} + +inline temporal_rs::ErrorKind temporal_rs::ErrorKind::FromFFI(temporal_rs::capi::ErrorKind c_enum) { + switch (c_enum) { + case temporal_rs::capi::ErrorKind_Generic: + case temporal_rs::capi::ErrorKind_Type: + case temporal_rs::capi::ErrorKind_Range: + case temporal_rs::capi::ErrorKind_Syntax: + case temporal_rs::capi::ErrorKind_Assert: + return static_cast(c_enum); + default: + std::abort(); + } +} +#endif // TEMPORAL_RS_ErrorKind_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/I128Nanoseconds.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/I128Nanoseconds.d.hpp new file mode 100644 index 00000000000000..21119b41494454 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/I128Nanoseconds.d.hpp @@ -0,0 +1,47 @@ +#ifndef TEMPORAL_RS_I128Nanoseconds_D_HPP +#define TEMPORAL_RS_I128Nanoseconds_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + struct I128Nanoseconds { + uint64_t high; + uint64_t low; + }; + + typedef struct I128Nanoseconds_option {union { I128Nanoseconds ok; }; bool is_ok; } I128Nanoseconds_option; +} // namespace capi +} // namespace + + +namespace temporal_rs { +/** + * For portability, we use two u64s instead of an i128. + * The high bit of the u64 is the sign. + * This cannot represent i128::MIN, and has a -0, but those are largely + * irrelevant for this purpose. + * + * This could potentially instead be a bit-by-bit split, or something else + */ +struct I128Nanoseconds { + uint64_t high; + uint64_t low; + + inline bool is_valid() const; + + inline temporal_rs::capi::I128Nanoseconds AsFFI() const; + inline static temporal_rs::I128Nanoseconds FromFFI(temporal_rs::capi::I128Nanoseconds c_struct); +}; + +} // namespace +#endif // TEMPORAL_RS_I128Nanoseconds_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/I128Nanoseconds.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/I128Nanoseconds.hpp new file mode 100644 index 00000000000000..706d643cc55718 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/I128Nanoseconds.hpp @@ -0,0 +1,48 @@ +#ifndef TEMPORAL_RS_I128Nanoseconds_HPP +#define TEMPORAL_RS_I128Nanoseconds_HPP + +#include "I128Nanoseconds.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + bool temporal_rs_I128Nanoseconds_is_valid(temporal_rs::capi::I128Nanoseconds self); + + } // extern "C" +} // namespace capi +} // namespace + +inline bool temporal_rs::I128Nanoseconds::is_valid() const { + auto result = temporal_rs::capi::temporal_rs_I128Nanoseconds_is_valid(this->AsFFI()); + return result; +} + + +inline temporal_rs::capi::I128Nanoseconds temporal_rs::I128Nanoseconds::AsFFI() const { + return temporal_rs::capi::I128Nanoseconds { + /* .high = */ high, + /* .low = */ low, + }; +} + +inline temporal_rs::I128Nanoseconds temporal_rs::I128Nanoseconds::FromFFI(temporal_rs::capi::I128Nanoseconds c_struct) { + return temporal_rs::I128Nanoseconds { + /* .high = */ c_struct.high, + /* .low = */ c_struct.low, + }; +} + + +#endif // TEMPORAL_RS_I128Nanoseconds_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Instant.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Instant.d.hpp new file mode 100644 index 00000000000000..e6cff3029d0e0f --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Instant.d.hpp @@ -0,0 +1,97 @@ +#ifndef TEMPORAL_RS_Instant_D_HPP +#define TEMPORAL_RS_Instant_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +namespace capi { struct Duration; } +class Duration; +namespace capi { struct Instant; } +class Instant; +namespace capi { struct Provider; } +class Provider; +namespace capi { struct ZonedDateTime; } +class ZonedDateTime; +struct DifferenceSettings; +struct I128Nanoseconds; +struct RoundingOptions; +struct TemporalError; +struct TimeZone; +struct ToStringRoundingOptions; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct Instant; +} // namespace capi +} // namespace + +namespace temporal_rs { +class Instant { +public: + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> try_new(temporal_rs::I128Nanoseconds ns); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_milliseconds(int64_t epoch_milliseconds); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf8(std::string_view s); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf16(std::u16string_view s); + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> add(const temporal_rs::Duration& duration) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> subtract(const temporal_rs::Duration& duration) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> since(const temporal_rs::Instant& other, temporal_rs::DifferenceSettings settings) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> until(const temporal_rs::Instant& other, temporal_rs::DifferenceSettings settings) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> round(temporal_rs::RoundingOptions options) const; + + inline int8_t compare(const temporal_rs::Instant& other) const; + + inline bool equals(const temporal_rs::Instant& other) const; + + inline int64_t epoch_milliseconds() const; + + inline temporal_rs::I128Nanoseconds epoch_nanoseconds() const; + + inline temporal_rs::diplomat::result to_ixdtf_string_with_compiled_data(std::optional zone, temporal_rs::ToStringRoundingOptions options) const; + template + inline temporal_rs::diplomat::result to_ixdtf_string_with_compiled_data_write(std::optional zone, temporal_rs::ToStringRoundingOptions options, W& writeable_output) const; + + inline temporal_rs::diplomat::result to_ixdtf_string_with_provider(std::optional zone, temporal_rs::ToStringRoundingOptions options, const temporal_rs::Provider& p) const; + template + inline temporal_rs::diplomat::result to_ixdtf_string_with_provider_write(std::optional zone, temporal_rs::ToStringRoundingOptions options, const temporal_rs::Provider& p, W& writeable_output) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> to_zoned_date_time_iso(temporal_rs::TimeZone zone) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> to_zoned_date_time_iso_with_provider(temporal_rs::TimeZone zone, const temporal_rs::Provider& p) const; + + inline std::unique_ptr clone() const; + + inline const temporal_rs::capi::Instant* AsFFI() const; + inline temporal_rs::capi::Instant* AsFFI(); + inline static const temporal_rs::Instant* FromFFI(const temporal_rs::capi::Instant* ptr); + inline static temporal_rs::Instant* FromFFI(temporal_rs::capi::Instant* ptr); + inline static void operator delete(void* ptr); +private: + Instant() = delete; + Instant(const temporal_rs::Instant&) = delete; + Instant(temporal_rs::Instant&&) noexcept = delete; + Instant operator=(const temporal_rs::Instant&) = delete; + Instant operator=(temporal_rs::Instant&&) noexcept = delete; + static void operator delete[](void*, size_t) = delete; +}; + +} // namespace +#endif // TEMPORAL_RS_Instant_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Instant.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Instant.hpp new file mode 100644 index 00000000000000..7f260f5cf8dd74 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Instant.hpp @@ -0,0 +1,238 @@ +#ifndef TEMPORAL_RS_Instant_HPP +#define TEMPORAL_RS_Instant_HPP + +#include "Instant.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "DifferenceSettings.hpp" +#include "Duration.hpp" +#include "I128Nanoseconds.hpp" +#include "Provider.hpp" +#include "RoundingOptions.hpp" +#include "TemporalError.hpp" +#include "TimeZone.hpp" +#include "ToStringRoundingOptions.hpp" +#include "ZonedDateTime.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + typedef struct temporal_rs_Instant_try_new_result {union {temporal_rs::capi::Instant* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Instant_try_new_result; + temporal_rs_Instant_try_new_result temporal_rs_Instant_try_new(temporal_rs::capi::I128Nanoseconds ns); + + typedef struct temporal_rs_Instant_from_epoch_milliseconds_result {union {temporal_rs::capi::Instant* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Instant_from_epoch_milliseconds_result; + temporal_rs_Instant_from_epoch_milliseconds_result temporal_rs_Instant_from_epoch_milliseconds(int64_t epoch_milliseconds); + + typedef struct temporal_rs_Instant_from_utf8_result {union {temporal_rs::capi::Instant* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Instant_from_utf8_result; + temporal_rs_Instant_from_utf8_result temporal_rs_Instant_from_utf8(temporal_rs::diplomat::capi::DiplomatStringView s); + + typedef struct temporal_rs_Instant_from_utf16_result {union {temporal_rs::capi::Instant* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Instant_from_utf16_result; + temporal_rs_Instant_from_utf16_result temporal_rs_Instant_from_utf16(temporal_rs::diplomat::capi::DiplomatString16View s); + + typedef struct temporal_rs_Instant_add_result {union {temporal_rs::capi::Instant* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Instant_add_result; + temporal_rs_Instant_add_result temporal_rs_Instant_add(const temporal_rs::capi::Instant* self, const temporal_rs::capi::Duration* duration); + + typedef struct temporal_rs_Instant_subtract_result {union {temporal_rs::capi::Instant* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Instant_subtract_result; + temporal_rs_Instant_subtract_result temporal_rs_Instant_subtract(const temporal_rs::capi::Instant* self, const temporal_rs::capi::Duration* duration); + + typedef struct temporal_rs_Instant_since_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Instant_since_result; + temporal_rs_Instant_since_result temporal_rs_Instant_since(const temporal_rs::capi::Instant* self, const temporal_rs::capi::Instant* other, temporal_rs::capi::DifferenceSettings settings); + + typedef struct temporal_rs_Instant_until_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Instant_until_result; + temporal_rs_Instant_until_result temporal_rs_Instant_until(const temporal_rs::capi::Instant* self, const temporal_rs::capi::Instant* other, temporal_rs::capi::DifferenceSettings settings); + + typedef struct temporal_rs_Instant_round_result {union {temporal_rs::capi::Instant* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Instant_round_result; + temporal_rs_Instant_round_result temporal_rs_Instant_round(const temporal_rs::capi::Instant* self, temporal_rs::capi::RoundingOptions options); + + int8_t temporal_rs_Instant_compare(const temporal_rs::capi::Instant* self, const temporal_rs::capi::Instant* other); + + bool temporal_rs_Instant_equals(const temporal_rs::capi::Instant* self, const temporal_rs::capi::Instant* other); + + int64_t temporal_rs_Instant_epoch_milliseconds(const temporal_rs::capi::Instant* self); + + temporal_rs::capi::I128Nanoseconds temporal_rs_Instant_epoch_nanoseconds(const temporal_rs::capi::Instant* self); + + typedef struct temporal_rs_Instant_to_ixdtf_string_with_compiled_data_result {union { temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Instant_to_ixdtf_string_with_compiled_data_result; + temporal_rs_Instant_to_ixdtf_string_with_compiled_data_result temporal_rs_Instant_to_ixdtf_string_with_compiled_data(const temporal_rs::capi::Instant* self, temporal_rs::capi::TimeZone_option zone, temporal_rs::capi::ToStringRoundingOptions options, temporal_rs::diplomat::capi::DiplomatWrite* write); + + typedef struct temporal_rs_Instant_to_ixdtf_string_with_provider_result {union { temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Instant_to_ixdtf_string_with_provider_result; + temporal_rs_Instant_to_ixdtf_string_with_provider_result temporal_rs_Instant_to_ixdtf_string_with_provider(const temporal_rs::capi::Instant* self, temporal_rs::capi::TimeZone_option zone, temporal_rs::capi::ToStringRoundingOptions options, const temporal_rs::capi::Provider* p, temporal_rs::diplomat::capi::DiplomatWrite* write); + + typedef struct temporal_rs_Instant_to_zoned_date_time_iso_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Instant_to_zoned_date_time_iso_result; + temporal_rs_Instant_to_zoned_date_time_iso_result temporal_rs_Instant_to_zoned_date_time_iso(const temporal_rs::capi::Instant* self, temporal_rs::capi::TimeZone zone); + + typedef struct temporal_rs_Instant_to_zoned_date_time_iso_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_Instant_to_zoned_date_time_iso_with_provider_result; + temporal_rs_Instant_to_zoned_date_time_iso_with_provider_result temporal_rs_Instant_to_zoned_date_time_iso_with_provider(const temporal_rs::capi::Instant* self, temporal_rs::capi::TimeZone zone, const temporal_rs::capi::Provider* p); + + temporal_rs::capi::Instant* temporal_rs_Instant_clone(const temporal_rs::capi::Instant* self); + + void temporal_rs_Instant_destroy(Instant* self); + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Instant::try_new(temporal_rs::I128Nanoseconds ns) { + auto result = temporal_rs::capi::temporal_rs_Instant_try_new(ns.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Instant::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Instant::from_epoch_milliseconds(int64_t epoch_milliseconds) { + auto result = temporal_rs::capi::temporal_rs_Instant_from_epoch_milliseconds(epoch_milliseconds); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Instant::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Instant::from_utf8(std::string_view s) { + auto result = temporal_rs::capi::temporal_rs_Instant_from_utf8({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Instant::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Instant::from_utf16(std::u16string_view s) { + auto result = temporal_rs::capi::temporal_rs_Instant_from_utf16({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Instant::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Instant::add(const temporal_rs::Duration& duration) const { + auto result = temporal_rs::capi::temporal_rs_Instant_add(this->AsFFI(), + duration.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Instant::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Instant::subtract(const temporal_rs::Duration& duration) const { + auto result = temporal_rs::capi::temporal_rs_Instant_subtract(this->AsFFI(), + duration.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Instant::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Instant::since(const temporal_rs::Instant& other, temporal_rs::DifferenceSettings settings) const { + auto result = temporal_rs::capi::temporal_rs_Instant_since(this->AsFFI(), + other.AsFFI(), + settings.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Instant::until(const temporal_rs::Instant& other, temporal_rs::DifferenceSettings settings) const { + auto result = temporal_rs::capi::temporal_rs_Instant_until(this->AsFFI(), + other.AsFFI(), + settings.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Instant::round(temporal_rs::RoundingOptions options) const { + auto result = temporal_rs::capi::temporal_rs_Instant_round(this->AsFFI(), + options.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Instant::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline int8_t temporal_rs::Instant::compare(const temporal_rs::Instant& other) const { + auto result = temporal_rs::capi::temporal_rs_Instant_compare(this->AsFFI(), + other.AsFFI()); + return result; +} + +inline bool temporal_rs::Instant::equals(const temporal_rs::Instant& other) const { + auto result = temporal_rs::capi::temporal_rs_Instant_equals(this->AsFFI(), + other.AsFFI()); + return result; +} + +inline int64_t temporal_rs::Instant::epoch_milliseconds() const { + auto result = temporal_rs::capi::temporal_rs_Instant_epoch_milliseconds(this->AsFFI()); + return result; +} + +inline temporal_rs::I128Nanoseconds temporal_rs::Instant::epoch_nanoseconds() const { + auto result = temporal_rs::capi::temporal_rs_Instant_epoch_nanoseconds(this->AsFFI()); + return temporal_rs::I128Nanoseconds::FromFFI(result); +} + +inline temporal_rs::diplomat::result temporal_rs::Instant::to_ixdtf_string_with_compiled_data(std::optional zone, temporal_rs::ToStringRoundingOptions options) const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + auto result = temporal_rs::capi::temporal_rs_Instant_to_ixdtf_string_with_compiled_data(this->AsFFI(), + zone.has_value() ? (temporal_rs::capi::TimeZone_option{ { zone.value().AsFFI() }, true }) : (temporal_rs::capi::TimeZone_option{ {}, false }), + options.AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(std::move(output))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} +template +inline temporal_rs::diplomat::result temporal_rs::Instant::to_ixdtf_string_with_compiled_data_write(std::optional zone, temporal_rs::ToStringRoundingOptions options, W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + auto result = temporal_rs::capi::temporal_rs_Instant_to_ixdtf_string_with_compiled_data(this->AsFFI(), + zone.has_value() ? (temporal_rs::capi::TimeZone_option{ { zone.value().AsFFI() }, true }) : (temporal_rs::capi::TimeZone_option{ {}, false }), + options.AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok()) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::Instant::to_ixdtf_string_with_provider(std::optional zone, temporal_rs::ToStringRoundingOptions options, const temporal_rs::Provider& p) const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + auto result = temporal_rs::capi::temporal_rs_Instant_to_ixdtf_string_with_provider(this->AsFFI(), + zone.has_value() ? (temporal_rs::capi::TimeZone_option{ { zone.value().AsFFI() }, true }) : (temporal_rs::capi::TimeZone_option{ {}, false }), + options.AsFFI(), + p.AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(std::move(output))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} +template +inline temporal_rs::diplomat::result temporal_rs::Instant::to_ixdtf_string_with_provider_write(std::optional zone, temporal_rs::ToStringRoundingOptions options, const temporal_rs::Provider& p, W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + auto result = temporal_rs::capi::temporal_rs_Instant_to_ixdtf_string_with_provider(this->AsFFI(), + zone.has_value() ? (temporal_rs::capi::TimeZone_option{ { zone.value().AsFFI() }, true }) : (temporal_rs::capi::TimeZone_option{ {}, false }), + options.AsFFI(), + p.AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok()) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Instant::to_zoned_date_time_iso(temporal_rs::TimeZone zone) const { + auto result = temporal_rs::capi::temporal_rs_Instant_to_zoned_date_time_iso(this->AsFFI(), + zone.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::Instant::to_zoned_date_time_iso_with_provider(temporal_rs::TimeZone zone, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_Instant_to_zoned_date_time_iso_with_provider(this->AsFFI(), + zone.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline std::unique_ptr temporal_rs::Instant::clone() const { + auto result = temporal_rs::capi::temporal_rs_Instant_clone(this->AsFFI()); + return std::unique_ptr(temporal_rs::Instant::FromFFI(result)); +} + +inline const temporal_rs::capi::Instant* temporal_rs::Instant::AsFFI() const { + return reinterpret_cast(this); +} + +inline temporal_rs::capi::Instant* temporal_rs::Instant::AsFFI() { + return reinterpret_cast(this); +} + +inline const temporal_rs::Instant* temporal_rs::Instant::FromFFI(const temporal_rs::capi::Instant* ptr) { + return reinterpret_cast(ptr); +} + +inline temporal_rs::Instant* temporal_rs::Instant::FromFFI(temporal_rs::capi::Instant* ptr) { + return reinterpret_cast(ptr); +} + +inline void temporal_rs::Instant::operator delete(void* ptr) { + temporal_rs::capi::temporal_rs_Instant_destroy(reinterpret_cast(ptr)); +} + + +#endif // TEMPORAL_RS_Instant_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/OffsetDisambiguation.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/OffsetDisambiguation.d.hpp new file mode 100644 index 00000000000000..b39f3cd9ed28e0 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/OffsetDisambiguation.d.hpp @@ -0,0 +1,53 @@ +#ifndef TEMPORAL_RS_OffsetDisambiguation_D_HPP +#define TEMPORAL_RS_OffsetDisambiguation_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + enum OffsetDisambiguation { + OffsetDisambiguation_Use = 0, + OffsetDisambiguation_Prefer = 1, + OffsetDisambiguation_Ignore = 2, + OffsetDisambiguation_Reject = 3, + }; + + typedef struct OffsetDisambiguation_option {union { OffsetDisambiguation ok; }; bool is_ok; } OffsetDisambiguation_option; +} // namespace capi +} // namespace + +namespace temporal_rs { +class OffsetDisambiguation { +public: + enum Value { + Use = 0, + Prefer = 1, + Ignore = 2, + Reject = 3, + }; + + OffsetDisambiguation(): value(Value::Use) {} + + // Implicit conversions between enum and ::Value + constexpr OffsetDisambiguation(Value v) : value(v) {} + constexpr operator Value() const { return value; } + // Prevent usage as boolean value + explicit operator bool() const = delete; + + inline temporal_rs::capi::OffsetDisambiguation AsFFI() const; + inline static temporal_rs::OffsetDisambiguation FromFFI(temporal_rs::capi::OffsetDisambiguation c_enum); +private: + Value value; +}; + +} // namespace +#endif // TEMPORAL_RS_OffsetDisambiguation_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/OffsetDisambiguation.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/OffsetDisambiguation.hpp new file mode 100644 index 00000000000000..46313f67c332d5 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/OffsetDisambiguation.hpp @@ -0,0 +1,40 @@ +#ifndef TEMPORAL_RS_OffsetDisambiguation_HPP +#define TEMPORAL_RS_OffsetDisambiguation_HPP + +#include "OffsetDisambiguation.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::capi::OffsetDisambiguation temporal_rs::OffsetDisambiguation::AsFFI() const { + return static_cast(value); +} + +inline temporal_rs::OffsetDisambiguation temporal_rs::OffsetDisambiguation::FromFFI(temporal_rs::capi::OffsetDisambiguation c_enum) { + switch (c_enum) { + case temporal_rs::capi::OffsetDisambiguation_Use: + case temporal_rs::capi::OffsetDisambiguation_Prefer: + case temporal_rs::capi::OffsetDisambiguation_Ignore: + case temporal_rs::capi::OffsetDisambiguation_Reject: + return static_cast(c_enum); + default: + std::abort(); + } +} +#endif // TEMPORAL_RS_OffsetDisambiguation_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/OwnedRelativeTo.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/OwnedRelativeTo.d.hpp new file mode 100644 index 00000000000000..27fb77ef341b38 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/OwnedRelativeTo.d.hpp @@ -0,0 +1,62 @@ +#ifndef TEMPORAL_RS_OwnedRelativeTo_D_HPP +#define TEMPORAL_RS_OwnedRelativeTo_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +namespace capi { struct PlainDate; } +class PlainDate; +namespace capi { struct Provider; } +class Provider; +namespace capi { struct ZonedDateTime; } +class ZonedDateTime; +struct OwnedRelativeTo; +struct TemporalError; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct OwnedRelativeTo { + temporal_rs::capi::PlainDate* date; + temporal_rs::capi::ZonedDateTime* zoned; + }; + + typedef struct OwnedRelativeTo_option {union { OwnedRelativeTo ok; }; bool is_ok; } OwnedRelativeTo_option; +} // namespace capi +} // namespace + + +namespace temporal_rs { +/** + * GetTemporalRelativeToOption can create fresh PlainDate/ZonedDateTimes by parsing them, + * we need a way to produce that result. + */ +struct OwnedRelativeTo { + std::unique_ptr date; + std::unique_ptr zoned; + + inline static temporal_rs::diplomat::result from_utf8(std::string_view s); + + inline static temporal_rs::diplomat::result from_utf8_with_provider(std::string_view s, const temporal_rs::Provider& p); + + inline static temporal_rs::diplomat::result from_utf16(std::u16string_view s); + + inline static temporal_rs::diplomat::result from_utf16_with_provider(std::u16string_view s, const temporal_rs::Provider& p); + + inline static temporal_rs::OwnedRelativeTo empty(); + + inline temporal_rs::capi::OwnedRelativeTo AsFFI() const; + inline static temporal_rs::OwnedRelativeTo FromFFI(temporal_rs::capi::OwnedRelativeTo c_struct); +}; + +} // namespace +#endif // TEMPORAL_RS_OwnedRelativeTo_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/OwnedRelativeTo.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/OwnedRelativeTo.hpp new file mode 100644 index 00000000000000..4ba8b6554c78bc --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/OwnedRelativeTo.hpp @@ -0,0 +1,86 @@ +#ifndef TEMPORAL_RS_OwnedRelativeTo_HPP +#define TEMPORAL_RS_OwnedRelativeTo_HPP + +#include "OwnedRelativeTo.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "PlainDate.hpp" +#include "Provider.hpp" +#include "TemporalError.hpp" +#include "ZonedDateTime.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + typedef struct temporal_rs_OwnedRelativeTo_from_utf8_result {union {temporal_rs::capi::OwnedRelativeTo ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_OwnedRelativeTo_from_utf8_result; + temporal_rs_OwnedRelativeTo_from_utf8_result temporal_rs_OwnedRelativeTo_from_utf8(temporal_rs::diplomat::capi::DiplomatStringView s); + + typedef struct temporal_rs_OwnedRelativeTo_from_utf8_with_provider_result {union {temporal_rs::capi::OwnedRelativeTo ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_OwnedRelativeTo_from_utf8_with_provider_result; + temporal_rs_OwnedRelativeTo_from_utf8_with_provider_result temporal_rs_OwnedRelativeTo_from_utf8_with_provider(temporal_rs::diplomat::capi::DiplomatStringView s, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_OwnedRelativeTo_from_utf16_result {union {temporal_rs::capi::OwnedRelativeTo ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_OwnedRelativeTo_from_utf16_result; + temporal_rs_OwnedRelativeTo_from_utf16_result temporal_rs_OwnedRelativeTo_from_utf16(temporal_rs::diplomat::capi::DiplomatString16View s); + + typedef struct temporal_rs_OwnedRelativeTo_from_utf16_with_provider_result {union {temporal_rs::capi::OwnedRelativeTo ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_OwnedRelativeTo_from_utf16_with_provider_result; + temporal_rs_OwnedRelativeTo_from_utf16_with_provider_result temporal_rs_OwnedRelativeTo_from_utf16_with_provider(temporal_rs::diplomat::capi::DiplomatString16View s, const temporal_rs::capi::Provider* p); + + temporal_rs::capi::OwnedRelativeTo temporal_rs_OwnedRelativeTo_empty(void); + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::diplomat::result temporal_rs::OwnedRelativeTo::from_utf8(std::string_view s) { + auto result = temporal_rs::capi::temporal_rs_OwnedRelativeTo_from_utf8({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(temporal_rs::OwnedRelativeTo::FromFFI(result.ok))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::OwnedRelativeTo::from_utf8_with_provider(std::string_view s, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_OwnedRelativeTo_from_utf8_with_provider({s.data(), s.size()}, + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(temporal_rs::OwnedRelativeTo::FromFFI(result.ok))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::OwnedRelativeTo::from_utf16(std::u16string_view s) { + auto result = temporal_rs::capi::temporal_rs_OwnedRelativeTo_from_utf16({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(temporal_rs::OwnedRelativeTo::FromFFI(result.ok))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::OwnedRelativeTo::from_utf16_with_provider(std::u16string_view s, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_OwnedRelativeTo_from_utf16_with_provider({s.data(), s.size()}, + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(temporal_rs::OwnedRelativeTo::FromFFI(result.ok))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::OwnedRelativeTo temporal_rs::OwnedRelativeTo::empty() { + auto result = temporal_rs::capi::temporal_rs_OwnedRelativeTo_empty(); + return temporal_rs::OwnedRelativeTo::FromFFI(result); +} + + +inline temporal_rs::capi::OwnedRelativeTo temporal_rs::OwnedRelativeTo::AsFFI() const { + return temporal_rs::capi::OwnedRelativeTo { + /* .date = */ date ? date->AsFFI() : nullptr, + /* .zoned = */ zoned ? zoned->AsFFI() : nullptr, + }; +} + +inline temporal_rs::OwnedRelativeTo temporal_rs::OwnedRelativeTo::FromFFI(temporal_rs::capi::OwnedRelativeTo c_struct) { + return temporal_rs::OwnedRelativeTo { + /* .date = */ std::unique_ptr(temporal_rs::PlainDate::FromFFI(c_struct.date)), + /* .zoned = */ std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(c_struct.zoned)), + }; +} + + +#endif // TEMPORAL_RS_OwnedRelativeTo_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedDate.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedDate.d.hpp new file mode 100644 index 00000000000000..6e3327c006925c --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedDate.d.hpp @@ -0,0 +1,58 @@ +#ifndef TEMPORAL_RS_ParsedDate_D_HPP +#define TEMPORAL_RS_ParsedDate_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +namespace capi { struct ParsedDate; } +class ParsedDate; +struct TemporalError; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct ParsedDate; +} // namespace capi +} // namespace + +namespace temporal_rs { +class ParsedDate { +public: + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf8(std::string_view s); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf16(std::u16string_view s); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> year_month_from_utf8(std::string_view s); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> year_month_from_utf16(std::u16string_view s); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> month_day_from_utf8(std::string_view s); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> month_day_from_utf16(std::u16string_view s); + + inline const temporal_rs::capi::ParsedDate* AsFFI() const; + inline temporal_rs::capi::ParsedDate* AsFFI(); + inline static const temporal_rs::ParsedDate* FromFFI(const temporal_rs::capi::ParsedDate* ptr); + inline static temporal_rs::ParsedDate* FromFFI(temporal_rs::capi::ParsedDate* ptr); + inline static void operator delete(void* ptr); +private: + ParsedDate() = delete; + ParsedDate(const temporal_rs::ParsedDate&) = delete; + ParsedDate(temporal_rs::ParsedDate&&) noexcept = delete; + ParsedDate operator=(const temporal_rs::ParsedDate&) = delete; + ParsedDate operator=(temporal_rs::ParsedDate&&) noexcept = delete; + static void operator delete[](void*, size_t) = delete; +}; + +} // namespace +#endif // TEMPORAL_RS_ParsedDate_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedDate.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedDate.hpp new file mode 100644 index 00000000000000..6a149424702e89 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedDate.hpp @@ -0,0 +1,97 @@ +#ifndef TEMPORAL_RS_ParsedDate_HPP +#define TEMPORAL_RS_ParsedDate_HPP + +#include "ParsedDate.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "TemporalError.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + typedef struct temporal_rs_ParsedDate_from_utf8_result {union {temporal_rs::capi::ParsedDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ParsedDate_from_utf8_result; + temporal_rs_ParsedDate_from_utf8_result temporal_rs_ParsedDate_from_utf8(temporal_rs::diplomat::capi::DiplomatStringView s); + + typedef struct temporal_rs_ParsedDate_from_utf16_result {union {temporal_rs::capi::ParsedDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ParsedDate_from_utf16_result; + temporal_rs_ParsedDate_from_utf16_result temporal_rs_ParsedDate_from_utf16(temporal_rs::diplomat::capi::DiplomatString16View s); + + typedef struct temporal_rs_ParsedDate_year_month_from_utf8_result {union {temporal_rs::capi::ParsedDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ParsedDate_year_month_from_utf8_result; + temporal_rs_ParsedDate_year_month_from_utf8_result temporal_rs_ParsedDate_year_month_from_utf8(temporal_rs::diplomat::capi::DiplomatStringView s); + + typedef struct temporal_rs_ParsedDate_year_month_from_utf16_result {union {temporal_rs::capi::ParsedDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ParsedDate_year_month_from_utf16_result; + temporal_rs_ParsedDate_year_month_from_utf16_result temporal_rs_ParsedDate_year_month_from_utf16(temporal_rs::diplomat::capi::DiplomatString16View s); + + typedef struct temporal_rs_ParsedDate_month_day_from_utf8_result {union {temporal_rs::capi::ParsedDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ParsedDate_month_day_from_utf8_result; + temporal_rs_ParsedDate_month_day_from_utf8_result temporal_rs_ParsedDate_month_day_from_utf8(temporal_rs::diplomat::capi::DiplomatStringView s); + + typedef struct temporal_rs_ParsedDate_month_day_from_utf16_result {union {temporal_rs::capi::ParsedDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ParsedDate_month_day_from_utf16_result; + temporal_rs_ParsedDate_month_day_from_utf16_result temporal_rs_ParsedDate_month_day_from_utf16(temporal_rs::diplomat::capi::DiplomatString16View s); + + void temporal_rs_ParsedDate_destroy(ParsedDate* self); + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ParsedDate::from_utf8(std::string_view s) { + auto result = temporal_rs::capi::temporal_rs_ParsedDate_from_utf8({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ParsedDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ParsedDate::from_utf16(std::u16string_view s) { + auto result = temporal_rs::capi::temporal_rs_ParsedDate_from_utf16({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ParsedDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ParsedDate::year_month_from_utf8(std::string_view s) { + auto result = temporal_rs::capi::temporal_rs_ParsedDate_year_month_from_utf8({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ParsedDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ParsedDate::year_month_from_utf16(std::u16string_view s) { + auto result = temporal_rs::capi::temporal_rs_ParsedDate_year_month_from_utf16({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ParsedDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ParsedDate::month_day_from_utf8(std::string_view s) { + auto result = temporal_rs::capi::temporal_rs_ParsedDate_month_day_from_utf8({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ParsedDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ParsedDate::month_day_from_utf16(std::u16string_view s) { + auto result = temporal_rs::capi::temporal_rs_ParsedDate_month_day_from_utf16({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ParsedDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline const temporal_rs::capi::ParsedDate* temporal_rs::ParsedDate::AsFFI() const { + return reinterpret_cast(this); +} + +inline temporal_rs::capi::ParsedDate* temporal_rs::ParsedDate::AsFFI() { + return reinterpret_cast(this); +} + +inline const temporal_rs::ParsedDate* temporal_rs::ParsedDate::FromFFI(const temporal_rs::capi::ParsedDate* ptr) { + return reinterpret_cast(ptr); +} + +inline temporal_rs::ParsedDate* temporal_rs::ParsedDate::FromFFI(temporal_rs::capi::ParsedDate* ptr) { + return reinterpret_cast(ptr); +} + +inline void temporal_rs::ParsedDate::operator delete(void* ptr) { + temporal_rs::capi::temporal_rs_ParsedDate_destroy(reinterpret_cast(ptr)); +} + + +#endif // TEMPORAL_RS_ParsedDate_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedDateTime.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedDateTime.d.hpp new file mode 100644 index 00000000000000..aa89382523e4ba --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedDateTime.d.hpp @@ -0,0 +1,50 @@ +#ifndef TEMPORAL_RS_ParsedDateTime_D_HPP +#define TEMPORAL_RS_ParsedDateTime_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +namespace capi { struct ParsedDateTime; } +class ParsedDateTime; +struct TemporalError; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct ParsedDateTime; +} // namespace capi +} // namespace + +namespace temporal_rs { +class ParsedDateTime { +public: + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf8(std::string_view s); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf16(std::u16string_view s); + + inline const temporal_rs::capi::ParsedDateTime* AsFFI() const; + inline temporal_rs::capi::ParsedDateTime* AsFFI(); + inline static const temporal_rs::ParsedDateTime* FromFFI(const temporal_rs::capi::ParsedDateTime* ptr); + inline static temporal_rs::ParsedDateTime* FromFFI(temporal_rs::capi::ParsedDateTime* ptr); + inline static void operator delete(void* ptr); +private: + ParsedDateTime() = delete; + ParsedDateTime(const temporal_rs::ParsedDateTime&) = delete; + ParsedDateTime(temporal_rs::ParsedDateTime&&) noexcept = delete; + ParsedDateTime operator=(const temporal_rs::ParsedDateTime&) = delete; + ParsedDateTime operator=(temporal_rs::ParsedDateTime&&) noexcept = delete; + static void operator delete[](void*, size_t) = delete; +}; + +} // namespace +#endif // TEMPORAL_RS_ParsedDateTime_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedDateTime.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedDateTime.hpp new file mode 100644 index 00000000000000..16b77809436e31 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedDateTime.hpp @@ -0,0 +1,65 @@ +#ifndef TEMPORAL_RS_ParsedDateTime_HPP +#define TEMPORAL_RS_ParsedDateTime_HPP + +#include "ParsedDateTime.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "TemporalError.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + typedef struct temporal_rs_ParsedDateTime_from_utf8_result {union {temporal_rs::capi::ParsedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ParsedDateTime_from_utf8_result; + temporal_rs_ParsedDateTime_from_utf8_result temporal_rs_ParsedDateTime_from_utf8(temporal_rs::diplomat::capi::DiplomatStringView s); + + typedef struct temporal_rs_ParsedDateTime_from_utf16_result {union {temporal_rs::capi::ParsedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ParsedDateTime_from_utf16_result; + temporal_rs_ParsedDateTime_from_utf16_result temporal_rs_ParsedDateTime_from_utf16(temporal_rs::diplomat::capi::DiplomatString16View s); + + void temporal_rs_ParsedDateTime_destroy(ParsedDateTime* self); + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ParsedDateTime::from_utf8(std::string_view s) { + auto result = temporal_rs::capi::temporal_rs_ParsedDateTime_from_utf8({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ParsedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ParsedDateTime::from_utf16(std::u16string_view s) { + auto result = temporal_rs::capi::temporal_rs_ParsedDateTime_from_utf16({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ParsedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline const temporal_rs::capi::ParsedDateTime* temporal_rs::ParsedDateTime::AsFFI() const { + return reinterpret_cast(this); +} + +inline temporal_rs::capi::ParsedDateTime* temporal_rs::ParsedDateTime::AsFFI() { + return reinterpret_cast(this); +} + +inline const temporal_rs::ParsedDateTime* temporal_rs::ParsedDateTime::FromFFI(const temporal_rs::capi::ParsedDateTime* ptr) { + return reinterpret_cast(ptr); +} + +inline temporal_rs::ParsedDateTime* temporal_rs::ParsedDateTime::FromFFI(temporal_rs::capi::ParsedDateTime* ptr) { + return reinterpret_cast(ptr); +} + +inline void temporal_rs::ParsedDateTime::operator delete(void* ptr) { + temporal_rs::capi::temporal_rs_ParsedDateTime_destroy(reinterpret_cast(ptr)); +} + + +#endif // TEMPORAL_RS_ParsedDateTime_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedZonedDateTime.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedZonedDateTime.d.hpp new file mode 100644 index 00000000000000..0f8b2c3e02f59d --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedZonedDateTime.d.hpp @@ -0,0 +1,56 @@ +#ifndef TEMPORAL_RS_ParsedZonedDateTime_D_HPP +#define TEMPORAL_RS_ParsedZonedDateTime_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +namespace capi { struct ParsedZonedDateTime; } +class ParsedZonedDateTime; +namespace capi { struct Provider; } +class Provider; +struct TemporalError; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct ParsedZonedDateTime; +} // namespace capi +} // namespace + +namespace temporal_rs { +class ParsedZonedDateTime { +public: + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf8(std::string_view s); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf8_with_provider(std::string_view s, const temporal_rs::Provider& p); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf16(std::u16string_view s); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf16_with_provider(std::u16string_view s, const temporal_rs::Provider& p); + + inline const temporal_rs::capi::ParsedZonedDateTime* AsFFI() const; + inline temporal_rs::capi::ParsedZonedDateTime* AsFFI(); + inline static const temporal_rs::ParsedZonedDateTime* FromFFI(const temporal_rs::capi::ParsedZonedDateTime* ptr); + inline static temporal_rs::ParsedZonedDateTime* FromFFI(temporal_rs::capi::ParsedZonedDateTime* ptr); + inline static void operator delete(void* ptr); +private: + ParsedZonedDateTime() = delete; + ParsedZonedDateTime(const temporal_rs::ParsedZonedDateTime&) = delete; + ParsedZonedDateTime(temporal_rs::ParsedZonedDateTime&&) noexcept = delete; + ParsedZonedDateTime operator=(const temporal_rs::ParsedZonedDateTime&) = delete; + ParsedZonedDateTime operator=(temporal_rs::ParsedZonedDateTime&&) noexcept = delete; + static void operator delete[](void*, size_t) = delete; +}; + +} // namespace +#endif // TEMPORAL_RS_ParsedZonedDateTime_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedZonedDateTime.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedZonedDateTime.hpp new file mode 100644 index 00000000000000..c8e95b2ad93f5c --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ParsedZonedDateTime.hpp @@ -0,0 +1,84 @@ +#ifndef TEMPORAL_RS_ParsedZonedDateTime_HPP +#define TEMPORAL_RS_ParsedZonedDateTime_HPP + +#include "ParsedZonedDateTime.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "Provider.hpp" +#include "TemporalError.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + typedef struct temporal_rs_ParsedZonedDateTime_from_utf8_result {union {temporal_rs::capi::ParsedZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ParsedZonedDateTime_from_utf8_result; + temporal_rs_ParsedZonedDateTime_from_utf8_result temporal_rs_ParsedZonedDateTime_from_utf8(temporal_rs::diplomat::capi::DiplomatStringView s); + + typedef struct temporal_rs_ParsedZonedDateTime_from_utf8_with_provider_result {union {temporal_rs::capi::ParsedZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ParsedZonedDateTime_from_utf8_with_provider_result; + temporal_rs_ParsedZonedDateTime_from_utf8_with_provider_result temporal_rs_ParsedZonedDateTime_from_utf8_with_provider(temporal_rs::diplomat::capi::DiplomatStringView s, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_ParsedZonedDateTime_from_utf16_result {union {temporal_rs::capi::ParsedZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ParsedZonedDateTime_from_utf16_result; + temporal_rs_ParsedZonedDateTime_from_utf16_result temporal_rs_ParsedZonedDateTime_from_utf16(temporal_rs::diplomat::capi::DiplomatString16View s); + + typedef struct temporal_rs_ParsedZonedDateTime_from_utf16_with_provider_result {union {temporal_rs::capi::ParsedZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ParsedZonedDateTime_from_utf16_with_provider_result; + temporal_rs_ParsedZonedDateTime_from_utf16_with_provider_result temporal_rs_ParsedZonedDateTime_from_utf16_with_provider(temporal_rs::diplomat::capi::DiplomatString16View s, const temporal_rs::capi::Provider* p); + + void temporal_rs_ParsedZonedDateTime_destroy(ParsedZonedDateTime* self); + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ParsedZonedDateTime::from_utf8(std::string_view s) { + auto result = temporal_rs::capi::temporal_rs_ParsedZonedDateTime_from_utf8({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ParsedZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ParsedZonedDateTime::from_utf8_with_provider(std::string_view s, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_ParsedZonedDateTime_from_utf8_with_provider({s.data(), s.size()}, + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ParsedZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ParsedZonedDateTime::from_utf16(std::u16string_view s) { + auto result = temporal_rs::capi::temporal_rs_ParsedZonedDateTime_from_utf16({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ParsedZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ParsedZonedDateTime::from_utf16_with_provider(std::u16string_view s, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_ParsedZonedDateTime_from_utf16_with_provider({s.data(), s.size()}, + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ParsedZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline const temporal_rs::capi::ParsedZonedDateTime* temporal_rs::ParsedZonedDateTime::AsFFI() const { + return reinterpret_cast(this); +} + +inline temporal_rs::capi::ParsedZonedDateTime* temporal_rs::ParsedZonedDateTime::AsFFI() { + return reinterpret_cast(this); +} + +inline const temporal_rs::ParsedZonedDateTime* temporal_rs::ParsedZonedDateTime::FromFFI(const temporal_rs::capi::ParsedZonedDateTime* ptr) { + return reinterpret_cast(ptr); +} + +inline temporal_rs::ParsedZonedDateTime* temporal_rs::ParsedZonedDateTime::FromFFI(temporal_rs::capi::ParsedZonedDateTime* ptr) { + return reinterpret_cast(ptr); +} + +inline void temporal_rs::ParsedZonedDateTime::operator delete(void* ptr) { + temporal_rs::capi::temporal_rs_ParsedZonedDateTime_destroy(reinterpret_cast(ptr)); +} + + +#endif // TEMPORAL_RS_ParsedZonedDateTime_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDate.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDate.d.hpp new file mode 100644 index 00000000000000..781c7b0c93b739 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDate.d.hpp @@ -0,0 +1,52 @@ +#ifndef TEMPORAL_RS_PartialDate_D_HPP +#define TEMPORAL_RS_PartialDate_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "AnyCalendarKind.d.hpp" +#include "diplomat_runtime.hpp" +namespace temporal_rs { +class AnyCalendarKind; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct PartialDate { + temporal_rs::diplomat::capi::OptionI32 year; + temporal_rs::diplomat::capi::OptionU8 month; + temporal_rs::diplomat::capi::DiplomatStringView month_code; + temporal_rs::diplomat::capi::OptionU8 day; + temporal_rs::diplomat::capi::DiplomatStringView era; + temporal_rs::diplomat::capi::OptionI32 era_year; + temporal_rs::capi::AnyCalendarKind calendar; + }; + + typedef struct PartialDate_option {union { PartialDate ok; }; bool is_ok; } PartialDate_option; +} // namespace capi +} // namespace + + +namespace temporal_rs { +struct PartialDate { + std::optional year; + std::optional month; + std::string_view month_code; + std::optional day; + std::string_view era; + std::optional era_year; + temporal_rs::AnyCalendarKind calendar; + + inline temporal_rs::capi::PartialDate AsFFI() const; + inline static temporal_rs::PartialDate FromFFI(temporal_rs::capi::PartialDate c_struct); +}; + +} // namespace +#endif // TEMPORAL_RS_PartialDate_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDate.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDate.hpp new file mode 100644 index 00000000000000..b7b9dc43998fc1 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDate.hpp @@ -0,0 +1,52 @@ +#ifndef TEMPORAL_RS_PartialDate_HPP +#define TEMPORAL_RS_PartialDate_HPP + +#include "PartialDate.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "AnyCalendarKind.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + + +inline temporal_rs::capi::PartialDate temporal_rs::PartialDate::AsFFI() const { + return temporal_rs::capi::PartialDate { + /* .year = */ year.has_value() ? (temporal_rs::diplomat::capi::OptionI32{ { year.value() }, true }) : (temporal_rs::diplomat::capi::OptionI32{ {}, false }), + /* .month = */ month.has_value() ? (temporal_rs::diplomat::capi::OptionU8{ { month.value() }, true }) : (temporal_rs::diplomat::capi::OptionU8{ {}, false }), + /* .month_code = */ {month_code.data(), month_code.size()}, + /* .day = */ day.has_value() ? (temporal_rs::diplomat::capi::OptionU8{ { day.value() }, true }) : (temporal_rs::diplomat::capi::OptionU8{ {}, false }), + /* .era = */ {era.data(), era.size()}, + /* .era_year = */ era_year.has_value() ? (temporal_rs::diplomat::capi::OptionI32{ { era_year.value() }, true }) : (temporal_rs::diplomat::capi::OptionI32{ {}, false }), + /* .calendar = */ calendar.AsFFI(), + }; +} + +inline temporal_rs::PartialDate temporal_rs::PartialDate::FromFFI(temporal_rs::capi::PartialDate c_struct) { + return temporal_rs::PartialDate { + /* .year = */ c_struct.year.is_ok ? std::optional(c_struct.year.ok) : std::nullopt, + /* .month = */ c_struct.month.is_ok ? std::optional(c_struct.month.ok) : std::nullopt, + /* .month_code = */ std::string_view(c_struct.month_code.data, c_struct.month_code.len), + /* .day = */ c_struct.day.is_ok ? std::optional(c_struct.day.ok) : std::nullopt, + /* .era = */ std::string_view(c_struct.era.data, c_struct.era.len), + /* .era_year = */ c_struct.era_year.is_ok ? std::optional(c_struct.era_year.ok) : std::nullopt, + /* .calendar = */ temporal_rs::AnyCalendarKind::FromFFI(c_struct.calendar), + }; +} + + +#endif // TEMPORAL_RS_PartialDate_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDateTime.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDateTime.d.hpp new file mode 100644 index 00000000000000..31ef4d5b68f657 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDateTime.d.hpp @@ -0,0 +1,44 @@ +#ifndef TEMPORAL_RS_PartialDateTime_D_HPP +#define TEMPORAL_RS_PartialDateTime_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "PartialDate.d.hpp" +#include "PartialTime.d.hpp" +#include "diplomat_runtime.hpp" +namespace temporal_rs { +struct PartialDate; +struct PartialTime; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct PartialDateTime { + temporal_rs::capi::PartialDate date; + temporal_rs::capi::PartialTime time; + }; + + typedef struct PartialDateTime_option {union { PartialDateTime ok; }; bool is_ok; } PartialDateTime_option; +} // namespace capi +} // namespace + + +namespace temporal_rs { +struct PartialDateTime { + temporal_rs::PartialDate date; + temporal_rs::PartialTime time; + + inline temporal_rs::capi::PartialDateTime AsFFI() const; + inline static temporal_rs::PartialDateTime FromFFI(temporal_rs::capi::PartialDateTime c_struct); +}; + +} // namespace +#endif // TEMPORAL_RS_PartialDateTime_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDateTime.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDateTime.hpp new file mode 100644 index 00000000000000..a1f79dc5253982 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDateTime.hpp @@ -0,0 +1,43 @@ +#ifndef TEMPORAL_RS_PartialDateTime_HPP +#define TEMPORAL_RS_PartialDateTime_HPP + +#include "PartialDateTime.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "PartialDate.hpp" +#include "PartialTime.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + + +inline temporal_rs::capi::PartialDateTime temporal_rs::PartialDateTime::AsFFI() const { + return temporal_rs::capi::PartialDateTime { + /* .date = */ date.AsFFI(), + /* .time = */ time.AsFFI(), + }; +} + +inline temporal_rs::PartialDateTime temporal_rs::PartialDateTime::FromFFI(temporal_rs::capi::PartialDateTime c_struct) { + return temporal_rs::PartialDateTime { + /* .date = */ temporal_rs::PartialDate::FromFFI(c_struct.date), + /* .time = */ temporal_rs::PartialTime::FromFFI(c_struct.time), + }; +} + + +#endif // TEMPORAL_RS_PartialDateTime_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDuration.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDuration.d.hpp new file mode 100644 index 00000000000000..bac2b06bb5a9b5 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDuration.d.hpp @@ -0,0 +1,55 @@ +#ifndef TEMPORAL_RS_PartialDuration_D_HPP +#define TEMPORAL_RS_PartialDuration_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + struct PartialDuration { + temporal_rs::diplomat::capi::OptionI64 years; + temporal_rs::diplomat::capi::OptionI64 months; + temporal_rs::diplomat::capi::OptionI64 weeks; + temporal_rs::diplomat::capi::OptionI64 days; + temporal_rs::diplomat::capi::OptionI64 hours; + temporal_rs::diplomat::capi::OptionI64 minutes; + temporal_rs::diplomat::capi::OptionI64 seconds; + temporal_rs::diplomat::capi::OptionI64 milliseconds; + temporal_rs::diplomat::capi::OptionF64 microseconds; + temporal_rs::diplomat::capi::OptionF64 nanoseconds; + }; + + typedef struct PartialDuration_option {union { PartialDuration ok; }; bool is_ok; } PartialDuration_option; +} // namespace capi +} // namespace + + +namespace temporal_rs { +struct PartialDuration { + std::optional years; + std::optional months; + std::optional weeks; + std::optional days; + std::optional hours; + std::optional minutes; + std::optional seconds; + std::optional milliseconds; + std::optional microseconds; + std::optional nanoseconds; + + inline bool is_empty() const; + + inline temporal_rs::capi::PartialDuration AsFFI() const; + inline static temporal_rs::PartialDuration FromFFI(temporal_rs::capi::PartialDuration c_struct); +}; + +} // namespace +#endif // TEMPORAL_RS_PartialDuration_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDuration.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDuration.hpp new file mode 100644 index 00000000000000..b73924d78365e9 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialDuration.hpp @@ -0,0 +1,64 @@ +#ifndef TEMPORAL_RS_PartialDuration_HPP +#define TEMPORAL_RS_PartialDuration_HPP + +#include "PartialDuration.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + bool temporal_rs_PartialDuration_is_empty(temporal_rs::capi::PartialDuration self); + + } // extern "C" +} // namespace capi +} // namespace + +inline bool temporal_rs::PartialDuration::is_empty() const { + auto result = temporal_rs::capi::temporal_rs_PartialDuration_is_empty(this->AsFFI()); + return result; +} + + +inline temporal_rs::capi::PartialDuration temporal_rs::PartialDuration::AsFFI() const { + return temporal_rs::capi::PartialDuration { + /* .years = */ years.has_value() ? (temporal_rs::diplomat::capi::OptionI64{ { years.value() }, true }) : (temporal_rs::diplomat::capi::OptionI64{ {}, false }), + /* .months = */ months.has_value() ? (temporal_rs::diplomat::capi::OptionI64{ { months.value() }, true }) : (temporal_rs::diplomat::capi::OptionI64{ {}, false }), + /* .weeks = */ weeks.has_value() ? (temporal_rs::diplomat::capi::OptionI64{ { weeks.value() }, true }) : (temporal_rs::diplomat::capi::OptionI64{ {}, false }), + /* .days = */ days.has_value() ? (temporal_rs::diplomat::capi::OptionI64{ { days.value() }, true }) : (temporal_rs::diplomat::capi::OptionI64{ {}, false }), + /* .hours = */ hours.has_value() ? (temporal_rs::diplomat::capi::OptionI64{ { hours.value() }, true }) : (temporal_rs::diplomat::capi::OptionI64{ {}, false }), + /* .minutes = */ minutes.has_value() ? (temporal_rs::diplomat::capi::OptionI64{ { minutes.value() }, true }) : (temporal_rs::diplomat::capi::OptionI64{ {}, false }), + /* .seconds = */ seconds.has_value() ? (temporal_rs::diplomat::capi::OptionI64{ { seconds.value() }, true }) : (temporal_rs::diplomat::capi::OptionI64{ {}, false }), + /* .milliseconds = */ milliseconds.has_value() ? (temporal_rs::diplomat::capi::OptionI64{ { milliseconds.value() }, true }) : (temporal_rs::diplomat::capi::OptionI64{ {}, false }), + /* .microseconds = */ microseconds.has_value() ? (temporal_rs::diplomat::capi::OptionF64{ { microseconds.value() }, true }) : (temporal_rs::diplomat::capi::OptionF64{ {}, false }), + /* .nanoseconds = */ nanoseconds.has_value() ? (temporal_rs::diplomat::capi::OptionF64{ { nanoseconds.value() }, true }) : (temporal_rs::diplomat::capi::OptionF64{ {}, false }), + }; +} + +inline temporal_rs::PartialDuration temporal_rs::PartialDuration::FromFFI(temporal_rs::capi::PartialDuration c_struct) { + return temporal_rs::PartialDuration { + /* .years = */ c_struct.years.is_ok ? std::optional(c_struct.years.ok) : std::nullopt, + /* .months = */ c_struct.months.is_ok ? std::optional(c_struct.months.ok) : std::nullopt, + /* .weeks = */ c_struct.weeks.is_ok ? std::optional(c_struct.weeks.ok) : std::nullopt, + /* .days = */ c_struct.days.is_ok ? std::optional(c_struct.days.ok) : std::nullopt, + /* .hours = */ c_struct.hours.is_ok ? std::optional(c_struct.hours.ok) : std::nullopt, + /* .minutes = */ c_struct.minutes.is_ok ? std::optional(c_struct.minutes.ok) : std::nullopt, + /* .seconds = */ c_struct.seconds.is_ok ? std::optional(c_struct.seconds.ok) : std::nullopt, + /* .milliseconds = */ c_struct.milliseconds.is_ok ? std::optional(c_struct.milliseconds.ok) : std::nullopt, + /* .microseconds = */ c_struct.microseconds.is_ok ? std::optional(c_struct.microseconds.ok) : std::nullopt, + /* .nanoseconds = */ c_struct.nanoseconds.is_ok ? std::optional(c_struct.nanoseconds.ok) : std::nullopt, + }; +} + + +#endif // TEMPORAL_RS_PartialDuration_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialTime.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialTime.d.hpp new file mode 100644 index 00000000000000..7465f6b3bdc3d6 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialTime.d.hpp @@ -0,0 +1,45 @@ +#ifndef TEMPORAL_RS_PartialTime_D_HPP +#define TEMPORAL_RS_PartialTime_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + struct PartialTime { + temporal_rs::diplomat::capi::OptionU8 hour; + temporal_rs::diplomat::capi::OptionU8 minute; + temporal_rs::diplomat::capi::OptionU8 second; + temporal_rs::diplomat::capi::OptionU16 millisecond; + temporal_rs::diplomat::capi::OptionU16 microsecond; + temporal_rs::diplomat::capi::OptionU16 nanosecond; + }; + + typedef struct PartialTime_option {union { PartialTime ok; }; bool is_ok; } PartialTime_option; +} // namespace capi +} // namespace + + +namespace temporal_rs { +struct PartialTime { + std::optional hour; + std::optional minute; + std::optional second; + std::optional millisecond; + std::optional microsecond; + std::optional nanosecond; + + inline temporal_rs::capi::PartialTime AsFFI() const; + inline static temporal_rs::PartialTime FromFFI(temporal_rs::capi::PartialTime c_struct); +}; + +} // namespace +#endif // TEMPORAL_RS_PartialTime_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialTime.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialTime.hpp new file mode 100644 index 00000000000000..8ac03c53ae11d9 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialTime.hpp @@ -0,0 +1,49 @@ +#ifndef TEMPORAL_RS_PartialTime_HPP +#define TEMPORAL_RS_PartialTime_HPP + +#include "PartialTime.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + + +inline temporal_rs::capi::PartialTime temporal_rs::PartialTime::AsFFI() const { + return temporal_rs::capi::PartialTime { + /* .hour = */ hour.has_value() ? (temporal_rs::diplomat::capi::OptionU8{ { hour.value() }, true }) : (temporal_rs::diplomat::capi::OptionU8{ {}, false }), + /* .minute = */ minute.has_value() ? (temporal_rs::diplomat::capi::OptionU8{ { minute.value() }, true }) : (temporal_rs::diplomat::capi::OptionU8{ {}, false }), + /* .second = */ second.has_value() ? (temporal_rs::diplomat::capi::OptionU8{ { second.value() }, true }) : (temporal_rs::diplomat::capi::OptionU8{ {}, false }), + /* .millisecond = */ millisecond.has_value() ? (temporal_rs::diplomat::capi::OptionU16{ { millisecond.value() }, true }) : (temporal_rs::diplomat::capi::OptionU16{ {}, false }), + /* .microsecond = */ microsecond.has_value() ? (temporal_rs::diplomat::capi::OptionU16{ { microsecond.value() }, true }) : (temporal_rs::diplomat::capi::OptionU16{ {}, false }), + /* .nanosecond = */ nanosecond.has_value() ? (temporal_rs::diplomat::capi::OptionU16{ { nanosecond.value() }, true }) : (temporal_rs::diplomat::capi::OptionU16{ {}, false }), + }; +} + +inline temporal_rs::PartialTime temporal_rs::PartialTime::FromFFI(temporal_rs::capi::PartialTime c_struct) { + return temporal_rs::PartialTime { + /* .hour = */ c_struct.hour.is_ok ? std::optional(c_struct.hour.ok) : std::nullopt, + /* .minute = */ c_struct.minute.is_ok ? std::optional(c_struct.minute.ok) : std::nullopt, + /* .second = */ c_struct.second.is_ok ? std::optional(c_struct.second.ok) : std::nullopt, + /* .millisecond = */ c_struct.millisecond.is_ok ? std::optional(c_struct.millisecond.ok) : std::nullopt, + /* .microsecond = */ c_struct.microsecond.is_ok ? std::optional(c_struct.microsecond.ok) : std::nullopt, + /* .nanosecond = */ c_struct.nanosecond.is_ok ? std::optional(c_struct.nanosecond.ok) : std::nullopt, + }; +} + + +#endif // TEMPORAL_RS_PartialTime_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialZonedDateTime.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialZonedDateTime.d.hpp new file mode 100644 index 00000000000000..0d879eff5412aa --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialZonedDateTime.d.hpp @@ -0,0 +1,50 @@ +#ifndef TEMPORAL_RS_PartialZonedDateTime_D_HPP +#define TEMPORAL_RS_PartialZonedDateTime_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "PartialDate.d.hpp" +#include "PartialTime.d.hpp" +#include "TimeZone.d.hpp" +#include "diplomat_runtime.hpp" +namespace temporal_rs { +struct PartialDate; +struct PartialTime; +struct TimeZone; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct PartialZonedDateTime { + temporal_rs::capi::PartialDate date; + temporal_rs::capi::PartialTime time; + temporal_rs::diplomat::capi::OptionStringView offset; + temporal_rs::capi::TimeZone_option timezone; + }; + + typedef struct PartialZonedDateTime_option {union { PartialZonedDateTime ok; }; bool is_ok; } PartialZonedDateTime_option; +} // namespace capi +} // namespace + + +namespace temporal_rs { +struct PartialZonedDateTime { + temporal_rs::PartialDate date; + temporal_rs::PartialTime time; + std::optional offset; + std::optional timezone; + + inline temporal_rs::capi::PartialZonedDateTime AsFFI() const; + inline static temporal_rs::PartialZonedDateTime FromFFI(temporal_rs::capi::PartialZonedDateTime c_struct); +}; + +} // namespace +#endif // TEMPORAL_RS_PartialZonedDateTime_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialZonedDateTime.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialZonedDateTime.hpp new file mode 100644 index 00000000000000..47bf1d218c6f22 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PartialZonedDateTime.hpp @@ -0,0 +1,48 @@ +#ifndef TEMPORAL_RS_PartialZonedDateTime_HPP +#define TEMPORAL_RS_PartialZonedDateTime_HPP + +#include "PartialZonedDateTime.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "PartialDate.hpp" +#include "PartialTime.hpp" +#include "TimeZone.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + + +inline temporal_rs::capi::PartialZonedDateTime temporal_rs::PartialZonedDateTime::AsFFI() const { + return temporal_rs::capi::PartialZonedDateTime { + /* .date = */ date.AsFFI(), + /* .time = */ time.AsFFI(), + /* .offset = */ offset.has_value() ? (temporal_rs::diplomat::capi::OptionStringView{ { {offset.value().data(), offset.value().size()} }, true }) : (temporal_rs::diplomat::capi::OptionStringView{ {}, false }), + /* .timezone = */ timezone.has_value() ? (temporal_rs::capi::TimeZone_option{ { timezone.value().AsFFI() }, true }) : (temporal_rs::capi::TimeZone_option{ {}, false }), + }; +} + +inline temporal_rs::PartialZonedDateTime temporal_rs::PartialZonedDateTime::FromFFI(temporal_rs::capi::PartialZonedDateTime c_struct) { + return temporal_rs::PartialZonedDateTime { + /* .date = */ temporal_rs::PartialDate::FromFFI(c_struct.date), + /* .time = */ temporal_rs::PartialTime::FromFFI(c_struct.time), + /* .offset = */ c_struct.offset.is_ok ? std::optional(std::string_view(c_struct.offset.ok.data, c_struct.offset.ok.len)) : std::nullopt, + /* .timezone = */ c_struct.timezone.is_ok ? std::optional(temporal_rs::TimeZone::FromFFI(c_struct.timezone.ok)) : std::nullopt, + }; +} + + +#endif // TEMPORAL_RS_PartialZonedDateTime_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainDate.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainDate.d.hpp new file mode 100644 index 00000000000000..e586d7cebd4a78 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainDate.d.hpp @@ -0,0 +1,163 @@ +#ifndef TEMPORAL_RS_PlainDate_D_HPP +#define TEMPORAL_RS_PlainDate_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +namespace capi { struct Calendar; } +class Calendar; +namespace capi { struct Duration; } +class Duration; +namespace capi { struct ParsedDate; } +class ParsedDate; +namespace capi { struct PlainDate; } +class PlainDate; +namespace capi { struct PlainDateTime; } +class PlainDateTime; +namespace capi { struct PlainMonthDay; } +class PlainMonthDay; +namespace capi { struct PlainTime; } +class PlainTime; +namespace capi { struct PlainYearMonth; } +class PlainYearMonth; +namespace capi { struct Provider; } +class Provider; +namespace capi { struct ZonedDateTime; } +class ZonedDateTime; +struct DifferenceSettings; +struct I128Nanoseconds; +struct PartialDate; +struct TemporalError; +struct TimeZone; +class AnyCalendarKind; +class ArithmeticOverflow; +class DisplayCalendar; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct PlainDate; +} // namespace capi +} // namespace + +namespace temporal_rs { +class PlainDate { +public: + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> try_new_constrain(int32_t year, uint8_t month, uint8_t day, temporal_rs::AnyCalendarKind calendar); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> try_new(int32_t year, uint8_t month, uint8_t day, temporal_rs::AnyCalendarKind calendar); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> try_new_with_overflow(int32_t year, uint8_t month, uint8_t day, temporal_rs::AnyCalendarKind calendar, temporal_rs::ArithmeticOverflow overflow); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_partial(temporal_rs::PartialDate partial, std::optional overflow); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_parsed(const temporal_rs::ParsedDate& parsed); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_milliseconds(int64_t ms, temporal_rs::TimeZone tz); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_milliseconds_with_provider(int64_t ms, temporal_rs::TimeZone tz, const temporal_rs::Provider& p); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_nanoseconds(temporal_rs::I128Nanoseconds ns, temporal_rs::TimeZone tz); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_nanoseconds_with_provider(temporal_rs::I128Nanoseconds ns, temporal_rs::TimeZone tz, const temporal_rs::Provider& p); + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> with(temporal_rs::PartialDate partial, std::optional overflow) const; + + inline std::unique_ptr with_calendar(temporal_rs::AnyCalendarKind calendar) const; + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf8(std::string_view s); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf16(std::u16string_view s); + + inline const temporal_rs::Calendar& calendar() const; + + inline bool is_valid() const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> add(const temporal_rs::Duration& duration, std::optional overflow) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> subtract(const temporal_rs::Duration& duration, std::optional overflow) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> until(const temporal_rs::PlainDate& other, temporal_rs::DifferenceSettings settings) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> since(const temporal_rs::PlainDate& other, temporal_rs::DifferenceSettings settings) const; + + inline bool equals(const temporal_rs::PlainDate& other) const; + + inline static int8_t compare(const temporal_rs::PlainDate& one, const temporal_rs::PlainDate& two); + + inline int32_t year() const; + + inline uint8_t month() const; + + inline std::string month_code() const; + template + inline void month_code_write(W& writeable_output) const; + + inline uint8_t day() const; + + inline uint16_t day_of_week() const; + + inline uint16_t day_of_year() const; + + inline std::optional week_of_year() const; + + inline std::optional year_of_week() const; + + inline uint16_t days_in_week() const; + + inline uint16_t days_in_month() const; + + inline uint16_t days_in_year() const; + + inline uint16_t months_in_year() const; + + inline bool in_leap_year() const; + + inline std::string era() const; + template + inline void era_write(W& writeable_output) const; + + inline std::optional era_year() const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> to_plain_date_time(const temporal_rs::PlainTime* time) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> to_plain_month_day() const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> to_plain_year_month() const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> to_zoned_date_time(temporal_rs::TimeZone time_zone, const temporal_rs::PlainTime* time) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> to_zoned_date_time_with_provider(temporal_rs::TimeZone time_zone, const temporal_rs::PlainTime* time, const temporal_rs::Provider& p) const; + + inline std::string to_ixdtf_string(temporal_rs::DisplayCalendar display_calendar) const; + template + inline void to_ixdtf_string_write(temporal_rs::DisplayCalendar display_calendar, W& writeable_output) const; + + inline std::unique_ptr clone() const; + + inline const temporal_rs::capi::PlainDate* AsFFI() const; + inline temporal_rs::capi::PlainDate* AsFFI(); + inline static const temporal_rs::PlainDate* FromFFI(const temporal_rs::capi::PlainDate* ptr); + inline static temporal_rs::PlainDate* FromFFI(temporal_rs::capi::PlainDate* ptr); + inline static void operator delete(void* ptr); +private: + PlainDate() = delete; + PlainDate(const temporal_rs::PlainDate&) = delete; + PlainDate(temporal_rs::PlainDate&&) noexcept = delete; + PlainDate operator=(const temporal_rs::PlainDate&) = delete; + PlainDate operator=(temporal_rs::PlainDate&&) noexcept = delete; + static void operator delete[](void*, size_t) = delete; +}; + +} // namespace +#endif // TEMPORAL_RS_PlainDate_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainDate.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainDate.hpp new file mode 100644 index 00000000000000..10673ade8f81f3 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainDate.hpp @@ -0,0 +1,455 @@ +#ifndef TEMPORAL_RS_PlainDate_HPP +#define TEMPORAL_RS_PlainDate_HPP + +#include "PlainDate.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "AnyCalendarKind.hpp" +#include "ArithmeticOverflow.hpp" +#include "Calendar.hpp" +#include "DifferenceSettings.hpp" +#include "DisplayCalendar.hpp" +#include "Duration.hpp" +#include "I128Nanoseconds.hpp" +#include "ParsedDate.hpp" +#include "PartialDate.hpp" +#include "PlainDateTime.hpp" +#include "PlainMonthDay.hpp" +#include "PlainTime.hpp" +#include "PlainYearMonth.hpp" +#include "Provider.hpp" +#include "TemporalError.hpp" +#include "TimeZone.hpp" +#include "ZonedDateTime.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + typedef struct temporal_rs_PlainDate_try_new_constrain_result {union {temporal_rs::capi::PlainDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_try_new_constrain_result; + temporal_rs_PlainDate_try_new_constrain_result temporal_rs_PlainDate_try_new_constrain(int32_t year, uint8_t month, uint8_t day, temporal_rs::capi::AnyCalendarKind calendar); + + typedef struct temporal_rs_PlainDate_try_new_result {union {temporal_rs::capi::PlainDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_try_new_result; + temporal_rs_PlainDate_try_new_result temporal_rs_PlainDate_try_new(int32_t year, uint8_t month, uint8_t day, temporal_rs::capi::AnyCalendarKind calendar); + + typedef struct temporal_rs_PlainDate_try_new_with_overflow_result {union {temporal_rs::capi::PlainDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_try_new_with_overflow_result; + temporal_rs_PlainDate_try_new_with_overflow_result temporal_rs_PlainDate_try_new_with_overflow(int32_t year, uint8_t month, uint8_t day, temporal_rs::capi::AnyCalendarKind calendar, temporal_rs::capi::ArithmeticOverflow overflow); + + typedef struct temporal_rs_PlainDate_from_partial_result {union {temporal_rs::capi::PlainDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_from_partial_result; + temporal_rs_PlainDate_from_partial_result temporal_rs_PlainDate_from_partial(temporal_rs::capi::PartialDate partial, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_PlainDate_from_parsed_result {union {temporal_rs::capi::PlainDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_from_parsed_result; + temporal_rs_PlainDate_from_parsed_result temporal_rs_PlainDate_from_parsed(const temporal_rs::capi::ParsedDate* parsed); + + typedef struct temporal_rs_PlainDate_from_epoch_milliseconds_result {union {temporal_rs::capi::PlainDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_from_epoch_milliseconds_result; + temporal_rs_PlainDate_from_epoch_milliseconds_result temporal_rs_PlainDate_from_epoch_milliseconds(int64_t ms, temporal_rs::capi::TimeZone tz); + + typedef struct temporal_rs_PlainDate_from_epoch_milliseconds_with_provider_result {union {temporal_rs::capi::PlainDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_from_epoch_milliseconds_with_provider_result; + temporal_rs_PlainDate_from_epoch_milliseconds_with_provider_result temporal_rs_PlainDate_from_epoch_milliseconds_with_provider(int64_t ms, temporal_rs::capi::TimeZone tz, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_PlainDate_from_epoch_nanoseconds_result {union {temporal_rs::capi::PlainDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_from_epoch_nanoseconds_result; + temporal_rs_PlainDate_from_epoch_nanoseconds_result temporal_rs_PlainDate_from_epoch_nanoseconds(temporal_rs::capi::I128Nanoseconds ns, temporal_rs::capi::TimeZone tz); + + typedef struct temporal_rs_PlainDate_from_epoch_nanoseconds_with_provider_result {union {temporal_rs::capi::PlainDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_from_epoch_nanoseconds_with_provider_result; + temporal_rs_PlainDate_from_epoch_nanoseconds_with_provider_result temporal_rs_PlainDate_from_epoch_nanoseconds_with_provider(temporal_rs::capi::I128Nanoseconds ns, temporal_rs::capi::TimeZone tz, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_PlainDate_with_result {union {temporal_rs::capi::PlainDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_with_result; + temporal_rs_PlainDate_with_result temporal_rs_PlainDate_with(const temporal_rs::capi::PlainDate* self, temporal_rs::capi::PartialDate partial, temporal_rs::capi::ArithmeticOverflow_option overflow); + + temporal_rs::capi::PlainDate* temporal_rs_PlainDate_with_calendar(const temporal_rs::capi::PlainDate* self, temporal_rs::capi::AnyCalendarKind calendar); + + typedef struct temporal_rs_PlainDate_from_utf8_result {union {temporal_rs::capi::PlainDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_from_utf8_result; + temporal_rs_PlainDate_from_utf8_result temporal_rs_PlainDate_from_utf8(temporal_rs::diplomat::capi::DiplomatStringView s); + + typedef struct temporal_rs_PlainDate_from_utf16_result {union {temporal_rs::capi::PlainDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_from_utf16_result; + temporal_rs_PlainDate_from_utf16_result temporal_rs_PlainDate_from_utf16(temporal_rs::diplomat::capi::DiplomatString16View s); + + const temporal_rs::capi::Calendar* temporal_rs_PlainDate_calendar(const temporal_rs::capi::PlainDate* self); + + bool temporal_rs_PlainDate_is_valid(const temporal_rs::capi::PlainDate* self); + + typedef struct temporal_rs_PlainDate_add_result {union {temporal_rs::capi::PlainDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_add_result; + temporal_rs_PlainDate_add_result temporal_rs_PlainDate_add(const temporal_rs::capi::PlainDate* self, const temporal_rs::capi::Duration* duration, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_PlainDate_subtract_result {union {temporal_rs::capi::PlainDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_subtract_result; + temporal_rs_PlainDate_subtract_result temporal_rs_PlainDate_subtract(const temporal_rs::capi::PlainDate* self, const temporal_rs::capi::Duration* duration, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_PlainDate_until_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_until_result; + temporal_rs_PlainDate_until_result temporal_rs_PlainDate_until(const temporal_rs::capi::PlainDate* self, const temporal_rs::capi::PlainDate* other, temporal_rs::capi::DifferenceSettings settings); + + typedef struct temporal_rs_PlainDate_since_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_since_result; + temporal_rs_PlainDate_since_result temporal_rs_PlainDate_since(const temporal_rs::capi::PlainDate* self, const temporal_rs::capi::PlainDate* other, temporal_rs::capi::DifferenceSettings settings); + + bool temporal_rs_PlainDate_equals(const temporal_rs::capi::PlainDate* self, const temporal_rs::capi::PlainDate* other); + + int8_t temporal_rs_PlainDate_compare(const temporal_rs::capi::PlainDate* one, const temporal_rs::capi::PlainDate* two); + + int32_t temporal_rs_PlainDate_year(const temporal_rs::capi::PlainDate* self); + + uint8_t temporal_rs_PlainDate_month(const temporal_rs::capi::PlainDate* self); + + void temporal_rs_PlainDate_month_code(const temporal_rs::capi::PlainDate* self, temporal_rs::diplomat::capi::DiplomatWrite* write); + + uint8_t temporal_rs_PlainDate_day(const temporal_rs::capi::PlainDate* self); + + uint16_t temporal_rs_PlainDate_day_of_week(const temporal_rs::capi::PlainDate* self); + + uint16_t temporal_rs_PlainDate_day_of_year(const temporal_rs::capi::PlainDate* self); + + typedef struct temporal_rs_PlainDate_week_of_year_result {union {uint8_t ok; }; bool is_ok;} temporal_rs_PlainDate_week_of_year_result; + temporal_rs_PlainDate_week_of_year_result temporal_rs_PlainDate_week_of_year(const temporal_rs::capi::PlainDate* self); + + typedef struct temporal_rs_PlainDate_year_of_week_result {union {int32_t ok; }; bool is_ok;} temporal_rs_PlainDate_year_of_week_result; + temporal_rs_PlainDate_year_of_week_result temporal_rs_PlainDate_year_of_week(const temporal_rs::capi::PlainDate* self); + + uint16_t temporal_rs_PlainDate_days_in_week(const temporal_rs::capi::PlainDate* self); + + uint16_t temporal_rs_PlainDate_days_in_month(const temporal_rs::capi::PlainDate* self); + + uint16_t temporal_rs_PlainDate_days_in_year(const temporal_rs::capi::PlainDate* self); + + uint16_t temporal_rs_PlainDate_months_in_year(const temporal_rs::capi::PlainDate* self); + + bool temporal_rs_PlainDate_in_leap_year(const temporal_rs::capi::PlainDate* self); + + void temporal_rs_PlainDate_era(const temporal_rs::capi::PlainDate* self, temporal_rs::diplomat::capi::DiplomatWrite* write); + + typedef struct temporal_rs_PlainDate_era_year_result {union {int32_t ok; }; bool is_ok;} temporal_rs_PlainDate_era_year_result; + temporal_rs_PlainDate_era_year_result temporal_rs_PlainDate_era_year(const temporal_rs::capi::PlainDate* self); + + typedef struct temporal_rs_PlainDate_to_plain_date_time_result {union {temporal_rs::capi::PlainDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_to_plain_date_time_result; + temporal_rs_PlainDate_to_plain_date_time_result temporal_rs_PlainDate_to_plain_date_time(const temporal_rs::capi::PlainDate* self, const temporal_rs::capi::PlainTime* time); + + typedef struct temporal_rs_PlainDate_to_plain_month_day_result {union {temporal_rs::capi::PlainMonthDay* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_to_plain_month_day_result; + temporal_rs_PlainDate_to_plain_month_day_result temporal_rs_PlainDate_to_plain_month_day(const temporal_rs::capi::PlainDate* self); + + typedef struct temporal_rs_PlainDate_to_plain_year_month_result {union {temporal_rs::capi::PlainYearMonth* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_to_plain_year_month_result; + temporal_rs_PlainDate_to_plain_year_month_result temporal_rs_PlainDate_to_plain_year_month(const temporal_rs::capi::PlainDate* self); + + typedef struct temporal_rs_PlainDate_to_zoned_date_time_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_to_zoned_date_time_result; + temporal_rs_PlainDate_to_zoned_date_time_result temporal_rs_PlainDate_to_zoned_date_time(const temporal_rs::capi::PlainDate* self, temporal_rs::capi::TimeZone time_zone, const temporal_rs::capi::PlainTime* time); + + typedef struct temporal_rs_PlainDate_to_zoned_date_time_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_to_zoned_date_time_with_provider_result; + temporal_rs_PlainDate_to_zoned_date_time_with_provider_result temporal_rs_PlainDate_to_zoned_date_time_with_provider(const temporal_rs::capi::PlainDate* self, temporal_rs::capi::TimeZone time_zone, const temporal_rs::capi::PlainTime* time, const temporal_rs::capi::Provider* p); + + void temporal_rs_PlainDate_to_ixdtf_string(const temporal_rs::capi::PlainDate* self, temporal_rs::capi::DisplayCalendar display_calendar, temporal_rs::diplomat::capi::DiplomatWrite* write); + + temporal_rs::capi::PlainDate* temporal_rs_PlainDate_clone(const temporal_rs::capi::PlainDate* self); + + void temporal_rs_PlainDate_destroy(PlainDate* self); + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::try_new_constrain(int32_t year, uint8_t month, uint8_t day, temporal_rs::AnyCalendarKind calendar) { + auto result = temporal_rs::capi::temporal_rs_PlainDate_try_new_constrain(year, + month, + day, + calendar.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::try_new(int32_t year, uint8_t month, uint8_t day, temporal_rs::AnyCalendarKind calendar) { + auto result = temporal_rs::capi::temporal_rs_PlainDate_try_new(year, + month, + day, + calendar.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::try_new_with_overflow(int32_t year, uint8_t month, uint8_t day, temporal_rs::AnyCalendarKind calendar, temporal_rs::ArithmeticOverflow overflow) { + auto result = temporal_rs::capi::temporal_rs_PlainDate_try_new_with_overflow(year, + month, + day, + calendar.AsFFI(), + overflow.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::from_partial(temporal_rs::PartialDate partial, std::optional overflow) { + auto result = temporal_rs::capi::temporal_rs_PlainDate_from_partial(partial.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::from_parsed(const temporal_rs::ParsedDate& parsed) { + auto result = temporal_rs::capi::temporal_rs_PlainDate_from_parsed(parsed.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::from_epoch_milliseconds(int64_t ms, temporal_rs::TimeZone tz) { + auto result = temporal_rs::capi::temporal_rs_PlainDate_from_epoch_milliseconds(ms, + tz.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::from_epoch_milliseconds_with_provider(int64_t ms, temporal_rs::TimeZone tz, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_PlainDate_from_epoch_milliseconds_with_provider(ms, + tz.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::from_epoch_nanoseconds(temporal_rs::I128Nanoseconds ns, temporal_rs::TimeZone tz) { + auto result = temporal_rs::capi::temporal_rs_PlainDate_from_epoch_nanoseconds(ns.AsFFI(), + tz.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::from_epoch_nanoseconds_with_provider(temporal_rs::I128Nanoseconds ns, temporal_rs::TimeZone tz, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_PlainDate_from_epoch_nanoseconds_with_provider(ns.AsFFI(), + tz.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::with(temporal_rs::PartialDate partial, std::optional overflow) const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_with(this->AsFFI(), + partial.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline std::unique_ptr temporal_rs::PlainDate::with_calendar(temporal_rs::AnyCalendarKind calendar) const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_with_calendar(this->AsFFI(), + calendar.AsFFI()); + return std::unique_ptr(temporal_rs::PlainDate::FromFFI(result)); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::from_utf8(std::string_view s) { + auto result = temporal_rs::capi::temporal_rs_PlainDate_from_utf8({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::from_utf16(std::u16string_view s) { + auto result = temporal_rs::capi::temporal_rs_PlainDate_from_utf16({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline const temporal_rs::Calendar& temporal_rs::PlainDate::calendar() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_calendar(this->AsFFI()); + return *temporal_rs::Calendar::FromFFI(result); +} + +inline bool temporal_rs::PlainDate::is_valid() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_is_valid(this->AsFFI()); + return result; +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::add(const temporal_rs::Duration& duration, std::optional overflow) const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_add(this->AsFFI(), + duration.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::subtract(const temporal_rs::Duration& duration, std::optional overflow) const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_subtract(this->AsFFI(), + duration.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::until(const temporal_rs::PlainDate& other, temporal_rs::DifferenceSettings settings) const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_until(this->AsFFI(), + other.AsFFI(), + settings.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::since(const temporal_rs::PlainDate& other, temporal_rs::DifferenceSettings settings) const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_since(this->AsFFI(), + other.AsFFI(), + settings.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline bool temporal_rs::PlainDate::equals(const temporal_rs::PlainDate& other) const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_equals(this->AsFFI(), + other.AsFFI()); + return result; +} + +inline int8_t temporal_rs::PlainDate::compare(const temporal_rs::PlainDate& one, const temporal_rs::PlainDate& two) { + auto result = temporal_rs::capi::temporal_rs_PlainDate_compare(one.AsFFI(), + two.AsFFI()); + return result; +} + +inline int32_t temporal_rs::PlainDate::year() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_year(this->AsFFI()); + return result; +} + +inline uint8_t temporal_rs::PlainDate::month() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_month(this->AsFFI()); + return result; +} + +inline std::string temporal_rs::PlainDate::month_code() const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + temporal_rs::capi::temporal_rs_PlainDate_month_code(this->AsFFI(), + &write); + return output; +} +template +inline void temporal_rs::PlainDate::month_code_write(W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + temporal_rs::capi::temporal_rs_PlainDate_month_code(this->AsFFI(), + &write); +} + +inline uint8_t temporal_rs::PlainDate::day() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_day(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainDate::day_of_week() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_day_of_week(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainDate::day_of_year() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_day_of_year(this->AsFFI()); + return result; +} + +inline std::optional temporal_rs::PlainDate::week_of_year() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_week_of_year(this->AsFFI()); + return result.is_ok ? std::optional(result.ok) : std::nullopt; +} + +inline std::optional temporal_rs::PlainDate::year_of_week() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_year_of_week(this->AsFFI()); + return result.is_ok ? std::optional(result.ok) : std::nullopt; +} + +inline uint16_t temporal_rs::PlainDate::days_in_week() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_days_in_week(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainDate::days_in_month() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_days_in_month(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainDate::days_in_year() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_days_in_year(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainDate::months_in_year() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_months_in_year(this->AsFFI()); + return result; +} + +inline bool temporal_rs::PlainDate::in_leap_year() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_in_leap_year(this->AsFFI()); + return result; +} + +inline std::string temporal_rs::PlainDate::era() const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + temporal_rs::capi::temporal_rs_PlainDate_era(this->AsFFI(), + &write); + return output; +} +template +inline void temporal_rs::PlainDate::era_write(W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + temporal_rs::capi::temporal_rs_PlainDate_era(this->AsFFI(), + &write); +} + +inline std::optional temporal_rs::PlainDate::era_year() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_era_year(this->AsFFI()); + return result.is_ok ? std::optional(result.ok) : std::nullopt; +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::to_plain_date_time(const temporal_rs::PlainTime* time) const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_to_plain_date_time(this->AsFFI(), + time ? time->AsFFI() : nullptr); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::to_plain_month_day() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_to_plain_month_day(this->AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainMonthDay::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::to_plain_year_month() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_to_plain_year_month(this->AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainYearMonth::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::to_zoned_date_time(temporal_rs::TimeZone time_zone, const temporal_rs::PlainTime* time) const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_to_zoned_date_time(this->AsFFI(), + time_zone.AsFFI(), + time ? time->AsFFI() : nullptr); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDate::to_zoned_date_time_with_provider(temporal_rs::TimeZone time_zone, const temporal_rs::PlainTime* time, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_to_zoned_date_time_with_provider(this->AsFFI(), + time_zone.AsFFI(), + time ? time->AsFFI() : nullptr, + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline std::string temporal_rs::PlainDate::to_ixdtf_string(temporal_rs::DisplayCalendar display_calendar) const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + temporal_rs::capi::temporal_rs_PlainDate_to_ixdtf_string(this->AsFFI(), + display_calendar.AsFFI(), + &write); + return output; +} +template +inline void temporal_rs::PlainDate::to_ixdtf_string_write(temporal_rs::DisplayCalendar display_calendar, W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + temporal_rs::capi::temporal_rs_PlainDate_to_ixdtf_string(this->AsFFI(), + display_calendar.AsFFI(), + &write); +} + +inline std::unique_ptr temporal_rs::PlainDate::clone() const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_clone(this->AsFFI()); + return std::unique_ptr(temporal_rs::PlainDate::FromFFI(result)); +} + +inline const temporal_rs::capi::PlainDate* temporal_rs::PlainDate::AsFFI() const { + return reinterpret_cast(this); +} + +inline temporal_rs::capi::PlainDate* temporal_rs::PlainDate::AsFFI() { + return reinterpret_cast(this); +} + +inline const temporal_rs::PlainDate* temporal_rs::PlainDate::FromFFI(const temporal_rs::capi::PlainDate* ptr) { + return reinterpret_cast(ptr); +} + +inline temporal_rs::PlainDate* temporal_rs::PlainDate::FromFFI(temporal_rs::capi::PlainDate* ptr) { + return reinterpret_cast(ptr); +} + +inline void temporal_rs::PlainDate::operator delete(void* ptr) { + temporal_rs::capi::temporal_rs_PlainDate_destroy(reinterpret_cast(ptr)); +} + + +#endif // TEMPORAL_RS_PlainDate_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainDateTime.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainDateTime.d.hpp new file mode 100644 index 00000000000000..f5052625fcfe95 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainDateTime.d.hpp @@ -0,0 +1,172 @@ +#ifndef TEMPORAL_RS_PlainDateTime_D_HPP +#define TEMPORAL_RS_PlainDateTime_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +namespace capi { struct Calendar; } +class Calendar; +namespace capi { struct Duration; } +class Duration; +namespace capi { struct ParsedDateTime; } +class ParsedDateTime; +namespace capi { struct PlainDate; } +class PlainDate; +namespace capi { struct PlainDateTime; } +class PlainDateTime; +namespace capi { struct PlainTime; } +class PlainTime; +namespace capi { struct Provider; } +class Provider; +namespace capi { struct ZonedDateTime; } +class ZonedDateTime; +struct DifferenceSettings; +struct I128Nanoseconds; +struct PartialDateTime; +struct RoundingOptions; +struct TemporalError; +struct TimeZone; +struct ToStringRoundingOptions; +class AnyCalendarKind; +class ArithmeticOverflow; +class Disambiguation; +class DisplayCalendar; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct PlainDateTime; +} // namespace capi +} // namespace + +namespace temporal_rs { +class PlainDateTime { +public: + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> try_new_constrain(int32_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint16_t millisecond, uint16_t microsecond, uint16_t nanosecond, temporal_rs::AnyCalendarKind calendar); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> try_new(int32_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint16_t millisecond, uint16_t microsecond, uint16_t nanosecond, temporal_rs::AnyCalendarKind calendar); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_partial(temporal_rs::PartialDateTime partial, std::optional overflow); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_parsed(const temporal_rs::ParsedDateTime& parsed); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_milliseconds(int64_t ms, temporal_rs::TimeZone tz); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_milliseconds_with_provider(int64_t ms, temporal_rs::TimeZone tz, const temporal_rs::Provider& p); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_nanoseconds(temporal_rs::I128Nanoseconds ns, temporal_rs::TimeZone tz); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_nanoseconds_with_provider(temporal_rs::I128Nanoseconds ns, temporal_rs::TimeZone tz, const temporal_rs::Provider& p); + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> with(temporal_rs::PartialDateTime partial, std::optional overflow) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> with_time(const temporal_rs::PlainTime* time) const; + + inline std::unique_ptr with_calendar(temporal_rs::AnyCalendarKind calendar) const; + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf8(std::string_view s); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf16(std::u16string_view s); + + inline uint8_t hour() const; + + inline uint8_t minute() const; + + inline uint8_t second() const; + + inline uint16_t millisecond() const; + + inline uint16_t microsecond() const; + + inline uint16_t nanosecond() const; + + inline const temporal_rs::Calendar& calendar() const; + + inline int32_t year() const; + + inline uint8_t month() const; + + inline std::string month_code() const; + template + inline void month_code_write(W& writeable_output) const; + + inline uint8_t day() const; + + inline uint16_t day_of_week() const; + + inline uint16_t day_of_year() const; + + inline std::optional week_of_year() const; + + inline std::optional year_of_week() const; + + inline uint16_t days_in_week() const; + + inline uint16_t days_in_month() const; + + inline uint16_t days_in_year() const; + + inline uint16_t months_in_year() const; + + inline bool in_leap_year() const; + + inline std::string era() const; + template + inline void era_write(W& writeable_output) const; + + inline std::optional era_year() const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> add(const temporal_rs::Duration& duration, std::optional overflow) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> subtract(const temporal_rs::Duration& duration, std::optional overflow) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> until(const temporal_rs::PlainDateTime& other, temporal_rs::DifferenceSettings settings) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> since(const temporal_rs::PlainDateTime& other, temporal_rs::DifferenceSettings settings) const; + + inline bool equals(const temporal_rs::PlainDateTime& other) const; + + inline static int8_t compare(const temporal_rs::PlainDateTime& one, const temporal_rs::PlainDateTime& two); + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> round(temporal_rs::RoundingOptions options) const; + + inline std::unique_ptr to_plain_date() const; + + inline std::unique_ptr to_plain_time() const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> to_zoned_date_time(temporal_rs::TimeZone time_zone, temporal_rs::Disambiguation disambiguation) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> to_zoned_date_time_with_provider(temporal_rs::TimeZone time_zone, temporal_rs::Disambiguation disambiguation, const temporal_rs::Provider& p) const; + + inline temporal_rs::diplomat::result to_ixdtf_string(temporal_rs::ToStringRoundingOptions options, temporal_rs::DisplayCalendar display_calendar) const; + template + inline temporal_rs::diplomat::result to_ixdtf_string_write(temporal_rs::ToStringRoundingOptions options, temporal_rs::DisplayCalendar display_calendar, W& writeable_output) const; + + inline std::unique_ptr clone() const; + + inline const temporal_rs::capi::PlainDateTime* AsFFI() const; + inline temporal_rs::capi::PlainDateTime* AsFFI(); + inline static const temporal_rs::PlainDateTime* FromFFI(const temporal_rs::capi::PlainDateTime* ptr); + inline static temporal_rs::PlainDateTime* FromFFI(temporal_rs::capi::PlainDateTime* ptr); + inline static void operator delete(void* ptr); +private: + PlainDateTime() = delete; + PlainDateTime(const temporal_rs::PlainDateTime&) = delete; + PlainDateTime(temporal_rs::PlainDateTime&&) noexcept = delete; + PlainDateTime operator=(const temporal_rs::PlainDateTime&) = delete; + PlainDateTime operator=(temporal_rs::PlainDateTime&&) noexcept = delete; + static void operator delete[](void*, size_t) = delete; +}; + +} // namespace +#endif // TEMPORAL_RS_PlainDateTime_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainDateTime.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainDateTime.hpp new file mode 100644 index 00000000000000..2513e06d722aac --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainDateTime.hpp @@ -0,0 +1,502 @@ +#ifndef TEMPORAL_RS_PlainDateTime_HPP +#define TEMPORAL_RS_PlainDateTime_HPP + +#include "PlainDateTime.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "AnyCalendarKind.hpp" +#include "ArithmeticOverflow.hpp" +#include "Calendar.hpp" +#include "DifferenceSettings.hpp" +#include "Disambiguation.hpp" +#include "DisplayCalendar.hpp" +#include "Duration.hpp" +#include "I128Nanoseconds.hpp" +#include "ParsedDateTime.hpp" +#include "PartialDateTime.hpp" +#include "PlainDate.hpp" +#include "PlainTime.hpp" +#include "Provider.hpp" +#include "RoundingOptions.hpp" +#include "TemporalError.hpp" +#include "TimeZone.hpp" +#include "ToStringRoundingOptions.hpp" +#include "ZonedDateTime.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + typedef struct temporal_rs_PlainDateTime_try_new_constrain_result {union {temporal_rs::capi::PlainDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_try_new_constrain_result; + temporal_rs_PlainDateTime_try_new_constrain_result temporal_rs_PlainDateTime_try_new_constrain(int32_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint16_t millisecond, uint16_t microsecond, uint16_t nanosecond, temporal_rs::capi::AnyCalendarKind calendar); + + typedef struct temporal_rs_PlainDateTime_try_new_result {union {temporal_rs::capi::PlainDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_try_new_result; + temporal_rs_PlainDateTime_try_new_result temporal_rs_PlainDateTime_try_new(int32_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint16_t millisecond, uint16_t microsecond, uint16_t nanosecond, temporal_rs::capi::AnyCalendarKind calendar); + + typedef struct temporal_rs_PlainDateTime_from_partial_result {union {temporal_rs::capi::PlainDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_from_partial_result; + temporal_rs_PlainDateTime_from_partial_result temporal_rs_PlainDateTime_from_partial(temporal_rs::capi::PartialDateTime partial, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_PlainDateTime_from_parsed_result {union {temporal_rs::capi::PlainDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_from_parsed_result; + temporal_rs_PlainDateTime_from_parsed_result temporal_rs_PlainDateTime_from_parsed(const temporal_rs::capi::ParsedDateTime* parsed); + + typedef struct temporal_rs_PlainDateTime_from_epoch_milliseconds_result {union {temporal_rs::capi::PlainDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_from_epoch_milliseconds_result; + temporal_rs_PlainDateTime_from_epoch_milliseconds_result temporal_rs_PlainDateTime_from_epoch_milliseconds(int64_t ms, temporal_rs::capi::TimeZone tz); + + typedef struct temporal_rs_PlainDateTime_from_epoch_milliseconds_with_provider_result {union {temporal_rs::capi::PlainDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_from_epoch_milliseconds_with_provider_result; + temporal_rs_PlainDateTime_from_epoch_milliseconds_with_provider_result temporal_rs_PlainDateTime_from_epoch_milliseconds_with_provider(int64_t ms, temporal_rs::capi::TimeZone tz, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_PlainDateTime_from_epoch_nanoseconds_result {union {temporal_rs::capi::PlainDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_from_epoch_nanoseconds_result; + temporal_rs_PlainDateTime_from_epoch_nanoseconds_result temporal_rs_PlainDateTime_from_epoch_nanoseconds(temporal_rs::capi::I128Nanoseconds ns, temporal_rs::capi::TimeZone tz); + + typedef struct temporal_rs_PlainDateTime_from_epoch_nanoseconds_with_provider_result {union {temporal_rs::capi::PlainDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_from_epoch_nanoseconds_with_provider_result; + temporal_rs_PlainDateTime_from_epoch_nanoseconds_with_provider_result temporal_rs_PlainDateTime_from_epoch_nanoseconds_with_provider(temporal_rs::capi::I128Nanoseconds ns, temporal_rs::capi::TimeZone tz, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_PlainDateTime_with_result {union {temporal_rs::capi::PlainDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_with_result; + temporal_rs_PlainDateTime_with_result temporal_rs_PlainDateTime_with(const temporal_rs::capi::PlainDateTime* self, temporal_rs::capi::PartialDateTime partial, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_PlainDateTime_with_time_result {union {temporal_rs::capi::PlainDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_with_time_result; + temporal_rs_PlainDateTime_with_time_result temporal_rs_PlainDateTime_with_time(const temporal_rs::capi::PlainDateTime* self, const temporal_rs::capi::PlainTime* time); + + temporal_rs::capi::PlainDateTime* temporal_rs_PlainDateTime_with_calendar(const temporal_rs::capi::PlainDateTime* self, temporal_rs::capi::AnyCalendarKind calendar); + + typedef struct temporal_rs_PlainDateTime_from_utf8_result {union {temporal_rs::capi::PlainDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_from_utf8_result; + temporal_rs_PlainDateTime_from_utf8_result temporal_rs_PlainDateTime_from_utf8(temporal_rs::diplomat::capi::DiplomatStringView s); + + typedef struct temporal_rs_PlainDateTime_from_utf16_result {union {temporal_rs::capi::PlainDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_from_utf16_result; + temporal_rs_PlainDateTime_from_utf16_result temporal_rs_PlainDateTime_from_utf16(temporal_rs::diplomat::capi::DiplomatString16View s); + + uint8_t temporal_rs_PlainDateTime_hour(const temporal_rs::capi::PlainDateTime* self); + + uint8_t temporal_rs_PlainDateTime_minute(const temporal_rs::capi::PlainDateTime* self); + + uint8_t temporal_rs_PlainDateTime_second(const temporal_rs::capi::PlainDateTime* self); + + uint16_t temporal_rs_PlainDateTime_millisecond(const temporal_rs::capi::PlainDateTime* self); + + uint16_t temporal_rs_PlainDateTime_microsecond(const temporal_rs::capi::PlainDateTime* self); + + uint16_t temporal_rs_PlainDateTime_nanosecond(const temporal_rs::capi::PlainDateTime* self); + + const temporal_rs::capi::Calendar* temporal_rs_PlainDateTime_calendar(const temporal_rs::capi::PlainDateTime* self); + + int32_t temporal_rs_PlainDateTime_year(const temporal_rs::capi::PlainDateTime* self); + + uint8_t temporal_rs_PlainDateTime_month(const temporal_rs::capi::PlainDateTime* self); + + void temporal_rs_PlainDateTime_month_code(const temporal_rs::capi::PlainDateTime* self, temporal_rs::diplomat::capi::DiplomatWrite* write); + + uint8_t temporal_rs_PlainDateTime_day(const temporal_rs::capi::PlainDateTime* self); + + uint16_t temporal_rs_PlainDateTime_day_of_week(const temporal_rs::capi::PlainDateTime* self); + + uint16_t temporal_rs_PlainDateTime_day_of_year(const temporal_rs::capi::PlainDateTime* self); + + typedef struct temporal_rs_PlainDateTime_week_of_year_result {union {uint8_t ok; }; bool is_ok;} temporal_rs_PlainDateTime_week_of_year_result; + temporal_rs_PlainDateTime_week_of_year_result temporal_rs_PlainDateTime_week_of_year(const temporal_rs::capi::PlainDateTime* self); + + typedef struct temporal_rs_PlainDateTime_year_of_week_result {union {int32_t ok; }; bool is_ok;} temporal_rs_PlainDateTime_year_of_week_result; + temporal_rs_PlainDateTime_year_of_week_result temporal_rs_PlainDateTime_year_of_week(const temporal_rs::capi::PlainDateTime* self); + + uint16_t temporal_rs_PlainDateTime_days_in_week(const temporal_rs::capi::PlainDateTime* self); + + uint16_t temporal_rs_PlainDateTime_days_in_month(const temporal_rs::capi::PlainDateTime* self); + + uint16_t temporal_rs_PlainDateTime_days_in_year(const temporal_rs::capi::PlainDateTime* self); + + uint16_t temporal_rs_PlainDateTime_months_in_year(const temporal_rs::capi::PlainDateTime* self); + + bool temporal_rs_PlainDateTime_in_leap_year(const temporal_rs::capi::PlainDateTime* self); + + void temporal_rs_PlainDateTime_era(const temporal_rs::capi::PlainDateTime* self, temporal_rs::diplomat::capi::DiplomatWrite* write); + + typedef struct temporal_rs_PlainDateTime_era_year_result {union {int32_t ok; }; bool is_ok;} temporal_rs_PlainDateTime_era_year_result; + temporal_rs_PlainDateTime_era_year_result temporal_rs_PlainDateTime_era_year(const temporal_rs::capi::PlainDateTime* self); + + typedef struct temporal_rs_PlainDateTime_add_result {union {temporal_rs::capi::PlainDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_add_result; + temporal_rs_PlainDateTime_add_result temporal_rs_PlainDateTime_add(const temporal_rs::capi::PlainDateTime* self, const temporal_rs::capi::Duration* duration, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_PlainDateTime_subtract_result {union {temporal_rs::capi::PlainDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_subtract_result; + temporal_rs_PlainDateTime_subtract_result temporal_rs_PlainDateTime_subtract(const temporal_rs::capi::PlainDateTime* self, const temporal_rs::capi::Duration* duration, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_PlainDateTime_until_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_until_result; + temporal_rs_PlainDateTime_until_result temporal_rs_PlainDateTime_until(const temporal_rs::capi::PlainDateTime* self, const temporal_rs::capi::PlainDateTime* other, temporal_rs::capi::DifferenceSettings settings); + + typedef struct temporal_rs_PlainDateTime_since_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_since_result; + temporal_rs_PlainDateTime_since_result temporal_rs_PlainDateTime_since(const temporal_rs::capi::PlainDateTime* self, const temporal_rs::capi::PlainDateTime* other, temporal_rs::capi::DifferenceSettings settings); + + bool temporal_rs_PlainDateTime_equals(const temporal_rs::capi::PlainDateTime* self, const temporal_rs::capi::PlainDateTime* other); + + int8_t temporal_rs_PlainDateTime_compare(const temporal_rs::capi::PlainDateTime* one, const temporal_rs::capi::PlainDateTime* two); + + typedef struct temporal_rs_PlainDateTime_round_result {union {temporal_rs::capi::PlainDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_round_result; + temporal_rs_PlainDateTime_round_result temporal_rs_PlainDateTime_round(const temporal_rs::capi::PlainDateTime* self, temporal_rs::capi::RoundingOptions options); + + temporal_rs::capi::PlainDate* temporal_rs_PlainDateTime_to_plain_date(const temporal_rs::capi::PlainDateTime* self); + + temporal_rs::capi::PlainTime* temporal_rs_PlainDateTime_to_plain_time(const temporal_rs::capi::PlainDateTime* self); + + typedef struct temporal_rs_PlainDateTime_to_zoned_date_time_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_to_zoned_date_time_result; + temporal_rs_PlainDateTime_to_zoned_date_time_result temporal_rs_PlainDateTime_to_zoned_date_time(const temporal_rs::capi::PlainDateTime* self, temporal_rs::capi::TimeZone time_zone, temporal_rs::capi::Disambiguation disambiguation); + + typedef struct temporal_rs_PlainDateTime_to_zoned_date_time_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_to_zoned_date_time_with_provider_result; + temporal_rs_PlainDateTime_to_zoned_date_time_with_provider_result temporal_rs_PlainDateTime_to_zoned_date_time_with_provider(const temporal_rs::capi::PlainDateTime* self, temporal_rs::capi::TimeZone time_zone, temporal_rs::capi::Disambiguation disambiguation, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_PlainDateTime_to_ixdtf_string_result {union { temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_to_ixdtf_string_result; + temporal_rs_PlainDateTime_to_ixdtf_string_result temporal_rs_PlainDateTime_to_ixdtf_string(const temporal_rs::capi::PlainDateTime* self, temporal_rs::capi::ToStringRoundingOptions options, temporal_rs::capi::DisplayCalendar display_calendar, temporal_rs::diplomat::capi::DiplomatWrite* write); + + temporal_rs::capi::PlainDateTime* temporal_rs_PlainDateTime_clone(const temporal_rs::capi::PlainDateTime* self); + + void temporal_rs_PlainDateTime_destroy(PlainDateTime* self); + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::try_new_constrain(int32_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint16_t millisecond, uint16_t microsecond, uint16_t nanosecond, temporal_rs::AnyCalendarKind calendar) { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_try_new_constrain(year, + month, + day, + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + calendar.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::try_new(int32_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint16_t millisecond, uint16_t microsecond, uint16_t nanosecond, temporal_rs::AnyCalendarKind calendar) { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_try_new(year, + month, + day, + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + calendar.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::from_partial(temporal_rs::PartialDateTime partial, std::optional overflow) { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_from_partial(partial.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::from_parsed(const temporal_rs::ParsedDateTime& parsed) { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_from_parsed(parsed.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::from_epoch_milliseconds(int64_t ms, temporal_rs::TimeZone tz) { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_from_epoch_milliseconds(ms, + tz.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::from_epoch_milliseconds_with_provider(int64_t ms, temporal_rs::TimeZone tz, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_from_epoch_milliseconds_with_provider(ms, + tz.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::from_epoch_nanoseconds(temporal_rs::I128Nanoseconds ns, temporal_rs::TimeZone tz) { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_from_epoch_nanoseconds(ns.AsFFI(), + tz.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::from_epoch_nanoseconds_with_provider(temporal_rs::I128Nanoseconds ns, temporal_rs::TimeZone tz, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_from_epoch_nanoseconds_with_provider(ns.AsFFI(), + tz.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::with(temporal_rs::PartialDateTime partial, std::optional overflow) const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_with(this->AsFFI(), + partial.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::with_time(const temporal_rs::PlainTime* time) const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_with_time(this->AsFFI(), + time ? time->AsFFI() : nullptr); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline std::unique_ptr temporal_rs::PlainDateTime::with_calendar(temporal_rs::AnyCalendarKind calendar) const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_with_calendar(this->AsFFI(), + calendar.AsFFI()); + return std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result)); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::from_utf8(std::string_view s) { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_from_utf8({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::from_utf16(std::u16string_view s) { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_from_utf16({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline uint8_t temporal_rs::PlainDateTime::hour() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_hour(this->AsFFI()); + return result; +} + +inline uint8_t temporal_rs::PlainDateTime::minute() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_minute(this->AsFFI()); + return result; +} + +inline uint8_t temporal_rs::PlainDateTime::second() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_second(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainDateTime::millisecond() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_millisecond(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainDateTime::microsecond() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_microsecond(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainDateTime::nanosecond() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_nanosecond(this->AsFFI()); + return result; +} + +inline const temporal_rs::Calendar& temporal_rs::PlainDateTime::calendar() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_calendar(this->AsFFI()); + return *temporal_rs::Calendar::FromFFI(result); +} + +inline int32_t temporal_rs::PlainDateTime::year() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_year(this->AsFFI()); + return result; +} + +inline uint8_t temporal_rs::PlainDateTime::month() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_month(this->AsFFI()); + return result; +} + +inline std::string temporal_rs::PlainDateTime::month_code() const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + temporal_rs::capi::temporal_rs_PlainDateTime_month_code(this->AsFFI(), + &write); + return output; +} +template +inline void temporal_rs::PlainDateTime::month_code_write(W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + temporal_rs::capi::temporal_rs_PlainDateTime_month_code(this->AsFFI(), + &write); +} + +inline uint8_t temporal_rs::PlainDateTime::day() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_day(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainDateTime::day_of_week() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_day_of_week(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainDateTime::day_of_year() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_day_of_year(this->AsFFI()); + return result; +} + +inline std::optional temporal_rs::PlainDateTime::week_of_year() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_week_of_year(this->AsFFI()); + return result.is_ok ? std::optional(result.ok) : std::nullopt; +} + +inline std::optional temporal_rs::PlainDateTime::year_of_week() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_year_of_week(this->AsFFI()); + return result.is_ok ? std::optional(result.ok) : std::nullopt; +} + +inline uint16_t temporal_rs::PlainDateTime::days_in_week() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_days_in_week(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainDateTime::days_in_month() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_days_in_month(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainDateTime::days_in_year() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_days_in_year(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainDateTime::months_in_year() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_months_in_year(this->AsFFI()); + return result; +} + +inline bool temporal_rs::PlainDateTime::in_leap_year() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_in_leap_year(this->AsFFI()); + return result; +} + +inline std::string temporal_rs::PlainDateTime::era() const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + temporal_rs::capi::temporal_rs_PlainDateTime_era(this->AsFFI(), + &write); + return output; +} +template +inline void temporal_rs::PlainDateTime::era_write(W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + temporal_rs::capi::temporal_rs_PlainDateTime_era(this->AsFFI(), + &write); +} + +inline std::optional temporal_rs::PlainDateTime::era_year() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_era_year(this->AsFFI()); + return result.is_ok ? std::optional(result.ok) : std::nullopt; +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::add(const temporal_rs::Duration& duration, std::optional overflow) const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_add(this->AsFFI(), + duration.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::subtract(const temporal_rs::Duration& duration, std::optional overflow) const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_subtract(this->AsFFI(), + duration.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::until(const temporal_rs::PlainDateTime& other, temporal_rs::DifferenceSettings settings) const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_until(this->AsFFI(), + other.AsFFI(), + settings.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::since(const temporal_rs::PlainDateTime& other, temporal_rs::DifferenceSettings settings) const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_since(this->AsFFI(), + other.AsFFI(), + settings.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline bool temporal_rs::PlainDateTime::equals(const temporal_rs::PlainDateTime& other) const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_equals(this->AsFFI(), + other.AsFFI()); + return result; +} + +inline int8_t temporal_rs::PlainDateTime::compare(const temporal_rs::PlainDateTime& one, const temporal_rs::PlainDateTime& two) { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_compare(one.AsFFI(), + two.AsFFI()); + return result; +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::round(temporal_rs::RoundingOptions options) const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_round(this->AsFFI(), + options.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline std::unique_ptr temporal_rs::PlainDateTime::to_plain_date() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_to_plain_date(this->AsFFI()); + return std::unique_ptr(temporal_rs::PlainDate::FromFFI(result)); +} + +inline std::unique_ptr temporal_rs::PlainDateTime::to_plain_time() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_to_plain_time(this->AsFFI()); + return std::unique_ptr(temporal_rs::PlainTime::FromFFI(result)); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::to_zoned_date_time(temporal_rs::TimeZone time_zone, temporal_rs::Disambiguation disambiguation) const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_to_zoned_date_time(this->AsFFI(), + time_zone.AsFFI(), + disambiguation.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainDateTime::to_zoned_date_time_with_provider(temporal_rs::TimeZone time_zone, temporal_rs::Disambiguation disambiguation, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_to_zoned_date_time_with_provider(this->AsFFI(), + time_zone.AsFFI(), + disambiguation.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::PlainDateTime::to_ixdtf_string(temporal_rs::ToStringRoundingOptions options, temporal_rs::DisplayCalendar display_calendar) const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_to_ixdtf_string(this->AsFFI(), + options.AsFFI(), + display_calendar.AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(std::move(output))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} +template +inline temporal_rs::diplomat::result temporal_rs::PlainDateTime::to_ixdtf_string_write(temporal_rs::ToStringRoundingOptions options, temporal_rs::DisplayCalendar display_calendar, W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_to_ixdtf_string(this->AsFFI(), + options.AsFFI(), + display_calendar.AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok()) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline std::unique_ptr temporal_rs::PlainDateTime::clone() const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_clone(this->AsFFI()); + return std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result)); +} + +inline const temporal_rs::capi::PlainDateTime* temporal_rs::PlainDateTime::AsFFI() const { + return reinterpret_cast(this); +} + +inline temporal_rs::capi::PlainDateTime* temporal_rs::PlainDateTime::AsFFI() { + return reinterpret_cast(this); +} + +inline const temporal_rs::PlainDateTime* temporal_rs::PlainDateTime::FromFFI(const temporal_rs::capi::PlainDateTime* ptr) { + return reinterpret_cast(ptr); +} + +inline temporal_rs::PlainDateTime* temporal_rs::PlainDateTime::FromFFI(temporal_rs::capi::PlainDateTime* ptr) { + return reinterpret_cast(ptr); +} + +inline void temporal_rs::PlainDateTime::operator delete(void* ptr) { + temporal_rs::capi::temporal_rs_PlainDateTime_destroy(reinterpret_cast(ptr)); +} + + +#endif // TEMPORAL_RS_PlainDateTime_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainMonthDay.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainMonthDay.d.hpp new file mode 100644 index 00000000000000..5638252ac2fd00 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainMonthDay.d.hpp @@ -0,0 +1,93 @@ +#ifndef TEMPORAL_RS_PlainMonthDay_D_HPP +#define TEMPORAL_RS_PlainMonthDay_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +namespace capi { struct Calendar; } +class Calendar; +namespace capi { struct ParsedDate; } +class ParsedDate; +namespace capi { struct PlainDate; } +class PlainDate; +namespace capi { struct PlainMonthDay; } +class PlainMonthDay; +namespace capi { struct Provider; } +class Provider; +struct PartialDate; +struct TemporalError; +struct TimeZone; +class AnyCalendarKind; +class ArithmeticOverflow; +class DisplayCalendar; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct PlainMonthDay; +} // namespace capi +} // namespace + +namespace temporal_rs { +class PlainMonthDay { +public: + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> try_new_with_overflow(uint8_t month, uint8_t day, temporal_rs::AnyCalendarKind calendar, temporal_rs::ArithmeticOverflow overflow, std::optional ref_year); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_partial(temporal_rs::PartialDate partial, std::optional overflow); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_parsed(const temporal_rs::ParsedDate& parsed); + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> with(temporal_rs::PartialDate partial, std::optional overflow) const; + + inline bool equals(const temporal_rs::PlainMonthDay& other) const; + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf8(std::string_view s); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf16(std::u16string_view s); + + inline uint8_t day() const; + + inline const temporal_rs::Calendar& calendar() const; + + inline std::string month_code() const; + template + inline void month_code_write(W& writeable_output) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> to_plain_date(std::optional year) const; + + inline temporal_rs::diplomat::result epoch_ms_for(temporal_rs::TimeZone time_zone) const; + + inline temporal_rs::diplomat::result epoch_ms_for_with_provider(temporal_rs::TimeZone time_zone, const temporal_rs::Provider& p) const; + + inline std::string to_ixdtf_string(temporal_rs::DisplayCalendar display_calendar) const; + template + inline void to_ixdtf_string_write(temporal_rs::DisplayCalendar display_calendar, W& writeable_output) const; + + inline std::unique_ptr clone() const; + + inline const temporal_rs::capi::PlainMonthDay* AsFFI() const; + inline temporal_rs::capi::PlainMonthDay* AsFFI(); + inline static const temporal_rs::PlainMonthDay* FromFFI(const temporal_rs::capi::PlainMonthDay* ptr); + inline static temporal_rs::PlainMonthDay* FromFFI(temporal_rs::capi::PlainMonthDay* ptr); + inline static void operator delete(void* ptr); +private: + PlainMonthDay() = delete; + PlainMonthDay(const temporal_rs::PlainMonthDay&) = delete; + PlainMonthDay(temporal_rs::PlainMonthDay&&) noexcept = delete; + PlainMonthDay operator=(const temporal_rs::PlainMonthDay&) = delete; + PlainMonthDay operator=(temporal_rs::PlainMonthDay&&) noexcept = delete; + static void operator delete[](void*, size_t) = delete; +}; + +} // namespace +#endif // TEMPORAL_RS_PlainMonthDay_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainMonthDay.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainMonthDay.hpp new file mode 100644 index 00000000000000..01e409f4ca5b1a --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainMonthDay.hpp @@ -0,0 +1,204 @@ +#ifndef TEMPORAL_RS_PlainMonthDay_HPP +#define TEMPORAL_RS_PlainMonthDay_HPP + +#include "PlainMonthDay.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "AnyCalendarKind.hpp" +#include "ArithmeticOverflow.hpp" +#include "Calendar.hpp" +#include "DisplayCalendar.hpp" +#include "ParsedDate.hpp" +#include "PartialDate.hpp" +#include "PlainDate.hpp" +#include "Provider.hpp" +#include "TemporalError.hpp" +#include "TimeZone.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + typedef struct temporal_rs_PlainMonthDay_try_new_with_overflow_result {union {temporal_rs::capi::PlainMonthDay* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_try_new_with_overflow_result; + temporal_rs_PlainMonthDay_try_new_with_overflow_result temporal_rs_PlainMonthDay_try_new_with_overflow(uint8_t month, uint8_t day, temporal_rs::capi::AnyCalendarKind calendar, temporal_rs::capi::ArithmeticOverflow overflow, temporal_rs::diplomat::capi::OptionI32 ref_year); + + typedef struct temporal_rs_PlainMonthDay_from_partial_result {union {temporal_rs::capi::PlainMonthDay* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_from_partial_result; + temporal_rs_PlainMonthDay_from_partial_result temporal_rs_PlainMonthDay_from_partial(temporal_rs::capi::PartialDate partial, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_PlainMonthDay_from_parsed_result {union {temporal_rs::capi::PlainMonthDay* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_from_parsed_result; + temporal_rs_PlainMonthDay_from_parsed_result temporal_rs_PlainMonthDay_from_parsed(const temporal_rs::capi::ParsedDate* parsed); + + typedef struct temporal_rs_PlainMonthDay_with_result {union {temporal_rs::capi::PlainMonthDay* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_with_result; + temporal_rs_PlainMonthDay_with_result temporal_rs_PlainMonthDay_with(const temporal_rs::capi::PlainMonthDay* self, temporal_rs::capi::PartialDate partial, temporal_rs::capi::ArithmeticOverflow_option overflow); + + bool temporal_rs_PlainMonthDay_equals(const temporal_rs::capi::PlainMonthDay* self, const temporal_rs::capi::PlainMonthDay* other); + + typedef struct temporal_rs_PlainMonthDay_from_utf8_result {union {temporal_rs::capi::PlainMonthDay* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_from_utf8_result; + temporal_rs_PlainMonthDay_from_utf8_result temporal_rs_PlainMonthDay_from_utf8(temporal_rs::diplomat::capi::DiplomatStringView s); + + typedef struct temporal_rs_PlainMonthDay_from_utf16_result {union {temporal_rs::capi::PlainMonthDay* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_from_utf16_result; + temporal_rs_PlainMonthDay_from_utf16_result temporal_rs_PlainMonthDay_from_utf16(temporal_rs::diplomat::capi::DiplomatString16View s); + + uint8_t temporal_rs_PlainMonthDay_day(const temporal_rs::capi::PlainMonthDay* self); + + const temporal_rs::capi::Calendar* temporal_rs_PlainMonthDay_calendar(const temporal_rs::capi::PlainMonthDay* self); + + void temporal_rs_PlainMonthDay_month_code(const temporal_rs::capi::PlainMonthDay* self, temporal_rs::diplomat::capi::DiplomatWrite* write); + + typedef struct temporal_rs_PlainMonthDay_to_plain_date_result {union {temporal_rs::capi::PlainDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_to_plain_date_result; + temporal_rs_PlainMonthDay_to_plain_date_result temporal_rs_PlainMonthDay_to_plain_date(const temporal_rs::capi::PlainMonthDay* self, temporal_rs::capi::PartialDate_option year); + + typedef struct temporal_rs_PlainMonthDay_epoch_ms_for_result {union {int64_t ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_epoch_ms_for_result; + temporal_rs_PlainMonthDay_epoch_ms_for_result temporal_rs_PlainMonthDay_epoch_ms_for(const temporal_rs::capi::PlainMonthDay* self, temporal_rs::capi::TimeZone time_zone); + + typedef struct temporal_rs_PlainMonthDay_epoch_ms_for_with_provider_result {union {int64_t ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainMonthDay_epoch_ms_for_with_provider_result; + temporal_rs_PlainMonthDay_epoch_ms_for_with_provider_result temporal_rs_PlainMonthDay_epoch_ms_for_with_provider(const temporal_rs::capi::PlainMonthDay* self, temporal_rs::capi::TimeZone time_zone, const temporal_rs::capi::Provider* p); + + void temporal_rs_PlainMonthDay_to_ixdtf_string(const temporal_rs::capi::PlainMonthDay* self, temporal_rs::capi::DisplayCalendar display_calendar, temporal_rs::diplomat::capi::DiplomatWrite* write); + + temporal_rs::capi::PlainMonthDay* temporal_rs_PlainMonthDay_clone(const temporal_rs::capi::PlainMonthDay* self); + + void temporal_rs_PlainMonthDay_destroy(PlainMonthDay* self); + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainMonthDay::try_new_with_overflow(uint8_t month, uint8_t day, temporal_rs::AnyCalendarKind calendar, temporal_rs::ArithmeticOverflow overflow, std::optional ref_year) { + auto result = temporal_rs::capi::temporal_rs_PlainMonthDay_try_new_with_overflow(month, + day, + calendar.AsFFI(), + overflow.AsFFI(), + ref_year.has_value() ? (temporal_rs::diplomat::capi::OptionI32{ { ref_year.value() }, true }) : (temporal_rs::diplomat::capi::OptionI32{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainMonthDay::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainMonthDay::from_partial(temporal_rs::PartialDate partial, std::optional overflow) { + auto result = temporal_rs::capi::temporal_rs_PlainMonthDay_from_partial(partial.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainMonthDay::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainMonthDay::from_parsed(const temporal_rs::ParsedDate& parsed) { + auto result = temporal_rs::capi::temporal_rs_PlainMonthDay_from_parsed(parsed.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainMonthDay::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainMonthDay::with(temporal_rs::PartialDate partial, std::optional overflow) const { + auto result = temporal_rs::capi::temporal_rs_PlainMonthDay_with(this->AsFFI(), + partial.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainMonthDay::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline bool temporal_rs::PlainMonthDay::equals(const temporal_rs::PlainMonthDay& other) const { + auto result = temporal_rs::capi::temporal_rs_PlainMonthDay_equals(this->AsFFI(), + other.AsFFI()); + return result; +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainMonthDay::from_utf8(std::string_view s) { + auto result = temporal_rs::capi::temporal_rs_PlainMonthDay_from_utf8({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainMonthDay::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainMonthDay::from_utf16(std::u16string_view s) { + auto result = temporal_rs::capi::temporal_rs_PlainMonthDay_from_utf16({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainMonthDay::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline uint8_t temporal_rs::PlainMonthDay::day() const { + auto result = temporal_rs::capi::temporal_rs_PlainMonthDay_day(this->AsFFI()); + return result; +} + +inline const temporal_rs::Calendar& temporal_rs::PlainMonthDay::calendar() const { + auto result = temporal_rs::capi::temporal_rs_PlainMonthDay_calendar(this->AsFFI()); + return *temporal_rs::Calendar::FromFFI(result); +} + +inline std::string temporal_rs::PlainMonthDay::month_code() const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + temporal_rs::capi::temporal_rs_PlainMonthDay_month_code(this->AsFFI(), + &write); + return output; +} +template +inline void temporal_rs::PlainMonthDay::month_code_write(W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + temporal_rs::capi::temporal_rs_PlainMonthDay_month_code(this->AsFFI(), + &write); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainMonthDay::to_plain_date(std::optional year) const { + auto result = temporal_rs::capi::temporal_rs_PlainMonthDay_to_plain_date(this->AsFFI(), + year.has_value() ? (temporal_rs::capi::PartialDate_option{ { year.value().AsFFI() }, true }) : (temporal_rs::capi::PartialDate_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::PlainMonthDay::epoch_ms_for(temporal_rs::TimeZone time_zone) const { + auto result = temporal_rs::capi::temporal_rs_PlainMonthDay_epoch_ms_for(this->AsFFI(), + time_zone.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(result.ok)) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::PlainMonthDay::epoch_ms_for_with_provider(temporal_rs::TimeZone time_zone, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_PlainMonthDay_epoch_ms_for_with_provider(this->AsFFI(), + time_zone.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(result.ok)) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline std::string temporal_rs::PlainMonthDay::to_ixdtf_string(temporal_rs::DisplayCalendar display_calendar) const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + temporal_rs::capi::temporal_rs_PlainMonthDay_to_ixdtf_string(this->AsFFI(), + display_calendar.AsFFI(), + &write); + return output; +} +template +inline void temporal_rs::PlainMonthDay::to_ixdtf_string_write(temporal_rs::DisplayCalendar display_calendar, W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + temporal_rs::capi::temporal_rs_PlainMonthDay_to_ixdtf_string(this->AsFFI(), + display_calendar.AsFFI(), + &write); +} + +inline std::unique_ptr temporal_rs::PlainMonthDay::clone() const { + auto result = temporal_rs::capi::temporal_rs_PlainMonthDay_clone(this->AsFFI()); + return std::unique_ptr(temporal_rs::PlainMonthDay::FromFFI(result)); +} + +inline const temporal_rs::capi::PlainMonthDay* temporal_rs::PlainMonthDay::AsFFI() const { + return reinterpret_cast(this); +} + +inline temporal_rs::capi::PlainMonthDay* temporal_rs::PlainMonthDay::AsFFI() { + return reinterpret_cast(this); +} + +inline const temporal_rs::PlainMonthDay* temporal_rs::PlainMonthDay::FromFFI(const temporal_rs::capi::PlainMonthDay* ptr) { + return reinterpret_cast(ptr); +} + +inline temporal_rs::PlainMonthDay* temporal_rs::PlainMonthDay::FromFFI(temporal_rs::capi::PlainMonthDay* ptr) { + return reinterpret_cast(ptr); +} + +inline void temporal_rs::PlainMonthDay::operator delete(void* ptr) { + temporal_rs::capi::temporal_rs_PlainMonthDay_destroy(reinterpret_cast(ptr)); +} + + +#endif // TEMPORAL_RS_PlainMonthDay_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainTime.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainTime.d.hpp new file mode 100644 index 00000000000000..b4f01054eb44dc --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainTime.d.hpp @@ -0,0 +1,109 @@ +#ifndef TEMPORAL_RS_PlainTime_D_HPP +#define TEMPORAL_RS_PlainTime_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +namespace capi { struct Duration; } +class Duration; +namespace capi { struct PlainTime; } +class PlainTime; +namespace capi { struct Provider; } +class Provider; +struct DifferenceSettings; +struct I128Nanoseconds; +struct PartialTime; +struct RoundingOptions; +struct TemporalError; +struct TimeZone; +struct ToStringRoundingOptions; +class ArithmeticOverflow; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct PlainTime; +} // namespace capi +} // namespace + +namespace temporal_rs { +class PlainTime { +public: + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> try_new_constrain(uint8_t hour, uint8_t minute, uint8_t second, uint16_t millisecond, uint16_t microsecond, uint16_t nanosecond); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> try_new(uint8_t hour, uint8_t minute, uint8_t second, uint16_t millisecond, uint16_t microsecond, uint16_t nanosecond); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_partial(temporal_rs::PartialTime partial, std::optional overflow); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_milliseconds(int64_t ms, temporal_rs::TimeZone tz); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_milliseconds_with_provider(int64_t ms, temporal_rs::TimeZone tz, const temporal_rs::Provider& p); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_nanoseconds(temporal_rs::I128Nanoseconds ns, temporal_rs::TimeZone tz); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_nanoseconds_with_provider(temporal_rs::I128Nanoseconds ns, temporal_rs::TimeZone tz, const temporal_rs::Provider& p); + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> with(temporal_rs::PartialTime partial, std::optional overflow) const; + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf8(std::string_view s); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf16(std::u16string_view s); + + inline uint8_t hour() const; + + inline uint8_t minute() const; + + inline uint8_t second() const; + + inline uint16_t millisecond() const; + + inline uint16_t microsecond() const; + + inline uint16_t nanosecond() const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> add(const temporal_rs::Duration& duration) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> subtract(const temporal_rs::Duration& duration) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> until(const temporal_rs::PlainTime& other, temporal_rs::DifferenceSettings settings) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> since(const temporal_rs::PlainTime& other, temporal_rs::DifferenceSettings settings) const; + + inline bool equals(const temporal_rs::PlainTime& other) const; + + inline static int8_t compare(const temporal_rs::PlainTime& one, const temporal_rs::PlainTime& two); + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> round(temporal_rs::RoundingOptions options) const; + + inline temporal_rs::diplomat::result to_ixdtf_string(temporal_rs::ToStringRoundingOptions options) const; + template + inline temporal_rs::diplomat::result to_ixdtf_string_write(temporal_rs::ToStringRoundingOptions options, W& writeable_output) const; + + inline std::unique_ptr clone() const; + + inline const temporal_rs::capi::PlainTime* AsFFI() const; + inline temporal_rs::capi::PlainTime* AsFFI(); + inline static const temporal_rs::PlainTime* FromFFI(const temporal_rs::capi::PlainTime* ptr); + inline static temporal_rs::PlainTime* FromFFI(temporal_rs::capi::PlainTime* ptr); + inline static void operator delete(void* ptr); +private: + PlainTime() = delete; + PlainTime(const temporal_rs::PlainTime&) = delete; + PlainTime(temporal_rs::PlainTime&&) noexcept = delete; + PlainTime operator=(const temporal_rs::PlainTime&) = delete; + PlainTime operator=(temporal_rs::PlainTime&&) noexcept = delete; + static void operator delete[](void*, size_t) = delete; +}; + +} // namespace +#endif // TEMPORAL_RS_PlainTime_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainTime.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainTime.hpp new file mode 100644 index 00000000000000..b15878bcbbc623 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainTime.hpp @@ -0,0 +1,289 @@ +#ifndef TEMPORAL_RS_PlainTime_HPP +#define TEMPORAL_RS_PlainTime_HPP + +#include "PlainTime.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ArithmeticOverflow.hpp" +#include "DifferenceSettings.hpp" +#include "Duration.hpp" +#include "I128Nanoseconds.hpp" +#include "PartialTime.hpp" +#include "Provider.hpp" +#include "RoundingOptions.hpp" +#include "TemporalError.hpp" +#include "TimeZone.hpp" +#include "ToStringRoundingOptions.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + typedef struct temporal_rs_PlainTime_try_new_constrain_result {union {temporal_rs::capi::PlainTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_try_new_constrain_result; + temporal_rs_PlainTime_try_new_constrain_result temporal_rs_PlainTime_try_new_constrain(uint8_t hour, uint8_t minute, uint8_t second, uint16_t millisecond, uint16_t microsecond, uint16_t nanosecond); + + typedef struct temporal_rs_PlainTime_try_new_result {union {temporal_rs::capi::PlainTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_try_new_result; + temporal_rs_PlainTime_try_new_result temporal_rs_PlainTime_try_new(uint8_t hour, uint8_t minute, uint8_t second, uint16_t millisecond, uint16_t microsecond, uint16_t nanosecond); + + typedef struct temporal_rs_PlainTime_from_partial_result {union {temporal_rs::capi::PlainTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_from_partial_result; + temporal_rs_PlainTime_from_partial_result temporal_rs_PlainTime_from_partial(temporal_rs::capi::PartialTime partial, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_PlainTime_from_epoch_milliseconds_result {union {temporal_rs::capi::PlainTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_from_epoch_milliseconds_result; + temporal_rs_PlainTime_from_epoch_milliseconds_result temporal_rs_PlainTime_from_epoch_milliseconds(int64_t ms, temporal_rs::capi::TimeZone tz); + + typedef struct temporal_rs_PlainTime_from_epoch_milliseconds_with_provider_result {union {temporal_rs::capi::PlainTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_from_epoch_milliseconds_with_provider_result; + temporal_rs_PlainTime_from_epoch_milliseconds_with_provider_result temporal_rs_PlainTime_from_epoch_milliseconds_with_provider(int64_t ms, temporal_rs::capi::TimeZone tz, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_PlainTime_from_epoch_nanoseconds_result {union {temporal_rs::capi::PlainTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_from_epoch_nanoseconds_result; + temporal_rs_PlainTime_from_epoch_nanoseconds_result temporal_rs_PlainTime_from_epoch_nanoseconds(temporal_rs::capi::I128Nanoseconds ns, temporal_rs::capi::TimeZone tz); + + typedef struct temporal_rs_PlainTime_from_epoch_nanoseconds_with_provider_result {union {temporal_rs::capi::PlainTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_from_epoch_nanoseconds_with_provider_result; + temporal_rs_PlainTime_from_epoch_nanoseconds_with_provider_result temporal_rs_PlainTime_from_epoch_nanoseconds_with_provider(temporal_rs::capi::I128Nanoseconds ns, temporal_rs::capi::TimeZone tz, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_PlainTime_with_result {union {temporal_rs::capi::PlainTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_with_result; + temporal_rs_PlainTime_with_result temporal_rs_PlainTime_with(const temporal_rs::capi::PlainTime* self, temporal_rs::capi::PartialTime partial, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_PlainTime_from_utf8_result {union {temporal_rs::capi::PlainTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_from_utf8_result; + temporal_rs_PlainTime_from_utf8_result temporal_rs_PlainTime_from_utf8(temporal_rs::diplomat::capi::DiplomatStringView s); + + typedef struct temporal_rs_PlainTime_from_utf16_result {union {temporal_rs::capi::PlainTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_from_utf16_result; + temporal_rs_PlainTime_from_utf16_result temporal_rs_PlainTime_from_utf16(temporal_rs::diplomat::capi::DiplomatString16View s); + + uint8_t temporal_rs_PlainTime_hour(const temporal_rs::capi::PlainTime* self); + + uint8_t temporal_rs_PlainTime_minute(const temporal_rs::capi::PlainTime* self); + + uint8_t temporal_rs_PlainTime_second(const temporal_rs::capi::PlainTime* self); + + uint16_t temporal_rs_PlainTime_millisecond(const temporal_rs::capi::PlainTime* self); + + uint16_t temporal_rs_PlainTime_microsecond(const temporal_rs::capi::PlainTime* self); + + uint16_t temporal_rs_PlainTime_nanosecond(const temporal_rs::capi::PlainTime* self); + + typedef struct temporal_rs_PlainTime_add_result {union {temporal_rs::capi::PlainTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_add_result; + temporal_rs_PlainTime_add_result temporal_rs_PlainTime_add(const temporal_rs::capi::PlainTime* self, const temporal_rs::capi::Duration* duration); + + typedef struct temporal_rs_PlainTime_subtract_result {union {temporal_rs::capi::PlainTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_subtract_result; + temporal_rs_PlainTime_subtract_result temporal_rs_PlainTime_subtract(const temporal_rs::capi::PlainTime* self, const temporal_rs::capi::Duration* duration); + + typedef struct temporal_rs_PlainTime_until_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_until_result; + temporal_rs_PlainTime_until_result temporal_rs_PlainTime_until(const temporal_rs::capi::PlainTime* self, const temporal_rs::capi::PlainTime* other, temporal_rs::capi::DifferenceSettings settings); + + typedef struct temporal_rs_PlainTime_since_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_since_result; + temporal_rs_PlainTime_since_result temporal_rs_PlainTime_since(const temporal_rs::capi::PlainTime* self, const temporal_rs::capi::PlainTime* other, temporal_rs::capi::DifferenceSettings settings); + + bool temporal_rs_PlainTime_equals(const temporal_rs::capi::PlainTime* self, const temporal_rs::capi::PlainTime* other); + + int8_t temporal_rs_PlainTime_compare(const temporal_rs::capi::PlainTime* one, const temporal_rs::capi::PlainTime* two); + + typedef struct temporal_rs_PlainTime_round_result {union {temporal_rs::capi::PlainTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_round_result; + temporal_rs_PlainTime_round_result temporal_rs_PlainTime_round(const temporal_rs::capi::PlainTime* self, temporal_rs::capi::RoundingOptions options); + + typedef struct temporal_rs_PlainTime_to_ixdtf_string_result {union { temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_to_ixdtf_string_result; + temporal_rs_PlainTime_to_ixdtf_string_result temporal_rs_PlainTime_to_ixdtf_string(const temporal_rs::capi::PlainTime* self, temporal_rs::capi::ToStringRoundingOptions options, temporal_rs::diplomat::capi::DiplomatWrite* write); + + temporal_rs::capi::PlainTime* temporal_rs_PlainTime_clone(const temporal_rs::capi::PlainTime* self); + + void temporal_rs_PlainTime_destroy(PlainTime* self); + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainTime::try_new_constrain(uint8_t hour, uint8_t minute, uint8_t second, uint16_t millisecond, uint16_t microsecond, uint16_t nanosecond) { + auto result = temporal_rs::capi::temporal_rs_PlainTime_try_new_constrain(hour, + minute, + second, + millisecond, + microsecond, + nanosecond); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainTime::try_new(uint8_t hour, uint8_t minute, uint8_t second, uint16_t millisecond, uint16_t microsecond, uint16_t nanosecond) { + auto result = temporal_rs::capi::temporal_rs_PlainTime_try_new(hour, + minute, + second, + millisecond, + microsecond, + nanosecond); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainTime::from_partial(temporal_rs::PartialTime partial, std::optional overflow) { + auto result = temporal_rs::capi::temporal_rs_PlainTime_from_partial(partial.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainTime::from_epoch_milliseconds(int64_t ms, temporal_rs::TimeZone tz) { + auto result = temporal_rs::capi::temporal_rs_PlainTime_from_epoch_milliseconds(ms, + tz.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainTime::from_epoch_milliseconds_with_provider(int64_t ms, temporal_rs::TimeZone tz, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_PlainTime_from_epoch_milliseconds_with_provider(ms, + tz.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainTime::from_epoch_nanoseconds(temporal_rs::I128Nanoseconds ns, temporal_rs::TimeZone tz) { + auto result = temporal_rs::capi::temporal_rs_PlainTime_from_epoch_nanoseconds(ns.AsFFI(), + tz.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainTime::from_epoch_nanoseconds_with_provider(temporal_rs::I128Nanoseconds ns, temporal_rs::TimeZone tz, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_PlainTime_from_epoch_nanoseconds_with_provider(ns.AsFFI(), + tz.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainTime::with(temporal_rs::PartialTime partial, std::optional overflow) const { + auto result = temporal_rs::capi::temporal_rs_PlainTime_with(this->AsFFI(), + partial.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainTime::from_utf8(std::string_view s) { + auto result = temporal_rs::capi::temporal_rs_PlainTime_from_utf8({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainTime::from_utf16(std::u16string_view s) { + auto result = temporal_rs::capi::temporal_rs_PlainTime_from_utf16({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline uint8_t temporal_rs::PlainTime::hour() const { + auto result = temporal_rs::capi::temporal_rs_PlainTime_hour(this->AsFFI()); + return result; +} + +inline uint8_t temporal_rs::PlainTime::minute() const { + auto result = temporal_rs::capi::temporal_rs_PlainTime_minute(this->AsFFI()); + return result; +} + +inline uint8_t temporal_rs::PlainTime::second() const { + auto result = temporal_rs::capi::temporal_rs_PlainTime_second(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainTime::millisecond() const { + auto result = temporal_rs::capi::temporal_rs_PlainTime_millisecond(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainTime::microsecond() const { + auto result = temporal_rs::capi::temporal_rs_PlainTime_microsecond(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainTime::nanosecond() const { + auto result = temporal_rs::capi::temporal_rs_PlainTime_nanosecond(this->AsFFI()); + return result; +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainTime::add(const temporal_rs::Duration& duration) const { + auto result = temporal_rs::capi::temporal_rs_PlainTime_add(this->AsFFI(), + duration.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainTime::subtract(const temporal_rs::Duration& duration) const { + auto result = temporal_rs::capi::temporal_rs_PlainTime_subtract(this->AsFFI(), + duration.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainTime::until(const temporal_rs::PlainTime& other, temporal_rs::DifferenceSettings settings) const { + auto result = temporal_rs::capi::temporal_rs_PlainTime_until(this->AsFFI(), + other.AsFFI(), + settings.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainTime::since(const temporal_rs::PlainTime& other, temporal_rs::DifferenceSettings settings) const { + auto result = temporal_rs::capi::temporal_rs_PlainTime_since(this->AsFFI(), + other.AsFFI(), + settings.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline bool temporal_rs::PlainTime::equals(const temporal_rs::PlainTime& other) const { + auto result = temporal_rs::capi::temporal_rs_PlainTime_equals(this->AsFFI(), + other.AsFFI()); + return result; +} + +inline int8_t temporal_rs::PlainTime::compare(const temporal_rs::PlainTime& one, const temporal_rs::PlainTime& two) { + auto result = temporal_rs::capi::temporal_rs_PlainTime_compare(one.AsFFI(), + two.AsFFI()); + return result; +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainTime::round(temporal_rs::RoundingOptions options) const { + auto result = temporal_rs::capi::temporal_rs_PlainTime_round(this->AsFFI(), + options.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::PlainTime::to_ixdtf_string(temporal_rs::ToStringRoundingOptions options) const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + auto result = temporal_rs::capi::temporal_rs_PlainTime_to_ixdtf_string(this->AsFFI(), + options.AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(std::move(output))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} +template +inline temporal_rs::diplomat::result temporal_rs::PlainTime::to_ixdtf_string_write(temporal_rs::ToStringRoundingOptions options, W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + auto result = temporal_rs::capi::temporal_rs_PlainTime_to_ixdtf_string(this->AsFFI(), + options.AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok()) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline std::unique_ptr temporal_rs::PlainTime::clone() const { + auto result = temporal_rs::capi::temporal_rs_PlainTime_clone(this->AsFFI()); + return std::unique_ptr(temporal_rs::PlainTime::FromFFI(result)); +} + +inline const temporal_rs::capi::PlainTime* temporal_rs::PlainTime::AsFFI() const { + return reinterpret_cast(this); +} + +inline temporal_rs::capi::PlainTime* temporal_rs::PlainTime::AsFFI() { + return reinterpret_cast(this); +} + +inline const temporal_rs::PlainTime* temporal_rs::PlainTime::FromFFI(const temporal_rs::capi::PlainTime* ptr) { + return reinterpret_cast(ptr); +} + +inline temporal_rs::PlainTime* temporal_rs::PlainTime::FromFFI(temporal_rs::capi::PlainTime* ptr) { + return reinterpret_cast(ptr); +} + +inline void temporal_rs::PlainTime::operator delete(void* ptr) { + temporal_rs::capi::temporal_rs_PlainTime_destroy(reinterpret_cast(ptr)); +} + + +#endif // TEMPORAL_RS_PlainTime_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainYearMonth.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainYearMonth.d.hpp new file mode 100644 index 00000000000000..b6ea924834db08 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainYearMonth.d.hpp @@ -0,0 +1,122 @@ +#ifndef TEMPORAL_RS_PlainYearMonth_D_HPP +#define TEMPORAL_RS_PlainYearMonth_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +namespace capi { struct Calendar; } +class Calendar; +namespace capi { struct Duration; } +class Duration; +namespace capi { struct ParsedDate; } +class ParsedDate; +namespace capi { struct PlainDate; } +class PlainDate; +namespace capi { struct PlainYearMonth; } +class PlainYearMonth; +namespace capi { struct Provider; } +class Provider; +struct DifferenceSettings; +struct PartialDate; +struct TemporalError; +struct TimeZone; +class AnyCalendarKind; +class ArithmeticOverflow; +class DisplayCalendar; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct PlainYearMonth; +} // namespace capi +} // namespace + +namespace temporal_rs { +class PlainYearMonth { +public: + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> try_new_with_overflow(int32_t year, uint8_t month, std::optional reference_day, temporal_rs::AnyCalendarKind calendar, temporal_rs::ArithmeticOverflow overflow); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_partial(temporal_rs::PartialDate partial, std::optional overflow); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_parsed(const temporal_rs::ParsedDate& parsed); + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> with(temporal_rs::PartialDate partial, std::optional overflow) const; + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf8(std::string_view s); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf16(std::u16string_view s); + + inline int32_t year() const; + + inline uint8_t month() const; + + inline std::string month_code() const; + template + inline void month_code_write(W& writeable_output) const; + + inline bool in_leap_year() const; + + inline uint16_t days_in_month() const; + + inline uint16_t days_in_year() const; + + inline uint16_t months_in_year() const; + + inline std::string era() const; + template + inline void era_write(W& writeable_output) const; + + inline std::optional era_year() const; + + inline const temporal_rs::Calendar& calendar() const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> add(const temporal_rs::Duration& duration, temporal_rs::ArithmeticOverflow overflow) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> subtract(const temporal_rs::Duration& duration, temporal_rs::ArithmeticOverflow overflow) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> until(const temporal_rs::PlainYearMonth& other, temporal_rs::DifferenceSettings settings) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> since(const temporal_rs::PlainYearMonth& other, temporal_rs::DifferenceSettings settings) const; + + inline bool equals(const temporal_rs::PlainYearMonth& other) const; + + inline static int8_t compare(const temporal_rs::PlainYearMonth& one, const temporal_rs::PlainYearMonth& two); + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> to_plain_date(std::optional day) const; + + inline temporal_rs::diplomat::result epoch_ms_for(temporal_rs::TimeZone time_zone) const; + + inline temporal_rs::diplomat::result epoch_ms_for_with_provider(temporal_rs::TimeZone time_zone, const temporal_rs::Provider& p) const; + + inline std::string to_ixdtf_string(temporal_rs::DisplayCalendar display_calendar) const; + template + inline void to_ixdtf_string_write(temporal_rs::DisplayCalendar display_calendar, W& writeable_output) const; + + inline std::unique_ptr clone() const; + + inline const temporal_rs::capi::PlainYearMonth* AsFFI() const; + inline temporal_rs::capi::PlainYearMonth* AsFFI(); + inline static const temporal_rs::PlainYearMonth* FromFFI(const temporal_rs::capi::PlainYearMonth* ptr); + inline static temporal_rs::PlainYearMonth* FromFFI(temporal_rs::capi::PlainYearMonth* ptr); + inline static void operator delete(void* ptr); +private: + PlainYearMonth() = delete; + PlainYearMonth(const temporal_rs::PlainYearMonth&) = delete; + PlainYearMonth(temporal_rs::PlainYearMonth&&) noexcept = delete; + PlainYearMonth operator=(const temporal_rs::PlainYearMonth&) = delete; + PlainYearMonth operator=(temporal_rs::PlainYearMonth&&) noexcept = delete; + static void operator delete[](void*, size_t) = delete; +}; + +} // namespace +#endif // TEMPORAL_RS_PlainYearMonth_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainYearMonth.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainYearMonth.hpp new file mode 100644 index 00000000000000..5f66d553e998ed --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/PlainYearMonth.hpp @@ -0,0 +1,313 @@ +#ifndef TEMPORAL_RS_PlainYearMonth_HPP +#define TEMPORAL_RS_PlainYearMonth_HPP + +#include "PlainYearMonth.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "AnyCalendarKind.hpp" +#include "ArithmeticOverflow.hpp" +#include "Calendar.hpp" +#include "DifferenceSettings.hpp" +#include "DisplayCalendar.hpp" +#include "Duration.hpp" +#include "ParsedDate.hpp" +#include "PartialDate.hpp" +#include "PlainDate.hpp" +#include "Provider.hpp" +#include "TemporalError.hpp" +#include "TimeZone.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + typedef struct temporal_rs_PlainYearMonth_try_new_with_overflow_result {union {temporal_rs::capi::PlainYearMonth* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_try_new_with_overflow_result; + temporal_rs_PlainYearMonth_try_new_with_overflow_result temporal_rs_PlainYearMonth_try_new_with_overflow(int32_t year, uint8_t month, temporal_rs::diplomat::capi::OptionU8 reference_day, temporal_rs::capi::AnyCalendarKind calendar, temporal_rs::capi::ArithmeticOverflow overflow); + + typedef struct temporal_rs_PlainYearMonth_from_partial_result {union {temporal_rs::capi::PlainYearMonth* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_from_partial_result; + temporal_rs_PlainYearMonth_from_partial_result temporal_rs_PlainYearMonth_from_partial(temporal_rs::capi::PartialDate partial, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_PlainYearMonth_from_parsed_result {union {temporal_rs::capi::PlainYearMonth* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_from_parsed_result; + temporal_rs_PlainYearMonth_from_parsed_result temporal_rs_PlainYearMonth_from_parsed(const temporal_rs::capi::ParsedDate* parsed); + + typedef struct temporal_rs_PlainYearMonth_with_result {union {temporal_rs::capi::PlainYearMonth* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_with_result; + temporal_rs_PlainYearMonth_with_result temporal_rs_PlainYearMonth_with(const temporal_rs::capi::PlainYearMonth* self, temporal_rs::capi::PartialDate partial, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_PlainYearMonth_from_utf8_result {union {temporal_rs::capi::PlainYearMonth* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_from_utf8_result; + temporal_rs_PlainYearMonth_from_utf8_result temporal_rs_PlainYearMonth_from_utf8(temporal_rs::diplomat::capi::DiplomatStringView s); + + typedef struct temporal_rs_PlainYearMonth_from_utf16_result {union {temporal_rs::capi::PlainYearMonth* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_from_utf16_result; + temporal_rs_PlainYearMonth_from_utf16_result temporal_rs_PlainYearMonth_from_utf16(temporal_rs::diplomat::capi::DiplomatString16View s); + + int32_t temporal_rs_PlainYearMonth_year(const temporal_rs::capi::PlainYearMonth* self); + + uint8_t temporal_rs_PlainYearMonth_month(const temporal_rs::capi::PlainYearMonth* self); + + void temporal_rs_PlainYearMonth_month_code(const temporal_rs::capi::PlainYearMonth* self, temporal_rs::diplomat::capi::DiplomatWrite* write); + + bool temporal_rs_PlainYearMonth_in_leap_year(const temporal_rs::capi::PlainYearMonth* self); + + uint16_t temporal_rs_PlainYearMonth_days_in_month(const temporal_rs::capi::PlainYearMonth* self); + + uint16_t temporal_rs_PlainYearMonth_days_in_year(const temporal_rs::capi::PlainYearMonth* self); + + uint16_t temporal_rs_PlainYearMonth_months_in_year(const temporal_rs::capi::PlainYearMonth* self); + + void temporal_rs_PlainYearMonth_era(const temporal_rs::capi::PlainYearMonth* self, temporal_rs::diplomat::capi::DiplomatWrite* write); + + typedef struct temporal_rs_PlainYearMonth_era_year_result {union {int32_t ok; }; bool is_ok;} temporal_rs_PlainYearMonth_era_year_result; + temporal_rs_PlainYearMonth_era_year_result temporal_rs_PlainYearMonth_era_year(const temporal_rs::capi::PlainYearMonth* self); + + const temporal_rs::capi::Calendar* temporal_rs_PlainYearMonth_calendar(const temporal_rs::capi::PlainYearMonth* self); + + typedef struct temporal_rs_PlainYearMonth_add_result {union {temporal_rs::capi::PlainYearMonth* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_add_result; + temporal_rs_PlainYearMonth_add_result temporal_rs_PlainYearMonth_add(const temporal_rs::capi::PlainYearMonth* self, const temporal_rs::capi::Duration* duration, temporal_rs::capi::ArithmeticOverflow overflow); + + typedef struct temporal_rs_PlainYearMonth_subtract_result {union {temporal_rs::capi::PlainYearMonth* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_subtract_result; + temporal_rs_PlainYearMonth_subtract_result temporal_rs_PlainYearMonth_subtract(const temporal_rs::capi::PlainYearMonth* self, const temporal_rs::capi::Duration* duration, temporal_rs::capi::ArithmeticOverflow overflow); + + typedef struct temporal_rs_PlainYearMonth_until_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_until_result; + temporal_rs_PlainYearMonth_until_result temporal_rs_PlainYearMonth_until(const temporal_rs::capi::PlainYearMonth* self, const temporal_rs::capi::PlainYearMonth* other, temporal_rs::capi::DifferenceSettings settings); + + typedef struct temporal_rs_PlainYearMonth_since_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_since_result; + temporal_rs_PlainYearMonth_since_result temporal_rs_PlainYearMonth_since(const temporal_rs::capi::PlainYearMonth* self, const temporal_rs::capi::PlainYearMonth* other, temporal_rs::capi::DifferenceSettings settings); + + bool temporal_rs_PlainYearMonth_equals(const temporal_rs::capi::PlainYearMonth* self, const temporal_rs::capi::PlainYearMonth* other); + + int8_t temporal_rs_PlainYearMonth_compare(const temporal_rs::capi::PlainYearMonth* one, const temporal_rs::capi::PlainYearMonth* two); + + typedef struct temporal_rs_PlainYearMonth_to_plain_date_result {union {temporal_rs::capi::PlainDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_to_plain_date_result; + temporal_rs_PlainYearMonth_to_plain_date_result temporal_rs_PlainYearMonth_to_plain_date(const temporal_rs::capi::PlainYearMonth* self, temporal_rs::capi::PartialDate_option day); + + typedef struct temporal_rs_PlainYearMonth_epoch_ms_for_result {union {int64_t ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_epoch_ms_for_result; + temporal_rs_PlainYearMonth_epoch_ms_for_result temporal_rs_PlainYearMonth_epoch_ms_for(const temporal_rs::capi::PlainYearMonth* self, temporal_rs::capi::TimeZone time_zone); + + typedef struct temporal_rs_PlainYearMonth_epoch_ms_for_with_provider_result {union {int64_t ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainYearMonth_epoch_ms_for_with_provider_result; + temporal_rs_PlainYearMonth_epoch_ms_for_with_provider_result temporal_rs_PlainYearMonth_epoch_ms_for_with_provider(const temporal_rs::capi::PlainYearMonth* self, temporal_rs::capi::TimeZone time_zone, const temporal_rs::capi::Provider* p); + + void temporal_rs_PlainYearMonth_to_ixdtf_string(const temporal_rs::capi::PlainYearMonth* self, temporal_rs::capi::DisplayCalendar display_calendar, temporal_rs::diplomat::capi::DiplomatWrite* write); + + temporal_rs::capi::PlainYearMonth* temporal_rs_PlainYearMonth_clone(const temporal_rs::capi::PlainYearMonth* self); + + void temporal_rs_PlainYearMonth_destroy(PlainYearMonth* self); + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainYearMonth::try_new_with_overflow(int32_t year, uint8_t month, std::optional reference_day, temporal_rs::AnyCalendarKind calendar, temporal_rs::ArithmeticOverflow overflow) { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_try_new_with_overflow(year, + month, + reference_day.has_value() ? (temporal_rs::diplomat::capi::OptionU8{ { reference_day.value() }, true }) : (temporal_rs::diplomat::capi::OptionU8{ {}, false }), + calendar.AsFFI(), + overflow.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainYearMonth::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainYearMonth::from_partial(temporal_rs::PartialDate partial, std::optional overflow) { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_from_partial(partial.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainYearMonth::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainYearMonth::from_parsed(const temporal_rs::ParsedDate& parsed) { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_from_parsed(parsed.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainYearMonth::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainYearMonth::with(temporal_rs::PartialDate partial, std::optional overflow) const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_with(this->AsFFI(), + partial.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainYearMonth::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainYearMonth::from_utf8(std::string_view s) { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_from_utf8({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainYearMonth::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainYearMonth::from_utf16(std::u16string_view s) { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_from_utf16({s.data(), s.size()}); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainYearMonth::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline int32_t temporal_rs::PlainYearMonth::year() const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_year(this->AsFFI()); + return result; +} + +inline uint8_t temporal_rs::PlainYearMonth::month() const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_month(this->AsFFI()); + return result; +} + +inline std::string temporal_rs::PlainYearMonth::month_code() const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + temporal_rs::capi::temporal_rs_PlainYearMonth_month_code(this->AsFFI(), + &write); + return output; +} +template +inline void temporal_rs::PlainYearMonth::month_code_write(W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + temporal_rs::capi::temporal_rs_PlainYearMonth_month_code(this->AsFFI(), + &write); +} + +inline bool temporal_rs::PlainYearMonth::in_leap_year() const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_in_leap_year(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainYearMonth::days_in_month() const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_days_in_month(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainYearMonth::days_in_year() const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_days_in_year(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::PlainYearMonth::months_in_year() const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_months_in_year(this->AsFFI()); + return result; +} + +inline std::string temporal_rs::PlainYearMonth::era() const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + temporal_rs::capi::temporal_rs_PlainYearMonth_era(this->AsFFI(), + &write); + return output; +} +template +inline void temporal_rs::PlainYearMonth::era_write(W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + temporal_rs::capi::temporal_rs_PlainYearMonth_era(this->AsFFI(), + &write); +} + +inline std::optional temporal_rs::PlainYearMonth::era_year() const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_era_year(this->AsFFI()); + return result.is_ok ? std::optional(result.ok) : std::nullopt; +} + +inline const temporal_rs::Calendar& temporal_rs::PlainYearMonth::calendar() const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_calendar(this->AsFFI()); + return *temporal_rs::Calendar::FromFFI(result); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainYearMonth::add(const temporal_rs::Duration& duration, temporal_rs::ArithmeticOverflow overflow) const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_add(this->AsFFI(), + duration.AsFFI(), + overflow.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainYearMonth::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainYearMonth::subtract(const temporal_rs::Duration& duration, temporal_rs::ArithmeticOverflow overflow) const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_subtract(this->AsFFI(), + duration.AsFFI(), + overflow.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainYearMonth::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainYearMonth::until(const temporal_rs::PlainYearMonth& other, temporal_rs::DifferenceSettings settings) const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_until(this->AsFFI(), + other.AsFFI(), + settings.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainYearMonth::since(const temporal_rs::PlainYearMonth& other, temporal_rs::DifferenceSettings settings) const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_since(this->AsFFI(), + other.AsFFI(), + settings.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline bool temporal_rs::PlainYearMonth::equals(const temporal_rs::PlainYearMonth& other) const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_equals(this->AsFFI(), + other.AsFFI()); + return result; +} + +inline int8_t temporal_rs::PlainYearMonth::compare(const temporal_rs::PlainYearMonth& one, const temporal_rs::PlainYearMonth& two) { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_compare(one.AsFFI(), + two.AsFFI()); + return result; +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainYearMonth::to_plain_date(std::optional day) const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_to_plain_date(this->AsFFI(), + day.has_value() ? (temporal_rs::capi::PartialDate_option{ { day.value().AsFFI() }, true }) : (temporal_rs::capi::PartialDate_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDate::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::PlainYearMonth::epoch_ms_for(temporal_rs::TimeZone time_zone) const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_epoch_ms_for(this->AsFFI(), + time_zone.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(result.ok)) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::PlainYearMonth::epoch_ms_for_with_provider(temporal_rs::TimeZone time_zone, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_epoch_ms_for_with_provider(this->AsFFI(), + time_zone.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(result.ok)) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline std::string temporal_rs::PlainYearMonth::to_ixdtf_string(temporal_rs::DisplayCalendar display_calendar) const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + temporal_rs::capi::temporal_rs_PlainYearMonth_to_ixdtf_string(this->AsFFI(), + display_calendar.AsFFI(), + &write); + return output; +} +template +inline void temporal_rs::PlainYearMonth::to_ixdtf_string_write(temporal_rs::DisplayCalendar display_calendar, W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + temporal_rs::capi::temporal_rs_PlainYearMonth_to_ixdtf_string(this->AsFFI(), + display_calendar.AsFFI(), + &write); +} + +inline std::unique_ptr temporal_rs::PlainYearMonth::clone() const { + auto result = temporal_rs::capi::temporal_rs_PlainYearMonth_clone(this->AsFFI()); + return std::unique_ptr(temporal_rs::PlainYearMonth::FromFFI(result)); +} + +inline const temporal_rs::capi::PlainYearMonth* temporal_rs::PlainYearMonth::AsFFI() const { + return reinterpret_cast(this); +} + +inline temporal_rs::capi::PlainYearMonth* temporal_rs::PlainYearMonth::AsFFI() { + return reinterpret_cast(this); +} + +inline const temporal_rs::PlainYearMonth* temporal_rs::PlainYearMonth::FromFFI(const temporal_rs::capi::PlainYearMonth* ptr) { + return reinterpret_cast(ptr); +} + +inline temporal_rs::PlainYearMonth* temporal_rs::PlainYearMonth::FromFFI(temporal_rs::capi::PlainYearMonth* ptr) { + return reinterpret_cast(ptr); +} + +inline void temporal_rs::PlainYearMonth::operator delete(void* ptr) { + temporal_rs::capi::temporal_rs_PlainYearMonth_destroy(reinterpret_cast(ptr)); +} + + +#endif // TEMPORAL_RS_PlainYearMonth_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Precision.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Precision.d.hpp new file mode 100644 index 00000000000000..fc8ff6c93bbe91 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Precision.d.hpp @@ -0,0 +1,37 @@ +#ifndef TEMPORAL_RS_Precision_D_HPP +#define TEMPORAL_RS_Precision_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + struct Precision { + bool is_minute; + temporal_rs::diplomat::capi::OptionU8 precision; + }; + + typedef struct Precision_option {union { Precision ok; }; bool is_ok; } Precision_option; +} // namespace capi +} // namespace + + +namespace temporal_rs { +struct Precision { + bool is_minute; + std::optional precision; + + inline temporal_rs::capi::Precision AsFFI() const; + inline static temporal_rs::Precision FromFFI(temporal_rs::capi::Precision c_struct); +}; + +} // namespace +#endif // TEMPORAL_RS_Precision_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Precision.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Precision.hpp new file mode 100644 index 00000000000000..798021ca96cb69 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Precision.hpp @@ -0,0 +1,41 @@ +#ifndef TEMPORAL_RS_Precision_HPP +#define TEMPORAL_RS_Precision_HPP + +#include "Precision.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + + +inline temporal_rs::capi::Precision temporal_rs::Precision::AsFFI() const { + return temporal_rs::capi::Precision { + /* .is_minute = */ is_minute, + /* .precision = */ precision.has_value() ? (temporal_rs::diplomat::capi::OptionU8{ { precision.value() }, true }) : (temporal_rs::diplomat::capi::OptionU8{ {}, false }), + }; +} + +inline temporal_rs::Precision temporal_rs::Precision::FromFFI(temporal_rs::capi::Precision c_struct) { + return temporal_rs::Precision { + /* .is_minute = */ c_struct.is_minute, + /* .precision = */ c_struct.precision.is_ok ? std::optional(c_struct.precision.ok) : std::nullopt, + }; +} + + +#endif // TEMPORAL_RS_Precision_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Provider.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Provider.d.hpp new file mode 100644 index 00000000000000..f704677b47a9ea --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Provider.d.hpp @@ -0,0 +1,62 @@ +#ifndef TEMPORAL_RS_Provider_D_HPP +#define TEMPORAL_RS_Provider_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +namespace capi { struct Provider; } +class Provider; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct Provider; +} // namespace capi +} // namespace + +namespace temporal_rs { +/** + * A time zone data provider + */ +class Provider { +public: + + /** + * Construct a provider backed by a zoneinfo64.res file + * + * This failing to construct is not a Temporal error, so it just returns () + */ + inline static temporal_rs::diplomat::result, std::monostate> new_zoneinfo64(temporal_rs::diplomat::span data); + + inline static std::unique_ptr new_compiled(); + + /** + * Fallback type in case construction does not work. + */ + inline static std::unique_ptr empty(); + + inline const temporal_rs::capi::Provider* AsFFI() const; + inline temporal_rs::capi::Provider* AsFFI(); + inline static const temporal_rs::Provider* FromFFI(const temporal_rs::capi::Provider* ptr); + inline static temporal_rs::Provider* FromFFI(temporal_rs::capi::Provider* ptr); + inline static void operator delete(void* ptr); +private: + Provider() = delete; + Provider(const temporal_rs::Provider&) = delete; + Provider(temporal_rs::Provider&&) noexcept = delete; + Provider operator=(const temporal_rs::Provider&) = delete; + Provider operator=(temporal_rs::Provider&&) noexcept = delete; + static void operator delete[](void*, size_t) = delete; +}; + +} // namespace +#endif // TEMPORAL_RS_Provider_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Provider.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Provider.hpp new file mode 100644 index 00000000000000..c01662f0a9fa80 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Provider.hpp @@ -0,0 +1,70 @@ +#ifndef TEMPORAL_RS_Provider_HPP +#define TEMPORAL_RS_Provider_HPP + +#include "Provider.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + typedef struct temporal_rs_Provider_new_zoneinfo64_result {union {temporal_rs::capi::Provider* ok; }; bool is_ok;} temporal_rs_Provider_new_zoneinfo64_result; + temporal_rs_Provider_new_zoneinfo64_result temporal_rs_Provider_new_zoneinfo64(temporal_rs::diplomat::capi::DiplomatU32View data); + + temporal_rs::capi::Provider* temporal_rs_Provider_new_compiled(void); + + temporal_rs::capi::Provider* temporal_rs_Provider_empty(void); + + void temporal_rs_Provider_destroy(Provider* self); + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::diplomat::result, std::monostate> temporal_rs::Provider::new_zoneinfo64(temporal_rs::diplomat::span data) { + auto result = temporal_rs::capi::temporal_rs_Provider_new_zoneinfo64({data.data(), data.size()}); + return result.is_ok ? temporal_rs::diplomat::result, std::monostate>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Provider::FromFFI(result.ok)))) : temporal_rs::diplomat::result, std::monostate>(temporal_rs::diplomat::Err()); +} + +inline std::unique_ptr temporal_rs::Provider::new_compiled() { + auto result = temporal_rs::capi::temporal_rs_Provider_new_compiled(); + return std::unique_ptr(temporal_rs::Provider::FromFFI(result)); +} + +inline std::unique_ptr temporal_rs::Provider::empty() { + auto result = temporal_rs::capi::temporal_rs_Provider_empty(); + return std::unique_ptr(temporal_rs::Provider::FromFFI(result)); +} + +inline const temporal_rs::capi::Provider* temporal_rs::Provider::AsFFI() const { + return reinterpret_cast(this); +} + +inline temporal_rs::capi::Provider* temporal_rs::Provider::AsFFI() { + return reinterpret_cast(this); +} + +inline const temporal_rs::Provider* temporal_rs::Provider::FromFFI(const temporal_rs::capi::Provider* ptr) { + return reinterpret_cast(ptr); +} + +inline temporal_rs::Provider* temporal_rs::Provider::FromFFI(temporal_rs::capi::Provider* ptr) { + return reinterpret_cast(ptr); +} + +inline void temporal_rs::Provider::operator delete(void* ptr) { + temporal_rs::capi::temporal_rs_Provider_destroy(reinterpret_cast(ptr)); +} + + +#endif // TEMPORAL_RS_Provider_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RelativeTo.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RelativeTo.d.hpp new file mode 100644 index 00000000000000..8c3b80d68706e2 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RelativeTo.d.hpp @@ -0,0 +1,44 @@ +#ifndef TEMPORAL_RS_RelativeTo_D_HPP +#define TEMPORAL_RS_RelativeTo_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +namespace capi { struct PlainDate; } +class PlainDate; +namespace capi { struct ZonedDateTime; } +class ZonedDateTime; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct RelativeTo { + const temporal_rs::capi::PlainDate* date; + const temporal_rs::capi::ZonedDateTime* zoned; + }; + + typedef struct RelativeTo_option {union { RelativeTo ok; }; bool is_ok; } RelativeTo_option; +} // namespace capi +} // namespace + + +namespace temporal_rs { +struct RelativeTo { + const temporal_rs::PlainDate* date; + const temporal_rs::ZonedDateTime* zoned; + + inline temporal_rs::capi::RelativeTo AsFFI() const; + inline static temporal_rs::RelativeTo FromFFI(temporal_rs::capi::RelativeTo c_struct); +}; + +} // namespace +#endif // TEMPORAL_RS_RelativeTo_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RelativeTo.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RelativeTo.hpp new file mode 100644 index 00000000000000..a5f28a56cdae21 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RelativeTo.hpp @@ -0,0 +1,43 @@ +#ifndef TEMPORAL_RS_RelativeTo_HPP +#define TEMPORAL_RS_RelativeTo_HPP + +#include "RelativeTo.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "PlainDate.hpp" +#include "ZonedDateTime.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + + +inline temporal_rs::capi::RelativeTo temporal_rs::RelativeTo::AsFFI() const { + return temporal_rs::capi::RelativeTo { + /* .date = */ date ? date->AsFFI() : nullptr, + /* .zoned = */ zoned ? zoned->AsFFI() : nullptr, + }; +} + +inline temporal_rs::RelativeTo temporal_rs::RelativeTo::FromFFI(temporal_rs::capi::RelativeTo c_struct) { + return temporal_rs::RelativeTo { + /* .date = */ temporal_rs::PlainDate::FromFFI(c_struct.date), + /* .zoned = */ temporal_rs::ZonedDateTime::FromFFI(c_struct.zoned), + }; +} + + +#endif // TEMPORAL_RS_RelativeTo_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RoundingMode.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RoundingMode.d.hpp new file mode 100644 index 00000000000000..a8ceeb790262bc --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RoundingMode.d.hpp @@ -0,0 +1,63 @@ +#ifndef TEMPORAL_RS_RoundingMode_D_HPP +#define TEMPORAL_RS_RoundingMode_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + enum RoundingMode { + RoundingMode_Ceil = 0, + RoundingMode_Floor = 1, + RoundingMode_Expand = 2, + RoundingMode_Trunc = 3, + RoundingMode_HalfCeil = 4, + RoundingMode_HalfFloor = 5, + RoundingMode_HalfExpand = 6, + RoundingMode_HalfTrunc = 7, + RoundingMode_HalfEven = 8, + }; + + typedef struct RoundingMode_option {union { RoundingMode ok; }; bool is_ok; } RoundingMode_option; +} // namespace capi +} // namespace + +namespace temporal_rs { +class RoundingMode { +public: + enum Value { + Ceil = 0, + Floor = 1, + Expand = 2, + Trunc = 3, + HalfCeil = 4, + HalfFloor = 5, + HalfExpand = 6, + HalfTrunc = 7, + HalfEven = 8, + }; + + RoundingMode(): value(Value::Ceil) {} + + // Implicit conversions between enum and ::Value + constexpr RoundingMode(Value v) : value(v) {} + constexpr operator Value() const { return value; } + // Prevent usage as boolean value + explicit operator bool() const = delete; + + inline temporal_rs::capi::RoundingMode AsFFI() const; + inline static temporal_rs::RoundingMode FromFFI(temporal_rs::capi::RoundingMode c_enum); +private: + Value value; +}; + +} // namespace +#endif // TEMPORAL_RS_RoundingMode_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RoundingMode.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RoundingMode.hpp new file mode 100644 index 00000000000000..7d5b9253118e99 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RoundingMode.hpp @@ -0,0 +1,45 @@ +#ifndef TEMPORAL_RS_RoundingMode_HPP +#define TEMPORAL_RS_RoundingMode_HPP + +#include "RoundingMode.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::capi::RoundingMode temporal_rs::RoundingMode::AsFFI() const { + return static_cast(value); +} + +inline temporal_rs::RoundingMode temporal_rs::RoundingMode::FromFFI(temporal_rs::capi::RoundingMode c_enum) { + switch (c_enum) { + case temporal_rs::capi::RoundingMode_Ceil: + case temporal_rs::capi::RoundingMode_Floor: + case temporal_rs::capi::RoundingMode_Expand: + case temporal_rs::capi::RoundingMode_Trunc: + case temporal_rs::capi::RoundingMode_HalfCeil: + case temporal_rs::capi::RoundingMode_HalfFloor: + case temporal_rs::capi::RoundingMode_HalfExpand: + case temporal_rs::capi::RoundingMode_HalfTrunc: + case temporal_rs::capi::RoundingMode_HalfEven: + return static_cast(c_enum); + default: + std::abort(); + } +} +#endif // TEMPORAL_RS_RoundingMode_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RoundingOptions.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RoundingOptions.d.hpp new file mode 100644 index 00000000000000..13256ac3374b74 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RoundingOptions.d.hpp @@ -0,0 +1,48 @@ +#ifndef TEMPORAL_RS_RoundingOptions_D_HPP +#define TEMPORAL_RS_RoundingOptions_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "RoundingMode.d.hpp" +#include "Unit.d.hpp" +#include "diplomat_runtime.hpp" +namespace temporal_rs { +class RoundingMode; +class Unit; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct RoundingOptions { + temporal_rs::capi::Unit_option largest_unit; + temporal_rs::capi::Unit_option smallest_unit; + temporal_rs::capi::RoundingMode_option rounding_mode; + temporal_rs::diplomat::capi::OptionU32 increment; + }; + + typedef struct RoundingOptions_option {union { RoundingOptions ok; }; bool is_ok; } RoundingOptions_option; +} // namespace capi +} // namespace + + +namespace temporal_rs { +struct RoundingOptions { + std::optional largest_unit; + std::optional smallest_unit; + std::optional rounding_mode; + std::optional increment; + + inline temporal_rs::capi::RoundingOptions AsFFI() const; + inline static temporal_rs::RoundingOptions FromFFI(temporal_rs::capi::RoundingOptions c_struct); +}; + +} // namespace +#endif // TEMPORAL_RS_RoundingOptions_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RoundingOptions.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RoundingOptions.hpp new file mode 100644 index 00000000000000..1804f7be41941b --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/RoundingOptions.hpp @@ -0,0 +1,47 @@ +#ifndef TEMPORAL_RS_RoundingOptions_HPP +#define TEMPORAL_RS_RoundingOptions_HPP + +#include "RoundingOptions.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "RoundingMode.hpp" +#include "Unit.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + + +inline temporal_rs::capi::RoundingOptions temporal_rs::RoundingOptions::AsFFI() const { + return temporal_rs::capi::RoundingOptions { + /* .largest_unit = */ largest_unit.has_value() ? (temporal_rs::capi::Unit_option{ { largest_unit.value().AsFFI() }, true }) : (temporal_rs::capi::Unit_option{ {}, false }), + /* .smallest_unit = */ smallest_unit.has_value() ? (temporal_rs::capi::Unit_option{ { smallest_unit.value().AsFFI() }, true }) : (temporal_rs::capi::Unit_option{ {}, false }), + /* .rounding_mode = */ rounding_mode.has_value() ? (temporal_rs::capi::RoundingMode_option{ { rounding_mode.value().AsFFI() }, true }) : (temporal_rs::capi::RoundingMode_option{ {}, false }), + /* .increment = */ increment.has_value() ? (temporal_rs::diplomat::capi::OptionU32{ { increment.value() }, true }) : (temporal_rs::diplomat::capi::OptionU32{ {}, false }), + }; +} + +inline temporal_rs::RoundingOptions temporal_rs::RoundingOptions::FromFFI(temporal_rs::capi::RoundingOptions c_struct) { + return temporal_rs::RoundingOptions { + /* .largest_unit = */ c_struct.largest_unit.is_ok ? std::optional(temporal_rs::Unit::FromFFI(c_struct.largest_unit.ok)) : std::nullopt, + /* .smallest_unit = */ c_struct.smallest_unit.is_ok ? std::optional(temporal_rs::Unit::FromFFI(c_struct.smallest_unit.ok)) : std::nullopt, + /* .rounding_mode = */ c_struct.rounding_mode.is_ok ? std::optional(temporal_rs::RoundingMode::FromFFI(c_struct.rounding_mode.ok)) : std::nullopt, + /* .increment = */ c_struct.increment.is_ok ? std::optional(c_struct.increment.ok) : std::nullopt, + }; +} + + +#endif // TEMPORAL_RS_RoundingOptions_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Sign.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Sign.d.hpp new file mode 100644 index 00000000000000..26bd59e5695193 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Sign.d.hpp @@ -0,0 +1,51 @@ +#ifndef TEMPORAL_RS_Sign_D_HPP +#define TEMPORAL_RS_Sign_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + enum Sign { + Sign_Positive = 1, + Sign_Zero = 0, + Sign_Negative = -1, + }; + + typedef struct Sign_option {union { Sign ok; }; bool is_ok; } Sign_option; +} // namespace capi +} // namespace + +namespace temporal_rs { +class Sign { +public: + enum Value { + Positive = 1, + Zero = 0, + Negative = -1, + }; + + Sign(): value(Value::Zero) {} + + // Implicit conversions between enum and ::Value + constexpr Sign(Value v) : value(v) {} + constexpr operator Value() const { return value; } + // Prevent usage as boolean value + explicit operator bool() const = delete; + + inline temporal_rs::capi::Sign AsFFI() const; + inline static temporal_rs::Sign FromFFI(temporal_rs::capi::Sign c_enum); +private: + Value value; +}; + +} // namespace +#endif // TEMPORAL_RS_Sign_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Sign.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Sign.hpp new file mode 100644 index 00000000000000..131b59507bdb00 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Sign.hpp @@ -0,0 +1,39 @@ +#ifndef TEMPORAL_RS_Sign_HPP +#define TEMPORAL_RS_Sign_HPP + +#include "Sign.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::capi::Sign temporal_rs::Sign::AsFFI() const { + return static_cast(value); +} + +inline temporal_rs::Sign temporal_rs::Sign::FromFFI(temporal_rs::capi::Sign c_enum) { + switch (c_enum) { + case temporal_rs::capi::Sign_Positive: + case temporal_rs::capi::Sign_Zero: + case temporal_rs::capi::Sign_Negative: + return static_cast(c_enum); + default: + std::abort(); + } +} +#endif // TEMPORAL_RS_Sign_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TemporalError.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TemporalError.d.hpp new file mode 100644 index 00000000000000..e07208d8003c5d --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TemporalError.d.hpp @@ -0,0 +1,42 @@ +#ifndef TEMPORAL_RS_TemporalError_D_HPP +#define TEMPORAL_RS_TemporalError_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ErrorKind.d.hpp" +#include "diplomat_runtime.hpp" +namespace temporal_rs { +class ErrorKind; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct TemporalError { + temporal_rs::capi::ErrorKind kind; + temporal_rs::diplomat::capi::OptionStringView msg; + }; + + typedef struct TemporalError_option {union { TemporalError ok; }; bool is_ok; } TemporalError_option; +} // namespace capi +} // namespace + + +namespace temporal_rs { +struct TemporalError { + temporal_rs::ErrorKind kind; + std::optional msg; + + inline temporal_rs::capi::TemporalError AsFFI() const; + inline static temporal_rs::TemporalError FromFFI(temporal_rs::capi::TemporalError c_struct); +}; + +} // namespace +#endif // TEMPORAL_RS_TemporalError_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TemporalError.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TemporalError.hpp new file mode 100644 index 00000000000000..aaccd0c1938cc1 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TemporalError.hpp @@ -0,0 +1,42 @@ +#ifndef TEMPORAL_RS_TemporalError_HPP +#define TEMPORAL_RS_TemporalError_HPP + +#include "TemporalError.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ErrorKind.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + + +inline temporal_rs::capi::TemporalError temporal_rs::TemporalError::AsFFI() const { + return temporal_rs::capi::TemporalError { + /* .kind = */ kind.AsFFI(), + /* .msg = */ msg.has_value() ? (temporal_rs::diplomat::capi::OptionStringView{ { {msg.value().data(), msg.value().size()} }, true }) : (temporal_rs::diplomat::capi::OptionStringView{ {}, false }), + }; +} + +inline temporal_rs::TemporalError temporal_rs::TemporalError::FromFFI(temporal_rs::capi::TemporalError c_struct) { + return temporal_rs::TemporalError { + /* .kind = */ temporal_rs::ErrorKind::FromFFI(c_struct.kind), + /* .msg = */ c_struct.msg.is_ok ? std::optional(std::string_view(c_struct.msg.ok.data, c_struct.msg.ok.len)) : std::nullopt, + }; +} + + +#endif // TEMPORAL_RS_TemporalError_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TimeZone.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TimeZone.d.hpp new file mode 100644 index 00000000000000..46f31b1d47c3e2 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TimeZone.d.hpp @@ -0,0 +1,90 @@ +#ifndef TEMPORAL_RS_TimeZone_D_HPP +#define TEMPORAL_RS_TimeZone_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +namespace capi { struct Provider; } +class Provider; +struct TemporalError; +struct TimeZone; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct TimeZone { + int16_t offset_minutes; + size_t resolved_id; + size_t normalized_id; + bool is_iana_id; + }; + + typedef struct TimeZone_option {union { TimeZone ok; }; bool is_ok; } TimeZone_option; +} // namespace capi +} // namespace + + +namespace temporal_rs { +/** + * A type representing a time zone over FFI. + * + * It is not recommended to directly manipulate the fields of this type. + */ +struct TimeZone { + int16_t offset_minutes; + size_t resolved_id; + size_t normalized_id; + bool is_iana_id; + + inline static temporal_rs::diplomat::result try_from_identifier_str(std::string_view ident); + + inline static temporal_rs::diplomat::result try_from_identifier_str_with_provider(std::string_view ident, const temporal_rs::Provider& p); + + inline static temporal_rs::diplomat::result try_from_offset_str(std::string_view ident); + + inline static temporal_rs::diplomat::result try_from_str(std::string_view ident); + + inline static temporal_rs::diplomat::result try_from_str_with_provider(std::string_view ident, const temporal_rs::Provider& p); + + inline std::string identifier() const; + template + inline void identifier_write(W& writeable_output) const; + + inline temporal_rs::diplomat::result identifier_with_provider(const temporal_rs::Provider& p) const; + template + inline temporal_rs::diplomat::result identifier_with_provider_write(const temporal_rs::Provider& p, W& writeable_output) const; + + inline static temporal_rs::TimeZone utc(); + + inline static temporal_rs::diplomat::result utc_with_provider(const temporal_rs::Provider& p); + + /** + * Create a TimeZone that represents +00:00 + * + * This is the only way to infallibly make a TimeZone without compiled_data, + * and can be used as a fallback. + */ + inline static temporal_rs::TimeZone zero(); + + /** + * Get the primary time zone identifier corresponding to this time zone + */ + inline temporal_rs::diplomat::result primary_identifier() const; + + inline temporal_rs::diplomat::result primary_identifier_with_provider(const temporal_rs::Provider& p) const; + + inline temporal_rs::capi::TimeZone AsFFI() const; + inline static temporal_rs::TimeZone FromFFI(temporal_rs::capi::TimeZone c_struct); +}; + +} // namespace +#endif // TEMPORAL_RS_TimeZone_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TimeZone.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TimeZone.hpp new file mode 100644 index 00000000000000..83f78af6b77388 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TimeZone.hpp @@ -0,0 +1,164 @@ +#ifndef TEMPORAL_RS_TimeZone_HPP +#define TEMPORAL_RS_TimeZone_HPP + +#include "TimeZone.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "Provider.hpp" +#include "TemporalError.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + typedef struct temporal_rs_TimeZone_try_from_identifier_str_result {union {temporal_rs::capi::TimeZone ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_try_from_identifier_str_result; + temporal_rs_TimeZone_try_from_identifier_str_result temporal_rs_TimeZone_try_from_identifier_str(temporal_rs::diplomat::capi::DiplomatStringView ident); + + typedef struct temporal_rs_TimeZone_try_from_identifier_str_with_provider_result {union {temporal_rs::capi::TimeZone ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_try_from_identifier_str_with_provider_result; + temporal_rs_TimeZone_try_from_identifier_str_with_provider_result temporal_rs_TimeZone_try_from_identifier_str_with_provider(temporal_rs::diplomat::capi::DiplomatStringView ident, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_TimeZone_try_from_offset_str_result {union {temporal_rs::capi::TimeZone ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_try_from_offset_str_result; + temporal_rs_TimeZone_try_from_offset_str_result temporal_rs_TimeZone_try_from_offset_str(temporal_rs::diplomat::capi::DiplomatStringView ident); + + typedef struct temporal_rs_TimeZone_try_from_str_result {union {temporal_rs::capi::TimeZone ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_try_from_str_result; + temporal_rs_TimeZone_try_from_str_result temporal_rs_TimeZone_try_from_str(temporal_rs::diplomat::capi::DiplomatStringView ident); + + typedef struct temporal_rs_TimeZone_try_from_str_with_provider_result {union {temporal_rs::capi::TimeZone ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_try_from_str_with_provider_result; + temporal_rs_TimeZone_try_from_str_with_provider_result temporal_rs_TimeZone_try_from_str_with_provider(temporal_rs::diplomat::capi::DiplomatStringView ident, const temporal_rs::capi::Provider* p); + + void temporal_rs_TimeZone_identifier(temporal_rs::capi::TimeZone self, temporal_rs::diplomat::capi::DiplomatWrite* write); + + typedef struct temporal_rs_TimeZone_identifier_with_provider_result {union { temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_identifier_with_provider_result; + temporal_rs_TimeZone_identifier_with_provider_result temporal_rs_TimeZone_identifier_with_provider(temporal_rs::capi::TimeZone self, const temporal_rs::capi::Provider* p, temporal_rs::diplomat::capi::DiplomatWrite* write); + + temporal_rs::capi::TimeZone temporal_rs_TimeZone_utc(void); + + typedef struct temporal_rs_TimeZone_utc_with_provider_result {union {temporal_rs::capi::TimeZone ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_utc_with_provider_result; + temporal_rs_TimeZone_utc_with_provider_result temporal_rs_TimeZone_utc_with_provider(const temporal_rs::capi::Provider* p); + + temporal_rs::capi::TimeZone temporal_rs_TimeZone_zero(void); + + typedef struct temporal_rs_TimeZone_primary_identifier_result {union {temporal_rs::capi::TimeZone ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_primary_identifier_result; + temporal_rs_TimeZone_primary_identifier_result temporal_rs_TimeZone_primary_identifier(temporal_rs::capi::TimeZone self); + + typedef struct temporal_rs_TimeZone_primary_identifier_with_provider_result {union {temporal_rs::capi::TimeZone ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_primary_identifier_with_provider_result; + temporal_rs_TimeZone_primary_identifier_with_provider_result temporal_rs_TimeZone_primary_identifier_with_provider(temporal_rs::capi::TimeZone self, const temporal_rs::capi::Provider* p); + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::diplomat::result temporal_rs::TimeZone::try_from_identifier_str(std::string_view ident) { + auto result = temporal_rs::capi::temporal_rs_TimeZone_try_from_identifier_str({ident.data(), ident.size()}); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(temporal_rs::TimeZone::FromFFI(result.ok))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::TimeZone::try_from_identifier_str_with_provider(std::string_view ident, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_TimeZone_try_from_identifier_str_with_provider({ident.data(), ident.size()}, + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(temporal_rs::TimeZone::FromFFI(result.ok))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::TimeZone::try_from_offset_str(std::string_view ident) { + auto result = temporal_rs::capi::temporal_rs_TimeZone_try_from_offset_str({ident.data(), ident.size()}); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(temporal_rs::TimeZone::FromFFI(result.ok))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::TimeZone::try_from_str(std::string_view ident) { + auto result = temporal_rs::capi::temporal_rs_TimeZone_try_from_str({ident.data(), ident.size()}); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(temporal_rs::TimeZone::FromFFI(result.ok))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::TimeZone::try_from_str_with_provider(std::string_view ident, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_TimeZone_try_from_str_with_provider({ident.data(), ident.size()}, + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(temporal_rs::TimeZone::FromFFI(result.ok))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline std::string temporal_rs::TimeZone::identifier() const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + temporal_rs::capi::temporal_rs_TimeZone_identifier(this->AsFFI(), + &write); + return output; +} +template +inline void temporal_rs::TimeZone::identifier_write(W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + temporal_rs::capi::temporal_rs_TimeZone_identifier(this->AsFFI(), + &write); +} + +inline temporal_rs::diplomat::result temporal_rs::TimeZone::identifier_with_provider(const temporal_rs::Provider& p) const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + auto result = temporal_rs::capi::temporal_rs_TimeZone_identifier_with_provider(this->AsFFI(), + p.AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(std::move(output))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} +template +inline temporal_rs::diplomat::result temporal_rs::TimeZone::identifier_with_provider_write(const temporal_rs::Provider& p, W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + auto result = temporal_rs::capi::temporal_rs_TimeZone_identifier_with_provider(this->AsFFI(), + p.AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok()) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::TimeZone temporal_rs::TimeZone::utc() { + auto result = temporal_rs::capi::temporal_rs_TimeZone_utc(); + return temporal_rs::TimeZone::FromFFI(result); +} + +inline temporal_rs::diplomat::result temporal_rs::TimeZone::utc_with_provider(const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_TimeZone_utc_with_provider(p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(temporal_rs::TimeZone::FromFFI(result.ok))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::TimeZone temporal_rs::TimeZone::zero() { + auto result = temporal_rs::capi::temporal_rs_TimeZone_zero(); + return temporal_rs::TimeZone::FromFFI(result); +} + +inline temporal_rs::diplomat::result temporal_rs::TimeZone::primary_identifier() const { + auto result = temporal_rs::capi::temporal_rs_TimeZone_primary_identifier(this->AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(temporal_rs::TimeZone::FromFFI(result.ok))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::TimeZone::primary_identifier_with_provider(const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_TimeZone_primary_identifier_with_provider(this->AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(temporal_rs::TimeZone::FromFFI(result.ok))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + + +inline temporal_rs::capi::TimeZone temporal_rs::TimeZone::AsFFI() const { + return temporal_rs::capi::TimeZone { + /* .offset_minutes = */ offset_minutes, + /* .resolved_id = */ resolved_id, + /* .normalized_id = */ normalized_id, + /* .is_iana_id = */ is_iana_id, + }; +} + +inline temporal_rs::TimeZone temporal_rs::TimeZone::FromFFI(temporal_rs::capi::TimeZone c_struct) { + return temporal_rs::TimeZone { + /* .offset_minutes = */ c_struct.offset_minutes, + /* .resolved_id = */ c_struct.resolved_id, + /* .normalized_id = */ c_struct.normalized_id, + /* .is_iana_id = */ c_struct.is_iana_id, + }; +} + + +#endif // TEMPORAL_RS_TimeZone_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ToStringRoundingOptions.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ToStringRoundingOptions.d.hpp new file mode 100644 index 00000000000000..0b39d46615b591 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ToStringRoundingOptions.d.hpp @@ -0,0 +1,48 @@ +#ifndef TEMPORAL_RS_ToStringRoundingOptions_D_HPP +#define TEMPORAL_RS_ToStringRoundingOptions_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "Precision.d.hpp" +#include "RoundingMode.d.hpp" +#include "Unit.d.hpp" +#include "diplomat_runtime.hpp" +namespace temporal_rs { +struct Precision; +class RoundingMode; +class Unit; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct ToStringRoundingOptions { + temporal_rs::capi::Precision precision; + temporal_rs::capi::Unit_option smallest_unit; + temporal_rs::capi::RoundingMode_option rounding_mode; + }; + + typedef struct ToStringRoundingOptions_option {union { ToStringRoundingOptions ok; }; bool is_ok; } ToStringRoundingOptions_option; +} // namespace capi +} // namespace + + +namespace temporal_rs { +struct ToStringRoundingOptions { + temporal_rs::Precision precision; + std::optional smallest_unit; + std::optional rounding_mode; + + inline temporal_rs::capi::ToStringRoundingOptions AsFFI() const; + inline static temporal_rs::ToStringRoundingOptions FromFFI(temporal_rs::capi::ToStringRoundingOptions c_struct); +}; + +} // namespace +#endif // TEMPORAL_RS_ToStringRoundingOptions_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ToStringRoundingOptions.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ToStringRoundingOptions.hpp new file mode 100644 index 00000000000000..e34ebefb8f596f --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ToStringRoundingOptions.hpp @@ -0,0 +1,46 @@ +#ifndef TEMPORAL_RS_ToStringRoundingOptions_HPP +#define TEMPORAL_RS_ToStringRoundingOptions_HPP + +#include "ToStringRoundingOptions.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "Precision.hpp" +#include "RoundingMode.hpp" +#include "Unit.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + + +inline temporal_rs::capi::ToStringRoundingOptions temporal_rs::ToStringRoundingOptions::AsFFI() const { + return temporal_rs::capi::ToStringRoundingOptions { + /* .precision = */ precision.AsFFI(), + /* .smallest_unit = */ smallest_unit.has_value() ? (temporal_rs::capi::Unit_option{ { smallest_unit.value().AsFFI() }, true }) : (temporal_rs::capi::Unit_option{ {}, false }), + /* .rounding_mode = */ rounding_mode.has_value() ? (temporal_rs::capi::RoundingMode_option{ { rounding_mode.value().AsFFI() }, true }) : (temporal_rs::capi::RoundingMode_option{ {}, false }), + }; +} + +inline temporal_rs::ToStringRoundingOptions temporal_rs::ToStringRoundingOptions::FromFFI(temporal_rs::capi::ToStringRoundingOptions c_struct) { + return temporal_rs::ToStringRoundingOptions { + /* .precision = */ temporal_rs::Precision::FromFFI(c_struct.precision), + /* .smallest_unit = */ c_struct.smallest_unit.is_ok ? std::optional(temporal_rs::Unit::FromFFI(c_struct.smallest_unit.ok)) : std::nullopt, + /* .rounding_mode = */ c_struct.rounding_mode.is_ok ? std::optional(temporal_rs::RoundingMode::FromFFI(c_struct.rounding_mode.ok)) : std::nullopt, + }; +} + + +#endif // TEMPORAL_RS_ToStringRoundingOptions_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TransitionDirection.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TransitionDirection.d.hpp new file mode 100644 index 00000000000000..73a2be2a101605 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TransitionDirection.d.hpp @@ -0,0 +1,49 @@ +#ifndef TEMPORAL_RS_TransitionDirection_D_HPP +#define TEMPORAL_RS_TransitionDirection_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + enum TransitionDirection { + TransitionDirection_Next = 0, + TransitionDirection_Previous = 1, + }; + + typedef struct TransitionDirection_option {union { TransitionDirection ok; }; bool is_ok; } TransitionDirection_option; +} // namespace capi +} // namespace + +namespace temporal_rs { +class TransitionDirection { +public: + enum Value { + Next = 0, + Previous = 1, + }; + + TransitionDirection(): value(Value::Next) {} + + // Implicit conversions between enum and ::Value + constexpr TransitionDirection(Value v) : value(v) {} + constexpr operator Value() const { return value; } + // Prevent usage as boolean value + explicit operator bool() const = delete; + + inline temporal_rs::capi::TransitionDirection AsFFI() const; + inline static temporal_rs::TransitionDirection FromFFI(temporal_rs::capi::TransitionDirection c_enum); +private: + Value value; +}; + +} // namespace +#endif // TEMPORAL_RS_TransitionDirection_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TransitionDirection.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TransitionDirection.hpp new file mode 100644 index 00000000000000..1241672350775b --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/TransitionDirection.hpp @@ -0,0 +1,38 @@ +#ifndef TEMPORAL_RS_TransitionDirection_HPP +#define TEMPORAL_RS_TransitionDirection_HPP + +#include "TransitionDirection.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::capi::TransitionDirection temporal_rs::TransitionDirection::AsFFI() const { + return static_cast(value); +} + +inline temporal_rs::TransitionDirection temporal_rs::TransitionDirection::FromFFI(temporal_rs::capi::TransitionDirection c_enum) { + switch (c_enum) { + case temporal_rs::capi::TransitionDirection_Next: + case temporal_rs::capi::TransitionDirection_Previous: + return static_cast(c_enum); + default: + std::abort(); + } +} +#endif // TEMPORAL_RS_TransitionDirection_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Unit.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Unit.d.hpp new file mode 100644 index 00000000000000..68cd1155102198 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Unit.d.hpp @@ -0,0 +1,67 @@ +#ifndef TEMPORAL_RS_Unit_D_HPP +#define TEMPORAL_RS_Unit_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + enum Unit { + Unit_Auto = 0, + Unit_Nanosecond = 1, + Unit_Microsecond = 2, + Unit_Millisecond = 3, + Unit_Second = 4, + Unit_Minute = 5, + Unit_Hour = 6, + Unit_Day = 7, + Unit_Week = 8, + Unit_Month = 9, + Unit_Year = 10, + }; + + typedef struct Unit_option {union { Unit ok; }; bool is_ok; } Unit_option; +} // namespace capi +} // namespace + +namespace temporal_rs { +class Unit { +public: + enum Value { + Auto = 0, + Nanosecond = 1, + Microsecond = 2, + Millisecond = 3, + Second = 4, + Minute = 5, + Hour = 6, + Day = 7, + Week = 8, + Month = 9, + Year = 10, + }; + + Unit(): value(Value::Auto) {} + + // Implicit conversions between enum and ::Value + constexpr Unit(Value v) : value(v) {} + constexpr operator Value() const { return value; } + // Prevent usage as boolean value + explicit operator bool() const = delete; + + inline temporal_rs::capi::Unit AsFFI() const; + inline static temporal_rs::Unit FromFFI(temporal_rs::capi::Unit c_enum); +private: + Value value; +}; + +} // namespace +#endif // TEMPORAL_RS_Unit_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Unit.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Unit.hpp new file mode 100644 index 00000000000000..6ab07392ce7c52 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/Unit.hpp @@ -0,0 +1,47 @@ +#ifndef TEMPORAL_RS_Unit_HPP +#define TEMPORAL_RS_Unit_HPP + +#include "Unit.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::capi::Unit temporal_rs::Unit::AsFFI() const { + return static_cast(value); +} + +inline temporal_rs::Unit temporal_rs::Unit::FromFFI(temporal_rs::capi::Unit c_enum) { + switch (c_enum) { + case temporal_rs::capi::Unit_Auto: + case temporal_rs::capi::Unit_Nanosecond: + case temporal_rs::capi::Unit_Microsecond: + case temporal_rs::capi::Unit_Millisecond: + case temporal_rs::capi::Unit_Second: + case temporal_rs::capi::Unit_Minute: + case temporal_rs::capi::Unit_Hour: + case temporal_rs::capi::Unit_Day: + case temporal_rs::capi::Unit_Week: + case temporal_rs::capi::Unit_Month: + case temporal_rs::capi::Unit_Year: + return static_cast(c_enum); + default: + std::abort(); + } +} +#endif // TEMPORAL_RS_Unit_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/UnsignedRoundingMode.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/UnsignedRoundingMode.d.hpp new file mode 100644 index 00000000000000..b6e3d1a544295a --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/UnsignedRoundingMode.d.hpp @@ -0,0 +1,55 @@ +#ifndef TEMPORAL_RS_UnsignedRoundingMode_D_HPP +#define TEMPORAL_RS_UnsignedRoundingMode_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + enum UnsignedRoundingMode { + UnsignedRoundingMode_Infinity = 0, + UnsignedRoundingMode_Zero = 1, + UnsignedRoundingMode_HalfInfinity = 2, + UnsignedRoundingMode_HalfZero = 3, + UnsignedRoundingMode_HalfEven = 4, + }; + + typedef struct UnsignedRoundingMode_option {union { UnsignedRoundingMode ok; }; bool is_ok; } UnsignedRoundingMode_option; +} // namespace capi +} // namespace + +namespace temporal_rs { +class UnsignedRoundingMode { +public: + enum Value { + Infinity = 0, + Zero = 1, + HalfInfinity = 2, + HalfZero = 3, + HalfEven = 4, + }; + + UnsignedRoundingMode(): value(Value::Infinity) {} + + // Implicit conversions between enum and ::Value + constexpr UnsignedRoundingMode(Value v) : value(v) {} + constexpr operator Value() const { return value; } + // Prevent usage as boolean value + explicit operator bool() const = delete; + + inline temporal_rs::capi::UnsignedRoundingMode AsFFI() const; + inline static temporal_rs::UnsignedRoundingMode FromFFI(temporal_rs::capi::UnsignedRoundingMode c_enum); +private: + Value value; +}; + +} // namespace +#endif // TEMPORAL_RS_UnsignedRoundingMode_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/UnsignedRoundingMode.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/UnsignedRoundingMode.hpp new file mode 100644 index 00000000000000..52f543b73934e3 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/UnsignedRoundingMode.hpp @@ -0,0 +1,41 @@ +#ifndef TEMPORAL_RS_UnsignedRoundingMode_HPP +#define TEMPORAL_RS_UnsignedRoundingMode_HPP + +#include "UnsignedRoundingMode.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::capi::UnsignedRoundingMode temporal_rs::UnsignedRoundingMode::AsFFI() const { + return static_cast(value); +} + +inline temporal_rs::UnsignedRoundingMode temporal_rs::UnsignedRoundingMode::FromFFI(temporal_rs::capi::UnsignedRoundingMode c_enum) { + switch (c_enum) { + case temporal_rs::capi::UnsignedRoundingMode_Infinity: + case temporal_rs::capi::UnsignedRoundingMode_Zero: + case temporal_rs::capi::UnsignedRoundingMode_HalfInfinity: + case temporal_rs::capi::UnsignedRoundingMode_HalfZero: + case temporal_rs::capi::UnsignedRoundingMode_HalfEven: + return static_cast(c_enum); + default: + std::abort(); + } +} +#endif // TEMPORAL_RS_UnsignedRoundingMode_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ZonedDateTime.d.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ZonedDateTime.d.hpp new file mode 100644 index 00000000000000..cdf2a0505bd8a6 --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ZonedDateTime.d.hpp @@ -0,0 +1,234 @@ +#ifndef TEMPORAL_RS_ZonedDateTime_D_HPP +#define TEMPORAL_RS_ZonedDateTime_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +namespace temporal_rs { +namespace capi { struct Calendar; } +class Calendar; +namespace capi { struct Duration; } +class Duration; +namespace capi { struct Instant; } +class Instant; +namespace capi { struct ParsedZonedDateTime; } +class ParsedZonedDateTime; +namespace capi { struct PlainDate; } +class PlainDate; +namespace capi { struct PlainDateTime; } +class PlainDateTime; +namespace capi { struct PlainTime; } +class PlainTime; +namespace capi { struct Provider; } +class Provider; +namespace capi { struct ZonedDateTime; } +class ZonedDateTime; +struct DifferenceSettings; +struct I128Nanoseconds; +struct PartialZonedDateTime; +struct RoundingOptions; +struct TemporalError; +struct TimeZone; +struct ToStringRoundingOptions; +class AnyCalendarKind; +class ArithmeticOverflow; +class Disambiguation; +class DisplayCalendar; +class DisplayOffset; +class DisplayTimeZone; +class OffsetDisambiguation; +class TransitionDirection; +} // namespace temporal_rs + + + +namespace temporal_rs { +namespace capi { + struct ZonedDateTime; +} // namespace capi +} // namespace + +namespace temporal_rs { +class ZonedDateTime { +public: + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> try_new(temporal_rs::I128Nanoseconds nanosecond, temporal_rs::AnyCalendarKind calendar, temporal_rs::TimeZone time_zone); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> try_new_with_provider(temporal_rs::I128Nanoseconds nanosecond, temporal_rs::AnyCalendarKind calendar, temporal_rs::TimeZone time_zone, const temporal_rs::Provider& p); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_partial(temporal_rs::PartialZonedDateTime partial, std::optional overflow, std::optional disambiguation, std::optional offset_option); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_partial_with_provider(temporal_rs::PartialZonedDateTime partial, std::optional overflow, std::optional disambiguation, std::optional offset_option, const temporal_rs::Provider& p); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_parsed(const temporal_rs::ParsedZonedDateTime& parsed, temporal_rs::Disambiguation disambiguation, temporal_rs::OffsetDisambiguation offset_option); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_parsed_with_provider(const temporal_rs::ParsedZonedDateTime& parsed, temporal_rs::Disambiguation disambiguation, temporal_rs::OffsetDisambiguation offset_option, const temporal_rs::Provider& p); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf8(std::string_view s, temporal_rs::Disambiguation disambiguation, temporal_rs::OffsetDisambiguation offset_disambiguation); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf8_with_provider(std::string_view s, temporal_rs::Disambiguation disambiguation, temporal_rs::OffsetDisambiguation offset_disambiguation, const temporal_rs::Provider& p); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf16(std::u16string_view s, temporal_rs::Disambiguation disambiguation, temporal_rs::OffsetDisambiguation offset_disambiguation); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf16_with_provider(std::u16string_view s, temporal_rs::Disambiguation disambiguation, temporal_rs::OffsetDisambiguation offset_disambiguation, const temporal_rs::Provider& p); + + inline int64_t epoch_milliseconds() const; + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_milliseconds(int64_t ms, temporal_rs::TimeZone tz); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_milliseconds_with_provider(int64_t ms, temporal_rs::TimeZone tz, const temporal_rs::Provider& p); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_nanoseconds(temporal_rs::I128Nanoseconds ns, temporal_rs::TimeZone tz); + + inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_nanoseconds_with_provider(temporal_rs::I128Nanoseconds ns, temporal_rs::TimeZone tz, const temporal_rs::Provider& p); + + inline temporal_rs::I128Nanoseconds epoch_nanoseconds() const; + + inline int64_t offset_nanoseconds() const; + + inline std::unique_ptr to_instant() const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> with(temporal_rs::PartialZonedDateTime partial, std::optional disambiguation, std::optional offset_option, std::optional overflow) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> with_with_provider(temporal_rs::PartialZonedDateTime partial, std::optional disambiguation, std::optional offset_option, std::optional overflow, const temporal_rs::Provider& p) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> with_timezone(temporal_rs::TimeZone zone) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> with_timezone_with_provider(temporal_rs::TimeZone zone, const temporal_rs::Provider& p) const; + + inline temporal_rs::TimeZone timezone() const; + + inline int8_t compare_instant(const temporal_rs::ZonedDateTime& other) const; + + inline bool equals(const temporal_rs::ZonedDateTime& other) const; + + inline temporal_rs::diplomat::result equals_with_provider(const temporal_rs::ZonedDateTime& other, const temporal_rs::Provider& p) const; + + inline temporal_rs::diplomat::result offset() const; + template + inline temporal_rs::diplomat::result offset_write(W& writeable_output) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> start_of_day() const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> start_of_day_with_provider(const temporal_rs::Provider& p) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> get_time_zone_transition(temporal_rs::TransitionDirection direction) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> get_time_zone_transition_with_provider(temporal_rs::TransitionDirection direction, const temporal_rs::Provider& p) const; + + inline temporal_rs::diplomat::result hours_in_day() const; + + inline temporal_rs::diplomat::result hours_in_day_with_provider(const temporal_rs::Provider& p) const; + + inline std::unique_ptr to_plain_datetime() const; + + inline std::unique_ptr to_plain_date() const; + + inline std::unique_ptr to_plain_time() const; + + inline temporal_rs::diplomat::result to_ixdtf_string(temporal_rs::DisplayOffset display_offset, temporal_rs::DisplayTimeZone display_timezone, temporal_rs::DisplayCalendar display_calendar, temporal_rs::ToStringRoundingOptions options) const; + template + inline temporal_rs::diplomat::result to_ixdtf_string_write(temporal_rs::DisplayOffset display_offset, temporal_rs::DisplayTimeZone display_timezone, temporal_rs::DisplayCalendar display_calendar, temporal_rs::ToStringRoundingOptions options, W& writeable_output) const; + + inline temporal_rs::diplomat::result to_ixdtf_string_with_provider(temporal_rs::DisplayOffset display_offset, temporal_rs::DisplayTimeZone display_timezone, temporal_rs::DisplayCalendar display_calendar, temporal_rs::ToStringRoundingOptions options, const temporal_rs::Provider& p) const; + template + inline temporal_rs::diplomat::result to_ixdtf_string_with_provider_write(temporal_rs::DisplayOffset display_offset, temporal_rs::DisplayTimeZone display_timezone, temporal_rs::DisplayCalendar display_calendar, temporal_rs::ToStringRoundingOptions options, const temporal_rs::Provider& p, W& writeable_output) const; + + inline std::unique_ptr with_calendar(temporal_rs::AnyCalendarKind calendar) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> with_plain_time(const temporal_rs::PlainTime* time) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> with_plain_time_and_provider(const temporal_rs::PlainTime* time, const temporal_rs::Provider& p) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> add(const temporal_rs::Duration& duration, std::optional overflow) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> add_with_provider(const temporal_rs::Duration& duration, std::optional overflow, const temporal_rs::Provider& p) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> subtract(const temporal_rs::Duration& duration, std::optional overflow) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> subtract_with_provider(const temporal_rs::Duration& duration, std::optional overflow, const temporal_rs::Provider& p) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> until(const temporal_rs::ZonedDateTime& other, temporal_rs::DifferenceSettings settings) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> until_with_provider(const temporal_rs::ZonedDateTime& other, temporal_rs::DifferenceSettings settings, const temporal_rs::Provider& p) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> since(const temporal_rs::ZonedDateTime& other, temporal_rs::DifferenceSettings settings) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> since_with_provider(const temporal_rs::ZonedDateTime& other, temporal_rs::DifferenceSettings settings, const temporal_rs::Provider& p) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> round(temporal_rs::RoundingOptions options) const; + + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> round_with_provider(temporal_rs::RoundingOptions options, const temporal_rs::Provider& p) const; + + inline uint8_t hour() const; + + inline uint8_t minute() const; + + inline uint8_t second() const; + + inline uint16_t millisecond() const; + + inline uint16_t microsecond() const; + + inline uint16_t nanosecond() const; + + inline const temporal_rs::Calendar& calendar() const; + + inline int32_t year() const; + + inline uint8_t month() const; + + inline std::string month_code() const; + template + inline void month_code_write(W& writeable_output) const; + + inline uint8_t day() const; + + inline uint16_t day_of_week() const; + + inline uint16_t day_of_year() const; + + inline std::optional week_of_year() const; + + inline std::optional year_of_week() const; + + inline uint16_t days_in_week() const; + + inline uint16_t days_in_month() const; + + inline uint16_t days_in_year() const; + + inline uint16_t months_in_year() const; + + inline bool in_leap_year() const; + + inline std::string era() const; + template + inline void era_write(W& writeable_output) const; + + inline std::optional era_year() const; + + inline std::unique_ptr clone() const; + + inline const temporal_rs::capi::ZonedDateTime* AsFFI() const; + inline temporal_rs::capi::ZonedDateTime* AsFFI(); + inline static const temporal_rs::ZonedDateTime* FromFFI(const temporal_rs::capi::ZonedDateTime* ptr); + inline static temporal_rs::ZonedDateTime* FromFFI(temporal_rs::capi::ZonedDateTime* ptr); + inline static void operator delete(void* ptr); +private: + ZonedDateTime() = delete; + ZonedDateTime(const temporal_rs::ZonedDateTime&) = delete; + ZonedDateTime(temporal_rs::ZonedDateTime&&) noexcept = delete; + ZonedDateTime operator=(const temporal_rs::ZonedDateTime&) = delete; + ZonedDateTime operator=(temporal_rs::ZonedDateTime&&) noexcept = delete; + static void operator delete[](void*, size_t) = delete; +}; + +} // namespace +#endif // TEMPORAL_RS_ZonedDateTime_D_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ZonedDateTime.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ZonedDateTime.hpp new file mode 100644 index 00000000000000..350a92bc22d6bc --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/ZonedDateTime.hpp @@ -0,0 +1,779 @@ +#ifndef TEMPORAL_RS_ZonedDateTime_HPP +#define TEMPORAL_RS_ZonedDateTime_HPP + +#include "ZonedDateTime.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "AnyCalendarKind.hpp" +#include "ArithmeticOverflow.hpp" +#include "Calendar.hpp" +#include "DifferenceSettings.hpp" +#include "Disambiguation.hpp" +#include "DisplayCalendar.hpp" +#include "DisplayOffset.hpp" +#include "DisplayTimeZone.hpp" +#include "Duration.hpp" +#include "I128Nanoseconds.hpp" +#include "Instant.hpp" +#include "OffsetDisambiguation.hpp" +#include "ParsedZonedDateTime.hpp" +#include "PartialZonedDateTime.hpp" +#include "PlainDate.hpp" +#include "PlainDateTime.hpp" +#include "PlainTime.hpp" +#include "Provider.hpp" +#include "RoundingOptions.hpp" +#include "TemporalError.hpp" +#include "TimeZone.hpp" +#include "ToStringRoundingOptions.hpp" +#include "TransitionDirection.hpp" +#include "diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + typedef struct temporal_rs_ZonedDateTime_try_new_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_try_new_result; + temporal_rs_ZonedDateTime_try_new_result temporal_rs_ZonedDateTime_try_new(temporal_rs::capi::I128Nanoseconds nanosecond, temporal_rs::capi::AnyCalendarKind calendar, temporal_rs::capi::TimeZone time_zone); + + typedef struct temporal_rs_ZonedDateTime_try_new_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_try_new_with_provider_result; + temporal_rs_ZonedDateTime_try_new_with_provider_result temporal_rs_ZonedDateTime_try_new_with_provider(temporal_rs::capi::I128Nanoseconds nanosecond, temporal_rs::capi::AnyCalendarKind calendar, temporal_rs::capi::TimeZone time_zone, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_ZonedDateTime_from_partial_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_partial_result; + temporal_rs_ZonedDateTime_from_partial_result temporal_rs_ZonedDateTime_from_partial(temporal_rs::capi::PartialZonedDateTime partial, temporal_rs::capi::ArithmeticOverflow_option overflow, temporal_rs::capi::Disambiguation_option disambiguation, temporal_rs::capi::OffsetDisambiguation_option offset_option); + + typedef struct temporal_rs_ZonedDateTime_from_partial_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_partial_with_provider_result; + temporal_rs_ZonedDateTime_from_partial_with_provider_result temporal_rs_ZonedDateTime_from_partial_with_provider(temporal_rs::capi::PartialZonedDateTime partial, temporal_rs::capi::ArithmeticOverflow_option overflow, temporal_rs::capi::Disambiguation_option disambiguation, temporal_rs::capi::OffsetDisambiguation_option offset_option, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_ZonedDateTime_from_parsed_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_parsed_result; + temporal_rs_ZonedDateTime_from_parsed_result temporal_rs_ZonedDateTime_from_parsed(const temporal_rs::capi::ParsedZonedDateTime* parsed, temporal_rs::capi::Disambiguation disambiguation, temporal_rs::capi::OffsetDisambiguation offset_option); + + typedef struct temporal_rs_ZonedDateTime_from_parsed_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_parsed_with_provider_result; + temporal_rs_ZonedDateTime_from_parsed_with_provider_result temporal_rs_ZonedDateTime_from_parsed_with_provider(const temporal_rs::capi::ParsedZonedDateTime* parsed, temporal_rs::capi::Disambiguation disambiguation, temporal_rs::capi::OffsetDisambiguation offset_option, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_ZonedDateTime_from_utf8_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_utf8_result; + temporal_rs_ZonedDateTime_from_utf8_result temporal_rs_ZonedDateTime_from_utf8(temporal_rs::diplomat::capi::DiplomatStringView s, temporal_rs::capi::Disambiguation disambiguation, temporal_rs::capi::OffsetDisambiguation offset_disambiguation); + + typedef struct temporal_rs_ZonedDateTime_from_utf8_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_utf8_with_provider_result; + temporal_rs_ZonedDateTime_from_utf8_with_provider_result temporal_rs_ZonedDateTime_from_utf8_with_provider(temporal_rs::diplomat::capi::DiplomatStringView s, temporal_rs::capi::Disambiguation disambiguation, temporal_rs::capi::OffsetDisambiguation offset_disambiguation, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_ZonedDateTime_from_utf16_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_utf16_result; + temporal_rs_ZonedDateTime_from_utf16_result temporal_rs_ZonedDateTime_from_utf16(temporal_rs::diplomat::capi::DiplomatString16View s, temporal_rs::capi::Disambiguation disambiguation, temporal_rs::capi::OffsetDisambiguation offset_disambiguation); + + typedef struct temporal_rs_ZonedDateTime_from_utf16_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_utf16_with_provider_result; + temporal_rs_ZonedDateTime_from_utf16_with_provider_result temporal_rs_ZonedDateTime_from_utf16_with_provider(temporal_rs::diplomat::capi::DiplomatString16View s, temporal_rs::capi::Disambiguation disambiguation, temporal_rs::capi::OffsetDisambiguation offset_disambiguation, const temporal_rs::capi::Provider* p); + + int64_t temporal_rs_ZonedDateTime_epoch_milliseconds(const temporal_rs::capi::ZonedDateTime* self); + + typedef struct temporal_rs_ZonedDateTime_from_epoch_milliseconds_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_epoch_milliseconds_result; + temporal_rs_ZonedDateTime_from_epoch_milliseconds_result temporal_rs_ZonedDateTime_from_epoch_milliseconds(int64_t ms, temporal_rs::capi::TimeZone tz); + + typedef struct temporal_rs_ZonedDateTime_from_epoch_milliseconds_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_epoch_milliseconds_with_provider_result; + temporal_rs_ZonedDateTime_from_epoch_milliseconds_with_provider_result temporal_rs_ZonedDateTime_from_epoch_milliseconds_with_provider(int64_t ms, temporal_rs::capi::TimeZone tz, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_ZonedDateTime_from_epoch_nanoseconds_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_epoch_nanoseconds_result; + temporal_rs_ZonedDateTime_from_epoch_nanoseconds_result temporal_rs_ZonedDateTime_from_epoch_nanoseconds(temporal_rs::capi::I128Nanoseconds ns, temporal_rs::capi::TimeZone tz); + + typedef struct temporal_rs_ZonedDateTime_from_epoch_nanoseconds_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_epoch_nanoseconds_with_provider_result; + temporal_rs_ZonedDateTime_from_epoch_nanoseconds_with_provider_result temporal_rs_ZonedDateTime_from_epoch_nanoseconds_with_provider(temporal_rs::capi::I128Nanoseconds ns, temporal_rs::capi::TimeZone tz, const temporal_rs::capi::Provider* p); + + temporal_rs::capi::I128Nanoseconds temporal_rs_ZonedDateTime_epoch_nanoseconds(const temporal_rs::capi::ZonedDateTime* self); + + int64_t temporal_rs_ZonedDateTime_offset_nanoseconds(const temporal_rs::capi::ZonedDateTime* self); + + temporal_rs::capi::Instant* temporal_rs_ZonedDateTime_to_instant(const temporal_rs::capi::ZonedDateTime* self); + + typedef struct temporal_rs_ZonedDateTime_with_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_result; + temporal_rs_ZonedDateTime_with_result temporal_rs_ZonedDateTime_with(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::capi::PartialZonedDateTime partial, temporal_rs::capi::Disambiguation_option disambiguation, temporal_rs::capi::OffsetDisambiguation_option offset_option, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_ZonedDateTime_with_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_with_provider_result; + temporal_rs_ZonedDateTime_with_with_provider_result temporal_rs_ZonedDateTime_with_with_provider(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::capi::PartialZonedDateTime partial, temporal_rs::capi::Disambiguation_option disambiguation, temporal_rs::capi::OffsetDisambiguation_option offset_option, temporal_rs::capi::ArithmeticOverflow_option overflow, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_ZonedDateTime_with_timezone_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_timezone_result; + temporal_rs_ZonedDateTime_with_timezone_result temporal_rs_ZonedDateTime_with_timezone(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::capi::TimeZone zone); + + typedef struct temporal_rs_ZonedDateTime_with_timezone_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_timezone_with_provider_result; + temporal_rs_ZonedDateTime_with_timezone_with_provider_result temporal_rs_ZonedDateTime_with_timezone_with_provider(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::capi::TimeZone zone, const temporal_rs::capi::Provider* p); + + temporal_rs::capi::TimeZone temporal_rs_ZonedDateTime_timezone(const temporal_rs::capi::ZonedDateTime* self); + + int8_t temporal_rs_ZonedDateTime_compare_instant(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::ZonedDateTime* other); + + bool temporal_rs_ZonedDateTime_equals(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::ZonedDateTime* other); + + typedef struct temporal_rs_ZonedDateTime_equals_with_provider_result {union {bool ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_equals_with_provider_result; + temporal_rs_ZonedDateTime_equals_with_provider_result temporal_rs_ZonedDateTime_equals_with_provider(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::ZonedDateTime* other, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_ZonedDateTime_offset_result {union { temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_offset_result; + temporal_rs_ZonedDateTime_offset_result temporal_rs_ZonedDateTime_offset(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::diplomat::capi::DiplomatWrite* write); + + typedef struct temporal_rs_ZonedDateTime_start_of_day_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_start_of_day_result; + temporal_rs_ZonedDateTime_start_of_day_result temporal_rs_ZonedDateTime_start_of_day(const temporal_rs::capi::ZonedDateTime* self); + + typedef struct temporal_rs_ZonedDateTime_start_of_day_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_start_of_day_with_provider_result; + temporal_rs_ZonedDateTime_start_of_day_with_provider_result temporal_rs_ZonedDateTime_start_of_day_with_provider(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_ZonedDateTime_get_time_zone_transition_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_get_time_zone_transition_result; + temporal_rs_ZonedDateTime_get_time_zone_transition_result temporal_rs_ZonedDateTime_get_time_zone_transition(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::capi::TransitionDirection direction); + + typedef struct temporal_rs_ZonedDateTime_get_time_zone_transition_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_get_time_zone_transition_with_provider_result; + temporal_rs_ZonedDateTime_get_time_zone_transition_with_provider_result temporal_rs_ZonedDateTime_get_time_zone_transition_with_provider(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::capi::TransitionDirection direction, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_ZonedDateTime_hours_in_day_result {union {double ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_hours_in_day_result; + temporal_rs_ZonedDateTime_hours_in_day_result temporal_rs_ZonedDateTime_hours_in_day(const temporal_rs::capi::ZonedDateTime* self); + + typedef struct temporal_rs_ZonedDateTime_hours_in_day_with_provider_result {union {double ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_hours_in_day_with_provider_result; + temporal_rs_ZonedDateTime_hours_in_day_with_provider_result temporal_rs_ZonedDateTime_hours_in_day_with_provider(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::Provider* p); + + temporal_rs::capi::PlainDateTime* temporal_rs_ZonedDateTime_to_plain_datetime(const temporal_rs::capi::ZonedDateTime* self); + + temporal_rs::capi::PlainDate* temporal_rs_ZonedDateTime_to_plain_date(const temporal_rs::capi::ZonedDateTime* self); + + temporal_rs::capi::PlainTime* temporal_rs_ZonedDateTime_to_plain_time(const temporal_rs::capi::ZonedDateTime* self); + + typedef struct temporal_rs_ZonedDateTime_to_ixdtf_string_result {union { temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_to_ixdtf_string_result; + temporal_rs_ZonedDateTime_to_ixdtf_string_result temporal_rs_ZonedDateTime_to_ixdtf_string(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::capi::DisplayOffset display_offset, temporal_rs::capi::DisplayTimeZone display_timezone, temporal_rs::capi::DisplayCalendar display_calendar, temporal_rs::capi::ToStringRoundingOptions options, temporal_rs::diplomat::capi::DiplomatWrite* write); + + typedef struct temporal_rs_ZonedDateTime_to_ixdtf_string_with_provider_result {union { temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_to_ixdtf_string_with_provider_result; + temporal_rs_ZonedDateTime_to_ixdtf_string_with_provider_result temporal_rs_ZonedDateTime_to_ixdtf_string_with_provider(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::capi::DisplayOffset display_offset, temporal_rs::capi::DisplayTimeZone display_timezone, temporal_rs::capi::DisplayCalendar display_calendar, temporal_rs::capi::ToStringRoundingOptions options, const temporal_rs::capi::Provider* p, temporal_rs::diplomat::capi::DiplomatWrite* write); + + temporal_rs::capi::ZonedDateTime* temporal_rs_ZonedDateTime_with_calendar(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::capi::AnyCalendarKind calendar); + + typedef struct temporal_rs_ZonedDateTime_with_plain_time_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_plain_time_result; + temporal_rs_ZonedDateTime_with_plain_time_result temporal_rs_ZonedDateTime_with_plain_time(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::PlainTime* time); + + typedef struct temporal_rs_ZonedDateTime_with_plain_time_and_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_plain_time_and_provider_result; + temporal_rs_ZonedDateTime_with_plain_time_and_provider_result temporal_rs_ZonedDateTime_with_plain_time_and_provider(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::PlainTime* time, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_ZonedDateTime_add_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_add_result; + temporal_rs_ZonedDateTime_add_result temporal_rs_ZonedDateTime_add(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::Duration* duration, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_ZonedDateTime_add_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_add_with_provider_result; + temporal_rs_ZonedDateTime_add_with_provider_result temporal_rs_ZonedDateTime_add_with_provider(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::Duration* duration, temporal_rs::capi::ArithmeticOverflow_option overflow, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_ZonedDateTime_subtract_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_subtract_result; + temporal_rs_ZonedDateTime_subtract_result temporal_rs_ZonedDateTime_subtract(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::Duration* duration, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_ZonedDateTime_subtract_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_subtract_with_provider_result; + temporal_rs_ZonedDateTime_subtract_with_provider_result temporal_rs_ZonedDateTime_subtract_with_provider(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::Duration* duration, temporal_rs::capi::ArithmeticOverflow_option overflow, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_ZonedDateTime_until_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_until_result; + temporal_rs_ZonedDateTime_until_result temporal_rs_ZonedDateTime_until(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::ZonedDateTime* other, temporal_rs::capi::DifferenceSettings settings); + + typedef struct temporal_rs_ZonedDateTime_until_with_provider_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_until_with_provider_result; + temporal_rs_ZonedDateTime_until_with_provider_result temporal_rs_ZonedDateTime_until_with_provider(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::ZonedDateTime* other, temporal_rs::capi::DifferenceSettings settings, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_ZonedDateTime_since_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_since_result; + temporal_rs_ZonedDateTime_since_result temporal_rs_ZonedDateTime_since(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::ZonedDateTime* other, temporal_rs::capi::DifferenceSettings settings); + + typedef struct temporal_rs_ZonedDateTime_since_with_provider_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_since_with_provider_result; + temporal_rs_ZonedDateTime_since_with_provider_result temporal_rs_ZonedDateTime_since_with_provider(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::ZonedDateTime* other, temporal_rs::capi::DifferenceSettings settings, const temporal_rs::capi::Provider* p); + + typedef struct temporal_rs_ZonedDateTime_round_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_round_result; + temporal_rs_ZonedDateTime_round_result temporal_rs_ZonedDateTime_round(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::capi::RoundingOptions options); + + typedef struct temporal_rs_ZonedDateTime_round_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_round_with_provider_result; + temporal_rs_ZonedDateTime_round_with_provider_result temporal_rs_ZonedDateTime_round_with_provider(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::capi::RoundingOptions options, const temporal_rs::capi::Provider* p); + + uint8_t temporal_rs_ZonedDateTime_hour(const temporal_rs::capi::ZonedDateTime* self); + + uint8_t temporal_rs_ZonedDateTime_minute(const temporal_rs::capi::ZonedDateTime* self); + + uint8_t temporal_rs_ZonedDateTime_second(const temporal_rs::capi::ZonedDateTime* self); + + uint16_t temporal_rs_ZonedDateTime_millisecond(const temporal_rs::capi::ZonedDateTime* self); + + uint16_t temporal_rs_ZonedDateTime_microsecond(const temporal_rs::capi::ZonedDateTime* self); + + uint16_t temporal_rs_ZonedDateTime_nanosecond(const temporal_rs::capi::ZonedDateTime* self); + + const temporal_rs::capi::Calendar* temporal_rs_ZonedDateTime_calendar(const temporal_rs::capi::ZonedDateTime* self); + + int32_t temporal_rs_ZonedDateTime_year(const temporal_rs::capi::ZonedDateTime* self); + + uint8_t temporal_rs_ZonedDateTime_month(const temporal_rs::capi::ZonedDateTime* self); + + void temporal_rs_ZonedDateTime_month_code(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::diplomat::capi::DiplomatWrite* write); + + uint8_t temporal_rs_ZonedDateTime_day(const temporal_rs::capi::ZonedDateTime* self); + + uint16_t temporal_rs_ZonedDateTime_day_of_week(const temporal_rs::capi::ZonedDateTime* self); + + uint16_t temporal_rs_ZonedDateTime_day_of_year(const temporal_rs::capi::ZonedDateTime* self); + + typedef struct temporal_rs_ZonedDateTime_week_of_year_result {union {uint8_t ok; }; bool is_ok;} temporal_rs_ZonedDateTime_week_of_year_result; + temporal_rs_ZonedDateTime_week_of_year_result temporal_rs_ZonedDateTime_week_of_year(const temporal_rs::capi::ZonedDateTime* self); + + typedef struct temporal_rs_ZonedDateTime_year_of_week_result {union {int32_t ok; }; bool is_ok;} temporal_rs_ZonedDateTime_year_of_week_result; + temporal_rs_ZonedDateTime_year_of_week_result temporal_rs_ZonedDateTime_year_of_week(const temporal_rs::capi::ZonedDateTime* self); + + uint16_t temporal_rs_ZonedDateTime_days_in_week(const temporal_rs::capi::ZonedDateTime* self); + + uint16_t temporal_rs_ZonedDateTime_days_in_month(const temporal_rs::capi::ZonedDateTime* self); + + uint16_t temporal_rs_ZonedDateTime_days_in_year(const temporal_rs::capi::ZonedDateTime* self); + + uint16_t temporal_rs_ZonedDateTime_months_in_year(const temporal_rs::capi::ZonedDateTime* self); + + bool temporal_rs_ZonedDateTime_in_leap_year(const temporal_rs::capi::ZonedDateTime* self); + + void temporal_rs_ZonedDateTime_era(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::diplomat::capi::DiplomatWrite* write); + + typedef struct temporal_rs_ZonedDateTime_era_year_result {union {int32_t ok; }; bool is_ok;} temporal_rs_ZonedDateTime_era_year_result; + temporal_rs_ZonedDateTime_era_year_result temporal_rs_ZonedDateTime_era_year(const temporal_rs::capi::ZonedDateTime* self); + + temporal_rs::capi::ZonedDateTime* temporal_rs_ZonedDateTime_clone(const temporal_rs::capi::ZonedDateTime* self); + + void temporal_rs_ZonedDateTime_destroy(ZonedDateTime* self); + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::try_new(temporal_rs::I128Nanoseconds nanosecond, temporal_rs::AnyCalendarKind calendar, temporal_rs::TimeZone time_zone) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_try_new(nanosecond.AsFFI(), + calendar.AsFFI(), + time_zone.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::try_new_with_provider(temporal_rs::I128Nanoseconds nanosecond, temporal_rs::AnyCalendarKind calendar, temporal_rs::TimeZone time_zone, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_try_new_with_provider(nanosecond.AsFFI(), + calendar.AsFFI(), + time_zone.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::from_partial(temporal_rs::PartialZonedDateTime partial, std::optional overflow, std::optional disambiguation, std::optional offset_option) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_from_partial(partial.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false }), + disambiguation.has_value() ? (temporal_rs::capi::Disambiguation_option{ { disambiguation.value().AsFFI() }, true }) : (temporal_rs::capi::Disambiguation_option{ {}, false }), + offset_option.has_value() ? (temporal_rs::capi::OffsetDisambiguation_option{ { offset_option.value().AsFFI() }, true }) : (temporal_rs::capi::OffsetDisambiguation_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::from_partial_with_provider(temporal_rs::PartialZonedDateTime partial, std::optional overflow, std::optional disambiguation, std::optional offset_option, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_from_partial_with_provider(partial.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false }), + disambiguation.has_value() ? (temporal_rs::capi::Disambiguation_option{ { disambiguation.value().AsFFI() }, true }) : (temporal_rs::capi::Disambiguation_option{ {}, false }), + offset_option.has_value() ? (temporal_rs::capi::OffsetDisambiguation_option{ { offset_option.value().AsFFI() }, true }) : (temporal_rs::capi::OffsetDisambiguation_option{ {}, false }), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::from_parsed(const temporal_rs::ParsedZonedDateTime& parsed, temporal_rs::Disambiguation disambiguation, temporal_rs::OffsetDisambiguation offset_option) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_from_parsed(parsed.AsFFI(), + disambiguation.AsFFI(), + offset_option.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::from_parsed_with_provider(const temporal_rs::ParsedZonedDateTime& parsed, temporal_rs::Disambiguation disambiguation, temporal_rs::OffsetDisambiguation offset_option, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_from_parsed_with_provider(parsed.AsFFI(), + disambiguation.AsFFI(), + offset_option.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::from_utf8(std::string_view s, temporal_rs::Disambiguation disambiguation, temporal_rs::OffsetDisambiguation offset_disambiguation) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_from_utf8({s.data(), s.size()}, + disambiguation.AsFFI(), + offset_disambiguation.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::from_utf8_with_provider(std::string_view s, temporal_rs::Disambiguation disambiguation, temporal_rs::OffsetDisambiguation offset_disambiguation, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_from_utf8_with_provider({s.data(), s.size()}, + disambiguation.AsFFI(), + offset_disambiguation.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::from_utf16(std::u16string_view s, temporal_rs::Disambiguation disambiguation, temporal_rs::OffsetDisambiguation offset_disambiguation) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_from_utf16({s.data(), s.size()}, + disambiguation.AsFFI(), + offset_disambiguation.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::from_utf16_with_provider(std::u16string_view s, temporal_rs::Disambiguation disambiguation, temporal_rs::OffsetDisambiguation offset_disambiguation, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_from_utf16_with_provider({s.data(), s.size()}, + disambiguation.AsFFI(), + offset_disambiguation.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline int64_t temporal_rs::ZonedDateTime::epoch_milliseconds() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_epoch_milliseconds(this->AsFFI()); + return result; +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::from_epoch_milliseconds(int64_t ms, temporal_rs::TimeZone tz) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_from_epoch_milliseconds(ms, + tz.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::from_epoch_milliseconds_with_provider(int64_t ms, temporal_rs::TimeZone tz, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_from_epoch_milliseconds_with_provider(ms, + tz.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::from_epoch_nanoseconds(temporal_rs::I128Nanoseconds ns, temporal_rs::TimeZone tz) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_from_epoch_nanoseconds(ns.AsFFI(), + tz.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::from_epoch_nanoseconds_with_provider(temporal_rs::I128Nanoseconds ns, temporal_rs::TimeZone tz, const temporal_rs::Provider& p) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_from_epoch_nanoseconds_with_provider(ns.AsFFI(), + tz.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::I128Nanoseconds temporal_rs::ZonedDateTime::epoch_nanoseconds() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_epoch_nanoseconds(this->AsFFI()); + return temporal_rs::I128Nanoseconds::FromFFI(result); +} + +inline int64_t temporal_rs::ZonedDateTime::offset_nanoseconds() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_offset_nanoseconds(this->AsFFI()); + return result; +} + +inline std::unique_ptr temporal_rs::ZonedDateTime::to_instant() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_to_instant(this->AsFFI()); + return std::unique_ptr(temporal_rs::Instant::FromFFI(result)); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::with(temporal_rs::PartialZonedDateTime partial, std::optional disambiguation, std::optional offset_option, std::optional overflow) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_with(this->AsFFI(), + partial.AsFFI(), + disambiguation.has_value() ? (temporal_rs::capi::Disambiguation_option{ { disambiguation.value().AsFFI() }, true }) : (temporal_rs::capi::Disambiguation_option{ {}, false }), + offset_option.has_value() ? (temporal_rs::capi::OffsetDisambiguation_option{ { offset_option.value().AsFFI() }, true }) : (temporal_rs::capi::OffsetDisambiguation_option{ {}, false }), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::with_with_provider(temporal_rs::PartialZonedDateTime partial, std::optional disambiguation, std::optional offset_option, std::optional overflow, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_with_with_provider(this->AsFFI(), + partial.AsFFI(), + disambiguation.has_value() ? (temporal_rs::capi::Disambiguation_option{ { disambiguation.value().AsFFI() }, true }) : (temporal_rs::capi::Disambiguation_option{ {}, false }), + offset_option.has_value() ? (temporal_rs::capi::OffsetDisambiguation_option{ { offset_option.value().AsFFI() }, true }) : (temporal_rs::capi::OffsetDisambiguation_option{ {}, false }), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false }), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::with_timezone(temporal_rs::TimeZone zone) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_with_timezone(this->AsFFI(), + zone.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::with_timezone_with_provider(temporal_rs::TimeZone zone, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_with_timezone_with_provider(this->AsFFI(), + zone.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::TimeZone temporal_rs::ZonedDateTime::timezone() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_timezone(this->AsFFI()); + return temporal_rs::TimeZone::FromFFI(result); +} + +inline int8_t temporal_rs::ZonedDateTime::compare_instant(const temporal_rs::ZonedDateTime& other) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_compare_instant(this->AsFFI(), + other.AsFFI()); + return result; +} + +inline bool temporal_rs::ZonedDateTime::equals(const temporal_rs::ZonedDateTime& other) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_equals(this->AsFFI(), + other.AsFFI()); + return result; +} + +inline temporal_rs::diplomat::result temporal_rs::ZonedDateTime::equals_with_provider(const temporal_rs::ZonedDateTime& other, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_equals_with_provider(this->AsFFI(), + other.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(result.ok)) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::ZonedDateTime::offset() const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_offset(this->AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(std::move(output))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} +template +inline temporal_rs::diplomat::result temporal_rs::ZonedDateTime::offset_write(W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_offset(this->AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok()) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::start_of_day() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_start_of_day(this->AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::start_of_day_with_provider(const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_start_of_day_with_provider(this->AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::get_time_zone_transition(temporal_rs::TransitionDirection direction) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_get_time_zone_transition(this->AsFFI(), + direction.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::get_time_zone_transition_with_provider(temporal_rs::TransitionDirection direction, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_get_time_zone_transition_with_provider(this->AsFFI(), + direction.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::ZonedDateTime::hours_in_day() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_hours_in_day(this->AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(result.ok)) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::ZonedDateTime::hours_in_day_with_provider(const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_hours_in_day_with_provider(this->AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(result.ok)) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline std::unique_ptr temporal_rs::ZonedDateTime::to_plain_datetime() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_to_plain_datetime(this->AsFFI()); + return std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result)); +} + +inline std::unique_ptr temporal_rs::ZonedDateTime::to_plain_date() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_to_plain_date(this->AsFFI()); + return std::unique_ptr(temporal_rs::PlainDate::FromFFI(result)); +} + +inline std::unique_ptr temporal_rs::ZonedDateTime::to_plain_time() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_to_plain_time(this->AsFFI()); + return std::unique_ptr(temporal_rs::PlainTime::FromFFI(result)); +} + +inline temporal_rs::diplomat::result temporal_rs::ZonedDateTime::to_ixdtf_string(temporal_rs::DisplayOffset display_offset, temporal_rs::DisplayTimeZone display_timezone, temporal_rs::DisplayCalendar display_calendar, temporal_rs::ToStringRoundingOptions options) const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_to_ixdtf_string(this->AsFFI(), + display_offset.AsFFI(), + display_timezone.AsFFI(), + display_calendar.AsFFI(), + options.AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(std::move(output))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} +template +inline temporal_rs::diplomat::result temporal_rs::ZonedDateTime::to_ixdtf_string_write(temporal_rs::DisplayOffset display_offset, temporal_rs::DisplayTimeZone display_timezone, temporal_rs::DisplayCalendar display_calendar, temporal_rs::ToStringRoundingOptions options, W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_to_ixdtf_string(this->AsFFI(), + display_offset.AsFFI(), + display_timezone.AsFFI(), + display_calendar.AsFFI(), + options.AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok()) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::ZonedDateTime::to_ixdtf_string_with_provider(temporal_rs::DisplayOffset display_offset, temporal_rs::DisplayTimeZone display_timezone, temporal_rs::DisplayCalendar display_calendar, temporal_rs::ToStringRoundingOptions options, const temporal_rs::Provider& p) const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_to_ixdtf_string_with_provider(this->AsFFI(), + display_offset.AsFFI(), + display_timezone.AsFFI(), + display_calendar.AsFFI(), + options.AsFFI(), + p.AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(std::move(output))) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} +template +inline temporal_rs::diplomat::result temporal_rs::ZonedDateTime::to_ixdtf_string_with_provider_write(temporal_rs::DisplayOffset display_offset, temporal_rs::DisplayTimeZone display_timezone, temporal_rs::DisplayCalendar display_calendar, temporal_rs::ToStringRoundingOptions options, const temporal_rs::Provider& p, W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_to_ixdtf_string_with_provider(this->AsFFI(), + display_offset.AsFFI(), + display_timezone.AsFFI(), + display_calendar.AsFFI(), + options.AsFFI(), + p.AsFFI(), + &write); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok()) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline std::unique_ptr temporal_rs::ZonedDateTime::with_calendar(temporal_rs::AnyCalendarKind calendar) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_with_calendar(this->AsFFI(), + calendar.AsFFI()); + return std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result)); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::with_plain_time(const temporal_rs::PlainTime* time) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_with_plain_time(this->AsFFI(), + time ? time->AsFFI() : nullptr); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::with_plain_time_and_provider(const temporal_rs::PlainTime* time, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_with_plain_time_and_provider(this->AsFFI(), + time ? time->AsFFI() : nullptr, + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::add(const temporal_rs::Duration& duration, std::optional overflow) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_add(this->AsFFI(), + duration.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::add_with_provider(const temporal_rs::Duration& duration, std::optional overflow, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_add_with_provider(this->AsFFI(), + duration.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false }), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::subtract(const temporal_rs::Duration& duration, std::optional overflow) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_subtract(this->AsFFI(), + duration.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::subtract_with_provider(const temporal_rs::Duration& duration, std::optional overflow, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_subtract_with_provider(this->AsFFI(), + duration.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false }), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::until(const temporal_rs::ZonedDateTime& other, temporal_rs::DifferenceSettings settings) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_until(this->AsFFI(), + other.AsFFI(), + settings.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::until_with_provider(const temporal_rs::ZonedDateTime& other, temporal_rs::DifferenceSettings settings, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_until_with_provider(this->AsFFI(), + other.AsFFI(), + settings.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::since(const temporal_rs::ZonedDateTime& other, temporal_rs::DifferenceSettings settings) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_since(this->AsFFI(), + other.AsFFI(), + settings.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::since_with_provider(const temporal_rs::ZonedDateTime& other, temporal_rs::DifferenceSettings settings, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_since_with_provider(this->AsFFI(), + other.AsFFI(), + settings.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::round(temporal_rs::RoundingOptions options) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_round(this->AsFFI(), + options.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::round_with_provider(temporal_rs::RoundingOptions options, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_round_with_provider(this->AsFFI(), + options.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline uint8_t temporal_rs::ZonedDateTime::hour() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_hour(this->AsFFI()); + return result; +} + +inline uint8_t temporal_rs::ZonedDateTime::minute() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_minute(this->AsFFI()); + return result; +} + +inline uint8_t temporal_rs::ZonedDateTime::second() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_second(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::ZonedDateTime::millisecond() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_millisecond(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::ZonedDateTime::microsecond() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_microsecond(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::ZonedDateTime::nanosecond() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_nanosecond(this->AsFFI()); + return result; +} + +inline const temporal_rs::Calendar& temporal_rs::ZonedDateTime::calendar() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_calendar(this->AsFFI()); + return *temporal_rs::Calendar::FromFFI(result); +} + +inline int32_t temporal_rs::ZonedDateTime::year() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_year(this->AsFFI()); + return result; +} + +inline uint8_t temporal_rs::ZonedDateTime::month() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_month(this->AsFFI()); + return result; +} + +inline std::string temporal_rs::ZonedDateTime::month_code() const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + temporal_rs::capi::temporal_rs_ZonedDateTime_month_code(this->AsFFI(), + &write); + return output; +} +template +inline void temporal_rs::ZonedDateTime::month_code_write(W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + temporal_rs::capi::temporal_rs_ZonedDateTime_month_code(this->AsFFI(), + &write); +} + +inline uint8_t temporal_rs::ZonedDateTime::day() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_day(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::ZonedDateTime::day_of_week() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_day_of_week(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::ZonedDateTime::day_of_year() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_day_of_year(this->AsFFI()); + return result; +} + +inline std::optional temporal_rs::ZonedDateTime::week_of_year() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_week_of_year(this->AsFFI()); + return result.is_ok ? std::optional(result.ok) : std::nullopt; +} + +inline std::optional temporal_rs::ZonedDateTime::year_of_week() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_year_of_week(this->AsFFI()); + return result.is_ok ? std::optional(result.ok) : std::nullopt; +} + +inline uint16_t temporal_rs::ZonedDateTime::days_in_week() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_days_in_week(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::ZonedDateTime::days_in_month() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_days_in_month(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::ZonedDateTime::days_in_year() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_days_in_year(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::ZonedDateTime::months_in_year() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_months_in_year(this->AsFFI()); + return result; +} + +inline bool temporal_rs::ZonedDateTime::in_leap_year() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_in_leap_year(this->AsFFI()); + return result; +} + +inline std::string temporal_rs::ZonedDateTime::era() const { + std::string output; + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); + temporal_rs::capi::temporal_rs_ZonedDateTime_era(this->AsFFI(), + &write); + return output; +} +template +inline void temporal_rs::ZonedDateTime::era_write(W& writeable) const { + temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteTrait::Construct(writeable); + temporal_rs::capi::temporal_rs_ZonedDateTime_era(this->AsFFI(), + &write); +} + +inline std::optional temporal_rs::ZonedDateTime::era_year() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_era_year(this->AsFFI()); + return result.is_ok ? std::optional(result.ok) : std::nullopt; +} + +inline std::unique_ptr temporal_rs::ZonedDateTime::clone() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_clone(this->AsFFI()); + return std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result)); +} + +inline const temporal_rs::capi::ZonedDateTime* temporal_rs::ZonedDateTime::AsFFI() const { + return reinterpret_cast(this); +} + +inline temporal_rs::capi::ZonedDateTime* temporal_rs::ZonedDateTime::AsFFI() { + return reinterpret_cast(this); +} + +inline const temporal_rs::ZonedDateTime* temporal_rs::ZonedDateTime::FromFFI(const temporal_rs::capi::ZonedDateTime* ptr) { + return reinterpret_cast(ptr); +} + +inline temporal_rs::ZonedDateTime* temporal_rs::ZonedDateTime::FromFFI(temporal_rs::capi::ZonedDateTime* ptr) { + return reinterpret_cast(ptr); +} + +inline void temporal_rs::ZonedDateTime::operator delete(void* ptr) { + temporal_rs::capi::temporal_rs_ZonedDateTime_destroy(reinterpret_cast(ptr)); +} + + +#endif // TEMPORAL_RS_ZonedDateTime_HPP diff --git a/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/diplomat_runtime.hpp b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/diplomat_runtime.hpp new file mode 100644 index 00000000000000..1e32c8929c99cd --- /dev/null +++ b/deps/temporal/temporal_capi/bindings/cpp/temporal_rs/diplomat_runtime.hpp @@ -0,0 +1,566 @@ +#ifndef TEMPORAL_RS_DIPLOMAT_RUNTIME_CPP_H +#define TEMPORAL_RS_DIPLOMAT_RUNTIME_CPP_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#if __cplusplus >= 202002L +#include +#else +#include +#endif + +namespace temporal_rs { +namespace diplomat { + +namespace capi { +extern "C" { + +static_assert(sizeof(char) == sizeof(uint8_t), "your architecture's `char` is not 8 bits"); +static_assert(sizeof(char16_t) == sizeof(uint16_t), "your architecture's `char16_t` is not 16 bits"); +static_assert(sizeof(char32_t) == sizeof(uint32_t), "your architecture's `char32_t` is not 32 bits"); + +typedef struct DiplomatWrite { + void* context; + char* buf; + size_t len; + size_t cap; + bool grow_failed; + void (*flush)(struct DiplomatWrite*); + bool (*grow)(struct DiplomatWrite*, size_t); +} DiplomatWrite; + +bool diplomat_is_str(const char* buf, size_t len); + +#define MAKE_SLICES(name, c_ty) \ + typedef struct Diplomat##name##View { \ + const c_ty* data; \ + size_t len; \ + } Diplomat##name##View; \ + typedef struct Diplomat##name##ViewMut { \ + c_ty* data; \ + size_t len; \ + } Diplomat##name##ViewMut; \ + typedef struct Diplomat##name##Array { \ + const c_ty* data; \ + size_t len; \ + } Diplomat##name##Array; + +#define MAKE_SLICES_AND_OPTIONS(name, c_ty) \ + MAKE_SLICES(name, c_ty) \ + typedef struct Option##name {union { c_ty ok; }; bool is_ok; } Option##name; \ + typedef struct Option##name##View {union { Diplomat##name##View ok; }; bool is_ok; } Option##name##View; \ + typedef struct Option##name##ViewMut {union { Diplomat##name##ViewMut ok; }; bool is_ok; } Option##name##ViewMut; \ + typedef struct Option##name##Array {union { Diplomat##name##Array ok; }; bool is_ok; } Option##name##Array; \ + +MAKE_SLICES_AND_OPTIONS(I8, int8_t) +MAKE_SLICES_AND_OPTIONS(U8, uint8_t) +MAKE_SLICES_AND_OPTIONS(I16, int16_t) +MAKE_SLICES_AND_OPTIONS(U16, uint16_t) +MAKE_SLICES_AND_OPTIONS(I32, int32_t) +MAKE_SLICES_AND_OPTIONS(U32, uint32_t) +MAKE_SLICES_AND_OPTIONS(I64, int64_t) +MAKE_SLICES_AND_OPTIONS(U64, uint64_t) +MAKE_SLICES_AND_OPTIONS(Isize, intptr_t) +MAKE_SLICES_AND_OPTIONS(Usize, size_t) +MAKE_SLICES_AND_OPTIONS(F32, float) +MAKE_SLICES_AND_OPTIONS(F64, double) +MAKE_SLICES_AND_OPTIONS(Bool, bool) +MAKE_SLICES_AND_OPTIONS(Char, char32_t) +MAKE_SLICES_AND_OPTIONS(String, char) +MAKE_SLICES_AND_OPTIONS(String16, char16_t) +MAKE_SLICES_AND_OPTIONS(Strings, DiplomatStringView) +MAKE_SLICES_AND_OPTIONS(Strings16, DiplomatString16View) + +} // extern "C" +} // namespace capi + +extern "C" inline void _flush(capi::DiplomatWrite* w) { + std::string* string = reinterpret_cast(w->context); + string->resize(w->len); +} + +extern "C" inline bool _grow(capi::DiplomatWrite* w, uintptr_t requested) { + std::string* string = reinterpret_cast(w->context); + string->resize(requested); + w->cap = string->length(); + w->buf = &(*string)[0]; + return true; +} + +inline capi::DiplomatWrite WriteFromString(std::string& string) { + capi::DiplomatWrite w; + w.context = &string; + w.buf = &string[0]; + w.len = string.length(); + w.cap = string.length(); + // Will never become true, as _grow is infallible. + w.grow_failed = false; + w.flush = _flush; + w.grow = _grow; + return w; +} + +// This "trait" allows one to use _write() methods to efficiently +// write to a custom string type. To do this you need to write a specialized +// `WriteTrait` (see WriteTrait below) +// that is capable of constructing a DiplomatWrite, which can wrap +// your string type with appropriate resize/flush functionality. +template struct WriteTrait { + // Fill in this method on a specialization to implement this trait + // static inline capi::DiplomatWrite Construct(T& t); +}; + +template<> struct WriteTrait { + static inline capi::DiplomatWrite Construct(std::string& t) { + return diplomat::WriteFromString(t); + } +}; + +template struct Ok { + T inner; + + // Move constructor always allowed + Ok(T&& i): inner(std::forward(i)) {} + + // copy constructor allowed only for trivially copyable types + template::value>::type> + Ok(const T& i) : inner(i) {} + + Ok() = default; + Ok(Ok&&) noexcept = default; + Ok(const Ok &) = default; + Ok& operator=(const Ok&) = default; + Ok& operator=(Ok&&) noexcept = default; +}; + + +template struct Err { + T inner; + + // Move constructor always allowed + Err(T&& i): inner(std::forward(i)) {} + + // copy constructor allowed only for trivially copyable types + template::value>::type> + Err(const T& i) : inner(i) {} + + Err() = default; + Err(Err&&) noexcept = default; + Err(const Err &) = default; + Err& operator=(const Err&) = default; + Err& operator=(Err&&) noexcept = default; +}; + +template struct fn_traits; + +template +class result { +protected: + std::variant, Err> val; +public: + template + friend struct fn_traits; + + result(Ok&& v): val(std::move(v)) {} + result(Err&& v): val(std::move(v)) {} + result() = default; + result(const result &) = default; + result& operator=(const result&) = default; + result& operator=(result&&) noexcept = default; + result(result &&) noexcept = default; + ~result() = default; + bool is_ok() const { + return std::holds_alternative>(this->val); + } + bool is_err() const { + return std::holds_alternative>(this->val); + } + + template, std::nullptr_t> = nullptr> + std::optional ok() && { + if (!this->is_ok()) { + return std::nullopt; + } + return std::make_optional(std::move(std::get>(std::move(this->val)).inner)); + } + + template, std::nullptr_t> = nullptr> + std::optional err() && { + if (!this->is_err()) { + return std::nullopt; + } + return std::make_optional(std::move(std::get>(std::move(this->val)).inner)); + } + + // std::optional does not work with reference types directly, so wrap them if present + template, std::nullptr_t> = nullptr> + std::optional>> ok() && { + if (!this->is_ok()) { + return std::nullopt; + } + return std::make_optional(std::reference_wrapper(std::forward(std::get>(std::move(this->val)).inner))); + } + + template, std::nullptr_t> = nullptr> + std::optional>> err() && { + if (!this->is_err()) { + return std::nullopt; + } + return std::make_optional(std::reference_wrapper(std::forward(std::get>(std::move(this->val)).inner))); + } + + void set_ok(T&& t) { + this->val = Ok(std::move(t)); + } + + void set_err(E&& e) { + this->val = Err(std::move(e)); + } + + template + result replace_ok(T2&& t) { + if (this->is_err()) { + return result(Err(std::get>(std::move(this->val)))); + } else { + return result(Ok(std::move(t))); + } + } +}; + +class Utf8Error {}; + +// Use custom std::span on C++17, otherwise use std::span +#if __cplusplus >= 202002L + +constexpr std::size_t dynamic_extent = std::dynamic_extent; +template using span = std::span; + +#else // __cplusplus < 202002L + +// C++-17-compatible-ish std::span +constexpr size_t dynamic_extent = std::numeric_limits::max(); +template +class span { +public: + constexpr span(T *data = nullptr, size_t size = Extent) + : data_(data), size_(size) {} + + constexpr span(const span &o) + : data_(o.data_), size_(o.size_) {} + template + constexpr span(std::array, N> &arr) + : data_(const_cast(arr.data())), size_(N) {} + + constexpr T* data() const noexcept { + return this->data_; + } + constexpr size_t size() const noexcept { + return this->size_; + } + + constexpr T *begin() const noexcept { return data(); } + constexpr T *end() const noexcept { return data() + size(); } + + void operator=(span o) { + data_ = o.data_; + size_ = o.size_; + } + +private: + T* data_; + size_t size_; +}; + +#endif // __cplusplus >= 202002L + +// An ABI stable std::basic_string_view equivalent for the case of string +// views in slices +template > +class basic_string_view_for_slice { +public: + using std_string_view = std::basic_string_view; + using traits_type = typename std_string_view::traits_type; + using value_type = typename std_string_view::value_type; + using pointer = typename std_string_view::pointer; + using const_pointer = typename std_string_view::const_pointer; + using size_type = typename std_string_view::size_type; + using difference_type = typename std_string_view::difference_type; + + constexpr basic_string_view_for_slice() noexcept + : basic_string_view_for_slice{std_string_view{}} {} + + constexpr basic_string_view_for_slice(const basic_string_view_for_slice& other) noexcept = default; + + constexpr basic_string_view_for_slice(const const_pointer s, const size_type count) + : basic_string_view_for_slice{std_string_view{s, count}} {} + + constexpr basic_string_view_for_slice(const const_pointer s) + : basic_string_view_for_slice{std_string_view{s}} {} + + constexpr basic_string_view_for_slice& operator=(const basic_string_view_for_slice& view) noexcept = default; + + constexpr basic_string_view_for_slice(const std_string_view& s) noexcept + : data_{s.data(), s.size()} {} + + constexpr basic_string_view_for_slice& operator=(const std_string_view& s) noexcept { + data_ = {s.data(), s.size()}; + return *this; + } + + constexpr operator std_string_view() const noexcept { return {data(), size()}; } + constexpr std_string_view as_sv() const noexcept { return *this; } + + constexpr const_pointer data() const noexcept { return data_.data; } + constexpr size_type size() const noexcept { return data_.len; } + +private: + using capi_type = + std::conditional_t, + capi::DiplomatStringView, + std::conditional_t, + capi::DiplomatString16View, + void>>; + + static_assert(!std::is_void_v, + "ABI compatible string_views are only supported for char and char16_t"); + + capi_type data_; +}; + +// We only implement these specialisations as diplomat doesn't provide c abi +// types for others +using string_view_for_slice = basic_string_view_for_slice; +using u16string_view_for_slice = basic_string_view_for_slice; + +using string_view_span = span; +using u16string_view_span = span; + +// Interop between std::function & our C Callback wrapper type + +template +struct as_ffi { + using type = T; +}; + +template +struct as_ffi>().AsFFI())>> { + using type = decltype(std::declval>().AsFFI()); +}; + +template +using as_ffi_t = typename as_ffi::type; + +template +using replace_string_view_t = std::conditional_t, capi::DiplomatStringView, T>; + +template +struct diplomat_c_span_convert { + using type = T; +}; + +#define MAKE_SLICE_CONVERTERS(name, c_ty) \ + template \ + struct diplomat_c_span_convert>>> { \ + using type = diplomat::capi::Diplomat##name##View; \ + }; \ + template \ + struct diplomat_c_span_convert>>> { \ + using type = diplomat::capi::Diplomat##name##ViewMut; \ + }; \ + +MAKE_SLICE_CONVERTERS(I8, int8_t) +MAKE_SLICE_CONVERTERS(U8, uint8_t) +MAKE_SLICE_CONVERTERS(I16, int16_t) +MAKE_SLICE_CONVERTERS(U16, uint16_t) +MAKE_SLICE_CONVERTERS(I32, int32_t) +MAKE_SLICE_CONVERTERS(U32, uint32_t) +MAKE_SLICE_CONVERTERS(I64, int64_t) +MAKE_SLICE_CONVERTERS(U64, uint64_t) +MAKE_SLICE_CONVERTERS(F32, float) +MAKE_SLICE_CONVERTERS(F64, double) +MAKE_SLICE_CONVERTERS(Bool, bool) +MAKE_SLICE_CONVERTERS(Char, char32_t) +MAKE_SLICE_CONVERTERS(String, char) +MAKE_SLICE_CONVERTERS(String16, char16_t) + +template +using diplomat_c_span_convert_t = typename diplomat_c_span_convert::type; + +/// Replace the argument types from the std::function with the argument types for th function pointer +template +using replace_fn_t = diplomat_c_span_convert_t>>; + +template struct fn_traits> { + using fn_ptr_t = Ret(Args...); + using function_t = std::function; + using ret = Ret; + + // For a given T, creates a function that take in the C ABI version & return the C++ type. + template + static T replace(replace_fn_t val) { + if constexpr(std::is_same_v) { + return std::string_view{val.data, val.len}; + } else if constexpr (!std::is_same_v>) { + return T{ val.data, val.len }; + } else if constexpr (!std::is_same_v>) { + if constexpr (std::is_lvalue_reference_v) { + return *std::remove_reference_t::FromFFI(val); + } + else { + return T::FromFFI(val); + } + } + else { + return val; + } + } + + template + static replace_fn_t replace_ret(T val) { + if constexpr(std::is_same_v) { + return {val.data(), val.size()}; + } else if constexpr (!std::is_same_v>) { + // Can we convert straight away to our slice type, or (in the case of ABI compatible structs), do we have to do a reinterpret cast? + if constexpr(std::is_same_v().data()), decltype(replace_fn_t::data)>) { + return replace_fn_t { val.data(), val.size() }; + } else { + return replace_fn_t { reinterpret_cast::data)>(val.data()), val.size() }; + } + } else if constexpr(!std::is_same_v>) { + return val.AsFFI(); + } else { + return val; + } + } + + static Ret c_run_callback(const void *cb, replace_fn_t... args) { + return (*reinterpret_cast(cb))(replace(args)...); + } + + template + static TOut c_run_callback_result(const void *cb, replace_fn_t... args) { + result res = c_run_callback(cb, args...); + + auto is_ok = res.is_ok(); + + constexpr bool has_ok = !std::is_same_v; + constexpr bool has_err = !std::is_same_v; + + TOut out; + out.is_ok = is_ok; + + if constexpr (has_ok) { + if (is_ok) { + out.ok = replace_ret(std::get>(res.val).inner); + } + } + + if constexpr(has_err) { + if (!is_ok) { + out.err = replace_ret(std::get>(res.val).inner); + } + } + + return out; + } + + // For DiplomatOption<> + template + static TOut c_run_callback_diplomat_option(const void *cb, replace_fn_t... args) { + constexpr bool has_ok = !std::is_same_v; + + std::optional ret = c_run_callback(cb, args...); + + bool is_ok = ret.has_value(); + + TOut out; + out.is_ok = is_ok; + + if constexpr(has_ok) { + if (is_ok) { + out.ok = replace_ret(ret.value()); + } + } + return out; + } + + // All we need to do is just convert one pointer to another, while keeping the arguments the same: + template + static T c_run_callback_diplomat_opaque(const void* cb, replace_fn_t... args) { + Ret out = c_run_callback(cb, args...); + + return out->AsFFI(); + } + + static void c_delete(const void *cb) { + delete reinterpret_cast(cb); + } + + fn_traits(function_t) {} // Allows less clunky construction (avoids decltype) +}; + +// additional deduction guide required +template +fn_traits(T) -> fn_traits; + +// Trait for extracting inner types from either std::optional or std::unique_ptr. +// These are the two potential types returned by next() functions +template struct inner { using type = T; }; +template struct inner> { using type = T; }; +template struct inner>{ using type = T; }; + +template::type> +inline const U get_inner_if_present(T v) { + if constexpr(std::is_same_v) { + return std::move(v); + } else { + return *std::move(v); + } +} + +// Adapter for iterator types +template struct has_next : std::false_type {}; +template struct has_next < T, std::void_t().next())>> : std::true_type {}; +template constexpr bool has_next_v = has_next::value; + +/// Helper template enabling native iteration over unique ptrs to objects which implement next() +template +struct next_to_iter_helper { + static_assert(has_next_v, "next_to_iter_helper may only be used with types implementing next()"); + using next_type = decltype(std::declval().next()); + + // STL Iterator trait definitions + using value_type = typename inner::type; + using difference_type = void; + using reference = std::add_lvalue_reference_t; + using iterator_category = std::input_iterator_tag; + + next_to_iter_helper(std::unique_ptr&& ptr) : _ptr(std::move(ptr)), _curr(_ptr->next()) {} + + // https://en.cppreference.com/w/cpp/named_req/InputIterator requires that the type be copyable + next_to_iter_helper(const next_to_iter_helper& o) : _ptr(o._ptr), _curr(o._curr) {} + + void operator++() { _curr = _ptr->next(); } + void operator++(int) { ++(*this); } + const value_type& operator*() const { return *_curr; } + + bool operator!=(std::nullopt_t) { + return (bool)_curr; + } + + std::shared_ptr _ptr; // shared to satisfy the copyable requirement + next_type _curr; +}; + +} // namespace diplomat +} // namespace temporal_rs +#endif \ No newline at end of file diff --git a/deps/temporal/temporal_capi/src/calendar.rs b/deps/temporal/temporal_capi/src/calendar.rs new file mode 100644 index 00000000000000..5184609e5b67bf --- /dev/null +++ b/deps/temporal/temporal_capi/src/calendar.rs @@ -0,0 +1,84 @@ +#[diplomat::bridge] +#[diplomat::abi_rename = "temporal_rs_{0}"] +pub mod ffi { + use crate::error::ffi::TemporalError; + use alloc::boxed::Box; + use diplomat_runtime::DiplomatStr; + use icu_calendar::preferences::CalendarAlgorithm; + + #[diplomat::enum_convert(icu_calendar::AnyCalendarKind, needs_wildcard)] + pub enum AnyCalendarKind { + Buddhist, + Chinese, + Coptic, + Dangi, + Ethiopian, + EthiopianAmeteAlem, + Gregorian, + Hebrew, + Indian, + HijriTabularTypeIIFriday, + HijriSimulatedMecca, + HijriTabularTypeIIThursday, + HijriUmmAlQura, + Iso, + Japanese, + JapaneseExtended, + Persian, + Roc, + } + + impl AnyCalendarKind { + pub fn get_for_str(s: &DiplomatStr) -> Option { + let value = icu_locale::extensions::unicode::Value::try_from_utf8(s).ok()?; + let algorithm = CalendarAlgorithm::try_from(&value).ok()?; + match icu_calendar::AnyCalendarKind::try_from(algorithm) { + Ok(c) => Some(c.into()), + Err(()) if algorithm == CalendarAlgorithm::Hijri(None) => { + Some(Self::HijriTabularTypeIIFriday) + } + Err(()) => None, + } + } + + // https://tc39.es/proposal-temporal/#sec-temporal-parsetemporalcalendarstring + pub fn parse_temporal_calendar_string(s: &DiplomatStr) -> Option { + match temporal_rs::parsers::parse_allowed_calendar_formats(s) { + Some([]) => Some(AnyCalendarKind::Iso), + Some(result) => Self::get_for_str(result), + None => Self::get_for_str(s), + } + } + } + + #[diplomat::opaque] + #[diplomat::transparent_convert] + /// By and large one should not need to construct this type; it mostly exists + /// to represent calendar data found on other Temporal types, obtained via `.calendar()`. + pub struct Calendar(pub temporal_rs::Calendar); + + impl Calendar { + pub fn try_new_constrain(kind: AnyCalendarKind) -> Box { + Box::new(Calendar(temporal_rs::Calendar::new(kind.into()))) + } + + pub fn from_utf8(s: &DiplomatStr) -> Result, TemporalError> { + temporal_rs::Calendar::try_from_utf8(s) + .map(|c| Box::new(Calendar(c))) + .map_err(Into::into) + } + + pub fn is_iso(&self) -> bool { + self.0.is_iso() + } + + pub fn identifier(&self) -> &'static str { + self.0.identifier() + } + /// Returns the kind of this calendar + #[inline] + pub fn kind(&self) -> AnyCalendarKind { + self.0.kind().into() + } + } +} diff --git a/deps/temporal/temporal_capi/src/duration.rs b/deps/temporal/temporal_capi/src/duration.rs new file mode 100644 index 00000000000000..bfa5d92eb1ae79 --- /dev/null +++ b/deps/temporal/temporal_capi/src/duration.rs @@ -0,0 +1,335 @@ +use crate::error::ffi::TemporalError; + +#[diplomat::bridge] +#[diplomat::abi_rename = "temporal_rs_{0}"] +pub mod ffi { + use crate::error::ffi::TemporalError; + use crate::options::ffi::ToStringRoundingOptions; + use crate::options::ffi::{RoundingOptions, Unit}; + use crate::provider::ffi::Provider; + use crate::zoned_date_time::ffi::RelativeTo; + use alloc::boxed::Box; + use alloc::string::String; + use core::str::FromStr; + use diplomat_runtime::DiplomatOption; + use diplomat_runtime::{DiplomatStr, DiplomatStr16}; + use num_traits::FromPrimitive; + + #[diplomat::opaque] + pub struct Duration(pub(crate) temporal_rs::Duration); + + #[diplomat::opaque] + #[diplomat::transparent_convert] + pub struct DateDuration(pub(crate) temporal_rs::duration::DateDuration); + + pub struct PartialDuration { + pub years: DiplomatOption, + pub months: DiplomatOption, + pub weeks: DiplomatOption, + pub days: DiplomatOption, + pub hours: DiplomatOption, + pub minutes: DiplomatOption, + pub seconds: DiplomatOption, + pub milliseconds: DiplomatOption, + pub microseconds: DiplomatOption, + pub nanoseconds: DiplomatOption, + } + + #[diplomat::enum_convert(temporal_rs::Sign)] + pub enum Sign { + Positive = 1, + Zero = 0, + Negative = -1, + } + + impl PartialDuration { + pub fn is_empty(self) -> bool { + temporal_rs::partial::PartialDuration::try_from(self) + .map(|p| p.is_empty()) + .unwrap_or(false) + } + } + + impl DateDuration { + pub fn try_new( + years: i64, + months: i64, + weeks: i64, + days: i64, + ) -> Result, TemporalError> { + temporal_rs::duration::DateDuration::new(years, months, weeks, days) + .map(|x| Box::new(DateDuration(x))) + .map_err(Into::into) + } + + pub fn abs(&self) -> Box { + Box::new(Self(self.0.abs())) + } + pub fn negated(&self) -> Box { + Box::new(Self(self.0.negated())) + } + + pub fn sign(&self) -> Sign { + self.0.sign().into() + } + } + impl Duration { + /// Temporary API until v8 can move off of it + pub fn create( + years: i64, + months: i64, + weeks: i64, + days: i64, + hours: i64, + minutes: i64, + seconds: i64, + milliseconds: i64, + microseconds: f64, + nanoseconds: f64, + ) -> Result, TemporalError> { + Self::try_new( + years, + months, + weeks, + days, + hours, + minutes, + seconds, + milliseconds, + microseconds, + nanoseconds, + ) + } + + pub fn try_new( + years: i64, + months: i64, + weeks: i64, + days: i64, + hours: i64, + minutes: i64, + seconds: i64, + milliseconds: i64, + microseconds: f64, + nanoseconds: f64, + ) -> Result, TemporalError> { + temporal_rs::Duration::new( + years, + months, + weeks, + days, + hours, + minutes, + seconds, + milliseconds, + i128::from_f64(microseconds).ok_or(TemporalError::range("μs out of range"))?, + i128::from_f64(nanoseconds).ok_or(TemporalError::range("ms out of range"))?, + ) + .map(|x| Box::new(Duration(x))) + .map_err(Into::into) + } + + pub fn from_partial_duration(partial: PartialDuration) -> Result, TemporalError> { + temporal_rs::Duration::from_partial_duration(partial.try_into()?) + .map(|x| Box::new(Duration(x))) + .map_err(Into::into) + } + + pub fn from_utf8(s: &DiplomatStr) -> Result, TemporalError> { + temporal_rs::Duration::from_utf8(s) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn from_utf16(s: &DiplomatStr16) -> Result, TemporalError> { + // TODO(#275) This should not need to convert + let s = String::from_utf16(s).map_err(|_| temporal_rs::TemporalError::range())?; + temporal_rs::Duration::from_str(&s) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn is_time_within_range(&self) -> bool { + self.0.is_time_within_range() + } + + // set_time_duration is NOT safe to expose over FFI if the date()/time() methods are available + // Diplomat plans to make this a hard error. + + pub fn years(&self) -> i64 { + self.0.years() + } + pub fn months(&self) -> i64 { + self.0.months() + } + pub fn weeks(&self) -> i64 { + self.0.weeks() + } + pub fn days(&self) -> i64 { + self.0.days() + } + pub fn hours(&self) -> i64 { + self.0.hours() + } + pub fn minutes(&self) -> i64 { + self.0.minutes() + } + pub fn seconds(&self) -> i64 { + self.0.seconds() + } + pub fn milliseconds(&self) -> i64 { + self.0.milliseconds() + } + pub fn microseconds(&self) -> f64 { + // The error case should never occur since + // duration values are clamped within range + // + // https://github.com/boa-dev/temporal/issues/189 + f64::from_i128(self.0.microseconds()).unwrap_or(0.) + } + pub fn nanoseconds(&self) -> f64 { + // The error case should never occur since + // duration values are clamped within range + // + // https://github.com/boa-dev/temporal/issues/189 + f64::from_i128(self.0.nanoseconds()).unwrap_or(0.) + } + + pub fn sign(&self) -> Sign { + self.0.sign().into() + } + + pub fn is_zero(&self) -> bool { + self.0.is_zero() + } + + pub fn abs(&self) -> Box { + Box::new(Self(self.0.abs())) + } + pub fn negated(&self) -> Box { + Box::new(Self(self.0.negated())) + } + + pub fn add(&self, other: &Self) -> Result, TemporalError> { + self.0 + .add(&other.0) + .map(|x| Box::new(Duration(x))) + .map_err(Into::into) + } + + pub fn subtract(&self, other: &Self) -> Result, TemporalError> { + self.0 + .subtract(&other.0) + .map(|x| Box::new(Duration(x))) + .map_err(Into::into) + } + + pub fn to_string( + &self, + options: ToStringRoundingOptions, + write: &mut DiplomatWrite, + ) -> Result<(), TemporalError> { + use core::fmt::Write; + let string = self.0.as_temporal_string(options.into())?; + // throw away the error, this should always succeed + let _ = write.write_str(&string); + + Ok(()) + } + + #[cfg(feature = "compiled_data")] + pub fn round( + &self, + options: RoundingOptions, + relative_to: RelativeTo, + ) -> Result, TemporalError> { + self.round_with_provider(options, relative_to, &Provider::compiled()) + } + pub fn round_with_provider<'p>( + &self, + options: RoundingOptions, + relative_to: RelativeTo, + p: &Provider<'p>, + ) -> Result, TemporalError> { + with_provider!(p, |p| self.0.round_with_provider( + options.try_into()?, + relative_to.into(), + p + )) + .map(|x| Box::new(Duration(x))) + .map_err(Into::into) + } + + #[cfg(feature = "compiled_data")] + pub fn compare(&self, other: &Self, relative_to: RelativeTo) -> Result { + self.compare_with_provider(other, relative_to, &Provider::compiled()) + } + pub fn compare_with_provider<'p>( + &self, + other: &Self, + relative_to: RelativeTo, + p: &Provider<'p>, + ) -> Result { + // Ideally we'd return core::cmp::Ordering here but Diplomat + // isn't happy about needing to convert the contents of a result + with_provider!(p, |p| self.0.compare_with_provider( + &other.0, + relative_to.into(), + p + )) + .map(|x| x as i8) + .map_err(Into::into) + } + + #[cfg(feature = "compiled_data")] + pub fn total(&self, unit: Unit, relative_to: RelativeTo) -> Result { + self.total_with_provider(unit, relative_to, &Provider::compiled()) + } + pub fn total_with_provider<'p>( + &self, + unit: Unit, + relative_to: RelativeTo, + p: &Provider<'p>, + ) -> Result { + with_provider!(p, |p| self.0.total_with_provider( + unit.into(), + relative_to.into(), + p + )) + .map(|x| x.as_inner()) + .map_err(Into::into) + } + + #[allow(clippy::should_implement_trait)] + pub fn clone(&self) -> Box { + Box::new(Self(self.0)) + } + } +} + +impl TryFrom for temporal_rs::partial::PartialDuration { + type Error = TemporalError; + fn try_from(other: ffi::PartialDuration) -> Result { + use num_traits::FromPrimitive; + Ok(Self { + years: other.years.into_option(), + months: other.months.into_option(), + weeks: other.weeks.into_option(), + days: other.days.into_option(), + hours: other.hours.into_option(), + minutes: other.minutes.into_option(), + seconds: other.seconds.into_option(), + milliseconds: other.milliseconds.into_option(), + microseconds: other + .microseconds + .into_option() + .map(|v| i128::from_f64(v).ok_or(TemporalError::range("μs out of range"))) + .transpose()?, + nanoseconds: other + .nanoseconds + .into_option() + .map(|v| i128::from_f64(v).ok_or(TemporalError::range("ns out of range"))) + .transpose()?, + }) + } +} diff --git a/deps/temporal/temporal_capi/src/error.rs b/deps/temporal/temporal_capi/src/error.rs new file mode 100644 index 00000000000000..95c632d14b3d77 --- /dev/null +++ b/deps/temporal/temporal_capi/src/error.rs @@ -0,0 +1,46 @@ +#[diplomat::bridge] +#[diplomat::abi_rename = "temporal_rs_{0}"] +pub mod ffi { + use diplomat_runtime::{DiplomatOption, DiplomatUtf8StrSlice}; + + #[diplomat::enum_convert(temporal_rs::error::ErrorKind)] + pub enum ErrorKind { + Generic, + Type, + Range, + Syntax, + Assert, + } + + // In the future we might turn this into an opaque type with a msg() field + pub struct TemporalError { + pub kind: ErrorKind, + pub msg: DiplomatOption>, + } + + impl TemporalError { + pub(crate) fn range(msg: &'static str) -> Self { + TemporalError { + kind: ErrorKind::Range, + msg: Some(DiplomatUtf8StrSlice::from(msg)).into(), + } + } + pub(crate) fn assert(msg: &'static str) -> Self { + TemporalError { + kind: ErrorKind::Assert, + msg: Some(DiplomatUtf8StrSlice::from(msg)).into(), + } + } + } +} + +impl From for ffi::TemporalError { + fn from(other: temporal_rs::TemporalError) -> Self { + let kind = other.kind().into(); + let msg = other.into_message(); + Self { + kind, + msg: Some(msg.into()).into(), + } + } +} diff --git a/deps/temporal/temporal_capi/src/instant.rs b/deps/temporal/temporal_capi/src/instant.rs new file mode 100644 index 00000000000000..e14a8b8a72c316 --- /dev/null +++ b/deps/temporal/temporal_capi/src/instant.rs @@ -0,0 +1,246 @@ +#[diplomat::bridge] +#[diplomat::abi_rename = "temporal_rs_{0}"] +pub mod ffi { + use crate::duration::ffi::Duration; + use crate::error::ffi::TemporalError; + use crate::options::ffi::{DifferenceSettings, RoundingOptions}; + use crate::zoned_date_time::ffi::ZonedDateTime; + use alloc::boxed::Box; + use alloc::string::String; + use core::str::FromStr; + use diplomat_runtime::{DiplomatStr, DiplomatStr16}; + + use crate::options::ffi::ToStringRoundingOptions; + use crate::provider::ffi::Provider; + use crate::time_zone::ffi::TimeZone; + + #[diplomat::opaque] + pub struct Instant(pub temporal_rs::Instant); + + /// For portability, we use two u64s instead of an i128. + /// The high bit of the u64 is the sign. + /// This cannot represent i128::MIN, and has a -0, but those are largely + /// irrelevant for this purpose. + /// + /// This could potentially instead be a bit-by-bit split, or something else + #[derive(Debug, Copy, Clone)] + pub struct I128Nanoseconds { + pub high: u64, + pub low: u64, + } + + impl I128Nanoseconds { + pub fn is_valid(self) -> bool { + let ns = i128::from(self); + temporal_rs::unix_time::EpochNanoseconds::from(ns) + .check_validity() + .is_ok() + } + } + + impl Instant { + pub fn try_new(ns: I128Nanoseconds) -> Result, TemporalError> { + temporal_rs::Instant::try_new(ns.into()) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn from_epoch_milliseconds( + epoch_milliseconds: i64, + ) -> Result, TemporalError> { + temporal_rs::Instant::from_epoch_milliseconds(epoch_milliseconds) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn from_utf8(s: &DiplomatStr) -> Result, TemporalError> { + temporal_rs::Instant::from_utf8(s) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn from_utf16(s: &DiplomatStr16) -> Result, TemporalError> { + // TODO(#275) This should not need to convert + let s = String::from_utf16(s).map_err(|_| temporal_rs::TemporalError::range())?; + temporal_rs::Instant::from_str(&s) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn add(&self, duration: &Duration) -> Result, TemporalError> { + self.0 + .add(&duration.0) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + pub fn subtract(&self, duration: &Duration) -> Result, TemporalError> { + self.0 + .subtract(&duration.0) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + pub fn since( + &self, + other: &Self, + settings: DifferenceSettings, + ) -> Result, TemporalError> { + self.0 + .since(&other.0, settings.try_into()?) + .map(|c| Box::new(Duration(c))) + .map_err(Into::into) + } + pub fn until( + &self, + other: &Self, + settings: DifferenceSettings, + ) -> Result, TemporalError> { + self.0 + .until(&other.0, settings.try_into()?) + .map(|c| Box::new(Duration(c))) + .map_err(Into::into) + } + pub fn round(&self, options: RoundingOptions) -> Result, TemporalError> { + self.0 + .round(options.try_into()?) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn compare(&self, other: &Self) -> core::cmp::Ordering { + self.0.cmp(&other.0) + } + + pub fn equals(&self, other: &Self) -> bool { + self.0 == other.0 + } + + pub fn epoch_milliseconds(&self) -> i64 { + self.0.epoch_milliseconds() + } + + pub fn epoch_nanoseconds(&self) -> I128Nanoseconds { + let ns = self.0.epoch_nanoseconds().as_i128(); + ns.into() + } + + // TODO: rename after 0.15/0.1.0 to remove the with_compiled_data + #[cfg(feature = "compiled_data")] + pub fn to_ixdtf_string_with_compiled_data( + &self, + zone: Option, + options: ToStringRoundingOptions, + write: &mut DiplomatWrite, + ) -> Result<(), TemporalError> { + self.to_ixdtf_string_with_provider(zone, options, &Provider::compiled(), write) + } + pub fn to_ixdtf_string_with_provider<'p>( + &self, + zone: Option, + options: ToStringRoundingOptions, + p: &Provider<'p>, + write: &mut DiplomatWrite, + ) -> Result<(), TemporalError> { + use writeable::Writeable; + with_provider!(p, |p| { + let writeable = self.0.to_ixdtf_writeable_with_provider( + zone.map(Into::into), + options.into(), + p, + )?; + // This can only fail in cases where the DiplomatWriteable is capped, we + // don't care about that. + let _ = writeable.write_to(write); + }); + Ok(()) + } + + #[cfg(feature = "compiled_data")] + pub fn to_zoned_date_time_iso( + &self, + zone: TimeZone, + ) -> Result, TemporalError> { + self.to_zoned_date_time_iso_with_provider(zone, &Provider::compiled()) + } + pub fn to_zoned_date_time_iso_with_provider<'p>( + &self, + zone: TimeZone, + p: &Provider<'p>, + ) -> Result, TemporalError> { + with_provider!(p, |p| self + .0 + .to_zoned_date_time_iso_with_provider(zone.into(), p)) + .map(|c| Box::new(ZonedDateTime(c))) + .map_err(Into::into) + } + + #[allow(clippy::should_implement_trait)] + pub fn clone(&self) -> Box { + Box::new(Self(self.0)) + } + } +} + +const U64_HIGH_BIT_MASK: u64 = 1 << 63; + +impl From for i128 { + fn from(ns: ffi::I128Nanoseconds) -> Self { + let is_neg = (ns.high & U64_HIGH_BIT_MASK) != 0; + // Remove the bitflag + let ns_high = (ns.high & !U64_HIGH_BIT_MASK) as u128; + // Stick them together + let total = ((ns_high << 64) + ns.low as u128) as i128; + // Reintroduce the sign + if is_neg { + -total + } else { + total + } + } +} + +impl From for ffi::I128Nanoseconds { + fn from(ns: i128) -> Self { + debug_assert!( + ns != i128::MIN, + "temporal_rs should never produce i128::MIN, it is out of valid range" + ); + let is_neg = ns < 0; + let ns = ns.unsigned_abs(); + + let high = (ns >> 64) as u64; + let low = (ns & u64::MAX as u128) as u64; + let high = if (is_neg) { + high | U64_HIGH_BIT_MASK + } else { + high + }; + + ffi::I128Nanoseconds { high, low } + } +} + +#[test] +fn test_i128_roundtrip() { + #[track_caller] + fn roundtrip(x: i128) { + let ns = ffi::I128Nanoseconds::from(x); + let round = i128::from(ns); + assert_eq!(x, round, "{x} does not roundtrip via {ns:?}"); + } + + roundtrip(0); + roundtrip(-1); + roundtrip(1); + roundtrip(100); + roundtrip(1000); + roundtrip(-1000); + roundtrip(1000000000); + roundtrip(-100000000); + roundtrip(u64::MAX as i128); + roundtrip(-(u64::MIN as i128)); + roundtrip(100 * (u64::MAX as i128)); + roundtrip(-100 * (u64::MAX as i128)); + roundtrip(i128::MIN + 1); + roundtrip(i128::MAX); + roundtrip(i128::MAX - 10); +} diff --git a/deps/temporal/temporal_capi/src/lib.rs b/deps/temporal/temporal_capi/src/lib.rs new file mode 100644 index 00000000000000..f9ba98e653f3b2 --- /dev/null +++ b/deps/temporal/temporal_capi/src/lib.rs @@ -0,0 +1,40 @@ +#![allow(unused)] // Until we add all the APIs +#![warn(unused_imports)] // But we want to clean up imports +#![allow(clippy::needless_lifetimes)] // Diplomat requires explicit lifetimes at times +#![allow(clippy::too_many_arguments)] // We're mapping APIs with the same argument size +#![allow(clippy::wrong_self_convention)] // Diplomat forces self conventions that may not always be ideal + +//! This crate contains the original definitions of [`temporal_rs`] APIs consumed by [Diplomat](https://github.com/rust-diplomat/diplomat) +//! to generate FFI bindings. We currently generate bindings for C++ and `extern "C"` APIs. +//! +//! The APIs exposed by this crate are *not intended to be used from Rust* and as such this crate may change its Rust API +//! across compatible semver versions. In contrast, the `extern "C"` APIs and all the language bindings are stable within +//! the same major semver version. +//! +//! [`temporal_rs`]: http://crates.io/crates/temporal_rs + +#![no_std] +#![cfg_attr( + not(test), + forbid(clippy::unwrap_used, clippy::expect_used, clippy::indexing_slicing) +)] + +extern crate alloc; + +#[macro_use] +pub mod provider; + +pub mod calendar; +pub mod duration; +pub mod error; +pub mod instant; +pub mod options; + +pub mod plain_date; +pub mod plain_date_time; +pub mod plain_month_day; +pub mod plain_time; +pub mod plain_year_month; +pub mod zoned_date_time; + +pub mod time_zone; diff --git a/deps/temporal/temporal_capi/src/options.rs b/deps/temporal/temporal_capi/src/options.rs new file mode 100644 index 00000000000000..445cf1549d825a --- /dev/null +++ b/deps/temporal/temporal_capi/src/options.rs @@ -0,0 +1,175 @@ +use crate::error::ffi::TemporalError; + +#[diplomat::bridge] +#[diplomat::abi_rename = "temporal_rs_{0}"] +pub mod ffi { + use diplomat_runtime::DiplomatOption; + use temporal_rs::options; + + #[diplomat::enum_convert(options::Overflow)] + pub enum ArithmeticOverflow { + #[diplomat::attr(auto, default)] + Constrain, + Reject, + } + #[diplomat::enum_convert(options::Disambiguation)] + pub enum Disambiguation { + #[diplomat::attr(auto, default)] + Compatible, + Earlier, + Later, + Reject, + } + + #[diplomat::enum_convert(options::DisplayCalendar)] + pub enum DisplayCalendar { + #[diplomat::attr(auto, default)] + Auto, + Always, + Never, + Critical, + } + + #[diplomat::enum_convert(options::DisplayOffset)] + pub enum DisplayOffset { + #[diplomat::attr(auto, default)] + Auto, + Never, + } + + #[diplomat::enum_convert(options::DisplayTimeZone)] + pub enum DisplayTimeZone { + #[diplomat::attr(auto, default)] + Auto, + Never, + Critical, + } + + #[diplomat::enum_convert(options::OffsetDisambiguation)] + pub enum OffsetDisambiguation { + Use, + Prefer, + Ignore, + Reject, + } + + #[diplomat::enum_convert(options::RoundingMode)] + pub enum RoundingMode { + Ceil, + Floor, + Expand, + Trunc, + HalfCeil, + HalfFloor, + HalfExpand, + HalfTrunc, + HalfEven, + } + + #[diplomat::enum_convert(options::Unit)] + pub enum Unit { + #[diplomat::attr(auto, default)] + Auto = 0, + Nanosecond = 1, + Microsecond = 2, + Millisecond = 3, + Second = 4, + Minute = 5, + Hour = 6, + Day = 7, + Week = 8, + Month = 9, + Year = 10, + } + + #[diplomat::enum_convert(options::UnsignedRoundingMode)] + pub enum UnsignedRoundingMode { + Infinity, + Zero, + HalfInfinity, + HalfZero, + HalfEven, + } + + #[diplomat::enum_convert(temporal_rs::provider::TransitionDirection)] + pub enum TransitionDirection { + Next, + Previous, + } + + pub struct Precision { + /// Sets the precision to minute precision. + pub is_minute: bool, + /// Sets the number of digits. Auto when None. Has no effect if is_minute is set. + pub precision: DiplomatOption, + } + + pub struct RoundingOptions { + pub largest_unit: DiplomatOption, + pub smallest_unit: DiplomatOption, + pub rounding_mode: DiplomatOption, + pub increment: DiplomatOption, + } + + pub struct ToStringRoundingOptions { + pub precision: Precision, + pub smallest_unit: DiplomatOption, + pub rounding_mode: DiplomatOption, + } + + pub struct DifferenceSettings { + pub largest_unit: DiplomatOption, + pub smallest_unit: DiplomatOption, + pub rounding_mode: DiplomatOption, + pub increment: DiplomatOption, + } +} + +impl From for temporal_rs::parsers::Precision { + fn from(other: ffi::Precision) -> Self { + if other.is_minute { + Self::Minute + } else if let Some(digit) = other.precision.into() { + Self::Digit(digit) + } else { + Self::Auto + } + } +} + +impl From for temporal_rs::options::ToStringRoundingOptions { + fn from(other: ffi::ToStringRoundingOptions) -> Self { + Self { + precision: other.precision.into(), + smallest_unit: other.smallest_unit.into_converted_option(), + rounding_mode: other.rounding_mode.into_converted_option(), + } + } +} + +impl TryFrom for temporal_rs::options::DifferenceSettings { + type Error = TemporalError; + fn try_from(other: ffi::DifferenceSettings) -> Result { + let mut ret = Self::default(); + ret.largest_unit = other.largest_unit.into_converted_option(); + ret.smallest_unit = other.smallest_unit.into_converted_option(); + ret.rounding_mode = other.rounding_mode.into_converted_option(); + if let Some(increment) = other.increment.into() { + ret.increment = Some(temporal_rs::options::RoundingIncrement::try_new(increment)?); + } + Ok(ret) + } +} +impl TryFrom for temporal_rs::options::RoundingOptions { + type Error = TemporalError; + fn try_from(other: ffi::RoundingOptions) -> Result { + let mut ret = Self::default(); + ret.largest_unit = other.largest_unit.into_converted_option(); + ret.smallest_unit = other.smallest_unit.into_converted_option(); + ret.rounding_mode = other.rounding_mode.into_converted_option(); + if let Some(increment) = other.increment.into() { + ret.increment = Some(temporal_rs::options::RoundingIncrement::try_new(increment)?); + } + Ok(ret) + } +} diff --git a/deps/temporal/temporal_capi/src/plain_date.rs b/deps/temporal/temporal_capi/src/plain_date.rs new file mode 100644 index 00000000000000..7752e3bd68bf6e --- /dev/null +++ b/deps/temporal/temporal_capi/src/plain_date.rs @@ -0,0 +1,469 @@ +use temporal_rs::MonthCode; + +use crate::error::ffi::TemporalError; + +#[diplomat::bridge] +#[diplomat::abi_rename = "temporal_rs_{0}"] +pub mod ffi { + use crate::calendar::ffi::{AnyCalendarKind, Calendar}; + use crate::duration::ffi::Duration; + use crate::error::ffi::TemporalError; + use crate::instant::ffi::I128Nanoseconds; + use crate::options::ffi::{ArithmeticOverflow, DifferenceSettings, DisplayCalendar}; + use crate::plain_date_time::ffi::PlainDateTime; + use crate::plain_month_day::ffi::PlainMonthDay; + use crate::plain_time::ffi::PlainTime; + use crate::plain_year_month::ffi::PlainYearMonth; + use crate::provider::ffi::Provider; + use crate::time_zone::ffi::TimeZone; + use crate::zoned_date_time::ffi::ZonedDateTime; + use alloc::boxed::Box; + use alloc::string::String; + use core::fmt::Write; + use diplomat_runtime::{DiplomatOption, DiplomatStrSlice, DiplomatWrite}; + use diplomat_runtime::{DiplomatStr, DiplomatStr16}; + use writeable::Writeable; + + use core::str::FromStr; + + #[diplomat::opaque] + pub struct PlainDate(pub(crate) temporal_rs::PlainDate); + + pub struct PartialDate<'a> { + pub year: DiplomatOption, + pub month: DiplomatOption, + // None if empty + pub month_code: DiplomatStrSlice<'a>, + pub day: DiplomatOption, + // None if empty + pub era: DiplomatStrSlice<'a>, + pub era_year: DiplomatOption, + pub calendar: AnyCalendarKind, + } + + #[diplomat::opaque] + pub struct ParsedDate(pub(crate) temporal_rs::parsed_intermediates::ParsedDate); + + impl ParsedDate { + pub fn from_utf8(s: &DiplomatStr) -> Result, TemporalError> { + temporal_rs::parsed_intermediates::ParsedDate::from_utf8(s) + .map(|x| Box::new(ParsedDate(x))) + .map_err(Into::::into) + } + pub fn from_utf16(s: &DiplomatStr16) -> Result, TemporalError> { + // TODO(#275) This should not need to convert + let s = String::from_utf16(s).map_err(|_| temporal_rs::TemporalError::range())?; + + temporal_rs::parsed_intermediates::ParsedDate::from_utf8(s.as_bytes()) + .map(|x| Box::new(ParsedDate(x))) + .map_err(Into::::into) + } + + pub fn year_month_from_utf8(s: &DiplomatStr) -> Result, TemporalError> { + temporal_rs::parsed_intermediates::ParsedDate::year_month_from_utf8(s) + .map(|x| Box::new(ParsedDate(x))) + .map_err(Into::::into) + } + pub fn year_month_from_utf16(s: &DiplomatStr16) -> Result, TemporalError> { + // TODO(#275) This should not need to convert + let s = String::from_utf16(s).map_err(|_| temporal_rs::TemporalError::range())?; + + temporal_rs::parsed_intermediates::ParsedDate::year_month_from_utf8(s.as_bytes()) + .map(|x| Box::new(ParsedDate(x))) + .map_err(Into::::into) + } + + pub fn month_day_from_utf8(s: &DiplomatStr) -> Result, TemporalError> { + temporal_rs::parsed_intermediates::ParsedDate::month_day_from_utf8(s) + .map(|x| Box::new(ParsedDate(x))) + .map_err(Into::::into) + } + pub fn month_day_from_utf16(s: &DiplomatStr16) -> Result, TemporalError> { + // TODO(#275) This should not need to convert + let s = String::from_utf16(s).map_err(|_| temporal_rs::TemporalError::range())?; + + temporal_rs::parsed_intermediates::ParsedDate::month_day_from_utf8(s.as_bytes()) + .map(|x| Box::new(ParsedDate(x))) + .map_err(Into::::into) + } + } + + impl PlainDate { + pub fn try_new_constrain( + year: i32, + month: u8, + day: u8, + calendar: AnyCalendarKind, + ) -> Result, TemporalError> { + temporal_rs::PlainDate::new( + year, + month, + day, + temporal_rs::Calendar::new(calendar.into()), + ) + .map(|x| Box::new(PlainDate(x))) + .map_err(Into::into) + } + pub fn try_new( + year: i32, + month: u8, + day: u8, + calendar: AnyCalendarKind, + ) -> Result, TemporalError> { + temporal_rs::PlainDate::try_new( + year, + month, + day, + temporal_rs::Calendar::new(calendar.into()), + ) + .map(|x| Box::new(PlainDate(x))) + .map_err(Into::into) + } + pub fn try_new_with_overflow( + year: i32, + month: u8, + day: u8, + calendar: AnyCalendarKind, + overflow: ArithmeticOverflow, + ) -> Result, TemporalError> { + temporal_rs::PlainDate::new_with_overflow( + year, + month, + day, + temporal_rs::Calendar::new(calendar.into()), + overflow.into(), + ) + .map(|x| Box::new(PlainDate(x))) + .map_err(Into::into) + } + pub fn from_partial( + partial: PartialDate, + overflow: Option, + ) -> Result, TemporalError> { + temporal_rs::PlainDate::from_partial(partial.try_into()?, overflow.map(Into::into)) + .map(|x| Box::new(PlainDate(x))) + .map_err(Into::into) + } + + pub fn from_parsed(parsed: &ParsedDate) -> Result, TemporalError> { + temporal_rs::PlainDate::from_parsed(parsed.0) + .map(|x| Box::new(PlainDate(x))) + .map_err(Into::into) + } + + #[cfg(feature = "compiled_data")] + pub fn from_epoch_milliseconds(ms: i64, tz: TimeZone) -> Result, TemporalError> { + Self::from_epoch_milliseconds_with_provider(ms, tz, &Provider::compiled()) + } + pub fn from_epoch_milliseconds_with_provider<'p>( + ms: i64, + tz: TimeZone, + p: &Provider<'p>, + ) -> Result, TemporalError> { + let zdt = crate::zoned_date_time::zdt_from_epoch_ms_with_provider(ms, tz.into(), p)?; + Ok(Box::new(Self(zdt.to_plain_date()))) + } + + #[cfg(feature = "compiled_data")] + pub fn from_epoch_nanoseconds( + ns: I128Nanoseconds, + tz: TimeZone, + ) -> Result, TemporalError> { + Self::from_epoch_nanoseconds_with_provider(ns, tz, &Provider::compiled()) + } + pub fn from_epoch_nanoseconds_with_provider<'p>( + ns: I128Nanoseconds, + tz: TimeZone, + p: &Provider<'p>, + ) -> Result, TemporalError> { + let zdt = crate::zoned_date_time::zdt_from_epoch_ns_with_provider(ns, tz.into(), p)?; + Ok(Box::new(Self(zdt.to_plain_date()))) + } + + pub fn with( + &self, + partial: PartialDate, + overflow: Option, + ) -> Result, TemporalError> { + self.0 + .with(partial.try_into()?, overflow.map(Into::into)) + .map(|x| Box::new(PlainDate(x))) + .map_err(Into::into) + } + + pub fn with_calendar(&self, calendar: AnyCalendarKind) -> Box { + Box::new(PlainDate( + self.0 + .with_calendar(temporal_rs::Calendar::new(calendar.into())), + )) + } + + pub fn from_utf8(s: &DiplomatStr) -> Result, TemporalError> { + temporal_rs::PlainDate::from_utf8(s) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn from_utf16(s: &DiplomatStr16) -> Result, TemporalError> { + // TODO(#275) This should not need to convert + let s = String::from_utf16(s).map_err(|_| temporal_rs::TemporalError::range())?; + temporal_rs::PlainDate::from_str(&s) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn calendar<'a>(&'a self) -> &'a Calendar { + Calendar::transparent_convert(self.0.calendar()) + } + + pub fn is_valid(&self) -> bool { + self.0.is_valid() + } + + pub fn add( + &self, + duration: &Duration, + overflow: Option, + ) -> Result, TemporalError> { + self.0 + .add(&duration.0, overflow.map(Into::into)) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + pub fn subtract( + &self, + duration: &Duration, + overflow: Option, + ) -> Result, TemporalError> { + self.0 + .subtract(&duration.0, overflow.map(Into::into)) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + pub fn until( + &self, + other: &Self, + settings: DifferenceSettings, + ) -> Result, TemporalError> { + self.0 + .until(&other.0, settings.try_into()?) + .map(|x| Box::new(Duration(x))) + .map_err(Into::into) + } + pub fn since( + &self, + other: &Self, + settings: DifferenceSettings, + ) -> Result, TemporalError> { + self.0 + .since(&other.0, settings.try_into()?) + .map(|x| Box::new(Duration(x))) + .map_err(Into::into) + } + + pub fn equals(&self, other: &Self) -> bool { + self.0 == other.0 + } + + pub fn compare(one: &Self, two: &Self) -> core::cmp::Ordering { + one.0.compare_iso(&two.0) + } + pub fn year(&self) -> i32 { + self.0.year() + } + pub fn month(&self) -> u8 { + self.0.month() + } + pub fn month_code(&self, write: &mut DiplomatWrite) { + let code = self.0.month_code(); + // throw away the error, this should always succeed + let _ = write.write_str(code.as_str()); + } + pub fn day(&self) -> u8 { + self.0.day() + } + pub fn day_of_week(&self) -> u16 { + self.0.day_of_week() + } + pub fn day_of_year(&self) -> u16 { + self.0.day_of_year() + } + pub fn week_of_year(&self) -> Option { + self.0.week_of_year() + } + pub fn year_of_week(&self) -> Option { + self.0.year_of_week() + } + pub fn days_in_week(&self) -> u16 { + self.0.days_in_week() + } + pub fn days_in_month(&self) -> u16 { + self.0.days_in_month() + } + pub fn days_in_year(&self) -> u16 { + self.0.days_in_year() + } + pub fn months_in_year(&self) -> u16 { + self.0.months_in_year() + } + pub fn in_leap_year(&self) -> bool { + self.0.in_leap_year() + } + // Writes an empty string for no era + pub fn era(&self, write: &mut DiplomatWrite) { + let era = self.0.era(); + if let Some(era) = era { + // throw away the error, this should always succeed + let _ = write.write_str(&era); + } + } + + pub fn era_year(&self) -> Option { + self.0.era_year() + } + + pub fn to_plain_date_time( + &self, + time: Option<&PlainTime>, + ) -> Result, TemporalError> { + self.0 + .to_plain_date_time(time.map(|t| t.0)) + .map(|x| Box::new(PlainDateTime(x))) + .map_err(Into::into) + } + + pub fn to_plain_month_day(&self) -> Result, TemporalError> { + self.0 + .to_plain_month_day() + .map(|x| Box::new(PlainMonthDay(x))) + .map_err(Into::into) + } + + pub fn to_plain_year_month(&self) -> Result, TemporalError> { + self.0 + .to_plain_year_month() + .map(|x| Box::new(PlainYearMonth(x))) + .map_err(Into::into) + } + #[cfg(feature = "compiled_data")] + pub fn to_zoned_date_time( + &self, + time_zone: TimeZone, + time: Option<&PlainTime>, + ) -> Result, TemporalError> { + self.to_zoned_date_time_with_provider(time_zone, time, &Provider::compiled()) + } + pub fn to_zoned_date_time_with_provider<'p>( + &self, + time_zone: TimeZone, + time: Option<&PlainTime>, + p: &Provider<'p>, + ) -> Result, TemporalError> { + with_provider!(p, |p| self.0.to_zoned_date_time_with_provider( + time_zone.into(), + time.map(|x| x.0), + p + )) + .map(|x| Box::new(ZonedDateTime(x))) + .map_err(Into::into) + } + pub fn to_ixdtf_string( + &self, + display_calendar: DisplayCalendar, + write: &mut DiplomatWrite, + ) { + let writeable = self.0.to_ixdtf_writeable(display_calendar.into()); + // This can only fail in cases where the DiplomatWriteable is capped, we + // don't care about that. + let _ = writeable.write_to(write); + } + + #[allow(clippy::should_implement_trait)] + pub fn clone(&self) -> Box { + Box::new(Self(self.0.clone())) + } + } +} + +impl TryFrom> for temporal_rs::partial::PartialDate { + type Error = TemporalError; + fn try_from(other: ffi::PartialDate<'_>) -> Result { + let calendar = temporal_rs::Calendar::new(other.calendar.into()); + Ok(Self { + calendar_fields: other.try_into()?, + calendar, + }) + } +} + +impl TryFrom> for temporal_rs::partial::PartialYearMonth { + type Error = TemporalError; + fn try_from(other: ffi::PartialDate<'_>) -> Result { + let calendar = temporal_rs::Calendar::new(other.calendar.into()); + Ok(Self { + calendar_fields: other.try_into()?, + calendar, + }) + } +} + +impl TryFrom> for temporal_rs::fields::CalendarFields { + type Error = TemporalError; + fn try_from(other: ffi::PartialDate<'_>) -> Result { + use temporal_rs::TinyAsciiStr; + + let month_code = if other.month_code.is_empty() { + None + } else { + Some(MonthCode::try_from_utf8(other.month_code.into()).map_err(TemporalError::from)?) + }; + + let era = if other.era.is_empty() { + None + } else { + Some(TinyAsciiStr::try_from_utf8(other.era.into()).map_err(|_| { + TemporalError::from( + temporal_rs::TemporalError::range().with_message("Invalid era code."), + ) + })?) + }; + Ok(Self { + year: other.year.into(), + month: other.month.into(), + month_code, + day: other.day.into(), + era_year: other.era_year.into(), + era, + }) + } +} + +impl TryFrom> for temporal_rs::fields::YearMonthCalendarFields { + type Error = TemporalError; + fn try_from(other: ffi::PartialDate<'_>) -> Result { + use temporal_rs::TinyAsciiStr; + + let month_code = if other.month_code.is_empty() { + None + } else { + Some(MonthCode::try_from_utf8(other.month_code.into()).map_err(TemporalError::from)?) + }; + + let era = if other.era.is_empty() { + None + } else { + Some(TinyAsciiStr::try_from_utf8(other.era.into()).map_err(|_| { + TemporalError::from( + temporal_rs::TemporalError::range().with_message("Invalid era code."), + ) + })?) + }; + Ok(Self { + year: other.year.into(), + month: other.month.into(), + month_code, + era_year: other.era_year.into(), + era, + }) + } +} diff --git a/deps/temporal/temporal_capi/src/plain_date_time.rs b/deps/temporal/temporal_capi/src/plain_date_time.rs new file mode 100644 index 00000000000000..b0800afdc6da8d --- /dev/null +++ b/deps/temporal/temporal_capi/src/plain_date_time.rs @@ -0,0 +1,401 @@ +use crate::error::ffi::TemporalError; + +#[diplomat::bridge] +#[diplomat::abi_rename = "temporal_rs_{0}"] +pub mod ffi { + use crate::calendar::ffi::{AnyCalendarKind, Calendar}; + use crate::duration::ffi::Duration; + use crate::error::ffi::TemporalError; + use crate::instant::ffi::I128Nanoseconds; + use crate::options::ffi::{ + ArithmeticOverflow, DifferenceSettings, DisplayCalendar, RoundingOptions, + ToStringRoundingOptions, + }; + use crate::provider::ffi::Provider; + use crate::time_zone::ffi::TimeZone; + use crate::zoned_date_time::ffi::ZonedDateTime; + use alloc::boxed::Box; + + use crate::options::ffi::Disambiguation; + use crate::plain_date::ffi::{PartialDate, PlainDate}; + use crate::plain_time::ffi::{PartialTime, PlainTime}; + use alloc::string::String; + use core::fmt::Write; + use core::str::FromStr; + use diplomat_runtime::DiplomatWrite; + use diplomat_runtime::{DiplomatStr, DiplomatStr16}; + use writeable::Writeable; + + #[diplomat::opaque] + pub struct PlainDateTime(pub(crate) temporal_rs::PlainDateTime); + + pub struct PartialDateTime<'a> { + pub date: PartialDate<'a>, + pub time: PartialTime, + } + + #[diplomat::opaque] + pub struct ParsedDateTime(temporal_rs::parsed_intermediates::ParsedDateTime); + + impl ParsedDateTime { + pub fn from_utf8(s: &DiplomatStr) -> Result, TemporalError> { + temporal_rs::parsed_intermediates::ParsedDateTime::from_utf8(s) + .map(|x| Box::new(ParsedDateTime(x))) + .map_err(Into::::into) + } + pub fn from_utf16(s: &DiplomatStr16) -> Result, TemporalError> { + // TODO(#275) This should not need to convert + let s = String::from_utf16(s).map_err(|_| temporal_rs::TemporalError::range())?; + + temporal_rs::parsed_intermediates::ParsedDateTime::from_utf8(s.as_bytes()) + .map(|x| Box::new(ParsedDateTime(x))) + .map_err(Into::::into) + } + } + + impl PlainDateTime { + pub fn try_new_constrain( + year: i32, + month: u8, + day: u8, + hour: u8, + minute: u8, + second: u8, + millisecond: u16, + microsecond: u16, + nanosecond: u16, + calendar: AnyCalendarKind, + ) -> Result, TemporalError> { + temporal_rs::PlainDateTime::new( + year, + month, + day, + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + temporal_rs::Calendar::new(calendar.into()), + ) + .map(|x| Box::new(PlainDateTime(x))) + .map_err(Into::into) + } + pub fn try_new( + year: i32, + month: u8, + day: u8, + hour: u8, + minute: u8, + second: u8, + millisecond: u16, + microsecond: u16, + nanosecond: u16, + calendar: AnyCalendarKind, + ) -> Result, TemporalError> { + temporal_rs::PlainDateTime::try_new( + year, + month, + day, + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + temporal_rs::Calendar::new(calendar.into()), + ) + .map(|x| Box::new(PlainDateTime(x))) + .map_err(Into::into) + } + + pub fn from_partial( + partial: PartialDateTime, + overflow: Option, + ) -> Result, TemporalError> { + temporal_rs::PlainDateTime::from_partial(partial.try_into()?, overflow.map(Into::into)) + .map(|x| Box::new(PlainDateTime(x))) + .map_err(Into::into) + } + + pub fn from_parsed(parsed: &ParsedDateTime) -> Result, TemporalError> { + temporal_rs::PlainDateTime::from_parsed(parsed.0) + .map(|x| Box::new(PlainDateTime(x))) + .map_err(Into::into) + } + + #[cfg(feature = "compiled_data")] + pub fn from_epoch_milliseconds(ms: i64, tz: TimeZone) -> Result, TemporalError> { + Self::from_epoch_milliseconds_with_provider(ms, tz, &Provider::compiled()) + } + pub fn from_epoch_milliseconds_with_provider<'p>( + ms: i64, + tz: TimeZone, + p: &Provider<'p>, + ) -> Result, TemporalError> { + let zdt = crate::zoned_date_time::zdt_from_epoch_ms_with_provider(ms, tz.into(), p)?; + Ok(Box::new(Self(zdt.to_plain_date_time()))) + } + #[cfg(feature = "compiled_data")] + pub fn from_epoch_nanoseconds( + ns: I128Nanoseconds, + tz: TimeZone, + ) -> Result, TemporalError> { + Self::from_epoch_nanoseconds_with_provider(ns, tz, &Provider::compiled()) + } + pub fn from_epoch_nanoseconds_with_provider<'p>( + ns: I128Nanoseconds, + tz: TimeZone, + p: &Provider<'p>, + ) -> Result, TemporalError> { + let zdt = crate::zoned_date_time::zdt_from_epoch_ns_with_provider(ns, tz.into(), p)?; + Ok(Box::new(Self(zdt.to_plain_date_time()))) + } + pub fn with( + &self, + partial: PartialDateTime, + overflow: Option, + ) -> Result, TemporalError> { + self.0 + .with(partial.try_into()?, overflow.map(Into::into)) + .map(|x| Box::new(PlainDateTime(x))) + .map_err(Into::into) + } + + pub fn with_time(&self, time: Option<&PlainTime>) -> Result, TemporalError> { + self.0 + .with_time(time.map(|t| t.0)) + .map(|x| Box::new(PlainDateTime(x))) + .map_err(Into::into) + } + + pub fn with_calendar(&self, calendar: AnyCalendarKind) -> Box { + Box::new(PlainDateTime( + self.0 + .with_calendar(temporal_rs::Calendar::new(calendar.into())), + )) + } + + pub fn from_utf8(s: &DiplomatStr) -> Result, TemporalError> { + temporal_rs::PlainDateTime::from_utf8(s) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn from_utf16(s: &DiplomatStr16) -> Result, TemporalError> { + // TODO(#275) This should not need to convert + let s = String::from_utf16(s).map_err(|_| temporal_rs::TemporalError::range())?; + temporal_rs::PlainDateTime::from_str(&s) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn hour(&self) -> u8 { + self.0.hour() + } + pub fn minute(&self) -> u8 { + self.0.minute() + } + pub fn second(&self) -> u8 { + self.0.second() + } + pub fn millisecond(&self) -> u16 { + self.0.millisecond() + } + pub fn microsecond(&self) -> u16 { + self.0.microsecond() + } + pub fn nanosecond(&self) -> u16 { + self.0.nanosecond() + } + + pub fn calendar<'a>(&'a self) -> &'a Calendar { + Calendar::transparent_convert(self.0.calendar()) + } + + pub fn year(&self) -> i32 { + self.0.year() + } + pub fn month(&self) -> u8 { + self.0.month() + } + pub fn month_code(&self, write: &mut DiplomatWrite) { + let code = self.0.month_code(); + // throw away the error, this should always succeed + let _ = write.write_str(code.as_str()); + } + pub fn day(&self) -> u8 { + self.0.day() + } + pub fn day_of_week(&self) -> u16 { + self.0.day_of_week() + } + pub fn day_of_year(&self) -> u16 { + self.0.day_of_year() + } + pub fn week_of_year(&self) -> Option { + self.0.week_of_year() + } + pub fn year_of_week(&self) -> Option { + self.0.year_of_week() + } + pub fn days_in_week(&self) -> u16 { + self.0.days_in_week() + } + pub fn days_in_month(&self) -> u16 { + self.0.days_in_month() + } + pub fn days_in_year(&self) -> u16 { + self.0.days_in_year() + } + pub fn months_in_year(&self) -> u16 { + self.0.months_in_year() + } + pub fn in_leap_year(&self) -> bool { + self.0.in_leap_year() + } + // Writes an empty string for no era + pub fn era(&self, write: &mut DiplomatWrite) { + let era = self.0.era(); + if let Some(era) = era { + // throw away the error, this should always succeed + let _ = write.write_str(&era); + } + } + + pub fn era_year(&self) -> Option { + self.0.era_year() + } + + pub fn add( + &self, + duration: &Duration, + overflow: Option, + ) -> Result, TemporalError> { + self.0 + .add(&duration.0, overflow.map(Into::into)) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + pub fn subtract( + &self, + duration: &Duration, + overflow: Option, + ) -> Result, TemporalError> { + self.0 + .subtract(&duration.0, overflow.map(Into::into)) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + pub fn until( + &self, + other: &Self, + settings: DifferenceSettings, + ) -> Result, TemporalError> { + self.0 + .until(&other.0, settings.try_into()?) + .map(|x| Box::new(Duration(x))) + .map_err(Into::into) + } + pub fn since( + &self, + other: &Self, + settings: DifferenceSettings, + ) -> Result, TemporalError> { + self.0 + .since(&other.0, settings.try_into()?) + .map(|x| Box::new(Duration(x))) + .map_err(Into::into) + } + + pub fn equals(&self, other: &Self) -> bool { + self.0 == other.0 + } + + pub fn compare(one: &Self, two: &Self) -> core::cmp::Ordering { + one.0.compare_iso(&two.0) + } + + pub fn round(&self, options: RoundingOptions) -> Result, TemporalError> { + self.0 + .round(options.try_into()?) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + + pub fn to_plain_date(&self) -> Box { + Box::new(PlainDate(self.0.to_plain_date())) + } + + pub fn to_plain_time(&self) -> Box { + Box::new(PlainTime(self.0.to_plain_time())) + } + + #[cfg(feature = "compiled_data")] + pub fn to_zoned_date_time( + &self, + time_zone: TimeZone, + disambiguation: Disambiguation, + ) -> Result, TemporalError> { + self.to_zoned_date_time_with_provider(time_zone, disambiguation, &Provider::compiled()) + } + + pub fn to_zoned_date_time_with_provider<'p>( + &self, + time_zone: TimeZone, + disambiguation: Disambiguation, + p: &Provider<'p>, + ) -> Result, TemporalError> { + with_provider!(p, |p| self.0.to_zoned_date_time_with_provider( + time_zone.into(), + disambiguation.into(), + p + )) + .map(|x| Box::new(ZonedDateTime(x))) + .map_err(Into::into) + } + + pub fn to_ixdtf_string( + &self, + options: ToStringRoundingOptions, + + display_calendar: DisplayCalendar, + write: &mut DiplomatWrite, + ) -> Result<(), TemporalError> { + let writeable = self + .0 + .to_ixdtf_writeable(options.into(), display_calendar.into())?; + + // This can only fail in cases where the DiplomatWriteable is capped, we + // don't care about that. + let _ = writeable.write_to(write); + Ok(()) + } + + #[allow(clippy::should_implement_trait)] + pub fn clone(&self) -> Box { + Box::new(Self(self.0.clone())) + } + } +} + +impl TryFrom> for temporal_rs::partial::PartialDateTime { + type Error = TemporalError; + fn try_from(other: ffi::PartialDateTime<'_>) -> Result { + let calendar = temporal_rs::Calendar::new(other.date.calendar.into()); + Ok(Self { + fields: other.try_into()?, + calendar, + }) + } +} + +impl TryFrom> for temporal_rs::fields::DateTimeFields { + type Error = TemporalError; + fn try_from(other: ffi::PartialDateTime<'_>) -> Result { + Ok(Self { + calendar_fields: other.date.try_into()?, + time: other.time.into(), + }) + } +} diff --git a/deps/temporal/temporal_capi/src/plain_month_day.rs b/deps/temporal/temporal_capi/src/plain_month_day.rs new file mode 100644 index 00000000000000..fe3878ab1fffab --- /dev/null +++ b/deps/temporal/temporal_capi/src/plain_month_day.rs @@ -0,0 +1,150 @@ +#[diplomat::bridge] +#[diplomat::abi_rename = "temporal_rs_{0}"] +pub mod ffi { + use crate::calendar::ffi::{AnyCalendarKind, Calendar}; + use crate::error::ffi::TemporalError; + use alloc::boxed::Box; + + use crate::options::ffi::{ArithmeticOverflow, DisplayCalendar}; + use crate::plain_date::ffi::{PartialDate, PlainDate}; + use crate::time_zone::ffi::TimeZone; + + use crate::provider::ffi::Provider; + use alloc::string::String; + use core::fmt::Write; + use core::str::FromStr; + use diplomat_runtime::DiplomatWrite; + use diplomat_runtime::{DiplomatStr, DiplomatStr16}; + use writeable::Writeable; + + #[diplomat::opaque] + pub struct PlainMonthDay(pub(crate) temporal_rs::PlainMonthDay); + + impl PlainMonthDay { + pub fn try_new_with_overflow( + month: u8, + day: u8, + calendar: AnyCalendarKind, + overflow: ArithmeticOverflow, + ref_year: Option, + ) -> Result, TemporalError> { + temporal_rs::PlainMonthDay::new_with_overflow( + month, + day, + temporal_rs::Calendar::new(calendar.into()), + overflow.into(), + ref_year, + ) + .map(|x| Box::new(PlainMonthDay(x))) + .map_err(Into::into) + } + + pub fn from_partial( + partial: PartialDate, + overflow: Option, + ) -> Result, TemporalError> { + temporal_rs::PlainMonthDay::from_partial(partial.try_into()?, overflow.map(Into::into)) + .map(|x| Box::new(PlainMonthDay(x))) + .map_err(Into::into) + } + pub fn from_parsed( + parsed: &crate::plain_date::ffi::ParsedDate, + ) -> Result, TemporalError> { + temporal_rs::PlainMonthDay::from_parsed(parsed.0) + .map(|x| Box::new(PlainMonthDay(x))) + .map_err(Into::into) + } + + pub fn with( + &self, + partial: PartialDate, + overflow: Option, + ) -> Result, TemporalError> { + self.0 + .with(partial.try_into()?, overflow.map(Into::into)) + .map(|x| Box::new(PlainMonthDay(x))) + .map_err(Into::into) + } + + pub fn equals(&self, other: &Self) -> bool { + self.0 == other.0 + } + + pub fn from_utf8(s: &DiplomatStr) -> Result, TemporalError> { + temporal_rs::PlainMonthDay::from_utf8(s) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn from_utf16(s: &DiplomatStr16) -> Result, TemporalError> { + // TODO(#275) This should not need to convert + let s = String::from_utf16(s).map_err(|_| temporal_rs::TemporalError::range())?; + temporal_rs::PlainMonthDay::from_str(&s) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn day(&self) -> u8 { + self.0.day() + } + pub fn calendar<'a>(&'a self) -> &'a Calendar { + Calendar::transparent_convert(self.0.calendar()) + } + + pub fn month_code(&self, write: &mut DiplomatWrite) { + let code = self.0.month_code(); + // throw away the error, this should always succeed + let _ = write.write_str(code.as_str()); + } + + pub fn to_plain_date( + &self, + year: Option, + ) -> Result, TemporalError> { + self.0 + .to_plain_date(year.map(|y| y.try_into()).transpose()?) + .map(|x| Box::new(PlainDate(x))) + .map_err(Into::into) + } + + #[cfg(feature = "compiled_data")] + pub fn epoch_ms_for(&self, time_zone: TimeZone) -> Result { + self.epoch_ms_for_with_provider(time_zone, &Provider::compiled()) + } + + pub fn epoch_ms_for_with_provider<'p>( + &self, + time_zone: TimeZone, + p: &Provider<'p>, + ) -> Result { + let ns = with_provider!(p, |p| self + .0 + .epoch_ns_for_with_provider(time_zone.into(), p) + .map_err(TemporalError::from))?; + + let ns_i128 = ns.as_i128(); + let ms = ns_i128 / 1_000_000; + if let Ok(ms) = i64::try_from(ms) { + Ok(ms) + } else { + Err(TemporalError::assert("Found an out-of-range MonthDay")) + } + } + + pub fn to_ixdtf_string( + &self, + display_calendar: DisplayCalendar, + write: &mut DiplomatWrite, + ) { + let writeable = self.0.to_ixdtf_writeable(display_calendar.into()); + // This can only fail in cases where the DiplomatWriteable is capped, we + // don't care about that. + let _ = writeable.write_to(write); + } + + #[allow(clippy::should_implement_trait)] + pub fn clone(&self) -> Box { + Box::new(Self(self.0.clone())) + } + } +} diff --git a/deps/temporal/temporal_capi/src/plain_time.rs b/deps/temporal/temporal_capi/src/plain_time.rs new file mode 100644 index 00000000000000..3320d4513bcb85 --- /dev/null +++ b/deps/temporal/temporal_capi/src/plain_time.rs @@ -0,0 +1,239 @@ +#[diplomat::bridge] +#[diplomat::abi_rename = "temporal_rs_{0}"] +pub mod ffi { + use alloc::boxed::Box; + + use crate::duration::ffi::Duration; + use crate::error::ffi::TemporalError; + use crate::instant::ffi::I128Nanoseconds; + use crate::options::ffi::{ + ArithmeticOverflow, DifferenceSettings, RoundingOptions, ToStringRoundingOptions, + }; + use crate::provider::ffi::Provider; + use crate::time_zone::ffi::TimeZone; + use alloc::string::String; + use core::str::FromStr; + use diplomat_runtime::{DiplomatOption, DiplomatWrite}; + use diplomat_runtime::{DiplomatStr, DiplomatStr16}; + use writeable::Writeable; + + #[diplomat::opaque] + pub struct PlainTime(pub(crate) temporal_rs::PlainTime); + + pub struct PartialTime { + pub hour: DiplomatOption, + pub minute: DiplomatOption, + pub second: DiplomatOption, + pub millisecond: DiplomatOption, + pub microsecond: DiplomatOption, + pub nanosecond: DiplomatOption, + } + + impl PlainTime { + pub fn try_new_constrain( + hour: u8, + minute: u8, + second: u8, + millisecond: u16, + microsecond: u16, + nanosecond: u16, + ) -> Result, TemporalError> { + temporal_rs::PlainTime::new(hour, minute, second, millisecond, microsecond, nanosecond) + .map(|x| Box::new(PlainTime(x))) + .map_err(Into::into) + } + pub fn try_new( + hour: u8, + minute: u8, + second: u8, + millisecond: u16, + microsecond: u16, + nanosecond: u16, + ) -> Result, TemporalError> { + temporal_rs::PlainTime::try_new( + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + ) + .map(|x| Box::new(PlainTime(x))) + .map_err(Into::into) + } + + pub fn from_partial( + partial: PartialTime, + overflow: Option, + ) -> Result, TemporalError> { + temporal_rs::PlainTime::from_partial(partial.into(), overflow.map(Into::into)) + .map(|x| Box::new(PlainTime(x))) + .map_err(Into::into) + } + + #[cfg(feature = "compiled_data")] + pub fn from_epoch_milliseconds(ms: i64, tz: TimeZone) -> Result, TemporalError> { + Self::from_epoch_milliseconds_with_provider(ms, tz, &Provider::compiled()) + } + pub fn from_epoch_milliseconds_with_provider<'p>( + ms: i64, + tz: TimeZone, + p: &Provider<'p>, + ) -> Result, TemporalError> { + let zdt = crate::zoned_date_time::zdt_from_epoch_ms_with_provider(ms, tz.into(), p)?; + Ok(Box::new(Self(zdt.to_plain_time()))) + } + + #[cfg(feature = "compiled_data")] + pub fn from_epoch_nanoseconds( + ns: I128Nanoseconds, + tz: TimeZone, + ) -> Result, TemporalError> { + Self::from_epoch_nanoseconds_with_provider(ns, tz, &Provider::compiled()) + } + pub fn from_epoch_nanoseconds_with_provider<'p>( + ns: I128Nanoseconds, + tz: TimeZone, + p: &Provider<'p>, + ) -> Result, TemporalError> { + let zdt = crate::zoned_date_time::zdt_from_epoch_ns_with_provider(ns, tz.into(), p)?; + Ok(Box::new(Self(zdt.to_plain_time()))) + } + + pub fn with( + &self, + partial: PartialTime, + overflow: Option, + ) -> Result, TemporalError> { + self.0 + .with(partial.into(), overflow.map(Into::into)) + .map(|x| Box::new(PlainTime(x))) + .map_err(Into::into) + } + + pub fn from_utf8(s: &DiplomatStr) -> Result, TemporalError> { + temporal_rs::PlainTime::from_utf8(s) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn from_utf16(s: &DiplomatStr16) -> Result, TemporalError> { + // TODO(#275) This should not need to convert + let s = String::from_utf16(s).map_err(|_| temporal_rs::TemporalError::range())?; + temporal_rs::PlainTime::from_str(&s) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn hour(&self) -> u8 { + self.0.hour() + } + pub fn minute(&self) -> u8 { + self.0.minute() + } + pub fn second(&self) -> u8 { + self.0.second() + } + pub fn millisecond(&self) -> u16 { + self.0.millisecond() + } + pub fn microsecond(&self) -> u16 { + self.0.microsecond() + } + pub fn nanosecond(&self) -> u16 { + self.0.nanosecond() + } + + pub fn add(&self, duration: &Duration) -> Result, TemporalError> { + self.0 + .add(&duration.0) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + pub fn subtract(&self, duration: &Duration) -> Result, TemporalError> { + self.0 + .subtract(&duration.0) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + pub fn until( + &self, + other: &Self, + settings: DifferenceSettings, + ) -> Result, TemporalError> { + self.0 + .until(&other.0, settings.try_into()?) + .map(|x| Box::new(Duration(x))) + .map_err(Into::into) + } + pub fn since( + &self, + other: &Self, + settings: DifferenceSettings, + ) -> Result, TemporalError> { + self.0 + .since(&other.0, settings.try_into()?) + .map(|x| Box::new(Duration(x))) + .map_err(Into::into) + } + pub fn equals(&self, other: &Self) -> bool { + self.0 == other.0 + } + pub fn compare(one: &Self, two: &Self) -> core::cmp::Ordering { + let tuple1 = ( + one.hour(), + one.minute(), + one.second(), + one.millisecond(), + one.microsecond(), + one.nanosecond(), + ); + let tuple2 = ( + two.hour(), + two.minute(), + two.second(), + two.millisecond(), + two.microsecond(), + two.nanosecond(), + ); + + tuple1.cmp(&tuple2) + } + pub fn round(&self, options: RoundingOptions) -> Result, TemporalError> { + self.0 + .round(options.try_into()?) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + pub fn to_ixdtf_string( + &self, + options: ToStringRoundingOptions, + write: &mut DiplomatWrite, + ) -> Result<(), TemporalError> { + let writeable = self.0.to_ixdtf_writeable(options.into())?; + // This can only fail in cases where the DiplomatWriteable is capped, we + // don't care about that. + let _ = writeable.write_to(write); + + Ok(()) + } + + #[allow(clippy::should_implement_trait)] + pub fn clone(&self) -> Box { + Box::new(Self(self.0)) + } + } +} + +impl From for temporal_rs::partial::PartialTime { + fn from(other: ffi::PartialTime) -> Self { + Self { + hour: other.hour.into(), + minute: other.minute.into(), + second: other.second.into(), + millisecond: other.millisecond.into(), + microsecond: other.microsecond.into(), + nanosecond: other.nanosecond.into(), + } + } +} diff --git a/deps/temporal/temporal_capi/src/plain_year_month.rs b/deps/temporal/temporal_capi/src/plain_year_month.rs new file mode 100644 index 00000000000000..066bbd77593aa0 --- /dev/null +++ b/deps/temporal/temporal_capi/src/plain_year_month.rs @@ -0,0 +1,221 @@ +#[diplomat::bridge] +#[diplomat::abi_rename = "temporal_rs_{0}"] +pub mod ffi { + use crate::calendar::ffi::{AnyCalendarKind, Calendar}; + use crate::duration::ffi::Duration; + use crate::error::ffi::TemporalError; + use crate::provider::ffi::Provider; + use crate::time_zone::ffi::TimeZone; + use alloc::boxed::Box; + + use crate::options::ffi::{ArithmeticOverflow, DifferenceSettings, DisplayCalendar}; + use crate::plain_date::ffi::{PartialDate, PlainDate}; + use alloc::string::String; + use core::fmt::Write; + use diplomat_runtime::DiplomatWrite; + use diplomat_runtime::{DiplomatStr, DiplomatStr16}; + use writeable::Writeable; + + use core::str::FromStr; + + #[diplomat::opaque] + pub struct PlainYearMonth(pub(crate) temporal_rs::PlainYearMonth); + + impl PlainYearMonth { + pub fn try_new_with_overflow( + year: i32, + month: u8, + reference_day: Option, + calendar: AnyCalendarKind, + overflow: ArithmeticOverflow, + ) -> Result, TemporalError> { + temporal_rs::PlainYearMonth::new_with_overflow( + year, + month, + reference_day, + temporal_rs::Calendar::new(calendar.into()), + overflow.into(), + ) + .map(|x| Box::new(PlainYearMonth(x))) + .map_err(Into::into) + } + + pub fn from_partial( + partial: PartialDate, + overflow: Option, + ) -> Result, TemporalError> { + temporal_rs::PlainYearMonth::from_partial(partial.try_into()?, overflow.map(Into::into)) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + + pub fn from_parsed( + parsed: &crate::plain_date::ffi::ParsedDate, + ) -> Result, TemporalError> { + temporal_rs::PlainYearMonth::from_parsed(parsed.0) + .map(|x| Box::new(PlainYearMonth(x))) + .map_err(Into::into) + } + + pub fn with( + &self, + partial: PartialDate, + overflow: Option, + ) -> Result, TemporalError> { + let fields: temporal_rs::fields::YearMonthCalendarFields = partial.try_into()?; + self.0 + .with(fields, overflow.map(Into::into)) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + + pub fn from_utf8(s: &DiplomatStr) -> Result, TemporalError> { + temporal_rs::PlainYearMonth::from_utf8(s) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn from_utf16(s: &DiplomatStr16) -> Result, TemporalError> { + // TODO(#275) This should not need to convert + let s = String::from_utf16(s).map_err(|_| temporal_rs::TemporalError::range())?; + temporal_rs::PlainYearMonth::from_str(&s) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn year(&self) -> i32 { + self.0.year() + } + pub fn month(&self) -> u8 { + self.0.month() + } + pub fn month_code(&self, write: &mut DiplomatWrite) { + let code = self.0.month_code(); + // throw away the error, this should always succeed + let _ = write.write_str(code.as_str()); + } + + pub fn in_leap_year(&self) -> bool { + self.0.in_leap_year() + } + pub fn days_in_month(&self) -> u16 { + self.0.days_in_month() + } + pub fn days_in_year(&self) -> u16 { + self.0.days_in_year() + } + pub fn months_in_year(&self) -> u16 { + self.0.months_in_year() + } + // Writes an empty string for no era + pub fn era(&self, write: &mut DiplomatWrite) { + let era = self.0.era(); + if let Some(era) = era { + // throw away the error, this should always succeed + let _ = write.write_str(&era); + } + } + + pub fn era_year(&self) -> Option { + self.0.era_year() + } + + pub fn calendar<'a>(&'a self) -> &'a Calendar { + Calendar::transparent_convert(self.0.calendar()) + } + pub fn add( + &self, + duration: &Duration, + overflow: ArithmeticOverflow, + ) -> Result, TemporalError> { + self.0 + .add(&duration.0, overflow.into()) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + pub fn subtract( + &self, + duration: &Duration, + overflow: ArithmeticOverflow, + ) -> Result, TemporalError> { + self.0 + .subtract(&duration.0, overflow.into()) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + pub fn until( + &self, + other: &Self, + settings: DifferenceSettings, + ) -> Result, TemporalError> { + self.0 + .until(&other.0, settings.try_into()?) + .map(|x| Box::new(Duration(x))) + .map_err(Into::into) + } + pub fn since( + &self, + other: &Self, + settings: DifferenceSettings, + ) -> Result, TemporalError> { + self.0 + .since(&other.0, settings.try_into()?) + .map(|x| Box::new(Duration(x))) + .map_err(Into::into) + } + pub fn equals(&self, other: &Self) -> bool { + self.0 == other.0 + } + pub fn compare(one: &Self, two: &Self) -> core::cmp::Ordering { + one.0.compare_iso(&two.0) + } + pub fn to_plain_date( + &self, + day: Option, + ) -> Result, TemporalError> { + self.0 + .to_plain_date(day.map(|d| d.try_into()).transpose()?) + .map(|x| Box::new(PlainDate(x))) + .map_err(Into::into) + } + + #[cfg(feature = "compiled_data")] + pub fn epoch_ms_for(&self, time_zone: TimeZone) -> Result { + self.epoch_ms_for_with_provider(time_zone, &Provider::compiled()) + } + pub fn epoch_ms_for_with_provider<'p>( + &self, + time_zone: TimeZone, + p: &Provider<'p>, + ) -> Result { + let ns = with_provider!(p, |p| self + .0 + .epoch_ns_for_with_provider(time_zone.into(), p)) + .map_err(TemporalError::from)?; + + let ns_i128 = ns.as_i128(); + let ms = ns_i128 / 1_000_000; + if let Ok(ms) = i64::try_from(ms) { + Ok(ms) + } else { + Err(TemporalError::assert("Found an out-of-range YearMonth")) + } + } + + pub fn to_ixdtf_string( + &self, + display_calendar: DisplayCalendar, + write: &mut DiplomatWrite, + ) { + let writeable = self.0.to_ixdtf_writeable(display_calendar.into()); + // This can only fail in cases where the DiplomatWriteable is capped, we + // don't care about that. + let _ = writeable.write_to(write); + } + + #[allow(clippy::should_implement_trait)] + pub fn clone(&self) -> Box { + Box::new(Self(self.0.clone())) + } + } +} diff --git a/deps/temporal/temporal_capi/src/provider.rs b/deps/temporal/temporal_capi/src/provider.rs new file mode 100644 index 00000000000000..70b4e39ef8bf2a --- /dev/null +++ b/deps/temporal/temporal_capi/src/provider.rs @@ -0,0 +1,90 @@ +use core::marker::PhantomData; +#[cfg(feature = "zoneinfo64")] +use timezone_provider::zoneinfo64::ZoneInfo64TzdbProvider; + +/// We use a macro to avoid dynamic dispatch: a given codebase will +/// typically only be compiled with a single provider. +macro_rules! with_provider( + ($provider:ident, |$p:ident| $code:expr) => { + match $provider.0 { + #[cfg(feature = "zoneinfo64")] + crate::provider::ProviderInner::ZoneInfo64(ref zi) => { + let $p = zi; + $code + } + #[cfg(feature = "compiled_data")] + crate::provider::ProviderInner::Compiled => { + let $p = &*temporal_rs::provider::COMPILED_TZ_PROVIDER; + $code + } + crate::provider::ProviderInner::Empty(..) => { + return Err(TemporalError::assert("Failed to load timezone info")); + // This ensures that type inference still works with --no-default-features + #[allow(dead_code)] { + let $p = &timezone_provider::provider::NeverProvider::default(); + $code + } + } + } + }; +); + +#[diplomat::bridge] +#[diplomat::abi_rename = "temporal_rs_{0}"] +pub mod ffi { + use super::ProviderInner; + use alloc::boxed::Box; + + use core::marker::PhantomData; + + #[cfg(feature = "zoneinfo64")] + use zoneinfo64::ZoneInfo64; + + /// A time zone data provider + #[diplomat::opaque] + pub struct Provider<'a>(pub(crate) ProviderInner<'a>); + + impl<'a> Provider<'a> { + #[cfg(feature = "zoneinfo64")] + /// Construct a provider backed by a zoneinfo64.res file + /// + /// This failing to construct is not a Temporal error, so it just returns () + #[allow( + clippy::result_unit_err, + reason = "Diplomat distinguishes between Result and Option" + )] + pub fn new_zoneinfo64(data: &'a [u32]) -> Result>, ()> { + let zi64 = ZoneInfo64::try_from_u32s(data).map_err(|_| ())?; + let data = super::ZoneInfo64TzdbProvider::new(zi64); + + Ok(Box::new(Self(ProviderInner::ZoneInfo64(data)))) + } + + #[cfg(feature = "compiled_data")] + pub fn new_compiled() -> Box { + Box::new(Self(ProviderInner::Compiled)) + } + + /// For internal use + #[cfg(feature = "compiled_data")] + pub(crate) fn compiled() -> Self { + Self(ProviderInner::Compiled) + } + + /// Fallback type in case construction does not work. + pub fn empty() -> Box { + Box::new(Self(ProviderInner::Empty(PhantomData))) + } + } +} + +pub(crate) enum ProviderInner<'a> { + #[cfg(feature = "zoneinfo64")] + ZoneInfo64(ZoneInfo64TzdbProvider<'a>), + + #[cfg(feature = "compiled_data")] + Compiled, + + /// This avoids unused lifetime errors when the feature is disabled + Empty(PhantomData<&'a u8>), +} diff --git a/deps/temporal/temporal_capi/src/time_zone.rs b/deps/temporal/temporal_capi/src/time_zone.rs new file mode 100644 index 00000000000000..60cb33bdf3a8e8 --- /dev/null +++ b/deps/temporal/temporal_capi/src/time_zone.rs @@ -0,0 +1,156 @@ +use temporal_rs::provider::TimeZoneId; +use temporal_rs::UtcOffset; +use timezone_provider::provider::{NormalizedId, ResolvedId}; + +#[diplomat::bridge] +#[diplomat::abi_rename = "temporal_rs_{0}"] +pub mod ffi { + use crate::error::ffi::TemporalError; + use crate::provider::ffi::Provider; + use core::fmt::Write; + use diplomat_runtime::DiplomatWrite; + + /// A type representing a time zone over FFI. + /// + /// It is not recommended to directly manipulate the fields of this type. + #[derive(Copy, Clone)] + pub struct TimeZone { + /// The UTC offset in minutes (is_iana_id = false) + pub offset_minutes: i16, + /// An id which can be used with the resolver (is_iana_id = true) + pub resolved_id: usize, + /// An id which can be used with the normalizer (is_iana_id = true) + pub normalized_id: usize, + /// Whether this is an IANA id or an offset + pub is_iana_id: bool, + } + + impl TimeZone { + #[cfg(feature = "compiled_data")] + pub fn try_from_identifier_str(ident: &DiplomatStr) -> Result { + Self::try_from_identifier_str_with_provider(ident, &Provider::compiled()) + } + pub fn try_from_identifier_str_with_provider<'p>( + ident: &DiplomatStr, + p: &Provider<'p>, + ) -> Result { + let Ok(ident) = core::str::from_utf8(ident) else { + return Err(temporal_rs::TemporalError::range().into()); + }; + with_provider!(p, |p| { + temporal_rs::TimeZone::try_from_identifier_str_with_provider(ident, p) + }) + .map(Into::into) + .map_err(Into::into) + } + pub fn try_from_offset_str(ident: &DiplomatStr) -> Result { + temporal_rs::UtcOffset::from_utf8(ident) + .map(|x| temporal_rs::TimeZone::UtcOffset(x).into()) + .map_err(Into::into) + } + #[cfg(feature = "compiled_data")] + pub fn try_from_str(ident: &DiplomatStr) -> Result { + Self::try_from_str_with_provider(ident, &Provider::compiled()) + } + pub fn try_from_str_with_provider<'p>( + ident: &DiplomatStr, + p: &Provider<'p>, + ) -> Result { + let Ok(ident) = core::str::from_utf8(ident) else { + return Err(temporal_rs::TemporalError::range().into()); + }; + with_provider!(p, |p| temporal_rs::TimeZone::try_from_str_with_provider( + ident, p + )) + .map(Into::into) + .map_err(Into::into) + } + + #[cfg(feature = "compiled_data")] + pub fn identifier(self, write: &mut DiplomatWrite) { + let _ = self.identifier_with_provider(&Provider::compiled(), write); + } + + pub fn identifier_with_provider<'p>( + self, + p: &Provider<'p>, + write: &mut DiplomatWrite, + ) -> Result<(), TemporalError> { + // TODO ideally this would use Writeable instead of allocating + let s = + with_provider!(p, |p| self.tz().identifier_with_provider(p)).unwrap_or_default(); + + // This can only fail in cases where the DiplomatWriteable is capped, we + // don't care about that. + let _ = write.write_str(&s); + Ok(()) + } + + #[cfg(feature = "compiled_data")] + pub fn utc() -> Self { + temporal_rs::TimeZone::utc().into() + } + + pub fn utc_with_provider<'p>(p: &Provider<'p>) -> Result { + Ok(with_provider!(p, |p| { temporal_rs::TimeZone::utc_with_provider(p) }).into()) + } + + /// Create a TimeZone that represents +00:00 + /// + /// This is the only way to infallibly make a TimeZone without compiled_data, + /// and can be used as a fallback. + pub fn zero() -> Self { + temporal_rs::TimeZone::UtcOffset(Default::default()).into() + } + + /// Get the primary time zone identifier corresponding to this time zone + #[cfg(feature = "compiled_data")] + pub fn primary_identifier(self) -> Result { + self.primary_identifier_with_provider(&Provider::compiled()) + } + pub fn primary_identifier_with_provider<'p>( + self, + p: &Provider<'p>, + ) -> Result { + with_provider!(p, |p| self.tz().primary_identifier_with_provider(p)) + .map(Into::into) + .map_err(Into::into) + } + + pub(crate) fn tz(self) -> temporal_rs::TimeZone { + self.into() + } + } +} + +impl From for temporal_rs::TimeZone { + fn from(other: ffi::TimeZone) -> Self { + if other.is_iana_id { + Self::IanaIdentifier(TimeZoneId { + normalized: NormalizedId(other.normalized_id), + resolved: ResolvedId(other.resolved_id), + }) + } else { + Self::UtcOffset(UtcOffset::from_minutes(other.offset_minutes)) + } + } +} + +impl From for ffi::TimeZone { + fn from(other: temporal_rs::TimeZone) -> Self { + match other { + temporal_rs::TimeZone::UtcOffset(offset) => Self { + offset_minutes: offset.minutes(), + is_iana_id: false, + normalized_id: 0, + resolved_id: 0, + }, + temporal_rs::TimeZone::IanaIdentifier(id) => Self { + normalized_id: id.normalized.0, + resolved_id: id.resolved.0, + is_iana_id: true, + offset_minutes: 0, + }, + } + } +} diff --git a/deps/temporal/temporal_capi/src/zoned_date_time.rs b/deps/temporal/temporal_capi/src/zoned_date_time.rs new file mode 100644 index 00000000000000..6d39b3ee177f37 --- /dev/null +++ b/deps/temporal/temporal_capi/src/zoned_date_time.rs @@ -0,0 +1,806 @@ +use crate::error::ffi::TemporalError; +use crate::instant::ffi::I128Nanoseconds; +use crate::provider::ffi::Provider; +use temporal_rs::options::RelativeTo; + +#[diplomat::bridge] +#[diplomat::abi_rename = "temporal_rs_{0}"] +pub mod ffi { + use crate::calendar::ffi::AnyCalendarKind; + use crate::calendar::ffi::Calendar; + use crate::duration::ffi::Duration; + use crate::error::ffi::TemporalError; + use crate::plain_date::ffi::{PartialDate, PlainDate}; + use crate::plain_date_time::ffi::PlainDateTime; + use crate::plain_time::ffi::{PartialTime, PlainTime}; + use alloc::boxed::Box; + + use crate::provider::ffi::Provider; + + use crate::instant::ffi::I128Nanoseconds; + use crate::instant::ffi::Instant; + use crate::options::ffi::{ + ArithmeticOverflow, DifferenceSettings, Disambiguation, DisplayCalendar, DisplayOffset, + DisplayTimeZone, OffsetDisambiguation, RoundingOptions, ToStringRoundingOptions, + TransitionDirection, + }; + + use crate::time_zone::ffi::TimeZone; + + use alloc::string::String; + use core::fmt::Write; + + use diplomat_runtime::DiplomatOption; + use diplomat_runtime::DiplomatStrSlice; + use diplomat_runtime::DiplomatWrite; + + pub struct PartialZonedDateTime<'a> { + pub date: PartialDate<'a>, + pub time: PartialTime, + pub offset: DiplomatOption>, + pub timezone: DiplomatOption, + } + + pub struct RelativeTo<'a> { + pub date: Option<&'a PlainDate>, + pub zoned: Option<&'a ZonedDateTime>, + } + + /// GetTemporalRelativeToOption can create fresh PlainDate/ZonedDateTimes by parsing them, + /// we need a way to produce that result. + #[diplomat::out] + pub struct OwnedRelativeTo { + pub date: Option>, + pub zoned: Option>, + } + + impl OwnedRelativeTo { + #[cfg(feature = "compiled_data")] + pub fn from_utf8(s: &DiplomatStr) -> Result { + Self::from_utf8_with_provider(s, &Provider::compiled()) + } + pub fn from_utf8_with_provider<'p>( + s: &DiplomatStr, + p: &Provider<'p>, + ) -> Result { + // TODO(#275) This should not need to check + let s = core::str::from_utf8(s).map_err(|_| temporal_rs::TemporalError::range())?; + + with_provider!(p, |p| super::RelativeTo::try_from_str_with_provider(s, p)) + .map(Into::into) + .map_err(Into::::into) + } + + #[cfg(feature = "compiled_data")] + pub fn from_utf16(s: &DiplomatStr16) -> Result { + Self::from_utf16_with_provider(s, &Provider::compiled()) + } + pub fn from_utf16_with_provider<'p>( + s: &DiplomatStr16, + p: &Provider<'p>, + ) -> Result { + // TODO(#275) This should not need to convert + let s = String::from_utf16(s).map_err(|_| temporal_rs::TemporalError::range())?; + with_provider!(p, |p| super::RelativeTo::try_from_str_with_provider(&s, p)) + .map(Into::into) + .map_err(Into::::into) + } + + pub fn empty() -> Self { + Self { + date: None, + zoned: None, + } + } + } + + #[diplomat::opaque] + pub struct ParsedZonedDateTime(temporal_rs::parsed_intermediates::ParsedZonedDateTime); + + impl ParsedZonedDateTime { + #[cfg(feature = "compiled_data")] + pub fn from_utf8(s: &DiplomatStr) -> Result, TemporalError> { + Self::from_utf8_with_provider(s, &Provider::compiled()) + } + pub fn from_utf8_with_provider<'p>( + s: &DiplomatStr, + p: &Provider<'p>, + ) -> Result, TemporalError> { + with_provider!(p, |p| { + temporal_rs::parsed_intermediates::ParsedZonedDateTime::from_utf8_with_provider( + s, p, + ) + }) + .map(|x| Box::new(ParsedZonedDateTime(x))) + .map_err(Into::::into) + } + + #[cfg(feature = "compiled_data")] + pub fn from_utf16(s: &DiplomatStr16) -> Result, TemporalError> { + Self::from_utf16_with_provider(s, &Provider::compiled()) + } + pub fn from_utf16_with_provider<'p>( + s: &DiplomatStr16, + p: &Provider<'p>, + ) -> Result, TemporalError> { + // TODO(#275) This should not need to convert + let s = String::from_utf16(s).map_err(|_| temporal_rs::TemporalError::range())?; + + with_provider!(p, |p| { + temporal_rs::parsed_intermediates::ParsedZonedDateTime::from_utf8_with_provider( + s.as_bytes(), + p, + ) + }) + .map(|x| Box::new(ParsedZonedDateTime(x))) + .map_err(Into::::into) + } + } + + #[diplomat::opaque] + pub struct ZonedDateTime(pub(crate) temporal_rs::ZonedDateTime); + + impl ZonedDateTime { + #[cfg(feature = "compiled_data")] + pub fn try_new( + nanosecond: I128Nanoseconds, + calendar: AnyCalendarKind, + time_zone: TimeZone, + ) -> Result, TemporalError> { + Self::try_new_with_provider(nanosecond, calendar, time_zone, &Provider::compiled()) + } + pub fn try_new_with_provider<'p>( + nanosecond: I128Nanoseconds, + calendar: AnyCalendarKind, + time_zone: TimeZone, + p: &Provider<'p>, + ) -> Result, TemporalError> { + with_provider!(p, |p| temporal_rs::ZonedDateTime::try_new_with_provider( + nanosecond.into(), + time_zone.into(), + temporal_rs::Calendar::new(calendar.into()), + p + )) + .map(|x| Box::new(ZonedDateTime(x))) + .map_err(Into::into) + } + #[cfg(feature = "compiled_data")] + pub fn from_partial( + partial: PartialZonedDateTime, + overflow: Option, + disambiguation: Option, + offset_option: Option, + ) -> Result, TemporalError> { + Self::from_partial_with_provider( + partial, + overflow, + disambiguation, + offset_option, + &Provider::compiled(), + ) + } + pub fn from_partial_with_provider<'p>( + partial: PartialZonedDateTime, + overflow: Option, + disambiguation: Option, + offset_option: Option, + p: &Provider<'p>, + ) -> Result, TemporalError> { + with_provider!(p, |p| { + temporal_rs::ZonedDateTime::from_partial_with_provider( + partial.try_into()?, + overflow.map(Into::into), + disambiguation.map(Into::into), + offset_option.map(Into::into), + p, + ) + }) + .map(|x| Box::new(ZonedDateTime(x))) + .map_err(Into::into) + } + #[cfg(feature = "compiled_data")] + pub fn from_parsed( + parsed: &ParsedZonedDateTime, + disambiguation: Disambiguation, + offset_option: OffsetDisambiguation, + ) -> Result, TemporalError> { + Self::from_parsed_with_provider( + parsed, + disambiguation, + offset_option, + &Provider::compiled(), + ) + } + pub fn from_parsed_with_provider<'p>( + parsed: &ParsedZonedDateTime, + disambiguation: Disambiguation, + offset_option: OffsetDisambiguation, + p: &Provider<'p>, + ) -> Result, TemporalError> { + with_provider!( + p, + |p| temporal_rs::ZonedDateTime::from_parsed_with_provider( + parsed.0.clone(), + disambiguation.into(), + offset_option.into(), + p + ) + ) + .map(|x| Box::new(ZonedDateTime(x))) + .map_err(Into::into) + } + #[cfg(feature = "compiled_data")] + pub fn from_utf8( + s: &DiplomatStr, + disambiguation: Disambiguation, + offset_disambiguation: OffsetDisambiguation, + ) -> Result, TemporalError> { + Self::from_utf8_with_provider( + s, + disambiguation, + offset_disambiguation, + &Provider::compiled(), + ) + } + pub fn from_utf8_with_provider<'p>( + s: &DiplomatStr, + disambiguation: Disambiguation, + offset_disambiguation: OffsetDisambiguation, + p: &Provider<'p>, + ) -> Result, TemporalError> { + // TODO(#275) This should not need to check + with_provider!(p, |p| temporal_rs::ZonedDateTime::from_utf8_with_provider( + s, + disambiguation.into(), + offset_disambiguation.into(), + p + )) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + #[cfg(feature = "compiled_data")] + pub fn from_utf16( + s: &DiplomatStr16, + disambiguation: Disambiguation, + offset_disambiguation: OffsetDisambiguation, + ) -> Result, TemporalError> { + Self::from_utf16_with_provider( + s, + disambiguation, + offset_disambiguation, + &Provider::compiled(), + ) + } + pub fn from_utf16_with_provider<'p>( + s: &DiplomatStr16, + disambiguation: Disambiguation, + offset_disambiguation: OffsetDisambiguation, + p: &Provider<'p>, + ) -> Result, TemporalError> { + // TODO(#275) This should not need to convert + let s = String::from_utf16(s).map_err(|_| temporal_rs::TemporalError::range())?; + with_provider!(p, |p| temporal_rs::ZonedDateTime::from_utf8_with_provider( + s.as_bytes(), + disambiguation.into(), + offset_disambiguation.into(), + p + )) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn epoch_milliseconds(&self) -> i64 { + self.0.epoch_milliseconds() + } + + #[cfg(feature = "compiled_data")] + pub fn from_epoch_milliseconds(ms: i64, tz: TimeZone) -> Result, TemporalError> { + Self::from_epoch_milliseconds_with_provider(ms, tz, &Provider::compiled()) + } + pub fn from_epoch_milliseconds_with_provider<'p>( + ms: i64, + tz: TimeZone, + p: &Provider<'p>, + ) -> Result, TemporalError> { + super::zdt_from_epoch_ms_with_provider(ms, tz.into(), p).map(|c| Box::new(Self(c))) + } + + #[cfg(feature = "compiled_data")] + pub fn from_epoch_nanoseconds( + ns: I128Nanoseconds, + tz: TimeZone, + ) -> Result, TemporalError> { + Self::from_epoch_nanoseconds_with_provider(ns, tz, &Provider::compiled()) + } + pub fn from_epoch_nanoseconds_with_provider<'p>( + ns: I128Nanoseconds, + tz: TimeZone, + p: &Provider<'p>, + ) -> Result, TemporalError> { + let zdt = crate::zoned_date_time::zdt_from_epoch_ns_with_provider(ns, tz.into(), p)?; + Ok(Box::new(Self(zdt))) + } + + pub fn epoch_nanoseconds(&self) -> I128Nanoseconds { + self.0.epoch_nanoseconds().as_i128().into() + } + + pub fn offset_nanoseconds(&self) -> i64 { + self.0.offset_nanoseconds() + } + + pub fn to_instant(&self) -> Box { + Box::new(Instant(self.0.to_instant())) + } + + #[cfg(feature = "compiled_data")] + pub fn with( + &self, + partial: PartialZonedDateTime, + disambiguation: Option, + offset_option: Option, + overflow: Option, + ) -> Result, TemporalError> { + self.with_with_provider( + partial, + disambiguation, + offset_option, + overflow, + &Provider::compiled(), + ) + } + pub fn with_with_provider<'p>( + &self, + partial: PartialZonedDateTime, + disambiguation: Option, + offset_option: Option, + overflow: Option, + p: &Provider<'p>, + ) -> Result, TemporalError> { + with_provider!(p, |p| self.0.with_with_provider( + partial.try_into()?, + disambiguation.map(Into::into), + offset_option.map(Into::into), + overflow.map(Into::into), + p + )) + .map(|x| Box::new(ZonedDateTime(x))) + .map_err(Into::into) + } + + #[cfg(feature = "compiled_data")] + pub fn with_timezone(&self, zone: TimeZone) -> Result, TemporalError> { + self.with_timezone_with_provider(zone, &Provider::compiled()) + } + pub fn with_timezone_with_provider<'p>( + &self, + zone: TimeZone, + p: &Provider<'p>, + ) -> Result, TemporalError> { + with_provider!(p, |p| self.0.with_time_zone_with_provider(zone.into(), p)) + .map(|x| Box::new(ZonedDateTime(x))) + .map_err(Into::into) + } + + pub fn timezone(&self) -> TimeZone { + TimeZone::from(*self.0.time_zone()) + } + + pub fn compare_instant(&self, other: &Self) -> core::cmp::Ordering { + self.0.compare_instant(&other.0) + } + + #[cfg(feature = "compiled_data")] + pub fn equals(&self, other: &Self) -> bool { + self.equals_with_provider(other, &Provider::compiled()) + .unwrap_or(false) + } + pub fn equals_with_provider<'p>( + &self, + other: &Self, + p: &Provider<'p>, + ) -> Result { + with_provider!(p, |p| self.0.equals_with_provider(&other.0, p)).map_err(Into::into) + } + + pub fn offset(&self, write: &mut DiplomatWrite) -> Result<(), TemporalError> { + let string = self.0.offset(); + // throw away the error, this should always succeed + let _ = write.write_str(&string); + Ok(()) + } + + #[cfg(feature = "compiled_data")] + pub fn start_of_day(&self) -> Result, TemporalError> { + self.start_of_day_with_provider(&Provider::compiled()) + } + pub fn start_of_day_with_provider<'p>( + &self, + p: &Provider<'p>, + ) -> Result, TemporalError> { + with_provider!(p, |p| self.0.start_of_day_with_provider(p)) + .map(|x| Box::new(ZonedDateTime(x))) + .map_err(Into::into) + } + + #[cfg(feature = "compiled_data")] + pub fn get_time_zone_transition( + &self, + direction: TransitionDirection, + ) -> Result>, TemporalError> { + self.get_time_zone_transition_with_provider(direction, &Provider::compiled()) + } + pub fn get_time_zone_transition_with_provider<'p>( + &self, + direction: TransitionDirection, + p: &Provider<'p>, + ) -> Result>, TemporalError> { + with_provider!(p, |p| self + .0 + .get_time_zone_transition_with_provider(direction.into(), p)) + .map(|x| x.map(|y| Box::new(ZonedDateTime(y)))) + .map_err(Into::into) + } + + #[cfg(feature = "compiled_data")] + pub fn hours_in_day(&self) -> Result { + self.hours_in_day_with_provider(&Provider::compiled()) + } + pub fn hours_in_day_with_provider<'p>( + &self, + p: &Provider<'p>, + ) -> Result { + with_provider!(p, |p| self.0.hours_in_day_with_provider(p)).map_err(Into::into) + } + + pub fn to_plain_datetime(&self) -> Box { + Box::new(PlainDateTime(self.0.to_plain_date_time())) + } + + pub fn to_plain_date(&self) -> Box { + Box::new(PlainDate(self.0.to_plain_date())) + } + + pub fn to_plain_time(&self) -> Box { + Box::new(PlainTime(self.0.to_plain_time())) + } + + #[cfg(feature = "compiled_data")] + pub fn to_ixdtf_string( + &self, + display_offset: DisplayOffset, + display_timezone: DisplayTimeZone, + display_calendar: DisplayCalendar, + options: ToStringRoundingOptions, + write: &mut DiplomatWrite, + ) -> Result<(), TemporalError> { + self.to_ixdtf_string_with_provider( + display_offset, + display_timezone, + display_calendar, + options, + &Provider::compiled(), + write, + ) + } + pub fn to_ixdtf_string_with_provider<'p>( + &self, + display_offset: DisplayOffset, + display_timezone: DisplayTimeZone, + display_calendar: DisplayCalendar, + options: ToStringRoundingOptions, + p: &Provider<'p>, + write: &mut DiplomatWrite, + ) -> Result<(), TemporalError> { + // TODO this double-allocates, an API returning a Writeable or impl Write would be better + let string = with_provider!(p, |p| self.0.to_ixdtf_string_with_provider( + display_offset.into(), + display_timezone.into(), + display_calendar.into(), + options.into(), + p + )?); + // throw away the error, this should always succeed + let _ = write.write_str(&string); + Ok(()) + } + + // Same as PlainDateTime (non-getters) + pub fn with_calendar(&self, calendar: AnyCalendarKind) -> Box { + Box::new(ZonedDateTime( + self.0 + .with_calendar(temporal_rs::Calendar::new(calendar.into())), + )) + } + #[cfg(feature = "compiled_data")] + pub fn with_plain_time( + &self, + time: Option<&PlainTime>, + ) -> Result, TemporalError> { + self.with_plain_time_and_provider(time, &Provider::compiled()) + } + pub fn with_plain_time_and_provider<'p>( + &self, + time: Option<&PlainTime>, + p: &Provider<'p>, + ) -> Result, TemporalError> { + with_provider!(p, |p| self + .0 + .with_plain_time_and_provider(time.map(|t| t.0), p)) + .map(|x| Box::new(ZonedDateTime(x))) + .map_err(Into::into) + } + #[cfg(feature = "compiled_data")] + pub fn add( + &self, + duration: &Duration, + overflow: Option, + ) -> Result, TemporalError> { + self.add_with_provider(duration, overflow, &Provider::compiled()) + } + pub fn add_with_provider<'p>( + &self, + duration: &Duration, + overflow: Option, + p: &Provider<'p>, + ) -> Result, TemporalError> { + with_provider!(p, |p| self.0.add_with_provider( + &duration.0, + overflow.map(Into::into), + p + )) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + #[cfg(feature = "compiled_data")] + pub fn subtract( + &self, + duration: &Duration, + overflow: Option, + ) -> Result, TemporalError> { + self.subtract_with_provider(duration, overflow, &Provider::compiled()) + } + pub fn subtract_with_provider<'p>( + &self, + duration: &Duration, + overflow: Option, + p: &Provider<'p>, + ) -> Result, TemporalError> { + with_provider!(p, |p| self.0.subtract_with_provider( + &duration.0, + overflow.map(Into::into), + p + )) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + #[cfg(feature = "compiled_data")] + pub fn until( + &self, + other: &Self, + settings: DifferenceSettings, + ) -> Result, TemporalError> { + self.until_with_provider(other, settings, &Provider::compiled()) + } + pub fn until_with_provider<'p>( + &self, + other: &Self, + settings: DifferenceSettings, + p: &Provider<'p>, + ) -> Result, TemporalError> { + with_provider!(p, |p| self.0.until_with_provider( + &other.0, + settings.try_into()?, + p + )) + .map(|x| Box::new(Duration(x))) + .map_err(Into::into) + } + #[cfg(feature = "compiled_data")] + pub fn since( + &self, + other: &Self, + settings: DifferenceSettings, + ) -> Result, TemporalError> { + self.since_with_provider(other, settings, &Provider::compiled()) + } + pub fn since_with_provider<'p>( + &self, + other: &Self, + settings: DifferenceSettings, + p: &Provider<'p>, + ) -> Result, TemporalError> { + with_provider!(p, |p| self.0.since_with_provider( + &other.0, + settings.try_into()?, + p + )) + .map(|x| Box::new(Duration(x))) + .map_err(Into::into) + } + #[cfg(feature = "compiled_data")] + pub fn round(&self, options: RoundingOptions) -> Result, TemporalError> { + self.round_with_provider(options, &Provider::compiled()) + } + pub fn round_with_provider<'p>( + &self, + options: RoundingOptions, + p: &Provider<'p>, + ) -> Result, TemporalError> { + with_provider!(p, |p| self.0.round_with_provider(options.try_into()?, p)) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + + // Same as PlainDateTime (getters) + pub fn hour(&self) -> u8 { + // unwrap_or_default because of + // https://github.com/boa-dev/temporal/issues/548 + self.0.hour() + } + pub fn minute(&self) -> u8 { + self.0.minute() + } + pub fn second(&self) -> u8 { + self.0.second() + } + pub fn millisecond(&self) -> u16 { + self.0.millisecond() + } + pub fn microsecond(&self) -> u16 { + self.0.microsecond() + } + pub fn nanosecond(&self) -> u16 { + self.0.nanosecond() + } + + pub fn calendar<'a>(&'a self) -> &'a Calendar { + Calendar::transparent_convert(self.0.calendar()) + } + pub fn year(&self) -> i32 { + self.0.year() + } + pub fn month(&self) -> u8 { + self.0.month() + } + pub fn month_code(&self, write: &mut DiplomatWrite) { + // https://github.com/boa-dev/temporal/issues/328 for the fallibility + let code = self.0.month_code(); + // throw away the error, this should always succeed + let _ = write.write_str(code.as_str()); + } + pub fn day(&self) -> u8 { + self.0.day() + } + + pub fn day_of_week(&self) -> u16 { + self.0.day_of_week() + } + + pub fn day_of_year(&self) -> u16 { + self.0.day_of_year() + } + + pub fn week_of_year(&self) -> Option { + self.0.week_of_year() + } + + pub fn year_of_week(&self) -> Option { + self.0.year_of_week() + } + + pub fn days_in_week(&self) -> u16 { + self.0.days_in_week() + } + pub fn days_in_month(&self) -> u16 { + self.0.days_in_month() + } + + pub fn days_in_year(&self) -> u16 { + self.0.days_in_year() + } + + pub fn months_in_year(&self) -> u16 { + self.0.months_in_year() + } + + pub fn in_leap_year(&self) -> bool { + self.0.in_leap_year() + } + // Writes an empty string for no era + pub fn era(&self, write: &mut DiplomatWrite) { + let era = self.0.era(); + if let Some(era) = era { + // throw away the error, this should always succeed + let _ = write.write_str(&era); + } + } + + pub fn era_year(&self) -> Option { + self.0.era_year() + } + + #[allow(clippy::should_implement_trait)] + pub fn clone(&self) -> Box { + Box::new(Self(self.0.clone())) + } + } +} + +pub(crate) fn zdt_from_epoch_ms_with_provider<'p>( + ms: i64, + time_zone: temporal_rs::TimeZone, + p: &Provider<'p>, +) -> Result { + let instant = temporal_rs::Instant::from_epoch_milliseconds(ms)?; + with_provider!(p, |p| instant + .to_zoned_date_time_iso_with_provider(time_zone, p)) + .map_err(Into::into) +} + +pub(crate) fn zdt_from_epoch_ns_with_provider<'p>( + ns: I128Nanoseconds, + time_zone: temporal_rs::TimeZone, + p: &Provider<'p>, +) -> Result { + let instant = temporal_rs::Instant::try_new(ns.into())?; + with_provider!(p, |p| instant + .to_zoned_date_time_iso_with_provider(time_zone, p)) + .map_err(Into::into) +} + +impl TryFrom> for temporal_rs::partial::PartialZonedDateTime { + type Error = TemporalError; + fn try_from(other: ffi::PartialZonedDateTime<'_>) -> Result { + let timezone = other.timezone.clone().into_option().map(|x| x.tz()); + let calendar = temporal_rs::Calendar::new(other.date.calendar.into()); + Ok(Self { + fields: other.try_into()?, + timezone, + calendar, + }) + } +} + +impl TryFrom> for temporal_rs::fields::ZonedDateTimeFields { + type Error = TemporalError; + fn try_from(other: ffi::PartialZonedDateTime<'_>) -> Result { + let offset = match other.offset.into_option() { + Some(o) => Some(temporal_rs::UtcOffset::from_utf8(o.into())?), + None => None, + }; + Ok(Self { + calendar_fields: other.date.try_into()?, + time: other.time.into(), + offset, + }) + } +} + +impl From> for Option { + fn from(other: ffi::RelativeTo) -> Self { + if let Some(pd) = other.date { + Some(temporal_rs::options::RelativeTo::PlainDate(pd.0.clone())) + } else { + other + .zoned + .map(|z| temporal_rs::options::RelativeTo::ZonedDateTime(z.0.clone())) + } + } +} + +impl From for ffi::OwnedRelativeTo { + fn from(other: RelativeTo) -> Self { + use alloc::boxed::Box; + match other { + RelativeTo::PlainDate(d) => Self { + date: Some(Box::new(crate::plain_date::ffi::PlainDate(d))), + zoned: None, + }, + RelativeTo::ZonedDateTime(d) => Self { + zoned: Some(Box::new(ffi::ZonedDateTime(d))), + date: None, + }, + } + } +} diff --git a/deps/temporal/temporal_capi/temporal_capi.gyp b/deps/temporal/temporal_capi/temporal_capi.gyp new file mode 100644 index 00000000000000..08ebcdcba56da2 --- /dev/null +++ b/deps/temporal/temporal_capi/temporal_capi.gyp @@ -0,0 +1,57 @@ +{ + 'targets': [ + { + 'target_name': 'temporal_capi', + 'type': 'none', + 'hard_dependency': 1, + 'sources': [ + 'src/calendar.rs', + 'src/error.rs', + 'src/lib.rs', + 'src/plain_date_time.rs', + 'src/plain_month_day.rs', + 'src/plain_year_month.rs', + 'src/time_zone.rs', + 'src/duration.rs', + 'src/instant.rs', + 'src/options.rs', + 'src/plain_date.rs', + 'src/plain_time.rs', + 'src/provider.rs', + 'src/zoned_date_time.rs', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + 'bindings/cpp', + ], + }, + 'link_settings': { + 'libraries': [ + '<(SHARED_INTERMEDIATE_DIR)/>(cargo_build_mode)/libtemporal_capi.a', + ], + }, + 'actions': [ + { + 'action_name': 'cargo_build', + 'inputs': [ + '<@(_sources)', + ], + 'outputs': [ + '<(SHARED_INTERMEDIATE_DIR)/>(cargo_build_mode)/libtemporal_capi.a' + ], + 'action': [ + 'cargo', + 'rustc', + '>@(cargo_build_flags)', + '--crate-type', + 'staticlib', + '--features', + 'zoneinfo64', + '--target-dir', + '<(SHARED_INTERMEDIATE_DIR)' + ], + } + ], + } + ] +} diff --git a/deps/temporal/temporal_capi/tests/c/Makefile b/deps/temporal/temporal_capi/tests/c/Makefile new file mode 100644 index 00000000000000..91a6fbef024d5d --- /dev/null +++ b/deps/temporal/temporal_capi/tests/c/Makefile @@ -0,0 +1,25 @@ +.DEFAULT_GOAL := test +.PHONY: build test +FORCE: + +HEADERS := ../../bindings/c/ +ALL_HEADERS := $(wildcard ${HEADERS}/**/*.h) + +C?=gcc + +TEST_FILES := $(wildcard *.c) +OUT_FILES = $(patsubst %.c,%.out,$(TEST_FILES)) + +$(ALL_HEADERS): + +../../../target/debug/libtemporal_capi.a: FORCE + cargo rustc -p temporal_capi --crate-type staticlib + +%.out: %.c ../../../target/debug/libtemporal_capi.a $(ALL_HEADERS) + $(C) -L ../../../target/debug/ -I ${HEADERS} $< -ltemporal_capi -lm -o $@ + ./$@ + +test: $(OUT_FILES) + +clean: + rm $(OUT_FILES) diff --git a/deps/temporal/temporal_capi/tests/c/simple.c b/deps/temporal/temporal_capi/tests/c/simple.c new file mode 100644 index 00000000000000..73c2ee66f3d7a8 --- /dev/null +++ b/deps/temporal/temporal_capi/tests/c/simple.c @@ -0,0 +1,33 @@ +#include "ArithmeticOverflow.d.h" +#include "Calendar.h" +#include "DisplayCalendar.d.h" +#include "PlainDate.h" +#include "diplomat_runtime.h" +#include + +int main() { + temporal_rs_PlainDate_try_new_with_overflow_result result = + temporal_rs_PlainDate_try_new_with_overflow(2025, 1, 33, AnyCalendarKind_Gregorian, ArithmeticOverflow_Constrain); + + if (!result.is_ok) { + fprintf(stderr, "failed to create a PlainDate\n"); + return 1; + } + + PlainDate *date = result.ok; + char formatted[40]; + DiplomatWrite write = diplomat_simple_write(formatted, 40); + + temporal_rs_PlainDate_to_ixdtf_string(date, DisplayCalendar_Always, &write); + if (write.grow_failed) { + fprintf(stderr, "format overflowed the string\n"); + temporal_rs_PlainDate_destroy(date); + return 1; + } + + printf("%s\n", formatted); + + temporal_rs_PlainDate_destroy(date); + + return 0; +} diff --git a/deps/temporal/temporal_capi/tests/cpp/Makefile b/deps/temporal/temporal_capi/tests/cpp/Makefile new file mode 100644 index 00000000000000..2e17a4845e311f --- /dev/null +++ b/deps/temporal/temporal_capi/tests/cpp/Makefile @@ -0,0 +1,25 @@ +.DEFAULT_GOAL := test +.PHONY: build test +FORCE: + +HEADERS := ../../bindings/cpp/ +ALL_HEADERS := $(wildcard ${HEADERS}/**/*.hpp) + +CXX?=g++ + +TEST_FILES := $(wildcard *.cpp) +OUT_FILES = $(patsubst %.cpp,%.out,$(TEST_FILES)) + +$(ALL_HEADERS): + +../../../target/debug/libtemporal_capi.a: FORCE + cargo rustc -p temporal_capi --crate-type staticlib + +%.out: %.cpp ../../../target/debug/libtemporal_capi.a $(ALL_HEADERS) + $(CXX) -std=c++17 -L ../../../target/debug/ -I ${HEADERS} $< -ltemporal_capi -lm -o $@ + ./$@ + +test: $(OUT_FILES) + +clean: + rm $(OUT_FILES) diff --git a/deps/temporal/temporal_capi/tests/cpp/simple.cpp b/deps/temporal/temporal_capi/tests/cpp/simple.cpp new file mode 100644 index 00000000000000..98b2ad56d60549 --- /dev/null +++ b/deps/temporal/temporal_capi/tests/cpp/simple.cpp @@ -0,0 +1,15 @@ +#include +#include + +#include + +using namespace temporal_rs; + +int main() { + auto date = PlainDate::try_new_with_overflow(2025, 1, 33, AnyCalendarKind::Gregorian, ArithmeticOverflow::Constrain).ok().value(); + + auto formatted = date->to_ixdtf_string(DisplayCalendar::Always); + + std::cout< io::Result<()>; + + fn write_debug(&self, debug_path: &Path) -> io::Result<()>; +} + +impl BakedDataProvider for ZoneInfoProvider<'_> { + fn write_data(&self, data_path: &Path) -> io::Result<()> { + fs::create_dir_all(data_path)?; + let generated_file = data_path.join("compiled_zoneinfo_provider.rs.data"); + let baked = self.bake(&Default::default()); + + let baked_macro = quote! { + #[macro_export] + macro_rules! compiled_zoneinfo_provider { + ($providername:ident) => { + pub const $providername: &'static timezone_provider::experimental_tzif::ZoneInfoProvider = &#baked; + } + } + }; + let file = syn::parse_file(&baked_macro.to_string()).unwrap(); + let formatted = prettyplease::unparse(&file); + let mut file = BufWriter::new(File::create(generated_file)?); + write!(file, "//@generated\n// (by `bakeddata` binary in temporal_rs, using `databake`)\n\n{formatted}") + } + + fn write_debug(&self, debug_path: &Path) -> io::Result<()> { + let zoneinfo_debug_path = debug_path.join("zoneinfo"); + // Remove zoneinfo directory and recreate, so we can rely on diff of what is + // changed / missing. + if zoneinfo_debug_path.exists() { + fs::remove_dir_all(zoneinfo_debug_path.clone())?; + } + // Recreate directory. + fs::create_dir_all(zoneinfo_debug_path.clone())?; + + let map_file = zoneinfo_debug_path.join("map.json"); + + // Create id sets for the tzifs + let mut tzif_ids: HashMap> = HashMap::new(); + for (identifier, index) in self.ids.to_btreemap().iter() { + if let Some(id_set) = tzif_ids.get_mut(index) { + id_set.insert(identifier.clone()); + } else { + tzif_ids.insert(*index, BTreeSet::from([identifier.clone()])); + } + } + + let tzif_dir_path = zoneinfo_debug_path.join("tzifs"); + fs::create_dir_all(tzif_dir_path.clone())?; + + let mut id_map: BTreeMap = BTreeMap::new(); + for (id, tzif) in self.tzifs.iter().enumerate() { + let mut tzif_data = serde_json::Map::new(); + let id_set = tzif_ids.get(&id).unwrap(); + tzif_data.insert("ids".into(), serde_json::to_value(id_set)?); + tzif_data.insert("tzif".into(), serde_json::to_value(tzif)?); + let filename = format!("tzif-{}-{}.json", hash_ids(id_set), hash_tzif(tzif)); + let filepath = tzif_dir_path.join(filename.clone()); + for id in id_set { + id_map.insert(id.clone(), filename.clone()); + } + fs::write(filepath, serde_json::to_string_pretty(&tzif_data)?)?; + } + + fs::write( + map_file, + format!("{}\n", serde_json::to_string_pretty(&id_map)?), + )?; + + // TODO: Add version + Ok(()) + } +} + +fn hash_ids(set: &BTreeSet) -> String { + let mut hasher = FxHasher::default(); + set.hash(&mut hasher); + format!("{:x}", hasher.finish()) +} + +fn hash_tzif(tzif: &ZeroTzifULE) -> String { + let mut hasher = FxHasher::default(); + tzif.as_bytes().hash(&mut hasher); + format!("{:x}", hasher.finish()) +} + +impl BakedDataProvider for IanaIdentifierNormalizer<'_> { + fn write_data(&self, data_path: &Path) -> io::Result<()> { + fs::create_dir_all(data_path)?; + let generated_file = data_path.join("iana_normalizer.rs.data"); + let baked = self.bake(&Default::default()); + + let baked_macro = quote! { + #[macro_export] + macro_rules! iana_normalizer_singleton { + ($providername:ident) => { + pub const $providername: &'static timezone_provider::IanaIdentifierNormalizer = &#baked; + } + } + }; + let file = syn::parse_file(&baked_macro.to_string()).unwrap(); + let formatted = prettyplease::unparse(&file); + let mut file = BufWriter::new(File::create(generated_file)?); + write!(file, "//@generated\n// (by `bakeddata` binary in temporal_rs, using `databake`)\n\n{formatted}") + } + + fn write_debug(&self, debug_path: &Path) -> io::Result<()> { + fs::create_dir_all(debug_path)?; + let debug_filename = debug_path.join("iana_normalizer.json"); + let json = serde_json::to_string_pretty(self).unwrap(); + fs::write(debug_filename, json) + } +} + +fn write_data_file_with_debug( + data_path: &Path, + provider: &impl BakedDataProvider, +) -> io::Result<()> { + let debug_path = data_path.join("debug"); + provider.write_debug(&debug_path)?; + provider.write_data(data_path) +} + +fn main() -> io::Result<()> { + let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); + let tzdata_input = std::env::var("TZDATA_DIR").unwrap_or("tzdata".into()); + let tzdata_path = Path::new(&tzdata_input); + let tzdata_dir = manifest_dir + .parent() + .unwrap() + .parent() + .unwrap() + .join(tzdata_path); + println!("Using tzdata directory: {tzdata_dir:?}"); + + let provider = Path::new(manifest_dir) + .parent() + .unwrap() + .parent() + .unwrap() + .join("provider/src"); + println!("Using provider directory: {provider:?}"); + + // Write identifiers + write_data_file_with_debug( + &provider.join("data"), + &IanaIdentifierNormalizer::build(&tzdata_dir).unwrap(), + )?; + + // Write tzif data + write_data_file_with_debug( + &provider.join("data"), + &ZoneInfoProvider::build(&tzdata_dir).unwrap(), + ) +} diff --git a/deps/temporal/tools/depcheck/Cargo.toml b/deps/temporal/tools/depcheck/Cargo.toml new file mode 100644 index 00000000000000..dede26c999aa5b --- /dev/null +++ b/deps/temporal/tools/depcheck/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "depcheck" +edition.workspace = true +version.workspace = true +rust-version.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +readme.workspace = true +exclude.workspace = true +publish = false + +[dependencies] diff --git a/deps/temporal/tools/depcheck/src/main.rs b/deps/temporal/tools/depcheck/src/main.rs new file mode 100644 index 00000000000000..2bfbc7580602fc --- /dev/null +++ b/deps/temporal/tools/depcheck/src/main.rs @@ -0,0 +1,191 @@ +//! Test for ensuring that we don't unintentionally add deps + +use std::collections::BTreeSet; +use std::process::{self, Command}; +use std::str; + +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +struct DepSpec { + crate_name: String, + crate_version: String, +} + +/// Get the deep (fully resolved) dependency list produced by `cargo tree -p {package} -e {edge_kind}` +fn get_dep_list(package: &str, edge_kind: &str, extra_args: &str) -> Vec { + let mut cmd = Command::new("cargo"); + cmd.arg("tree") + .arg("-p") + .arg(package) + .arg("-e") + .arg(edge_kind) + .arg("--no-default-features"); + for arg in extra_args.split(' ') { + if !arg.is_empty() { + cmd.arg(arg); + } + } + let output = cmd.output().expect("Failed to run `cargo tree`"); + + if !output.status.success() { + eprintln!("Failed to run `cargo tree -p {package} -e {edge_kind} --no-default-features {extra_args}`:"); + if let Ok(s) = str::from_utf8(&output.stderr) { + eprintln!("{s}"); + } + process::exit(1); + } + let mut spec: Vec<_> = output + .stdout + .split(|b| *b == b'\n') + .filter_map(|slice| { + if slice.is_empty() { + return None; + } + if slice[0] == b'[' { + // cargo tree output has sections like `[dev-dependencies]` + return None; + } + + let mut iter = slice.split(|b| *b == b' '); + let mut found_crate_name = None; + for section in &mut iter { + if section.is_empty() { + continue; + } + // The format is {line drawing characters} {crate name} {crate version} + if char::from(section[0]).is_ascii_alphabetic() { + found_crate_name = + Some(str::from_utf8(section).expect("Must be utf-8").to_owned()); + break; + } + } + if let Some(crate_name) = found_crate_name { + let crate_version = iter + .next() + .expect("There must be a version after the crate name!"); + let crate_version = str::from_utf8(crate_version) + .expect("Must be utf-8") + .to_owned(); + Some(DepSpec { + crate_name, + crate_version, + }) + } else { + None + } + }) + .collect(); + spec.sort(); + spec.dedup(); + + spec +} + +/// Given a `cargo tree` invocation and the dependency sets to check, checks for any unlisted or duplicated deps +/// +/// `dep_list_name_for_error` is the name of the const above to show in the error suggestion +fn test_dep_list( + package: &str, + edge_kind: &str, + extra_args: &str, + sets: &[&BTreeSet<&str>], + dep_list_name_for_error: &str, +) { + println!("Testing `cargo tree -p {package} -e {edge_kind} --no-default-features {extra_args}`"); + let mut errors = Vec::new(); + let dep_list = get_dep_list(package, edge_kind, extra_args); + for i in dep_list.windows(2) { + if i[0].crate_name == i[1].crate_name { + errors.push(format!( + "Found two versions for `{0}` ({1} & {2})", + i[0].crate_name, i[0].crate_version, i[1].crate_version + )); + } + } + + 'dep_loop: for i in dep_list { + if i.crate_name == package { + continue; + } + let name = &i.crate_name; + for s in sets { + if s.contains(&**name) { + continue 'dep_loop; + } + } + errors.push(format!( + "Found non-allowlisted crate `{name}`, consider adding to \ + {dep_list_name_for_error} in depcheck/src/main.rs if intentional" + )); + } + + if !errors.is_empty() { + eprintln!("Found invalid dependencies:"); + for e in errors { + eprintln!("\t{e}"); + } + process::exit(1); + } +} + +fn main() { + let basic_runtime: BTreeSet<_> = BASIC_RUNTIME_DEPS.iter().copied().collect(); + let compiled_data: BTreeSet<_> = COMPILED_DEPS.iter().copied().collect(); + + test_dep_list( + "temporal_capi", + "normal,no-proc-macro", + "", + &[&basic_runtime], + "`BASIC_RUNTIME_DEPS`", + ); + + test_dep_list( + "temporal_capi", + "normal,no-proc-macro", + "--features compiled_data", + &[&basic_runtime, &compiled_data], + "`COMPILED_DEPS`", + ); +} + +/// Dependencies that are always allowed as runtime dependencies +/// +pub const BASIC_RUNTIME_DEPS: &[&str] = &[ + // temporal_rs crates + "temporal_rs", + "timezone_provider", + // ICU4X components and utils + "calendrical_calculations", + "core_maths", + "diplomat-runtime", + "icu_calendar", + "icu_calendar_data", + "icu_collections", + "icu_locale", + "icu_locale_core", + "icu_locale_data", + "icu_provider", + "ixdtf", + "litemap", + "potential_utf", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", + // Other deps + "libm", + "num-traits", + "stable_deref_trait", +]; + +// Most of these should be removed +pub const COMPILED_DEPS: &[&str] = &[ + "bytes", + "combine", + "jiff-tzdb", + "memchr", + "tzif", + "timezone_provider", +]; diff --git a/deps/temporal/tools/diplomat-gen/Cargo.toml b/deps/temporal/tools/diplomat-gen/Cargo.toml new file mode 100644 index 00000000000000..80028e3c1732a1 --- /dev/null +++ b/deps/temporal/tools/diplomat-gen/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "diplomat-gen" +edition.workspace = true +version.workspace = true +rust-version.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +readme.workspace = true +exclude.workspace = true +publish = false + +[dependencies] +diplomat-tool.workspace = true diff --git a/deps/temporal/tools/diplomat-gen/src/main.rs b/deps/temporal/tools/diplomat-gen/src/main.rs new file mode 100644 index 00000000000000..5f879b013d5005 --- /dev/null +++ b/deps/temporal/tools/diplomat-gen/src/main.rs @@ -0,0 +1,44 @@ +use std::{io, path::Path}; + +use diplomat_tool::config::Config; + +fn main() -> std::io::Result<()> { + const LANGUAGES: [&str; 2] = ["c", "cpp"]; + + let manifest = Path::new(env!("CARGO_MANIFEST_DIR")); + + let capi = manifest + .parent() + .unwrap() + .parent() + .unwrap() + .join("temporal_capi"); + + let mut library_config = Config::default(); + library_config.shared_config.lib_name = Some("temporal_rs".into()); + + for lang in LANGUAGES { + diplomat_tool::gen( + &capi.join("src/lib.rs"), + lang, + &{ + let mut include = capi.join("bindings").join(lang); + if lang == "cpp" { + include = include.join("temporal_rs"); + } + if let Err(err) = std::fs::remove_dir_all(&include) { + if err.kind() != io::ErrorKind::NotFound { + return Err(err); + } + } + std::fs::create_dir(&include)?; + include + }, + &Default::default(), + library_config.clone(), + false, + )?; + } + + Ok(()) +} diff --git a/deps/temporal/tools/tzif-inspect/Cargo.toml b/deps/temporal/tools/tzif-inspect/Cargo.toml new file mode 100644 index 00000000000000..80131cc5049b36 --- /dev/null +++ b/deps/temporal/tools/tzif-inspect/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "tzif-inspect" +edition.workspace = true +version.workspace = true +rust-version.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +readme.workspace = true +exclude.workspace = true +publish = false + +[dependencies] +jiff-tzdb.workspace = true +tzif.workspace = true +temporal_rs = {workspace = true, features = ["tzdb", "compiled_data"]} +timezone_provider = {workspace = true, features = ["tzif"]} diff --git a/deps/temporal/tools/tzif-inspect/README.md b/deps/temporal/tools/tzif-inspect/README.md new file mode 100644 index 00000000000000..2975394bc5a0e4 --- /dev/null +++ b/deps/temporal/tools/tzif-inspect/README.md @@ -0,0 +1,9 @@ +# tzif-inspect + +Simple utility tool to dump the data for a given tzdb entry + +To run: + +```sh +cargo run -p tzif-inspect -- America/Los_Angeles +``` diff --git a/deps/temporal/tools/tzif-inspect/src/main.rs b/deps/temporal/tools/tzif-inspect/src/main.rs new file mode 100644 index 00000000000000..c05854a3e49fcb --- /dev/null +++ b/deps/temporal/tools/tzif-inspect/src/main.rs @@ -0,0 +1,219 @@ +use std::env; +use std::string::ToString; +use temporal_rs::partial::PartialDuration; +use temporal_rs::{Duration, PlainDate, PlainTime, TimeZone, ZonedDateTime}; +use timezone_provider::tzif::Tzif; +use tzif::data::posix::TransitionDay; +use tzif::data::time::Seconds; +use tzif::data::tzif::{StandardWallIndicator, UtLocalIndicator}; + +macro_rules! format_line( + ($arr:ident[$i:expr], $($args:expr),*) => { + let string = stringify!($arr); + let array = format!("{}[{}]", string, $i); + format_line!(array, $($args),*) + }; + ($a:expr, $b:expr, $c: expr, $d: expr) => { + println!("{:<25} {:<20} {:<5} {}", $a, $b, $c, $d) + }; + ($a:expr, $b:expr, $c: expr) => { + println!("{:<25} {:<20} {}", $a, $b, $c) + }; + ($a:expr, $b:expr) => { + println!("{:<25} {}", $a, $b) + }; +); + +fn seconds_to_zdt_string(s: Seconds, time_zone: TimeZone) -> String { + ZonedDateTime::try_new_iso(s.0 as i128 * 1_000_000_000, time_zone) + .unwrap() + .to_string() +} + +fn seconds_to_offset_time(s: Seconds) -> String { + let is_negative = s.0 < 0; + let seconds = s.0.abs(); + let partial = PartialDuration::default().with_seconds(seconds); + let time = PlainTime::default() + .add(&Duration::from_partial_duration(partial).unwrap()) + .unwrap(); + let string = time.to_ixdtf_string(Default::default()).unwrap(); + if is_negative { + format!("-{string}") + } else { + string + } +} + +fn month(m: u16) -> &'static str { + match m { + 1 => "Jan", + 2 => "Feb", + 3 => "Mar", + 4 => "Apr", + 5 => "May", + 6 => "Jun", + 7 => "Jul", + 8 => "Aug", + 9 => "Sep", + 10 => "Oct", + 11 => "Nov", + 12 => "Dec", + _ => unreachable!(), + } +} + +fn format_transition_day(trans_day: TransitionDay) -> String { + match trans_day { + TransitionDay::NoLeap(d) | TransitionDay::WithLeap(d) => { + let no_leap = matches!(trans_day, TransitionDay::NoLeap(_)); + let start_year = if no_leap { 2001 } else { 2004 }; + let start_date = PlainDate::new(start_year, 1, 1, Default::default()).unwrap(); + let date_duration = Duration::new(0, 0, 0, d.into(), 0, 0, 0, 0, 0, 0).unwrap(); + let adjusted = start_date.add(&date_duration, None).unwrap(); + let m = month(adjusted.month().into()); + let day = adjusted.day(); + if no_leap { + format!("NoLeap({d}): {m} {day}") + } else { + format!("WithLeap({d}): {m} {day}") + } + } + TransitionDay::Mwd(m, w, d) => { + let month = month(m); + let day = match d { + 0 => "Sun", + 1 => "Mon", + 2 => "Tue", + 3 => "Wed", + 4 => "Thu", + 5 => "Fri", + 6 => "Sat", + _ => unreachable!(), + }; + + format!("{day} #{w} of {month}") + } + } +} +fn main() { + let tz = env::args().nth(1).expect("Needs one argument"); + let tzif = jiff_tzdb::get(&tz).unwrap(); + let tzif = Tzif::from_bytes(tzif.1).unwrap(); + let time_zone = TimeZone::try_from_identifier_str(&tz).unwrap(); + let utc = TimeZone::try_from_identifier_str("UTC").unwrap(); + + let Some(header) = tzif.header2 else { + println!("No V2 header"); + return; + }; + let Some(db) = tzif.data_block2 else { + println!("No V2 data"); + return; + }; + + println!("--------- Header ----------"); + format_line!("version", header.version); + format_line!("isutcnt", header.isutcnt); + format_line!("isstdcnt", header.isstdcnt); + format_line!("leapcnt", header.leapcnt); + format_line!("timecnt", header.timecnt); + format_line!("typecnt", header.typecnt); + format_line!("charcnt", header.charcnt); + println!("\n--------- Data ----------"); + format_line!("Transition", "Time", "Type", "Time (formatted)"); + for (i, seconds) in db.transition_times.iter().enumerate() { + format_line!( + transitions[i], + seconds.0, + db.transition_types[i], + seconds_to_zdt_string(*seconds, time_zone) + ); + } + + println!(); + for (i, ltt) in db.local_time_type_records.iter().enumerate() { + format_line!(localtimetype[i], ""); + format_line!(" utcoff", ltt.utoff.0, seconds_to_offset_time(ltt.utoff)); + format_line!(" is_dst", ltt.is_dst); + format_line!(" idx", ltt.idx); + } + + if !db.time_zone_designations.is_empty() { + println!(); + } + for (i, desig) in db.time_zone_designations.iter().enumerate() { + format_line!(desginations[i], desig); + } + + if !db.leap_second_records.is_empty() { + println!(); + } + for (i, leap) in db.leap_second_records.iter().enumerate() { + format_line!( + leap[i], + leap.occurrence.0, + leap.correction, + seconds_to_zdt_string(leap.occurrence, utc) + ); + } + + if !db.ut_local_indicators.is_empty() { + println!(); + } + for (i, utlocal) in db.ut_local_indicators.iter().enumerate() { + let utlocal = if *utlocal == UtLocalIndicator::Ut { + "UT" + } else { + "local" + }; + format_line!(ut_local[i], utlocal); + } + + if !db.standard_wall_indicators.is_empty() { + println!(); + } + for (i, sw) in db.standard_wall_indicators.iter().enumerate() { + let sw = if *sw == StandardWallIndicator::Standard { + "standard" + } else { + "wall" + }; + format_line!(standard_wall[i], sw); + } + + println!("\n--------- Footer ----------"); + if let Some(footer) = tzif.footer { + let offset = footer.std_info.offset.0; + format_line!( + "std_info", + footer.std_info.name, + offset, + // Posix offsets are backwards + seconds_to_offset_time(Seconds(-offset)) + ); + if let Some(dst_info) = footer.dst_info { + format_line!("dst_info", ""); + let offset = dst_info.variant_info.offset.0; + format_line!( + " variant_info", + dst_info.variant_info.name, + offset, + // Posix offsets are backwards + seconds_to_offset_time(Seconds(-offset)) + ); + format_line!( + " start_date", + format_transition_day(dst_info.start_date.day), + dst_info.start_date.time.0, + seconds_to_offset_time(dst_info.start_date.time) + ); + format_line!( + " end_date", + format_transition_day(dst_info.end_date.day), + dst_info.end_date.time.0, + seconds_to_offset_time(dst_info.end_date.time) + ); + } + } +} diff --git a/deps/temporal/tools/zoneinfo-test-gen/Cargo.toml b/deps/temporal/tools/zoneinfo-test-gen/Cargo.toml new file mode 100644 index 00000000000000..f16e0cfe55806b --- /dev/null +++ b/deps/temporal/tools/zoneinfo-test-gen/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "zoneinfo-test-gen" +edition.workspace = true +version.workspace = true +rust-version.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +readme.workspace = true +exclude.workspace = true +publish = false + +[dependencies] +clap = { version = "4.5.47", features = ["derive"] } +serde = { version = "1.0.225", features = ["derive"] } +serde_json = "1.0.145" +tzif.workspace = true diff --git a/deps/temporal/tools/zoneinfo-test-gen/README.md b/deps/temporal/tools/zoneinfo-test-gen/README.md new file mode 100644 index 00000000000000..7d23e9efcb9aed --- /dev/null +++ b/deps/temporal/tools/zoneinfo-test-gen/README.md @@ -0,0 +1,37 @@ +# zoneinfo-test-gen + +`zoneinfo-test-gen` is a tool for generating `zoneinfo` test data from +TZif data. + +To use, run: + +``` +cargo run -p zoneinfo-test-gen +``` + +This tool will by default attempt to read from the local UNIX zoneinfo +directory, `/usr/share/zoneinfo`. + +For specialized data, download a new tzdata from IANA by clicking on the +link below. + +[IANA Download](https://data.iana.org/time-zones/tzdata-latest.tar.gz) + +Once downloaded and extracted, new tzif files can be compiled with the +below command: + +``` +zic [OPTIONS] -d +``` + +Options must be set for the specific configuration that the test data +should be in. + +NOTE: zoneinfo files are in `vanguard` by default. + +From IANA's `tzdata` directory, switching zoneinfo files to rearguard +from vanguard can be completed by running: + +``` +awk -v DATAFORM=rearguard -f ziguard.awk > output +``` diff --git a/deps/temporal/tools/zoneinfo-test-gen/src/main.rs b/deps/temporal/tools/zoneinfo-test-gen/src/main.rs new file mode 100644 index 00000000000000..89684348f13b9e --- /dev/null +++ b/deps/temporal/tools/zoneinfo-test-gen/src/main.rs @@ -0,0 +1,115 @@ +use clap::Parser; +use serde::{Deserialize, Serialize}; +use std::{ + fs, + path::{Path, PathBuf}, +}; + +#[derive(Debug, Serialize, Deserialize)] +struct TzifTestData { + first_record: LocalRecord, + transitions: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +struct TransitionRecord { + transition_time: i64, + record: LocalRecord, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +struct LocalRecord { + offset: i64, + is_dst: bool, + abbr: String, +} + +// Utility function for generating example files +fn generate_test_data(input_dir: PathBuf, output_dir: PathBuf, identifier: &str) { + let filename = identifier.to_lowercase().replace("/", "-"); + let test_data_path = output_dir.join(format!("{filename}.json")); + + let tzif_path = input_dir.join(identifier); + std::println!("Parsing tzif from {tzif_path:?}"); + let tzif = tzif::parse_tzif_file(&tzif_path).unwrap(); + + let tzif_block_v2 = tzif.data_block2.unwrap(); + let first_record_data = tzif_block_v2.local_time_type_records[0]; + let first_record = LocalRecord { + offset: first_record_data.utoff.0, + is_dst: first_record_data.is_dst, + abbr: tzif_block_v2.time_zone_designations[0].clone(), + }; + + // TODO: There may be a bug in `tzif` around handling of split abbr (EX: IST/GMT) + let local_records = tzif_block_v2 + .local_time_type_records + .iter() + .map(|r| LocalRecord { + offset: r.utoff.0, + is_dst: r.is_dst, + abbr: tzif_block_v2 + .time_zone_designations + .get(r.idx / 4) + .cloned() + .unwrap_or(String::from("unknown")), + }) + .collect::>(); + + let transitions = tzif_block_v2 + .transition_times + .iter() + .zip(tzif_block_v2.transition_types) + .map(|(time, time_type)| TransitionRecord { + transition_time: time.0, + record: local_records[time_type].clone(), + }) + .collect::>(); + + let tzif_data = TzifTestData { + first_record, + transitions, + }; + + std::println!("Writing generated example data to {test_data_path:?}"); + fs::write( + test_data_path, + serde_json::to_string_pretty(&tzif_data).unwrap(), + ) + .unwrap(); +} + +const UNIX_ZONEINFO: &str = "/usr/share/zoneinfo/"; + +#[derive(clap::Parser)] +struct Args { + /// Output directory relative to `CARGO_MANIFEST_DIR` + #[arg(short, long)] + output_dir: Option, + + /// The zoneinfo / tzdata directory relative to `CARGO_MANIFEST_DIR` (defaults to UNIX zoneinfo) + #[arg(short = 'i', long)] + zoneinfo_dir: Option, + + identifier: String, +} + +fn main() { + let args = Args::parse(); + let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); + + // Create input directory + let zoneinfo_dir = if let Some(dir) = args.zoneinfo_dir { + manifest_dir.join(dir) + } else { + PathBuf::from(UNIX_ZONEINFO) + }; + // Create output directory + let out_dir = if let Some(dir) = args.output_dir { + manifest_dir.join(dir) + } else { + manifest_dir.into() + }; + + generate_test_data(zoneinfo_dir, out_dir, "Antarctica/Troll"); +} diff --git a/deps/temporal/zoneinfo/Cargo.toml b/deps/temporal/zoneinfo/Cargo.toml new file mode 100644 index 00000000000000..f69398319c07c9 --- /dev/null +++ b/deps/temporal/zoneinfo/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "zoneinfo_rs" +description = "Zoneinfo parser and compiler" +edition.workspace = true +version = "0.0.17" +rust-version.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +readme.workspace = true +exclude.workspace = true +include = [ + "src/**/*", + "Cargo.toml", + "LICENSE-Apache", + "LICENSE-MIT", + "README.md", +] + +[features] +std = [] + +[dependencies] +hashbrown = "0.16.0" +indexmap = "2.11.4" + +[dev-dependencies] +tzif = { workspace = true } +serde_json = "1.0.145" +serde = { version = "1.0.225", features = ["derive"] } diff --git a/deps/temporal/zoneinfo/README.md b/deps/temporal/zoneinfo/README.md new file mode 100644 index 00000000000000..f5ad045e99e06e --- /dev/null +++ b/deps/temporal/zoneinfo/README.md @@ -0,0 +1,28 @@ + +# Zoneinfo_rs + +**NOTE:** This crate is experimental and should be considered unstable. + +`zoneinfo_rs` provides basic parsing and compilation of IANA's time zone database +zoneinfo files. + +```rust +use std::path::Path; +use zoneinfo_rs::{ZoneInfoData, ZoneInfoCompiler}; +// Below assumes we are in the parent directory of `tzdata` +let zoneinfo_filepath = Path::new("./tzdata/"); +let parsed_data = ZoneInfoData::from_zoneinfo_directory(zoneinfo_filepath)?; +let _compiled_data = ZoneInfoCompiler::new(parsed_data).build(); +``` + +## Extra notes + +Currently, parsing only supports parsing of zoneinfo files and none of the preprocessing +typically completed by `awk` scripts in tzdata. + +It is recommended to still use the baseline awk script until preprocessing is supported. + +## IANA tzdb repository + +The latest version of the time zone database can be found [here](https://www.iana.org/time-zones) + diff --git a/deps/temporal/zoneinfo/src/compiler.rs b/deps/temporal/zoneinfo/src/compiler.rs new file mode 100644 index 00000000000000..48f079b2e9d6cb --- /dev/null +++ b/deps/temporal/zoneinfo/src/compiler.rs @@ -0,0 +1,189 @@ +//! Zone info compiler functionality +//! +//! This module contains the zone info compiler logic along +//! with output types. +//! + +use alloc::collections::BTreeSet; +use alloc::string::String; +use hashbrown::HashMap; + +#[derive(Debug, Clone, PartialEq)] +pub struct LocalTimeRecord { + pub offset: i64, + pub saving: Time, + pub letter: Option, + pub designation: String, // AKA format / abbr +} + +// TODO: improve `Transition` repr this type provides a lot of +// information by design, but the local time record data +// should be separated from the transition info with a clear +// separation. +// +// EX: +// pub struct Transition { +// /// The time to transition at +// pub at_time: i64, +// /// The transition time kind. +// pub time_type: QualifiedTimeKind, +// /// LocalTimeRecord transitioned into +// pub to_local: ZoneInfoLocalTimeRecord, +// } +// +/// The primary transition data. +#[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] +pub struct Transition { + /// The time to transition at + /// + /// This represents the time in Unix Epoch seconds + /// at which a transition should occur. + pub at_time: i64, + /// The transition time kind. + /// + /// Whether the transition was specified in Local, Standard, or Universal time. + pub time_type: QualifiedTimeKind, + + // TODO: Below are fields that should be split into a + // currently non-existent LocalTime record. + /// The offset of the transition. + pub offset: i64, + /// Whether the transition is a savings offset or not + /// + /// This flag corresponds to the `is_dst` flag + pub dst: bool, + /// The savings for the local time record + /// + /// This field represents the exact [`Time`] value + /// used for savings. + pub savings: Time, + /// The letter designation for the local time record + /// + /// The LETTER designation used in the fully formatted + /// abbreviation + pub letter: Option, + /// The abbreviation format for the local time record. + pub format: String, +} + +impl Ord for Transition { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + self.at_time.cmp(&other.at_time) + } +} + +impl PartialOrd for Transition { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +/// `CompiledTransitions` is the complete compiled transition data +/// for one zone. +/// +/// The compiled transition data contains an initial local time record, an ordered +/// set of transition data, and a POSIX time zone string. +/// +/// In general, this struct offers the required data in a consummable format +/// for anyone who compiled zoneinfo data. +#[non_exhaustive] +#[derive(Debug, PartialEq)] +pub struct CompiledTransitions { + /// The initial local time record. + /// + /// This is used in the case where a time predates a transition time. + pub initial_record: LocalTimeRecord, + + /// The full set of calculated time zone transitions + pub transitions: BTreeSet, + + /// The POSIX time zone string + /// + /// This string should be used to calculate the time zone beyond the last available transition. + pub posix_time_zone: PosixTimeZone, +} + +// NOTE: candidate for removal? Should this library offer TZif structs long term? +// +// I think I would prefer all of that live in the `tzif` crate, but that will +// be a process to update. So implement it here, and then upstream it? +impl CompiledTransitions { + pub fn to_v2_data_block(&self) -> TzifBlockV2 { + TzifBlockV2::from_transition_data(self) + } +} + +/// The `CompiledTransitionsMap` struct contains a mapping of zone identifiers (AKA IANA identifiers) to +/// the zone's `CompiledTransitions` +#[derive(Debug, Default)] +pub struct CompiledTransitionsMap { + pub data: HashMap, +} + +// ==== ZoneInfoCompiler build / compile methods ==== + +use crate::{ + posix::PosixTimeZone, + types::{QualifiedTimeKind, Time}, + tzif::TzifBlockV2, + zone::ZoneRecord, + ZoneInfoData, +}; + +/// The compiler for turning `ZoneInfoData` into `CompiledTransitionsData` +pub struct ZoneInfoCompiler { + data: ZoneInfoData, +} + +impl ZoneInfoCompiler { + /// Create a new `ZoneInfoCompiler` instance with provided `ZoneInfoData`. + pub fn new(data: ZoneInfoData) -> Self { + Self { data } + } + + /// Build transition data for a specific zone. + pub fn build_zone(&mut self, target: &str) -> CompiledTransitions { + if let Some(zone) = self.data.zones.get_mut(target) { + zone.associate_rules(&self.data.rules); + } + self.build_zone_internal(target) + } + + pub fn build(&mut self) -> CompiledTransitionsMap { + // Associate the necessary rules with the ZoneTable + self.associate(); + // TODO: Validate and resolve settings here. + let mut zoneinfo = CompiledTransitionsMap::default(); + for identifier in self.data.zones.keys() { + let transition_data = self.build_zone_internal(identifier); + let _ = zoneinfo.data.insert(identifier.clone(), transition_data); + } + zoneinfo + } + + /// The internal method for retrieving a zone table and compiling it. + pub(crate) fn build_zone_internal(&self, target: &str) -> CompiledTransitions { + let zone_table = self + .data + .zones + .get(target) + .expect("Invalid identifier provided."); + zone_table.compile() + } + + pub fn get_posix_time_zone(&mut self, target: &str) -> Option { + self.associate(); + self.data + .zones + .get(target) + .map(ZoneRecord::get_posix_time_zone) + } + + /// Associates the current `ZoneTables` with their applicable rules. + pub fn associate(&mut self) { + for zones in self.data.zones.values_mut() { + zones.associate_rules(&self.data.rules); + } + } +} diff --git a/deps/temporal/zoneinfo/src/lib.rs b/deps/temporal/zoneinfo/src/lib.rs new file mode 100644 index 00000000000000..57726bfb4abc06 --- /dev/null +++ b/deps/temporal/zoneinfo/src/lib.rs @@ -0,0 +1,153 @@ +//! A library for parsing and compiling zoneinfo files into +//! time zone transition data that can be used to build +//! TZif files or any other desired time zone format. +//! +//! `zoneinfo_rs` offers default parsing and compiling +//! of zoneinfo files into time zone transition data. +//! +//! Why `zoneinfo_rs`? +//! +//! In general, this library seeks to maximally expose as much +//! data from the zoneinfo files as possible while also supporting +//! extra time zone database features like the zone.tab, PACKRATLIST, +//! and POSIX time zone strings. +//! + +// TODO list: +// +// - Support PACKRATLIST +// - Support zone.tab +// - Support leap second +// - Support vanguard and rear guard parsing (potential backlog) +// - Provide easy defaults for SLIM and FAT compiling. +// - Support v1 TZif with conversion to i32. +// + +// Implementation note: this library is NOT designed to be the most +// optimal speed. Instead invariance and clarity is preferred where +// need be. +// +// We can get away with any performance penalty primarily because +// this library is designed to aid with build time libraries, on +// a limited dataset, NOT at runtime on extremely large datasets. + +#![no_std] + +extern crate alloc; + +use alloc::string::String; +use parser::ZoneInfoParseError; + +use hashbrown::HashMap; + +#[cfg(feature = "std")] +extern crate std; + +#[cfg(feature = "std")] +use std::{io, path::Path}; + +pub(crate) mod utils; + +pub mod compiler; +pub mod parser; +pub mod posix; +pub mod rule; +pub mod types; +pub mod tzif; +pub mod zone; + +#[doc(inline)] +pub use compiler::ZoneInfoCompiler; + +#[doc(inline)] +pub use parser::ZoneInfoParser; + +use rule::Rules; +use zone::ZoneRecord; + +/// Well-known zone info file +pub const ZONEINFO_FILES: [&str; 9] = [ + "africa", + "antarctica", + "asia", + "australasia", + "backward", + "etcetera", + "europe", + "northamerica", + "southamerica", +]; + +/// The general error type for `ZoneInfo` operations +#[derive(Debug)] +pub enum ZoneInfoError { + Parse(ZoneInfoParseError), + #[cfg(feature = "std")] + Io(io::Error), +} + +#[cfg(feature = "std")] +impl From for ZoneInfoError { + fn from(value: io::Error) -> Self { + Self::Io(value) + } +} + +/// `ZoneInfoData` represents raw unprocessed zone info data +/// as parsed from a zone info file. +/// +/// See [`ZoneInfoCompiler`] if transitions are required. +#[non_exhaustive] +#[derive(Debug, Clone, Default)] +pub struct ZoneInfoData { + /// Data parsed from zone info Rule lines keyed by Rule name + pub rules: HashMap, + /// Data parsed from zone info Zone records. + pub zones: HashMap, + /// Data parsed from Link lines + pub links: HashMap, + /// Data parsed from `#PACKRATLIST` lines + pub pack_rat: HashMap, +} + +// ==== ZoneInfoData parsing methods ==== + +impl ZoneInfoData { + /// Parse data from a path to a directory of zoneinfo files, using well known + /// zoneinfo file names. + /// + /// This is usually pointed to a "tzdata" directory. + #[cfg(feature = "std")] + pub fn from_zoneinfo_directory>(dir: P) -> Result { + let mut zoneinfo = Self::default(); + for filename in ZONEINFO_FILES { + let file_path = dir.as_ref().join(filename); + let parsed = Self::from_filepath(file_path)?; + zoneinfo.extend(parsed); + } + Ok(zoneinfo) + } + + /// Parse data from a filepath to a zoneinfo file. + #[cfg(feature = "std")] + pub fn from_filepath + core::fmt::Debug>( + path: P, + ) -> Result { + Self::from_zoneinfo_file(&std::fs::read_to_string(path)?) + } + + /// Parses data from a zoneinfo file as a string slice. + pub fn from_zoneinfo_file(src: &str) -> Result { + ZoneInfoParser::from_zoneinfo_str(src) + .parse() + .map_err(ZoneInfoError::Parse) + } + + /// Extend the current `ZoneInfoCompiler` data from another `ZoneInfoCompiler`. + pub fn extend(&mut self, other: Self) { + self.rules.extend(other.rules); + self.zones.extend(other.zones); + self.links.extend(other.links); + self.pack_rat.extend(other.pack_rat); + } +} diff --git a/deps/temporal/zoneinfo/src/parser.rs b/deps/temporal/zoneinfo/src/parser.rs new file mode 100644 index 00000000000000..efe7606b6e61f7 --- /dev/null +++ b/deps/temporal/zoneinfo/src/parser.rs @@ -0,0 +1,222 @@ +//! Zone info parsing implementation + +use core::{ + iter::Peekable, + num::ParseIntError, + str::{Lines, SplitWhitespace}, +}; + +use alloc::{borrow::ToOwned, string::String, vec, vec::Vec}; + +use crate::{ + rule::{Rule, Rules}, + zone::ZoneRecord, + ZoneInfoData, +}; + +/// The zoneinfo parsing error +#[derive(Debug)] +pub enum ZoneInfoParseError { + InvalidZoneHeader(u32), + MissingIdentifier(u32), + UnexpectedEndOfLine(u32, &'static str), + UnknownValue(u32, String), + ParseIntError(u32, ParseIntError, &'static str), +} + +impl ZoneInfoParseError { + pub(crate) fn unexpected_eol(ctx: &LineParseContext) -> Self { + Self::UnexpectedEndOfLine(ctx.line_number, ctx.span()) + } + + pub(crate) fn unknown(s: &str, ctx: &LineParseContext) -> Self { + Self::UnknownValue(ctx.line_number, s.to_owned()) + } +} + +/// A utility trait for implementing a `try_from_str` with a provided +/// context. +pub trait TryFromStr: Sized { + type Error; + fn try_from_str(s: &str, context: &mut C) -> Result; +} + +/// The context for the line parser +#[derive(Debug, Clone)] +pub struct LineParseContext { + pub line_number: u32, + pub spans: Vec<&'static str>, +} + +impl LineParseContext { + pub fn enter(&mut self, name: &'static str) { + self.spans.push(name); + } + + pub fn span(&self) -> &'static str { + self.spans.last().expect("span not defined") + } + + pub fn exit(&mut self) { + self.spans.pop(); + } +} + +impl Default for LineParseContext { + fn default() -> Self { + Self { + line_number: 1, + spans: vec!["undefined"], + } + } +} + +pub trait ContextParse { + fn context_parse>( + &self, + ctx: &mut LineParseContext, + ) -> Result>::Error>; +} + +impl ContextParse for &str { + fn context_parse>( + &self, + ctx: &mut LineParseContext, + ) -> Result>::Error> { + T::try_from_str(self, ctx) + } +} + +impl ContextParse for String { + fn context_parse>( + &self, + ctx: &mut LineParseContext, + ) -> Result>::Error> { + T::try_from_str(self, ctx) + } +} + +impl TryFromStr for String { + type Error = ZoneInfoParseError; + fn try_from_str(s: &str, _: &mut LineParseContext) -> Result { + Ok(s.to_owned()) + } +} + +impl TryFromStr for i8 { + type Error = ZoneInfoParseError; + fn try_from_str(s: &str, ctx: &mut LineParseContext) -> Result { + s.parse::() + .map_err(|e| ZoneInfoParseError::ParseIntError(ctx.line_number, e, ctx.span())) + } +} + +impl TryFromStr for u8 { + type Error = ZoneInfoParseError; + fn try_from_str(s: &str, ctx: &mut LineParseContext) -> Result { + s.parse::() + .map_err(|e| ZoneInfoParseError::ParseIntError(ctx.line_number, e, ctx.span())) + } +} + +impl TryFromStr for u16 { + type Error = ZoneInfoParseError; + fn try_from_str(s: &str, ctx: &mut LineParseContext) -> Result { + s.parse::() + .map_err(|e| ZoneInfoParseError::ParseIntError(ctx.line_number, e, ctx.span())) + } +} + +impl TryFromStr for i32 { + type Error = ZoneInfoParseError; + fn try_from_str(s: &str, ctx: &mut LineParseContext) -> Result { + s.parse::() + .map_err(|e| ZoneInfoParseError::ParseIntError(ctx.line_number, e, ctx.span())) + } +} + +pub(crate) fn next_split<'a>( + splits: &mut SplitWhitespace<'a>, + context: &LineParseContext, +) -> Result<&'a str, ZoneInfoParseError> { + splits.next().ok_or(ZoneInfoParseError::UnexpectedEndOfLine( + context.line_number, + context.span(), + )) +} + +pub(crate) fn remove_comments(line: &str) -> &str { + if let Some((cleaned, _comment)) = line.split_once("#") { + cleaned + } else { + line + } +} + +/// The primary parser for zoneinfo code points. +/// +/// This parser takes a single `&str` of data and parses the provided +/// `&str` into zoneinfo data. +/// +/// The parser uses the approach of a line parser, and evaluates the text +/// line by line. +#[non_exhaustive] +pub struct ZoneInfoParser<'data> { + lines: Peekable>, +} + +impl<'data> ZoneInfoParser<'data> { + /// Creates a parser from a `&str` + pub fn from_zoneinfo_str(source: &'data str) -> Self { + Self { + lines: source.lines().peekable(), + } + } + + /// Parse the provided lines + pub fn parse(&mut self) -> Result { + let mut zoneinfo = ZoneInfoData::default(); + let mut context = LineParseContext::default(); + + // The allow clippy is used in favor of for so that `ZoneTable` can + // iterate and parse it's own lines in `Zone::parse_full_table`. + #[allow(clippy::while_let_on_iterator)] + while let Some(line) = self.lines.peek() { + // Check if line is empty or a comment + if line.is_empty() || line.starts_with("#") { + // NOTE: This may be able to be consildated with link based off a flag. + if line.starts_with("#PACKRATLIST") { + let mut splits = line.split_whitespace(); + next_split(&mut splits, &context)?; // Consume the #PACKRATLIST + next_split(&mut splits, &context)?; // Consume the zone.tab + next_split(&mut splits, &context)?; // Consume the Link + let zone = next_split(&mut splits, &context)?; + let link = next_split(&mut splits, &context)?; + zoneinfo.pack_rat.insert(link.to_owned(), zone.to_owned()); + } + } else if line.starts_with("Rule") { + // TODO: Return a Rule Table and handle extending the table when needed. + let (identifier, data) = Rule::parse_from_line(line, &mut context).unwrap(); + if let Some(rules) = zoneinfo.rules.get_mut(&identifier) { + rules.extend(data); + } else { + zoneinfo.rules.insert(identifier, Rules::initialize(data)); + } + } else if line.starts_with("Zone") { + let (identifer, table) = + ZoneRecord::parse_full_table(&mut self.lines, &mut context).unwrap(); + zoneinfo.zones.insert(identifer, table); + continue; // Skip the next line call + } else if line.starts_with("Link") { + let mut splits = line.split_whitespace(); + next_split(&mut splits, &context)?; // Consume the Link + let zone = next_split(&mut splits, &context)?; + let link = next_split(&mut splits, &context)?; + zoneinfo.links.insert(link.to_owned(), zone.to_owned()); + } + self.lines.next(); + context.line_number += 1; + } + Ok(zoneinfo) + } +} diff --git a/deps/temporal/zoneinfo/src/posix.rs b/deps/temporal/zoneinfo/src/posix.rs new file mode 100644 index 00000000000000..ff1f7f467fb3ea --- /dev/null +++ b/deps/temporal/zoneinfo/src/posix.rs @@ -0,0 +1,228 @@ +use crate::{ + rule::{LastRules, Rule}, + types::{DayOfMonth, Month, QualifiedTime, Sign, Time, WeekDay}, + utils::month_to_day, + zone::ZoneEntry, +}; +use alloc::string::String; +use core::fmt::Write; + +/// The POSIX time zone designated by the [GNU documentation][gnu-docs] +/// +/// [gnu-docs]: https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html +#[derive(Debug, PartialEq)] +pub struct PosixTimeZone { + pub abbr: PosixAbbreviation, + pub offset: Time, + pub transition_info: Option, +} + +impl PosixTimeZone { + pub(crate) fn from_zone_and_savings(entry: &ZoneEntry, savings: Time) -> Self { + let offset = entry.std_offset.add(savings); + let formatted = entry + .format + .format(offset.as_secs(), None, savings != Time::default()); + let is_numeric = is_numeric(&formatted); + let abbr = PosixAbbreviation { + is_numeric, + formatted, + }; + Self { + abbr, + offset, + transition_info: None, + } + } + + pub(crate) fn from_zone_and_rules(entry: &ZoneEntry, rules: &LastRules) -> Self { + let offset = entry.std_offset.add(rules.standard.save); + let formatted = entry.format.format( + entry.std_offset.as_secs(), + rules.standard.letter.as_deref(), + rules.standard.is_dst(), + ); + let is_numeric = is_numeric(&formatted); + let abbr = PosixAbbreviation { + is_numeric, + formatted, + }; + + let transition_info = rules.saving.as_ref().map(|rule| { + let formatted = entry.format.format( + entry.std_offset.as_secs() + rule.save.as_secs(), + rule.letter.as_deref(), + rule.is_dst(), + ); + let abbr = PosixAbbreviation { + is_numeric, + formatted, + }; + let savings = rule.save; + let start = PosixDateTime::from_rule_and_transition_info( + rule, + entry.std_offset, + rules.standard.save, + ); + let end = PosixDateTime::from_rule_and_transition_info( + &rules.standard, + entry.std_offset, + rule.save, + ); + PosixTransition { + abbr, + savings, + start, + end, + } + }); + + PosixTimeZone { + abbr, + offset, + transition_info, + } + } +} + +impl PosixTimeZone { + pub fn to_string(&self) -> Result { + let mut posix_string = String::new(); + write_abbr(&self.abbr, &mut posix_string)?; + write_inverted_time(&self.offset, &mut posix_string)?; + + if let Some(transition_info) = &self.transition_info { + write_abbr(&transition_info.abbr, &mut posix_string)?; + if transition_info.savings != Time::one_hour() { + write_inverted_time(&self.offset.add(transition_info.savings), &mut posix_string)?; + } + write_date_time(&transition_info.start, &mut posix_string)?; + write_date_time(&transition_info.end, &mut posix_string)?; + } + Ok(posix_string) + } +} + +/// The representation of a POSIX time zone transition +#[non_exhaustive] +#[derive(Debug, PartialEq)] +pub struct PosixTransition { + /// The transitions designated abbreviation + pub abbr: PosixAbbreviation, + /// The savings value to be added to the offset + pub savings: Time, + /// The start time for the transition + pub start: PosixDateTime, + /// The end time for the transition + pub end: PosixDateTime, +} + +#[non_exhaustive] +#[derive(Debug, PartialEq, Clone)] +pub struct PosixAbbreviation { + /// Flag whether formatted abbreviation is numeric + pub is_numeric: bool, + /// The formatted abbreviation + pub formatted: String, +} +#[derive(Debug, PartialEq, Clone, Copy)] +pub struct MonthWeekDay(pub Month, pub u8, pub WeekDay); + +#[derive(Debug, PartialEq, Clone, Copy)] +pub enum PosixDate { + JulianNoLeap(u16), + JulianLeap(u16), + MonthWeekDay(MonthWeekDay), +} + +impl PosixDate { + pub(crate) fn from_rule(rule: &Rule) -> Self { + match rule.on_date { + DayOfMonth::Day(day) if rule.in_month == Month::Jan || rule.in_month == Month::Feb => { + PosixDate::JulianNoLeap(month_to_day(rule.in_month as u8, 1) as u16 + day as u16) + } + DayOfMonth::Day(day) => { + PosixDate::JulianLeap(month_to_day(rule.in_month as u8, 1) as u16 + day as u16) + } + DayOfMonth::Last(wd) => PosixDate::MonthWeekDay(MonthWeekDay(rule.in_month, 5, wd)), + DayOfMonth::WeekDayGEThanMonthDay(week_day, day_of_month) => { + let week = 1 + (day_of_month - 1) / 7; + PosixDate::MonthWeekDay(MonthWeekDay(rule.in_month, week, week_day)) + } + DayOfMonth::WeekDayLEThanMonthDay(week_day, day_of_month) => { + let week = day_of_month / 7; + PosixDate::MonthWeekDay(MonthWeekDay(rule.in_month, week, week_day)) + } + } + } +} + +#[derive(Debug, PartialEq, Clone, Copy)] +pub struct PosixDateTime { + pub date: PosixDate, + pub time: Time, +} + +impl PosixDateTime { + pub(crate) fn from_rule_and_transition_info(rule: &Rule, offset: Time, savings: Time) -> Self { + let date = PosixDate::from_rule(rule); + let time = match rule.at { + QualifiedTime::Local(time) => time, + QualifiedTime::Standard(standard_time) => standard_time.add(rule.save), + QualifiedTime::Universal(universal_time) => universal_time.add(offset).add(savings), + }; + Self { date, time } + } +} + +// ==== Helper functions ==== + +fn is_numeric(str: &str) -> bool { + str.parse::().is_ok() +} + +fn write_abbr(posix_abbr: &PosixAbbreviation, output: &mut String) -> core::fmt::Result { + if posix_abbr.is_numeric { + write!(output, "<")?; + write!(output, "{}", posix_abbr.formatted)?; + write!(output, ">")?; + return Ok(()); + } + write!(output, "{}", posix_abbr.formatted) +} + +fn write_inverted_time(time: &Time, output: &mut String) -> core::fmt::Result { + // Yep, it's inverted + if time.sign == Sign::Positive && time.hour != 0 { + write!(output, "-")?; + } + write_time(time, output) +} + +fn write_time(time: &Time, output: &mut String) -> core::fmt::Result { + write!(output, "{}", time.hour)?; + if time.minute == 0 && time.second == 0 { + return Ok(()); + } + write!(output, ":{}", time.minute)?; + if time.second > 0 { + write!(output, ":{}", time.second)?; + } + Ok(()) +} + +fn write_date_time(datetime: &PosixDateTime, output: &mut String) -> core::fmt::Result { + write!(output, ",")?; + match datetime.date { + PosixDate::JulianLeap(d) => write!(output, "{d}")?, + PosixDate::JulianNoLeap(d) => write!(output, "J{d}")?, + PosixDate::MonthWeekDay(MonthWeekDay(month, week, day)) => { + write!(output, "M{}.{week}.{}", month as u8, day as u8)? + } + } + if datetime.time != Time::two_hour() { + write!(output, "/")?; + write_time(&datetime.time, output)?; + } + Ok(()) +} diff --git a/deps/temporal/zoneinfo/src/rule.rs b/deps/temporal/zoneinfo/src/rule.rs new file mode 100644 index 00000000000000..1a598fb526fba2 --- /dev/null +++ b/deps/temporal/zoneinfo/src/rule.rs @@ -0,0 +1,393 @@ +//! Zone info Rule functionality +//! +//! This module implements the core zoneinfo [`Rule`]. + +use core::ops::RangeInclusive; + +use alloc::{borrow::ToOwned, string::String, vec, vec::Vec}; + +use crate::{ + parser::{next_split, ContextParse, LineParseContext, ZoneInfoParseError}, + types::{DayOfMonth, Month, QualifiedTime, Time, ToYear}, + utils::{self, epoch_seconds_for_epoch_days}, +}; + +#[derive(Debug)] +pub struct LastRules { + pub standard: Rule, + pub saving: Option, +} + +/// The `Rule` is a collection of zone info rules under the same +/// rule name. +/// +/// These rule collections can be seen throughout zoneinfo files. +/// +/// # Example +/// +/// The `Chicago` rules can be seen below. +/// +/// ```txt +/// # Rule NAME FROM TO - IN ON AT SAVE LETTER +/// Rule Chicago 1920 only - Jun 13 2:00 1:00 D +/// Rule Chicago 1920 1921 - Oct lastSun 2:00 0 S +/// Rule Chicago 1921 only - Mar lastSun 2:00 1:00 D +/// Rule Chicago 1922 1966 - Apr lastSun 2:00 1:00 D +/// Rule Chicago 1922 1954 - Sep lastSun 2:00 0 S +/// Rule Chicago 1955 1966 - Oct lastSun 2:00 0 S +/// ``` +/// +/// Interestingly, Rules appear to be sorted in chronological +/// order from their start date (FROM). However, their end dates may differ +/// meaning at any one time there can be rule pairs of: [std, dst], +/// [dst, std], [std, empty], or [dst, empty] +/// +#[derive(Debug, Clone)] +pub struct Rules { + rules: Vec, +} + +impl Rules { + pub fn initialize(rule: Rule) -> Self { + Self { rules: vec![rule] } + } + + pub fn extend(&mut self, rule: Rule) { + self.rules.push(rule); + } + + pub(crate) fn rules_for_year(&self, year: i32) -> Vec { + self.rules + .iter() + .filter(|rule| rule.range().contains(&year)) + .cloned() + .collect() + } + + pub(crate) fn find_initial_transition_letter(&self) -> Option { + let first_rule = self + .rules + .iter() + .find(|rule| rule.save == Time::default()) + .expect("A rule must exist with a SAVE = 0"); + first_rule.letter.clone() + } + + pub(crate) fn search_last_active_rule(&self, transition_point: i64) -> Option<&Rule> { + // Reasonable assumption: when searching for a last Rule, + // we are dealing with an orphan. This means we do not need to check years + // with an upper bound or inside them + let mut rule_savings = (i64::MIN, None); + for rule in &self.rules { + let year = rule.to.map(ToYear::to_i32).unwrap_or(i32::from(rule.from)); + let epoch_days = epoch_days_for_rule_date(year, rule.in_month, rule.on_date); + let rule_date_in_seconds = epoch_seconds_for_epoch_days(epoch_days); + // But we do want to keep track of the savings. + if rule_date_in_seconds < transition_point && rule_savings.0 < rule_date_in_seconds { + rule_savings = (rule_date_in_seconds, Some(rule)) + } else if transition_point < rule_date_in_seconds { + break; + } + } + + rule_savings.1 + } + + pub(crate) fn get_last_rules(&self) -> LastRules { + let mut final_epoch_days = i32::MIN; + let mut final_rule = None; + let mut std_max = None; + let mut savings_max = None; + + for rule in &self.rules { + let calc_to_year = rule + .to + .map(|y| { + if let ToYear::Year(y) = y { + Some(y) + } else { + None + } + }) + .unwrap_or(Some(rule.from)); + if let Some(year) = calc_to_year { + let epoch_days = epoch_days_for_rule_date(year as i32, rule.in_month, rule.on_date); + if final_epoch_days < epoch_days { + final_epoch_days = epoch_days; + final_rule = Some(rule.clone()); + } + } + + if rule.to == Some(ToYear::Max) { + if rule.is_dst() { + savings_max = Some(rule.clone()) + } else { + std_max = Some(rule.clone()) + } + } + } + + let standard = if let Some(max_rule) = std_max { + max_rule + } else { + final_rule.expect("must be set") + }; + + LastRules { + standard, + saving: savings_max, + } + } +} + +/// A zone info rule. +#[derive(Debug, Clone, PartialEq)] +pub struct Rule { + pub from: u16, + pub to: Option, + pub in_month: Month, + pub on_date: DayOfMonth, + pub at: QualifiedTime, + pub save: Time, + pub letter: Option, +} + +impl Rule { + fn range(&self) -> RangeInclusive { + i32::from(self.from)..=self.to.map(ToYear::to_i32).unwrap_or(self.from as i32) + } + + pub(crate) fn is_dst(&self) -> bool { + self.save != Time::default() + } + + /// Returns the transition time for that year + pub(crate) fn transition_time_for_year( + &self, + year: i32, + std_offset: &Time, + saving: &Time, + ) -> i64 { + let epoch_days = epoch_days_for_rule_date(year, self.in_month, self.on_date); + let epoch_seconds = epoch_seconds_for_epoch_days(epoch_days); + epoch_seconds + + self + .at + .to_universal_seconds(std_offset.as_secs(), saving.as_secs()) + } +} + +/// epoch_days_for_rule_date calculates the epoch days given values provided for a specific `Rule` +pub(crate) fn epoch_days_for_rule_date(year: i32, month: Month, day_of_month: DayOfMonth) -> i32 { + let day_of_year_for_month = month.month_start_to_day_of_year(year); + let epoch_days_for_year = utils::epoch_days_for_year(year); + let epoch_days = epoch_days_for_year + day_of_year_for_month; + let day_of_month = match day_of_month { + DayOfMonth::Last(weekday) => { + let mut day_of_month = month.month_end_to_day_of_year(year) - day_of_year_for_month; + loop { + let target_days = epoch_days + day_of_month; + let target_week_day = utils::epoch_days_to_week_day(target_days); + if target_week_day == weekday as u8 { + break; + } + day_of_month -= 1; + } + day_of_month + } + DayOfMonth::WeekDayGEThanMonthDay(week_day, d) => { + let mut day_of_month = d as i32 - 1; + loop { + let target_days = epoch_days + day_of_month; + let target_week_day = utils::epoch_days_to_week_day(target_days); + if week_day as u8 == target_week_day { + break day_of_month; + } + day_of_month += 1; + } + } + DayOfMonth::WeekDayLEThanMonthDay(week_day, d) => { + let mut day_of_month = d as i32 - 1; + loop { + let target_days = epoch_days + day_of_month; + let target_week_day = utils::epoch_days_to_week_day(target_days); + if week_day as u8 == target_week_day { + break day_of_month; + } + day_of_month -= 1; + } + } + DayOfMonth::Day(day) => day as i32 - 1, + }; + epoch_days + day_of_month +} + +impl Rule { + /// Parse a `Rule` from a line + /// + /// A rule line is made up of the following columns: + /// + /// # Rule NAME FROM TO - IN ON AT SAVE LETTER + /// + /// The "-" is a reserved field that represents the deprecated TYPE + /// field. It is preserved for backward compatibility reasons. + pub fn parse_from_line( + line: &str, + context: &mut LineParseContext, + ) -> Result<(String, Self), ZoneInfoParseError> { + context.enter("Rule"); + let mut splits = line.split_whitespace(); + let first = splits.next(); // Consume "Rule" + debug_assert!(first == Some("Rule")); + // AKA the NAME field + let identifier = next_split(&mut splits, context)?.to_owned(); + let from = next_split(&mut splits, context)?.context_parse::(context)?; + let to = ToYear::parse_optional_to_year(next_split(&mut splits, context)?, context)?; + next_split(&mut splits, context)?; // Skip the deprecated TYPE field + let in_month = next_split(&mut splits, context)?.context_parse::(context)?; + let on_date = next_split(&mut splits, context)?.context_parse::(context)?; + let at = next_split(&mut splits, context)?.context_parse::(context)?; + let save = next_split(&mut splits, context)?.context_parse::