<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.geministation.com/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-questchecker-core.js</id>
	<title>MediaWiki:Gadget-questchecker-core.js - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.geministation.com/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-questchecker-core.js"/>
	<link rel="alternate" type="text/html" href="https://wiki.geministation.com/index.php?title=MediaWiki:Gadget-questchecker-core.js&amp;action=history"/>
	<updated>2026-06-04T16:21:46Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://wiki.geministation.com/index.php?title=MediaWiki:Gadget-questchecker-core.js&amp;diff=8912&amp;oldid=prev</id>
		<title>Banri: Created page with &quot;/** &lt;nowiki&gt;  * Adds the ability to check a user&#039;s quests and skills against requirements  * on quest pages.  *   * Adapted from https://github.com/MidasLamb/RS-Wiki-Quest-Che...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.geministation.com/index.php?title=MediaWiki:Gadget-questchecker-core.js&amp;diff=8912&amp;oldid=prev"/>
		<updated>2021-03-24T03:21:21Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;/** &amp;lt;nowiki&amp;gt;  * Adds the ability to check a user&amp;#039;s quests and skills against requirements  * on quest pages.  *   * Adapted from https://github.com/MidasLamb/RS-Wiki-Quest-Che...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;/** &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 * Adds the ability to check a user&amp;#039;s quests and skills against requirements&lt;br /&gt;
 * on quest pages.&lt;br /&gt;
 * &lt;br /&gt;
 * Adapted from https://github.com/MidasLamb/RS-Wiki-Quest-Checker/&lt;br /&gt;
 * &lt;br /&gt;
 * This gadget is utilised on the following templates/modules/pages:&lt;br /&gt;
 * - Module:QuestDetails&lt;br /&gt;
 * - Template:Infobox achievement&lt;br /&gt;
 * - Quests/Strategy&lt;br /&gt;
 * - List of quests&lt;br /&gt;
 * - List of quests by age&lt;br /&gt;
 *&lt;br /&gt;
 * @author JaydenKieran&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
var ACTIVATOR_CLASS = &amp;#039;.qc-active&amp;#039;,&lt;br /&gt;
	LIGHTTABLE_CLASS = &amp;#039;.lighttable&amp;#039;,&lt;br /&gt;
	LIGHTTABLE_RESET_CLASS = &amp;#039;.ht-reset&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
var questCorrections = {&lt;br /&gt;
	// first value is RuneMetrics name, second is correct (wiki) name&lt;br /&gt;
	&amp;#039;Recipe for Disaster: Freeing the Goblin Generals&amp;#039;: &amp;#039;Recipe for Disaster: Freeing the Goblin generals&amp;#039;,&lt;br /&gt;
	&amp;#039;Recipe for Disaster: Freeing the Mountain Dwarf&amp;#039;: &amp;#039;Recipe for Disaster: Freeing the Mountain dwarf&amp;#039;,&lt;br /&gt;
	// first value is RuneMetrics name, second is correct (wiki) name without the suffix (miniquest) or (saga)&lt;br /&gt;
	&amp;#039;A Guild of Our Own (miniquest)&amp;#039;:&amp;#039;A Guild of Our Own&amp;#039;,&lt;br /&gt;
	&amp;#039;Bar Crawl (miniquest)&amp;#039;:&amp;#039;Bar Crawl&amp;#039;,&lt;br /&gt;
	&amp;#039;Benedict\&amp;#039;s World Tour (miniquest)&amp;#039;:&amp;#039;Benedict\&amp;#039;s World Tour&amp;#039;,&lt;br /&gt;
	&amp;#039;Boric\&amp;#039;s Task I (miniquest)&amp;#039;:&amp;#039;Boric\&amp;#039;s Task I&amp;#039;,&lt;br /&gt;
	&amp;#039;Boric\&amp;#039;s Task II (miniquest)&amp;#039;:&amp;#039;Boric\&amp;#039;s Task II&amp;#039;,&lt;br /&gt;
	&amp;#039;Boric\&amp;#039;s Task III (miniquest)&amp;#039;:&amp;#039;Boric\&amp;#039;s Task III&amp;#039;,&lt;br /&gt;
	&amp;#039;Damage Control (miniquest)&amp;#039;:&amp;#039;Damage Control&amp;#039;,&lt;br /&gt;
	&amp;#039;Desert Slayer Dungeon (miniquest)&amp;#039;:&amp;#039;Desert Slayer Dungeon&amp;#039;,&lt;br /&gt;
	&amp;#039;Doric\&amp;#039;s Task I (miniquest)&amp;#039;:&amp;#039;Doric\&amp;#039;s Task I&amp;#039;,&lt;br /&gt;
	&amp;#039;Doric\&amp;#039;s Task II (miniquest)&amp;#039;:&amp;#039;Doric\&amp;#039;s Task II&amp;#039;,&lt;br /&gt;
	&amp;#039;Doric\&amp;#039;s Task III (miniquest)&amp;#039;:&amp;#039;Doric\&amp;#039;s Task III&amp;#039;,&lt;br /&gt;
	&amp;#039;Doric\&amp;#039;s Task IV (miniquest)&amp;#039;:&amp;#039;Doric\&amp;#039;s Task IV&amp;#039;,&lt;br /&gt;
	&amp;#039;Doric\&amp;#039;s Task V (miniquest)&amp;#039;:&amp;#039;Doric\&amp;#039;s Task V&amp;#039;,&lt;br /&gt;
	&amp;#039;Doric\&amp;#039;s Task VI (miniquest)&amp;#039;:&amp;#039;Doric\&amp;#039;s Task VI&amp;#039;,&lt;br /&gt;
	&amp;#039;Doric\&amp;#039;s Task VII (miniquest)&amp;#039;:&amp;#039;Doric\&amp;#039;s Task VII&amp;#039;,&lt;br /&gt;
	&amp;#039;Doric\&amp;#039;s Task VIII (miniquest)&amp;#039;:&amp;#039;Doric\&amp;#039;s Task VIII&amp;#039;,&lt;br /&gt;
	&amp;#039;Enter the Abyss (miniquest)&amp;#039;: &amp;#039;Enter the Abyss&amp;#039;,&lt;br /&gt;
	&amp;#039;Eye for an Eye (miniquest)&amp;#039;:&amp;#039;Eye for an Eye&amp;#039;,&lt;br /&gt;
	&amp;#039;Final Destination (miniquest)&amp;#039;:&amp;#039;Final Destination&amp;#039;,&lt;br /&gt;
	&amp;#039;Flag Fall (miniquest)&amp;#039;:&amp;#039;Flag Fall&amp;#039;,&lt;br /&gt;
	&amp;#039;Foreshadowing (miniquest)&amp;#039;:&amp;#039;Foreshadowing&amp;#039;,&lt;br /&gt;
	&amp;#039;From Tiny Acorns (miniquest)&amp;#039;:&amp;#039;From Tiny Acorns&amp;#039;,&lt;br /&gt;
	&amp;#039;Ghosts from the Past (miniquest)&amp;#039;:&amp;#039;Ghosts from the Past&amp;#039;,&lt;br /&gt;
	&amp;#039;Harbinger (miniquest)&amp;#039;:&amp;#039;Harbinger&amp;#039;,&lt;br /&gt;
	&amp;#039;Head of the Family (miniquest)&amp;#039;:&amp;#039;Head of the Family&amp;#039;,&lt;br /&gt;
	&amp;#039;Hopespear\&amp;#039;s Will (miniquest)&amp;#039;:&amp;#039;Hopespear\&amp;#039;s Will&amp;#039;,&lt;br /&gt;
	&amp;#039;In Memory of the Myreque (miniquest)&amp;#039;:&amp;#039;In Memory of the Myreque&amp;#039;,&lt;br /&gt;
	&amp;#039;Jed Hunter (miniquest)&amp;#039;:&amp;#039;Jed Hunter&amp;#039;,&lt;br /&gt;
	&amp;#039;Koschei\&amp;#039;s Troubles (miniquest)&amp;#039;:&amp;#039;Koschei\&amp;#039;s Troubles&amp;#039;,&lt;br /&gt;
	&amp;#039;Lair of Tarn Razorlor (miniquest)&amp;#039;:&amp;#039;Lair of Tarn Razorlor&amp;#039;,&lt;br /&gt;
	&amp;#039;Lost Her Marbles (miniquest)&amp;#039;:&amp;#039;Lost Her Marbles&amp;#039;,&lt;br /&gt;
	&amp;#039;Mahjarrat Memories (miniquest)&amp;#039;:&amp;#039;Mahjarrat Memories&amp;#039;,&lt;br /&gt;
	&amp;#039;One Foot in the Grave (miniquest)&amp;#039;:&amp;#039;One Foot in the Grave&amp;#039;,&lt;br /&gt;
	&amp;#039;Purple Cat (miniquest)&amp;#039;:&amp;#039;Purple Cat&amp;#039;,&lt;br /&gt;
	&amp;#039;Raksha, the Shadow Colossus (miniquest)&amp;#039;:&amp;#039;Raksha, the Shadow Colossus&amp;#039;,&lt;br /&gt;
	&amp;#039;Rebuilding Edgeville (miniquest)&amp;#039;:&amp;#039;Rebuilding Edgeville&amp;#039;,&lt;br /&gt;
	&amp;#039;Sheep Shearer (miniquest)&amp;#039;:&amp;#039;Sheep Shearer&amp;#039;,&lt;br /&gt;
	&amp;#039;Sins of the Father (miniquest)&amp;#039;:&amp;#039;Sins of the Father&amp;#039;,&lt;br /&gt;
	&amp;#039;Spiritual Enlightenment (miniquest)&amp;#039;:&amp;#039;Spiritual Enlightenment&amp;#039;,&lt;br /&gt;
	&amp;#039;Tales of Nomad (miniquest)&amp;#039;:&amp;#039;Tales of Nomad&amp;#039;,&lt;br /&gt;
	&amp;#039;Tales of the God Wars (miniquest)&amp;#039;:&amp;#039;Tales of the God Wars&amp;#039;,&lt;br /&gt;
	&amp;#039;The Curse of Zaros (miniquest)&amp;#039;:&amp;#039;The Curse of Zaros&amp;#039;,&lt;br /&gt;
	&amp;#039;The General\&amp;#039;s Shadow (miniquest)&amp;#039;:&amp;#039;The General\&amp;#039;s Shadow&amp;#039;,&lt;br /&gt;
	&amp;#039;The Hunt for Surok (miniquest)&amp;#039;:&amp;#039;The Hunt for Surok&amp;#039;,&lt;br /&gt;
	&amp;#039;The Lost Toys (miniquest)&amp;#039;:&amp;#039;The Lost Toys&amp;#039;,&lt;br /&gt;
	&amp;#039;Tortle Combat (miniquest)&amp;#039;:&amp;#039;Tortle Combat&amp;#039;,&lt;br /&gt;
	&amp;#039;Tuai Leit\&amp;#039;s Own (miniquest)&amp;#039;:&amp;#039;Tuai Leit\&amp;#039;s Own&amp;#039;,&lt;br /&gt;
	&amp;#039;Wandering Ga\&amp;#039;al (miniquest)&amp;#039;:&amp;#039;Wandering Ga\&amp;#039;al&amp;#039;,&lt;br /&gt;
	&amp;#039;Witch\&amp;#039;s Potion (miniquest)&amp;#039;:&amp;#039;Witch\&amp;#039;s Potion&amp;#039;,&lt;br /&gt;
	&amp;#039;Nadir (saga)&amp;#039;:&amp;#039;Nadir&amp;#039;,&lt;br /&gt;
	&amp;#039;Thok It To \&amp;#039;Em (saga)&amp;#039;:&amp;#039;Thok It To \&amp;#039;Em&amp;#039;,&lt;br /&gt;
	&amp;#039;Thok Your Block Off (saga)&amp;#039;:&amp;#039;Thok Your Block Off&amp;#039;,&lt;br /&gt;
	&amp;#039;Three\&amp;#039;s Company (saga)&amp;#039;:&amp;#039;Three\&amp;#039;s Company&amp;#039;,&lt;br /&gt;
	&amp;#039;The Vault of Shadows (miniquest)&amp;#039;:&amp;#039;The Vault of Shadows&amp;#039;,&lt;br /&gt;
	&amp;#039;Vengeance (saga)&amp;#039;:&amp;#039;Vengeance&amp;#039;,&lt;br /&gt;
},&lt;br /&gt;
	skills = [&amp;quot;Attack&amp;quot;,&amp;quot;Defence&amp;quot;,&amp;quot;Strength&amp;quot;,&amp;quot;Constitution&amp;quot;,&amp;quot;Ranged&amp;quot;,&amp;quot;Prayer&amp;quot;,&lt;br /&gt;
				&amp;quot;Magic&amp;quot;,&amp;quot;Cooking&amp;quot;,&amp;quot;Woodcutting&amp;quot;,&amp;quot;Fletching&amp;quot;,&amp;quot;Fishing&amp;quot;,&amp;quot;Firemaking&amp;quot;,&lt;br /&gt;
				&amp;quot;Crafting&amp;quot;,&amp;quot;Smithing&amp;quot;,&amp;quot;Mining&amp;quot;,&amp;quot;Herblore&amp;quot;,&amp;quot;Agility&amp;quot;,&amp;quot;Thieving&amp;quot;,&amp;quot;Slayer&amp;quot;,&lt;br /&gt;
				&amp;quot;Farming&amp;quot;,&amp;quot;Runecrafting&amp;quot;,&amp;quot;Hunter&amp;quot;,&amp;quot;Construction&amp;quot;,&amp;quot;Summoning&amp;quot;,&lt;br /&gt;
				&amp;quot;Dungeoneering&amp;quot;,&amp;quot;Divination&amp;quot;,&amp;quot;Invention&amp;quot;,&amp;quot;Archaeology&amp;quot;], // Used to turn skill ID&amp;#039;s into usable names.&lt;br /&gt;
	&lt;br /&gt;
	conf = mw.config.get([&lt;br /&gt;
        &amp;#039;wgArticlePath&amp;#039;&lt;br /&gt;
    ]),&lt;br /&gt;
&lt;br /&gt;
	icons = {&lt;br /&gt;
		&amp;#039;yes&amp;#039;: &amp;#039;/images/f/fb/Yes_check.svg&amp;#039;,&lt;br /&gt;
		&amp;#039;no&amp;#039;:  &amp;#039;/images/a/a2/X_mark.svg&amp;#039;,&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
    self = {&lt;br /&gt;
        /**&lt;br /&gt;
         * Startup method&lt;br /&gt;
         */&lt;br /&gt;
        init: function () {&lt;br /&gt;
            self.createFields();&lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        /**&lt;br /&gt;
         * Resets the lighttables&lt;br /&gt;
         */&lt;br /&gt;
        resetLighttable: function () {&lt;br /&gt;
        	$(ACTIVATOR_CLASS).each(function(index) {&lt;br /&gt;
        		if ($(this).hasClass(&amp;#039;lighttable&amp;#039;)) {&lt;br /&gt;
        			var reset = $(this).find(LIGHTTABLE_RESET_CLASS)&lt;br /&gt;
        			if (reset.length) {&lt;br /&gt;
        				// This fires the reset click handler specified in Gadget-highlighttable.js&lt;br /&gt;
        				// It&amp;#039;s really messy, but there&amp;#039;s no other way to do this&lt;br /&gt;
        				reset.trigger(&amp;#039;click&amp;#039;)&lt;br /&gt;
        			}&lt;br /&gt;
        		}&lt;br /&gt;
        	})&lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        /**&lt;br /&gt;
         * Creates the input fields on the quest page for the user&amp;#039;s RSN&lt;br /&gt;
         */&lt;br /&gt;
        createFields: function () {&lt;br /&gt;
        	if (rs.hasLocalStorage() === true) {&lt;br /&gt;
        		$.removeCookie(&amp;#039;RSN&amp;#039;, { path: &amp;#039;/&amp;#039; }); // remove any existing cookies using jQuery, will return false if it doesn&amp;#039;t exist so it&amp;#039;s fine&lt;br /&gt;
        		var name = localStorage.getItem(&amp;#039;rsn&amp;#039;);&lt;br /&gt;
        	} else {&lt;br /&gt;
        		var name = self.getCookie(&amp;#039;RSN&amp;#039;);&lt;br /&gt;
        	}&lt;br /&gt;
        	&lt;br /&gt;
        	$(ACTIVATOR_CLASS).each( function() {&lt;br /&gt;
                var input1 = new OO.ui.TextInputWidget( { placeholder: &amp;#039;Display name&amp;#039;, id: &amp;#039;rs-qc-rsn&amp;#039;} );&lt;br /&gt;
                &lt;br /&gt;
                if (name) { // set input to cookie/localStorage value&lt;br /&gt;
                    input1.setValue(name);&lt;br /&gt;
                    self.loadData(name);&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                var button1 = new OO.ui.ButtonInputWidget( {&lt;br /&gt;
                      label: &amp;#039;Look up&amp;#039;,&lt;br /&gt;
                      flags: [ &amp;#039;primary&amp;#039;, &amp;#039;progressive&amp;#039; ]&lt;br /&gt;
                } );&lt;br /&gt;
                button1.on(&amp;#039;click&amp;#039;, function() {&lt;br /&gt;
                    if (rs.hasLocalStorage() === true) {&lt;br /&gt;
                        localStorage.setItem(&amp;#039;rsn&amp;#039;, input1.value); // save in localStorage&lt;br /&gt;
                    } else {&lt;br /&gt;
                        self.setCookie(&amp;#039;RSN&amp;#039;, input1.value, 30); // set a cookie for 30 days&lt;br /&gt;
                    }&lt;br /&gt;
                    self.loadData(input1.value);&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                var fieldset = new OO.ui.FieldsetLayout( { &lt;br /&gt;
                  id: &amp;#039;rs-qc-form&amp;#039;,&lt;br /&gt;
                } );&lt;br /&gt;
&lt;br /&gt;
                fieldset.addItems( [ &lt;br /&gt;
                  new OO.ui.ActionFieldLayout(&lt;br /&gt;
                      input1,&lt;br /&gt;
                      button1&lt;br /&gt;
                  )&lt;br /&gt;
                ] );&lt;br /&gt;
                &lt;br /&gt;
                if ($(this).hasClass(&amp;#039;lighttable&amp;#039;)) {&lt;br /&gt;
                    // If it&amp;#039;s a lighttable, insert the fieldset before the table&lt;br /&gt;
                    fieldset.$element.insertBefore(this)&lt;br /&gt;
                } else {&lt;br /&gt;
                    // If not, insert it inside the element that has the class&lt;br /&gt;
                    $(this).prepend( fieldset.$element );&lt;br /&gt;
                }&lt;br /&gt;
        	} );&lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        /**&lt;br /&gt;
         * Updates the status text&lt;br /&gt;
         */&lt;br /&gt;
        updateStatus: function (text) {&lt;br /&gt;
        	mw.notify( text, { tag: &amp;#039;questchecker&amp;#039; } );&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
		/**&lt;br /&gt;
		 * Sets a cookie&lt;br /&gt;
		 */&lt;br /&gt;
		setCookie: function (name, value, days) {&lt;br /&gt;
		    var expires = &amp;quot;&amp;quot;;&lt;br /&gt;
		    if (days) {&lt;br /&gt;
		        var date = new Date();&lt;br /&gt;
		        date.setTime(date.getTime() + (days*24*60*60*1000));&lt;br /&gt;
		        expires = &amp;quot;; expires=&amp;quot; + date.toUTCString();&lt;br /&gt;
		    }&lt;br /&gt;
		    document.cookie = name + &amp;quot;=&amp;quot; + (value || &amp;quot;&amp;quot;)  + expires + &amp;quot;; path=/&amp;quot;;&lt;br /&gt;
		},&lt;br /&gt;
        &lt;br /&gt;
        /**&lt;br /&gt;
         * Returns the value of a cookie, or null if it doesn&amp;#039;t exist&lt;br /&gt;
         */&lt;br /&gt;
        getCookie: function (name) {&lt;br /&gt;
        	var cookie = new RegExp(&amp;quot;^(?:.*;)?\\s*&amp;quot; + name + &amp;quot;\\s*=\\s*([^;]+)(?:.*)?$&amp;quot;),&lt;br /&gt;
        		match = document.cookie.match(cookie);&lt;br /&gt;
        	&lt;br /&gt;
        	if (match !== null) {&lt;br /&gt;
        		return match[1];&lt;br /&gt;
        	} else {&lt;br /&gt;
        		return null;&lt;br /&gt;
        	}&lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        /**&lt;br /&gt;
         * Load data&lt;br /&gt;
         */&lt;br /&gt;
         loadData: function (rsn) {&lt;br /&gt;
         	self.resetLighttable();&lt;br /&gt;
         	&lt;br /&gt;
         	if (!rsn) {&lt;br /&gt;
         		self.updateStatus(&amp;quot;Invalid RSN&amp;quot;);&lt;br /&gt;
         		return;&lt;br /&gt;
         	}&lt;br /&gt;
         	&lt;br /&gt;
         	self.updateStatus(&amp;#039;Loading data for &amp;#039; + rsn);&lt;br /&gt;
         	&lt;br /&gt;
		    $.ajax({ // Get the quest data&lt;br /&gt;
		        type: &amp;quot;GET&amp;quot;,&lt;br /&gt;
		        url: &amp;quot;/cors/m=runemetrics/quests?user=&amp;quot; + rsn,&lt;br /&gt;
		        dataType: &amp;quot;json&amp;quot;,&lt;br /&gt;
		        success: function(msg) {&lt;br /&gt;
		            if (msg.quests.length === 0) {&lt;br /&gt;
		            	self.updateStatus(&amp;quot;Error loading data. The account&amp;#039;s RuneMetrics profile may be private.&amp;quot;);&lt;br /&gt;
		                console.error(&amp;quot;Could not fetch quest data&amp;quot;);&lt;br /&gt;
		            } else {&lt;br /&gt;
		                var userQuests = {};&lt;br /&gt;
		                var userQuestPoints = 0;&lt;br /&gt;
		                msg.quests.forEach(function(item, index) {&lt;br /&gt;
		                	// Calculate the user&amp;#039;s quest points&lt;br /&gt;
		                	if (item.status == &amp;#039;COMPLETED&amp;#039;) {&lt;br /&gt;
		                		// If quest is completed, add it to the user&amp;#039;s total quest points&lt;br /&gt;
		                		userQuestPoints = userQuestPoints + item.questPoints;&lt;br /&gt;
		                	}&lt;br /&gt;
		                	&lt;br /&gt;
		                	// Correct quest names to wiki page names&lt;br /&gt;
		                    if (item.title in questCorrections) {&lt;br /&gt;
		                        var correctName = questCorrections[item.title];&lt;br /&gt;
		                        userQuests[correctName] = item.status;&lt;br /&gt;
		                    } else {&lt;br /&gt;
		                    	userQuests[item.title] = item.status;&lt;br /&gt;
		                    }&lt;br /&gt;
		                });&lt;br /&gt;
		                self.addQuestIcons(userQuests);&lt;br /&gt;
		                self.addQuestPoints(userQuestPoints);&lt;br /&gt;
		            }&lt;br /&gt;
		        }&lt;br /&gt;
		    });&lt;br /&gt;
		    &lt;br /&gt;
		    $.ajax({ // Get the skill data.&lt;br /&gt;
		        type: &amp;quot;GET&amp;quot;,&lt;br /&gt;
		        url: &amp;quot;/cors/m=runemetrics/profile/profile?user=&amp;quot; + rsn + &amp;quot;&amp;amp;activities=0&amp;quot;,&lt;br /&gt;
		        dataType: &amp;quot;json&amp;quot;,&lt;br /&gt;
		        success: function(msg) {&lt;br /&gt;
		            if (&amp;quot;error&amp;quot; in msg) {&lt;br /&gt;
		            	self.updateStatus(&amp;quot;Error loading data. The account&amp;#039;s RuneMetrics profile may be private.&amp;quot;);&lt;br /&gt;
		                console.error(&amp;quot;Could not fetch skills data&amp;quot;);&lt;br /&gt;
		            } else {&lt;br /&gt;
		                var userLevels = {};&lt;br /&gt;
		                msg.skillvalues.forEach(function(item, index){&lt;br /&gt;
		                    userLevels[skills[item.id]] = item.level; &lt;br /&gt;
		                });&lt;br /&gt;
		                self.addSkillIcons(userLevels);&lt;br /&gt;
		            }&lt;br /&gt;
		        }&lt;br /&gt;
		    });&lt;br /&gt;
		    &lt;br /&gt;
		    self.updateStatus(&amp;#039;Quest and skills data loaded for &amp;#039; + rsn);&lt;br /&gt;
         },&lt;br /&gt;
         &lt;br /&gt;
         /**&lt;br /&gt;
          * Adds icons next to respective quest points&lt;br /&gt;
          */&lt;br /&gt;
         addQuestPoints: function (questPoints) {&lt;br /&gt;
         	var qpRegex = /([0-9]+)\squest point/gi;&lt;br /&gt;
         	$(ACTIVATOR_CLASS + &amp;quot; li:not(:has(&amp;gt;ul))&amp;quot;).each(function(index) {&lt;br /&gt;
         		var icon = $(this).find(&amp;#039;.rs-qc-icon&amp;#039;)&lt;br /&gt;
         		var matches = qpRegex.exec($(this).text())&lt;br /&gt;
         		if (matches &amp;amp;&amp;amp; matches.length) {&lt;br /&gt;
         			// This is a list element in the format of &amp;quot;[x]&amp;quot; quest points&lt;br /&gt;
         			// Now we get the first capture group, which contains the number&lt;br /&gt;
         			var requiredPoints = matches[1]&lt;br /&gt;
         			if (requiredPoints &amp;gt; questPoints) {&lt;br /&gt;
         				// Does not have the required points&lt;br /&gt;
		            	if (icon.length !== 0) {&lt;br /&gt;
		            		var existingImg = icon.eq(0).find(&amp;#039;img&amp;#039;).eq(0);&lt;br /&gt;
		            		existingImg.attr(&amp;#039;src&amp;#039;, icons.no);&lt;br /&gt;
		            		existingImg.attr(&amp;#039;title&amp;#039;, &amp;#039;You have &amp;#039; + questPoints + &amp;#039; quest points.&amp;#039;)&lt;br /&gt;
		            	} else {&lt;br /&gt;
		            		$(this).append(&amp;#039; &amp;lt;span class=&amp;quot;rs-qc-icon&amp;quot;&amp;gt;&amp;lt;img class=&amp;quot;qc-not-started&amp;quot; src=&amp;quot;&amp;#039; + icons.no + &amp;#039;&amp;quot; width=&amp;quot;13px&amp;quot; title=&amp;quot;You have &amp;#039; + questPoints + &amp;#039; quest points.&amp;quot; &amp;gt;&amp;lt;/span&amp;gt; &amp;#039;);&lt;br /&gt;
		            	}&lt;br /&gt;
         			} else if (requiredPoints &amp;lt;= questPoints) {&lt;br /&gt;
         				// Has the required points&lt;br /&gt;
		            	if (icon.length !== 0) {&lt;br /&gt;
		            		var existingImg = icon.eq(0).find(&amp;#039;img&amp;#039;).eq(0);&lt;br /&gt;
		            		existingImg.attr(&amp;#039;src&amp;#039;, icons.yes);&lt;br /&gt;
		            		existingImg.attr(&amp;#039;title&amp;#039;, &amp;#039;You have &amp;#039; + questPoints + &amp;#039; quest points.&amp;#039;)&lt;br /&gt;
		            	} else {&lt;br /&gt;
         					$(this).append(&amp;#039; &amp;lt;span class=&amp;quot;rs-qc-icon&amp;quot;&amp;gt;&amp;lt;img class=&amp;quot;qc-complete&amp;quot; src=&amp;quot;&amp;#039; + icons.yes + &amp;#039;&amp;quot; width=&amp;quot;15px&amp;quot; title=&amp;quot;You have &amp;#039; + questPoints + &amp;#039; quest points.&amp;quot; &amp;gt;&amp;lt;/span&amp;gt; &amp;#039;);&lt;br /&gt;
		            	}&lt;br /&gt;
         			}&lt;br /&gt;
         		}&lt;br /&gt;
         	});&lt;br /&gt;
         },&lt;br /&gt;
         &lt;br /&gt;
         /**&lt;br /&gt;
          * Adds the icons next to respective quests&lt;br /&gt;
          */&lt;br /&gt;
         addQuestIcons: function (quests) {&lt;br /&gt;
		    $(ACTIVATOR_CLASS + &amp;quot; a&amp;quot;).each(function(index) {&lt;br /&gt;
		        if ($(this).html().toLowerCase() != &amp;quot;expand&amp;quot; || $(this).html().toLowerCase() != &amp;quot;collapse&amp;quot;) {&lt;br /&gt;
		            var questTitle = $(this).text().trim(),&lt;br /&gt;
		            	icon = $(this).find(&amp;#039;.rs-qc-icon&amp;#039;),&lt;br /&gt;
		            	imgsrc = &amp;#039;&amp;#039;;&lt;br /&gt;
		            if ($(this).parents(&amp;#039;table&amp;#039; + LIGHTTABLE_CLASS).length) {&lt;br /&gt;
		            	/* We are in a highlight table, so we need to handle things differently&lt;br /&gt;
		            	   Because highlight tables have no exposed API, we have to trigger the click handler&lt;br /&gt;
		            	   that Gadget-highlighttable.js adds to the rows in order to highlight&lt;br /&gt;
		            	   and set the data accordingly. It&amp;#039;s messy, but it will probably work */&lt;br /&gt;
		            	var trs = $(this).parents(&amp;#039;tr&amp;#039;)&lt;br /&gt;
		            	if (trs.length) {&lt;br /&gt;
		            		var parent = trs[0]&lt;br /&gt;
		            		if (quests[questTitle] == &amp;quot;COMPLETED&amp;quot;) {&lt;br /&gt;
		            			$(parent).trigger(&amp;#039;click&amp;#039;)&lt;br /&gt;
		            		}&lt;br /&gt;
		            	}&lt;br /&gt;
		            } else {&lt;br /&gt;
			            if (quests[questTitle] == &amp;quot;COMPLETED&amp;quot;) {&lt;br /&gt;
			            	if (icon.length !== 0) {&lt;br /&gt;
			            		icon.eq(0).find(&amp;#039;img&amp;#039;).eq(0).attr(&amp;#039;src&amp;#039;, icons.yes );&lt;br /&gt;
			            	} else {&lt;br /&gt;
			                	$(this).append(&amp;#039; &amp;lt;span class=&amp;quot;rs-qc-icon&amp;quot;&amp;gt;&amp;lt;img class=&amp;quot;qc-complete&amp;quot; src=&amp;quot;&amp;#039; + icons.yes + &amp;#039;&amp;quot; width=&amp;quot;15px&amp;quot; &amp;gt;&amp;lt;/span&amp;gt;&amp;#039;);&lt;br /&gt;
			            	}&lt;br /&gt;
			            }&lt;br /&gt;
			            if (quests[questTitle] == &amp;quot;NOT_STARTED&amp;quot;) {&lt;br /&gt;
			            	if (icon.length !== 0) {&lt;br /&gt;
			            		icon.eq(0).find(&amp;#039;img&amp;#039;).eq(0).attr(&amp;#039;src&amp;#039;, icons.no );&lt;br /&gt;
			            	} else {&lt;br /&gt;
			                	$(this).append(&amp;#039; &amp;lt;span class=&amp;quot;rs-qc-icon&amp;quot;&amp;gt;&amp;lt;img class=&amp;quot;qc-not-started&amp;quot; src=&amp;quot;&amp;#039; + icons.no + &amp;#039;&amp;quot; width=&amp;quot;13px&amp;quot; &amp;gt;&amp;lt;/span&amp;gt;&amp;#039;);&lt;br /&gt;
			            	}&lt;br /&gt;
			            }&lt;br /&gt;
			            if (quests[questTitle] == &amp;quot;STARTED&amp;quot;) {&lt;br /&gt;
			            	if (icon.length !== 0) {&lt;br /&gt;
			            		icon.eq(0).find(&amp;#039;img&amp;#039;).eq(0).attr(&amp;#039;src&amp;#039;, icons.started );&lt;br /&gt;
			            	} else {&lt;br /&gt;
			                	$(this).append(&amp;#039; &amp;lt;span class=&amp;quot;rs-qc-icon&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;qc-in-progress&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;#039;);&lt;br /&gt;
			            	}&lt;br /&gt;
			            }&lt;br /&gt;
		            }&lt;br /&gt;
		        }&lt;br /&gt;
		    });&lt;br /&gt;
         },&lt;br /&gt;
&lt;br /&gt;
         /**&lt;br /&gt;
          * Adds the icons next to respective skills&lt;br /&gt;
          */&lt;br /&gt;
         addSkillIcons: function (userLevels) {&lt;br /&gt;
		    $(ACTIVATOR_CLASS + &amp;quot; &amp;gt; ul &amp;gt; li&amp;quot;).each(function(index) {&lt;br /&gt;
		        var textArr = $(this).text().split(&amp;quot; &amp;quot;),&lt;br /&gt;
		        	level = textArr[0],&lt;br /&gt;
		        	imgsrc = &amp;quot;&amp;quot;;&lt;br /&gt;
		        if (isNaN(level)) { //Check if it is a number.&lt;br /&gt;
		            return;&lt;br /&gt;
		        }&lt;br /&gt;
&lt;br /&gt;
		        var skillElement = $(this).find(&amp;quot;a&amp;quot;).filter(function(index) {&lt;br /&gt;
		            // Find the link element which has a skill name.&lt;br /&gt;
		            return ($(this).text().trim() in userLevels);&lt;br /&gt;
		        });&lt;br /&gt;
		        &lt;br /&gt;
		        skillElement.each(function(index) {&lt;br /&gt;
			        var skill = $(this).text().trim(),&lt;br /&gt;
			        	icon = $(this).find(&amp;#039;.rs-qc-icon&amp;#039;);&lt;br /&gt;
			        &lt;br /&gt;
			        if (level !== &amp;quot;&amp;quot; &amp;amp;&amp;amp; skill !== &amp;quot;&amp;quot;){&lt;br /&gt;
			            if (userLevels[skill] &amp;gt;= level) {&lt;br /&gt;
			            	if (icon.length !== 0) {&lt;br /&gt;
			            		icon.eq(0).find(&amp;#039;img&amp;#039;).eq(0).attr(&amp;#039;src&amp;#039;, icons.yes );&lt;br /&gt;
			            	} else {&lt;br /&gt;
			                	skillElement.append(&amp;#039; &amp;lt;span class=&amp;quot;rs-qc-icon&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&amp;#039; + icons.yes + &amp;#039;&amp;quot; width=&amp;quot;15px&amp;quot; &amp;gt;&amp;lt;/span&amp;gt;&amp;#039;);&lt;br /&gt;
			            	}&lt;br /&gt;
			            } else {&lt;br /&gt;
			            	if (icon.length !== 0) {&lt;br /&gt;
			            		icon.eq(0).find(&amp;#039;img&amp;#039;).eq(0).attr(&amp;#039;src&amp;#039;, icons.no );&lt;br /&gt;
			            	} else {&lt;br /&gt;
			                	skillElement.append(&amp;#039; &amp;lt;span class=&amp;quot;rs-qc-icon&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&amp;#039; + icons.no + &amp;#039;&amp;quot; width=&amp;quot;15px&amp;quot; &amp;gt;&amp;lt;/span&amp;gt;&amp;#039;);&lt;br /&gt;
			            	}&lt;br /&gt;
			            }&lt;br /&gt;
			        }&lt;br /&gt;
		        })&lt;br /&gt;
		    });&lt;br /&gt;
         }&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
$(self.init);&lt;br /&gt;
&lt;br /&gt;
// &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Banri</name></author>
	</entry>
</feed>