Skip to content

Commit 5ffbe02

Browse files
committed
added §4.3 script
1 parent 561cf1a commit 5ffbe02

2 files changed

Lines changed: 176 additions & 2 deletions

File tree

docs/04_3_Creating_New_Views.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ Start out by generating a list of edges:
383383
```
384384
envelope xid edge all $XID
385385
```
386-
Then use whatever method you prefer to find the right edge.
386+
Then use whatever method you prefer to edge with DevReviewer's peer endorsement.
387387

388388
It's:
389389
```
@@ -638,7 +638,7 @@ commitment edge. They are:
638638

639639
| Description | Notes | Created In |
640640
|-------------|-------------|------------|
641-
| 🔒 Private View | §4.2 |
641+
| 🔒 Private View | | §4.2 |
642642
| 👁️ Public View | Elided key material | §4.2 |
643643
| 🔑 Simplified View | Elided contract key | §4.3 |
644644
| ❗ Non-Correlatable View | Elided correlatable content | §4.3 |
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
#!/bin/bash
2+
# 04_3_Creating_New_Views-SCRIPT.sh
3+
#
4+
# Tests all commands from §4.3, verifying:
5+
# - Removing a top-level object from a XID.
6+
# - Removing a lower-level object from a XID.
7+
#
8+
# Usage: bash 04_3_Creating_New_Views-SCRIPT.sh
9+
10+
11+
set -e
12+
13+
echo "=== LEARNING XIDS §4.3: Creating New Views ==="
14+
15+
# Configuration
16+
17+
# Create output directory
18+
19+
OUTPUT_DIR="output/script-04-3-$(date +%Y%m%d-%H%M%S)"
20+
mkdir -p "$OUTPUT_DIR"
21+
22+
XID="ur:xid/tpsplftpsplotpsotanshdhdcxnsvelewdmugsjksomhcsdngumosodnlffnlpcxfeylutcseeluatlyihdphyieadoycfaorylftpsplrtpsokseyjoihihjpdpihjtiejljpjkihjnihjtjydpiyjpjljndpieihkojpihkoinihktihjpdpideyeeihehhsieehihemetiyeyehieeeoycfaornlstpsotanshdhdcxhdsfzozcetjkztcmwnvaqzhkdyvlytswpmhttoprrtskioesiyhlkeotjecaknhdoytpsojkjkiaisihjnhsftihjnjojzjlkkihihgmjljzihtpsokscsfdihhsiecxguihiakpjpinjykkcxgdjpjliojphsjnjnihjpoytpsojljkiaisihjnhsftktjljpjejkfgjljptpsojzguinjkjyihjpgujohsiaihjkoycfaorslntpsotanshdhdcxnsvelewdmugsjksomhcsdngumosodnlffnlpcxfeylutcseeluatlyihdphyieadoytpsojsjpihjzhsjyinjljtjkisinjofwhsjkinjktpsoksiaguihiakpjpinjykkcxiajljzjzhsidjljphsjyinjljtcxjohsjpjyjtihjpcxktisjlcxkoihjpiniyinihiecxiajpihieihjtjyinhsjzjkcxjyisjpjlkpioiscxiajljnjninjydpjpihkoihhsjzcxhsjtiecxihjtiajpkkjojyihiecxjkishsjpinjtiooybetpsokoeydyeyendpdyeedpdyemghehehftehecdpehdyftdydyoytpsojpihjtiejljpjkihjnihjtjyfxjljtjyihksjytpsokshghfihjpiyinihiecxjojpihkoinjlkpjkcxjkihiakpjpinjykkcxihksjoihjpinihjtiaihdwcxktjljpjeihiecxjyjlioihjyisihjpcxjljtcxjkisjljpjycxjojpjlimihiajycxiyjljpcxguinjkjyihjpgujohsiaihjkoytpsojljoihihjpfejtiejljpjkihjnihjtjytpsoksguhgjpinjyihjkcxjkihiakpjpihdwcxktihjzjzdpjyihjkjyihiecxiajlieihcxktinjyiscxiajzihhsjpcxhsjyjyihjtjyinjljtcxjyjlcxjojpinkohsiakkdpjojpihjkihjpkoinjtiocxjohsjyjyihjpjtjkoytpsojoihjtiejljpjkihjnihjtjyguiajljoihtpsoksfeguihiakpjpinjykkcxhsjpiaisinjyihiajykpjpihdwcxiajpkkjojyjliojphsjoisiniacxinjnjojzihjnihjtjyhsjyinjljtdwcxjojpinkohsiakkcxjohsjyjyihjpjtjkoyadtpsojehsjyjyihjkjyhsjyinjljtoyaxtpsotansghlfaohdfznbytwmprtoiegsdekihpltdnrtstcnykzcvaenbkjlpejksbhnatlyontkvotpmosodmfsgajtpmielrlgzowpvevlstveadmknetdrkykbachkindwnrdtisalaltaxoyaylrtpsotansgylftanshflfaohdcxlumegtzorkdntkrolkosmyrffndiwkrofhbblfzerodipahhkkcejtatinbsjtintansgrhdcxlnjzbnfwasfshtfgvehhktdschdwttrtctdepkbyhlhkbdsogwashkgobsqzgwjtlfoycsfplftansfwlrhdghghzceetljywzehjedwzewkaopezocwknhldrqdmystghwtoltyfmcnkpfyrpuocygwpmrlnlmnadfxjorfbyvekepfylwkfmspbktladrtmyrnswbagywlcxdtasplnbreztdawkgycmtyvtdejtplgmosrprocwesmesttdgsjkcsbgzoondwaxtyktglweesgdsnaypddnmhsbsaeytdzsvwfymklrpyeyhddatansfphdcxayhkjpidzehpytiesnkofybgbbinntaezozstbctideyykdsbzylimwsvadplnlaoybwtpsotanshptansfwlrhdcxvyvymhveuyrliodsgmnlgykndtrtpslfkoktoyfheojndnkkmktkwnfejzqzkketgsjtskmujeqduymeahhfsbatbzgdeywtsgrdjejtjtdkglasytzehhtawezshflfaxtansgmgdaekkytjzwmlfhlaomhsagswzaetdhttdoybstpsotansgmhdcxyaflntkectinioyttklocelbmhaseswnoeetdmtprnfmytmyhfghimjzhebnctftoycscstpsojziajljtjyjphsiajydpjeihkkoycsfncsfdoycsfzlftpsotngdgmgwhflfaxhdimutwyskfwihlagwoxhytdrtrngtdwmujobgmsdrfpehdroetibnttndoscydwrhtomkrkknutcfhynntsqzmthtoecaclhkhksgpdhlkpcyfgievwktuepmrtatrpotecsrtkmohdhdfpgltpgykphkknmtcnbapmpdrooxfhwfpklkoeosgapylgdkonwzfpvlremubnztghftgszslslfoycsfylftansfwlrhdrofpmddpengdnsvyhemtgumeteasbsnnrppfdehkdlpdgygoskselrjnfxwzasditypyktvsenonhfdmcsenwknngdcniaahksbzoeaafpbevdcplstefeeezoweprhnkplakipmehassfhkkeimteaholluvladgykerktnfweyeygtrdgtglbzgoglvwwessfdrpuyfrpmtnvsytwtlekshnyafsoeurldgllsaxtlskpyfwhntymwiosphekpprcedefgayhkrninndpdluislnrkzsbahfcflyjkleamonqzmhsrtylfurlfnnsadnbkdtecztkkcegsmhftvebzpkcheegyflwyndmygafxjnbzehgseyensfgwguetdrresayagytsgdhnuorocauouotnrsztswpkrhlfkovwjohddatansfphdcxiaeoceneechesrryihdemdpagepdosuthffwehfyhlvsnetevtchknrsdsgscafzoybwtpsotanshptansfwlrhdcxfekemoathhfhutsfcwjpwdgteyrtgdzenbaoztrslbtpvyjnbdrlsadklnolstfsgsztlfvlisiyaspsdykthsfrtbgdimwmcsaahphlcxhgcsotcnaxbbfrchiohflfaxtansgmgdmwbnhdasimkstyrldmcavolyeykblktsoybstpsotansgmhdcxiyvwcpcptddkeemdwfoylrrnspcttebgsbrnfmoetirfmwehhsrehdpmstdadaytoyaylrtpsotansgylftanshflfaohdcxonbbaxfdchqzlfcptlbbyachdypehyaxtecavlhymnmyceeekotpcamnamguclmotansgrhdcxcsrnchrnrpbsrnuecwaymoihplfnkgrdaxiefgpyidvysecnluhtwlwmpfwndnctlfoycsfplftansfwlrhdghykhlpmwerksnfseslnrpttdiltgotschpttlpacfctimjyykihhtfpteyllolsuesbnyetoxprseskhdykwlwnknstldahehdszefmdtbsdenbtbsndepddrroonbdmhztbapytatykimdvefzkinldpbyhymuwnkbbtvsflgshyzcaaetammwqdfnwlvlpkcmgdkovwesaeaojoaygafmjoynmecklartfghddatansfphdcxjemdmobewtihrohsgaghsglkgepdcmhdflhnamvegwssjzolpsjslesrwypkrydwoybwtpsotanshptansfwlrhdcxveoewfpmhgdywymkjylrndiseoytbdpantgdsrnbkihneoztasgreokecmchrsbtgsiyghclsabalkuywzamidctfsgdnnetihrywzmnhytbsbbnkisgswdlcmvyhflfaxtansgmgdosdrotksvdbtwsvsvevocycxgeuymtwmoybstpsotansgmhdcxrsfpfpfmldltkbsaamecmogabacsjtdedtsshlmdutaoaoylstndserdwdnedwmnoycscstpsoisfwgmhsiekojliaetoycsfncsfgoycfaorylftpsplrtpsokscfhsiaiajlkpjtjydpiajpihieihjtjyinhsjzdpioinjyiskpidoyadtpsojpiyjlhsiyftgwjtjzinjtihfpiaiajlkpjtjyoycfaorsldtpsotanshdhdcxnsvelewdmugsjksomhcsdngumosodnlffnlpcxfeylutcseeluatlyihdphyieadoytpsojsjkjkisguiniojtinjtiogrihkkjkgogmgstpsotpcxksenisjyjyjojkftdldlhsjoindmioinjyiskpiddmiajljndlkpjkihjpjkdlfwgmhsiekojliaetdljkjkishejkiniojtinjtiohejeihkkjkoytpsojoiyjlhsiyfthsiaiajlkpjtjyglhsjnihtpsoisfwgmhsiekojliaetoytpsojnjkjkisguiniojtinjtiogrihkktpsotansgylftanshftanehsksgdjkjkisdpihieeyececehescxfpfpfpfpfxeoglknhsfxehjzhtfygaehglghfeecfpfpfpfpgafdeceyjlgogmjehkkpjpjtihiygojtjlfgiddnfpgsjpjpfxeedlhdihdngdkpgwgmfxfgkninjlgmfyhfjkgmtansgrhdcxfhtkhnmyoeoyvdvdgolosrpfrosnrsaycmiycelnqdjyjzlplpeykgesmnvwoeimoytpsokscwiyjlhsiyfthsiaiajlkpjtjyguihjpkoiniaihfdjljnihjohsioihtpsotpcxksdkisjyjyjojkftdldlioinjyiskpiddmiajljndlfwgmhsiekojliaetdlfwgmhsiekojliaetoycscwtpsotpcxksdaisjyjyjojkftdldlhsjoindmioinjyiskpiddmiajljndlkpjkihjpjkdlfwgmhsiekojliaetoycseetpsotpcxjpisjyjyjojkftdldlioinjyiskpiddmiajljnoytpsojsjkjkisguiniojtinjtiogrihkkghihksjytpsoksgdjkjkisdpihieeyececehescxfpfpfpfpfxeoglknhsfxehjzhtfygaehglghfeecfpfpfpfpgafdeceyjlgogmjehkkpjpjtihiygojtjlfgiddnfpgsjpjpfxeedlhdihdngdkpgwgmfxfgkninjlgmfyhfjkgmoybetpsokoeydyeyendpdyeedpdyehgheheefteeetdpehdyftdydyoycfaorntpsotanshdhdcxnsvelewdmugsjksomhcsdngumosodnlffnlpcxfeylutcseeluatlyihdphyieadoyaxtpsotansghtaneidkkaddmdpdpdpdpdpfwfeflgaglcxgugufdcxgugaflglfpghgogmfedpdpdpdpdpbkgoehglgagodyjzfdfpfpfpfpfpgyfpfpfpfygtfpfpfpfpgsiaeogljlgshghfjegtimgoehgtghjefpfpfpfpioiyjthsisgmflgminenkpieecesguihiohfkoeefpkpkpjkgsimesbkieemeedneeecfegahdgwgrisfeglhgksfefpfpfpfpgahthgeceyhthgkskoiaflgofpfpfpfpfpfpfpfpfpfwjtgljlhkghgaehgliofpfpfpfggtfpfpfpfpgsiaeogljlgshghfjebkgtimgoehgtghjefpfpfpfwfphkihjeidkpjofxetihiyiejegejzgmeefdkkjpfyjkksgufljlghgtesdleejofdjegsjkghemdletgriygwhskoisecfgjtkkgmemfwkpgyeedlgwfwbkkkgufxghgrghkkhfenghiheefgeofdknhshfjtdldnjyehgwfyfefwiofsfsbkdpdpdpdpdpfeglfycxgugufdcxgugaflglfpghgogmfedpdpdpdpdpbkoycfaorylftpsplrtpsokscxjojpjlimihiajydpjkinjkjyihjpdpjkjohsiaihjkdpjkihiakpjpihhskpjyisoycfaorslrtpsotanshdhdcxnsvelewdmugsjksomhcsdngumosodnlffnlpcxfeylutcseeluatlyihdphyieadoytpsoiniajzhsfyinioihjkjytpsotansfphdcxhkrsoyhnoyuodrnsjewsylmybwmouonbtkglbbaxyakilfmnlaptpkjkiepszsdmoycscwtpsoksesisjyjyjojkftdldlioinjyiskpiddmiajljndlguinjkjyihjpgujohsiaihjkdlguihiakpjpihfpkpjyisdlfxgsfpjkdlgmfefpfygtfedmjnieoytpsojziyjlhsiyftgdjpjlimihiajytpsojzguinjkjyihjpgujohsiaihjkoyadtpsojziyjlhsiyftgdjpjlimihiajyoycfaorntpsotanshdhdcxnsvelewdmugsjksomhcsdngumosodnlffnlpcxfeylutcseeluatlyihdphyieadoyaxtpsotansghlfaohdfzmtiniolbreytcnyncnwmsoeyvtlkwzjzprlupebbbzghdnmnoyprenmdlflucaonsffelpfehkaaiyguzttartsfhdvtwfwdsboxfdlfbtwmwekbimdtemftatmhttbsoyaylrtpsotansgylftanshflfaohdcxplvdotinmnwensttrtlrtiisqzehrltlnlguhdludywzsebztnqdndwztpdazeqdtansgrhdcxfmlpjkhspautsfmwlndrpavobwpyotsazsdidwrnrpcylfintnwtgrnnhdhhpyjpoycscstpsojlhsjyjyihjkjyhsjyinjljtdpjeihkklfoycsfplftansfwlrhdghutjtlbhlwztbrdltsfvotnloutsabzjpnblnloehspbnseaojzceseeshtcxjsaydrltryjsamaaetgmcnctsfkbrhlfwpdtamhnyllbpfkgzeeyamfdgrinesemkpticlhljnvsytykwnfgvdesfyzsadhfesdmrdrthtfygshfvyoskbglgmcnhdhnrttsaogdbwlsmedndtynjzgdbehshlletpdrdtishddatansfphdcxiopakburhprngowmtshlrswzihbytpflgtrootzosfrpnnfprymuveasenotaeadoybwtpsotanshptansfwlrhdcxfpaohdbtndgyvsdnprcejtcwylaartjzdyfddtrosbpfbwsrwnhpmdmnadembdvlgslobdzmlphnvdbdskgyjnluzsgdtatinnjkcmtyylmucadwinjooyeosnylhflfaxtansgmgdstremsfwkisatnrdhlbbmhswdyadbelpoybstpsotansgmhdcxghchykwlghoxpftljectmyyldyamgycwamfwbnsbjelbsshkbzcnuttyrltlwtgmoycsfncsfdoyaxtpsotansghlfaohdfzhdetdtoxemlnrtltcncnpaglvoeynbehnewmbdjtzsperewlhynsisnekgmolrbyhszcwzlfpelafmdwenoswyspetdajsntytdlfepkpkidnswtchhhhhmsztbgtdaarywkylrl"
23+
24+
XID_ID=$(envelope xid id $XID)
25+
PASSWORD="test-password-for-tutorial"
26+
27+
echo ""
28+
echo "Step 1: Generate an Object List"
29+
echo "==============================="
30+
31+
KEYLIST=$(envelope xid key all $XID)
32+
KEYS=($KEYLIST)
33+
34+
if [ $KEYS ]
35+
then
36+
echo "✅ Key list created"
37+
else
38+
echo "❌ Failed to create key list"
39+
exit 1;
40+
fi
41+
42+
echo ""
43+
echo "Step 2: Choose a Key"
44+
echo "===================="
45+
46+
47+
CONTRACTKEY=$(for i in "${KEYS[@]}"; do if [[ -n `envelope assertion find object string "contract-key" $i` ]]; then echo $i; fi; done)
48+
49+
if [ $CONTRACTKEY ]
50+
then
51+
echo "✅ Contract key found"
52+
else
53+
echo "❌ Failed to find contract key"
54+
exit 1;
55+
fi
56+
57+
echo ""
58+
echo "Step 3: Digest a Key"
59+
echo "===================="
60+
61+
CONTRACTKEY_DIGEST=$(envelope digest $CONTRACTKEY)
62+
63+
if [ $CONTRACTKEY_DIGEST ]
64+
then
65+
echo "✅ Contract key digested"
66+
echo $CONTRACTKEY_DIGEST
67+
else
68+
echo "❌ Failed to digest contract key"
69+
exit 1;
70+
fi
71+
72+
echo ""
73+
echo "Step 4: Remove the Content"
74+
echo "=========================="
75+
76+
XID_WO_CONTRACTKEY=$(envelope elide removing $CONTRACTKEY_DIGEST $XID)
77+
78+
if envelope format $XID_WO_CONTRACTKEY | grep -q "contract-key"
79+
then
80+
echo "❌ Failed to remove contract key"
81+
exit 1;
82+
else
83+
echo "✅ Contract key removed"
84+
fi
85+
86+
echo ""
87+
echo "Step 5: Create a New Public Edition"
88+
echo "==================================="
89+
90+
PUBLIC_XID_WO_CONTRACTKEY=$(envelope xid export --private elide --generator elide "$XID_WO_CONTRACTKEY")
91+
92+
echo "$PUBLIC_XID_WO_CONTRACTKEY" > $OUTPUT_DIR/01-bradvoc8-xid-public-elided1.envelope
93+
94+
echo ""
95+
echo "Step 6: Find the Edge"
96+
echo "====================="
97+
98+
# No fancy find commands; this is the right edge for the included XID
99+
100+
DEV_EDGE="ur:envelope/lftpsplrtpsokseyjoihihjpdpihjtiejljpjkihjnihjtjydpiyjpjljndpieihkojpihkoinihktihjpdpideyeeihehhsieehihemetiyeyehieeeoycfaornlstpsotanshdhdcxhdsfzozcetjkztcmwnvaqzhkdyvlytswpmhttoprrtskioesiyhlkeotjecaknhdoytpsojkjkiaisihjnhsftihjnjojzjlkkihihgmjljzihtpsokscsfdihhsiecxguihiakpjpinjykkcxgdjpjliojphsjnjnihjpoytpsojljkiaisihjnhsftktjljpjejkfgjljptpsojzguinjkjyihjpgujohsiaihjkoycfaorslntpsotanshdhdcxnsvelewdmugsjksomhcsdngumosodnlffnlpcxfeylutcseeluatlyihdphyieadoytpsojsjpihjzhsjyinjljtjkisinjofwhsjkinjktpsoksiaguihiakpjpinjykkcxiajljzjzhsidjljphsjyinjljtcxjohsjpjyjtihjpcxktisjlcxkoihjpiniyinihiecxiajpihieihjtjyinhsjzjkcxjyisjpjlkpioiscxiajljnjninjydpjpihkoihhsjzcxhsjtiecxihjtiajpkkjojyihiecxjkishsjpinjtiooybetpsokoeydyeyendpdyeedpdyemghehehftehecdpehdyftdydyoytpsojpihjtiejljpjkihjnihjtjyfxjljtjyihksjytpsokshghfihjpiyinihiecxjojpihkoinjlkpjkcxjkihiakpjpinjykkcxihksjoihjpinihjtiaihdwcxktjljpjeihiecxjyjlioihjyisihjpcxjljtcxjkisjljpjycxjojpjlimihiajycxiyjljpcxguinjkjyihjpgujohsiaihjkoytpsojljoihihjpfejtiejljpjkihjnihjtjytpsoksguhgjpinjyihjkcxjkihiakpjpihdwcxktihjzjzdpjyihjkjyihiecxiajlieihcxktinjyiscxiajzihhsjpcxhsjyjyihjtjyinjljtcxjyjlcxjojpinkohsiakkdpjojpihjkihjpkoinjtiocxjohsjyjyihjpjtjkoytpsojoihjtiejljpjkihjnihjtjyguiajljoihtpsoksfeguihiakpjpinjykkcxhsjpiaisinjyihiajykpjpihdwcxiajpkkjojyjliojphsjoisiniacxinjnjojzihjnihjtjyhsjyinjljtdwcxjojpinkohsiakkcxjohsjyjyihjpjtjkoyadtpsojehsjyjyihjkjyhsjyinjljtoyaxtpsotansghlfaohdfznbytwmprtoiegsdekihpltdnrtstcnykzcvaenbkjlpejksbhnatlyontkvotpmosodmfsgajtpmielrlgzowpvevlstveadmknetdrkykbachkindwnrdtisalaltaxglkbpmcx"
101+
102+
echo ""
103+
echo "Step 7: Extract Objects to Reach the Subject/Assertion Level"
104+
echo "============================================================"
105+
106+
DEV_UNWRAPPED=$(envelope extract wrapped $DEV_EDGE)
107+
DEV_TARGET=$(envelope assertion find predicate known 'target' $DEV_UNWRAPPED)
108+
DEV_TARGET_XID=$(envelope extract object $DEV_TARGET)
109+
DEV_EC=$(envelope assertion find predicate string "endorsementContext" $DEV_TARGET_XID)
110+
DEV_EC_OBJECT=$(envelope extract object $DEV_EC)
111+
DEV_DIGEST=$(envelope digest $DEV_EC_OBJECT)
112+
113+
if [ $DEV_DIGEST ]
114+
then
115+
echo "✅ Correlatable context found"
116+
echo $DEV_DIGEST
117+
else
118+
echo "❌ Failed to find correlatable information"
119+
exit 1;
120+
fi
121+
122+
echo ""
123+
echo "Step 8: Remove the Sub-Content"
124+
echo "=============================="
125+
126+
XID_V3=$(envelope elide removing $DEV_DIGEST $XID_WO_CONTRACTKEY)
127+
128+
if envelope format $XID_WO_CONTRACTKEY | grep -q "security expertise"
129+
then
130+
echo "❌ Failed to remove correlatable information"
131+
exit 1;
132+
else
133+
echo "✅ Correlatable information removed"
134+
fi
135+
136+
echo ""
137+
echo "Step 9: Create a New Public Edition"
138+
echo "==================================="
139+
140+
PXID_V3=$(envelope xid export --private elide --generator elide "$XID_V3")
141+
142+
echo "Double elided public edition:"
143+
envelope format $PXID_V3
144+
145+
echo "$PXID_V3" > $OUTPUT_DIR/02-bradvoc8-xid-public-elided2.envelope
146+
147+
ELIDED_COUNT=$(envelope format $(cat $OUTPUT_DIR/02-bradvoc8-xid-public-elided2.envelope) | grep ELIDED | wc -l)
148+
149+
echo "$ELIDED_COUNT items are elided"
150+
echo ""
151+
echo "Expected Count:"
152+
echo "+ 1 elision of contract key"
153+
echo "+ 1 elision of correlatable information"
154+
echo "+ 2 automatic elisions of other keys' secrets"
155+
echo "+ 1 automatic elision of provenance mark generator"
156+
echo ""
157+
echo "= 5 total"
158+
159+
if [ ! $ELIDED_COUNT -eq 5 ]
160+
then
161+
echo "❌ Whoops, count should have been 5"
162+
exit 1;
163+
fi
164+
165+
echo ""
166+
echo "==============================="
167+
echo "All Tutorial §4.3 Tests Passed!"
168+
echo "==============================="
169+
echo ""
170+
echo "Output files saved to: $OUTPUT_DIR/"
171+
ls -la "$OUTPUT_DIR/"
172+
173+
174+

0 commit comments

Comments
 (0)