diff --git a/README.html b/README.html index 1c1266f2..1920384f 100644 --- a/README.html +++ b/README.html @@ -12,7 +12,7 @@ const baseUrl = '/2025' -

CS3281&2 student data website

+

CS3281&2 student data website

diff --git a/README.page-vue-render.js b/README.page-vue-render.js index 8b1a0023..210afe9c 100644 --- a/README.page-vue-render.js +++ b/README.page-vue-render.js @@ -8,6 +8,6 @@ with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"fixed":""} with(this){return _c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_c('h1',{attrs:{"id":"cs3281-and-amp-2-student-data-website"}},[_v("CS3281&2 student data website"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#cs3281-and-amp-2-student-data-website","onclick":"event.stopPropagation()"}})])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('p',[_v("["),_c('strong',[_v("This site was generated using "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"25"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.3")])]),_v(" on Sat, 8 Feb 2025, 16:36:29 UTC]"),_c('br'),_v(" "),_c('span',{staticClass:"dimmed"},[_c('small',[_c('small',[_v("favicon.ico of this site was made by "),_c('a',{attrs:{"href":"https://www.flaticon.com/authors/smashicons","title":"Smashicons"}},[_v("Smashicons")]),_v(" from "),_c('a',{attrs:{"href":"https://www.flaticon.com/","title":"Flaticon"}},[_v("www.flaticon.com")]),_v(" is licensed by "),_c('a',{attrs:{"href":"http://creativecommons.org/licenses/by/3.0/","title":"Creative Commons BY 3.0","target":"_blank"}},[_v("CC 3.0 BY")])])])])])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('p',[_v("["),_c('strong',[_v("This site was generated using "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"25"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.3")])]),_v(" on Sun, 9 Feb 2025, 7:49:50 UTC]"),_c('br'),_v(" "),_c('span',{staticClass:"dimmed"},[_c('small',[_c('small',[_v("favicon.ico of this site was made by "),_c('a',{attrs:{"href":"https://www.flaticon.com/authors/smashicons","title":"Smashicons"}},[_v("Smashicons")]),_v(" from "),_c('a',{attrs:{"href":"https://www.flaticon.com/","title":"Flaticon"}},[_v("www.flaticon.com")]),_v(" is licensed by "),_c('a',{attrs:{"href":"http://creativecommons.org/licenses/by/3.0/","title":"Creative Commons BY 3.0","target":"_blank"}},[_v("CC 3.0 BY")])])])])])])])} }]; \ No newline at end of file diff --git a/activities-dashboard.html b/activities-dashboard.html index 98fa22d1..b3a3f240 100644 --- a/activities-dashboard.html +++ b/activities-dashboard.html @@ -14,7 +14,7 @@

GitHub Activities Dashboard

  • This page contains a list of your NUS-OSS GitHub posts during the period eligible for course credit.
    For CS3282 students, the activity period varies based on when you finished CS3282.
  • The content of each panel body may not be exactly as it shows up on GitHub, as some crude sanitizations have been done to prevent post contents interfering with MarkBind parsing.
  • It goes without saying that GitHub activities are not the sole representation of your work. It's just one source of evidence only. So, don't put too much importance on what you see in this page.
    -Furthermore, the stats (i.e., posts counts) are not directly comparable between devs, as they are influenced by the type of work/project.
  • This page will be updated once in a while, in 1-2 week intervals.

[This page was last updated on 2024-05-07 @22:54]

CS3281

ARIF..ALID @Arif-Khalid 23 27+84 10 9


MISR..ITYA @MadLamprey 13 0+10 3 1


NERE.. BIN @NereusWB922 36 16+35 8 7


NGUY..UYEN @nknguyenhc 20 39+67 12 22


EYO ..EVIN @KevinEyo1 13 42+10 6 26


LAM ..FONG @LamJiuFong 8 36+13 2 14


WANG..TING @jingting1412 9 45+6 2 4


WANG..IWEN @yiwen101 14 92+6 7 21


XU S..UYAO @Tim-Siu 8 55+16 3 15


ALVI..S NG @supermii2 3 9+5 3 4


GEOR.. YAO @asdfghjkxd 15 50+38 9 5


JONA.. WEI @jonasongg 15 49+22 7 5


POON..RYAN @sopa301 20 47+43 11 8


CHIN..YUAN @mingyuanc 15 46+22 0 0


DOMI.. GIN @domoberzin 31 14+20 1 1


TYE ..QUES @marquestye 11 26+9 1 0


XENO..NONG @xenosf 17 13+11 3 1


YEO ..HENG @dishenggg 20 18+7 1 1


ZHU ..ANXI @yuanxi1 10 7+3 0 0



CS3282

GOH ..RIEL @gycgabriel 3 0+42 5 5


LEE ..SAAC @luminousleek 11 11+112 7 11


VIGN..IYER @vigneshsankariyer1234567890 5 0+43 1 4


WONG..HONG @cheehongw 8 10+45 7 11


CHAN..HENG @yucheng11122017 12 23+485 9 69


ELTO.. HAO @EltonGohJH 2 5+83 3 16


HANN.. XIN @kaixin-hc 12 3+201 7 67


LEE ..AVID @itsyme 4 5+62 5 5


CHAR..USAR @ckcherry23 2 0+226 11 23


DAVI.. ONG @vvidday 0 0+107 1 1


GOKU..AJIV @gok99 1 0+63 3 13


MARC.. KYE @MarcusTXK 0 0+63 3 4


CHAN..OLAS @Nicolascwy 30 27+172 7 11


DOMI.. JUN @domlimm 7 11+107 3 35


JAY ..TING @jayasting98 14 13+168 5 10


KEVI..TONG @kevin9foong 6 3+26 3 2


MOK ..RGUS @FergusMok 22 27+156 4 4


NEO ..QING @weiquu 34 4+332 24 58


ONG ..DRIC @cedricongjh 55 15+406 12 79


SIM ..NICE @EuniceSim142 18 16+62 0 0


ZHAN..QING @ziqing26 24 7+206 4 6


+Furthermore, the stats (i.e., posts counts) are not directly comparable between devs, as they are influenced by the type of work/project.
  • This page will be updated once in a while, in 1-2 week intervals.
  • [This page was last updated on 2024-05-07 @22:54]

    CS3281

    ARIF..ALID @Arif-Khalid 23 27+84 10 9


    MISR..ITYA @MadLamprey 13 0+10 3 1


    NERE.. BIN @NereusWB922 36 16+35 8 7


    NGUY..UYEN @nknguyenhc 20 39+67 12 22


    EYO ..EVIN @KevinEyo1 13 42+10 6 26


    LAM ..FONG @LamJiuFong 8 36+13 2 14


    WANG..TING @jingting1412 9 45+6 2 4


    WANG..IWEN @yiwen101 14 92+6 7 21


    XU S..UYAO @Tim-Siu 8 55+16 3 15


    ALVI..S NG @supermii2 3 9+5 3 4


    GEOR.. YAO @asdfghjkxd 15 50+38 9 5


    JONA.. WEI @jonasongg 15 49+22 7 5


    POON..RYAN @sopa301 20 47+43 11 8


    CHIN..YUAN @mingyuanc 15 46+22 0 0


    DOMI.. GIN @domoberzin 31 14+20 1 1


    TYE ..QUES @marquestye 11 26+9 1 0


    XENO..NONG @xenosf 17 13+11 3 1


    YEO ..HENG @dishenggg 20 18+7 1 1


    ZHU ..ANXI @yuanxi1 10 7+3 0 0



    CS3282

    GOH ..RIEL @gycgabriel 3 0+42 5 5


    LEE ..SAAC @luminousleek 11 11+112 7 11


    VIGN..IYER @vigneshsankariyer1234567890 5 0+43 1 4


    WONG..HONG @cheehongw 8 10+45 7 11


    CHAN..HENG @yucheng11122017 12 23+485 9 69


    ELTO.. HAO @EltonGohJH 2 5+83 3 16


    HANN.. XIN @kaixin-hc 12 3+201 7 67


    LEE ..AVID @itsyme 4 5+62 5 5


    CHAR..USAR @ckcherry23 2 0+226 11 23


    DAVI.. ONG @vvidday 0 0+107 1 1


    GOKU..AJIV @gok99 1 0+63 3 13


    MARC.. KYE @MarcusTXK 0 0+63 3 4


    CHAN..OLAS @Nicolascwy 30 27+172 7 11


    DOMI.. JUN @domlimm 7 11+107 3 35


    JAY ..TING @jayasting98 14 13+168 5 10


    KEVI..TONG @kevin9foong 6 3+26 3 2


    MOK ..RGUS @FergusMok 22 27+156 4 4


    NEO ..QING @weiquu 34 4+332 24 58


    ONG ..DRIC @cedricongjh 55 15+406 12 79


    SIM ..NICE @EuniceSim142 18 16+62 0 0


    ZHAN..QING @ziqing26 24 7+206 4 6


    diff --git a/activities-dashboard.page-vue-render.js b/activities-dashboard.page-vue-render.js index 36fbf748..50837db3 100644 --- a/activities-dashboard.page-vue-render.js +++ b/activities-dashboard.page-vue-render.js @@ -20,6 +20,6 @@ with(this){return _c('h1',{attrs:{"id":"cs3281"}},[_v("CS3281"),_c('a',{staticCl with(this){return _c('h1',{attrs:{"id":"cs3282"}},[_v("CS3282"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#cs3282","onclick":"event.stopPropagation()"}})])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('p',[_v("["),_c('strong',[_v("This site was generated using "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"25"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.3")])]),_v(" on Sat, 8 Feb 2025, 16:36:29 UTC]"),_c('br'),_v(" "),_c('span',{staticClass:"dimmed"},[_c('small',[_c('small',[_v("favicon.ico of this site was made by "),_c('a',{attrs:{"href":"https://www.flaticon.com/authors/smashicons","title":"Smashicons"}},[_v("Smashicons")]),_v(" from "),_c('a',{attrs:{"href":"https://www.flaticon.com/","title":"Flaticon"}},[_v("www.flaticon.com")]),_v(" is licensed by "),_c('a',{attrs:{"href":"http://creativecommons.org/licenses/by/3.0/","title":"Creative Commons BY 3.0","target":"_blank"}},[_v("CC 3.0 BY")])])])])])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('p',[_v("["),_c('strong',[_v("This site was generated using "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"25"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.3")])]),_v(" on Sun, 9 Feb 2025, 7:49:50 UTC]"),_c('br'),_v(" "),_c('span',{staticClass:"dimmed"},[_c('small',[_c('small',[_v("favicon.ico of this site was made by "),_c('a',{attrs:{"href":"https://www.flaticon.com/authors/smashicons","title":"Smashicons"}},[_v("Smashicons")]),_v(" from "),_c('a',{attrs:{"href":"https://www.flaticon.com/","title":"Flaticon"}},[_v("www.flaticon.com")]),_v(" is licensed by "),_c('a',{attrs:{"href":"http://creativecommons.org/licenses/by/3.0/","title":"Creative Commons BY 3.0","target":"_blank"}},[_v("CC 3.0 BY")])])])])])])])} }]; \ No newline at end of file diff --git a/cs3282-index.html b/cs3282-index.html index 0c2f5053..64c58a69 100644 --- a/cs3282-index.html +++ b/cs3282-index.html @@ -12,7 +12,7 @@ const baseUrl = '/2025' -

    CS3282 - 2025 Batch

    CATcher:

    MarkBind:

    RepoSense:

    TEAMMATES:

    CATcher

    ARIF KHALID

    Li Zhaoqi

    NGUYEN KHOI NGUYEN

    MarkBind

    Lee Hyung Woon

    RepoSense

    Chang Si Kai

    JONAS ONG SI WEI

    POON YIP HANG, RYAN

    TEAMMATES

    DOMINIC BERZIN CHUA WAY GIN

    Qiu Jiasheng, Jason

    XENOS FIORENZO ANONG

    ZHU YUANXI

    +

    CS3282 - 2025 Batch

    CATcher:

    MarkBind:

    RepoSense:

    TEAMMATES:

    CATcher

    ARIF KHALID

    Li Zhaoqi

    NGUYEN KHOI NGUYEN

    MarkBind

    Lee Hyung Woon

    RepoSense

    Chang Si Kai

    JONAS ONG SI WEI

    POON YIP HANG, RYAN

    TEAMMATES

    DOMINIC BERZIN CHUA WAY GIN

    Qiu Jiasheng, Jason

    XENOS FIORENZO ANONG

    ZHU YUANXI

    diff --git a/cs3282-index.page-vue-render.js b/cs3282-index.page-vue-render.js index 32337a58..c3a79395 100644 --- a/cs3282-index.page-vue-render.js +++ b/cs3282-index.page-vue-render.js @@ -44,6 +44,6 @@ with(this){return _c('h1',{attrs:{"id":"reposense"}},[_v("RepoSense"),_c('a',{st with(this){return _c('h1',{attrs:{"id":"teammates"}},[_v("TEAMMATES"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#teammates","onclick":"event.stopPropagation()"}})])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('p',[_v("["),_c('strong',[_v("This site was generated using "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"25"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.3")])]),_v(" on Sat, 8 Feb 2025, 16:36:29 UTC]"),_c('br'),_v(" "),_c('span',{staticClass:"dimmed"},[_c('small',[_c('small',[_v("favicon.ico of this site was made by "),_c('a',{attrs:{"href":"https://www.flaticon.com/authors/smashicons","title":"Smashicons"}},[_v("Smashicons")]),_v(" from "),_c('a',{attrs:{"href":"https://www.flaticon.com/","title":"Flaticon"}},[_v("www.flaticon.com")]),_v(" is licensed by "),_c('a',{attrs:{"href":"http://creativecommons.org/licenses/by/3.0/","title":"Creative Commons BY 3.0","target":"_blank"}},[_v("CC 3.0 BY")])])])])])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('p',[_v("["),_c('strong',[_v("This site was generated using "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"25"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.3")])]),_v(" on Sun, 9 Feb 2025, 7:49:50 UTC]"),_c('br'),_v(" "),_c('span',{staticClass:"dimmed"},[_c('small',[_c('small',[_v("favicon.ico of this site was made by "),_c('a',{attrs:{"href":"https://www.flaticon.com/authors/smashicons","title":"Smashicons"}},[_v("Smashicons")]),_v(" from "),_c('a',{attrs:{"href":"https://www.flaticon.com/","title":"Flaticon"}},[_v("www.flaticon.com")]),_v(" is licensed by "),_c('a',{attrs:{"href":"http://creativecommons.org/licenses/by/3.0/","title":"Creative Commons BY 3.0","target":"_blank"}},[_v("CC 3.0 BY")])])])])])])])} }]; \ No newline at end of file diff --git a/index.html b/index.html index d119eb02..b14a7df0 100644 --- a/index.html +++ b/index.html @@ -12,7 +12,7 @@ const baseUrl = '/2025' -

    CS3281 - 2025 Batch

    CATcher:

    MarkBind:

    RepoSense:

    TEAMMATES:

    CATcher

    ISAAC NG JUN JIE

    KOO YU CONG

    LOH ZE QING, NORBERT

    SOH ZHENG YANG, MARCUS

    TNG WEN XI

    MarkBind

    ADRIAN LEONARDO LIANG

    CHAN GER TECK

    CHEAH GEE NUNG, IAN

    JAVIER TAN MENG WEE

    YU CHENBO

    RepoSense

    ALEXANDER LISWANDY

    CHEN YIXUN

    HING YEN XING

    NG YIN JOE

    WONG LI YUAN

    TEAMMATES

    DHIRAPUTTA PATHAMA TENGARA

    LI MINGYANG

    POH JUN KANG

    TENG WEI LOON

    WONG XING HUI BERTRAND

    +

    CS3281 - 2025 Batch

    CATcher:

    MarkBind:

    RepoSense:

    TEAMMATES:

    CATcher

    ISAAC NG JUN JIE

    KOO YU CONG

    LOH ZE QING, NORBERT

    SOH ZHENG YANG, MARCUS

    TNG WEN XI

    MarkBind

    ADRIAN LEONARDO LIANG

    CHAN GER TECK

    CHEAH GEE NUNG, IAN

    JAVIER TAN MENG WEE

    YU CHENBO

    RepoSense

    ALEXANDER LISWANDY

    CHEN YIXUN

    HING YEN XING

    NG YIN JOE

    WONG LI YUAN

    TEAMMATES

    DHIRAPUTTA PATHAMA TENGARA

    LI MINGYANG

    POH JUN KANG

    TENG WEI LOON

    WONG XING HUI BERTRAND

    diff --git a/index.page-vue-render.js b/index.page-vue-render.js index da77c9c2..073c7e12 100644 --- a/index.page-vue-render.js +++ b/index.page-vue-render.js @@ -1,7 +1,7 @@ var pageVueRenderFn = function anonymous( ) { -with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"fixed":""}},[_c('navbar',{attrs:{"placement":"top","type":"primary"},scopedSlots:_u([{key:"brand",fn:function(){return [_c('a',{staticClass:"navbar-brand",attrs:{"href":"/2025/index.html","title":"Home"}},[_v("CS3281&2-2025/Students")])]},proxy:true},{key:"right",fn:function(){return [_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"https://github.com/nus-cs3281/2025"}},[_c('span',[_c('span',{staticClass:"fab fa-github",attrs:{"aria-hidden":"true"}})])])])]},proxy:true}])},[_v(" "),_c('dropdown',{staticClass:"nav-link",scopedSlots:_u([{key:"header",fn:function(){return [_v("CS3281")]},proxy:true}])},[_v(" "),_c('li',[_c('a',{staticClass:"dropdown-item",attrs:{"href":"/2025/index.html"}},[_v("Students")])]),_v(" "),_c('li',[_c('a',{staticClass:"dropdown-item",attrs:{"href":"/2025/students/knowledge.html"}},[_v("Knowledge")])]),_v(" "),_c('li',[_c('a',{staticClass:"dropdown-item",attrs:{"href":"https://nus-cs3281.github.io/2025-dashboard/?search=&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByAuthors&breakdown=false"}},[_v("Code Dashboard")])]),_v(" "),_c('li',[_c('a',{staticClass:"dropdown-item",attrs:{"href":"/2025/activities-dashboard.html"}},[_v("Activities Dashboard")])])]),_v(" "),_c('dropdown',{staticClass:"nav-link",scopedSlots:_u([{key:"header",fn:function(){return [_v("CS3282")]},proxy:true}])},[_v(" "),_c('li',[_c('a',{staticClass:"dropdown-item",attrs:{"href":"/2025/cs3282-index.html"}},[_v("Students")])]),_v(" "),_c('li',[_c('a',{staticClass:"dropdown-item",attrs:{"href":"/2025/students/talksSchedule.html"}},[_v("Lightning Talks")])]),_v(" "),_c('li',[_c('a',{staticClass:"dropdown-item",attrs:{"href":"/2025/activities-dashboard.html"}},[_v("Activities Dashboard")])])]),_v(" "),_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"/2025/instructions.html"}},[_v("Instructions")])]),_v(" "),_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"https://nus-cs3281.github.io/website/"}},[_v("CS3281&2 Website "),_c('span',[_c('span',{staticClass:"glyphicon glyphicon-share-alt",attrs:{"aria-hidden":"true"}})])])])],1)],1),_v(" "),_c('div',{attrs:{"id":"flex-body"}},[_c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_m(0),_v(" "),_m(1),_v(" "),_m(2),_v(" "),_m(3),_v(" "),_m(4),_v(" "),_m(5),_v(" "),_m(6),_v(" "),_m(7),_v(" "),_m(8),_v(" "),_m(9),_v(" "),_c('div',[_c('box',[_c('h2',{attrs:{"id":"isaac-ng-jun-jie"}},[_v("ISAAC NG JUN JIE"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#isaac-ng-jun-jie","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"container"},[_c('div',{staticClass:"row"},[_c('div',{staticClass:"col"},[_c('img',{attrs:{"src":"/2025/students/Izn432/photo.png","width":"100"}}),_c('br')]),_v(" "),_c('div',{staticClass:"col"},[_c('p',[_c('strong',[_v("GitHub:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://www.github.com/IzN432"}},[_v("https://www.github.com/IzN432")])]),_c('br')]),_v(" "),_c('p',[_c('strong',[_v("Projects:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher"}},[_v("CATcher")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher"}},[_v("WATcher")])])])])])]),_v(" "),_c('p'),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Progress")])])]},proxy:true}])},[_v(" "),_c('div',[_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("PR")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Opened PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1302"}},[_v("Update to use more typescript types #1302")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Merged PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1303"}},[_v("Fix formats in the comments #1303")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Opened PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1302"}},[_v("Solve Github Actions failing for macos-setup-and-tests #394")])])]),_v(" "),_c('tr',[_c('td',[_v("3")]),_v(" "),_c('td',[_v("Contributed to issue: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/issues/398"}},[_v("Remove all button doesn't work #398")])])])])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Knowledge gained")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"angular"}},[_v("Angular"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#angular","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Angular components are split into three parts, "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("*.component.ts")]),_v(", "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("*.component.html")]),_v(" and "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("*.component.css")])]),_v(" "),_c('h4',{attrs:{"id":"component-ts"}},[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("*.component.ts")]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#component-ts","onclick":"event.stopPropagation()"}})]),_v(" "),_c('pre',[_c('code',{pre:true,attrs:{"class":"hljs"}},[_c('span',[_v("@Component({\n")]),_c('span',[_v(" selector: 'app-auth',\n")]),_c('span',[_v(" templateUrl: './auth.component.html',\n")]),_c('span',[_v(" styleUrls: ['./auth.component.css']\n")]),_c('span',[_v("})\n")])])]),_c('p',[_v("This segment is found at the top of the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("*.component.ts")]),_v(" files.")]),_v(" "),_c('ol',[_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("selector")]),_v(" indicates the keyword that will be used in "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("*.component.html")]),_v(" files to identify this component. For example, "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v(" ")])]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("templateUrl")]),_v(" indicates the filepath to the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("*.component.html")]),_v(" file.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("styleUrls")]),_v(" indicates the filepath(s) to the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("*.component.css")]),_v(" file(s).")])]),_v(" "),_c('h4',{attrs:{"id":"component-html"}},[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("*.component.html")]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#component-html","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("This is the template file. Template files use mostly HTML syntax, with a bit of angular specific syntax included. This includes the structural directives such as *ngIf, *ngFor, etc. The "),_c('a',{attrs:{"href":"https://v17.angular.io/guide/architecture-components"}},[_v("documentation")]),_v(" is quite sufficient for understanding the angular syntax.")]),_v(" "),_c('h4',{attrs:{"id":"component-css"}},[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("*.component.css")]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#component-css","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("This is a stylesheet, using normal css. There is a "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("::ng-deep")]),_v(" selector available, which promotes a component style to global style.")]),_v(" "),_c('h3',{attrs:{"id":"arcsecond"}},[_v("Arcsecond"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#arcsecond","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Arcsecond is a string parsing library for javascript. An example arcsecond parser is as follows:")]),_v(" "),_c('pre',[_c('code',{pre:true,attrs:{"class":"hljs"}},[_c('span',[_v("export const TutorModerationTodoParser = coroutine(function* () {\n")]),_c('span',[_v(" yield str(TODO_HEADER);\n")]),_c('span',[_v(" yield whitespace;\n")]),_c('span',[_v("\n")]),_c('span',[_v(" const tutorResponses = yield many1(ModerationSectionParser);\n")]),_c('span',[_v("\n")]),_c('span',[_v(" const result: TutorModerationTodoParseResult = {\n")]),_c('span',[_v(" disputesToResolve: tutorResponses\n")]),_c('span',[_v(" };\n")]),_c('span',[_v(" return result;\n")]),_c('span',[_v("});\n")])])]),_c('ol',[_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("str(TODO_HEADER)")]),_v(" matches the starting of the string with "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("TODO_HEADER")]),_v(".")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("whitespace")]),_v(" matches the next part of the string with one or more whitespaces.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("many1(ModerationSectionParser)")]),_v(" applies the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("ModerationSectionParser")]),_v(" one or more times.")])]),_v(" "),_c('h3',{attrs:{"id":"graphql"}},[_v("GraphQL"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#graphql","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("GraphQL is a architecture for building APIs like REST. Unlike REST where the server defines the structure of the response, in GraphQL, the client and request the exact data they need.")]),_v(" "),_c('h3',{attrs:{"id":"node-14-x-support-on-macos"}},[_v("Node 14.x support on macos"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#node-14-x-support-on-macos","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Apple laptops changed to using ARM64 architecture back in 2020. This meant that Node versions released before then were not directly supported by the ARM64 architecture. This caused issues with the github actions. There is a workaround for this by running "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("arch -x86_64")]),_v(" and manually installing node instead of using the setup-node Github action, but the simpler solution was to upgrade the test to use Node version 16.x.")]),_v(" "),_c('p',[_v("...")])])])],1)],1),_v(" "),_c('div',[_c('box',[_c('h2',{attrs:{"id":"koo-yu-cong"}},[_v("KOO YU CONG"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#koo-yu-cong","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"container"},[_c('div',{staticClass:"row"},[_c('div',{staticClass:"col"},[_c('img',{attrs:{"src":"/2025/students/yucongkoo/photo.png","width":"100"}}),_c('br')]),_v(" "),_c('div',{staticClass:"col"},[_c('p',[_c('strong',[_v("GitHub:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://www.github.com/yucongkoo"}},[_v("https://www.github.com/yucongkoo")])]),_c('br')]),_v(" "),_c('p',[_c('strong',[_v("Projects:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher"}},[_v("CATcher")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher"}},[_v("WATcher")])])])])])]),_v(" "),_c('p'),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Progress")])])]},proxy:true}])},[_v(" "),_c('div',[_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Merged PR : "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1291"}},[_v("Fix formatting style of issue-table component")])])]),_v(" "),_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Submitted and Researched Issue: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/issues/1292"}},[_v("Playwright Github workflow failing #1292")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Merged PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1298"}},[_v("Downgrade ubuntu version in playwright.yml #1298")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Participated in Issue Investigation : "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/issues/1304#issuecomment-2609636737"}},[_v("Workflow failing due to updated nested dependencies #1304")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Reported and Researched Bug: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/issues/1310"}},[_v("Problematic RestGithubIssueState value #1310")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Merged PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1311"}},[_v("Fix RestGithubIssueState value for closed states #1311")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Initiated and participated in discussion of UI and user workflow for new bug-trimming phase: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/issues/1309"}},[_v("Create new UI for bug reporting phase that allows deleting and un-deleting of issues #1309")])])])])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Knowledge gained")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"nvm-node-version-manager"}},[_v("NVM (Node Version Manager)"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#nvm-node-version-manager","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Issue faced: CATcher uses node v16.x while WATcher uses node v14.x, it is hard to switch between node versions quickly when working on both projects")]),_v(" "),_c('p',[_v("Tool used: Used nvm to easily manage and switch between different node versions locally")]),_v(" "),_c('h3',{attrs:{"id":"angular-2"}},[_v("Angular"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#angular-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h4',{attrs:{"id":"components-and-modules"}},[_v("Components and Modules"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#components-and-modules","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("A typical component in Angular consists of 3 files:")]),_v(" "),_c('ul',[_c('li',[_v("A html file that defines the layout of the component")]),_v(" "),_c('li',[_v("A css file that provides styling to the UI")]),_v(" "),_c('li',[_v("A typescript file that controls the logic and behaviour of the application, typically handles the data of the application too")])]),_v(" "),_c('p',[_v("Each component can have a module file where we can state the components/modules that this component is dependent on (i.e. the imports array) and the components that is provided by this module (i.e. the declarations array). This helps increasing the modularity and scalability of the whole application.")]),_v(" "),_c('p',[_v("As a developer coming from React, here are some clear differences I have observed:")]),_v(" "),_c('ul',[_c('li',[_v("There is no concept of states in Angular and the data passing is 2-ways, when the user updates from the UI, the value is automatically updated in the component and vice versa, whereas in React we would have to use states and explicitly update the states via setState or similar functions.")]),_v(" "),_c('li',[_v("Instead of defining the layout of componenet and logic in the same file, Angular split them into 2 seperate files (i.e. the html and typescript file), personally I felt that this split helps enforce the MVC architecture more strictly, but also imposes more restrictions when it comes to components that have tightly coupled logic")])]),_v(" "),_c('h3',{attrs:{"id":"catcher-2"}},[_v("CATcher"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#catcher-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h4',{attrs:{"id":"issuetablescomponent-and-how-issues-are-being-shown-in-tables"}},[_v("IssueTablesComponent and how issues are being shown in tables"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#issuetablescomponent-and-how-issues-are-being-shown-in-tables","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("While working on issue "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/issues/1309"}},[_v("#1309")]),_v(", I had to delve deep into how the the IssueTablesComponent is implemented in order to create new tables. A few meaningful observations learnt is summarised as follows:")]),_v(" "),_c('ul',[_c('li',[_v("The issues displayed in the table is mainly dependent on 2 things,\n"),_c('ul',[_c('li',[_v("The base issues data provided by "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("IssueService")]),_v(", which is initialized based on "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("IssuesFilter")]),_v(", and will periodically pull the issues from github")]),_v(" "),_c('li',[_v("The "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("filters")]),_v(" we inject when creating the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("IssueTablesComponent")]),_v(", where the base issues can be filtered down to the issues that we are concerned of")]),_v(" "),_c('li',[_v("The action buttons and its respective functionalities are pre-defined in the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("IssueTableComponent")]),_v(" itself, we only specify the action buttons that we want when creating the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("IssuesTablesComponent")]),_v(" through the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("actions")]),_v(" input.")])])])])])])],1)],1),_v(" "),_c('div',[_c('box',[_c('h2',{attrs:{"id":"loh-ze-qing-norbert"}},[_v("LOH ZE QING, NORBERT"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#loh-ze-qing-norbert","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"container"},[_c('div',{staticClass:"row"},[_c('div',{staticClass:"col"},[_c('img',{attrs:{"src":"/2025/students/NorbertLoh/photo.png","width":"100"}}),_c('br')]),_v(" "),_c('div',{staticClass:"col"},[_c('p',[_c('strong',[_v("GitHub:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/NorbertLoh"}},[_v("https://github.com/NorbertLoh")])]),_c('br')]),_v(" "),_c('p',[_c('strong',[_v("Projects:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher"}},[_v("CATcher")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher"}},[_v("WATcher")])])])])])]),_v(" "),_c('p'),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Progress")])])]},proxy:true}])},[_v(" "),_c('div',[_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("PR")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Merged PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1295"}},[_v("Add white-space style to markdown code block css #1295")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Submitted Issue: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/issues/1299"}},[_v("Invalid tester response example #1299")])])]),_v(" "),_c('tr',[_c('td',[_v("3")]),_v(" "),_c('td',[_v("Submitted Issue: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/issues/399"}},[_v("Remove magic strings for filters #399")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Opened PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/400"}},[_v("Remove magic strings #400")])])])])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Knowledge gained")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"ngx-markdown"}},[_v("ngx-markdown"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#ngx-markdown","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I learned about the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("ngx-markdown")]),_v(" library while I was working on a fix to preserve whitespace when converting Markdown to HTML. "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("ngx-markdown")]),_v(" combines multiple different language parsers and renders them in one library. "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("ngx-markdown")]),_v(" supports Marked, Prism.js, Emoji-Toolkit, KaTeX, Mermaid, and Clipboard.js. I learned about configuring the options for the Markdown HTML element.")]),_v(" "),_c('h3',{attrs:{"id":"marked"}},[_v("Marked"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#marked","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Marked is the main parser we use for our comment editor in creating/editing issues and responses. I learned that any text that we write in Markdown syntax is converted into HTML elements using Marked. I found out that we can actually override how Marked generates the HTML elements, and we can add more attributes like classes, styles, and even modify the text before rendering it.")]),_v(" "),_c('h3',{attrs:{"id":"nvm-windows"}},[_v("nvm-windows"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#nvm-windows","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("WATcher requires node 14 in order to "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("npm install")]),_v(" some of its dependencies. However, instead of having to install and reinstall a different node version between different projects, I can use "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("nvm-windows")]),_v(" to install multiple node versions and switch between them. However, the latest version of "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("nvm-windows")]),_v(" has some issues if youwant to install node 14. After some debugging, I found out that "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("nvm-windows v1.1.11")]),_v(" can install node 14 with no issues.")])])])],1)],1),_v(" "),_c('div',[_c('box',[_c('h2',{attrs:{"id":"soh-zheng-yang-marcus"}},[_v("SOH ZHENG YANG, MARCUS"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#soh-zheng-yang-marcus","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"container"},[_c('div',{staticClass:"row"},[_c('div',{staticClass:"col"},[_c('img',{attrs:{"src":"/2025/students/HollaG/photo.png","width":"100"}}),_c('br')]),_v(" "),_c('div',{staticClass:"col"},[_c('p',[_c('strong',[_v("GitHub:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://www.github.com/hollag"}},[_v("https://www.github.com/hollag")])]),_c('br')]),_v(" "),_c('p',[_c('strong',[_v("Projects:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher"}},[_v("CATcher")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher"}},[_v("WATcher")])])])])])]),_v(" "),_c('p'),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Progress")])])]},proxy:true}])},[_v(" "),_c('div',[_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Submitted PR "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/391"}},[_v("#391")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Contributed to issue "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/issues/363"}},[_v("#363")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Created issue "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/issues/396"}},[_v("#396")])])]),_v(" "),_c('tr',[_c('td',[_v("3")]),_v(" "),_c('td',[_v("Created issue "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/issues/401"}},[_v("#401")])])])])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Knowledge gained")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"tool-technology-1"}},[_v("Tool/Technology 1"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#tool-technology-1","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h4',{attrs:{"id":"angular-3"}},[_v("Angular"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#angular-3","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Angular is the main tool used in both CATcher and WATcher. It is based on TypeScript.")]),_v(" "),_c('p',[_v("Angular is a component-based framework.\nEach component is generated with:")]),_v(" "),_c('ol',[_c('li',[_v("*.component.ts")]),_v(" "),_c('li',[_v("*.component.html")]),_v(" "),_c('li',[_v("*.component.css")])]),_v(" "),_c('p',[_v("Component state is maintained in the .ts file. These state variables can be bound to HTML elements through use of curly braces {{}}.")]),_v(" "),_c('p',[_v("Angular offers directives such as ngIf, ngFor that allow us to \"use\" JS in the HTML files.")]),_v(" "),_c('p',[_v("Services are used for processing, for tasks that don't involve what the user sees. This is different from the .component file, which directly handles things the users see.\nServices are kept in a separate directory /services/*.")]),_v(" "),_c('h3',{attrs:{"id":"tool-technology-2"}},[_v("Tool/Technology 2"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#tool-technology-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("...")])])])],1)],1),_v(" "),_c('div',[_c('box',[_c('h2',{attrs:{"id":"tng-wen-xi"}},[_v("TNG WEN XI"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#tng-wen-xi","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"container"},[_c('div',{staticClass:"row"},[_c('div',{staticClass:"col"},[_c('img',{attrs:{"src":"/2025/students/wx-03/photo.png","width":"100"}}),_c('br')]),_v(" "),_c('div',{staticClass:"col"},[_c('p',[_c('strong',[_v("GitHub:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://www.github.com/wx-03"}},[_v("https://www.github.com/wx-03")])]),_c('br')]),_v(" "),_c('p',[_c('strong',[_v("Projects:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher"}},[_v("CATcher")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher"}},[_v("WATcher")])])])])])]),_v(" "),_c('p'),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Progress")])])]},proxy:true}])},[_v(" "),_c('div',[_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Submitted issue: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/issues/395"}},[_v("'View current page on GitHub' button uses an invalid filter #395")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Merged PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/392"}},[_v("Show issues and PRs without milestones in 'Contributions' preset view #392")])])]),_v(" "),_c('tr',[_c('td',[_v("3")]),_v(" "),_c('td',[_v("Submitted issue: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/issues/397"}},[_v("Invalid repo gets saved to suggestions #397")])])]),_v(" "),_c('tr',[_c('td',[_v("3")]),_v(" "),_c('td',[_v("Submitted issue: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/issues/398"}},[_v("Remove all button doesn't work #398")])])])])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Knowledge gained")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"angular-4"}},[_v("Angular"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#angular-4","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("CATcher and WATcher are both built using the Angular framework, which is a single-page web appliation framework. Angular comes with a CLI tool to accelerate development.")]),_v(" "),_c('h4',{attrs:{"id":"components"}},[_v("Components"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#components","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_v("Components are the fundamental building blocks of Angular applications.")]),_v(" "),_c('li',[_v("Generating a component will create a TypeScript file, a HTML file, a CSS file, and a test file.")]),_v(" "),_c('li',[_v("The TypeScript class defines the interaction of the HTML template and the rendered DOM structure, while the style sheet describes its appearance.")]),_v(" "),_c('li',[_v("The "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("@Component")]),_v(" decorator in the .ts file identifies the class immediately below it as a component class, and specifies its metadata. It associates a template with the component by referencing the .html file (or with inline code).")]),_v(" "),_c('li',[_v("Template syntax\n"),_c('ul',[_c('li',[_v("A template contains regular html as well as Angular template syntax, which alters the HTML based on the application's logic and the state of application and DOM data.")]),_v(" "),_c('li',[_v("Templates can use:\n"),_c('ul',[_c('li',[_v("Data binding")]),_v(" "),_c('li',[_v("Pipes")]),_v(" "),_c('li',[_v("Directives")])])])])])])])])],1)],1),_v(" "),_m(10),_v(" "),_c('div',[_c('box',[_c('h2',{attrs:{"id":"adrian-leonardo-liang"}},[_v("ADRIAN LEONARDO LIANG"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#adrian-leonardo-liang","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"container"},[_c('div',{staticClass:"row"},[_c('div',{staticClass:"col"},[_c('img',{attrs:{"src":"/2025/students/AgentHagu/photo.png","width":"100"}}),_c('br')]),_v(" "),_c('div',{staticClass:"col"},[_c('p',[_c('strong',[_v("GitHub:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/AgentHagu"}},[_v("https://github.com/AgentHagu")])]),_c('br')]),_v(" "),_c('p',[_c('strong',[_v("Projects:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind"}},[_v("MarkBind")])])])])])]),_v(" "),_c('p'),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Progress")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"markbind-2"}},[_v("MarkBind"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#markbind-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Authored PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2584"}},[_v("Add optional absolute char indexing for highlighting #2584")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Responded to contributor queries: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2584"}},[_v("#2584")])])])])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Knowledge gained")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"markbind-highlighter-component"}},[_v("MarkBind Highlighter Component"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#markbind-highlighter-component","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Learned the underlying workings of MarkBind's Highlighter component and how it parses highlighter rules in order to determine the characters or lines to highlight. Learned how to implement an enhancement to the existing feature and add relevant tests and documentation.")]),_v(" "),_c('h3',{attrs:{"id":"typescript"}},[_v("TypeScript"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#typescript","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("TypeScript is a programming language that builds upon JavaScript by adding static typing, enabling developers to catch errors at compile time and write more maintainable code as compared to JavaScript.")]),_v(" "),_c('h4',{attrs:{"id":"resources"}},[_v("Resources:"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#resources","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ol',[_c('li',[_c('a',{attrs:{"href":"https://www.typescriptlang.org/docs/handbook/intro.html"}},[_v("TypeScript Handbook")]),_v(" - Official documentation for TypeScript")])])])])],1)],1),_v(" "),_c('div',[_c('box',[_c('h2',{attrs:{"id":"chan-ger-teck"}},[_v("CHAN GER TECK"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#chan-ger-teck","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"container"},[_c('div',{staticClass:"row"},[_c('div',{staticClass:"col"},[_c('img',{attrs:{"src":"/2025/students/gerteck/photo.png","width":"100"}}),_c('br')]),_v(" "),_c('div',{staticClass:"col"},[_c('p',[_c('strong',[_v("GitHub:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://www.github.com/gerteck"}},[_v("https://www.github.com/gerteck")])]),_c('br')]),_v(" "),_c('p',[_c('strong',[_v("Projects:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind"}},[_v("MarkBind")]),_v(", "),_c('a',{attrs:{"href":""}},[_v("Project2")])])])])])]),_v(" "),_c('p'),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Progress")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"summary"}},[_v("Summary"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#summary","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Over the semester, I will be working on MarkBind.")]),_v(" "),_c('p',[_v("The work will build on previous work done, recorded "),_c('a',{attrs:{"href":"https://docs.google.com/document/d/1PjA6jfa7G_ZNjc8zSWi1hVSMmhbrGUY95k0ytyDCo-Y/edit?usp=sharing"}},[_v("here")])]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Authored PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2568"}},[_v("Add Pagefind Plugin #2568")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2584"}},[_v("#2584")])])]),_v(" "),_c('tr',[_c('td',[_v("3")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2589"}},[_v("#2589")])])]),_v(" "),_c('tr',[_c('td',[_v("3")]),_v(" "),_c('td',[_v("Opened Issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2590"}},[_v("Curly braces cause fail #2590")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Opened Issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2595"}},[_v("Update eslint gitignore #2595")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Authored PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2596"}},[_v("Vue Migration #2596")])])])])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Knowledge gained")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"tool-technology"}},[_v("Tool/Technology"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#tool-technology","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("List the aspects you learned, and the resources you used to learn them, and a brief summary of each resource.")]),_v(" "),_c('h2',{attrs:{"id":"internal-tools-technology"}},[_v("Internal Tools/Technology"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#internal-tools-technology","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h3',{attrs:{"id":"how-markbind-works-overview-of-everything"}},[_v("How MarkBind Works (Overview of everything)"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#how-markbind-works-overview-of-everything","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("In order to make more well informed changes and tackle deeper issues, I decided to cover the whole codebase of Markbind just so I could have a much fuller understanding of how different parts worked together.")]),_v(" "),_c('p',[_v("While doing so, I used a MarkBind site to document the architecture and different packages and classes in the MarkBind codebase. The site can be viewed here: "),_c('a',{attrs:{"href":"https://gerteck.github.io/mb-architecture/"}},[_v("https://gerteck.github.io/mb-architecture/")])]),_v(" "),_c('h3',{attrs:{"id":"markbind-s-search-utility"}},[_v("Markbind's Search Utility"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#markbind-s-search-utility","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h4',{attrs:{"id":"how-native-markbind-search-works"}},[_v("How Native MarkBind Search works"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#how-native-markbind-search-works","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_c('strong',[_v("Collection of Title and headings in generation:")])]),_v(" "),_c('ul',[_c('li',[_v("We trace the website generation in "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Site/index.ts")]),_v(".")]),_v(" "),_c('li',[_v("When building source files, during the page generation process, "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Page.collectHeadingsAndKeywords")]),_v(" records headings and keywords inside rendered page into this.headings and this.keywords respectively.")]),_v(" "),_c('li',[_v("When writing site data, the title, headings, keywords are collected into pages object.")])]),_v(" "),_c('p',[_c('strong',[_v("Page Generation and Vue Initialization")])]),_v(" "),_c('ul',[_c('li',[_v("In "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("core-web/src/index.js")]),_v(", the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("setupWithSearch()")]),_v(" updates the SearchData by collecting the pages from the site data.\n"),_c('ul',[_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("setupWithSearch()")]),_v(" is added as a script in the file template "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("page.njk")]),_v(" used to render the HTML structure of Markbind pages.")]),_v(" "),_c('li',[_v("This file template is used during the page generation process.")])])]),_v(" "),_c('li',[_v("Note also that "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("VueCommonAppFactory.js")]),_v(" provides a factory function (appFactory) to set up the common data and methods for Vue application shared between server-side and client-side, and provides the common data properties and methods.\n"),_c('ul',[_c('li',[_v("In particular, "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("searchData[]")]),_v(" and "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("searchCallback()")]),_v(", which are relevant in the following portion.")]),_v(" "),_c('li',[_v("When using "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("")]),_v(", this is where to use MarkBind's search functionality, we set the appropriate values: "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v(" ")])])])])]),_v(" "),_c('p',[_c('strong',[_v("Vue Components: Searchbar/SearchbarPageItem.vue")]),_v(" "),_c('strong',[_v("Searchbar.vue")])]),_v(" "),_c('ul',[_c('li',[_v("The searchbar uses the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("searchData[]")]),_v(" in "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("data")]),_v(", filters and ranks the data based on keyword matches and populates the dropdown with "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("searchbarPageItems")]),_v(".")]),_v(" "),_c('li',[_v("It calls the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("on-hit")]),_v(" function (which "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("searchCallback")]),_v(" is passed into) when a search result is selected.")]),_v(" "),_c('li',[_v("Presentation wise, each search result is represented by a "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("searchbar-pageitem")]),_v(" vue component.")])]),_v(" "),_c('p',[_c('strong',[_v("SearchbarPageItem.vue")])]),_v(" "),_c('ul',[_c('li',[_v("Presents the component conditionally based on whether item is a heading or a page title.")])]),_v(" "),_c('h4',{attrs:{"id":"how-the-new-markbind-pagefind-plugin-works"}},[_v("How the new Markbind PageFind Plugin Works"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#how-the-new-markbind-pagefind-plugin-works","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("About "),_c('a',{attrs:{"href":"https://pagefind.app/"}},[_v("PageFind")]),_v(": A fully static search library that aims to perform well on large sites, while using as little of users bandwidth\nas possible, and without hosting any infrastructure.")]),_v(" "),_c('p',[_c('strong',[_v("Documentation:")])]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://pagefind.app/docs/node-api/"}},[_v("PageFind NodeJS Indexing API")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/CloudCannon/pagefind/blob/production-docs/pagefind_web_js/types/index.d.ts"}},[_v("The types returned by Pagefind’s JavaScript search API")])])]),_v(" "),_c('h4',{attrs:{"id":"integration-of-pagefind-into-markbind"}},[_c('strong',[_v("Integration of Pagefind into MarkBind")]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#integration-of-pagefind-into-markbind","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("It runs after the website framework, and only requires the folder containing the built static files of the website. A short explanation of how it works would be:")]),_v(" "),_c('ul',[_c('li',[_v("PageFind indexes the static files\n"),_c('ul',[_c('li',[_v("If pagefind is included as a plugin, we indexSites with PageFind, which writes the index files _site/pagefind")])])]),_v(" "),_c('li',[_v("Plugin exposes a pagefind JS API for searching\n"),_c('ul',[_c('li',[_v("Alternatively, use pagefind default UI for searching. This is done by processes containers with "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("id=\"pagefind-search-input\"")]),_v(", and initialing a default PageFindUI instance on it, not unlike how algolia search works.")])])]),_v(" "),_c('li',[_v("This JS API is used by a custom Vue component searchbar.")])]),_v(" "),_c('h2',{attrs:{"id":"external-tools-technology"}},[_v("External Tools/Technology"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#external-tools-technology","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h3',{attrs:{"id":"vue"}},[_v("Vue"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#vue","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h4',{attrs:{"id":"vue-2-to-vue-3"}},[_v("Vue 2 to Vue 3"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#vue-2-to-vue-3","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_c('a',{attrs:{"href":"https://v3-migration.vuejs.org/migration-build"}},[_v("https://v3-migration.vuejs.org/migration-build")])]),_v(" "),_c('p',[_v("MarkBind (v5.5.3) is currently using Vue 2. However, Vue 2 has reached EOL and limits the extensibility and maintainability of MarkBind, especially the vue-components package. (UI Library Package).")]),_v(" "),_c('p',[_v("Vue 2 components can be authored in two different API styles: Option API and Composition API. Read the difference "),_c('a',{attrs:{"href":"https://dev.to/sucodelarangela/vue3-options-api-vs-composition-api-en-1fbo#:~:text=However%2C%20with%20the%20release%20of,known%20as%20the%20Options%20API."}},[_v("here")]),_v(" It was interesting to read the difference between the two.")]),_v(" "),_c('ul',[_c('li',[_v("The Option API organizes code into predefined options like data, methods, and computed, making it simpler and more beginner-friendly but less flexible for complex logic.")]),_v(" "),_c('li',[_v("In contrast, the Composition API uses a setup() function and reactive utilities like ref and reactive, allowing logic to be grouped by feature for better modularity and reusability. While the Option API relies on mixins for reuse, which can lead to conflicts, the Composition API enables cleaner and more scalable code through composable functions.\n"),_c('ul',[_c('li',[_v("Additionally, the Composition API offers superior TypeScript support and is better suited for large, complex applications, though it has a steeper learning curve compared to the straightforward Option API.")])])])]),_v(" "),_c('blockquote',[_c('p',[_v("Server-side rendering: the migration build can be used for SSR, but migrating a custom SSR setup is much more involved. The general idea is replacing vue-server-renderer with @vue/server-renderer. Vue 3 no longer provides a bundle renderer and it is recommended to use Vue 3 SSR with Vite. If you are using Nuxt.js, it is probably better to wait for Nuxt 3.")])]),_v(" "),_c('p',[_v("Currently, MarkBind Vue components are authored in the Options API style. If migrated to Vue 3, we can continue to use this API style.")]),_v(" "),_c('h4',{attrs:{"id":"vue-sfc-single-file-components"}},[_v("Vue SFC (Single File Components)"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#vue-sfc-single-file-components","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_c('a',{attrs:{"href":"https://vuejs.org/guide/scaling-up/sfc.html"}},[_v("Reference")])]),_v(" "),_c('blockquote',[_c('p',[_v("Vue uses an HTML based template syntax. All Vue templates "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("