code: def intervals(self, reverse, thr=0):
          
  
          d = [(thr,thr)]
          dl = 0
          for tup in self.cigar_iter(reverse):
              if tup[1] == "D":
                  dl = tup[0]
              else:
                  s = d[-1][1] + dl
                  d.append( (s, s+tup[0]) )
  
          assert d[0] == (thr, thr)
          # assert that nr. of Ms in the interval == sum of produced intervals
          assert sum( t[0] for t in self.cigar_iter(False) if t[1] == "M" ) == sum( t[1]-t[0] for t in d )
  
          d_sum = sum( t[1]-t[0] for t in d )
          assert self.end - self.start + 1 == d_sum, "[ (%d, %d) = %d ] != %d" % (self.start, self.end,
                  self.end-self.start+1, d_sum)
          return d[1:]
docs: return a list of (0-based half-open) intervals representing the match regions of the cigar
  
          for example 4MD4M2DM with reverse=False will produce [(0,4), (5,9), (11,12)]
          4MD4M2DM with reverse=True will produce [(0,1), (3,7), (8,12)] (= 12 - previous interval)
  
          :param reverse: whether to iterate in the reverse direction (right-to-left) (this is passed as is to self.cigar_iter)
          :type reverse: boolean
          :param thr: shift all intervals by this much
          :type thr: integer
  
          :return: list of pairs