Nanopublication

< Home

ID

https://w3id.org/np/RAZ91VKijoZZumm8JX5BBsVD1Fb5t8Eo74WxBNg_0AVos

Formats

.trig | .trig.txt | .jelly | .jelly.txt | .jsonld | .jsonld.txt | .nq | .nq.txt | .xml | .xml.txt

Content

@prefix this: <https://w3id.org/np/RAZ91VKijoZZumm8JX5BBsVD1Fb5t8Eo74WxBNg_0AVos> .
@prefix sub: <https://w3id.org/np/RAZ91VKijoZZumm8JX5BBsVD1Fb5t8Eo74WxBNg_0AVos/> .
@prefix np: <http://www.nanopub.org/nschema#> .
@prefix grlc: <https://w3id.org/kpxl/grlc/> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix nt: <https://w3id.org/np/o/ntemplate/> .
@prefix npx: <http://purl.org/nanopub/x/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix orcid: <https://orcid.org/> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

sub:Head {
  this: a np:Nanopublication;
    np:hasAssertion sub:assertion;
    np:hasProvenance sub:provenance;
    np:hasPublicationInfo sub:pubinfo .
}

sub:assertion {
  sub:get-presentations-grid-svg a grlc:grlc-query;
    dct:description "Renders the presentations of an event as a programme grid, one SVG per day: one column per room, boxes placed by clock time and split vertically when several talks share a slot. Each box links to the presentation and shows its authors and title. Reads both the http:// and https:// schema.org namespaces.";
    dct:license <http://www.apache.org/licenses/LICENSE-2.0>;
    rdfs:label "Get the presentation programme of an event as an SVG grid";
    grlc:endpoint <https://w3id.org/np/l/nanopub-query-1.1/repo/type/3952cad1a6d2561f045d33e5e79c03e7264b0a492b8becf6c62656c596cf398c>;
    grlc:sparql """prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix dct: <http://purl.org/dc/terms/>
prefix np: <http://www.nanopub.org/nschema#>
prefix npa: <http://purl.org/nanopub/admin/>
prefix npx: <http://purl.org/nanopub/x/>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix wd: <http://www.wikidata.org/entity/>
prefix schema: <https://schema.org/>
prefix schemaold: <http://schema.org/>
prefix foaf: <http://xmlns.com/foaf/0.1/>
prefix pav: <http://purl.org/pav/>

select ?title (concat(
    '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ', str(?w), ' ', str(?h),
    '\" width=\"', str(round(?w * 3 / 2)), '\" height=\"', str(round(?h * 3 / 2)), '\" font-family=\"sans-serif\">',
    ?frags, '</svg>') as ?svg)
where {
  {
    select ?day (group_concat(?frag; separator=\"\") as ?frags)
           (max(?ybot) as ?maxy) (max(?xright) as ?maxx)
    where {
      # ============ talk boxes ============
      {
        select ?day ?frag (?by + ?bh as ?ybot) (?bx + 250 as ?xright)
        where {
          {
            select ?pres ?day ?room ?smin ?emin ?tlabel
                   (group_concat(distinct ?aname; separator=\", \") as ?authors)
            where {
      graph npa:graph {
        ?np npa:hasValidSignatureForPublicKeyHash ?pk ;
          np:hasAssertion ?a ; npx:introduces ?pres .
        filter not exists { ?inv npx:invalidates ?np ; npa:hasValidSignatureForPublicKeyHash ?pk . }
        filter not exists { ?np npx:hasNanopubType npx:ExampleNanopub . }
      }
      filter not exists { graph ?sg { ?newer npx:supersedes ?np . } }
      values ?_event_multi_iri {}
      graph ?a { ?pres a wd:Q604733 ; dct:isPartOf ?_event_multi_iri . }
      optional { graph ?a { ?pres schema:startDate ?sdA } }
      optional { graph ?a { ?pres schemaold:startDate ?sdB } }
      optional { graph ?a { ?pres schema:endDate ?edA } }
      optional { graph ?a { ?pres schemaold:endDate ?edB } }
      optional { graph ?a { ?pres schema:location ?loA } }
      optional { graph ?a { ?pres schemaold:location ?loB } }
      optional { graph ?a { ?pres rdfs:label ?lb } }
      bind(coalesce(?sdA, ?sdB) as ?sd)
      filter(bound(?sd))
      bind(coalesce(?edA, ?edB) as ?ed)
      bind(coalesce(str(?loA), str(?loB), \"\") as ?room)
      bind(substr(str(?sd), 1, 10) as ?day)
      bind(xsd:integer(substr(str(?sd), 12, 2)) * 60 + xsd:integer(substr(str(?sd), 15, 2)) as ?smin)
      bind(coalesce(xsd:integer(substr(str(?ed), 12, 2)) * 60 + xsd:integer(substr(str(?ed), 15, 2)), ?smin + 30) as ?emin)
      bind(coalesce(str(?lb), \"(untitled)\") as ?tlabel)
              optional {
                graph ?a { ?pres pav:authoredBy ?ag }
                optional { graph ?pi2 { ?ag foaf:name ?agn } }
                bind(coalesce(?agn, replace(str(?ag), \"^.*/\", \"\")) as ?aname)
              }
            } group by ?pres ?day ?room ?smin ?emin ?tlabel
          }
          # rank inside the (day, room, slot) cell, and how many share it
          {
            select ?pres (count(distinct ?o) as ?rank) where {
      graph npa:graph {
        ?npR npa:hasValidSignatureForPublicKeyHash ?pkR ;
          np:hasAssertion ?a2 ; npx:introduces ?pres .
        filter not exists { ?invR npx:invalidates ?npR ; npa:hasValidSignatureForPublicKeyHash ?pkR . }
        filter not exists { ?npR npx:hasNanopubType npx:ExampleNanopub . }
      }
      filter not exists { graph ?sgR { ?newerR npx:supersedes ?npR . } }
      values ?_event_multi_iri {}
      graph ?a2 { ?pres a wd:Q604733 ; dct:isPartOf ?_event_multi_iri . }
      optional { graph ?a2 { ?pres schema:startDate ?sdAR } }
      optional { graph ?a2 { ?pres schemaold:startDate ?sdBR } }
      optional { graph ?a2 { ?pres schema:endDate ?edAR } }
      optional { graph ?a2 { ?pres schemaold:endDate ?edBR } }
      optional { graph ?a2 { ?pres schema:location ?loAR } }
      optional { graph ?a2 { ?pres schemaold:location ?loBR } }
      optional { graph ?a2 { ?pres rdfs:label ?lbR } }
      bind(coalesce(?sdAR, ?sdBR) as ?sdR)
      filter(bound(?sdR))
      bind(coalesce(?edAR, ?edBR) as ?edR)
      bind(coalesce(str(?loAR), str(?loBR), \"\") as ?roomR)
      bind(substr(str(?sdR), 1, 10) as ?dayR)
      bind(xsd:integer(substr(str(?sdR), 12, 2)) * 60 + xsd:integer(substr(str(?sdR), 15, 2)) as ?sminR)
      bind(coalesce(xsd:integer(substr(str(?edR), 12, 2)) * 60 + xsd:integer(substr(str(?edR), 15, 2)), ?sminR + 30) as ?eminR)
      bind(coalesce(str(?lbR), \"(untitled)\") as ?tlabelR)
      graph npa:graph {
        ?npO npa:hasValidSignatureForPublicKeyHash ?pkO ;
          np:hasAssertion ?ao ; npx:introduces ?o .
        filter not exists { ?invO npx:invalidates ?npO ; npa:hasValidSignatureForPublicKeyHash ?pkO . }
        filter not exists { ?npO npx:hasNanopubType npx:ExampleNanopub . }
      }
      filter not exists { graph ?sgO { ?newerO npx:supersedes ?npO . } }
      values ?_event_multi_iri {}
      graph ?ao { ?o a wd:Q604733 ; dct:isPartOf ?_event_multi_iri . }
      optional { graph ?ao { ?o schema:startDate ?sdAO } }
      optional { graph ?ao { ?o schemaold:startDate ?sdBO } }
      optional { graph ?ao { ?o schema:endDate ?edAO } }
      optional { graph ?ao { ?o schemaold:endDate ?edBO } }
      optional { graph ?ao { ?o schema:location ?loAO } }
      optional { graph ?ao { ?o schemaold:location ?loBO } }
      optional { graph ?ao { ?o rdfs:label ?lbO } }
      bind(coalesce(?sdAO, ?sdBO) as ?sdO)
      filter(bound(?sdO))
      bind(coalesce(?edAO, ?edBO) as ?edO)
      bind(coalesce(str(?loAO), str(?loBO), \"\") as ?roomO)
      bind(substr(str(?sdO), 1, 10) as ?dayO)
      bind(xsd:integer(substr(str(?sdO), 12, 2)) * 60 + xsd:integer(substr(str(?sdO), 15, 2)) as ?sminO)
      bind(coalesce(xsd:integer(substr(str(?edO), 12, 2)) * 60 + xsd:integer(substr(str(?edO), 15, 2)), ?sminO + 30) as ?eminO)
      bind(coalesce(str(?lbO), \"(untitled)\") as ?tlabelO)
              filter(?dayR = ?dayO && ?roomR = ?roomO && ?sminR = ?sminO && str(?tlabelO) <= str(?tlabelR))
            } group by ?pres
          }
          {
            select ?pres (count(distinct ?o2) as ?nslot) where {
      graph npa:graph {
        ?npS npa:hasValidSignatureForPublicKeyHash ?pkS ;
          np:hasAssertion ?a3 ; npx:introduces ?pres .
        filter not exists { ?invS npx:invalidates ?npS ; npa:hasValidSignatureForPublicKeyHash ?pkS . }
        filter not exists { ?npS npx:hasNanopubType npx:ExampleNanopub . }
      }
      filter not exists { graph ?sgS { ?newerS npx:supersedes ?npS . } }
      values ?_event_multi_iri {}
      graph ?a3 { ?pres a wd:Q604733 ; dct:isPartOf ?_event_multi_iri . }
      optional { graph ?a3 { ?pres schema:startDate ?sdAS } }
      optional { graph ?a3 { ?pres schemaold:startDate ?sdBS } }
      optional { graph ?a3 { ?pres schema:endDate ?edAS } }
      optional { graph ?a3 { ?pres schemaold:endDate ?edBS } }
      optional { graph ?a3 { ?pres schema:location ?loAS } }
      optional { graph ?a3 { ?pres schemaold:location ?loBS } }
      optional { graph ?a3 { ?pres rdfs:label ?lbS } }
      bind(coalesce(?sdAS, ?sdBS) as ?sdS)
      filter(bound(?sdS))
      bind(coalesce(?edAS, ?edBS) as ?edS)
      bind(coalesce(str(?loAS), str(?loBS), \"\") as ?roomS)
      bind(substr(str(?sdS), 1, 10) as ?dayS)
      bind(xsd:integer(substr(str(?sdS), 12, 2)) * 60 + xsd:integer(substr(str(?sdS), 15, 2)) as ?sminS)
      bind(coalesce(xsd:integer(substr(str(?edS), 12, 2)) * 60 + xsd:integer(substr(str(?edS), 15, 2)), ?sminS + 30) as ?eminS)
      bind(coalesce(str(?lbS), \"(untitled)\") as ?tlabelS)
      graph npa:graph {
        ?npP npa:hasValidSignatureForPublicKeyHash ?pkP ;
          np:hasAssertion ?ao2 ; npx:introduces ?o2 .
        filter not exists { ?invP npx:invalidates ?npP ; npa:hasValidSignatureForPublicKeyHash ?pkP . }
        filter not exists { ?npP npx:hasNanopubType npx:ExampleNanopub . }
      }
      filter not exists { graph ?sgP { ?newerP npx:supersedes ?npP . } }
      values ?_event_multi_iri {}
      graph ?ao2 { ?o2 a wd:Q604733 ; dct:isPartOf ?_event_multi_iri . }
      optional { graph ?ao2 { ?o2 schema:startDate ?sdAP } }
      optional { graph ?ao2 { ?o2 schemaold:startDate ?sdBP } }
      optional { graph ?ao2 { ?o2 schema:endDate ?edAP } }
      optional { graph ?ao2 { ?o2 schemaold:endDate ?edBP } }
      optional { graph ?ao2 { ?o2 schema:location ?loAP } }
      optional { graph ?ao2 { ?o2 schemaold:location ?loBP } }
      optional { graph ?ao2 { ?o2 rdfs:label ?lbP } }
      bind(coalesce(?sdAP, ?sdBP) as ?sdP)
      filter(bound(?sdP))
      bind(coalesce(?edAP, ?edBP) as ?edP)
      bind(coalesce(str(?loAP), str(?loBP), \"\") as ?roomP)
      bind(substr(str(?sdP), 1, 10) as ?dayP)
      bind(xsd:integer(substr(str(?sdP), 12, 2)) * 60 + xsd:integer(substr(str(?sdP), 15, 2)) as ?sminP)
      bind(coalesce(xsd:integer(substr(str(?edP), 12, 2)) * 60 + xsd:integer(substr(str(?edP), 15, 2)), ?sminP + 30) as ?eminP)
      bind(coalesce(str(?lbP), \"(untitled)\") as ?tlabelP)
              filter(?dayS = ?dayP && ?roomS = ?roomP && ?sminS = ?sminP)
            } group by ?pres
          }
          # column index of the room
          {
            select ?room (count(distinct ?r2) - 1 as ?col) where {
              { select distinct ?room where {
      graph npa:graph {
        ?npC npa:hasValidSignatureForPublicKeyHash ?pkC ;
          np:hasAssertion ?ac1 ; npx:introduces ?c1 .
        filter not exists { ?invC npx:invalidates ?npC ; npa:hasValidSignatureForPublicKeyHash ?pkC . }
        filter not exists { ?npC npx:hasNanopubType npx:ExampleNanopub . }
      }
      filter not exists { graph ?sgC { ?newerC npx:supersedes ?npC . } }
      values ?_event_multi_iri {}
      graph ?ac1 { ?c1 a wd:Q604733 ; dct:isPartOf ?_event_multi_iri . }
      optional { graph ?ac1 { ?c1 schema:startDate ?sdAC } }
      optional { graph ?ac1 { ?c1 schemaold:startDate ?sdBC } }
      optional { graph ?ac1 { ?c1 schema:endDate ?edAC } }
      optional { graph ?ac1 { ?c1 schemaold:endDate ?edBC } }
      optional { graph ?ac1 { ?c1 schema:location ?loAC } }
      optional { graph ?ac1 { ?c1 schemaold:location ?loBC } }
      optional { graph ?ac1 { ?c1 rdfs:label ?lbC } }
      bind(coalesce(?sdAC, ?sdBC) as ?sdC)
      filter(bound(?sdC))
      bind(coalesce(?edAC, ?edBC) as ?edC)
      bind(coalesce(str(?loAC), str(?loBC), \"\") as ?room)
      bind(substr(str(?sdC), 1, 10) as ?dayC)
      bind(xsd:integer(substr(str(?sdC), 12, 2)) * 60 + xsd:integer(substr(str(?sdC), 15, 2)) as ?sminC)
      bind(coalesce(xsd:integer(substr(str(?edC), 12, 2)) * 60 + xsd:integer(substr(str(?edC), 15, 2)), ?sminC + 30) as ?eminC)
      bind(coalesce(str(?lbC), \"(untitled)\") as ?tlabelC) } }
              { select distinct ?r2 where {
      graph npa:graph {
        ?npD npa:hasValidSignatureForPublicKeyHash ?pkD ;
          np:hasAssertion ?ac2 ; npx:introduces ?c2 .
        filter not exists { ?invD npx:invalidates ?npD ; npa:hasValidSignatureForPublicKeyHash ?pkD . }
        filter not exists { ?npD npx:hasNanopubType npx:ExampleNanopub . }
      }
      filter not exists { graph ?sgD { ?newerD npx:supersedes ?npD . } }
      values ?_event_multi_iri {}
      graph ?ac2 { ?c2 a wd:Q604733 ; dct:isPartOf ?_event_multi_iri . }
      optional { graph ?ac2 { ?c2 schema:startDate ?sdAD } }
      optional { graph ?ac2 { ?c2 schemaold:startDate ?sdBD } }
      optional { graph ?ac2 { ?c2 schema:endDate ?edAD } }
      optional { graph ?ac2 { ?c2 schemaold:endDate ?edBD } }
      optional { graph ?ac2 { ?c2 schema:location ?loAD } }
      optional { graph ?ac2 { ?c2 schemaold:location ?loBD } }
      optional { graph ?ac2 { ?c2 rdfs:label ?lbD } }
      bind(coalesce(?sdAD, ?sdBD) as ?sdD)
      filter(bound(?sdD))
      bind(coalesce(?edAD, ?edBD) as ?edD)
      bind(coalesce(str(?loAD), str(?loBD), \"\") as ?r2)
      bind(substr(str(?sdD), 1, 10) as ?dayD)
      bind(xsd:integer(substr(str(?sdD), 12, 2)) * 60 + xsd:integer(substr(str(?sdD), 15, 2)) as ?sminD)
      bind(coalesce(xsd:integer(substr(str(?edD), 12, 2)) * 60 + xsd:integer(substr(str(?edD), 15, 2)), ?sminD + 30) as ?eminD)
      bind(coalesce(str(?lbD), \"(untitled)\") as ?tlabelD) } }
              filter(str(?r2) <= str(?room))
            } group by ?room
          }
          {
            select ?day (min(?sminY) as ?dstart) where {
      graph npa:graph {
        ?npY npa:hasValidSignatureForPublicKeyHash ?pkY ;
          np:hasAssertion ?ay1 ; npx:introduces ?y1 .
        filter not exists { ?invY npx:invalidates ?npY ; npa:hasValidSignatureForPublicKeyHash ?pkY . }
        filter not exists { ?npY npx:hasNanopubType npx:ExampleNanopub . }
      }
      filter not exists { graph ?sgY { ?newerY npx:supersedes ?npY . } }
      values ?_event_multi_iri {}
      graph ?ay1 { ?y1 a wd:Q604733 ; dct:isPartOf ?_event_multi_iri . }
      optional { graph ?ay1 { ?y1 schema:startDate ?sdAY } }
      optional { graph ?ay1 { ?y1 schemaold:startDate ?sdBY } }
      optional { graph ?ay1 { ?y1 schema:endDate ?edAY } }
      optional { graph ?ay1 { ?y1 schemaold:endDate ?edBY } }
      optional { graph ?ay1 { ?y1 schema:location ?loAY } }
      optional { graph ?ay1 { ?y1 schemaold:location ?loBY } }
      optional { graph ?ay1 { ?y1 rdfs:label ?lbY } }
      bind(coalesce(?sdAY, ?sdBY) as ?sdY)
      filter(bound(?sdY))
      bind(coalesce(?edAY, ?edBY) as ?edY)
      bind(coalesce(str(?loAY), str(?loBY), \"\") as ?roomY)
      bind(substr(str(?sdY), 1, 10) as ?day)
      bind(xsd:integer(substr(str(?sdY), 12, 2)) * 60 + xsd:integer(substr(str(?sdY), 15, 2)) as ?sminY)
      bind(coalesce(xsd:integer(substr(str(?edY), 12, 2)) * 60 + xsd:integer(substr(str(?edY), 15, 2)), ?sminY + 30) as ?eminY)
      bind(coalesce(str(?lbY), \"(untitled)\") as ?tlabelY)
            } group by ?day
          }
          bind(56 + ?col * 258 as ?bx)
          bind(36 + (?smin - ?dstart + 15) * 3.0 as ?slotY)
          bind((?emin - ?smin) * 3.0 as ?slotH)
          bind(?slotY + (?rank - 1) * (?slotH / ?nslot) as ?by)
          bind(?slotH / ?nslot - 3 as ?bh)

      bind(replace(?tlabel, \"^(.{0,42})\\\\s.*$\", \"$1\") as ?l1)
      bind(if(strlen(?tlabel) > strlen(?l1), substr(?tlabel, strlen(?l1) + 2), \"\") as ?r1)
      bind(replace(?r1, \"^(.{0,42})\\\\s.*$\", \"$1\") as ?l2)
      bind(if(strlen(?r1) > strlen(?l2), substr(?r1, strlen(?l2) + 2), \"\") as ?r2)
      bind(if(strlen(?r2) > 42, concat(substr(?r2, 1, 41), \"\\u2026\"), ?r2) as ?l3)
          bind(if(strlen(?authors) > 44,
                  concat(replace(substr(?authors, 1, 44), \",[^,]*$\", \"\"), \" …\"),
                  ?authors) as ?authShort)
          bind(concat(
            '<a href=\"/part?id=', encode_for_uri(str(?pres)), '\">',
            '<rect x=\"', str(?bx), '\" y=\"', str(?by), '\" width=\"250\" height=\"', str(?bh),
              '\" rx=\"3\" fill=\"#eaf1f8\" stroke=\"#9bb4cc\"></rect>',
            '<text x=\"', str(?bx + 8), '\" y=\"', str(?by + 15), '\" font-size=\"9\" font-weight=\"bold\" fill=\"#33475b\">',
              replace(replace(replace(?authShort, \"&\", \"&amp;\"), \"<\", \"&lt;\"), \">\", \"&gt;\"), '</text>',
            '<text x=\"', str(?bx + 8), '\" y=\"', str(?by + 29), '\" font-size=\"10\" fill=\"#12263a\">',
              '<tspan x=\"', str(?bx + 8), '\" y=\"', str(?by + 29), '\">', replace(replace(replace(?l1, \"&\", \"&amp;\"), \"<\", \"&lt;\"), \">\", \"&gt;\"), '</tspan>',
              if(strlen(?l2) > 0, concat('<tspan x=\"', str(?bx + 8), '\" y=\"', str(?by + 41), '\">', replace(replace(replace(?l2, \"&\", \"&amp;\"), \"<\", \"&lt;\"), \">\", \"&gt;\"), '</tspan>'), ''),
              if(strlen(?l3) > 0, concat('<tspan x=\"', str(?bx + 8), '\" y=\"', str(?by + 53), '\">', replace(replace(replace(?l3, \"&\", \"&amp;\"), \"<\", \"&lt;\"), \">\", \"&gt;\"), '</tspan>'), ''),
            '</text></a>') as ?frag)
        }
      }
      union
      # ============ room headers ============
      {
        select ?day ?frag (0 as ?ybot) (?hx + 250 as ?xright)
        where {
          {
            select distinct ?day ?room where {
      graph npa:graph {
        ?npH npa:hasValidSignatureForPublicKeyHash ?pkH ;
          np:hasAssertion ?ah1 ; npx:introduces ?h1 .
        filter not exists { ?invH npx:invalidates ?npH ; npa:hasValidSignatureForPublicKeyHash ?pkH . }
        filter not exists { ?npH npx:hasNanopubType npx:ExampleNanopub . }
      }
      filter not exists { graph ?sgH { ?newerH npx:supersedes ?npH . } }
      values ?_event_multi_iri {}
      graph ?ah1 { ?h1 a wd:Q604733 ; dct:isPartOf ?_event_multi_iri . }
      optional { graph ?ah1 { ?h1 schema:startDate ?sdAH } }
      optional { graph ?ah1 { ?h1 schemaold:startDate ?sdBH } }
      optional { graph ?ah1 { ?h1 schema:endDate ?edAH } }
      optional { graph ?ah1 { ?h1 schemaold:endDate ?edBH } }
      optional { graph ?ah1 { ?h1 schema:location ?loAH } }
      optional { graph ?ah1 { ?h1 schemaold:location ?loBH } }
      optional { graph ?ah1 { ?h1 rdfs:label ?lbH } }
      bind(coalesce(?sdAH, ?sdBH) as ?sdH)
      filter(bound(?sdH))
      bind(coalesce(?edAH, ?edBH) as ?edH)
      bind(coalesce(str(?loAH), str(?loBH), \"\") as ?room)
      bind(substr(str(?sdH), 1, 10) as ?day)
      bind(xsd:integer(substr(str(?sdH), 12, 2)) * 60 + xsd:integer(substr(str(?sdH), 15, 2)) as ?sminH)
      bind(coalesce(xsd:integer(substr(str(?edH), 12, 2)) * 60 + xsd:integer(substr(str(?edH), 15, 2)), ?sminH + 30) as ?eminH)
      bind(coalesce(str(?lbH), \"(untitled)\") as ?tlabelH) }
          }
          {
            select ?room (count(distinct ?r3) - 1 as ?hcol) where {
              { select distinct ?room where {
      graph npa:graph {
        ?npE npa:hasValidSignatureForPublicKeyHash ?pkE ;
          np:hasAssertion ?ae1 ; npx:introduces ?e1 .
        filter not exists { ?invE npx:invalidates ?npE ; npa:hasValidSignatureForPublicKeyHash ?pkE . }
        filter not exists { ?npE npx:hasNanopubType npx:ExampleNanopub . }
      }
      filter not exists { graph ?sgE { ?newerE npx:supersedes ?npE . } }
      values ?_event_multi_iri {}
      graph ?ae1 { ?e1 a wd:Q604733 ; dct:isPartOf ?_event_multi_iri . }
      optional { graph ?ae1 { ?e1 schema:startDate ?sdAE } }
      optional { graph ?ae1 { ?e1 schemaold:startDate ?sdBE } }
      optional { graph ?ae1 { ?e1 schema:endDate ?edAE } }
      optional { graph ?ae1 { ?e1 schemaold:endDate ?edBE } }
      optional { graph ?ae1 { ?e1 schema:location ?loAE } }
      optional { graph ?ae1 { ?e1 schemaold:location ?loBE } }
      optional { graph ?ae1 { ?e1 rdfs:label ?lbE } }
      bind(coalesce(?sdAE, ?sdBE) as ?sdE)
      filter(bound(?sdE))
      bind(coalesce(?edAE, ?edBE) as ?edE)
      bind(coalesce(str(?loAE), str(?loBE), \"\") as ?room)
      bind(substr(str(?sdE), 1, 10) as ?dayE)
      bind(xsd:integer(substr(str(?sdE), 12, 2)) * 60 + xsd:integer(substr(str(?sdE), 15, 2)) as ?sminE)
      bind(coalesce(xsd:integer(substr(str(?edE), 12, 2)) * 60 + xsd:integer(substr(str(?edE), 15, 2)), ?sminE + 30) as ?eminE)
      bind(coalesce(str(?lbE), \"(untitled)\") as ?tlabelE) } }
              { select distinct ?r3 where {
      graph npa:graph {
        ?npF npa:hasValidSignatureForPublicKeyHash ?pkF ;
          np:hasAssertion ?ae2 ; npx:introduces ?e2 .
        filter not exists { ?invF npx:invalidates ?npF ; npa:hasValidSignatureForPublicKeyHash ?pkF . }
        filter not exists { ?npF npx:hasNanopubType npx:ExampleNanopub . }
      }
      filter not exists { graph ?sgF { ?newerF npx:supersedes ?npF . } }
      values ?_event_multi_iri {}
      graph ?ae2 { ?e2 a wd:Q604733 ; dct:isPartOf ?_event_multi_iri . }
      optional { graph ?ae2 { ?e2 schema:startDate ?sdAF } }
      optional { graph ?ae2 { ?e2 schemaold:startDate ?sdBF } }
      optional { graph ?ae2 { ?e2 schema:endDate ?edAF } }
      optional { graph ?ae2 { ?e2 schemaold:endDate ?edBF } }
      optional { graph ?ae2 { ?e2 schema:location ?loAF } }
      optional { graph ?ae2 { ?e2 schemaold:location ?loBF } }
      optional { graph ?ae2 { ?e2 rdfs:label ?lbF } }
      bind(coalesce(?sdAF, ?sdBF) as ?sdF)
      filter(bound(?sdF))
      bind(coalesce(?edAF, ?edBF) as ?edF)
      bind(coalesce(str(?loAF), str(?loBF), \"\") as ?r3)
      bind(substr(str(?sdF), 1, 10) as ?dayF)
      bind(xsd:integer(substr(str(?sdF), 12, 2)) * 60 + xsd:integer(substr(str(?sdF), 15, 2)) as ?sminF)
      bind(coalesce(xsd:integer(substr(str(?edF), 12, 2)) * 60 + xsd:integer(substr(str(?edF), 15, 2)), ?sminF + 30) as ?eminF)
      bind(coalesce(str(?lbF), \"(untitled)\") as ?tlabelF) } }
              filter(str(?r3) <= str(?room))
            } group by ?room
          }
          bind(56 + ?hcol * 258 as ?hx)
          bind(concat(
            '<rect x=\"', str(?hx), '\" y=\"6\" width=\"250\" height=\"24\" rx=\"3\" fill=\"#1d3d5c\"></rect>',
            '<text x=\"', str(?hx + 250 / 2), '\" y=\"22\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"bold\" fill=\"#ffffff\">',
              replace(replace(replace(?room, \"&\", \"&amp;\"), \"<\", \"&lt;\"), \">\", \"&gt;\"), '</text>') as ?frag)
        }
      }
      union
      # ============ hour labels on the left ============
      {
        select ?day ?frag (0 as ?ybot) (0 as ?xright)
        where {
          {
            select ?day (min(?smin) as ?first) (max(?emin) as ?last) where {
      graph npa:graph {
        ?npT npa:hasValidSignatureForPublicKeyHash ?pkT ;
          np:hasAssertion ?at1 ; npx:introduces ?t1 .
        filter not exists { ?invT npx:invalidates ?npT ; npa:hasValidSignatureForPublicKeyHash ?pkT . }
        filter not exists { ?npT npx:hasNanopubType npx:ExampleNanopub . }
      }
      filter not exists { graph ?sgT { ?newerT npx:supersedes ?npT . } }
      values ?_event_multi_iri {}
      graph ?at1 { ?t1 a wd:Q604733 ; dct:isPartOf ?_event_multi_iri . }
      optional { graph ?at1 { ?t1 schema:startDate ?sdAT } }
      optional { graph ?at1 { ?t1 schemaold:startDate ?sdBT } }
      optional { graph ?at1 { ?t1 schema:endDate ?edAT } }
      optional { graph ?at1 { ?t1 schemaold:endDate ?edBT } }
      optional { graph ?at1 { ?t1 schema:location ?loAT } }
      optional { graph ?at1 { ?t1 schemaold:location ?loBT } }
      optional { graph ?at1 { ?t1 rdfs:label ?lbT } }
      bind(coalesce(?sdAT, ?sdBT) as ?sdT)
      filter(bound(?sdT))
      bind(coalesce(?edAT, ?edBT) as ?edT)
      bind(coalesce(str(?loAT), str(?loBT), \"\") as ?roomT)
      bind(substr(str(?sdT), 1, 10) as ?day)
      bind(xsd:integer(substr(str(?sdT), 12, 2)) * 60 + xsd:integer(substr(str(?sdT), 15, 2)) as ?smin)
      bind(coalesce(xsd:integer(substr(str(?edT), 12, 2)) * 60 + xsd:integer(substr(str(?edT), 15, 2)), ?smin + 30) as ?emin)
      bind(coalesce(str(?lbT), \"(untitled)\") as ?tlabelT)
            } group by ?day
          }
          values ?hr { 8 9 10 11 12 13 14 15 16 17 18 19 20 }
          filter(?hr * 60 >= ?first - 60 && ?hr * 60 <= ?last + 60)
          bind(36 + (?hr * 60 - ?first + 15) * 3.0 as ?hy)
          bind(concat(
            '<text x=\"8\" y=\"', str(?hy + 4), '\" font-size=\"10\" fill=\"#6b7c8d\">',
              if(?hr < 10, concat(\"0\", str(?hr)), str(?hr)), ':00</text>',
            '<line x1=\"44\" y1=\"', str(?hy), '\" x2=\"52\" y2=\"', str(?hy),
              '\" stroke=\"#b9c6d2\"></line>') as ?frag)
        }
      }
    } group by ?day
  }
  bind(?day as ?title)
  bind(?maxx + 8 as ?w)
  bind(?maxy + 16 as ?h)
}
order by ?title""" .
}

sub:provenance {
  sub:assertion prov:wasAttributedTo orcid:0000-0002-1267-0234 .
}

sub:pubinfo {
  orcid:0000-0002-1267-0234 foaf:name "Tobias Kuhn" .
  
  this: dct:created "2026-08-28T16:10:41Z"^^xsd:dateTime;
    dct:creator orcid:0000-0002-1267-0234;
    dct:license <https://creativecommons.org/licenses/by/4.0/>;
    npx:embeds sub:get-presentations-grid-svg;
    rdfs:label "Get the presentation programme of an event as an SVG grid";
    nt:wasCreatedFromProvenanceTemplate <http://purl.org/np/RANwQa4ICWS5SOjw7gp99nBpXBasapwtZF1fIM3H2gYTM>;
    nt:wasCreatedFromPubinfoTemplate <https://w3id.org/np/RA-N4_kFxcruvBTlo1yJv29E4SLOXsx5KO_th69PprMrA>,
      <https://w3id.org/np/RACJ58Gvyn91LqCKIO9zu1eijDQIeEff28iyDrJgjSJF8>, <https://w3id.org/np/RARJj78P72NR5edKOnu_f4ePE9NYYuW2m2pM-fEoobMBk>;
    nt:wasCreatedFromTemplate <https://w3id.org/np/RAEFAt-QcFK0ZhqfvlsmS10BnzGJA0xwOICZXkO-ai87k> .
  
  sub:sig npx:hasAlgorithm "RSA";
    npx:hasPublicKey "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwUtewGCpT5vIfXYE1bmf/Uqu1ojqnWdYxv+ySO80ul8Gu7m8KoyPAwuvaPj0lvPtHrg000qMmkxzKhYknEjq8v7EerxZNYp5B3/3+5ZpuWOYAs78UnQVjbHSmDdmryr4D4VvvNIiUmd0yxci47dTFUj4DvfHnGd6hVe5+goqdcwIDAQAB";
    npx:hasSignature "THsJnxIQIPCICUQFjArbc9DzJAbDb9HrrkcJVMM6wVH0MbNIN/VZ76URXI2ZLcdN5d5ZiSv6COlM4DanelwlmcXrshEMK0mlHuDvODcsFmNHYnjkj+jMYkpO3SY23XPPPKj1AoWja1kOX1ZlRHVZslzK/LU1VaQI/Mb8wWfbWHU=";
    npx:hasSignatureTarget this:;
    npx:signedBy orcid:0000-0002-1267-0234 .
}