{"version":3,"file":"polygonjs_editor_components.5ef305b085b39bbea7a9.css","mappings":";AAkaA;CACC,oCAAoC;CACpC,aAAa;CACb,wBAAwB;AACzB;AAEA;CACC,kBAAkB;CAClB,kBAAkB;CAClB,iBAAiB;CACjB,WAAW;AACZ;AAEA;CACC,aAAa;CACb,uBAAuB;CACvB,WAAW;CACX,kBAAkB;CAClB,eAAe;CACf,YAAY;CACZ,WAAW;CACX,0BAA0B;CAC1B,4GAA4G;AAC7G;AAEA;CACC,mHAAmH;AACpH;AAEA;CACC,aAAa;CACb,qBAAqB;CACrB,uBAAuB;CACvB,kBAAkB;CAClB,eAAe;CACf,WAAW;CACX,UAAU;CACV,SAAS;CACT,UAAU;CACV,YAAY;CACZ,0BAA0B;CAC1B;8BAC6B;AAC9B;AAEA;CACC;8BAC6B;AAC9B;AAEA;CACC,oBAAoB;CACpB,aAAa;CACb,sBAAsB;CACtB,mBAAmB;CACnB,oBAAoB;CACpB,gBAAgB;AACjB;AAEA;CACC,iBAAiB;AAClB;AAEA;CACC,eAAe;CACf,eAAe;AAChB;AACA;CACC,yBAAyB;AAC1B;AAEA;CACC,kBAAkB;CAClB,UAAU;CACV,cAAc;CACd,cAAc;AACf;AAEA;CACC,2BAA2B;CAC3B,yBAAyB;CAEzB,sBAAsB;CAEtB,iBAAiB;AAClB","sources":["webpack:///../src/editor/components/panels/params/components/extras/instruments/piano/Piano.vue"],"sourcesContent":["<template>\n\t<div class=\"piano-keyboard unselectable\">\n\t\t<div class=\"error-container\" v-if=\"isErrored\">\n\t\t\t<p>{{ errorMessage }}</p>\n\t\t</div>\n\t\t<div\n\t\t\tclass=\"white-note\"\n\t\t\tv-for=\"noteObject in notes\"\n\t\t\t:key=\"noteObject.note\"\n\t\t\t:class=\"[noteObject.pressed ? 'white-note-pressed' : '']\"\n\t\t\t:style=\"{width: whiteNoteWidthSize + '%', background: whiteNoteBackground(noteObject.pressed)}\"\n\t\t\t@mousedown=\"playNoteMouse(noteObject)\"\n\t\t\t@mouseup=\"removePressedKeyMouse(noteObject)\"\n\t\t\t@mouseover=\"playNoteHover(noteObject)\"\n\t\t\t@mouseleave=\"removePressedKey(noteObject)\"\n\t\t>\n\t\t\t<div\n\t\t\t\tclass=\"black-note black-note\"\n\t\t\t\tv-if=\"noteObject.blackNote\"\n\t\t\t\t:class=\"[noteObject.blackNote.pressed ? 'black-note-pressed' : '']\"\n\t\t\t\t:style=\"{background: blackNoteBackground(noteObject.blackNote.pressed)}\"\n\t\t\t\t@mousedown.stop=\"playNoteMouse(noteObject.blackNote)\"\n\t\t\t\t@mouseup.stop=\"removePressedKeyMouse(noteObject.blackNote)\"\n\t\t\t\t@mouseover.stop=\"playNoteHover(noteObject.blackNote)\"\n\t\t\t\t@mouseleave.stop=\"removePressedKey(noteObject.blackNote)\"\n\t\t\t>\n\t\t\t\t<div class=\"key-group unselectable\">\n\t\t\t\t\t<div class=\"key-input\" v-if=\"showKeys\">{{ noteObject.blackNote.key }}</div>\n\t\t\t\t\t<div\n\t\t\t\t\t\tv-if=\"showNotes\"\n\t\t\t\t\t\t:class=\"['key-text', 'key-text-on-black-note', indianNotes ? '' : 'key-text-vertical']\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ noteObject.blackNote.label }}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div class=\"key-group unselectable\">\n\t\t\t\t<div class=\"key-input\" v-if=\"showKeys\">{{ noteObject.key }}</div>\n\t\t\t\t<div class=\"key-text\" v-if=\"showNotes\">{{ noteObject.label }}</div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<script lang=\"ts\">\n// import * as Tone from 'tone';\n// import SwaralipiCore from 'swaralipi-core';\nimport {defineComponent, onMounted, ref, watch, computed, onUnmounted} from 'vue';\nimport {PlayInstrumentAudioNode} from '../../../../../../../../../@polygonjs/polygonjs/src/engine/nodes/audio/PlayInstrument';\nimport {StoreController} from '../../../../../../../../../src/editor/store/controllers/StoreController';\nimport {InstrumentType} from '../../../../../../../../../@polygonjs/polygonjs/src/core/audio/AudioBuilder';\nimport {NotesBuilder} from '../../../../../../../../../@polygonjs/polygonjs/src/core/audio/NotesBuilder';\nimport {PolyDictionary} from '../../../../../../../../../@polygonjs/polygonjs/src/types/GlobalTypes';\nimport {AudioController} from '../../../../../../../../../@polygonjs/polygonjs/src/core/audio/AudioController';\nimport {CoreGraphNode} from '../../../../../../../../../@polygonjs/polygonjs/src/core/graph/CoreGraphNode';\nimport {isBooleanTrue} from '../../../../../../../../../@polygonjs/polygonjs/src/core/Type';\nimport {CoreGraphNodeId} from '../../../../../../../../../@polygonjs/polygonjs/src/core/graph/CoreGraph';\n\nconst ALL_KEYS = [\n\t'`',\n\t`1`,\n\t'2',\n\t'3',\n\t'4',\n\t'5',\n\t'6',\n\t'7',\n\t'8',\n\t'9',\n\t'0',\n\t'-',\n\t'=',\n\t'q',\n\t'w',\n\t'e',\n\t'r',\n\t't',\n\t'y',\n\t'u',\n\t'i',\n\t'o',\n\t'p',\n\t'[',\n\t']',\n\t'\\\\',\n\t'a',\n\t's',\n\t'd',\n\t'f',\n\t'g',\n\t'h',\n\t'j',\n\t'k',\n\t'l',\n\t';',\n\t'z',\n\t'x',\n\t'c',\n\t'v',\n\t'b',\n\t'n',\n\t'm',\n\t',',\n\t'.',\n];\n\ninterface NoteConfig {\n\tscale: string;\n\tlang: string;\n\tmiddleOctave: number;\n}\n\ninterface PianoProps {\n\tnodeId: number;\n\tallKeys: string[];\n\twhiteNoteColor: string;\n\tblackNoteColor: string;\n\t// showKeys: boolean;\n\t// showNotes: boolean;\n\t// startOctave: number;\n\t// endOctave: number;\n\t// sustain: boolean;\n\tindianNotes: boolean;\n\tnoteConfig: NoteConfig;\n}\n\ninterface NoteObject {\n\tnote: string;\n\tkey: string;\n\tpressed: boolean;\n\tlabel: any;\n\tblackNote?: NoteObject;\n}\n\n/*\nconverted to typescript from\nhttps://github.com/MicuEmerson/vue-piano\n*/\n\nexport default defineComponent({\n\tname: 'piano',\n\t// components: {},\n\n\tprops: {\n\t\tnodeId: {\n\t\t\ttype: Number as () => CoreGraphNodeId,\n\t\t\tdefault: null,\n\t\t},\n\t\tallKeys: {\n\t\t\ttype: Array as () => string[],\n\t\t\tdefault: () => ALL_KEYS,\n\t\t},\n\t\twhiteNoteColor: {\n\t\t\ttype: String,\n\t\t\tdefault: '#1eb7eb',\n\t\t},\n\t\tblackNoteColor: {\n\t\t\ttype: String,\n\t\t\tdefault: '#f9bb2d',\n\t\t},\n\t\t// showKeys: {\n\t\t// \ttype: Boolean,\n\t\t// \tdefault: true,\n\t\t// },\n\t\t// showNotes: {\n\t\t// \ttype: Boolean,\n\t\t// \tdefault: true,\n\t\t// },\n\t\t// startOctave: {\n\t\t// \ttype: Number,\n\t\t// \tdefault: 2,\n\t\t// },\n\t\t// endOctave: {\n\t\t// \ttype: Number,\n\t\t// \tdefault: 4,\n\t\t// },\n\t\t// sustain: {\n\t\t// \ttype: Boolean,\n\t\t// \tdefault: false,\n\t\t// },\n\t\tindianNotes: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\tnoteConfig: {\n\t\t\ttype: Object as () => NoteConfig,\n\t\t\tdefault: function () {\n\t\t\t\tconst config: NoteConfig = {\n\t\t\t\t\tscale: 'C',\n\t\t\t\t\tmiddleOctave: 4,\n\t\t\t\t\tlang: 'hi',\n\t\t\t\t};\n\t\t\t\treturn config;\n\t\t\t},\n\t\t},\n\t},\n\tsetup(props: PianoProps) {\n\t\tlet instrument: InstrumentType | null = null; //= ref<InstrumentType | null>(null);\n\t\tconst notesIndexesByKey = ref<PolyDictionary<number>>({});\n\t\tconst notes = ref<NoteObject[]>([]);\n\t\tconst whiteNoteWidthSize = ref(0);\n\t\tconst isMousePressed = ref(false);\n\t\tconst errorMessage = ref<string | null>(null);\n\t\tconst isErrored = computed(() => {\n\t\t\treturn errorMessage.value != null;\n\t\t});\n\t\t// const swaralipi = ref<SwaralipiCore | null>(null);\n\n\t\tconst scale = computed(() => props.noteConfig.scale);\n\t\tconst lang = computed(() => props.noteConfig.lang);\n\t\tconst middleOctave = computed(() => props.noteConfig.middleOctave);\n\n\t\tconst showKeys = ref(false);\n\t\tconst showNotes = ref(false);\n\t\tconst startOctave = ref(2);\n\t\tconst endOctave = ref(4);\n\n\t\tconst node = StoreController.engine.node(props.nodeId) as PlayInstrumentAudioNode;\n\t\tif (!node) {\n\t\t\tconsole.warn('piano: no node found');\n\t\t\t// return;\n\t\t}\n\t\tconst coreGraphNode = new CoreGraphNode(node.scene(), 'piano');\n\t\tcoreGraphNode.dirtyController.addPostDirtyHook('onPlayInstrumentDirty', _fetchInstrument);\n\t\tcoreGraphNode.addGraphInput(node);\n\n\t\tonMounted(async () => {\n\t\t\t_addEvents();\n\t\t\t_fetchInstrument();\n\t\t});\n\t\tonUnmounted(() => {\n\t\t\t_removeEvents();\n\t\t\t_removeCoreGraphNode();\n\t\t});\n\n\t\tconst allKeys = computed(() => {\n\t\t\tprops.allKeys;\n\t\t});\n\t\tconst indianNotes = computed(() => {\n\t\t\tprops.indianNotes;\n\t\t});\n\t\twatch(startOctave, regenerate);\n\t\twatch(endOctave, regenerate);\n\t\twatch(allKeys, regenerate, {deep: true});\n\t\twatch(indianNotes, regenerate);\n\t\twatch(scale, regenerate);\n\t\twatch(lang, regenerate);\n\t\twatch(middleOctave, regenerate);\n\n\t\tasync function _fetchInstrument() {\n\t\t\terrorMessage.value = null;\n\t\t\tshowKeys.value = isBooleanTrue(node.pv.showKeys);\n\t\t\tshowNotes.value = isBooleanTrue(node.pv.showNotes);\n\t\t\tstartOctave.value = node.pv.startOctave;\n\t\t\tendOctave.value = node.pv.endOctave;\n\n\t\t\tconst audioBuilder = (await node.compute()).coreContent();\n\t\t\tif (!audioBuilder) {\n\t\t\t\terrorMessage.value = 'no audio builder found';\n\t\t\t\tconsole.warn('no audio builder found');\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst audioBuilderInstrument = audioBuilder.instrument();\n\t\t\tif (!audioBuilderInstrument) {\n\t\t\t\terrorMessage.value = 'no instrument found';\n\t\t\t\tconsole.warn('no instrument found');\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tinstrument = audioBuilderInstrument;\n\t\t\tregenerate();\n\t\t\tawait AudioController.start();\n\t\t}\n\t\tfunction _removeCoreGraphNode() {\n\t\t\tcoreGraphNode?.dispose();\n\t\t}\n\t\tfunction _removeEvents() {\n\t\t\twindow.removeEventListener('keyup', _onKeyUp);\n\t\t\twindow.removeEventListener('mouseup', _onMouseUp);\n\t\t}\n\t\tfunction _addEvents() {\n\t\t\twindow.addEventListener('keyup', _onKeyUp);\n\t\t\twindow.addEventListener('mouseup', _onMouseUp);\n\t\t}\n\t\tfunction _onKeyUp(e: KeyboardEvent) {\n\t\t\tconst key = e.key;\n\t\t\tconst index = notesIndexesByKey.value[key];\n\t\t\tif (index != undefined) {\n\t\t\t\tconst noteObject = notes.value[index].key === key ? notes.value[index] : notes.value[index].blackNote;\n\t\t\t\tif (noteObject) {\n\t\t\t\t\tremovePressedKey(noteObject);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfunction _onMouseUp(e: MouseEvent) {\n\t\t\tisMousePressed.value = false;\n\t\t}\n\n\t\tfunction playNote(noteObject?: NoteObject) {\n\t\t\tif (!noteObject) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!instrument) {\n\t\t\t\tconsole.warn('no instrument');\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!noteObject.pressed) {\n\t\t\t\t// synth.value.triggerAttackRelease(noteObject.note, props.sustain ? '2n' : '8n');\n\t\t\t\ttry {\n\t\t\t\t\tinstrument.triggerAttackRelease(noteObject.note, node.pv.duration);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconsole.error('failed to play note');\n\t\t\t\t\tconsole.error(e);\n\t\t\t\t}\n\t\t\t\tnoteObject.pressed = true;\n\t\t\t\tif (isBooleanTrue(node.pv.updateNoteFromInstrument)) {\n\t\t\t\t\tnode.p.note.set(noteObject.note);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfunction playNoteMouse(noteObject?: NoteObject) {\n\t\t\tisMousePressed.value = true;\n\t\t\tplayNote(noteObject);\n\t\t}\n\t\tfunction playNoteHover(noteObject?: NoteObject) {\n\t\t\tif (isMousePressed.value) playNote(noteObject);\n\t\t}\n\t\tfunction removePressedKey(noteObject?: NoteObject) {\n\t\t\tif (!noteObject) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnoteObject.pressed = false;\n\t\t}\n\t\tfunction removePressedKeyMouse(noteObject?: NoteObject) {\n\t\t\tif (!noteObject) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tisMousePressed.value = false;\n\t\t\tremovePressedKey(noteObject);\n\t\t}\n\t\tfunction whiteNoteBackground(pressed: boolean) {\n\t\t\treturn pressed ? props.whiteNoteColor : 'linear-gradient(to bottom, #eee 0%, #fff 100%)';\n\t\t}\n\n\t\tfunction blackNoteBackground(pressed: boolean) {\n\t\t\treturn pressed ? props.blackNoteColor : 'linear-gradient(45deg, #555, #222)';\n\t\t}\n\n\t\tfunction generateNotes() {\n\t\t\tlet keyIndex = 0;\n\t\t\tlet noteIndex = 0;\n\t\t\tnotes.value.length = 0;\n\t\t\tconst ALL_NOTES = NotesBuilder.ALL_NOTES;\n\t\t\tfor (let octave = startOctave.value; octave <= endOctave.value; octave++) {\n\t\t\t\twhile (noteIndex < ALL_NOTES.length) {\n\t\t\t\t\tconst currentNote = ALL_NOTES[noteIndex];\n\t\t\t\t\tconst newNote: NoteObject = {\n\t\t\t\t\t\tnote: currentNote + octave,\n\t\t\t\t\t\tkey: props.allKeys[keyIndex++],\n\t\t\t\t\t\tpressed: false,\n\t\t\t\t\t\tlabel: getLabel(currentNote, octave),\n\t\t\t\t\t};\n\t\t\t\t\tif (currentNote !== 'B' && currentNote !== 'E') {\n\t\t\t\t\t\tconst blackNote: NoteObject = {\n\t\t\t\t\t\t\tnote: currentNote + '#' + octave,\n\t\t\t\t\t\t\tkey: props.allKeys[keyIndex++],\n\t\t\t\t\t\t\tpressed: false,\n\t\t\t\t\t\t\tlabel: getLabel(currentNote + '#', octave),\n\t\t\t\t\t\t};\n\t\t\t\t\t\tnewNote['blackNote'] = blackNote;\n\t\t\t\t\t}\n\t\t\t\t\tnotes.value.push(newNote);\n\n\t\t\t\t\tif (octave === endOctave.value && currentNote === 'B') break;\n\n\t\t\t\t\tnoteIndex++;\n\t\t\t\t}\n\t\t\t\tnoteIndex = 0;\n\t\t\t}\n\t\t\twhiteNoteWidthSize.value = 100 / notes.value.length;\n\t\t}\n\t\tfunction generateNotesIndexesByKey() {\n\t\t\tnotesIndexesByKey.value = {};\n\t\t\tfor (let index = 0; index < notes.value.length; index++) {\n\t\t\t\tconst k = notes.value[index].key;\n\t\t\t\tnotesIndexesByKey.value[k] = index;\n\t\t\t\tconst blackNote = notes.value[index].blackNote;\n\t\t\t\tif (blackNote) notesIndexesByKey.value[blackNote.key] = index;\n\t\t\t}\n\t\t}\n\t\tfunction regenerate() {\n\t\t\t// swaralipi.value = new SwaralipiCore(scale.value, middleOctave.value, lang.value);\n\t\t\tgenerateNotes();\n\t\t\tgenerateNotesIndexesByKey();\n\t\t}\n\t\tfunction getLabel(note: string, octave: number) {\n\t\t\treturn note;\n\t\t\t// return props.indianNotes ? swaralipi.toIndianNote(note + octave) : note;\n\t\t}\n\n\t\treturn {\n\t\t\tisErrored,\n\t\t\terrorMessage,\n\t\t\tshowKeys,\n\t\t\tshowNotes,\n\t\t\tplayNoteMouse,\n\t\t\tplayNoteHover,\n\t\t\tremovePressedKey,\n\t\t\tremovePressedKeyMouse,\n\t\t\twhiteNoteBackground,\n\t\t\tblackNoteBackground,\n\t\t\twhiteNoteWidthSize,\n\t\t\tnotes,\n\t\t};\n\t},\n});\n</script>\n\n<style>\n.error-container {\n\tbackground-color: rgb(182, 103, 103);\n\tpadding: 20px;\n\tborder: rgb(201, 60, 60);\n}\n\n.piano-keyboard {\n\tposition: relative;\n\t/* height: 100%; */\n\tmin-height: 140px;\n\twidth: 100%;\n}\n\n.white-note {\n\tdisplay: flex;\n\tjustify-content: center;\n\tfloat: left;\n\tposition: relative;\n\tcursor: pointer;\n\tcolor: black;\n\theight: 98%;\n\tborder-radius: 0 0 5px 5px;\n\tbox-shadow: 0px 0px 0px rgba(255, 255, 255, 0.8) inset, -2px -5px 3px #ccc inset, 0 0 3px rgba(0, 0, 0, 0.5);\n}\n\n.white-note-pressed {\n\tbox-shadow: 2px 0 3px rgba(0, 0, 0, 0.2) inset, -5px -1px 20px rgba(0, 0, 0, 0.2) inset, 0 0 3px rgba(0, 0, 0, 0.5);\n}\n\n.black-note {\n\tdisplay: flex;\n\talign-items: flex-end;\n\tjustify-content: center;\n\tposition: absolute;\n\tcursor: pointer;\n\theight: 65%;\n\twidth: 65%;\n\tleft: 68%;\n\tz-index: 1;\n\tcolor: white;\n\tborder-radius: 0 0 3px 3px;\n\tbox-shadow: -1px -1px 2px rgba(255, 255, 255, 0.2) inset, 0 -5px 2px rgba(0, 0, 0, 0.5) inset,\n\t\t0 2px 4px rgba(0, 0, 0, 0.5);\n}\n\n.black-note-pressed {\n\tbox-shadow: -1px -1px 2px rgba(255, 255, 255, 0.2) inset, 0 -1px 2px rgba(0, 0, 0, 0.2) inset,\n\t\t0 1px 2px rgba(0, 0, 0, 0.2);\n}\n\n.key-group {\n\talign-self: flex-end;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tmargin-bottom: 0.8vw;\n\tfont-size: 1.2vw;\n}\n\n.key-text {\n\tmargin-top: 0.8vw;\n}\n\n.key-text-on-black-note {\n\tmargin: 0.8vw 0;\n\tmargin-top: 1vw;\n}\n.key-text-vertical {\n\ttransform: rotate(-90deg);\n}\n\n.key-input {\n\ttext-align: center;\n\twidth: 2em;\n\tcolor: inherit;\n\tfont-size: 1vw;\n}\n\n.unselectable {\n\t-webkit-touch-callout: none;\n\t-webkit-user-select: none;\n\t-khtml-user-select: none;\n\t-moz-user-select: none;\n\t-ms-user-select: none;\n\tuser-select: none;\n}\n</style>\n"],"names":[],"sourceRoot":""}