company {
	name:
		VST3: PFactoryInfo.vendor
		LV2: manifest.ttl doap:maintainer foaf:name
		web: not used
		cmd: not used
		android: not used
		ios: not used
	url:
		VST3: PFactoryInfo.url
		LV2: manifest.ttl doap:maintainer rdfs:seeAlso
		web: not used
		cmd: not used
		android: not used
		ios: not used
	email:
		VST3: PFactoryInfo.email
		LV2: manifest.ttl doap:maintainer foaf:mbox
		web: not used
		cmd: not used
		android: not used
		ios: not used
}

product {
	name:
		VST3: PClassInfo{,2,W}.name
		LV2: manifest.ttl plugin doap:name
		web: web-demo <title> and <h1>
		cmd: not used
		android: index.html <title>, AndroidManifest.xml <application> <activity> android:label
		ios: index.html <title>
	version:
		VST3: PClassInfo{2,W}.version (first 3 numbers)
		LV2: not used
		web: not used
		cmd: not used
		android: not used
		ios: not used
	buildVersion:
		VST3: PClassInfo{2,W}.version (last number)
		LV2: not used
		web: not used
		cmd: not used
		android: not used
		ios: not used
	bundleName:
		VST3: plugin folder name, plugin .dll name, Info.plist
		LV2: plugin folder name, plugin .dll name, manifest.ttl plugin lv2:binary
		web: registerProcessor(), output file names
		cmd: executable file name
		android: .so/.apk filenames
		ios: xcodegen name and target name, xcodeproj filename
	buses: [
		{
			name:
				bus name string, required
				VST3: BusInfo name
				LV2: manifest.ttl lv2:port lv2:name
				web: not used
				cmd: not used
				android: not used
				ios: not used
			shortName:
				bus short name string, required
				VST3: not used
				LV2: manifest.ttl lv2:port lv2:shortName
				web: not used
				cmd: not used
				android: not used
				ios: not used
			id:
				bus unique id string, required
				VST3; not used
				LV2: manifest.ttl lv2:port lv2:symbol (resulting ports can have _l or _r appended)
				web: not used
				cmd: not used
				android: not used
				ios: not used
			direction:
				"input" or "output", required
				VST3: BusInfo flags - lots of implications
				LV2: manifest.ttl lv2:port a - lots of implications
				web: AudioWorkletNode.{numberOfInputs,numberOfOutputs,outputChannelCount} - lots of implications
				cmd: lots of places
				android: lots of places
				ios: lots of places
			type:
				"audio" or "midi", required
				VST3: BusInfo mediaType, ParameterInfo (channel pressure, pitch bend params) - lots of implications
				LV2: lots of implications everywhere
				web: AudioWorkletNode.{numberOfInputs,numberOfOutputs,outputChannelCount} - lots of implications
				cmd: lots of places
				android: lots of places
				ios: lots of places
			channels:
				"mono" or "stereo", audio type only, required
				VST3: BusInfo channelCount, plugin get/set bus arrangements
				LV2: manifest.ttl lv2:port - lots of implications
				web: AudioWorkletNode.outputChannelCount - lots of implications
				cmd: lots of places
				android: lots of places
				ios: lots of places
			sidechain:
				bus is not part of main audio path (sidechain)? boolean, default false
				VST3: BusInfo busType
				LV2: manifest.ttl lv2:port lv2:portProperty lv2:isSideChain
				web: web-demo choice of audio I/O buses
				cmd: choice of audio I/O buses
				android: choice of audio I/O buses
			cv:
				bus is control voltage audio-rate? boolean, audio type only, default false
				VST3: BusInfo flags
				LV2: manifest.ttl lv2:port a lv2:CVPort
				web: web-demo choice of audio I/O buses
				cmd: choice of audio I/O buses
				android: choice of audio I/O buses
				ios: choice of audio I/O buses
			control:
				bus is the "primary control channel" (send cmds, receive responses)? boolean, midi type only, default false
				VST3: not used
				LV2: manifest.ttl lv2:port lv2:designation lv2:control
				web: not used
				cmd: not used
				android: not used
				ios: not used
			optional:
				bus is optionally connected? boolean, default false
				VST3: BusInfo flags, plugin initialize, activate bus, set active
				LV2: manifest.ttl lv2:port lv2:portProperty lv2:connectionOptional
				web: not used
				cmd: whether to pass NULLs if not chosen audio I/O buses
				android: whether to pass NULLs if not chosen audio I/O buses
				ios: whether to pass NULLs if not chosen audio I/O buses
		}
	]
	parameters: [
		{
			name:
				parameter name string, required
				VST3: ParameterInfo title
				LV2: manifest.ttl lv2:port lv2:name
				web: AudioWorkletProcessor.parameterDescriptors, web-demo <label>
				cmd: not used
				android: index.html <label>
				ios: index.html <label>
			shortName:
				parameter short name string, required
				VST3: ParameterInfo shortTitle
				LV2: manifest.ttl lv2:port lv2:shortName
				web: not used
				cmd: not used
				android: not used
				ios: not used
			id:
				parameter unique id string, required
				VST3; not used
				LV2: manifest.ttl lv2:port lv2:symbol (bypass ports used "enabled")
				web: not used
				cmd: command line parameter name etc.
				android: not used
				ios: not used
			direction:
				"input" or "output", required
				VST3: ParameterInfo flags - lots of implications
				LV2: manifest.ttl lv2:port a - lots of implications
				web: AudioWorkletProcessor.parameterDescriptors, web-demo <range> readonly/input listener - lots of implications
				cmd: lots of places
				android: lots of places
				ios: lots of places
			isBypass:
				parameter is bypass/enabled? boolean - lots of implications, default false
				VST3: ParameterInfo, controller get/set parameter/state
				LV2: manifest.ttl lv2:port, run() (set parameter)
				web: AudoWorkletProcessor.process(), web-demo <range> min/max/step
				cmd: set parameter
				android: JNI set parameter, index.html <range> min/max/step
				ios: native set parameter, index.html <range> min/max/step
			isLatency:
				parameter is latency output? boolean - lots of implications, default false
				VST3: TBD
				LV2: manifest.ttl lv2:port, TBD round output value
				web: not (yet) used
				cmd: not (yet) used
				android: not (yet) used
				ios: not (yet) used
			defaultValue:
				default value, number, mapped, required for non-bypass
				VST3: ParameterInfo defaultNormalizedValue, controller initialize
				LV2: manifest.ttl lv2:port lv2:default, activate() (set initial parameter)
				web: AudioWorkletProcessor.parameterDescriptors, processor_new(), web-demo initial <range> value and value <span> innerText
				cmd: default parameter value
				android: JNI set parameter initial value, index.html initial <range> value
				ios: native set parameter initial value, index.html initial <range> value
			minimum:
				minimum value, number, mapped, required for non-bypass
				VST3: ParameterInfo stepCount, defaultNormalizedValue, controller get/set parameter (value clamped)
				LV2: manifest.ttl lv2:port lv2:minimum, run() (set parameter, value clamped)
				web: AudioWorkletProcessor.parameterDescriptors, AudioWorkletProcessor.process() (value clamped), web-demo <range> mapping
				cmd: set parameter (value clamped)
				android: JNI set parameter (value clamped), index.html <range> mapping
				ios: native set parameter (value clamped), index.html <range> mapping
			maximum:
				maximum value, number, mapped, required for non-bypass
				VST3: ParameterInfo stepCount, defaultNormalizedValue, controller get/set parameter (value clamped)
				LV2: manifest.ttl lv2:port lv2:maximum, run() (set parameter, value clamped)
				web: AudioWorkletProcessor.parameterDescriptors, AudioWorkletProcessor.process() (value clamped), web-demo <range> mapping
				cmd: set parameter (value clamped)
				android: JNI set parameter (value clamped), index.html <range> mapping
				ios: native set parameter (value clamped), index.html <range> mapping
			toggled:
				parameter is on/off? boolean, default false
				VST3: ParameterInfo stepCount, controller set parameter/state
				LV2: manifest.ttl lv2:port lv2:portProperty lv2:toggled, run() (set parameter)
				web: AudoWorkletProcessor.process(), web-demo <range> min/max/step
				cmd: set parameter
				android: JNI set parameter, index.html <range> min/max/step
				ios: native set parameter, index.html <range> min/max/step
			optional:
				parameter is optionally connected? boolean, default false
				VST3: not used
				LV2: manifest.ttl lv2:port lv2:portProperty lv2:connectionOptional
				web: not used
				cmd: not used
				android: not used
				ios: not used
			integer:
				parameter values are integers? boolean, default false
				VST3: ParameterInfo stepCount, controller set parameter/state
				LV2: manifest.ttl lv2:port lv2:portProperty lv2:integer, run() (set parameter)
				web: AudoWorkletProcessor.process(), web-demo <range> step
				cmd: set parameter
				android: JNI set parameter, index.html <range> step
				ios: native set parameter, index.html <range> step
			scalePoints:
				{ "label1": value1, "label2", value2, ... }
				labeled values, default none
				VST3: TBD
				LV2: manifest.ttl lv2:port lv2:scalePoint
				web: not (yet) used
				cmd: not (yet) used
				android: not (yet) used
				ios: not (yet) used
			list:
				parameter is a list (using scalePoints values)? default false
				VST3: TBD (+approx to closest?)
				LV2: manifest.ttl lv2:port lv2:enumeration - run() (set parameter) TBD?
				web: TBD (approx to closest? dropdown? both?)
				cmd: not (yet) used
				android: not (yet) used
				ios: not (yet) used
			unit:
				unit of measure (from predefined list, see tibia-index.js), default ""
				VST3: ParameterInfo units
				LV2: manifest.ttl lv2:port units:unit
				web: web-demo value <span> innerText
				cmd: not (yet) used
				android: not (yet) used
				ios: not (yet) used
			map:
				"linear" vs "logarithmic"
				VST3: many places (requires libm)
				LV2: manifest.ttl lv2:port lv2:portProperty pprops:logarithmic
				web: web-demo <range> values
				cmd: not used
				android: index.html <range> values
				ios: index.html <range> values
		}
	]
}