| 
					
				 | 
			
			
				@@ -42,6 +42,7 @@ export const metronomeData = reactive({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	cursorTips: '' as string, // 光标模式提示文字 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	followAudioIndex: 1, // 当前的拍数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	totalNumerator: 2, // 总拍数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	firstBeatTypeArr:[] as number[] // 第一小节的节拍 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 watch( 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -323,6 +324,11 @@ class Metronome { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			// console.log("🚀 ~ measureNumberXML", measureNumberXML, note) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			// console.log("🚀 ~ measureNumberXML", note) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const measureListIndex = measureNumberXML - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// 当渐快渐慢的时候  不播节拍器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if(isWithinRange(state.gradual, measureListIndex)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				xmlNumber = measureNumberXML; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if (measureNumberXML > -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				if (measureNumberXML != xmlNumber) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					// 弱起的时候 根据音符结尾时间减去音符开头时间,得到的不是正常小节的时间,然后平均分配节拍之后,当前节拍间隔会非常短 这里弱起取整个小节的时间 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -367,7 +373,9 @@ class Metronome { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					const m = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						measureNumberXML: measureNumberXML, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						measureNumberIndex: measureListIndex, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						CompoundTempo: note?.noteElement?.sourceMeasure?.CompoundTempo || "", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						numerator: note?.noteElement?.sourceMeasure?.ActiveTimeSignature?.numerator || 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						denominator: note?.noteElement?.sourceMeasure?.ActiveTimeSignature?.denominator || 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						start: startTime, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						end: noteEndTime, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						time: noteEndTime - startTime, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -377,48 +385,15 @@ class Metronome { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						svgs: [] as any[], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						isRestFlag: note.isRestFlag, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					// 2.统计小节的拍数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					// 3.统计小节的时长, 开始时间,结束时间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					// console.log(measureNumberXML,note.measures, times.filter((n: any) => n?.noteElement?.sourceMeasure?.measureListIndex == measureListIndex)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if ([121].includes(state.subjectId)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						const _measures = times.filter((n: any) => n?.noteElement?.sourceMeasure?.measureListIndex == measureListIndex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						note.measures = _measures; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						m.start = note.measures[0].time; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						m.end = note.measures[note.measures.length - 1].endtime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						m.time = note.measures[note.measures.length - 1].endtime - note.measures[0].time; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							const tickables = note.noteElement.sourceMeasure.verticalMeasureList.reduce((arr: any[], value: any) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-								arr.push(...value.vfVoices["1"].tickables); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-								return arr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							}, []); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							const xList: any[] = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							m.svgs = tickables 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-								.map((n: any) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-									const x = n.getBoundingBox().x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-									if (!xList.includes(x) && n.duration !== "w") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-										xList.push(x); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-										n._start_x = x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-										return n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-									} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-								}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-								.filter(Boolean) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-								.sort((a: any, b: any) => a._start_x - b._start_x); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							// console.log(measureNumberXML, m.svgs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						} catch (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							console.log(error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						m.stepList = calculateMutilpleMetroStep(note.measures, m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						 * bug:#9877 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						 * 多分轨合并显示,不同分轨的音符数量可能不同 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						let measureArr = note.measures; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						if (state.isCombineRender) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							measureArr = measureArr.filter((item: any) => item.MeasureNumberXML === m.measureNumberXML) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						m.stepList = calculateMetroStep(measureArr, m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					 * bug:#9877 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					 * 多分轨合并显示,不同分轨的音符数量可能不同 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					let measureArr = note.measures; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					if (state.isCombineRender) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						measureArr = measureArr.filter((item: any) => item.MeasureNumberXML === m.measureNumberXML) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					m.stepList = calculateMetroStep(measureArr, m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					measures.push(m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					xmlNumber = measureNumberXML; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -435,34 +410,60 @@ class Metronome { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				measureNumberXML: item.measureNumberXML 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		})) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// 4.按照拍数将时长平均分配 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			for (let i = 0; i < measures.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				const measure = measures[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const noteStep = measure.time / measure.numerator; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// console.log("🚀 ~ measure.measureNumberXML",measure.measureNumberXML, noteStep) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const WIDTH = [121].includes(state.subjectId) ? 95 : 100; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const widthStep = WIDTH / (measure.numerator + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// 87拍和45拍要根据小节返回的CompoundTempo特殊处理 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const beatTypeArr = getBeatTypeArr(measure.numerator, measure.denominator, measure.CompoundTempo) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const CompoundTempoArr = beatTypeArr.map((beatType:number) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return Math.abs(beatType*measure.numerator) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if(i===0){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					metronomeData.firstBeatTypeArr = beatTypeArr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				metroMeasure[i] = [] as number[]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// console.log('stepList', [...measure.stepList], measure.measureNumberXML) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				for (let j = 0; j < measure.numerator; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					const time = noteStep * j + measure.start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// 根据有几个拍子,划分成几份 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const widthStep = 100 / (beatTypeArr.length+1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// 当前拍子的组合数(2+3+2,3+2)中的数字 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				let beatNum = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// if (measure.measureNumberXML == 98) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// 	debugger 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				for (let j = 0; j < beatTypeArr.length; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					// 累加 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					const beatMuit = Array(j).fill("").reduce((num:number,v:any,i:number) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						return num += Math.abs(beatTypeArr[i]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					}, 0) || 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					const time = measure.time * beatMuit + measure.start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					metroList.push(time); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					let left = ""; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if (measure.stepList[j]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						left = measure.stepList[j] + "px"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					// 当前拍子数对应的节拍位置索引 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					let currentIdx = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					if (j == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						currentIdx = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						beatNum += CompoundTempoArr[j-1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						currentIdx = beatNum 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					// 如果是87拍,并且是3+2+2的组合,第二拍的节拍指针需要定位到第四个音符的位置 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					// if (measure.numerator === 7 && measure.denominator === 8 && measure.CompoundTempo === '3+2+2' && j === 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					// 	currentIdx += 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					// } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					if (measure.stepList[currentIdx]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						left = measure.stepList[currentIdx] + "px"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						const preLeft = measure.stepList[j - 1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						left = !preLeft ? `${widthStep}%` : preLeft.toString().indexOf("%") > -1 ? `${preLeft} + ${widthStep}%` : `${preLeft}px + ${widthStep}%`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						left = !preLeft || preLeft.toString().indexOf("%") > -1 ? `${widthStep*(j+1)}%` : `${preLeft}px + ${widthStep}%`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						measure.stepList[j] = left; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					}					 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					metroMeasure[i].push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						isTick: beatTypeArr[j] < 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						index: j, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						time, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						// left: (measure.stepList[j] ? measure.stepList[j] + 'px' : (j + 1) * widthStep + '%'), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						left: left?.indexOf("%") > -1 ? `calc(${left})` : left, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						measureNumberXML: measure.measureNumberXML, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						isRestFlag: measure.isRestFlag, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						stepList: measure.stepList 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -478,6 +479,64 @@ class Metronome { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 获取节拍类型数组 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+export function getBeatTypeArr(numerator?:number, denominator?:number, CompoundTempo?:string){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const speedBeatUnit = state.speedBeatUnit 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const Numerator = numerator || state.osmd?.Sheet?.SheetPlaybackSetting?.Rhythm?.Numerator || 4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const Denominator = denominator || state.osmd?.Sheet?.SheetPlaybackSetting?.Rhythm?.Denominator || 4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	let loopArr = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 规则 负数代表重声,正数代表轻声 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch (`${Numerator}/${Denominator}`) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case "2/2": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			loopArr = [-1/2, 1/2] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			break;		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case "3/2": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			loopArr = [-1/3, 1/3, 1/3] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case "5/4": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			//5/4拍根据谱面的CompoundTempo来特殊处理 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if(CompoundTempo==="2+3"){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				loopArr = [-1/5, 1/5, -1/5, 1/5, 1/5] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				loopArr = [-1/5, 1/5, 1/5, -1/5, 1/5] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case "3/8": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// 3/8拍 速度为浮点4分音符时候特殊处理 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if(speedBeatUnit==="1/4."){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				loopArr = [-1/1] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				loopArr = [-1/3, 1/3, 1/3] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case "6/8": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			loopArr = [-1/2, 1/2] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			break;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case "7/8": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			//7/8拍根据谱面的CompoundTempo来特殊处理 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if(CompoundTempo==="2+2+3"){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				loopArr = [-2/7, 2/7, 3/7] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}else if(CompoundTempo==="2+3+2"){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				loopArr = [-2/7, 3/7, 2/7] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				loopArr = [-3/7, 2/7, 2/7] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			break;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case "9/8": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			loopArr = [-3/9, 3/9, 3/9] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				break;				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			loopArr.push(-1/Numerator); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			for (let i = 1; i < Numerator; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				loopArr.push(1/Numerator); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// console.log(loopArr, "loopArr") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return loopArr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // 计算拍子的时值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 function calculateMetroStep(arr: any[], m: any): number[] { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	const measureLength = arr.reduce((total: number, item: any) => { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -604,72 +663,6 @@ function calculateMetroStep(arr: any[], m: any): number[] { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// console.log("stepList", [...stepList], m.measureNumberXML); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return stepList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 计算单声部多声轨的拍子的时值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function calculateMutilpleMetroStep(arr: any[], m: any): number[] { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	// console.log("🚀 ~ m:", [...m.svgs]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const step = m.time / m.numerator; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const measure_bbox = arr[0]?.svgElement?.attrs?.el?.parentElement?.parentElement?.getBoundingClientRect?.() || { x: 0 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (arr.length === 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const staveNote = m.svgs[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// 大于一拍 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		let bbox = staveNote?.attrs?.el?.getBoundingClientRect?.() || { x: 0 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (staveNote && !staveNote.isRest()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return [bbox.x - measure_bbox.x]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	// console.log("🚀 ~ arr", arr, step, m.measureNumberXML); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	let total = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	let notes: any[] = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	let stepList: number[] = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	for (let i = 0; i < arr.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const item = arr[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		item._index = i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const noteTime = item.endtime - item.time; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		total += noteTime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		let svgEle = m.svgs[i]?.attrs?.el; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// 大于一拍 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		let bbox = svgEle?.getBoundingClientRect?.() || { x: 0 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// console.log(m.measureNumberXML, svgEle, i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (noteTime > step) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			total -= step; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			// console.log('超过一拍了', notes, m.measureNumberXML) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			let x = bbox.x - measure_bbox.x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (notes.length > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				svgEle = m.svgs[notes[0]._index]?.attrs?.el; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				bbox = svgEle?.getBoundingClientRect?.() || { x: 0 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				x = bbox.x - measure_bbox.x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			stepList.push(x); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			notes = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			notes.push(item); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// console.log(notes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (Math.abs(total - step) < 0.001) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			let x = bbox.x - measure_bbox.x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (notes.length > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				svgEle = m.svgs[notes[0]._index]?.attrs?.el; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				bbox = svgEle?.getBoundingClientRect?.() || { x: 0 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				x = bbox.x - measure_bbox.x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			// console.log("一拍",svgEle,notes,m.svgs, m.measureNumberXML); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			stepList.push(x); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			total = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			notes = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	stepList = stepList.reduce((list: any[], n: number) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (list.includes(n)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			list.push(undefined as any); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			list.push(n); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return list; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	}, []); //Array.from(new Set(stepList)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	// console.log('stepList', stepList, m.measureNumberXML) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	return stepList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // 延迟兼容处理 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 function setCurrentTime(time: number) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -700,5 +693,14 @@ function hideCursorTip() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		}, 2000); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function isWithinRange(ranges:any[], index:number) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (const range of ranges) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		const start = range[0].measureIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		const end = range[1].measureIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (index >= start && index < end) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 export default Metronome; 
			 |