W3C

- DRAFT -

XML Processing Model WG

Meeting 223, 01/02 Nov 2012

Agenda

See also: IRC log

Attendees

Present
Henry, Norm, Jim, Liam (partial)
Regrets
Vojtech, Mohamed, Alex
Chair
Norm
Scribe
Jim (mostly) and Norm

Contents


01 Nov 2012

Accept this agenda?

-> http://www.w3.org/XML/XProc/2012/11/01-agenda

<jfuller> comments

<jfuller> http://lists.w3.org/Archives/Public/public-xml-processing-model-comments/2012Oct/0004.html

<jfuller> http://lists.w3.org/Archives/Public/public-xml-processing-model-comments/2012Oct/0006.html

Henry: We should try to talk about some design issues: binary data/resource manager; parameters

Accept minutes from the previous meeting?

-> http://www.w3.org/XML/XProc/2012/10/18-minutes

Accepted.

Next meeting: telcon 15 Nov

Accepted.

Parameters

-> http://lists.w3.org/Archives/Public/public-xml-processing-model-wg/2012Sep/0014.html

Random points of discussion:

Where do maps fit in the data model?

Having p:with-param that takes a context node and adding a function that can read a serialization of a map and produce a map is probably necessary

Henry: We could allow multiple with-params with the same name and that would allow you to have each parameter have its own line.

<ht> <p:with-param name="parameters" pname="foo" select="[xpath expression]"/>

<ht> would be an alternative to

Norm wonders if we really need to support the case where a pipeline can have *more than one* set of parameters.

scribe: Ostensibly its for the case where a pipeline has two XSLT steps and need two different sets of parameters.

<ht> <p:with-param name="parameters" select="merge-maps(map(('foo',[xpath expression])))"/>

We could do this:

<p:with-param group="parameters" name="foo" select="[expr]"/>

<p:with-param name="foo" select='[expr]'/>

Henry: That makes the 'name' of a p:with-param very different from the name on a p:with-option

We all agree that V.next will be XDM/XPath 2.0 based

Norm: step that computes hashes has parameters
... Lets investigate the notion of removing parameters alltogether and dig into allowing options with map type
... as an author, how do with options allow options defined in the pipeline automatically bind

Henry: we dont have to mandate it, make it flexible and default it
... the default option for option parameters are parameters -- {scribe - ummmmm }

Norm: exp shows that its not even in the 90% ?

Henry: making it a flag on option, allows u to do that, then having to say paramater option are ...
... at the commandline thats where magic should happen

Norm: this has the advantage of getting rid of params
... we need inherit=true .... the case is that the value is true today
... explaining how binding works/flows through to p:xslt

Henry: here is a v1 pipeline example with params, and here is v2 equiv
... if foo = type map there might be new syntax with option

http://www.w3.org/TR/xslt-30/#map

Norm: we dont need parameters
... talked ourselves around too ...

<Norm> we don't need p:parameters or p:with-param

Henry: xpath funcs that have signatures, you may get some value
... in v1 variables contain strings

Henry/Norm: we are not going to do that anymore

<Norm> ACTION: Norm to write up our revised parameter story [recorded in http://www.w3.org/2012/11/01-xproc-minutes.html#action01]

Norm: the focus for vnext is usability, I think we should consider some syntactic shortcut

<Norm> href= and data= on p:input (equivalent to a single nested p:document or p:data element)

<Norm> Maybe even inventing a syntax for port=

Henry: do you want do (Norm) articulate your concern about variables

Norm: I think its problematic that we require all variables to be at the top of a compound step
... encourage to use maps, if we should allow variables to occur in different places

<scribe> scribe: Liam has joined us

Henry: how do u get an output of step to a variable ?
... putting a group in provides a scope, only one set of rules required
... we would have to invent ... we could consider implicit p:group ...
... we tried hard to p:group transparent
... its not true that the step inside the group are siblings of the steps outside the group

Norm: we could ... in vnext, if p:variable does not read from a port....

Henry: that does not solve your use case
... one of the consequences of allowing this, there is an implicit sync point ... anyone who references that variable has to wait until the step is compelte

Norm: I now remember ...

(goes to the post board)

Image of pipeline with variables

Norm: (demonstrates issue with allowing variable decl in middle of pipeline)

Henry: to make that a syntactical valid pipeline, put a p:group around

Norm: the other topic is how to deal with binary

Alex thread - http://lists.w3.org/Archives/Public/public-xml-processing-model-wg/2012Oct/0006.html

Vojtech - http://lists.w3.org/Archives/Public/public-xml-processing-model-wg/2012Sep/0020.html

Vojtech xml prague paper - http://archive.xmlprague.cz/2012/presentations/XProc_Beyond_application_xml.pdf

<ht> http://lists.w3.org/Archives/Public/public-xml-processing-model-comments/2012Oct/0005.html

Jim: What do we mean by resource manager ? (1 hr ago)

Henry: our experience ... we had a resource manager which was an implementation detail, when any step involved invoking a URI it would check the resource manager if it had a cached copy
... it was more then that, it was typed

Hentry: notion of resource and processed resource, essentially data model instances

Henry: example, you could get the internal compiled form of the stylesheet .
... we would say 'no doc is ever fetched twice'
... global resource manager was higher scope then an individual pipeline instance, also had expiry checking
... resource managers could be chained ... it could look up the hierarchy
... all of that was an 'efficiency story' but we also used it for several other purposes
... I think that we used the resource manager to deal with document sets ... the step that produced them had to have a naming scheme, so needed prior knowledge, not ideal
... that required somewhere to put these things

Norm: my impl has a resource manager that basically does the same thing, any step that produces a document or that makes a request to the web to make a document
... you can satisfy the case where a doc uses xinclude

Liam: instace or sequence o xdm resources

Norm: my impl has xdm instances

Henry: the crucial aspect of what you just said, is that pipeline outputs can get stored in the resource manager ...
... at the extreme end, remember the orbean arch, where there is no notion of ports, no notion of connection ... all connectivity is via uri
... some uris are 'engine internal' ... thats how the topology of the pipeline gets built up
... what Alex proposal amounts too: we will stick that floats through the pipe is xml, resource manager will store the non xml ... definition of a handle

Norm: what do we want to do with a binary in a pipeline ?
... imagine a pipeline with digital signatures ...
... we could invent a p:serialise step ...
... steps that dont care about binary, dont care, steps that care about binaries need to interrogate resource manager
... p:store, p:http-request has to be smart enough
... it is attractive to do this w/o amending the xdm

Jim: +1

Henry: I do too

from Alex Muir http://lists.w3.org/Archives/Public/public-xml-processing-model-comments/2012Oct/0004.html

he asks if there could be more control over a potential resource manager, concerned about memory usage

he also proposes a simplification of parameters using resource manager (interesting, but we removed them)

Norm: if we decide to address binary using Resource manager, we may need to consider a p:resource-manager step which would allow config of resource manager

Philip Fennell email - http://lists.w3.org/Archives/Public/xproc-dev/2012Jan/0012.html

Henry: I am uncomfortable with using private uri scheme
... though its prob ok, they really have no meaning outside the pipeline

Norm: I dont think we have to say anything about the scheme

http://lists.w3.org/Archives/Public/xproc-dev/2012Jan/0012.html

Norm: I think we should attempt binary solution as provided by Alex
... c:data is the wrapper we use for base64 binary
... if you do an http-request when u get a text doc, u get a c:body element with encoding of base64 and the body contains base64 string directly

<Norm> http://tests.xproc.org/tests/required/http-request-004.xml

<Norm> Henry: We can ameliorate the backwards incopatibility with a p:base64-encode shim step

Henry: we are going to need some examples, signature example
... enc/dec steps ...

<Norm> We can also have a p:serialize step that puts a serialized representation in the cache

Henry: but not having a story about uris in resource manager, if we had a uri scheme for the resource manager entries then we would not need p:serialise to the cache because p:store would do the job

Norm: what p:store is impl defined
... maybe we overload p:store ... with no href attribute pushes to resource manager

Henry: that is fine, what I didnt want is to have significant decrease in all their pipelines

Norm: define a handle as c:result | c:data which has content-type and href attribute
... we can also preserve what we do with c:body
... there are only a few contexts where a binary handle is expected today

Jim: any xpath funcs we need to add ?

Norm: only one I can think of is p:content-type

Henry: how could u have a handle uri w/o having a handle element ?

Norm: having a func that gives back binary is not possible
... break for lunch and we come back and review v2 req docs

<Norm> Reconvened.

<Norm> Norm: Let's review the shorter requirements document: v

<Norm> http://www.w3.org/XML/XProc/docs/requirements-v2-jim.xml

Norm: we have a story for 4.1 and 4.2
... we all to drop 4.3 Compact Syntax
... we all agree on 4.4

Henry: we are counting on map

Norm: we cant be finished until XSLT 3.0 ?

http://lists.w3.org/Archives/Public/public-xml-processing-model-wg/2012Oct/0012.html

All: discussing Vojtech response ....

Norm: I would not want to change defaulting rules, at runtime only one of those steps would be selected
... special rules apply to p:when

Henry: I am fine with Vojtech option 1 and for the editor to try it on
... notice that the good thing about talking about it this way, every child of choose has the same arity of output port is now a theorem
... means for coherence, all of those alternatives have the same arity

Norm: choose is magic .. .static rule, all the when must have same arity of ports

Henry: if someone is statically checking a pipeline ... computing the dep graph,
... I need be able to operate the default primary input rules

Norm: default readable ports ... number of funky things .. number of special rules for p:choose et al

Henry: wrapper turned out easy to write

Norm: in the case of try/catch, plumb ports to group, if runs successfully ...

Henry: we need to put notes in the definitions of scoping and defaulting, related to when special rules apply to some compound steps

Jim: can we move on to reviewing 4.7 - step categories

Henry: reviewing previous minutes on the subject, what we do is akin to step registries
... we wasted a lot of time, in v1, talking about user defined compound steps
... vnext should be shorter as v1 spec
... all we do is establish a registry
... which registers a bunch of steps

<scribe> scribe: Liam has come back

Norm: we've gone meta meta until your head explodes !

Henry: the ITF works like this, establishing a registry and giving it an initial population
... you can add stuff, w/o having to change something normative

Norm: xpointer does things this way

Henry: the amount of scrutiny required would be minimal
... you raised indirectly, does it take a WG to register a step ?

Norm: if we are going to allow registries ... we allow everyone to allow their own steps in their own namespaces

Henry: do u think about publishing an API
... how do u get your step interoperably ?

Norm: I would rather avoid that
... the registry contains declaration of the step

Henry: to be a conformant processor that says, what the status of each step ?
... if we had done this, the v1.0 step is allowed in v2 ... all of them that has parameters will have to change
... every entry in a step registry, has to be version

Norm: lets assume no registry for v1.0 steps
... agrees that entry in the registry should be versioned ...

Henry: there is some versioning metadata

Jim: what are we getting

Norm: if we go this route, do we want to allow dynamic lookup
... the problem with saying 'you dont need decl' is that a processor that doesnt have decl cant do static checking

Henry: the real question is, w3c process going forward ... this will improve

Norm: who will this, in practice if we had v2 spec + notes

Henry: notes are not normative,
... public registry would be open
... registering something in the W3C namespace would require a recc ... which would be easy to go through recc process
... min could be for a single step,

Liam: I am going to disagree with Henry, if is a requirement of XProc then require a change there ...

Henry: the mechanism can be used in a lightweight way

Liam: you can go to PR and RECC

Henry: 2 drafts and a spec

Norm: delete 4.7
... if Alex comes back with set of categories and its a straightforward then all good

<Norm> allow href= and data= on p:input

<Norm> allow port= and step= on p:input

<Norm> make p:inline optional

<Norm> if port=x is specified and step= is not, then the implicit step is the step from which the default readable port would be read

<Norm> http://lists.w3.org/Archives/Public/public-xml-processing-model-comments/2012Oct/0002.html

<scribe> scribe: reviewing logging + debugging

<Norm> http://lists.w3.org/Archives/Public/public-xml-processing-model-comments/2012Oct/0004.html

Henry: there has been some work here, to allow ppl to provide hints to the processor

Norm: first section of this, we need to clarify our understanding
... in current spec, we say its an error with parameter input ports
... in the new regime, <p:option name="parameters" params="true"/>

Liam: this maybe related to XSLT tunnel parameters

Norm: pipeline the contains a declare-step, there is no way to know, there is a dam here where parameters dont go through

Henry: if person authors <x:y name="parameters"/> then we get a static error, which is ok
... what would the downside be, if current our tentative parameter design from the morning
... if the user puts nothing at all ...

Liam: its close to something I want, e.g. if I make a typo in a param name then I get no error,

Norm: but the xslt step will throw an error (I think)

Henry: I always have to go to xmlspec.xsl to find out the param for diff markup

Norm: if a declare-step has no options, then it has an anonymous p:option, that pass silently through
... first, a declare-step that does not declare any parameters gets an implicit an anonymous parameters
... steps inside a pipeline that have a paramater option that has no parameters, inherit from parent

Henry: we now need 2 examples, one explicit and one implicit
... all for it

scribe - Norm providing examples of v1.0 versus vnext

<examples xmlns:p="…" xmlns:c="…">

<p:pipeline>
  <p:xslt>
    <p:input port="stylesheet">
      <p:document href="docbook.xsl"/>
    </p:input>
  </p:xslt>
</p:pipeline>

<p:pipeline>
  <p:xslt>
    <p:input port="stylesheet" href="docbook.xsl"/>
  </p:xslt>
</p:pipeline>



<p:pipeline>
  <p:xslt>
    <p:input port="stylesheet">
      <p:document href="docbook.xsl"/>
    </p:input>
    <p:with-param name="page-size" select="'A4'"/>
    <p:input port="parameters"/>
  </p:xslt>
</p:pipeline>

<p:pipeline>
  <p:xslt>
    <p:input port="stylesheet" href="docbook.xsl"/>
    <p:with-param name="page-size" select="/config/page-size" as="xs:string"
                  step="configuration"/>
<!--
    <p:with-param name="page-size" select="/config/page-size" as="xs:string">
      <p:pipe step="configuration" port="result"/>
    </p:with-param>
    <p:with-param name="page-size" select="p:pipe('configuration','result')/config/page-size"
                  as="xs:string"/>
       - has to be static names
       - with-param still has a default binding
    <p:with-param name="page-size" select="'A4'"/>
-->
<!--
    <p:with-param name="page-size" select="(map:get($parameters, 'page-size'), 'A4')[1]"/>
    <p:with-param name="page-size" select="if map:contains($parameters, 'page-size')
                                           then map:get($parameters, 'page-size')
                                           else 'A4'"/>
    <p:with-option name="parameters" select="map{'page-size' := 'A4'}"/>
    <p:with-option name="parameters" select="map:new(($parameters, map{'page-size' := 'A4'}))"/>
-->
  </p:xslt>
</p:pipeline>



<p:declare-step name="main">
  <p:input port="source"/>
  <p:output port="source"/>
  <p:input port="myparams" kind="parameters"/>

  <p:xslt>
    <p:input port="stylesheet">
      <p:document href="docbook.xsl"/>
    </p:input>
    <p:input port="parameters">
      <p:pipe step="main" port="myparams"/>
    </p:input>
  </p:xslt>
</p:declare-step>

<p:declare-step name="main">
  <p:input port="source"/>
  <p:output port="source"/>
  <p:option name="myparams" parameters="true"/>

  <p:xslt>
    <p:input port="stylesheet" href="docbook.xsl"/>
    <p:with-option name="parameters" select="$myparams"/>
  </p:xslt>
</p:declare-step>



<p:declare-step name="main">
  <p:input port="source"/>
  <p:output port="source"/>
  <p:input port="parameters" kind="parameters" primary="true"/>
  <p:input port="optionalp" kind="parameters"/>

  <p:xslt>
    <p:input port="stylesheet">
      <p:document href="docbook.xsl"/>
    </p:input>
  </p:xslt>

  <p:xslt>
    <p:input port="stylesheet">
      <p:document href="docbook.xsl"/>
    </p:input>
    <p:input port="parameters">
      <p:pipe step="main" port="optionalp"/>
    </p:input>
  </p:xslt>
</p:declare-step>

<p:declare-step name="main">
  <p:input port="source"/>
  <p:output port="source"/>
  <p:option name="parameters" parameters="true"/>
  <p:option name="optionalp" parameters="true"/>

  <p:xslt>
    <p:input port="stylesheet" href="docbook.xsl"/>
    <!-- it is a static error to leave out the with-option below
         OR you get no parameters at all
    -->
    <p:with-option name="parameters" select="$parameters"/>

<!--
    <p:with-option name="parameters" select="()"/>
-->
  </p:xslt>

  <p:xslt>
    <p:input port="stylesheet" href="docbook.xsl"/>
    <p:with-option name="parameters" select="$optionalp"/>
  </p:xslt>
</p:declare-step>



<p:declare-step>
  <p:output port="result"/>

  <p:parameters name="params">
    <p:with-param port="parameters" name="input1" select="'value1'">
      <p:empty/>
    </p:with-param>
    <p:input port="parameters">
      <p:inline>
        <c:param-set>
          <c:param name="input1" value="value2"/>
          <c:param name="input2" value="value1"/>
        </c:param-set>
      </p:inline>
    </p:input>
    <p:with-param port="parameters" name="param1" select="'value1'">
      <p:empty/>
    </p:with-param>
    <p:with-param port="parameters" name="input2" select="'value2'">
      <p:empty/>
    </p:with-param>
  </p:parameters>

  <p:identity name="pick1">
    <p:input port="source" select="/c:param-set/c:param[@name='input1']">
      <p:pipe step="params" port="result"/>
    </p:input>
  </p:identity>

  <p:identity name="pick2">
    <p:input port="source" select="/c:param-set/c:param[@name='input2']">
      <p:pipe step="params" port="result"/>
    </p:input>
  </p:identity>

  <p:identity name="pick3">
    <p:input port="source" select="/c:param-set/c:param[@name='param1']">
      <p:pipe step="params" port="result"/>
    </p:input>
  </p:identity>

  <p:wrap-sequence wrapper="c:param-set">
    <p:input port="source">
      <p:pipe step="pick1" port="result"/>
      <p:pipe step="pick2" port="result"/>
      <p:pipe step="pick3" port="result"/>
    </p:input>
  </p:wrap-sequence>
</p:declare-step>

<p:declare-step>
  <p:output port="result"/>

  <p:parameters name="params1">
    <p:with-option name="parameters" select="map{'input1' := 'value1'}"/>
  </p:parameters>

  <p:parameters name="params2">
    <p:input port="parameters">
      <p:inline>
        <c:param-set>
          <c:param name="input1" value="value2"/>
          <c:param name="input2" value="value1"/>
        </c:param-set>
      </p:inline>
    </p:input>
  </p:parameters>

  <p:parameters name="params3">
    <p:with-param name="param1" select='value2'"/>
    <p:with-param name="input2" select="'value2'"/>
  </p:parameters>

  <p:parameters name="params">
    <p:input port="parameters">
      <p:pipe step="params1" port="result"/>
      <p:pipe step="params2" port="result"/>
      <p:pipe step="params3" port="result"/>
    </p:input>
  </p:parameters>

  <p:identity name="pick1">
    <p:input port="source" select="/c:param-set/c:param[@name='input1']">
      <p:pipe step="params" port="result"/>
    </p:input>
  </p:identity>

  <p:identity name="pick2">
    <p:input port="source" select="/c:param-set/c:param[@name='input2']">
      <p:pipe step="params" port="result"/>
    </p:input>
  </p:identity>

  <p:identity name="pick3">
    <p:input port="source" select="/c:param-set/c:param[@name='param1']">
      <p:pipe step="params" port="result"/>
    </p:input>
  </p:identity>

  <p:wrap-sequence wrapper="c:param-set">
    <p:input port="source">
      <p:pipe step="pick1" port="result"/>
      <p:pipe step="pick2" port="result"/>
      <p:pipe step="pick3" port="result"/>
    </p:input>
  </p:wrap-sequence>
</p:declare-step>



<p:declare-step version="1.0" name="main">
  <p:input port="source"/>
  <p:output port="result"/>

  <p:parameters name="params">
    <p:input port="parameters">
      <p:inline>
        <c:param-set>
          <c:param name="param1" value="value1"/>
          <c:param name="param2" namespace="http://www.example.com"
                   value="value2"/>
          <c:param name="param1" value="valueX"/>
        </c:param-set>
      </p:inline>
    </p:input>
  </p:parameters>

  <p:identity name="pick1">
    <p:input port="source" select="/c:param-set/c:param[@name='param1']">
      <p:pipe step="params" port="result"/>
    </p:input>
  </p:identity>

  <p:identity name="pick2">
    <p:input port="source" select="/c:param-set/c:param[@name='param2']">
      <p:pipe step="params" port="result"/>
    </p:input>
  </p:identity>

  <p:wrap-sequence wrapper="c:param-set">
    <p:input port="source">
      <p:pipe step="pick1" port="result"/>
      <p:pipe step="pick2" port="result"/>
    </p:input>
  </p:wrap-sequence>
</p:declare-step>

<p:declare-step version="1.0" name="main">
  <p:input port="source"/>
  <p:output port="result"/>

  <p:parameters name="params">
    <p:input port="parameters">
      <c:param-set>
        <c:param name="param1" value="value1"/>
        <c:param name="param2" namespace="http://www.example.com"
                 value="value2"/>
        <c:param name="param1" value="valueX"/>
      </c:param-set>
    </p:input>
  </p:parameters>

  <p:identity name="pick1">
    <p:input port="source" select="/c:param-set/c:param[@name='param1']">
      <p:pipe step="params" port="result"/>
    </p:input>
  </p:identity>

  <p:identity name="pick2">
    <p:input port="source" select="/c:param-set/c:param[@name='param2']">
      <p:pipe step="params" port="result"/>
    </p:input>
  </p:identity>

  <p:wrap-sequence wrapper="c:param-set">
    <p:input port="source">
      <p:pipe step="pick1" port="result"/>
      <p:pipe step="pick2" port="result"/>
    </p:input>
  </p:wrap-sequence>
</p:declare-step>

</examples>

scribe- after much discussion

Liam: (proposed some syntax) with p:step() as xpath extension function

Norm: I would not be able to do static analysis
... one other bit of syntax, add step attribute to p:with-option, p:with-param
... we have to decide context for AVT, perhaps there are 2 approaches, empty or default readable port

Henry: (explains avt as true shortcut)

02 Nov 2012

Test suite

Jim: Wrt to categorizing the 1.0 solutions, do we want to look at deficiencies in the test suite?
... And do we need new tests for V.next

Norm: We'll certainly need new tests
... Converting all the current tests to V.next

Henry: We added a version and an edition attribute to the metadata and made that be a space-separated list of identifiers
... So you can have a test that works under multiple versions and the harness takes a version number.

Some discussion of the nature of the XML Schema tests.

Jim: Are we going to propose a different mount point in the repo?

Norm: I think I'm going to suggest doing the version number thing so that we have one test to correct if there are ambiguities

-> http://tests.xproc.org/testsuite/coverage.html

Jim: For steps in general, we seem to have good coverage, but perhaps not in errors and negative tests.
... What about error codes for V.next?

Norm: I think we just invent new ones if we don't have good values

Jim: How do we get the tests?

Norm: Implementors wrote most of the tests.

Henry: Is there a schema? Can we ask users to write tests that conform to the schema?

Norm: Yes, and there are docs, though I should review them; there was some drift.
... We can turn use cases from the requirements document into tests pretty easily, I hope

Review of the comments list

-> http://lists.w3.org/Archives/Public/public-xml-processing-model-comments/2012Jul/thread.html

-> http://lists.w3.org/Archives/Public/public-xml-processing-model-comments/2012Jul/0003.html

Henry: We're going to have to revisit this in the context of our ideas about compound-step and containers; we should consider these comments in the course of that work.

Norm: Makes sense to me.

-> http://lists.w3.org/Archives/Public/public-xml-processing-model-comments/2012Jul/0004.html

Editorial

Jim proposed errata:

-> http://lists.w3.org/Archives/Public/public-xml-processing-model-comments/2012Oct/0000.html

Henry: It's easy to be confused by this.

-> http://tests.xproc.org/tests/required/err-s0018-002.xml

Norm: Tim's right.

->http://www.w3.org/TR/xslt20/#dt-pattern

Norm: Possibly an erratum since it should be an error
... You'd have to do static analysis of every XPath expression to compute the dependency graph and in the case of collection($foo), it wouldn't be possible.

<scribe> ACTION: Norm to put document metadata on a future agenda

-> http://lists.w3.org/Archives/Public/xproc-dev/2012Jan/0011.html

Summary of Action Items

[NEW] ACTION: Norm to write up our revised parameter story
 
[NEW] ACTION: Norm to put document metadata on a future agenda
[End of minutes]

Minutes formatted by David Booth's scribe.perl version 1.137 (CVS log)
$Date: 2012-11-27 22:57:33 $