Gravitate Health FHIR Implementation Guide, published by Gravitate Health Project. This guide is not an authorized publication; it is the continuous build for version 0.1.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/hl7-eu/gravitate-health/ and changes regularly. See the Directory of published versions
Draft as of 2024-06-12 |
<Library xmlns="http://hl7.org/fhir">
<id value="pregnancy-lens"/>
<meta>
<profile
value="http://hl7.eu/fhir/ig/gravitate-health/StructureDefinition/lens"/>
</meta>
<text>
<status value="generated"/>
<div xmlns="http://www.w3.org/1999/xhtml"><p class="res-header-id"><b>Generated Narrative: Library pregnancy-lens</b></p><a name="pregnancy-lens"> </a><a name="hcpregnancy-lens"> </a><a name="pregnancy-lens-en-US"> </a><h2>Parameters</h2><table class="grid"><tr><td/><td>in</td><td/><td/><td>CodeableConcept</td><td>parameter if it exists</td></tr></table><h2>Contents</h2><p>Lens for pregnancy: (<code>application/javascript</code>)</p><pre><code>let pvData = pv;
let htmlData = html;
let epiData = epi;
let ipsData = ips;
let getSpecification = () => {
return "1.0.0";
};
let annotationProcess = (listOfCategories, enhanceTag, document, response) => {
listOfCategories.forEach((check) => {
if (response.includes(check)) {
let elements = document.getElementsByClassName(check);
for (let i = 0; i < elements.length; i++) {
elements[i].classList.add(enhanceTag);
}
if (document.getElementsByTagName("head").length > 0) {
document.getElementsByTagName("head")[0].remove();
}
if (document.getElementsByTagName("body").length > 0) {
response = document.getElementsByTagName("body")[0].innerHTML;
console.log("Response: " + response);
} else {
console.log("Response: " + document.documentElement.innerHTML);
response = document.documentElement.innerHTML;
}
}
});
if (response == null || response == "") {
throw new Error(
"Annotation proccess failed: Returned empty or null response"
);
//return htmlData
} else {
console.log("Response: " + response);
return response;
}
}
let annotateHTMLsection = async (listOfCategories, enhanceTag) => {
let response = htmlData;
let document;
if (typeof window === "undefined") {
let jsdom = await import("jsdom");
let { JSDOM } = jsdom;
let dom = new JSDOM(htmlData);
document = dom.window.document;
return annotationProcess(listOfCategories, enhanceTag, document, response);
} else {
document = window.document;
return annotationProcess(listOfCategories, enhanceTag, document, response);
}
};
let getIPSAge = (birthDate) => {
let today = new Date();
let birthDateParsed = new Date(birthDate);
let ageMiliseconds = today - birthDateParsed;
let age = Math.floor(ageMiliseconds / 31536000000);
return age;
}
let enhance = async () => {
// pregnancyCategory breastfeedingCategory
// SNOMED SNOMED
let listOfCategoriesToSearch = ["W78", "77386006", "69840006"]; //"contra-indication-pregancy"]
// Get IPS gender and check if is female
let gender;
let enhanceTag;
if (ips == "" || ips == null) {
throw new Error("Failed to load IPS: the LEE is getting a empty IPS");
}
ips.entry.forEach((element) => {
if (element.resource.resourceType == "Patient") {
gender = element.resource.gender;
if (gender != "female" || getIPSAge(element.resource.birthDate) >= 75) {
enhanceTag = "collapsed";
} else {
enhanceTag = "highlight";
}
}
});
// ePI traslation from terminology codes to their human redable translations in the sections
let compositions = 0;
let categories = [];
epi.entry.forEach((entry) => {
if (entry.resource.resourceType == "Composition") {
compositions++;
//Iterated through the Condition element searching for conditions
entry.resource.extension.forEach((element) => {
// Check if the position of the extension[1] is correct
if (element.extension[1].url == "concept") {
// Search through the different terminologies that may be avaible to check in the condition
if (element.extension[1].valueCodeableReference.concept != undefined) {
element.extension[1].valueCodeableReference.concept.coding.forEach(
(coding) => {
console.log("Extension: " + element.extension[0].valueString + ":" + coding.code)
// Check if the code is in the list of categories to search
if (listOfCategoriesToSearch.includes(coding.code)) {
// Check if the category is already in the list of categories
categories.push(element.extension[0].valueString);
}
}
);
}
}
});
}
});
if (compositions == 0) {
throw new Error('Bad ePI: no category "Composition" found');
}
if (categories.length == 0) {
// throw new Error("No categories found", categories);
return htmlData;
}
//Focus (adds highlight class) the html applying every category found
return await annotateHTMLsection(categories, enhanceTag);
};
return {
enhance: enhance,
getSpecification: getSpecification,
};
</code></pre></div>
</text>
<extension
url="http://hl7.eu/fhir/ig/gravitate-health/StructureDefinition/lee-version">
<valueString value="dev"/>
</extension>
<url value="http://hl7.eu/fhir/ig/gravitate-health/Library/mock-lib"/>
<identifier>
<system value="http://gravitate-health.lst.tfo.upm.es"/>
<value value="pregnancy-lens"/>
</identifier>
<version value="0.1.0"/>
<name value="pregnancy-lens">
<extension url="http://hl7.org/fhir/StructureDefinition/translation">
<extension url="lang">
<valueCode value="es"/>
</extension>
<extension url="content">
<valueString value="Lente para el embarazo"/>
</extension>
</extension>
</name>
<title value="pregnancy-lens">
<extension url="http://hl7.org/fhir/StructureDefinition/translation">
<extension url="lang">
<valueCode value="es"/>
</extension>
<extension url="content">
<valueString value="Lente para el embarazo"/>
</extension>
</extension>
</title>
<status value="draft"/>
<experimental value="true"/>
<type>
<coding>
<code value="logical-library"/>
</coding>
</type>
<date value="2024-06-12T12:23:10.005Z"/>
<publisher value="Gravitate Health Project"/>
<contact>
<name value="Gravitate Health Project"/>
<telecom>
<system value="url"/>
<value value="https://www.gravitatehealth.eu/"/>
</telecom>
</contact>
<contact>
<name value="Gravitate Health Project"/>
<telecom>
<system value="url"/>
<value value="https://www.gravitatehealth.eu/"/>
</telecom>
</contact>
<description
value="Lens that highlight or collapses pregnancy related information">
<extension url="http://hl7.org/fhir/StructureDefinition/translation">
<extension url="lang">
<valueCode value="es"/>
</extension>
<extension url="content">
<valueString
value="Lente que resalta o colapsa la información relacionada con el embarazo"/>
</extension>
</extension>
</description>
<purpose
value="Collapse or highlight pregnancy related information on a preprocessed ePI.">
<extension url="http://hl7.org/fhir/StructureDefinition/translation">
<extension url="lang">
<valueCode value="es"/>
</extension>
<extension url="content">
<valueString
value="Colapsar o resaltar la información relacionada con el embarazo en un ePI preprocesado."/>
</extension>
</extension>
</purpose>
<usage
value="You can import this lens directly to your FHIR Server which suports Library Resource type.">
<extension url="http://hl7.org/fhir/StructureDefinition/translation">
<extension url="lang">
<valueCode value="es"/>
</extension>
<extension url="content">
<valueString
value="Puedes importar esta lente directamente a tu servidor FHIR que soporte el tipo de recurso Library."/>
</extension>
</extension>
</usage>
<copyright value="© 2024 Gravitate Health"/>
<parameter>
<use value="in"/>
<documentation value="parameter if it exists"/>
<type value="CodeableConcept"/>
</parameter>
<content>
<contentType value="application/javascript"/>
<data
value="bGV0IHB2RGF0YSA9IHB2OwpsZXQgaHRtbERhdGEgPSBodG1sOwoKbGV0IGVwaURhdGEgPSBlcGk7CmxldCBpcHNEYXRhID0gaXBzOwoKbGV0IGdldFNwZWNpZmljYXRpb24gPSAoKSA9PiB7CiAgICByZXR1cm4gIjEuMC4wIjsKfTsKCmxldCBhbm5vdGF0aW9uUHJvY2VzcyA9IChsaXN0T2ZDYXRlZ29yaWVzLCBlbmhhbmNlVGFnLCBkb2N1bWVudCwgcmVzcG9uc2UpID0+IHsKICAgIGxpc3RPZkNhdGVnb3JpZXMuZm9yRWFjaCgoY2hlY2spID0+IHsKICAgICAgICBpZiAocmVzcG9uc2UuaW5jbHVkZXMoY2hlY2spKSB7CiAgICAgICAgICAgIGxldCBlbGVtZW50cyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoY2hlY2spOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICBlbGVtZW50c1tpXS5jbGFzc0xpc3QuYWRkKGVuaGFuY2VUYWcpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiaGVhZCIpLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJoZWFkIilbMF0ucmVtb3ZlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJib2R5IikubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYm9keSIpWzBdLmlubmVySFRNTDsKICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCJSZXNwb25zZTogIiArIHJlc3BvbnNlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCJSZXNwb25zZTogIiArIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5pbm5lckhUTUwpOwogICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuaW5uZXJIVE1MOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7CgogICAgaWYgKHJlc3BvbnNlID09IG51bGwgfHwgcmVzcG9uc2UgPT0gIiIpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoCiAgICAgICAgICAgICJBbm5vdGF0aW9uIHByb2NjZXNzIGZhaWxlZDogUmV0dXJuZWQgZW1wdHkgb3IgbnVsbCByZXNwb25zZSIKICAgICAgICApOwogICAgICAgIC8vcmV0dXJuIGh0bWxEYXRhCiAgICB9IGVsc2UgewogICAgICAgIGNvbnNvbGUubG9nKCJSZXNwb25zZTogIiArIHJlc3BvbnNlKTsKICAgICAgICByZXR1cm4gcmVzcG9uc2U7CiAgICB9Cn0KCmxldCBhbm5vdGF0ZUhUTUxzZWN0aW9uID0gYXN5bmMgKGxpc3RPZkNhdGVnb3JpZXMsIGVuaGFuY2VUYWcpID0+IHsKICAgIGxldCByZXNwb25zZSA9IGh0bWxEYXRhOwogICAgbGV0IGRvY3VtZW50OwoKICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAidW5kZWZpbmVkIikgewogICAgICAgIGxldCBqc2RvbSA9IGF3YWl0IGltcG9ydCgianNkb20iKTsKICAgICAgICBsZXQgeyBKU0RPTSB9ID0ganNkb207CiAgICAgICAgbGV0IGRvbSA9IG5ldyBKU0RPTShodG1sRGF0YSk7CiAgICAgICAgZG9jdW1lbnQgPSBkb20ud2luZG93LmRvY3VtZW50OwogICAgICAgIHJldHVybiBhbm5vdGF0aW9uUHJvY2VzcyhsaXN0T2ZDYXRlZ29yaWVzLCBlbmhhbmNlVGFnLCBkb2N1bWVudCwgcmVzcG9uc2UpOwogICAgfSBlbHNlIHsKICAgICAgICBkb2N1bWVudCA9IHdpbmRvdy5kb2N1bWVudDsKICAgICAgICByZXR1cm4gYW5ub3RhdGlvblByb2Nlc3MobGlzdE9mQ2F0ZWdvcmllcywgZW5oYW5jZVRhZywgZG9jdW1lbnQsIHJlc3BvbnNlKTsKICAgIH0KfTsKCmxldCBnZXRJUFNBZ2UgPSAoYmlydGhEYXRlKSA9PiB7CiAgICBsZXQgdG9kYXkgPSBuZXcgRGF0ZSgpOwogICAgbGV0IGJpcnRoRGF0ZVBhcnNlZCA9IG5ldyBEYXRlKGJpcnRoRGF0ZSk7CgogICAgbGV0IGFnZU1pbGlzZWNvbmRzID0gdG9kYXkgLSBiaXJ0aERhdGVQYXJzZWQ7CiAgICBsZXQgYWdlID0gTWF0aC5mbG9vcihhZ2VNaWxpc2Vjb25kcyAvIDMxNTM2MDAwMDAwKTsKCiAgICByZXR1cm4gYWdlOwp9CgpsZXQgZW5oYW5jZSA9IGFzeW5jICgpID0+IHsKICAgIC8vICAgICAgICAgICAgICAgICAgcHJlZ25hbmN5Q2F0ZWdvcnkgICAgYnJlYXN0ZmVlZGluZ0NhdGVnb3J5CiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05PTUVEICAgIFNOT01FRAogICAgbGV0IGxpc3RPZkNhdGVnb3JpZXNUb1NlYXJjaCA9IFsiVzc4IiwgIjc3Mzg2MDA2IiwgIjY5ODQwMDA2Il07IC8vImNvbnRyYS1pbmRpY2F0aW9uLXByZWdhbmN5Il0KCiAgICAvLyBHZXQgSVBTIGdlbmRlciBhbmQgY2hlY2sgaWYgaXMgZmVtYWxlCiAgICBsZXQgZ2VuZGVyOwoKICAgIGxldCBlbmhhbmNlVGFnOwoKICAgIGlmIChpcHMgPT0gIiIgfHwgaXBzID09IG51bGwpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkZhaWxlZCB0byBsb2FkIElQUzogdGhlIExFRSBpcyBnZXR0aW5nIGEgZW1wdHkgSVBTIik7CiAgICB9CiAgICBpcHMuZW50cnkuZm9yRWFjaCgoZWxlbWVudCkgPT4gewogICAgICAgIGlmIChlbGVtZW50LnJlc291cmNlLnJlc291cmNlVHlwZSA9PSAiUGF0aWVudCIpIHsKICAgICAgICAgICAgZ2VuZGVyID0gZWxlbWVudC5yZXNvdXJjZS5nZW5kZXI7CiAgICAgICAgICAgIGlmIChnZW5kZXIgIT0gImZlbWFsZSIgfHwgZ2V0SVBTQWdlKGVsZW1lbnQucmVzb3VyY2UuYmlydGhEYXRlKSA+PSA3NSkgewogICAgICAgICAgICAgICAgZW5oYW5jZVRhZyA9ICJjb2xsYXBzZWQiOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZW5oYW5jZVRhZyA9ICJoaWdobGlnaHQiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7CgogICAgLy8gZVBJIHRyYXNsYXRpb24gZnJvbSB0ZXJtaW5vbG9neSBjb2RlcyB0byB0aGVpciBodW1hbiByZWRhYmxlIHRyYW5zbGF0aW9ucyBpbiB0aGUgc2VjdGlvbnMKICAgIGxldCBjb21wb3NpdGlvbnMgPSAwOwogICAgbGV0IGNhdGVnb3JpZXMgPSBbXTsKICAgIGVwaS5lbnRyeS5mb3JFYWNoKChlbnRyeSkgPT4gewogICAgICAgIGlmIChlbnRyeS5yZXNvdXJjZS5yZXNvdXJjZVR5cGUgPT0gIkNvbXBvc2l0aW9uIikgewogICAgICAgICAgICBjb21wb3NpdGlvbnMrKzsKICAgICAgICAgICAgLy9JdGVyYXRlZCB0aHJvdWdoIHRoZSBDb25kaXRpb24gZWxlbWVudCBzZWFyY2hpbmcgZm9yIGNvbmRpdGlvbnMKICAgICAgICAgICAgZW50cnkucmVzb3VyY2UuZXh0ZW5zaW9uLmZvckVhY2goKGVsZW1lbnQpID0+IHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIHBvc2l0aW9uIG9mIHRoZSBleHRlbnNpb25bMV0gaXMgY29ycmVjdAogICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQuZXh0ZW5zaW9uWzFdLnVybCA9PSAiY29uY2VwdCIpIHsKICAgICAgICAgICAgICAgICAgICAvLyBTZWFyY2ggdGhyb3VnaCB0aGUgZGlmZmVyZW50IHRlcm1pbm9sb2dpZXMgdGhhdCBtYXkgYmUgYXZhaWJsZSB0byBjaGVjayBpbiB0aGUgY29uZGl0aW9uCiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQuZXh0ZW5zaW9uWzFdLnZhbHVlQ29kZWFibGVSZWZlcmVuY2UuY29uY2VwdCAhPSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5leHRlbnNpb25bMV0udmFsdWVDb2RlYWJsZVJlZmVyZW5jZS5jb25jZXB0LmNvZGluZy5mb3JFYWNoKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvZGluZykgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCJFeHRlbnNpb246ICIgKyBlbGVtZW50LmV4dGVuc2lvblswXS52YWx1ZVN0cmluZyArICI6IiArIGNvZGluZy5jb2RlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSBjb2RlIGlzIGluIHRoZSBsaXN0IG9mIGNhdGVnb3JpZXMgdG8gc2VhcmNoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxpc3RPZkNhdGVnb3JpZXNUb1NlYXJjaC5pbmNsdWRlcyhjb2RpbmcuY29kZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGNhdGVnb3J5IGlzIGFscmVhZHkgaW4gdGhlIGxpc3Qgb2YgY2F0ZWdvcmllcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXRlZ29yaWVzLnB1c2goZWxlbWVudC5leHRlbnNpb25bMF0udmFsdWVTdHJpbmcpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0pOwoKICAgIGlmIChjb21wb3NpdGlvbnMgPT0gMCkgewogICAgICAgIHRocm93IG5ldyBFcnJvcignQmFkIGVQSTogbm8gY2F0ZWdvcnkgIkNvbXBvc2l0aW9uIiBmb3VuZCcpOwogICAgfQoKICAgIGlmIChjYXRlZ29yaWVzLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgLy8gdGhyb3cgbmV3IEVycm9yKCJObyBjYXRlZ29yaWVzIGZvdW5kIiwgY2F0ZWdvcmllcyk7CiAgICAgICAgcmV0dXJuIGh0bWxEYXRhOwogICAgfQogICAgLy9Gb2N1cyAoYWRkcyBoaWdobGlnaHQgY2xhc3MpIHRoZSBodG1sIGFwcGx5aW5nIGV2ZXJ5IGNhdGVnb3J5IGZvdW5kCiAgICByZXR1cm4gYXdhaXQgYW5ub3RhdGVIVE1Mc2VjdGlvbihjYXRlZ29yaWVzLCBlbmhhbmNlVGFnKTsKfTsKCnJldHVybiB7CiAgICBlbmhhbmNlOiBlbmhhbmNlLAogICAgZ2V0U3BlY2lmaWNhdGlvbjogZ2V0U3BlY2lmaWNhdGlvbiwKfTsK"/>
<title value="Lens for pregnancy">
<extension url="http://hl7.org/fhir/StructureDefinition/translation">
<extension url="lang">
<valueCode value="es"/>
</extension>
<extension url="content">
<valueString value="Lente para el embarazo"/>
</extension>
</extension>
</title>
</content>
</Library>