docs: function pc_dump() {
  
  var hidden = 0;
  
  	console.log('\n* Programme Cache:');
  	for (var i in programme_cache) {
  		var p = programme_cache[i];
  
  		var present = giUtils.binarySearch(download_history,p.pid)>=0;
  
  		var title = (p.title ? p.title : p.presentation_title);
  		var parents = '';
  		var ancestor_titles = '';
  		for (var at in p.ancestor_titles) {
  			present = present || (download_history.indexOf(p.ancestor_titles[at].pid)>=0);
  			var t = '';
  			if (p.ancestor_titles[at].title) {
  				t = p.ancestor_titles[at].title;
  			}
  			else if (p.ancestor_titles[at].presentation_title) {
  				t = p.ancestor_titles[at].presentation_title;
  			}
  			if (p.ancestor_titles[at].ancestor_type != 'episode') {
  				ancestor_titles += t + ' : ';
  			}
  			else if (!title) {
  				title = t;
  			}
  			parents += '  ' + p.ancestor_titles[at].pid + ' ('+t+') ';
  		}
  		title = ancestor_titles + title;
  		if (p.version && p.version.pid) {
  			parents += '  ' + p.version.pid + ' (vPID)';
  		}
  
  		var available = ((p.available_versions) && (p.available_versions.available > 0));
  
  		if  ((!present && available) || (pidList.indexOf(p.pid)>=0) || showAll) {
  
  			if (programme_cache.length==1) {
  				debuglog(JSON.stringify(p,null,2));
  			}
  
  			var position = p.episode_of ? p.episode_of.position : 1;
  			var totaleps = p.x_parent && p.x_parent.expected_child_count ? p.x_parent.expected_child_count : 1;
  			var series = 1;
  
  			console.log(p.pid+' '+pad(p.item_type,'       ',true)+' '+
  				(p.media_type ? p.media_type : 'Audio')+' '+(available ? 'Available' : 'Unavailable')+'  '+green+title+normal);
  
  			var len = (p.version && p.version.duration) ? p.version.duration : '0s';
  
  			if (p.available_versions) {
  				for (var v in p.available_versions.version) {
  				    var version = p.available_versions.version[v];
  					if (len == '0s') {
  						len = version.duration;
  					}
  					parents += '  ' + version.pid + ' (vPID '+version.types.type[0]+')';
  					for (var va in p.available_versions.version[v].availabilities) {
  						var a = p.available_versions.version[v].availabilities[va];
  						// dump mediasets
  						if (dumpMediaSets) {
  							for (var vaa in a) {
  								var vaaa = a[vaa];
  								for (var ms in vaaa.media_sets.media_set) {
  									console.log(p.available_versions.version[v].pid+' '+vaaa.status+' '+vaaa.media_sets.media_set[ms].name);
  								}
  							}
  						}
  					}
  				}
  			}
  
  			if (!len) len = '';
  			len = len.replace('PT','').toLocaleLowerCase(); // ISO 8601 duration
  
  			console.log('  '+len+' S'+pad(series,'00')+'E'+pad(position,'00')+
  				'/'+pad(totaleps,'00')+' '+(p.synopses && p.synopses.short ? p.synopses.short : 'No description'));
  			if (parents) console.log(parents);
  			if (p.master_brand) {
  				console.log('  '+p.master_brand.mid+' @ '+(p.release_date ? p.release_date :
  					(p.release_year ? p.release_year : p.updated_time)));
  			}
  
  			if (p.contributions) {
  				console.log();
  				var contribution = toArray(p.contributions.contribution);
  				for (var cont of contribution) {
  					console.log((cont.character_name ? cont.character_name : (cont.credit_role ? cont.credit_role.$ : 'Unknown'))+' - '+
  						(cont.contributor && cont.contributor.name ? (cont.contributor.name.given ? cont.contributor.name.given+' '+cont.contributor.name.family :
  						cont.contributor.name.presentation) : 'Unknown'));
  				}
  			}
  
  			//if (p.x_parent) {
  			//	console.log(JSON.stringify(p.x_parent,null,2));
  			//}
  
  		}
  		else {
  			hidden++;
  		}
  	}
  
  	if (programme_cache.length == 1) {
  		var item = programme_cache[0];
  		if (item.synopses && (item.synopses.long || item.synopses.medium)) {
  			console.log();
  			console.log(item.synopses.long ? item.synopses.long : item.synopses.medium);
  		}
  	}
  
  	console.log();
  	console.log('Cache has '+programme_cache.length+' entries, '+hidden+' hidden');
  }