 e89f2f4b7b
			
		
	
	e89f2f4b7b
	
	
	
		
			
			Created 10 detailed GitHub issues covering: - Project activation and management UI (#1-2) - Worker node coordination and visualization (#3-4) - Automated GitHub repository scanning (#5) - Intelligent model-to-issue matching (#6) - Multi-model task execution system (#7) - N8N workflow integration (#8) - Hive-Bzzz P2P bridge (#9) - Peer assistance protocol (#10) Each issue includes detailed specifications, acceptance criteria, technical implementation notes, and dependency mapping. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			125 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // For each opening emphasis-like marker find a matching closing one
 | |
| //
 | |
| 
 | |
| function processDelimiters (delimiters) {
 | |
|   const openersBottom = {}
 | |
|   const max = delimiters.length
 | |
| 
 | |
|   if (!max) return
 | |
| 
 | |
|   // headerIdx is the first delimiter of the current (where closer is) delimiter run
 | |
|   let headerIdx = 0
 | |
|   let lastTokenIdx = -2 // needs any value lower than -1
 | |
|   const jumps = []
 | |
| 
 | |
|   for (let closerIdx = 0; closerIdx < max; closerIdx++) {
 | |
|     const closer = delimiters[closerIdx]
 | |
| 
 | |
|     jumps.push(0)
 | |
| 
 | |
|     // markers belong to same delimiter run if:
 | |
|     //  - they have adjacent tokens
 | |
|     //  - AND markers are the same
 | |
|     //
 | |
|     if (delimiters[headerIdx].marker !== closer.marker || lastTokenIdx !== closer.token - 1) {
 | |
|       headerIdx = closerIdx
 | |
|     }
 | |
| 
 | |
|     lastTokenIdx = closer.token
 | |
| 
 | |
|     // Length is only used for emphasis-specific "rule of 3",
 | |
|     // if it's not defined (in strikethrough or 3rd party plugins),
 | |
|     // we can default it to 0 to disable those checks.
 | |
|     //
 | |
|     closer.length = closer.length || 0
 | |
| 
 | |
|     if (!closer.close) continue
 | |
| 
 | |
|     // Previously calculated lower bounds (previous fails)
 | |
|     // for each marker, each delimiter length modulo 3,
 | |
|     // and for whether this closer can be an opener;
 | |
|     // https://github.com/commonmark/cmark/commit/34250e12ccebdc6372b8b49c44fab57c72443460
 | |
|     /* eslint-disable-next-line no-prototype-builtins */
 | |
|     if (!openersBottom.hasOwnProperty(closer.marker)) {
 | |
|       openersBottom[closer.marker] = [-1, -1, -1, -1, -1, -1]
 | |
|     }
 | |
| 
 | |
|     const minOpenerIdx = openersBottom[closer.marker][(closer.open ? 3 : 0) + (closer.length % 3)]
 | |
| 
 | |
|     let openerIdx = headerIdx - jumps[headerIdx] - 1
 | |
| 
 | |
|     let newMinOpenerIdx = openerIdx
 | |
| 
 | |
|     for (; openerIdx > minOpenerIdx; openerIdx -= jumps[openerIdx] + 1) {
 | |
|       const opener = delimiters[openerIdx]
 | |
| 
 | |
|       if (opener.marker !== closer.marker) continue
 | |
| 
 | |
|       if (opener.open && opener.end < 0) {
 | |
|         let isOddMatch = false
 | |
| 
 | |
|         // from spec:
 | |
|         //
 | |
|         // If one of the delimiters can both open and close emphasis, then the
 | |
|         // sum of the lengths of the delimiter runs containing the opening and
 | |
|         // closing delimiters must not be a multiple of 3 unless both lengths
 | |
|         // are multiples of 3.
 | |
|         //
 | |
|         if (opener.close || closer.open) {
 | |
|           if ((opener.length + closer.length) % 3 === 0) {
 | |
|             if (opener.length % 3 !== 0 || closer.length % 3 !== 0) {
 | |
|               isOddMatch = true
 | |
|             }
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         if (!isOddMatch) {
 | |
|           // If previous delimiter cannot be an opener, we can safely skip
 | |
|           // the entire sequence in future checks. This is required to make
 | |
|           // sure algorithm has linear complexity (see *_*_*_*_*_... case).
 | |
|           //
 | |
|           const lastJump = openerIdx > 0 && !delimiters[openerIdx - 1].open
 | |
|             ? jumps[openerIdx - 1] + 1
 | |
|             : 0
 | |
| 
 | |
|           jumps[closerIdx] = closerIdx - openerIdx + lastJump
 | |
|           jumps[openerIdx] = lastJump
 | |
| 
 | |
|           closer.open  = false
 | |
|           opener.end   = closerIdx
 | |
|           opener.close = false
 | |
|           newMinOpenerIdx = -1
 | |
|           // treat next token as start of run,
 | |
|           // it optimizes skips in **<...>**a**<...>** pathological case
 | |
|           lastTokenIdx = -2
 | |
|           break
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if (newMinOpenerIdx !== -1) {
 | |
|       // If match for this delimiter run failed, we want to set lower bound for
 | |
|       // future lookups. This is required to make sure algorithm has linear
 | |
|       // complexity.
 | |
|       //
 | |
|       // See details here:
 | |
|       // https://github.com/commonmark/cmark/issues/178#issuecomment-270417442
 | |
|       //
 | |
|       openersBottom[closer.marker][(closer.open ? 3 : 0) + ((closer.length || 0) % 3)] = newMinOpenerIdx
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| export default function link_pairs (state) {
 | |
|   const tokens_meta = state.tokens_meta
 | |
|   const max = state.tokens_meta.length
 | |
| 
 | |
|   processDelimiters(state.delimiters)
 | |
| 
 | |
|   for (let curr = 0; curr < max; curr++) {
 | |
|     if (tokens_meta[curr] && tokens_meta[curr].delimiters) {
 | |
|       processDelimiters(tokens_meta[curr].delimiters)
 | |
|     }
 | |
|   }
 | |
| }
 |