<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:sobek="http://sobekrepository.org/schemas/sobekcm_config"
  targetNamespace="http://sobekrepository.org/schemas/sobekcm_config" >

	<!-- ====================================================================================================
	     SobekCM_Config.xsd

	     Updated 2026-08-25. This schema is the single shared schema referenced (via xsi:schemaLocation) by
	     every *.config file under SobekCM/config and SobekCM/plugins/*/Plugin.config - all of them use the
	     same <SobekCM_Config> root element in this namespace, and each file only ever populates one (or a
	     few) of the optional top-level sections below. This revision adds the sections that existing config
	     files were already using but that the previous version of this schema did not yet describe:
	     WriterViewers (item/aggregation/results/other-content viewer configuration), BriefItem_Mapping,
	     Citation, ContactForm, Languages, MapEditor, MicroservicesClient, OAI-PMH, TemplateElements,
	     Static_Resources, Extension/AdminInfo (plugin manifests), and Localization (translation dictionaries).
	     It also extends Authentication (OIDC/SAML providers, AllowLocalAuth, Shibboleth Debug), the Engine
	     protocol enumeration (TEXT), and Metadata (Metadata_Mappers) to match what the current config files
	     actually contain.
	     ==================================================================================================== -->

	<xs:element name="SobekCM_Config">
		<xs:complexType>
			<!-- xs:all (rather than xs:sequence): each config/plugin file only ever populates a subset of
			     these top-level sections, and different files (notably plugin manifests, which combine
			     Extension/AdminInfo with e.g. Engine, Metadata, BriefItem_Mapping, Citation, TemplateConfig,
			     WriterViewers) place them in different relative orders. -->
			<xs:all>
				<xs:element name="Connections" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element maxOccurs="unbounded" name="Connection_String">
								<xs:complexType>
									<xs:simpleContent>
										<xs:extension base="xs:string">
											<xs:attribute name="name" type="xs:string" use="optional" />
											<xs:attribute name="type" type="sobek:databaseType" use="required" />
											<xs:attribute name="active" type="xs:boolean" use="optional" />
											<xs:attribute name="canAbort" type="xs:boolean" use="optional" />
											<xs:attribute name="isHosted" type="xs:boolean" use="optional" />
										</xs:extension>
									</xs:simpleContent>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
					</xs:complexType>
				</xs:element>
				<!-- Current (post-4.10.0) multi-instance format used by the Builder's config file, replacing
				     Connections above (still read for backward compatibility, but no longer written). -->
				<xs:element name="Instances" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Instance" minOccurs="0" maxOccurs="unbounded">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="Connection_String" minOccurs="0" maxOccurs="1">
											<xs:complexType>
												<xs:simpleContent>
													<xs:extension base="xs:string">
														<xs:attribute name="type" type="sobek:databaseType" use="optional" />
													</xs:extension>
												</xs:simpleContent>
											</xs:complexType>
										</xs:element>
										<xs:element name="Microservices" minOccurs="0" maxOccurs="1">
											<xs:complexType>
												<xs:sequence>
													<xs:element name="Add" minOccurs="0" maxOccurs="unbounded">
														<xs:complexType>
															<xs:attribute name="Key" type="xs:string" use="required" />
															<xs:attribute name="URL" type="xs:string" use="required" />
															<xs:attribute name="Protocol" type="sobek:engineProtocol" use="required" />
														</xs:complexType>
													</xs:element>
												</xs:sequence>
											</xs:complexType>
										</xs:element>
										<!-- Optional. Only relevant when this instance's File System Mode is "GCS Hybrid" or
										     "GCS Full". Full local path, on the Builder machine itself, to this instance's
										     GCS service account JSON key file. Omitted/blank falls back to the same
										     Base_Directory-relative default the web application uses
										     (config\user\gcs-service-account.json). Lets different instances serviced by
										     one Builder use different service accounts; deliberately kept out of the
										     database. -->
										<xs:element name="GCS_Service_Account_Json_Path" type="xs:string" minOccurs="0" maxOccurs="1" />
									</xs:sequence>
									<xs:attribute name="name" type="xs:string" use="optional" />
									<xs:attribute name="active" type="xs:boolean" use="optional" />
								</xs:complexType>
							</xs:element>
						</xs:sequence>
					</xs:complexType>
				</xs:element>
				<xs:element name="ErrorHandling" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="ErrorEmails" type="xs:string" maxOccurs="1" />
							<xs:element name="ErrorPage" type="xs:string" maxOccurs="1" />
						</xs:sequence>
					</xs:complexType>
				</xs:element>
				<xs:element name="Builder" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<!-- xs:all (rather than xs:sequence): none of these are required by the reader (it just
						     switches on whichever element names it finds), and existing config files don't agree
						     on an order or which subset they include. -->
						<xs:all>
							<xs:element name="Ghostscript_Executable" type="xs:string" minOccurs="0" maxOccurs="1" />
							<xs:element name="Imagemagick_Executable" type="xs:string" minOccurs="0" maxOccurs="1" />
							<xs:element name="Tesseract_Executable" type="xs:string" minOccurs="0" maxOccurs="1" />
							<xs:element name="LibreOffice_Executable" type="xs:string" minOccurs="0" maxOccurs="1" />
							<xs:element name="Pause_Between_Polls" type="xs:int" minOccurs="0" maxOccurs="1" />
							<xs:element name="Publish_Logs_Directory" type="xs:string" minOccurs="0" maxOccurs="1" />
							<!-- Hour of the day (0-23) after which the builder stops polling for new work and exits.
							     0 means never stop. Compared against machine-local time unless TimeZone is also set. -->
							<xs:element name="Stop_Hour" type="xs:int" minOccurs="0" maxOccurs="1" />
							<!-- IANA or Windows time zone identifier (e.g. "America/New_York") that Stop_Hour, and
							     status timestamps like "Builder Last Run Finished", should be reported in, instead
							     of the machine's own local time. -->
							<xs:element name="TimeZone" type="xs:string" minOccurs="0" maxOccurs="1" />
						</xs:all>
					</xs:complexType>
				</xs:element>
        <xs:element name="Engine" minOccurs="0" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>

              <!-- Maps URLs to methods to perform the requested transactions -->
              <xs:element name="Mapping" minOccurs="0" maxOccurs="1">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="RemoveAll" minOccurs="0" maxOccurs="1" />
                    <xs:element name="Path" type="sobek:enginePath" minOccurs="0" maxOccurs="unbounded"  />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>

              <!-- Components here hold the methods referred to in the mapping above -->
              <xs:element name="Components" minOccurs="0" maxOccurs="1">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element maxOccurs="unbounded" name="Component">
                      <xs:complexType>
                        <xs:attribute name="ID" type="xs:string" use="required" />
                        <xs:attribute name="Assembly" type="xs:string" use="optional" />
                        <xs:attribute name="Namespace" type="xs:string" use="optional" />
                        <xs:attribute name="Class" type="xs:string" use="required" />
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>

              <!-- Restriction ranges here can be referenced in the mapping to restrict access  to individual endpoints (or HTTP verb request types under an endpoint) by IP -->
              <xs:element name="RestrictionRanges" minOccurs="0" maxOccurs="1">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element maxOccurs="unbounded" name="Range">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element minOccurs="0" maxOccurs="1" name="RemoveAll" />
                          <xs:element maxOccurs="unbounded" name="IpRange">
                            <xs:complexType>
                              <xs:attribute name="Label" type="xs:string" use="required" />
                              <xs:attribute name="Start" type="xs:string" use="required" />
                            </xs:complexType>
                          </xs:element>
                        </xs:sequence>
                        <xs:attribute name="ID" type="xs:string" use="required" />
                        <xs:attribute name="Label" type="xs:string" use="required" />
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>

            <!-- Attribute on the main engine element would clear any pre-existing information -->
            <xs:attribute name="ClearAll" type="xs:boolean" use="optional" default="false" />
          </xs:complexType>
        </xs:element>
				<xs:element name="Metadata" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Metadata_File_ReaderWriters" type="sobek:metadataFileReaderWriterType" minOccurs="0" maxOccurs="1" />
							<xs:element name="METS_Sec_ReaderWriters" type="sobek:metsSectionReaderWritersType" minOccurs="0" maxOccurs="1" />
							<xs:element name="METS_Writing" type="sobek:metsWritingType" minOccurs="0" maxOccurs="1" />
							<xs:element name="Additional_Metadata_Modules" type="sobek:additionalMetadataModulesType" minOccurs="0" maxOccurs="1" />
							<!-- Bibliographic mappers that translate raw resource metadata into the internal BriefItem model -->
							<xs:element name="Metadata_Mappers" minOccurs="0" maxOccurs="1">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="Clear" minOccurs="0" maxOccurs="1" />
										<xs:element name="Mapper" minOccurs="0" maxOccurs="unbounded">
											<xs:complexType>
												<xs:attribute name="name" type="xs:string" use="required" />
												<xs:attribute name="namespace" type="xs:string" use="required" />
												<xs:attribute name="class" type="xs:string" use="required" />
											</xs:complexType>
										</xs:element>
									</xs:sequence>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
						<xs:attribute name="ClearAll" type="xs:boolean" use="optional" />
					</xs:complexType>
				</xs:element>
				<xs:element name="QualityControl" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Profiles" minOccurs="0" maxOccurs="1">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="Clear" minOccurs="0" maxOccurs="1" />
										<xs:element maxOccurs="unbounded" name="Profile" type="sobek:qcProfileType" />
									</xs:sequence>
								</xs:complexType>
							</xs:element>
							<xs:element name="Errors" minOccurs="0" maxOccurs="1">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="Profile">
											<xs:complexType>
												<xs:sequence>
													<xs:element name="ErrorCategories">
														<xs:complexType>
															<xs:sequence>
																<xs:element name="Clear" minOccurs="0" maxOccurs="1" />
																<xs:element maxOccurs="unbounded" name="ErrorCategory">
																	<xs:complexType>
																		<xs:sequence>
																			<xs:element maxOccurs="unbounded" name="ErrorType">
																				<xs:complexType>
																					<xs:sequence>
																						<xs:element maxOccurs="unbounded" name="Translation">
																							<xs:complexType>
																								<xs:attribute name="language" type="xs:string" use="required" />
																								<xs:attribute name="text" type="xs:string" use="required" />
																							</xs:complexType>
																						</xs:element>
																					</xs:sequence>
																					<xs:attribute name="ErrorID" type="xs:unsignedByte" use="required" />
																					<xs:attribute name="type" type="xs:string" use="required" />
																					<xs:attribute name="isOther" type="xs:boolean" use="required" />
																				</xs:complexType>
																			</xs:element>
																		</xs:sequence>
																		<xs:attribute name="ID" type="xs:unsignedByte" use="required" />
																		<xs:attribute name="type" type="xs:string" use="required" />
																	</xs:complexType>
																</xs:element>
															</xs:sequence>
														</xs:complexType>
													</xs:element>
												</xs:sequence>
												<xs:attribute name="isDefault" type="xs:boolean" use="required" />
												<xs:attribute name="name" type="xs:string" use="required" />
												<xs:attribute name="description" type="xs:string" use="required" />
											</xs:complexType>
										</xs:element>
									</xs:sequence>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
					</xs:complexType>
				</xs:element>
				<xs:element name="Authentication" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<!-- Defaults to true if omitted. Set to "false" to disable self-registration/local-password
							     logon for an instance that only wants sign-in through OIDC/SAML - existing local
							     accounts can still log on, only self-registration is affected. -->
							<xs:element name="Shibboleth" minOccurs="0" maxOccurs="1">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="AttributeMapping" maxOccurs="1">
											<xs:complexType>
												<xs:sequence>
													<xs:element maxOccurs="unbounded" name="Mapping">
														<xs:complexType>
															<xs:attribute name="ServerVariable" type="xs:string" use="required" />
															<xs:attribute name="UserAttribute" type="sobek:userAttributeMappingType" use="required" />
														</xs:complexType>
													</xs:element>
												</xs:sequence>
											</xs:complexType>
										</xs:element>
										<xs:element name="Constants" maxOccurs="1">
											<xs:complexType>
												<xs:sequence>
													<xs:element maxOccurs="unbounded" name="Constant">
														<xs:complexType>
															<xs:simpleContent>
																<xs:extension base="xs:string">
																	<xs:attribute name="UserAttribute" type="sobek:userAttributeMappingType" use="required" />
																</xs:extension>
															</xs:simpleContent>
														</xs:complexType>
													</xs:element>
												</xs:sequence>
											</xs:complexType>
										</xs:element>
										<xs:element name="Logic" maxOccurs="1">
											<xs:complexType>
												<xs:sequence>
													<xs:element maxOccurs="unbounded" name="CanSubmit">
														<xs:complexType>
															<xs:attribute name="ServerVariable" type="xs:string" use="required" />
															<xs:attribute name="Value" type="xs:string" use="required" />
														</xs:complexType>
													</xs:element>
												</xs:sequence>
											</xs:complexType>
										</xs:element>
									</xs:sequence>
									<xs:attribute name="UserIdentityAttribute" type="xs:string" use="required" />
									<xs:attribute name="URL" type="xs:string" use="required" />
									<xs:attribute name="Label" type="xs:string" use="required" />
									<xs:attribute name="Enabled" type="xs:boolean" use="optional" />
									<!-- Turns on verbose logging of the Shibboleth server variables seen during logon -->
									<xs:attribute name="Debug" type="xs:boolean" use="optional" />
								</xs:complexType>
							</xs:element>

							<!-- One <provider> per OpenID Connect identity provider (Google, Microsoft Entra, Okta, ...).
							     ProviderCode is used both as the ASP.NET Core authentication scheme name and as the
							     "/my/oidc/{ProviderCode}" URL segment, so it must be unique and URL-safe. -->
							<xs:element name="oidc" minOccurs="0" maxOccurs="1">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="provider" type="sobek:externalAuthProviderType" minOccurs="0" maxOccurs="unbounded" />
									</xs:sequence>
								</xs:complexType>
							</xs:element>

							<!-- One <provider> per SAML identity provider, handled via Sustainsys.Saml2. -->
							<xs:element name="saml" minOccurs="0" maxOccurs="1">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="provider" type="sobek:samlAuthProviderType" minOccurs="0" maxOccurs="unbounded" />
									</xs:sequence>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
						<xs:attribute name="AllowLocalAuth" type="xs:boolean" use="optional" default="true" />
					</xs:complexType>
				</xs:element>

				<!-- ============================== WRITER/VIEWER CONFIGURATION ================================== -->
				<!-- Used by sobekcm_aggregation_viewers.config, sobekcm_item_viewers.config, sobekcm_results_viewers.config
				     and sobekcm_other_viewers.config, each of which populates only the piece(s) it customizes. -->
				<xs:element name="WriterViewers" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="SpecialWriters" minOccurs="0" maxOccurs="1">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="ItemWriterConfig" type="sobek:itemWriterConfigType" minOccurs="0" maxOccurs="1" />
										<!-- Older/sample config style wraps AggregationWriter in AggregationWriterConfig with a ClearAll -->
										<xs:element name="AggregationWriterConfig" minOccurs="0" maxOccurs="1">
											<xs:complexType>
												<xs:sequence>
													<xs:element name="ClearAll" minOccurs="0" maxOccurs="1" />
													<xs:element name="AggregationWriter" type="sobek:aggregationWriterType" minOccurs="0" maxOccurs="1" />
													<!-- In this older wrapped style, HtmlHeadWriters is a sibling of AggregationWriter
													     rather than nested inside it -->
													<xs:element name="HtmlHeadWriters" minOccurs="0" maxOccurs="1">
														<xs:complexType>
															<xs:sequence>
																<xs:element name="HtmlHeadWriter" type="sobek:htmlHeadWriterType" minOccurs="0" maxOccurs="unbounded" />
															</xs:sequence>
														</xs:complexType>
													</xs:element>
												</xs:sequence>
											</xs:complexType>
										</xs:element>
										<!-- Current config style places AggregationWriter directly under SpecialWriters -->
										<xs:element name="AggregationWriter" type="sobek:aggregationWriterType" minOccurs="0" maxOccurs="1" />
										<xs:element name="ResultsWriterConfig" type="sobek:resultsWriterConfigType" minOccurs="0" maxOccurs="1" />
										<xs:element name="WebContentWriter" type="sobek:writerClassRefType" minOccurs="0" maxOccurs="1" />
									</xs:sequence>
								</xs:complexType>
							</xs:element>
							<!-- Writers selected purely from the URL segment (not a BibID, aggregation code, or web content page) -->
							<xs:element name="OtherWriters" minOccurs="0" maxOccurs="1">
								<xs:complexType>
									<xs:sequence>
										<xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax" namespace="##targetNamespace" />
									</xs:sequence>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
						<xs:attribute name="ClearAll" type="xs:boolean" use="optional" />
					</xs:complexType>
				</xs:element>

				<!-- ============================== BRIEF ITEM MAPPING ================================== -->
				<xs:element name="BriefItem_Mapping" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="MappingSet" minOccurs="0" maxOccurs="unbounded">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="ClearAll" minOccurs="0" maxOccurs="1" />
										<xs:element name="Mapper" minOccurs="0" maxOccurs="unbounded">
											<xs:complexType>
												<xs:attribute name="Assembly" type="xs:string" use="optional" />
												<xs:attribute name="Class" type="xs:string" use="required" />
												<xs:attribute name="Enabled" type="xs:boolean" use="optional" />
											</xs:complexType>
										</xs:element>
									</xs:sequence>
									<xs:attribute name="ID" type="xs:string" use="required" />
									<xs:attribute name="Default" type="xs:boolean" use="optional" />
								</xs:complexType>
							</xs:element>
						</xs:sequence>
						<xs:attribute name="ClearAll" type="xs:boolean" use="optional" />
					</xs:complexType>
				</xs:element>

				<!-- ============================== CITATION ================================== -->
				<xs:element name="Citation" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="CitationSet" minOccurs="0" maxOccurs="unbounded">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="FieldSet" minOccurs="0" maxOccurs="unbounded">
											<xs:complexType>
												<xs:sequence>
													<xs:element name="Elements">
														<xs:complexType>
															<xs:sequence>
																<xs:element name="Append" minOccurs="0" maxOccurs="unbounded">
																	<xs:complexType>
																		<xs:sequence>
																			<xs:element name="SectionWriter" minOccurs="0" maxOccurs="1">
																				<xs:complexType>
																					<xs:attribute name="assembly" type="xs:string" use="optional" />
																					<xs:attribute name="class" type="xs:string" use="required" />
																				</xs:complexType>
																			</xs:element>
																		</xs:sequence>
																		<xs:attribute name="MetadataTerm" type="xs:string" use="required" />
																		<xs:attribute name="DisplayTerm" type="xs:string" use="optional" />
																		<!-- Legacy misspelling seen in some CitationSets; kept for compatibility -->
																		<xs:attribute name="DislpayTerm" type="xs:string" use="optional" />
																		<xs:attribute name="OverrideDisplayTerm" type="xs:string" use="optional" />
																		<xs:attribute name="SearchCode" type="xs:string" use="optional" />
																		<xs:attribute name="ItemProp" type="xs:string" use="optional" />
																		<!-- Lower-case variant also appears in shipped config -->
																		<xs:attribute name="itemProp" type="xs:string" use="optional" />
																	</xs:complexType>
																</xs:element>
															</xs:sequence>
														</xs:complexType>
													</xs:element>
												</xs:sequence>
												<xs:attribute name="ID" type="xs:string" use="required" />
												<xs:attribute name="Heading" type="xs:string" use="optional" />
												<xs:attribute name="Order" type="xs:string" use="optional" />
											</xs:complexType>
										</xs:element>
									</xs:sequence>
									<xs:attribute name="Name" type="xs:string" use="required" />
									<xs:attribute name="Default" type="xs:boolean" use="optional" />
								</xs:complexType>
							</xs:element>
						</xs:sequence>
						<xs:attribute name="ClearAll" type="xs:boolean" use="optional" />
					</xs:complexType>
				</xs:element>

				<!-- ============================== CONTACT FORM ================================== -->
				<xs:element name="ContactForm" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Elements">
								<xs:complexType>
									<xs:choice minOccurs="0" maxOccurs="unbounded">
										<xs:element name="ExplanationText" type="sobek:contactFormTranslatedType" />
										<xs:element name="Subject" type="sobek:contactFormFieldType" />
										<xs:element name="TextArea" type="sobek:contactFormFieldType" />
										<xs:element name="TextBox" type="sobek:contactFormFieldType" />
										<xs:element name="Email" type="sobek:contactFormFieldType" />
										<xs:element name="HiddenValue">
											<xs:complexType>
												<xs:attribute name="Name" type="xs:string" use="required" />
												<xs:attribute name="UserAttribute" type="xs:string" use="optional" />
											</xs:complexType>
										</xs:element>
										<xs:element name="SelectBox" type="sobek:contactFormOptionSetType" />
										<xs:element name="RadioSet" type="sobek:contactFormOptionSetType" />
										<xs:element name="CheckBoxSet" type="sobek:contactFormOptionSetType" />
									</xs:choice>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
						<xs:attribute name="Name" type="xs:string" use="optional" />
					</xs:complexType>
				</xs:element>

				<!-- ============================== SITE LANGUAGES ================================== -->
				<!-- Also used (with a single <Language>) inside a localization Plugin.config to declare the
				     language that plugin adds. -->
				<xs:element name="Languages" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Language" minOccurs="0" maxOccurs="unbounded">
								<xs:complexType>
									<xs:simpleContent>
										<xs:extension base="xs:string">
											<xs:attribute name="name" type="xs:string" use="required" />
											<xs:attribute name="default" type="xs:string" use="optional" />
										</xs:extension>
									</xs:simpleContent>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
						<xs:attribute name="ClearAll" type="xs:boolean" use="optional" />
					</xs:complexType>
				</xs:element>

				<!-- ============================== MAP EDITOR ================================== -->
				<xs:element name="MapEditor" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="collection" minOccurs="0" maxOccurs="unbounded">
								<xs:complexType>
									<xs:all>
										<xs:element name="baseImageDirURL" type="xs:string" minOccurs="0" />
										<xs:element name="mapDrawingManagerDisplayed" type="xs:string" minOccurs="0" />
										<xs:element name="mapLayerActive" type="xs:string" minOccurs="0" />
										<xs:element name="mapCenter" type="xs:string" minOccurs="0" />
										<xs:element name="mapControlsDisplayed" type="xs:string" minOccurs="0" />
										<xs:element name="defaultDisplayDrawingMangerTool" type="xs:string" minOccurs="0" />
										<xs:element name="toolboxDisplayed" type="xs:string" minOccurs="0" />
										<xs:element name="toolbarDisplayed" type="xs:string" minOccurs="0" />
										<xs:element name="kmlDisplayed" type="xs:string" minOccurs="0" />
										<xs:element name="kmlLayer" type="xs:string" minOccurs="0" />
										<xs:element name="defaultZoomLevel" type="xs:string" minOccurs="0" />
										<xs:element name="maxZoomLevel" type="xs:string" minOccurs="0" />
										<xs:element name="minZoomLevel_Terrain" type="xs:string" minOccurs="0" />
										<xs:element name="minZoomLevel_Satellite" type="xs:string" minOccurs="0" />
										<xs:element name="minZoomLevel_Roadmap" type="xs:string" minOccurs="0" />
										<xs:element name="minZoomLevel_BlockLot" type="xs:string" minOccurs="0" />
										<xs:element name="isCustomOverlay" type="xs:string" minOccurs="0" />
										<xs:element name="preservedRotation" type="xs:string" minOccurs="0" />
										<xs:element name="knobRotationValue" type="xs:string" minOccurs="0" />
										<xs:element name="preservedOpacity" type="xs:string" minOccurs="0" />
										<xs:element name="hasCustomMapType" type="xs:string" minOccurs="0" />
										<xs:element name="strictBounds" type="xs:string" minOccurs="0" />
									</xs:all>
									<xs:attribute name="id" type="xs:string" use="required" />
								</xs:complexType>
							</xs:element>
						</xs:sequence>
					</xs:complexType>
				</xs:element>

				<!-- ============================== MICROSERVICES CLIENT (engine endpoint URL patterns) ================================== -->
				<xs:element name="MicroservicesClient" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Add" minOccurs="0" maxOccurs="unbounded">
								<xs:complexType>
									<xs:attribute name="Key" type="xs:string" use="required" />
									<xs:attribute name="URL" type="xs:string" use="required" />
									<xs:attribute name="Protocol" type="sobek:engineProtocol" use="required" />
									<xs:attribute name="Verb" type="sobek:engineHttpVerb" use="optional" />
								</xs:complexType>
							</xs:element>
						</xs:sequence>
					</xs:complexType>
				</xs:element>

				<!-- ============================== OAI-PMH ================================== -->
				<xs:element name="OAI-PMH" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Repository" minOccurs="0" maxOccurs="1">
								<xs:complexType>
									<xs:attribute name="IdentifierBase" type="xs:string" use="optional" />
								</xs:complexType>
							</xs:element>
							<xs:element name="Identify" minOccurs="0" maxOccurs="1">
								<!-- mixed=true: the shipped default config has stray text left over from a malformed
								     comment inside this element; tolerate incidental text here rather than error on it -->
								<xs:complexType mixed="true">
									<xs:sequence>
										<xs:element name="Name" type="xs:string" minOccurs="0" maxOccurs="1" />
										<xs:element name="Identifier" type="xs:string" minOccurs="0" maxOccurs="1" />
										<xs:element name="AdminEmail" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
										<xs:element name="Description" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
									</xs:sequence>
								</xs:complexType>
							</xs:element>
							<xs:element name="MetadataPrefixes" minOccurs="0" maxOccurs="1">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="MetadataFormat" minOccurs="0" maxOccurs="unbounded">
											<xs:complexType>
												<xs:attribute name="Prefix" type="xs:string" use="required" />
												<xs:attribute name="Schema" type="xs:string" use="required" />
												<xs:attribute name="MetadataNamespace" type="xs:string" use="required" />
												<xs:attribute name="Assembly" type="xs:string" use="optional" />
												<xs:attribute name="Namespace" type="xs:string" use="required" />
												<xs:attribute name="Class" type="xs:string" use="required" />
												<xs:attribute name="Enabled" type="xs:boolean" use="optional" />
											</xs:complexType>
										</xs:element>
									</xs:sequence>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
						<xs:attribute name="Enabled" type="xs:boolean" use="optional" />
					</xs:complexType>
				</xs:element>

				<!-- ============================== TEMPLATE ELEMENTS (metadata entry form field types) ================================== -->
				<xs:element name="TemplateElements" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="TemplateElement" type="sobek:templateElementType" minOccurs="0" maxOccurs="unbounded" />
						</xs:sequence>
					</xs:complexType>
				</xs:element>

				<!-- ============================== STATIC RESOURCES (CDN / local file maps) ================================== -->
				<xs:element name="Static_Resources" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:choice minOccurs="0" maxOccurs="unbounded">
							<xs:element name="grouping">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="file" type="sobek:staticResourceFileType" minOccurs="0" maxOccurs="unbounded" />
									</xs:sequence>
									<xs:attribute name="name" type="xs:string" use="required" />
								</xs:complexType>
							</xs:element>
							<xs:element name="file" type="sobek:staticResourceFileType" />
						</xs:choice>
						<xs:attribute name="code" type="xs:string" use="optional" />
						<xs:attribute name="baseUrl" type="xs:string" use="optional" />
					</xs:complexType>
				</xs:element>

				<!-- ============================== PLUGIN MANIFEST (Plugin.config) ================================== -->
				<!-- Describes the plugin/extension itself; used by SobekCM/plugins/*/Plugin.config (usually alongside
				     just <Languages>, for the simple localization plugins) and by fuller plugins such as PostcardCore
				     and Timeline, which also register CSS, install/uninstall database settings, and arbitrary or
				     key/value custom configuration sections read back via InstanceWide_Configuration. -->
				<xs:element name="Extension" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="AdminInfo" minOccurs="0" maxOccurs="1">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="Description" type="xs:string" minOccurs="0" maxOccurs="1" />
										<xs:element name="Authors" minOccurs="0" maxOccurs="1">
											<xs:complexType>
												<xs:sequence>
													<xs:element name="Author" minOccurs="0" maxOccurs="unbounded">
														<xs:complexType>
															<xs:attribute name="name" type="xs:string" use="required" />
															<xs:attribute name="email" type="xs:string" use="optional" />
														</xs:complexType>
													</xs:element>
												</xs:sequence>
											</xs:complexType>
										</xs:element>
										<xs:element name="Permissions" type="xs:string" minOccurs="0" maxOccurs="1" />
									</xs:sequence>
								</xs:complexType>
							</xs:element>
							<!-- One or more assemblies, referenced relative to the plugin folder -->
							<xs:element name="Assembly" minOccurs="0" maxOccurs="unbounded">
								<xs:complexType>
									<xs:attribute name="id" type="xs:string" use="required" />
									<xs:attribute name="name" type="xs:string" use="required" />
								</xs:complexType>
							</xs:element>
							<!-- Registers a CSS file to be included; condition controls where it is pulled in -->
							<xs:element name="Css" minOccurs="0" maxOccurs="unbounded">
								<xs:complexType>
									<xs:attribute name="url" type="xs:string" use="required" />
									<xs:attribute name="condition" type="sobek:cssConditionType" use="optional" />
								</xs:complexType>
							</xs:element>
							<!-- Instance-wide settings added to the database when this plugin is enabled -->
							<xs:element name="Install" minOccurs="0" maxOccurs="1">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="AddSetting" minOccurs="0" maxOccurs="unbounded">
											<xs:complexType>
												<xs:attribute name="key" type="xs:string" use="required" />
												<xs:attribute name="value" type="xs:string" use="optional" />
												<xs:attribute name="tabpage" type="xs:string" use="optional" />
												<xs:attribute name="heading" type="xs:string" use="optional" />
											</xs:complexType>
										</xs:element>
									</xs:sequence>
								</xs:complexType>
							</xs:element>
							<!-- Removes the settings added by Install above when this plugin is uninstalled/disabled -->
							<xs:element name="Uninstall" minOccurs="0" maxOccurs="1">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="RemoveSetting" minOccurs="0" maxOccurs="unbounded">
											<xs:complexType>
												<xs:attribute name="key" type="xs:string" use="required" />
											</xs:complexType>
										</xs:element>
									</xs:sequence>
								</xs:complexType>
							</xs:element>
							<!-- Custom, plugin-defined configuration data, made available via InstanceWide_Configuration
							     and looked up by name. Either reserves arbitrary XML for the plugin's own code to parse
							     (ReserveXML), or a flat list of key/value pairs the host will parse for it. -->
							<xs:element name="Configuration" minOccurs="0" maxOccurs="unbounded">
								<xs:complexType>
									<xs:choice minOccurs="0" maxOccurs="1">
										<xs:element name="ReserveXML">
											<xs:complexType>
												<xs:sequence>
													<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip" namespace="##any" />
												</xs:sequence>
											</xs:complexType>
										</xs:element>
										<xs:element name="KeyValuePairs">
											<xs:complexType>
												<xs:sequence>
													<xs:element name="KeyValuePair" minOccurs="0" maxOccurs="unbounded">
														<xs:complexType>
															<xs:attribute name="key" type="xs:string" use="required" />
															<xs:attribute name="value" type="xs:string" use="optional" />
														</xs:complexType>
													</xs:element>
												</xs:sequence>
											</xs:complexType>
										</xs:element>
									</xs:choice>
									<xs:attribute name="name" type="xs:string" use="required" />
								</xs:complexType>
							</xs:element>
						</xs:sequence>
						<xs:attribute name="code" type="xs:string" use="required" />
						<xs:attribute name="name" type="xs:string" use="required" />
						<xs:attribute name="version" type="xs:string" use="optional" />
						<xs:attribute name="category" type="xs:string" use="optional" />
					</xs:complexType>
				</xs:element>

				<!-- ============================== LOCALIZATION DICTIONARIES ================================== -->
				<!-- Used by sobekcm_localization_*.config (aggregations/chrome/general/items/mysobek, per language) -->
				<xs:element name="Localization" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Section" minOccurs="0" maxOccurs="unbounded">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="Phrase" minOccurs="0" maxOccurs="unbounded">
											<xs:complexType>
												<xs:simpleContent>
													<xs:extension base="xs:string">
														<xs:attribute name="Key" type="xs:string" use="required" />
													</xs:extension>
												</xs:simpleContent>
											</xs:complexType>
										</xs:element>
									</xs:sequence>
									<xs:attribute name="Name" type="xs:string" use="required" />
								</xs:complexType>
							</xs:element>
						</xs:sequence>
						<xs:attribute name="Language" type="xs:string" use="required" />
					</xs:complexType>
				</xs:element>

				<!-- ============================== PLUGIN: EXTRA METADATA ENTRY TEMPLATE ELEMENTS ================================== -->
				<!-- Some plugins (e.g. PostcardCore) register new metadata-entry template elements via an unwrapped
				     <TemplateConfig> list, rather than the <TemplateElements> wrapper used in sobekcm_template_elements.config -->
				<xs:element name="TemplateConfig" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="TemplateElement" type="sobek:templateElementType" minOccurs="0" maxOccurs="unbounded" />
						</xs:sequence>
						<xs:attribute name="ClearAll" type="xs:boolean" use="optional" />
					</xs:complexType>
				</xs:element>

			</xs:all>
		</xs:complexType>
	</xs:element>

	<!-- ============================== CONNECTIONS SPECIFIC TYPES ======================================== -->
	<xs:simpleType name="databaseType">
		<xs:restriction base="xs:string">
			<xs:enumeration value="MSSQL" />
			<xs:enumeration value="PostgreSQL" />
		</xs:restriction>
	</xs:simpleType>


  <!-- ============================== ENGINE SPECIFIC TYPES ================================== -->
  <!-- Path definition for mapping endpoints to methods/components in the SobekCM engine -->
  <xs:complexType name="enginePath">
    <xs:sequence minOccurs="0" maxOccurs="1">
      <xs:element name="RemoveAll" minOccurs="0" maxOccurs="1" />
      <xs:element name="AutoDoc" type="sobek:engineAutoDoc" minOccurs="0" maxOccurs="1" />
      <xs:sequence minOccurs="0" maxOccurs="unbounded">
        <xs:choice>
          <xs:element name="Path" type="sobek:enginePath" />
          <xs:element name="Endpoint" type="sobek:engineSimpleEndpoint" />
          <xs:element name="ComplexEndpoint" type="sobek:engineComplexEndpoint" />
        </xs:choice>
      </xs:sequence>
    </xs:sequence>
    <xs:attribute name="Segment" type="xs:string" use="required" />
  </xs:complexType>

  <!-- A simple endpoint definition for the SobekCM engine, this exposes a method to a GET request only -->
  <xs:complexType name="engineSimpleEndpoint">
    <xs:sequence minOccurs="0">
      <xs:element name="AutoDoc" type="sobek:engineAutoDoc" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute name="Segment" type="xs:string" use="required" />

    <!-- Must reference a component id in some of the config files from the Engine/Components region -->
    <xs:attribute name="ComponentID" type="xs:string" use="required" />
    <xs:attribute name="Method" type="xs:string" use="required" />
    <xs:attribute name="Enabled" type="xs:boolean" use="optional" default="true" />
    <xs:attribute name="Protocol" type="sobek:engineProtocol" use="required" />

    <!-- Must reference a restriction range (or multiple) in the the Engine/RestrictionRanges region.  To refer to multiple, separate with a comma or pipe (|)                         -->
    <xs:attribute name="RestrictionRangeID" type="xs:string" use="optional" />
  </xs:complexType>

  <!-- Complex endpoint definition for the SobekCM engine, this exposes a number of methods to be called based on the HTTP verb, or exposes a single non-GET request endpoint                -->
  <xs:complexType name="engineComplexEndpoint">
    <xs:sequence minOccurs="0">
      <xs:element name="AutoDoc" type="sobek:engineAutoDoc" minOccurs="0" maxOccurs="1" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="VerbMapping">
        <xs:complexType>
          <xs:attribute name="Verb" type="sobek:engineHttpVerb" use="required" />

          <!-- Must reference a component id in some of the config files from the Engine/Components region -->
          <xs:attribute name="ComponentID" type="xs:string" use="required" />
          <xs:attribute name="Method" type="xs:string" use="required" />
          <xs:attribute name="Enabled" type="xs:boolean" use="optional" default="true" />
          <xs:attribute name="Protocol" type="sobek:engineProtocol" use="required" />

          <!-- Must reference a restriction range (or multiple) in the the Engine/RestrictionRanges region.  To refer to multiple, separate with a comma or pipe (|)                         -->
          <xs:attribute name="RestrictionRangeID" type="xs:string" use="optional" />
        </xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="Segment" type="xs:string" use="required" />
    <xs:attribute name="Enabled" type="xs:boolean" use="optional" default="true" />

    <!-- Must reference a restriction range (or multiple) in the the Engine/RestrictionRanges region.  To refer to multiple, separate with a comma or pipe (|)                         -->
    <xs:attribute name="RestrictionRangeID" type="xs:string" use="optional" />
  </xs:complexType>

  <!-- Exposes some basic descriptive elements that can be utilitized to automatically generate documentation for the exposed SobekCM engine endpoints                                    -->
  <xs:complexType name="engineAutoDoc">
    <xs:sequence>
      <xs:element name="Description" type="xs:string" />
      <xs:element name="RequestType" type="xs:string" />
      <xs:element name="Arguments" type="xs:string" />
      <xs:element name="Returns" type="xs:string" />
    </xs:sequence>
  </xs:complexType>

  <!-- List of possible protocol types -->
  <xs:simpleType name="engineProtocol">
		<xs:restriction base="xs:string">
			<xs:enumeration value="JSON" />
			<xs:enumeration value="JSON-P" />
			<xs:enumeration value="PROTOBUF" />
			<xs:enumeration value="XML" />
			<!-- Used by a small number of legacy plain-text endpoints, e.g. the bookshelf HTTP snippet -->
			<xs:enumeration value="TEXT" />
		</xs:restriction>
  </xs:simpleType>

  <!-- List of HTTP verb types -->
  <xs:simpleType name="engineHttpVerb">
		<xs:restriction base="xs:string">
			<xs:enumeration value="DELETE" />
			<xs:enumeration value="GET" />
			<xs:enumeration value="POST" />
			<xs:enumeration value="PUT" />
		</xs:restriction>
  </xs:simpleType>

	<!-- ============================== METADATA STANDARD SPECIFIC TYPES ================================== -->
	<xs:complexType name="metadataFileReaderWriterType">
		<xs:sequence>
			<xs:element maxOccurs="unbounded" name="ReaderWriter">
				<xs:complexType>
					<xs:sequence minOccurs="0">
						<xs:element name="Options">
							<xs:complexType>
								<xs:sequence>
									<xs:element maxOccurs="unbounded" name="Option">
										<xs:complexType>
											<xs:attribute name="key" type="xs:string" use="required" />
											<xs:attribute name="value" type="xs:string" use="required" />
										</xs:complexType>
									</xs:element>
								</xs:sequence>
							</xs:complexType>
						</xs:element>
					</xs:sequence>
					<xs:attribute name="mdtype" type="sobek:metadataFileStandardTypes" use="required" />
					<xs:attribute name="label" type="xs:string" use="required" />
					<xs:attribute name="canRead" type="xs:boolean" use="required" />
					<xs:attribute name="canWrite" type="xs:boolean" use="required" />
					<xs:attribute name="namespace" type="xs:string" use="required" />
					<xs:attribute name="class" type="xs:string" use="required" />
					<xs:attribute name="assembly" type="xs:string" use="optional" />
					<xs:attribute name="othermdtype" type="xs:string" use="optional" />
				</xs:complexType>
			</xs:element>
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="metsSectionReaderWritersType">
		<xs:sequence>
			<xs:element maxOccurs="unbounded" name="ReaderWriter">
				<xs:complexType>
					<xs:sequence minOccurs="0">
						<xs:element name="Options" minOccurs="0" maxOccurs="1">
							<xs:complexType>
								<xs:sequence>
									<xs:element maxOccurs="unbounded" name="Option">
										<xs:complexType>
											<xs:attribute name="key" type="xs:string" use="required" />
											<xs:attribute name="value" type="xs:string" use="required" />
										</xs:complexType>
									</xs:element>
								</xs:sequence>
							</xs:complexType>
						</xs:element>
						<xs:element name="Mappings" minOccurs="0" maxOccurs="1">
							<xs:complexType>
								<xs:sequence>
									<xs:element maxOccurs="unbounded" name="Mapping">
										<xs:complexType>
											<xs:attribute name="mdtype" type="xs:string" use="required" />
											<xs:attribute name="othermdtype" type="xs:string" use="optional" />
											<xs:attribute name="label" type="xs:string" use="optional" />
											<xs:attribute name="isDefault" type="xs:boolean" use="optional" default="false" />
										</xs:complexType>
									</xs:element>
								</xs:sequence>
							</xs:complexType>
						</xs:element>
					</xs:sequence>
					<xs:attribute name="ID" type="xs:string" use="optional" />
					<xs:attribute name="label" type="xs:string" use="required" />
					<xs:attribute name="namespace" type="xs:string" use="required" />
					<xs:attribute name="class" type="xs:string" use="required" />
					<xs:attribute name="assembly" type="xs:string" use="optional" />
					<xs:attribute name="isActive" type="xs:boolean" use="optional" default="true" />
					<xs:attribute name="section" type="sobek:metsSection" use="required"  />
					<xs:attribute name="amdSecType" type="sobek:amdSectionType" use="optional"  />
				</xs:complexType>
			</xs:element>
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="metsWritingType">
		<xs:sequence>
			<xs:element maxOccurs="unbounded" name="Profile">
				<xs:complexType>
					<xs:sequence>
						<xs:element name="Package_Scope" type="sobek:metsWriterScopeType" minOccurs="0" maxOccurs="1" />
						<xs:element name="Division_Scope" type="sobek:metsWriterScopeType" minOccurs="0" maxOccurs="1" />
						<xs:element name="File_Scope" type="sobek:metsWriterScopeType" minOccurs="0" maxOccurs="1"  />
					</xs:sequence>
					<xs:attribute name="isDefault" type="xs:boolean" use="optional" default="false" />
					<xs:attribute name="name" type="xs:string" use="required" />
					<xs:attribute name="description" type="xs:string" use="optional" />
				</xs:complexType>
			</xs:element>
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="additionalMetadataModulesType">
		<xs:sequence>
			<xs:element maxOccurs="unbounded" name="MetadataModule">
				<xs:complexType>
					<xs:attribute name="key" type="xs:string" use="required" />
					<xs:attribute name="assembly" type="xs:string" use="optional" />
					<xs:attribute name="namespace" type="xs:string" use="required" />
					<xs:attribute name="class" type="xs:string" use="required" />
				</xs:complexType>
			</xs:element>
		</xs:sequence>
	</xs:complexType>

	<xs:simpleType name="metadataFileStandardTypes">
		<xs:restriction base="xs:string">
			<xs:enumeration value="DC" />
			<xs:enumeration value="EAD" />
			<xs:enumeration value="MARC21" />
			<xs:enumeration value="MARCXML" />
			<xs:enumeration value="METS" />
			<xs:enumeration value="MODS" />
			<xs:enumeration value="OTHER" />
		</xs:restriction>
	</xs:simpleType>

	<xs:complexType name="metsWriterScopeType">
		<xs:sequence>
			<xs:element name="dmdSec" type="sobek:metsWriterRefType" minOccurs="0" maxOccurs="1" />
			<xs:element name="amdSec" type="sobek:metsWriterRefType" minOccurs="0" maxOccurs="1" />
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="metsWriterRefType">
		<xs:sequence>
			<xs:element maxOccurs="unbounded" name="ReaderWriterRef">
				<xs:complexType>
					<xs:attribute name="ID" type="xs:string" use="required" />
				</xs:complexType>
			</xs:element>
		</xs:sequence>
	</xs:complexType>

	<xs:simpleType name="metsSection">
		<xs:restriction base="xs:string">
			<xs:enumeration value="dmdSec" />
			<xs:enumeration value="amdSec" />
		</xs:restriction>
	</xs:simpleType>

	<xs:simpleType name="amdSectionType">
		<xs:restriction base="xs:string">
			<xs:enumeration value="rightsMD" />
			<xs:enumeration value="sourceMD" />
			<xs:enumeration value="digiProvMD" />
			<xs:enumeration value="techMD" />
		</xs:restriction>
	</xs:simpleType>

	<!-- ============================== QUALITY CONTROL SPECIFIC TYPES ================================== -->
	<xs:complexType name="qcProfileType">
		<xs:sequence>
			<xs:element maxOccurs="unbounded" name="DivisionType">
				<xs:complexType>
					<xs:sequence minOccurs="0">
						<xs:element maxOccurs="unbounded" name="Translation">
							<xs:complexType>
								<xs:attribute name="language" type="xs:string" use="required" />
								<xs:attribute name="text" type="xs:string" use="required" />
							</xs:complexType>
						</xs:element>
					</xs:sequence>
					<xs:attribute name="DivisionID" type="xs:int" use="required" />
					<xs:attribute name="type" type="xs:string" use="required" />
					<xs:attribute name="isActive" type="xs:boolean" use="optional" default="true" />
					<xs:attribute name="isNameable" type="xs:boolean" use="required" />
					<xs:attribute name="base" type="xs:string" use="optional" />
				</xs:complexType>
			</xs:element>
		</xs:sequence>
		<xs:attribute name="isDefault" type="xs:boolean" use="optional" default="false" />
		<xs:attribute name="name" type="xs:string" use="required" />
		<xs:attribute name="description" type="xs:string" use="required" />
	</xs:complexType>



	<!-- ============================== AUTHENTICATION SPECIFIC TYPES ================================== -->
	<xs:simpleType name="userAttributeMappingType">
		<xs:restriction base="xs:string">
			<xs:enumeration value="USERNAME" />
			<xs:enumeration value="EMAIL" />
			<xs:enumeration value="FIRSTNAME" />
			<xs:enumeration value="LASTNAME" />
			<xs:enumeration value="NICKNAME" />
			<xs:enumeration value="NOTES" />
			<xs:enumeration value="ORGANIZATION" />
			<xs:enumeration value="ORGCODE" />
			<xs:enumeration value="COLLEGE" />
			<xs:enumeration value="DEPARTMENT" />
		</xs:restriction>
	</xs:simpleType>

	<!-- One OpenID Connect identity provider -->
	<xs:complexType name="externalAuthProviderType">
		<xs:sequence>
			<xs:element name="mapping" minOccurs="0" maxOccurs="unbounded">
				<xs:complexType>
					<xs:attribute name="Name" type="xs:string" use="required" />
					<xs:attribute name="UserAttribute" type="sobek:userAttributeMappingType" use="required" />
				</xs:complexType>
			</xs:element>
		</xs:sequence>
		<xs:attribute name="ProviderCode" type="xs:string" use="required" />
		<xs:attribute name="Label" type="xs:string" use="required" />
		<xs:attribute name="Authority" type="xs:string" use="required" />
		<xs:attribute name="ClientId" type="xs:string" use="required" />
		<xs:attribute name="ClientSecret" type="xs:string" use="required" />
		<xs:attribute name="Enabled" type="xs:boolean" use="optional" default="true" />
	</xs:complexType>

	<!-- One SAML identity provider, handled via Sustainsys.Saml2 -->
	<xs:complexType name="samlAuthProviderType">
		<xs:sequence>
			<xs:element name="mapping" minOccurs="0" maxOccurs="unbounded">
				<xs:complexType>
					<xs:attribute name="Name" type="xs:string" use="required" />
					<xs:attribute name="UserAttribute" type="sobek:userAttributeMappingType" use="required" />
				</xs:complexType>
			</xs:element>
		</xs:sequence>
		<xs:attribute name="ProviderCode" type="xs:string" use="required" />
		<xs:attribute name="Label" type="xs:string" use="required" />
		<xs:attribute name="IdpMetadataUrl" type="xs:string" use="required" />
		<!-- This application's own SP identifier, registered as trusted with the identity provider -->
		<xs:attribute name="EntityId" type="xs:string" use="required" />
		<!-- The identity provider's own entityID, from its metadata's EntityDescriptor - NOT the same as EntityId -->
		<xs:attribute name="IdpEntityId" type="xs:string" use="required" />
		<xs:attribute name="Enabled" type="xs:boolean" use="optional" default="true" />
	</xs:complexType>

	<!-- ============================== WRITER/VIEWER SPECIFIC TYPES ================================== -->
	<xs:complexType name="writerClassRefType">
		<xs:attribute name="assembly" type="xs:string" use="optional" />
		<xs:attribute name="class" type="xs:string" use="required" />
	</xs:complexType>

	<xs:complexType name="htmlHeadWriterType">
		<xs:attribute name="id" type="xs:string" use="required" />
		<xs:attribute name="assembly" type="xs:string" use="optional" />
		<xs:attribute name="class" type="xs:string" use="required" />
		<xs:attribute name="enabled" type="xs:boolean" use="optional" default="true" />
	</xs:complexType>

	<xs:complexType name="itemWriterConfigType">
		<xs:sequence>
			<xs:element name="ClearAll" minOccurs="0" maxOccurs="1" />
			<xs:element name="ItemWriter" type="sobek:writerClassRefType" minOccurs="0" maxOccurs="1" />
			<xs:element name="HtmlHeadWriters" minOccurs="0" maxOccurs="1">
				<xs:complexType>
					<xs:sequence>
						<xs:element name="HtmlHeadWriter" type="sobek:htmlHeadWriterType" minOccurs="0" maxOccurs="unbounded" />
					</xs:sequence>
				</xs:complexType>
			</xs:element>
			<xs:element name="Layouts" minOccurs="0" maxOccurs="1">
				<xs:complexType>
					<xs:sequence>
						<xs:element name="Layout" minOccurs="0" maxOccurs="unbounded">
							<xs:complexType>
								<xs:sequence>
									<xs:element name="Stylesheets" minOccurs="0" maxOccurs="1">
										<xs:complexType>
											<xs:sequence>
												<xs:element name="Stylesheet" minOccurs="0" maxOccurs="unbounded">
													<xs:complexType>
														<xs:attribute name="source" type="xs:string" use="required" />
														<xs:attribute name="media" type="xs:string" use="optional" />
													</xs:complexType>
												</xs:element>
											</xs:sequence>
										</xs:complexType>
									</xs:element>
									<xs:element name="SectionWriters" minOccurs="0" maxOccurs="1">
										<xs:complexType>
											<xs:sequence>
												<xs:element name="Section" minOccurs="0" maxOccurs="unbounded">
													<xs:complexType>
														<xs:sequence>
															<xs:element name="SectionWriter" minOccurs="0" maxOccurs="unbounded">
																<xs:complexType>
																	<xs:attribute name="id" type="xs:string" use="required" />
																	<xs:attribute name="assembly" type="xs:string" use="optional" />
																	<xs:attribute name="class" type="xs:string" use="required" />
																	<xs:attribute name="enabled" type="xs:boolean" use="optional" default="true" />
																</xs:complexType>
															</xs:element>
														</xs:sequence>
														<xs:attribute name="name" type="xs:string" use="required" />
													</xs:complexType>
												</xs:element>
											</xs:sequence>
										</xs:complexType>
									</xs:element>
								</xs:sequence>
								<xs:attribute name="id" type="xs:string" use="required" />
								<xs:attribute name="source" type="xs:string" use="required" />
								<xs:attribute name="default" type="xs:boolean" use="optional" />
							</xs:complexType>
						</xs:element>
					</xs:sequence>
				</xs:complexType>
			</xs:element>
			<xs:element name="ItemViewers" minOccurs="0" maxOccurs="1">
				<xs:complexType>
					<xs:sequence>
						<xs:element name="ItemViewer" minOccurs="0" maxOccurs="unbounded">
							<xs:complexType>
								<xs:attribute name="type" type="xs:string" use="required" />
								<xs:attribute name="viewerCode" type="xs:string" use="optional" />
								<xs:attribute name="assembly" type="xs:string" use="optional" />
								<xs:attribute name="class" type="xs:string" use="required" />
								<xs:attribute name="enabled" type="xs:boolean" use="optional" default="true" />
								<xs:attribute name="fileExtensions" type="xs:string" use="optional" />
								<xs:attribute name="pageFileExtensions" type="xs:string" use="optional" />
								<xs:attribute name="mgmtViewer" type="xs:boolean" use="optional" />
								<xs:attribute name="mgmtOrder" type="xs:int" use="optional" />
								<xs:attribute name="alwaysAdd" type="xs:boolean" use="optional" />
							</xs:complexType>
						</xs:element>
					</xs:sequence>
				</xs:complexType>
			</xs:element>
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="aggregationWriterType">
		<xs:sequence>
			<xs:element name="MenuProvider" type="sobek:writerClassRefType" minOccurs="0" maxOccurs="1" />
			<xs:element name="HtmlHeadWriters" minOccurs="0" maxOccurs="1">
				<xs:complexType>
					<xs:sequence>
						<xs:element name="HtmlHeadWriter" type="sobek:htmlHeadWriterType" minOccurs="0" maxOccurs="unbounded" />
					</xs:sequence>
				</xs:complexType>
			</xs:element>
			<xs:element name="AggregationViewers" minOccurs="0" maxOccurs="1">
				<xs:complexType>
					<xs:sequence>
						<xs:element name="AggregationViewer" minOccurs="0" maxOccurs="unbounded">
							<xs:complexType>
								<xs:attribute name="id" type="xs:string" use="required" />
								<xs:attribute name="assembly" type="xs:string" use="optional" />
								<xs:attribute name="class" type="xs:string" use="required" />
								<xs:attribute name="enabled" type="xs:boolean" use="optional" default="true" />
							</xs:complexType>
						</xs:element>
					</xs:sequence>
				</xs:complexType>
			</xs:element>
			<xs:element name="AggregationLayoutSets" minOccurs="0" maxOccurs="1">
				<xs:complexType>
					<xs:sequence>
						<xs:element name="AggregationLayoutSet" minOccurs="0" maxOccurs="unbounded">
							<xs:complexType>
								<xs:sequence>
									<xs:element name="AggregationLayout" minOccurs="0" maxOccurs="unbounded">
										<xs:complexType>
											<xs:sequence>
												<xs:element name="Section" minOccurs="0" maxOccurs="unbounded">
													<xs:complexType>
														<xs:attribute name="AggregationViewerId" type="xs:string" use="required" />
														<xs:attribute name="id" type="xs:string" use="optional" />
														<xs:attribute name="class" type="xs:string" use="optional" />
													</xs:complexType>
												</xs:element>
											</xs:sequence>
											<xs:attribute name="code" type="xs:string" use="optional" />
											<xs:attribute name="default" type="xs:boolean" use="optional" />
											<xs:attribute name="container" type="xs:string" use="optional" />
										</xs:complexType>
									</xs:element>
								</xs:sequence>
								<xs:attribute name="type" type="xs:string" use="required" />
								<xs:attribute name="default" type="xs:boolean" use="optional" />
							</xs:complexType>
						</xs:element>
					</xs:sequence>
				</xs:complexType>
			</xs:element>
		</xs:sequence>
		<xs:attribute name="assembly" type="xs:string" use="optional" />
		<xs:attribute name="class" type="xs:string" use="required" />
	</xs:complexType>

	<xs:complexType name="resultsWriterConfigType">
		<xs:sequence>
			<xs:element name="ClearAll" minOccurs="0" maxOccurs="1" />
			<xs:element name="ResultsWriter" type="sobek:writerClassRefType" minOccurs="0" maxOccurs="1" />
			<xs:element name="ResultsViewers" minOccurs="0" maxOccurs="1">
				<xs:complexType>
					<xs:sequence>
						<xs:element name="ResultsViewer" minOccurs="0" maxOccurs="unbounded">
							<xs:complexType>
								<xs:attribute name="type" type="xs:string" use="optional" />
								<!-- Used instead of "type" for special-purpose viewers, e.g. special="NORESULTS" -->
								<xs:attribute name="special" type="xs:string" use="optional" />
								<xs:attribute name="viewerCode" type="xs:string" use="optional" />
								<xs:attribute name="assembly" type="xs:string" use="optional" />
								<xs:attribute name="class" type="xs:string" use="required" />
								<xs:attribute name="enabled" type="xs:boolean" use="optional" default="true" />
								<xs:attribute name="label" type="xs:string" use="optional" />
								<xs:attribute name="icon" type="xs:string" use="optional" />
								<xs:attribute name="description" type="xs:string" use="optional" />
							</xs:complexType>
						</xs:element>
					</xs:sequence>
				</xs:complexType>
			</xs:element>
		</xs:sequence>
	</xs:complexType>

	<!-- ============================== CONTACT FORM SPECIFIC TYPES ================================== -->
	<xs:complexType name="contactFormTranslationsType">
		<xs:sequence>
			<xs:element name="Language" minOccurs="0" maxOccurs="unbounded">
				<xs:complexType>
					<xs:simpleContent>
						<xs:extension base="xs:string">
							<xs:attribute name="Code" type="xs:string" use="required" />
						</xs:extension>
					</xs:simpleContent>
				</xs:complexType>
			</xs:element>
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="contactFormTranslatedType">
		<xs:sequence>
			<xs:element name="Translations" type="sobek:contactFormTranslationsType" minOccurs="0" maxOccurs="1" />
		</xs:sequence>
		<xs:attribute name="Text" type="xs:string" use="optional" />
	</xs:complexType>

	<!-- Covers Subject, TextArea, TextBox and Email form fields (the shared attribute set is a superset;
	     not every attribute applies to every element) -->
	<xs:complexType name="contactFormFieldType">
		<xs:sequence>
			<xs:element name="Translations" type="sobek:contactFormTranslationsType" minOccurs="0" maxOccurs="1" />
		</xs:sequence>
		<xs:attribute name="Name" type="xs:string" use="optional" />
		<xs:attribute name="Query" type="xs:string" use="optional" />
		<xs:attribute name="UserAttribute" type="xs:string" use="optional" />
		<xs:attribute name="Required" type="xs:string" use="optional" />
		<xs:attribute name="AlwaysShow" type="xs:string" use="optional" />
		<xs:attribute name="CssClass" type="xs:string" use="optional" />
	</xs:complexType>

	<!-- Covers SelectBox, RadioSet and CheckBoxSet -->
	<xs:complexType name="contactFormOptionSetType">
		<xs:sequence>
			<xs:element name="Options" minOccurs="0" maxOccurs="1">
				<xs:complexType>
					<xs:sequence>
						<xs:element name="Option" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
					</xs:sequence>
				</xs:complexType>
			</xs:element>
		</xs:sequence>
		<xs:attribute name="Name" type="xs:string" use="required" />
		<xs:attribute name="Query" type="xs:string" use="optional" />
	</xs:complexType>

	<!-- ============================== STATIC RESOURCES SPECIFIC TYPES ================================== -->
	<xs:complexType name="staticResourceFileType">
		<xs:attribute name="key" type="xs:string" use="required" />
		<xs:attribute name="source" type="xs:string" use="required" />
	</xs:complexType>

	<!-- ============================== TEMPLATE ELEMENT / PLUGIN MANIFEST SPECIFIC TYPES ================================== -->
	<!-- Shared by the <TemplateElements> wrapper (sobekcm_template_elements.config) and the unwrapped
	     <TemplateConfig> list some plugins use to register additional metadata-entry element types -->
	<xs:complexType name="templateElementType">
		<xs:attribute name="type" type="xs:string" use="required" />
		<xs:attribute name="subtype" type="xs:string" use="optional" />
		<xs:attribute name="class" type="xs:string" use="required" />
		<xs:attribute name="image" type="xs:string" use="optional" />
		<xs:attribute name="helpUri" type="xs:string" use="optional" />
		<xs:attribute name="adminUri" type="xs:string" use="optional" />
		<!-- Present when the element type is registered by a plugin, rather than being a core element -->
		<xs:attribute name="assembly" type="xs:string" use="optional" />
	</xs:complexType>

	<xs:simpleType name="cssConditionType">
		<xs:restriction base="xs:string">
			<xs:enumeration value="always" />
			<xs:enumeration value="admin" />
			<xs:enumeration value="item" />
			<xs:enumeration value="metadata" />
			<xs:enumeration value="mysobek" />
			<xs:enumeration value="aggregation" />
			<xs:enumeration value="results" />
		</xs:restriction>
	</xs:simpleType>

</xs:schema>
