# Copyright (c) 2015-2019 Hanspeter Portner (dev@open-music-kontrollers.ch)
#
# This is free software: you can redistribute it and/or modify
# it under the terms of the Artistic License 2.0 as published by
# The Perl Foundation.
#
# This source is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Artistic License 2.0 for more details.
#
# You should have received a copy of the Artistic License 2.0
# along the source as a COPYING file. If not, obtain it from
# http://www.perlfoundation.org/artistic_license_2_0.

@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix doap: <http://usefulinc.com/ns/doap#> .
@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
@prefix work: <http://lv2plug.in/ns/ext/worker#> .
@prefix midi: <http://lv2plug.in/ns/ext/midi#> .
@prefix time: <http://lv2plug.in/ns/ext/time#> .
@prefix state: <http://lv2plug.in/ns/ext/state#> .
@prefix patch: <http://lv2plug.in/ns/ext/patch#> .
@prefix rdfs:	<http://www.w3.org/2000/01/rdf-schema#> .
@prefix rsz:  <http://lv2plug.in/ns/ext/resize-port#> .
@prefix bufsz: <http://lv2plug.in/ns/ext/buf-size#> .
@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
@prefix opts: <http://lv2plug.in/ns/ext/options#> .
@prefix param: <http://lv2plug.in/ns/ext/parameters#> .
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
@prefix kx:		<http://kxstudio.sf.net/ns/lv2ext/external-ui#> .
@prefix idisp: <http://harrisonconsoles.com/lv2/inlinedisplay#> .

@prefix xpress: <http://open-music-kontrollers.ch/lv2/xpress#> .
@prefix osc:  <http://open-music-kontrollers.ch/lv2/osc#> .
@prefix lic:	<http://opensource.org/licenses/> .
@prefix omk:	<http://open-music-kontrollers.ch/ventosus#> .
@prefix proj:	<http://open-music-kontrollers.ch/lv2/> .
@prefix moony:	<http://open-music-kontrollers.ch/lv2/moony#> .

# to please sord_validate
idisp:queue_draw
	a lv2:Feature .
idisp:interface
	a lv2:ExtensionData .
xpress:voiceMap
	a lv2:Feature .
osc:schedule
	a lv2:Feature .

osc:Event
	a rdfs:Class ;
	rdfs:subClassOf atom:Object ;
	rdfs:label "OSC Event (Bundle or Message)" .

# Maintainer
omk:me
	a foaf:Person ;
	foaf:name "Hanspeter Portner" ;
	foaf:mbox <mailto:dev@open-music-kontrollers.ch> ;
	foaf:homepage <http://open-music-kontrollers.ch> .

# Project
proj:moony
	a doap:Project ;
	doap:maintainer omk:me ;
	doap:developer omk:me ;
	doap:name "Moony Bundle" .

# Parameters
moony:error
	a lv2:Parameter ;
	rdfs:label "Error" ;
	rdfs:comment "shows current error message" ;
	rdfs:range atom:String .

moony:editorHidden
	a lv2:Parameter ;
	rdfs:label "Editor hidden" ;
	rdfs:comment "hidden state of editor tab" ;
	rdfs:range atom:Bool .

moony:logHidden
	a lv2:Parameter ;
	rdfs:label "Log hidden" ;
	rdfs:comment "hidden state of log tab" ;
	rdfs:range atom:Bool .

moony:logFollow
	a lv2:Parameter ;
	rdfs:label "Log follow" ;
	rdfs:comment "follow state of log tab" ;
	rdfs:range atom:Bool .

moony:logReset
	a lv2:Parameter ;
	rdfs:label "Log reset" ;
	rdfs:comment "reset log upon code send" ;
	rdfs:range atom:Bool .

moony:paramHidden
	a lv2:Parameter ;
	rdfs:label "Parameter hidden" ;
	rdfs:comment "hidden state of parameter tab" ;
	rdfs:range atom:Bool .

moony:paramCols
	a lv2:Parameter ;
	rdfs:label "Parameter columns" ;
	rdfs:comment "number of columns in parameter tab" ;
	rdfs:range atom:Int ;
	lv2:minimum 1 ;
	lv2:maximum 16 .

moony:paramRows
	a lv2:Parameter ;
	rdfs:label "Parameter rows" ;
	rdfs:comment "number of rows in parameter tab" ;
	rdfs:range atom:Int ;
	lv2:minimum 1 ;
	lv2:maximum 16 .

moony:code
	a lv2:Parameter ;
	rdfs:label "Code" ;
	rdfs:comment "shows script code" ;
	rdfs:range atom:String .

# C1XC1 Plugin
moony:c1xc1
	a lv2:Plugin ,
		lv2:ConverterPlugin ;
	doap:name "Moony C1 x C1" ;
	doap:license lic:Artistic-2.0 ;
	rdfs:comment "Realtime Lua as programmable glue in LV2";
	lv2:project proj:moony ;
	lv2:optionalFeature lv2:isLive, lv2:hardRTCapable, bufsz:boundedBlockLength, osc:schedule, state:loadDefaultState, xpress:voiceMap, state:threadSafeRestore, opts:options ;
	lv2:extensionData work:interface, state:interface ;
	#lv2:optionalFeature idisp:queue_draw ;
	#lv2:extensionData idisp:interface ;
	lv2:requiredFeature work:schedule, urid:map, urid:unmap ;
	opts:supportedOption bufsz:minBlockLength, bufsz:maxBlockLength, bufsz:nominalBlockLength, bufsz:sequenceSize, ui:updateRate, param:sampleRate ;

	lv2:port [
	# input control ports
	  a lv2:InputPort ,
			lv2:ControlPort ;
		lv2:index 0 ;
		lv2:symbol "input_1" ;
		lv2:name "Input 1" ;
		lv2:default 0.0;
		lv2:minimum 0.0 ;
		lv2:maximum 1.0 ;
	] , [
	# output control ports
	  a lv2:OutputPort ,
			lv2:ControlPort ;
		lv2:index 1 ;
		lv2:symbol "output_1" ;
		lv2:name "Output 1" ;
	] , [
	# input control port
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 2 ;
		lv2:symbol "control" ;
		lv2:name "Control" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] , [
	# output notify port
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 3 ;
		lv2:symbol "notify" ;
		lv2:name "Notify" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] ;

	patch:readable
		moony:error ;

	patch:writable
		moony:code ;
	
	state:state [
		moony:editorHidden false ;
		moony:logHidden true ;
		moony:logFollow true ;
		moony:logReset false ;
		moony:paramHidden true ;
		moony:paramCols 3 ;
		moony:paramRows 4 ;
		moony:code """function run(n, control, notify, c1)
	return c1
end"""
	] .

# C2XC2 Plugin
moony:c2xc2
	a lv2:Plugin ,
		lv2:ConverterPlugin ;
	doap:name "Moony C2 x C2" ;
	doap:license lic:Artistic-2.0 ;
	rdfs:comment "Realtime Lua as programmable glue in LV2";
	lv2:project proj:moony ;
	lv2:optionalFeature lv2:isLive, lv2:hardRTCapable, bufsz:boundedBlockLength, osc:schedule, state:loadDefaultState, xpress:voiceMap, state:threadSafeRestore, opts:options ;
	lv2:extensionData work:interface, state:interface ;
	#lv2:optionalFeature idisp:queue_draw ;
	#lv2:extensionData idisp:interface ;
	lv2:requiredFeature work:schedule, urid:map, urid:unmap ;
	opts:supportedOption bufsz:minBlockLength, bufsz:maxBlockLength, bufsz:nominalBlockLength, bufsz:sequenceSize, ui:updateRate, param:sampleRate ;

	lv2:port [
	# input control ports
	  a lv2:InputPort ,
			lv2:ControlPort ;
		lv2:index 0 ;
		lv2:symbol "input_1" ;
		lv2:name "Input 1" ;
		lv2:default 0.0;
		lv2:minimum 0.0 ;
		lv2:maximum 1.0 ;
	] , [
	  a lv2:InputPort ,
			lv2:ControlPort ;
		lv2:index 1 ;
		lv2:symbol "input_2" ;
		lv2:name "Input 2" ;
		lv2:default 0.0;
		lv2:minimum 0.0 ;
		lv2:maximum 1.0 ;
	] , [
	# output control ports
	  a lv2:OutputPort ,
			lv2:ControlPort ;
		lv2:index 2 ;
		lv2:symbol "output_1" ;
		lv2:name "Output 1" ;
	] , [
	  a lv2:OutputPort ,
			lv2:ControlPort ;
		lv2:index 3 ;
		lv2:symbol "output_2" ;
		lv2:name "Output 2" ;
	] , [
	# input control port
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 4 ;
		lv2:symbol "control" ;
		lv2:name "Control" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] , [
	# output notify port
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 5 ;
		lv2:symbol "notify" ;
		lv2:name "Notify" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] ;

	patch:readable
		moony:error ;

	patch:writable
		moony:code ;
	
	state:state [
		moony:editorHidden false ;
		moony:logHidden true ;
		moony:logFollow true ;
		moony:logReset false ;
		moony:paramHidden true ;
		moony:paramCols 3 ;
		moony:paramRows 4 ;
		moony:code """function run(n, control, notify, c1, c2)
	return c1, c2
end"""
	] .

# C4XC4 Plugin
moony:c4xc4
	a lv2:Plugin ,
		lv2:ConverterPlugin ;
	doap:name "Moony C4 x C4" ;
	doap:license lic:Artistic-2.0 ;
	rdfs:comment "Realtime Lua as programmable glue in LV2";
	lv2:project proj:moony ;
	lv2:optionalFeature lv2:isLive, lv2:hardRTCapable, bufsz:boundedBlockLength, osc:schedule, state:loadDefaultState, xpress:voiceMap, state:threadSafeRestore, opts:options ;
	lv2:extensionData work:interface, state:interface ;
	#lv2:optionalFeature idisp:queue_draw ;
	#lv2:extensionData idisp:interface ;
	lv2:requiredFeature work:schedule, urid:map, urid:unmap ;
	opts:supportedOption bufsz:minBlockLength, bufsz:maxBlockLength, bufsz:nominalBlockLength, bufsz:sequenceSize, ui:updateRate, param:sampleRate ;

	lv2:port [
	# input control ports
	  a lv2:InputPort ,
			lv2:ControlPort ;
		lv2:index 0 ;
		lv2:symbol "input_1" ;
		lv2:name "Input 1" ;
		lv2:default 0.0 ;
		lv2:minimum 0.0 ;
		lv2:maximum 1.0 ;
	] , [
	  a lv2:InputPort ,
			lv2:ControlPort ;
		lv2:index 1 ;
		lv2:symbol "input_2" ;
		lv2:name "Input 2" ;
		lv2:default 0.0 ;
		lv2:minimum 0.0 ;
		lv2:maximum 1.0 ;
	] , [
	  a lv2:InputPort ,
			lv2:ControlPort ;
		lv2:index 2 ;
		lv2:symbol "input_3" ;
		lv2:name "Input 3" ;
		lv2:default 0.0 ;
		lv2:minimum 0.0 ;
		lv2:maximum 1.0 ;
	] , [
	  a lv2:InputPort ,
			lv2:ControlPort ;
		lv2:index 3 ;
		lv2:symbol "input_4" ;
		lv2:name "Input 4" ;
		lv2:default 0.0 ;
		lv2:minimum 0.0 ;
		lv2:maximum 1.0 ;
	] , [
	# output control ports
	  a lv2:OutputPort ,
			lv2:ControlPort ;
		lv2:index 4 ;
		lv2:symbol "output_1" ;
		lv2:name "Output 1" ;
	] , [
	  a lv2:OutputPort ,
			lv2:ControlPort ;
		lv2:index 5 ;
		lv2:symbol "output_2" ;
		lv2:name "Output 2" ;
	] , [
	  a lv2:OutputPort ,
			lv2:ControlPort ;
		lv2:index 6 ;
		lv2:symbol "output_3" ;
		lv2:name "Output 3" ;
	] , [
	  a lv2:OutputPort ,
			lv2:ControlPort ;
		lv2:index 7 ;
		lv2:symbol "output_4" ;
		lv2:name "Output 4" ;
	] , [
	# input control port
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 8 ;
		lv2:symbol "control" ;
		lv2:name "Control" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] , [
	# output notify port
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 9 ;
		lv2:symbol "notify" ;
		lv2:name "Notify" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] ;

	patch:readable
		moony:error ;

	patch:writable
		moony:code ;
	
	state:state [
		moony:editorHidden false ;
		moony:logHidden true ;
		moony:logFollow true ;
		moony:logReset false ;
		moony:paramHidden true ;
		moony:paramCols 3 ;
		moony:paramRows 4 ;
		moony:code """function run(n, control, notify, c1, c2, c3, c4)
	return c1, c2, c3, c4
end"""
	] .

# A1XA1 Plugin
moony:a1xa1
	a lv2:Plugin ,
		lv2:ConverterPlugin ;
	doap:name "Moony A1 x A1" ;
	doap:license lic:Artistic-2.0 ;
	rdfs:comment "Realtime Lua as programmable glue in LV2";
	lv2:project proj:moony ;
	lv2:optionalFeature lv2:isLive, lv2:hardRTCapable, bufsz:boundedBlockLength, osc:schedule, state:loadDefaultState, xpress:voiceMap, state:threadSafeRestore, opts:options ;
	lv2:extensionData work:interface, state:interface ;
	#lv2:optionalFeature idisp:queue_draw ;
	#lv2:extensionData idisp:interface ;
	lv2:requiredFeature work:schedule, urid:map, urid:unmap ;
	opts:supportedOption bufsz:minBlockLength, bufsz:maxBlockLength, bufsz:nominalBlockLength, bufsz:sequenceSize, ui:updateRate, param:sampleRate ;

	lv2:port [
	# input event port
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 0 ;
		lv2:symbol "event_in_1" ;
		lv2:name "Event In 1" ;
	] , [
	# output event port
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 1 ;
		lv2:symbol "event_out_1" ;
		lv2:name "Event Out 1" ;
	] , [
	# input control port
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 2 ;
		lv2:symbol "control" ;
		lv2:name "Control" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] , [
	# output notify port
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 3 ;
		lv2:symbol "notify" ;
		lv2:name "Notify" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] ;

	patch:readable
		moony:error ;

	patch:writable
		moony:code ;

	state:state [
		moony:editorHidden false ;
		moony:logHidden true ;
		moony:logFollow true ;
		moony:logReset false ;
		moony:paramHidden true ;
		moony:paramCols 3 ;
		moony:paramRows 4 ;
		moony:code """function run(n, control, notify, seq, forge)
	for frames, atom in seq:foreach() do
		forge:time(frames):atom(atom)
	end
end"""
	] .

# A2XA2 Plugin
moony:a2xa2
	a lv2:Plugin ,
		lv2:ConverterPlugin ;
	doap:name "Moony A2 x A2" ;
	doap:license lic:Artistic-2.0 ;
	rdfs:comment "Realtime Lua as programmable glue in LV2";
	lv2:project proj:moony ;
	lv2:optionalFeature lv2:isLive, lv2:hardRTCapable, bufsz:boundedBlockLength, osc:schedule, state:loadDefaultState, xpress:voiceMap, state:threadSafeRestore, opts:options ;
	lv2:extensionData work:interface, state:interface ;
	#lv2:optionalFeature idisp:queue_draw ;
	#lv2:extensionData idisp:interface ;
	lv2:requiredFeature work:schedule, urid:map, urid:unmap ;
	opts:supportedOption bufsz:minBlockLength, bufsz:maxBlockLength, bufsz:nominalBlockLength, bufsz:sequenceSize, ui:updateRate, param:sampleRate ;

	lv2:port [
	# input event port
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 0 ;
		lv2:symbol "event_in_1" ;
		lv2:name "Event In 1" ;
	] , [
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 1 ;
		lv2:symbol "event_in_2" ;
		lv2:name "Event In 2" ;
	] , [
	# output event port
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 2 ;
		lv2:symbol "event_out_1" ;
		lv2:name "Event Out 1" ;
	] , [
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 3 ;
		lv2:symbol "event_out_2" ;
		lv2:name "Event Out 2" ;
	] , [
	# input control port
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 4 ;
		lv2:symbol "control" ;
		lv2:name "Control" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] , [
	# output notify port
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 5 ;
		lv2:symbol "notify" ;
		lv2:name "Notify" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] ;

	patch:readable
		moony:error ;

	patch:writable
		moony:code ;

	state:state [
		moony:editorHidden false ;
		moony:logHidden true ;
		moony:logFollow true ;
		moony:logReset false ;
		moony:paramHidden true ;
		moony:paramCols 3 ;
		moony:paramRows 4 ;
		moony:code """function run(n, control, notify, seq1, forge1, seq2, forge2)
	for frames, atom in seq1:foreach() do
		forge1:time(frames):atom(atom)
	end

	for frames, atom in seq2:foreach() do
		forge2:time(frames):atom(atom)
	end
end"""
	] .

# A4XA4 Plugin
moony:a4xa4
	a lv2:Plugin ,
		lv2:ConverterPlugin ;
	doap:name "Moony A4 x A4" ;
	doap:license lic:Artistic-2.0 ;
	rdfs:comment "Realtime Lua as programmable glue in LV2";
	lv2:project proj:moony ;
	lv2:optionalFeature lv2:isLive, lv2:hardRTCapable, bufsz:boundedBlockLength, osc:schedule, state:loadDefaultState, xpress:voiceMap, state:threadSafeRestore, opts:options ;
	lv2:extensionData work:interface, state:interface ;
	#lv2:optionalFeature idisp:queue_draw ;
	#lv2:extensionData idisp:interface ;
	lv2:requiredFeature work:schedule, urid:map, urid:unmap ;
	opts:supportedOption bufsz:minBlockLength, bufsz:maxBlockLength, bufsz:nominalBlockLength, bufsz:sequenceSize, ui:updateRate, param:sampleRate ;

	lv2:port [
	# input event port
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 0 ;
		lv2:symbol "event_in_1" ;
		lv2:name "Event In 1" ;
	] , [
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 1 ;
		lv2:symbol "event_in_2" ;
		lv2:name "Event In 2" ;
	] , [
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 2 ;
		lv2:symbol "event_in_3" ;
		lv2:name "Event In 3" ;
	] , [
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 3 ;
		lv2:symbol "event_in_4" ;
		lv2:name "Event In 4" ;
	] , [
	# output event port
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 4 ;
		lv2:symbol "event_out_1" ;
		lv2:name "Event Out 1" ;
	] , [
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 5 ;
		lv2:symbol "event_out_2" ;
		lv2:name "Event Out 2" ;
	] , [
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 6 ;
		lv2:symbol "event_out_3" ;
		lv2:name "Event Out 3" ;
	] , [
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 7 ;
		lv2:symbol "event_out_4" ;
		lv2:name "Event Out 4" ;
	] , [
	# input control port
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 8 ;
		lv2:symbol "control" ;
		lv2:name "Control" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] , [
	# output notify port
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 9 ;
		lv2:symbol "notify" ;
		lv2:name "Notify" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] ;

	patch:readable
		moony:error ;

	patch:writable
		moony:code ;

	state:state [
		moony:editorHidden false ;
		moony:logHidden true ;
		moony:logFollow true ;
		moony:logReset false ;
		moony:paramHidden true ;
		moony:paramCols 3 ;
		moony:paramRows 4 ;
		moony:code """function run(n, control, notify, seq1, forge1, seq2, forge2, seq3, forge3, seq4, forge4)
	for frames, atom in seq1:foreach() do
		forge1:time(frames):atom(atom)
	end

	for frames, atom in seq2:foreach() do
		forge2:time(frames):atom(atom)
	end

	for frames, atom in seq3:foreach() do
		forge3:time(frames):atom(atom)
	end

	for frames, atom in seq4:foreach() do
		forge4:time(frames):atom(atom)
	end
end"""
	] .

# C1A1XC1A1 Plugin
moony:c1a1xc1a1
	a lv2:Plugin ,
		lv2:ConverterPlugin ;
	doap:name "Moony C1+A1 x C1+A1" ;
	doap:license lic:Artistic-2.0 ;
	rdfs:comment "Realtime Lua as programmable glue in LV2";
	lv2:project proj:moony ;
	lv2:optionalFeature lv2:isLive, lv2:hardRTCapable, bufsz:boundedBlockLength, osc:schedule, state:loadDefaultState, xpress:voiceMap, state:threadSafeRestore, opts:options ;
	lv2:extensionData work:interface, state:interface ;
	#lv2:optionalFeature idisp:queue_draw ;
	#lv2:extensionData idisp:interface ;
	lv2:requiredFeature work:schedule, urid:map, urid:unmap ;
	opts:supportedOption bufsz:minBlockLength, bufsz:maxBlockLength, bufsz:nominalBlockLength, bufsz:sequenceSize, ui:updateRate, param:sampleRate ;

	lv2:port [
	# input event port
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 0 ;
		lv2:symbol "event_in_1" ;
		lv2:name "Event In 1" ;
	] , [
	# output event port
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 1 ;
		lv2:symbol "event_out_1" ;
		lv2:name "Event Out 1" ;
	] , [
	# input port
	  a lv2:InputPort ,
			lv2:ControlPort ;
		lv2:index 2 ;
		lv2:symbol "input_1" ;
		lv2:name "Input 1" ;
		lv2:default 0.0;
		lv2:minimum 0.0 ;
		lv2:maximum 1.0 ;
	] , [
	# output port
	  a lv2:OutputPort ,
			lv2:ControlPort ;
		lv2:index 3 ;
		lv2:symbol "output_1" ;
		lv2:name "Output 1" ;
	] , [
	# input control port
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 4 ;
		lv2:symbol "control" ;
		lv2:name "Control" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] , [
	# output notify port
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 5 ;
		lv2:symbol "notify" ;
		lv2:name "Notify" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] ;

	patch:readable
		moony:error ;

	patch:writable
		moony:code ;

	state:state [
		moony:editorHidden false ;
		moony:logHidden true ;
		moony:logFollow true ;
		moony:logReset false ;
		moony:paramHidden true ;
		moony:paramCols 3 ;
		moony:paramRows 4 ;
		moony:code """function run(n, control, notify, seq, forge, c1)
	for frames, atom in seq:foreach() do
		forge:time(frames):atom(atom)
	end

	return c1
end"""
	] .

# C2A1XC2A1 Plugin
moony:c2a1xc2a1
	a lv2:Plugin ,
		lv2:ConverterPlugin ;
	doap:name "Moony C2+A1 x C2+A1" ;
	doap:license lic:Artistic-2.0 ;
	rdfs:comment "Realtime Lua as programmable glue in LV2";
	lv2:project proj:moony ;
	lv2:optionalFeature lv2:isLive, lv2:hardRTCapable, bufsz:boundedBlockLength, osc:schedule, state:loadDefaultState, xpress:voiceMap, state:threadSafeRestore, opts:options ;
	lv2:extensionData work:interface, state:interface ;
	#lv2:optionalFeature idisp:queue_draw ;
	#lv2:extensionData idisp:interface ;
	lv2:requiredFeature work:schedule, urid:map, urid:unmap ;
	opts:supportedOption bufsz:minBlockLength, bufsz:maxBlockLength, bufsz:nominalBlockLength, bufsz:sequenceSize, ui:updateRate, param:sampleRate ;

	lv2:port [
	# input event port
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 0 ;
		lv2:symbol "event_in_1" ;
		lv2:name "Event In 1" ;
	] , [
	# output event port
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 1 ;
		lv2:symbol "event_out_1" ;
		lv2:name "Event Out 1" ;
	] , [
	# input port
	  a lv2:InputPort ,
			lv2:ControlPort ;
		lv2:index 2 ;
		lv2:symbol "input_1" ;
		lv2:name "Input 1" ;
		lv2:default 0.0;
		lv2:minimum 0.0 ;
		lv2:maximum 1.0 ;
	] , [
	  a lv2:InputPort ,
			lv2:ControlPort ;
		lv2:index 3 ;
		lv2:symbol "input_2" ;
		lv2:name "Input 2" ;
		lv2:default 0.0;
		lv2:minimum 0.0 ;
		lv2:maximum 1.0 ;
	] , [
	# output port
	  a lv2:OutputPort ,
			lv2:ControlPort ;
		lv2:index 4 ;
		lv2:symbol "output_1" ;
		lv2:name "Output 1" ;
	] , [
	  a lv2:OutputPort ,
			lv2:ControlPort ;
		lv2:index 5 ;
		lv2:symbol "output_2" ;
		lv2:name "Output 2" ;
	] , [
	# input control port
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 6 ;
		lv2:symbol "control" ;
		lv2:name "Control" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] , [
	# output notify port
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 7 ;
		lv2:symbol "notify" ;
		lv2:name "Notify" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] ;

	patch:readable
		moony:error ;

	patch:writable
		moony:code ;

	state:state [
		moony:editorHidden false ;
		moony:logHidden true ;
		moony:logFollow true ;
		moony:logReset false ;
		moony:paramHidden true ;
		moony:paramCols 3 ;
		moony:paramRows 4 ;
		moony:code """function run(n, control, notify, seq, forge, c1, c2)
	for frames, atom in seq:foreach() do
		forge:time(frames):atom(atom)
	end

	return c1, c2
end"""
	] .

# C4A1XC4A1 Plugin
moony:c4a1xc4a1
	a lv2:Plugin ,
		lv2:ConverterPlugin ;
	doap:name "Moony C4+A1 x C4+A1" ;
	doap:license lic:Artistic-2.0 ;
	rdfs:comment "Realtime Lua as programmable glue in LV2";
	lv2:project proj:moony ;
	lv2:optionalFeature lv2:isLive, lv2:hardRTCapable, bufsz:boundedBlockLength, osc:schedule, state:loadDefaultState, xpress:voiceMap, state:threadSafeRestore, opts:options ;
	lv2:extensionData work:interface, state:interface ;
	#lv2:optionalFeature idisp:queue_draw ;
	#lv2:extensionData idisp:interface ;
	lv2:requiredFeature work:schedule, urid:map, urid:unmap ;
	opts:supportedOption bufsz:minBlockLength, bufsz:maxBlockLength, bufsz:nominalBlockLength, bufsz:sequenceSize, ui:updateRate, param:sampleRate ;

	lv2:port [
	# input event port
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 0 ;
		lv2:symbol "event_in_1" ;
		lv2:name "Event In 1" ;
	] , [
	# output event port
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports midi:MidiEvent ;
		atom:supports osc:Event ;
		atom:supports time:Position ;
		lv2:index 1 ;
		lv2:symbol "event_out_1" ;
		lv2:name "Event Out 1" ;
	] , [
	# input port
	  a lv2:InputPort ,
			lv2:ControlPort ;
		lv2:index 2 ;
		lv2:symbol "input_1" ;
		lv2:name "Input 1" ;
		lv2:default 0.0 ;
		lv2:minimum 0.0 ;
		lv2:maximum 1.0 ;
	] , [
	  a lv2:InputPort ,
			lv2:ControlPort ;
		lv2:index 3 ;
		lv2:symbol "input_2" ;
		lv2:name "Input 2" ;
		lv2:default 0.0 ;
		lv2:minimum 0.0 ;
		lv2:maximum 1.0 ;
	] , [
	  a lv2:InputPort ,
			lv2:ControlPort ;
		lv2:index 4 ;
		lv2:symbol "input_3" ;
		lv2:name "Input 3" ;
		lv2:default 0.0 ;
		lv2:minimum 0.0 ;
		lv2:maximum 1.0 ;
	] , [
	  a lv2:InputPort ,
			lv2:ControlPort ;
		lv2:index 5 ;
		lv2:symbol "input_4" ;
		lv2:name "Input 4" ;
		lv2:default 0.0 ;
		lv2:minimum 0.0 ;
		lv2:maximum 1.0 ;
	] , [
	# output port
	  a lv2:OutputPort ,
			lv2:ControlPort ;
		lv2:index 6 ;
		lv2:symbol "output_1" ;
		lv2:name "Output 1" ;
	] , [
	  a lv2:OutputPort ,
			lv2:ControlPort ;
		lv2:index 7 ;
		lv2:symbol "output_2" ;
		lv2:name "Output 2" ;
	] , [
	  a lv2:OutputPort ,
			lv2:ControlPort ;
		lv2:index 8 ;
		lv2:symbol "output_3" ;
		lv2:name "Output 3" ;
	] , [
	  a lv2:OutputPort ,
			lv2:ControlPort ;
		lv2:index 9 ;
		lv2:symbol "output_4" ;
		lv2:name "Output 4" ;
	] , [
	# input control port
	  a lv2:InputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 10 ;
		lv2:symbol "control" ;
		lv2:name "Control" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] , [
	# output notify port
	  a lv2:OutputPort ,
			atom:AtomPort ;
		atom:bufferType atom:Sequence ;
		atom:supports atom:Object ;
		atom:supports patch:Message ;
		lv2:index 11 ;
		lv2:symbol "notify" ;
		lv2:name "Notify" ;
		rsz:minimumSize 131072 ;
		lv2:designation lv2:control ;
	] ;

	patch:readable
		moony:error ;

	patch:writable
		moony:code ;

	state:state [
		moony:editorHidden false ;
		moony:logHidden true ;
		moony:logFollow true ;
		moony:logReset false ;
		moony:paramHidden true ;
		moony:paramCols 3 ;
		moony:paramRows 4 ;
		moony:code """function run(n, control, notify, seq, forge, c1, c2, c3, c4)
	for frames, atom in seq:foreach() do
		forge:time(frames):atom(atom)
	end

	return c1, c2, c3, c4
end"""
	] .
