From 33d1fb9bc169b55a5563e34b9fd60f1deeee2f40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Garc=C3=ADa?= Date: Wed, 20 Dec 2023 14:29:56 +0100 Subject: [PATCH 01/50] Add German codelist translations for scope code (#7566) --- .../src/main/plugin/iso19139/loc/ger/codelists.xml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/schemas/iso19139/src/main/plugin/iso19139/loc/ger/codelists.xml b/schemas/iso19139/src/main/plugin/iso19139/loc/ger/codelists.xml index a715df4a283..fdf6efea660 100644 --- a/schemas/iso19139/src/main/plugin/iso19139/loc/ger/codelists.xml +++ b/schemas/iso19139/src/main/plugin/iso19139/loc/ger/codelists.xml @@ -1578,26 +1578,25 @@ Publication --> - map - + staticMap - + interactiveMap - + featureCatalog - + From 1f16287e654bc24b6b19b6f3bcd98ef593229676 Mon Sep 17 00:00:00 2001 From: Joachim Nielandt Date: Wed, 20 Dec 2023 15:59:07 +0100 Subject: [PATCH 02/50] fix for empty language leading to spurious comma --- .../catalog/components/catalog/CatalogService.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/web-ui/src/main/resources/catalog/components/catalog/CatalogService.js b/web-ui/src/main/resources/catalog/components/catalog/CatalogService.js index 9dd692aaf65..dc9ec9f7779 100644 --- a/web-ui/src/main/resources/catalog/components/catalog/CatalogService.js +++ b/web-ui/src/main/resources/catalog/components/catalog/CatalogService.js @@ -766,7 +766,13 @@ if (!this.mainLanguage) { return []; } - return [this.mainLanguage].concat(this.otherLanguage).unique(); + return [this.mainLanguage] + .concat(this.otherLanguage) + .unique() + .filter(function (l) { + // do not allow null values + return !!l; + }); }, isPublished: function (pubOption) { if (pubOption) { From 68cb69aaac8f394818323fb1144e2a7baf4e75f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Garc=C3=ADa?= Date: Fri, 22 Dec 2023 15:05:35 +0100 Subject: [PATCH 03/50] Overview not shown in PDF export when the overview image is stored in GeoNetwork and requires authentication to access it. Fixes #7540 (#7556) --- .../ImageReplacedElementFactory.java | 85 +++++++++++++++---- 1 file changed, 70 insertions(+), 15 deletions(-) diff --git a/services/src/main/java/org/fao/geonet/api/records/formatters/ImageReplacedElementFactory.java b/services/src/main/java/org/fao/geonet/api/records/formatters/ImageReplacedElementFactory.java index b078c626117..d16513f6c92 100644 --- a/services/src/main/java/org/fao/geonet/api/records/formatters/ImageReplacedElementFactory.java +++ b/services/src/main/java/org/fao/geonet/api/records/formatters/ImageReplacedElementFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2016 Food and Agriculture Organization of the + * Copyright (C) 2001-2023 Food and Agriculture Organization of the * United Nations (FAO-UN), United Nations World Food Programme (WFP) * and United Nations Environment Programme (UNEP) * @@ -28,11 +28,14 @@ import com.lowagie.text.Image; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; +import org.fao.geonet.ApplicationContextHolder; import org.fao.geonet.api.ApiUtils; +import org.fao.geonet.api.records.attachments.Store; import org.fao.geonet.api.records.extent.MapRenderer; import org.fao.geonet.api.records.extent.MetadataExtentApi; import org.fao.geonet.constants.Geonet; import org.fao.geonet.constants.Params; +import org.fao.geonet.domain.MetadataResourceVisibility; import org.fao.geonet.utils.Log; import org.xhtmlrenderer.extend.FSImage; import org.xhtmlrenderer.extend.ReplacedElement; @@ -82,10 +85,11 @@ private static Set getSupportedExts() { if (imgFormatExts == null) { synchronized (ImageReplacedElementFactory.class) { if (imgFormatExts == null) { - imgFormatExts = Sets.newHashSet(); + Set tmpImgFormatExts = Sets.newHashSet(); for (String ext : ImageIO.getReaderFileSuffixes()) { - imgFormatExts.add(ext.toLowerCase()); + tmpImgFormatExts.add(ext.toLowerCase()); } + imgFormatExts = tmpImgFormatExts; } } } @@ -93,9 +97,11 @@ private static Set getSupportedExts() { return imgFormatExts; } - static private Pattern ONE_EXTENT_API_REGEX = Pattern.compile(".*/(.*)/extents/([0-9]+)\\.png.*"); - static private Pattern ALL_EXTENT_API_REGEX = Pattern.compile(".*/(.*)/extents\\.png.*"); - static private final String EXTENT_XPATH = ".//*[local-name() ='extent']/*/*[local-name() = 'geographicElement']/*"; + private static final Pattern ONE_EXTENT_API_REGEX = Pattern.compile(".*/(.*)/extents/(\\d+)\\.png.*"); + private static final Pattern ALL_EXTENT_API_REGEX = Pattern.compile(".*/(.*)/extents\\.png.*"); + private static final String EXTENT_XPATH = ".//*[local-name() ='extent']/*/*[local-name() = 'geographicElement']/*"; + + private static final String DEFAULT_SRS = "EPSG:4326"; @Override public ReplacedElement createReplacedElement(LayoutContext layoutContext, BlockBox box, @@ -109,15 +115,15 @@ public ReplacedElement createReplacedElement(LayoutContext layoutContext, BlockB if (!"img".equals(nodeName)) { try { return superFactory.createReplacedElement(layoutContext, box, userAgentCallback, cssWidth, cssHeight); - } catch (Throwable e) { + } catch (Exception e) { return new EmptyReplacedElement(cssWidth, cssHeight); } } - String src = element.getAttribute("src"); + String baseUrlNoLang = baseURL.substring(0, baseURL.length() - 4); - boolean useExtentApi = src.startsWith(baseURL.substring(0, baseURL.length() - 4)) + boolean useExtentApi = src.startsWith(baseUrlNoLang) && mapRenderer != null && (ALL_EXTENT_API_REGEX.matcher(src).matches() || ONE_EXTENT_API_REGEX.matcher(src).matches()); @@ -135,7 +141,7 @@ public ReplacedElement createReplacedElement(LayoutContext layoutContext, BlockB regionId = String.format("metadata:@id%s:@xpath(%s)[%s]", ApiUtils.getInternalId(oneMatcher.group(1), true), EXTENT_XPATH, oneMatcher.group(2)); } Map parameters = getParams(src); - String srs = parameters.get(MetadataExtentApi.MAP_SRS_PARAM) != null ? parameters.get(MetadataExtentApi.MAP_SRS_PARAM) : "EPSG:4326"; + String srs = parameters.get(MetadataExtentApi.MAP_SRS_PARAM) != null ? parameters.get(MetadataExtentApi.MAP_SRS_PARAM) : DEFAULT_SRS; Integer width = parameters.get(MetadataExtentApi.WIDTH_PARAM) != null ? Integer.parseInt(parameters.get(MetadataExtentApi.WIDTH_PARAM)) : null; Integer height = parameters.get(MetadataExtentApi.HEIGHT_PARAM) != null ? Integer.parseInt(parameters.get(MetadataExtentApi.HEIGHT_PARAM)) : null; String background = parameters.get(MetadataExtentApi.BACKGROUND_PARAM); @@ -145,20 +151,25 @@ public ReplacedElement createReplacedElement(LayoutContext layoutContext, BlockB } float factor = layoutContext.getDotsPerPixel(); return loadImage(layoutContext, box, userAgentCallback, cssWidth, cssHeight, new BufferedImageLoader(image), factor); - } else if (src.startsWith(baseURL + "region.getmap.png") | src.endsWith("/geom.png") && mapRenderer != null) { + } else if (src.startsWith(baseURL + "region.getmap.png") || src.endsWith("/geom.png") && mapRenderer != null) { BufferedImage image = null; try { Map parameters = getParams(src); String id = parameters.get(Params.ID); - String srs = parameters.get(MetadataExtentApi.MAP_SRS_PARAM) != null ? parameters.get(MetadataExtentApi.MAP_SRS_PARAM) : "EPSG:4326"; + String srs = parameters.get(MetadataExtentApi.MAP_SRS_PARAM) != null ? parameters.get(MetadataExtentApi.MAP_SRS_PARAM) : DEFAULT_SRS; Integer width = parameters.get(MetadataExtentApi.WIDTH_PARAM) != null ? Integer.parseInt(parameters.get(MetadataExtentApi.WIDTH_PARAM)) : null; Integer height = parameters.get(MetadataExtentApi.HEIGHT_PARAM) != null ? Integer.parseInt(parameters.get(MetadataExtentApi.HEIGHT_PARAM)) : null; String background = parameters.get(MetadataExtentApi.BACKGROUND_PARAM); String geomParam = parameters.get(MetadataExtentApi.GEOM_PARAM); String geomType = parameters.get(MetadataExtentApi.GEOM_TYPE_PARAM) != null ? parameters.get(MetadataExtentApi.GEOM_TYPE_PARAM) : "WKT"; - String geomSrs = parameters.get(MetadataExtentApi.GEOM_SRS_PARAM) != null ? parameters.get(MetadataExtentApi.GEOM_SRS_PARAM) : "EPSG:4326"; + String geomSrs = parameters.get(MetadataExtentApi.GEOM_SRS_PARAM) != null ? parameters.get(MetadataExtentApi.GEOM_SRS_PARAM) : DEFAULT_SRS; + if ((width == null) && (height == null)) { + // Width or height are required. If not set the default width with the same value + // as defined in MetadataExtentApi.getOneRecordExtentAsImage + width = 300; + } image = mapRenderer.render( id, srs, width, height, background, geomParam, geomType, geomSrs, null, null); } catch (Exception e) { @@ -189,6 +200,21 @@ public ReplacedElement createReplacedElement(LayoutContext layoutContext, BlockB } float factor = layoutContext.getDotsPerPixel(); return loadImage(layoutContext, box, userAgentCallback, cssWidth, cssHeight, new UrlImageLoader(builder.toString()), factor); + + } else if (src.startsWith(baseUrlNoLang) && src.contains("/attachments/")) { + // Process attachments urls to load the images from the data directory + Matcher m = Pattern.compile(baseUrlNoLang + "api/records/(.*)/attachments/(.*)$").matcher(src); + if (m.find()) { + String uuid = m.group(1); + String file = m.group(2); + + float factor = layoutContext.getDotsPerPixel(); + return loadImage(layoutContext, box, userAgentCallback, cssWidth, cssHeight, new DataDirectoryImageLoader(uuid, file), factor); + } else if (isSupportedImageFormat(src)) { + float factor = layoutContext.getDotsPerPixel(); + return loadImage(layoutContext, box, userAgentCallback, cssWidth, cssHeight, new UrlImageLoader(src), factor); + } + } else if (isSupportedImageFormat(src)) { float factor = layoutContext.getDotsPerPixel(); return loadImage(layoutContext, box, userAgentCallback, cssWidth, cssHeight, new UrlImageLoader(src), factor); @@ -196,7 +222,7 @@ public ReplacedElement createReplacedElement(LayoutContext layoutContext, BlockB try { return superFactory.createReplacedElement(layoutContext, box, userAgentCallback, cssWidth, cssHeight); - } catch (Throwable e) { + } catch (Exception e) { return new EmptyReplacedElement(cssWidth, cssHeight); } } @@ -247,7 +273,7 @@ private ReplacedElement loadImage(LayoutContext layoutContext, BlockBox box, Use try { return superFactory.createReplacedElement(layoutContext, box, userAgentCallback, cssWidth, cssHeight); - } catch (Throwable e2) { + } catch (Exception e2) { return new EmptyReplacedElement(cssWidth, cssHeight); } } @@ -296,6 +322,35 @@ public Image loadImage() throws Exception { } } + + /** + * Class to load images from the metadata data directory. + */ + private class DataDirectoryImageLoader implements ImageLoader { + private final String uuid; + private final String file; + public DataDirectoryImageLoader(String uuid, String file) { + this.uuid = uuid; + this.file = file; + } + + @Override + public Image loadImage() throws Exception { + Store store = ApplicationContextHolder.get().getBean("filesystemStore", Store.class); + BufferedImage bufferedImage; + try (Store.ResourceHolder imageFile = store.getResourceInternal( + this.uuid, + MetadataResourceVisibility.PUBLIC, + this.file, true)) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + bufferedImage = ImageIO.read(imageFile.getPath().toFile()); + ImageIO.write(bufferedImage, "png", baos); + return Image.getInstance(baos.toByteArray()); + } + } + } + + /* Define an AWT BufferedImage image loader */ private class BufferedImageLoader implements ImageLoader { From a54f3d5bb06dc28d61a423c8161335cc1815b52d Mon Sep 17 00:00:00 2001 From: Ian Allen Date: Sun, 31 Dec 2023 08:47:07 -0400 Subject: [PATCH 04/50] Fix case of wrong use for HttpStatus.CREATED and HttpStatus.OK In some cases HttpStatus.CREATED was used when it should have been HttpStatus.OK and other cases it is the opposite. --- services/src/main/java/org/fao/geonet/api/groups/GroupsApi.java | 2 +- .../src/main/java/org/fao/geonet/api/records/MetadataApi.java | 2 +- .../java/org/fao/geonet/api/usersearches/UserSearchesApi.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/services/src/main/java/org/fao/geonet/api/groups/GroupsApi.java b/services/src/main/java/org/fao/geonet/api/groups/GroupsApi.java index 138208a134f..04f2837e1ff 100644 --- a/services/src/main/java/org/fao/geonet/api/groups/GroupsApi.java +++ b/services/src/main/java/org/fao/geonet/api/groups/GroupsApi.java @@ -296,7 +296,7 @@ public List getGroups( produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.PUT ) - @ResponseStatus(value = HttpStatus.OK) + @ResponseStatus(value = HttpStatus.CREATED) @PreAuthorize("hasAuthority('UserAdmin')") @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "Group created."), diff --git a/services/src/main/java/org/fao/geonet/api/records/MetadataApi.java b/services/src/main/java/org/fao/geonet/api/records/MetadataApi.java index 2323f1439ab..8314f12b576 100644 --- a/services/src/main/java/org/fao/geonet/api/records/MetadataApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/MetadataApi.java @@ -521,7 +521,7 @@ private List getUuidsOfAssociatedRecords(IListOnlyClassToArray associate @ApiResponse(responseCode = "403", description = ApiParams.API_RESPONSE_NOT_ALLOWED_CAN_VIEW), @ApiResponse(responseCode = "404", description = ApiParams.API_RESPONSE_RESOURCE_NOT_FOUND) }) - @ResponseStatus(HttpStatus.CREATED) + @ResponseStatus(HttpStatus.OK) public ResponseEntity getRecordPopularity( @Parameter(description = API_PARAM_RECORD_UUID, required = true) diff --git a/services/src/main/java/org/fao/geonet/api/usersearches/UserSearchesApi.java b/services/src/main/java/org/fao/geonet/api/usersearches/UserSearchesApi.java index 8a59adf9cb7..517744f9ce7 100644 --- a/services/src/main/java/org/fao/geonet/api/usersearches/UserSearchesApi.java +++ b/services/src/main/java/org/fao/geonet/api/usersearches/UserSearchesApi.java @@ -290,7 +290,7 @@ public UserSearchDto getUserCustomSearch( @RequestMapping( produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.PUT) - @ResponseStatus(value = HttpStatus.OK) + @ResponseStatus(value = HttpStatus.CREATED) @PreAuthorize("isAuthenticated()") @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "User search created.") From 0223ed2c64567775323b326d32ed7d4d676bf512 Mon Sep 17 00:00:00 2001 From: Ian Allen Date: Thu, 21 Dec 2023 10:43:43 -0400 Subject: [PATCH 05/50] Fix duplicate spring doc tags. Ensure that all tags have the same description. --- services/src/main/java/org/fao/geonet/api/ApiParams.java | 4 ++++ .../src/main/java/org/fao/geonet/api/records/DoiApi.java | 4 +++- .../org/fao/geonet/api/records/InspireValidationApi.java | 4 +++- .../api/records/attachments/AttachmentsActionsApi.java | 6 ++++-- .../fao/geonet/api/records/attachments/AttachmentsApi.java | 6 +++++- .../org/fao/geonet/api/records/formatters/CacheApi.java | 7 +++++-- .../geonet/api/records/formatters/FormatterAdminApi.java | 6 ++++-- services/src/main/java/org/fao/geonet/api/sld/SldApi.java | 7 +++++-- .../java/org/fao/geonet/api/tools/i18n/TranslationApi.java | 5 ++++- .../main/java/org/fao/geonet/api/tools/mail/MailApi.java | 7 +++++-- .../org/fao/geonet/api/tools/migration/MigrationApi.java | 6 +++++- 11 files changed, 47 insertions(+), 15 deletions(-) diff --git a/services/src/main/java/org/fao/geonet/api/ApiParams.java b/services/src/main/java/org/fao/geonet/api/ApiParams.java index d3c5825c26c..55720ac7579 100644 --- a/services/src/main/java/org/fao/geonet/api/ApiParams.java +++ b/services/src/main/java/org/fao/geonet/api/ApiParams.java @@ -33,6 +33,10 @@ public class ApiParams { public static final String API_CLASS_CATALOG_TAG = "site"; public static final String API_CLASS_REGISTRIES_OPS = "Registries related operations"; public static final String API_CLASS_REGISTRIES_TAG = "registries"; + public static final String API_CLASS_TOOLS_TAG = "tools"; + public static final String API_CLASS_TOOLS_OPS = "Utility operations"; + public static final String API_CLASS_FORMATTERS_TAG = "formatters"; + public static final String API_CLASS_FORMATTERS_OPS = "Formatter operations"; public static final String API_PARAM_RECORD_UUID = "Record UUID."; diff --git a/services/src/main/java/org/fao/geonet/api/records/DoiApi.java b/services/src/main/java/org/fao/geonet/api/records/DoiApi.java index 69fa10aa7ad..ce59aa1d8e4 100644 --- a/services/src/main/java/org/fao/geonet/api/records/DoiApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/DoiApi.java @@ -48,6 +48,7 @@ import javax.servlet.http.HttpSession; import java.util.Map; +import static org.fao.geonet.api.ApiParams.API_CLASS_RECORD_OPS; import static org.fao.geonet.api.ApiParams.API_CLASS_RECORD_TAG; import static org.fao.geonet.api.ApiParams.API_PARAM_RECORD_UUID; @@ -57,7 +58,8 @@ @RequestMapping(value = { "/{portal}/api/records" }) -@Tag(name = API_CLASS_RECORD_TAG) +@Tag(name = API_CLASS_RECORD_TAG, + description = API_CLASS_RECORD_OPS) @Controller("doi") @PreAuthorize("hasAuthority('Editor')") @ReadWriteController diff --git a/services/src/main/java/org/fao/geonet/api/records/InspireValidationApi.java b/services/src/main/java/org/fao/geonet/api/records/InspireValidationApi.java index 9e3a015780a..86fda4b1f6c 100644 --- a/services/src/main/java/org/fao/geonet/api/records/InspireValidationApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/InspireValidationApi.java @@ -82,6 +82,7 @@ import java.util.HashMap; import java.util.Map; +import static org.fao.geonet.api.ApiParams.API_CLASS_RECORD_OPS; import static org.fao.geonet.api.ApiParams.API_CLASS_RECORD_TAG; import static org.fao.geonet.api.ApiParams.API_PARAM_RECORD_UUID; @@ -89,7 +90,8 @@ @RequestMapping(value = { "/{portal}/api/records" }) -@Tag(name = API_CLASS_RECORD_TAG) +@Tag(name = API_CLASS_RECORD_TAG, + description = API_CLASS_RECORD_OPS) @Controller("inspire") @PreAuthorize("hasAuthority('Editor')") @ReadWriteController diff --git a/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsActionsApi.java b/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsActionsApi.java index 3c2bef091c9..f57016bd462 100644 --- a/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsActionsApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsActionsApi.java @@ -50,13 +50,15 @@ import javax.servlet.http.HttpServletRequest; import java.nio.file.Path; +import static org.fao.geonet.api.ApiParams.API_CLASS_RECORD_OPS; +import static org.fao.geonet.api.ApiParams.API_CLASS_RECORD_TAG; import static org.fao.geonet.api.ApiParams.API_PARAM_RECORD_UUID; @EnableWebMvc @Controller @Service -@Tag(name = "records", - description = "Metadata record operations") +@Tag(name = API_CLASS_RECORD_TAG, + description = API_CLASS_RECORD_OPS) public class AttachmentsActionsApi { private final ApplicationContext appContext = ApplicationContextHolder.get(); @Autowired diff --git a/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsApi.java b/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsApi.java index 01830efc5f6..9f04ba5ef5d 100644 --- a/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsApi.java @@ -25,6 +25,9 @@ package org.fao.geonet.api.records.attachments; +import static org.fao.geonet.api.ApiParams.API_CLASS_RECORD_OPS; +import static org.fao.geonet.api.ApiParams.API_CLASS_RECORD_TAG; + import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; @@ -80,7 +83,8 @@ @EnableWebMvc @Service @RequestMapping(value = {"/{portal}/api/records/{metadataUuid}/attachments"}) -@Tag(name = "records", description = "Metadata record operations") +@Tag(name = API_CLASS_RECORD_TAG, + description = API_CLASS_RECORD_OPS) public class AttachmentsApi { public static final Integer MIN_IMAGE_SIZE = 1; public static final Integer MAX_IMAGE_SIZE = 2048; diff --git a/services/src/main/java/org/fao/geonet/api/records/formatters/CacheApi.java b/services/src/main/java/org/fao/geonet/api/records/formatters/CacheApi.java index fa0ce65a394..d90ea166d70 100644 --- a/services/src/main/java/org/fao/geonet/api/records/formatters/CacheApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/formatters/CacheApi.java @@ -23,6 +23,9 @@ package org.fao.geonet.api.records.formatters; +import static org.fao.geonet.api.ApiParams.API_CLASS_FORMATTERS_OPS; +import static org.fao.geonet.api.ApiParams.API_CLASS_FORMATTERS_TAG; + import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; @@ -40,8 +43,8 @@ @RequestMapping(value = { "/{portal}/api/formatters" }) -@Tag(name = "formatters", - description = "Formatter operations") +@Tag(name = API_CLASS_FORMATTERS_TAG, + description = API_CLASS_FORMATTERS_OPS) @Controller("formatters") @ReadWriteController public class CacheApi { diff --git a/services/src/main/java/org/fao/geonet/api/records/formatters/FormatterAdminApi.java b/services/src/main/java/org/fao/geonet/api/records/formatters/FormatterAdminApi.java index 2541576729a..db2b6fb6eac 100644 --- a/services/src/main/java/org/fao/geonet/api/records/formatters/FormatterAdminApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/formatters/FormatterAdminApi.java @@ -73,6 +73,8 @@ import java.util.List; import java.util.Set; +import static org.fao.geonet.api.ApiParams.API_CLASS_FORMATTERS_OPS; +import static org.fao.geonet.api.ApiParams.API_CLASS_FORMATTERS_TAG; import static org.fao.geonet.api.records.formatters.FormatterConstants.SCHEMA_PLUGIN_FORMATTER_DIR; import static org.fao.geonet.api.records.formatters.FormatterConstants.VIEW_XSL_FILENAME; import static org.springframework.web.bind.annotation.RequestMethod.GET; @@ -82,8 +84,8 @@ * * @author jeichar */ -@Tag(name = "formatters", - description = "Formatter admin operations") +@Tag(name = API_CLASS_FORMATTERS_TAG, + description = API_CLASS_FORMATTERS_OPS) @Controller("formattersList") public class FormatterAdminApi extends AbstractFormatService { diff --git a/services/src/main/java/org/fao/geonet/api/sld/SldApi.java b/services/src/main/java/org/fao/geonet/api/sld/SldApi.java index 27b766679cf..fc8cd2dfc47 100644 --- a/services/src/main/java/org/fao/geonet/api/sld/SldApi.java +++ b/services/src/main/java/org/fao/geonet/api/sld/SldApi.java @@ -1,5 +1,8 @@ package org.fao.geonet.api.sld; +import static org.fao.geonet.api.ApiParams.API_CLASS_TOOLS_OPS; +import static org.fao.geonet.api.ApiParams.API_CLASS_TOOLS_TAG; + import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jeeves.transaction.TransactionManager; @@ -47,8 +50,8 @@ @RequestMapping(value = { "/{portal}/api/tools/ogc" }) -@Tag(name = "tools", - description = "Utility operations") +@Tag(name = API_CLASS_TOOLS_TAG, + description = API_CLASS_TOOLS_OPS) public class SldApi { public static final String LOGGER = Geonet.GEONETWORK + ".api.sld"; diff --git a/services/src/main/java/org/fao/geonet/api/tools/i18n/TranslationApi.java b/services/src/main/java/org/fao/geonet/api/tools/i18n/TranslationApi.java index 0ed2fce83f4..45bb57216bc 100644 --- a/services/src/main/java/org/fao/geonet/api/tools/i18n/TranslationApi.java +++ b/services/src/main/java/org/fao/geonet/api/tools/i18n/TranslationApi.java @@ -52,6 +52,8 @@ import java.util.stream.Collectors; import static java.util.stream.Collectors.groupingBy; +import static org.fao.geonet.api.ApiParams.API_CLASS_TOOLS_OPS; +import static org.fao.geonet.api.ApiParams.API_CLASS_TOOLS_TAG; import static org.springframework.http.HttpStatus.CREATED; import static org.springframework.http.HttpStatus.OK; @@ -61,7 +63,8 @@ @RequestMapping(value = { "/{portal}/api/i18n" }) -@Tag(name = "tools") +@Tag(name = API_CLASS_TOOLS_TAG, + description = API_CLASS_TOOLS_OPS) @RestController public class TranslationApi { diff --git a/services/src/main/java/org/fao/geonet/api/tools/mail/MailApi.java b/services/src/main/java/org/fao/geonet/api/tools/mail/MailApi.java index a5f2bf6519f..2ff5f7f9e9b 100644 --- a/services/src/main/java/org/fao/geonet/api/tools/mail/MailApi.java +++ b/services/src/main/java/org/fao/geonet/api/tools/mail/MailApi.java @@ -45,6 +45,9 @@ //=== Rome - Italy. email: geonetwork@osgeo.org //============================================================================== +import static org.fao.geonet.api.ApiParams.API_CLASS_TOOLS_OPS; +import static org.fao.geonet.api.ApiParams.API_CLASS_TOOLS_TAG; + import io.swagger.v3.oas.annotations.tags.Tag; import org.fao.geonet.api.API; import org.fao.geonet.api.tools.i18n.LanguageUtils; @@ -73,8 +76,8 @@ @RequestMapping(value = { "/{portal}/api/tools/mail" }) -@Tag(name = "tools", - description = "Utility operations") +@Tag(name = API_CLASS_TOOLS_TAG, + description = API_CLASS_TOOLS_OPS) @Controller("mail") public class MailApi { diff --git a/services/src/main/java/org/fao/geonet/api/tools/migration/MigrationApi.java b/services/src/main/java/org/fao/geonet/api/tools/migration/MigrationApi.java index c5a5a8f8568..63c72bb3ae5 100644 --- a/services/src/main/java/org/fao/geonet/api/tools/migration/MigrationApi.java +++ b/services/src/main/java/org/fao/geonet/api/tools/migration/MigrationApi.java @@ -23,6 +23,9 @@ package org.fao.geonet.api.tools.migration; +import static org.fao.geonet.api.ApiParams.API_CLASS_TOOLS_OPS; +import static org.fao.geonet.api.ApiParams.API_CLASS_TOOLS_TAG; + import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import org.fao.geonet.ApplicationContextHolder; @@ -43,7 +46,8 @@ @RequestMapping(value = { "/{portal}/api/tools/migration" }) -@Tag(name = "tools") +@Tag(name = API_CLASS_TOOLS_TAG, + description = API_CLASS_TOOLS_OPS) @RestController public class MigrationApi { From 1068a6ca949f050aa7ea0c5058aa4634b9c901d4 Mon Sep 17 00:00:00 2001 From: Ian Date: Tue, 2 Jan 2024 04:07:14 -0400 Subject: [PATCH 06/50] Fix initialization of SpringDoc so that it does not use null servername and null version (#7575) * Fix initialization of SpringDoc so that it does not use null servername and null version Modified OpenApi object so that it is a static object that is shared with all context. This helped fix initial api setting so that it was not set to null://null:80/geonetwork/srv/api Also update SiteApi so that if the server properties are changed then it will update the OpenApi object without requiring an application restart. * Update OpenAPI bean so that it calls the static method to ensure that no static values are changed directly in the bean. --- .../org/fao/geonet/api/OpenApiConfig.java | 102 +++++++++++++----- .../java/org/fao/geonet/api/site/SiteApi.java | 7 ++ 2 files changed, 84 insertions(+), 25 deletions(-) diff --git a/services/src/main/java/org/fao/geonet/api/OpenApiConfig.java b/services/src/main/java/org/fao/geonet/api/OpenApiConfig.java index b2ab44c2914..eb98b76db06 100644 --- a/services/src/main/java/org/fao/geonet/api/OpenApiConfig.java +++ b/services/src/main/java/org/fao/geonet/api/OpenApiConfig.java @@ -1,6 +1,6 @@ /* * ============================================================================= - * === Copyright (C) 2001-2016 Food and Agriculture Organization of the + * === Copyright (C) 2001-2023 Food and Agriculture Organization of the * === United Nations (FAO-UN), United Nations World Food Programme (WFP) * === and United Nations Environment Programme (UNEP) * === @@ -36,7 +36,6 @@ import io.swagger.v3.oas.models.servers.ServerVariables; import org.fao.geonet.NodeInfo; import org.fao.geonet.kernel.setting.SettingManager; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.concurrent.ConcurrentMapCacheManager; @@ -51,7 +50,11 @@ @Configuration @EnableCaching @OpenAPIDefinition -public class OpenApiConfig { +public class OpenApiConfig { + + private static OpenAPI openAPI = null; + + private static SettingManager settingManager = null; @Bean(name = "cacheManager") public CacheManager cacheManager() { @@ -59,11 +62,77 @@ public CacheManager cacheManager() { } @Bean - @Autowired - public OpenAPI OpenApiConfig(SettingManager settingManager) { - List servers = new ArrayList<>(); + public OpenAPI openApi(final SettingManager settingManager) { + return OpenApiConfig.setupOpenApiConfig(settingManager); + } + + /** + * Setup OpenAPI configuration. + * + * Using static function so that should the bean be called twice (which it does), it will reuse the same static objects. + * During first call, the settingManager may not be properly setup (i.e. initial install) and will return null values for version and host information. + * Subsequent calls will update the related OpenAPI information with the settingManager values. + * + * It is also static so that when we update the object on second call, it will also update the object returned from the first call as they will be + * pointing to the same object. + * + * @param settingManager containing host and version information required. + * @return OpenAPI object. + */ + private static OpenAPI setupOpenApiConfig(final SettingManager settingManager) { + OpenApiConfig.settingManager = settingManager; + if (openAPI == null) { + openAPI = new OpenAPI().info(new Info() + .description("This is the description of the GeoNetwork OpenAPI. Use this API to manage your catalog.") + .contact(new Contact() + .email("geonetwork-users@lists.sourceforge.net") + .name("GeoNetwork user mailing list") + .url("https://sourceforge.net/p/geonetwork/mailman/geonetwork-users/") + ) + .license(new License() + .name("GPL 2.0") + .url("http://www.gnu.org/licenses/old-licenses/gpl-2.0.html"))) + .externalDocs(new ExternalDocumentation() + .description("Learn how to access the catalog using the GeoNetwork REST API.")); + + setVersionRelatedInfo(); + setHostRelatedInfo(); + + } else if (openAPI.getInfo() != null && openAPI.getInfo().getVersion() == null) { + // During initial install, the version will not be set when using the JeevesApplicationContext + // But it will be set afterward when creating WebApplicationContext. So if the version is null but our new version is not null + // then lets update data based on the version. + setVersionRelatedInfo(); + // If the version was not set then the hostUrl was also not set correctly so update that as well. + setHostRelatedInfo(); + } + + return openAPI; + } + + /** + * Update openAPI object with version related information. + */ + private static void setVersionRelatedInfo() { String version = settingManager.getValue(SYSTEM_PLATFORM_VERSION); + + openAPI.getInfo().setVersion(version); + openAPI.getInfo().setTitle(String.format( + "GeoNetwork %s OpenAPI Documentation", + version)); + } + + /** + * Update openAPI object with host related information. + */ + public static void setHostRelatedInfo() { + if (settingManager == null || openAPI == null) { + return; + } + + List servers = new ArrayList<>(); + String hostUrl = settingManager.getBaseURL().replaceAll("/+$", ""); ServerVariable catalogVariable = new ServerVariable() @@ -85,24 +154,7 @@ public OpenAPI OpenApiConfig(SettingManager settingManager) { .addServerVariable("portal", portalVariable) ) ); - - return new OpenAPI().info(new Info() - .title(String.format( - "GeoNetwork %s OpenAPI Documentation", - version)) - .description("This is the description of the GeoNetwork OpenAPI. Use this API to manage your catalog.") - .contact(new Contact() - .email("geonetwork-users@lists.sourceforge.net") - .name("GeoNetwork user mailing list") - .url("https://sourceforge.net/p/geonetwork/mailman/geonetwork-users/") - ) - .version(version) - .license(new License() - .name("GPL 2.0") - .url("http://www.gnu.org/licenses/old-licenses/gpl-2.0.html"))) - .externalDocs(new ExternalDocumentation() - .description("Learn how to access the catalog using the GeoNetwork REST API.") - .url(String.format("%s/doc/api", hostUrl))) - .servers(servers); + openAPI.setServers(servers); + openAPI.getExternalDocs().setUrl(String.format("%s/doc/api", hostUrl)); } } diff --git a/services/src/main/java/org/fao/geonet/api/site/SiteApi.java b/services/src/main/java/org/fao/geonet/api/site/SiteApi.java index 00f478966be..ae4aea888fa 100644 --- a/services/src/main/java/org/fao/geonet/api/site/SiteApi.java +++ b/services/src/main/java/org/fao/geonet/api/site/SiteApi.java @@ -42,6 +42,7 @@ import org.fao.geonet.SystemInfo; import org.fao.geonet.api.ApiParams; import org.fao.geonet.api.ApiUtils; +import org.fao.geonet.api.OpenApiConfig; import org.fao.geonet.api.exception.NotAllowedException; import org.fao.geonet.api.site.model.SettingSet; import org.fao.geonet.api.site.model.SettingsListResponse; @@ -420,6 +421,7 @@ public void saveSettings( ApplicationContext applicationContext = ApplicationContextHolder.get(); String currentUuid = settingManager.getSiteId(); String oldSiteName = settingManager.getSiteName(); + String oldBaseUrl = settingManager.getBaseURL(); if (!settingManager.setValues(allRequestParams)) { throw new OperationAbortedEx("Cannot set all values"); @@ -439,6 +441,11 @@ public void saveSettings( sourceRepository.save(siteSource); } } + String newBaseUrl = settingManager.getBaseURL(); + // Update SpringDoc host information if the base url is changed. + if (!oldBaseUrl.equals(newBaseUrl)) { + OpenApiConfig.setHostRelatedInfo(); + } // Update the system default timezone. If the setting is blank use the timezone user.timezone property from command line or // TZ environment variable From 5fb3196504757c2f757245f452644a5c66de258b Mon Sep 17 00:00:00 2001 From: Ian Date: Tue, 2 Jan 2024 04:52:47 -0400 Subject: [PATCH 07/50] API should return a structured object instead of JSONObject (#7584) Updated indexer to return an object IndexResponse instead of JSONObject --- .../geonet/api/records/MetadataIndexApi.java | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/services/src/main/java/org/fao/geonet/api/records/MetadataIndexApi.java b/services/src/main/java/org/fao/geonet/api/records/MetadataIndexApi.java index 57303c9be00..b26cfc4bd43 100644 --- a/services/src/main/java/org/fao/geonet/api/records/MetadataIndexApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/MetadataIndexApi.java @@ -29,13 +29,10 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import jeeves.server.UserSession; -import jeeves.server.context.ServiceContext; import jeeves.services.ReadWriteController; -import net.sf.json.JSONObject; import org.fao.geonet.api.ApiParams; import org.fao.geonet.api.ApiUtils; import org.fao.geonet.kernel.DataManager; -import org.fao.geonet.kernel.SelectionManager; import org.fao.geonet.kernel.datamanager.IMetadataUtils; import org.fao.geonet.kernel.search.index.BatchOpsMetadataReindexer; import org.fao.geonet.kernel.setting.SettingManager; @@ -46,7 +43,6 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; -import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.Set; @@ -86,7 +82,7 @@ public class MetadataIndexApi { }) public @ResponseBody - JSONObject index( + IndexResponse index( @Parameter(description = API_PARAM_RECORD_UUIDS_OR_SELECTION, required = false, example = "") @@ -125,11 +121,30 @@ JSONObject index( new BatchOpsMetadataReindexer(dataManager, ids) .process(settingManager.getSiteId(), false); - JSONObject res = new JSONObject(); - res.put("success", true); - res.put("count", index); - - return res; + IndexResponse indexResponse = new IndexResponse(); + indexResponse.setSuccess(true); + indexResponse.setCount(index); + return indexResponse; } + private static class IndexResponse { + private boolean success; + private int count; + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + } } From 6376582dcbe040d0b167629ffa7110f7207b29a7 Mon Sep 17 00:00:00 2001 From: Ian Date: Tue, 2 Jan 2024 07:17:24 -0400 Subject: [PATCH 08/50] Add missing apiResponse for group and map api (#7590) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add missing apiResponse for group and map api * Update services/src/main/java/org/fao/geonet/api/mapservers/MapServersApi.java Co-authored-by: François Prunayre --------- Co-authored-by: François Prunayre --- services/src/main/java/org/fao/geonet/api/groups/GroupsApi.java | 1 + .../main/java/org/fao/geonet/api/mapservers/MapServersApi.java | 1 + 2 files changed, 2 insertions(+) diff --git a/services/src/main/java/org/fao/geonet/api/groups/GroupsApi.java b/services/src/main/java/org/fao/geonet/api/groups/GroupsApi.java index 04f2837e1ff..0b0fb4980d2 100644 --- a/services/src/main/java/org/fao/geonet/api/groups/GroupsApi.java +++ b/services/src/main/java/org/fao/geonet/api/groups/GroupsApi.java @@ -357,6 +357,7 @@ public ResponseEntity addGroup( method = RequestMethod.GET) @ResponseStatus(value = HttpStatus.OK) @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Group information for the group id supplied."), @ApiResponse(responseCode = "404", description = ApiParams.API_RESPONSE_RESOURCE_NOT_FOUND) }) @ResponseBody diff --git a/services/src/main/java/org/fao/geonet/api/mapservers/MapServersApi.java b/services/src/main/java/org/fao/geonet/api/mapservers/MapServersApi.java index f09a537da72..bdff18496a5 100644 --- a/services/src/main/java/org/fao/geonet/api/mapservers/MapServersApi.java +++ b/services/src/main/java/org/fao/geonet/api/mapservers/MapServersApi.java @@ -109,6 +109,7 @@ public class MapServersApi { @ResponseStatus(HttpStatus.OK) @PreAuthorize("hasAuthority('Editor')") @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "List of all mapservers."), @ApiResponse(responseCode = "403", description = ApiParams.API_RESPONSE_NOT_ALLOWED_ONLY_EDITOR) }) List getMapservers() throws Exception { From 92851367b01496530c43af9afedb2536ca0e3648 Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 3 Jan 2024 10:06:39 -0400 Subject: [PATCH 09/50] Update SpringDoc json/yaml generator to make the results more deterministic. (#7574) * Update SpringDoc json/yaml generator to make the results more deterministic. This will make it easier to compare different versions between gn releases. These are the properties that were enabled. springdoc.writer-with-order-by-keys=true springdoc.writer-with-default-pretty-printer=true * Cleanup imports --- .../org/fao/geonet/api/OpenApiController.java | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/services/src/main/java/org/fao/geonet/api/OpenApiController.java b/services/src/main/java/org/fao/geonet/api/OpenApiController.java index b2a93bbf367..801041201e2 100644 --- a/services/src/main/java/org/fao/geonet/api/OpenApiController.java +++ b/services/src/main/java/org/fao/geonet/api/OpenApiController.java @@ -21,9 +21,7 @@ package org.fao.geonet.api; import com.fasterxml.jackson.core.JsonProcessingException; -import io.swagger.v3.core.util.Json; import io.swagger.v3.core.util.PathUtils; -import io.swagger.v3.core.util.Yaml; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.models.OpenAPI; import org.springdoc.api.AbstractOpenApiResource; @@ -33,12 +31,9 @@ import org.springdoc.webmvc.core.RouterFunctionProvider; import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.annotation.AnnotationUtils; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.ModelAndView; @@ -47,6 +42,7 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping; import javax.servlet.http.HttpServletRequest; + import java.util.*; import static org.springdoc.core.Constants.*; @@ -64,6 +60,8 @@ * springdoc.api-docs.enabled=true * springdoc.api-docs.path=/api/doc * springdoc.cache.disabled=true + * springdoc.writer-with-order-by-keys=true + * springdoc.writer-with-default-pretty-printer=true */ @RestController public class OpenApiController extends AbstractOpenApiResource { @@ -95,6 +93,11 @@ public OpenApiController(ObjectFactory openAPIBuilderObjectFacto "org.fao.geonet.api", "org.fao.geonet.services.inspireatom", "org.fao.geonet.monitor.service"})); + + // Ensure open api document is consistently orders to make it easier to compare changes later. + springDocConfigProperties.setWriterWithOrderByKeys(true); + springDocConfigProperties.setWriterWithDefaultPrettyPrinter(true); + this.requestMappingHandlerMapping = requestMappingHandlerMapping; this.servletContextProvider = servletContextProvider; this.springSecurityOAuth2Provider = springSecurityOAuth2Provider; @@ -103,20 +106,20 @@ public OpenApiController(ObjectFactory openAPIBuilderObjectFacto @Operation(hidden = true) @GetMapping(value = "/{portal}/api/doc", produces = MediaType.APPLICATION_JSON_VALUE) - public String openapiJson(HttpServletRequest request, @Value(API_DOCS_URL) String apiDocsUrl) + public String openapiJson(HttpServletRequest request) throws JsonProcessingException { - calculateServerUrl(request, apiDocsUrl); + setServerBaseUrl(request); OpenAPI openAPI = this.getOpenApi(request.getLocale()); - return Json.mapper().writeValueAsString(openAPI); + return writeJsonValue(openAPI); } @Operation(hidden = true) @GetMapping(value = "/{portal}/api/doc.yml", produces = APPLICATION_OPENAPI_YAML) - public String openapiYaml(HttpServletRequest request, @Value(DEFAULT_API_DOCS_URL_YAML) String apiDocsUrl) + public String openapiYaml(HttpServletRequest request) throws JsonProcessingException { - calculateServerUrl(request, apiDocsUrl); + setServerBaseUrl(request); OpenAPI openAPI = this.getOpenApi(request.getLocale()); - return Yaml.mapper().writeValueAsString(openAPI); + return writeYamlValue(openAPI); } @Override @@ -180,9 +183,14 @@ protected boolean isRestController(Map restControllers, || !ModelAndView.class.isAssignableFrom(handlerMethod.getMethod().getReturnType())); } - protected void calculateServerUrl(HttpServletRequest request, String apiDocsUrl) { - String requestUrl = decode(request.getRequestURL().toString()); - String calculatedUrl = requestUrl.substring(0, requestUrl.length() - apiDocsUrl.length()); - this.openAPIService.setServerBaseUrl(calculatedUrl); + private String getServerBaseUrl(HttpServletRequest request) { + String contextPath = request.getContextPath(); + StringBuffer requestURL = request.getRequestURL(); + String serverBaseUrl = requestURL.substring(0, requestURL.indexOf(contextPath) + contextPath.length()); + return serverBaseUrl; + } + + protected void setServerBaseUrl(HttpServletRequest request) { + this.openAPIService.setServerBaseUrl(getServerBaseUrl(request)); } } From b892b268f9ba4bfdf85d18f3a56848fd2f24b129 Mon Sep 17 00:00:00 2001 From: Ian Date: Thu, 4 Jan 2024 07:04:38 -0400 Subject: [PATCH 10/50] Spring doc API for link api should accept a structured object instead of JSONObject (#7585) * API should accept a structured object instead of JSONObject Updated link search to accept an object LinkFilter instead of JSONObject * Fix error with Failed to convert value of type by adding a @InitBinder --- .../org/fao/geonet/api/links/LinksApi.java | 80 +++++++++++++++---- 1 file changed, 65 insertions(+), 15 deletions(-) diff --git a/services/src/main/java/org/fao/geonet/api/links/LinksApi.java b/services/src/main/java/org/fao/geonet/api/links/LinksApi.java index aac2aa1342d..46f17469977 100644 --- a/services/src/main/java/org/fao/geonet/api/links/LinksApi.java +++ b/services/src/main/java/org/fao/geonet/api/links/LinksApi.java @@ -25,6 +25,8 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import com.google.gson.Gson; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; @@ -52,7 +54,6 @@ import org.fao.geonet.repository.specification.LinkSpecs; import org.jdom.JDOMException; import org.json.JSONException; -import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.data.domain.Page; @@ -64,6 +65,7 @@ import org.springframework.jmx.export.naming.SelfNaming; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; +import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.config.annotation.EnableWebMvc; @@ -72,6 +74,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; + +import java.beans.PropertyEditorSupport; import java.io.IOException; import java.sql.SQLException; import java.util.ArrayDeque; @@ -146,9 +150,9 @@ public void iniMBeansSlidingWindowWithEmptySlot() { @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) @PreAuthorize("isAuthenticated()") public Page getRecordLinks( - @Parameter(description = "Filter, e.g. \"{url: 'png', lastState: 'ko', records: 'e421', groupId: 12}\", lastState being 'ok'/'ko'/'unknown'", required = false) + @Parameter(description = "Filter, e.g. \"{url: 'png', lastState: 'ko', records: 'e421'}\", lastState being 'ok'/'ko'/'unknown'", required = false) @RequestParam(required = false) - JSONObject filter, + LinkFilter filter, @Parameter(description = "Optional, filter links to records published in that group.", required = false) @RequestParam(required = false) Integer[] groupIdFilter, @@ -187,9 +191,9 @@ public Page getRecordLinks( produces = MediaType.APPLICATION_JSON_VALUE) @PreAuthorize("isAuthenticated()") public Page getRecordLinksPost( - @Parameter(description = "Filter, e.g. \"{url: 'png', lastState: 'ko', records: 'e421', groupId: 12}\", lastState being 'ok'/'ko'/'unknown'", required = false) + @Parameter(description = "Filter, e.g. \"{url: 'png', lastState: 'ko', records: 'e421'}\", lastState being 'ok'/'ko'/'unknown'", required = false) @RequestParam(required = false) - JSONObject filter, + LinkFilter filter, @Parameter(description = "Optional, filter links to records published in that group.", required = false) @RequestParam(required = false) Integer[] groupIdFilter, @@ -207,7 +211,7 @@ public Page getRecordLinksPost( return getLinks(filter, groupIdFilter, groupOwnerIdFilter, pageRequest, userSession); } private Page getLinks( - JSONObject filter, + LinkFilter filter, Integer[] groupIdFilter, Integer[] groupOwnerIdFilter, Pageable pageRequest, @@ -228,22 +232,22 @@ private Page getLinks( Integer stateToMatch = null; String url = null; List associatedRecords = null; - if (filter.has("lastState")) { + if (filter.getLastState() != null) { stateToMatch = 0; - if (filter.getString("lastState").equalsIgnoreCase("ok")) { + if (filter.getLastState().equalsIgnoreCase("ok")) { stateToMatch = 1; - } else if (filter.getString("lastState").equalsIgnoreCase("ko")) { + } else if (filter.getLastState().equalsIgnoreCase("ko")) { stateToMatch = -1; } } - if (filter.has("url")) { - url = filter.getString("url"); + if (filter.getUrl() != null) { + url = filter.getUrl(); } - if (filter.has("records")) { + if (filter.getRecords() != null) { associatedRecords = Arrays.stream( - filter.getString("records").split(" ") + filter.getRecords().split(" ") ).collect(Collectors.toList()); } @@ -277,9 +281,9 @@ private Page getLinks( @PreAuthorize("isAuthenticated()") @ResponseBody public void getRecordLinksAsCsv( - @Parameter(description = "Filter, e.g. \"{url: 'png', lastState: 'ko', records: 'e421', groupId: 12}\", lastState being 'ok'/'ko'/'unknown'", required = false) + @Parameter(description = "Filter, e.g. \"{url: 'png', lastState: 'ko', records: 'e421'}\", lastState being 'ok'/'ko'/'unknown'", required = false) @RequestParam(required = false) - JSONObject filter, + LinkFilter filter, @Parameter(description = "Optional, filter links to records published in that group.", required = false) @RequestParam(required = false) Integer[] groupIdFilter, @@ -445,4 +449,50 @@ private MAnalyseProcess getRegistredMAnalyseProcess() { mAnalyseProcesses.addFirst(mAnalyseProcess); return mAnalyseProcess; } + + @InitBinder + public void initBinder(WebDataBinder dataBinder) { + dataBinder.registerCustomEditor(LinkFilter.class, new PropertyEditorSupport() { + Object value; + @Override + public Object getValue() { + return value; + } + + @Override + public void setAsText(String text) throws IllegalArgumentException { + value = new Gson().fromJson(text, LinkFilter.class); + } + }); + } + + private static class LinkFilter { + private String url; + private String lastState; + private String records; + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getLastState() { + return lastState; + } + + public void setLastState(String lastState) { + this.lastState = lastState; + } + + public String getRecords() { + return records; + } + + public void setRecords(String records) { + this.records = records; + } + } } From 2af1efb371532d2334f071c9706a57bd2939f521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Garc=C3=ADa?= Date: Thu, 4 Jan 2024 15:06:29 +0100 Subject: [PATCH 11/50] Metadata extents API / Make configurable to display the metadata bboxes using geodesic extents for local projections. (#7560) * Metadata extents API / Make configurable to display the metadata bboxes using geodesic extents for local projections. * Add unit tests --- .../fao/geonet/kernel/setting/Settings.java | 3 +- .../api/records/extent/MapRenderer.java | 66 +++++++++-------- .../api/records/extent/MapRendererTest.java | 74 +++++++++++++++++++ .../resources/catalog/locales/en-admin.json | 2 + .../setup/sql/data/data-db-default.sql | 1 + .../sql/migrate/v442/migrate-default.sql | 2 + 6 files changed, 117 insertions(+), 31 deletions(-) diff --git a/core/src/main/java/org/fao/geonet/kernel/setting/Settings.java b/core/src/main/java/org/fao/geonet/kernel/setting/Settings.java index 01a878903fb..f64e17ee3bf 100644 --- a/core/src/main/java/org/fao/geonet/kernel/setting/Settings.java +++ b/core/src/main/java/org/fao/geonet/kernel/setting/Settings.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2021 Food and Agriculture Organization of the + * Copyright (C) 2001-2023 Food and Agriculture Organization of the * United Nations (FAO-UN), United Nations World Food Programme (WFP) * and United Nations Environment Programme (UNEP) * @@ -128,6 +128,7 @@ public class Settings { public static final String REGION_GETMAP_MAPPROJ = "region/getmap/mapproj"; public static final String REGION_GETMAP_WIDTH = "region/getmap/width"; public static final String REGION_GETMAP_SUMMARY_WIDTH = "region/getmap/summaryWidth"; + public static final String REGION_GETMAP_GEODESIC_EXTENTS = "region/getmap/useGeodesicExtents"; public static final String METADATA_WORKFLOW_ENABLE = "metadata/workflow/enable"; public static final String METADATA_WORKFLOW_DRAFT_WHEN_IN_GROUP = "metadata/workflow/draftWhenInGroup"; public static final String METADATA_WORKFLOW_ALLOW_SUBMIT_APPROVE_INVALID_MD = "metadata/workflow/allowSubmitApproveInvalidMd"; diff --git a/services/src/main/java/org/fao/geonet/api/records/extent/MapRenderer.java b/services/src/main/java/org/fao/geonet/api/records/extent/MapRenderer.java index 5fe0922a251..21673b2aea0 100644 --- a/services/src/main/java/org/fao/geonet/api/records/extent/MapRenderer.java +++ b/services/src/main/java/org/fao/geonet/api/records/extent/MapRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2022 Food and Agriculture Organization of the + * Copyright (C) 2001-2023 Food and Agriculture Organization of the * United Nations (FAO-UN), United Nations World Food Programme (WFP) * and United Nations Environment Programme (UNEP) * @@ -24,7 +24,6 @@ package org.fao.geonet.api.records.extent; import jeeves.server.context.ServiceContext; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.fao.geonet.api.regions.GeomFormat; import org.fao.geonet.exceptions.BadParameterEx; @@ -33,15 +32,12 @@ import org.fao.geonet.kernel.region.RegionsDAO; import org.fao.geonet.kernel.setting.SettingManager; import org.fao.geonet.kernel.setting.Settings; -import org.fao.geonet.lib.Lib; import org.geotools.geometry.jts.JTS; -import org.geotools.geometry.jts.JTSFactoryFinder; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.referencing.CRS; import org.locationtech.jts.awt.ShapeWriter; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; -import org.locationtech.jts.geom.GeometryFactory; import org.geotools.api.metadata.extent.Extent; import org.geotools.api.metadata.extent.GeographicBoundingBox; import org.geotools.api.metadata.extent.GeographicExtent; @@ -49,15 +45,9 @@ import org.geotools.api.referencing.operation.MathTransform; import org.springframework.context.ApplicationContext; -import javax.imageio.ImageIO; import java.awt.*; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.net.URLConnection; import java.util.Collection; import java.util.Map; import java.util.SortedSet; @@ -84,35 +74,48 @@ public static AffineTransform worldToScreenTransform(Envelope mapExtent, Dimensi return new AffineTransform(scaleX, 0.0d, 0.0d, -scaleY, tx, ty); } + /** + * Returns a bounding box geometry. + * + * @param geom Bounding box geometry. + * @param srs Bounding box geometry srs. + * @param useGeodesicExtents false: returns the bounding box geometry as a rectangle (using min / max bounds). + * true: returns the bounding box geometry. + * @return bounding box geometry. + */ + public static Geometry getGeometryExtent(Geometry geom, String srs, boolean useGeodesicExtents) { + boolean isGlobalSrs = srs.equals("EPSG:4326") || srs.equals("EPSG:3857"); + + return (!isGlobalSrs && !useGeodesicExtents ? geom.getEnvelope() : geom); + } + /** * Check if a geometry is in the domain of validity of a projection and if not return the * intersection of the geometry with the coordinate system domain of validity. */ public static Geometry computeGeomInDomainOfValidity(Geometry geom, CoordinateReferenceSystem mapCRS) { - final GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null); final Extent domainOfValidity = mapCRS.getDomainOfValidity(); Geometry adjustedGeom = geom; if (domainOfValidity != null) { for (final GeographicExtent extent : domainOfValidity.getGeographicElements()) { - if (Boolean.FALSE.equals(extent.getInclusion())) { + if ((extent == null) || (Boolean.FALSE.equals(extent.getInclusion()))) { continue; } + if (extent instanceof GeographicBoundingBox) { - if (extent != null) { - GeographicBoundingBox box = (GeographicBoundingBox) extent; - - Envelope env = new Envelope( - box.getWestBoundLongitude(), - box.getEastBoundLongitude(), - box.getSouthBoundLatitude(), - box.getNorthBoundLatitude()); - if (env.contains(geom.getEnvelopeInternal())) { - return geom; - } else { - Geometry extentPolygon = JTS.toGeometry(env); - adjustedGeom = geom.intersection(extentPolygon); - } + GeographicBoundingBox box = (GeographicBoundingBox) extent; + + Envelope env = new Envelope( + box.getWestBoundLongitude(), + box.getEastBoundLongitude(), + box.getSouthBoundLatitude(), + box.getNorthBoundLatitude()); + if (env.contains(geom.getEnvelopeInternal())) { + return geom; + } else { + Geometry extentPolygon = JTS.toGeometry(env); + adjustedGeom = geom.intersection(extentPolygon); } } } @@ -123,12 +126,15 @@ public static Geometry computeGeomInDomainOfValidity(Geometry geom, CoordinateRe } public BufferedImage render(String id, String srs, Integer width, Integer height, - String background, String geomParam, String geomType, String geomSrs, String fillColor, String strokeColor) throws Exception { + String background, String geomParam, String geomType, + String geomSrs, String fillColor, String strokeColor) throws Exception { ApplicationContext appContext = context.getApplicationContext(); Map regionGetMapBackgroundLayers = appContext.getBean("regionGetMapBackgroundLayers", Map.class); SortedSet regionGetMapExpandFactors = appContext.getBean("regionGetMapExpandFactors", SortedSet.class); SettingManager settingManager = appContext.getBean(SettingManager.class); + boolean useGeodesicExtents = settingManager.getValueAsBool(Settings.REGION_GETMAP_GEODESIC_EXTENTS, false); + Geometry geom = null; if (id != null) { Collection daos = context.getApplicationContext().getBeansOfType(RegionsDAO.class).values(); @@ -192,7 +198,6 @@ public BufferedImage render(String id, String srs, Integer width, Integer height ; BufferedImage baseMapImage = baseMapRenderer.render(); - // ImageIO.write(baseMapImage, "png", new File("delme.png")); image = baseMapImage; } else { @@ -209,8 +214,9 @@ public BufferedImage render(String id, String srs, Integer width, Integer height Color geomStrokeColor = getColor(strokeColor, new Color(0, 0, 0, 255)); AffineTransform worldToScreenTransform = worldToScreenTransform(bboxOfImage, imageDimensions); for (int i = 0; i < geom.getNumGeometries(); i++) { + Geometry geomExtent = MapRenderer.getGeometryExtent(geom.getGeometryN(i), srs, useGeodesicExtents); // draw each included geometry separately to ensure they are filled correctly - Shape shape = worldToScreenTransform.createTransformedShape(shapeWriter.toShape(geom.getGeometryN(i))); + Shape shape = worldToScreenTransform.createTransformedShape(shapeWriter.toShape(geomExtent)); graphics.setColor(geomFillColor); graphics.fill(shape); diff --git a/services/src/test/java/org/fao/geonet/api/records/extent/MapRendererTest.java b/services/src/test/java/org/fao/geonet/api/records/extent/MapRendererTest.java index 47ca774eea0..4a176232520 100644 --- a/services/src/test/java/org/fao/geonet/api/records/extent/MapRendererTest.java +++ b/services/src/test/java/org/fao/geonet/api/records/extent/MapRendererTest.java @@ -1,3 +1,26 @@ +/* + * Copyright (C) 2001-2023 Food and Agriculture Organization of the + * United Nations (FAO-UN), United Nations World Food Programme (WFP) + * and United Nations Environment Programme (UNEP) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, + * Rome - Italy. email: geonetwork@osgeo.org + */ + package org.fao.geonet.api.records.extent; import org.fao.geonet.kernel.region.Region; @@ -48,4 +71,55 @@ public void domainIntersectsBoundingPolygon() throws Exception { String result = wktWriter.write(MapRenderer.computeGeomInDomainOfValidity(bbox, Region.decodeCRS("EPSG:3857"))); assertEquals("POLYGON ((159.70909090909092 -85.06, 135 -76, 161 -76, 153 -81, 161.12 -85.06, 159.70909090909092 -85.06))", result); } + + @Test + public void extentGeodesicLocalProjection() throws Exception { + String test = "POLYGON ((646.3563610491983 308975.2885578188, 10545.528150276805 637111.0281460616, 276050.8102636032 636456.3084312443, 284347.2430806639 308289.5622343737, 646.3563610491983 308975.2885578188))"; + String localSrs = "EPSG:28992"; + Geometry geometry = wktReader.read(test); + geometry.setSRID(28992); + + Geometry geometryExtent = MapRenderer.getGeometryExtent(geometry, localSrs, true); + assertEquals(geometry, geometryExtent); + } + + @Test + public void extentNonGeodesicLocalProjection() throws Exception { + String test = "POLYGON ((646.3563610491983 308975.2885578188, 10545.528150276805 637111.0281460616, 276050.8102636032 636456.3084312443, 284347.2430806639 308289.5622343737, 646.3563610491983 308975.2885578188))"; + String localSrs = "EPSG:28992"; + Geometry geometry = wktReader.read(test); + geometry.setSRID(28992); + + Geometry geometryExtent = MapRenderer.getGeometryExtent(geometry, localSrs, false); + assertEquals(geometry.getEnvelope(), geometryExtent); + } + + @Test + public void extentGlobal3857Projection() throws Exception { + String test = "POLYGON ((159.70909090909092 -85.06, 135 -76, 161 -76, 153 -81, 161.12 -85.06, 159.70909090909092 -85.06))"; + String globalSrs = "EPSG:3857"; + Geometry geometry = wktReader.read(test); + geometry.setSRID(3857); + + // For global projections + Geometry geometryExtent = MapRenderer.getGeometryExtent(geometry, globalSrs, true); + assertEquals(geometry, geometryExtent); + + geometryExtent = MapRenderer.getGeometryExtent(geometry, globalSrs, false); + assertEquals(geometry, geometryExtent); + } + + @Test + public void extentGlobal4326Projection() throws Exception { + String test = "POLYGON ((165 -87, 135 -76, 161 -76, 153 -81, 165 -87))"; + String globalSrs = "EPSG:4326"; + Geometry geometry = wktReader.read(test); + geometry.setSRID(4326); + + Geometry geometryExtent = MapRenderer.getGeometryExtent(geometry, globalSrs, true); + assertEquals(geometry, geometryExtent); + + geometryExtent = MapRenderer.getGeometryExtent(geometry, globalSrs, false); + assertEquals(geometry, geometryExtent); + } } diff --git a/web-ui/src/main/resources/catalog/locales/en-admin.json b/web-ui/src/main/resources/catalog/locales/en-admin.json index 1379e8db5b9..8db7f48107a 100644 --- a/web-ui/src/main/resources/catalog/locales/en-admin.json +++ b/web-ui/src/main/resources/catalog/locales/en-admin.json @@ -1041,6 +1041,8 @@ "region/getmap/background": "Background map, URL or Named Layer ID", "region/getmap/mapproj": "Map projection", "region/getmap/summaryWidth": "Summary width", + "region/getmap/useGeodesicExtents": "Display geodesic extents", + "region/getmap/useGeodesicExtents-help": "By default, the displayed metadata extents are planar (i.e. rectangular). If you enable this option, the metadata extents will become geodesic. If the map uses a projected coordinate system, this may lead to non-rectangular extents (e.g. trapezoid).", "region/getmap/width": "Width", "metadata/editor": "Metadata editor configuration", "metadata/editor/schemaConfig": "Standard configuration", diff --git a/web/src/main/webapp/WEB-INF/classes/setup/sql/data/data-db-default.sql b/web/src/main/webapp/WEB-INF/classes/setup/sql/data/data-db-default.sql index af573b706fc..ea1226beb62 100644 --- a/web/src/main/webapp/WEB-INF/classes/setup/sql/data/data-db-default.sql +++ b/web/src/main/webapp/WEB-INF/classes/setup/sql/data/data-db-default.sql @@ -670,6 +670,7 @@ INSERT INTO Settings (name, value, datatype, position, internal) VALUES ('region INSERT INTO Settings (name, value, datatype, position, internal) VALUES ('region/getmap/width', '500', 0, 9590, 'n'); INSERT INTO Settings (name, value, datatype, position, internal) VALUES ('region/getmap/summaryWidth', '500', 0, 9590, 'n'); INSERT INTO Settings (name, value, datatype, position, internal) VALUES ('region/getmap/mapproj', 'EPSG:3857', 0, 9590, 'n'); +INSERT INTO Settings (name, value, datatype, position, internal) VALUES ('region/getmap/useGeodesicExtents', 'false', 2, 9591, 'n'); INSERT INTO Settings (name, value, datatype, position, internal) VALUES ('metadata/url/sitemapLinkUrl', NULL, 0, 9165, 'y'); diff --git a/web/src/main/webapp/WEB-INF/classes/setup/sql/migrate/v442/migrate-default.sql b/web/src/main/webapp/WEB-INF/classes/setup/sql/migrate/v442/migrate-default.sql index 08631d86040..c9852f9a999 100644 --- a/web/src/main/webapp/WEB-INF/classes/setup/sql/migrate/v442/migrate-default.sql +++ b/web/src/main/webapp/WEB-INF/classes/setup/sql/migrate/v442/migrate-default.sql @@ -1,4 +1,6 @@ UPDATE Settings SET value='4.4.2' WHERE name='system/platform/version'; UPDATE Settings SET value='SNAPSHOT' WHERE name='system/platform/subVersion'; +INSERT INTO Settings (name, value, datatype, position, internal) VALUES ('region/getmap/useGeodesicExtents', 'false', 2, 9591, 'n'); + ALTER TABLE public.spg_page ADD icon varchar NULL; From 3b3180d9fcabe21e4d03c90b41923094c996ec51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Garc=C3=ADa?= Date: Thu, 4 Jan 2024 15:08:03 +0100 Subject: [PATCH 12/50] Home page / sort topic categories and INSPIRE themes facets alphabetically (#7569) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Home page / sort topic categories and INSPIRE themes facets alphabetically * Home page / use facets configuration to sort alphabetically or by quantity * Update web-ui/src/main/resources/catalog/components/elasticsearch/directives/FacetDirective.js Co-authored-by: François Prunayre * Home page / sort topic categories and INSPIRE themes facets alphabetically - remove not required code --------- Co-authored-by: François Prunayre --- .../components/elasticsearch/directives/FacetDirective.js | 4 +++- .../elasticsearch/directives/partials/facet-cards.html | 2 +- web-ui/src/main/resources/catalog/js/CatController.js | 6 ++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/web-ui/src/main/resources/catalog/components/elasticsearch/directives/FacetDirective.js b/web-ui/src/main/resources/catalog/components/elasticsearch/directives/FacetDirective.js index bae90be49a0..054318496f3 100644 --- a/web-ui/src/main/resources/catalog/components/elasticsearch/directives/FacetDirective.js +++ b/web-ui/src/main/resources/catalog/components/elasticsearch/directives/FacetDirective.js @@ -453,8 +453,9 @@ ]); module.directive("esFacetCards", [ + "gnFacetSorter", "gnLangs", - function (gnLangs) { + function (gnFacetSorter, gnLangs) { return { restrict: "A", scope: { @@ -486,6 +487,7 @@ init(); + scope.facetSorter = gnFacetSorter.sortByTranslation; scope.$watch("key", function (n, o) { if (n && n !== o) { init(); diff --git a/web-ui/src/main/resources/catalog/components/elasticsearch/directives/partials/facet-cards.html b/web-ui/src/main/resources/catalog/components/elasticsearch/directives/partials/facet-cards.html index baa0f6eac73..ebedaa78727 100644 --- a/web-ui/src/main/resources/catalog/components/elasticsearch/directives/partials/facet-cards.html +++ b/web-ui/src/main/resources/catalog/components/elasticsearch/directives/partials/facet-cards.html @@ -1,5 +1,5 @@
Date: Thu, 14 Dec 2023 12:03:37 +0100 Subject: [PATCH 13/50] Record view / Invalid timezone shift for years outside moment's 10 years range. Use moment-timezone-with-data-1970-2030.min.js version 0.5.43. For catalogues with metadata containing dates before 1970, consider to use https://momentjs.com/downloads/moment-timezone-with-data.min.js --- .../src/main/resources/WEB-INF/classes/web-ui-wro-sources.xml | 4 ++-- .../lib/moment-timezone-with-data-10-year-range.min.js | 1 - .../catalog/lib/moment-timezone-with-data-1970-2030.min.js | 1 + web/src/main/webapp/xslt/base-layout-cssjs-loader.xsl | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 web-ui/src/main/resources/catalog/lib/moment-timezone-with-data-10-year-range.min.js create mode 100644 web-ui/src/main/resources/catalog/lib/moment-timezone-with-data-1970-2030.min.js diff --git a/web-ui/src/main/resources/WEB-INF/classes/web-ui-wro-sources.xml b/web-ui/src/main/resources/WEB-INF/classes/web-ui-wro-sources.xml index 8d7932387c3..723897c0687 100644 --- a/web-ui/src/main/resources/WEB-INF/classes/web-ui-wro-sources.xml +++ b/web-ui/src/main/resources/WEB-INF/classes/web-ui-wro-sources.xml @@ -36,7 +36,7 @@ - + @@ -106,7 +106,7 @@ - + diff --git a/web-ui/src/main/resources/catalog/lib/moment-timezone-with-data-10-year-range.min.js b/web-ui/src/main/resources/catalog/lib/moment-timezone-with-data-10-year-range.min.js deleted file mode 100644 index e83b21456d7..00000000000 --- a/web-ui/src/main/resources/catalog/lib/moment-timezone-with-data-10-year-range.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(a,i){"use strict";"object"==typeof module&&module.exports?module.exports=i(require("moment")):"function"==typeof define&&define.amd?define(["moment"],i):i(a.moment)}(this,function(c){"use strict";void 0===c.version&&c.default&&(c=c.default);var i,A={},n={},t={},s={},u={};c&&"string"==typeof c.version||y("Moment Timezone requires Moment.js. See https://momentjs.com/timezone/docs/#/use-it/browser/");var a=c.version.split("."),r=+a[0],e=+a[1];function m(a){return 96= 2.6.0. You are using Moment.js "+c.version+". See momentjs.com"),M.prototype={_set:function(a){this.name=a.name,this.abbrs=a.abbrs,this.untils=a.untils,this.offsets=a.offsets,this.population=a.population},_index:function(a){var i,r=+a,e=this.untils;for(i=0;i= 2.9.0. You are using Moment.js "+c.version+"."),c.defaultZone=a?z(a):null,c};var G=c.momentProperties;return"[object Array]"===Object.prototype.toString.call(G)?(G.push("_z"),G.push("_a")):G&&(G._z=null),C({version:"2022c",zones:["Africa/Abidjan|GMT|0|0||48e5","Africa/Nairobi|EAT|-30|0||47e5","Africa/Algiers|CET|-10|0||26e5","Africa/Lagos|WAT|-10|0||17e6","Africa/Maputo|CAT|-20|0||26e5","Africa/Cairo|EET|-20|0||15e6","Africa/Casablanca|+00 +01|0 -10|01010101010101010101010101|1T0q0 mo0 gM0 LA0 WM0 jA0 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00|32e5","Europe/Paris|CET CEST|-10 -20|01010101010101010101010|1T0p0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0|11e6","Africa/Johannesburg|SAST|-20|0||84e5","Africa/Juba|EAT CAT|-30 -20|01|24nx0|","Africa/Khartoum|EAT CAT|-30 -20|01|1Usl0|51e5","Africa/Sao_Tome|GMT WAT|0 -10|010|1UQN0 2q00|","Africa/Windhoek|CAT WAT|-20 -10|010|1T3c0 11B0|32e4","America/Adak|HST HDT|a0 90|01010101010101010101010|1ST00 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0|326","America/Anchorage|AKST AKDT|90 80|01010101010101010101010|1SSX0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0|30e4","America/Santo_Domingo|AST|40|0||29e5","America/Fortaleza|-03|30|0||34e5","America/Asuncion|-03 -04|30 40|01010101010101010101010|1T0r0 1fB0 19X0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0|28e5","America/Panama|EST|50|0||15e5","America/Mexico_City|CST CDT|60 50|01010101010101010101010|1T3k0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0|20e6","America/Managua|CST|60|0||22e5","America/Caracas|-04|40|0||29e5","America/Lima|-05|50|0||11e6","America/Denver|MST MDT|70 60|01010101010101010101010|1SSV0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0|26e5","America/Campo_Grande|-03 -04|30 40|010101|1SKr0 1zd0 On0 1HB0 FX0|77e4","America/Chicago|CST CDT|60 50|01010101010101010101010|1SSU0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0|92e5","America/Chihuahua|MST MDT|70 60|01010101010101010101010|1T3l0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0|81e4","America/Phoenix|MST|70|0||42e5","America/Whitehorse|PST PDT MST|80 70 70|010101012|1SSW0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1z90|23e3","America/New_York|EST EDT|50 40|01010101010101010101010|1SST0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0|21e6","America/Los_Angeles|PST PDT|80 70|01010101010101010101010|1SSW0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0|15e6","America/Halifax|AST ADT|40 30|01010101010101010101010|1SSS0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0|39e4","America/Godthab|-03 -02|30 20|01010101010101010101010|1T0p0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0|17e3","America/Grand_Turk|AST EDT EST|40 40 50|012121212121212121212|1Vkv0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0|37e2","America/Havana|CST CDT|50 40|01010101010101010101010|1SSR0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0|21e5","America/Metlakatla|AKST AKDT PST|90 80 80|010120101010101010101010|1SSX0 1zb0 Op0 1zb0 uM0 jB0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0|14e2","America/Miquelon|-03 -02|30 20|01010101010101010101010|1SSR0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0|61e2","America/Noronha|-02|20|0||30e2","America/Santiago|-03 -04|30 40|01010101010101010101010|1Tk30 Ap0 1Nb0 Ap0 1zb0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0|62e5","America/Sao_Paulo|-02 -03|20 30|010101|1SKq0 1zd0 On0 1HB0 FX0|20e6","Atlantic/Azores|-01 +00|10 0|01010101010101010101010|1T0p0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0|25e4","America/St_Johns|NST NDT|3u 2u|01010101010101010101010|1SSRu 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0|11e4","Antarctica/Casey|+11 +08|-b0 -80|0101010|1Vkh0 1o30 14k0 1kr0 12l0 1o01|10","Asia/Bangkok|+07|-70|0||15e6","Asia/Vladivostok|+10|-a0|0||60e4","Australia/Sydney|AEDT AEST|-b0 -a0|01010101010101010101010|1T340 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|40e5","Asia/Tashkent|+05|-50|0||23e5","Pacific/Auckland|NZDT NZST|-d0 -c0|01010101010101010101010|1T320 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00|14e5","Europe/Istanbul|+03|-30|0||13e6","Antarctica/Troll|+00 +02|0 -20|01010101010101010101010|1T0p0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0|40","Asia/Dhaka|+06|-60|0||16e6","Asia/Amman|EET EEST|-20 -30|01010101010101010101010|1T2m0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 LA0 1C00 LA0 1C00 Oo0 1zc0 Oo0 1C00 LA0 1C00 LA0 1C00|25e5","Asia/Kamchatka|+12|-c0|0||18e4","Asia/Dubai|+04|-40|0||39e5","Asia/Beirut|EET EEST|-20 -30|01010101010101010101010|1T0m0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0|22e5","Asia/Kuala_Lumpur|+08|-80|0||71e5","Asia/Kolkata|IST|-5u|0||15e6","Asia/Chita|+09|-90|0||33e4","Asia/Shanghai|CST|-80|0||23e6","Asia/Colombo|+0530|-5u|0||22e5","Asia/Damascus|EET EEST|-20 -30|01010101010101010101010|1T2m0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0|26e5","Asia/Famagusta|+03 EET EEST|-30 -20 -30|0121212121212121212121|1Urd0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0|","Asia/Gaza|EET EEST|-20 -30|01010101010101010101010|1SXX0 1qL0 WN0 1qL0 11c0 1on0 11B0 1o00 11A0 1qo0 XA0 1q00 XA0 1q00 12o0 1nc0 12o0 1nc0 12o0 1nc0 12o0 1q00|18e5","Asia/Hong_Kong|HKT|-80|0||73e5","Asia/Jakarta|WIB|-70|0||31e6","Asia/Jayapura|WIT|-90|0||26e4","Asia/Jerusalem|IST IDT|-20 -30|01010101010101010101010|1SXA0 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0|81e4","Asia/Kabul|+0430|-4u|0||46e5","Asia/Karachi|PKT|-50|0||24e6","Asia/Kathmandu|+0545|-5J|0||12e5","Asia/Sakhalin|+11|-b0|0||58e4","Asia/Makassar|WITA|-80|0||15e5","Asia/Manila|PST|-80|0||24e6","Europe/Athens|EET EEST|-20 -30|01010101010101010101010|1T0p0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0|35e5","Asia/Pyongyang|KST KST|-8u -90|01|1VGf0|29e5","Asia/Qyzylorda|+06 +05|-60 -50|01|1Xei0|73e4","Asia/Rangoon|+0630|-6u|0||48e5","Asia/Seoul|KST|-90|0||23e6","Asia/Tehran|+0330 +0430|-3u -4u|0101010101010|1SWIu 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0|14e6","Asia/Tokyo|JST|-90|0||38e6","Europe/Lisbon|WET WEST|0 -10|01010101010101010101010|1T0p0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0|27e5","Atlantic/Cape_Verde|-01|10|0||50e4","Australia/Adelaide|ACDT ACST|-au -9u|01010101010101010101010|1T34u 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|11e5","Australia/Brisbane|AEST|-a0|0||20e5","Australia/Darwin|ACST|-9u|0||12e4","Australia/Eucla|+0845|-8J|0||368","Australia/Lord_Howe|+11 +1030|-b0 -au|01010101010101010101010|1T330 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu|347","Australia/Perth|AWST|-80|0||18e5","Pacific/Easter|-05 -06|50 60|01010101010101010101010|1Tk30 Ap0 1Nb0 Ap0 1zb0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0|30e2","Europe/Dublin|GMT IST|0 -10|01010101010101010101010|1T0p0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0|12e5","Etc/GMT-1|+01|-10|0||","Pacific/Fakaofo|+13|-d0|0||483","Pacific/Kiritimati|+14|-e0|0||51e2","Etc/GMT-2|+02|-20|0||","Pacific/Tahiti|-10|a0|0||18e4","Pacific/Niue|-11|b0|0||12e2","Etc/GMT+12|-12|c0|0||","Pacific/Galapagos|-06|60|0||25e3","Etc/GMT+7|-07|70|0||","Pacific/Pitcairn|-08|80|0||56","Pacific/Gambier|-09|90|0||125","Etc/UTC|UTC|0|0||","Europe/London|GMT BST|0 -10|01010101010101010101010|1T0p0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0|10e6","Europe/Chisinau|EET EEST|-20 -30|01010101010101010101010|1T0o0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0|67e4","Europe/Moscow|MSK|-30|0||16e6","Europe/Volgograd|+03 +04|-30 -40|010|1WQL0 5gn0|10e5","Pacific/Honolulu|HST|a0|0||37e4","MET|MET MEST|-10 -20|01010101010101010101010|1T0p0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0|","Pacific/Chatham|+1345 +1245|-dJ -cJ|01010101010101010101010|1T320 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00|600","Pacific/Apia|+14 +13|-e0 -d0|0101010101|1T320 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0|37e3","Pacific/Fiji|+13 +12|-d0 -c0|010101010101010101010|1Swe0 1VA0 s00 1VA0 s00 20o0 pc0 2hc0 bc0 4q00 pc0 20o0 pc0 20o0 pc0 20o0 s00 1VA0 s00 20o0|88e4","Pacific/Guam|ChST|-a0|0||17e4","Pacific/Marquesas|-0930|9u|0||86e2","Pacific/Pago_Pago|SST|b0|0||37e2","Pacific/Norfolk|+11 +12|-b0 -c0|010101010101010101|219P0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|25e4","Pacific/Tongatapu|+14 +13|-e0 -d0|01|1Swd0|75e3"],links:["Africa/Abidjan|Africa/Accra","Africa/Abidjan|Africa/Bamako","Africa/Abidjan|Africa/Banjul","Africa/Abidjan|Africa/Bissau","Africa/Abidjan|Africa/Conakry","Africa/Abidjan|Africa/Dakar","Africa/Abidjan|Africa/Freetown","Africa/Abidjan|Africa/Lome","Africa/Abidjan|Africa/Monrovia","Africa/Abidjan|Africa/Nouakchott","Africa/Abidjan|Africa/Ouagadougou","Africa/Abidjan|Africa/Timbuktu","Africa/Abidjan|America/Danmarkshavn","Africa/Abidjan|Atlantic/Reykjavik","Africa/Abidjan|Atlantic/St_Helena","Africa/Abidjan|Etc/GMT","Africa/Abidjan|Etc/GMT+0","Africa/Abidjan|Etc/GMT-0","Africa/Abidjan|Etc/GMT0","Africa/Abidjan|Etc/Greenwich","Africa/Abidjan|GMT","Africa/Abidjan|GMT+0","Africa/Abidjan|GMT-0","Africa/Abidjan|GMT0","Africa/Abidjan|Greenwich","Africa/Abidjan|Iceland","Africa/Algiers|Africa/Tunis","Africa/Cairo|Africa/Tripoli","Africa/Cairo|Egypt","Africa/Cairo|Europe/Kaliningrad","Africa/Cairo|Libya","Africa/Casablanca|Africa/El_Aaiun","Africa/Johannesburg|Africa/Maseru","Africa/Johannesburg|Africa/Mbabane","Africa/Lagos|Africa/Bangui","Africa/Lagos|Africa/Brazzaville","Africa/Lagos|Africa/Douala","Africa/Lagos|Africa/Kinshasa","Africa/Lagos|Africa/Libreville","Africa/Lagos|Africa/Luanda","Africa/Lagos|Africa/Malabo","Africa/Lagos|Africa/Ndjamena","Africa/Lagos|Africa/Niamey","Africa/Lagos|Africa/Porto-Novo","Africa/Maputo|Africa/Blantyre","Africa/Maputo|Africa/Bujumbura","Africa/Maputo|Africa/Gaborone","Africa/Maputo|Africa/Harare","Africa/Maputo|Africa/Kigali","Africa/Maputo|Africa/Lubumbashi","Africa/Maputo|Africa/Lusaka","Africa/Nairobi|Africa/Addis_Ababa","Africa/Nairobi|Africa/Asmara","Africa/Nairobi|Africa/Asmera","Africa/Nairobi|Africa/Dar_es_Salaam","Africa/Nairobi|Africa/Djibouti","Africa/Nairobi|Africa/Kampala","Africa/Nairobi|Africa/Mogadishu","Africa/Nairobi|Indian/Antananarivo","Africa/Nairobi|Indian/Comoro","Africa/Nairobi|Indian/Mayotte","America/Adak|America/Atka","America/Adak|US/Aleutian","America/Anchorage|America/Juneau","America/Anchorage|America/Nome","America/Anchorage|America/Sitka","America/Anchorage|America/Yakutat","America/Anchorage|US/Alaska","America/Campo_Grande|America/Cuiaba","America/Caracas|America/Boa_Vista","America/Caracas|America/Guyana","America/Caracas|America/La_Paz","America/Caracas|America/Manaus","America/Caracas|America/Porto_Velho","America/Caracas|Brazil/West","America/Caracas|Etc/GMT+4","America/Chicago|America/Indiana/Knox","America/Chicago|America/Indiana/Tell_City","America/Chicago|America/Knox_IN","America/Chicago|America/Matamoros","America/Chicago|America/Menominee","America/Chicago|America/North_Dakota/Beulah","America/Chicago|America/North_Dakota/Center","America/Chicago|America/North_Dakota/New_Salem","America/Chicago|America/Rainy_River","America/Chicago|America/Rankin_Inlet","America/Chicago|America/Resolute","America/Chicago|America/Winnipeg","America/Chicago|CST6CDT","America/Chicago|Canada/Central","America/Chicago|US/Central","America/Chicago|US/Indiana-Starke","America/Chihuahua|America/Mazatlan","America/Chihuahua|Mexico/BajaSur","America/Denver|America/Boise","America/Denver|America/Cambridge_Bay","America/Denver|America/Edmonton","America/Denver|America/Inuvik","America/Denver|America/Ojinaga","America/Denver|America/Shiprock","America/Denver|America/Yellowknife","America/Denver|Canada/Mountain","America/Denver|MST7MDT","America/Denver|Navajo","America/Denver|US/Mountain","America/Fortaleza|America/Araguaina","America/Fortaleza|America/Argentina/Buenos_Aires","America/Fortaleza|America/Argentina/Catamarca","America/Fortaleza|America/Argentina/ComodRivadavia","America/Fortaleza|America/Argentina/Cordoba","America/Fortaleza|America/Argentina/Jujuy","America/Fortaleza|America/Argentina/La_Rioja","America/Fortaleza|America/Argentina/Mendoza","America/Fortaleza|America/Argentina/Rio_Gallegos","America/Fortaleza|America/Argentina/Salta","America/Fortaleza|America/Argentina/San_Juan","America/Fortaleza|America/Argentina/San_Luis","America/Fortaleza|America/Argentina/Tucuman","America/Fortaleza|America/Argentina/Ushuaia","America/Fortaleza|America/Bahia","America/Fortaleza|America/Belem","America/Fortaleza|America/Buenos_Aires","America/Fortaleza|America/Catamarca","America/Fortaleza|America/Cayenne","America/Fortaleza|America/Cordoba","America/Fortaleza|America/Jujuy","America/Fortaleza|America/Maceio","America/Fortaleza|America/Mendoza","America/Fortaleza|America/Montevideo","America/Fortaleza|America/Paramaribo","America/Fortaleza|America/Punta_Arenas","America/Fortaleza|America/Recife","America/Fortaleza|America/Rosario","America/Fortaleza|America/Santarem","America/Fortaleza|Antarctica/Palmer","America/Fortaleza|Antarctica/Rothera","America/Fortaleza|Atlantic/Stanley","America/Fortaleza|Etc/GMT+3","America/Godthab|America/Nuuk","America/Halifax|America/Glace_Bay","America/Halifax|America/Goose_Bay","America/Halifax|America/Moncton","America/Halifax|America/Thule","America/Halifax|Atlantic/Bermuda","America/Halifax|Canada/Atlantic","America/Havana|Cuba","America/Lima|America/Bogota","America/Lima|America/Eirunepe","America/Lima|America/Guayaquil","America/Lima|America/Porto_Acre","America/Lima|America/Rio_Branco","America/Lima|Brazil/Acre","America/Lima|Etc/GMT+5","America/Los_Angeles|America/Ensenada","America/Los_Angeles|America/Santa_Isabel","America/Los_Angeles|America/Tijuana","America/Los_Angeles|America/Vancouver","America/Los_Angeles|Canada/Pacific","America/Los_Angeles|Mexico/BajaNorte","America/Los_Angeles|PST8PDT","America/Los_Angeles|US/Pacific","America/Managua|America/Belize","America/Managua|America/Costa_Rica","America/Managua|America/El_Salvador","America/Managua|America/Guatemala","America/Managua|America/Regina","America/Managua|America/Swift_Current","America/Managua|America/Tegucigalpa","America/Managua|Canada/Saskatchewan","America/Mexico_City|America/Bahia_Banderas","America/Mexico_City|America/Merida","America/Mexico_City|America/Monterrey","America/Mexico_City|Mexico/General","America/New_York|America/Detroit","America/New_York|America/Fort_Wayne","America/New_York|America/Indiana/Indianapolis","America/New_York|America/Indiana/Marengo","America/New_York|America/Indiana/Petersburg","America/New_York|America/Indiana/Vevay","America/New_York|America/Indiana/Vincennes","America/New_York|America/Indiana/Winamac","America/New_York|America/Indianapolis","America/New_York|America/Iqaluit","America/New_York|America/Kentucky/Louisville","America/New_York|America/Kentucky/Monticello","America/New_York|America/Louisville","America/New_York|America/Montreal","America/New_York|America/Nassau","America/New_York|America/Nipigon","America/New_York|America/Pangnirtung","America/New_York|America/Port-au-Prince","America/New_York|America/Thunder_Bay","America/New_York|America/Toronto","America/New_York|Canada/Eastern","America/New_York|EST5EDT","America/New_York|US/East-Indiana","America/New_York|US/Eastern","America/New_York|US/Michigan","America/Noronha|Atlantic/South_Georgia","America/Noronha|Brazil/DeNoronha","America/Noronha|Etc/GMT+2","America/Panama|America/Atikokan","America/Panama|America/Cancun","America/Panama|America/Cayman","America/Panama|America/Coral_Harbour","America/Panama|America/Jamaica","America/Panama|EST","America/Panama|Jamaica","America/Phoenix|America/Creston","America/Phoenix|America/Dawson_Creek","America/Phoenix|America/Fort_Nelson","America/Phoenix|America/Hermosillo","America/Phoenix|MST","America/Phoenix|US/Arizona","America/Santiago|Chile/Continental","America/Santo_Domingo|America/Anguilla","America/Santo_Domingo|America/Antigua","America/Santo_Domingo|America/Aruba","America/Santo_Domingo|America/Barbados","America/Santo_Domingo|America/Blanc-Sablon","America/Santo_Domingo|America/Curacao","America/Santo_Domingo|America/Dominica","America/Santo_Domingo|America/Grenada","America/Santo_Domingo|America/Guadeloupe","America/Santo_Domingo|America/Kralendijk","America/Santo_Domingo|America/Lower_Princes","America/Santo_Domingo|America/Marigot","America/Santo_Domingo|America/Martinique","America/Santo_Domingo|America/Montserrat","America/Santo_Domingo|America/Port_of_Spain","America/Santo_Domingo|America/Puerto_Rico","America/Santo_Domingo|America/St_Barthelemy","America/Santo_Domingo|America/St_Kitts","America/Santo_Domingo|America/St_Lucia","America/Santo_Domingo|America/St_Thomas","America/Santo_Domingo|America/St_Vincent","America/Santo_Domingo|America/Tortola","America/Santo_Domingo|America/Virgin","America/Sao_Paulo|Brazil/East","America/St_Johns|Canada/Newfoundland","America/Whitehorse|America/Dawson","America/Whitehorse|Canada/Yukon","Asia/Bangkok|Antarctica/Davis","Asia/Bangkok|Asia/Barnaul","Asia/Bangkok|Asia/Ho_Chi_Minh","Asia/Bangkok|Asia/Hovd","Asia/Bangkok|Asia/Krasnoyarsk","Asia/Bangkok|Asia/Novokuznetsk","Asia/Bangkok|Asia/Novosibirsk","Asia/Bangkok|Asia/Phnom_Penh","Asia/Bangkok|Asia/Saigon","Asia/Bangkok|Asia/Tomsk","Asia/Bangkok|Asia/Vientiane","Asia/Bangkok|Etc/GMT-7","Asia/Bangkok|Indian/Christmas","Asia/Chita|Asia/Dili","Asia/Chita|Asia/Khandyga","Asia/Chita|Asia/Yakutsk","Asia/Chita|Etc/GMT-9","Asia/Chita|Pacific/Palau","Asia/Dhaka|Antarctica/Vostok","Asia/Dhaka|Asia/Almaty","Asia/Dhaka|Asia/Bishkek","Asia/Dhaka|Asia/Dacca","Asia/Dhaka|Asia/Kashgar","Asia/Dhaka|Asia/Omsk","Asia/Dhaka|Asia/Qostanay","Asia/Dhaka|Asia/Thimbu","Asia/Dhaka|Asia/Thimphu","Asia/Dhaka|Asia/Urumqi","Asia/Dhaka|Etc/GMT-6","Asia/Dhaka|Indian/Chagos","Asia/Dubai|Asia/Baku","Asia/Dubai|Asia/Muscat","Asia/Dubai|Asia/Tbilisi","Asia/Dubai|Asia/Yerevan","Asia/Dubai|Etc/GMT-4","Asia/Dubai|Europe/Astrakhan","Asia/Dubai|Europe/Samara","Asia/Dubai|Europe/Saratov","Asia/Dubai|Europe/Ulyanovsk","Asia/Dubai|Indian/Mahe","Asia/Dubai|Indian/Mauritius","Asia/Dubai|Indian/Reunion","Asia/Gaza|Asia/Hebron","Asia/Hong_Kong|Hongkong","Asia/Jakarta|Asia/Pontianak","Asia/Jerusalem|Asia/Tel_Aviv","Asia/Jerusalem|Israel","Asia/Kamchatka|Asia/Anadyr","Asia/Kamchatka|Etc/GMT-12","Asia/Kamchatka|Kwajalein","Asia/Kamchatka|Pacific/Funafuti","Asia/Kamchatka|Pacific/Kwajalein","Asia/Kamchatka|Pacific/Majuro","Asia/Kamchatka|Pacific/Nauru","Asia/Kamchatka|Pacific/Tarawa","Asia/Kamchatka|Pacific/Wake","Asia/Kamchatka|Pacific/Wallis","Asia/Kathmandu|Asia/Katmandu","Asia/Kolkata|Asia/Calcutta","Asia/Kuala_Lumpur|Asia/Brunei","Asia/Kuala_Lumpur|Asia/Choibalsan","Asia/Kuala_Lumpur|Asia/Irkutsk","Asia/Kuala_Lumpur|Asia/Kuching","Asia/Kuala_Lumpur|Asia/Singapore","Asia/Kuala_Lumpur|Asia/Ulaanbaatar","Asia/Kuala_Lumpur|Asia/Ulan_Bator","Asia/Kuala_Lumpur|Etc/GMT-8","Asia/Kuala_Lumpur|Singapore","Asia/Makassar|Asia/Ujung_Pandang","Asia/Rangoon|Asia/Yangon","Asia/Rangoon|Indian/Cocos","Asia/Sakhalin|Asia/Magadan","Asia/Sakhalin|Asia/Srednekolymsk","Asia/Sakhalin|Etc/GMT-11","Asia/Sakhalin|Pacific/Bougainville","Asia/Sakhalin|Pacific/Efate","Asia/Sakhalin|Pacific/Guadalcanal","Asia/Sakhalin|Pacific/Kosrae","Asia/Sakhalin|Pacific/Noumea","Asia/Sakhalin|Pacific/Pohnpei","Asia/Sakhalin|Pacific/Ponape","Asia/Seoul|ROK","Asia/Shanghai|Asia/Chongqing","Asia/Shanghai|Asia/Chungking","Asia/Shanghai|Asia/Harbin","Asia/Shanghai|Asia/Macao","Asia/Shanghai|Asia/Macau","Asia/Shanghai|Asia/Taipei","Asia/Shanghai|PRC","Asia/Shanghai|ROC","Asia/Tashkent|Antarctica/Mawson","Asia/Tashkent|Asia/Aqtau","Asia/Tashkent|Asia/Aqtobe","Asia/Tashkent|Asia/Ashgabat","Asia/Tashkent|Asia/Ashkhabad","Asia/Tashkent|Asia/Atyrau","Asia/Tashkent|Asia/Dushanbe","Asia/Tashkent|Asia/Oral","Asia/Tashkent|Asia/Samarkand","Asia/Tashkent|Asia/Yekaterinburg","Asia/Tashkent|Etc/GMT-5","Asia/Tashkent|Indian/Kerguelen","Asia/Tashkent|Indian/Maldives","Asia/Tehran|Iran","Asia/Tokyo|Japan","Asia/Vladivostok|Antarctica/DumontDUrville","Asia/Vladivostok|Asia/Ust-Nera","Asia/Vladivostok|Etc/GMT-10","Asia/Vladivostok|Pacific/Chuuk","Asia/Vladivostok|Pacific/Port_Moresby","Asia/Vladivostok|Pacific/Truk","Asia/Vladivostok|Pacific/Yap","Atlantic/Azores|America/Scoresbysund","Atlantic/Cape_Verde|Etc/GMT+1","Australia/Adelaide|Australia/Broken_Hill","Australia/Adelaide|Australia/South","Australia/Adelaide|Australia/Yancowinna","Australia/Brisbane|Australia/Lindeman","Australia/Brisbane|Australia/Queensland","Australia/Darwin|Australia/North","Australia/Lord_Howe|Australia/LHI","Australia/Perth|Australia/West","Australia/Sydney|Antarctica/Macquarie","Australia/Sydney|Australia/ACT","Australia/Sydney|Australia/Canberra","Australia/Sydney|Australia/Currie","Australia/Sydney|Australia/Hobart","Australia/Sydney|Australia/Melbourne","Australia/Sydney|Australia/NSW","Australia/Sydney|Australia/Tasmania","Australia/Sydney|Australia/Victoria","Etc/UTC|Etc/UCT","Etc/UTC|Etc/Universal","Etc/UTC|Etc/Zulu","Etc/UTC|UCT","Etc/UTC|UTC","Etc/UTC|Universal","Etc/UTC|Zulu","Europe/Athens|Asia/Nicosia","Europe/Athens|EET","Europe/Athens|Europe/Bucharest","Europe/Athens|Europe/Helsinki","Europe/Athens|Europe/Kiev","Europe/Athens|Europe/Kyiv","Europe/Athens|Europe/Mariehamn","Europe/Athens|Europe/Nicosia","Europe/Athens|Europe/Riga","Europe/Athens|Europe/Sofia","Europe/Athens|Europe/Tallinn","Europe/Athens|Europe/Uzhgorod","Europe/Athens|Europe/Vilnius","Europe/Athens|Europe/Zaporozhye","Europe/Chisinau|Europe/Tiraspol","Europe/Dublin|Eire","Europe/Istanbul|Antarctica/Syowa","Europe/Istanbul|Asia/Aden","Europe/Istanbul|Asia/Baghdad","Europe/Istanbul|Asia/Bahrain","Europe/Istanbul|Asia/Istanbul","Europe/Istanbul|Asia/Kuwait","Europe/Istanbul|Asia/Qatar","Europe/Istanbul|Asia/Riyadh","Europe/Istanbul|Etc/GMT-3","Europe/Istanbul|Europe/Kirov","Europe/Istanbul|Europe/Minsk","Europe/Istanbul|Turkey","Europe/Lisbon|Atlantic/Canary","Europe/Lisbon|Atlantic/Faeroe","Europe/Lisbon|Atlantic/Faroe","Europe/Lisbon|Atlantic/Madeira","Europe/Lisbon|Portugal","Europe/Lisbon|WET","Europe/London|Europe/Belfast","Europe/London|Europe/Guernsey","Europe/London|Europe/Isle_of_Man","Europe/London|Europe/Jersey","Europe/London|GB","Europe/London|GB-Eire","Europe/Moscow|Europe/Simferopol","Europe/Moscow|W-SU","Europe/Paris|Africa/Ceuta","Europe/Paris|Arctic/Longyearbyen","Europe/Paris|Atlantic/Jan_Mayen","Europe/Paris|CET","Europe/Paris|Europe/Amsterdam","Europe/Paris|Europe/Andorra","Europe/Paris|Europe/Belgrade","Europe/Paris|Europe/Berlin","Europe/Paris|Europe/Bratislava","Europe/Paris|Europe/Brussels","Europe/Paris|Europe/Budapest","Europe/Paris|Europe/Busingen","Europe/Paris|Europe/Copenhagen","Europe/Paris|Europe/Gibraltar","Europe/Paris|Europe/Ljubljana","Europe/Paris|Europe/Luxembourg","Europe/Paris|Europe/Madrid","Europe/Paris|Europe/Malta","Europe/Paris|Europe/Monaco","Europe/Paris|Europe/Oslo","Europe/Paris|Europe/Podgorica","Europe/Paris|Europe/Prague","Europe/Paris|Europe/Rome","Europe/Paris|Europe/San_Marino","Europe/Paris|Europe/Sarajevo","Europe/Paris|Europe/Skopje","Europe/Paris|Europe/Stockholm","Europe/Paris|Europe/Tirane","Europe/Paris|Europe/Vaduz","Europe/Paris|Europe/Vatican","Europe/Paris|Europe/Vienna","Europe/Paris|Europe/Warsaw","Europe/Paris|Europe/Zagreb","Europe/Paris|Europe/Zurich","Europe/Paris|Poland","Pacific/Auckland|Antarctica/McMurdo","Pacific/Auckland|Antarctica/South_Pole","Pacific/Auckland|NZ","Pacific/Chatham|NZ-CHAT","Pacific/Easter|Chile/EasterIsland","Pacific/Fakaofo|Etc/GMT-13","Pacific/Fakaofo|Pacific/Enderbury","Pacific/Fakaofo|Pacific/Kanton","Pacific/Galapagos|Etc/GMT+6","Pacific/Gambier|Etc/GMT+9","Pacific/Guam|Pacific/Saipan","Pacific/Honolulu|HST","Pacific/Honolulu|Pacific/Johnston","Pacific/Honolulu|US/Hawaii","Pacific/Kiritimati|Etc/GMT-14","Pacific/Niue|Etc/GMT+11","Pacific/Pago_Pago|Pacific/Midway","Pacific/Pago_Pago|Pacific/Samoa","Pacific/Pago_Pago|US/Samoa","Pacific/Pitcairn|Etc/GMT+8","Pacific/Tahiti|Etc/GMT+10","Pacific/Tahiti|Pacific/Rarotonga"],countries:["AD|Europe/Andorra","AE|Asia/Dubai","AF|Asia/Kabul","AG|America/Puerto_Rico America/Antigua","AI|America/Puerto_Rico America/Anguilla","AL|Europe/Tirane","AM|Asia/Yerevan","AO|Africa/Lagos Africa/Luanda","AQ|Antarctica/Casey Antarctica/Davis Antarctica/Mawson Antarctica/Palmer Antarctica/Rothera Antarctica/Troll Asia/Urumqi Pacific/Auckland Pacific/Port_Moresby Asia/Riyadh Antarctica/McMurdo Antarctica/DumontDUrville Antarctica/Syowa Antarctica/Vostok","AR|America/Argentina/Buenos_Aires America/Argentina/Cordoba America/Argentina/Salta America/Argentina/Jujuy America/Argentina/Tucuman America/Argentina/Catamarca America/Argentina/La_Rioja America/Argentina/San_Juan America/Argentina/Mendoza America/Argentina/San_Luis America/Argentina/Rio_Gallegos America/Argentina/Ushuaia","AS|Pacific/Pago_Pago","AT|Europe/Vienna","AU|Australia/Lord_Howe Antarctica/Macquarie Australia/Hobart Australia/Melbourne Australia/Sydney Australia/Broken_Hill Australia/Brisbane Australia/Lindeman Australia/Adelaide Australia/Darwin Australia/Perth Australia/Eucla","AW|America/Puerto_Rico America/Aruba","AX|Europe/Helsinki Europe/Mariehamn","AZ|Asia/Baku","BA|Europe/Belgrade Europe/Sarajevo","BB|America/Barbados","BD|Asia/Dhaka","BE|Europe/Brussels","BF|Africa/Abidjan Africa/Ouagadougou","BG|Europe/Sofia","BH|Asia/Qatar Asia/Bahrain","BI|Africa/Maputo Africa/Bujumbura","BJ|Africa/Lagos Africa/Porto-Novo","BL|America/Puerto_Rico America/St_Barthelemy","BM|Atlantic/Bermuda","BN|Asia/Kuching Asia/Brunei","BO|America/La_Paz","BQ|America/Puerto_Rico America/Kralendijk","BR|America/Noronha America/Belem America/Fortaleza America/Recife America/Araguaina America/Maceio America/Bahia America/Sao_Paulo America/Campo_Grande America/Cuiaba America/Santarem America/Porto_Velho America/Boa_Vista America/Manaus America/Eirunepe America/Rio_Branco","BS|America/Toronto America/Nassau","BT|Asia/Thimphu","BW|Africa/Maputo Africa/Gaborone","BY|Europe/Minsk","BZ|America/Belize","CA|America/St_Johns America/Halifax America/Glace_Bay America/Moncton America/Goose_Bay America/Toronto America/Nipigon America/Thunder_Bay America/Iqaluit America/Pangnirtung America/Winnipeg America/Rainy_River America/Resolute America/Rankin_Inlet America/Regina America/Swift_Current America/Edmonton America/Cambridge_Bay America/Yellowknife America/Inuvik America/Dawson_Creek America/Fort_Nelson America/Whitehorse America/Dawson America/Vancouver America/Panama America/Puerto_Rico America/Phoenix America/Blanc-Sablon America/Atikokan America/Creston","CC|Asia/Yangon Indian/Cocos","CD|Africa/Maputo Africa/Lagos Africa/Kinshasa Africa/Lubumbashi","CF|Africa/Lagos Africa/Bangui","CG|Africa/Lagos Africa/Brazzaville","CH|Europe/Zurich","CI|Africa/Abidjan","CK|Pacific/Rarotonga","CL|America/Santiago America/Punta_Arenas Pacific/Easter","CM|Africa/Lagos Africa/Douala","CN|Asia/Shanghai Asia/Urumqi","CO|America/Bogota","CR|America/Costa_Rica","CU|America/Havana","CV|Atlantic/Cape_Verde","CW|America/Puerto_Rico America/Curacao","CX|Asia/Bangkok Indian/Christmas","CY|Asia/Nicosia Asia/Famagusta","CZ|Europe/Prague","DE|Europe/Zurich Europe/Berlin Europe/Busingen","DJ|Africa/Nairobi Africa/Djibouti","DK|Europe/Berlin Europe/Copenhagen","DM|America/Puerto_Rico America/Dominica","DO|America/Santo_Domingo","DZ|Africa/Algiers","EC|America/Guayaquil Pacific/Galapagos","EE|Europe/Tallinn","EG|Africa/Cairo","EH|Africa/El_Aaiun","ER|Africa/Nairobi Africa/Asmara","ES|Europe/Madrid Africa/Ceuta Atlantic/Canary","ET|Africa/Nairobi Africa/Addis_Ababa","FI|Europe/Helsinki","FJ|Pacific/Fiji","FK|Atlantic/Stanley","FM|Pacific/Kosrae Pacific/Port_Moresby Pacific/Guadalcanal Pacific/Chuuk Pacific/Pohnpei","FO|Atlantic/Faroe","FR|Europe/Paris","GA|Africa/Lagos Africa/Libreville","GB|Europe/London","GD|America/Puerto_Rico America/Grenada","GE|Asia/Tbilisi","GF|America/Cayenne","GG|Europe/London Europe/Guernsey","GH|Africa/Abidjan Africa/Accra","GI|Europe/Gibraltar","GL|America/Nuuk America/Danmarkshavn America/Scoresbysund America/Thule","GM|Africa/Abidjan Africa/Banjul","GN|Africa/Abidjan Africa/Conakry","GP|America/Puerto_Rico America/Guadeloupe","GQ|Africa/Lagos Africa/Malabo","GR|Europe/Athens","GS|Atlantic/South_Georgia","GT|America/Guatemala","GU|Pacific/Guam","GW|Africa/Bissau","GY|America/Guyana","HK|Asia/Hong_Kong","HN|America/Tegucigalpa","HR|Europe/Belgrade Europe/Zagreb","HT|America/Port-au-Prince","HU|Europe/Budapest","ID|Asia/Jakarta Asia/Pontianak Asia/Makassar Asia/Jayapura","IE|Europe/Dublin","IL|Asia/Jerusalem","IM|Europe/London Europe/Isle_of_Man","IN|Asia/Kolkata","IO|Indian/Chagos","IQ|Asia/Baghdad","IR|Asia/Tehran","IS|Africa/Abidjan Atlantic/Reykjavik","IT|Europe/Rome","JE|Europe/London Europe/Jersey","JM|America/Jamaica","JO|Asia/Amman","JP|Asia/Tokyo","KE|Africa/Nairobi","KG|Asia/Bishkek","KH|Asia/Bangkok Asia/Phnom_Penh","KI|Pacific/Tarawa Pacific/Kanton Pacific/Kiritimati","KM|Africa/Nairobi Indian/Comoro","KN|America/Puerto_Rico America/St_Kitts","KP|Asia/Pyongyang","KR|Asia/Seoul","KW|Asia/Riyadh Asia/Kuwait","KY|America/Panama America/Cayman","KZ|Asia/Almaty Asia/Qyzylorda Asia/Qostanay Asia/Aqtobe Asia/Aqtau Asia/Atyrau Asia/Oral","LA|Asia/Bangkok Asia/Vientiane","LB|Asia/Beirut","LC|America/Puerto_Rico America/St_Lucia","LI|Europe/Zurich Europe/Vaduz","LK|Asia/Colombo","LR|Africa/Monrovia","LS|Africa/Johannesburg Africa/Maseru","LT|Europe/Vilnius","LU|Europe/Brussels Europe/Luxembourg","LV|Europe/Riga","LY|Africa/Tripoli","MA|Africa/Casablanca","MC|Europe/Paris Europe/Monaco","MD|Europe/Chisinau","ME|Europe/Belgrade Europe/Podgorica","MF|America/Puerto_Rico America/Marigot","MG|Africa/Nairobi Indian/Antananarivo","MH|Pacific/Tarawa Pacific/Kwajalein Pacific/Majuro","MK|Europe/Belgrade Europe/Skopje","ML|Africa/Abidjan Africa/Bamako","MM|Asia/Yangon","MN|Asia/Ulaanbaatar Asia/Hovd Asia/Choibalsan","MO|Asia/Macau","MP|Pacific/Guam Pacific/Saipan","MQ|America/Martinique","MR|Africa/Abidjan Africa/Nouakchott","MS|America/Puerto_Rico America/Montserrat","MT|Europe/Malta","MU|Indian/Mauritius","MV|Indian/Maldives","MW|Africa/Maputo Africa/Blantyre","MX|America/Mexico_City America/Cancun America/Merida America/Monterrey America/Matamoros America/Mazatlan America/Chihuahua America/Ojinaga America/Hermosillo America/Tijuana America/Bahia_Banderas","MY|Asia/Kuching Asia/Singapore Asia/Kuala_Lumpur","MZ|Africa/Maputo","NA|Africa/Windhoek","NC|Pacific/Noumea","NE|Africa/Lagos Africa/Niamey","NF|Pacific/Norfolk","NG|Africa/Lagos","NI|America/Managua","NL|Europe/Brussels Europe/Amsterdam","NO|Europe/Berlin Europe/Oslo","NP|Asia/Kathmandu","NR|Pacific/Nauru","NU|Pacific/Niue","NZ|Pacific/Auckland Pacific/Chatham","OM|Asia/Dubai Asia/Muscat","PA|America/Panama","PE|America/Lima","PF|Pacific/Tahiti Pacific/Marquesas Pacific/Gambier","PG|Pacific/Port_Moresby Pacific/Bougainville","PH|Asia/Manila","PK|Asia/Karachi","PL|Europe/Warsaw","PM|America/Miquelon","PN|Pacific/Pitcairn","PR|America/Puerto_Rico","PS|Asia/Gaza Asia/Hebron","PT|Europe/Lisbon Atlantic/Madeira Atlantic/Azores","PW|Pacific/Palau","PY|America/Asuncion","QA|Asia/Qatar","RE|Asia/Dubai Indian/Reunion","RO|Europe/Bucharest","RS|Europe/Belgrade","RU|Europe/Kaliningrad Europe/Moscow Europe/Simferopol Europe/Kirov Europe/Volgograd Europe/Astrakhan Europe/Saratov Europe/Ulyanovsk Europe/Samara Asia/Yekaterinburg Asia/Omsk Asia/Novosibirsk Asia/Barnaul Asia/Tomsk Asia/Novokuznetsk Asia/Krasnoyarsk Asia/Irkutsk Asia/Chita Asia/Yakutsk Asia/Khandyga Asia/Vladivostok Asia/Ust-Nera Asia/Magadan Asia/Sakhalin Asia/Srednekolymsk Asia/Kamchatka Asia/Anadyr","RW|Africa/Maputo Africa/Kigali","SA|Asia/Riyadh","SB|Pacific/Guadalcanal","SC|Asia/Dubai Indian/Mahe","SD|Africa/Khartoum","SE|Europe/Berlin Europe/Stockholm","SG|Asia/Singapore","SH|Africa/Abidjan Atlantic/St_Helena","SI|Europe/Belgrade Europe/Ljubljana","SJ|Europe/Berlin Arctic/Longyearbyen","SK|Europe/Prague Europe/Bratislava","SL|Africa/Abidjan Africa/Freetown","SM|Europe/Rome Europe/San_Marino","SN|Africa/Abidjan Africa/Dakar","SO|Africa/Nairobi Africa/Mogadishu","SR|America/Paramaribo","SS|Africa/Juba","ST|Africa/Sao_Tome","SV|America/El_Salvador","SX|America/Puerto_Rico America/Lower_Princes","SY|Asia/Damascus","SZ|Africa/Johannesburg Africa/Mbabane","TC|America/Grand_Turk","TD|Africa/Ndjamena","TF|Asia/Dubai Indian/Maldives Indian/Kerguelen","TG|Africa/Abidjan Africa/Lome","TH|Asia/Bangkok","TJ|Asia/Dushanbe","TK|Pacific/Fakaofo","TL|Asia/Dili","TM|Asia/Ashgabat","TN|Africa/Tunis","TO|Pacific/Tongatapu","TR|Europe/Istanbul","TT|America/Puerto_Rico America/Port_of_Spain","TV|Pacific/Tarawa Pacific/Funafuti","TW|Asia/Taipei","TZ|Africa/Nairobi Africa/Dar_es_Salaam","UA|Europe/Simferopol Europe/Kyiv Europe/Uzhgorod Europe/Zaporozhye","UG|Africa/Nairobi Africa/Kampala","UM|Pacific/Pago_Pago Pacific/Tarawa Pacific/Honolulu Pacific/Midway Pacific/Wake","US|America/New_York America/Detroit America/Kentucky/Louisville America/Kentucky/Monticello America/Indiana/Indianapolis America/Indiana/Vincennes America/Indiana/Winamac America/Indiana/Marengo America/Indiana/Petersburg America/Indiana/Vevay America/Chicago America/Indiana/Tell_City America/Indiana/Knox America/Menominee America/North_Dakota/Center America/North_Dakota/New_Salem America/North_Dakota/Beulah America/Denver America/Boise America/Phoenix America/Los_Angeles America/Anchorage America/Juneau America/Sitka America/Metlakatla America/Yakutat America/Nome America/Adak Pacific/Honolulu","UY|America/Montevideo","UZ|Asia/Samarkand Asia/Tashkent","VA|Europe/Rome Europe/Vatican","VC|America/Puerto_Rico America/St_Vincent","VE|America/Caracas","VG|America/Puerto_Rico America/Tortola","VI|America/Puerto_Rico America/St_Thomas","VN|Asia/Bangkok Asia/Ho_Chi_Minh","VU|Pacific/Efate","WF|Pacific/Tarawa Pacific/Wallis","WS|Pacific/Apia","YE|Asia/Riyadh Asia/Aden","YT|Africa/Nairobi Indian/Mayotte","ZA|Africa/Johannesburg","ZM|Africa/Maputo Africa/Lusaka","ZW|Africa/Maputo Africa/Harare"]}),c}); diff --git a/web-ui/src/main/resources/catalog/lib/moment-timezone-with-data-1970-2030.min.js b/web-ui/src/main/resources/catalog/lib/moment-timezone-with-data-1970-2030.min.js new file mode 100644 index 00000000000..34bcea30177 --- /dev/null +++ b/web-ui/src/main/resources/catalog/lib/moment-timezone-with-data-1970-2030.min.js @@ -0,0 +1 @@ +!function(c,M){"use strict";"object"==typeof module&&module.exports?module.exports=M(require("moment")):"function"==typeof define&&define.amd?define(["moment"],M):M(c.moment)}(this,function(o){"use strict";void 0===o.version&&o.default&&(o=o.default);var M,z={},i={},b={},e={},r={},c=(o&&"string"==typeof o.version||S("Moment Timezone requires Moment.js. See https://momentjs.com/timezone/docs/#/use-it/browser/"),o.version.split(".")),a=+c[0],A=+c[1];function n(c){return 96= 2.6.0. You are using Moment.js "+o.version+". See momentjs.com"),f.prototype={_set:function(c){this.name=c.name,this.abbrs=c.abbrs,this.untils=c.untils,this.offsets=c.offsets,this.population=c.population},_index:function(c){for(var M=+c,a=this.untils,A=0;A= 2.9.0. You are using Moment.js "+o.version+"."),o.defaultZone=c?X(c):null,o};c=o.momentProperties;return"[object Array]"===Object.prototype.toString.call(c)?(c.push("_z"),c.push("_a")):c&&(c._z=null),T({version:"2023c",zones:["Africa/Abidjan|GMT|0|0||48e5","Africa/Nairobi|EAT|-30|0||47e5","Africa/Algiers|WET WEST CET CEST|0 -10 -10 -20|01012320102|3bX0 11A0 dDd0 17b0 11B0 1cN0 2Dy0 1cN0 1fB0 1cL0|26e5","Africa/Lagos|WAT|-10|0||17e6","Africa/Bissau|-01 GMT|10 0|01|cap0|39e4","Africa/Maputo|CAT|-20|0||26e5","Africa/Cairo|EET EEST|-20 -30|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|LX0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1WL0 rd0 1Rz0 wp0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1qL0 Xd0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1ny0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 WL0 1qN0 Rb0 1wp0 On0 1zd0 Lz0 1EN0 Fb0 c10 8n0 8Nd0 gL0 e10 mn0 kSp0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0|15e6","Africa/Casablanca|+00 +01|0 -10|01010101010101010101010101010101010101010101010101010101010101010101010|aS00 rz0 43d0 AL0 1Nd0 XX0 1Cp0 pz0 dEp0 4mn0 SyN0 AL0 1Nd0 wn0 1FB0 Db0 1zd0 Lz0 1Nf0 wM0 co0 go0 1o00 s00 dA0 vc0 11A0 A00 e00 y00 11A0 uM0 e00 Dc0 11A0 s00 e00 IM0 WM0 mo0 gM0 LA0 WM0 jA0 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600|32e5","Africa/Ceuta|WET WEST CET CEST|0 -10 -10 -20|0101010102323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|aS00 rz0 43d0 AL0 1Nd0 XX0 1Cp0 pz0 dEp0 4VB0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|85e3","Africa/El_Aaiun|-01 +00 +01|10 0 -10|01212121212121212121212121212121212121212121212121212121212121212121|fi10 6L0 AL0 1Nd0 XX0 1Cp0 pz0 1cBB0 AL0 1Nd0 wn0 1FB0 Db0 1zd0 Lz0 1Nf0 wM0 co0 go0 1o00 s00 dA0 vc0 11A0 A00 e00 y00 11A0 uM0 e00 Dc0 11A0 s00 e00 IM0 WM0 mo0 gM0 LA0 WM0 jA0 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600|20e4","Africa/Johannesburg|SAST|-20|0||84e5","Africa/Juba|CAT CAST EAT|-20 -30 -30|01010101010101010101010101010101020|LW0 16L0 1iN0 17b0 1jd0 17b0 1ip0 17z0 1i10 17X0 1hB0 18n0 1hd0 19b0 1gp0 19z0 1iN0 17b0 1ip0 17z0 1i10 18n0 1hd0 18L0 1gN0 19b0 1gp0 19z0 1iN0 17z0 1i10 17X0 yGd0 PeX0|","Africa/Khartoum|CAT CAST EAT|-20 -30 -30|01010101010101010101010101010101020|LW0 16L0 1iN0 17b0 1jd0 17b0 1ip0 17z0 1i10 17X0 1hB0 18n0 1hd0 19b0 1gp0 19z0 1iN0 17b0 1ip0 17z0 1i10 18n0 1hd0 18L0 1gN0 19b0 1gp0 19z0 1iN0 17z0 1i10 17X0 yGd0 HjL0|51e5","Africa/Monrovia|MMT GMT|I.u 0|01|4SoI.u|11e5","Africa/Ndjamena|WAT WAST|-10 -20|010|nNb0 Wn0|13e5","Africa/Sao_Tome|GMT WAT|0 -10|010|1UQN0 2q00|","Africa/Tripoli|EET CET CEST|-20 -10 -20|0121212121212121210120120|tda0 A10 1db0 1cN0 1db0 1dd0 1db0 1eN0 1bb0 1e10 1cL0 1c10 1db0 1dd0 1db0 1cN0 1db0 1q10 fAn0 1ep0 1db0 AKq0 TA0 1o00|11e5","Africa/Tunis|CET CEST|-10 -20|0101010101010101010|hOn0 WM0 1rA0 11c0 nwo0 Ko0 1cM0 1cM0 1rA0 10M0 zuM0 10N0 1aN0 1qM0 WM0 1qM0 11A0 1o00|20e5","Africa/Windhoek|SAST CAT WAT|-20 -20 -10|01212121212121212121212121212121212121212121212121|Ndy0 9Io0 16P0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0|32e4","America/Adak|BST BDT AHST HST HDT|b0 a0 a0 a0 90|0101010101010101010101010101234343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|Kd0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 cm0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|326","America/Anchorage|AHST AHDT YST AKST AKDT|a0 90 90 90 80|0101010101010101010101010101234343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|Kc0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 cm0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|30e4","America/Puerto_Rico|AST|40|0||24e5","America/Araguaina|-03 -02|30 20|01010101010101010101010101010|CxD0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 dMN0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 ny10 Lz0|14e4","America/Argentina/Buenos_Aires|-03 -02|30 20|01010101010101010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wp0 Rb0 1wp0 TX0 A4p0 uL0 1qN0 WL0|","America/Argentina/Catamarca|-03 -02 -04|30 20 40|01010101210102010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wq0 Ra0 1wp0 TX0 rlB0 7B0 8zb0 uL0|","America/Argentina/Cordoba|-03 -02 -04|30 20 40|01010101210101010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wq0 Ra0 1wp0 TX0 A4p0 uL0 1qN0 WL0|","America/Argentina/Jujuy|-03 -02 -04|30 20 40|010101202101010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1ze0 TX0 1ld0 WK0 1wp0 TX0 A4p0 uL0|","America/Argentina/La_Rioja|-03 -02 -04|30 20 40|010101012010102010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Qn0 qO0 16n0 Rb0 1wp0 TX0 rlB0 7B0 8zb0 uL0|","America/Argentina/Mendoza|-03 -02 -04|30 20 40|01010120202102010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1u20 SL0 1vd0 Tb0 1wp0 TW0 ri10 Op0 7TX0 uL0|","America/Argentina/Rio_Gallegos|-03 -02 -04|30 20 40|01010101010102010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wp0 Rb0 1wp0 TX0 rlB0 7B0 8zb0 uL0|","America/Argentina/Salta|-03 -02 -04|30 20 40|010101012101010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wq0 Ra0 1wp0 TX0 A4p0 uL0|","America/Argentina/San_Juan|-03 -02 -04|30 20 40|010101012010102010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Qn0 qO0 16n0 Rb0 1wp0 TX0 rld0 m10 8lb0 uL0|","America/Argentina/San_Luis|-03 -02 -04|30 20 40|010101202020102020|9Rf0 Db0 zvd0 Bz0 1tB0 XX0 1q20 SL0 AN0 vDb0 m10 8lb0 8L0 jd0 1qN0 WL0 1qN0|","America/Argentina/Tucuman|-03 -02 -04|30 20 40|0101010121010201010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wq0 Ra0 1wp0 TX0 rlB0 4N0 8BX0 uL0 1qN0 WL0|","America/Argentina/Ushuaia|-03 -02 -04|30 20 40|01010101010102010|9Rf0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wp0 Rb0 1wp0 TX0 rkN0 8p0 8zb0 uL0|","America/Asuncion|-04 -03|40 30|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|6FE0 3CL0 3Dd0 10L0 1pB0 10n0 1pB0 10n0 1pB0 1cL0 1dd0 1db0 1dd0 1cL0 1dd0 1cL0 1dd0 1cL0 1dd0 1db0 1dd0 1cL0 1dd0 1cL0 1dd0 1cL0 1dd0 1db0 1dd0 1cL0 1lB0 14n0 1dd0 1cL0 1fd0 WL0 1rd0 1aL0 1dB0 Xz0 1qp0 Xb0 1qN0 10L0 1rB0 TX0 1tB0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 1cL0 WN0 1qL0 11B0 1nX0 1ip0 WL0 1qN0 WL0 1qN0 WL0 1tB0 TX0 1tB0 TX0 1tB0 19X0 1a10 1fz0 1a10 1fz0 1cN0 17b0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0|28e5","America/Panama|EST|50|0||15e5","America/Bahia_Banderas|PST MST MDT CDT CST|80 70 60 50 60|01212121212121212121212121212134343434343434343434343434|80 13Vd0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nW0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0|84e3","America/Bahia|-03 -02|30 20|010101010101010101010101010101010101010|CxD0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 1EN0 Lz0 1C10 IL0 1HB0 Db0 1HB0 On0 1zd0 On0 1zd0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 l5B0 Rb0|27e5","America/Barbados|AST ADT|40 30|010101010|i7G0 IL0 1ip0 17b0 1ip0 17b0 1ld0 13b0|28e4","America/Belem|-03 -02|30 20|0101010|CxD0 Rb0 1tB0 IL0 1Fd0 FX0|20e5","America/Belize|CST CDT|60 50|01010|9xG0 qn0 lxB0 mn0|57e3","America/Boa_Vista|-04 -03|40 30|01010101010|CxE0 Rb0 1tB0 IL0 1Fd0 FX0 smp0 WL0 1tB0 2L0|62e2","America/Bogota|-05 -04|50 40|010|Snh0 1PX0|90e5","America/Boise|MST MDT|70 60|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K90 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 Dd0 1Kn0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|21e4","America/Cambridge_Bay|MST MDT CST CDT EST|70 60 60 50 50|010101010101010101010101010101010101010101010101010101012342101010101010101010101010101010101010101010101010101010101010|5E90 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11A0 1nX0 2K0 WQ0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|15e2","America/Campo_Grande|-04 -03|40 30|010101010101010101010101010101010101010101010101010101010101010101010|CxE0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 1EN0 Lz0 1C10 IL0 1HB0 Db0 1HB0 On0 1zd0 On0 1zd0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 1C10 Lz0 1Ip0 HX0 1zd0 On0 1HB0 IL0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 Rb0 1zd0 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1HB0 FX0|77e4","America/Cancun|CST EST EDT CDT|60 50 40 50|012121230303030303030303030303030303030301|t9G0 yLB0 1lb0 14p0 1lb0 14p0 Lz0 xB0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 Dd0|63e4","America/Caracas|-04 -0430|40 4u|010|1wmv0 kqo0|29e5","America/Cayenne|-03|30|0||58e3","America/Chicago|CST CDT|60 50|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K80 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|92e5","America/Chihuahua|CST CDT MDT MST|60 50 60 70|0101023232323232323232323232323232323232323232323232320|13Vk0 1lb0 14p0 1lb0 14q0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0|81e4","America/Ciudad_Juarez|CST CDT MDT MST|60 50 60 70|010102323232323232323232323232323232323232323232323232032323232323232323|13Vk0 1lb0 14p0 1lb0 14q0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 U10 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1wn0 cm0 EP0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Costa_Rica|CST CDT|60 50|010101010|mgS0 Db0 1Kp0 Db0 pRB0 15b0 1kp0 mL0|12e5","America/Phoenix|MST|70|0||42e5","America/Cuiaba|-04 -03|40 30|0101010101010101010101010101010101010101010101010101010101010101010|CxE0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 1EN0 Lz0 1C10 IL0 1HB0 Db0 1HB0 On0 1zd0 On0 1zd0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 4a10 HX0 1zd0 On0 1HB0 IL0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 Rb0 1zd0 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1HB0 FX0|54e4","America/Danmarkshavn|-03 -02 GMT|30 20 0|0101010101010101010101010101010102|oXh0 19U0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 DC0|8","America/Dawson_Creek|PST PDT MST|80 70 70|0101012|Ka0 1cL0 1cN0 1fz0 1cN0 ML0|12e3","America/Dawson|YST PST PDT MST|90 80 70 70|012121212121212121212121212121212121212121212121212121212121212121212121212121212123|9ix0 fNd0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1z90|13e2","America/Denver|MST MDT|70 60|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K90 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|26e5","America/Detroit|EST EDT|50 40|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|85H0 1cL0 s10 1Vz0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|37e5","America/Edmonton|MST MDT|70 60|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|5E90 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|10e5","America/Eirunepe|-05 -04|50 40|01010101010|CxF0 Rb0 1tB0 IL0 1Fd0 FX0 dPB0 On0 yTd0 d5X0|31e3","America/El_Salvador|CST CDT|60 50|01010|Gcu0 WL0 1qN0 WL0|11e5","America/Tijuana|PST PDT|80 70|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|fmy0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 U10 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|20e5","America/Fort_Nelson|PST PDT MST|80 70 70|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010102|Ka0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0|39e2","America/Fort_Wayne|EST EDT|50 40|01010101010101010101010101010101010101010101010101010|K70 1cL0 1qhd0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Fortaleza|-03 -02|30 20|01010101010101010|CxD0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 nsp0 WL0 1tB0 5z0 2mN0 On0|34e5","America/Glace_Bay|AST ADT|40 30|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|5E60 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|19e3","America/Godthab|-03 -02 -01|30 20 10|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010121212121212121|oXh0 19U0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 2so0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|17e3","America/Goose_Bay|AST ADT ADDT|40 30 20|010101010101010101010101010101010101020101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K60 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14n1 1lb0 14p0 1nW0 11C0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zcX Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|76e2","America/Grand_Turk|EST EDT AST|50 40 40|0101010101010101010101010101010101010101010101010101010101010101010101010210101010101010101010101010|mG70 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 7jA0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|37e2","America/Guatemala|CST CDT|60 50|010101010|9tG0 An0 mtd0 Nz0 ifB0 17b0 zDB0 11z0|13e5","America/Guayaquil|-05 -04|50 40|010|TKR0 rz0|27e5","America/Guyana|-0345 -03 -04|3J 30 40|012|dzfJ Ey0f|80e4","America/Halifax|AST ADT|40 30|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K60 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|39e4","America/Havana|CST CDT|50 40|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K50 1cL0 1cN0 1fz0 1cN0 14n0 1ld0 14L0 1kN0 15b0 1kp0 1cL0 1cN0 1fz0 1a10 1fz0 1fB0 11z0 14p0 1nX0 11B0 1nX0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 14n0 1ld0 14n0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 1a10 1in0 1a10 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 17c0 1o00 11A0 1qM0 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 11A0 6i00 Rc0 1wo0 U00 1tA0 Rc0 1wo0 U00 1wo0 U00 1zc0 U00 1qM0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0|21e5","America/Hermosillo|PST MST MDT|80 70 60|01212121|80 13Vd0 1lb0 14p0 1lb0 14p0 1lb0|64e4","America/Indiana/Knox|CST CDT EST|60 50 50|01010101010101010101010101010101010101010101210101010101010101010101010101010101010101010101010|K80 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 z8o0 1o00 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Indiana/Marengo|EST EDT CDT|50 40 50|010101010201010101010101010101010101010101010101010101010101010|K70 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1VA0 LA0 1BX0 1e6p0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Indiana/Petersburg|CST CDT EST EDT|60 50 50 40|0101010101010101210123232323232323232323232323232323232323232323232|K80 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 19co0 1o00 Rd0 1zb0 Oo0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Indiana/Tell_City|EST EDT CDT CST|50 40 50 60|01023232323232323232323232323232323232323232323232323|K70 1cL0 1qhd0 1o00 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Indiana/Vevay|EST EDT|50 40|010101010101010101010101010101010101010101010101010101010|K70 1cL0 1cN0 1fz0 1cN0 1cL0 1lnd0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Indiana/Vincennes|EST EDT CDT CST|50 40 50 60|01023201010101010101010101010101010101010101010101010|K70 1cL0 1qhd0 1o00 Rd0 1zb0 Oo0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Indiana/Winamac|EST EDT CDT CST|50 40 50 60|01023101010101010101010101010101010101010101010101010|K70 1cL0 1qhd0 1o00 Rd0 1za0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Inuvik|PST PDT MDT MST|80 70 60 70|01010101010101023232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323|5Ea0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cK0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|35e2","America/Iqaluit|EST EDT CST CDT|50 40 60 50|01010101010101010101010101010101010101010101010101010101230101010101010101010101010101010101010101010101010101010101010|5E70 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11C0 1nX0 11A0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|67e2","America/Jamaica|EST EDT|50 40|010101010101010101010|9Kv0 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0|94e4","America/Juneau|PST PDT YDT YST AKST AKDT|80 70 80 90 90 80|0101010101010101010102010101345454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454|Ka0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cM0 1cM0 1cL0 1cN0 1fz0 1a10 1fz0 co0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|33e3","America/Kentucky/Louisville|EST EDT CDT|50 40 50|010101010201010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K70 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1VA0 LA0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Kentucky/Monticello|CST CDT EST EDT|60 50 50 40|010101010101010101010101010101010101010101010101010101010101012323232323232323232323232323232323232323232323232323232323232|K80 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11A0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/La_Paz|-04|40|0||19e5","America/Lima|-05 -04|50 40|010101010|CVF0 zX0 1O10 zX0 6Gp0 zX0 98p0 zX0|11e6","America/Los_Angeles|PST PDT|80 70|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|Ka0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|15e6","America/Maceio|-03 -02|30 20|0101010101010101010|CxD0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 dMN0 Lz0 8Q10 WL0 1tB0 5z0 2mN0 On0|93e4","America/Managua|CST EST CDT|60 50 50|010202010102020|86u0 4mn0 9Up0 Dz0 1K10 Dz0 s3F0 1KH0 DB0 9In0 k8p0 19X0 1o30 11y0|22e5","America/Manaus|-04 -03|40 30|010101010|CxE0 Rb0 1tB0 IL0 1Fd0 FX0 dPB0 On0|19e5","America/Martinique|AST ADT|40 30|010|oXg0 19X0|39e4","America/Matamoros|CST CDT|60 50|0101010101010101010101010101010101010101010101010101010101010101010101010|IqU0 1nX0 i6p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 U10 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|45e4","America/Mazatlan|PST MST MDT|80 70 60|01212121212121212121212121212121212121212121212121212121|80 13Vd0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0|44e4","America/Menominee|EST CDT CST|50 50 60|012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212|85H0 1cM0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|85e2","America/Merida|CST EST CDT|60 50 50|010202020202020202020202020202020202020202020202020202020|t9G0 2hz0 wu30 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0|11e5","America/Metlakatla|PST PDT AKST AKDT|80 70 90 80|0101010101010101010101010101023232302323232323232323232323232|Ka0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1hU10 Rd0 1zb0 Op0 1zb0 Op0 1zb0 uM0 jB0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|14e2","America/Mexico_City|CST CDT|60 50|0101010101010101010101010101010101010101010101010101010|13Vk0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0|20e6","America/Miquelon|AST -03 -02|40 30 20|012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|p9g0 gQ10 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|61e2","America/Moncton|AST ADT|40 30|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K60 1cL0 1cN0 1fz0 1cN0 1cL0 3Cp0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14n1 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 ReX 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|64e3","America/Monterrey|CST CDT|60 50|010101010101010101010101010101010101010101010101010101010|IqU0 1nX0 i6p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0|41e5","America/Montevideo|-03 -02 -0130 -0230|30 20 1u 2u|0101023010101010101010101010101010101010101010101010|JD0 jX0 4vB0 xz0 3Cp0 mmu 1a10 IMu Db0 4c10 uL0 1Nd0 An0 1SN0 uL0 mp0 28L0 iPB0 un0 1SN0 xz0 1zd0 Lz0 1zd0 Rb0 1zd0 On0 1wp0 Rb0 s8p0 1fB0 1ip0 11z0 1ld0 14n0 1o10 11z0 1o10 11z0 1o10 14n0 1ld0 14n0 1ld0 14n0 1o10 11z0 1o10 11z0 1o10 11z0|17e5","America/Toronto|EST EDT|50 40|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K70 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|65e5","America/New_York|EST EDT|50 40|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K70 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|21e6","America/Nome|BST BDT YST AKST AKDT|b0 a0 90 90 80|0101010101010101010101010101234343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|Kd0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 cl0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|38e2","America/Noronha|-02 -01|20 10|01010101010101010|CxC0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 nsp0 WL0 1tB0 2L0 2pB0 On0|30e2","America/North_Dakota/Beulah|MST MDT CST CDT|70 60 60 50|010101010101010101010101010101010101010101010101010101010101010101010101010101010123232323232323232323232323232323232323232|K90 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Oo0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/North_Dakota/Center|MST MDT CST CDT|70 60 60 50|010101010101010101010101010101010101010101010123232323232323232323232323232323232323232323232323232323232323232323232323232|K90 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14o0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/North_Dakota/New_Salem|MST MDT CST CDT|70 60 60 50|010101010101010101010101010101010101010101010101010101010101010101012323232323232323232323232323232323232323232323232323232|K90 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14o0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|","America/Ojinaga|CST CDT MDT MST|60 50 60 70|01010232323232323232323232323232323232323232323232323201010101010101010|13Vk0 1lb0 14p0 1lb0 14q0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 U10 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1wn0 Rc0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|23e3","America/Paramaribo|-0330 -03|3u 30|01|zSPu|24e4","America/Port-au-Prince|EST EDT|50 40|01010101010101010101010101010101010101010101010101010101010101010101010|wu50 19X0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14q0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 i6n0 1nX0 11B0 1nX0 d430 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 3iN0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|23e5","America/Rio_Branco|-05 -04|50 40|010101010|CxF0 Rb0 1tB0 IL0 1Fd0 FX0 NBd0 d5X0|31e4","America/Porto_Velho|-04 -03|40 30|0101010|CxE0 Rb0 1tB0 IL0 1Fd0 FX0|37e4","America/Punta_Arenas|-03 -04|30 40|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|yP0 1ip0 11z0 1o10 11z0 1qN0 WL0 1ld0 14n0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 1cL0 1cN0 11z0 1o10 11z0 1qN0 WL0 1fB0 19X0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1ip0 1fz0 1fB0 11z0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1o10 19X0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0|","America/Winnipeg|CST CDT|60 50|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K80 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1a00 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1a00 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|66e4","America/Rankin_Inlet|CST CDT EST|60 50 50|01010101010101010101010101010101010101010101010101010101012101010101010101010101010101010101010101010101010101010101010|5E80 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|26e2","America/Recife|-03 -02|30 20|01010101010101010|CxD0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 nsp0 WL0 1tB0 2L0 2pB0 On0|33e5","America/Regina|CST|60|0||19e4","America/Resolute|CST CDT EST|60 50 50|01010101010101010101010101010101010101010101010101010101012101010101012101010101010101010101010101010101010101010101010|5E80 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|229","America/Santarem|-04 -03|40 30|01010101|CxE0 Rb0 1tB0 IL0 1Fd0 FX0 NBd0|21e4","America/Santiago|-03 -04|30 40|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|yP0 1ip0 11z0 1o10 11z0 1qN0 WL0 1ld0 14n0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 1cL0 1cN0 11z0 1o10 11z0 1qN0 WL0 1fB0 19X0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1ip0 1fz0 1fB0 11z0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1o10 19X0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1zb0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0|62e5","America/Santo_Domingo|-0430 EST AST|4u 50 40|0101010101212|ksu 1Cou yLu 1RAu wLu 1QMu xzu 1Q0u xXu 1PAu 13jB0 e00|29e5","America/Sao_Paulo|-03 -02|30 20|010101010101010101010101010101010101010101010101010101010101010101010|CxD0 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 1EN0 Lz0 1C10 IL0 1HB0 Db0 1HB0 On0 1zd0 On0 1zd0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 1C10 Lz0 1Ip0 HX0 1zd0 On0 1HB0 IL0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 Rb0 1zd0 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1HB0 FX0|20e6","America/Scoresbysund|-02 -01 +00|20 10 0|0102121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|oXg0 1a00 1cK0 1cL0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|452","America/Sitka|PST PDT YST AKST AKDT|80 70 90 90 80|0101010101010101010101010101234343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|Ka0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 co0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|90e2","America/St_Johns|NST NDT NDDT|3u 2u 1u|010101010101010101010101010101010101020101010101010101010101010101010101010101010101010101010101010101010101010101010101010|K5u 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14n1 1lb0 14p0 1nW0 11C0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zcX Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|11e4","America/Swift_Current|MST CST|70 60|01|5E90|16e3","America/Tegucigalpa|CST CDT|60 50|0101010|Gcu0 WL0 1qN0 WL0 GRd0 AL0|11e5","America/Thule|AST ADT|40 30|010101010101010101010101010101010101010101010101010101010101010101010101010101010|PHG0 1cL0 1cN0 1cL0 1fB0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|656","America/Vancouver|PST PDT|80 70|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|Ka0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|23e5","America/Whitehorse|PST PDT MST|80 70 70|01010101010101010101010101010101010101010101010101010101010101010101010101010101012|p7K0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1z90|23e3","America/Yakutat|YST YDT AKST AKDT|90 80 90 80|0101010101010101010101010101023232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|Kb0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 cn0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|642","Antarctica/Casey|+08 +11|-80 -b0|010101010101|1ARS0 T90 40P0 KL0 blz0 3m10 1o30 14k0 1kr0 12l0 1o01|10","Antarctica/Davis|+07 +05|-70 -50|01010|1ART0 VB0 3Wn0 KN0|70","Pacific/Port_Moresby|+10|-a0|0||25e4","Antarctica/Macquarie|AEDT AEST|-b0 -a0|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|qg0 1wo0 U00 1wo0 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1qM0 WM0 1qM0 Oo0 1zc0 Oo0 1zc0 Oo0 1wo0 WM0 1tA0 WM0 1tA0 U00 1tA0 U00 1tA0 11A0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 11A0 1o00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1cM0 1a00 1io0 1cM0 1cM0 1cM0 1cM0 3Co0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0|1","Antarctica/Mawson|+06 +05|-60 -50|01|1ARU0|60","Pacific/Auckland|NZST NZDT|-c0 -d0|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|bKC0 IM0 1C00 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1qM0 14o0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1io0 17c0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1io0 17c0 1io0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00|14e5","Antarctica/Palmer|-03 -02 -04|30 20 40|01020202020202020202020202020202020202020202020202020202020202020202020|9Rf0 Db0 jsN0 14N0 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 1cL0 1cN0 11z0 1o10 11z0 1qN0 WL0 1fB0 19X0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1ip0 1fz0 1fB0 11z0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1o10 19X0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0|40","Antarctica/Rothera|-00 -03|0 30|01|gOo0|130","Asia/Riyadh|+03|-30|0||57e5","Antarctica/Troll|-00 +00 +02|0 0 -20|012121212121212121212121212121212121212121212121212121|1puo0 hd0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|40","Asia/Urumqi|+06|-60|0||32e5","Europe/Berlin|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|oXd0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|41e5","Asia/Almaty|+06 +07 +05|-60 -70 -50|0101010101010101010102010101010101010101010101010|rn60 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0|15e5","Asia/Amman|EET EEST +03|-20 -30 -30|010101010101010101010101010101010101010101010101010101010101010101010101010101010101012|8kK0 KL0 1oN0 11b0 1oN0 11b0 1pd0 1dz0 1cp0 11b0 1op0 11b0 fO10 1db0 1e10 1cL0 1cN0 1cL0 1cN0 1fz0 1pd0 10n0 1ld0 14n0 1hB0 15b0 1ip0 19X0 1cN0 1cL0 1cN0 17b0 1ld0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1So0 y00 1fc0 1dc0 1co0 1dc0 1cM0 1cM0 1cM0 1o00 11A0 1lc0 17c0 1cM0 1cM0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 4bX0 Dd0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 LA0 1C00|25e5","Asia/Anadyr|+13 +14 +12 +11|-d0 -e0 -c0 -b0|010202020202020202023202020202020202020202020202020202020232|rmX0 1db0 2q10 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 2sp0 WM0|13e3","Asia/Aqtau|+05 +06 +04|-50 -60 -40|0101010101010101010201010120202020202020202020|sAj0 2pX0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0|15e4","Asia/Aqtobe|+05 +06 +04|-50 -60 -40|01010101010101010102010101010101010101010101010|rn70 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0|27e4","Asia/Ashgabat|+05 +06 +04|-50 -60 -40|01010101010101010101020|rn70 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0|41e4","Asia/Atyrau|+05 +06 +04|-50 -60 -40|010101010101010101020101010101010102020202020|sAj0 2pX0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 2sp0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0|","Asia/Baghdad|+03 +04|-30 -40|01010101010101010101010101010101010101010101010101010|u190 11b0 1cp0 1dz0 1dd0 1db0 1cN0 1cp0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1de0 1dc0 1dc0 1dc0 1cM0 1dc0 1cM0 1dc0 1cM0 1dc0 1dc0 1dc0 1cM0 1dc0 1cM0 1dc0 1cM0 1dc0 1dc0 1dc0 1cM0 1dc0 1cM0 1dc0 1cM0 1dc0 1dc0 1dc0 1cM0 1dc0 1cM0 1dc0 1cM0 1dc0|66e5","Asia/Qatar|+04 +03|-40 -30|01|5QI0|96e4","Asia/Baku|+04 +05 +03|-40 -50 -30|010101010101010101010201010101010101010101010101010101010101010|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 1cM0 9Je0 1o00 11z0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|27e5","Asia/Bangkok|+07|-70|0||15e6","Asia/Barnaul|+07 +08 +06|-70 -80 -60|01010101010101010101020101010102020202020202020202020202020202020|rn50 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 p90 LE0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3rd0|","Asia/Beirut|EET EEST|-20 -30|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|61a0 En0 1oN0 11b0 1oN0 11b0 1oN0 11b0 1pd0 11b0 1oN0 11b0 1op0 11b0 dA10 17b0 1iN0 17b0 1iN0 17b0 1iN0 17b0 1vB0 SL0 1mp0 13z0 1iN0 17b0 1iN0 17b0 1jd0 12n0 1a10 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0|22e5","Asia/Bishkek|+06 +07 +05|-60 -70 -50|0101010101010101010102020202020202020202020202020|rn60 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2e00 1tX0 17b0 1ip0 17b0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1cPu 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0|87e4","Asia/Brunei|+08|-80|0||42e4","Asia/Kolkata|IST|-5u|0||15e6","Asia/Chita|+09 +10 +08|-90 -a0 -80|0101010101010101010102010101010101010101010101010101010101010120|rn30 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3re0|33e4","Asia/Choibalsan|+07 +08 +10 +09|-70 -80 -a0 -90|012323232323232323232323232323232323232323232313131|jsF0 cKn0 1da0 1dd0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 6hD0 11z0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 3Db0 h1f0 1cJ0 1cP0 1cJ0|38e3","Asia/Shanghai|CST CDT|-80 -90|0101010101010|DKG0 Rb0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0|23e6","Asia/Colombo|+0530 +0630 +06|-5u -6u -60|0120|14giu 11zu n3cu|22e5","Asia/Dhaka|+06 +07|-60 -70|010|1A5R0 1i00|16e6","Asia/Damascus|EET EEST +03|-20 -30 -30|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101012|M00 11b0 1oN0 11b0 1pd0 11b0 1oN0 11b0 1oN0 11b0 1oN0 11b0 1pd0 11b0 1oN0 Nb0 1AN0 Nb0 bcp0 19X0 1gp0 19X0 3ld0 1xX0 Vd0 1Bz0 Sp0 1vX0 10p0 1dz0 1cN0 1cL0 1db0 1db0 1g10 1an0 1ap0 1db0 1fd0 1db0 1cN0 1db0 1dd0 1db0 1cp0 1dz0 1c10 1dX0 1cN0 1db0 1dd0 1db0 1cN0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1db0 1cN0 1db0 1cN0 19z0 1fB0 1qL0 11B0 1on0 Wp0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0|26e5","Asia/Dili|+09 +08|-90 -80|010|fpr0 Xld0|19e4","Asia/Dubai|+04|-40|0||39e5","Asia/Dushanbe|+06 +07 +05|-60 -70 -50|0101010101010101010102|rn60 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2hB0|76e4","Asia/Famagusta|EET EEST +03|-20 -30 -30|0101010101010101010101010101010101010101010101010101010101010101010101010101010101012010101010101010101010101010|cPa0 1cL0 1qp0 Xz0 19B0 19X0 1fB0 1db0 1cp0 1cL0 1fB0 19X0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1o30 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 15U0 2Ks0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|","Asia/Gaza|IST IDT EET EEST|-20 -30 -20 -30|010101010101010101010101010101023232323232323232323232323232323232323232323232323232323232323232323232|aXa0 Db0 1fB0 Rb0 bXB0 gM0 8Q00 IM0 1wo0 TX0 1HB0 IL0 1s10 10n0 1o10 WL0 1zd0 On0 1ld0 11z0 1o10 14n0 1o10 14n0 1nd0 12n0 1nd0 Xz0 1q10 12n0 M10 C00 17c0 1io0 17c0 1io0 17c0 1o00 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 17c0 1io0 18N0 1bz0 19z0 1gp0 1610 1iL0 11z0 1o10 14o0 1lA1 SKX 1xd1 MKX 1AN0 1a00 1fA0 1cL0 1cN0 1nX0 1210 1nA0 1210 1qL0 WN0 1qL0 WN0 1qL0 11c0 1on0 11B0 1o00 11A0 1qo0 XA0 1qp0 1cN0 1cL0 17d0 1in0 14p0 1lb0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0|18e5","Asia/Hebron|IST IDT EET EEST|-20 -30 -20 -30|01010101010101010101010101010102323232323232323232323232323232323232323232323232323232323232323232323232|aXa0 Db0 1fB0 Rb0 bXB0 gM0 8Q00 IM0 1wo0 TX0 1HB0 IL0 1s10 10n0 1o10 WL0 1zd0 On0 1ld0 11z0 1o10 14n0 1o10 14n0 1nd0 12n0 1nd0 Xz0 1q10 12n0 M10 C00 17c0 1io0 17c0 1io0 17c0 1o00 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 17c0 1io0 18N0 1bz0 19z0 1gp0 1610 1iL0 12L0 1mN0 14o0 1lc0 Tb0 1xd1 MKX bB0 cn0 1cN0 1a00 1fA0 1cL0 1cN0 1nX0 1210 1nA0 1210 1qL0 WN0 1qL0 WN0 1qL0 11c0 1on0 11B0 1o00 11A0 1qo0 XA0 1qp0 1cN0 1cL0 17d0 1in0 14p0 1lb0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0|25e4","Asia/Ho_Chi_Minh|+08 +07|-80 -70|01|dfs0|90e5","Asia/Hong_Kong|HKT HKST|-80 -90|01010101010101010|H7u 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 s10 1Vz0 1cN0 1cL0 1cN0 1cL0 6fd0 14n0|73e5","Asia/Hovd|+06 +07 +08|-60 -70 -80|01212121212121212121212121212121212121212121212121|jsG0 cKn0 1db0 1dd0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 6hD0 11z0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 kEp0 1cJ0 1cP0 1cJ0|81e3","Asia/Irkutsk|+08 +09 +07|-80 -90 -70|010101010101010101010201010101010101010101010101010101010101010|rn40 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|60e4","Europe/Istanbul|EET EEST +03 +04|-20 -30 -30 -40|01010101010123201010101010101010101010101010101010101010101010101010101010101012|8jz0 11A0 WN0 1qL0 TB0 1tX0 U10 1tz0 11B0 1in0 17d0 z90 cne0 pb0 2Cp0 1800 14o0 1dc0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1a00 1fA0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WO0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 Xc0 1qo0 WM0 1qM0 11A0 1o00 1200 1nA0 11A0 1tA0 U00 15w0|13e6","Asia/Jakarta|WIB|-70|0||31e6","Asia/Jayapura|WIT|-90|0||26e4","Asia/Jerusalem|IST IDT|-20 -30|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|aXa0 Db0 1fB0 Rb0 bXB0 gM0 8Q00 IM0 1wo0 TX0 1HB0 IL0 1s10 10n0 1o10 WL0 1zd0 On0 1ld0 11z0 1o10 14n0 1o10 14n0 1nd0 12n0 1nd0 Xz0 1q10 12n0 1hB0 1dX0 1ep0 1aL0 1eN0 17X0 1nf0 11z0 1tB0 19W0 1e10 17b0 1ep0 1gL0 18N0 1fz0 1eN0 17b0 1gq0 1gn0 19d0 1dz0 1c10 17X0 1hB0 1gn0 19d0 1dz0 1c10 17X0 1kp0 1dz0 1c10 1aL0 1eN0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0|81e4","Asia/Kabul|+0430|-4u|0||46e5","Asia/Kamchatka|+12 +13 +11|-c0 -d0 -b0|0101010101010101010102010101010101010101010101010101010101020|rn00 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 2sp0 WM0|18e4","Asia/Karachi|+05 PKT PKST|-50 -50 -60|01212121|2Xv0 1fy00 1cL0 dK10 11b0 1610 1jX0|24e6","Asia/Kathmandu|+0530 +0545|-5u -5J|01|CVuu|12e5","Asia/Khandyga|+09 +10 +08 +11|-90 -a0 -80 -b0|01010101010101010101020101010101010101010101010131313131313131310|rn30 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 qK0 yN0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 17V0 7zD0|66e2","Asia/Krasnoyarsk|+07 +08 +06|-70 -80 -60|010101010101010101010201010101010101010101010101010101010101010|rn50 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|10e5","Asia/Kuala_Lumpur|+0730 +08|-7u -80|01|td40|71e5","Asia/Macau|CST CDT|-80 -90|01010101010101010|H7u 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 s10 1Vz0 1cN0 1cL0 1cN0 1cL0 6fd0 14n0|57e4","Asia/Magadan|+11 +12 +10|-b0 -c0 -a0|0101010101010101010102010101010101010101010101010101010101010120|rn10 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3Cq0|95e3","Asia/Makassar|WITA|-80|0||15e5","Asia/Manila|PST PDT|-80 -90|010|k0E0 1db0|24e6","Asia/Nicosia|EET EEST|-20 -30|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|cPa0 1cL0 1qp0 Xz0 19B0 19X0 1fB0 1db0 1cp0 1cL0 1fB0 19X0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1o30 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|32e4","Asia/Novokuznetsk|+07 +08 +06|-70 -80 -60|0101010101010101010102010101010101010101010101010101010101020|rn50 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 2sp0 WM0|55e4","Asia/Novosibirsk|+07 +08 +06|-70 -80 -60|01010101010101010101020101020202020202020202020202020202020202020|rn50 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 ml0 Os0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 4eN0|15e5","Asia/Omsk|+06 +07 +05|-60 -70 -50|010101010101010101010201010101010101010101010101010101010101010|rn60 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|12e5","Asia/Oral|+05 +06 +04|-50 -60 -40|010101010101010202020202020202020202020202020|rn70 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1fA0 1cM0 1cM0 IM0 1EM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0|27e4","Asia/Pontianak|WITA WIB|-80 -70|01|HNs0|23e4","Asia/Pyongyang|KST KST|-90 -8u|010|1P4D0 6BA0|29e5","Asia/Qostanay|+05 +06 +04|-50 -60 -40|0101010101010101010201010101010101010101010101|rn70 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0|","Asia/Qyzylorda|+05 +06|-50 -60|010101010101010101010101010101010101010101010|rn70 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 3ao0 1EM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 zQl0|73e4","Asia/Rangoon|+0630|-6u|0||48e5","Asia/Sakhalin|+11 +12 +10|-b0 -c0 -a0|010101010101010101010201010101010202020202020202020202020202020|rn10 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 2pB0 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3rd0|58e4","Asia/Samarkand|+05 +06|-50 -60|010101010101010101010|rn70 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0|36e4","Asia/Seoul|KST KDT|-90 -a0|01010|Gf50 11A0 1o00 11A0|23e6","Asia/Srednekolymsk|+11 +12 +10|-b0 -c0 -a0|010101010101010101010201010101010101010101010101010101010101010|rn10 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|35e2","Asia/Taipei|CST CDT|-80 -90|0101010|akg0 1db0 1cN0 1db0 97B0 AL0|74e5","Asia/Tashkent|+06 +07 +05|-60 -70 -50|0101010101010101010102|rn60 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0|23e5","Asia/Tbilisi|+04 +05 +03|-40 -50 -30|01010101010101010101020202010101010101010101020|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 1cK0 1cL0 1cN0 1cL0 1cN0 2pz0 1cL0 1fB0 3Nz0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 An0 Os0 WM0|11e5","Asia/Tehran|+0330 +0430 +04 +05|-3u -4u -40 -50|0123201010101010101010101010101010101010101010101010101010101010101010|hyHu 1pc0 120u Rc0 XA0 Wou JX0 1dB0 1en0 pNB0 UL0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 64p0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0|14e6","Asia/Thimphu|+0530 +06|-5u -60|01|HcGu|79e3","Asia/Tokyo|JST|-90|0||38e6","Asia/Tomsk|+07 +08 +06|-70 -80 -60|01010101010101010101020101010101010101010101020202020202020202020|rn50 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 co0 1bB0 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3Qp0|10e5","Asia/Ulaanbaatar|+07 +08 +09|-70 -80 -90|01212121212121212121212121212121212121212121212121|jsF0 cKn0 1db0 1dd0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 6hD0 11z0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 kEp0 1cJ0 1cP0 1cJ0|12e5","Asia/Ust-Nera|+09 +12 +11 +10|-90 -c0 -b0 -a0|0121212121212121212123212121212121212121212121212121212121212123|rn30 1d90 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 17V0 7zD0|65e2","Asia/Vladivostok|+10 +11 +09|-a0 -b0 -90|010101010101010101010201010101010101010101010101010101010101010|rn20 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|60e4","Asia/Yakutsk|+09 +10 +08|-90 -a0 -80|010101010101010101010201010101010101010101010101010101010101010|rn30 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|28e4","Asia/Yekaterinburg|+05 +06 +04|-50 -60 -40|010101010101010101010201010101010101010101010101010101010101010|rn70 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|14e5","Asia/Yerevan|+04 +05 +03|-40 -50 -30|01010101010101010101020202020101010101010101010101010101010|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 4RX0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|13e5","Atlantic/Azores|-01 +00 WET|10 0 0|0101010101010101010101010101010121010101010101010101010101010101010101010101010101010101010101010101010101010|hAN0 1cM0 1fA0 1cM0 1cM0 1cN0 1cL0 1cN0 1cM0 1cM0 1cM0 1cM0 1cN0 1cL0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cL0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|25e4","Atlantic/Bermuda|AST ADT|40 30|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|avi0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|65e3","Atlantic/Canary|WET WEST|0 -10|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|oXc0 1a10 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|54e4","Atlantic/Cape_Verde|-02 -01|20 10|01|elE0|50e4","Atlantic/Faroe|WET WEST|0 -10|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|rm10 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|49e3","Atlantic/Madeira|WET WEST|0 -10|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|hAM0 1cM0 1fA0 1cM0 1cM0 1cN0 1cL0 1cN0 1cM0 1cM0 1cM0 1cM0 1cN0 1cL0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|27e4","Atlantic/South_Georgia|-02|20|0||30","Atlantic/Stanley|-04 -03 -02|40 30 20|01212101010101010101010101010101010101010101010101010101|wrg0 WL0 1qL0 U10 1tz0 2mN0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1tz0 U10 1tz0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1tz0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qN0 U10 1wn0 Rd0 1wn0 U10 1tz0 U10 1tz0 U10 1tz0 U10 1tz0 U10 1wn0 U10 1tz0 U10 1tz0 U10|21e2","Australia/Sydney|AEST AEDT|-a0 -b0|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|4r40 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 14o0 1o00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 U00 1qM0 WM0 1tA0 WM0 1tA0 U00 1tA0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 11A0 1o00 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 14o0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0|40e5","Australia/Adelaide|ACST ACDT|-9u -au|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|4r4u LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 U00 1qM0 WM0 1tA0 WM0 1tA0 U00 1tA0 U00 1tA0 Oo0 1zc0 WM0 1qM0 Rc0 1zc0 U00 1tA0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 14o0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0|11e5","Australia/Brisbane|AEST AEDT|-a0 -b0|010101010|4r40 LA0 H1A0 Oo0 1zc0 Oo0 1zc0 Oo0|20e5","Australia/Broken_Hill|ACST ACDT|-9u -au|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|4r4u LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 14o0 1o00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 U00 1qM0 WM0 1tA0 WM0 1tA0 U00 1tA0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 14o0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0|18e3","Australia/Hobart|AEDT AEST|-b0 -a0|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|qg0 1wo0 U00 1wo0 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1qM0 WM0 1qM0 Oo0 1zc0 Oo0 1zc0 Oo0 1wo0 WM0 1tA0 WM0 1tA0 U00 1tA0 U00 1tA0 11A0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 11A0 1o00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1cM0 1a00 1io0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0|21e4","Australia/Darwin|ACST|-9u|0||12e4","Australia/Eucla|+0845 +0945|-8J -9J|0101010101010|bHRf Oo0 l5A0 Oo0 iJA0 G00 zU00 IM0 1qM0 11A0 1o00 11A0|368","Australia/Lord_Howe|AEST +1030 +1130 +11|-a0 -au -bu -b0|01212121213131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313|raC0 1zdu Rb0 1zd0 On0 1zd0 On0 1zd0 On0 1zd0 TXu 1qMu WLu 1tAu WLu 1tAu TXu 1tAu Onu 1zcu Onu 1zcu Onu 1zcu Rbu 1zcu Onu 1zcu Onu 1zcu 11zu 1o0u 11zu 1o0u 11zu 1o0u 11zu 1qMu WLu 11Au 1nXu 1qMu 11zu 1o0u 11zu 1o0u 11zu 1qMu WLu 1qMu 11zu 1o0u WLu 1qMu 14nu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu|347","Australia/Lindeman|AEST AEDT|-a0 -b0|0101010101010|4r40 LA0 H1A0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0|10","Australia/Melbourne|AEST AEDT|-a0 -b0|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|4r40 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 U00 1qM0 WM0 1qM0 11A0 1tA0 U00 1tA0 U00 1tA0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 11A0 1o00 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 14o0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0|39e5","Australia/Perth|AWST AWDT|-80 -90|0101010101010|bHS0 Oo0 l5A0 Oo0 iJA0 G00 zU00 IM0 1qM0 11A0 1o00 11A0|18e5","Europe/Brussels|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|hDB0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|21e5","Pacific/Easter|-06 -07 -05|60 70 50|010101010101010101010101020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202|yP0 1ip0 11z0 1o10 11z0 1qN0 WL0 1ld0 14n0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 2pA0 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 1cL0 1cN0 11z0 1o10 11z0 1qN0 WL0 1fB0 19X0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1ip0 1fz0 1fB0 11z0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1o10 19X0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1zb0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0|30e2","EET|EET EEST|-20 -30|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|hDB0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|","Europe/Dublin|IST GMT|-10 0|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|4re0 U00 1tA0 U00 1tA0 U00 1tA0 U00 1tA0 WM0 1qM0 WM0 1qM0 WM0 1tA0 U00 1tA0 U00 1tA0 11z0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 14o0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|12e5","Etc/GMT-1|+01|-10|0||","Pacific/Guadalcanal|+11|-b0|0||11e4","Pacific/Tarawa|+12|-c0|0||29e3","Etc/GMT-13|+13|-d0|0||","Etc/GMT-14|+14|-e0|0||","Etc/GMT-2|+02|-20|0||","Indian/Maldives|+05|-50|0||35e4","Pacific/Palau|+09|-90|0||21e3","Etc/GMT+1|-01|10|0||","Pacific/Tahiti|-10|a0|0||18e4","Pacific/Niue|-11|b0|0||12e2","Etc/GMT+12|-12|c0|0||","Etc/GMT+5|-05|50|0||","Etc/GMT+6|-06|60|0||","Etc/GMT+7|-07|70|0||","Etc/GMT+8|-08|80|0||","Pacific/Gambier|-09|90|0||125","Etc/UTC|UTC|0|0||","Europe/Andorra|CET CEST|-10 -20|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|B7d0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|79e3","Europe/Astrakhan|+04 +05 +03|-40 -50 -30|0101010101010101020202020202020202020202020202020202020202020|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1fA0 1cM0 3Co0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3rd0|10e5","Europe/Athens|EET EEST|-20 -30|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|cOK0 1vc0 SO0 1cM0 1a00 1ao0 1fc0 1a10 1fG0 1cg0 1dX0 1bX0 1cQ0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|35e5","Europe/London|BST GMT|-10 0|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|4re0 U00 1tA0 U00 1tA0 U00 1tA0 U00 1tA0 WM0 1qM0 WM0 1qM0 WM0 1tA0 U00 1tA0 U00 1tA0 11z0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 14o0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|10e6","Europe/Belgrade|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|wdd0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|12e5","Europe/Prague|CET CEST|-10 -20|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|muN0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|13e5","Europe/Bucharest|EET EEST|-20 -30|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|mRa0 On0 1fA0 1a10 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cK0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cL0 1cN0 1cL0 1fB0 1nX0 11E0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|19e5","Europe/Budapest|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|oXb0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cO0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|17e5","Europe/Zurich|CET CEST|-10 -20|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|rm10 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|38e4","Europe/Chisinau|MSK MSD EEST EET|-30 -40 -30 -20|010101010101010101012323232323232323232323232323232323232323232323232323232323232323232323232323232323|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 gL0 WO0 1cM0 1cM0 1cK0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1nX0 11D0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|67e4","Europe/Gibraltar|CET CEST|-10 -20|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|tLB0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|30e3","Europe/Helsinki|EET EEST|-20 -30|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|rm00 1cM0 1cM0 1cM0 1cN0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|12e5","Europe/Kaliningrad|MSK MSD EEST EET +03|-30 -40 -30 -20 -30|010101010101010102323232323232323232323232323232323232323232343|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|44e4","Europe/Kiev|MSK MSD EEST EET|-30 -40 -30 -20|0101010101010101010123232323232323232323232323232323232323232323232323232323232323232323232323232323|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 Db0 3220 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o10 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|34e5","Europe/Kirov|+04 +05 MSD MSK MSK|-40 -50 -40 -30 -40|01010101010101010232302323232323232323232323232323232323232343|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 2pz0 1cN0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|48e4","Europe/Lisbon|CET WET WEST CEST|-10 0 -10 -20|01212121212121212121212121212121203030302121212121212121212121212121212121212121212121212121212121212121212121|go00 1cM0 1cM0 1fA0 1cM0 1cM0 1cN0 1cL0 1cN0 1cM0 1cM0 1cM0 1cM0 1cN0 1cL0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|27e5","Europe/Madrid|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|apy0 1a10 1fz0 1a10 19X0 1cN0 1fz0 1a10 1fC0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|62e5","Europe/Malta|CET CEST|-10 -20|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|XX0 LA0 1zc0 Oo0 1C00 Oo0 1co0 1cM0 1lA0 Xc0 1qq0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1iN0 19z0 1fB0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|42e4","Europe/Minsk|MSK MSD EEST EET +03|-30 -40 -30 -20 -30|010101010101010101023232323232323232323232323232323232323234|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 3Fc0 1cN0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0|19e5","Europe/Paris|CET CEST|-10 -20|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|fbc0 1cL0 1fC0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|11e6","Europe/Moscow|MSK MSD EEST EET MSK|-30 -40 -30 -20 -40|0101010101010101010102301010101010101010101010101010101010101040|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|16e6","Europe/Riga|MSK MSD EEST EET|-30 -40 -30 -20|010101010101010102323232323232323232323232323232323232323232323232323232323232323232323232323232323|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 1o00 11A0 1o00 11A0 1qM0 3oo0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|64e4","Europe/Rome|CET CEST|-10 -20|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|XX0 LA0 1zc0 Oo0 1C00 Oo0 1C00 LA0 1zc0 Oo0 1C00 LA0 1C00 LA0 1zc0 Oo0 1C00 Oo0 1zc0 Oo0 1fC0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|39e5","Europe/Samara|+04 +05 +03|-40 -50 -30|01010101010101010202010101010101010101010101010101010101020|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1fA0 2y10 14m0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 2sp0 WM0|12e5","Europe/Saratov|+04 +05 +03|-40 -50 -30|0101010101010102020202020202020202020202020202020202020202020|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1cM0 1cM0 1fA0 1cM0 3Co0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 5810|","Europe/Simferopol|MSK MSD EET EEST MSK|-30 -40 -20 -30 -40|0101010101010101010232323101010323232323232323232323232323232323240|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1Q00 4eN0 1cM0 1cM0 1cM0 1cM0 dV0 WO0 1cM0 1cM0 1fy0 1o30 11B0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11z0 1nW0|33e4","Europe/Sofia|EET EEST|-20 -30|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|muJ0 1dd0 1fb0 1ap0 1fb0 1a20 1fy0 1a30 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cK0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1nX0 11E0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|12e5","Europe/Tallinn|MSK MSD EEST EET|-30 -40 -30 -20|0101010101010101023232323232323232323232323232323232323232323232323232323232323232323232323232323|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o10 11A0 1qM0 5QM0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|41e4","Europe/Tirane|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|axz0 10n0 1op0 11z0 1pd0 11z0 1qN0 WL0 1qp0 Xb0 1qp0 Xb0 1qp0 11z0 1lB0 11z0 1qN0 11z0 1iN0 16n0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|42e4","Europe/Ulyanovsk|+04 +05 +03 +02|-40 -50 -30 -20|010101010101010102023202020202020202020202020202020202020202020|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3rd0|13e5","Europe/Vienna|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|oXb0 19X0 1cP0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|18e5","Europe/Vilnius|MSK MSD EEST EET CEST CET|-30 -40 -30 -20 -20 -10|01010101010101010232323232323232323454323232323232323232323232323232323232323232323232323232323|rn90 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11B0 1o00 11A0 1qM0 8io0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|54e4","Europe/Volgograd|+04 +05 MSD MSK MSK|-40 -50 -40 -30 -40|0101010101010102323230232323232323232323232323232323232323234303|rn80 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1cM0 1cM0 1fA0 1cM0 2pz0 1cN0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 9Jd0 5gn0|10e5","Europe/Warsaw|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|hDA0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|17e5","Pacific/Honolulu|HST|a0|0||37e4","Indian/Chagos|+05 +06|-50 -60|01|13ij0|30e2","Indian/Mauritius|+04 +05|-40 -50|01010|v5U0 14L0 12kr0 11z0|15e4","Pacific/Kwajalein|-12 +12|c0 -c0|01|Vxo0|14e3","MET|MET MEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|hDB0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|","Pacific/Chatham|+1245 +1345|-cJ -dJ|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|bKC0 IM0 1C00 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1qM0 14o0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1io0 17c0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1io0 17c0 1io0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00|600","Pacific/Apia|-11 -10 +14 +13|b0 a0 -e0 -d0|010123232323232323232323|1Dbn0 1ff0 1a00 CI0 AQ0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0|37e3","Pacific/Bougainville|+10 +11|-a0 -b0|01|1NwE0|18e4","Pacific/Efate|+11 +12|-b0 -c0|01010101010101010101010|9EA0 Dc0 n610 1cL0 1cN0 1cL0 1fB0 19X0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 Lz0 1Nd0 An0|66e3","Pacific/Enderbury|-12 -11 +13|c0 b0 -d0|012|nIc0 B7X0|1","Pacific/Fakaofo|-11 +13|b0 -d0|01|1Gfn0|483","Pacific/Fiji|+12 +13|-c0 -d0|01010101010101010101010101010|1ace0 LA0 1EM0 IM0 nJc0 LA0 1o00 Rc0 1wo0 Ao0 1Nc0 Ao0 1Q00 xz0 1SN0 uM0 1SM0 uM0 1VA0 s00 1VA0 s00 1VA0 s00 20o0 pc0 2hc0 bc0|88e4","Pacific/Galapagos|-05 -06|50 60|0101|CVF0 gNd0 rz0|25e3","Pacific/Guam|GST GDT ChST|-a0 -b0 -a0|010101010102|JQ0 Rb0 1wp0 Rb0 5xd0 rX0 5sN0 zb1 1C0X On0 ULb0|17e4","Pacific/Kiritimati|-1040 -10 +14|aE a0 -e0|012|nIaE B7Xk|51e2","Pacific/Kosrae|+12 +11|-c0 -b0|01|1aAA0|66e2","Pacific/Marquesas|-0930|9u|0||86e2","Pacific/Pago_Pago|SST|b0|0||37e2","Pacific/Nauru|+1130 +12|-bu -c0|01|maCu|10e3","Pacific/Norfolk|+1130 +1230 +11 +12|-bu -cu -b0 -c0|010232323232323232323232323|bHOu Oo0 1COo0 9Jcu 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0|25e4","Pacific/Noumea|+11 +12|-b0 -c0|0101010|jhp0 xX0 1PB0 yn0 HeP0 Ao0|98e3","Pacific/Pitcairn|-0830 -08|8u 80|01|18Vku|56","Pacific/Rarotonga|-1030 -0930 -10|au 9u a0|012121212121212121212121212|lyWu IL0 1zcu Onu 1zcu Onu 1zcu Rbu 1zcu Onu 1zcu Onu 1zcu Onu 1zcu Onu 1zcu Onu 1zcu Rbu 1zcu Onu 1zcu Onu 1zcu Onu|13e3","Pacific/Tongatapu|+13 +14|-d0 -e0|010101010|1csd0 15A0 1wo0 xz0 1Q10 xz0 zWN0 s00|75e3","WET|WET WEST|0 -10|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|hDB0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00|"],links:["Africa/Abidjan|Africa/Accra","Africa/Abidjan|Africa/Bamako","Africa/Abidjan|Africa/Banjul","Africa/Abidjan|Africa/Conakry","Africa/Abidjan|Africa/Dakar","Africa/Abidjan|Africa/Freetown","Africa/Abidjan|Africa/Lome","Africa/Abidjan|Africa/Nouakchott","Africa/Abidjan|Africa/Ouagadougou","Africa/Abidjan|Africa/Timbuktu","Africa/Abidjan|Atlantic/Reykjavik","Africa/Abidjan|Atlantic/St_Helena","Africa/Abidjan|Etc/GMT","Africa/Abidjan|Etc/GMT+0","Africa/Abidjan|Etc/GMT-0","Africa/Abidjan|Etc/GMT0","Africa/Abidjan|Etc/Greenwich","Africa/Abidjan|GMT","Africa/Abidjan|GMT+0","Africa/Abidjan|GMT-0","Africa/Abidjan|GMT0","Africa/Abidjan|Greenwich","Africa/Abidjan|Iceland","Africa/Cairo|Egypt","Africa/Johannesburg|Africa/Maseru","Africa/Johannesburg|Africa/Mbabane","Africa/Lagos|Africa/Bangui","Africa/Lagos|Africa/Brazzaville","Africa/Lagos|Africa/Douala","Africa/Lagos|Africa/Kinshasa","Africa/Lagos|Africa/Libreville","Africa/Lagos|Africa/Luanda","Africa/Lagos|Africa/Malabo","Africa/Lagos|Africa/Niamey","Africa/Lagos|Africa/Porto-Novo","Africa/Maputo|Africa/Blantyre","Africa/Maputo|Africa/Bujumbura","Africa/Maputo|Africa/Gaborone","Africa/Maputo|Africa/Harare","Africa/Maputo|Africa/Kigali","Africa/Maputo|Africa/Lubumbashi","Africa/Maputo|Africa/Lusaka","Africa/Nairobi|Africa/Addis_Ababa","Africa/Nairobi|Africa/Asmara","Africa/Nairobi|Africa/Asmera","Africa/Nairobi|Africa/Dar_es_Salaam","Africa/Nairobi|Africa/Djibouti","Africa/Nairobi|Africa/Kampala","Africa/Nairobi|Africa/Mogadishu","Africa/Nairobi|Indian/Antananarivo","Africa/Nairobi|Indian/Comoro","Africa/Nairobi|Indian/Mayotte","Africa/Tripoli|Libya","America/Adak|America/Atka","America/Adak|US/Aleutian","America/Anchorage|US/Alaska","America/Argentina/Buenos_Aires|America/Buenos_Aires","America/Argentina/Catamarca|America/Argentina/ComodRivadavia","America/Argentina/Catamarca|America/Catamarca","America/Argentina/Cordoba|America/Cordoba","America/Argentina/Cordoba|America/Rosario","America/Argentina/Jujuy|America/Jujuy","America/Argentina/Mendoza|America/Mendoza","America/Cayenne|Etc/GMT+3","America/Chicago|CST6CDT","America/Chicago|US/Central","America/Denver|America/Shiprock","America/Denver|MST7MDT","America/Denver|Navajo","America/Denver|US/Mountain","America/Detroit|US/Michigan","America/Edmonton|America/Yellowknife","America/Edmonton|Canada/Mountain","America/Fort_Wayne|America/Indiana/Indianapolis","America/Fort_Wayne|America/Indianapolis","America/Fort_Wayne|US/East-Indiana","America/Godthab|America/Nuuk","America/Halifax|Canada/Atlantic","America/Havana|Cuba","America/Indiana/Knox|America/Knox_IN","America/Indiana/Knox|US/Indiana-Starke","America/Iqaluit|America/Pangnirtung","America/Jamaica|Jamaica","America/Kentucky/Louisville|America/Louisville","America/La_Paz|Etc/GMT+4","America/Los_Angeles|PST8PDT","America/Los_Angeles|US/Pacific","America/Manaus|Brazil/West","America/Mazatlan|Mexico/BajaSur","America/Mexico_City|Mexico/General","America/New_York|EST5EDT","America/New_York|US/Eastern","America/Noronha|Brazil/DeNoronha","America/Panama|America/Atikokan","America/Panama|America/Cayman","America/Panama|America/Coral_Harbour","America/Panama|EST","America/Phoenix|America/Creston","America/Phoenix|MST","America/Phoenix|US/Arizona","America/Puerto_Rico|America/Anguilla","America/Puerto_Rico|America/Antigua","America/Puerto_Rico|America/Aruba","America/Puerto_Rico|America/Blanc-Sablon","America/Puerto_Rico|America/Curacao","America/Puerto_Rico|America/Dominica","America/Puerto_Rico|America/Grenada","America/Puerto_Rico|America/Guadeloupe","America/Puerto_Rico|America/Kralendijk","America/Puerto_Rico|America/Lower_Princes","America/Puerto_Rico|America/Marigot","America/Puerto_Rico|America/Montserrat","America/Puerto_Rico|America/Port_of_Spain","America/Puerto_Rico|America/St_Barthelemy","America/Puerto_Rico|America/St_Kitts","America/Puerto_Rico|America/St_Lucia","America/Puerto_Rico|America/St_Thomas","America/Puerto_Rico|America/St_Vincent","America/Puerto_Rico|America/Tortola","America/Puerto_Rico|America/Virgin","America/Regina|Canada/Saskatchewan","America/Rio_Branco|America/Porto_Acre","America/Rio_Branco|Brazil/Acre","America/Santiago|Chile/Continental","America/Sao_Paulo|Brazil/East","America/St_Johns|Canada/Newfoundland","America/Tijuana|America/Ensenada","America/Tijuana|America/Santa_Isabel","America/Tijuana|Mexico/BajaNorte","America/Toronto|America/Montreal","America/Toronto|America/Nassau","America/Toronto|America/Nipigon","America/Toronto|America/Thunder_Bay","America/Toronto|Canada/Eastern","America/Vancouver|Canada/Pacific","America/Whitehorse|Canada/Yukon","America/Winnipeg|America/Rainy_River","America/Winnipeg|Canada/Central","Asia/Ashgabat|Asia/Ashkhabad","Asia/Bangkok|Asia/Phnom_Penh","Asia/Bangkok|Asia/Vientiane","Asia/Bangkok|Etc/GMT-7","Asia/Bangkok|Indian/Christmas","Asia/Brunei|Asia/Kuching","Asia/Brunei|Etc/GMT-8","Asia/Dhaka|Asia/Dacca","Asia/Dubai|Asia/Muscat","Asia/Dubai|Etc/GMT-4","Asia/Dubai|Indian/Mahe","Asia/Dubai|Indian/Reunion","Asia/Ho_Chi_Minh|Asia/Saigon","Asia/Hong_Kong|Hongkong","Asia/Jerusalem|Asia/Tel_Aviv","Asia/Jerusalem|Israel","Asia/Kathmandu|Asia/Katmandu","Asia/Kolkata|Asia/Calcutta","Asia/Kuala_Lumpur|Asia/Singapore","Asia/Kuala_Lumpur|Singapore","Asia/Macau|Asia/Macao","Asia/Makassar|Asia/Ujung_Pandang","Asia/Nicosia|Europe/Nicosia","Asia/Qatar|Asia/Bahrain","Asia/Rangoon|Asia/Yangon","Asia/Rangoon|Indian/Cocos","Asia/Riyadh|Antarctica/Syowa","Asia/Riyadh|Asia/Aden","Asia/Riyadh|Asia/Kuwait","Asia/Riyadh|Etc/GMT-3","Asia/Seoul|ROK","Asia/Shanghai|Asia/Chongqing","Asia/Shanghai|Asia/Chungking","Asia/Shanghai|Asia/Harbin","Asia/Shanghai|PRC","Asia/Taipei|ROC","Asia/Tehran|Iran","Asia/Thimphu|Asia/Thimbu","Asia/Tokyo|Japan","Asia/Ulaanbaatar|Asia/Ulan_Bator","Asia/Urumqi|Antarctica/Vostok","Asia/Urumqi|Asia/Kashgar","Asia/Urumqi|Etc/GMT-6","Atlantic/Faroe|Atlantic/Faeroe","Atlantic/South_Georgia|Etc/GMT+2","Australia/Adelaide|Australia/South","Australia/Brisbane|Australia/Queensland","Australia/Broken_Hill|Australia/Yancowinna","Australia/Darwin|Australia/North","Australia/Hobart|Australia/Currie","Australia/Hobart|Australia/Tasmania","Australia/Lord_Howe|Australia/LHI","Australia/Melbourne|Australia/Victoria","Australia/Perth|Australia/West","Australia/Sydney|Australia/ACT","Australia/Sydney|Australia/Canberra","Australia/Sydney|Australia/NSW","Etc/UTC|Etc/UCT","Etc/UTC|Etc/Universal","Etc/UTC|Etc/Zulu","Etc/UTC|UCT","Etc/UTC|UTC","Etc/UTC|Universal","Etc/UTC|Zulu","Europe/Belgrade|Europe/Ljubljana","Europe/Belgrade|Europe/Podgorica","Europe/Belgrade|Europe/Sarajevo","Europe/Belgrade|Europe/Skopje","Europe/Belgrade|Europe/Zagreb","Europe/Berlin|Arctic/Longyearbyen","Europe/Berlin|Atlantic/Jan_Mayen","Europe/Berlin|Europe/Copenhagen","Europe/Berlin|Europe/Oslo","Europe/Berlin|Europe/Stockholm","Europe/Brussels|CET","Europe/Brussels|Europe/Amsterdam","Europe/Brussels|Europe/Luxembourg","Europe/Chisinau|Europe/Tiraspol","Europe/Dublin|Eire","Europe/Helsinki|Europe/Mariehamn","Europe/Istanbul|Asia/Istanbul","Europe/Istanbul|Turkey","Europe/Kiev|Europe/Kyiv","Europe/Kiev|Europe/Uzhgorod","Europe/Kiev|Europe/Zaporozhye","Europe/Lisbon|Portugal","Europe/London|Europe/Belfast","Europe/London|Europe/Guernsey","Europe/London|Europe/Isle_of_Man","Europe/London|Europe/Jersey","Europe/London|GB","Europe/London|GB-Eire","Europe/Moscow|W-SU","Europe/Paris|Europe/Monaco","Europe/Prague|Europe/Bratislava","Europe/Rome|Europe/San_Marino","Europe/Rome|Europe/Vatican","Europe/Warsaw|Poland","Europe/Zurich|Europe/Busingen","Europe/Zurich|Europe/Vaduz","Indian/Maldives|Etc/GMT-5","Indian/Maldives|Indian/Kerguelen","Pacific/Auckland|Antarctica/McMurdo","Pacific/Auckland|Antarctica/South_Pole","Pacific/Auckland|NZ","Pacific/Chatham|NZ-CHAT","Pacific/Easter|Chile/EasterIsland","Pacific/Enderbury|Pacific/Kanton","Pacific/Gambier|Etc/GMT+9","Pacific/Guadalcanal|Etc/GMT-11","Pacific/Guadalcanal|Pacific/Pohnpei","Pacific/Guadalcanal|Pacific/Ponape","Pacific/Guam|Pacific/Saipan","Pacific/Honolulu|HST","Pacific/Honolulu|Pacific/Johnston","Pacific/Honolulu|US/Hawaii","Pacific/Kwajalein|Kwajalein","Pacific/Niue|Etc/GMT+11","Pacific/Pago_Pago|Pacific/Midway","Pacific/Pago_Pago|Pacific/Samoa","Pacific/Pago_Pago|US/Samoa","Pacific/Palau|Etc/GMT-9","Pacific/Port_Moresby|Antarctica/DumontDUrville","Pacific/Port_Moresby|Etc/GMT-10","Pacific/Port_Moresby|Pacific/Chuuk","Pacific/Port_Moresby|Pacific/Truk","Pacific/Port_Moresby|Pacific/Yap","Pacific/Tahiti|Etc/GMT+10","Pacific/Tarawa|Etc/GMT-12","Pacific/Tarawa|Pacific/Funafuti","Pacific/Tarawa|Pacific/Majuro","Pacific/Tarawa|Pacific/Wake","Pacific/Tarawa|Pacific/Wallis"],countries:["AD|Europe/Andorra","AE|Asia/Dubai","AF|Asia/Kabul","AG|America/Puerto_Rico America/Antigua","AI|America/Puerto_Rico America/Anguilla","AL|Europe/Tirane","AM|Asia/Yerevan","AO|Africa/Lagos Africa/Luanda","AQ|Antarctica/Casey Antarctica/Davis Antarctica/Mawson Antarctica/Palmer Antarctica/Rothera Antarctica/Troll Asia/Urumqi Pacific/Auckland Pacific/Port_Moresby Asia/Riyadh Antarctica/McMurdo Antarctica/DumontDUrville Antarctica/Syowa Antarctica/Vostok","AR|America/Argentina/Buenos_Aires America/Argentina/Cordoba America/Argentina/Salta America/Argentina/Jujuy America/Argentina/Tucuman America/Argentina/Catamarca America/Argentina/La_Rioja America/Argentina/San_Juan America/Argentina/Mendoza America/Argentina/San_Luis America/Argentina/Rio_Gallegos America/Argentina/Ushuaia","AS|Pacific/Pago_Pago","AT|Europe/Vienna","AU|Australia/Lord_Howe Antarctica/Macquarie Australia/Hobart Australia/Melbourne Australia/Sydney Australia/Broken_Hill Australia/Brisbane Australia/Lindeman Australia/Adelaide Australia/Darwin Australia/Perth Australia/Eucla","AW|America/Puerto_Rico America/Aruba","AX|Europe/Helsinki Europe/Mariehamn","AZ|Asia/Baku","BA|Europe/Belgrade Europe/Sarajevo","BB|America/Barbados","BD|Asia/Dhaka","BE|Europe/Brussels","BF|Africa/Abidjan Africa/Ouagadougou","BG|Europe/Sofia","BH|Asia/Qatar Asia/Bahrain","BI|Africa/Maputo Africa/Bujumbura","BJ|Africa/Lagos Africa/Porto-Novo","BL|America/Puerto_Rico America/St_Barthelemy","BM|Atlantic/Bermuda","BN|Asia/Kuching Asia/Brunei","BO|America/La_Paz","BQ|America/Puerto_Rico America/Kralendijk","BR|America/Noronha America/Belem America/Fortaleza America/Recife America/Araguaina America/Maceio America/Bahia America/Sao_Paulo America/Campo_Grande America/Cuiaba America/Santarem America/Porto_Velho America/Boa_Vista America/Manaus America/Eirunepe America/Rio_Branco","BS|America/Toronto America/Nassau","BT|Asia/Thimphu","BW|Africa/Maputo Africa/Gaborone","BY|Europe/Minsk","BZ|America/Belize","CA|America/St_Johns America/Halifax America/Glace_Bay America/Moncton America/Goose_Bay America/Toronto America/Iqaluit America/Winnipeg America/Resolute America/Rankin_Inlet America/Regina America/Swift_Current America/Edmonton America/Cambridge_Bay America/Inuvik America/Dawson_Creek America/Fort_Nelson America/Whitehorse America/Dawson America/Vancouver America/Panama America/Puerto_Rico America/Phoenix America/Blanc-Sablon America/Atikokan America/Creston","CC|Asia/Yangon Indian/Cocos","CD|Africa/Maputo Africa/Lagos Africa/Kinshasa Africa/Lubumbashi","CF|Africa/Lagos Africa/Bangui","CG|Africa/Lagos Africa/Brazzaville","CH|Europe/Zurich","CI|Africa/Abidjan","CK|Pacific/Rarotonga","CL|America/Santiago America/Punta_Arenas Pacific/Easter","CM|Africa/Lagos Africa/Douala","CN|Asia/Shanghai Asia/Urumqi","CO|America/Bogota","CR|America/Costa_Rica","CU|America/Havana","CV|Atlantic/Cape_Verde","CW|America/Puerto_Rico America/Curacao","CX|Asia/Bangkok Indian/Christmas","CY|Asia/Nicosia Asia/Famagusta","CZ|Europe/Prague","DE|Europe/Zurich Europe/Berlin Europe/Busingen","DJ|Africa/Nairobi Africa/Djibouti","DK|Europe/Berlin Europe/Copenhagen","DM|America/Puerto_Rico America/Dominica","DO|America/Santo_Domingo","DZ|Africa/Algiers","EC|America/Guayaquil Pacific/Galapagos","EE|Europe/Tallinn","EG|Africa/Cairo","EH|Africa/El_Aaiun","ER|Africa/Nairobi Africa/Asmara","ES|Europe/Madrid Africa/Ceuta Atlantic/Canary","ET|Africa/Nairobi Africa/Addis_Ababa","FI|Europe/Helsinki","FJ|Pacific/Fiji","FK|Atlantic/Stanley","FM|Pacific/Kosrae Pacific/Port_Moresby Pacific/Guadalcanal Pacific/Chuuk Pacific/Pohnpei","FO|Atlantic/Faroe","FR|Europe/Paris","GA|Africa/Lagos Africa/Libreville","GB|Europe/London","GD|America/Puerto_Rico America/Grenada","GE|Asia/Tbilisi","GF|America/Cayenne","GG|Europe/London Europe/Guernsey","GH|Africa/Abidjan Africa/Accra","GI|Europe/Gibraltar","GL|America/Nuuk America/Danmarkshavn America/Scoresbysund America/Thule","GM|Africa/Abidjan Africa/Banjul","GN|Africa/Abidjan Africa/Conakry","GP|America/Puerto_Rico America/Guadeloupe","GQ|Africa/Lagos Africa/Malabo","GR|Europe/Athens","GS|Atlantic/South_Georgia","GT|America/Guatemala","GU|Pacific/Guam","GW|Africa/Bissau","GY|America/Guyana","HK|Asia/Hong_Kong","HN|America/Tegucigalpa","HR|Europe/Belgrade Europe/Zagreb","HT|America/Port-au-Prince","HU|Europe/Budapest","ID|Asia/Jakarta Asia/Pontianak Asia/Makassar Asia/Jayapura","IE|Europe/Dublin","IL|Asia/Jerusalem","IM|Europe/London Europe/Isle_of_Man","IN|Asia/Kolkata","IO|Indian/Chagos","IQ|Asia/Baghdad","IR|Asia/Tehran","IS|Africa/Abidjan Atlantic/Reykjavik","IT|Europe/Rome","JE|Europe/London Europe/Jersey","JM|America/Jamaica","JO|Asia/Amman","JP|Asia/Tokyo","KE|Africa/Nairobi","KG|Asia/Bishkek","KH|Asia/Bangkok Asia/Phnom_Penh","KI|Pacific/Tarawa Pacific/Kanton Pacific/Kiritimati","KM|Africa/Nairobi Indian/Comoro","KN|America/Puerto_Rico America/St_Kitts","KP|Asia/Pyongyang","KR|Asia/Seoul","KW|Asia/Riyadh Asia/Kuwait","KY|America/Panama America/Cayman","KZ|Asia/Almaty Asia/Qyzylorda Asia/Qostanay Asia/Aqtobe Asia/Aqtau Asia/Atyrau Asia/Oral","LA|Asia/Bangkok Asia/Vientiane","LB|Asia/Beirut","LC|America/Puerto_Rico America/St_Lucia","LI|Europe/Zurich Europe/Vaduz","LK|Asia/Colombo","LR|Africa/Monrovia","LS|Africa/Johannesburg Africa/Maseru","LT|Europe/Vilnius","LU|Europe/Brussels Europe/Luxembourg","LV|Europe/Riga","LY|Africa/Tripoli","MA|Africa/Casablanca","MC|Europe/Paris Europe/Monaco","MD|Europe/Chisinau","ME|Europe/Belgrade Europe/Podgorica","MF|America/Puerto_Rico America/Marigot","MG|Africa/Nairobi Indian/Antananarivo","MH|Pacific/Tarawa Pacific/Kwajalein Pacific/Majuro","MK|Europe/Belgrade Europe/Skopje","ML|Africa/Abidjan Africa/Bamako","MM|Asia/Yangon","MN|Asia/Ulaanbaatar Asia/Hovd Asia/Choibalsan","MO|Asia/Macau","MP|Pacific/Guam Pacific/Saipan","MQ|America/Martinique","MR|Africa/Abidjan Africa/Nouakchott","MS|America/Puerto_Rico America/Montserrat","MT|Europe/Malta","MU|Indian/Mauritius","MV|Indian/Maldives","MW|Africa/Maputo Africa/Blantyre","MX|America/Mexico_City America/Cancun America/Merida America/Monterrey America/Matamoros America/Chihuahua America/Ciudad_Juarez America/Ojinaga America/Mazatlan America/Bahia_Banderas America/Hermosillo America/Tijuana","MY|Asia/Kuching Asia/Singapore Asia/Kuala_Lumpur","MZ|Africa/Maputo","NA|Africa/Windhoek","NC|Pacific/Noumea","NE|Africa/Lagos Africa/Niamey","NF|Pacific/Norfolk","NG|Africa/Lagos","NI|America/Managua","NL|Europe/Brussels Europe/Amsterdam","NO|Europe/Berlin Europe/Oslo","NP|Asia/Kathmandu","NR|Pacific/Nauru","NU|Pacific/Niue","NZ|Pacific/Auckland Pacific/Chatham","OM|Asia/Dubai Asia/Muscat","PA|America/Panama","PE|America/Lima","PF|Pacific/Tahiti Pacific/Marquesas Pacific/Gambier","PG|Pacific/Port_Moresby Pacific/Bougainville","PH|Asia/Manila","PK|Asia/Karachi","PL|Europe/Warsaw","PM|America/Miquelon","PN|Pacific/Pitcairn","PR|America/Puerto_Rico","PS|Asia/Gaza Asia/Hebron","PT|Europe/Lisbon Atlantic/Madeira Atlantic/Azores","PW|Pacific/Palau","PY|America/Asuncion","QA|Asia/Qatar","RE|Asia/Dubai Indian/Reunion","RO|Europe/Bucharest","RS|Europe/Belgrade","RU|Europe/Kaliningrad Europe/Moscow Europe/Simferopol Europe/Kirov Europe/Volgograd Europe/Astrakhan Europe/Saratov Europe/Ulyanovsk Europe/Samara Asia/Yekaterinburg Asia/Omsk Asia/Novosibirsk Asia/Barnaul Asia/Tomsk Asia/Novokuznetsk Asia/Krasnoyarsk Asia/Irkutsk Asia/Chita Asia/Yakutsk Asia/Khandyga Asia/Vladivostok Asia/Ust-Nera Asia/Magadan Asia/Sakhalin Asia/Srednekolymsk Asia/Kamchatka Asia/Anadyr","RW|Africa/Maputo Africa/Kigali","SA|Asia/Riyadh","SB|Pacific/Guadalcanal","SC|Asia/Dubai Indian/Mahe","SD|Africa/Khartoum","SE|Europe/Berlin Europe/Stockholm","SG|Asia/Singapore","SH|Africa/Abidjan Atlantic/St_Helena","SI|Europe/Belgrade Europe/Ljubljana","SJ|Europe/Berlin Arctic/Longyearbyen","SK|Europe/Prague Europe/Bratislava","SL|Africa/Abidjan Africa/Freetown","SM|Europe/Rome Europe/San_Marino","SN|Africa/Abidjan Africa/Dakar","SO|Africa/Nairobi Africa/Mogadishu","SR|America/Paramaribo","SS|Africa/Juba","ST|Africa/Sao_Tome","SV|America/El_Salvador","SX|America/Puerto_Rico America/Lower_Princes","SY|Asia/Damascus","SZ|Africa/Johannesburg Africa/Mbabane","TC|America/Grand_Turk","TD|Africa/Ndjamena","TF|Asia/Dubai Indian/Maldives Indian/Kerguelen","TG|Africa/Abidjan Africa/Lome","TH|Asia/Bangkok","TJ|Asia/Dushanbe","TK|Pacific/Fakaofo","TL|Asia/Dili","TM|Asia/Ashgabat","TN|Africa/Tunis","TO|Pacific/Tongatapu","TR|Europe/Istanbul","TT|America/Puerto_Rico America/Port_of_Spain","TV|Pacific/Tarawa Pacific/Funafuti","TW|Asia/Taipei","TZ|Africa/Nairobi Africa/Dar_es_Salaam","UA|Europe/Simferopol Europe/Kyiv","UG|Africa/Nairobi Africa/Kampala","UM|Pacific/Pago_Pago Pacific/Tarawa Pacific/Midway Pacific/Wake","US|America/New_York America/Detroit America/Kentucky/Louisville America/Kentucky/Monticello America/Indiana/Indianapolis America/Indiana/Vincennes America/Indiana/Winamac America/Indiana/Marengo America/Indiana/Petersburg America/Indiana/Vevay America/Chicago America/Indiana/Tell_City America/Indiana/Knox America/Menominee America/North_Dakota/Center America/North_Dakota/New_Salem America/North_Dakota/Beulah America/Denver America/Boise America/Phoenix America/Los_Angeles America/Anchorage America/Juneau America/Sitka America/Metlakatla America/Yakutat America/Nome America/Adak Pacific/Honolulu","UY|America/Montevideo","UZ|Asia/Samarkand Asia/Tashkent","VA|Europe/Rome Europe/Vatican","VC|America/Puerto_Rico America/St_Vincent","VE|America/Caracas","VG|America/Puerto_Rico America/Tortola","VI|America/Puerto_Rico America/St_Thomas","VN|Asia/Bangkok Asia/Ho_Chi_Minh","VU|Pacific/Efate","WF|Pacific/Tarawa Pacific/Wallis","WS|Pacific/Apia","YE|Asia/Riyadh Asia/Aden","YT|Africa/Nairobi Indian/Mayotte","ZA|Africa/Johannesburg","ZM|Africa/Maputo Africa/Lusaka","ZW|Africa/Maputo Africa/Harare"]}),o}); diff --git a/web/src/main/webapp/xslt/base-layout-cssjs-loader.xsl b/web/src/main/webapp/xslt/base-layout-cssjs-loader.xsl index 3df6b42f16e..1a13d1d4f70 100644 --- a/web/src/main/webapp/xslt/base-layout-cssjs-loader.xsl +++ b/web/src/main/webapp/xslt/base-layout-cssjs-loader.xsl @@ -113,7 +113,7 @@ - + From 14dbaaccf29748de7609c6c05162d3991caddef6 Mon Sep 17 00:00:00 2001 From: joachimnielandt Date: Thu, 4 Jan 2024 15:10:25 +0100 Subject: [PATCH 14/50] fix duplicate check on uuid+initiative+association (#7567) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix duplicate check on uuid+initiative+association * added gmx:anchor option and unit tests * Format / Update SchematronRulesIsoTest.java --------- Co-authored-by: François Prunayre --- .../schematron/schematron-rules-iso.sch | 9 +- .../kernel/schema/SchematronRulesIsoTest.java | 88 ++++++++++++++++++- 2 files changed, 89 insertions(+), 8 deletions(-) diff --git a/schemas/iso19139/src/main/plugin/iso19139/schematron/schematron-rules-iso.sch b/schemas/iso19139/src/main/plugin/iso19139/schematron/schematron-rules-iso.sch index 87bb01c4cb9..fd1cb718fae 100755 --- a/schemas/iso19139/src/main/plugin/iso19139/schematron/schematron-rules-iso.sch +++ b/schemas/iso19139/src/main/plugin/iso19139/schematron/schematron-rules-iso.sch @@ -64,6 +64,7 @@ USA. + @@ -348,21 +349,19 @@ USA. $loc/strings/report.M23 - - - + + $loc/strings/report.M23-dup - diff --git a/web/src/test/java/org/fao/geonet/kernel/schema/SchematronRulesIsoTest.java b/web/src/test/java/org/fao/geonet/kernel/schema/SchematronRulesIsoTest.java index ee1be670a50..7b38e20856b 100644 --- a/web/src/test/java/org/fao/geonet/kernel/schema/SchematronRulesIsoTest.java +++ b/web/src/test/java/org/fao/geonet/kernel/schema/SchematronRulesIsoTest.java @@ -33,13 +33,13 @@ import java.util.Arrays; import java.util.Collections; -import static org.fao.geonet.constants.Geonet.Namespaces.GCO; -import static org.fao.geonet.constants.Geonet.Namespaces.GMD; +import static org.fao.geonet.constants.Geonet.Namespaces.*; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; /** * Test some of the rules in the schematron-rules-iso.sch files in the iso19139 schema plugin. - * + *

* Created by Jesse on 3/25/14. */ public class SchematronRulesIsoTest extends AbstractSchematronTest { @@ -149,6 +149,88 @@ public void testMissingDataIdentificationCitationDateType() throws Exception { testNoStringErrors(testMetadata, dateTypeEl); } + @Test + public void testAggregationInfoCombinations() throws Exception { + final Element testMetadata = Xml.loadStream(SchematronRulesIsoTest.class.getResourceAsStream(INSPIRE_VALID_ISO19139_XML)); + final Element mdDataIdentification = Xml.selectElement(testMetadata, "gmd:identificationInfo/gmd:MD_DataIdentification", Collections.singletonList(GMD)); + assertNotNull(mdDataIdentification); + + Element results = Xml.transform(testMetadata, getSchematronXsl(), params); + int errorsStart = countFailures(results); + + // first we test cases that should not introduce failures + addDatasetIdentifier(mdDataIdentification, "uuid-1", null, "largerWorkCitation", null); + assertEquals(errorsStart, countFailures(Xml.transform(testMetadata, getSchematronXsl(), params))); + addDatasetIdentifier(mdDataIdentification, "uuid-2", null, "largerWorkCitation", null); + assertEquals(errorsStart, countFailures(Xml.transform(testMetadata, getSchematronXsl(), params))); + addDatasetIdentifier(mdDataIdentification, "uuid-2", null, "crossReference", null); + assertEquals(errorsStart, countFailures(Xml.transform(testMetadata, getSchematronXsl(), params))); + addDatasetIdentifier(mdDataIdentification, "uuid-3", null, "crossReference", "campaign"); + assertEquals(errorsStart, countFailures(Xml.transform(testMetadata, getSchematronXsl(), params))); + addDatasetIdentifier(mdDataIdentification, "uuid-3", null, "crossReference", "collection"); + assertEquals(errorsStart, countFailures(Xml.transform(testMetadata, getSchematronXsl(), params))); + addDatasetIdentifier(mdDataIdentification, "uuid-4", "href-4", "crossReference", "collection"); + assertEquals(errorsStart, countFailures(Xml.transform(testMetadata, getSchematronXsl(), params))); + + // adding duplicate uuid+initiativeType+associationType combinations should fail + Element bad = addDatasetIdentifier(mdDataIdentification, "uuid-1", null, "largerWorkCitation", null); + assertEquals(errorsStart + 2, countFailures(Xml.transform(testMetadata, getSchematronXsl(), params))); + bad.detach(); + bad = addDatasetIdentifier(mdDataIdentification, "uuid-3", null, "crossReference", "campaign"); + assertEquals(errorsStart + 2, countFailures(Xml.transform(testMetadata, getSchematronXsl(), params))); + bad.detach(); + bad = addDatasetIdentifier(mdDataIdentification, "uuid-1", "href-1", "largerWorkCitation", null); + assertEquals(errorsStart + 2, countFailures(Xml.transform(testMetadata, getSchematronXsl(), params))); + bad.detach(); + bad = addDatasetIdentifier(mdDataIdentification, "uuid-4", "href-4", "crossReference", "collection"); + assertEquals(errorsStart + 2, countFailures(Xml.transform(testMetadata, getSchematronXsl(), params))); + bad.detach(); + } + + private static Element addDatasetIdentifier(Element parent, String uuid, String href, String associationType, String initiativeType) { + Element ai = new Element("aggregationInfo", GMD); + Element mdAi = new Element("MD_AggregateInformation", GMD); + Element adsi = new Element("aggregateDataSetIdentifier", GMD); + Element mdIdentifier = new Element("MD_Identifier", GMD); + Element code = new Element("code", GMD); + + Element at = new Element("associationType", GMD); + Element dsAt = new Element("DS_AssociationTypeCode", GMD); + dsAt.setAttribute("codeListValue", associationType); + dsAt.setAttribute("codeList", "http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#DS_AssociationTypeCode"); + + at.addContent(dsAt); + ai.addContent(mdAi); + mdAi.addContent(adsi); + mdAi.addContent(at); + adsi.addContent(mdIdentifier); + mdIdentifier.addContent(code); + + if (initiativeType != null) { + Element it = new Element("initiativeType", GMD); + Element dsIt = new Element("DS_InitiativeTypeCode", GMD); + dsIt.setAttribute("codeListValue", initiativeType); + dsIt.setAttribute("codeList", "http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#DS_InitiativeTypeCode"); + it.addContent(dsIt); + mdAi.addContent(it); + } + + if (href != null) { + Element anchor = new Element("Anchor", GMX); + anchor.setAttribute("href", href, XLINK); + anchor.setText(uuid); + code.addContent(anchor); + } else { + Element cs = new Element("CharacterString", GCO); + cs.setText(uuid); + code.addContent(cs); + } + + parent.addContent(ai); + + return ai; + } + private void testNoStringErrors(Element testMetadata, Element contact) throws Exception { contact.setContent(Collections.emptyList()); From ddd8be584868a44e166783f3a061a0c62c917d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Garc=C3=ADa?= Date: Tue, 2 Jan 2024 14:36:59 +0100 Subject: [PATCH 15/50] Fix add element attribute in the metadata editor, causing the element section is removed from the user interface until the metadata is saved --- .../xslt/ui-metadata/edit/edit-embedded.xsl | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/web/src/main/webapp/xslt/ui-metadata/edit/edit-embedded.xsl b/web/src/main/webapp/xslt/ui-metadata/edit/edit-embedded.xsl index a877105da93..afe54934720 100644 --- a/web/src/main/webapp/xslt/ui-metadata/edit/edit-embedded.xsl +++ b/web/src/main/webapp/xslt/ui-metadata/edit/edit-embedded.xsl @@ -45,7 +45,7 @@ - + @@ -57,6 +57,23 @@ + + + + + + + + + + + + + + + + - [ ] *Clean commit history* broken into understandable chucks, avoiding big commits with hundreds of files, cautious of reformatting and whitespace changes - [ ] *Clean commit message*s, longer verbose messages are encouraged - [ ] *API Changes* are identified in commit messages -- [ ] *Testing* provided for features or enhancements using [automatic tests](https://github.com/geonetwork/core-geonetwork/blob/main/software_development/TESTING.md)) -- [ ] *User documentation* provided for new features or enhancements in [mannual](https://github.com/geonetwork/core-geonetwork/tree/main/docs/manual) +- [ ] *Testing* provided for features or enhancements using [automatic tests](https://github.com/geonetwork/core-geonetwork/blob/main/software_development/TESTING.md) +- [ ] *User documentation* provided for new features or enhancements in [manual](https://github.com/geonetwork/core-geonetwork/tree/main/docs/manual) - [ ] *Build documentation* provided for development instructions in `README.md` files - [ ] *Library management* using `pom.xml` dependency management. Update build documentation with intended library use and library tutorials or documentation + + + From 81efcfc8a4456fe7596e2b1328a74fe3a699dad8 Mon Sep 17 00:00:00 2001 From: Francois Prunayre Date: Fri, 27 Oct 2023 10:57:42 +0200 Subject: [PATCH 18/50] Harvesting / WFS feature / Add WFS2 support for MapServer Mapserver may return by default GetCapabilities in version 2.0.0. Depending on the URL set in metadata records, WFS harvesting may fails with: ``` 2023-10-27T10:54:42,350 ERROR [geonetwork.harvest.wfs.features] - Failed to connect to server 'http://geoservices.brgm.fr/geologie?language=fre&'. Error is class net.opengis.wfs20.impl.WFSCapabilitiesTypeImpl cannot be cast to class net.opengis.wfs.WFSCapabilitiesType (net.opengis.wfs20.impl.WFSCapabilitiesTypeImpl and net.opengis.wfs.WFSCapabilitiesType are in unnamed module of loader org.eclipse.jetty.webapp.WebAppClassLoader @cda6100) ``` because of the `MapServerWFSStrategy` extending WFS1 strategy. Use `StrictWFS_2_0_Strategy` if harvesting is done using 2.0.0 on MapServer. Can be tested with ``` curl 'http://localhost:8080/geonetwork/srv/api/workers/data/wfs/actions/start' \ -X 'PUT' \ -H 'Accept: application/json, text/plain, */*' \ -H 'Accept-Language: eng' \ -H 'Content-Type: application/json;charset=UTF-8' \ -H 'Cookie: JSESSIONID=node0hjdye0js612o1qex2n36lekt81.node0; serverTime=1698396822574; sessionExpiry=1698398922574; XSRF-TOKEN=c353b2ca-a77c-4552-839c-37405771c4e2;' \ -H 'X-XSRF-TOKEN: c353b2ca-a77c-4552-839c-37405771c4e2' \ --data-raw '{"url":"http://geoservices.brgm.fr/geologie?language=fre&","strategy":"investigator","typeName":"GITES_EMP","version":"2.0.0"}' \ --compressed ``` --- .../wfsfeatures/model/WFSHarvesterParameter.java | 3 ++- .../worker/WFSClientWithStrategyInvestigator.java | 10 ++++++++-- .../worker/WFSDataStoreWithStrategyInvestigator.java | 7 +++---- .../wfsfeatures/worker/WFSHarvesterExchangeState.java | 8 +------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/workers/wfsfeature-harvester/src/main/java/org/fao/geonet/harvester/wfsfeatures/model/WFSHarvesterParameter.java b/workers/wfsfeature-harvester/src/main/java/org/fao/geonet/harvester/wfsfeatures/model/WFSHarvesterParameter.java index d356526f399..b5c6bf80826 100644 --- a/workers/wfsfeature-harvester/src/main/java/org/fao/geonet/harvester/wfsfeatures/model/WFSHarvesterParameter.java +++ b/workers/wfsfeature-harvester/src/main/java/org/fao/geonet/harvester/wfsfeatures/model/WFSHarvesterParameter.java @@ -33,6 +33,7 @@ */ @XmlRootElement(name = "wfs") public class WFSHarvesterParameter implements Serializable { + public static final String DEFAULT_VERSION = "1.1.0"; private String metadataUuid; private String url; @@ -41,7 +42,7 @@ public class WFSHarvesterParameter implements Serializable { private String typeName; - private String version = "1.1.0"; + private String version = DEFAULT_VERSION; private int timeOut = 300000; diff --git a/workers/wfsfeature-harvester/src/main/java/org/fao/geonet/harvester/wfsfeatures/worker/WFSClientWithStrategyInvestigator.java b/workers/wfsfeature-harvester/src/main/java/org/fao/geonet/harvester/wfsfeatures/worker/WFSClientWithStrategyInvestigator.java index 140238d92e5..cc3b979d250 100644 --- a/workers/wfsfeature-harvester/src/main/java/org/fao/geonet/harvester/wfsfeatures/worker/WFSClientWithStrategyInvestigator.java +++ b/workers/wfsfeature-harvester/src/main/java/org/fao/geonet/harvester/wfsfeatures/worker/WFSClientWithStrategyInvestigator.java @@ -30,6 +30,7 @@ import org.geotools.data.wfs.internal.WFSGetCapabilities; import org.geotools.data.wfs.internal.WFSStrategy; import org.geotools.data.wfs.internal.v1_x.MapServerWFSStrategy; +import org.geotools.data.wfs.internal.v2_0.StrictWFS_2_0_Strategy; import org.geotools.http.HTTPClient; import org.geotools.http.HTTPResponse; import org.geotools.ows.ServiceException; @@ -38,6 +39,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.nio.charset.StandardCharsets; import static org.fao.geonet.harvester.wfsfeatures.worker.WFSHarvesterExchangeState.MAPSERVER_STRATEGY; import static org.fao.geonet.harvester.wfsfeatures.worker.WFSHarvesterExchangeState.QGIS_STRATEGY; @@ -84,12 +86,16 @@ private WFSStrategy determineCorrectStrategy(HTTPClient httpClient) { while ((readCount = inputStream.read(buff)) != -1) { out.write(buff, 0, readCount); } - String responsePayload = out.toString("UTF-8"); + String responsePayload = out.toString(StandardCharsets.UTF_8); if (responsePayload.contains("targetNamespace=\"http://www.qgis.org/gml\"")) { strategy = new QgisStrategy(); strategyId = QGIS_STRATEGY; } else if (responsePayload.contains("targetNamespace=\"http://mapserver.gis.umn.edu/mapserver\"")) { - strategy = new MapServerWFSStrategy(capabilities.getRawDocument()); + if (capabilities.getVersion().equals("2.0.0")) { + strategy = new StrictWFS_2_0_Strategy(); + } else { + strategy = new MapServerWFSStrategy(capabilities.getRawDocument()); + } strategyId = MAPSERVER_STRATEGY; } } catch (Exception e) { diff --git a/workers/wfsfeature-harvester/src/main/java/org/fao/geonet/harvester/wfsfeatures/worker/WFSDataStoreWithStrategyInvestigator.java b/workers/wfsfeature-harvester/src/main/java/org/fao/geonet/harvester/wfsfeatures/worker/WFSDataStoreWithStrategyInvestigator.java index 4849f8a7fa2..eac7b317ea1 100644 --- a/workers/wfsfeature-harvester/src/main/java/org/fao/geonet/harvester/wfsfeatures/worker/WFSDataStoreWithStrategyInvestigator.java +++ b/workers/wfsfeature-harvester/src/main/java/org/fao/geonet/harvester/wfsfeatures/worker/WFSDataStoreWithStrategyInvestigator.java @@ -45,11 +45,10 @@ */ public class WFSDataStoreWithStrategyInvestigator extends WFSDataStoreFactory { - private static Logger LOGGER = LoggerFactory.getLogger(WFSHarvesterRouteBuilder.LOGGER_NAME); private String describeFeatureTypeUrl; - public void init (String url, String typeName) throws Exception { - this.describeFeatureTypeUrl = new OwsUtils().getDescribeFeatureTypeUrl(url, typeName, "1.1.0"); + public void init (String url, String typeName, String version) throws Exception { + this.describeFeatureTypeUrl = new OwsUtils().getDescribeFeatureTypeUrl(url, typeName, version); } @Override @@ -66,7 +65,7 @@ public WFSDataStore createDataStore(Map params) throws IOException { } } - final URL capabilitiesURL = (URL) URL.lookUp(params); + final URL capabilitiesURL = URL.lookUp(params); final HTTPClient http = getHttpClient(params); http.setTryGzip(config.isTryGZIP()); diff --git a/workers/wfsfeature-harvester/src/main/java/org/fao/geonet/harvester/wfsfeatures/worker/WFSHarvesterExchangeState.java b/workers/wfsfeature-harvester/src/main/java/org/fao/geonet/harvester/wfsfeatures/worker/WFSHarvesterExchangeState.java index d9b563dadad..e26f463e995 100644 --- a/workers/wfsfeature-harvester/src/main/java/org/fao/geonet/harvester/wfsfeatures/worker/WFSHarvesterExchangeState.java +++ b/workers/wfsfeature-harvester/src/main/java/org/fao/geonet/harvester/wfsfeatures/worker/WFSHarvesterExchangeState.java @@ -116,7 +116,7 @@ public void initDataStore() throws Exception { if (INVESTIGATOR_STRATEGY.equals(parameters.getStrategy())) { factory = new WFSDataStoreWithStrategyInvestigator(); ((WFSDataStoreWithStrategyInvestigator) factory).init( - parameters.getUrl(), parameters.getTypeName()); + parameters.getUrl(), parameters.getTypeName(), parameters.getVersion()); } else { factory = new WFSDataStoreFactory(); } @@ -145,15 +145,9 @@ public void initDataStore() throws Exception { } wfsDatastore = factory.createDataStore(m); - // Default to GeoTools auto mode for MapServer. if(factory instanceof WFSDataStoreWithStrategyInvestigator) { WFSClientWithStrategyInvestigator wfsClientWithStrategyInvestigator = (WFSClientWithStrategyInvestigator) wfsDatastore.getWfsClient(); this.strategyId = wfsClientWithStrategyInvestigator.getStrategyId(); - if (MAPSERVER_STRATEGY.equals(wfsClientWithStrategyInvestigator.getStrategyId())) { - Map connectionParameters = new HashMap<>(); - connectionParameters.put("WFSDataStoreFactory:GET_CAPABILITIES_URL", parameters.getUrl()); - wfsDatastore = (WFSDataStore) DataStoreFinder.getDataStore(connectionParameters); - } } } catch (IOException e) { String errorMsg = String.format( From 4a5a17f24c74cea4b51e9c0beb18feacf7e972c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Prunayre?= Date: Fri, 5 Jan 2024 08:14:04 +0100 Subject: [PATCH 19/50] Build info improvements. (#7400) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Build info improvements. Remove unused server.prop file. Display git branch, git commit, build time only (remove git describe which is misleading). * Add application version to site information API --------- Co-authored-by: Jose García --- .gitignore | 1 - .../org/fao/geonet/api/site/SiteInformation.java | 14 +++++++++++--- .../main/resources/catalog/locales/en-admin.json | 2 ++ web/pom.xml | 1 - web/src/main/webapp/WEB-INF/server.prop | 16 ---------------- 5 files changed, 13 insertions(+), 21 deletions(-) delete mode 100644 web/src/main/webapp/WEB-INF/server.prop diff --git a/.gitignore b/.gitignore index 60446e3e3c0..265f74f1dc0 100644 --- a/.gitignore +++ b/.gitignore @@ -80,7 +80,6 @@ web/src/main/webapp/WEB-INF/data/wro4j*.db web/src/main/webapp/WEB-INF/data/wro4j-cache* web/src/main/webapp/WEB-INF/data_* web/src/main/webapp/WEB-INF/metadata_subversion/ -web/src/main/webapp/WEB-INF/server.prop web/src/main/webapp/WEB-INF/prebuilt web/src/main/webapp/data/ web/src/main/webapp/doc/en diff --git a/services/src/main/java/org/fao/geonet/api/site/SiteInformation.java b/services/src/main/java/org/fao/geonet/api/site/SiteInformation.java index 7041658c6dc..c188f63c6a3 100644 --- a/services/src/main/java/org/fao/geonet/api/site/SiteInformation.java +++ b/services/src/main/java/org/fao/geonet/api/site/SiteInformation.java @@ -32,6 +32,9 @@ import org.fao.geonet.GeonetContext; import org.fao.geonet.constants.Geonet; import org.fao.geonet.kernel.search.EsSearchManager; +import org.fao.geonet.kernel.setting.SettingInfo; +import org.fao.geonet.kernel.setting.SettingManager; +import org.fao.geonet.kernel.setting.Settings; import org.fao.geonet.utils.Env; import org.fao.geonet.utils.Log; import org.fao.geonet.utils.TransformerFactoryFactory; @@ -70,7 +73,7 @@ public SiteInformation(final ServiceContext context, final GeonetContext gc) { Log.error(Geonet.GEONETWORK, e.getMessage(), e); } loadEnvInfo(); - loadVersionInfo(); + loadVersionInfo(context); loadSystemInfo(); } } @@ -266,12 +269,17 @@ private void loadDatabaseInfo(ServiceContext context) throws SQLException { } /** - * Compute information about git commit. + * Compute information about the application and git commit. */ - private void loadVersionInfo() { + private void loadVersionInfo(ServiceContext context) { Properties prop = new Properties(); try (InputStream input = getClass().getResourceAsStream("/git.properties")) { + SettingManager settingManager = context.getBean(SettingManager.class); + + versionProperties.put("app.version", settingManager.getValue(Settings.SYSTEM_PLATFORM_VERSION)); + versionProperties.put("app.subVersion", settingManager.getValue(Settings.SYSTEM_PLATFORM_SUBVERSION)); + prop.load(input); Enumeration e = prop.propertyNames(); diff --git a/web-ui/src/main/resources/catalog/locales/en-admin.json b/web-ui/src/main/resources/catalog/locales/en-admin.json index 8db7f48107a..bb842b39688 100644 --- a/web-ui/src/main/resources/catalog/locales/en-admin.json +++ b/web-ui/src/main/resources/catalog/locales/en-admin.json @@ -1475,6 +1475,8 @@ "es.version": "Elasticsearch version", "es.index": "Index name", "systemPropertiesProxyConfiguration": "Using http proxy settings in system properties.", + "app.version": "Application version", + "app.subVersion": "Application minor version", "fieldRequired": "The value is required", "fieldTooLong": "The value is too long", "fieldTooShort": "The value is too short", diff --git a/web/pom.xml b/web/pom.xml index 64e19889532..61473c5ae3d 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -668,7 +668,6 @@ ^git.tags$ ^git.branch$ ^git.commit.id$ - ^git.commit.id.describe.*$ ^git.build.time$ diff --git a/web/src/main/webapp/WEB-INF/server.prop b/web/src/main/webapp/WEB-INF/server.prop deleted file mode 100644 index f5ef6a89f40..00000000000 --- a/web/src/main/webapp/WEB-INF/server.prop +++ /dev/null @@ -1,16 +0,0 @@ -#GeoNetwork opensource properties. These are also used by geonetwork at runtime -#Fri, 18 Jun 2021 08:12:05 +0000 - -version=4.0.5 -subVersion=0 -release=4.0.5 -javaVersion=1.8.0 -jre_url=http\://openjdk.java.net/ -ant.build.javac.target=1.8 -buildDate=2021-06-18T08\:12\:05+0000 -date=2112180812 -day=18-6-2021 -OS=Compiled on Linux (unix) -debugOn=on -git_revision=224e45beccec1a666556aab59f4d7b65de29f2d1 -git_url=https\://github.com/geonetwork/core-geonetwork.git (push) From 6c8c450ff6dd23babd1e22237e59dfad60065445 Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 5 Jan 2024 06:57:43 -0400 Subject: [PATCH 20/50] Fix duplicate operation id caused by use of 2 methods GET/POST method from getKeywordById api (#7586) * Remove POST method from getKeywordById. api A get method should not generally support a POST? It caused duplicates duplicate OperationID that would occur (getKeywordById and getKeywordById_1) * Re added POST method for keyword and depreciated the GET api. * Use common private getKeyword function for both api calls. * Revert endpoint back to /keyword for GET --- .../registries/vocabularies/KeywordsApi.java | 114 +++++++++++++++++- 1 file changed, 108 insertions(+), 6 deletions(-) diff --git a/services/src/main/java/org/fao/geonet/api/registries/vocabularies/KeywordsApi.java b/services/src/main/java/org/fao/geonet/api/registries/vocabularies/KeywordsApi.java index 93ad30ec0c2..d28d7507a6c 100644 --- a/services/src/main/java/org/fao/geonet/api/registries/vocabularies/KeywordsApi.java +++ b/services/src/main/java/org/fao/geonet/api/registries/vocabularies/KeywordsApi.java @@ -327,10 +327,7 @@ public Object searchKeywords( ) @RequestMapping( path = "/keyword", - method = { - RequestMethod.GET, - RequestMethod.POST - }, + method = RequestMethod.GET, produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE @@ -382,6 +379,112 @@ public Object getKeywordById( @Parameter(hidden = true) HttpServletRequest request ) throws Exception { + return getKeyword(uri,sThesaurusName,langs, keywordOnly, transformation,langMapJson,allRequestParams, accept, request); + } + + /** + * Gets the keyword by id. + * + * @param uri the uri + * @param sThesaurusName the s thesaurus name + * @param langs the langs + * @param keywordOnly the keyword only + * @param transformation the transformation + * @param allRequestParams the all request params + * @param request the request + * @return the keyword by id + * @throws Exception the exception + */ + @io.swagger.v3.oas.annotations.Operation( + summary = "Get keyword by ids", + description = "Retrieve XML representation of keyword(s) from same thesaurus" + + "using different transformations. " + + "'to-iso19139-keyword' is the default and return an ISO19139 snippet." + + "'to-iso19139-keyword-as-xlink' return an XLinked element. Custom transformation " + + "can be create on a per schema basis." + + "This can be used instead of the GET method for cases where you need to submit large parameters list" + ) + @RequestMapping( + path = "/keyword", + method = RequestMethod.POST, + produces = { + MediaType.APPLICATION_XML_VALUE, + MediaType.APPLICATION_JSON_VALUE + }) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "XML snippet with requested keywords."), + }) + @ResponseBody + @ResponseStatus(HttpStatus.OK) + public Object getKeywordByIds( + @Parameter( + description = "Keyword identifier or list of keyword identifiers comma separated.", + required = true) + @RequestParam(name = "id") + String uri, + @Parameter( + description = "Thesaurus to look info for the keyword(s).", + required = true) + @RequestParam(name = "thesaurus") + String sThesaurusName, + @Parameter( + description = "Languages.", + required = false) + @RequestParam(name = "lang", required = false) + String[] langs, + @Parameter( + description = "Only print the keyword, no thesaurus information.", + required = false) + @RequestParam(required = false, defaultValue = "false") + boolean keywordOnly, + @Parameter( + description = "XSL template to use (ISO19139 keyword by default, see convert.xsl).", + required = false) + @RequestParam(required = false) + String transformation, + @Parameter( + description = "langMap, that converts the values in the 'lang' parameter to how they will be actually represented in the record. {'fre':'fra'} or {'fre':'fr'}. Missing/empty means to convert to iso 2 letter.", + required = false) + @RequestParam (name = "langMap", required = false) + String langMapJson, + @Parameter(hidden = true) + @RequestParam + Map allRequestParams, + @RequestHeader( + value = "Accept", + defaultValue = MediaType.APPLICATION_XML_VALUE + ) + String accept, + @Parameter(hidden = true) + HttpServletRequest request + ) throws Exception { + return getKeyword(uri,sThesaurusName,langs, keywordOnly, transformation,langMapJson,allRequestParams, accept, request); + } + + /** + * Gets the keyword by id. + * + * @param uri the uri + * @param sThesaurusName the s thesaurus name + * @param langs the langs + * @param keywordOnly the keyword only + * @param transformation the transformation + * @param allRequestParams the all request params + * @param request the request + * @return the keyword by id + * @throws Exception the exception + */ + private Object getKeyword( + String uri, + String sThesaurusName, + String[] langs, + boolean keywordOnly, + String transformation, + String langMapJson, + Map allRequestParams, + String accept, + HttpServletRequest request + ) throws Exception { final String SEPARATOR = ","; ServiceContext context = ApiUtils.createServiceContext(request); boolean isJson = MediaType.APPLICATION_JSON_VALUE.equals(accept); @@ -458,7 +561,7 @@ public Object getKeywordById( } } - Element langConversion = null; + Element langConversion = null; if ( (langMapJson != null) && (!langMapJson.isEmpty()) ){ JSONObject obj = JSONObject.fromObject(langMapJson); langConversion = new Element("languageConversions"); @@ -512,7 +615,6 @@ public Object getKeywordById( } } - /** * Gets the thesaurus. * From dc5df0c341e28b56793791d423b60d14c61b344e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Prunayre?= Date: Fri, 5 Jan 2024 12:57:15 +0100 Subject: [PATCH 21/50] Search results / Configure related records type depending on template. (#7376) * Search results / Configure related records type depending on template. The search API provides the possibility to load related records for each hits. This allows to easily display them in search results but it also slow down a bit the search. Currently only the `list.html` template was displaying them based on the following configuration: ``` resultViewTpls: ... grid: { related: ["parent", "children", "services", "datasets"] }, ``` but user may want to customize this depending on the result template. This move the configuration to the `resultViewTpls` (and preserve previous mechanism) ``` resultViewTpls: ... { tplUrl: "../../catalog/components/" + "search/resultsview/partials/viewtemplates/list.html", tooltip: "List", icon: "fa-bars", related: ["parent", "children", "services", "datasets"] }, ``` so that user can more easily define which relations to load during search depending on the result template used. * Search / Optimize field based on current template Each search results templates display a specific set of fields. Add possibility to exclude unused fields from search to speed up search. At some point, it could be better to declare all required fields for rendering records on a per template basis on top of required fields needed for the JS app logic (eg. privileges, status, draft). * Batch edit / Properly init result template config. * Search / Optimize field based on current template / Add admin UI config. --- .../admin/uiconfig/partials/uiconfig.html | 25 +++++++++-- .../components/elasticsearch/EsFacet.js | 12 ++++- .../components/elasticsearch/EsService.js | 10 ++++- .../resultsview/ResultsviewDirective.js | 22 +++------- .../partials/templateswitcher.html | 4 +- .../searchmanager/SearchFormDirective.js | 44 +++++++++++++++---- .../viewer/owscontext/OwsContextDirective.js | 8 ++-- .../resources/catalog/js/CatController.js | 27 ++++++++++-- .../catalog/js/edit/BatchEditController.js | 2 +- .../catalog/js/edit/EditorBoardController.js | 2 +- .../catalog/js/search/SearchController.js | 2 +- .../resources/catalog/locales/en-admin.json | 5 +++ .../resources/catalog/views/default/module.js | 10 +++-- 13 files changed, 125 insertions(+), 48 deletions(-) diff --git a/web-ui/src/main/resources/catalog/components/admin/uiconfig/partials/uiconfig.html b/web-ui/src/main/resources/catalog/components/admin/uiconfig/partials/uiconfig.html index ee1f2c513f3..786d13aabfc 100644 --- a/web-ui/src/main/resources/catalog/components/admin/uiconfig/partials/uiconfig.html +++ b/web-ui/src/main/resources/catalog/components/admin/uiconfig/partials/uiconfig.html @@ -333,21 +333,27 @@

{{('ui-mod-' + m) | translate}}

- Icon + {{('ui-' + key + '-icon') | translate}} - Template URL + {{('ui-' + key + '-tplUrl') | translate}} - Tooltip + {{('ui-' + key + '-tooltip') | translate}} {{('ui-mod-' + m) | translate}} data-ng-model="opt.tooltip" />
+ +
+ + +
+
+ + +
@@ -17,7 +17,7 @@
- call {{c.phone}} + + {{c.phone}} @@ -91,7 +92,8 @@ {{c.address}} - call {{c.phone}} + + {{c.phone}} @@ -147,7 +149,8 @@ {{c.address}} - call {{c.phone}} + + {{c.phone}} @@ -187,7 +190,8 @@

{{c.address}}
- call {{c.phone}} + + {{c.phone}} @@ -226,7 +230,8 @@

{{c.address}}
- call {{c.phone}} + + {{c.phone}}
From 523a8c7f07889ccc043ba4d1c57e5106d228e3e9 Mon Sep 17 00:00:00 2001 From: Ian Date: Tue, 9 Jan 2024 08:48:34 -0400 Subject: [PATCH 25/50] Add missing swagger icons that were referenced in the index.html file. (#7597) Icons taken from https://github.com/swagger-api/swagger-ui/tree/master/dist --- web/src/main/webapp/doc/api/favicon-16x16.png | Bin 0 -> 665 bytes web/src/main/webapp/doc/api/favicon-32x32.png | Bin 0 -> 628 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 web/src/main/webapp/doc/api/favicon-16x16.png create mode 100644 web/src/main/webapp/doc/api/favicon-32x32.png diff --git a/web/src/main/webapp/doc/api/favicon-16x16.png b/web/src/main/webapp/doc/api/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..8b194e617af1c135e6b37939591d24ac3a5efa18 GIT binary patch literal 665 zcmV;K0%rY*P)}JKSduyL>)s!A4EhTMMEM%Q;aL6%l#xiZiF>S;#Y{N2Zz%pvTGHJduXuC6Lx-)0EGfRy*N{Tv4i8@4oJ41gw zKzThrcRe|7J~(YYIBq{SYCkn-KQm=N8$CrEK1CcqMI1dv9z#VRL_{D)L|`QmF8}}l zJ9JV`Q}p!p_4f7m_U`WQ@apR4;o;!mnU<7}iG_qr zF(e)x9~BG-3IzcG2M4an0002kNkl41`ZiN1i62V%{PM@Ry|IS_+Yc7{bb`MM~xm(7p4|kMHP&!VGuDW4kFixat zXw43VmgwEvB$hXt_u=vZ>+v4i7E}n~eG6;n4Z=zF1n?T*yg<;W6kOfxpC6nao>VR% z?fpr=asSJ&`L*wu^rLJ5Peq*PB0;alL#XazZCBxJLd&giTfw@!hW167F^`7kobi;( ze<<>qNlP|xy7S1zl@lZNIBR7#o9ybJsptO#%}P0hz~sBp00000NkvXXu0mjfUsDF? literal 0 HcmV?d00001 diff --git a/web/src/main/webapp/doc/api/favicon-32x32.png b/web/src/main/webapp/doc/api/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..249737fe44558e679f0b67134e274461d988fa98 GIT binary patch literal 628 zcmV-)0*n2LP)Ma*GM0}OV<074bNCP7P7GVd{iMr*I6y~TMLss@FjvgL~HxU z%Vvj33AwpD(Z4*$Mfx=HaU16axM zt2xG_rloN<$iy9j9I5 Date: Tue, 9 Jan 2024 10:19:25 -0400 Subject: [PATCH 26/50] Spring doc - Set API enum as ref (#7595) * Set API enum as ref - This will allow common reference to enum in the open api spec. * set enum asref for ReservedGroup group as well. --- .../geonet/api/records/model/related/RelatedItemType.java | 3 +++ .../main/java/org/fao/geonet/config/PublicationOption.java | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/services/src/main/java/org/fao/geonet/api/records/model/related/RelatedItemType.java b/services/src/main/java/org/fao/geonet/api/records/model/related/RelatedItemType.java index a2fc5e8df43..396f26d6513 100644 --- a/services/src/main/java/org/fao/geonet/api/records/model/related/RelatedItemType.java +++ b/services/src/main/java/org/fao/geonet/api/records/model/related/RelatedItemType.java @@ -1,6 +1,9 @@ package org.fao.geonet.api.records.model.related; +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(enumAsRef = true) public enum RelatedItemType { /** diff --git a/services/src/main/java/org/fao/geonet/config/PublicationOption.java b/services/src/main/java/org/fao/geonet/config/PublicationOption.java index 6be7da114b3..5c2e53783c5 100644 --- a/services/src/main/java/org/fao/geonet/config/PublicationOption.java +++ b/services/src/main/java/org/fao/geonet/config/PublicationOption.java @@ -30,6 +30,8 @@ import java.util.List; import java.util.Map; +import io.swagger.v3.oas.annotations.media.Schema; + /** * Defines a publication configuration. * @@ -42,12 +44,15 @@ public class PublicationOption { private String name; // Group to publish + @Schema(enumAsRef = true) private ReservedGroup publicationGroup; // List of operations to activate in the group to publish/unpublish. - List publicationOperations; + @Schema(enumAsRef = true) + private List publicationOperations; // Additional group(s)/operations(s) to publish/unpublish when the publication is selected. + @Schema(enumAsRef = true) private EnumMap> additionalPublications = new EnumMap<>(ReservedGroup.class); PublicationOption(String name, ReservedGroup publicationGroup, List publicationOperations) { From 6dacf282e9db24d07ef4babe883fbd4551da6999 Mon Sep 17 00:00:00 2001 From: Ian Date: Tue, 9 Jan 2024 10:22:47 -0400 Subject: [PATCH 27/50] Fix issue with @ResponseStatus and @ApiResponse being out of sync. (#7588) * Fix issue with @ResponseStatus and @ApiResponse being out of sync. Update @ApiResponse so that they are in sync with @ResponseStatus * Change Delete on record/tags so that it returns OK 200. --- .../org/fao/geonet/api/records/MetadataInsertDeleteApi.java | 2 +- .../java/org/fao/geonet/api/records/MetadataProcessApi.java | 2 +- .../main/java/org/fao/geonet/api/records/MetadataTagApi.java | 4 ++-- .../fao/geonet/api/records/attachments/AttachmentsApi.java | 2 +- .../src/main/java/org/fao/geonet/api/sources/SourcesApi.java | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/services/src/main/java/org/fao/geonet/api/records/MetadataInsertDeleteApi.java b/services/src/main/java/org/fao/geonet/api/records/MetadataInsertDeleteApi.java index 1c50daf45e3..54ad6f38557 100644 --- a/services/src/main/java/org/fao/geonet/api/records/MetadataInsertDeleteApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/MetadataInsertDeleteApi.java @@ -253,7 +253,7 @@ public void deleteRecord( MediaType.APPLICATION_JSON_VALUE } ) - @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Report about deleted records."), + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Report about deleted records."), @ApiResponse(responseCode = "403", description = ApiParams.API_RESPONSE_NOT_ALLOWED_ONLY_EDITOR)}) @PreAuthorize("hasAuthority('Editor')") @ResponseStatus(HttpStatus.OK) diff --git a/services/src/main/java/org/fao/geonet/api/records/MetadataProcessApi.java b/services/src/main/java/org/fao/geonet/api/records/MetadataProcessApi.java index f40d2e293b0..eabe2b9f437 100644 --- a/services/src/main/java/org/fao/geonet/api/records/MetadataProcessApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/MetadataProcessApi.java @@ -162,7 +162,7 @@ ResponseEntity processRecordPreview( RequestMethod.POST,}, produces = MediaType.APPLICATION_XML_VALUE) @PreAuthorize("hasAuthority('Editor')") @ResponseStatus(HttpStatus.OK) - @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Record processed and saved."), + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Record processed and saved."), @ApiResponse(responseCode = "403", description = ApiParams.API_RESPONSE_NOT_ALLOWED_CAN_EDIT)}) public @ResponseBody ResponseEntity processRecord( diff --git a/services/src/main/java/org/fao/geonet/api/records/MetadataTagApi.java b/services/src/main/java/org/fao/geonet/api/records/MetadataTagApi.java index 11a2cd603d4..21a62deeb4a 100644 --- a/services/src/main/java/org/fao/geonet/api/records/MetadataTagApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/MetadataTagApi.java @@ -389,9 +389,9 @@ public MetadataProcessingReport tagRecords( produces = { MediaType.APPLICATION_JSON_VALUE }) - @ResponseStatus(value = HttpStatus.NO_CONTENT) + @ResponseStatus(value = HttpStatus.OK) @ApiResponses(value = { - @ApiResponse(responseCode = "201", description = "Report about removed records."), + @ApiResponse(responseCode = "200", description = "Report about removed records."), @ApiResponse(responseCode = "403", description = ApiParams.API_RESPONSE_NOT_ALLOWED_ONLY_EDITOR) }) @PreAuthorize("hasAuthority('Editor')") diff --git a/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsApi.java b/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsApi.java index 9f04ba5ef5d..1751e9f67a1 100644 --- a/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsApi.java @@ -250,7 +250,7 @@ public MetadataResource putResourceFromURL( // @PreAuthorize("permitAll") @RequestMapping(value = "/{resourceId:.+}", method = RequestMethod.GET) @ResponseStatus(value = HttpStatus.OK) - @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Record attachment."), + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Record attachment."), @ApiResponse(responseCode = "403", description = "Operation not allowed. " + "User needs to be able to download the resource.")}) public void getResource( diff --git a/services/src/main/java/org/fao/geonet/api/sources/SourcesApi.java b/services/src/main/java/org/fao/geonet/api/sources/SourcesApi.java index 2c268bab668..ce6013e3f7f 100644 --- a/services/src/main/java/org/fao/geonet/api/sources/SourcesApi.java +++ b/services/src/main/java/org/fao/geonet/api/sources/SourcesApi.java @@ -272,7 +272,7 @@ public ResponseEntity updateSource( @PreAuthorize("hasAuthority('Administrator')") @ResponseStatus(HttpStatus.NO_CONTENT) @ApiResponses(value = { - @ApiResponse(responseCode = "201", description = "Source deleted."), + @ApiResponse(responseCode = "204", description = "Source deleted."), @ApiResponse(responseCode = "403", description = ApiParams.API_RESPONSE_NOT_ALLOWED_ONLY_ADMIN) }) @ResponseBody From 4b6b30cefc337d33e95ecce0f5d3db8bb70fe51c Mon Sep 17 00:00:00 2001 From: CMath04 Date: Tue, 9 Jan 2024 17:01:31 +0100 Subject: [PATCH 28/50] Fix linux specific file separator used for harvester transform option list --- services/src/main/java/org/fao/geonet/api/site/SiteApi.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/src/main/java/org/fao/geonet/api/site/SiteApi.java b/services/src/main/java/org/fao/geonet/api/site/SiteApi.java index ae4aea888fa..27dd5e5975a 100644 --- a/services/src/main/java/org/fao/geonet/api/site/SiteApi.java +++ b/services/src/main/java/org/fao/geonet/api/site/SiteApi.java @@ -93,6 +93,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.awt.image.BufferedImage; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -876,7 +877,7 @@ public List getXslTransformations( )) { for (Path sheet : sheets) { String id = sheet.toString(); - if (id != null && id.contains("convert/from") && id.endsWith(".xsl")) { + if (id != null && id.contains("convert" + File.separator + "from") && id.endsWith(".xsl")) { String name = com.google.common.io.Files.getNameWithoutExtension( sheet.getFileName().toString()); list.add(IMPORT_STYLESHEETS_SCHEMA_PREFIX + schema + ":convert/" + name); From 07349d682cb6090984b3b9e4bd1d4b194316deb9 Mon Sep 17 00:00:00 2001 From: Joachim Nielandt Date: Wed, 10 Jan 2024 09:10:37 +0100 Subject: [PATCH 29/50] Preventing indexing error by limiting selection amount --- .../iso19139/src/main/plugin/iso19139/index-fields/index.xsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/iso19139/src/main/plugin/iso19139/index-fields/index.xsl b/schemas/iso19139/src/main/plugin/iso19139/index-fields/index.xsl index ab8df8449fa..82b2fa89ece 100644 --- a/schemas/iso19139/src/main/plugin/iso19139/index-fields/index.xsl +++ b/schemas/iso19139/src/main/plugin/iso19139/index-fields/index.xsl @@ -977,7 +977,7 @@ + select="(../../gmd:dateTime/gco:DateTime)[1]"/> { "name": "", From 161c1df1adcf80cbf9516e623bc751f1fb240f59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Garc=C3=ADa?= Date: Wed, 10 Jan 2024 12:00:59 +0100 Subject: [PATCH 30/50] Update files with Prettier formatting --- .../catalog/components/common/openlayers/olMapDirective.js | 2 +- .../catalog/views/default/templates/recordView/type-series.html | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/web-ui/src/main/resources/catalog/components/common/openlayers/olMapDirective.js b/web-ui/src/main/resources/catalog/components/common/openlayers/olMapDirective.js index 8f633ddfcfc..9f182ad35f5 100644 --- a/web-ui/src/main/resources/catalog/components/common/openlayers/olMapDirective.js +++ b/web-ui/src/main/resources/catalog/components/common/openlayers/olMapDirective.js @@ -68,7 +68,7 @@ map.setTarget(target); var target = element[0]; - var resizeObserver = new ResizeObserver(function() { + var resizeObserver = new ResizeObserver(function () { map.updateSize(); resizeObserver.unobserve(target); }); diff --git a/web-ui/src/main/resources/catalog/views/default/templates/recordView/type-series.html b/web-ui/src/main/resources/catalog/views/default/templates/recordView/type-series.html index 5dcfd18da20..45d27acb532 100644 --- a/web-ui/src/main/resources/catalog/views/default/templates/recordView/type-series.html +++ b/web-ui/src/main/resources/catalog/views/default/templates/recordView/type-series.html @@ -43,8 +43,6 @@ >
- -
Date: Wed, 10 Jan 2024 14:02:26 -0500 Subject: [PATCH 31/50] Service context null pointer (#7593) * Service context null pointer * Service context null pointer for JCloud and S3 --- .../org/fao/geonet/api/records/attachments/AbstractStore.java | 2 +- .../org/fao/geonet/api/records/attachments/CMISStore.java | 4 ++-- .../org/fao/geonet/api/records/attachments/JCloudStore.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/fao/geonet/api/records/attachments/AbstractStore.java b/core/src/main/java/org/fao/geonet/api/records/attachments/AbstractStore.java index dfcd55a1b51..c2c20f8c898 100644 --- a/core/src/main/java/org/fao/geonet/api/records/attachments/AbstractStore.java +++ b/core/src/main/java/org/fao/geonet/api/records/attachments/AbstractStore.java @@ -97,7 +97,7 @@ public final ResourceHolder getResource(ServiceContext context, String metadataU } protected static AccessManager getAccessManager(final ServiceContext context) { - return context.getBean(AccessManager.class); + return ApplicationContextHolder.get().getBean(AccessManager.class); } public static int getAndCheckMetadataId(String metadataUuid, Boolean approved) throws Exception { diff --git a/datastorages/cmis/src/main/java/org/fao/geonet/api/records/attachments/CMISStore.java b/datastorages/cmis/src/main/java/org/fao/geonet/api/records/attachments/CMISStore.java index 87f74ab9982..769267a5a14 100644 --- a/datastorages/cmis/src/main/java/org/fao/geonet/api/records/attachments/CMISStore.java +++ b/datastorages/cmis/src/main/java/org/fao/geonet/api/records/attachments/CMISStore.java @@ -617,7 +617,7 @@ protected Path getBaseMetadataDir(ServiceContext context, Path metadataFullDir) } private GeonetworkDataDirectory getDataDirectory(ServiceContext context) { - return context.getBean(GeonetworkDataDirectory.class); + return ApplicationContextHolder.get().getBean(GeonetworkDataDirectory.class); } /** @@ -690,7 +690,7 @@ protected MetadataResourceExternalManagementProperties getMetadataResourceExtern if (metadataResourceExternalManagementPropertiesUrl.contains("{lang}") || metadataResourceExternalManagementPropertiesUrl.contains("{ISO3lang}")) { final IsoLanguagesMapper mapper = ApplicationContextHolder.get().getBean(IsoLanguagesMapper.class); - String contextLang = context.getLanguage() == null ? Geonet.DEFAULT_LANGUAGE : context.getLanguage(); + String contextLang = context==null || context.getLanguage() == null ? Geonet.DEFAULT_LANGUAGE : context.getLanguage(); String lang; String iso3Lang; diff --git a/datastorages/jcloud/src/main/java/org/fao/geonet/api/records/attachments/JCloudStore.java b/datastorages/jcloud/src/main/java/org/fao/geonet/api/records/attachments/JCloudStore.java index d7ed09b1837..02bccbedc49 100644 --- a/datastorages/jcloud/src/main/java/org/fao/geonet/api/records/attachments/JCloudStore.java +++ b/datastorages/jcloud/src/main/java/org/fao/geonet/api/records/attachments/JCloudStore.java @@ -381,7 +381,7 @@ private Path getBaseMetadataDir(ServiceContext context, Path metadataFullDir) { } private GeonetworkDataDirectory getDataDirectory(ServiceContext context) { - return context.getBean(GeonetworkDataDirectory.class); + return ApplicationContextHolder.get().getBean(GeonetworkDataDirectory.class); } /** From 541b0137775149996d9974f03297eedc4dd09353 Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 10 Jan 2024 15:03:25 -0400 Subject: [PATCH 32/50] Fix duplicate API endpoint /feeds (#7581) * Fix duplicate API endpoint There were GET 2 apis with the end point /feeds. One was renamed to /feedsAsHtml * Based on feedback. Removed /feedsAsHtml endpoint and now check Accept header when calling /feeds to determine if XML or HTML should be returned. --- .../services/inspireatom/AtomSearch.java | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/inspire-atom/src/main/java/org/fao/geonet/services/inspireatom/AtomSearch.java b/inspire-atom/src/main/java/org/fao/geonet/services/inspireatom/AtomSearch.java index cd1e247b53c..5cdad3f2026 100644 --- a/inspire-atom/src/main/java/org/fao/geonet/services/inspireatom/AtomSearch.java +++ b/inspire-atom/src/main/java/org/fao/geonet/services/inspireatom/AtomSearch.java @@ -56,10 +56,13 @@ import org.jdom.Content; import org.jdom.Element; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; + +import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.stream.Collectors; @@ -103,14 +106,17 @@ public class AtomSearch { description = "") @GetMapping( value = "/feeds", - produces = MediaType.APPLICATION_XML_VALUE + produces = { + MediaType.APPLICATION_XML_VALUE, + MediaType.TEXT_HTML_VALUE + } ) @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Get a list of feeds."), @ApiResponse(responseCode = "204", description = "Not authenticated.") }) @ResponseStatus(OK) - public Element feeds( + public Object feeds( @Parameter( description = "fileIdentifier", required = false) @@ -118,6 +124,20 @@ public Element feeds( String fileIdentifier, @Parameter(hidden = true) HttpServletRequest request) throws Exception { + + String acceptHeader = StringUtils.isBlank(request.getHeader(HttpHeaders.ACCEPT))?MediaType.APPLICATION_XML_VALUE:request.getHeader(HttpHeaders.ACCEPT); + List accept = Arrays.asList(acceptHeader.split(",")); + + if (accept.contains(MediaType.TEXT_HTML_VALUE)) { + return feedsAsHtml(fileIdentifier, request); + } else{ + return feedsAsXml(fileIdentifier, request); + } + } + private Element feedsAsXml( + String fileIdentifier, + HttpServletRequest request) throws Exception { + ServiceContext context = ApiUtils.createServiceContext(request); boolean inspireEnable = sm.getValueAsBool(Settings.SYSTEM_INSPIRE_ENABLE); @@ -196,27 +216,10 @@ public Element feeds( } - @io.swagger.v3.oas.annotations.Operation( - summary = "Get ATOM feeds", - description = "") - @GetMapping( - value = "/feeds", - produces = MediaType.TEXT_HTML_VALUE - ) - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Get a list of feeds."), - @ApiResponse(responseCode = "204", description = "Not authenticated.") - }) - @ResponseStatus(OK) - public String feedsAsHtml( - @Parameter( - description = "fileIdentifier", - required = false) - @RequestParam(defaultValue = "") + private String feedsAsHtml( String fileIdentifier, - @Parameter(hidden = true) HttpServletRequest request) throws Exception { - Element feeds = feeds(fileIdentifier, request); + Element feeds = feedsAsXml(fileIdentifier, request); Locale locale = languageUtils.parseAcceptLanguage(request.getLocales()); String language = IsoLanguagesMapper.iso639_2T_to_iso639_2B(locale.getISO3Language()); From c9738e2577a8fa4ff8dafc54d7907a72809e7941 Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 10 Jan 2024 15:05:15 -0400 Subject: [PATCH 33/50] Changed http to https for urls that appear in open api specification. (#7601) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Changed http to https for urls that appear in open api specification. Also fixed some minor formatting. Co-authored-by: Jose García --- services/src/main/java/org/fao/geonet/api/OpenApiConfig.java | 2 +- .../src/main/java/org/fao/geonet/api/records/CatalogApi.java | 2 +- .../src/main/java/org/fao/geonet/api/records/MetadataApi.java | 4 ++-- .../org/fao/geonet/api/records/MetadataAssociatedApi.java | 2 +- .../java/org/fao/geonet/api/records/MetadataProcessApi.java | 2 +- .../java/org/fao/geonet/api/records/MetadataSharingApi.java | 2 +- .../main/java/org/fao/geonet/api/records/MetadataTagApi.java | 2 +- .../geonet/api/records/attachments/AttachmentsActionsApi.java | 2 +- .../fao/geonet/api/records/attachments/AttachmentsApi.java | 2 +- .../src/main/java/org/fao/geonet/api/related/Related.java | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/services/src/main/java/org/fao/geonet/api/OpenApiConfig.java b/services/src/main/java/org/fao/geonet/api/OpenApiConfig.java index eb98b76db06..e6633562b99 100644 --- a/services/src/main/java/org/fao/geonet/api/OpenApiConfig.java +++ b/services/src/main/java/org/fao/geonet/api/OpenApiConfig.java @@ -91,7 +91,7 @@ private static OpenAPI setupOpenApiConfig(final SettingManager settingManager) { ) .license(new License() .name("GPL 2.0") - .url("http://www.gnu.org/licenses/old-licenses/gpl-2.0.html"))) + .url("https://www.gnu.org/licenses/old-licenses/gpl-2.0.html"))) .externalDocs(new ExternalDocumentation() .description("Learn how to access the catalog using the GeoNetwork REST API.")); diff --git a/services/src/main/java/org/fao/geonet/api/records/CatalogApi.java b/services/src/main/java/org/fao/geonet/api/records/CatalogApi.java index 77f6b2833ea..48f27ababf5 100644 --- a/services/src/main/java/org/fao/geonet/api/records/CatalogApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/CatalogApi.java @@ -175,7 +175,7 @@ private static String paramsAsString(Map requestParams) { summary = "Get a set of metadata records as ZIP", description = "Metadata Exchange Format (MEF) is returned. MEF is a ZIP file containing " + "the metadata as XML and some others files depending on the version requested. " + - "See http://geonetwork-opensource.org/manuals/trunk/eng/users/annexes/mef-format.html.") + "See https://docs.geonetwork-opensource.org/latest/annexes/mef-format/.") @GetMapping(value = "/zip", consumes = { MediaType.ALL_VALUE diff --git a/services/src/main/java/org/fao/geonet/api/records/MetadataApi.java b/services/src/main/java/org/fao/geonet/api/records/MetadataApi.java index 8314f12b576..4a05c3c1caa 100644 --- a/services/src/main/java/org/fao/geonet/api/records/MetadataApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/MetadataApi.java @@ -367,7 +367,7 @@ Object getRecordAs( summary = "Get a metadata record as ZIP", description = "Metadata Exchange Format (MEF) is returned. MEF is a ZIP file containing " + "the metadata as XML and some others files depending on the version requested. " + - "See http://geonetwork-opensource.org/manuals/trunk/eng/users/annexes/mef-format.html.") + "See https://docs.geonetwork-opensource.org/latest/annexes/mef-format/.") @RequestMapping(value = "/{metadataUuid}/formatters/zip", method = RequestMethod.GET, consumes = { @@ -596,7 +596,7 @@ public ResponseEntity increaseRecordPopularity( summary = "Get record related resources", description = "Retrieve related services, datasets, onlines, thumbnails, sources, ... " + "to this records.
" + - "More info") + "More info") @RequestMapping(value = "/{metadataUuid:.+}/related", method = RequestMethod.GET, produces = { diff --git a/services/src/main/java/org/fao/geonet/api/records/MetadataAssociatedApi.java b/services/src/main/java/org/fao/geonet/api/records/MetadataAssociatedApi.java index 5859385b99c..5a62a945f15 100644 --- a/services/src/main/java/org/fao/geonet/api/records/MetadataAssociatedApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/MetadataAssociatedApi.java @@ -93,7 +93,7 @@ public synchronized void setApplicationContext(ApplicationContext context) { summary = "Get record associated resources", description = "Retrieve related services, datasets, sources, ... " + "to this records.
" + - "More info") + "More info") @RequestMapping(value = "/{metadataUuid:.+}/associated", method = RequestMethod.GET, produces = { diff --git a/services/src/main/java/org/fao/geonet/api/records/MetadataProcessApi.java b/services/src/main/java/org/fao/geonet/api/records/MetadataProcessApi.java index eabe2b9f437..2392c7fc2ae 100644 --- a/services/src/main/java/org/fao/geonet/api/records/MetadataProcessApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/MetadataProcessApi.java @@ -84,7 +84,7 @@ public class MetadataProcessApi { SettingManager sm; @io.swagger.v3.oas.annotations.Operation(summary = "Get suggestions", description ="Analyze the record an suggest processes to improve the quality of the record.
" - + "More info") + + "More info") @RequestMapping(value = "/{metadataUuid}/processes", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @PreAuthorize("hasAuthority('Editor')") @ResponseStatus(HttpStatus.OK) diff --git a/services/src/main/java/org/fao/geonet/api/records/MetadataSharingApi.java b/services/src/main/java/org/fao/geonet/api/records/MetadataSharingApi.java index 70f0872e85d..d88a247e15b 100644 --- a/services/src/main/java/org/fao/geonet/api/records/MetadataSharingApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/MetadataSharingApi.java @@ -280,7 +280,7 @@ public void unpublish( "Clear first allows to unset all operations first before setting the new ones." + "Clear option does not remove reserved groups operation if user is not an " + "administrator, a reviewer or the owner of the record.
" + - "More info") + "More info") @RequestMapping( value = "/{metadataUuid}/sharing", method = RequestMethod.PUT diff --git a/services/src/main/java/org/fao/geonet/api/records/MetadataTagApi.java b/services/src/main/java/org/fao/geonet/api/records/MetadataTagApi.java index 21a62deeb4a..0e326143429 100644 --- a/services/src/main/java/org/fao/geonet/api/records/MetadataTagApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/MetadataTagApi.java @@ -95,7 +95,7 @@ public class MetadataTagApi { @io.swagger.v3.oas.annotations.Operation( summary = "Get record tags", description = "Tags are used to classify information.
" + - "More info") + "More info") @GetMapping( value = "/{metadataUuid}/tags", produces = { diff --git a/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsActionsApi.java b/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsActionsApi.java index f57016bd462..be90091b318 100644 --- a/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsActionsApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsActionsApi.java @@ -93,7 +93,7 @@ public void init() { @io.swagger.v3.oas.annotations.Operation( summary = "Create an overview using the map print module", - description = "More info" + description = "More info" //response = MetadataResource.class) ) @RequestMapping( diff --git a/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsApi.java b/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsApi.java index 1751e9f67a1..43f2dcdbf20 100644 --- a/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsApi.java @@ -153,7 +153,7 @@ public List getResources() { return null; } - @io.swagger.v3.oas.annotations.Operation(summary = "List all metadata attachments", description = "More info") + @io.swagger.v3.oas.annotations.Operation(summary = "List all metadata attachments", description = "More info") @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(value = HttpStatus.OK) @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Return the record attachments."), diff --git a/services/src/main/java/org/fao/geonet/api/related/Related.java b/services/src/main/java/org/fao/geonet/api/related/Related.java index ae800982a45..460ab60b6aa 100644 --- a/services/src/main/java/org/fao/geonet/api/related/Related.java +++ b/services/src/main/java/org/fao/geonet/api/related/Related.java @@ -81,7 +81,7 @@ public synchronized void setApplicationContext(ApplicationContext context) { summary = "Get record related resources for all requested metadatas", description = "Retrieve related services, datasets, onlines, thumbnails, sources, ... " + "to all requested records.
" + - "More info") + "More info") @RequestMapping(value = "", method = RequestMethod.GET, produces = { From ca3513be87110ee6396bf36e7a1739eb7ce0efb8 Mon Sep 17 00:00:00 2001 From: Ian Allen Date: Wed, 10 Jan 2024 16:16:55 -0400 Subject: [PATCH 34/50] Add missing import from commit 63cd59fb38df389694566d69459bcfbedb7ca89e (Service context null pointer (#7593)) --- .../java/org/fao/geonet/api/records/attachments/JCloudStore.java | 1 + 1 file changed, 1 insertion(+) diff --git a/datastorages/jcloud/src/main/java/org/fao/geonet/api/records/attachments/JCloudStore.java b/datastorages/jcloud/src/main/java/org/fao/geonet/api/records/attachments/JCloudStore.java index 02bccbedc49..c4f11d4a365 100644 --- a/datastorages/jcloud/src/main/java/org/fao/geonet/api/records/attachments/JCloudStore.java +++ b/datastorages/jcloud/src/main/java/org/fao/geonet/api/records/attachments/JCloudStore.java @@ -30,6 +30,7 @@ import jeeves.server.context.ServiceContext; import org.apache.commons.lang.StringUtils; +import org.fao.geonet.ApplicationContextHolder; import org.fao.geonet.api.exception.ResourceNotFoundException; import org.fao.geonet.constants.Geonet; import org.fao.geonet.domain.MetadataResource; From 23140d5c3a70e08e503810cb286894258e60b3c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Garc=C3=ADa?= Date: Thu, 11 Jan 2024 12:15:04 +0100 Subject: [PATCH 35/50] CSW GetRecords doesn't escape query values when creating the Elasticsearch query (#7529) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CSW GetRecords doesn't escape query values when creating the Elasticsearch query / Escape Elasticsearch special chars in EQUAL / NOT EQUAL / IS LIKE literal queries Fixes #7527. --------- Co-authored-by: Juan Luis Rodríguez --- .../services/getrecords/es/CswFilter2Es.java | 222 +++++++----------- .../getrecords/es/CswFilter2EsTest.java | 209 +++++++++++------ 2 files changed, 224 insertions(+), 207 deletions(-) diff --git a/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java b/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java index ba7aff93722..2122a8c4a10 100644 --- a/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java +++ b/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2016 Food and Agriculture Organization of the + * Copyright (C) 2001-2024 Food and Agriculture Organization of the * United Nations (FAO-UN), United Nations World Food Programme (WFP) * and United Nations Environment Programme (UNEP) * @@ -26,131 +26,73 @@ import org.apache.commons.lang.NotImplementedException; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; +import org.apache.commons.text.StringEscapeUtils; import org.fao.geonet.constants.Geonet; import org.fao.geonet.kernel.csw.services.getrecords.IFieldMapper; import org.fao.geonet.utils.Log; -import org.geotools.filter.visitor.AbstractFilterVisitor; -import org.locationtech.jts.geom.*; -import org.locationtech.jts.io.WKTReader; -import org.geotools.api.filter.And; -import org.geotools.api.filter.BinaryComparisonOperator; -import org.geotools.api.filter.BinaryLogicOperator; -import org.geotools.api.filter.ExcludeFilter; -import org.geotools.api.filter.Filter; -import org.geotools.api.filter.Id; -import org.geotools.api.filter.IncludeFilter; -import org.geotools.api.filter.Not; -import org.geotools.api.filter.Or; -import org.geotools.api.filter.PropertyIsBetween; -import org.geotools.api.filter.PropertyIsEqualTo; -import org.geotools.api.filter.PropertyIsGreaterThan; -import org.geotools.api.filter.PropertyIsGreaterThanOrEqualTo; -import org.geotools.api.filter.PropertyIsLessThan; -import org.geotools.api.filter.PropertyIsLessThanOrEqualTo; -import org.geotools.api.filter.PropertyIsLike; -import org.geotools.api.filter.PropertyIsNil; -import org.geotools.api.filter.PropertyIsNotEqualTo; -import org.geotools.api.filter.PropertyIsNull; +import org.geotools.api.filter.*; import org.geotools.api.filter.expression.Expression; import org.geotools.api.filter.expression.Literal; import org.geotools.api.filter.expression.PropertyName; -import org.geotools.api.filter.spatial.BBOX; -import org.geotools.api.filter.spatial.Beyond; -import org.geotools.api.filter.spatial.BinarySpatialOperator; -import org.geotools.api.filter.spatial.Contains; -import org.geotools.api.filter.spatial.Crosses; -import org.geotools.api.filter.spatial.DWithin; -import org.geotools.api.filter.spatial.Disjoint; -import org.geotools.api.filter.spatial.Equals; -import org.geotools.api.filter.spatial.Intersects; -import org.geotools.api.filter.spatial.Overlaps; -import org.geotools.api.filter.spatial.Touches; -import org.geotools.api.filter.spatial.Within; -import org.geotools.api.filter.temporal.After; -import org.geotools.api.filter.temporal.AnyInteracts; -import org.geotools.api.filter.temporal.Before; -import org.geotools.api.filter.temporal.Begins; -import org.geotools.api.filter.temporal.BegunBy; -import org.geotools.api.filter.temporal.During; -import org.geotools.api.filter.temporal.EndedBy; -import org.geotools.api.filter.temporal.Ends; -import org.geotools.api.filter.temporal.Meets; -import org.geotools.api.filter.temporal.MetBy; -import org.geotools.api.filter.temporal.OverlappedBy; -import org.geotools.api.filter.temporal.TContains; -import org.geotools.api.filter.temporal.TEquals; -import org.geotools.api.filter.temporal.TOverlaps; +import org.geotools.api.filter.spatial.*; +import org.geotools.api.filter.temporal.*; import org.geotools.api.geometry.BoundingBox; +import org.geotools.filter.visitor.AbstractFilterVisitor; +import org.locationtech.jts.geom.*; +import org.locationtech.jts.io.WKTReader; import java.util.*; import java.util.regex.Pattern; /** - * Manages the translation from CSW <Filter> into a ES query. + * Manages the translation from CSW <Filter> into an ES query. */ public class CswFilter2Es extends AbstractFilterVisitor { - private final String BINARY_OPERATOR_AND = "AND"; - private final String BINARY_OPERATOR_OR = "OR"; + private static final String BINARY_OPERATOR_AND = "AND"; + private static final String BINARY_OPERATOR_OR = "OR"; - static final String SPECIAL_RE = "([" + Pattern.quote("+-&|!(){}[]^\\\"~*?:/") + "])"; - static final String SPECIAL_LIKE_RE = "(? stack = new ArrayDeque(); - - private final String templateNot = " {\"bool\": {\n" + + private static final String SPECIAL_RE = "([" + Pattern.quote("+-&|!(){}[]^\\\"~*?:/") + "])"; + private static final String SPECIAL_LIKE_RE = "(? stack = new ArrayDeque<>(); + private boolean useFilter = true; public CswFilter2Es(IFieldMapper fieldMapper) { expressionVisitor = new Expression2CswVisitor(stack, fieldMapper); @@ -214,22 +159,24 @@ protected static String convertLikePattern(PropertyIsLike filter) { : filter.getSingleChar(); result = result.replaceAll(singleCharRe, "?"); } + + result = StringEscapeUtils.escapeJson(escapeLikeLiteral(result)); return result; } public String getFilter() { - String condition = stack.isEmpty()?"":stack.pop(); + String condition = stack.isEmpty() ? "" : stack.pop(); // Check for single condition (no binary operators to wrap the query if (!condition.startsWith(" \"bool\":")) { - condition = String.format(templateAndWithFilter, condition, "%s"); + condition = String.format(TEMPLATE_AND_WITH_FILTER, condition, "%s"); } if (StringUtils.isEmpty(condition)) { // No filter - condition = "{\"bool\":{\"must\":[{\"query_string\":{\"query\":\"*\"}}],\"filter\":{\"query_string\":{\"query\":\"%s\"}}}"; + condition = "{\"bool\":{\"must\":[{\"query_string\":{\"query\":\"*\"}}],\"filter\":{\"query_string\":{\"query\":\"%s\"}}}"; } else { // Add wrapper - condition = "{" + condition + "}"; + condition = "{" + condition + "}"; } outQueryString.append(condition); @@ -237,21 +184,6 @@ public String getFilter() { return outQueryString.toString(); } - @Override - public Object visitNullFilter(Object extraData) { - return super.visitNullFilter(extraData); - } - - @Override - public Object visit(ExcludeFilter filter, Object extraData) { - return super.visit(filter, extraData); - } - - @Override - public Object visit(IncludeFilter filter, Object extraData) { - return super.visit(filter, extraData); - } - @Override public Object visit(And filter, Object extraData) { return visitBinaryLogic(filter, BINARY_OPERATOR_AND, extraData); @@ -261,9 +193,9 @@ private Object visitBinaryLogic(BinaryLogicOperator filter, String operator, Obj String filterCondition; if (operator.equals(BINARY_OPERATOR_AND)) { - filterCondition = (useFilter?templateAndWithFilter:templateAnd); + filterCondition = (useFilter ? TEMPLATE_AND_WITH_FILTER : TEMPLATE_AND); } else if (operator.equals(BINARY_OPERATOR_OR)) { - filterCondition = (useFilter?templateOrWithFilter:templateOr); + filterCondition = (useFilter ? TEMPLATE_OR_WITH_FILTER : TEMPLATE_OR); } else { throw new NotImplementedException(); } @@ -288,10 +220,10 @@ private Object visitBinaryLogic(BinaryLogicOperator filter, String operator, Obj int count = StringUtils.countMatches(filterCondition, "%s"); if (count == 1) { - filterCondition = String.format(filterCondition, String.join(",", conditionList)); + filterCondition = String.format(filterCondition, String.join(",", conditionList)); } else { - filterCondition = String.format(filterCondition, String.join(",", conditionList), "%s"); + filterCondition = String.format(filterCondition, String.join(",", conditionList), "%s"); } stack.push(filterCondition); @@ -307,7 +239,7 @@ public Object visit(Id filter, Object extraData) { @Override public Object visit(Not filter, Object extraData) { - String filterNot = templateNot; + String filterNot = TEMPLATE_NOT; filter.getFilter().accept(this, extraData); @@ -324,25 +256,32 @@ public Object visit(Or filter, Object extraData) { @Override public Object visit(PropertyIsBetween filter, Object extraData) { - String filterBetween = templateBetween; + String filterBetween = TEMPLATE_BETWEEN; - assert filter.getExpression() instanceof PropertyName; - filter.getExpression().accept(expressionVisitor, extraData); + if (!(filter.getExpression() instanceof PropertyName)) { + throw new IllegalArgumentException("Invalid expression property provided"); + } - assert filter.getLowerBoundary() instanceof Literal; - filter.getLowerBoundary().accept(expressionVisitor, extraData); + if (!(filter.getLowerBoundary() instanceof Literal)) { + throw new IllegalArgumentException("Invalid expression lower boundary literal provided"); + } + + if (!(filter.getUpperBoundary() instanceof Literal)) { + throw new IllegalArgumentException("Invalid expression upper boundary literal provided"); + } - assert filter.getUpperBoundary() instanceof Literal; + filter.getExpression().accept(expressionVisitor, extraData); + filter.getLowerBoundary().accept(expressionVisitor, extraData); filter.getUpperBoundary().accept(expressionVisitor, extraData); String dataPropertyUpperValue = stack.pop(); if (!NumberUtils.isNumber(dataPropertyUpperValue)) { - dataPropertyUpperValue = CswFilter2Es.quoteString(dataPropertyUpperValue); + dataPropertyUpperValue = StringEscapeUtils.escapeJson(CswFilter2Es.quoteString(dataPropertyUpperValue)); } String dataPropertyLowerValue = stack.pop(); if (!NumberUtils.isNumber(dataPropertyLowerValue)) { - dataPropertyLowerValue = CswFilter2Es.quoteString(dataPropertyLowerValue); + dataPropertyLowerValue = StringEscapeUtils.escapeJson(CswFilter2Es.quoteString(dataPropertyLowerValue)); } String dataPropertyName = stack.pop(); @@ -355,17 +294,15 @@ public Object visit(PropertyIsBetween filter, Object extraData) { @Override public Object visit(PropertyIsEqualTo filter, Object extraData) { + checkFilterExpressionsInBinaryComparisonOperator(filter); - assert filter.getExpression1() instanceof PropertyName; filter.getExpression1().accept(expressionVisitor, extraData); - - assert filter.getExpression2() instanceof Literal; filter.getExpression2().accept(expressionVisitor, extraData); String dataPropertyValue = stack.pop(); String dataPropertyName = stack.pop(); - final String filterEqualTo = String.format(templateMatch, dataPropertyName, dataPropertyValue); + final String filterEqualTo = String.format(TEMPLATE_MATCH, dataPropertyName, StringEscapeUtils.escapeJson(escapeLiteral(dataPropertyValue))); stack.push(filterEqualTo); return this; @@ -373,37 +310,36 @@ public Object visit(PropertyIsEqualTo filter, Object extraData) { @Override public Object visit(PropertyIsNotEqualTo filter, Object extraData) { - String filterPropertyIsNot = templatePropertyIsNot; + String filterPropertyIsNot = TEMPLATE_PROPERTY_IS_NOT; - assert filter.getExpression1() instanceof PropertyName; - filter.getExpression1().accept(expressionVisitor, extraData); + checkFilterExpressionsInBinaryComparisonOperator(filter); - assert filter.getExpression2() instanceof Literal; + filter.getExpression1().accept(expressionVisitor, extraData); filter.getExpression2().accept(expressionVisitor, extraData); String dataPropertyValue = stack.pop(); String dataPropertyName = stack.pop(); - filterPropertyIsNot = String.format(filterPropertyIsNot, dataPropertyName, dataPropertyValue); + filterPropertyIsNot = String.format(filterPropertyIsNot, dataPropertyName, + StringEscapeUtils.escapeJson(escapeLiteral(dataPropertyValue))); stack.push(filterPropertyIsNot); return this; } public Object visitRange(BinaryComparisonOperator filter, String operator, Object extraData) { - String filterRange = templateRange; + String filterRange = TEMPLATE_RANGE; - assert filter.getExpression1() instanceof PropertyName; - filter.getExpression1().accept(expressionVisitor, extraData); + checkFilterExpressionsInBinaryComparisonOperator(filter); - assert filter.getExpression2() instanceof Literal; + filter.getExpression1().accept(expressionVisitor, extraData); filter.getExpression2().accept(expressionVisitor, extraData); String dataPropertyValue = stack.pop(); String dataPropertyName = stack.pop(); if (!NumberUtils.isNumber(dataPropertyValue)) { - dataPropertyValue = CswFilter2Es.quoteString(dataPropertyValue); + dataPropertyValue = StringEscapeUtils.escapeJson(CswFilter2Es.quoteString(dataPropertyValue)); } filterRange = String.format(filterRange, dataPropertyName, operator, dataPropertyValue); @@ -423,7 +359,7 @@ public Object visit(PropertyIsGreaterThanOrEqualTo filter, Object extraData) { } @Override - public Object visit(PropertyIsLessThan filter, Object extraData) { + public Object visit(PropertyIsLessThan filter, Object extraData) { return visitRange(filter, "lt", extraData); } @@ -434,7 +370,7 @@ public Object visit(PropertyIsLessThanOrEqualTo filter, Object extraData) { @Override public Object visit(PropertyIsLike filter, Object extraData) { - String filterIsLike = templateIsLike; + String filterIsLike = TEMPLATE_IS_LIKE; String expression = convertLikePattern(filter); @@ -472,7 +408,7 @@ public Object visit(PropertyIsNil filter, Object extraData) { * @return */ private String fillTemplateSpatial(String shapeType, String coords, String relation) { - return String.format(templateSpatial, shapeType, coords, relation); + return String.format(TEMPLATE_SPATIAL, shapeType, coords, relation); } @Override @@ -495,14 +431,12 @@ public Object visit(BBOX filter, Object extraData) { } private Object addGeomFilter(BinarySpatialOperator filter, String geoOperator, Object extraData) { - if (!(filter.getExpression2() == null || filter.getExpression1() == null)) { filter.getExpression1().accept(expressionVisitor, extraData); } - // out.append(":\"").append(geoOperator).append("("); final Expression geoExpression = filter.getExpression2() == null ? filter.getExpression1() - : filter.getExpression2(); + : filter.getExpression2(); geoExpression.accept(expressionVisitor, extraData); String geom = stack.pop(); @@ -542,7 +476,7 @@ private Object addGeomFilter(BinarySpatialOperator filter, String geoOperator, O stack.push(filterSpatial); } catch (Exception ex) { Log.error(Geonet.CSW, "Error parsing geospatial object", ex); - throw new RuntimeException(ex); + throw new IllegalArgumentException("Invalid expression for spatial filter", ex); } return this; @@ -674,7 +608,7 @@ public Object visit(TOverlaps contains, Object extraData) { private String buildCoordinatesString(Coordinate[] coordinates) { List coordinatesList = new ArrayList<>(); - for(Coordinate c : coordinates) { + for (Coordinate c : coordinates) { // Use Locale.US to make Java use dot "." as decimal separator String coordsValue = String.format(Locale.US, "[%f, %f] ", c.getX(), c.getY()); @@ -684,4 +618,14 @@ private String buildCoordinatesString(Coordinate[] coordinates) { return String.join(" , ", coordinatesList); } + + private void checkFilterExpressionsInBinaryComparisonOperator(BinaryComparisonOperator filter) { + if (!(filter.getExpression1() instanceof PropertyName)) { + throw new IllegalArgumentException("Invalid expression property provided"); + } + + if (!(filter.getExpression2() instanceof Literal)) { + throw new IllegalArgumentException("Invalid expression literal provided"); + } + } } diff --git a/csw-server/src/test/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2EsTest.java b/csw-server/src/test/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2EsTest.java index 4b8a6024258..f8a31dabbfb 100644 --- a/csw-server/src/test/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2EsTest.java +++ b/csw-server/src/test/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2EsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2023 Food and Agriculture Organization of the + * Copyright (C) 2001-2024 Food and Agriculture Organization of the * United Nations (FAO-UN), United Nations World Food Programme (WFP) * and United Nations Environment Programme (UNEP) * @@ -29,10 +29,10 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import org.fao.geonet.kernel.csw.services.getrecords.FilterParser; import org.fao.geonet.kernel.csw.services.getrecords.IFieldMapper; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.geotools.api.filter.Filter; import org.geotools.api.filter.capability.FilterCapabilities; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -141,12 +141,11 @@ void testPropertyIsEqualTo() throws IOException { // INPUT: final String input = "\n" // - + " \n" // - + " Title\n" // - + " Hydrological\n" // - + " \n" // - + " " // - + ""; + + " \n" // + + " Title\n" // + + " Hydrological\n" // + + " \n" // + + " "; // EXPECTED: final ObjectNode expected = EsJsonHelper.boolbdr(). // @@ -157,34 +156,109 @@ void testPropertyIsEqualTo() throws IOException { assertFilterEquals(expected, input); } + @Test + void testPropertyIsEqualToSpecialChars() throws IOException { + final String input = + "\n" // + + " \n" // + + " OnlineResourceType\n" // + + " OGC:WMS\n" // + + " \n" // + + " "; + + // EXPECTED: + final ObjectNode expected = EsJsonHelper.boolbdr(). // + must(array(queryStringPart("OnlineResourceType", "OGC\\:WMS"))). // + filter(queryStringPart()). // + bld(); + + assertFilterEquals(expected, input); + } + + @Test + void testPropertyIsLike() throws IOException { + + final String input = + "\n" // + + " \n" // + + " AnyText\n" // + + " s\\_rvice\\%\n" // + + " \n" // + + " "; + + // EXPECTED: + final ObjectNode expected = EsJsonHelper.boolbdr(). // + must(array(queryStringPart("AnyText", "s?rvice*"))). // + filter(queryStringPart()). // + bld(); + + assertFilterEquals(expected, input); + } + + @Test + void testPropertyIsLikeSpecialChars() throws IOException { + + final String input = + "\n" // + + " \n" // + + " AnyText\n" // + + " \"service\"\n" // + + " \n" // + + " "; + + // EXPECTED: + final ObjectNode expected = EsJsonHelper.boolbdr(). // + must(array(queryStringPart("AnyText", "\\\"service\\\""))). // + filter(queryStringPart()). // + bld(); + + assertFilterEquals(expected, input); + + + final String input2 = + "\n" // + + " \n" // + + " AnyText\n" // + + " OGC:WMS\\%\n" // + + " \n" // + + " "; + + // EXPECTED: + final ObjectNode expected2 = EsJsonHelper.boolbdr(). // + must(array(queryStringPart("AnyText", "OGC\\:WMS*"))). // + filter(queryStringPart()). // + bld(); + + assertFilterEquals(expected2, input2); + } + @Test void testLogicalAnd() throws IOException { // INPUT: final String input = " \n" // - + " \n" // - + " \n" // - + " Title\n" // - + " Hydrological\n" // - + " \n" // - + " \n" // - + " Title\n" // - + " Africa\n" // - + " \n" // - + " \n" // - + " \n" // - + ""; + + " \n" // + + " \n" // + + " Title\n" // + + " Hydrological\n" // + + " \n" // + + " \n" // + + " Title\n" // + + " Africa\n" // + + " \n" // + + " \n" // + + " \n"; // EXPECTED: final ObjectNode expected = EsJsonHelper.boolbdr(). // must( - array( - queryStringPart("Title", "Africa"), - queryStringPart("Title", "Hydrological"))) // + array( + queryStringPart("Title", "Africa"), + queryStringPart("Title", "Hydrological"))) // . // - filter(queryStringPart()). // - bld(); + filter(queryStringPart()). // + bld(); assertFilterEquals(expected, input); } @@ -195,23 +269,22 @@ void testSpatialBBox() throws IOException { // INPUT: final String input = // " \n" // - + " \n" // - + " \n" // - + " -180 -90\n" // - + " 180 90\n" // - + " \n" // - + " \n" // - + " \n" // - + ""; + + " \n" // + + " \n" // + + " -180 -90\n" // + + " 180 90\n" // + + " \n" // + + " \n" // + + " \n"; // EXPECTED: final ObjectNode expected = boolbdr(). // must(array(geoShape("geom", // - envelope(-180d, 90d, 180d, -90d), // - "intersects"))) // + envelope(-180d, 90d, 180d, -90d), // + "intersects"))) // . // - filter(queryStringPart()). // - bld(); + filter(queryStringPart()). // + bld(); assertFilterEquals(expected, input); } @@ -227,33 +300,33 @@ void testFilterWithAndOrAndSpatialBBox() throws IOException { // INPUT: final String input = // " \n" // - + " \n" // - + " \n" // - + " \n" // - + " Type\n" // - + " data\n" // - + " \n" // - + " \n" // - + " Type\n" // - + " dataset\n" // - + " \n" // - + " \n" // - + " Type\n" // - + " datasetcollection\n" // - + " \n" // - + " \n" // - + " Type\n" // - + " series\n" // - + " \n" // - + " \n" // - + " \n" // - + " \n" // - + " -180 -90\n" // - + " 180 90\n" // - + " \n" // - + " \n" // - + " \n" // - + " "; + + " \n" // + + " \n" // + + " \n" // + + " Type\n" // + + " data\n" // + + " \n" // + + " \n" // + + " Type\n" // + + " dataset\n" // + + " \n" // + + " \n" // + + " Type\n" // + + " datasetcollection\n" // + + " \n" // + + " \n" // + + " Type\n" // + + " series\n" // + + " \n" // + + " \n" // + + " \n" // + + " \n" // + + " -180 -90\n" // + + " 180 90\n" // + + " \n" // + + " \n" // + + " \n" // + + " "; final ObjectNode propertiesPart = boolbdr().should(array( // queryStringPart("Type", "series"), // @@ -270,10 +343,10 @@ void testFilterWithAndOrAndSpatialBBox() throws IOException { // EXPECTED: final ObjectNode expected = boolbdr(). // must(array(geoShapePart, // - propertiesPart)) // + propertiesPart)) // . // - filter(queryStringPart()). // - bld(); + filter(queryStringPart()). // + bld(); assertFilterEquals(expected, input); } From eaaa06d849d49220c912fab46d6a17e148dbeb82 Mon Sep 17 00:00:00 2001 From: Ian Date: Mon, 15 Jan 2024 03:26:06 -0400 Subject: [PATCH 36/50] Fix SpringDoc duplicate OperationId (#7580) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix SpringDoc duplicate OperationId OperationId are generally created based on the function name. In some cases multiple function names were the same and this was causing OperationId conflicts which was causing one to be called functionName and the other to be called functionName_1. By simply renaming the function names, it resolves the duplicate OperationId * Update services/src/main/java/org/fao/geonet/api/records/MetadataSharingApi.java Co-authored-by: Jose García --------- Co-authored-by: Jose García --- .../org/fao/geonet/api/mapservers/MapServersApi.java | 2 +- .../java/org/fao/geonet/api/records/MetadataApi.java | 10 +++++----- .../org/fao/geonet/api/records/MetadataSharingApi.java | 6 +++--- .../geonet/api/records/editing/MetadataEditingApi.java | 2 +- .../src/main/java/org/fao/geonet/api/site/SiteApi.java | 2 +- .../org/fao/geonet/api/tools/i18n/TranslationApi.java | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/services/src/main/java/org/fao/geonet/api/mapservers/MapServersApi.java b/services/src/main/java/org/fao/geonet/api/mapservers/MapServersApi.java index bdff18496a5..f6a86262247 100644 --- a/services/src/main/java/org/fao/geonet/api/mapservers/MapServersApi.java +++ b/services/src/main/java/org/fao/geonet/api/mapservers/MapServersApi.java @@ -258,7 +258,7 @@ public void updateMapserver( @ApiResponse(responseCode = "403", description = ApiParams.API_RESPONSE_NOT_ALLOWED_ONLY_REVIEWER) }) @ResponseStatus(HttpStatus.NO_CONTENT) - public void updateMapserver( + public void updateMapserverAuth( @Parameter( description = API_PARAM_MAPSERVER_IDENTIFIER, required = true, diff --git a/services/src/main/java/org/fao/geonet/api/records/MetadataApi.java b/services/src/main/java/org/fao/geonet/api/records/MetadataApi.java index 4a05c3c1caa..c81667b89bc 100644 --- a/services/src/main/java/org/fao/geonet/api/records/MetadataApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/MetadataApi.java @@ -106,7 +106,7 @@ public class MetadataApi { private ApplicationContext context; - public static RelatedResponse getAssociatedResources( + public static RelatedResponse getRelatedResources( String language, ServiceContext context, AbstractMetadata md, RelatedItemType[] type, int start, int rows) throws Exception { // TODO PERF: ByPass XSL processing and create response directly @@ -471,7 +471,7 @@ void getRecordAsZip( if (withRelated) { // Adding children in MEF file - RelatedResponse related = getAssociatedResources( + RelatedResponse related = getRelatedResources( metadataUuid, null, approved, 0, 100, request); uuidsToExport.addAll(getUuidsOfAssociatedRecords(related.getParent())); uuidsToExport.addAll(getUuidsOfAssociatedRecords(related.getChildren())); @@ -609,7 +609,7 @@ public ResponseEntity increaseRecordPopularity( @ApiResponse(responseCode = "403", description = ApiParams.API_RESPONSE_NOT_ALLOWED_CAN_VIEW) }) @ResponseBody - public RelatedResponse getAssociatedResources( + public RelatedResponse getRelatedResources( @Parameter( description = API_PARAM_RECORD_UUID, required = true) @@ -644,7 +644,7 @@ public RelatedResponse getAssociatedResources( String language = languageUtils.getIso3langCode(request.getLocales()); final ServiceContext serviceContext = ApiUtils.createServiceContext(request); - return getAssociatedResources(language, serviceContext, md, type, start, rows); + return getRelatedResources(language, serviceContext, md, type, start, rows); } @io.swagger.v3.oas.annotations.Operation( @@ -680,7 +680,7 @@ public FeatureResponse getFeatureCatalog( Map decodeMap = new HashMap<>(); try { - RelatedResponse related = getAssociatedResources( + RelatedResponse related = getRelatedResources( metadataUuid, type, approved, 0, 100, request); if (isIncludedAttributeTable(related.getFcats())) { diff --git a/services/src/main/java/org/fao/geonet/api/records/MetadataSharingApi.java b/services/src/main/java/org/fao/geonet/api/records/MetadataSharingApi.java index d88a247e15b..a417e5ec0ea 100644 --- a/services/src/main/java/org/fao/geonet/api/records/MetadataSharingApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/MetadataSharingApi.java @@ -357,7 +357,7 @@ public void share( @ResponseStatus(HttpStatus.CREATED) public @ResponseBody - MetadataProcessingReport publish( + MetadataProcessingReport publishMultipleRecords( @Parameter(description = ApiParams.API_PARAM_RECORD_UUIDS_OR_SELECTION, required = false) @RequestParam(required = false) String[] uuids, @@ -393,7 +393,7 @@ MetadataProcessingReport publish( @ResponseStatus(HttpStatus.CREATED) public @ResponseBody - MetadataProcessingReport unpublish( + MetadataProcessingReport unpublishMultipleRecords( @Parameter(description = ApiParams.API_PARAM_RECORD_UUIDS_OR_SELECTION, required = false) @RequestParam(required = false) String[] uuids, @@ -429,7 +429,7 @@ MetadataProcessingReport unpublish( @ResponseStatus(HttpStatus.CREATED) public @ResponseBody - MetadataProcessingReport share( + MetadataProcessingReport shareMultipleRecords( @Parameter(description = ApiParams.API_PARAM_RECORD_UUIDS_OR_SELECTION, required = false) @RequestParam(required = false) String[] uuids, diff --git a/services/src/main/java/org/fao/geonet/api/records/editing/MetadataEditingApi.java b/services/src/main/java/org/fao/geonet/api/records/editing/MetadataEditingApi.java index e38140c0809..d77eea18e68 100644 --- a/services/src/main/java/org/fao/geonet/api/records/editing/MetadataEditingApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/editing/MetadataEditingApi.java @@ -596,7 +596,7 @@ public void addElement(@Parameter(description = API_PARAM_RECORD_UUID, required @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Element reordered."), @ApiResponse(responseCode = "403", description = ApiParams.API_RESPONSE_NOT_ALLOWED_CAN_EDIT)}) @ResponseBody - public void addElement(@Parameter(description = API_PARAM_RECORD_UUID, required = true) @PathVariable String metadataUuid, + public void reorderElement(@Parameter(description = API_PARAM_RECORD_UUID, required = true) @PathVariable String metadataUuid, @Parameter(description = "Reference of the element to move.", required = true) @RequestParam String ref, @Parameter(description = "Direction", required = true) @PathVariable Direction direction, @Parameter(description = "Should attributes be shown on the editor snippet?", required = false) @RequestParam(defaultValue = "false") boolean displayAttributes, diff --git a/services/src/main/java/org/fao/geonet/api/site/SiteApi.java b/services/src/main/java/org/fao/geonet/api/site/SiteApi.java index 27dd5e5975a..dcefa7dd5e0 100644 --- a/services/src/main/java/org/fao/geonet/api/site/SiteApi.java +++ b/services/src/main/java/org/fao/geonet/api/site/SiteApi.java @@ -579,7 +579,7 @@ public boolean isIndexing( method = RequestMethod.PUT) @PreAuthorize("hasAuthority('Editor')") @ResponseBody - public HttpEntity index( + public HttpEntity indexSite( @Parameter(description = "Drop and recreate index", required = false) @RequestParam(required = false, defaultValue = "true") diff --git a/services/src/main/java/org/fao/geonet/api/tools/i18n/TranslationApi.java b/services/src/main/java/org/fao/geonet/api/tools/i18n/TranslationApi.java index 45bb57216bc..1d667c47d1f 100644 --- a/services/src/main/java/org/fao/geonet/api/tools/i18n/TranslationApi.java +++ b/services/src/main/java/org/fao/geonet/api/tools/i18n/TranslationApi.java @@ -316,7 +316,7 @@ public Map getDbTranslations( MediaType.APPLICATION_JSON_VALUE }) @ResponseBody - public Map> getTranslationsPackage() { + public Map> getTranslationsPackages() { return translationPackBuilder.getPackages(); } From aed448c7de484b1591bb46d1e0713d0440e6816f Mon Sep 17 00:00:00 2001 From: Ian Date: Mon, 15 Jan 2024 03:45:38 -0400 Subject: [PATCH 37/50] Add missing @ApiResponse status for successful api search response. (#7594) * Add missing @ApiResponse status for successful api search response. Otherwise OpenAPI spec was missing response which caused issues when using codegen. Fixed body parameters and removed httpEntity.getBody() Also added example value for body. * Remove @Schema from request body as maps object will be corrected in PR #7611 * Revert request body back to string. --- .../org/fao/geonet/api/es/EsHTTPProxy.java | 74 ++++++++++++------- 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/services/src/main/java/org/fao/geonet/api/es/EsHTTPProxy.java b/services/src/main/java/org/fao/geonet/api/es/EsHTTPProxy.java index 7766e2053c5..c3f46034ae7 100644 --- a/services/src/main/java/org/fao/geonet/api/es/EsHTTPProxy.java +++ b/services/src/main/java/org/fao/geonet/api/es/EsHTTPProxy.java @@ -37,7 +37,11 @@ import com.jayway.jsonpath.JsonPath; import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.parameters.RequestBody; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import jeeves.server.UserSession; import jeeves.server.context.ServiceContext; @@ -65,8 +69,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.HttpEntity; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; @@ -273,9 +277,13 @@ private static boolean hasOperation(ObjectNode doc, ReservedGroup group, Reserve summary = "Search endpoint", description = "See https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html for search parameters details.") @RequestMapping(value = "/search/records/_search", - method = { - RequestMethod.POST - }) + method = RequestMethod.POST, + produces = MediaType.APPLICATION_JSON_VALUE, + consumes = MediaType.APPLICATION_JSON_VALUE) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Search results.", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(type = "string"))) + }) @ResponseStatus(value = HttpStatus.OK) @ResponseBody public void search( @@ -292,12 +300,14 @@ public void search( HttpServletRequest request, @Parameter(hidden = true) HttpServletResponse response, - @RequestBody(description = "JSON request based on Elasticsearch API.") - String body, - @Parameter(hidden = true) - HttpEntity httpEntity) throws Exception { + @RequestBody + @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "JSON request based on Elasticsearch API.", + content = @Content(examples = { + @ExampleObject(value = "{\"query\":{\"match\":{\"_id\":\"catalogue_uuid\"}}}") + })) + String body) throws Exception { ServiceContext context = ApiUtils.createServiceContext(request); - call(context, httpSession, request, response, SEARCH_ENDPOINT, httpEntity.getBody(), bucket, relatedTypes); + call(context, httpSession, request, response, SEARCH_ENDPOINT, body, bucket, relatedTypes); } @@ -305,9 +315,13 @@ public void search( summary = "Search endpoint", description = "See https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html for search parameters details.") @RequestMapping(value = "/search/records/_msearch", - method = { - RequestMethod.POST - }) + method = RequestMethod.POST, + produces = MediaType.APPLICATION_JSON_VALUE, + consumes = MediaType.APPLICATION_JSON_VALUE) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Search results.", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(type = "string"))) + }) @ResponseStatus(value = HttpStatus.OK) @ResponseBody public void msearch( @@ -324,12 +338,14 @@ public void msearch( HttpServletRequest request, @Parameter(hidden = true) HttpServletResponse response, - @RequestBody(description = "JSON request based on Elasticsearch API.") - String body, - @Parameter(hidden = true) - HttpEntity httpEntity) throws Exception { + @RequestBody + @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "JSON request based on Elasticsearch API.", + content = @Content(examples = { + @ExampleObject(value = "{\"query\":{\"match\":{\"_id\":\"catalogue_uuid\"}}}") + })) + String body) throws Exception { ServiceContext context = ApiUtils.createServiceContext(request); - call(context, httpSession, request, response, MULTISEARCH_ENDPOINT, httpEntity.getBody(), bucket, relatedTypes); + call(context, httpSession, request, response, MULTISEARCH_ENDPOINT, body, bucket, relatedTypes); } @@ -342,7 +358,13 @@ public void msearch( @RequestMapping(value = "/search/records/{endPoint}", method = { RequestMethod.POST, RequestMethod.GET - }) + }, + produces = MediaType.APPLICATION_JSON_VALUE, + consumes = MediaType.APPLICATION_JSON_VALUE) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Search results.", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(type = "string"))) + }) @ResponseStatus(value = HttpStatus.OK) @PreAuthorize("hasAuthority('Administrator')") @ResponseBody @@ -357,16 +379,18 @@ public void call( HttpServletRequest request, @Parameter(hidden = true) HttpServletResponse response, - @RequestBody(description = "JSON request based on Elasticsearch API.") - String body, - @Parameter(hidden = true) - HttpEntity httpEntity) throws Exception { + @RequestBody + @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "JSON request based on Elasticsearch API.", + content = @Content(examples = { + @ExampleObject(value = "{\"query\":{\"match\":{\"_id\":\"catalogue_uuid\"}}}") + })) + String body) throws Exception { ServiceContext context = ApiUtils.createServiceContext(request); - call(context, httpSession, request, response, endPoint, httpEntity.getBody(), bucket, null); + call(context, httpSession, request, response, endPoint, body, bucket, null); } - public void call(ServiceContext context, HttpSession httpSession, HttpServletRequest request, + private void call(ServiceContext context, HttpSession httpSession, HttpServletRequest request, HttpServletResponse response, String endPoint, String body, String selectionBucket, From e06fbdd84f42ad5599d491208b52fe0f4c97ea6e Mon Sep 17 00:00:00 2001 From: Ian Date: Mon, 15 Jan 2024 12:32:29 -0400 Subject: [PATCH 38/50] Cleanup consumes from metadata insert api. (#7616) The insert api only accepts XML so remove others. --- .../org/fao/geonet/api/records/MetadataInsertDeleteApi.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/src/main/java/org/fao/geonet/api/records/MetadataInsertDeleteApi.java b/services/src/main/java/org/fao/geonet/api/records/MetadataInsertDeleteApi.java index 54ad6f38557..0dfb298d2c3 100644 --- a/services/src/main/java/org/fao/geonet/api/records/MetadataInsertDeleteApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/MetadataInsertDeleteApi.java @@ -315,9 +315,9 @@ public SimpleMetadataProcessingReport deleteRecords( + "URL or file in a folder on the catalog server. When loading" + "from the catalog server folder, it might be faster to use a " + "local filesystem harvester.") - @RequestMapping(method = {RequestMethod.PUT}, produces = {MediaType.APPLICATION_JSON_VALUE}, consumes = { - MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE, - MediaType.APPLICATION_FORM_URLENCODED_VALUE}) + @RequestMapping(method = RequestMethod.PUT, + produces = MediaType.APPLICATION_JSON_VALUE, + consumes = MediaType.APPLICATION_XML_VALUE) @ApiResponses(value = {@ApiResponse(responseCode = "201", description = API_PARAM_REPORT_ABOUT_IMPORTED_RECORDS), @ApiResponse(responseCode = "403", description = ApiParams.API_RESPONSE_NOT_ALLOWED_ONLY_EDITOR)}) @PreAuthorize("hasAuthority('Editor')") From 5d85e8c29556d69f80a9a4fe56bf7a602ee7773c Mon Sep 17 00:00:00 2001 From: Ian Date: Mon, 15 Jan 2024 12:32:57 -0400 Subject: [PATCH 39/50] Remove default response from open api specification. (#7609) This will remove application/json as the default which causes issues with codegen. --- .../src/main/java/org/fao/geonet/api/OpenApiController.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/services/src/main/java/org/fao/geonet/api/OpenApiController.java b/services/src/main/java/org/fao/geonet/api/OpenApiController.java index 801041201e2..cc585db0b65 100644 --- a/services/src/main/java/org/fao/geonet/api/OpenApiController.java +++ b/services/src/main/java/org/fao/geonet/api/OpenApiController.java @@ -98,6 +98,9 @@ public OpenApiController(ObjectFactory openAPIBuilderObjectFacto springDocConfigProperties.setWriterWithOrderByKeys(true); springDocConfigProperties.setWriterWithDefaultPrettyPrinter(true); + // remove default response + springDocConfigProperties.setOverrideWithGenericResponse(false); + this.requestMappingHandlerMapping = requestMappingHandlerMapping; this.servletContextProvider = servletContextProvider; this.springSecurityOAuth2Provider = springSecurityOAuth2Provider; From 44105b524ee13d7a88674840c406719e812e9116 Mon Sep 17 00:00:00 2001 From: Jody Garnett Date: Tue, 16 Jan 2024 01:02:34 -0800 Subject: [PATCH 40/50] Build / release module build workflow improvements / fixes (#7619) * schemas now uses `SNAPSHOTS`, no longer to manage schemas `3.8` explicitly. * Remember to include `-Drelease` flag so that all modules (even optional modules) are compiled and tested during QA. * Troubleshoot release module order of execution and profile activation and handling of jetty folder. * Web profile with-doc profile needs dependency to build docs first. --------- Signed-off-by: Jody Garnett --- .github/workflows/codeql-analysis.yml | 3 -- .github/workflows/linux.yml | 10 +---- docs/manual/pom.xml | 7 --- pom.xml | 8 ++++ release/README.md | 32 ++++++++++---- release/build.xml | 3 +- release/pom.xml | 41 ++++++++++++++++-- web/pom.xml | 62 +++++++++++++++++++-------- 8 files changed, 115 insertions(+), 51 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index dbda173e220..54d302b50f4 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -85,6 +85,3 @@ jobs: - name: Remove SNAPSHOT jars from repository run: | find ~/.m2/repository -name "*SNAPSHOT*" -type d | xargs rm -rf {} - - name: Remove Schema 3.8 jars from repository - run: | - find ~/.m2/repository -name "*3.8*" -type d | xargs rm -rf {} diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index c0ee1e8c4ec..8cf3d86000d 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -40,13 +40,10 @@ jobs: maven-version: 3.6.3 - name: Build with Maven run: | - mvn -B -ntp -V install -DskipTests=true -Dmaven.javadoc.skip=true -Pwith-doc + mvn -B -ntp -V install -DskipTests=true -Dmaven.javadoc.skip=true -Drelease -Pwith-doc - name: Remove SNAPSHOT jars from repository run: | find ~/.m2/repository -name "*SNAPSHOT*" -type d | xargs rm -rf {} - - name: Remove Schema 3.8 jars from repository - run: | - find ~/.m2/repository -name "*3.8*" -type d | xargs rm -rf {} QA: runs-on: ubuntu-22.04 @@ -70,10 +67,7 @@ jobs: - name: Test with maven run: | mvn -B resources:resources@copy-index-schema-to-source -f web - mvn -B -ntp -V -fae verify -Pit + mvn -B -ntp -V -fae verify -Drelesae -Pit - name: Remove SNAPSHOT jars from repository run: | find ~/.m2/repository -name "*SNAPSHOT*" -type d | xargs rm -rf {} - - name: Remove Schema 3.8 jars from repository - run: | - find ~/.m2/repository -name "*3.8*" -type d | xargs rm -rf {} diff --git a/docs/manual/pom.xml b/docs/manual/pom.xml index 5c5ba26f734..84e3b980a7d 100644 --- a/docs/manual/pom.xml +++ b/docs/manual/pom.xml @@ -104,13 +104,6 @@ - - - maven-install-plugin - - true - - maven-deploy-plugin diff --git a/pom.xml b/pom.xml index e11ccc016ef..0d2ee1c5ac5 100644 --- a/pom.xml +++ b/pom.xml @@ -133,6 +133,14 @@ maven-clean-plugin 3.1.0 + + maven-install-plugin + 3.1.1 + + + maven-deploy-plugin + 3.1.1 + net.alchim31.maven yuicompressor-maven-plugin diff --git a/release/README.md b/release/README.md index 899ac2f3251..656b84986a1 100644 --- a/release/README.md +++ b/release/README.md @@ -14,19 +14,33 @@ cd release mvn clean install -Drelease ``` -## Manual +This module is designed to be used as part of a full build. It copies files from web/target so gn-web-app must be built first. + +## Manual release Open a terminal window and execute the following steps from within the ``release`` folder. -* Once GeoNetwork has been built (run Maven in the repository root), download Jetty: +1. Once GeoNetwork has been built (run Maven in the repository root), download Jetty: + + ```bash + mvn clean install -Pjetty-download + ``` + + This will download the version of jetty indicated in dependency management, and rename to ``jetty`` folder + (adjusting ``jetty-deploy.xml`` configuration to use `web` rather than default ``webapps``). + +2. Next, create the ZIP distributions and copy the WAR: - ` - mvn clean install -Pjetty-download - ` + ``` + ant + ``` + + The build.xml file will check everything is available and assemble into a zip. -* Next, create the ZIP distributions and copy the WAR: +## Jetty download - ` - ant - ` +To clean up the ``jetty`` download, when switching between branches: +```bash +mvn clean:clean@reset +``` diff --git a/release/build.xml b/release/build.xml index bc2aa3a8743..1b89d8c48e5 100644 --- a/release/build.xml +++ b/release/build.xml @@ -106,7 +106,7 @@ - + @@ -118,6 +118,7 @@ + diff --git a/release/pom.xml b/release/pom.xml index 2b6937d65a4..431521647d7 100644 --- a/release/pom.xml +++ b/release/pom.xml @@ -12,8 +12,8 @@ gn-release pom - Release module - Use to create distribution packages. + GeoNetwork Release module + Use to create zip distribution packages (copies from files from web which must be built first). @@ -23,6 +23,35 @@ + + + ${project.groupId} + gn-web-app + ${project.version} + war + + + + + + maven-clean-plugin + + + reset + clean + + + + jetty + + + + + + + + + @@ -40,8 +69,9 @@ download-maven-plugin - download-jetty + jetty-download pre-integration-test + wget @@ -57,7 +87,9 @@ maven-antrun-plugin - install + jetty-rename + pre-integration-test + run @@ -91,6 +123,7 @@ post-integration-test + run diff --git a/web/pom.xml b/web/pom.xml index 61473c5ae3d..853b1e9dae9 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -709,7 +709,7 @@ false - + maven-clean-plugin @@ -851,24 +851,6 @@ true - - copy-documentation - process-resources - - copy-resources - - - true - true - ${build.webapp.resources} - - - ${project.basedir}/../docs/manual/target/help - ${basedir}/src/main/webapp/doc - - - - copy-index-schema-to-source process-resources @@ -1310,6 +1292,48 @@ + + with-doc + + + ${project.groupId} + gn-guide + ${project.version} + help + zip + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-documentation + process-resources + + copy-resources + + + true + true + ${build.webapp.resources} + + + ${project.basedir}/../docs/manual/target/help + ${basedir}/src/main/webapp/doc/en + + + + + + + + + + slave From e7f64b7666fb6e7b7ee595ca74b967c0a76745a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Luis=20Rodr=C3=ADguez=20Ponce?= Date: Tue, 16 Jan 2024 12:19:33 +0100 Subject: [PATCH 41/50] Use Java 21 for Sonarcloud plugin (#7622) Sonarcloud analyzer now requires at least Java 17. --- .github/workflows/sonarcloud.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 33abdc2a46b..fb2f9cf2388 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -19,7 +19,7 @@ jobs: submodules: 'recursive' show-progress: 'false' - name: Set up JDK 11 - uses: actions/setup-java@v3.12.0 + uses: actions/setup-java@v4.0.0 with: distribution: 'temurin' java-version: '11' @@ -33,6 +33,12 @@ jobs: - name: Build GN run: mvn -B package -DskipTests + - name: Set up JDK 21 # Sonarcloud analyzer needs at least JDK 17 + uses: actions/setup-java@v4.0.0 + with: + distribution: 'temurin' + java-version: '21' + cache: 'maven' - name: Analyze with Sonar env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any From e1ac22b59b10175472a73d0129da61dc355ec025 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 12:48:16 +0100 Subject: [PATCH 42/50] Bump actions/setup-java from 3.12.0 to 4.0.0 (#7522) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 3.12.0 to 4.0.0. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/v3.12.0...v4.0.0) --- updated-dependencies: - dependency-name: actions/setup-java dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/linux.yml | 4 ++-- .github/workflows/mvn-dep-tree.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 54d302b50f4..3815b70a9bc 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -43,7 +43,7 @@ jobs: show-progress: 'false' - name: Setup Java JDK - uses: actions/setup-java@v3.12.0 + uses: actions/setup-java@v4.0.0 with: java-version: 11 # Java distribution. See the list of supported distributions in README file diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 8cf3d86000d..dd60f346486 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -22,7 +22,7 @@ jobs: submodules: 'recursive' show-progress: 'false' - name: Set up JDK - uses: actions/setup-java@v3.12.0 + uses: actions/setup-java@v4.0.0 with: distribution: 'temurin' java-version: ${{ matrix.jdk }} @@ -55,7 +55,7 @@ jobs: submodules: 'recursive' show-progress: 'false' - name: Set up JDK - uses: actions/setup-java@v3.12.0 + uses: actions/setup-java@v4.0.0 with: distribution: 'temurin' java-version: 11 diff --git a/.github/workflows/mvn-dep-tree.yml b/.github/workflows/mvn-dep-tree.yml index 74bd2f9cad7..1b5e7ce0088 100644 --- a/.github/workflows/mvn-dep-tree.yml +++ b/.github/workflows/mvn-dep-tree.yml @@ -20,7 +20,7 @@ jobs: show-progress: 'false' - name: Setup Java JDK - uses: actions/setup-java@v3.12.0 + uses: actions/setup-java@v4.0.0 with: java-version: 11 # Java distribution. See the list of supported distributions in README file From e1145884d555048c6642cff31bcbcabd793478e2 Mon Sep 17 00:00:00 2001 From: Jody Garnett Date: Tue, 16 Jan 2024 11:38:08 -0800 Subject: [PATCH 43/50] build fix: do not remove api docs during clean:clean@reset Signed-off-by: Jody Garnett --- web/pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/pom.xml b/web/pom.xml index 853b1e9dae9..2688414ccab 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -978,7 +978,8 @@ catalog/lib/style/bootstrap/*.js, catalog/lib/style/bootstrap/*.md, catalog/lib/style/bootstrap/CNAME, - catalog/lib/style/bootstrap/docs/**, + catalog/lib/style/bootstrap/docs/en/**, + catalog/lib/style/bootstrap/docs/fr/**, catalog/lib/style/bootstrap/fonts/**, catalog/lib/style/bootstrap/nuget/**, catalog/lib/style/bootstrap/grunt/**, From 01c26ece3b68616b8c185c29cc82545943a3cd74 Mon Sep 17 00:00:00 2001 From: Jody Garnett Date: Tue, 16 Jan 2024 13:04:10 -0800 Subject: [PATCH 44/50] Do not clean api docs out of src/main/webapp Signed-off-by: Jody Garnett --- web/pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/pom.xml b/web/pom.xml index 2688414ccab..8985790999b 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -752,7 +752,8 @@ META-INF/MANIFEST.MF data/** - doc/** + doc/en/** + doc/fr/** images/logos/* images/logos/statTmp scripts/lib/** From 172bce2f67cfd577d811f28e3ffa18586b745623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Garc=C3=ADa?= Date: Wed, 17 Jan 2024 10:11:02 +0100 Subject: [PATCH 45/50] Record view / Display WFS downloads for WFS online resources without a name defined (#7626) --- .../components/metadataactions/partials/related.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/web-ui/src/main/resources/catalog/components/metadataactions/partials/related.html b/web-ui/src/main/resources/catalog/components/metadataactions/partials/related.html index 0b936fb9c0e..6d3cd7ecebc 100644 --- a/web-ui/src/main/resources/catalog/components/metadataactions/partials/related.html +++ b/web-ui/src/main/resources/catalog/components/metadataactions/partials/related.html @@ -80,6 +80,13 @@

data-typename="{{::isLayerProtocol(r) ? r.locTitle : ''}}" data-url="{{::r.locUrl}}" >

+ +
From 9837e31786ac17a6c1c855dc32351858bf3a6f89 Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 17 Jan 2024 07:50:33 -0400 Subject: [PATCH 46/50] Fix error on edit page elements with non-unique id #gnRemoteRecordUrl (#7621) --- .../components/edit/onlinesrc/OnlineSrcDirective.js | 3 +++ .../edit/onlinesrc/partials/remote-record-selector.html | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/web-ui/src/main/resources/catalog/components/edit/onlinesrc/OnlineSrcDirective.js b/web-ui/src/main/resources/catalog/components/edit/onlinesrc/OnlineSrcDirective.js index c37c6c935cd..ec8b4098706 100644 --- a/web-ui/src/main/resources/catalog/components/edit/onlinesrc/OnlineSrcDirective.js +++ b/web-ui/src/main/resources/catalog/components/edit/onlinesrc/OnlineSrcDirective.js @@ -204,6 +204,9 @@ scope.isRemoteRecordPropertiesExtracted = false; scope.selectionList = undefined; + // Get the parent div's ID + scope.popupId = element.closest(".onlinesrc-popup").attr("id"); + scope.$on("resetSearch", function (event, args) { scope.remoteRecord = { remoteUrl: "", diff --git a/web-ui/src/main/resources/catalog/components/edit/onlinesrc/partials/remote-record-selector.html b/web-ui/src/main/resources/catalog/components/edit/onlinesrc/partials/remote-record-selector.html index 13b05402ffc..47579ecf9e4 100644 --- a/web-ui/src/main/resources/catalog/components/edit/onlinesrc/partials/remote-record-selector.html +++ b/web-ui/src/main/resources/catalog/components/edit/onlinesrc/partials/remote-record-selector.html @@ -1,7 +1,10 @@
-
@@ -9,7 +12,7 @@ Date: Wed, 17 Jan 2024 09:04:37 -0800 Subject: [PATCH 47/50] backport bot to respond to PR tags Signed-off-by: Jody Garnett --- .github/workflows/backport.yml | 25 +++++++++++++++++++++++++ software_development/GITHUB.md | 20 ++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 .github/workflows/backport.yml diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml new file mode 100644 index 00000000000..272cd05d974 --- /dev/null +++ b/.github/workflows/backport.yml @@ -0,0 +1,25 @@ +name: ♻ Backport +on: + pull_request_target: + types: + - closed + - labeled + +permissions: + contents: read + +jobs: + backport: + permissions: + contents: write + pull-requests: write + issues: write + runs-on: ubuntu-20.04 + name: Backport + steps: + - name: Backport Bot + id: backport + if: github.event.pull_request.merged && ( ( github.event.action == 'closed' && contains( join( github.event.pull_request.labels.*.name ), 'backport') ) || contains( github.event.label.name, 'backport' ) ) + uses: m-kuhn/backport@v1.2.7 + with: + github_token: ${{ secrets.GH_TOKEN_BOT }} diff --git a/software_development/GITHUB.md b/software_development/GITHUB.md index defd00d6e85..e12e6ba0af1 100644 --- a/software_development/GITHUB.md +++ b/software_development/GITHUB.md @@ -34,3 +34,23 @@ GeoNetwork uses feature branches for development, and a pull-request workflow fo * [Contributing](../CONTRIBUTING.md). * [Making a pull request](https://docs.geonetwork-opensource.org/latest/contributing/making-a-pull-request/). + +## Automation + +### Quality Assurance + +A number of [workflows]((../.github/workflows/) are setup to ensure each PR compiles, passes tests and so forth. + +* [linux.yml](../.github/workflows/linux.yml): build and QA, including -Drelease check +* [docs.yml](../.github/workflows/docs.yml): publish docs to gh-pages branch +* [backport.yml](../.github/workflows/backport.yml): backport tagged pull requests + +### Tags + +Use backport tags to take advantage of the [backport.yml](https://github.com/m-kuhn/backport) automation: + +> Backport is a JavaScript GitHub Action to backport a pull request by simply adding a label to it. +> +> It can backport rebased and merged pull requests with a single commit and squashed and merged pull requests. I + +This agrees with our CONTRIBUTING policy of using rebase and squash and merge. From 0c0fd04cc58410ff20ae5b657e953fbe18bfd267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20Gabri=C3=ABl?= Date: Wed, 17 Jan 2024 18:32:12 +0100 Subject: [PATCH 48/50] Fix the grid on the homepage of the documentation (#7559) * Remove the custom grid styles, the latest version of Material for MkDocs has this as a default option. The minimum version for Material for MkDocs is 9.5, this is added in the `requirements.txt` --- docs/manual/docs/index.fr.md | 78 +++++++++++-------- docs/manual/docs/index.md | 78 +++++++++++-------- .../overrides/assets/stylesheets/extra.css | 42 ---------- docs/manual/requirements.txt | 2 +- 4 files changed, 95 insertions(+), 105 deletions(-) diff --git a/docs/manual/docs/index.fr.md b/docs/manual/docs/index.fr.md index a491841fe52..13e3b55195b 100644 --- a/docs/manual/docs/index.fr.md +++ b/docs/manual/docs/index.fr.md @@ -9,36 +9,52 @@ Bienvenue à GeoNetwork. Cette documentation est organisée en guides spécifiqu
-:fontawesome-solid-signs-post: [Vue d'ensemble](overview/index.md) - -: Historique de GeoNetwork, communauté, détails de la licence et derniers changements. - -:fontawesome-solid-circle-info: [Aide en ligne](help/index.md) - -: Aide en ligne pour les visiteurs du catalogue (aucune connexion n'est requise). - -:fontawesome-solid-person-circle-question: [Guide de l'utilisateur](user-guide/index.md) - -: Guide de l'utilisateur opérationnel décrivant l'édition, la révision et la gestion des enregistrements (nécessite une connexion). - -:fontawesome-solid-screwdriver-wrench: [Guide du mainteneur](maintainer-guide/index.md) - -: Instructions d'installation, de configuration et de mise à jour - -:fontawesome-solid-user-graduate: [Tutoriels](tutorials/index.md) - -: Explorer des sujets à l'aide de tutoriels étape par étape - -:fontawesome-solid-plug: [Référence API](api/index.md) - -: Référence API pour les développeurs accédant aux services du catalogue. - -:fontawesome-regular-file-code: [Développement](devel/index.md) - -: Informations sur le développement, la personnalisation de GeoNetwork et la participation au projet GeoNetwork. - -:fontawesome-regular-bookmark: [Annexes](annexes/index.md) - -: Informations de référence +- :fontawesome-solid-signs-post: [Vue d'ensemble](overview/index.md) + + --- + + Historique de GeoNetwork, communauté, détails de la licence et derniers changements. + +- :fontawesome-solid-circle-info: [Aide en ligne](help/index.md) + + --- + + Aide en ligne pour les visiteurs du catalogue (aucune connexion n'est requise). + +- :fontawesome-solid-person-circle-question: [Guide de l'utilisateur](user-guide/index.md) + + --- + + Guide de l'utilisateur opérationnel décrivant l'édition, la révision et la gestion des enregistrements (nécessite une connexion). + +- :fontawesome-solid-screwdriver-wrench: [Guide du mainteneur](maintainer-guide/index.md) + + --- + + Instructions d'installation, de configuration et de mise à jour + +- :fontawesome-solid-user-graduate: [Tutoriels](tutorials/index.md) + + --- + + Explorer des sujets à l'aide de tutoriels étape par étape + +- :fontawesome-solid-plug: [Référence API](api/index.md) + + --- + + Référence API pour les développeurs accédant aux services du catalogue. + +- :fontawesome-regular-file-code: [Développement](devel/index.md) + + --- + + Informations sur le développement, la personnalisation de GeoNetwork et la participation au projet GeoNetwork. + +- :fontawesome-regular-bookmark: [Annexes](annexes/index.md) + + --- + + Informations de référence
diff --git a/docs/manual/docs/index.md b/docs/manual/docs/index.md index 5780bdfdb5e..d8e34f4b6b0 100644 --- a/docs/manual/docs/index.md +++ b/docs/manual/docs/index.md @@ -9,36 +9,52 @@ Welcome to GeoNetwork. This documentation is organized into specific guides targ
-:fontawesome-solid-signs-post: [Overview](overview/index.md) - -: GeoNetwork background, community, license details, and the latest changes. - -:fontawesome-solid-circle-info: [Online Help](help/index.md) - -: Online help for visitors to the catalogue (no login required). - -:fontawesome-solid-person-circle-question: [User Guide](user-guide/index.md) - -: Operational user-guide describing the editing, review and management of records (requires-login). - -:fontawesome-solid-screwdriver-wrench: [Maintainer Guide](maintainer-guide/index.md) - -: Installation, setup and update instructions - -:fontawesome-solid-user-graduate: [Tutorials](tutorials/index.md) - -: Explore topics using step-by-step tutorials - -:fontawesome-solid-plug: [API Reference](api/index.md) - -: API Reference for developers accecssing catalogue services. - -:fontawesome-regular-file-code: [Development](devel/index.md) - -: Development information on customizing GeoNetwork and taking part in the GeoNetwork project. - -:fontawesome-regular-bookmark: [Annexes](annexes/index.md) - -: Reference information +- :fontawesome-solid-signs-post: [Overview](overview/index.md) + + --- + + GeoNetwork background, community, license details, and the latest changes. + +- :fontawesome-solid-circle-info: [Online Help](help/index.md) + + --- + + Online help for visitors to the catalogue (no login required). + +- :fontawesome-solid-person-circle-question: [User Guide](user-guide/index.md) + + --- + + Operational user-guide describing the editing, review and management of records (requires-login). + +- :fontawesome-solid-screwdriver-wrench: [Maintainer Guide](maintainer-guide/index.md) + + --- + + Installation, setup and update instructions + + - :fontawesome-solid-user-graduate: [Tutorials](tutorials/index.md) + + --- + + Explore topics using step-by-step tutorials + +- :fontawesome-solid-plug: [API Reference](api/index.md) + + --- + + API Reference for developers accecssing catalogue services. + +- :fontawesome-regular-file-code: [Development](devel/index.md) + + --- + + Development information on customizing GeoNetwork and taking part in the GeoNetwork project. + +- :fontawesome-regular-bookmark: [Annexes](annexes/index.md) + + --- + + Reference information
diff --git a/docs/manual/overrides/assets/stylesheets/extra.css b/docs/manual/overrides/assets/stylesheets/extra.css index 8155e94365e..07b39e34520 100644 --- a/docs/manual/overrides/assets/stylesheets/extra.css +++ b/docs/manual/overrides/assets/stylesheets/extra.css @@ -9,48 +9,6 @@ img + em, .browser-border + em, .browser-mockup + em { font-size: 0.75rem; } -/* grid */ -.md-typeset .grid { - column-count: 2; - column-gap: 2em; - margin-bottom: 20px; -} -.md-typeset .grid dl { - display: grid; - grid-template-columns: repeat(auto-fit,minmax(16rem,1fr)); - margin: 0; -} -.md-typeset .grid.cards dt, .md-typeset .grid.cards dd { - border: 0.05rem solid var(--md-default-fg-color--lightest); - border-radius: 0.1rem; - display: block; - margin: 0; - padding: 0.8rem; - transition: border .25s,box-shadow .25s; -} -.md-typeset .grid.cards dt { - font-weight: bold; -} -.md-typeset .grid.cards dt .twemoji { - margin-right: 5px; -} -.md-typeset .grid.cards dd { - margin-bottom: 0.8rem; - margin-top: -1px; -} -.md-typeset .grid.cards dd p { - margin: 0; -} -@media (max-width: 768px) { - .md-typeset .grid dl { - display: inline-block; - margin-bottom: 20px; - } - .md-typeset .grid.cards dt, .md-typeset .grid.cards dd { - width: calc(100vw - 1.2rem - 1.2rem); - } -} - /* definition list used to display general inputs */ .md-typeset dl dd { margin: 10px 0; diff --git a/docs/manual/requirements.txt b/docs/manual/requirements.txt index a3fae0623c6..8a3fcb93da6 100644 --- a/docs/manual/requirements.txt +++ b/docs/manual/requirements.txt @@ -1,4 +1,4 @@ -mkdocs-material +mkdocs-material>=9.5.3 mkdocs-static-i18n>=1.0.5 mkdocs-include-markdown-plugin mkdocs-exclude From a52109e627e17a1fe4e93ea5e151473261b13adf Mon Sep 17 00:00:00 2001 From: Jody Garnett Date: Wed, 17 Jan 2024 10:27:20 -0800 Subject: [PATCH 49/50] document `backport 4.2.x` label change required for bot Signed-off-by: Jody Garnett --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2ae045a912f..b1b4cc4fc5c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,8 +14,8 @@ Thank you for contributing to GeoNetwork: * Before merging a pull request, should be defined the following properties: - Milestone to include the change. - - Add the label `changelog` when the change is relevant to be added to the release changelog file . - - Add the label(s) to the backport to previous branch(es), when the change is a bug fix or if it is a small improvement that may be relevant to the backport. + - Add the label `changelog` when the change is relevant to be added to the release changelog file. + - Add `backport ` to indicate when change is a bug fix or is a small improvement that may be relevant to the backport. * Good housekeeping: Anytime you commit, try and clean the code around it to latest style guide. If you improve a function without comments: add comments. If you modify functionality that does not have tests: write a test. If you fix functionality without documentation: add documentation. From 4dfbb33c40e511dbdab053916e31ab70fca2e47e Mon Sep 17 00:00:00 2001 From: Jeroen Ticheler Date: Wed, 17 Jan 2024 22:27:33 +0100 Subject: [PATCH 50/50] Update CONTRIBUTING.md Minor text edits --- CONTRIBUTING.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b1b4cc4fc5c..1bff3df03f5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,31 +1,31 @@ # Contributing -Thank you for contributing to GeoNetwork: +Thank you for contributing to GeoNetwork! * Free-software: GeoNetwork is free-software, using the [GNU GENERAL PUBLIC LICENSE](LICENSE.md). Contributions provided by you, or your employer, are required to be compatible with this free-software license. * Pull-request: GeoNetwork uses a pull-request workflow to review and accept changes. Pull-requests must be submitted against the *main* branch first, and may be back ported as required. # Pull requests -* Pull request is required, even if you have commit access, so the tests are run and other developer can check your code. +* Pull request is required, even if you have commit access, so the tests are run and another developer can check your code. * Pull requests must be applied to `main`, before being backported. -* Before merging a pull request, should be defined the following properties: +* Before merging a pull request, the following properties should be defined: - Milestone to include the change. - - Add the label `changelog` when the change is relevant to be added to the release changelog file. - - Add `backport ` to indicate when change is a bug fix or is a small improvement that may be relevant to the backport. + - Add the label `changelog` when the change is relevant to be added to the release changelog file. + - Add `backport ` to indicate when the change is a bug fix or when it is a small improvement that is relevant to be backported. -* Good housekeeping: Anytime you commit, try and clean the code around it to latest style guide. If you improve a function without comments: add comments. If you modify functionality that does not have tests: write a test. If you fix functionality without documentation: add documentation. +* Good housekeeping: Anytime you commit, try and clean the code around it according to the latest style guide. If you improve a function without comments: _add comments!!_ If you modify functionality that does not have tests: _write a test!!_ If you fix functionality without documentation: _add documentation!!_ -* History: Clean commit messages and history: avoid big commits with hundreds of files, break commits up into understandable chunks, longer verbose commit messages are encouraged. Avoid reformatting and needless whitespace changes. +* History: Clean commit messages and history. Avoid big commits with hundreds of files, break commits up into understandable chunks. Longer, verbose commit messages are encouraged. Avoid reformatting and needless whitespace changes. -* Draft: Use pull request *Draft** (or even the text "WIP") to identify work in progress. +* Draft: Use pull request **Draft** (or even the text "WIP") to identify _Work In Progress_. -* Rebase / Squash and merge: No merge commits with current branch, use Rebase or Squash and merge! +* Rebase / Squash and merge: Do not merge commits with the current branch, use Rebase or Squash and merge! -* API Change: Please identify any API change or behavior changes in commit messages. Also make sure that a [process for deprecation](PROCESS_FOR_DEPRECATION.md) of a feature is carefully dealt with. +* API Changes: Please identify any API change or behavior changes in commit messages. Also make sure that a [process for deprecation](PROCESS_FOR_DEPRECATION.md) of a feature is carefully dealt with. * Review: Review is required by another person, or more than one! Don't be shy asking for help or reviewing.