function appendPropertyTRs (parent, plist, inverse, predicateFilter) {
      // UI.log.info('@appendPropertyTRs, 'this' is %s, dom is %s, '+ // Gives 'can't access dead object'
      //                   'thisOutline.document is %s', this, dom.location, thisOutline.document.location);
      // UI.log.info('@appendPropertyTRs, dom is now ' + this.document.location);
      // UI.log.info('@appendPropertyTRs, dom is now ' + thisOutline.document.location);
    UI.log.debug('Property list length = ' + plist.length)
    if (plist.length === 0) return ''
    var sel, j, k
    if (inverse) {
      sel = function (x) {
        return x.subject
      }
      plist = plist.sort(UI.utils.RDFComparePredicateSubject)
    } else {
      sel = function (x) {
        return x.object
      }
      plist = plist.sort(UI.utils.RDFComparePredicateObject)
    }

    var max = plist.length
    for (j = 0; j < max; j++) { // squishing together equivalent properties I think
      var s = plist[j]
          //      if (s.object == parentSubject) continue; // that we knew

        // Avoid predicates from other panes
      if (predicateFilter && !predicateFilter(s.predicate, inverse)) continue

      var tr = propertyTR(dom, s, inverse)
      parent.appendChild(tr)
      var predicateTD = tr.firstChild // we need to kludge the rowspan later

      var defaultpropview = views.defaults[s.predicate.uri]

      //   LANGUAGE PREFERENCES WAS AVAILABLE WITH FF EXTENSION - get from elsewhere?

      var dups = 0 // How many rows have the same predicate, -1?
      var langTagged = 0 // how many objects have language tags?
      var myLang = 0 // Is there one I like?

      for (k = 0;
          (k + j < max) && (plist[j + k].predicate.sameTerm(s.predicate)); k++) {
        if (k > 0 && (sel(plist[j + k]).sameTerm(sel(plist[j + k - 1])))) dups++
        if (sel(plist[j + k]).lang && outline.labeller.LanguagePreference) {
          langTagged += 1
          if (sel(plist[j + k]).lang.indexOf(outline.labeller.LanguagePreference) >= 0) myLang++
        }
      }

        /* Display only the one in the preferred language
          ONLY in the case (currently) when all the values are tagged.
          Then we treat them as alternatives. */

      if (myLang > 0 && langTagged === dups + 1) {
        for (let k = j; k <= j + dups; k++) {
          if (outline.labeller.LanguagePreference && sel(plist[k]).lang.indexOf(outline.labeller.LanguagePreference) >= 0) {
            tr.appendChild(thisOutline.outlineObjectTD(sel(plist[k]), defaultpropview, undefined, s))
            break
          }
        }
        j += dups // extra push
        continue
      }

      tr.appendChild(thisOutline.outlineObjectTD(sel(s), defaultpropview, undefined, s))

        /* Note: showNobj shows between n to 2n objects.
         * This is to prevent the case where you have a long list of objects
         * shown, and dangling at the end is '1 more' (which is easily ignored)
         * Therefore more objects are shown than hidden.
         */

      tr.showNobj = function (n) {
        var predDups = k - dups
        var show = ((2 * n) < predDups) ? n : predDups
        var showLaterArray = []
        if (predDups !== 1) {
          predicateTD.setAttribute('rowspan', (show === predDups) ? predDups : n + 1)
          var l
          if ((show < predDups) && (show === 1)) { // what case is this...
            predicateTD.setAttribute('rowspan', 2)
          }
          var displayed = 0 // The number of cells generated-1,
              // all duplicate thing removed
          for (l = 1; l < k; l++) {
                // This detects the same things
            if (!kb.canon(sel(plist[j + l])).sameTerm(kb.canon(sel(plist[j + l - 1])))) {
              displayed++
              s = plist[j + l]
              defaultpropview = views.defaults[s.predicate.uri]
              var trObj = dom.createElement('tr')
              trObj.style.colspan = '1'
              trObj.appendChild(thisOutline.outlineObjectTD(
                    sel(plist[j + l]), defaultpropview, undefined, s))
              trObj.AJAR_statement = s
              trObj.AJAR_inverse = inverse
              parent.appendChild(trObj)
              if (displayed >= show) {
                trObj.style.display = 'none'
                showLaterArray.push(trObj)
              }
            } else {
                  // ToDo: show all the data sources of this statement
              UI.log.info('there are duplicates here: %s', plist[j + l - 1])
            }
          }
              // @@a quick fix on the messing problem.
          if (show === predDups) { predicateTD.setAttribute('rowspan', displayed + 1) }
        } // end of if (predDups!==1)

        if (show < predDups) { // Add the x more <TR> here
          var moreTR = dom.createElement('tr')
          var moreTD = moreTR.appendChild(dom.createElement('td'))
          moreTD.setAttribute('style', 'margin: 0.2em; border: none; padding: 0; vertical-align: top;')
          moreTD.setAttribute('notSelectable', 'false')
          if (predDups > n) { // what is this for??
            var small = dom.createElement('a')
            moreTD.appendChild(small)

            var predToggle = (function (f) {
              return f(predicateTD, k, dups, n)
            })(function (predicateTD, k, dups, n) {
              return function (display) {
                small.innerHTML = ''
                if (display === 'none') {
                  small.appendChild(UI.utils.AJARImage(UI.icons.originalIconBase + 'tbl-more-trans.png', 'more', 'See all', dom))
                  small.appendChild(dom.createTextNode((predDups - n) + ' more...'))
                  predicateTD.setAttribute('rowspan', n + 1)
                } else {
                  small.appendChild(UI.utils.AJARImage(UI.icons.originalIconBase + 'tbl-shrink.png', '(less)', undefined, dom))
                  predicateTD.setAttribute('rowspan', predDups + 1)
                }
                for (var i = 0; i < showLaterArray.length; i++) {
                  var trObj = showLaterArray[i]
                  trObj.style.display = display
                }
              }
            }) // ???
            var current = 'none'
            var toggleObj = function (event) {
              predToggle(current)
              current = (current === 'none') ? '' : 'none'
              if (event) event.stopPropagation()
              return false // what is this for?
            }
            toggleObj()
            small.addEventListener('click', toggleObj, false)
          } // if(predDups>n)
          parent.appendChild(moreTR)
        } // if
      } // tr.showNobj

      tr.showAllobj = function () {
        tr.showNobj(k - dups)
      }

      tr.showNobj(10)

      j += k - 1 // extra push
    }
  }
function appendPropertyTRs (parent, plist, inverse, predicateFilter) {
      
      
      
      
    UI.log.debug('Property list length = ' + plist.length)
    if (plist.length === 0) return ''
    var sel, j, k
    if (inverse) {
      sel = function (x) {
        return x.subject
      }
      plist = plist.sort(UI.utils.RDFComparePredicateSubject)
    } else {
      sel = function (x) {
        return x.object
      }
      plist = plist.sort(UI.utils.RDFComparePredicateObject)
    }

    var max = plist.length
    for (j = 0; j < max; j++) { 
      var s = plist[j]
          

        
      if (predicateFilter && !predicateFilter(s.predicate, inverse)) continue

      var tr = propertyTR(dom, s, inverse)
      parent.appendChild(tr)
      var predicateTD = tr.firstChild 

      var defaultpropview = views.defaults[s.predicate.uri]

      

      var dups = 0 
      var langTagged = 0 
      var myLang = 0 

      for (k = 0;
          (k + j < max) && (plist[j + k].predicate.sameTerm(s.predicate)); k++) {
        if (k > 0 && (sel(plist[j + k]).sameTerm(sel(plist[j + k - 1])))) dups++
        if (sel(plist[j + k]).lang && outline.labeller.LanguagePreference) {
          langTagged += 1
          if (sel(plist[j + k]).lang.indexOf(outline.labeller.LanguagePreference) >= 0) myLang++
        }
      }

        

      if (myLang > 0 && langTagged === dups + 1) {
        for (let k = j; k <= j + dups; k++) {
          if (outline.labeller.LanguagePreference && sel(plist[k]).lang.indexOf(outline.labeller.LanguagePreference) >= 0) {
            tr.appendChild(thisOutline.outlineObjectTD(sel(plist[k]), defaultpropview, undefined, s))
            break
          }
        }
        j += dups 
        continue
      }

      tr.appendChild(thisOutline.outlineObjectTD(sel(s), defaultpropview, undefined, s))

        

      tr.showNobj = function (n) {
        var predDups = k - dups
        var show = ((2 * n) < predDups) ? n : predDups
        var showLaterArray = []
        if (predDups !== 1) {
          predicateTD.setAttribute('rowspan', (show === predDups) ? predDups : n + 1)
          var l
          if ((show < predDups) && (show === 1)) { 
            predicateTD.setAttribute('rowspan', 2)
          }
          var displayed = 0 
              
          for (l = 1; l < k; l++) {
                
            if (!kb.canon(sel(plist[j + l])).sameTerm(kb.canon(sel(plist[j + l - 1])))) {
              displayed++
              s = plist[j + l]
              defaultpropview = views.defaults[s.predicate.uri]
              var trObj = dom.createElement('tr')
              trObj.style.colspan = '1'
              trObj.appendChild(thisOutline.outlineObjectTD(
                    sel(plist[j + l]), defaultpropview, undefined, s))
              trObj.AJAR_statement = s
              trObj.AJAR_inverse = inverse
              parent.appendChild(trObj)
              if (displayed >= show) {
                trObj.style.display = 'none'
                showLaterArray.push(trObj)
              }
            } else {
                  
              UI.log.info('there are duplicates here: %s', plist[j + l - 1])
            }
          }
              
          if (show === predDups) { predicateTD.setAttribute('rowspan', displayed + 1) }
        } 

        if (show < predDups) { 
          var moreTR = dom.createElement('tr')
          var moreTD = moreTR.appendChild(dom.createElement('td'))
          moreTD.setAttribute('style', 'margin: 0.2em; border: none; padding: 0; vertical-align: top;')
          moreTD.setAttribute('notSelectable', 'false')
          if (predDups > n) { 
            var small = dom.createElement('a')
            moreTD.appendChild(small)

            var predToggle = (function (f) {
              return f(predicateTD, k, dups, n)
            })(function (predicateTD, k, dups, n) {
              return function (display) {
                small.innerHTML = ''
                if (display === 'none') {
                  small.appendChild(UI.utils.AJARImage(UI.icons.originalIconBase + 'tbl-more-trans.png', 'more', 'See all', dom))
                  small.appendChild(dom.createTextNode((predDups - n) + ' more...'))
                  predicateTD.setAttribute('rowspan', n + 1)
                } else {
                  small.appendChild(UI.utils.AJARImage(UI.icons.originalIconBase + 'tbl-shrink.png', '(less)', undefined, dom))
                  predicateTD.setAttribute('rowspan', predDups + 1)
                }
                for (var i = 0; i < showLaterArray.length; i++) {
                  var trObj = showLaterArray[i]
                  trObj.style.display = display
                }
              }
            }) 
            var current = 'none'
            var toggleObj = function (event) {
              predToggle(current)
              current = (current === 'none') ? '' : 'none'
              if (event) event.stopPropagation()
              return false 
            }
            toggleObj()
            small.addEventListener('click', toggleObj, false)
          } 
          parent.appendChild(moreTR)
        } 
      } 

      tr.showAllobj = function () {
        tr.showNobj(k - dups)
      }

      tr.showNobj(10)

      j += k - 1 
    }
  }
function appendPropertyTRs ( parent , plist , inverse , predicateFilter ) { // UI.log.info('@appendPropertyTRs, 'this' is %s, dom is %s, '+ // Gives 'can't access dead object' //                   'thisOutline.document is %s', this, dom.location, thisOutline.document.location); // UI.log.info('@appendPropertyTRs, dom is now ' + this.document.location); // UI.log.info('@appendPropertyTRs, dom is now ' + thisOutline.document.location); UI . log . debug ( 'Property list length = ' + plist . length ) if ( plist . length === 0 ) return '' var sel , j , k if ( inverse ) { sel = function ( x ) { return x . subject } plist = plist . sort ( UI . utils . RDFComparePredicateSubject ) } else { sel = function ( x ) { return x . object } plist = plist . sort ( UI . utils . RDFComparePredicateObject ) } var max = plist . length for ( j = 0 ; j < max ; j ++ ) { // squishing together equivalent properties I think var s = plist [ j ] //      if (s.object == parentSubject) continue; // that we knew // Avoid predicates from other panes if ( predicateFilter && ! predicateFilter ( s . predicate , inverse ) ) continue var tr = propertyTR ( dom , s , inverse ) parent . appendChild ( tr ) var predicateTD = tr . firstChild // we need to kludge the rowspan later var defaultpropview = views . defaults [ s . predicate . uri ] //   LANGUAGE PREFERENCES WAS AVAILABLE WITH FF EXTENSION - get from elsewhere? var dups = 0 // How many rows have the same predicate, -1? var langTagged = 0 // how many objects have language tags? var myLang = 0 // Is there one I like? for ( k = 0 ; ( k + j < max ) && ( plist [ j + k ] . predicate . sameTerm ( s . predicate ) ) ; k ++ ) { if ( k > 0 && ( sel ( plist [ j + k ] ) . sameTerm ( sel ( plist [ j + k - 1 ] ) ) ) ) dups ++ if ( sel ( plist [ j + k ] ) . lang && outline . labeller . LanguagePreference ) { langTagged += 1 if ( sel ( plist [ j + k ] ) . lang . indexOf ( outline . labeller . LanguagePreference ) >= 0 ) myLang ++ } } /* Display only the one in the preferred language
          ONLY in the case (currently) when all the values are tagged.
          Then we treat them as alternatives. */ if ( myLang > 0 && langTagged === dups + 1 ) { for ( let k = j ; k <= j + dups ; k ++ ) { if ( outline . labeller . LanguagePreference && sel ( plist [ k ] ) . lang . indexOf ( outline . labeller . LanguagePreference ) >= 0 ) { tr . appendChild ( thisOutline . outlineObjectTD ( sel ( plist [ k ] ) , defaultpropview , undefined , s ) ) break } } j += dups // extra push continue } tr . appendChild ( thisOutline . outlineObjectTD ( sel ( s ) , defaultpropview , undefined , s ) ) /* Note: showNobj shows between n to 2n objects.
         * This is to prevent the case where you have a long list of objects
         * shown, and dangling at the end is '1 more' (which is easily ignored)
         * Therefore more objects are shown than hidden.
         */ tr . showNobj = function ( n ) { var predDups = k - dups var show = ( ( 2 * n ) < predDups ) ? n : predDups var showLaterArray = [ ] if ( predDups !== 1 ) { predicateTD . setAttribute ( 'rowspan' , ( show === predDups ) ? predDups : n + 1 ) var l if ( ( show < predDups ) && ( show === 1 ) ) { // what case is this... predicateTD . setAttribute ( 'rowspan' , 2 ) } var displayed = 0 // The number of cells generated-1, // all duplicate thing removed for ( l = 1 ; l < k ; l ++ ) { // This detects the same things if ( ! kb . canon ( sel ( plist [ j + l ] ) ) . sameTerm ( kb . canon ( sel ( plist [ j + l - 1 ] ) ) ) ) { displayed ++ s = plist [ j + l ] defaultpropview = views . defaults [ s . predicate . uri ] var trObj = dom . createElement ( 'tr' ) trObj . style . colspan = '1' trObj . appendChild ( thisOutline . outlineObjectTD ( sel ( plist [ j + l ] ) , defaultpropview , undefined , s ) ) trObj . AJAR_statement = s trObj . AJAR_inverse = inverse parent . appendChild ( trObj ) if ( displayed >= show ) { trObj . style . display = 'none' showLaterArray . push ( trObj ) } } else { // ToDo: show all the data sources of this statement UI . log . info ( 'there are duplicates here: %s' , plist [ j + l - 1 ] ) } } // @@a quick fix on the messing problem. if ( show === predDups ) { predicateTD . setAttribute ( 'rowspan' , displayed + 1 ) } } // end of if (predDups!==1) if ( show < predDups ) { // Add the x more <TR> here var moreTR = dom . createElement ( 'tr' ) var moreTD = moreTR . appendChild ( dom . createElement ( 'td' ) ) moreTD . setAttribute ( 'style' , 'margin: 0.2em; border: none; padding: 0; vertical-align: top;' ) moreTD . setAttribute ( 'notSelectable' , 'false' ) if ( predDups > n ) { // what is this for?? var small = dom . createElement ( 'a' ) moreTD . appendChild ( small ) var predToggle = ( function ( f ) { return f ( predicateTD , k , dups , n ) } ) ( function ( predicateTD , k , dups , n ) { return function ( display ) { small . innerHTML = '' if ( display === 'none' ) { small . appendChild ( UI . utils . AJARImage ( UI . icons . originalIconBase + 'tbl-more-trans.png' , 'more' , 'See all' , dom ) ) small . appendChild ( dom . createTextNode ( ( predDups - n ) + ' more...' ) ) predicateTD . setAttribute ( 'rowspan' , n + 1 ) } else { small . appendChild ( UI . utils . AJARImage ( UI . icons . originalIconBase + 'tbl-shrink.png' , '(less)' , undefined , dom ) ) predicateTD . setAttribute ( 'rowspan' , predDups + 1 ) } for ( var i = 0 ; i < showLaterArray . length ; i ++ ) { var trObj = showLaterArray [ i ] trObj . style . display = display } } } ) // ??? var current = 'none' var toggleObj = function ( event ) { predToggle ( current ) current = ( current === 'none' ) ? '' : 'none' if ( event ) event . stopPropagation ( ) return false // what is this for? } toggleObj ( ) small . addEventListener ( 'click' , toggleObj , false ) } // if(predDups>n) parent . appendChild ( moreTR ) } // if } // tr.showNobj tr . showAllobj = function ( ) { tr . showNobj ( k - dups ) } tr . showNobj ( 10 ) j += k - 1 // extra push } }
/ ////////// Property list
/ ////////// Property list