Spaces:
Sleeping
Sleeping
xribene
commited on
Commit
·
df4b493
1
Parent(s):
7687352
first
Browse files- .editorconfig +19 -0
- .gitignore +24 -0
- app.py +66 -0
- frontend/README.md +7 -0
- frontend/eslint.config.js +31 -0
- frontend/index.html +18 -0
- frontend/package-lock.json +0 -0
- frontend/package.json +56 -0
- frontend/pnpm-lock.yaml +0 -0
- frontend/public/_headers +1 -0
- frontend/public/cedar_guitar_1663.png +0 -0
- frontend/public/cedar_guitar_400.png +0 -0
- frontend/public/cedar_guitar_800.png +0 -0
- frontend/public/example.xml +0 -0
- frontend/public/g14671.png +0 -0
- frontend/public/g9541.png +0 -0
- frontend/public/guitar-diff-example.musicxml +507 -0
- frontend/public/guitar-diff-example.vextab.txt +6 -0
- frontend/public/guitarDiffLogo2.svg +0 -0
- frontend/public/guitarDiffLogo3.svg +0 -0
- frontend/public/guitar_faded_noReport.png +0 -0
- frontend/public/guitar_rotated.svg +0 -0
- frontend/public/guitar_rotated_report.svg +0 -0
- frontend/public/guitar_straight.svg +0 -0
- frontend/public/inkscape_canvas.svg +0 -0
- frontend/public/test.svg +0 -0
- frontend/public/vite.svg +1 -0
- frontend/src/App.vue +89 -0
- frontend/src/assets/vue.svg +1 -0
- frontend/src/components/CounterButton.vue +20 -0
- frontend/src/components/HelloWorld.vue +42 -0
- frontend/src/components/MusicXmlWidget.vue +320 -0
- frontend/src/components/TweakComponent.vue +26 -0
- frontend/src/components/TweakComponent2.vue +107 -0
- frontend/src/components/VextabWidget.vue +225 -0
- frontend/src/main.js +51 -0
- frontend/src/plugins/router.js +21 -0
- frontend/src/style.css +157 -0
- frontend/src/views/Analyzer.vue +197 -0
- frontend/src/views/Home.vue +33 -0
- frontend/uno.config.js +46 -0
- frontend/vite.config.js +21 -0
- pyproject.toml +70 -0
.editorconfig
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# top-most EditorConfig file
|
| 2 |
+
root = true
|
| 3 |
+
|
| 4 |
+
[*]
|
| 5 |
+
indent_style = space
|
| 6 |
+
indent_size = 2
|
| 7 |
+
end_of_line = crlf
|
| 8 |
+
charset = utf-8
|
| 9 |
+
trim_trailing_whitespace = true
|
| 10 |
+
insert_final_newline = true
|
| 11 |
+
|
| 12 |
+
[*.py]
|
| 13 |
+
indent_size = 4
|
| 14 |
+
|
| 15 |
+
[*.{js,vue}]
|
| 16 |
+
indent_size = 2
|
| 17 |
+
|
| 18 |
+
[*.vue]
|
| 19 |
+
indent_size = 2
|
.gitignore
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Logs
|
| 2 |
+
logs
|
| 3 |
+
*.log
|
| 4 |
+
npm-debug.log*
|
| 5 |
+
yarn-debug.log*
|
| 6 |
+
yarn-error.log*
|
| 7 |
+
pnpm-debug.log*
|
| 8 |
+
lerna-debug.log*
|
| 9 |
+
|
| 10 |
+
node_modules
|
| 11 |
+
dist
|
| 12 |
+
dist-ssr
|
| 13 |
+
*.local
|
| 14 |
+
|
| 15 |
+
# Editor directories and files
|
| 16 |
+
.vscode/*
|
| 17 |
+
!.vscode/extensions.json
|
| 18 |
+
.idea
|
| 19 |
+
.DS_Store
|
| 20 |
+
*.suo
|
| 21 |
+
*.ntvs*
|
| 22 |
+
*.njsproj
|
| 23 |
+
*.sln
|
| 24 |
+
*.sw?
|
app.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# import gradio as gr
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
# def process(name):
|
| 5 |
+
# return "Hello re malakako" + name + "!"
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
# with gr.Blocks() as demo:
|
| 9 |
+
# name = gr.Textbox(label="Score (vextab or musicxml)")
|
| 10 |
+
# output = gr.Textbox(label="Difficulty Analysis Report")
|
| 11 |
+
# greet_btn = gr.Button("Process")
|
| 12 |
+
# greet_btn.click(fn=process, inputs=name, outputs=output, api_name="process")
|
| 13 |
+
|
| 14 |
+
# demo.launch()
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
import time
|
| 18 |
+
import gradio as gr
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def fake_diffusion(steps):
|
| 22 |
+
for i in range(steps):
|
| 23 |
+
print(f"Current step: {i}")
|
| 24 |
+
time.sleep(1)
|
| 25 |
+
yield str(i)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def long_prediction(*args, **kwargs):
|
| 29 |
+
time.sleep(10)
|
| 30 |
+
return 42
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
with gr.Blocks() as demo:
|
| 34 |
+
with gr.Row():
|
| 35 |
+
with gr.Column():
|
| 36 |
+
n = gr.Slider(1, 10, value=9, step=1, label="Number Steps")
|
| 37 |
+
run = gr.Button(value="Start Iterating")
|
| 38 |
+
output = gr.Textbox(label="Iterative Output")
|
| 39 |
+
stop = gr.Button(value="Stop Iterating")
|
| 40 |
+
with gr.Column():
|
| 41 |
+
textbox = gr.Textbox(label="Prompt")
|
| 42 |
+
prediction = gr.Number(label="Expensive Calculation")
|
| 43 |
+
run_pred = gr.Button(value="Run Expensive Calculation")
|
| 44 |
+
with gr.Column():
|
| 45 |
+
cancel_on_change = gr.Textbox(label="Cancel Iteration and Expensive Calculation on Change")
|
| 46 |
+
cancel_on_submit = gr.Textbox(label="Cancel Iteration and Expensive Calculation on Submit")
|
| 47 |
+
echo = gr.Textbox(label="Echo")
|
| 48 |
+
with gr.Row():
|
| 49 |
+
with gr.Column():
|
| 50 |
+
image = gr.Image(sources=["webcam"], label="Cancel on clear", interactive=True)
|
| 51 |
+
with gr.Column():
|
| 52 |
+
video = gr.Video(sources=["webcam"], label="Cancel on start recording", interactive=True)
|
| 53 |
+
|
| 54 |
+
click_event = run.click(fake_diffusion, n, output)
|
| 55 |
+
stop.click(fn=None, inputs=None, outputs=None, cancels=[click_event])
|
| 56 |
+
pred_event = run_pred.click(fn=long_prediction, inputs=[textbox], outputs=prediction)
|
| 57 |
+
|
| 58 |
+
cancel_on_change.change(None, None, None, cancels=[click_event, pred_event])
|
| 59 |
+
cancel_on_submit.submit(lambda s: s, cancel_on_submit, echo, cancels=[click_event, pred_event])
|
| 60 |
+
image.clear(None, None, None, cancels=[click_event, pred_event])
|
| 61 |
+
video.start_recording(None, None, None, cancels=[click_event, pred_event])
|
| 62 |
+
|
| 63 |
+
demo.queue(max_size=20)
|
| 64 |
+
|
| 65 |
+
if __name__ == "__main__":
|
| 66 |
+
demo.launch()
|
frontend/README.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Vue 3 + Vite
|
| 2 |
+
|
| 3 |
+
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
| 4 |
+
|
| 5 |
+
## Recommended IDE Setup
|
| 6 |
+
|
| 7 |
+
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
|
frontend/eslint.config.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import antfu from '@antfu/eslint-config'
|
| 2 |
+
|
| 3 |
+
export default antfu(
|
| 4 |
+
{
|
| 5 |
+
// customizations
|
| 6 |
+
rules: {
|
| 7 |
+
'no-unused-vars': 'off',
|
| 8 |
+
'unused-imports/no-unused-vars': 'off',
|
| 9 |
+
'no-console': 'off',
|
| 10 |
+
},
|
| 11 |
+
unocss: true,
|
| 12 |
+
formatters: {
|
| 13 |
+
/**
|
| 14 |
+
* Format CSS, LESS, SCSS files, also the `<style>` blocks in Vue
|
| 15 |
+
* By default uses Prettier
|
| 16 |
+
*/
|
| 17 |
+
// css: true,
|
| 18 |
+
/**
|
| 19 |
+
* Format HTML files
|
| 20 |
+
* By default uses Prettier
|
| 21 |
+
*/
|
| 22 |
+
// html: true,
|
| 23 |
+
/**
|
| 24 |
+
* Format Markdown files
|
| 25 |
+
* Supports Prettier and dprint
|
| 26 |
+
* By default uses Prettier
|
| 27 |
+
*/
|
| 28 |
+
// markdown: 'prettier',
|
| 29 |
+
},
|
| 30 |
+
},
|
| 31 |
+
)
|
frontend/index.html
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<!-- <meta http-equiv="Cross-Origin-Opener-Policy" content="same-origin">
|
| 5 |
+
<meta http-equiv="Cross-Origin-Embedder-Policy" content="require-corp"> -->
|
| 6 |
+
<meta charset="UTF-8" />
|
| 7 |
+
<link rel="icon" type="image/svg+xml" href="/cedar_guitar_400.png" />
|
| 8 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 9 |
+
|
| 10 |
+
<script src="https://cdn.jsdelivr.net/npm/vexflow@4.2.3/build/cjs/vexflow.min.js"></script>
|
| 11 |
+
<script src="https://cdn.jsdelivr.net/npm/vextab@2.0.13/releases/vextab-div.js"></script>
|
| 12 |
+
<title>Guitar Diff</title>
|
| 13 |
+
</head>
|
| 14 |
+
<body>
|
| 15 |
+
<div id="app"></div>
|
| 16 |
+
<script type="module" src="/src/main.js"></script>
|
| 17 |
+
</body>
|
| 18 |
+
</html>
|
frontend/package-lock.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
frontend/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "guitar-diff-client",
|
| 3 |
+
"type": "module",
|
| 4 |
+
"version": "0.1.0",
|
| 5 |
+
"private": true,
|
| 6 |
+
"scripts": {
|
| 7 |
+
"dev": "vite",
|
| 8 |
+
"build": "vite build",
|
| 9 |
+
"preview": "vite preview",
|
| 10 |
+
"up": "taze major -I",
|
| 11 |
+
"lint": "eslint .",
|
| 12 |
+
"lint:fix": "eslint . --fix"
|
| 13 |
+
},
|
| 14 |
+
"dependencies": {
|
| 15 |
+
"@coderline/alphatab": "^1.2.3",
|
| 16 |
+
"@gradio/client": "^0.9.4",
|
| 17 |
+
"@pangenerator/tweakpane-textarea-plugin": "github:kitschpatrol/tweakpane-textarea-plugin#tweakpane-v4",
|
| 18 |
+
"@tweakpane/plugin-essentials": "^0.2.1",
|
| 19 |
+
"@unocss/preset-icons": "^0.58.2",
|
| 20 |
+
"i": "^0.3.7",
|
| 21 |
+
"opensheetmusicdisplay": "^1.8.4",
|
| 22 |
+
"tweakpane": "^4.0.3",
|
| 23 |
+
"unocss": "^0.58.2",
|
| 24 |
+
"v-github-icon": "^3.1.2",
|
| 25 |
+
"v-tweakpane": "github:vinayakkulkarni/v-tweakpane#main",
|
| 26 |
+
"vexflow": "4.2.3",
|
| 27 |
+
"vextab": "3.0.6",
|
| 28 |
+
"vue": "^3.3.13",
|
| 29 |
+
"vue-meta": "^3.0.0-alpha.10",
|
| 30 |
+
"vue-router": "^4.2.5",
|
| 31 |
+
"vue3-tabs-component": "^1.3.7",
|
| 32 |
+
"vuetify": "^3.4.9"
|
| 33 |
+
},
|
| 34 |
+
"devDependencies": {
|
| 35 |
+
"@antfu/eslint-config": "^2.6.1",
|
| 36 |
+
"@iconify/json": "^2.2.162",
|
| 37 |
+
"@mdi/font": "^7.4.47",
|
| 38 |
+
"@unocss/eslint-plugin": "^0.58.2",
|
| 39 |
+
"@vitejs/plugin-vue": "^5.0.0",
|
| 40 |
+
"eslint": "^8.56.0",
|
| 41 |
+
"eslint-config-google": "^0.14.0",
|
| 42 |
+
"eslint-flat-config-viewer": "0.1.3",
|
| 43 |
+
"eslint-plugin-format": "^0.1.0",
|
| 44 |
+
"eslint-plugin-vue": "^9.19.2",
|
| 45 |
+
"lint-staged": "^15.2.0",
|
| 46 |
+
"simple-git-hooks": "^2.9.0",
|
| 47 |
+
"taze": "^0.13.1",
|
| 48 |
+
"vite": "^5.0.10"
|
| 49 |
+
},
|
| 50 |
+
"simple-git-hooks": {
|
| 51 |
+
"pre-commit": "pnpm lint-staged"
|
| 52 |
+
},
|
| 53 |
+
"lint-staged": {
|
| 54 |
+
"*": "eslint --fix"
|
| 55 |
+
}
|
| 56 |
+
}
|
frontend/pnpm-lock.yaml
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
frontend/public/_headers
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
|
frontend/public/cedar_guitar_1663.png
ADDED
|
frontend/public/cedar_guitar_400.png
ADDED
|
frontend/public/cedar_guitar_800.png
ADDED
|
frontend/public/example.xml
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
frontend/public/g14671.png
ADDED
|
frontend/public/g9541.png
ADDED
|
frontend/public/guitar-diff-example.musicxml
ADDED
|
@@ -0,0 +1,507 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
|
| 3 |
+
<score-partwise version="3.1">
|
| 4 |
+
<work>
|
| 5 |
+
<work-title>Fantasia no.2 </work-title>
|
| 6 |
+
</work>
|
| 7 |
+
<identification>
|
| 8 |
+
<creator type="composer">Michalis Sourvinos</creator>
|
| 9 |
+
<encoding>
|
| 10 |
+
<software>MuseScore 3.6.2</software>
|
| 11 |
+
<encoding-date>2023-11-28</encoding-date>
|
| 12 |
+
<supports element="accidental" type="yes"/>
|
| 13 |
+
<supports element="beam" type="yes"/>
|
| 14 |
+
<supports element="print" attribute="new-page" type="yes" value="yes"/>
|
| 15 |
+
<supports element="print" attribute="new-system" type="yes" value="yes"/>
|
| 16 |
+
<supports element="stem" type="yes"/>
|
| 17 |
+
</encoding>
|
| 18 |
+
</identification>
|
| 19 |
+
<defaults>
|
| 20 |
+
<scaling>
|
| 21 |
+
<millimeters>6.99912</millimeters>
|
| 22 |
+
<tenths>40</tenths>
|
| 23 |
+
</scaling>
|
| 24 |
+
<page-layout>
|
| 25 |
+
<page-height>1596.77</page-height>
|
| 26 |
+
<page-width>1233.87</page-width>
|
| 27 |
+
<page-margins type="even">
|
| 28 |
+
<left-margin>85.7251</left-margin>
|
| 29 |
+
<right-margin>85.7251</right-margin>
|
| 30 |
+
<top-margin>85.7251</top-margin>
|
| 31 |
+
<bottom-margin>85.7251</bottom-margin>
|
| 32 |
+
</page-margins>
|
| 33 |
+
<page-margins type="odd">
|
| 34 |
+
<left-margin>85.7251</left-margin>
|
| 35 |
+
<right-margin>85.7251</right-margin>
|
| 36 |
+
<top-margin>85.7251</top-margin>
|
| 37 |
+
<bottom-margin>85.7251</bottom-margin>
|
| 38 |
+
</page-margins>
|
| 39 |
+
</page-layout>
|
| 40 |
+
<word-font font-family="Edwin" font-size="10"/>
|
| 41 |
+
<lyric-font font-family="Edwin" font-size="10"/>
|
| 42 |
+
</defaults>
|
| 43 |
+
<credit page="1">
|
| 44 |
+
<credit-type>title</credit-type>
|
| 45 |
+
<credit-words default-x="616.935" default-y="1511.05" justify="center" valign="top" font-size="22">Fantasia no.2 </credit-words>
|
| 46 |
+
</credit>
|
| 47 |
+
<credit page="1">
|
| 48 |
+
<credit-type>subtitle</credit-type>
|
| 49 |
+
<credit-words default-x="616.935" default-y="1453.9" justify="center" valign="top" font-size="16">in A major</credit-words>
|
| 50 |
+
</credit>
|
| 51 |
+
<credit page="1">
|
| 52 |
+
<credit-type>composer</credit-type>
|
| 53 |
+
<credit-words default-x="1148.14" default-y="1411.05" justify="right" valign="bottom">Michalis Sourvinos</credit-words>
|
| 54 |
+
</credit>
|
| 55 |
+
<part-list>
|
| 56 |
+
<part-group type="start" number="1">
|
| 57 |
+
<group-symbol>none</group-symbol>
|
| 58 |
+
</part-group>
|
| 59 |
+
<score-part id="P1">
|
| 60 |
+
<part-name>Classical Guitar</part-name>
|
| 61 |
+
<part-abbreviation>Guit.</part-abbreviation>
|
| 62 |
+
<score-instrument id="P1-I1">
|
| 63 |
+
<instrument-name>Classical Guitar</instrument-name>
|
| 64 |
+
</score-instrument>
|
| 65 |
+
<midi-device id="P1-I1" port="1"></midi-device>
|
| 66 |
+
<midi-instrument id="P1-I1">
|
| 67 |
+
<midi-channel>1</midi-channel>
|
| 68 |
+
<midi-program>25</midi-program>
|
| 69 |
+
<volume>78.7402</volume>
|
| 70 |
+
<pan>0</pan>
|
| 71 |
+
</midi-instrument>
|
| 72 |
+
</score-part>
|
| 73 |
+
<part-group type="stop" number="1"/>
|
| 74 |
+
</part-list>
|
| 75 |
+
<part id="P1">
|
| 76 |
+
<measure number="0" implicit="yes" width="389.07">
|
| 77 |
+
<print>
|
| 78 |
+
<system-layout>
|
| 79 |
+
<system-margins>
|
| 80 |
+
<left-margin>50.00</left-margin>
|
| 81 |
+
<right-margin>0.00</right-margin>
|
| 82 |
+
</system-margins>
|
| 83 |
+
<top-system-distance>170.00</top-system-distance>
|
| 84 |
+
</system-layout>
|
| 85 |
+
<staff-layout number="2">
|
| 86 |
+
<staff-distance>130.23</staff-distance>
|
| 87 |
+
</staff-layout>
|
| 88 |
+
</print>
|
| 89 |
+
<attributes>
|
| 90 |
+
<divisions>4</divisions>
|
| 91 |
+
<key>
|
| 92 |
+
<fifths>3</fifths>
|
| 93 |
+
</key>
|
| 94 |
+
<time>
|
| 95 |
+
<beats>2</beats>
|
| 96 |
+
<beat-type>4</beat-type>
|
| 97 |
+
</time>
|
| 98 |
+
<staves>2</staves>
|
| 99 |
+
<clef number="1">
|
| 100 |
+
<sign>G</sign>
|
| 101 |
+
<line>2</line>
|
| 102 |
+
<clef-octave-change>-1</clef-octave-change>
|
| 103 |
+
</clef>
|
| 104 |
+
<clef number="2">
|
| 105 |
+
<sign>TAB</sign>
|
| 106 |
+
<line>5</line>
|
| 107 |
+
</clef>
|
| 108 |
+
<staff-details number="2">
|
| 109 |
+
<staff-lines>6</staff-lines>
|
| 110 |
+
<staff-tuning line="1">
|
| 111 |
+
<tuning-step>E</tuning-step>
|
| 112 |
+
<tuning-octave>2</tuning-octave>
|
| 113 |
+
</staff-tuning>
|
| 114 |
+
<staff-tuning line="2">
|
| 115 |
+
<tuning-step>A</tuning-step>
|
| 116 |
+
<tuning-octave>2</tuning-octave>
|
| 117 |
+
</staff-tuning>
|
| 118 |
+
<staff-tuning line="3">
|
| 119 |
+
<tuning-step>D</tuning-step>
|
| 120 |
+
<tuning-octave>3</tuning-octave>
|
| 121 |
+
</staff-tuning>
|
| 122 |
+
<staff-tuning line="4">
|
| 123 |
+
<tuning-step>G</tuning-step>
|
| 124 |
+
<tuning-octave>3</tuning-octave>
|
| 125 |
+
</staff-tuning>
|
| 126 |
+
<staff-tuning line="5">
|
| 127 |
+
<tuning-step>B</tuning-step>
|
| 128 |
+
<tuning-octave>3</tuning-octave>
|
| 129 |
+
</staff-tuning>
|
| 130 |
+
<staff-tuning line="6">
|
| 131 |
+
<tuning-step>E</tuning-step>
|
| 132 |
+
<tuning-octave>4</tuning-octave>
|
| 133 |
+
</staff-tuning>
|
| 134 |
+
</staff-details>
|
| 135 |
+
</attributes>
|
| 136 |
+
<direction placement="above">
|
| 137 |
+
<direction-type>
|
| 138 |
+
<metronome parentheses="no" default-x="-37.68" relative-y="20.00">
|
| 139 |
+
<beat-unit>quarter</beat-unit>
|
| 140 |
+
<per-minute>60</per-minute>
|
| 141 |
+
</metronome>
|
| 142 |
+
</direction-type>
|
| 143 |
+
<staff>1</staff>
|
| 144 |
+
<sound tempo="60"/>
|
| 145 |
+
</direction>
|
| 146 |
+
<note>
|
| 147 |
+
<rest/>
|
| 148 |
+
<duration>2</duration>
|
| 149 |
+
<voice>1</voice>
|
| 150 |
+
<type>eighth</type>
|
| 151 |
+
<staff>1</staff>
|
| 152 |
+
</note>
|
| 153 |
+
<note default-x="254.78" default-y="-5.00">
|
| 154 |
+
<pitch>
|
| 155 |
+
<step>E</step>
|
| 156 |
+
<octave>4</octave>
|
| 157 |
+
</pitch>
|
| 158 |
+
<duration>2</duration>
|
| 159 |
+
<voice>1</voice>
|
| 160 |
+
<type>eighth</type>
|
| 161 |
+
<stem>down</stem>
|
| 162 |
+
<staff>1</staff>
|
| 163 |
+
</note>
|
| 164 |
+
<backup>
|
| 165 |
+
<duration>4</duration>
|
| 166 |
+
</backup>
|
| 167 |
+
<note>
|
| 168 |
+
<rest/>
|
| 169 |
+
<duration>2</duration>
|
| 170 |
+
<voice>5</voice>
|
| 171 |
+
<type>eighth</type>
|
| 172 |
+
<staff>2</staff>
|
| 173 |
+
</note>
|
| 174 |
+
<note default-x="257.68" default-y="-170.23">
|
| 175 |
+
<pitch>
|
| 176 |
+
<step>E</step>
|
| 177 |
+
<octave>4</octave>
|
| 178 |
+
</pitch>
|
| 179 |
+
<duration>2</duration>
|
| 180 |
+
<voice>5</voice>
|
| 181 |
+
<type>eighth</type>
|
| 182 |
+
<stem>down</stem>
|
| 183 |
+
<staff>2</staff>
|
| 184 |
+
<notations>
|
| 185 |
+
<technical>
|
| 186 |
+
<string>1</string>
|
| 187 |
+
<fret>0</fret>
|
| 188 |
+
</technical>
|
| 189 |
+
</notations>
|
| 190 |
+
</note>
|
| 191 |
+
</measure>
|
| 192 |
+
<measure number="1" width="589.63">
|
| 193 |
+
<note default-x="16.50" default-y="30.00">
|
| 194 |
+
<pitch>
|
| 195 |
+
<step>E</step>
|
| 196 |
+
<octave>5</octave>
|
| 197 |
+
</pitch>
|
| 198 |
+
<duration>4</duration>
|
| 199 |
+
<tie type="start"/>
|
| 200 |
+
<voice>1</voice>
|
| 201 |
+
<type>quarter</type>
|
| 202 |
+
<stem>up</stem>
|
| 203 |
+
<staff>1</staff>
|
| 204 |
+
<notations>
|
| 205 |
+
<tied type="start"/>
|
| 206 |
+
</notations>
|
| 207 |
+
</note>
|
| 208 |
+
<note default-x="216.09" default-y="30.00">
|
| 209 |
+
<pitch>
|
| 210 |
+
<step>E</step>
|
| 211 |
+
<octave>5</octave>
|
| 212 |
+
</pitch>
|
| 213 |
+
<duration>1</duration>
|
| 214 |
+
<tie type="stop"/>
|
| 215 |
+
<voice>1</voice>
|
| 216 |
+
<type>16th</type>
|
| 217 |
+
<stem>up</stem>
|
| 218 |
+
<staff>1</staff>
|
| 219 |
+
<beam number="1">begin</beam>
|
| 220 |
+
<beam number="2">begin</beam>
|
| 221 |
+
<notations>
|
| 222 |
+
<tied type="stop"/>
|
| 223 |
+
</notations>
|
| 224 |
+
</note>
|
| 225 |
+
<note default-x="306.81" default-y="25.00">
|
| 226 |
+
<pitch>
|
| 227 |
+
<step>D</step>
|
| 228 |
+
<octave>5</octave>
|
| 229 |
+
</pitch>
|
| 230 |
+
<duration>1</duration>
|
| 231 |
+
<voice>1</voice>
|
| 232 |
+
<type>16th</type>
|
| 233 |
+
<stem>up</stem>
|
| 234 |
+
<staff>1</staff>
|
| 235 |
+
<beam number="1">continue</beam>
|
| 236 |
+
<beam number="2">continue</beam>
|
| 237 |
+
</note>
|
| 238 |
+
<note default-x="397.54" default-y="20.00">
|
| 239 |
+
<pitch>
|
| 240 |
+
<step>C</step>
|
| 241 |
+
<alter>1</alter>
|
| 242 |
+
<octave>5</octave>
|
| 243 |
+
</pitch>
|
| 244 |
+
<duration>1</duration>
|
| 245 |
+
<voice>1</voice>
|
| 246 |
+
<type>16th</type>
|
| 247 |
+
<stem>up</stem>
|
| 248 |
+
<staff>1</staff>
|
| 249 |
+
<beam number="1">continue</beam>
|
| 250 |
+
<beam number="2">continue</beam>
|
| 251 |
+
</note>
|
| 252 |
+
<note default-x="488.26" default-y="15.00">
|
| 253 |
+
<pitch>
|
| 254 |
+
<step>B</step>
|
| 255 |
+
<octave>4</octave>
|
| 256 |
+
</pitch>
|
| 257 |
+
<duration>1</duration>
|
| 258 |
+
<voice>1</voice>
|
| 259 |
+
<type>16th</type>
|
| 260 |
+
<stem>up</stem>
|
| 261 |
+
<staff>1</staff>
|
| 262 |
+
<beam number="1">end</beam>
|
| 263 |
+
<beam number="2">end</beam>
|
| 264 |
+
</note>
|
| 265 |
+
<backup>
|
| 266 |
+
<duration>8</duration>
|
| 267 |
+
</backup>
|
| 268 |
+
<note default-x="16.50" default-y="-60.00">
|
| 269 |
+
<pitch>
|
| 270 |
+
<step>A</step>
|
| 271 |
+
<octave>2</octave>
|
| 272 |
+
</pitch>
|
| 273 |
+
<duration>8</duration>
|
| 274 |
+
<voice>2</voice>
|
| 275 |
+
<type>half</type>
|
| 276 |
+
<stem>down</stem>
|
| 277 |
+
<staff>1</staff>
|
| 278 |
+
</note>
|
| 279 |
+
<backup>
|
| 280 |
+
<duration>8</duration>
|
| 281 |
+
</backup>
|
| 282 |
+
<forward>
|
| 283 |
+
<duration>4</duration>
|
| 284 |
+
</forward>
|
| 285 |
+
<note default-x="216.09" default-y="-20.00">
|
| 286 |
+
<pitch>
|
| 287 |
+
<step>B</step>
|
| 288 |
+
<octave>3</octave>
|
| 289 |
+
</pitch>
|
| 290 |
+
<duration>4</duration>
|
| 291 |
+
<voice>4</voice>
|
| 292 |
+
<type>quarter</type>
|
| 293 |
+
<stem>down</stem>
|
| 294 |
+
<staff>1</staff>
|
| 295 |
+
</note>
|
| 296 |
+
<note default-x="216.09" default-y="0.00">
|
| 297 |
+
<chord/>
|
| 298 |
+
<pitch>
|
| 299 |
+
<step>F</step>
|
| 300 |
+
<alter>1</alter>
|
| 301 |
+
<octave>4</octave>
|
| 302 |
+
</pitch>
|
| 303 |
+
<duration>4</duration>
|
| 304 |
+
<voice>4</voice>
|
| 305 |
+
<type>quarter</type>
|
| 306 |
+
<stem>down</stem>
|
| 307 |
+
<staff>1</staff>
|
| 308 |
+
</note>
|
| 309 |
+
<note default-x="216.09" default-y="10.00">
|
| 310 |
+
<chord/>
|
| 311 |
+
<pitch>
|
| 312 |
+
<step>A</step>
|
| 313 |
+
<octave>4</octave>
|
| 314 |
+
</pitch>
|
| 315 |
+
<duration>4</duration>
|
| 316 |
+
<voice>4</voice>
|
| 317 |
+
<type>quarter</type>
|
| 318 |
+
<stem>down</stem>
|
| 319 |
+
<staff>1</staff>
|
| 320 |
+
</note>
|
| 321 |
+
<backup>
|
| 322 |
+
<duration>8</duration>
|
| 323 |
+
</backup>
|
| 324 |
+
<note default-x="14.80" default-y="-170.23">
|
| 325 |
+
<pitch>
|
| 326 |
+
<step>E</step>
|
| 327 |
+
<octave>5</octave>
|
| 328 |
+
</pitch>
|
| 329 |
+
<duration>4</duration>
|
| 330 |
+
<tie type="start"/>
|
| 331 |
+
<voice>5</voice>
|
| 332 |
+
<type>quarter</type>
|
| 333 |
+
<stem>up</stem>
|
| 334 |
+
<staff>2</staff>
|
| 335 |
+
<notations>
|
| 336 |
+
<tied type="start"/>
|
| 337 |
+
<technical>
|
| 338 |
+
<string>1</string>
|
| 339 |
+
<fret>12</fret>
|
| 340 |
+
</technical>
|
| 341 |
+
</notations>
|
| 342 |
+
</note>
|
| 343 |
+
<note default-x="214.39" default-y="-170.23">
|
| 344 |
+
<pitch>
|
| 345 |
+
<step>E</step>
|
| 346 |
+
<octave>5</octave>
|
| 347 |
+
</pitch>
|
| 348 |
+
<duration>1</duration>
|
| 349 |
+
<tie type="stop"/>
|
| 350 |
+
<voice>5</voice>
|
| 351 |
+
<type>16th</type>
|
| 352 |
+
<stem>up</stem>
|
| 353 |
+
<staff>2</staff>
|
| 354 |
+
<beam number="1">begin</beam>
|
| 355 |
+
<beam number="2">begin</beam>
|
| 356 |
+
<notations>
|
| 357 |
+
<tied type="stop"/>
|
| 358 |
+
<technical>
|
| 359 |
+
<string>1</string>
|
| 360 |
+
<fret>12</fret>
|
| 361 |
+
</technical>
|
| 362 |
+
</notations>
|
| 363 |
+
</note>
|
| 364 |
+
<note default-x="305.11" default-y="-170.23">
|
| 365 |
+
<pitch>
|
| 366 |
+
<step>D</step>
|
| 367 |
+
<octave>5</octave>
|
| 368 |
+
</pitch>
|
| 369 |
+
<duration>1</duration>
|
| 370 |
+
<voice>5</voice>
|
| 371 |
+
<type>16th</type>
|
| 372 |
+
<stem>up</stem>
|
| 373 |
+
<staff>2</staff>
|
| 374 |
+
<beam number="1">continue</beam>
|
| 375 |
+
<beam number="2">continue</beam>
|
| 376 |
+
<notations>
|
| 377 |
+
<technical>
|
| 378 |
+
<string>1</string>
|
| 379 |
+
<fret>10</fret>
|
| 380 |
+
</technical>
|
| 381 |
+
</notations>
|
| 382 |
+
</note>
|
| 383 |
+
<note default-x="400.44" default-y="-170.23">
|
| 384 |
+
<pitch>
|
| 385 |
+
<step>C</step>
|
| 386 |
+
<alter>1</alter>
|
| 387 |
+
<octave>5</octave>
|
| 388 |
+
</pitch>
|
| 389 |
+
<duration>1</duration>
|
| 390 |
+
<voice>5</voice>
|
| 391 |
+
<type>16th</type>
|
| 392 |
+
<stem>up</stem>
|
| 393 |
+
<staff>2</staff>
|
| 394 |
+
<beam number="1">continue</beam>
|
| 395 |
+
<beam number="2">continue</beam>
|
| 396 |
+
<notations>
|
| 397 |
+
<technical>
|
| 398 |
+
<string>1</string>
|
| 399 |
+
<fret>9</fret>
|
| 400 |
+
</technical>
|
| 401 |
+
</notations>
|
| 402 |
+
</note>
|
| 403 |
+
<note default-x="491.16" default-y="-170.23">
|
| 404 |
+
<pitch>
|
| 405 |
+
<step>B</step>
|
| 406 |
+
<octave>4</octave>
|
| 407 |
+
</pitch>
|
| 408 |
+
<duration>1</duration>
|
| 409 |
+
<voice>5</voice>
|
| 410 |
+
<type>16th</type>
|
| 411 |
+
<stem>up</stem>
|
| 412 |
+
<staff>2</staff>
|
| 413 |
+
<beam number="1">end</beam>
|
| 414 |
+
<beam number="2">end</beam>
|
| 415 |
+
<notations>
|
| 416 |
+
<technical>
|
| 417 |
+
<string>1</string>
|
| 418 |
+
<fret>7</fret>
|
| 419 |
+
</technical>
|
| 420 |
+
</notations>
|
| 421 |
+
</note>
|
| 422 |
+
<backup>
|
| 423 |
+
<duration>8</duration>
|
| 424 |
+
</backup>
|
| 425 |
+
<note default-x="19.40" default-y="-230.23">
|
| 426 |
+
<pitch>
|
| 427 |
+
<step>A</step>
|
| 428 |
+
<octave>2</octave>
|
| 429 |
+
</pitch>
|
| 430 |
+
<duration>8</duration>
|
| 431 |
+
<voice>6</voice>
|
| 432 |
+
<type>half</type>
|
| 433 |
+
<stem>down</stem>
|
| 434 |
+
<staff>2</staff>
|
| 435 |
+
<notations>
|
| 436 |
+
<technical>
|
| 437 |
+
<string>5</string>
|
| 438 |
+
<fret>0</fret>
|
| 439 |
+
</technical>
|
| 440 |
+
</notations>
|
| 441 |
+
</note>
|
| 442 |
+
<backup>
|
| 443 |
+
<duration>8</duration>
|
| 444 |
+
</backup>
|
| 445 |
+
<forward>
|
| 446 |
+
<duration>4</duration>
|
| 447 |
+
</forward>
|
| 448 |
+
<note default-x="218.99" default-y="-215.23">
|
| 449 |
+
<pitch>
|
| 450 |
+
<step>B</step>
|
| 451 |
+
<octave>3</octave>
|
| 452 |
+
</pitch>
|
| 453 |
+
<duration>4</duration>
|
| 454 |
+
<voice>8</voice>
|
| 455 |
+
<type>quarter</type>
|
| 456 |
+
<stem>down</stem>
|
| 457 |
+
<staff>2</staff>
|
| 458 |
+
<notations>
|
| 459 |
+
<technical>
|
| 460 |
+
<string>4</string>
|
| 461 |
+
<fret>9</fret>
|
| 462 |
+
</technical>
|
| 463 |
+
</notations>
|
| 464 |
+
</note>
|
| 465 |
+
<note default-x="214.39" default-y="-200.23">
|
| 466 |
+
<chord/>
|
| 467 |
+
<pitch>
|
| 468 |
+
<step>F</step>
|
| 469 |
+
<alter>1</alter>
|
| 470 |
+
<octave>4</octave>
|
| 471 |
+
</pitch>
|
| 472 |
+
<duration>4</duration>
|
| 473 |
+
<voice>8</voice>
|
| 474 |
+
<type>quarter</type>
|
| 475 |
+
<stem>down</stem>
|
| 476 |
+
<staff>2</staff>
|
| 477 |
+
<notations>
|
| 478 |
+
<technical>
|
| 479 |
+
<string>3</string>
|
| 480 |
+
<fret>11</fret>
|
| 481 |
+
</technical>
|
| 482 |
+
</notations>
|
| 483 |
+
</note>
|
| 484 |
+
<note default-x="214.39" default-y="-185.23">
|
| 485 |
+
<chord/>
|
| 486 |
+
<pitch>
|
| 487 |
+
<step>A</step>
|
| 488 |
+
<octave>4</octave>
|
| 489 |
+
</pitch>
|
| 490 |
+
<duration>4</duration>
|
| 491 |
+
<voice>8</voice>
|
| 492 |
+
<type>quarter</type>
|
| 493 |
+
<stem>down</stem>
|
| 494 |
+
<staff>2</staff>
|
| 495 |
+
<notations>
|
| 496 |
+
<technical>
|
| 497 |
+
<string>2</string>
|
| 498 |
+
<fret>10</fret>
|
| 499 |
+
</technical>
|
| 500 |
+
</notations>
|
| 501 |
+
</note>
|
| 502 |
+
<barline location="right">
|
| 503 |
+
<bar-style>light-heavy</bar-style>
|
| 504 |
+
</barline>
|
| 505 |
+
</measure>
|
| 506 |
+
</part>
|
| 507 |
+
</score-partwise>
|
frontend/public/guitar-diff-example.vextab.txt
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
tabstave notation=true key=A time=4/4
|
| 2 |
+
|
| 3 |
+
notes :q =|: (5/2.5/3.7/4) :8 7-5h6/3 ^3^ 5h6-7/5 ^3^ :q 7V/4 |
|
| 4 |
+
notes :8 t12p7/4 s5s3/4 :8 3s:16:5-7/5 :q p5/4
|
| 5 |
+
|
| 6 |
+
text :w, |#segno, ,|, :hd, , #tr
|
frontend/public/guitarDiffLogo2.svg
ADDED
|
|
frontend/public/guitarDiffLogo3.svg
ADDED
|
|
frontend/public/guitar_faded_noReport.png
ADDED
|
frontend/public/guitar_rotated.svg
ADDED
|
|
frontend/public/guitar_rotated_report.svg
ADDED
|
|
frontend/public/guitar_straight.svg
ADDED
|
|
frontend/public/inkscape_canvas.svg
ADDED
|
|
frontend/public/test.svg
ADDED
|
|
frontend/public/vite.svg
ADDED
|
|
frontend/src/App.vue
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<script setup>
|
| 2 |
+
import { RouterLink, RouterView } from 'vue-router'
|
| 3 |
+
import { ref } from 'vue'
|
| 4 |
+
|
| 5 |
+
const state = ref({
|
| 6 |
+
position: 'top-right',
|
| 7 |
+
url: 'https://github.com/xribene',
|
| 8 |
+
background: '#FFF',
|
| 9 |
+
fill: '#0a2050',
|
| 10 |
+
})
|
| 11 |
+
</script>
|
| 12 |
+
|
| 13 |
+
<template>
|
| 14 |
+
<div class="app-container">
|
| 15 |
+
<v-github-icon
|
| 16 |
+
:position="state.position"
|
| 17 |
+
:url="state.url"
|
| 18 |
+
:bg-color="state.background"
|
| 19 |
+
:fill-color="state.fill"
|
| 20 |
+
/>
|
| 21 |
+
|
| 22 |
+
<nav class="navbar">
|
| 23 |
+
<ul class="nav-list">
|
| 24 |
+
<li>
|
| 25 |
+
<RouterLink :to="{ name: 'Home' }">
|
| 26 |
+
Home
|
| 27 |
+
</RouterLink>
|
| 28 |
+
</li>
|
| 29 |
+
<li>
|
| 30 |
+
<RouterLink :to="{ name: 'Analyzer' }">
|
| 31 |
+
Analyzer
|
| 32 |
+
</RouterLink>
|
| 33 |
+
</li>
|
| 34 |
+
</ul>
|
| 35 |
+
</nav>
|
| 36 |
+
|
| 37 |
+
<div class="content">
|
| 38 |
+
<!-- <a href="https://vitejs.dev" target="_blank">
|
| 39 |
+
<img src="/guitarDiffLogo2.svg" class="logo" alt="Vite logo" />
|
| 40 |
+
</a> -->
|
| 41 |
+
|
| 42 |
+
<!-- <keep-alive>
|
| 43 |
+
<router-view />
|
| 44 |
+
</keep-alive> -->
|
| 45 |
+
<RouterView v-slot="{ Component }">
|
| 46 |
+
<keep-alive>
|
| 47 |
+
<component :is="Component" :key="$route.fullPath" />
|
| 48 |
+
</keep-alive>
|
| 49 |
+
</RouterView>
|
| 50 |
+
</div>
|
| 51 |
+
</div>
|
| 52 |
+
</template>
|
| 53 |
+
|
| 54 |
+
<style scoped>
|
| 55 |
+
.app-container {
|
| 56 |
+
display: flex;
|
| 57 |
+
flex-direction: column;
|
| 58 |
+
align-items: center;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
.navbar {
|
| 62 |
+
background-color: #c5bdbd;
|
| 63 |
+
padding: 1rem;
|
| 64 |
+
width: 100%;
|
| 65 |
+
/* margin-left: 10px; */
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
.nav-list {
|
| 69 |
+
list-style: none;
|
| 70 |
+
padding: 0;
|
| 71 |
+
margin: 0;
|
| 72 |
+
display: flex;
|
| 73 |
+
/* background-color: #0a2050; */
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
.nav-list li {
|
| 77 |
+
margin-right: 1rem;
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
.nav-list li a {
|
| 81 |
+
text-decoration: none;
|
| 82 |
+
color: rgb(78, 74, 74);
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
.content {
|
| 86 |
+
margin: 2rem;
|
| 87 |
+
text-align: center;
|
| 88 |
+
}
|
| 89 |
+
</style>
|
frontend/src/assets/vue.svg
ADDED
|
|
frontend/src/components/CounterButton.vue
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<script setup>
|
| 2 |
+
import { ref } from 'vue'
|
| 3 |
+
|
| 4 |
+
defineProps({
|
| 5 |
+
msg: String,
|
| 6 |
+
})
|
| 7 |
+
|
| 8 |
+
const counter = ref(0)
|
| 9 |
+
|
| 10 |
+
function increment() {
|
| 11 |
+
counter.value++
|
| 12 |
+
}
|
| 13 |
+
</script>
|
| 14 |
+
|
| 15 |
+
<template>
|
| 16 |
+
<h1>{{ msg }}</h1>
|
| 17 |
+
<button @click="increment">
|
| 18 |
+
{{ counter }}
|
| 19 |
+
</button>
|
| 20 |
+
</template>
|
frontend/src/components/HelloWorld.vue
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<script setup>
|
| 2 |
+
import { ref } from 'vue'
|
| 3 |
+
|
| 4 |
+
defineProps({
|
| 5 |
+
msg: String,
|
| 6 |
+
})
|
| 7 |
+
|
| 8 |
+
const count = ref(0)
|
| 9 |
+
</script>
|
| 10 |
+
|
| 11 |
+
<template>
|
| 12 |
+
<h1>{{ msg }}</h1>
|
| 13 |
+
|
| 14 |
+
<div class="card">
|
| 15 |
+
<button type="button" @click="count++">
|
| 16 |
+
count is {{ count }}
|
| 17 |
+
</button>
|
| 18 |
+
<p>
|
| 19 |
+
Edit
|
| 20 |
+
<code>components/HelloWorld.vue</code> to test HMR
|
| 21 |
+
</p>
|
| 22 |
+
</div>
|
| 23 |
+
|
| 24 |
+
<p>
|
| 25 |
+
Check out
|
| 26 |
+
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank">create-vue</a>, the official Vue + Vite starter
|
| 27 |
+
</p>
|
| 28 |
+
<p>
|
| 29 |
+
Install
|
| 30 |
+
<a href="https://github.com/vuejs/language-tools" target="_blank">Volar</a>
|
| 31 |
+
in your IDE for a better DX
|
| 32 |
+
</p>
|
| 33 |
+
<p class="read-the-docs">
|
| 34 |
+
Click on the Vite and Vue logos to learn more
|
| 35 |
+
</p>
|
| 36 |
+
</template>
|
| 37 |
+
|
| 38 |
+
<style scoped>
|
| 39 |
+
.read-the-docs {
|
| 40 |
+
color: #888;
|
| 41 |
+
}
|
| 42 |
+
</style>
|
frontend/src/components/MusicXmlWidget.vue
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<script setup>
|
| 2 |
+
import { computed, onMounted, onUpdated, ref, watch } from 'vue'
|
| 3 |
+
import { OpenSheetMusicDisplay } from 'opensheetmusicdisplay'
|
| 4 |
+
import { Pane } from 'tweakpane'
|
| 5 |
+
|
| 6 |
+
const props = defineProps({
|
| 7 |
+
// int id
|
| 8 |
+
id: {
|
| 9 |
+
type: String,
|
| 10 |
+
required: true,
|
| 11 |
+
},
|
| 12 |
+
xmlText: {
|
| 13 |
+
type: String,
|
| 14 |
+
required: false,
|
| 15 |
+
},
|
| 16 |
+
isActive: {
|
| 17 |
+
type: Boolean,
|
| 18 |
+
required: false,
|
| 19 |
+
default: false,
|
| 20 |
+
},
|
| 21 |
+
|
| 22 |
+
})
|
| 23 |
+
|
| 24 |
+
const emit = defineEmits(['updateScoreCode'])
|
| 25 |
+
|
| 26 |
+
// let renderer = null;
|
| 27 |
+
// let artist = null;
|
| 28 |
+
// let tab = null;
|
| 29 |
+
|
| 30 |
+
let openSheetMusicDisplay = null
|
| 31 |
+
let timeoutID = null
|
| 32 |
+
let pane = null
|
| 33 |
+
|
| 34 |
+
// const message = ref('hello')
|
| 35 |
+
const currentScoreCode = ref(props.xmlText)
|
| 36 |
+
const showParsingError = ref(false)
|
| 37 |
+
const parsingError = ref('')
|
| 38 |
+
// const count = ref(0)
|
| 39 |
+
const settingsStatus = ref(false)
|
| 40 |
+
const isActive = ref(false)
|
| 41 |
+
|
| 42 |
+
const SETTINGS_PARAMS = {
|
| 43 |
+
scale: 1.0,
|
| 44 |
+
// width: 800,
|
| 45 |
+
// factor: 123,
|
| 46 |
+
// title: 'hello',
|
| 47 |
+
// color: '#ff0055',
|
| 48 |
+
// percentage: 50,
|
| 49 |
+
// theme: 'dark',
|
| 50 |
+
// prop: 'Put your\nmultiline\ntext here!'
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
const divId = computed(() => {
|
| 54 |
+
return `xmlScoreContainer_${props.id}`
|
| 55 |
+
})
|
| 56 |
+
|
| 57 |
+
function initializePane() {
|
| 58 |
+
pane = new Pane({
|
| 59 |
+
container: document.getElementById('paneContainerXml'),
|
| 60 |
+
title: 'MusicXML Settings',
|
| 61 |
+
},
|
| 62 |
+
)
|
| 63 |
+
pane.addBinding(SETTINGS_PARAMS, 'scale', {
|
| 64 |
+
min: 0.5,
|
| 65 |
+
max: 2.0,
|
| 66 |
+
step: 0.1,
|
| 67 |
+
}).on('change', (ev) => {
|
| 68 |
+
console.log(ev.value)
|
| 69 |
+
openSheetMusicDisplay.zoom = ev.value
|
| 70 |
+
openSheetMusicDisplay.render()
|
| 71 |
+
})
|
| 72 |
+
|
| 73 |
+
// pane.addBinding(SETTINGS_PARAMS, 'width', {
|
| 74 |
+
// min: 400,
|
| 75 |
+
// max: 1200,
|
| 76 |
+
// step: 50
|
| 77 |
+
// }).on('change', (ev) => {
|
| 78 |
+
// console.log(ev.value);
|
| 79 |
+
// artist.reset();
|
| 80 |
+
// tab.reset();
|
| 81 |
+
// tab.parse(currentTabText.value);
|
| 82 |
+
// artist.width = ev.value;
|
| 83 |
+
// artist.render(renderer);
|
| 84 |
+
// });
|
| 85 |
+
}
|
| 86 |
+
async function initializeOSMD() {
|
| 87 |
+
// renderer = new Flow.Renderer($('#' + divId.value)[0], Flow.Renderer.Backends.SVG);
|
| 88 |
+
// artist = new Artist(10, 10, 750, { scale: 0.8 });
|
| 89 |
+
// tab = new VexTab(artist);
|
| 90 |
+
openSheetMusicDisplay = new OpenSheetMusicDisplay(divId.value, {
|
| 91 |
+
autoResize: false,
|
| 92 |
+
backend: 'svg',
|
| 93 |
+
disableCursor: false,
|
| 94 |
+
drawingParameters: 'full', // : "default", // try compact (instead of default)
|
| 95 |
+
drawPartNames: false, // try false
|
| 96 |
+
drawTitle: false,
|
| 97 |
+
drawSubtitle: false,
|
| 98 |
+
drawComposer: false,
|
| 99 |
+
// darkMode: true,
|
| 100 |
+
// cursor
|
| 101 |
+
followCursor: true,
|
| 102 |
+
drawFingerings: true,
|
| 103 |
+
// fingeringPosition: "left", // Above/Below is default. try left or right. experimental: above, below.
|
| 104 |
+
// fingeringPositionFromXML: false, // do this if you want them always left, for example.
|
| 105 |
+
// fingeringInsideStafflines: "true", // default: false. true draws fingerings directly above/below notes
|
| 106 |
+
setWantedStemDirectionByXml: true, // try false, which was previously the default behavior
|
| 107 |
+
drawUpToMeasureNumber: 20, // draws only up to measure 3, meaning it draws measure 1 to 3 of the piece.
|
| 108 |
+
// drawFromMeasureNumber : 1,
|
| 109 |
+
// drawUpToMeasureNumber : 3,
|
| 110 |
+
drawMeasureNumbers: true,
|
| 111 |
+
|
| 112 |
+
// drawMeasureNumbers: false, // disable drawing measure numbers
|
| 113 |
+
// measureNumberInterval: 4, // draw measure numbers only every 4 bars (and at the beginning of a new system)
|
| 114 |
+
useXMLMeasureNumbers: true, // read measure numbers from xml
|
| 115 |
+
|
| 116 |
+
// coloring options
|
| 117 |
+
coloringEnabled: true,
|
| 118 |
+
// defaultColorNotehead: "#CC0055", // try setting a default color. default is black (undefined)
|
| 119 |
+
// defaultColorStem: "#BB0099",
|
| 120 |
+
|
| 121 |
+
autoBeam: false, // try true, OSMD Function Test AutoBeam sample
|
| 122 |
+
autoBeamOptions: {
|
| 123 |
+
beam_rests: false,
|
| 124 |
+
beam_middle_rests_only: false,
|
| 125 |
+
// groups: [[3,4], [1,1]],
|
| 126 |
+
maintain_stem_directions: false,
|
| 127 |
+
},
|
| 128 |
+
// pageFormat: "A4_P",//"Endless",//pageFormat,
|
| 129 |
+
// pageBackgroundColor: "red",
|
| 130 |
+
renderSingleHorizontalStaffline: true, // true
|
| 131 |
+
|
| 132 |
+
// tupletsBracketed: true, // creates brackets for all tuplets except triplets, even when not set by xml
|
| 133 |
+
// tripletsBracketed: true,
|
| 134 |
+
// tupletsRatioed: true, // unconventional; renders ratios for tuplets (3:2 instead of 3 for triplets)
|
| 135 |
+
})
|
| 136 |
+
// window.osmd = openSheetMusicDisplay;
|
| 137 |
+
// artist.reset();
|
| 138 |
+
// tab.reset();
|
| 139 |
+
// tab.parse(currentTabText.value);
|
| 140 |
+
// artist.render(renderer);
|
| 141 |
+
await fetch('/guitar-diff-example.musicxml')
|
| 142 |
+
.then((response) => {
|
| 143 |
+
return response.text()
|
| 144 |
+
})
|
| 145 |
+
.then((data) => {
|
| 146 |
+
console.log('in data')
|
| 147 |
+
openSheetMusicDisplay.load(data)
|
| 148 |
+
.then(
|
| 149 |
+
() => {
|
| 150 |
+
window.osmd = openSheetMusicDisplay
|
| 151 |
+
openSheetMusicDisplay.render()
|
| 152 |
+
// openSheetMusicDisplay.cursor.show();
|
| 153 |
+
console.log('in load')
|
| 154 |
+
showParsingError.value = false
|
| 155 |
+
currentScoreCode.value = data
|
| 156 |
+
},
|
| 157 |
+
)
|
| 158 |
+
.catch((e) => {
|
| 159 |
+
showParsingError.value = true
|
| 160 |
+
console.log(e.message.replace(/(?:\r\n|\r|\n)/g, '<br>'))
|
| 161 |
+
parsingError.value = e.message.replace(/(?:\r\n|\r|\n)/g, '<br>')
|
| 162 |
+
})
|
| 163 |
+
|
| 164 |
+
// .catch((e) => {
|
| 165 |
+
// showParsingError.value = true;
|
| 166 |
+
// console.log(e.message.replace(/(?:\r\n|\r|\n)/g, '<br>'));
|
| 167 |
+
// parsingError.value = e.message.replace(/(?:\r\n|\r|\n)/g, '<br>');
|
| 168 |
+
// });
|
| 169 |
+
})
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
// function loadScoreCode(scoreCode) {
|
| 173 |
+
// currentScoreCode.value = scoreCode
|
| 174 |
+
// showScore()
|
| 175 |
+
// }
|
| 176 |
+
|
| 177 |
+
function showScore() {
|
| 178 |
+
openSheetMusicDisplay.clear()
|
| 179 |
+
console.log(currentScoreCode.value)
|
| 180 |
+
openSheetMusicDisplay.load(currentScoreCode.value)
|
| 181 |
+
.then(
|
| 182 |
+
() => {
|
| 183 |
+
window.osmd = openSheetMusicDisplay
|
| 184 |
+
openSheetMusicDisplay.render()
|
| 185 |
+
// openSheetMusicDisplay.cursor.show();
|
| 186 |
+
console.log('in load')
|
| 187 |
+
showParsingError.value = false
|
| 188 |
+
},
|
| 189 |
+
)
|
| 190 |
+
.catch((e) => {
|
| 191 |
+
showParsingError.value = true
|
| 192 |
+
console.log(e.message.replace(/(?:\r\n|\r|\n)/g, '<br>'))
|
| 193 |
+
parsingError.value = e.message.replace(/(?:\r\n|\r|\n)/g, '<br>')
|
| 194 |
+
})
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
function handleKeyUp(_event) {
|
| 198 |
+
if (timeoutID)
|
| 199 |
+
clearTimeout(timeoutID)
|
| 200 |
+
timeoutID = setTimeout(showScore, 500)
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
onMounted(async () => {
|
| 204 |
+
// console.log($(`#${divId.value}`)[0])
|
| 205 |
+
initializePane()
|
| 206 |
+
await initializeOSMD()
|
| 207 |
+
})
|
| 208 |
+
|
| 209 |
+
function handleDrop(event) {
|
| 210 |
+
event.preventDefault()
|
| 211 |
+
const textData = event.dataTransfer.getData('text')
|
| 212 |
+
const file = event.dataTransfer.files[0]
|
| 213 |
+
console.log(textData)
|
| 214 |
+
console.log(file)
|
| 215 |
+
if (file) {
|
| 216 |
+
const reader = new FileReader()
|
| 217 |
+
reader.onload = function (e) {
|
| 218 |
+
currentScoreCode.value = e.target.result
|
| 219 |
+
showScore()
|
| 220 |
+
}
|
| 221 |
+
reader.readAsText(file)
|
| 222 |
+
}
|
| 223 |
+
else if (textData) {
|
| 224 |
+
currentScoreCode.value = textData
|
| 225 |
+
showScore()
|
| 226 |
+
}
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
function showHideSettings() {
|
| 230 |
+
console.log('showHideSettings')
|
| 231 |
+
settingsStatus.value = !settingsStatus.value
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
// invoked when there is any type of change in the component
|
| 235 |
+
onUpdated(() => {
|
| 236 |
+
if (props.isActive !== isActive.value) {
|
| 237 |
+
// Prop has changed, update the ref and emit an event
|
| 238 |
+
if (props.isActive) {
|
| 239 |
+
isActive.value = props.isActive
|
| 240 |
+
emit('updateScoreCode', currentScoreCode.value)
|
| 241 |
+
// console.log("emitted updateScoreCode");
|
| 242 |
+
// console.log(currentScoreCode.value);
|
| 243 |
+
}
|
| 244 |
+
isActive.value = props.isActive
|
| 245 |
+
}
|
| 246 |
+
})
|
| 247 |
+
|
| 248 |
+
watch(currentScoreCode, () => {
|
| 249 |
+
// Emit the event so that the parent component can update the tabText
|
| 250 |
+
// prop
|
| 251 |
+
emit('updateScoreCode', currentScoreCode.value)
|
| 252 |
+
// console.log("emitted updateScoreCode");
|
| 253 |
+
// console.log(currentScoreCode.value);
|
| 254 |
+
})
|
| 255 |
+
|
| 256 |
+
// const moveCursor = () => {
|
| 257 |
+
// openSheetMusicDisplay.cursor.next();
|
| 258 |
+
// };
|
| 259 |
+
|
| 260 |
+
// const fillScore = () => {
|
| 261 |
+
// // console.log(vt);
|
| 262 |
+
// // Perform any logic to fill the score
|
| 263 |
+
// response.value = 'Button pressed!'; // Update response if needed
|
| 264 |
+
|
| 265 |
+
// };
|
| 266 |
+
</script>
|
| 267 |
+
|
| 268 |
+
<template>
|
| 269 |
+
<!--
|
| 270 |
+
Which ever of the following elements wants to use the class
|
| 271 |
+
attributes coming from the parent component needs to use
|
| 272 |
+
:class="$attrs.class"
|
| 273 |
+
UNLESS I have a single root div-element
|
| 274 |
+
-->
|
| 275 |
+
<div>
|
| 276 |
+
<!-- <button @click="showScore">You clicked me {{ count }} times</button> -->
|
| 277 |
+
<button class="left-align" @click="showHideSettings">
|
| 278 |
+
<!-- <v-icon icon="mdi-pencil-box" /> -->
|
| 279 |
+
Settings
|
| 280 |
+
</button>
|
| 281 |
+
<div :id="divId" class="scoreContainer" />
|
| 282 |
+
|
| 283 |
+
<div v-show="settingsStatus" id="tabSettingsArea">
|
| 284 |
+
<!-- <TweakComponent :visible="settingsStatus"/> -->
|
| 285 |
+
<div id="paneContainerXml" />
|
| 286 |
+
<textarea
|
| 287 |
+
v-model="currentScoreCode"
|
| 288 |
+
class="editorBox"
|
| 289 |
+
placeholder="add your musicxml code here or drag a file"
|
| 290 |
+
@keyup="handleKeyUp"
|
| 291 |
+
@drop="handleDrop"
|
| 292 |
+
@dragover.prevent
|
| 293 |
+
/>
|
| 294 |
+
</div>
|
| 295 |
+
|
| 296 |
+
<div v-if="showParsingError" class="parsing-error" v-html="parsingError" />
|
| 297 |
+
</div>
|
| 298 |
+
</template>
|
| 299 |
+
|
| 300 |
+
<style scoped>
|
| 301 |
+
.xmlContainer {
|
| 302 |
+
/* width: 100%;
|
| 303 |
+
height: 100%; */
|
| 304 |
+
/* background-color: #f80707; */
|
| 305 |
+
border: 0px solid rgb(212, 22, 22);
|
| 306 |
+
overflow-x: auto;
|
| 307 |
+
}
|
| 308 |
+
|
| 309 |
+
.left-align {
|
| 310 |
+
display: flex;
|
| 311 |
+
margin-right: auto;
|
| 312 |
+
}
|
| 313 |
+
#tabSettingsArea {
|
| 314 |
+
display: flex;
|
| 315 |
+
flex-direction: row;
|
| 316 |
+
align-items: center; /* Optional: align items in the center vertically */
|
| 317 |
+
gap: 20px;
|
| 318 |
+
margin-left: 10px;
|
| 319 |
+
}
|
| 320 |
+
</style>
|
frontend/src/components/TweakComponent.vue
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<script>
|
| 2 |
+
import { ref } from 'vue'
|
| 3 |
+
|
| 4 |
+
const state = ref({
|
| 5 |
+
pane: {
|
| 6 |
+
title: 'My Awesome Pane',
|
| 7 |
+
inputs: [
|
| 8 |
+
{
|
| 9 |
+
factor: 123,
|
| 10 |
+
title: 'hello',
|
| 11 |
+
color: '#0f0',
|
| 12 |
+
},
|
| 13 |
+
],
|
| 14 |
+
},
|
| 15 |
+
})
|
| 16 |
+
const skata = 3
|
| 17 |
+
</script>
|
| 18 |
+
|
| 19 |
+
<template>
|
| 20 |
+
<!-- <v-tweakpane :pane="state.pane" /> -->
|
| 21 |
+
<div>blabla</div>
|
| 22 |
+
</template>
|
| 23 |
+
|
| 24 |
+
<style>
|
| 25 |
+
@import 'v-tweakpane/dist/v-tweakpane.css';
|
| 26 |
+
</style>
|
frontend/src/components/TweakComponent2.vue
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<script setup>
|
| 2 |
+
import { Pane } from 'tweakpane'
|
| 3 |
+
import * as TextareaPlugin from '@pangenerator/tweakpane-textarea-plugin'
|
| 4 |
+
import { onMounted, watch } from 'vue'
|
| 5 |
+
|
| 6 |
+
const props = defineProps({
|
| 7 |
+
visible: {
|
| 8 |
+
type: Boolean,
|
| 9 |
+
required: false,
|
| 10 |
+
default: false,
|
| 11 |
+
},
|
| 12 |
+
data: {
|
| 13 |
+
type: Object,
|
| 14 |
+
required: true,
|
| 15 |
+
default: () => {},
|
| 16 |
+
},
|
| 17 |
+
})
|
| 18 |
+
|
| 19 |
+
let pane = null
|
| 20 |
+
|
| 21 |
+
onMounted(() => {
|
| 22 |
+
initializePane()
|
| 23 |
+
})
|
| 24 |
+
|
| 25 |
+
watch(() => props.visible, () => {
|
| 26 |
+
updateVisibility()
|
| 27 |
+
})
|
| 28 |
+
|
| 29 |
+
// const updateData = (changeEvent) => {
|
| 30 |
+
// console.log(changeEvent);
|
| 31 |
+
// };
|
| 32 |
+
|
| 33 |
+
// const showHide = () => {
|
| 34 |
+
// pane.hidden = !pane.hidden;
|
| 35 |
+
// };
|
| 36 |
+
|
| 37 |
+
function updateVisibility() {
|
| 38 |
+
if (pane)
|
| 39 |
+
pane.hidden = !props.visible
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
function initializePane() {
|
| 43 |
+
const PARAMS = {
|
| 44 |
+
factor: 123,
|
| 45 |
+
title: 'hello',
|
| 46 |
+
color: '#ff0055',
|
| 47 |
+
percentage: 50,
|
| 48 |
+
theme: 'dark',
|
| 49 |
+
prop: 'Put your\nmultiline\ntext here!',
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
pane = new Pane({
|
| 53 |
+
container: document.getElementById('paneContainer'),
|
| 54 |
+
title: 'Mixer',
|
| 55 |
+
},
|
| 56 |
+
)
|
| 57 |
+
pane.registerPlugin(TextareaPlugin)
|
| 58 |
+
|
| 59 |
+
pane.addBinding(PARAMS, 'factor')
|
| 60 |
+
pane.addBinding(PARAMS, 'title')
|
| 61 |
+
pane.addBinding(PARAMS, 'color')
|
| 62 |
+
pane.addBinding(
|
| 63 |
+
PARAMS,
|
| 64 |
+
'percentage',
|
| 65 |
+
{ min: 0, max: 100, step: 10 },
|
| 66 |
+
)
|
| 67 |
+
|
| 68 |
+
// `options`: list
|
| 69 |
+
pane.addBinding(
|
| 70 |
+
PARAMS,
|
| 71 |
+
'theme',
|
| 72 |
+
{ options: { Dark: 'dark', Light: 'light' } },
|
| 73 |
+
)
|
| 74 |
+
|
| 75 |
+
// multiline pluggin
|
| 76 |
+
|
| 77 |
+
// pane.addBinding(PARAMS, 'prop', {
|
| 78 |
+
// view: 'textarea',
|
| 79 |
+
// rows: 6,
|
| 80 |
+
// placeholder: 'Type here...'
|
| 81 |
+
// }).on('change', (ev) => {
|
| 82 |
+
// console.log(ev.value);
|
| 83 |
+
// });
|
| 84 |
+
|
| 85 |
+
pane.hidden = !props.visible
|
| 86 |
+
}
|
| 87 |
+
</script>
|
| 88 |
+
|
| 89 |
+
<template>
|
| 90 |
+
<div id="paneContainer" />
|
| 91 |
+
</template>
|
| 92 |
+
|
| 93 |
+
<style scoped>
|
| 94 |
+
#paneContainer2 {
|
| 95 |
+
position: absolute;
|
| 96 |
+
top:300px;
|
| 97 |
+
right: 100px;
|
| 98 |
+
|
| 99 |
+
/* top: 0px; */
|
| 100 |
+
/* left: 0px; */
|
| 101 |
+
/* width: 100%; */
|
| 102 |
+
/* height: 100%; */
|
| 103 |
+
/* background-color: #f80707; */
|
| 104 |
+
/* border: 1px solid black; */
|
| 105 |
+
/* overflow-x: scroll; */
|
| 106 |
+
}
|
| 107 |
+
</style>
|
frontend/src/components/VextabWidget.vue
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<script setup>
|
| 2 |
+
import { computed, onMounted, onUpdated, ref, watch } from 'vue'
|
| 3 |
+
import { Artist, Flow, VexTab } from 'vextab/releases/vextab-div.js'
|
| 4 |
+
|
| 5 |
+
// import TweakComponent from '@/components/TweakComponent2.vue'
|
| 6 |
+
import { Pane } from 'tweakpane'
|
| 7 |
+
import * as TextareaPlugin from '@pangenerator/tweakpane-textarea-plugin'
|
| 8 |
+
|
| 9 |
+
const props = defineProps({
|
| 10 |
+
// int id
|
| 11 |
+
id: {
|
| 12 |
+
type: String,
|
| 13 |
+
required: true,
|
| 14 |
+
},
|
| 15 |
+
tabText: {
|
| 16 |
+
type: String,
|
| 17 |
+
required: false,
|
| 18 |
+
},
|
| 19 |
+
isActive: {
|
| 20 |
+
type: Boolean,
|
| 21 |
+
required: false,
|
| 22 |
+
default: false,
|
| 23 |
+
},
|
| 24 |
+
|
| 25 |
+
})
|
| 26 |
+
|
| 27 |
+
const emit = defineEmits(['updateScoreCode'])
|
| 28 |
+
|
| 29 |
+
let renderer = null
|
| 30 |
+
let artist = null
|
| 31 |
+
let tab = null
|
| 32 |
+
let timeoutID = null
|
| 33 |
+
let pane = null
|
| 34 |
+
|
| 35 |
+
const SETTINGS_PARAMS = {
|
| 36 |
+
scale: 1.0,
|
| 37 |
+
width: 800,
|
| 38 |
+
// factor: 123,
|
| 39 |
+
// title: 'hello',
|
| 40 |
+
// color: '#ff0055',
|
| 41 |
+
// percentage: 50,
|
| 42 |
+
// theme: 'dark',
|
| 43 |
+
// prop: 'Put your\nmultiline\ntext here!'
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
const message = ref('hello')
|
| 47 |
+
const currentScoreCode = ref(props.tabText)
|
| 48 |
+
const showParsingError = ref(false)
|
| 49 |
+
const parsingError = ref('')
|
| 50 |
+
const count = ref(0)
|
| 51 |
+
const settingsStatus = ref(false)
|
| 52 |
+
const isActive = ref(props.isActive)
|
| 53 |
+
|
| 54 |
+
const scoreRef = ref(null)
|
| 55 |
+
const paneContainer = ref(null)
|
| 56 |
+
const divId = computed(() => {
|
| 57 |
+
console.log('inside computed')
|
| 58 |
+
return `scoreContainer_${props.id}`
|
| 59 |
+
})
|
| 60 |
+
|
| 61 |
+
onMounted(() => {
|
| 62 |
+
// console.log($(`#${divId.value}`)[0])
|
| 63 |
+
console.log('mounted start')
|
| 64 |
+
initializePane()
|
| 65 |
+
initializeVexTab()
|
| 66 |
+
console.log('mounted end')
|
| 67 |
+
})
|
| 68 |
+
|
| 69 |
+
function initializeVexTab() {
|
| 70 |
+
// renderer = new Flow.Renderer($(`#${divId.value}`)[0], Flow.Renderer.Backends.SVG)
|
| 71 |
+
renderer = new Flow.Renderer(scoreRef.value, Flow.Renderer.Backends.SVG)
|
| 72 |
+
artist = new Artist(10, 10, SETTINGS_PARAMS.width, { scale: SETTINGS_PARAMS.scale })
|
| 73 |
+
tab = new VexTab(artist)
|
| 74 |
+
showScore()
|
| 75 |
+
}
|
| 76 |
+
function initializePane() {
|
| 77 |
+
pane = new Pane({
|
| 78 |
+
container: paneContainer.value,
|
| 79 |
+
title: 'VexTab Settings',
|
| 80 |
+
},
|
| 81 |
+
)
|
| 82 |
+
pane.registerPlugin(TextareaPlugin)
|
| 83 |
+
pane.addBinding(SETTINGS_PARAMS, 'scale', {
|
| 84 |
+
min: 0.5,
|
| 85 |
+
max: 2.0,
|
| 86 |
+
step: 0.1,
|
| 87 |
+
}).on('change', (ev) => {
|
| 88 |
+
console.log(ev.value)
|
| 89 |
+
artist.reset()
|
| 90 |
+
tab.reset()
|
| 91 |
+
tab.parse(currentScoreCode.value)
|
| 92 |
+
artist.options.scale = ev.value
|
| 93 |
+
artist.render(renderer)
|
| 94 |
+
})
|
| 95 |
+
|
| 96 |
+
pane.addBinding(SETTINGS_PARAMS, 'width', {
|
| 97 |
+
min: 400,
|
| 98 |
+
max: 1200,
|
| 99 |
+
step: 50,
|
| 100 |
+
}).on('change', (ev) => {
|
| 101 |
+
console.log(ev.value)
|
| 102 |
+
artist.reset()
|
| 103 |
+
tab.reset()
|
| 104 |
+
tab.parse(currentScoreCode.value)
|
| 105 |
+
artist.width = ev.value
|
| 106 |
+
artist.render(renderer)
|
| 107 |
+
})
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
function showScore() {
|
| 111 |
+
try {
|
| 112 |
+
artist.reset()
|
| 113 |
+
tab.reset()
|
| 114 |
+
tab.parse(currentScoreCode.value)
|
| 115 |
+
|
| 116 |
+
// artist.width += 100;
|
| 117 |
+
artist.render(renderer)
|
| 118 |
+
console.log('test')
|
| 119 |
+
console.log(artist.width)
|
| 120 |
+
showParsingError.value = false
|
| 121 |
+
}
|
| 122 |
+
catch (e) {
|
| 123 |
+
showParsingError.value = true
|
| 124 |
+
console.log(e.message.replace(/(?:\r\n|\r|\n)/g, '<br>'))
|
| 125 |
+
parsingError.value = e.message.replace(/(?:\r\n|\r|\n)/g, '<br>')
|
| 126 |
+
}
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
function handleKeyUp(event) {
|
| 130 |
+
if (timeoutID)
|
| 131 |
+
clearTimeout(timeoutID)
|
| 132 |
+
timeoutID = setTimeout(showScore, 500)
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
function handleDrop(event) {
|
| 136 |
+
event.preventDefault()
|
| 137 |
+
const textData = event.dataTransfer.getData('text')
|
| 138 |
+
const file = event.dataTransfer.files[0]
|
| 139 |
+
console.log(textData)
|
| 140 |
+
console.log(file)
|
| 141 |
+
if (file) {
|
| 142 |
+
const reader = new FileReader()
|
| 143 |
+
reader.onload = function (e) {
|
| 144 |
+
currentScoreCode.value = e.target.result
|
| 145 |
+
showScore()
|
| 146 |
+
}
|
| 147 |
+
reader.readAsText(file)
|
| 148 |
+
}
|
| 149 |
+
else if (textData) {
|
| 150 |
+
currentScoreCode.value = textData
|
| 151 |
+
showScore()
|
| 152 |
+
}
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
function showHideSettings() {
|
| 156 |
+
console.log('showHideSettings')
|
| 157 |
+
settingsStatus.value = !settingsStatus.value
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
// invoked when there is any type of change in the component
|
| 161 |
+
onUpdated(() => {
|
| 162 |
+
if (props.isActive !== isActive.value) {
|
| 163 |
+
// Prop has changed, update the ref and emit an event
|
| 164 |
+
if (props.isActive) {
|
| 165 |
+
isActive.value = props.isActive
|
| 166 |
+
emit('updateScoreCode', currentScoreCode.value)
|
| 167 |
+
console.log('emitted updateScoreCode')
|
| 168 |
+
}
|
| 169 |
+
isActive.value = props.isActive
|
| 170 |
+
}
|
| 171 |
+
})
|
| 172 |
+
|
| 173 |
+
watch(currentScoreCode, () => {
|
| 174 |
+
// Emit the event so that the parent component can update the tabText
|
| 175 |
+
// prop
|
| 176 |
+
emit('updateScoreCode', currentScoreCode.value)
|
| 177 |
+
console.log('emitted updateScoreCode')
|
| 178 |
+
// this should go to the first tab that is shown (for now vextab)
|
| 179 |
+
}, { immediate: true })
|
| 180 |
+
</script>
|
| 181 |
+
|
| 182 |
+
<template>
|
| 183 |
+
<!--
|
| 184 |
+
Which ever of the following elements wants to use the class
|
| 185 |
+
attributes coming from the parent component needs to use
|
| 186 |
+
:class="$attrs.class"
|
| 187 |
+
UNLESS I have a single root div-element
|
| 188 |
+
-->
|
| 189 |
+
<div>
|
| 190 |
+
<!-- <button class="left-align i-twemoji:globe-showing-europe-africa" @click="showHideSettings">
|
| 191 |
+
Settings
|
| 192 |
+
</button> -->
|
| 193 |
+
<button class="i-mdi:file-document-edit-outline?mask flex text-3xl text-stone-700" @click="showHideSettings" />
|
| 194 |
+
<!-- <div class="mt-4 w-full flex items-center justify-center gap-x-4 p-2 text-4xl">
|
| 195 |
+
<button class="i-vscode:file-type-light-pnpm" />
|
| 196 |
+
<button class="i-vscode:file-type-light-pnpm?mask text-red-300" />
|
| 197 |
+
</div> -->
|
| 198 |
+
<div :id="divId" ref="scoreRef" class="scoreContainer" />
|
| 199 |
+
<div v-show="settingsStatus" class="tabSettingsArea">
|
| 200 |
+
<div ref="paneContainer" class="basis-3/12" />
|
| 201 |
+
<textarea
|
| 202 |
+
v-show="settingsStatus" v-model="currentScoreCode"
|
| 203 |
+
class="editorBox justify-center"
|
| 204 |
+
placeholder="add your vextab code here or drag a file"
|
| 205 |
+
@keyup="handleKeyUp"
|
| 206 |
+
@drop="handleDrop"
|
| 207 |
+
@dragover.prevent
|
| 208 |
+
/>
|
| 209 |
+
</div>
|
| 210 |
+
|
| 211 |
+
<div v-if="showParsingError" class="ml-10px mt-10px text-red-500" v-html="parsingError" />
|
| 212 |
+
</div>
|
| 213 |
+
</template>
|
| 214 |
+
|
| 215 |
+
<style scoped>
|
| 216 |
+
.tabSettingsArea {
|
| 217 |
+
display: flex;
|
| 218 |
+
/* flex-direction: row; */
|
| 219 |
+
align-items: center;
|
| 220 |
+
justify-content: center;
|
| 221 |
+
|
| 222 |
+
gap: 20px;
|
| 223 |
+
margin-left: 10px;
|
| 224 |
+
}
|
| 225 |
+
</style>
|
frontend/src/main.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { createApp } from 'vue'
|
| 2 |
+
import { Tab, Tabs } from 'vue3-tabs-component'
|
| 3 |
+
import { VGithubIcon } from 'v-github-icon'
|
| 4 |
+
import { router } from '@/plugins/router'
|
| 5 |
+
import '@/style.css'
|
| 6 |
+
import App from '@/App.vue'
|
| 7 |
+
|
| 8 |
+
// import { createMetaManager } from 'vue-meta'
|
| 9 |
+
import 'virtual:uno.css'
|
| 10 |
+
|
| 11 |
+
// Vuetify
|
| 12 |
+
// import 'vuetify/styles'
|
| 13 |
+
// import { createVuetify } from 'vuetify'
|
| 14 |
+
// import * as components from 'vuetify/components'
|
| 15 |
+
// import * as directives from 'vuetify/directives'
|
| 16 |
+
// import { aliases, mdi } from 'vuetify/iconsets/mdi'
|
| 17 |
+
// import '@mdi/font/css/materialdesignicons.css' // Ensure you are using css-loader
|
| 18 |
+
|
| 19 |
+
// const vuetify = createVuetify({
|
| 20 |
+
// components,
|
| 21 |
+
// directives,
|
| 22 |
+
// // icons: {
|
| 23 |
+
// // defaultSet: 'mdi',
|
| 24 |
+
// // aliases,
|
| 25 |
+
// // sets: {
|
| 26 |
+
// // mdi,
|
| 27 |
+
// // },
|
| 28 |
+
// // },
|
| 29 |
+
// icons: {
|
| 30 |
+
// defaultSet: 'mdi', // This is already the default value - only for display purposes
|
| 31 |
+
// },
|
| 32 |
+
// defaults: {
|
| 33 |
+
// VBtn: {
|
| 34 |
+
// color: 'primary',
|
| 35 |
+
// variant: 'outlined',
|
| 36 |
+
// rounded: true,
|
| 37 |
+
// },
|
| 38 |
+
// },
|
| 39 |
+
// })
|
| 40 |
+
|
| 41 |
+
const app = createApp(App)
|
| 42 |
+
.use(router)
|
| 43 |
+
// .use(store)
|
| 44 |
+
// .use(vuetify)
|
| 45 |
+
.component('tabs', Tabs)
|
| 46 |
+
.component('tab', Tab)
|
| 47 |
+
.component('v-github-icon', VGithubIcon)
|
| 48 |
+
// .use(createMetaManager())
|
| 49 |
+
|
| 50 |
+
// await router.isReady()
|
| 51 |
+
app.mount('#app')
|
frontend/src/plugins/router.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { createRouter, createWebHistory } from 'vue-router'
|
| 2 |
+
|
| 3 |
+
const routes = [
|
| 4 |
+
{
|
| 5 |
+
path: '/analyzer',
|
| 6 |
+
name: 'Analyzer',
|
| 7 |
+
component: () => import('@/views/Analyzer.vue'),
|
| 8 |
+
},
|
| 9 |
+
{
|
| 10 |
+
path: '/',
|
| 11 |
+
name: 'Home',
|
| 12 |
+
component: () => import('@/views/Home.vue'),
|
| 13 |
+
},
|
| 14 |
+
]
|
| 15 |
+
|
| 16 |
+
const router = createRouter({
|
| 17 |
+
history: createWebHistory(),
|
| 18 |
+
routes,
|
| 19 |
+
})
|
| 20 |
+
|
| 21 |
+
export { router }
|
frontend/src/style.css
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:root {
|
| 2 |
+
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
| 3 |
+
line-height: 1.5;
|
| 4 |
+
font-weight: 400;
|
| 5 |
+
|
| 6 |
+
color-scheme: light dark;
|
| 7 |
+
color: rgba(255, 255, 255, 0.87);
|
| 8 |
+
background-color: #242424;
|
| 9 |
+
|
| 10 |
+
font-synthesis: none;
|
| 11 |
+
text-rendering: optimizeLegibility;
|
| 12 |
+
-webkit-font-smoothing: antialiased;
|
| 13 |
+
-moz-osx-font-smoothing: grayscale;
|
| 14 |
+
|
| 15 |
+
--primary-color: #3498db;
|
| 16 |
+
--background-light: #c6dbfa;
|
| 17 |
+
--background-dark: #3c3d3d;
|
| 18 |
+
--accent-color: #b9a329;
|
| 19 |
+
--text-color-dark: #333333;
|
| 20 |
+
--text-color-light: #e0e0e0;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
a {
|
| 24 |
+
font-weight: 500;
|
| 25 |
+
color: #646cff;
|
| 26 |
+
text-decoration: inherit;
|
| 27 |
+
}
|
| 28 |
+
a:hover {
|
| 29 |
+
color: #535bf2;
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
body {
|
| 33 |
+
margin: 0px;
|
| 34 |
+
display: flex;
|
| 35 |
+
place-items: top center;
|
| 36 |
+
min-width: 320px;
|
| 37 |
+
min-height: 100vh;
|
| 38 |
+
/* background-color: #ff0000; */
|
| 39 |
+
background-color: var(--background-light);
|
| 40 |
+
|
| 41 |
+
overflow: auto;
|
| 42 |
+
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
body::-webkit-scrollbar {
|
| 46 |
+
width: 0em;
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
body::-webkit-scrollbar-thumb {
|
| 50 |
+
background-color: #888; /* Color of the thumb */
|
| 51 |
+
border-radius: 0.25em; /* Roundness of the thumb */
|
| 52 |
+
display: none;
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
body::-webkit-scrollbar-track {
|
| 56 |
+
background-color: #f0f0f0; /* Color of the track */
|
| 57 |
+
display: none;
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
h1 {
|
| 61 |
+
font-size: 3.2em;
|
| 62 |
+
line-height: 1.1;
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
button {
|
| 66 |
+
border-radius: 8px;
|
| 67 |
+
border: 1px solid transparent;
|
| 68 |
+
padding: 0.6em 1.2em;
|
| 69 |
+
font-size: 1em;
|
| 70 |
+
font-weight: 500;
|
| 71 |
+
font-family: inherit;
|
| 72 |
+
background-color: #1a1a1a;
|
| 73 |
+
cursor: pointer;
|
| 74 |
+
transition: border-color 0.25s;
|
| 75 |
+
}
|
| 76 |
+
button:hover {
|
| 77 |
+
border-color: #646cff;
|
| 78 |
+
}
|
| 79 |
+
button:focus,
|
| 80 |
+
button:focus-visible {
|
| 81 |
+
outline: 4px auto -webkit-focus-ring-color;
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
.card {
|
| 85 |
+
padding: 2em;
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
#app {
|
| 89 |
+
max-width: 1280px;
|
| 90 |
+
margin: 0 auto;
|
| 91 |
+
padding: 2rem;
|
| 92 |
+
text-align: center;
|
| 93 |
+
background-color: var(--background-dark);
|
| 94 |
+
margin-top: 0px;
|
| 95 |
+
border-radius: 8px;
|
| 96 |
+
/* give some 3d shade */
|
| 97 |
+
box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.75);
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
@media (prefers-color-scheme: light) {
|
| 101 |
+
:root {
|
| 102 |
+
color: #213547;
|
| 103 |
+
background-color: #ffffff;
|
| 104 |
+
}
|
| 105 |
+
a:hover {
|
| 106 |
+
color: #747bff;
|
| 107 |
+
}
|
| 108 |
+
button {
|
| 109 |
+
background-color: #f9f9f9;
|
| 110 |
+
}
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
.editorBox {
|
| 115 |
+
min-height: 100px;
|
| 116 |
+
min-width: 200px;
|
| 117 |
+
width: 500px;
|
| 118 |
+
height: 145px;
|
| 119 |
+
max-width:800px;
|
| 120 |
+
overflow: auto;
|
| 121 |
+
background-color: rgb(40, 41, 46);
|
| 122 |
+
color: rgb(187, 188, 196);
|
| 123 |
+
border-radius: 8px;
|
| 124 |
+
}
|
| 125 |
+
.editorBox::-webkit-scrollbar {
|
| 126 |
+
width: 0.5em;
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
.editorBox::-webkit-scrollbar-thumb {
|
| 130 |
+
background-color: #888; /* Color of the thumb */
|
| 131 |
+
border-radius: 0.25em; /* Roundness of the thumb */
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
.editorBox::-webkit-scrollbar-track {
|
| 135 |
+
background-color: #f0f0f0; /* Color of the track */
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
.parsing-error {
|
| 139 |
+
color: red;
|
| 140 |
+
margin-top: 10px;
|
| 141 |
+
text-align: left; /* Set text alignment to left */
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
.scoreContainer {
|
| 145 |
+
border: 0px solid rgb(212, 22, 22);
|
| 146 |
+
overflow-x: auto;
|
| 147 |
+
}
|
| 148 |
+
.scoreContainer::-webkit-scrollbar {
|
| 149 |
+
height: 0.5em;
|
| 150 |
+
}
|
| 151 |
+
.scoreContainer::-webkit-scrollbar-thumb {
|
| 152 |
+
background-color: #888; /* Color of the thumb */
|
| 153 |
+
border-radius: 0.25em; /* Roundness of the thumb */
|
| 154 |
+
}
|
| 155 |
+
.scoreContainer::-webkit-scrollbar-track {
|
| 156 |
+
background-color: #f0f0f0; /* Color of the track */
|
| 157 |
+
}
|
frontend/src/views/Analyzer.vue
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<script setup>
|
| 2 |
+
import { client } from '@gradio/client'
|
| 3 |
+
import { onMounted, ref } from 'vue'
|
| 4 |
+
import VextabWidget from '@/components/VextabWidget.vue'
|
| 5 |
+
import MusicXmlWidget from '@/components/MusicXmlWidget.vue'
|
| 6 |
+
import '@/style.css'
|
| 7 |
+
|
| 8 |
+
let app = null
|
| 9 |
+
const response = ref('')
|
| 10 |
+
const currentTab = ref(0)
|
| 11 |
+
const currentScoreCode = ref('')
|
| 12 |
+
const tabs = [
|
| 13 |
+
{ name: 'VexTab', component: VextabWidget, id: 'first' },
|
| 14 |
+
{ name: 'VexTab2', component: VextabWidget, id: 'second' },
|
| 15 |
+
{ name: 'MusicXml', component: MusicXmlWidget, id: 'second' },
|
| 16 |
+
]
|
| 17 |
+
const tabText_component1 = `
|
| 18 |
+
tabstave notation=true key=A time=4/4
|
| 19 |
+
|
| 20 |
+
notes :q =|: (5/2.5/3.7/4) :8 7-5h6/3 ^3^ 5h6-7/5 ^3^ :q 7V/4 |
|
| 21 |
+
notes :8 t12p7/4 s5s3/4 :8 3s:16:5-7/5 :q p5/4
|
| 22 |
+
text :w, |#segno, ,|, :hd, , #tr
|
| 23 |
+
`
|
| 24 |
+
const tabText_component2 = `
|
| 25 |
+
tabstave notation=true key=A time=4/4
|
| 26 |
+
|
| 27 |
+
notes :q =|: (5/2.5/3.7/4) :8 7-5h6/3 ^3^ 5h6-7/5 ^3^ :q 7V/4 |
|
| 28 |
+
`
|
| 29 |
+
|
| 30 |
+
async function connectToServer() {
|
| 31 |
+
try {
|
| 32 |
+
app = await client('xribene/guitar_diff')
|
| 33 |
+
}
|
| 34 |
+
catch (error) {
|
| 35 |
+
console.error('Error fetching data:', error)
|
| 36 |
+
}
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
onMounted(async () => {
|
| 40 |
+
// Call the async function when the component is mounted
|
| 41 |
+
await connectToServer()
|
| 42 |
+
})
|
| 43 |
+
|
| 44 |
+
async function processScore() {
|
| 45 |
+
try {
|
| 46 |
+
const result = await app.predict('/process', [currentScoreCode.value])
|
| 47 |
+
response.value = result.data
|
| 48 |
+
console.log(result.data)
|
| 49 |
+
}
|
| 50 |
+
catch (error) {
|
| 51 |
+
console.error('Error processing the score:', error)
|
| 52 |
+
}
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
function updateScoreCode(scoreCode) {
|
| 56 |
+
currentScoreCode.value = scoreCode
|
| 57 |
+
// console.log("updateScoreCode")
|
| 58 |
+
// console.log(currentScoreCode.value);
|
| 59 |
+
}
|
| 60 |
+
</script>
|
| 61 |
+
|
| 62 |
+
<template>
|
| 63 |
+
<div class="guitar-score-analyzer">
|
| 64 |
+
<h1 class="title">
|
| 65 |
+
Guitar Score Analyzer
|
| 66 |
+
</h1>
|
| 67 |
+
<p class="description">
|
| 68 |
+
You can load a guitar score either using Vextab or MusicXml
|
| 69 |
+
</p>
|
| 70 |
+
<br>
|
| 71 |
+
|
| 72 |
+
<!-- Tab Buttons -->
|
| 73 |
+
<div class="debug-background-color tab-buttons">
|
| 74 |
+
<button
|
| 75 |
+
v-for="(tab, index) in tabs"
|
| 76 |
+
:key="index"
|
| 77 |
+
class="tab-button" :class="[{ active: currentTab === index }]"
|
| 78 |
+
@click="currentTab = index"
|
| 79 |
+
>
|
| 80 |
+
{{ tab.name }}
|
| 81 |
+
</button>
|
| 82 |
+
</div>
|
| 83 |
+
<br>
|
| 84 |
+
<br>
|
| 85 |
+
<br>
|
| 86 |
+
|
| 87 |
+
<!-- <div>
|
| 88 |
+
<TweakComponent />
|
| 89 |
+
</div> -->
|
| 90 |
+
<!-- Vextab Widget -->
|
| 91 |
+
<div v-show="currentTab === 0" class="tab" :class="{ active: currentTab === 0 }">
|
| 92 |
+
<VextabWidget
|
| 93 |
+
:id="tabs[currentTab].id"
|
| 94 |
+
class="tab-vexTab"
|
| 95 |
+
:tab-text="tabText_component1"
|
| 96 |
+
:is-active="currentTab === 0"
|
| 97 |
+
@update-score-code="updateScoreCode"
|
| 98 |
+
/>
|
| 99 |
+
</div>
|
| 100 |
+
|
| 101 |
+
<div v-show="currentTab === 1" class="tab" :class="{ active: currentTab === 1 }">
|
| 102 |
+
<VextabWidget
|
| 103 |
+
:id="tabs[currentTab].id"
|
| 104 |
+
class="tab-vexTab"
|
| 105 |
+
:tab-text="tabText_component2"
|
| 106 |
+
:is-active="currentTab === 1"
|
| 107 |
+
@update-score-code="updateScoreCode"
|
| 108 |
+
/>
|
| 109 |
+
</div>
|
| 110 |
+
|
| 111 |
+
<!-- MusicXml Widget -->
|
| 112 |
+
<div v-show="currentTab === 2" class="tab" :class="{ active: currentTab === 2 }">
|
| 113 |
+
<MusicXmlWidget
|
| 114 |
+
:id="tabs[currentTab].id"
|
| 115 |
+
class="tab-musicXml"
|
| 116 |
+
:is-active="currentTab === 2"
|
| 117 |
+
@update-score-code="updateScoreCode"
|
| 118 |
+
/>
|
| 119 |
+
</div>
|
| 120 |
+
|
| 121 |
+
<!-- Report Container -->
|
| 122 |
+
<div class="debug-background-color report-container">
|
| 123 |
+
<button class="analyze-button" @click="processScore">
|
| 124 |
+
Analyze
|
| 125 |
+
</button>
|
| 126 |
+
<p class="response">
|
| 127 |
+
{{ response }}
|
| 128 |
+
</p>
|
| 129 |
+
</div>
|
| 130 |
+
</div>
|
| 131 |
+
</template>
|
| 132 |
+
|
| 133 |
+
<style scoped>
|
| 134 |
+
.guitar-score-analyzer {
|
| 135 |
+
max-width: 1280px; /* Adjust the max width as needed */
|
| 136 |
+
margin: auto;
|
| 137 |
+
background-color: rgb(238, 235, 212);
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
.title {
|
| 141 |
+
font-size: 2em;
|
| 142 |
+
margin-bottom: 10px;
|
| 143 |
+
/* background-color: aqua; */
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
.description {
|
| 147 |
+
font-size: 1.2em;
|
| 148 |
+
margin-bottom: 20px;
|
| 149 |
+
/* background-color: aquamarine; */
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
.tab-buttons {
|
| 153 |
+
display: block;
|
| 154 |
+
/* background-color: #4caf50; */
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
.tab-button {
|
| 158 |
+
background-color: rgb(248, 240, 201);
|
| 159 |
+
padding: 10px;
|
| 160 |
+
margin-right: 5px;
|
| 161 |
+
cursor: pointer;
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
.tab-button.active {
|
| 165 |
+
background-color: var(--accent-color);
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
.tab {
|
| 169 |
+
display: none;
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
.tab.active {
|
| 173 |
+
display: flex;
|
| 174 |
+
/* background-color: #4caf50; */
|
| 175 |
+
width: 800px;
|
| 176 |
+
max-width: 1280px;
|
| 177 |
+
min-width:200px;
|
| 178 |
+
min-height:300px;
|
| 179 |
+
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
.analyze-button {
|
| 183 |
+
padding: 10px;
|
| 184 |
+
background-color: #4caf50;
|
| 185 |
+
color: #fff;
|
| 186 |
+
cursor: pointer;
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
.report-container {
|
| 190 |
+
margin-top: 20px;
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
/* Debug Styles - Remove when done */
|
| 194 |
+
/* .debug-background-color {
|
| 195 |
+
background-color: #f0f0f0;
|
| 196 |
+
} */
|
| 197 |
+
</style>
|
frontend/src/views/Home.vue
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<template>
|
| 2 |
+
<div class="home-container">
|
| 3 |
+
<!-- <a href="https://vuejs.org/" target="_blank"> -->
|
| 4 |
+
<img src="/cedar_guitar_800.png" class="logo" alt="guitar">
|
| 5 |
+
<!-- </a> -->
|
| 6 |
+
<h1>Home</h1>
|
| 7 |
+
</div>
|
| 8 |
+
</template>
|
| 9 |
+
|
| 10 |
+
<style scoped>
|
| 11 |
+
.home-container {
|
| 12 |
+
display: flex;
|
| 13 |
+
flex-direction: column;
|
| 14 |
+
align-items: center;
|
| 15 |
+
width: 800px;
|
| 16 |
+
max-width: 1280px; /* Adjust the max width as needed */
|
| 17 |
+
margin: auto;
|
| 18 |
+
background-color: bisque;
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
.logo {
|
| 22 |
+
height: 12em;
|
| 23 |
+
padding: 1.5em;
|
| 24 |
+
will-change: filter;
|
| 25 |
+
transition: filter 300ms;
|
| 26 |
+
}
|
| 27 |
+
.logo:hover {
|
| 28 |
+
filter: drop-shadow(0 0 2em #646cffaa);
|
| 29 |
+
}
|
| 30 |
+
.logo.vue:hover {
|
| 31 |
+
filter: drop-shadow(0 0 2em #b8a642aa);
|
| 32 |
+
}
|
| 33 |
+
</style>
|
frontend/uno.config.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import {
|
| 2 |
+
defineConfig,
|
| 3 |
+
// presetIcons,
|
| 4 |
+
presetUno,
|
| 5 |
+
presetWebFonts,
|
| 6 |
+
transformerDirectives,
|
| 7 |
+
transformerVariantGroup,
|
| 8 |
+
} from 'unocss'
|
| 9 |
+
|
| 10 |
+
import presetIcons from '@unocss/preset-icons/browser'
|
| 11 |
+
|
| 12 |
+
export default defineConfig({
|
| 13 |
+
presets: [
|
| 14 |
+
presetUno(),
|
| 15 |
+
presetIcons({
|
| 16 |
+
scale: 1.5,
|
| 17 |
+
warn: true,
|
| 18 |
+
unit: 'em',
|
| 19 |
+
extraProperties: {
|
| 20 |
+
'display': 'inline-block',
|
| 21 |
+
'vertical-align': 'middle',
|
| 22 |
+
// ...
|
| 23 |
+
},
|
| 24 |
+
collections: {
|
| 25 |
+
// carbon: () => import('@iconify/json/carbon.json').then(i => i.default),
|
| 26 |
+
// mdi: () => import('@iconify/json/mid.json').then(i => i.default),
|
| 27 |
+
// logos: () => import('@iconify/json/logos.json').then(i => i.default),
|
| 28 |
+
// twemoji: () => import('@iconify/json/twemoji.json').then(i => i.default),
|
| 29 |
+
mdi: () => import('@iconify/json/json/mdi.json').then(i => i.default),
|
| 30 |
+
logos: () => import('@iconify/json/json/logos.json').then(i => i.default),
|
| 31 |
+
twemoji: () => import('@iconify/json/json/twemoji.json').then(i => i.default),
|
| 32 |
+
vscode: () => import('@iconify/json/json/vscode-icons.json').then(i => i.default),
|
| 33 |
+
},
|
| 34 |
+
}),
|
| 35 |
+
presetWebFonts({
|
| 36 |
+
provider: 'bunny',
|
| 37 |
+
fonts: {
|
| 38 |
+
sans: 'Inter',
|
| 39 |
+
},
|
| 40 |
+
}),
|
| 41 |
+
],
|
| 42 |
+
transformers: [
|
| 43 |
+
transformerDirectives(),
|
| 44 |
+
transformerVariantGroup(),
|
| 45 |
+
],
|
| 46 |
+
})
|
frontend/vite.config.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import path from 'node:path'
|
| 2 |
+
import UnoCSS from 'unocss/vite'
|
| 3 |
+
import { defineConfig } from 'vite'
|
| 4 |
+
import vue from '@vitejs/plugin-vue'
|
| 5 |
+
|
| 6 |
+
// https://vitejs.dev/config/
|
| 7 |
+
export default defineConfig({
|
| 8 |
+
plugins: [
|
| 9 |
+
vue(),
|
| 10 |
+
UnoCSS(),
|
| 11 |
+
],
|
| 12 |
+
resolve: {
|
| 13 |
+
alias: {
|
| 14 |
+
'@': path.resolve(__dirname, './src'),
|
| 15 |
+
},
|
| 16 |
+
},
|
| 17 |
+
// build:{
|
| 18 |
+
// target: "esnext" // or "es2019",
|
| 19 |
+
// }
|
| 20 |
+
|
| 21 |
+
})
|
pyproject.toml
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[tool.ruff]
|
| 2 |
+
# Exclude a variety of commonly ignored directories.
|
| 3 |
+
exclude = [
|
| 4 |
+
".bzr",
|
| 5 |
+
".direnv",
|
| 6 |
+
".eggs",
|
| 7 |
+
".git",
|
| 8 |
+
".git-rewrite",
|
| 9 |
+
".hg",
|
| 10 |
+
".ipynb_checkpoints",
|
| 11 |
+
".mypy_cache",
|
| 12 |
+
".nox",
|
| 13 |
+
".pants.d",
|
| 14 |
+
".pyenv",
|
| 15 |
+
".pytest_cache",
|
| 16 |
+
".pytype",
|
| 17 |
+
".ruff_cache",
|
| 18 |
+
".svn",
|
| 19 |
+
".tox",
|
| 20 |
+
".venv",
|
| 21 |
+
".vscode",
|
| 22 |
+
"__pypackages__",
|
| 23 |
+
"_build",
|
| 24 |
+
"buck-out",
|
| 25 |
+
"build",
|
| 26 |
+
"dist",
|
| 27 |
+
"node_modules",
|
| 28 |
+
"site-packages",
|
| 29 |
+
"venv",
|
| 30 |
+
"frontend"
|
| 31 |
+
]
|
| 32 |
+
|
| 33 |
+
# Same as Black.
|
| 34 |
+
line-length = 100
|
| 35 |
+
indent-width = 4
|
| 36 |
+
|
| 37 |
+
# Assume Python 3.9
|
| 38 |
+
target-version = "py39"
|
| 39 |
+
|
| 40 |
+
[tool.ruff.lint]
|
| 41 |
+
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
|
| 42 |
+
# select = ["E4", "E7", "E9", "F", "W", "PLR"]
|
| 43 |
+
select = ["ALL"]
|
| 44 |
+
ignore = ["ERA", "T201"]
|
| 45 |
+
|
| 46 |
+
# Allow fix for all enabled rules (when `--fix`) is provided.
|
| 47 |
+
fixable = ["ALL"]
|
| 48 |
+
unfixable = []
|
| 49 |
+
|
| 50 |
+
# Allow unused variables when underscore-prefixed.
|
| 51 |
+
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
| 52 |
+
|
| 53 |
+
[tool.ruff.lint.pylint]
|
| 54 |
+
max-args = 5
|
| 55 |
+
|
| 56 |
+
[tool.ruff.lint.pycodestyle]
|
| 57 |
+
max-doc-length = 100
|
| 58 |
+
|
| 59 |
+
[tool.ruff.format]
|
| 60 |
+
# Like Black, use double quotes for strings.
|
| 61 |
+
quote-style = "double"
|
| 62 |
+
|
| 63 |
+
# Like Black, indent with spaces, rather than tabs.
|
| 64 |
+
indent-style = "space"
|
| 65 |
+
|
| 66 |
+
# Like Black, respect magic trailing commas.
|
| 67 |
+
skip-magic-trailing-comma = false
|
| 68 |
+
|
| 69 |
+
# Like Black, automatically detect the appropriate line ending.
|
| 70 |
+
line-ending = "auto"
|