193 FileName translationFileName;
195 if (inputLabel->findObject(
"IsisCube").hasGroup(
"Instrument")) {
198 translationFileName =
"$ISISROOT/appdata/translations/pds4ExportInstrument.trn";
203 QDomElement obsAreaNode =
m_domDoc->documentElement().firstChildElement(
"Observation_Area");
205 if ( !obsAreaNode.isNull() ) {
208 QDomElement timeNode = obsAreaNode.firstChildElement(
"Time_Coordinates");
209 if (!timeNode.isNull()) {
210 QDomElement startTime = timeNode.firstChildElement(
"start_date_time");
211 if (startTime.text() ==
"") {
212 startTime.setAttribute(
"xsi:nil",
"true");
215 QString timeValue = startTime.text();
218 QDomElement stopTime = timeNode.firstChildElement(
"stop_date_time");
219 if (stopTime.text() ==
"") {
220 stopTime.setAttribute(
"xsi:nil",
"true");
223 QString timeValue = stopTime.text();
228 QDomElement obsSysNode = obsAreaNode.firstChildElement(
"Observing_System");
229 if ( !obsSysNode.isNull() ) {
230 QString instrumentName;
231 QString spacecraftName;
232 QDomElement obsSysCompNode = obsSysNode.firstChildElement(
"Observing_System_Component");
233 while ( !obsSysCompNode.isNull()) {
234 QDomElement compTypeNode = obsSysCompNode.firstChildElement(
"type");
235 if ( compTypeNode.text().compare(
"Spacecraft") == 0 ) {
236 QString componentName = obsSysCompNode.firstChildElement(
"name").text();
237 if (QString::compare(componentName,
"TBD", Qt::CaseInsensitive) != 0) {
238 spacecraftName = componentName;
241 else if ( compTypeNode.text().compare(
"Instrument") == 0 ) {
242 QString componentName = obsSysCompNode.firstChildElement(
"name").text();
243 if (QString::compare(componentName,
"TBD", Qt::CaseInsensitive) != 0) {
244 instrumentName = componentName;
247 obsSysCompNode = obsSysCompNode.nextSiblingElement(
"Observing_System_Component");
249 QDomElement combinedNode =
m_domDoc->createElement(
"name");
250 QString combinedValue =
"TBD";
251 if ( !instrumentName.isEmpty() && !spacecraftName.isEmpty() ) {
252 combinedValue = spacecraftName +
" " + instrumentName;
254 combinedNode.appendChild(
m_domDoc->createTextNode(combinedValue) );
255 obsSysNode.insertBefore( combinedNode, obsSysNode.firstChild() );
260 translationFileName =
"$ISISROOT/appdata/translations/pds4ExportTargetFromInstrument.trn";
265 QDomElement targetIdNode = obsAreaNode.firstChildElement(
"Target_Identification");
266 obsAreaNode.insertAfter(targetIdNode, obsAreaNode.firstChildElement(
"Observing_System"));
268 else if (inputLabel->findObject(
"IsisCube").hasGroup(
"Mapping")) {
270 translationFileName =
"$ISISROOT/appdata/translations/pds4ExportTargetFromMapping.trn";
275 throw IException(IException::Unknown,
"Unable to find a target in input cube.", _FILEINFO_);
285 QDomElement obsAreaNode =
m_domDoc->documentElement().firstChildElement(
"Observation_Area");
286 if ( !obsAreaNode.isNull() ) {
289 QDomElement timeNode = obsAreaNode.firstChildElement(
"Time_Coordinates");
290 if (!timeNode.isNull()) {
291 QDomElement startTime = timeNode.firstChildElement(
"start_date_time");
292 if (startTime.text() ==
"") {
293 startTime.setAttribute(
"xsi:nil",
"true");
296 QString timeValue = startTime.text();
297 if (!timeValue.contains(
"Z")) {
302 QDomElement stopTime = timeNode.firstChildElement(
"stop_date_time");
303 if (stopTime.text() ==
"") {
304 stopTime.setAttribute(
"xsi:nil",
"true");
307 QString timeValue = stopTime.text();
308 if (!timeValue.contains(
"Z")) {
313 xmlPath <<
"Product_Observational"
314 <<
"Observation_Area"
317 <<
"geom:Geometry_Orbiter"
318 <<
"geom:geometry_reference_time_utc";
320 QDomElement baseElement =
m_domDoc->documentElement();
321 QDomElement geomRefTime =
getElement(xmlPath, baseElement);
322 if (geomRefTime.text() ==
"") {
323 geomRefTime.setAttribute(
"xsi:nil",
"true");
326 QString timeValue = geomRefTime.text();
330 xmlPath <<
"Product_Observational"
331 <<
"Observation_Area"
334 <<
"geom:Image_Display_Geometry"
335 <<
"geom:Object_Orientation_North_East"
336 <<
"geom:east_azimuth";
337 QDomElement eastAzimuth =
getElement(xmlPath, baseElement);
338 if (eastAzimuth.text() !=
"") {
343 QDomElement investigationAreaNode = obsAreaNode.firstChildElement(
"Investigation_Area");
344 obsAreaNode.insertAfter(investigationAreaNode, obsAreaNode.firstChildElement(
"Time_Coordinates"));
346 QDomElement obsSystemNode = obsAreaNode.firstChildElement(
"Observing_System");
347 obsAreaNode.insertAfter(obsSystemNode, obsAreaNode.firstChildElement(
"Investigation_Area"));
349 QDomElement targetIdNode = obsAreaNode.firstChildElement(
"Target_Identification");
350 obsAreaNode.insertAfter(targetIdNode, obsAreaNode.firstChildElement(
"Observing_System"));
352 QDomElement missionAreaNode = obsAreaNode.firstChildElement(
"Mission_Area");
353 obsAreaNode.insertAfter(missionAreaNode, obsAreaNode.firstChildElement(
"Target_Identification"));
355 QDomElement disciplineAreaNode = obsAreaNode.firstChildElement(
"Discipline_Area");
356 obsAreaNode.insertAfter(disciplineAreaNode, obsAreaNode.firstChildElement(
"Mission_Area"));
359 QDomElement identificationAreaNode =
m_domDoc->documentElement().firstChildElement(
"Identification_Area");
360 if ( !identificationAreaNode.isNull() ) {
361 QDomElement aliasListNode = identificationAreaNode.firstChildElement(
"Alias_List");
362 identificationAreaNode.insertAfter(aliasListNode, identificationAreaNode.firstChildElement(
"product_class"));
366 QDomElement referenceListNode =
m_domDoc->documentElement().firstChildElement(
"Reference_List");
367 if ( !referenceListNode.isNull() && !identificationAreaNode.isNull() ) {
368 m_domDoc->documentElement().insertAfter(referenceListNode, obsAreaNode);
371 QDomElement fileAreaObservationalNode =
m_domDoc->documentElement().firstChildElement(
"File_Area_Observational");
372 QDomElement array2DImageNode = fileAreaObservationalNode.firstChildElement(
"Array_2D_Image");
373 if ( !array2DImageNode.isNull() ) {
374 QDomElement descriptionNode = array2DImageNode.firstChildElement(
"description");
375 array2DImageNode.insertAfter(descriptionNode, array2DImageNode.firstChildElement(
"axis_index_order"));
585 QString translationFile =
"$ISISROOT/appdata/translations/";
586 translationFile +=
"pds4ExportBandBinSpectrumUniform.trn";
587 FileName translationFileName(translationFile);
591 PvlGroup bandBinGroup = inputLabel.findObject(
"IsisCube").findGroup(
"BandBin");
594 xmlPath <<
"Product_Observational"
595 <<
"Observation_Area"
597 <<
"sp:Spectral_Characteristics";
598 QDomElement baseElement =
m_domDoc->documentElement();
599 QDomElement spectralCharElement =
getElement(xmlPath, baseElement);
606 if (bandBinGroup.hasKeyword(
"Center")) {
607 center = bandBinGroup[
"Center"];
609 else if (bandBinGroup.hasKeyword(
"FilterCenter")) {
610 center = bandBinGroup[
"FilterCenter"];
613 QString msg =
"Unable to translate BandBin info for BinSetSpectrum. "
614 "Translation for PDS4 required value [center_value] not found.";
615 throw IException(IException::Programmer, msg, _FILEINFO_);
618 if (bandBinGroup.hasKeyword(
"Width")) {
619 width = bandBinGroup[
"Width"];
621 else if (bandBinGroup.hasKeyword(
"FilterWidth")) {
622 width = bandBinGroup[
"FilterWidth"];
625 QString msg =
"Unable to translate BandBin info for BinSetSpectrum. "
626 "Translation for PDS4 required value [bin_width] not found.";
627 throw IException(IException::Programmer, msg, _FILEINFO_);
630 QString units = center.unit();
632 if (!width.unit().isEmpty() ) {
633 if (units.isEmpty()) {
634 units = width.unit();
636 if (units.compare(width.unit(), Qt::CaseInsensitive) != 0) {
637 QString msg =
"Unable to translate BandBin info for BinSetSpectrum. "
638 "Unknown or unmatching units for [center_value] and [bin_width].";
639 throw IException(IException::Programmer, msg, _FILEINFO_);
643 PvlKeyword originalBand;
644 if (bandBinGroup.hasKeyword(
"OriginalBand")) {
645 originalBand = bandBinGroup[
"OriginalBand"];
648 if (bandBinGroup.hasKeyword(
"Name")) {
649 name = bandBinGroup[
"Name"];
651 else if (bandBinGroup.hasKeyword(
"FilterName")) {
652 name = bandBinGroup[
"FilterName"];
654 else if (bandBinGroup.hasKeyword(
"FilterId")) {
655 name = bandBinGroup[
"FilterId"];
658 if (bandBinGroup.hasKeyword(
"Number")) {
659 number = bandBinGroup[
"Number"];
661 else if (bandBinGroup.hasKeyword(
"FilterNumber")) {
662 number = bandBinGroup[
"FilterNumber"];
665 QDomElement axisBinSetElement = spectralCharElement.firstChildElement(
"sp:Axis_Bin_Set");
666 if (axisBinSetElement.isNull()) {
667 axisBinSetElement =
m_domDoc->createElement(
"sp:Axis_Bin_Set");
668 spectralCharElement.appendChild(axisBinSetElement);
670 int bands = (int)inputLabel.findObject(
"IsisCube")
672 .findGroup(
"Dimensions")
673 .findKeyword(
"Bands");
675 for (
int i = 0; i < bands; i++) {
677 QDomElement bin =
m_domDoc->createElement(
"sp:Bin");
678 axisBinSetElement.appendChild(bin);
680 QDomElement binSequenceNumber =
m_domDoc->createElement(
"sp:bin_sequence_number");
682 bin.appendChild(binSequenceNumber);
685 QDomElement centerValue =
m_domDoc->createElement(
"sp:center_value");
687 bin.appendChild(centerValue);
689 QDomElement binWidth =
m_domDoc->createElement(
"sp:bin_width");
690 if (width.size() == bands) {
696 bin.appendChild(binWidth);
698 QDomElement originalBinNumber =
m_domDoc->createElement(
"sp:original_bin_number");
699 if (originalBand.size() > 0) {
701 bin.appendChild(originalBinNumber);
704 if (name.size() > 0 || number.size() > 0) {
705 QDomElement filter =
m_domDoc->createElement(
"sp:Filter");
706 bin.appendChild(filter);
707 if (name.size() > 0) {
708 QDomElement filterName =
m_domDoc->createElement(
"sp:filter_name");
710 filter.appendChild(filterName);
712 if (number.size() > 0) {
713 QDomElement filterNumber=
m_domDoc->createElement(
"sp:filter_number");
715 filter.appendChild(filterNumber);
804 QString imageObject =
"";
806 QString translationFile =
"$ISISROOT/appdata/translations/pds4Export";
808 int bands = (int)inputLabel->findObject(
"IsisCube")
810 .findGroup(
"Dimensions")
811 .findKeyword(
"Bands");
813 imageObject =
"Array_3D_Image";
816 imageObject =
"Array_2D_Image";
818 translationFile += QString(imageObject).remove(
'_');
821 imageObject =
"Array_3D_Spectrum";
822 translationFile += QString(imageObject).remove(
'_');
824 translationFile +=
"Uniform";
827 translationFile +=
"BinSet";
830 translationFile +=
".trn";
831 FileName translationFileName(translationFile);
836 QDomElement rootElement =
m_domDoc->documentElement();
837 QDomElement fileAreaObservationalElement =
838 rootElement.firstChildElement(
"File_Area_Observational");
842 double multiplier = 1.0;
843 double outputMin, outputMax;
859 multiplier = (inputMax - inputMin) / (outputMax - outputMin);
860 base = inputMin - multiplier * outputMin;
863 if (!fileAreaObservationalElement.isNull()) {
864 QDomElement arrayImageElement =
865 fileAreaObservationalElement.firstChildElement(imageObject);
866 if (!arrayImageElement.isNull()) {
871 QDomElement axisArrayElement = arrayImageElement.firstChildElement(
"Axis_Array");
872 while( !axisArrayElement.isNull() ) {
873 QDomElement axisNameElement = axisArrayElement.firstChildElement(
"axis_name");
874 axisArrayElement.insertBefore(axisNameElement,
875 axisArrayElement.firstChildElement(
"elements"));
876 axisArrayElement = axisArrayElement.nextSiblingElement(
"Axis_Array");
879 QDomElement elementArrayElement =
m_domDoc->createElement(
"Element_Array");
880 arrayImageElement.insertBefore(elementArrayElement,
881 arrayImageElement.firstChildElement(
"Axis_Array"));
883 QDomElement dataTypeElement =
m_domDoc->createElement(
"data_type");
886 elementArrayElement.appendChild(dataTypeElement);
888 QDomElement scalingFactorElement =
m_domDoc->createElement(
"scaling_factor");
891 elementArrayElement.appendChild(scalingFactorElement);
893 QDomElement offsetElement =
m_domDoc->createElement(
"value_offset");
896 elementArrayElement.appendChild(offsetElement);
900 QDomElement specialConstantElement =
m_domDoc->createElement(
"Special_Constants");
901 arrayImageElement.insertAfter(specialConstantElement,
902 arrayImageElement.lastChildElement(
"Axis_Array"));
906 { QDomElement nullElement =
m_domDoc->createElement(
"missing_constant");
908 specialConstantElement.appendChild(nullElement);
910 QDomElement highInstrumentSatElement =
m_domDoc->createElement(
"high_instrument_saturation");
912 specialConstantElement.appendChild(highInstrumentSatElement);
914 QDomElement highRepresentationSatElement =
m_domDoc->createElement(
"high_representation_saturation");
916 specialConstantElement.appendChild(highRepresentationSatElement);
918 QDomElement lowInstrumentSatElement =
m_domDoc->createElement(
"low_instrument_saturation");
920 specialConstantElement.appendChild(lowInstrumentSatElement);
922 QDomElement lowRepresentationSatElement =
m_domDoc->createElement(
"low_representation_saturation");
924 specialConstantElement.appendChild(lowRepresentationSatElement);
928 { QDomElement nullElement =
m_domDoc->createElement(
"missing_constant");
930 specialConstantElement.appendChild(nullElement);
932 QDomElement highInstrumentSatElement =
m_domDoc->createElement(
"high_instrument_saturation");
934 specialConstantElement.appendChild(highInstrumentSatElement);
936 QDomElement highRepresentationSatElement =
m_domDoc->createElement(
"high_representation_saturation");
938 specialConstantElement.appendChild(highRepresentationSatElement);
940 QDomElement lowInstrumentSatElement =
m_domDoc->createElement(
"low_instrument_saturation");
942 specialConstantElement.appendChild(lowInstrumentSatElement);
944 QDomElement lowRepresentationSatElement =
m_domDoc->createElement(
"low_representation_saturation");
946 specialConstantElement.appendChild(lowRepresentationSatElement);
950 { QDomElement nullElement =
m_domDoc->createElement(
"missing_constant");
952 specialConstantElement.appendChild(nullElement);
954 QDomElement highInstrumentSatElement =
m_domDoc->createElement(
"high_instrument_saturation");
956 specialConstantElement.appendChild(highInstrumentSatElement);
958 QDomElement highRepresentationSatElement =
m_domDoc->createElement(
"high_representation_saturation");
960 specialConstantElement.appendChild(highRepresentationSatElement);
962 QDomElement lowInstrumentSatElement =
m_domDoc->createElement(
"low_instrument_saturation");
964 specialConstantElement.appendChild(lowInstrumentSatElement);
966 QDomElement lowRepresentationSatElement =
m_domDoc->createElement(
"low_representation_saturation");
968 specialConstantElement.appendChild(lowRepresentationSatElement);
972 { QDomElement nullElement =
m_domDoc->createElement(
"missing_constant");
974 specialConstantElement.appendChild(nullElement);
976 QDomElement highInstrumentSatElement =
m_domDoc->createElement(
"high_instrument_saturation");
978 specialConstantElement.appendChild(highInstrumentSatElement);
980 QDomElement highRepresentationSatElement =
m_domDoc->createElement(
"high_representation_saturation");
982 specialConstantElement.appendChild(highRepresentationSatElement);
984 QDomElement lowInstrumentSatElement =
m_domDoc->createElement(
"low_instrument_saturation");
986 specialConstantElement.appendChild(lowInstrumentSatElement);
988 QDomElement lowRepresentationSatElement =
m_domDoc->createElement(
"low_representation_saturation");
990 specialConstantElement.appendChild(lowRepresentationSatElement);
1003 QDomElement descriptionElement =
m_domDoc->createElement(
"description");
1006 arrayImageElement.insertAfter(descriptionElement, arrayImageElement.lastChildElement());
1112 FileName outputFile(outFile);
1115 QString path(outputFile.originalPath());
1116 QString name(outputFile.baseName());
1117 QString labelName = path +
"/" + name +
".xml";
1120 QString imageName = outputFile.expanded();
1124 if (QString::compare(outputFile.extension(),
"xml", Qt::CaseInsensitive) == 0) {
1125 imageName = path +
"/" + name +
".img";
1128 QDomElement rootElement =
m_domDoc->documentElement();
1129 QDomElement fileAreaObservationalElement =
1130 rootElement.firstChildElement(
"File_Area_Observational");
1132 QDomElement fileElement =
m_domDoc->createElement(
"File");
1133 fileAreaObservationalElement.insertBefore(fileElement,
1134 fileAreaObservationalElement.firstChildElement());
1136 QDomElement fileNameElement =
m_domDoc->createElement(
"file_name");
1138 fileElement.appendChild(fileNameElement);
1144 ofstream outputLabel(labelName.toLatin1().data());
1146 outputLabel.close();
1148 ofstream outputImageFile(imageName.toLatin1().data());
1150 outputImageFile.close();
1168 if(inputLabel->hasObject(
"IsisCube") &&
1169 !(inputLabel->findObject(
"IsisCube").hasGroup(
"Mapping")))
return;
1170 PvlGroup &inputMapping = inputLabel->findGroup(
"Mapping", Pvl::Traverse);
1173 "PDS4_CART_1900.xsd",
1175 "http://pds.nasa.gov/pds4/cart/v1");
1179 QString projName = proj->
Name();
1182 "$ISISROOT/appdata/translations/pds4Export" + projName +
".trn");
1185 catch (IException &e) {
1186 QString msg =
"Unable to export projection [" + projName +
"] to PDS4 product. " +
1187 "This projection is not supported in ISIS3.";
1188 throw IException(e, IException::User, msg, _FILEINFO_);
1193 xmlPath <<
"Product_Observational"
1194 <<
"Observation_Area"
1195 <<
"Discipline_Area"
1196 <<
"cart:Cartography"
1197 <<
"cart:Map_Projection"
1198 <<
"cart:Spatial_Reference_Information"
1199 <<
"cart:Horizontal_Coordinate_System_Definition"
1200 <<
"cart:Geodetic_Model";
1202 QDomElement baseElement =
m_domDoc->documentElement();
1203 QDomElement geodeticModelElement =
getElement(xmlPath, baseElement);
1204 QDomElement semiMajorRadElement = geodeticModelElement.firstChildElement(
"cart:semi_major_radius");
1205 if (!semiMajorRadElement.isNull()) {
1207 QString units = semiMajorRadElement.attribute(
"unit");
1208 if( units.compare(
"km", Qt::CaseInsensitive) != 0 && units.compare(
"kilometers", Qt::CaseInsensitive) != 0) {
1211 double dValue = toDouble(semiMajorRadElement.text());
1217 QDomElement semiMinorRadElement = geodeticModelElement.firstChildElement(
"cart:semi_minor_radius");
1218 if (!semiMinorRadElement.isNull()) {
1220 QString units = semiMinorRadElement.attribute(
"unit");
1221 if( units.compare(
"km", Qt::CaseInsensitive) != 0 && units.compare(
"kilometers", Qt::CaseInsensitive) != 0) {
1223 double dValue = toDouble(semiMinorRadElement.text());
1229 QDomElement polarRadElement = geodeticModelElement.firstChildElement(
"cart:polar_radius");
1230 if (!polarRadElement.isNull()) {
1231 QString units = polarRadElement.attribute(
"unit");
1232 if( units.compare(
"km", Qt::CaseInsensitive) != 0 && units.compare(
"kilometers", Qt::CaseInsensitive) != 0) {
1234 double dValue = toDouble(polarRadElement.text());
1240 PvlKeyword &isisLonDir = inputMapping.findKeyword(
"LongitudeDirection");
1241 QString lonDir = isisLonDir[0];
1242 lonDir = lonDir.toUpper();
1245 double maxLon, minLon, maxLat, minLat;
1246 InputCubes[0]->latLonRange(minLat, maxLat, minLon, maxLon);
1249 xmlPath <<
"Product_Observational"
1250 <<
"Observation_Area"
1251 <<
"Discipline_Area"
1252 <<
"cart:Cartography"
1253 <<
"cart:Spatial_Domain"
1254 <<
"cart:Bounding_Coordinates";
1255 QDomElement boundingCoordElement =
getElement(xmlPath, baseElement);
1256 QDomElement eastElement = boundingCoordElement.firstChildElement(
"cart:east_bounding_coordinate");
1257 QDomElement westElement = boundingCoordElement.firstChildElement(
"cart:west_bounding_coordinate");
1258 QDomElement northElement = boundingCoordElement.firstChildElement(
"cart:north_bounding_coordinate");
1259 QDomElement southElement = boundingCoordElement.firstChildElement(
"cart:south_bounding_coordinate");
1263 if(QString::compare(lonDir,
"PositiveEast", Qt::CaseInsensitive) == 0) {
1278 xmlPath <<
"Product_Observational"
1279 <<
"Observation_Area"
1280 <<
"Discipline_Area"
1281 <<
"cart:Cartography"
1282 <<
"cart:Spatial_Reference_Information"
1283 <<
"cart:Horizontal_Coordinate_System_Definition"
1285 <<
"cart:Map_Projection";
1288 QDomElement projectionElement =
getElement(xmlPath, baseElement);
1289 QDomElement tempElement = projectionElement.firstChildElement();
1290 QDomElement nameElement = tempElement.nextSiblingElement();
1292 QDomElement longitudeElement = nameElement.firstChildElement(
"cart:longitude_of_central_meridian");
1293 QDomElement originElement = nameElement.firstChildElement(
"cart:latitude_of_projection_origin");
1295 double longitudeElementValue = longitudeElement.text().toDouble();
1296 double originElementValue = originElement.text().toDouble();
1299 if (!longitudeElement.text().contains(
'.')) {
1300 QString toset1 = QString::number(longitudeElementValue,
'f', 1);
1304 if (!originElement.text().contains(
'.')) {
1305 QString toset2 = QString::number(originElementValue,
'f', 1);
1401 QDomElement identificationElement;
1403 identificationPath.append(
"Product_Observational");
1404 identificationPath.append(
"Identification_Area");
1406 identificationElement =
getElement(identificationPath);
1407 if( identificationElement.isNull() ) {
1408 throw IException(IException::Unknown,
"", _FILEINFO_);
1411 catch(IException &e) {
1412 QString msg =
"Could not find Identification_Area element "
1413 "to add modification history under.";
1414 throw IException(IException::Programmer, msg, _FILEINFO_);
1419 QDomElement historyElement = identificationElement.firstChildElement(
"Modification_History");
1420 if ( historyElement.isNull() ) {
1421 historyElement =
m_domDoc->createElement(
"Modification_History");
1422 identificationElement.insertAfter( historyElement,
1423 identificationElement.lastChildElement() );
1428 QDomElement detailElement =
m_domDoc->createElement(
"Modification_Detail");
1430 QDomElement modDateElement =
m_domDoc->createElement(
"modification_date");
1432 detailElement.appendChild(modDateElement);
1434 QDomElement versionIdElement =
m_domDoc->createElement(
"version_id");
1436 detailElement.appendChild(versionIdElement);
1438 QDomElement descriptionElement =
m_domDoc->createElement(
"description");
1440 detailElement.appendChild(descriptionElement);
1442 historyElement.insertAfter( detailElement,
1443 historyElement.lastChildElement() );