emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* TODO dependencies
@ 2007-10-19  6:27 Carsten Dominik
  2007-10-19  6:35 ` Rainer Stengele
  2008-01-21 14:43 ` Carsten Dominik
  0 siblings, 2 replies; 7+ messages in thread
From: Carsten Dominik @ 2007-10-19  6:27 UTC (permalink / raw)
  To: org-mode mailing list

On Oct 11, 2007, at 16:46, Carsten Dominik wrote:

> - concerning the TRIGGER proposal by John, and the TRIGGER/BLOCKER 
> functionality
>   discussed later:  In Emacs terms, this seems to translate into a 
> *hook*
>   that is called at the right moment.  I'd say that a single hook is 
> enough.
>   The right moment to call it would be when Org-mode has figured out 
> everything
>   about a change that is about to occur, but before actually doing it.
>   We can be general what kind of change this could be, a TODO state 
> change,
>   adding a tag, setting a property, changing the priority, anything 
> really.

>   So we would have a property that contains a Lisp form, and that lisp 
> form would
>   be evaluated at that moment.
>   TRIGGER would then mean to perform actions in other entries.
>   BLOCKER would mean to query other entries for information, and, if 
> necessary,
>   abort the current action, for example by throwing to a specified 
> catch form.
>   Obviously, if you nee both triggers and blockers, the blockers need 
> to run
>   first, but we don't need separate properties/functions for this.
>
>   The detailed implementation would then be a number of Lisp functions 
> that
>   take as arguments a *single* structure that contains all the info of 
> the change,
>   for example a property list like
>
>       (list :type 'TODOSTATE :from nil %to "INPROGRESS" ....

Due to the controversial nature of the discussion on this subject,
it seems to be better, for the time being, to keep this functionality
outside the core of org-mode.  Other reasons for this are that the
free-form nature of Org-mode files do make it non-trivial to implement
dependencies in a bullet-proof way.

I will actually take still another step back from the proposals we
discussed:  I'd like to not even fix the properties that should be
used for dependencies.

Instead, I am proposing and starting up the following route:

Org-mode version 5.13 contains two new hooks, `org-blocker-hook' and
`org-trigger-hook'.  These hooks are called before and after a state
change, respectively.  Currently only TODO state changes will do
this, but more could be added in the future.

The blocker hook is able to block a state change, the trigger
hook just happens after the change.  This is all that will go into
the core for now.

While this may seem little, it actually opens the dore wide for
a number of dependency extensions to be written, with free
choice of properties to be used and the "language" applied in
these properties to describe dependencies.  In this way
we can have different implementations working alongside without
conflicts.

As a proof of concept, I am providing a small file org-depend.el.
This is not meant as a definition of how things should be, but
as an inspiration to people who want to try their teeth at this.

Nevertheless, this small set of functions already does most of
what at least some of you have been asking for:  It introduces
the concept of chaining a sequence of TODO entries together by
insinuating only the first entry in the chain.
It also allows for entries to be identified by an :ID: property,
and this property to be used to trigger or be blocked by entries
in arbitrary places in the current file.  So I hope it will be a
good starting point, I have tried to comment it well enough
so that hacking should be easy.

Here is a copy of the documentation from that file.  The file
itself is available at http://orgmode.el/org-depend.el.

- Carsten

---8><--------------------------------------------------------><8------

WARNING: This file is just a PROOF OF CONCEPT, not a supported part
          of Org-mode.

This is an example implementation of TODO dependencies in Org-mode.
It uses the new hooks in version 5.13 of Org-mode,
`org-trigger-hook' and `org-blocker-hook'.

It implements the following:

Triggering
----------

1) If an entry contains a TRIGGER property that contains the word
    "chain-siblings", then switching that entry to DONE does the
    following:
    - The sibling following this entry is marked DONE.
    - The sibling also get the "chain-sibling" property, to make
      sure that, when *it* is DONE, the chain will continue.
2) If the TRIGGER property contains any other words, these are
    treated as entry id's.  That means, Org-mode will search for an
    entry with the ID property exactly equal to this word, and
    switch that entry to TODO as well.

Blocking
--------
1) If an entry contains a BLOCKER property that contains the word
    "previous-sibling", the sibling above the current entry is
    checked.  If it is still in a TODO state, the current state
    change is blocked.
2) If the BLOCKER property contains any other words, these are
    treated as entry id's.  That means, Org-mode will search for an
    entry with the ID property exactly equal to this word, and make
    sure that this entry is done as well, before allowing the state
    change to occur.

Example:
--------

When trying this example, make sure that the settings for TODO keywords
have been activated, i.e. include the following line and press C-c C-c
on the line before working with the example:

* TODO Win a million in Las Vegas
   The "third" TODO (see above) cannot become a TODO without this money.

   :PROPERTIES:
     :ID: I-cannot-do-it-without-money
   :END:

* Do this by doing a chain of TODO's
** TODO This is the first in this chain
    :PROPERTIES:
      :TRIGGER: chain-siblings
    :END:

** This is the second in this chain

** This is the third in this chain
    :PROPERTIES:
      :BLOCKER: I-cannot-do-it-without-money
    :END:

** This is the forth in this chain
    When this is DONE, we will also trigger entry XYZ-is-my-id
   :PROPERTIES:
     :TRIGGER: XYZ-is-my-id
   :END:

** This is the fifth in this chain

* Write report
   :PROPERTIES:
     :ID: XYZ-is-my-id
   :END:

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: TODO dependencies
  2007-10-19  6:27 TODO dependencies Carsten Dominik
@ 2007-10-19  6:35 ` Rainer Stengele
  2008-01-21 14:43 ` Carsten Dominik
  1 sibling, 0 replies; 7+ messages in thread
From: Rainer Stengele @ 2007-10-19  6:35 UTC (permalink / raw)
  To: emacs-orgmode

Carsten Dominik schrieb:
> On Oct 11, 2007, at 16:46, Carsten Dominik wrote:
> 
>> - concerning the TRIGGER proposal by John, and the TRIGGER/BLOCKER
>> functionality
>>   discussed later:  In Emacs terms, this seems to translate into a *hook*
>>   that is called at the right moment.  I'd say that a single hook is
>> enough.
>>   The right moment to call it would be when Org-mode has figured out
>> everything
>>   about a change that is about to occur, but before actually doing it.
>>   We can be general what kind of change this could be, a TODO state
>> change,
>>   adding a tag, setting a property, changing the priority, anything
>> really.
> 
>>   So we would have a property that contains a Lisp form, and that lisp
>> form would
>>   be evaluated at that moment.
>>   TRIGGER would then mean to perform actions in other entries.
>>   BLOCKER would mean to query other entries for information, and, if
>> necessary,
>>   abort the current action, for example by throwing to a specified
>> catch form.
>>   Obviously, if you nee both triggers and blockers, the blockers need
>> to run
>>   first, but we don't need separate properties/functions for this.
>>
>>   The detailed implementation would then be a number of Lisp functions
>> that
>>   take as arguments a *single* structure that contains all the info of
>> the change,
>>   for example a property list like
>>
>>       (list :type 'TODOSTATE :from nil %to "INPROGRESS" ....
> 
> Due to the controversial nature of the discussion on this subject,
> it seems to be better, for the time being, to keep this functionality
> outside the core of org-mode.  Other reasons for this are that the
> free-form nature of Org-mode files do make it non-trivial to implement
> dependencies in a bullet-proof way.
> 
> I will actually take still another step back from the proposals we
> discussed:  I'd like to not even fix the properties that should be
> used for dependencies.
> 
> Instead, I am proposing and starting up the following route:
> 
> Org-mode version 5.13 contains two new hooks, `org-blocker-hook' and
> `org-trigger-hook'.  These hooks are called before and after a state
> change, respectively.  Currently only TODO state changes will do
> this, but more could be added in the future.
> 
> The blocker hook is able to block a state change, the trigger
> hook just happens after the change.  This is all that will go into
> the core for now.
> 
> While this may seem little, it actually opens the dore wide for
> a number of dependency extensions to be written, with free
> choice of properties to be used and the "language" applied in
> these properties to describe dependencies.  In this way
> we can have different implementations working alongside without
> conflicts.
> 
> As a proof of concept, I am providing a small file org-depend.el.
> This is not meant as a definition of how things should be, but
> as an inspiration to people who want to try their teeth at this.
> 
> Nevertheless, this small set of functions already does most of
> what at least some of you have been asking for:  It introduces
> the concept of chaining a sequence of TODO entries together by
> insinuating only the first entry in the chain.
> It also allows for entries to be identified by an :ID: property,
> and this property to be used to trigger or be blocked by entries
> in arbitrary places in the current file.  So I hope it will be a
> good starting point, I have tried to comment it well enough
> so that hacking should be easy.
> 
> Here is a copy of the documentation from that file.  The file
> itself is available at http://orgmode.el/org-depend.el.
> 
> - Carsten
> 
> ---8><--------------------------------------------------------><8------
> 
> WARNING: This file is just a PROOF OF CONCEPT, not a supported part
>          of Org-mode.
> 
> This is an example implementation of TODO dependencies in Org-mode.
> It uses the new hooks in version 5.13 of Org-mode,
> `org-trigger-hook' and `org-blocker-hook'.
> 
> It implements the following:
> 
> Triggering
> ----------
> 
> 1) If an entry contains a TRIGGER property that contains the word
>    "chain-siblings", then switching that entry to DONE does the
>    following:
>    - The sibling following this entry is marked DONE.
>    - The sibling also get the "chain-sibling" property, to make
>      sure that, when *it* is DONE, the chain will continue.
> 2) If the TRIGGER property contains any other words, these are
>    treated as entry id's.  That means, Org-mode will search for an
>    entry with the ID property exactly equal to this word, and
>    switch that entry to TODO as well.
> 
> Blocking
> --------
> 1) If an entry contains a BLOCKER property that contains the word
>    "previous-sibling", the sibling above the current entry is
>    checked.  If it is still in a TODO state, the current state
>    change is blocked.
> 2) If the BLOCKER property contains any other words, these are
>    treated as entry id's.  That means, Org-mode will search for an
>    entry with the ID property exactly equal to this word, and make
>    sure that this entry is done as well, before allowing the state
>    change to occur.
> 
> Example:
> --------
> 
> When trying this example, make sure that the settings for TODO keywords
> have been activated, i.e. include the following line and press C-c C-c
> on the line before working with the example:
> 
> * TODO Win a million in Las Vegas
>   The "third" TODO (see above) cannot become a TODO without this money.
> 
>   :PROPERTIES:
>     :ID: I-cannot-do-it-without-money
>   :END:
> 
> * Do this by doing a chain of TODO's
> ** TODO This is the first in this chain
>    :PROPERTIES:
>      :TRIGGER: chain-siblings
>    :END:
> 
> ** This is the second in this chain
> 
> ** This is the third in this chain
>    :PROPERTIES:
>      :BLOCKER: I-cannot-do-it-without-money
>    :END:
> 
> ** This is the forth in this chain
>    When this is DONE, we will also trigger entry XYZ-is-my-id
>   :PROPERTIES:
>     :TRIGGER: XYZ-is-my-id
>   :END:
> 
> ** This is the fifth in this chain
> 
> * Write report
>   :PROPERTIES:
>     :ID: XYZ-is-my-id
>   :END:
> 
> 
> 
> _______________________________________________
> Emacs-orgmode mailing list
> Remember: use `Reply All' to send replies to the list.
> Emacs-orgmode@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode
> 

should say


http://orgmode.org/org-depend.el

instead of

http://orgmode.el/org-depend.el


rainer

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: TODO dependencies
  2007-10-19  6:27 TODO dependencies Carsten Dominik
  2007-10-19  6:35 ` Rainer Stengele
@ 2008-01-21 14:43 ` Carsten Dominik
  2008-01-21 17:43   ` Adam Spiers
  1 sibling, 1 reply; 7+ messages in thread
From: Carsten Dominik @ 2008-01-21 14:43 UTC (permalink / raw)
  To: Carsten Dominik; +Cc: org-mode mailing list

Hi

I am curious why I never got any feedback on this implementation
of task dependencies.  Did people overlook this?  Or is the need
for dependencies not as pressing as some of you thought?

- Carsten

On Oct 19, 2007, at 8:27 AM, Carsten Dominik wrote:

> On Oct 11, 2007, at 16:46, Carsten Dominik wrote:
>
>> - concerning the TRIGGER proposal by John, and the TRIGGER/BLOCKER  
>> functionality
>>  discussed later:  In Emacs terms, this seems to translate into a  
>> *hook*
>>  that is called at the right moment.  I'd say that a single hook is  
>> enough.
>>  The right moment to call it would be when Org-mode has figured out  
>> everything
>>  about a change that is about to occur, but before actually doing it.
>>  We can be general what kind of change this could be, a TODO state  
>> change,
>>  adding a tag, setting a property, changing the priority, anything  
>> really.
>
>>  So we would have a property that contains a Lisp form, and that  
>> lisp form would
>>  be evaluated at that moment.
>>  TRIGGER would then mean to perform actions in other entries.
>>  BLOCKER would mean to query other entries for information, and, if  
>> necessary,
>>  abort the current action, for example by throwing to a specified  
>> catch form.
>>  Obviously, if you nee both triggers and blockers, the blockers  
>> need to run
>>  first, but we don't need separate properties/functions for this.
>>
>>  The detailed implementation would then be a number of Lisp  
>> functions that
>>  take as arguments a *single* structure that contains all the info  
>> of the change,
>>  for example a property list like
>>
>>      (list :type 'TODOSTATE :from nil %to "INPROGRESS" ....
>
> Due to the controversial nature of the discussion on this subject,
> it seems to be better, for the time being, to keep this functionality
> outside the core of org-mode.  Other reasons for this are that the
> free-form nature of Org-mode files do make it non-trivial to implement
> dependencies in a bullet-proof way.
>
> I will actually take still another step back from the proposals we
> discussed:  I'd like to not even fix the properties that should be
> used for dependencies.
>
> Instead, I am proposing and starting up the following route:
>
> Org-mode version 5.13 contains two new hooks, `org-blocker-hook' and
> `org-trigger-hook'.  These hooks are called before and after a state
> change, respectively.  Currently only TODO state changes will do
> this, but more could be added in the future.
>
> The blocker hook is able to block a state change, the trigger
> hook just happens after the change.  This is all that will go into
> the core for now.
>
> While this may seem little, it actually opens the dore wide for
> a number of dependency extensions to be written, with free
> choice of properties to be used and the "language" applied in
> these properties to describe dependencies.  In this way
> we can have different implementations working alongside without
> conflicts.
>
> As a proof of concept, I am providing a small file org-depend.el.
> This is not meant as a definition of how things should be, but
> as an inspiration to people who want to try their teeth at this.
>
> Nevertheless, this small set of functions already does most of
> what at least some of you have been asking for:  It introduces
> the concept of chaining a sequence of TODO entries together by
> insinuating only the first entry in the chain.
> It also allows for entries to be identified by an :ID: property,
> and this property to be used to trigger or be blocked by entries
> in arbitrary places in the current file.  So I hope it will be a
> good starting point, I have tried to comment it well enough
> so that hacking should be easy.
>
> Here is a copy of the documentation from that file.  The file
> itself is available at http://orgmode.el/org-depend.el.
>
> - Carsten
>
> ---8><-------------------------------------------------------- 
> ><8------
>
> WARNING: This file is just a PROOF OF CONCEPT, not a supported part
>         of Org-mode.
>
> This is an example implementation of TODO dependencies in Org-mode.
> It uses the new hooks in version 5.13 of Org-mode,
> `org-trigger-hook' and `org-blocker-hook'.
>
> It implements the following:
>
> Triggering
> ----------
>
> 1) If an entry contains a TRIGGER property that contains the word
>   "chain-siblings", then switching that entry to DONE does the
>   following:
>   - The sibling following this entry is marked DONE.
>   - The sibling also get the "chain-sibling" property, to make
>     sure that, when *it* is DONE, the chain will continue.
> 2) If the TRIGGER property contains any other words, these are
>   treated as entry id's.  That means, Org-mode will search for an
>   entry with the ID property exactly equal to this word, and
>   switch that entry to TODO as well.
>
> Blocking
> --------
> 1) If an entry contains a BLOCKER property that contains the word
>   "previous-sibling", the sibling above the current entry is
>   checked.  If it is still in a TODO state, the current state
>   change is blocked.
> 2) If the BLOCKER property contains any other words, these are
>   treated as entry id's.  That means, Org-mode will search for an
>   entry with the ID property exactly equal to this word, and make
>   sure that this entry is done as well, before allowing the state
>   change to occur.
>
> Example:
> --------
>
> When trying this example, make sure that the settings for TODO  
> keywords
> have been activated, i.e. include the following line and press C-c C-c
> on the line before working with the example:
>
> * TODO Win a million in Las Vegas
>  The "third" TODO (see above) cannot become a TODO without this money.
>
>  :PROPERTIES:
>    :ID: I-cannot-do-it-without-money
>  :END:
>
> * Do this by doing a chain of TODO's
> ** TODO This is the first in this chain
>   :PROPERTIES:
>     :TRIGGER: chain-siblings
>   :END:
>
> ** This is the second in this chain
>
> ** This is the third in this chain
>   :PROPERTIES:
>     :BLOCKER: I-cannot-do-it-without-money
>   :END:
>
> ** This is the forth in this chain
>   When this is DONE, we will also trigger entry XYZ-is-my-id
>  :PROPERTIES:
>    :TRIGGER: XYZ-is-my-id
>  :END:
>
> ** This is the fifth in this chain
>
> * Write report
>  :PROPERTIES:
>    :ID: XYZ-is-my-id
>  :END:
>
>
>
> _______________________________________________
> Emacs-orgmode mailing list
> Remember: use `Reply All' to send replies to the list.
> Emacs-orgmode@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: TODO dependencies
  2008-01-21 14:43 ` Carsten Dominik
@ 2008-01-21 17:43   ` Adam Spiers
  2008-01-21 19:10     ` Carsten Dominik
  0 siblings, 1 reply; 7+ messages in thread
From: Adam Spiers @ 2008-01-21 17:43 UTC (permalink / raw)
  To: emacs-orgmode

On Mon, Jan 21, 2008 at 03:43:18PM +0100, Carsten Dominik wrote:
> Hi
> 
> I am curious why I never got any feedback on this implementation
> of task dependencies.  Did people overlook this?  Or is the need
> for dependencies not as pressing as some of you thought?

I guess maybe not.  Or maybe we all have an entry in our TODO lists

** BLOCKED implement automatic unblocking upon dependency completion
*** DONE read Carsten's reply

;-)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: TODO dependencies
  2008-01-21 17:43   ` Adam Spiers
@ 2008-01-21 19:10     ` Carsten Dominik
  0 siblings, 0 replies; 7+ messages in thread
From: Carsten Dominik @ 2008-01-21 19:10 UTC (permalink / raw)
  To: Adam Spiers; +Cc: emacs-orgmode


On Jan 21, 2008, at 6:43 PM, Adam Spiers wrote:

> On Mon, Jan 21, 2008 at 03:43:18PM +0100, Carsten Dominik wrote:
>> Hi
>>
>> I am curious why I never got any feedback on this implementation
>> of task dependencies.  Did people overlook this?  Or is the need
>> for dependencies not as pressing as some of you thought?
>
> I guess maybe not.  Or maybe we all have an entry in our TODO lists
>
> ** BLOCKED implement automatic unblocking upon dependency completion
> *** DONE read Carsten's reply

LoL!

- Carsten

^ permalink raw reply	[flat|nested] 7+ messages in thread

* TODO dependencies
@ 2008-01-25 15:45 Stuart McLean
  2008-01-25 16:11 ` Hugo Schmitt
  0 siblings, 1 reply; 7+ messages in thread
From: Stuart McLean @ 2008-01-25 15:45 UTC (permalink / raw)
  To: emacs-orgmode

Hi,

Sorry if I have started a new thread on this subject, GMail and I are
not getting along right now.

** TODO a main project
*** TODO step 1
*** TODO step 2
*** TODO step 3
**** TODO step 3 part a
**** TODO step 3 part b
**** TODO step 3 part c
and so on
*** TODO step 4

Here is the functionality that I would like, and (as I see it) that
would be possible with the hooks provided and extensions that the user
could write...

marking ** TODO a main project
as DONE would mark all subheadings done (say you did them all at once)

marking *** TODO step 1
as DONE would mark this item as done and no more, and so on for step two.

marking step three as DONE would mark step three and all children (a,
b, c) as done, again, say you did them all at once. However, if you
marked step 3, part a as DONE, then b (at a later time), then c, only
triggering "c" would mark *** TODO step 3 as DONE as well.

In other words marking a heading as DONE will mark all children as
DONE, marking children as DONE one-by-one will only mark the parent as
DONE when all the children are marked DONE.

Is this a correct understanding?

This is (one of the functionalities) I would like. Maybe it is already
possible, or I have misread something?

Thanks again for org-mode, *fantastic software*

Stuart

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: TODO dependencies
  2008-01-25 15:45 Stuart McLean
@ 2008-01-25 16:11 ` Hugo Schmitt
  0 siblings, 0 replies; 7+ messages in thread
From: Hugo Schmitt @ 2008-01-25 16:11 UTC (permalink / raw)
  To: Stuart McLean; +Cc: emacs-orgmode


[-- Attachment #1.1: Type: text/plain, Size: 1736 bytes --]

And the parent could also support the [%] notation that exists for
checkboxes :)

-Hugo

On Jan 25, 2008 12:45 PM, Stuart McLean <makhector@gmail.com> wrote:

> Hi,
>
> Sorry if I have started a new thread on this subject, GMail and I are
> not getting along right now.
>
> ** TODO a main project
> *** TODO step 1
> *** TODO step 2
> *** TODO step 3
> **** TODO step 3 part a
> **** TODO step 3 part b
> **** TODO step 3 part c
> and so on
> *** TODO step 4
>
> Here is the functionality that I would like, and (as I see it) that
> would be possible with the hooks provided and extensions that the user
> could write...
>
> marking ** TODO a main project
> as DONE would mark all subheadings done (say you did them all at once)
>
> marking *** TODO step 1
> as DONE would mark this item as done and no more, and so on for step two.
>
> marking step three as DONE would mark step three and all children (a,
> b, c) as done, again, say you did them all at once. However, if you
> marked step 3, part a as DONE, then b (at a later time), then c, only
> triggering "c" would mark *** TODO step 3 as DONE as well.
>
> In other words marking a heading as DONE will mark all children as
> DONE, marking children as DONE one-by-one will only mark the parent as
> DONE when all the children are marked DONE.
>
> Is this a correct understanding?
>
> This is (one of the functionalities) I would like. Maybe it is already
> possible, or I have misread something?
>
> Thanks again for org-mode, *fantastic software*
>
> Stuart
>
>
> _______________________________________________
> Emacs-orgmode mailing list
> Remember: use `Reply All' to send replies to the list.
> Emacs-orgmode@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode
>

[-- Attachment #1.2: Type: text/html, Size: 2183 bytes --]

[-- Attachment #2: Type: text/plain, Size: 204 bytes --]

_______________________________________________
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2008-01-25 16:11 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-10-19  6:27 TODO dependencies Carsten Dominik
2007-10-19  6:35 ` Rainer Stengele
2008-01-21 14:43 ` Carsten Dominik
2008-01-21 17:43   ` Adam Spiers
2008-01-21 19:10     ` Carsten Dominik
  -- strict thread matches above, loose matches on Subject: below --
2008-01-25 15:45 Stuart McLean
2008-01-25 16:11 ` Hugo Schmitt

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).