Pogues icon indicating copy to clipboard operation
Pogues copied to clipboard

Roundabout component - DDI model

Open romaintailhurat opened this issue 2 years ago • 23 comments

WIP

  • [x] First model of the object
  • [x] Check name
  • [ ] Update controlled vocabulary
  • [x] How to parametrize?
  • [ ] Final model

Describe what this component is about

This could be modelled as a DDI Sequence with a TypeOfSequence with value "roundabout".

<d:Sequence>
    <r:Agency>fr.insee</r:Agency>
    <r:ID>abcd1234</r:ID>
    <r:Version>1</r:Version>
    <d:ConstructName>
        <r:String xml:lang="fr-FR">ROUNDABOUT</r:String>
    </d:ConstructName>
    <r:Label>
        <r:Content xml:lang="fr-FR">Le rond-point</r:Content>
    </r:Label>
    <!-- Typing the sequence -->
    <d:TypeOfSequence controlledVocabularyID="INSEE-TOS-CL-1">roundabout</d:TypeOfSequence>
    <d:ControlConstructReference>
        [...]
    </d:ControlConstructReference>
</d:Sequence>

romaintailhurat avatar Jan 13 '23 12:01 romaintailhurat

Pour le rond-point, je ne sais pas s'il faut en faire une séquence ou un attribut de la boucle qu'il introduit. Je ne sais pas ce que l'on souhaite mettre exactement sur la page de rond-point à part :

  • des liens vers la page précédente
  • pour chacune des occurrences de la boucle qui suit : - l'état d'avancement de la saisie pour cette occurrence - un lien vers la première page - un lien vers la dernière page atteinte

Si l'on ne souhaite pas afficher davantage, le label de la boucle (qui n'est a priori pas utilisé) peut suffire comme label pour la page (ou du tableau des occurrences de boucle) et le reste peut s'en déduire...

Pour identifier la meilleure modélisation, il faudrait un exemple de ce que l'on souhaite obtenir avec l'orchestrateur. Le but est moins d'identifier ce à quoi cette page devra ressembler (l'UX design pourra la faire évoluer) que d'identifier quelles informations devront être fournies par Pogues, donc quelles informations devront figurer dans les modèles Pogues, DDI et Lunatic.

BulotF avatar Feb 14 '23 08:02 BulotF

Pour avancer :

En terme d'usage du rond-point, deux éléments de configuration au moins :

  1. les expressions permettant de préciser comment déterminer l'état des sous-questionnaires ;
"expressions": {
    "unnecessary": {
        "value": "AGE < 13",
        "type": "VTL"
    },
    "complete": {
        "value": "not(isnull(KNOWREC)) and not(isnull(SEXE)) and not(isnull(SOMETHING))",
        "type": "VTL"
    },
    "partial": {
        "value": "not(isnull(KNOWREC)) or not(isnull(SEXE)) or not(isnull(SOMETHING))",
        "type": "VTL"
    },
    "label": {
        "value": "\"Série de question pour \" || PRENOMS",
        "type": "VTL"
    }
}
  1. la liste des composants pour chaque sous-questionnaire.
"components": [
    {
        "id": "radio",
        "componentType": "Radio",
        "mandatory": false,
        "page": "4.1",
        "label": {
            "value": "\"Connaissez-vous le recensement de la population ?\"",
            "type": "VTL|MD"
        },

        "conditionFilter": { "value": "true", "type": "VTL" },

        "options": [
            { "value": "1", "label": { "value": "\"oui\"", "type": "VTL|MD" } },

            { "value": "2", "label": { "value": "\"non\"", "type": "VTL|MD" } }
        ],
        "response": { "name": "KNOWREC" }
    },
    {
        "id": "jsygk7m7",
        "componentType": "Subsequence",
        "page": "4.2",
        "label": {
            "value": "\"Deuxième page de questions pour \"|| PRENOMS",
            "type": "VTL|MD"
        },
        "conditionFilter": { "value": "true", "type": "VTL" }
    },
    ...
]

A priori, on inclut uniquement des sous-séquences et des questions comme enfants du rond-point.

romaintailhurat avatar Mar 08 '23 07:03 romaintailhurat

Asking @renaud23 if subsequence is the higher component level or not.

UPDATE : same constraint as for paged loop ("boucles paginées"), so any component seems good.

romaintailhurat avatar Mar 21 '23 09:03 romaintailhurat

De ce que je vois au niveau du modèle Lunatic présent en lien, on est assez près de la boucle liée :

  • même contenu au niveau des components
  • le filtre présent au niveau de unnecessary ressemble à celui d'une boucle liée

Il manque :

  • le label
  • complete ou partial (c'est 2 conditions sont opposées, donc avoir l'une revient à avoir l'autre)
  • locked (je ne sais pas ce que c'est)

Dans le cas d'une boucle liée avec filtre sur les occurrences, on était parti sur une Loop référençant un filtre, référençant lui-même une séquence -> ce sont les 3 éléments que l'on peut enrichir pour avoir les informations manquantes (mais il faudrait pour Eno indiquer dans la Loop qu'il s'agit d'un rond-point)

BulotF avatar Apr 17 '23 12:04 BulotF

Would the following be a good design ?

<d:Loop>
    <r:Agency>fr.insee</r:Agency>
    <r:ID>lmomdlun</r:ID>
    <r:Version>1</r:Version>
    <d:ConstructName>
        <r:String xml:lang="fr-FR">B2</r:String>
    </d:ConstructName>
    <d:ControlConstructReference>
        <r:Agency>fr.insee</r:Agency>
        <r:ID>lmommfe7</r:ID>
        <r:Version>1</r:Version>
        <r:TypeOfObject>Sequence</r:TypeOfObject>
    </d:ControlConstructReference>
    <r:UserAttributePair>
        <r:AttributeKey>Navigation</r:AttributeKey>
        <r:AttributeValue>Roundabout</r:AttributeValue>
    </r:UserAttributePair>
    <r:UserAttributePair>
        <r:AttributeKey>RoundaboutConfiguration</r:AttributeKey>
        <r:AttributeValue><![CDATA[
                  "expressions": {
                     "unnecessary": {
                         "value": "AGE < 13",
                         "type": "VTL"
                     },
                     "complete": {
                         "value": "not(isnull(KNOWREC)) and not(isnull(SEXE)) and not(isnull(SOMETHING))",
                         "type": "VTL"
                     },
                     "partial": {
                         "value": "not(isnull(KNOWREC)) or not(isnull(SEXE)) or not(isnull(SOMETHING))",
                         "type": "VTL"
                     },
                     "label": {
                         "value": "\"Série de question pour \" || PRENOMS",
                         "type": "VTL"
                     }
                  }
                  ]]></r:AttributeValue>
    </r:UserAttributePair>
</d:Loop>

As suggested by @BulotF we are reusing here the DDI design for linked loops, adding two <r:UserAttributePair>:

  • the first one indicating that this linked loop will be displayed as as Roundabout
  • the second one giving all necessary parameters.

Asking for validation @BulotF and @laurentC35 🤗

romaintailhurat avatar Sep 18 '23 08:09 romaintailhurat

There are sevreal problem with the second element :

  • "unnecessary" is redundant : the loop references a IfThenElse with this condition : no information present twice if not necessary
  • "complete" / "partial" contain duplicated code : started "not(isnull(KNOWREC))" and complete "not(isnull(SEXE)) and not(isnull(SOMETHING))" would be better (partial = started and not complete)
  • everywhere else, code references to other element. Not here
  • it is not possible pour internationalize "label"

BulotF avatar Sep 18 '23 09:09 BulotF

VTL code is written "as is" as it is an example provided by a Lunatic roundabout developer.

So if i understand correctly, the configuration part of the Roundabout would be produced by scanning part of the DDI? Or all?

romaintailhurat avatar Sep 18 '23 09:09 romaintailhurat

Alternative design : A round-about is a mono-paged loop or a QuestionGrid with a roster. Still with something indicating that that component is a roundabout.

That component may be inside a Sequence with label "Libellé du rondpoint".

If it is a Loop, its content should be a unique ControlConstruct, but I don't know which kind of element inside : a StatementItem ?

If it is a QuestionGrid, probably a noDataByDefinition in each cell with a label containing the complete and partial formulas. Maybe with several columns if there are several linked loops.

BulotF avatar Sep 18 '23 15:09 BulotF

It seems to me that if really makes sense to use a Loop as the base construct for the Roundabout 😃

romaintailhurat avatar Oct 03 '23 11:10 romaintailhurat

The main idea is to design the roundabout as a Loop that contains a Sequence which itself contains a StatementItem and three ComputationItems, one for each Roundabout parameter:

Loop
	Sequence
		StatementItem
		ComputationItem[unnecessary]
		ComputationItem[partial]
		ComputationItem[complete]

The Loop

<d:Loop>
    <r:Agency>fr.insee</r:Agency>
    <r:ID>lnbp643q</r:ID>
    <r:Version>1</r:Version>
    <r:UserAttributePair>
        <r:AttributeKey>ROUNDABOUT_OBJECT</r:AttributeKey>
        <r:AttributeValue>ROUNDABOUT_LOOP</r:AttributeValue>
    </r:UserAttributePair>
    <d:ConstructName>
        <r:String xml:lang="fr-FR">B_RONDPOINT</r:String>
    </d:ConstructName>
    <d:ControlConstructReference>
        <r:Agency>fr.insee</r:Agency>
        <r:ID>lnbpayrw</r:ID>
        <r:Version>1</r:Version>
        <r:TypeOfObject>Sequence</r:TypeOfObject>
    </d:ControlConstructReference>
</d:Loop>

The Sequence

<d:Sequence>
    <r:Agency>fr.insee</r:Agency>
    <r:ID>lnbpayrw</r:ID>
    <r:Version>1</r:Version>
    <d:ConstructName>
        <r:String xml:lang="fr-FR">RONDPOINT</r:String>
    </d:ConstructName>
    <d:ControlConstructReference>[StatementItem]</d:ControlConstructReference>
    <d:ControlConstructReference>[ComputationItem]</d:ControlConstructReference>
    <d:ControlConstructReference>[ComputationItem]</d:ControlConstructReference>
    <d:ControlConstructReference>[ComputationItem]</d:ControlConstructReference>
</d:Sequence>

The StatementItem

<d:StatementItem>
    <r:Agency>fr.insee</r:Agency>
    <r:ID>LABEL_ET_BOUTON</r:ID>
    <r:Version>1</r:Version>
    <r:UserAttributePair>
        <r:AttributeKey>ROUNDABOUT_OBJECT</r:AttributeKey>
        <r:AttributeValue>LABEL_AND_BUTTON</r:AttributeValue>
    </r:UserAttributePair>
    <r:Label>
        <r:Content>Le libellé au-dessus du bouton</r:Content>
    </r:Label>
</d:StatementItem>

The ComputationItems

In order to describe completion parameters we use <d:ComputationItem>. For example here, for the unnecessary Lunatic Parameter:

<d:ComputationItem>
    <r:Agency>fr.insee</r:Agency>
    <r:ID>lahvkp0z-CI-0</r:ID>
    <r:Version>1</r:Version>
    <d:ConstructName>
        <r:String xml:lang="fr-FR">ROUNDABOUT_UNNECESSARY</r:String>
    </d:ConstructName>
    <r:Description>
        <r:Content xml:lang="fr-FR">Rond-point - Les itérations à masquer.</r:Content>
    </r:Description>
    <d:InterviewerInstructionReference>
        <r:Agency>fr.insee</r:Agency>
        <r:ID>lahvkp0z-CI-0-II-0</r:ID>
        <r:Version>1</r:Version>
        <r:TypeOfObject>Instruction</r:TypeOfObject>
    </d:InterviewerInstructionReference>
    <d:TypeOfComputationItem controlledVocabularyID="INSEE-LUNATIC">roundabout-unnecessary</d:TypeOfComputationItem>
    <r:CommandCode>
        <r:Command>
            <r:ProgramLanguage>vtl</r:ProgramLanguage>
            <r:CommandContent>AGE ;&lt; 13</r:CommandContent>
        </r:Command>
    </r:CommandCode>
</d:ComputationItem>

romaintailhurat avatar Oct 04 '23 13:10 romaintailhurat

  1. To specify the type of loop, I would prefer :
<r:UserAttributePair>
   <r:AttributeKey>loopType</r:AttributeKey>
   <r:AttributeValue>roundabout</r:AttributeValue>
</r:UserAttributePair>

  1. For the StatementItem :
<r:UserAttributePair>
   <r:AttributeKey>button</r:AttributeKey>
   <r:AttributeValue>roundabout-link</r:AttributeValue>
</r:UserAttributePair>

  1. The controlledVocabulary for TypeOfComputationItem would be : roundabout-unnecessary roundabout-complete roundabout-partial

  2. ComputationItem have no InterviewerInstructionReference

  3. For at least dynamic arrays (QuestionGrid with 2 dimensions for which the first dimension is a roster and the second one is a codeList), I'd use a Variable to indicate where the buttons should be displayed. It would be mandatory when there is at least 2 buttons, to assign correctly the computation items to each. Alternative in the component that displays the link, I'd like to have a reference (basedOn ?) to the 3 parameters ComputationItem...

BulotF avatar Oct 04 '23 16:10 BulotF

ComputationItem have no InterviewerInstructionReference

Yes, i just forgot to delete this part 😉

romaintailhurat avatar Oct 06 '23 07:10 romaintailhurat

Maybe it could be important to fill a controlled vocabulary for attributevaluekeys too I don't see how the choice is made between the partial label and complet label , when all the fields are completed I change my previous comment. two possibilities. the basedOnObject cardinality is 0 1. it can contain several basedOnReferences we could type with RserAttributPair. Why not using inparameter instead to get computation item value ?

dzkwsk avatar Oct 14 '23 11:10 dzkwsk

I thought that controlled vocabulary's AttributeKeys was specified in the DDI profile (and only in it)

InParameter is a better alternative. Nice.

BulotF avatar Oct 17 '23 13:10 BulotF

I agree in the DDI profile it's fine ! not the same status as a value

dzkwsk avatar Oct 24 '23 09:10 dzkwsk

So it seems that we have an agreement on the design, i propose to add that to a proper and versionned document.

The implementation can start.

romaintailhurat avatar Oct 31 '23 09:10 romaintailhurat

I wrapped up our comments in this document 👇

DDI - Roundabout design.pdf

I don't think we need an alternative QuestionGrid based design with this. But:

  • we still have the 5. of François remarks to discuss
  • we probably need a french version of this document.

romaintailhurat avatar Oct 31 '23 15:10 romaintailhurat

a suggestion of identifying the used suggester also by a version number , if it evolves over time

dzkwsk avatar Nov 09 '23 12:11 dzkwsk

A last review by @BulotF is in progress.

romaintailhurat avatar Nov 10 '23 12:11 romaintailhurat

Reprise des réflexions sur le rond-point... J'écris en français pour permettre aux participations à la discussion de ne pas alourdir la compréhension de mes explications avec la traduction.

Résumé de ma vision du rond-point du point de vue métier : Lorsqu'on est sur un questionnaire sans rond-point, l'avancement dans le questionnaire ne peut être que linéaire : Au niveau des boucles, on répond aux occurrences dans l'ordre et on attend d'en finir une avant d'entamer la suivante.

Avec le rond-point, on se donne la possibilité de basculer d'une occurrence à une autre, dans un ordre déterminé par le(s) répondant(s) et sans forcément avoir terminé une occurrence avant de basculer à une autre.

Pour faire un parallèle : le questionnaire global est le processus principal. On le met en pause pour lancer plusieurs petits processus parallèles. On le reprend lorsque tous ces petits processus sont terminés.

Pour avoir une expérience utilisateur la plus claire possible, on a besoin des éléments suivants :

  • le rond-point est sur une page spécifique
  • il peut avoir un titre et éventuellement des instructions
  • pour chaque occurrence :
    • il affiche un libellé qui permet d'identifier l'occurrence
    • il permet d'accéder à la dernière page renseignée de l'occurrence (si cela a du sens)
    • il renseigne sur l'état de l'occurrence : "non concerné" ; "non commencé" ; "en cours" ; "terminé" (libellés donnés à titre indicatif)
  • si le rond-point permet d'accéder à plusieurs boucles qui se suivent et que l'on souhaite clarifier au répondant les étapes (ex : informations individu ; questions individus majeurs ; informations grosses dépenses ; carnet de dépenses), l'information pour chaque occurrence peut être préciser pour chaque étape + chaque étape possède un libellé.
  • en cours de navigation au sein d'une occurrence, le rond-point est immédiatement accessible

Le rond-point peut être vu comme un conteneur de boucle(s), plutôt que comme un type de boucle particulier. Le définir comme une séquence de typeOfSequence = "roundabout" offre plusieurs possibilités intéressantes :

  • fournir une présentation structurée au niveau de la page, en dehors des liens vers les boucles : en plus du titre de page, utiliser des déclarations
  • pouvoir référencer plusieurs boucles au lieu d'être restreint à une seule

Par ailleurs, je pense que le filtre d'occurrence que l'on indiquait sous la forme d'un ComputationItem "unnecessary" mérite de redevenir un filtre (ce qu'il est déjà avec les boucles hors rond-point). Je conserverais les ComputationItem "complete" et "partial" tels quels.

Au niveau StatementItem, outre le libellé pour désigner l'occurrence, j'utiliserais des StatementItem pour les boutons "Ajouter une occurrence" (actuellement, on utiliser le label de la Loop et c'est assez moyen) et "supprimer une occurrence". Si on choisit de les indiquer au sein de la Sequence qui dépend directement de la Loop, on peut même choisir d'en faire des d:Instruction et donc de leur donner des InstructionName correspondant à leur statut : Loop.InstanceLabel ; Loop.Add ; Loop.Remove

Si on souhaite modéliser l'exemple suivant : rounabout

N.B. Modélisation en mode déréférencé (je remplace la référence par l'objet) qui n'indiquerait que les éléments utiles...

<d:Sequence>
    <r:Label>Liens vers les différentes personnes du ménage :</r:Label>
    <d:Instruction>
        <d:InstructionName>help</d:InstructionName>
        <d:InstructionText>Cette page permet d’accéder aux questionnaires des différentes personnes du ménage.
            Vous pouvez revenir à cette page en appuyant sur le bouton « revenir au rond-point »</d:InstructionText>
    </d:Instruction>
    <d:TypeOfSequence controlledVocabularyID="INSEE-TOS-CL-1">roundabout</d:TypeOfSequence>
    <d:Loop>
        <r:Label>Questions individuelles</r:Label>
        <d:Sequence>
            <d:Instruction>
                <d:InstructionName>Loop.InstanceLabel</d:InstructionName>
                <d:InstructionText>¤PRENOM¤</d:InstructionText>
            </d:Instruction>
            <d:Instruction>
                <d:InstructionName>Loop.Add</d:InstructionName>
                <d:InstructionText>Ajouter un individu</d:InstructionText>
            </d:Instruction>
            <d:Instruction>
                <d:InstructionName>Loop.Remove</d:InstructionName>
                <d:InstructionText>Supprimer un individu</d:InstructionText>
            </d:Instruction>
            <d:TypeOfSequence controlledVocabularyID="INSEE-TOS-CL-1">loopContent</d:TypeOfSequence>
            <d:ComputationItem>
                <d:TypeOfComputationItem controlledVocabularyID="INSEE-TOCI-CL-1">loop.complete</d:TypeOfComputationItem>
                <r:CommandCode>Tout est renseigné</r:CommandCode>
            </d:ComputationItem>
            <d:ComputationItem>
                <d:TypeOfComputationItem controlledVocabularyID="INSEE-TOCI-CL-1">loop.partial</d:TypeOfComputationItem>
                <r:CommandCode>Au moins une variable est renseignés</r:CommandCode>
            </d:ComputationItem>
            ... Contenu de la boucle questions individuelles ...
        </d:Sequence>
    </d:Loop>
    <d:Loop>
        <r:Label>Questions sur les majeurs</r:Label>
        <d:IfThenElse>
            <d:IfCondition>AGE >= 18</d:IfCondition>
            <d:Sequence>
                <d:TypeOfSequence controlledVocabularyID="INSEE-TOS-CL-1">filteredLoopContent</d:TypeOfSequence>
                <d:ComputationItem>
                    <d:TypeOfComputationItem controlledVocabularyID="INSEE-TOCI-CL-1">loop.complete</d:TypeOfComputationItem>
                    <r:CommandCode>Tout est renseigné</r:CommandCode>
                </d:ComputationItem>
                <d:ComputationItem>
                    <d:TypeOfComputationItem controlledVocabularyID="INSEE-TOCI-CL-1">loop.partial</d:TypeOfComputationItem>
                    <r:CommandCode>Au moins une variable est renseignés</r:CommandCode>
                </d:ComputationItem>
                ... Contenu de la boucle questions sur les majeurs ...
            </d:Sequence>
        </d:IfThenElse>
    </d:Loop>
    <d:Loop>
        <r:Label>Cœur de l’enquête</r:Label>
        <d:IfThenElse>
            <d:IfCondition>Indiv = Kish</d:IfCondition>
            <d:Sequence>
                <d:TypeOfSequence controlledVocabularyID="INSEE-TOS-CL-1">filteredLoopContent</d:TypeOfSequence>
                <d:ComputationItem>
                    <d:TypeOfComputationItem controlledVocabularyID="INSEE-TOCI-CL-1">loop.complete</d:TypeOfComputationItem>
                    <r:CommandCode>Tout est renseigné</r:CommandCode>
                </d:ComputationItem>
                <d:ComputationItem>
                    <d:TypeOfComputationItem controlledVocabularyID="INSEE-TOCI-CL-1">loop.partial</d:TypeOfComputationItem>
                    <r:CommandCode>Au moins une variable est renseignés</r:CommandCode>
                </d:ComputationItem>
                ... Contenu de la boucle cœur de l’enquête ...
            </d:Sequence>
        </d:IfThenElse>
    </d:Loop>
</d:Sequence>

Eléments de vocabulaire qui n'existent pas encore, mais auraient de l'intérêt pour les séquences : ajouter des valeurs à typeOfSequence : filterContent ; loopContent et filteredLoopContent (contenu d'une boucle dont les occurrences sont filtrées)

Cette description a l'avantage de ne pas utiliser r:UserAttributePair. L'enrichissement de la sémantique est porté par les modalités de TypeOfSequence ; InstructionName ; TypeOfComputationItem

BulotF avatar Mar 13 '24 15:03 BulotF

à documenter ailleurs qu'ici Faire une issue Pogues-Model + Eno

laurentC35 avatar Mar 18 '24 13:03 laurentC35

Modification des besoins Lunatic :

  • suppression du besoin des ComputationItem loop.complete et loop.partial (directement calculés)
  • le besoin des Instruction Loop.Add et Loop.Remove n'est plus lié au rond-point (mais reste pertinent dans le cas des boucles principales)
  • ajout d'une variable collectée indiquant la page d'avancement du répondant sur chaque occurrence : pour moi, il s'agit d'une paradonnée (comme l'information de la page courante du répondant hors rond-point) ; elle mérite de ne pas formuler dans le DDI ; je propose de faire générer cette variable à Eno à partir du nom du rond-point
  • Remplacement du libellé destiné à décrire la raison de non-collecte des occurrences exclues par les filtres (que j'avais mis en r:Label du IfThenElse, par une description de l'état de l'occurrence vis-à-vis du rond-point. Plutôt que partir sur l'utilisation du r:Description de l'Instruction Loop.InstanceLabel, je propose une Instruction Loop.InstanceDescription : pour Dylan, il s'agit de la description de l'occurrence ; pour moi, il s'agit de 2 concepts distincts : un identifiant de l'occurrence à destination du répondant pour le InstanceLabel ; une description de l'état de l'occurrence vis-à-vis des réponses qu'elle devra donner.
  • ajout d'un paramètre "Locked" : pour le moment, un booléen, qui indique si on est bloqué pour revenir sur une occurrence terminée. Pour le moment, au niveau du modèle Lunatic, il s'agit d'un booléen simple. Je pense néanmoins que les concepteurs pourraient souhaiter mettre une condition au fait de bloquer ou non les occurrences. Je propose donc un ComputationItem de type loop.lock qui, dans un premier temps, vaudrait true en condition et n'aurait pas de libellé

BulotF avatar Jun 13 '24 10:06 BulotF

quelques remarques -je suis d'accord sur le fait que dans le DDI il n'est pas nécessaire de mettre tous les objets techniques pour gérer l'affichage, l'essentiel c'est d'avoir l'information logique/métier de la passation -je suis ok sur la présentation du ddi de l'exemple du 13 mars, il faudra voir avec les imports dans Colectica que les instructions des séquences sont bien importées (actuellement non décrits dans Designer), on est plutot sur interviewerinstruction il me semble -sur les exemples ce serait pratique de mentionner la version de DDI utilisé, ddi3_2 ou ddi3_3 et par la suite ddi3_4

dzkwsk avatar Jul 02 '24 13:07 dzkwsk