Class DocumentRevisionsValidator
java.lang.Object
com.itextpdf.signatures.validation.DocumentRevisionsValidator
Validator, which is responsible for document revisions validation according to doc-MDP and field-MDP rules.
-
Field Summary
FieldsModifier and TypeFieldDescription(package private) static final String
private AccessPermissions
(package private) static final String
private Set
<PdfDictionary> (package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
private static final PdfDictionary
private static final float
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
private IMetaInfo
private Set
<PdfDictionary> (package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
private final SignatureValidationProperties
(package private) static final String
private Set
<PdfDictionary> private AccessPermissions
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
(package private) static final String
private ReportItem.ReportItemStatus
(package private) static final String
(package private) static final String
private Pair
<Set<PdfIndirectReference>, Set<PdfIndirectReference>> -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotected
DocumentRevisionsValidator
(ValidatorChainBuilder chainBuilder) Creates new instance ofDocumentRevisionsValidator
. -
Method Summary
Modifier and TypeMethodDescriptionprivate void
addAllNestedArrayEntries
(Set<PdfIndirectReference> allowedReferences, PdfArray pdfArray) private void
addAllNestedDictionaryEntries
(Set<PdfIndirectReference> allowedReferences, PdfDictionary dictionary) private void
addPageEntriesToSet
(PdfDictionary page, Set<PdfIndirectReference> set) private void
addStructTreeElementsToSet
(PdfArray structTreeRootKids, Set<PdfIndirectReference> set) private void
addStructTreeElementsToSet
(PdfObject structTreeRootKids, Set<PdfIndirectReference> set) private void
addWidgetAnnotation
(Set<PdfIndirectReference> allowedReferences, PdfDictionary annotDict) private boolean
checkAllowedReferences
(Set<PdfIndirectReference> currentAllowedReferences, Set<PdfIndirectReference> previousAllowedReferences, PdfIndirectReference indirectReference, PdfDocument documentWithoutRevision) private void
collectRemovedAndAddedAnnotations
(PdfArray previousAnnotations, PdfArray currentAnnotations) private boolean
compareAcroForms
(PdfDictionary prevAcroForm, PdfDictionary currAcroForm, ValidationReport report) private boolean
compareAcroFormsWithFieldMDP
(PdfDocument documentWithoutRevision, PdfDocument documentWithRevision, ValidationReport report) private boolean
compareCatalogs
(PdfDocument documentWithoutRevision, PdfDocument documentWithRevision, ValidationReport report, ValidationContext context) private boolean
compareDss
(PdfObject previousDss, PdfObject currentDss, ValidationReport report) private boolean
compareExtensions
(PdfObject previousExtensions, PdfObject currentExtensions, ValidationReport report) private boolean
compareFields
(PdfDictionary previousField, PdfDictionary currentField, ValidationReport report) DocMDP level >= 2 allows setting values of the fields and accordingly update the widget appearances of them.private boolean
compareFormFields
(PdfArray prevFields, PdfArray currFields, ValidationReport report) private boolean
compareFormFieldWithFieldMDP
(PdfDictionary previousField, PdfDictionary currentField, String fieldName, ValidationReport report) private boolean
compareIndirectReferencesObjNums
(PdfObject prevObj, PdfObject currObj, ValidationReport report, String type) private boolean
comparePageAnnotations
(PdfArray prevAnnots, PdfArray currAnnots, ValidationReport report) private boolean
comparePageAnnotations
(PdfDictionary prevAnnot, PdfDictionary currAnnot, ValidationReport report) private boolean
comparePages
(PdfDictionary prevPages, PdfDictionary currPages, ValidationReport report) private static boolean
comparePdfArrays
(PdfArray array1, PdfArray array2, List<Pair<PdfObject, PdfObject>> visitedObjects, Pair<Set<PdfIndirectReference>, Set<PdfIndirectReference>> usuallyModifiedObjects) private static boolean
comparePdfDictionaries
(PdfDictionary dictionary1, PdfDictionary dictionary2, List<Pair<PdfObject, PdfObject>> visitedObjects, Pair<Set<PdfIndirectReference>, Set<PdfIndirectReference>> usuallyModifiedObjects) private static boolean
comparePdfObjects
(PdfObject pdfObject1, PdfObject pdfObject2, Pair<Set<PdfIndirectReference>, Set<PdfIndirectReference>> usuallyModifiedObjects) private static boolean
comparePdfObjects
(PdfObject pdfObject1, PdfObject pdfObject2, List<Pair<PdfObject, PdfObject>> visitedObjects, Pair<Set<PdfIndirectReference>, Set<PdfIndirectReference>> usuallyModifiedObjects) private static boolean
comparePdfStreams
(PdfStream stream1, PdfStream stream2, List<Pair<PdfObject, PdfObject>> visitedObjects, Pair<Set<PdfIndirectReference>, Set<PdfIndirectReference>> usuallyModifiedObjects) private boolean
comparePermissions
(PdfObject previousPerms, PdfObject currentPerms, ValidationReport report) private boolean
compareSignatureDictionaries
(PdfObject prevSigDict, PdfObject curSigDict, ValidationReport report) private boolean
compareSignatureReferenceDictionaries
(PdfArray previousReferences, PdfArray currentReferences, ValidationReport report) private boolean
compareStructTreeContents
(PdfObject previousStructTreeContent, PdfObject currentStructTreeContent, ValidationReport report) private boolean
compareStructTreeElementKids
(PdfDictionary previousStructElement, PdfDictionary currentStructElement, ValidationReport report) private boolean
compareStructTreeElements
(PdfDictionary previousStructElement, PdfDictionary currentStructElement, ValidationReport report) private boolean
compareStructTreeRoot
(PdfObject previousStructTreeRoot, PdfObject currentStructTreeRoot, ValidationReport report) private boolean
compareWidgets
(PdfArray prevFields, PdfArray currFields, ValidationReport report) private PdfDictionary
copyAcroformDictionary
(PdfDictionary acroForm) private PdfDictionary
copyCatalogEntriesToCompare
(PdfDictionary catalog) private PdfDictionary
copyFieldDictionary
(PdfDictionary field) private Set
<PdfIndirectReference> createAllowedDssEntries
(PdfDocument document) private void
createAllowedFormFieldEntries
(PdfArray fields, Set<PdfIndirectReference> allowedReferences) private Collection
<PdfIndirectReference> createAllowedPagesEntries
(PdfDictionary pagesDictionary) private Set
<PdfIndirectReference> createAllowedReferences
(PdfDocument document) private Set
<PdfIndirectReference> createAllowedStructTreeRootEntries
(PdfDictionary structTreeRoot) private void
createAllowedStructTreeRootKidsEntries
(PdfArray structTreeRootKids, Set<PdfIndirectReference> allowedReferences) private void
createAllowedStructTreeRootKidsEntries
(PdfObject structTreeRootKids, Set<PdfIndirectReference> allowedReferences) private void
createAllowedTreeEntries
(PdfObject treeNode, Set<PdfIndirectReference> allowedReferences, PdfName contentName) private boolean
createDocumentAndPerformOperation
(DocumentRevision revision, PdfDocument originalDocument, ValidationReport report, Function<PdfDocument, Boolean> operation) private static InputStream
createInputStreamFromRevision
(PdfDocument originalDocument, DocumentRevision revision) private Set
<PdfIndirectReference> createUsuallyModifiedObjectsSet
(PdfDocument document) (package private) AccessPermissions
private PdfArray
private static PdfObject
getObjectFromStructTreeContent
(PdfObject structTreeContent) private boolean
isAllowedSignatureField
(PdfDictionary field, ValidationReport report) DocMDP level invalid input: '<'=2 allows adding new fields in the following cases: docMDP level 1: allows adding only DocTimeStamp signature fields; docMDP level 2: same as level 1 and also adding and then signing signature fields, so signature dictionary shouldn't be null.private boolean
isAllowedStreamObj
(PdfIndirectReference indirectReference, PdfDocument document) private boolean
isCertificationSignature
(PdfSignature signature) private static boolean
isLinearizedPdf
(PdfDocument originalDocument) private static boolean
isMaxGenerationObject
(PdfIndirectReference indirectReference) private static boolean
isSameReference
(PdfIndirectReference indirectReference1, PdfIndirectReference indirectReference2) private static boolean
isStructTreeElement
(PdfObject object) private void
lockAllFormFields
(DocumentRevision revision, List<String> excludedFields, PdfDocument originalDocument, ValidationReport report) private void
mergeRevisionsInLinearizedDocument
(PdfDocument document, List<DocumentRevision> documentRevisions) private Set
<PdfDictionary> populateFormFields
(PdfArray fieldsArray) private List
<PdfDictionary> populateWidgetAnnotations
(PdfArray fieldsArray) private void
removeAppearanceRelatedProperties
(PdfDictionary annotDict) private void
private PdfDictionary
retrieveTheSameField
(Set<PdfDictionary> currFields, PdfDictionary previousField) private boolean
revisionContainsSignature
(DocumentRevision revision, String signature, PdfDocument originalDocument, ValidationReport report) setAccessPermissions
(AccessPermissions accessPermissions) Set access permissions to be used during docMDP validation.setEventCountingMetaInfo
(IMetaInfo metaInfo) Sets theIMetaInfo
that will be used during newPdfDocument
creations.Set the status to be used for the report items produced during docMDP validation in case revision contains unexpected changes in the XREF table.private boolean
stopValidation
(ValidationReport result, ValidationContext validationContext) private void
updateApprovalSignatureAccessPermissions
(PdfDictionary signatureField, ValidationReport report) private void
updateApprovalSignatureFieldLock
(DocumentRevision revision, PdfDictionary signatureField, PdfDocument document, ValidationReport report) private void
updateCertificationSignatureAccessPermissions
(PdfSignature signature, ValidationReport report) validateAllDocumentRevisions
(ValidationContext context, PdfDocument document) Validate all document revisions according to docMDP and fieldMDP transform methods.(package private) ValidationReport
validateAllDocumentRevisions
(ValidationContext context, PdfDocument document, String signatureName) Validate all document revisions according to docMDP and fieldMDP transform methods and collect validation report related to the single signature field checks if specified.(package private) void
validateRevision
(DocumentRevision previousRevision, DocumentRevision currentRevision, PdfDocument originalDocument, ValidationReport validationReport, ValidationContext context) private boolean
validateRevision
(ValidationReport validationReport, ValidationContext context, PdfDocument documentWithoutRevision, PdfDocument documentWithRevision, DocumentRevision currentRevision)
-
Field Details
-
DOC_MDP_CHECK
- See Also:
-
FIELD_MDP_CHECK
- See Also:
-
ACCESS_PERMISSIONS_ADDED
- See Also:
-
ACROFORM_REMOVED
- See Also:
-
ANNOTATIONS_MODIFIED
- See Also:
-
BASE_VERSION_DECREASED
- See Also:
-
BASE_VERSION_EXTENSION_NOT_PARSABLE
- See Also:
-
DEVELOPER_EXTENSION_REMOVED
- See Also:
-
DIRECT_OBJECT
- See Also:
-
DOCUMENT_WITHOUT_SIGNATURES
- See Also:
-
DSS_REMOVED
- See Also:
-
EXTENSIONS_REMOVED
- See Also:
-
EXTENSIONS_TYPE
- See Also:
-
EXTENSION_LEVEL_DECREASED
- See Also:
-
FIELD_NOT_DICTIONARY
- See Also:
-
FIELD_REMOVED
- See Also:
-
LOCKED_FIELD_KIDS_ADDED
- See Also:
-
LOCKED_FIELD_KIDS_REMOVED
- See Also:
-
LOCKED_FIELD_MODIFIED
- See Also:
-
LOCKED_FIELD_REMOVED
- See Also:
-
NOT_ALLOWED_ACROFORM_CHANGES
- See Also:
-
NOT_ALLOWED_CATALOG_CHANGES
- See Also:
-
NOT_ALLOWED_CERTIFICATION_SIGNATURE
- See Also:
-
OBJECT_REMOVED
- See Also:
-
PAGES_MODIFIED
- See Also:
-
PAGE_ANNOTATIONS_MODIFIED
- See Also:
-
PAGE_MODIFIED
- See Also:
-
PERMISSIONS_REMOVED
- See Also:
-
PERMISSIONS_TYPE
- See Also:
-
PERMISSION_REMOVED
- See Also:
-
REFERENCE_REMOVED
- See Also:
-
REVISIONS_READING_EXCEPTION
- See Also:
-
REVISIONS_RETRIEVAL_FAILED
- See Also:
-
REVISIONS_RETRIEVAL_FAILED_UNEXPECTEDLY
- See Also:
-
SIGNATURE_MODIFIED
- See Also:
-
SIGNATURE_REVISION_NOT_FOUND
- See Also:
-
STRUCT_TREE_CONTENT_MODIFIED
- See Also:
-
STRUCT_TREE_ELEMENT_MODIFIED
- See Also:
-
STRUCT_TREE_ROOT_ADDED
- See Also:
-
STRUCT_TREE_ROOT_MODIFIED
- See Also:
-
STRUCT_TREE_ROOT_NOT_DICT
- See Also:
-
STRUCT_TREE_ROOT_REMOVED
- See Also:
-
TOO_MANY_CERTIFICATION_SIGNATURES
- See Also:
-
UNEXPECTED_ENTRY_IN_XREF
- See Also:
-
UNEXPECTED_FORM_FIELD
- See Also:
-
UNKNOWN_ACCESS_PERMISSIONS
- See Also:
-
UNRECOGNIZED_ACTION
- See Also:
-
EPS
private static final float EPS- See Also:
-
DUMMY_STRUCT_TREE_ELEMENT
-
lockedFields
-
properties
-
metaInfo
-
accessPermissions
-
requestedAccessPermissions
-
unexpectedXrefChangesStatus
-
checkedAnnots
-
newlyAddedFields
-
removedTaggedObjects
-
addedTaggedObjects
-
usuallyModifiedObjects
-
-
Constructor Details
-
DocumentRevisionsValidator
Creates new instance ofDocumentRevisionsValidator
.- Parameters:
chainBuilder
- SeeValidatorChainBuilder
-
-
Method Details
-
setEventCountingMetaInfo
Sets theIMetaInfo
that will be used during newPdfDocument
creations.- Parameters:
metaInfo
- meta info to set- Returns:
- the same
DocumentRevisionsValidator
instance.
-
setAccessPermissions
Set access permissions to be used during docMDP validation. If value is provided, access permission related signature parameters will be ignored during the validation.- Parameters:
accessPermissions
-AccessPermissions
docMDP validation level- Returns:
- the same
DocumentRevisionsValidator
instance.
-
setUnexpectedXrefChangesStatus
public DocumentRevisionsValidator setUnexpectedXrefChangesStatus(ReportItem.ReportItemStatus status) Set the status to be used for the report items produced during docMDP validation in case revision contains unexpected changes in the XREF table. Default value isReportItem.ReportItemStatus.INFO
.- Parameters:
status
-ReportItem.ReportItemStatus
to be used in case of unexpected changes in the XREF table- Returns:
- the same
DocumentRevisionsValidator
instance.
-
validateAllDocumentRevisions
public ValidationReport validateAllDocumentRevisions(ValidationContext context, PdfDocument document) Validate all document revisions according to docMDP and fieldMDP transform methods.- Parameters:
context
- the validation context in which to validate document revisionsdocument
- the document to be validated- Returns:
ValidationReport
which contains detailed validation results.
-
validateAllDocumentRevisions
ValidationReport validateAllDocumentRevisions(ValidationContext context, PdfDocument document, String signatureName) Validate all document revisions according to docMDP and fieldMDP transform methods and collect validation report related to the single signature field checks if specified.- Parameters:
context
- the validation context in which to validate document revisionsdocument
- the document to be validatedsignatureName
- signature field to collect validation result for. If null, all signatures will be checked- Returns:
ValidationReport
which contains detailed validation results.
-
validateRevision
void validateRevision(DocumentRevision previousRevision, DocumentRevision currentRevision, PdfDocument originalDocument, ValidationReport validationReport, ValidationContext context) -
mergeRevisionsInLinearizedDocument
private void mergeRevisionsInLinearizedDocument(PdfDocument document, List<DocumentRevision> documentRevisions) -
validateRevision
private boolean validateRevision(ValidationReport validationReport, ValidationContext context, PdfDocument documentWithoutRevision, PdfDocument documentWithRevision, DocumentRevision currentRevision) -
getAccessPermissions
AccessPermissions getAccessPermissions() -
createInputStreamFromRevision
private static InputStream createInputStreamFromRevision(PdfDocument originalDocument, DocumentRevision revision) -
isLinearizedPdf
-
isStructTreeElement
-
getObjectFromStructTreeContent
-
stopValidation
-
updateApprovalSignatureAccessPermissions
private void updateApprovalSignatureAccessPermissions(PdfDictionary signatureField, ValidationReport report) -
updateApprovalSignatureFieldLock
private void updateApprovalSignatureFieldLock(DocumentRevision revision, PdfDictionary signatureField, PdfDocument document, ValidationReport report) -
lockAllFormFields
private void lockAllFormFields(DocumentRevision revision, List<String> excludedFields, PdfDocument originalDocument, ValidationReport report) -
updateCertificationSignatureAccessPermissions
private void updateCertificationSignatureAccessPermissions(PdfSignature signature, ValidationReport report) -
isCertificationSignature
-
revisionContainsSignature
private boolean revisionContainsSignature(DocumentRevision revision, String signature, PdfDocument originalDocument, ValidationReport report) -
createDocumentAndPerformOperation
private boolean createDocumentAndPerformOperation(DocumentRevision revision, PdfDocument originalDocument, ValidationReport report, Function<PdfDocument, Boolean> operation) -
resetClassFields
private void resetClassFields() -
compareCatalogs
private boolean compareCatalogs(PdfDocument documentWithoutRevision, PdfDocument documentWithRevision, ValidationReport report, ValidationContext context) -
compareStructTreeRoot
private boolean compareStructTreeRoot(PdfObject previousStructTreeRoot, PdfObject currentStructTreeRoot, ValidationReport report) -
compareStructTreeElementKids
private boolean compareStructTreeElementKids(PdfDictionary previousStructElement, PdfDictionary currentStructElement, ValidationReport report) -
compareStructTreeElements
private boolean compareStructTreeElements(PdfDictionary previousStructElement, PdfDictionary currentStructElement, ValidationReport report) -
compareStructTreeContents
private boolean compareStructTreeContents(PdfObject previousStructTreeContent, PdfObject currentStructTreeContent, ValidationReport report) -
compareExtensions
private boolean compareExtensions(PdfObject previousExtensions, PdfObject currentExtensions, ValidationReport report) -
comparePermissions
private boolean comparePermissions(PdfObject previousPerms, PdfObject currentPerms, ValidationReport report) -
compareDss
-
compareAcroFormsWithFieldMDP
private boolean compareAcroFormsWithFieldMDP(PdfDocument documentWithoutRevision, PdfDocument documentWithRevision, ValidationReport report) -
compareFormFieldWithFieldMDP
private boolean compareFormFieldWithFieldMDP(PdfDictionary previousField, PdfDictionary currentField, String fieldName, ValidationReport report) -
compareAcroForms
private boolean compareAcroForms(PdfDictionary prevAcroForm, PdfDictionary currAcroForm, ValidationReport report) -
compareFormFields
private boolean compareFormFields(PdfArray prevFields, PdfArray currFields, ValidationReport report) -
retrieveTheSameField
private PdfDictionary retrieveTheSameField(Set<PdfDictionary> currFields, PdfDictionary previousField) -
compareFields
private boolean compareFields(PdfDictionary previousField, PdfDictionary currentField, ValidationReport report) DocMDP level >= 2 allows setting values of the fields and accordingly update the widget appearances of them. But you cannot change the form structure, so it is not allowed to add, remove or rename fields, change most of their properties.- Parameters:
previousField
- field from the previous revision to checkcurrentField
- field from the current revision to checkreport
- validation report- Returns:
true
if the changes of the field are allowed,false
otherwise.
-
compareSignatureDictionaries
private boolean compareSignatureDictionaries(PdfObject prevSigDict, PdfObject curSigDict, ValidationReport report) -
compareSignatureReferenceDictionaries
private boolean compareSignatureReferenceDictionaries(PdfArray previousReferences, PdfArray currentReferences, ValidationReport report) -
compareWidgets
-
comparePages
private boolean comparePages(PdfDictionary prevPages, PdfDictionary currPages, ValidationReport report) -
collectRemovedAndAddedAnnotations
-
comparePageAnnotations
private boolean comparePageAnnotations(PdfArray prevAnnots, PdfArray currAnnots, ValidationReport report) -
comparePageAnnotations
private boolean comparePageAnnotations(PdfDictionary prevAnnot, PdfDictionary currAnnot, ValidationReport report) -
compareIndirectReferencesObjNums
private boolean compareIndirectReferencesObjNums(PdfObject prevObj, PdfObject currObj, ValidationReport report, String type) -
isAllowedSignatureField
DocMDP level invalid input: '<'=2 allows adding new fields in the following cases: docMDP level 1: allows adding only DocTimeStamp signature fields; docMDP level 2: same as level 1 and also adding and then signing signature fields, so signature dictionary shouldn't be null.- Parameters:
field
- newly added field entryreport
- validation report- Returns:
- true if newly added field is allowed to be added, false otherwise.
-
populateFormFields
-
populateWidgetAnnotations
-
getAnnotsNotAllowedToBeModified
-
copyCatalogEntriesToCompare
-
copyAcroformDictionary
-
copyFieldDictionary
-
removeAppearanceRelatedProperties
-
comparePdfObjects
private static boolean comparePdfObjects(PdfObject pdfObject1, PdfObject pdfObject2, Pair<Set<PdfIndirectReference>, Set<PdfIndirectReference>> usuallyModifiedObjects) -
comparePdfObjects
-
comparePdfArrays
-
comparePdfDictionaries
private static boolean comparePdfDictionaries(PdfDictionary dictionary1, PdfDictionary dictionary2, List<Pair<PdfObject, PdfObject>> visitedObjects, Pair<Set<PdfIndirectReference>, Set<PdfIndirectReference>> usuallyModifiedObjects) -
comparePdfStreams
-
isSameReference
private static boolean isSameReference(PdfIndirectReference indirectReference1, PdfIndirectReference indirectReference2) -
isMaxGenerationObject
-
createUsuallyModifiedObjectsSet
-
addStructTreeElementsToSet
private void addStructTreeElementsToSet(PdfObject structTreeRootKids, Set<PdfIndirectReference> set) -
addStructTreeElementsToSet
-
addPageEntriesToSet
-
createAllowedReferences
-
checkAllowedReferences
private boolean checkAllowedReferences(Set<PdfIndirectReference> currentAllowedReferences, Set<PdfIndirectReference> previousAllowedReferences, PdfIndirectReference indirectReference, PdfDocument documentWithoutRevision) -
isAllowedStreamObj
-
createAllowedDssEntries
-
createAllowedStructTreeRootEntries
-
createAllowedTreeEntries
private void createAllowedTreeEntries(PdfObject treeNode, Set<PdfIndirectReference> allowedReferences, PdfName contentName) -
createAllowedStructTreeRootKidsEntries
private void createAllowedStructTreeRootKidsEntries(PdfObject structTreeRootKids, Set<PdfIndirectReference> allowedReferences) -
createAllowedStructTreeRootKidsEntries
private void createAllowedStructTreeRootKidsEntries(PdfArray structTreeRootKids, Set<PdfIndirectReference> allowedReferences) -
createAllowedPagesEntries
-
createAllowedFormFieldEntries
private void createAllowedFormFieldEntries(PdfArray fields, Set<PdfIndirectReference> allowedReferences) -
addWidgetAnnotation
private void addWidgetAnnotation(Set<PdfIndirectReference> allowedReferences, PdfDictionary annotDict) -
addAllNestedDictionaryEntries
private void addAllNestedDictionaryEntries(Set<PdfIndirectReference> allowedReferences, PdfDictionary dictionary) -
addAllNestedArrayEntries
private void addAllNestedArrayEntries(Set<PdfIndirectReference> allowedReferences, PdfArray pdfArray)
-