Jump to content

Module:Infobox gene/sandbox

From Wikipedia, the free encyclopedia
local p = { }
--To translate visual items of this module, you do not modify this module !!. 
--You must to copy and save the file "en:Module:Infobox gene/sandbox/en" in your wiki, 
--changing the name of the Module (as needed) and the "en" with your language international code

local root

--CHANGED, BEGIN--
--local SD = require "Module:SimpleDebug"
local local_lang = mw.getContentLanguage().code
local LOC = require (mw.getCurrentFrame():getTitle().."/"..local_lang) --the translated module
local CFG = LOC.CFG
local RS = LOC.RS
local MkExtLnk = LOC.MkExtLnk
local LToRWriting = CFG.LeftToRigthWriting
local ColTextAlign_MarginToModi = ''
if LToRWriting then
	ColTextAlign_MarginToModi = 'left'
else
	ColTextAlign_MarginToModi = 'right'
end	
--CHANGED, END

local function title_without_disambig () --CHANGED, NEW, from Global infobox tools
	-- returns the current page name without text between "()"
	local s = mw.title.getCurrentTitle().baseText
	s = mw.ustring.gsub(s,'%s%(.*%)','')
	return s
end	

local function GetParam (args, NameValues)  --CHANGED, NEW
	local value = nil
	for k, v in pairs(NameValues) do
		if args[v] ~= nil then
			value = args[v]
			break
		end	
	end	
	return value
end	--GetParam

local function MkIntLnk (S)   --CHANGED, NEW
	return "[["..S.."]]"
end

local function getInYourLang (ident)  --CHANGED, NEW
	local function lnk ()
		return "https://www.wikidata.org/wiki/" .. ident .. "?uselang="..local_lang
	end	
	local label = mw.wikibase.getLabelByLang(ident, local_lang)
	local addEnd = ''
	local Article = nil
	if label == nil then
		label = mw.wikibase.getLabelByLang(ident,'en')
		if CFG.WDLnk_Transl then
			local Inv = ''
			if not LToRWriting then
				Inv = '-inv'
			end	
			addEnd = ' [[File:OOjs UI icon Wikidata Echo lightcolors en'..Inv..'.svg|17px|text-bottom|'..RS.youCanTranslateIt
			.. "|link="..lnk().."]]"
		end	
	else
		if CFG.ArticleLnk then
			Article = mw.wikibase.getSitelink (ident)
		end	
		if (Article == nil) and CFG.WDLnk_CorrectTransl then
			addEnd = ' [[File:OOjs UI icon Wikidata Echo lightcolors.svg|10px|baseline|'..RS.youCanModifyIt
			.. "|link="..lnk().."]]"
		end
	end
	return label, addEnd, Article
end	--getInYourLang				

local function getInYourLang1 (ident)  --CHANGED, NEW. Used for p.getDisease and p.getDrug
	label, addEnd, Article =  getInYourLang (ident)
	if Article then
		label = MkIntLnk (Article..'|'..label)
	end
	return label..addEnd
end	

-- wrapped "protected call", return "value error" with error info on error
local function check_values(f,args)
	--local u= table.upack(args)
	local exist, val = pcall(f, unpack(args))
	if exist and val ~= nil then
		return(val)
	else
		-- Leaking some debugging info won't hurt....
		return("'''VALUE_ERROR''' (" .. tostring(val) .. ")")
	end
end --check_values

local function trim(s)
   return (s:gsub("^%s*(.-)%s*$", "%1"))
end

function p.GetArgs (frame) --CHANGED, NEW
	local origArgs
	if frame == mw.getCurrentFrame() then
		-- We're being called via #invoke. If the invoking template passed any parameters,
		-- use them. Otherwise, use the parameters that were passed into the template.
		origArgs = frame:getParent().args
		for _, v in pairs( frame.args ) do
			origArgs = frame.args
			break
		end
	else		
		-- We're being called from another module or from the debug console, so assume
		-- the parameters are passed in directly.
		origArgs = frame
	end
	return origArgs
end --GetArgs

--on a page {{#invoke:Sandbox/genewiki/alllua|getTemplateData|QID=Q14865053}}
--in debug window
--frame = mw.getCurrentFrame()
--frame.args = {QID="Q14865053"} Q18031325
--print(p.getTemplateData(frame))
function p.getTemplateData(frame)
	if (local_lang == 'en') or (local_lang == 'simple') then --CHANGED, NEW
		CFG.WDLnk_Transl = false
		CFG.WDLnk_CorrectTransl = false
	end
	--make some guesses about whether the provided QID is a good one
	--could expand here if we had some kind of error handling framework
	--did we get it from the page
	local args = p.GetArgs (frame)
	local root_qid = mw.text.trim(args['QID']  or "") --try to get it from the args
	local mm_qid = ""
	--pull all the entity objects that we will need
	local entity = {} 
	local entity_protein = {}
	local entity_mouse = {}
	local entity_mouse_protein = {}
	local checkOrtholog = "" --flag used to see if mouse data avaliable
	
	local mouse_propertyID = "P684" --actually ortholog property additional orthologs can exist
	local protein_propertyID = "P688" 

	--get root gene entity
	if root_qid == "" then
		entity = mw.wikibase.getEntity()
		if entity then root_qid = entity.id else root_qid = "" end
	else
		--assuming we think its good make one call to retrieve and store its wikidata representation
		entity = mw.wikibase.getEntity(root_qid)
	end
	
  	--need to figure out if it is protein or gene here
	local subclass = p.getValue(entity, "P31") or ""
	if string.find(subclass, RS.proteinL) then --if protein switch entity to gene 
		local claims
		if entity.claims then
			claims = entity.claims["P702"] --encoded bychrLength_mm
		end
		if claims then
			--go through each index and reassign entity
			entity = {}
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
				for k, v in pairs(claims) do --this would be problematic if multiple genes for the protein
					local itemID = "Q" .. claims[#entity + 1].mainsnak.datavalue.value["numeric-id"]
					entity[#entity + 1] = mw.wikibase.getEntity(itemID)
					root_qid = itemID
				end
				
			end --will return nothing if no claims are found
		end
		entity = mw.wikibase.getEntity(root_qid) 	
	end
	
	--get the other related entities
	if entity then
		local claims
		--get protein entity object
		if entity.claims then
			claims = entity.claims[protein_propertyID]
		end
		if claims then
			--go through each index and then make entity_protein indexed
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
				for k, v in pairs(claims) do
					local protein_itemID = "Q" .. claims[#entity_protein + 1].mainsnak.datavalue.value["numeric-id"]
					entity_protein[#entity_protein + 1] = mw.wikibase.getEntity(protein_itemID)
				end
				
			end --will return nothing if no claims are found
		end
	
		--get mouse entity object
		if entity.claims then
			claims = entity.claims[mouse_propertyID]
		end
		local qualifierID = "P703" --found in taxon
		local mouse_qual = "Q83310"
		if claims then
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
				for k, v in pairs(claims) do
					if checkOrtholog == 1 then -- Don't have to go on if we already got it
						break
					end

					local mouse_itemID = "Q" .. v.mainsnak.datavalue.value["numeric-id"]
					local quals
					if v.qualifiers then
						quals = v.qualifiers.P703
					end
					if quals then
						for qk, qv in pairs(quals) do
							--get the taxon qualifier id
							local qual_obj_id = "Q"..qv.datavalue.value["numeric-id"]
							if qual_obj_id == mouse_qual then --check if this is mouse or other
								mm_qid = mouse_itemID
								entity_mouse = mw.wikibase.getEntity(mouse_itemID)
								checkOrtholog = 1
								break
							end
						end
					end
				end
			end --will return nothing if no claims are found
		else
			checkOrtholog = 0
		end

		--get mouse protein entity object
		if entity_mouse and entity_mouse.claims then
			claims = entity_mouse.claims[protein_propertyID]
		end
		if claims then
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
				for k, v in pairs(claims) do
					local protein_itemID = "Q" .. claims[#entity_mouse_protein + 1].mainsnak.datavalue.value["numeric-id"]
					entity_mouse_protein[#entity_mouse_protein + 1] = mw.wikibase.getEntity(protein_itemID)
				end
			end --will return nothing if no claims are found
		end

	end
	
	if entity then --only require the main gene entity
		--a list variables of all the data in the info box
		local name = check_values(p.getLabel,{entity})  
		local bgee_wikidata_id = 'Q54985720'
		local expressed_in_tissues = check_values(p.getValue, {entity, "P5572", CFG.NotApplicableStr, CFG.SeparatorStr, bgee_wikidata_id, CFG.ArticleLnk}) --P5572: expressed in --CHANGED: add CFG.ArticleLnk
		local expressed_in_mouse_tissues = check_values(p.getValue, {entity_mouse, "P5572", CFG.NotApplicableStr, CFG.SeparatorStr, bgee_wikidata_id, false}) --P5572: expressed in --CHANGED: add false
		local entrez_gene = check_values(p.getValue, {entity, "P351", CFG.NotApplicableStr} )
		local entrez_gene_mm = check_values(p.getValue, {entity_mouse, "P351", CFG.NotApplicableStr})
		local image = GetParam (args, RS.imageNames) --CHANGED, image from args
		local caption = nil --CHANGED, NEW
		if image == nil then
			--image = check_values( p.getImage, {entity, "P18", " ", "250px"})   --need to set size  
			image, caption = p.getImage (entity, "P18", " ", "250px", true)   --CHANGED, need to set size  
		else
			image =	"[[File:" .. image .. "|250px]]"
			caption = GetParam (args, RS.captionNames) --CHANGED, NEW
		end	
		local uniprotID_hs = check_values(p.getValueProtein, {entity_protein, "P352", CFG.NotApplicableStr})
		local uniprotID_mm = check_values(p.getValueProtein, {entity_mouse_protein, "P352", CFG.NotApplicableStr})
		local pdbIDs = check_values(p.getPDB, {entity_protein}) --makes a list with links to RCSB
		local aliases = check_values(p.getAliases, {entity})
		local gene_symbol = check_values(p.getValue, {entity, "P353"})
		local hgnc_id = check_values(p.getValue, {entity, "P354"})
		local homologene_id = check_values(p.getValue, {entity, "P593"})
		local omim_id = check_values(p.getValue, {entity, "P492"})
		local mgi_id = check_values(p.getValue, {entity_mouse, "P671"})
		local ChEMBL_id = check_values(p.getValue, {entity_protein, "P592"})
		local IUPHAR_id = check_values(p.getValue, {entity_protein, "P595"})
		local ec_no = check_values(p.getValueProtein, {entity_protein, "P591"})
		local mol_funct = check_values(p.getGO, {entity_protein, "P680"})
		local cell_comp = check_values(p.getGO, {entity_protein, "P681"})
		local bio_process = check_values(p.getGO, {entity_protein, "P682"})
		local expression_images = check_values(p.getImage, {entity,"P692","<br><br>","250px"})
		local ensembl = check_values(p.getValue, {entity, "P594", CFG.NotApplicableStr})
		local ensembl_mm = check_values(p.getValue, {entity_mouse, "P594", CFG.NotApplicableStr})
		local refseq_mRNA = check_values(p.getRefseq_mRNA, {entity, "P639", CFG.NotApplicableStr})
		local refseq_mRNA_mm = check_values(p.getRefseq_mRNA, {entity_mouse, "P639", CFG.NotApplicableStr})
		local refseq_prot = check_values(p.getRefseq_protein, {entity_protein, "P637", CFG.NotApplicableStr})
		local refseq_prot_mm = check_values(p.getRefseq_protein, {entity_mouse_protein, "P637", CFG.NotApplicableStr})
		local gstart = check_values(p.getChromosomeLoc, {entity, "P644", "hg"})
		local gend = check_values(p.getChromosomeLoc, {entity, "P645", "hg"})
		local chr = p.trimChromosome (entity)
		local cytoband = check_values(p.getValue, {entity, "P4196", CFG.NotApplicableStr})
		local db = check_values(p.getAliasFromGenomeAssembly, {entity,"hg"})
		local gstart_mm = check_values(p.getChromosomeLoc, {entity_mouse, "P644", "mm"})
		local gend_mm = check_values(p.getChromosomeLoc, {entity_mouse, "P645", "mm"})
		local chr_mm = p.trimChromosome (entity_mouse)
		local db_mm = check_values(p.getAliasFromGenomeAssembly, {entity_mouse,"mm"})
		local cytoband_mm = check_values(p.getValue, {entity_mouse, "P4196", CFG.NotApplicableStr})
		local disease, dis_ref = p.getDisease(entity, "P2293")
		local drug, drug_ref, drug_pqid, drug_pname = p.getDrug(entity_protein, "P129")
		--local drug = check_values(p.getDrug, {entity_protein, "P129"})

		p.createTable()
		p.renderUpperTitle(name)
		--p.renderCaption()
		p.renderImage(image, caption) --CHANGED, Added caption
		p.renderAvailableStructures(uniprotID_hs, uniprotID_mm, checkOrtholog, pdbIDs) --PDB info
		p.renderIdentifiers(aliases, hgnc_id, gene_symbol, homologene_id, omim_id, mgi_id, ChEMBL_id, IUPHAR_id, ec_no, entrez_gene, ensembl)
		
		--uncomment here to add a section of the infobox about genetically related diseases, with references
		if (CFG.ShowDiseases and disease ~= "" and dis_ref ~= "") then --removes section from those items without disease info
			p.renderDiseases(frame, disease, dis_ref, name, root_qid)
		end

		--uncomment here to add a section of the infobox about drugs that target the protein product of this gene, with references
		if (CFG.ShowDrugs and drug ~= "" ) then --removes section from those items without drug info
			p.renderDrug(frame,drug, drug_ref, drug_pqid, drug_pname)
		end

		if (chr ~= "" and gstart ~= "" and gend ~= "") or (chr_mm ~= "" and gstart_mm ~= "" and gend_mm ~= "") then
			p.renderGeneLocation(frame, chr, gstart, gend, db, cytoband, ensembl, chr_mm, gstart_mm, gend_mm, db_mm, cytoband_mm, ensembl_mm, name)
		end
		if expression_images ~= "" or expressed_in_tissues ~= CFG.NotApplicableStr then
			p.renderRNAexpression(expression_images, entrez_gene, ensembl, expressed_in_tissues, ensembl_mm, expressed_in_mouse_tissues)
		end
		if (mol_funct ~= "" and cell_comp ~= "" and bio_process ~= "") then
			p.renderGeneOntology(mol_funct, cell_comp, bio_process, uniprotID_hs)
		end
		p.renderOrthologs(frame, entrez_gene, entrez_gene_mm, ensembl, ensembl_mm, uniprotID_hs, uniprotID_mm, refseq_mRNA, refseq_mRNA_mm, refseq_prot, refseq_prot_mm, db, chr, gstart, gend, db_mm, chr_mm, gstart_mm, gend_mm)
		p.renderFooter(root_qid, mm_qid)		
		
		return tostring(root)
		--return table.concat(drug_pqid)
		
	else 
		return "An Error has occurred retrieving Wikidata item for infobox"
	end	
end

function p.createTable(subbox)

	if subbox == 'sub' then --doesn't work 
		 root
			:tag('table') 
			:css('padding', '0')
			:css('border', 'none')
			:css('margin', '0')
			:css('width', 'auto')
			:css('min-width', '100%')
			:css('font-size', '100%')
			:css('clear', 'none')
			:css('float', 'none')
			:css('background-color', 'transparent')
		   
	else
		root = mw.html.create('table')
		root
			:addClass('infobox')
			:css('font-size', CFG.InfoboxFontSize) --NEW
			:css('width',  CFG.InfoboxWidth) --NEW
	end

end

--Title above image
function p.renderUpperTitle(name)
	local title = name
	if not title then return "error: failed to get label"; end
	if CFG.TitleIcon ~= '' and CFG.TitleIcon ~= nil then
		title = '<span style="float:left; margin-left: 3px;">[[File:'..CFG.TitleIcon..'|8px|Infotaula de gen|link=]]</span>'
		..' '..title --CHANGED, NEW
	end	
	root
		:tag('tr')
			:tag('th')
				:attr('colspan', 4)
				:css('text-align', 'center')
				:css('font-size', '125%')
				:css('font-weight', 'bold')
				:css('background-color', CFG.topTitleBGcolor) --CHANGED, NEW
				:wikitext(title)
				:done() --end th
			:done() --end tr
end

--This is a place holder for the image caption, which is stored in wikicommons comments unsure how to access 
function p.renderCaption(entity)
	--caption
end

--gets default image
--function p.renderImage(image)
function p.renderImage(image, caption) --CHANGED, New
	if caption ~= nil then
		image = image.."<br />"..caption
	end	
	root
		:tag('tr')
			:tag('td')
				:attr('colspan', 4)
				:css('text-align', 'center')
				:wikitext(image)
				:done() --end td
			:done() --end tr
end

function p.renderAvailableStructures(uniprotID_hs, uniprotID_mm, checkOrtholog, pdbIDs)

	local title = RS.AvailableStructures
	local pdb_link = MkIntLnk (RS.PDB_lnk)
	local searchTitle = "" 
	local listTitle = RS.PDBListTitle
	local PDBe_base = 'https://www.ebi.ac.uk/pdbe/searchResults.html?display=both&amp;term='
	local RCSB_base = 'https://www.rcsb.org/search?q='
					..'rcsb_polymer_entity_container_identifiers.reference_sequence_identifiers.database_name:UniProt%20AND%20'
					..'rcsb_polymer_entity_container_identifiers.reference_sequence_identifiers.database_accession:'
	local url_uniprot = " " 
	
	if checkOrtholog == 1 and uniprotID_mm ~= 'n/a' then
		searchTitle = RS.checkOrtholog
		url_uniprot = uniprotID_mm..','..uniprotID_hs
	else
		searchTitle = RS.checkOrthologH
		url_uniprot = uniprotID_hs
	end
	searchTitle = searchTitle ..': ' --CHANGED, New
	local PDBe_list = " " --create a list with " or " if there is more than one uniprot
	--get LinkList_first uniprot in a list
	if url_uniprot:match("([^,]+),") then--LinkList_first check if there is a list if not just assume one value
		PDBe_list = string.gsub(url_uniprot, ",", "%%20or%%20") --add or's inststead of commas
	else
		PDBe_list = url_uniprot
	end
	
	local PDBe = "["..PDBe_base..PDBe_list.." PDBe] "
	local RCSB = "["..RCSB_base..url_uniprot.." RCSB] "
	
	if string.match(pdbIDs, '%w+') then --if there aren't any PDB_ID don't display this part of the infobox
		--p.formatRow(title)---how to not close the tags is a mystery and I could condense code once I figure out
		root
			:tag('tr')
				:tag('td')
					:attr('colspan', 4)
					:css('text-align', 'center')
					:css('background-color', CFG.rowBGcolor)
					:tag('table')
						:css('padding', '0')
						:css('border', 'none')
						:css('margin', '0')
						:css('width', '100%')
						:css('text-align', ColTextAlign_MarginToModi) --CHANGED, for the different directions in writing
						:tag('tr')	--create title header
							:tag('th')
								:attr('colspan', '4')
								:css('text-align', 'center')
								:css('background-color', CFG.titleBGcolor)
								:wikitext(title)
								:done() --end th
							:done() --end tr

						:tag('tr')
							:tag('th')
								:attr('rowspan', '2')
								:css('background-color', CFG.sideTitleBGcolor)
								:css('width', CFG.PDB_bar_width) --CHANGED
								:wikitext(pdb_link)
								:done() --end th
							:tag('td')
								:attr('colspan', '2')
								:css('background-color', CFG.rowBGcolor)
								:wikitext(searchTitle)
								:tag('span')
									:attr('class', 'plainlinks')
									:wikitext(PDBe)
									:wikitext(RCSB)
									:done() --end span
								:done() --end td
							:done() --end tr

						:tag('tr') --new row for collapsible list of PDB codes
							:tag('td')
								:tag('table')
									:attr('class', 'collapsible collapsed')
									:css('padding', '0')
									:css('border', 'none')
									:css('margin', '0')
									:css('width', '100%')
									:css('text-align', ColTextAlign_MarginToModi) --CHANGED, for the different directions in writing
									:tag('tr')
										:css('background-color', CFG.titleBGcolor)
										:css('text-align', 'center')
										:tag('th')
											:attr('colspan', '2')
											:wikitext(listTitle)
											:done() --end th
										:done() --end tr
									:tag('tr')
										:tag('td')
											:attr('colspan', '2')
											:css('background-color', CFG.rowBGcolor)
											:tag('p')
												:tag('span')
													:attr('class', 'plainlinks')
													:wikitext(pdbIDs)
													:done() --end span
												:done() --end p
											:done() --end td
										:done() --end tr
									:done() --end table
								:done() --end td
							:done() --end tr
						:done() --end table
					:done() --end td
				:done() --end tr
	else
		return ""
	end
end

function p.renderIdentifiers(aliases, hgnc_id, gene_symbol, homologene_id, omim_id, mgi_id, ChEMBL_id, IUPHAR_id, ec_no, entrez_gene, ensembl)
	local title = RS.IdentifiersU
	local label_aliases = MkIntLnk (RS.aliases_lnk)
	local symbol_url
	if gene_symbol == "" or gene_symbol == nil  then
		symbol_url = ""
	else
		if hgnc_id == "" or hgnc_id == nil  then
			symbol_url = gene_symbol

		else
			symbol_url = "[https://www.genenames.org/data/gene-symbol-report/#!/hgnc_id/"..hgnc_id.." "..gene_symbol.."]"
			.." ("..MkIntLnk(RS.HUGO_lnk)..")" --CHANGED, New
		end
	end
 	-- *lclz*: see getAliases. You can, say, use another punctuation for your language.
 	if (gene_symbol ~= "") and (gene_symbol ~= nil) then  --CHANGED with checking gene_symbol
		aliases = string.gsub(aliases, ', '..gene_symbol..'$', '') --get rid of gene name if last in alias list
		aliases = string.gsub(aliases, gene_symbol..', ', '') --get rid of gene name if LinkList_first in aliases list
		aliases = string.gsub(aliases, ', '..gene_symbol..',', ',') --get rid of gene name if in aliases list
	end	
	aliases = string.gsub(aliases, ", ,", ",") --remove comma from middle
	aliases = string.gsub(aliases, ", $", "") --remove comma from end
	local label_ext_id = RS.ext_id
	omim_id = string.gsub(omim_id, "%s", "")
	local omim_list = mw.text.split(omim_id, CFG.SeparatorStr)
	local omim = ""
	if (omim_id ~= nil and omim_id ~= "") then
		omim = MkIntLnk (RS.OMIM_lnk)..": "
	end
	for i, v in ipairs(omim_list) do
		if string.match(v, '%w+') then
			omim = omim.."[https://omim.org/entry/"..v.." "..v.."], "
		end
	end
	omim = string.gsub(omim, ", $"," ")	--remove comma from end
	homologene_id = string.gsub(homologene_id, "%s", "")
	local homolo_list = mw.text.split(homologene_id, CFG.SeparatorStr)
	local homolo =""
	if (homologene_id ~= nil and homologene_id ~= "") then
		homolo = MkIntLnk (RS.Homolo_lnk)..": "
	end
	for i, v in ipairs(homolo_list) do
		if string.match(v, '%w+') then
			homolo = homolo.."[https://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=homologene&dopt=HomoloGene&list_uids="..v.." "..v.."] "
		end
	end
	homolo = string.gsub(homolo, ", $"," ")  --remove comma from end
	local genecards = MkIntLnk (RS.GeneCards_lnk)..": "
	genecards = genecards.."[https://www.genecards.org/cgi-bin/carddisp.pl?gene="..gene_symbol.." "..gene_symbol.."] "
	mgi_id = string.gsub(mgi_id, "%s", "")
	local mgi_list = mw.text.split(mgi_id, CFG.SeparatorStr)
	local mgi = "" 
	if (mgi_id ~= nil and mgi_id ~= "") then
		mgi = MkIntLnk (RS.MGI_lnk)..": "
	end
	for i, v in ipairs(mgi_list) do
		if string.match(v, '%w+') then
			local mgi_number = string.sub(mgi_id, 5)
			mgi = mgi.."[http://www.informatics.jax.org/marker/"..mgi_id.." "..mgi_number.."] "
		end
	end
	mgi = string.gsub(mgi, ", $"," ")--remove comma from end
	local ChEMBL = ""
	if string.match(ChEMBL_id, '%w+') then
		ChEMBL = MkIntLnk (RS.ChEMBL_lnk)..": ".."[https://www.ebi.ac.uk/chembldb/index.php/target/inspect/CHEMBL"..ChEMBL_id.." "..ChEMBL_id.."] "
	end
	local IUPHAR = ""
	if string.match(IUPHAR_id, '%w+') then 
		IUPHAR = MkIntLnk (RS.IUPHAR_lnk)..": ".."[http://www.guidetopharmacology.org/GRAC/ObjectDisplayForward?objectId="..IUPHAR_id.." "..IUPHAR_id.."] "
	end
	local label_EC = MkIntLnk (RS.EC_lnk)
	ec_no = string.gsub(ec_no, "%d%.%d+%.%d+%.%-,", "")--remove those with"-" in list
	ec_no = string.gsub(ec_no, "%d%.%d+%.%d+%.%-", "")--remove those with"-" not in list
	local link_ec_no = string.gsub(ec_no, "," ,"+") --create format for link
	local EC = "[https://www.genome.jp/dbget-bin/www_bget?enzyme+" .. link_ec_no .. " " .. ec_no .. "]"
	local oma = MkIntLnk (RS.OMA_lnk)..": "
	oma = oma.."[https://omabrowser.org/oma/vps/"..mw.text.split(ensembl,",")[1].." "..gene_symbol.." - orthologs]"
	external_id_table = {omim, mgi, homolo, ChEMBL, IUPHAR, genecards, oma}
	external_id_processed_table = {}
	for i, v in ipairs(external_id_table) do
		if (v ~= "") then 
			external_id_processed_table[#external_id_processed_table + 1] = v 
		end
	end
	external_ids = tostring(table.concat(external_id_processed_table, "&nbsp; "))
	root
		:tag('tr')
			:tag('th')
				:attr('colspan', 4)
				:css('text-align', 'center')
				:css('background-color', CFG.titleBGcolor)
				:wikitext(title)
				:done() --end th
			:done() --end tr
		:tag('tr')
			:tag('th')
				:attr('scope', 'row')
				:css('background-color', CFG.sideTitleBGcolor)
				:css('width', CFG.id_bar_width)  --CHANGED, New
				:css('text-align', ColTextAlign_MarginToModi) --CHANGED, New for the different directions in writing
				:tag('span')
					:attr('class', 'plainlinks')
					:wikitext(label_aliases)
					:done() --end span
				:done() --end th

				:tag('td')
					:attr('colspan','3')
					:css('background', CFG.rowBGcolor)
					:tag('span')
						:attr('class', 'plainlinks')
						:wikitext(symbol_url)
						:done() --end span
					:wikitext(mw.text.nowiki(aliases)) -- escape raw text so it cannot be wikitext markup
					:done() --end td
				:done() --end tr
			:done() --end tr

		:tag('tr')
			:tag('th')
				:attr('scope', 'row')
				:css('background-color', CFG.sideTitleBGcolor)
				:css('width', CFG.id_bar_width)  --CHANGED, New
				:css('text-align', ColTextAlign_MarginToModi) --CHANGED, New for the different directions in writing
				:wikitext(label_ext_id)
				:done() --end th
			:tag('td')
				:attr('colspan', '3')
				:css('background-color', CFG.rowBGcolor)
				:tag('span')
					:attr('class', 'plainlinks')
					:wikitext(external_ids)
					:done() --end span
				:done() --end td
			:done() --end tr

	if ec_no ~= "" then
		root
			:tag('tr')
				:tag('th')
					:attr('scope', 'row')
					:css('background-color', CFG.sideTitleBGcolor)
					:wikitext(label_EC)
					:done() --end th
				:tag('td')
					:attr('colspan', '3')
					:css('background-color', CFG.rowBGcolor)
					:tag('span')
						:attr('class', 'plainlinks')
						:wikitext(EC)
						:done() --end span
					:done() --end td
				:done() --end tr
	end
end

function p.renderDiseases(frame, disease, dis_ref, name, qid)
	local title = RS.RelDiseases 
	--check LinkList_first to see if any of the diseases have references
	local ref_flag_all = false --check if any disease have references if not then don't render the headers
	local disease_name = '' --local disease_name = table.concat(disease, ", ")
	for index,value in ipairs(disease) do
		if (dis_ref[index] ~= nil and dis_ref[index] ~= '') then
			if disease_name == '' then
				disease_name = value
			else
				disease_name = disease_name..CFG.SeparatorStr.." "..value --CHANGED
			end
			ref_flag_all = true
		end		
	end
	if ref_flag_all then
		root
			:tag('tr')
				:tag('td')
					:attr('colspan', 4)
					:css('text-align', 'center')
					:css('background-color', CFG.rowBGcolor)
					:tag('tr') --create title bar
						:tag('th')
							:attr('colspan', '3')
							:css('text-align', 'center')
							:css('background-color', CFG.titleBGcolor)
							:wikitext(title)
							:done() --end th
						:done() --end tr
					:done() --end td
				:done() --end tr
				
		local ref_url = "https://www.wikidata.org/wiki/"..qid.."#P2293" --direct page to property genetically associated disease
		local title = RS.AssocDiseases..name..RS.SeeEditWDRef
		local ref_link = disease_name..' '..frame:extensionTag("ref", MkExtLnk (frame, title, ref_url)) --CHANGED

		root
			:tag('tr')
				:attr('colspan', 4)
				:css('text-align', 'center')
				:css('background-color', CFG.rowBGcolor)
				:tag('td')
					:css('background-color', CFG.rowBGcolor)
					:attr('scope', 'row')
					:attr('colspan', '3')
					:wikitext(ref_link)
					:done() --end td
				:done() --end tr
	end
end

function p.renderDrug(frame,drug, drug_ref, drug_pqid, drug_pname)
	local title = RS.TargDrug

	--check LinkList_first to see if any of the drugs have references
	local ref_flag_all = false --check if any drugs have references if not then don't render the headers
	local drug_list_per_protein = {} -- a list of lists of drugs to put in reference string each protein will have a list 
	--for i,v in ipairs(drug_pqid) do -- set all lists keys to empty so can append without key errors 
		
	--end
	for index,value in ipairs(drug) do
		if (drug_ref[index] ~= nil and drug_ref[index] ~= '') then
			local protein_qid = drug_pqid[index]
			if drug_list_per_protein[protein_qid] == '' or drug_list_per_protein[protein_qid] == nil then
				drug_list_per_protein[protein_qid] = value
			else
				drug_list_per_protein[protein_qid] = drug_list_per_protein[protein_qid]..CFG.SeparatorStr.." "..value --CHANGED, each list of drugs keyed on protein qid 
			end
			ref_flag_all = true
		end		
	end

	if ref_flag_all then
		root
			:tag('tr')
				:tag('td')
					:attr('colspan', 4)
					:css('text-align', 'center')
					:css('background-color', CFG.rowBGcolor)
					:tag('tr') --create title bar
						:tag('th')
							:attr('colspan', '3')
							:css('text-align', 'center')
							:css('background-color', CFG.titleBGcolor)
							:wikitext(title)
							:done() --end th
						:done() --end tr
					:done() --end td
				:done() --end tr

		--loop to create reference links from drug lists
		for k,v in pairs(drug_list_per_protein) do
			local drug_name = v
			local ref_url =   "https://www.wikidata.org/wiki/"..k.."#P129" --direct page to property genetically associated disease
			local title = RS.InterDrug..drug_pname[k]..RS.SeeEditWDRef
			local ref_link = drug_name..' '..frame:extensionTag("ref", MkExtLnk (frame, title, ref_url)) --CHANGED
				
			root
				:tag('tr')
					:attr('colspan', 4)
					:css('text-align', 'center')
					:css('background-color', CFG.rowBGcolor)
					:tag('td')
						:css('background-color', CFG.rowBGcolor)
						:attr('scope', 'row')
						:attr('colspan', '3')
						:wikitext(ref_link)
						:done() --end td
				:done() --end tr
		end
	end
	
end

function p.renderGeneLocation(frame, chr, gstart, gend, db, cytoband, ensembl, chr_mm, gstart_mm, gend_mm, db_mm, cytoband_mm, ensembl_mm, name)

local function MkChrLabels (chr, specie, isHuman)  --CHANGED, NEW
	local val, val2
	if chr == "MT" then
		val = string.format (RS.ChromosomeMit, specie)
		val2 = val
	elseif (chr == 'X') or (chr == 'Y') then
		local chr_lab
		if chr == 'X' then
			chr_lab = RS.XForChromosome
		else
			chr_lab = RS.YForChromosome
		end	
		val = string.format (RS.ChromosomeAutoSex_abbr, chr_lab, specie)
		val2 = string.format (RS.ChromosomeSex_lnk, chr_lab, specie)
		if isHuman then
			val = val2..'|'..val
		end	
	else	
		val = string.format (RS.ChromosomeAutoSex_abbr, chr, specie)
		val2 = string.format (RS.ChromosomeAuto_lnk, chr, specie)
		if isHuman then
			val = val2..'|'..val
		end	
	end	
	return val, val2
end	--MkChrLabels

local function rootItems (specie_lnk, ideogramChromo, LabelLnkChromo, wikitext_for_ideogram, cytob, 
  pair_start, link_start, pair_end, link_end)  --CHANGED, NEW
	root
		:tag('tr')
			:tag('td')
				:attr('colspan', 4)
				:css('text-align', 'center')
				:css('background-color', CFG.rowBGcolor)
				:tag('table')
					:attr('class', 'collapsible collapsed')
					:css('padding', '0')
					:css('border', 'none')
					:css('margin', '0')
					:css('width', '100%')
					:css('text-align', ColTextAlign_MarginToModi) --CHANGED, for the different directions in writing
					:tag('tr')
						:tag('th')
							:attr('colspan', '4')
							:css('text-align', 'center')
							:css('background-color', CFG.titleBGcolor)
							:wikitext(RS.GL_GeneLoc..' ('..MkIntLnk(specie_lnk)..')')
							:done() --end th
						:done() --end tr
					:tag('tr')
						:tag('td')
							:attr('colspan', '4')
							:css('text-align', 'center')
							:css('background-color', CFG.rowBGcolor)
							:wikitext(ideogramChromo)
							:done() --end td
						:done() --end tr
					:tag('tr')
						:tag('td')
							:attr('colspan', '4')
							:css('background-color', CFG.titleBGcolor)
							:done() --end td
						:done() --end tr
					:tag('tr')
						:tag('td') --CHANGED, BEGIN
							:attr('colspan', '4')
							:css('text-align', 'center')
							:wikitext(LabelLnkChromo)
							:done() --end td --CHANGED, END
						:done() --end tr
					:tag('tr')
						:tag('td')
							:attr('colspan', '4')
							:css('text-align', 'center')
							:css('background-color', CFG.rowBGcolor)
							:wikitext(wikitext_for_ideogram)
							:done() --end td
						:done() --end tr
					:tag('tr')
						:tag('th')
							:attr('scope', 'row')
							:attr('rowspan', '2')
							:css('width', CFG.label_locus_width) --CHANGED
							:css('background-color', CFG.sideTitleBGcolor)
							:css('text-align', ColTextAlign_MarginToModi) --CHANGED, New for the different directions in writing
							:wikitext(MkIntLnk (RS.GL_locus_lnk))
							:done() --end th
						:tag('td')
							:attr('rowspan', '2')
							:css('background-color', CFG.rowBGcolor)
							:css('width', CFG.cytoband_width) --CHANGED
							:tag('span')
								:attr('class', 'plainlinks')
								:wikitext(cytob)
								:done() --end span
							:done() --end td
						:tag('th')
							:attr('scope', 'row')
							:css('background-color', CFG.sideTitleBGcolor)
							:css('text-align', ColTextAlign_MarginToModi) --CHANGED, New for the different directions in writing
							:css('width', CFG.label_StartEnd_width) --CHANGED, NEW!!!!
							:wikitext(RS.GL_gstart)
							:done() --end th
						:tag('td')
							:css('background-color', CFG.rowBGcolor)
							:tag('span')
								:attr('class', 'plainlinks')
								:wikitext(p.FormatNaturalNumber(pair_start).." "
									..MkIntLnk(RS.BasePair_only_lnk..'|'..RS.BasePair)..link_start)
								:done() --end span
							:done() --end td
						:done() --end tr
					:tag('tr')
						:tag('th')
							:attr('scope', 'row')
							:css('background-color', CFG.sideTitleBGcolor)
							:css('text-align', ColTextAlign_MarginToModi) --CHANGED, New for the different directions in writing
							:css('width', CFG.label_StartEnd_width) --CHANGED, NEW!!!!
							:wikitext(RS.GL_gend)
							:done() --end th
						:tag('td')
							:css('background-color', CFG.rowBGcolor)
							:tag('span')
								:attr('class', 'plainlinks')
								:wikitext(p.FormatNaturalNumber(pair_end).." "
									..RS.BasePair..link_end)
								:done() --end span
							:done() --end td
						:done() --end tr
					:done() --end table
				:done() --end td
			:done() --end tr
end	--rootItems

local function MkWikitextForChrIdeoImg (Filename, chr, chrText2, 
  gend, gstart, chrLength)  --CHANGED, NEW
  
	--about the calculation below, see https://en.wikipedia.org/wiki/User:Was_a_bee/Gene#3._Calculation_detail
	local arrowSign_width = 14
	local markerWidth = ((gend - gstart) * 294.133 )/ chrLength
	if markerWidth < 2 then
		markerWidth = 2
	else
		markerWidth = math.ceil(markerWidth)
	end
	local markerLocation = (147.0666 * (gstart + gend) / chrLength ) + 1.6 - (markerWidth / 2)
	local arrowSignLocation = markerLocation + (markerWidth / 2) - (arrowSign_width / 2)
	markerLocation = math.floor( markerLocation * 10 + 0.5 ) / 10

	local tooltip_arrowSign = RS.GL_tooltip..name
	local wtfii --wikitext used for showing gene location
	if chr == "MT" then -- wikitext for mitochondrial DNA
		--wtfii = 
		--"<div align=\"center\">"
		--.."<div style=\"position: relative; width: 300px;\">"
		--.."[[File:Map of the human mitochondrial genome.svg|300px|"..chrText.."]]"
		--.."</div>"
		--.."</div>"

	else -- wikitext for autosome and sex chromosome
		wtfii = 
			"<div align=\"center\">"
			.."<div style=\"position: relative; width: 300px;\">"
			.."[[File:"..string.format (Filename, chr)..".svg|300px|"..chrText2.."]]"
			.."<div style=\"position: absolute; left: "..arrowSignLocation.."px; top: 2px; padding: 0;\">"
			.."[[File:HSR 1996 II 3.5e.svg|"..arrowSign_width.."px|"..tooltip_arrowSign.."]]"
			.."</div>"
			.."<div style=\"position: absolute; left: "..markerLocation.."px; top: 19px; padding: 0;\">"
			.."[[File:Red rectangle "..markerWidth.."x18.png|"..markerWidth.."px|"..tooltip_arrowSign.."]]"
			.."</div>"
			.."</div>"
			.."</div>"
	end
	return wtfii
end --MkWikitextForChrIdeoImg
		
	local label_chr = MkIntLnk (RS.GL_chr_lnk)

	if chr ~= "" and chr ~= nil and gstart ~= "" and gend ~= "" then
		--Chromosome lengths are from GRCh38.p10 https://www.ncbi.nlm.nih.gov/grc/human/data?asm=GRCh38.p10
		--This table is used only for calculating "Where should red-rectangle put?"
		--Curretly, Aug 2017, it seems all gene data, which are stored in Wikidata, have start/end positions based on GRCh38.
		local chrLengthTable = {
			["1"] = 248956422,
			["2"] = 242193529,
			["3"] = 198295559,
			["4"] = 190214555,
			["5"] = 181538259,
			["6"] = 170805979,
			["7"] = 159345973,
			["8"] = 145138636,
			["9"] = 138394717,
			["10"] = 133797422,
			["11"] = 135086622,
			["12"] = 133275309,
			["13"] = 114364328,
			["14"] = 107043718,
			["15"] = 101991189,
			["16"] = 90338345,
			["17"] = 83257441,
			["18"] = 80373285,
			["19"] = 58617616,
			["20"] = 64444167,
			["21"] = 46709983,
			["22"] = 50818468,
			["X"] = 156040895,
			["Y"] = 57227415,
			["MT"] = 16569}
		local chrLength = chrLengthTable[chr]

		--Different languages have different word order.
		local chrText, chrText2 = MkChrLabels (chr, RS.HumanL, true)  --CHANGED, NEW

		local source_link_chr, source_link_gstart, source_link_gend
		if( db == "hg38" ) then
			source_link_chr = frame:extensionTag("ref", "[http://May2017.archive.ensembl.org/Homo_sapiens/Gene/Summary?db=core;g="..ensembl.." GRCh38: Ensembl release 89: "..ensembl.."] - "..MkIntLnk(RS.Ensembl_lnk)..", May 2017", {name = "refGRCh38Ensembl"})
			source_link_gstart = frame:extensionTag("ref", "", {name = "refGRCh38Ensembl"})
			source_link_gend = frame:extensionTag("ref", "", {name = "refGRCh38Ensembl"})
		elseif( db == "hg37") then
			source_link_chr = frame:extensionTag("ref", "[http://grch37.ensembl.org/Homo_sapiens/Gene/Summary?db=core;&g="..ensembl.." GRCh37: Ensembl release 89: "..ensembl.."] - "..MkIntLnk(RS.Ensembl_lnk)..", May 2017", {name = "refGRCh37Ensembl"})
			source_link_gstart = frame:extensionTag("ref", "", {name = "refGRCh37Ensembl"})
			source_link_gend = frame:extensionTag("ref", "", {name = "refGRCh37Ensembl"})
		else
			source_link_chr = ""
			source_link_gstart = ""
			source_link_gend = ""
		end

		local wikitext_for_ideogram_image = 
			MkWikitextForChrIdeoImg ("Human chromosome %s ideogram", chr, chrText2, 
				gend, gstart, chrLength)

		rootItems (
			RS.GL_Human_lnk,
			"[[File:Ideogram human chromosome "..chr..".svg|300px|"..string.format (RS.HumanChromosomeIdeogr,chr).."]]",
			"'''"..label_chr..": '''[["..chrText.."]]"..source_link_chr,
			wikitext_for_ideogram_image,
			cytoband,
			gstart, source_link_gstart,
			gend, source_link_gend)
	end

	if chr_mm ~= "" and gstart_mm ~= "" and gend_mm ~= "" then
		--Chromosome lengths are from GRCm38.p5 https://www.ncbi.nlm.nih.gov/grc/mouse/data?asm=GRCm38.p5
		local chrLengthTable_mm = {
			["1"] = 195471971,
			["2"] = 182113224,
			["3"] = 160039680,
			["4"] = 156508116,
			["5"] = 151834684,
			["6"] = 149736546,
			["7"] = 145441459,
			["8"] = 129401213,
			["9"] = 124595110,
			["10"] = 130694993,
			["11"] = 122082543,
			["12"] = 120129022,
			["13"] = 120421639,
			["14"] = 124902244,
			["15"] = 104043685,
			["16"] = 98207768,
			["17"] = 94987271,
			["18"] = 90702639,
			["19"] = 61431566,
			["X"] = 171031299,
			["Y"] = 91744698,
			["MT"] = 16299}
		local chrLength_mm = chrLengthTable_mm[chr_mm]

		--Different languages have different word order.
		local chrText_mm, chrText_mm2 = MkChrLabels (chr_mm, RS.MouseL, false)  --CHANGED, NEW

		local source_link_chr_mm = ""
		local source_link_gstart_mm = ""
		local source_link_gend_mm = ""
		if( db_mm == "mm10" or db_mm == "mm0") then
			--"mm0" happens because of function "getAliasFromGenomeAssembly()" is not prepared for mouse data.
			--But as of now, Aug. 2017, it seems that all data which is stored in Wikidata are based on GRCm38/mm10.
			--So treating mouse genomic data as GRCm38/mm10 if not specified.
			source_link_chr_mm = frame:extensionTag("ref", "[http://May2017.archive.ensembl.org/Mus_musculus/Gene/Summary?db=core;g="..ensembl_mm.." GRCm38: Ensembl release 89: "..ensembl_mm.."] &ndash; "..MkIntLnk(RS.Ensembl_lnk)..", May 2017", {name = "refGRCm38Ensembl"})
			source_link_gstart_mm = frame:extensionTag("ref", "", {name = "refGRCm38Ensembl"})
			source_link_gend_mm = frame:extensionTag("ref", "", {name = "refGRCm38Ensembl"})
		else
			source_link_chr_mm = ""
			source_link_gstart_mm = ""
			source_link_gend_mm = ""
		end
		
		local wikitext_for_ideogram_image_mm = 
			MkWikitextForChrIdeoImg ("Ideogram of house mouse chromosome %s", chr_mm, chrText_mm2, 
				gend_mm, gstart_mm, chrLength_mm)
	
		rootItems (
			RS.GL_Mouse_lnk,
			"[[File:Ideogram house mouse chromosome "..chr_mm..".svg|260px|"..string.format (RS.MouseChromosomeIdeogr,chr_mm).."]]",
			"'''"..label_chr..": '''"..chrText_mm..source_link_chr_mm,
			wikitext_for_ideogram_image_mm,
			cytoband_mm,
			gstart_mm, source_link_gstart_mm,
			gend_mm, source_link_gend_mm)	
	end
end

--Get the render elements collapse option, collapsed anatomic entities (defaut text),
--and anatomic entity list for the gene expression list rendering.
function p.renderExpressionList(expressed_in_tissues, default_text)
	--create list of expressed in anatomic entities
	if default_text == nil then default_text = "" end
	local anatomic_entity_labels = CFG.NotApplicableStr
	local collapse = "none"
	local split_values = mw.text.split(expressed_in_tissues, CFG.SeparatorStr)
	local anatomic_entity_list = {}
	local anatomic_entities = {}
	local results
	for k,v in ipairs(split_values) do
		if string.match(v, '%w+') and v ~= CFG.NotApplicableStr then
			anatomic_entity_list[#anatomic_entity_list+1] = "<li style='line-height: 137%;'>"..v.."</li>"
			anatomic_entities[#anatomic_entities+1] = v
		end
	end
	--if less than 11 don't create collapsible list
	if table.getn(anatomic_entity_list) < 11 then
		if table.getn(anatomic_entity_list) == 0 then
			anatomic_entity_labels = CFG.NotApplicableStr
			default_text = ""
		end
	else
		collapse = "collapsible collapsed"
		default_text = default_text .. '<br>' .. table.remove(anatomic_entities, 1) .. '<br>' .. table.remove(anatomic_entities, 1) .. '<br>' ..table.remove(anatomic_entities, 1) .. '<br>' .. table.remove(anatomic_entities, 1) .. '<br>' .. table.remove(anatomic_entities, 1) .. '<br>'--get LinkList_first 5 elements in table and use for display
	end
	if anatomic_entity_list[#anatomic_entity_list] then
		anatomic_entity_labels = table.concat(anatomic_entity_list, "<br>")
	end
	results = {collapse, default_text, anatomic_entity_labels}
	return results
end

function p.renderRNAexpression(expression_images, entrez_gene,
		ensembl, bgee_expression, ensembl_mouse, bgee_expression_mouse)
	local bgee_gene_page = "https://bgee.org/gene/"
	local title = RS.RNAexpres
	local biogps_link = ""
	local biogps_title = RS.BioGPS
	biogps_title = "[http://biogps.org/ " .. biogps_title .. "]"
	-- If no expression image exist in BioGPS, the N/A is displayed
	if expression_images ~= "" then
		biogps_link = "[http://biogps.org/gene/"..entrez_gene.."/ "..RS.RNAexpres_more_exprdata.."]"
	else
		expression_images = CFG.NotApplicableStr
	end
	local bgee_title = RS.Bgee
	bgee_title = "[https://bgee.org/ " .. bgee_title .. "]"
	
	local function EnsemblBgee (ensembl0, bgee_expression0)  --CHANGED, New
		local ensembl_id = string.match(ensembl0,"%a+%d+") or ""
		local bgee_default = "["..bgee_gene_page..ensembl_id.." "..RS.RNAexpres_more_expl.."]"
		bgee_expression0 = p.renderExpressionList(bgee_expression0, bgee_default)
		local bgee_collapse = bgee_expression0[1]
		bgee_default = bgee_expression0[2]
		local bgee_tissues = bgee_expression0[3]
		return ensembl_id, bgee_default, bgee_collapse, bgee_tissues
	end
	
	local ensembl_id, bgee_default, bgee_collapse, bgee_tissues = EnsemblBgee (ensembl, bgee_expression) --CHANGED, New
	local ensembl_id_mouse, bgee_default_mm, bgee_collapse_mm, bgee_tissues_mm = EnsemblBgee (ensembl_mouse, bgee_expression_mouse) --CHANGED, New
	
	local bgee_more_link = ""
	if bgee_tissues ~= CFG.NotApplicableStr then
		bgee_more_link = "["..bgee_gene_page..ensembl_id.." "..RS.RNAexpres_more_exprdata.."]"
	end

	root
		:tag('tr')
			:tag('td')
				:attr('colspan', 4)
				:css('text-align', 'center')
				:css('background-color', CFG.rowBGcolor)
				:tag('table')
					:attr('class', 'collapsible collapsed')
					:css('padding', '0')
					:css('border', 'none')
					:css('margin', '0')
					:css('width', '100%')
					:css('text-align', 'left')
					:tag('tr')
						:tag('th')
							:attr('colspan', '4')
							:css('text-align', 'center')
							:css('background-color', CFG.titleBGcolor)
							:wikitext(title)
							:done() --end th
						:done() --end tr
					:tag('tr')
						:tag('th')
							:attr('scope', 'row')
							:css('background-color', CFG.sideTitleBGcolor)
							:css('text-align', ColTextAlign_MarginToModi) --CHANGED, for the different directions in writing
							:css('width', CFG.BgeeBioGPS_width)
							:wikitext(bgee_title)
							:done() --end th
						:tag('td')
							:tag('table')
								:attr('class', 'none')
								:css('padding', '0')
								:css('border', 'none')
								:css('margin', '0')
								:css('width', '100%')
								:css('text-align', ColTextAlign_MarginToModi) --CHANGED, for the different directions in writing
								:tag('tr')
									:tag('th')
										:wikitext("'''"..MkIntLnk(RS.GL_Human_lnk).."'''")
										:done() --end th
									:tag('th')
										:wikitext("'''"..MkIntLnk(RS.GL_Mouse_lnk).."''' "..RS.GL_ortholog) 
										:done() --end th
									:done() --end tr
								:tag('tr')
									:tag('td')
										:tag('table')
											:attr('class', bgee_collapse)
											:css('padding', '0')
											:css('border', 'none')
											:css('margin', '0')
											:css('width', '100%')
											:css('text-align', ColTextAlign_MarginToModi) --CHANGED, for the different directions in writing
											:tag('tr')	
												:tag('td')
													:attr('colspan', '1')
													:tag('span')
														:attr('class', 'plainlinks')
														:css('margin', '-3px')
														:wikitext(bgee_default)
														:done() --end span
													:done() --end td
												:done() --end tr
											:tag('tr')
												:tag('td')
													:attr('colspan', '1')
													:tag('div')
														:css('margin', '-12px 0px -10px 0px')
														:attr('class', 'plainlinks')
														:tag('ul')
															:css('line-height', '15%')
															:css('margin', '9px')
															:wikitext(bgee_tissues)
															:done() --end ul
														:done() --end div
													:done() --end td
												:done() --end tr
											:done() --end table
										:done() --end td
									:tag('td')
										:tag('table')
											:attr('class', bgee_collapse_mm)
											:css('padding', '0')
											:css('border', 'none')
											:css('margin', '0')
											:css('width', '100%')
											:css('text-align', ColTextAlign_MarginToModi) --CHANGED, for the different directions in writing
											:tag('tr')	
												:tag('td')
													:attr('colspan', '1')
													:tag('span')
														:attr('class', 'plainlinks')
														:css('margin', '-3px')
														:wikitext(bgee_default_mm)
														:done() --end span
													:done() --end td
												:done() --end tr
											:tag('tr')
												:tag('td')
													:attr('colspan', '1')
													:tag('div')
														:css('margin', '-12px 0px -10px 0px')
														:attr('class', 'plainlinks')
														:tag('ul')
															:css('line-height', '15%')
															:css('margin', '9px')
															:wikitext(bgee_tissues_mm)
															:done() --end ul
														:done() --end div
													:done() --end td
												:done() --end tr
											:done() --end table
										:done() --end td
									:done() --end tr
								:tag('tr')
									:tag('td')
										:attr('colspan', '4')
										:css('text-align', 'center')
										:css('background-color', CFG.rowBGcolor)
										:tag('span')
											:attr('class', 'plainlinks')
											:wikitext(bgee_more_link)
											:done() --end span
										:done() --end td
									:done() --end tr
								:done() --end table
							:done() --end td
						:done() --end tr
					:tag('tr')
						:tag('th')
							:attr('scope', 'row')
							:css('background-color', CFG.sideTitleBGcolor)
							:css('text-align', ColTextAlign_MarginToModi) --CHANGED, for the different directions in writing
							:css('width', CFG.BgeeBioGPS_width)
							:wikitext(biogps_title)
							:done() --end th
						:tag('td')
							:tag('table')
								:attr('class', bgee_collapse)
								:css('padding', '0')
								:css('border', 'none')
								:css('margin', '0')
								:css('width', '100%')
								:css('text-align', ColTextAlign_MarginToModi) --CHANGED, for the different directions in writing
								:tag('tr')
									:tag('td')
										:attr('colspan', '4')
										:css('text-align', 'center')
										:css('background-color', CFG.rowBGcolor)
										:wikitext(expression_images)
										:done() --end td
									:done() --end tr
								:tag('tr')
									:tag('td')
										:attr('colspan', '4')
										:css('text-align', 'center')
										:css('background-color', CFG.rowBGcolor)
										:tag('span')
											:attr('class', 'plainlinks')
											:wikitext(biogps_link)
											:done() --end span
										:done() --end td
									:done() --end tr
								:done() --end table
							:done() --end td
						:done() --end tr
					:done() --end table
				:done() --end td
			:done() --end tr
end


function p.renderGeneOntology(mol_funct, cell_comp, bio_process, uniprotID)
	local title = MkIntLnk (RS.GO_title_lnk)
	--local mol_funct_title = RS.GO_mol_funct
	--local cell_comp_title = RS.GO_cell_comp
	--local bio_process_title = RS.GO_bio_process
	local amigo_link = "[http://amigo.geneontology.org/" .. " Amigo]"
	local quickGO_link = "[https://www.ebi.ac.uk/QuickGO/" .. " QuickGO]"
	local tab1 --CHANGED, NEW
	local function GOMkRow (title, items) --NEW
		tab1
			:tag('tr')
				:tag('td')
					:css('width', CFG.GO_bar_width) --CHANGED. New
					:css('background-color', CFG.sideTitleBGcolor)
					:css('font-weight', 'bold')
					:wikitext(title)
					:done() --end td
				:tag('td')
					:css('background-color', CFG.rowBGcolor)
					:tag('div')
						:attr('class', 'plainlinks')
						:css('margin-'..ColTextAlign_MarginToModi, '-0.5em')
						:wikitext(items)
						:wikitext( '\n' ) -- newline before ending div tag, to ensure next section formats properly
						:done() --end div
					:done() --end td
				:done() --end tr
		return tab1
	end	--GOMkRow

	local tr1 = root:tag('tr') --CHANGED
		local td1 = tr1:tag('td') --CHANGED
		td1 --CHANGED
			:attr('colspan', 4)
			:css('text-align', 'center')
			:css('background-color', CFG.rowBGcolor)
			tab1 = td1:tag('table') --CHANGED
			tab1 --CHANGED
				:attr('class', 'collapsible collapsed')
				:css('padding', '0')
				:css('border', 'none')
				:css('margin', '0')
				:css('width', '100%')
				:css('text-align', ColTextAlign_MarginToModi) --CHANGED, for the different directions in writing
				:tag('tr') --create title bar
					:tag('th')
						:attr('colspan', '4')
						:css('text-align', 'center')
						:css('background-color', CFG.titleBGcolor)
						:wikitext(title)
						:done() --end th
					:done() --end tr
				--BEGIN NEW	
				GOMkRow (RS.GO_mol_funct, mol_funct)
				GOMkRow (RS.GO_cell_comp, cell_comp)
				GOMkRow (RS.GO_bio_process, bio_process)
				--END NEW
				:tag('tr')
					:tag('td')
						:css('background-color', CFG.rowBGcolor)
						:css('text-align', 'center') --CHANGED
						:attr('colspan', '4')
						:wikitext(RS.SourcesTP..': '..amigo_link.." / "..quickGO_link)
						:done() --end td
					:done() --end tr
				:done() --end table
			:done() --end td
		:done() --end tr
end

function p.renderOrthologs(frame, entrez_gene, entrez_gene_mm, ensembl, ensembl_mm, uniprot, uniprot_mm, refseq_mRNA, refseq_mRNA_mm, refseq_prot, refseq_prot_mm, db, chr, gstart, gend, db_mm, chr_mm,gstart_mm, gend_mm)
	local title = MkIntLnk (RS.Orth_Orthologs_lnk)
	--to do make the list creation a function
	
	local category_chromosome
	if (chr == 'X') or (chr == 'Y') then
		category_chromosome = MkIntLnk (RS.Orth_Categ..string.format (RS.Orth_C_Sex, chr))
	elseif chr == "MT" then
		category_chromosome = MkIntLnk (RS.Orth_Categ..RS.Orth_C_Mit) --Category name for mtDNA genes
	elseif chr ~= "" then	
		category_chromosome = MkIntLnk (RS.Orth_Categ..string.format (RS.Orth_C_Num, chr)) --Category name
	elseif chr == "" then
		category_chromosome = MkIntLnk (RS.Orth_Categ..RS.Orth_HumanGens)  -- Per [[Wikipedia:Categories for discussion/Log/2023 August 15]]
	end
	if mw.title.getCurrentTitle().namespace ~= 0 then
		category_chromosome = ""
	end
	
	local function ArrangeCollap (link_list, collapse, default, link, num)  --CHANGED New
		--if less than num don't create collapsible list
		if CFG.OrthologsCollapsed or (table.getn(link_list) < num) then --CHANGED, added OrthologsCollapsed
			collapse = "none"
			if default == nil and table.getn(link_list) == 0 then link = CFG.NotApplicableStr end
		else	
			collapse = "collapsible collapsed"
			default = table.remove(link_list, 1) .. '<br>' .. table.remove(link_list, 1) .. '<br>' ..table.remove(link_list, 1) .. '<br>' .. table.remove(link_list, 1) .. '<br>' .. table.remove(link_list, 1) .. '<br>'--get LinkList_first 5 elements in table and use for display
		end
		if link_list[#link_list] then
			link = table.concat(link_list, "<br>")
		end
		return collapse, default, link
	end
	
	
	local function Entrez0 (VV, isHuman)	
		VV = string.gsub(VV, "%s", "")
		local link = CFG.NotApplicableStr
		local collapse 
		local default = ""
		local Split = mw.text.split(VV, CFG.SeparatorStr)
		local LinkList = {}
		for k,v in ipairs(Split) do 
			if string.match(v, '%w+') and v ~= CFG.NotApplicableStr then
				local p
				if isHuman then
					p = VV
				else
					p = v
				end
				LinkList[#LinkList+1] = "[https://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=gene&amp;cmd=retrieve&amp;dopt=default&amp;list_uids="..p.."&amp;rn=1 "..p.."]"
			end
		end
		return ArrangeCollap (LinkList, collapse, default, link, 5)
	end	--Entrez0
	
	--create lists of Entrez
	local entrezTitle = MkIntLnk (RS.Orth_Entrez_lnk)
	local entrez_collapse, entrez_default, entrez_link = 
		Entrez0 (entrez_gene, true)
	local entrez_mm_collapse, entrez_mm_default, entrez_mm_link =
		Entrez0 (entrez_gene_mm, false)

	
	local function Ensemble0 (VV, genderName)
		VV = string.gsub(VV, "%s", "")
		local link = CFG.NotApplicableStr
		local collapse
		local default = ""
		local Split = mw.text.split(VV, CFG.SeparatorStr)
		local LinkList = {}
		for k,v in ipairs(Split) do
			if string.match(v, '%w+') and v ~= CFG.NotApplicableStr then
				LinkList[#LinkList+1] = "[http://www.ensembl.org/"..genderName.."/geneview?gene="..v..";db=core".." "..v.."]"
			end
		end
		return ArrangeCollap (LinkList, collapse, default, link, 5)
	end --Ensemble0

	--create lists of Ensembl
	local ensemblTitle = MkIntLnk (RS.Orth_Ensembl_lnk)
	ensembl_collapse, ensembl_default, ensembl_link = 
		Ensemble0 (ensembl, "Homo_sapiens")
	ensembl_mm_collapse, ensembl_mm_default, ensembl_mm_link =	
		Ensemble0 (ensembl_mm, "Mus_musculus")


	local function UniProt0 (VV)
		local uniprot_url = "https://www.uniprot.org/uniprot/"
		local link = CFG.NotApplicableStr
		local collapse
		local default = ""
		--split string and loop through concatenate by <br>
		local Split = mw.text.split(VV, '%p') -- the separator may be different sometimes, see note on zhwiki. This is unlikely to have punctuation, prayer.
		local LinkList = {}
		local LinkList_first = {} --preferred values only display [O,P,Q] prefixed entries if they exist
		local LinkList_alternate = {} --[A-N,R-Z] entries
		local hash = {} --storage to look for duplicated values 
		for k,v in ipairs(Split) do 
			if not hash[v] then --only add if not found previously..some encodes UniProtID dup in different encodes
				local label = mw.text.trim(v)
				local concat_link = uniprot_url .. label
				if string.match(v, '%w+') and v ~= CFG.NotApplicableStr then
					if string.match(v, '^O') or string.match(v,'^P') or string.match(v, '^Q') then
						LinkList_first[#LinkList_first+1] = "[" .. concat_link .. " " ..label .. "]"
					else
						LinkList_alternate[#LinkList_alternate+1] = "[" .. concat_link .. " " ..label .. "]"
					end
				end
				hash[v] = true
			end
		end
		if table.getn(LinkList_first)>0 then --if there is something in the preferred values display else display anything else
			LinkList  = LinkList_first
		else
			LinkList  = LinkList_alternate
		end
		return ArrangeCollap (LinkList, collapse, default, link, 6)
	end --UniProt0
	
	--create lists of links of UniProt
	local uniprotTitle = MkIntLnk (RS.Orth_UniProt_lnk)
	local uniprot_collapse, uniprot_default, uniprot_link =
		UniProt0 (uniprot) 
	local uniprot_mm_collapse, uniprot_mm_default, uniprot_mm_link = 
		UniProt0 (uniprot_mm) 

	
	local function RefSeq0 (VV)
		local ncbi_link = "https://www.ncbi.nlm.nih.gov/entrez/viewer.fcgi?val="
		local link = CFG.NotApplicableStr
		local collapse 
		local default = ""
		local Split = mw.text.split(VV, CFG.SeparatorStr)
		local LinkList = {} --if NM,NP display if not display XM, XP values
		local LinkList_LinkList_first = {} --hold those the have NM or NP values
		local LinkList_alternate = {} --hold those that are XM or XP values
		for k,v in ipairs(Split) do
			local label = mw.text.trim(v)
			local concat_ncbi_link = ncbi_link .. label
			if string.match(v, '%w+') and v ~= CFG.NotApplicableStr then
				if string.match(v, 'NM') or string.match(v, 'NP') then
					LinkList_LinkList_first[#LinkList_LinkList_first+1] = "[" .. concat_ncbi_link .. " " ..label .. "]"
				elseif string.match(v, 'XM') or string.match(v, 'XP') then
					LinkList_alternate[#LinkList_alternate+1] = "[" .. concat_ncbi_link .. " " ..label .. "]"
				end
			end
		end
		if table.getn(LinkList_LinkList_first)>0 then
			LinkList  = LinkList_LinkList_first
		else
			LinkList  = LinkList_alternate
		end
		return ArrangeCollap (LinkList, collapse, default, link, 6)
	end --RefSeq0

	--create lists of links for RefSeq mRNA
	local refseq_mRNATitle = MkIntLnk (RS.Orth_RefSeq_lnk).." "..RS.refseq_RNAm
	local refseq_mRNA_collapse, refseq_mRNA_default, refseq_mRNA_link = 
		RefSeq0 (refseq_mRNA)
	local refseq_mRNA_mm_collapse, refseq_mRNA_mm_default, refseq_mRNA_mm_link = 
		RefSeq0 (refseq_mRNA_mm)
	
	--create lists of links for RefSeq protein
	local refseq_protTitle = RS.Orth_RefSeq.." "..RS.refseq_protein
	local refseq_prot_collapse, refseq_prot_default, refseq_prot_link =
		RefSeq0 (refseq_prot) 
	local refseq_prot_mm_collapse, refseq_prot_mm_default, refseq_prot_mm_link = 
		RefSeq0 (refseq_prot_mm) 


	local function UCSC0 (GStart, GEnd, Db, Chr, specie)
		local gstart_mb = p.locToMb(GStart, 2)
		local gend_mb = p.locToMb(GEnd, 2)
		local link = ""
		if (string.match(Db, '%w+') and string.match(Chr, '%w+') and string.match(GStart, '%w+') and string.match(GEnd, '%w+') )then
			local chr_ucsc
			if Chr == "MT" then
				chr_ucsc = "M" --UCSC uses "M" (not "MT") in URL for mitochondrial DNA
			else
				chr_ucsc = Chr
			end
			link = "[https://genome.ucsc.edu/cgi-bin/hgTracks?org="..specie.."&Db="..Db.."&position=Chr"..chr_ucsc..":"..GStart.."-"..GEnd.." ".."Chr "..chr_ucsc..": "..gstart_mb.." – "..gend_mb.." Mb]"
		else
			link = CFG.NotApplicableStr
		end
		return link
	end --UCSC0
	
	local locTitle = string.format (RS.Orth_UCSC, MkIntLnk(RS.Orth_UCSC_lnk))
	local chr_loc_link = UCSC0 (gstart, gend, db, chr, 'Human')
	local chr_loc_mm_link = UCSC0 (gstart_mm, gend_mm, db_mm, chr_mm, 'Mouse')
	

	local function PubMed (VV, specie)
		local link = "" --CHANGED: Added
		if string.match(VV, '%w+') and VV ~= CFG.NotApplicableStr then
			link = frame:extensionTag("ref", MkExtLnk (frame, specie.." PubMed Reference:" , --CHANGED
				"https://www.ncbi.nlm.nih.gov/sites/entrez?db=gene&cmd=Link&LinkName=gene_pubmed&from_uid="..VV, 
				"National Center for Biotechnology Information, U.S. National Library of Medicine") )--expandTemplate creates cite web template {{cite web|title=value|url=ref_link..ect}}
		end
		return link
	end --PubMed
	
	local pubmedTitle = string.format (RS.PubMed_Search, MkIntLnk(RS.PubMed_lnk))
	local pubmed_link = PubMed (entrez_gene, "Human")
	local pubmed_mm_link = PubMed (entrez_gene_mm, "Mouse")
	

	local OrthologsClass = 'collapsible'
	if CFG.OrthologsCollapsed then  --CHANGED, NEW
		OrthologsClass = 'collapsible collapsed'  
	end	
	
	local tab1 --CHANGED, NEW for OMkRow and OM2kRow
	-- For Entrez, Ensembl, UniProt and RefSeq (RNAm and protein):
	local function OMkRow (title, collapse_h, default_h, link_h, collapse_mm, default_mm, link_mm) --NEW
		tab1
			:tag('tr')
				:tag('th')
					:attr('scope', 'row')
					:css('background-color', CFG.sideTitleBGcolor)
					:css('text-align', ColTextAlign_MarginToModi) --CHANGED, New for the different directions in writing
					:wikitext(title)
					:done() --end th
				:tag('td')
					:tag('table')
						:attr('class', collapse_h)
						:css('padding', '0')
						:css('border', 'none')
						:css('margin', '0')
						:css('width', '100%')
						:css('text-align', ColTextAlign_MarginToModi) --CHANGED, for the different directions in writing
						:tag('tr')
							:tag('th')
								:attr('colspan', '1')
								:tag('span')
									:attr('class', 'plainlinks')
									:wikitext(default_h)
									:done() --end span
								:done() --end th
							:done() --end tr
						:tag('tr')
							:tag('td')
								:attr('colspan', '1')
								:tag('p')
									:attr('class', 'plainlinks')
									:wikitext(link_h)
									:done() --end p
								:done() --end td
							:done() --end tr
						:done() --end table
					:done() --end td
				:tag('td')
					:tag('table')
						:attr('class', collapse_mm)
						:css('padding', '0')
						:css('border', 'none')
						:css('margin', '0')
						:css('width', '100%')
						:css('text-align', ColTextAlign_MarginToModi) --CHANGED, for the different directions in writing
						:tag('tr')
							:tag('th')
								:attr('colspan', '1')
								:tag('span')
									:attr('class', 'plainlinks')
									:wikitext(default_mm)
									:done() --end span
								:done() --end th
							:done() --end tr
						:tag('tr')
							:tag('td')
								:attr('colspan', '1')
								:tag('p')
									:attr('class', 'plainlinks')
									:wikitext(link_mm)
									:done() --end p
								:done() --end td
							:done() --end tr
						:done() --end table
					:done() --end td
				:done() --end tr
		return tab1
	end	--OMkRow
	
	-- For Location and PubMed:
	local function OM2kRow (title, link_h, link_mm, AtEnd) --CHANGED, NEW
		tab1
			:tag('tr')
				:tag('th')
					:attr('scope', 'row')
					:css('background-color', CFG.sideTitleBGcolor)
					:css('text-align', ColTextAlign_MarginToModi) --CHANGED, New for the different directions in writing
					:wikitext(title)
					:done() --end th
				:tag('td')
					:tag('span')
						:attr('class', 'plainlinks')
						:wikitext(link_h)
						:done() --end span
					:done() --end td
				:tag('td')
					:tag('span')
						:attr('class', 'plainlinks')
						:wikitext(link_mm)
						:done() --end span
					:wikitext(AtEnd)
					:done() --end td
				:done() --end tr
		return tab1
	end
	local tr1 = root:tag('tr') --CHANGED
		local td1 = tr1:tag('td') --CHANGED
		td1 --CHANGED
			:attr('colspan', 4)
			:css('text-align', 'center')
			:css('background-color', CFG.rowBGcolor)
			tab1 = td1:tag('table') --CHANGED
			tab1 --CHANGED
				:attr('class', OrthologsClass)  --CHANGED, NEW
				:css('padding', '0')
				:css('border', 'none')
				:css('margin', '0')
				:css('width', '100%')
				:css('text-align', ColTextAlign_MarginToModi) --CHANGED, for the different directions in writing
				:tag('tr')
					:tag('th')
						:attr('colspan', '4')
						:css('text-align', 'center')
						:css('background-color', CFG.titleBGcolor)
						:wikitext(title)
						:done() --end th
					:done() --end tr
				:tag('tr')
					:tag('th')
						:attr('scope', 'row')
						:css('background-color', CFG.sideTitleBGcolor)
						:css('text-align', ColTextAlign_MarginToModi) --CHANGED, New for the different directions in writing
						:wikitext(RS.SpeciesU)
						:done() --end th
					:tag('td')
						:wikitext("'''"..RS.HumanU.."'''")
						:done() --end td
					:tag('td')
						:wikitext("'''"..RS.MouseU.."'''")
						:done() --end td
					:done() --end tr
				--BEGIN NEW	
				OMkRow (entrezTitle, entrez_collapse, entrez_default, entrez_link,
					entrez_mm_collapse, entrez_mm_default, entrez_mm_link)
				OMkRow (ensemblTitle, ensembl_collapse, ensembl_default, ensembl_link,
					ensembl_mm_collapse, ensembl_mm_default, ensembl_mm_link)
				OMkRow (uniprotTitle, uniprot_collapse, uniprot_default, uniprot_link,
					uniprot_mm_collapse, uniprot_mm_default, uniprot_mm_link)
				OMkRow (refseq_mRNATitle, refseq_mRNA_collapse, refseq_mRNA_default, refseq_mRNA_link,
					refseq_mRNA_mm_collapse, refseq_mRNA_mm_default, refseq_mRNA_mm_link)
				OMkRow (refseq_protTitle, refseq_prot_collapse, refseq_prot_default, refseq_prot_link,
					refseq_prot_mm_collapse, refseq_prot_mm_default, refseq_prot_mm_link)
				OM2kRow (locTitle, chr_loc_link, chr_loc_mm_link, '')
				OM2kRow (pubmedTitle, pubmed_link, pubmed_mm_link, category_chromosome)
				--END NEW
				:done() --end table
			:done() --end td
		:done() --end tr
end

function p.formatRow(title)
	root
		:tag('tr')
			:tag('td')
				:attr('colspan', '4')
				:css('text-align', 'center')
				:css('background-color', CFG.rowBGcolor)
				:tag('table')
					:css('padding', '0')
					:css('border', 'none')
					:css('margin', '0')
					:css('width', '100%')
					:css('text-align', ColTextAlign_MarginToModi) --CHANGED, for the different directions in writing
					:tag('tr')	--create title header
						:css('background-color', CFG.titleBGcolor)
						:css('text-align', 'center')
						:tag('th')
							:attr('colspan',"2")
							:wikitext(title)
							:done() --end th
						:done() --end tr
					:done() --end table
				:done() --end td
			:done() --end tr
end

function p.renderFooter(Qid, Qid_mm)
	local text = MkIntLnk (RS.Wikidata_lnk) 
	local hs_link = MkIntLnk ("d:"..Qid.."|"..RS.SeeEditHuman)
	local mm_link = ""
	local link_no_hs
	local link_no_mm
 
	if Qid_mm == "" then
	 	link_no_mm = 0
	 	link_no_hs = 4
	else 
	 	link_no_mm = 2
	 	link_no_hs = 2
	 	mm_link = MkIntLnk ("d:"..Qid_mm.."|"..RS.SeeEditMouse)
	end
 
 	root
		:tag('tr')
			:tag('td')
				:attr('colspan', '4')
				:css('text-align', 'center')
				:css('background-color', CFG.rowBGcolor)
				:wikitext(text)
				:done() --end td
		:tag('tr')
			:tag('td')
				:attr('colspan', '4')
				:css('text-align', 'center')
				:css('background-color', CFG.rowBGcolor)
			:tag('table')
				:css('padding', '0')
				:css('border', 'none')
				:css('margin', '0')
				:css('width', '100%')
				:css('text-align', 'center')
				:tag('tr')
					:tag('td')
						:attr('colspan', link_no_hs)
						:css('background-color', CFG.rowBGcolor)
						:css('text-align', 'center')
						:wikitext(hs_link)
						:done() --end td
					:tag('td')
						:attr('colspan', link_no_mm)
						:css('background-color', CFG.rowBGcolor)
						:css('text-align', 'center')
						:wikitext(mm_link)
						:done() --end td
					:done() --end tr
				:done() --end table
			:done() --end tr
	root:done() --end root table
end

-- look into entity object
function p.getLabel(entity)
	local data = entity

	local f = {'labels', local_lang, 'value'} --CHANGED: use of local_lang

	local i = 1
	while true do
		local index = f[i]
		if not index then
			if type(data) == "table" then
				return mw.text.jsonEncode(data, mw.text.JSON_PRESERVE_KEYS + mw.text.JSON_PRETTY)
			else
				return tostring(data)
			end
		end
		
		data = data[index] or data[tonumber(index)]
		if not data then
			return
		end
		
		i = i + 1
	end
end

-- Get property values formatted as a string of a given instance/entity.
-- 'entity' parameter denfines the instance from which we want to get some property values.
-- 'propertyID' parameter defines from which property the values are gotten.
-- 'rertun_val' parameter, if no result is returned, the value assigned to this parameter is returned, the default value is an empty string.
-- 'sep' parameter is the separation caracter used to separate returned values (e.g. ','), default is a space caracter, e.g. ' '.
-- Assign to 'stated_in' a wikidata entry id, if getValue() should only return values containing a reference statement 'stated in' (e.g. database, project, catalog). Note that the 'stated_in' parameter is only considered, if the assigned value to 'propertyID' is a wikidata entry.

function p.getValue(entity, propertyID, return_val, sep, stated_in) --CHANGED, Add CFG.ArticleLnkH
	local claims
	if return_val == nil then return_val = "" end
	if sep == nil then sep = " " end
	if entity and entity.claims then
		claims = entity.claims[propertyID]
	end
	if claims then
		-- if wiki-linked value output as link if possible
		if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
			local out = {}
			for k, v in pairs(claims) do
				--local datav = mw.wikibase.label(v.mainsnak.datavalue.value["id"]) --CHANGED, OLD
				local datav, addEnd, Article = getInYourLang (v.mainsnak.datavalue.value["id"]) --CHANGED, BEGIN 
				if datav == nil then 
					datav = " " 
				else --CHANGED, BEGIN 
					if Article ~= nil then
						datav = MkIntLnk (Article..'|'..datav)
					end
					if addEnd ~= '' then
						datav = datav..addEnd
					end	
				end --CHANGED, END	
				--Filter statements with the specified stated_in reference value, if none (stated_in = nil) all statements are considered.
				local is_from_given_source = true
				if stated_in ~= nil then
					is_from_given_source = false
					if v.references then
						for rk, rv in pairs(v.references) do
							local ref_val = rv.snaks.P248
							if ref_val then
								for stated_k, stated_v in pairs(ref_val) do
									if (stated_v and stated_v.snaktype == "value" and stated_v.datavalue.type == "wikibase-entityid") then
										local ref_stated_in_val = stated_v.datavalue.value["id"]
										if ref_stated_in_val == stated_in then is_from_given_source = true end
									end
								end
							end
						end
					end
				end
				if is_from_given_source then
					out[#out + 1] = datav
				end
			end
			return table.concat(out, sep)
		else
		-- just return best values
			return entity:formatPropertyValues(propertyID).value
		end
	else
		return return_val
	end
end

function p.getValueProtein(protein_entities, propertyID, return_val)
	if return_val == nil then return_val = "" end
	local sep = ","
	local overall_results = {} --should return empty if nothing assigned
	for key, val in pairs(protein_entities) do --in cases where there are multiple encodes we loop through each and return concatenated data as a whole
		local claims
		local entity = val --each protein in encodes
		if entity and entity.claims then
			claims = entity.claims[propertyID]
		end
		if claims then
			local results
			-- if wiki-linked value output as link if possible
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
				local out = {}
				for k, v in pairs(claims) do
					local datav = mw.wikibase.getLabel("Q" .. v.mainsnak.datavalue.value["numeric-id"])
					if datav == nil then datav = " " end 
					out[#out + 1] = datav			
				end
				results = table.concat(out, sep)
			else
				results = entity:formatPropertyValues(propertyID).value
			end
			overall_results[#overall_results+1] = results --individual propertyID value stored in this index	
		end
	end

	local str_overall_results = table.concat(overall_results, sep) --weirdness happens when add a sep = " " otherwise each value represented one time
	if string.match(str_overall_results, '%w+') then
		return str_overall_results 
	else
		return return_val
	end
end

--general function to get value given an entity and property
function p.getQid(entity)
	local Qid
	if entity and entity.id then
		Qid = entity.id
		return Qid
	else
		return ""
	end
end

--get random value that is preferred ranked
-- *lclz*: Sometimes Wikibase returns punctuations other than "," depending on
--		 your site's language. Consider adding a gsub here.
function p.getRefseq_mRNA(entity, propertyID, return_val)
	if return_val == nil then return_val = "" end
	local input_rank = "RANK_PREFERRED" ---this is mostly like won't do anything because ranking isn't maintained in wikidata 
	local claims
	
	if entity.claims then
		claims = entity.claims[propertyID]
	end
	if claims then
		-- if wiki-linked value output as link if possible
		if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid" ) then
			local out = {}
			for k, v in pairs(claims) do
				local sitelink = mw.wikibase.getSitelink("Q" .. v.mainsnak.datavalue.value["numeric-id"])
				local label = mw.wikibase.getLabel("Q" .. v.mainsnak.datavalue.value["numeric-id"])
				if label == nil then label = "Q" .. v.mainsnak.datavalue.value["numeric-id"] end
							
				if sitelink then
					out[#out + 1] = "[[" .. sitelink .. "|" .. label .. "]]"
				else
					out[#out + 1] = "[[:d:Q" .. v.mainsnak.datavalue.value["numeric-id"] .. "|" .. label .. "]]"
				end
			end
			return table.concat(out, ", ")
		else
			local results = entity:formatPropertyValues(propertyID, mw.wikibase.entity.claimRanks).value 
			
			--loop through results until get a NP or NM or just return whatever is in LinkList_first element
			--[[local results_split = mw.text.split(results, CFG.SeparatorStr)
			
			local preffered_results = " "
			if results_split[1] then
				preferred_result = mw.text.trim(results_split[1]) --return LinkList_first element if desired prefix not found and remove whitespace
			end
			local id --refseq id in question
			for i, id in ipairs(results_split) do
				local trim_id = mw.text.trim(id)
  				if string.match( trim_id, '^NM_%d+') then 
  					preferred_result = trim_id --overwrite each time found only need one to display
  				end
			end
			if preferred_result then
				return preferred_result --return a id starting with NP or NM
			else
				return return_val --return LinkList_first element because desired prefix not found and remove whitespaces
			end
			--]]
			return results
		end
	else
		return return_val
	end
end

-- *lclz*: same as getRefseq_mRNA
function p.getRefseq_protein(protein_entities, propertyID, return_val)
local sep = CFG.SeparatorStr
local overall_results = {} --should return empty if nothing assigned

	for key, val in pairs(protein_entities) do --in cases where there are multiple encodes we loop through each and return concatenated data as a whole
	
		local claims
		local entity = val --each protein in encodes
		if entity.claims then
			claims = entity.claims[propertyID]
		end
		if claims then
			local results
			-- if wiki-linked value output as link if possible
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid" ) then
				local out = {}
				for k, v in pairs(claims) do
					local datav = mw.wikibase.getLabel("Q" .. v.mainsnak.datavalue.value["numeric-id"])
					if datav == nil then datav = " " end 
					out[#out + 1] = datav			
				end
				results = table.concat(out, sep)
			else
				results = entity:formatPropertyValues(propertyID, mw.wikibase.entity.claimRanks).value
			end
			overall_results[#overall_results+1] = results --a list is in each index 
		end	
		
	end
	--why are there duplicate results here
	local str_overall_results = table.concat(overall_results, sep)
	return str_overall_results

end
	--[[
	local results_split = mw.text.split(str_overall_results, sep) --split complete list so can loop through..probably a more direct way to do this
				--loop through results until get a NP or NM or just return whatever is in LinkList_first element

	local preffered_result = results_split[1] or ""

	for i, id in ipairs(results_split) do
		local trim_id = mw.text.trim(id)
		--check of id starts with NP or NM
		if string.match( trim_id, '^NP_%d+') then
			preferred_result = trim_id --overwrite each time found only need one to display
		end
	end
	--check if something in preffered_result if not get LinkList_first element in result_split
	if p.isempty(preffered_result) then
		return return_val
	else
		return preferred_result --return a id starting with NP or NM
	end

end --]]

--gets an image
--function p.getImage(entity, propertyID, sep, imgsize)
function p.getImage(entity, propertyID, sep, imgsize, searchCaption) --CHANGED
  
 	local claims
  
 	if entity and entity.claims then  
 		claims = entity.claims[propertyID]  
 	end
  
 	if claims then
 		if (claims[1] and claims[1].mainsnak.datatype == "commonsMedia") then  
 			local out = {}  
 			for k, v in pairs(claims) do  
 				local filename = v.mainsnak.datavalue.value  
 				out[#out + 1] = "[[File:" .. filename .. "|" .. imgsize .. "]]" 
 			end
 			if searchCaption and (claims[1].qualifiers ~= nil) then
 				local caption = nil
 				local vals = claims[1].qualifiers["P2096"][1].datavalue
 				if vals ~= nil then
	 				for k, v in pairs(vals) do
	 					if v.language == local_lang then
	 						caption = v.text
	 						break
	 					end	
	 				end
	 			end
 				return table.concat(out, sep), caption   
 			else	
 				return table.concat(out, sep)   
 			end	
 		else   
 			return ""   
 		end   
	else   
 		return ""   
 	end   
end

function p.getPDB(protein_entities)
	local pdb_propertyID = "P638"
	local overall_results = {}
	for key, val in pairs(protein_entities) do --in cases where there are multiple encodes we loop through each and return concatenated data as a whole
		local claims
		local entity = val
		if entity and entity.claims then
			claims = entity.claims[pdb_propertyID]
		end
		local sitelink = "https://www.rcsb.org/structure/"
		if claims then
			local results
			if (claims[1] and claims[1].mainsnak.snaktype == "value") then
			
				local out = {}
				for k, v in pairs(claims) do
					local label = mw.wikibase.getLabel(v.mainsnak.datavalue.value)
					if label == nil then label = v.mainsnak.datavalue.value end
				
					if sitelink then
						out[#out + 1] = "[" .. sitelink .. label .. " " ..label .. "]"
					else
						out[#out + 1] = "[[:d:Q" .. v.mainsnak.datavalue.value .. "|" .. label .. "]]"
					end
				end
				results = table.concat(out, ", ") -- *lclz*: punctuation (CJK comma, etc.)
			else
				results = entity:formatPropertyValues(pdb_propertyID, mw.wikibase.entity.claimRanks).value
			end
			overall_results[#overall_results+1] = results --individual propertyID values stored in this index
		end
	end
	return table.concat(overall_results, ",%%s")
end

function p.getAliases(entity)
	if entity['aliases'] ~= nil then
		-- *lclz*: You will need a different language here.
		--		 If you are aiming for an "en" fallback, consider a set data structure.

		-- zhwp went a bit further here: they moved this call after "gene_symbol",
		-- so that this function can perform the deduplication here instead of
		-- in renderIdentifiers. That way they skip messing with commas and spaces.
		local test = entity['aliases']['en']
		if test then
			local a = ''
			for key, value in ipairs(test) do
				a = a .. ', ' .. value['value']
			end
			return a
		else
			return ""
		end
	else
		return ""
	end

end

--get a geneome start P644 or end P645
function p.getChromosomeLoc(entity, propertyID, prefix)
	-- will contain the numeric value for the requested coordinate
	local output = ""
	local sep = " "
	-- can only be P644 (genomic start) or P645 (genomic end) for this to work
	-- should probably try to catch that.  Might also increase legibility to use specific variable names when possible
--	local propertyID = mw.text.trim(frame.args[1] or "") 
	-- this can really only be P659 right now.  I'm not sure of the value of including it as a parameter as other values will likely break this function
	local qualifierID = "P659" --mw.text.trim(frame.args[2] or "")
	-- Why do we include this here?  What should happen if FETCH_WIKIDATA is not included? 
	--local input_parm = mw.text.trim(frame.args[3] or "")
	-- this can needs to be fed to the function either by a call to {{#invoke:Wikidata|pageId}} or by setting it directly (e.g. if the function was applied on a page other than the targeted gene)
	--alert if this id is not a valid thing in wikidata, a Lua error will occur that says
	--The ID entered is unknown to the system. Please use a valid entity ID.
	--local itemID = mw.text.trim(frame.args[4] or "")
	-- will track the different builds pulled from the qualifiers
	local newest_build = "0"
	-- starts the process
	--local entity = mw.wikibase.getEntity(itemID)
	local claims
	--gets a table of claims on the (genomic start or end) property Q19847637
	if entity and entity.claims then
		claims = entity.claims[propertyID]
	end
	--will return nothing if no claims are found
	if claims then
		--checking to be sure claims is populated, not sure it its needed
		if (claims[1] ) then
			--useful for debugging
			--local out = {}
			--pulls the genome location from the claim
			for k, v in pairs(claims) do
				local location = v.mainsnak.datavalue.value
				--debugging
				--out[#out + 1] = k.." location:" .. location.. " || " 
				--gets the qualifiers linked to the current claim
				local quals 
				if v.qualifiers then
					quals = v.qualifiers.P659
				end
				--if there are any
				if quals then
					for qk, qv in pairs(quals) do
						local qual_obj_id = "Q"..qv.datavalue.value["numeric-id"]
						--get to the entity targeted by the qualifier property.  Genome builds are Items in wikidata
						local qual_obj = mw.wikibase.getEntity(qual_obj_id)
						local alias = ""
						--this uses the aliases to pull out version numbers
						--seems like there ought to be a better way to do this, but likely would need to change the data added by the bot
						if qual_obj["aliases"] ~= nil then
							local test = qual_obj["aliases"]["en"]
							for key, value in ipairs(test) do
								if string.match(value['value'], prefix) then
									alias = value['value']
									local build_no = alias:gsub(prefix,"")
									--report only the most location associated with the most recent build
									--if there is more than one location per build, just give one back as that is not our problem right now.
									if build_no > newest_build then
										output = location
										newest_build = build_no
									end
								end
							end
						end
					end
				--in case there are no qualifiers, but there is a location, might as well return it
				else 
					output = location 
				end
			end
			return output
		else
			return ""
		end
	else
		return ""
		--debug
		--"no claims for "..itemID.." prop "..propertyID
	end
end

function p.getAliasFromGenomeAssembly(entity, prefix)
	-- will contain the numeric value for the requested coordinate
	local output = ""
	local sep = " "
	local propertyID = "P644" --genomic start used 
	local qualifierID = "P659" --genomic assembly

	local newest_build = "0"
	local claims
	if entity.claims then
	 claims = entity.claims[propertyID]
	end
	--will return nothing if no claims are found
	if claims then
		--checking to be sure claims is populated, not sure it its needed
		if (claims[1] ) then
			--useful for debugging
			--local out = {}
			--pulls the genome location from the claim
			for k, v in pairs(claims) do
				local location = ''  -- TODO what should this be? defining location is required for 'output = location' below
				local quals
				if v.qualifiers then
					quals = v.qualifiers.P659
				end
				--if there are any
				--as of Aug. 2017, P659-genomic assembly is stored only in human genomic data. GRCh38 (newer) or GRCh37(older).
				--Mouse genomic data doesn't have P659-genomic assembly data. But mouse has only one version. GRCm38/mm10.
				if quals then
					for qk, qv in pairs(quals) do
						local qual_obj_id = "Q"..qv.datavalue.value["numeric-id"]
						--get to the entity targeted by the qualifier property.  Genome builds are Items in wikidata
						local qual_obj = mw.wikibase.getEntity(qual_obj_id)
						local alias = ""
						--this uses the aliases to pull out version numbers
						--seems like there ought to be a better way to do this, but likely would need to change the data added by the bot
						if qual_obj["aliases"] ~= nil then
							local test = qual_obj["aliases"]["en"]
							for key, value in ipairs(test) do
								if string.match(value['value'], prefix) then
									alias = value['value']
									local build_no = alias:gsub(prefix,"")
									--For example, prefix is "hg" (this is set when the function was called),
									--alias is "hg38" (which is data stored in Wikidata). Then "build_no" becomes "38".
									--report only the most location associated with the most recent build
									--if there is more than one location per build, just give one back as that is not our problem right now.
									if build_no > newest_build then
										newest_build = build_no
									end
								end
							end
						end
					end
				--in case there are no qualifiers, but there is a location, might as well return it
				else
					output = location
				end
			end
			return prefix .. newest_build
		else
			return ""
		end
	else
		return ""
	end
end

-- *lclz*: Your language's wikidata may have different nouns for chromosome and
--		 mitochodria.
function p.trimChromosome(entity) --CHANGED, FULL CHANGED
	local function getValue(entity, propertyID)
		local claims
		if entity and entity.claims then
			claims = entity.claims[propertyID]
		end
		if claims then
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
				 return mw.wikibase.getLabelByLang (claims[1].mainsnak.datavalue['value']['id'],'en')
			end
		else
			return ''
		end
	end

	local string_to_trim = getValue(entity, "P1057")
	local out = ''
	--"mitochondrion" and "chromosome MT" is used for mitochondrial DNA.
	--See [[d:Special:WhatLinksHere/Q18694495]]
	if string.find(string_to_trim, 'chromosome MT') or string.find(string_to_trim, 'mitochondri') then --match both 'mitochondrio'/'mitochondrial'
		out = "MT"
	elseif string.find(string_to_trim, 'chromosome') then
		out = string.match(string_to_trim, "%d+")--extract number from string
		if out == nil then
			out = string.match(string_to_trim, "X") or string.match(string_to_trim, "Y")
		end
	end
	return out
end

function p.locToMb(num, idp)
  num = tonumber(num)
  if num == nil then 
  	return ""
  else
  	local mb = num/1000000
  	local mult = 10^(idp or 0)
  	return math.floor(mb * mult + 0.5) / mult
  end
end

function p.isempty(s)
  	return s == nil or s == ''
end

function p.getGO(protein_entities, propertyID)
	--propertyID ie molecular, cellular, function
	
	local overall_results = {}
	local results = "" --string to return
	
	for key, val in pairs(protein_entities) do
	
		local claims
		local entity = val
		if entity.claims then
			claims = entity.claims[propertyID] -- ie molecular, cellular, function
		end
		local propertyID_child = "P686" -- Gene Ontology ID
		
		if claims then
			
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
				--local out = {}
				for k, v in pairs(claims) do
					local itemID_child = "Q" .. v.mainsnak.datavalue.value["numeric-id"] --get Qid of property item so can get the GOid
					local entity = mw.wikibase.getEntity(itemID_child)
					local claims
					local result_GOID = ''
					if entity and entity.claims then claims = entity.claims[propertyID_child] end
					if claims then
						result_GOID = entity:formatPropertyValues(propertyID_child, {mw.wikibase.entity.claimRanks.RANK_NORMAL}).value
					else
						result_GOID = nil --no GO ID
					end
					local sitelink = "http://amigo.geneontology.org/amigo/term/"
					local identH = "Q" .. v.mainsnak.datavalue.value["numeric-id"]
					--local label = mw.wikibase.getLabel(identH) --CHANGED
					local label, addEnd, Article = getInYourLang (identH) --CHANGED
					if label == nil then label = identH end
					local wiki_link = ""
					--CHANGED, BEGIN
					if sitelink and result_GOID ~= nil then
						wiki_link = "\n* [" .. sitelink .. result_GOID .. " " .. label .."]"
					else
						wiki_link = "\n* [[:d:Q" .. v.mainsnak.datavalue.value["numeric-id"] .. "|" .. label .. "]]"
					end
					local AtEnd = ''
					if Article ~= nil then
						Article = string.gsub (Article, ' ', '_')
						AtEnd = '&thinsp;[[File:Wiki article small light.svg|text-bottom|'
						.. "|link=https://ca.wikipedia.org/wiki/"..Article.."]]"
					elseif addEnd ~= '' then
						AtEnd = addEnd
					end	
					if AtEnd ~= '' then
						wiki_link = wiki_link..AtEnd
					end	
					--CHANGED, END
					overall_results[#overall_results+1] = wiki_link
				end
				
			else
				results = entity:formatPropertyValues(propertyID, mw.wikibase.entity.claimRanks).value
			end
			
		end
		--overall_results[#overall_results+1] = results --each protein GO terms stored in this index, so table contains all the GO terms with duplicates 
	end

	local hash = {} --temp check
	local res = {} --no dups

	for _,v in ipairs(overall_results) do
   		if (not hash[v]) then
	   		res[#res+1] = v 
	   		hash[v] = true
   		end
	end
	return table.concat(res, "")
end

local function getReference(qID, entity, property_id, ref_index)
	local f = {"claims",property_id, ref_index, "references"} 
	local id = qID
	--if id and (#id == 0) then
	--	id = nil
	--end
	local data = entity
	if not data then
		return nil
	end
	
	local i = 1
	while true do
		local index = f[i]
		if not index then
			if type(data) == "table" then
				return mw.text.jsonEncode(data, mw.text.JSON_PRESERVE_KEYS + mw.text.JSON_PRETTY)
			else
				return tostring(data)
			end
		end
		
		data = data[index] or data[tonumber(index)]
		if not data then
			return ""
		end
		i = i + 1
	end
end

function getRefLink (id, entity, prop, k) --CHANGED, NEW. Used for p.getDisease and p.getDrug
	local refLink = ""
	local ref = ""
	ref = getReference (id, entity, prop, k)
	if (ref ~= nil and ref ~= '') then
		refLink = ref
	end
	return refLink
end

function p.getDisease(entity, propertyID)
	local claims
	local return_val = ""  -- define variable; this line was 'if return_val == nil then return_val = "" end' which looks like a copy/paste
	if entity and entity.claims then
		claims = entity.claims[propertyID]
	end
	if claims then
		-- if wiki-linked value output as link if possible

		if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then

			local out = {}
			local datasource = {}
			--{{#invoke:Wikidata |ViewSomething |id=Q18023174 |claims|P2293|1|references|1|snaks|P854|1|datavalue|value}}
			--maybe there is a more direct way to find this than looping through the json object
			for k, v in pairs(claims) do --CHANGED
				--local datav = mw.wikibase.getLabel("Q" .. v.mainsnak.datavalue.value["numeric-id"])
				--if datav == nil then datav = " " end
				--local id = "Q" .. v.mainsnak.datavalue.value["numeric-id"]
				--local linkTarget = mw.wikibase.getSitelink(id)
				--local refLink = ""
				--local ref = ""
				--ref = getReference("", entity, "P2293", k)
				--if (ref ~= nil and ref ~= '') then
					----refLink = refLink..","..ref
					--refLink = ref
				--end
				--if refLink = "" then --skip if there isn't a reference found
				--if linkTarget then
				--	out[#out + 1] = "[["..linkTarget.."|"..datav.."]]"
				--else
				--	out[#out + 1] = "[[:d:" .. id .. "|" .. datav .. "]]"
				--end
				out[#out + 1] = getInYourLang1 ("Q" .. v.mainsnak.datavalue.value["numeric-id"]) --CHANGED, NEW
				--datasource[#out] = refLink
				datasource[#out] = getRefLink ("", entity, "P2293", k) --CHANGED, NEW
			end
			return out, datasource
		else
		-- just return best values
			--return entity:formatPropertyValues(propertyID).value
			return return_val, return_val
		end
	else
		return return_val
	end	
   return return_val
end

function p.getDrug(protein_entities, propertyID)
	local out = {}
	local datasource = {}
	local pname = {}
	local pqid = {}

	for key, val in pairs(protein_entities) do
		local claims
		local entity = val
		local name = check_values(p.getLabel,{entity})
		if entity.claims then
			claims = entity.claims[propertyID] -- ie physically interacts with
		end
		local protein_id
		if entity then protein_id = entity.id else protein_id = "" end
		if claims then
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
				for k, v in pairs(claims) do --CHANGED
					--local datav = mw.wikibase.getLabel("Q" .. v.mainsnak.datavalue.value["numeric-id"])
					--if datav == nil then datav = "" end
					--local id = "Q" .. v.mainsnak.datavalue.value["numeric-id"]
					--local linkTarget = mw.wikibase.getSitelink(id)
					--local refLink = ""
					--local ref = getReference(protein_id, entity, "P129",k)  --just check if anything returned
					--if (ref ~= nil and ref ~= '') then
						--refLink = ref
					--end
					--if linkTarget then
						--out[#out + 1] = "[["..linkTarget.."|"..datav.."]]"
					--else
						--out[#out + 1] = "[[:d:" .. id .. "|" .. datav .. "]]"
					--end
					out[#out + 1] = getInYourLang1 ("Q" .. v.mainsnak.datavalue.value["numeric-id"]) --CHANGED, NEW
					datasource[#out] = getRefLink (protein_id, entity, "P129",k) --CHANGED, NEW
					pname[protein_id] = name
					pqid[#out] = protein_id
				end --end k,v claims loop
			end --end claims[1]
		end --if claims
	end -- end protein_entities loop
	return out, datasource, pqid, pname
end

function p.FormatNaturalNumber(bp)  --CHANGED function name
	--Separate number with comma. For example when this function gets "12345678", returns "12.345.678"
	local FormatedNumber = bp
	while true do
		local k
		FormatedNumber, k = string.gsub(FormatedNumber, "^(-?%d+)(%d%d%d)", '%1'..CFG.ThousandSeparator..'%2') --CHANGED, using CFG.ThousandSeparator 
		if k == 0 then
			break
		end
	end
	return FormatedNumber
end

return p