Working version that actually exports!!
This commit is contained in:
parent
503938230f
commit
dde28bc286
512
package-lock.json
generated
512
package-lock.json
generated
@ -8,6 +8,7 @@
|
||||
"name": "rekordbox-reader",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@chakra-ui/modal": "^2.3.1",
|
||||
"@chakra-ui/react": "^3.12.0",
|
||||
"@chakra-ui/transition": "^2.1.0",
|
||||
"@emotion/react": "^11.14.0",
|
||||
@ -17,7 +18,8 @@
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"sax": "^1.4.1",
|
||||
"xml2js": "^0.6.2"
|
||||
"xml2js": "^0.6.2",
|
||||
"xmlbuilder": "^15.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.21.0",
|
||||
@ -399,6 +401,107 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/anatomy": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/anatomy/-/anatomy-2.2.2.tgz",
|
||||
"integrity": "sha512-MV6D4VLRIHr4PkW4zMyqfrNS1mPlCTiCXwvYGtDFQYr+xHFfonhAuf9WjsSc0nyp2m0OdkSLnzmVKkZFLo25Tg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@chakra-ui/close-button": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/close-button/-/close-button-2.1.1.tgz",
|
||||
"integrity": "sha512-gnpENKOanKexswSVpVz7ojZEALl2x5qjLYNqSQGbxz+aP9sOXPfUS56ebyBrre7T7exuWGiFeRwnM0oVeGPaiw==",
|
||||
"dependencies": {
|
||||
"@chakra-ui/icon": "3.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@chakra-ui/system": ">=2.0.0",
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/color-mode": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/color-mode/-/color-mode-2.2.0.tgz",
|
||||
"integrity": "sha512-niTEA8PALtMWRI9wJ4LL0CSBDo8NBfLNp4GD6/0hstcm3IlbBHTVKxN6HwSaoNYfphDQLxCjT4yG+0BJA5tFpg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@chakra-ui/react-use-safe-layout-effect": "2.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/dom-utils": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/dom-utils/-/dom-utils-2.1.0.tgz",
|
||||
"integrity": "sha512-ZmF2qRa1QZ0CMLU8M1zCfmw29DmPNtfjR9iTo74U5FPr3i1aoAh7fbJ4qAlZ197Xw9eAW28tvzQuoVWeL5C7fQ=="
|
||||
},
|
||||
"node_modules/@chakra-ui/focus-lock": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/focus-lock/-/focus-lock-2.1.0.tgz",
|
||||
"integrity": "sha512-EmGx4PhWGjm4dpjRqM4Aa+rCWBxP+Rq8Uc/nAVnD4YVqkEhBkrPTpui2lnjsuxqNaZ24fIAZ10cF1hlpemte/w==",
|
||||
"dependencies": {
|
||||
"@chakra-ui/dom-utils": "2.1.0",
|
||||
"react-focus-lock": "^2.9.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/icon": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.2.0.tgz",
|
||||
"integrity": "sha512-xxjGLvlX2Ys4H0iHrI16t74rG9EBcpFvJ3Y3B7KMQTrnW34Kf7Da/UC8J67Gtx85mTHW020ml85SVPKORWNNKQ==",
|
||||
"dependencies": {
|
||||
"@chakra-ui/shared-utils": "2.0.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@chakra-ui/system": ">=2.0.0",
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/modal": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/modal/-/modal-2.3.1.tgz",
|
||||
"integrity": "sha512-TQv1ZaiJMZN+rR9DK0snx/OPwmtaGH1HbZtlYt4W4s6CzyK541fxLRTjIXfEzIGpvNW+b6VFuFjbcR78p4DEoQ==",
|
||||
"dependencies": {
|
||||
"@chakra-ui/close-button": "2.1.1",
|
||||
"@chakra-ui/focus-lock": "2.1.0",
|
||||
"@chakra-ui/portal": "2.1.0",
|
||||
"@chakra-ui/react-context": "2.1.0",
|
||||
"@chakra-ui/react-types": "2.0.7",
|
||||
"@chakra-ui/react-use-merge-refs": "2.1.0",
|
||||
"@chakra-ui/shared-utils": "2.0.5",
|
||||
"@chakra-ui/transition": "2.1.0",
|
||||
"aria-hidden": "^1.2.3",
|
||||
"react-remove-scroll": "^2.5.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@chakra-ui/system": ">=2.0.0",
|
||||
"framer-motion": ">=4.0.0",
|
||||
"react": ">=18",
|
||||
"react-dom": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/object-utils": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/object-utils/-/object-utils-2.1.0.tgz",
|
||||
"integrity": "sha512-tgIZOgLHaoti5PYGPTwK3t/cqtcycW0owaiOXoZOcpwwX/vlVb+H1jFsQyWiiwQVPt9RkoSLtxzXamx+aHH+bQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@chakra-ui/portal": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/portal/-/portal-2.1.0.tgz",
|
||||
"integrity": "sha512-9q9KWf6SArEcIq1gGofNcFPSWEyl+MfJjEUg/un1SMlQjaROOh3zYr+6JAwvcORiX7tyHosnmWC3d3wI2aPSQg==",
|
||||
"dependencies": {
|
||||
"@chakra-ui/react-context": "2.1.0",
|
||||
"@chakra-ui/react-use-safe-layout-effect": "2.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=18",
|
||||
"react-dom": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/react": {
|
||||
"version": "3.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-3.12.0.tgz",
|
||||
@ -419,11 +522,126 @@
|
||||
"react-dom": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/react-context": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/react-context/-/react-context-2.1.0.tgz",
|
||||
"integrity": "sha512-iahyStvzQ4AOwKwdPReLGfDesGG+vWJfEsn0X/NoGph/SkN+HXtv2sCfYFFR9k7bb+Kvc6YfpLlSuLvKMHi2+w==",
|
||||
"peerDependencies": {
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/react-types": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/react-types/-/react-types-2.0.7.tgz",
|
||||
"integrity": "sha512-12zv2qIZ8EHwiytggtGvo4iLT0APris7T0qaAWqzpUGS0cdUtR8W+V1BJ5Ocq+7tA6dzQ/7+w5hmXih61TuhWQ==",
|
||||
"peerDependencies": {
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/react-use-merge-refs": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/react-use-merge-refs/-/react-use-merge-refs-2.1.0.tgz",
|
||||
"integrity": "sha512-lERa6AWF1cjEtWSGjxWTaSMvneccnAVH4V4ozh8SYiN9fSPZLlSG3kNxfNzdFvMEhM7dnP60vynF7WjGdTgQbQ==",
|
||||
"peerDependencies": {
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/react-use-safe-layout-effect": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/react-use-safe-layout-effect/-/react-use-safe-layout-effect-2.1.0.tgz",
|
||||
"integrity": "sha512-Knbrrx/bcPwVS1TorFdzrK/zWA8yuU/eaXDkNj24IrKoRlQrSBFarcgAEzlCHtzuhufP3OULPkELTzz91b0tCw==",
|
||||
"peerDependencies": {
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/react-utils": {
|
||||
"version": "2.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/react-utils/-/react-utils-2.0.12.tgz",
|
||||
"integrity": "sha512-GbSfVb283+YA3kA8w8xWmzbjNWk14uhNpntnipHCftBibl0lxtQ9YqMFQLwuFOO0U2gYVocszqqDWX+XNKq9hw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@chakra-ui/utils": "2.0.15"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/shared-utils": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/shared-utils/-/shared-utils-2.0.5.tgz",
|
||||
"integrity": "sha512-4/Wur0FqDov7Y0nCXl7HbHzCg4aq86h+SXdoUeuCMD3dSj7dpsVnStLYhng1vxvlbUnLpdF4oz5Myt3i/a7N3Q=="
|
||||
},
|
||||
"node_modules/@chakra-ui/styled-system": {
|
||||
"version": "2.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/styled-system/-/styled-system-2.9.2.tgz",
|
||||
"integrity": "sha512-To/Z92oHpIE+4nk11uVMWqo2GGRS86coeMmjxtpnErmWRdLcp1WVCVRAvn+ZwpLiNR+reWFr2FFqJRsREuZdAg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@chakra-ui/shared-utils": "2.0.5",
|
||||
"csstype": "^3.1.2",
|
||||
"lodash.mergewith": "4.6.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/system": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/system/-/system-2.6.2.tgz",
|
||||
"integrity": "sha512-EGtpoEjLrUu4W1fHD+a62XR+hzC5YfsWm+6lO0Kybcga3yYEij9beegO0jZgug27V+Rf7vns95VPVP6mFd/DEQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@chakra-ui/color-mode": "2.2.0",
|
||||
"@chakra-ui/object-utils": "2.1.0",
|
||||
"@chakra-ui/react-utils": "2.0.12",
|
||||
"@chakra-ui/styled-system": "2.9.2",
|
||||
"@chakra-ui/theme-utils": "2.0.21",
|
||||
"@chakra-ui/utils": "2.0.15",
|
||||
"react-fast-compare": "3.2.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.0.0",
|
||||
"@emotion/styled": "^11.0.0",
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/theme": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/theme/-/theme-3.3.1.tgz",
|
||||
"integrity": "sha512-Hft/VaT8GYnItGCBbgWd75ICrIrIFrR7lVOhV/dQnqtfGqsVDlrztbSErvMkoPKt0UgAkd9/o44jmZ6X4U2nZQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@chakra-ui/anatomy": "2.2.2",
|
||||
"@chakra-ui/shared-utils": "2.0.5",
|
||||
"@chakra-ui/theme-tools": "2.1.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@chakra-ui/styled-system": ">=2.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/theme-tools": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/theme-tools/-/theme-tools-2.1.2.tgz",
|
||||
"integrity": "sha512-Qdj8ajF9kxY4gLrq7gA+Azp8CtFHGO9tWMN2wfF9aQNgG9AuMhPrUzMq9AMQ0MXiYcgNq/FD3eegB43nHVmXVA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@chakra-ui/anatomy": "2.2.2",
|
||||
"@chakra-ui/shared-utils": "2.0.5",
|
||||
"color2k": "^2.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@chakra-ui/styled-system": ">=2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/theme-utils": {
|
||||
"version": "2.0.21",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/theme-utils/-/theme-utils-2.0.21.tgz",
|
||||
"integrity": "sha512-FjH5LJbT794r0+VSCXB3lT4aubI24bLLRWB+CuRKHijRvsOg717bRdUN/N1fEmEpFnRVrbewttWh/OQs0EWpWw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@chakra-ui/shared-utils": "2.0.5",
|
||||
"@chakra-ui/styled-system": "2.9.2",
|
||||
"@chakra-ui/theme": "3.3.1",
|
||||
"lodash.mergewith": "4.6.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/transition": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/transition/-/transition-2.1.0.tgz",
|
||||
@ -436,6 +654,18 @@
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@chakra-ui/utils": {
|
||||
"version": "2.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@chakra-ui/utils/-/utils-2.0.15.tgz",
|
||||
"integrity": "sha512-El4+jL0WSaYYs+rJbuYFDbjmfCcfGDmRY95GO4xwzit6YAPZBLcR65rOEwLps+XWluZTy1xdMrusg/hW0c1aAA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/lodash.mergewith": "4.6.7",
|
||||
"css-box-model": "1.2.1",
|
||||
"framesync": "6.1.2",
|
||||
"lodash.mergewith": "4.6.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/babel-plugin": {
|
||||
"version": "11.13.5",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz",
|
||||
@ -1696,6 +1926,21 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/lodash": {
|
||||
"version": "4.17.16",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.16.tgz",
|
||||
"integrity": "sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@types/lodash.mergewith": {
|
||||
"version": "4.6.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.7.tgz",
|
||||
"integrity": "sha512-3m+lkO5CLRRYU0fhGRp7zbsGi6+BZj0uTVSwvcKU+nSlhjA9/QRNfuSGnD2mX6hQA7ZbmcCkzk5h4ZYGOtk14A==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/lodash": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.13.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz",
|
||||
@ -1716,7 +1961,7 @@
|
||||
"version": "19.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.10.tgz",
|
||||
"integrity": "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"csstype": "^3.0.2"
|
||||
@ -2819,6 +3064,17 @@
|
||||
"dev": true,
|
||||
"license": "Python-2.0"
|
||||
},
|
||||
"node_modules/aria-hidden": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz",
|
||||
"integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/autoprefixer": {
|
||||
"version": "10.4.21",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
|
||||
@ -3003,6 +3259,12 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/color2k": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.3.tgz",
|
||||
"integrity": "sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
@ -3057,6 +3319,15 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/css-box-model": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz",
|
||||
"integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tiny-invariant": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
@ -3087,6 +3358,11 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/detect-node-es": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
|
||||
"integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.114",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.114.tgz",
|
||||
@ -3489,6 +3765,17 @@
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/focus-lock": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-1.3.6.tgz",
|
||||
"integrity": "sha512-Ik/6OCk9RQQ0T5Xw+hKNLWrjSMtv51dD4GRmJjbD5a58TIEpI5a5iXagKVl3Z5UuyslMCA8Xwnu76jQob62Yhg==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/fraction.js": {
|
||||
"version": "4.3.7",
|
||||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
|
||||
@ -3529,6 +3816,21 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/framesync": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/framesync/-/framesync-6.1.2.tgz",
|
||||
"integrity": "sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/framesync/node_modules/tslib": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
||||
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
@ -3563,6 +3865,14 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/get-nonce": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
|
||||
"integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/glob-parent": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||
@ -3848,6 +4158,23 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.mergewith": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
|
||||
"integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||
"dependencies": {
|
||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"loose-envify": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||
@ -3959,6 +4286,14 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/optionator": {
|
||||
"version": "0.9.4",
|
||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
|
||||
@ -4145,6 +4480,16 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prop-types": {
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"react-is": "^16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-compare": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-3.0.1.tgz",
|
||||
@ -4200,6 +4545,17 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-clientside-effect": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.7.tgz",
|
||||
"integrity": "sha512-gce9m0Pk/xYYMEojRI9bgvqQAkl6hm7ozQvqWPyQx+kULiatdHgkNM1QG4DQRx5N9BAzWSCJmt9mMV8/KsdgVg==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.13"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "19.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz",
|
||||
@ -4212,6 +4568,34 @@
|
||||
"react": "^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-fast-compare": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
|
||||
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/react-focus-lock": {
|
||||
"version": "2.13.6",
|
||||
"resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.13.6.tgz",
|
||||
"integrity": "sha512-ehylFFWyYtBKXjAO9+3v8d0i+cnc1trGS0vlTGhzFW1vbFXVUTmR8s2tt/ZQG8x5hElg6rhENlLG1H3EZK0Llg==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.0.0",
|
||||
"focus-lock": "^1.3.6",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-clientside-effect": "^1.2.7",
|
||||
"use-callback-ref": "^1.3.3",
|
||||
"use-sidecar": "^1.1.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
@ -4228,6 +4612,72 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-remove-scroll": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.3.tgz",
|
||||
"integrity": "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==",
|
||||
"dependencies": {
|
||||
"react-remove-scroll-bar": "^2.3.7",
|
||||
"react-style-singleton": "^2.2.3",
|
||||
"tslib": "^2.1.0",
|
||||
"use-callback-ref": "^1.3.3",
|
||||
"use-sidecar": "^1.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-remove-scroll-bar": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz",
|
||||
"integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==",
|
||||
"dependencies": {
|
||||
"react-style-singleton": "^2.2.2",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-style-singleton": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
|
||||
"integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==",
|
||||
"dependencies": {
|
||||
"get-nonce": "^1.0.0",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/regenerator-runtime": {
|
||||
"version": "0.14.1",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
|
||||
@ -4451,6 +4901,12 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tiny-invariant": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
|
||||
"integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
@ -4587,6 +5043,47 @@
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/use-callback-ref": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz",
|
||||
"integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/use-sidecar": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",
|
||||
"integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==",
|
||||
"dependencies": {
|
||||
"detect-node-es": "^1.1.0",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.1.tgz",
|
||||
@ -4697,15 +5194,22 @@
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/xmlbuilder": {
|
||||
"node_modules/xml2js/node_modules/xmlbuilder": {
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
|
||||
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/xmlbuilder": {
|
||||
"version": "15.1.1",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
|
||||
"integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
|
||||
"engines": {
|
||||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@chakra-ui/modal": "^2.3.1",
|
||||
"@chakra-ui/react": "^3.12.0",
|
||||
"@chakra-ui/transition": "^2.1.0",
|
||||
"@emotion/react": "^11.14.0",
|
||||
@ -19,7 +20,8 @@
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"sax": "^1.4.1",
|
||||
"xml2js": "^0.6.2"
|
||||
"xml2js": "^0.6.2",
|
||||
"xmlbuilder": "^15.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.21.0",
|
||||
|
||||
122
src/App.tsx
122
src/App.tsx
@ -9,7 +9,18 @@ import {
|
||||
Stack,
|
||||
Text,
|
||||
VStack,
|
||||
useDisclosure,
|
||||
} from "@chakra-ui/react";
|
||||
import {
|
||||
Modal,
|
||||
ModalOverlay,
|
||||
ModalContent,
|
||||
ModalHeader,
|
||||
ModalFooter,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
} from "@chakra-ui/modal";
|
||||
import { create } from "xmlbuilder";
|
||||
|
||||
interface Song {
|
||||
id: string;
|
||||
@ -26,6 +37,8 @@ export default function RekordboxReader() {
|
||||
const [songs, setSongs] = useState<Song[]>([]);
|
||||
const [playlists, setPlaylists] = useState<Playlist[]>([]);
|
||||
const [selectedItem, setSelectedItem] = useState<string | null>("All Songs");
|
||||
const { open, onOpen, onClose } = useDisclosure();
|
||||
const [newPlaylistName, setNewPlaylistName] = useState("");
|
||||
|
||||
const handleFileUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = event.target.files?.[0];
|
||||
@ -65,6 +78,76 @@ export default function RekordboxReader() {
|
||||
setSelectedItem(item);
|
||||
};
|
||||
|
||||
const handleCreatePlaylist = () => {
|
||||
if (newPlaylistName.trim()) {
|
||||
setPlaylists([...playlists, { name: newPlaylistName, tracks: [] }]);
|
||||
setNewPlaylistName("");
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
|
||||
const handleAddSongToPlaylist = (songId: string, playlistName: string) => {
|
||||
const updatedPlaylists = playlists.map((playlist) =>
|
||||
playlist.name === playlistName
|
||||
? { ...playlist, tracks: [...playlist.tracks, songId] }
|
||||
: playlist
|
||||
);
|
||||
setPlaylists(updatedPlaylists);
|
||||
};
|
||||
|
||||
const exportToXML = () => {
|
||||
const doc = create("DJ_PLAYLISTS", { Version: "1.0.0" });
|
||||
const collection = doc.ele("COLLECTION", {
|
||||
Entries: songs.length.toString(),
|
||||
});
|
||||
|
||||
// Add tracks to the collection
|
||||
songs.forEach((song) => {
|
||||
collection.ele("TRACK", {
|
||||
TrackID: song.id,
|
||||
Name: song.title,
|
||||
Artist: song.artist,
|
||||
});
|
||||
});
|
||||
|
||||
// Create the playlists structure
|
||||
const playlistsNode = doc.ele("PLAYLISTS");
|
||||
const playlistsFolder = playlistsNode.ele("NODE", {
|
||||
Name: "ROOT",
|
||||
Type: "0",
|
||||
Count: playlists.length.toString(),
|
||||
});
|
||||
|
||||
// Add each playlist and its tracks
|
||||
playlists.forEach((playlist) => {
|
||||
const playlistNode = playlistsFolder.ele("NODE", {
|
||||
Name: playlist.name,
|
||||
KeyType: "0",
|
||||
Type: "1",
|
||||
Entries: playlist.tracks.length.toString(),
|
||||
});
|
||||
playlist.tracks.forEach((trackId) => {
|
||||
playlistNode.ele("TRACK", { Key: trackId });
|
||||
});
|
||||
});
|
||||
|
||||
// Generate the XML content as a string
|
||||
const xmlContent = doc.end({ prettyPrint: true });
|
||||
|
||||
// Create a Blob from the XML content
|
||||
const blob = new Blob([xmlContent], { type: "application/xml" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
|
||||
// Create a download link and trigger the download
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = "rekordbox_playlists.xml";
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
};
|
||||
|
||||
|
||||
const renderContent = () => {
|
||||
if (selectedItem === "All Songs") {
|
||||
return (
|
||||
@ -73,6 +156,17 @@ export default function RekordboxReader() {
|
||||
<Box key={song.id} borderWidth="1px" borderRadius="lg" p={4} shadow="md">
|
||||
<Text fontWeight="bold">{song.title}</Text>
|
||||
<Text color="gray.500">{song.artist}</Text>
|
||||
<select
|
||||
onChange={(e) => handleAddSongToPlaylist(song.id, e.target.value)}
|
||||
value=""
|
||||
>
|
||||
<option value="" disabled>Add to playlist</option>
|
||||
{playlists.map((playlist) => (
|
||||
<option key={playlist.name} value={playlist.name}>
|
||||
{playlist.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</Box>
|
||||
))}
|
||||
</Stack>
|
||||
@ -110,14 +204,42 @@ export default function RekordboxReader() {
|
||||
{playlist.name}
|
||||
</Button>
|
||||
))}
|
||||
<Button onClick={onOpen} w="100%">
|
||||
Create New Playlist
|
||||
</Button>
|
||||
</VStack>
|
||||
<Box p={4} flex="1">
|
||||
<Input type="file" accept=".xml" onChange={handleFileUpload} mb={4} />
|
||||
<Button onClick={exportToXML} mb={4}>
|
||||
Export to XML
|
||||
</Button>
|
||||
<Heading size="lg" mb={4}>
|
||||
{selectedItem}
|
||||
</Heading>
|
||||
{renderContent()}
|
||||
</Box>
|
||||
<Modal isOpen={open} onClose={onClose}>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>Create New Playlist</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody>
|
||||
<Input
|
||||
placeholder="Playlist Name"
|
||||
value={newPlaylistName}
|
||||
onChange={(e) => setNewPlaylistName(e.target.value)}
|
||||
/>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button colorScheme="blue" mr={3} onClick={handleCreatePlaylist}>
|
||||
Create
|
||||
</Button>
|
||||
<Button variant="ghost" onClick={onClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user