Wednesday, 25 February 2026

Restricted Setting Android AppLock

 

newer android versions automatically flag all apps which require elevated permissions like display over other apps and accessibility service if they are not installed from play store directly. You can go to system settings > Apps > App Lock > Three dots > Enable restricted Settings, and then you should be able to enable the permission
you can check that it is safe by analyzing the code over github. the fdroid builds are also reproducible

Edit sudo nano /etc/cups/cupsd.conf untuk Print melalui server debian

 

Baik Guru Duan, ini sudah jelas penyebab utamanya 👍

Masalahnya ada di sini:

Allow 192.168.100.0/24

Padahal sekarang jaringan Anda:

192.168.200.xxx

Jadi CUPS hanya mengizinkan jaringan lama (100) → jaringan baru (200) otomatis Forbidden.


✅ SOLUSI CEPAT & AMAN (Rekomendasi)

Kita ganti semua 192.168.100.0/24192.168.200.0/24


1️⃣ Edit File

sudo nano /etc/cups/cupsd.conf

2️⃣ Ganti Bagian Ini (ADA 3 TEMPAT)

🔹 Bagian <Location />

Ubah dari:

Allow 192.168.100.0/24

Menjadi:

Allow 192.168.200.0/24

🔹 Bagian <Location /admin>

Ubah juga:

Allow 192.168.200.0/24

🔹 Bagian <Location /admin/log>

Ubah juga:

Allow 192.168.200.0/24

3️⃣ (Lebih Simpel & Fleksibel) Pakai @LOCAL (Opsional)

Kalau mau supaya tidak perlu ubah tiap ganti subnet, boleh ganti semua itu jadi:

Allow @LOCAL

Contoh:

<Location />
  Order allow,deny
  Allow localhost
  Allow 127.0.0.1
  Allow @LOCAL
</Location>

Ini otomatis izinkan semua LAN.

👉 Saya sarankan cara ini untuk server sekolah 👍


4️⃣ Restart CUPS

Wajib setelah edit:

sudo systemctl restart cups

5️⃣ Test Lagi

Buka dari HP / PC:

http://192.168.200.20:631

Sekarang harusnya sudah masuk.


✅ BONUS: Supaya Client Bisa Print Langsung

Karena printer USB di server, client print lewat server.

Pastikan ada baris ini (sudah ada, bagus):

Browsing On
BrowseLocalProtocols dnssd

Kalau belum muncul di client, restart juga Avahi:

sudo systemctl restart avahi-daemon

🎯 KESIMPULAN

❌ Bukan printer rusak
❌ Bukan CUPS rusak
❌ Bukan server rusak

✅ Hanya subnet berubah → akses diblok
✅ Tinggal ganti Allow → normal lagi


Kalau setelah ini masih belum bisa print dari client, kirim:

lpstat -r
lpstat -a

Nanti kita cek sharing-nya juga.

Tuesday, 24 February 2026

tambahkan di profile user "profile_field_nis" nip nowa

 

 

 **************

 

 

 

===============

 

 

 

 

Baik Guru Duan, berikut cara menambahkan field di profil user Moodle:

Target field:

  • profile_field_nisNIS

  • nipNIP

  • nowaNo WhatsApp


Cara 1 (Resmi & Aman – Lewat Admin Panel Moodle)

Disarankan pakai cara ini 👍

1. Masuk sebagai Admin

Login → Site administration

2. Buka Custom Profile Fields

Masuk ke:

Site administration
→ Users
→ Accounts
→ User profile fields

3. Buat Kategori (Opsional)

Klik Create a new profile category
Misal:

Data Sekolah

4. Tambah Field Baru

Klik Create a new profile field → Short text

Lakukan 3 kali:


🔹 A. Field NIS

SettingIsi
NameNIS
Short namenis
RequiredYes (opsional)
VisibleVisible to user
LockedNo

👉 Klik Save changes


🔹 B. Field NIP

SettingIsi
NameNIP
Short namenip

🔹 C. Field No WhatsApp

SettingIsi
NameNo WhatsApp
Short namenowa

✅ Hasilnya

Setelah selesai, di halaman profil user akan muncul:

NIS
NIP
No WhatsApp

Dan di database otomatis jadi:

profile_field_nis
profile_field_nip
profile_field_nowa

✅ Cara Cek di Database (Opsional)

Kalau mau pastikan sudah masuk:

mysql -u root -p moodle
SELECT shortname, name 
FROM mdl_user_info_field;

Harus muncul:

nis
nip
nowa

⚠️ Catatan Penting

  1. Jangan edit langsung database kalau belum perlu
    → Pakai admin panel lebih aman.

  2. Field ini bisa dipakai di:

    • Plugin

    • Jurnal Mengajar

    • Export

    • Integrasi WA

    • Rekap siswa/guru

Kalau Guru Duan mau, nanti saya bantu juga:

✅ Supaya:

  • User tidak bisa mengubah sendiri NIS/NIP

  • Hanya admin yang bisa edit

  • Atau otomatis isi dari CSV/Excel

Tinggal bilang mau arahkan ke mana 👍

 

🔥Backup Moodle di Laptop


✅ 3️⃣ Backup Moodle Code

sudo tar -czf ~/backup_laptop/moodle-code-$(date +%F).tar.gz /var/www/html/moodle

✅ 4️⃣ Backup Folder moodledata

sudo tar -czf ~/backup_laptop/moodledata-$(date +%F).tar.gz /var/moodledata

✅ 5️⃣ Backup Database

Cek dulu nama database:

sudo grep dbname /var/www/html/moodle/config.php

Biasanya namanya moodle.

Lalu backup:

sudo mysqldump -u root -p moodle > ~/backup_laptop/db-$(date +%F).sql

Masukkan password MariaDB.


✅ 6️⃣ Cek Hasil Backup

ls -lh ~/backup_laptop

Harusnya muncul 3 file:

moodle-code-2026-02-21.tar.gz
moodledata-2026-02-21.tar.gz
db-2026-02-21.sql

Kalau sudah ada → Moodle Guru Duan sudah aman 💾


🔥 Cara Lebih Praktis (Satu Perintah Saja)

Kalau mau sekalian dalam satu folder:

sudo tar -czf ~/backup_laptop/backup-moodle-lengkap-$(date +%F).tar.gz \
/var/www/html/moodle \
/var/moodledata

Database tetap perlu dump terpisah.



Monday, 23 February 2026

Buat role gurujurnal

 

Untuk membuat role baru "Guru Jurnal" dan memberikan capability local/jurnalmengajar:submit di Moodle 4.5, ikuti langkah-langkah berikut:


🛠️ LANGKAH 1: Buat Role Baru "Guru Jurnal"

  1. Login sebagai admin di Moodle.

  2. Buka menu:
    Site administration > Users > Permissions > Define roles

  3. Klik tombol "Add a new role".

  4. Pada bagian "Use role or archetype", pilih:

    • ⚪ No role

    • (Atau pilih "Teacher" jika ingin mewarisi dari role guru)

  5. Klik Continue.


📝 LANGKAH 2: Konfigurasi Role Baru

Isi detail berikut:

  • Short name: gurujurnal

  • Custom full name: Guru Jurnal

  • Description: (Opsional, misalnya: Role untuk guru yang dapat mengisi jurnal mengajar)

  • Context types where this role may be assigned:
    Centang sesuai kebutuhan, misalnya:

    • System

    • Course

    • Category

Klik Next.


✅ LANGKAH 3: Beri Capability local/jurnalmengajar:submit

  1. Pada kolom pencarian capability, ketik:

    local/jurnalmengajar:submit
    
  2. Saat ditemukan, beri nilai:

    • ✅ Allow

Klik Save changes di bagian bawah.


🔁 LANGKAH 4: Assign Role ke User

  1. Masuk ke Site administration > Users > Permissions > Assign system roles

  2. Klik pada role Guru Jurnal

  3. Pilih user yang ingin diberi role ini, lalu klik Add


Selesai!
Sekarang hanya user dengan role Guru Jurnal yang memiliki kemampuan local/jurnalmengajar:submit untuk mengakses atau mengisi jurnal di plugin local_jurnalmengajar.

Jika kamu ingin membatasi akses halaman index.php hanya untuk user dengan role ini, saya bisa bantu juga menambahkan logika tersebut di file plugin.

Menghilangan Guess Access di Moodle

Itu adalah notifikasi Guest Access di Moodle. Untuk menghilangkannya, silakan lakukan salah satu cara berikut:


Cara 1: Matikan Login sebagai Tamu (Disarankan)

  1. Login sebagai Admin Moodle

  2. Masuk ke:

    👉 Site administration → Plugins → Authentication → Manage authentication

  3. Cari Guest login button

  4. Klik ikon 👁️ (Disable) sampai mati

  5. Simpan

📌 Setelah ini, tombol “Access as a guest” tidak akan muncul lagi.


Cara 2: Matikan Guest di Level Course

Kalau hanya ingin hilang di mata pelajaran tertentu:

  1. Masuk ke Course

  2. Klik Settings

  3. Cari Guest access

  4. Set ke: No

  5. Save


Cara 3 (Opsional): Paksa Login di Homepage

Supaya semua pengunjung wajib login:

  1. Site administration → Security → Site policies

  2. Aktifkan:

    ✔️ Force users to login

  3. Save

📌 Ini akan membuat semua halaman Moodle wajib login.


Rekomendasi untuk Server CBT Sekolah

Untuk CBT & Moodle sekolah (seperti yang Guru Duan pakai):

👉 Paling aman: pakai Cara 1 + Cara 3

Supaya:

  • Tidak ada tamu masuk

  • Tidak ada siswa iseng lihat-lihat

  • Sistem lebih aman


Kalau mau, sebutkan:

Mau dihilangkan di semua course atau hanya sebagian saja?

Nanti saya pandu lebih tepat sesuai kebutuhan Guru Duan 👍

 

 

 

 

 

agar user tidak bisa edit profile

 http://localhost/admin/roles/define.php

 

 

Buat Favicon.ico dengan PixelLab dan imagemagick

 

Baik, Guru Duan!
Saya jelaskan langkah paling aman dan bersih untuk mengganti favicon Moodle menggunakan desain yang Guru buat di PixelLab.


🟩 LANGKAH 1 — Buat Desain di PixelLab

Di PixelLab:

  1. Buat kanvas 1:1 (square), misalnya 512×512 px atau 1024×1024 px

  2. Setelah selesai desain → Export sebagai PNG (transparan atau tidak)

  3. Transfer PNG itu ke laptop (via WhatsApp, Telegram, kabel, dsb.)

Setelah PNG ada di laptop, kita lanjut.


🟩 LANGKAH 2 — Ubah PNG menjadi favicon.ico

Ada dua cara:

Cara A — Konversi lewat terminal (disarankan)

Install ImageMagick:

sudo apt install imagemagick

Konversi PNG menjadi ICO multi-size:

convert icon.png -define icon:auto-resize=64,48,32,16 favicon.ico

Atau, jika PNG besar:

convert icon.png -resize 256x256 favicon.ico

Hasilnya: favicon.ico.


Cara B — Konversi online (lebih mudah)

Bisa pakai:

  • favicon.io

  • convertico.com

  • iconifier.net

Upload PNG → download favicon.ico


🟩 LANGKAH 3 — Upload favicon.ico ke server Moodle

Jika favicon Moodle Anda berada di:

/var/www/html/moodle/favicon.ico

Maka cukup upload menggantikan file itu:

scp favicon.ico admincbt@IP_SERVER:/var/www/html/moodle/

Jika permission error → beri izin dulu:

sudo chmod 644 /var/www/html/moodle/favicon.ico

Lalu SCP lagi.


🟩 LANGKAH 4 — Purge Cache Moodle

Sangat penting karena favicon di-cache kuat oleh Moodle.

sudo -u www-data php /var/www/html/moodle/admin/cli/purge_caches.php

Atau dari web:

Site administration → Development → Purge all caches


🟩 LANGKAH 5 — Refresh browser (harus Ctrl+Shift+R)

Chrome/Firefox menyimpan favicon di cache lama.

Tekan:

Ctrl + Shift + R

atau

Ctrl + F5

Baru favicon akan berubah.


Ganti favicon ico moodle

 

perhatikan lokasi

=================== 

 $ sudo cp ~/cbt/ico/favicon.ico /var/www/html/moodle/favicon.ico
sudo chmod 644 /var/www/html/moodle/favicon.ico



Konfigurasi 2 moodle di laptop

 

SistemURLPortFolderDatabase
Jurnalhttp://localhost80/var/www/html/moodlemoodle
CBThttp://localhost:90009000/var/www/html/moodle_cbtmoodle_cbt

Sunday, 22 February 2026

Setup Nextdns di debian SiM server

 # sh -c "$(curl -sL https://nextdns.io/install)"
INFO: OS: debian
INFO: GOARCH: amd64
INFO: GOOS: linux
INFO: NEXTDNS_BIN: /usr/bin/nextdns
INFO: INSTALL_RELEASE: 1.47.1
c) Configure NextDNS
r) Remove NextDNS
e) Exit
Choice (default=c): c
NextDNS Profile ID: 6445b3                                        
Sending your devices name lets you filter analytics and logs by device.
Report device name? [Y|n]: y
Accept DNS request from other network hosts.
Setup as a router? (y/n): y
Make NextDNS CLI cache responses. This improves latency and reduces the amount
of queries sent to NextDNS.
Enable caching? (y/n): y
Instant refresh will force low TTL on responses sent to clients so they rely
on CLI DNS cache. This will allow changes on your NextDNS config to be applied
on your LAN hosts without having to wait for their cache to expire.
Enable instant refresh? (y/n): y
Changes DNS settings of the host automatically when NextDNS is started.
If you say no here, you will have to manually configure DNS to 127.0.0.1.
Automatically setup local host DNS? [Y|n]: y
NextDNS installed and started using systemd init
c) Configure NextDNS
r) Remove NextDNS
e) Exit
Choice (default=c): e

================================

# DEBUG=1 sh -c "$(curl -sL https://nextdns.io/install)"
INFO: OS: debian
INFO: GOARCH: amd64
INFO: GOOS: linux
INFO: NEXTDNS_BIN: /usr/bin/nextdns
INFO: INSTALL_RELEASE: 1.47.1
DEBUG: Start install loop with CURRENT_RELEASE=1.47.1
DEBUG: NextDNS is up to date (1.47.1)
c) Configure NextDNS
r) Remove NextDNS
e) Exit
Choice (default=c): r
INFO: Uninstalling NextDNS...
DEBUG: Using deb uninstall type
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages were automatically installed and are no longer required:
  gyp libc-ares2 libjs-highlight.js libjs-inherits libjs-is-typedarray libjs-psl libjs-typedarray-to-buffer libssl-dev
  libuv1-dev node-chownr node-color-name node-err-code node-extsprintf node-fast-deep-equal node-indent-string node-ini
  node-is-typedarray node-json-parse-better-errors node-json-schema node-json-schema-traverse node-qs node-resolve-from
  node-through node-typedarray-to-buffer node-universalify node-uuid
Use 'apt autoremove' to remove them.
The following packages will be REMOVED:
  nextdns
0 upgraded, 0 newly installed, 1 to remove and 103 not upgraded.
After this operation, 9,560 kB disk space will be freed.
(Reading database ... 63459 files and directories currently installed.)
Removing nextdns (1.47.1) ...
DEBUG: Start install loop with CURRENT_RELEASE=
DEBUG: NextDNS is not installed
i) Install NextDNS
e) Exit
Choice (default=i): i
INFO: Installing NextDNS...
DEBUG: Using deb install type
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
apt-transport-https is already the newest version (2.2.4).
The following packages were automatically installed and are no longer required:
  gyp libc-ares2 libjs-highlight.js libjs-inherits libjs-is-typedarray libjs-psl libjs-typedarray-to-buffer libssl-dev
  libuv1-dev node-chownr node-color-name node-err-code node-extsprintf node-fast-deep-equal node-indent-string node-ini
  node-is-typedarray node-json-parse-better-errors node-json-schema node-json-schema-traverse node-qs node-resolve-from
  node-through node-typedarray-to-buffer node-universalify node-uuid
Use 'apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 103 not upgraded.
Hit:1 http://security.debian.org/debian-security bullseye-security InRelease
Hit:2 http://deb.debian.org/debian bullseye InRelease                                                     
Hit:3 http://deb.debian.org/debian bullseye-updates InRelease                                             
Hit:4 https://pkg.cloudflare.com/cloudflared buster InRelease                                             
Hit:5 https://repo.nextdns.io/deb stable InRelease
Get:6 https://packages.sury.org/php bullseye InRelease [6,136 B]                                                               
Err:6 https://packages.sury.org/php bullseye InRelease                                                                         
  The following signatures were invalid: EXPKEYSIG B188E2B695BD4743 DEB.SURY.ORG Automatic Signing Key <deb@sury.org>
Hit:8 https://deb.nodesource.com/node_22.x nodistro InRelease                                                                  
Hit:9 https://download.docker.com/linux/debian buster InRelease                                                                
Get:13 https://pkgs.tailscale.com/stable/debian bullseye InRelease                                                             
Hit:10 https://dlm.mariadb.com/repo/mariadb-server/10.6/repo/debian bullseye InRelease
Get:12 https://dlm.mariadb.com/repo/maxscale/latest/apt bullseye InRelease [11.9 kB]
Err:12 https://dlm.mariadb.com/repo/maxscale/latest/apt bullseye InRelease
  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 5D87FACA8C27D14E
Hit:7 https://custom-downloads.mariadb.com/legacy/tools/debian bullseye InRelease                                              
Hit:11 https://packagecloud.io/ookla/speedtest-cli/debian bullseye InRelease
Fetched 18.5 kB in 22s (832 B/s)
Reading package lists... Done
W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: https://packages.sury.org/php bullseye InRelease: The following signatures were invalid: EXPKEYSIG B188E2B695BD4743 DEB.SURY.ORG Automatic Signing Key <deb@sury.org>
W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: https://dlm.mariadb.com/repo/maxscale/latest/apt bullseye InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 5D87FACA8C27D14E
W: Failed to fetch https://dlm.mariadb.com/repo/maxscale/latest/apt/dists/bullseye/InRelease  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 5D87FACA8C27D14E
W: Failed to fetch https://packages.sury.org/php/dists/bullseye/InRelease  The following signatures were invalid: EXPKEYSIG B188E2B695BD4743 DEB.SURY.ORG Automatic Signing Key <deb@sury.org>
W: Some index files failed to download. They have been ignored, or old ones used instead.
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages were automatically installed and are no longer required:
  gyp libc-ares2 libjs-highlight.js libjs-inherits libjs-is-typedarray libjs-psl libjs-typedarray-to-buffer libssl-dev
  libuv1-dev node-chownr node-color-name node-err-code node-extsprintf node-fast-deep-equal node-indent-string node-ini
  node-is-typedarray node-json-parse-better-errors node-json-schema node-json-schema-traverse node-qs node-resolve-from
  node-through node-typedarray-to-buffer node-universalify node-uuid
Use 'apt autoremove' to remove them.
The following NEW packages will be installed:
  nextdns
0 upgraded, 1 newly installed, 0 to remove and 103 not upgraded.
Need to get 0 B/3,924 kB of archives.
After this operation, 9,560 kB of additional disk space will be used.
Selecting previously unselected package nextdns.
(Reading database ... 63459 files and directories currently installed.)
Preparing to unpack .../nextdns_1.47.1_amd64.deb ...
Unpacking nextdns (1.47.1) ...
Setting up nextdns (1.47.1) ...
NextDNS installed and started using systemd init
DEBUG: Start configure
DEBUG: Get profile ID
DEBUG: Previous profile ID: 6445b3
NextDNS Profile ID (default=6445b3): 
DEBUG: Add arg -profile=6445b3
Sending your devices name lets you filter analytics and logs by device.
Report device name? [Y|n]: y
DEBUG: Add arg -report-client-info=true
Accept DNS request from other network hosts.
Setup as a router? [Y|n]: y
DEBUG: Add arg -setup-router=true
Make NextDNS CLI cache responses. This improves latency and reduces the amount
of queries sent to NextDNS.
Enable caching? [Y|n]: y
DEBUG: Add arg -cache-size=10MB
Instant refresh will force low TTL on responses sent to clients so they rely
on CLI DNS cache. This will allow changes on your NextDNS config to be applied
on your LAN hosts without having to wait for their cache to expire.
Enable instant refresh? [Y|n]: y
DEBUG: Add arg -max-ttl=5s
Changes DNS settings of the host automatically when NextDNS is started.
If you say no here, you will have to manually configure DNS to 127.0.0.1.
Automatically setup local host DNS? [Y|n]: y
DEBUG: Add arg -auto-activate=true
NextDNS installed and started using systemd init

Congratulations! NextDNS is now installed.

To upgrade/uninstall, run this command again and select the appropriate option.

You can use the NextDNS command to control the daemon.
Here are a few important commands to know:

# Start, stop, restart the daemon:
nextdns start
nextdns stop
nextdns restart

# Configure the local host to point to NextDNS or not:
nextdns activate
nextdns deactivate

# Explore daemon logs:
nextdns log

# For more commands, use:
nextdns help


Tuesday, 17 February 2026

Alias di laptop Ubuntu

 

Siap, Guru 👍
Saya jelaskan satu per satu dengan bahasa sederhana, supaya jelas mana yang penting dan mana yang aman.


✅ 1️⃣ alert → Notifikasi Terminal

alias alert='notify-send ...'

Fungsi:
👉 Munculin notifikasi kalau perintah sebelumnya selesai.

Contoh:

sleep 10; alert

Setelah 10 detik → muncul notifikasi.

➡️ Ini bawaan Ubuntu, aman ✅


✅ 2️⃣ cetakizin → Cetak Surat via Server

alias cetakizin='ssh root@100.106.40.93 print_remote_surat'

Fungsi:
👉 Login ke server jarak jauh → cetak surat izin.

Ini khas kerja Guru 😄
➡️ Custom pribadi, aman ✅


✅ 3️⃣ grep / egrep / fgrep → Pencarian Berwarna

alias grep='grep --color=auto'

Fungsi:
👉 Hasil pencarian jadi warna-warni.

Contoh:

grep error log.txt

➡️ Lebih enak dilihat, aman ✅


✅ 4️⃣ l, la, ll, ls → Shortcut List Folder

AliasAsliFungsi
lls -CFList ringkas
lals -ATampilkan file tersembunyi
llls -alFDetail lengkap
lsls --color=autoWarna

Ini standar Linux 👍
➡️ Aman ✅


✅ 5️⃣ serveron → Mode Server ON

alias serveron='sudo systemctl start docker && cd /home/dhwan/immich && docker compose up -d'

Fungsi:
👉 Nyalakan Docker → Jalankan Immich.

➡️ Yang tadi kita buat 💪
➡️ Sangat berguna ✅


✅ 6️⃣ serveroff → Mode Server OFF

alias serveroff='cd /home/dhwan/immich && docker compose down && sudo systemctl stop docker'

Fungsi:
👉 Matikan Immich → Matikan Docker.

➡️ Pasangan serveron 😄
➡️ Wajib dipakai harian ✅


✅ 7️⃣ yta → Putar YouTube Audio

alias yta='mpv --no-video ...'

Fungsi:
👉 Dengar audio YouTube (kayak radio / ceramah).

Contoh:

yta https://youtube.com/...

➡️ Hemat kuota + tanpa video ✅


✅ 8️⃣ ytv → Putar YouTube Video

alias ytv='mpv ...'

Fungsi:
👉 Nonton YouTube langsung di terminal 😄

Contoh:

ytv https://youtube.com/...

➡️ Keren & ringan ✅


📌 RINGKASAN CEPAT

AliasFungsiAman?
alertNotifikasi
cetakizinCetak via server
grep*Cari teks
l/ll/laList folder
serveron/offMode server
yta/ytvYouTube terminal

➡️ Semua alias Guru: AMAN & BERGUNA 👍
Tidak ada yang mencurigakan.


🎯 Kesimpulan

Setup terminal Guru sudah:

✅ Rapi
✅ Profesional
✅ Efisien
✅ Tidak berbahaya

Kalau mau, saya juga bisa bantu:

👉 Bikin alias backup
👉 Alias update sistem
👉 Alias bersih disk
👉 Alias monitoring

Tinggal bilang saja 😄