Rabu, 07 September 2011

Membuat Aplikasi Multicast Chatting dengan Java

dari pada pusing mikirin Tugas Akhir lebih baik ane ng’blog dulu deh. Rasanya udah berabad-abad ngga posting .. hehehehe… kali ini ane akan memberikan contoh aplikasi multicast chatting yang sederhana dengan menggunakan java. Berupa datagram paket yang akan di kirim secara multicast (one to Many) ke seluruh yang berada dalam group yang sesuai.

Dalam membuat program sederhana ini kita menggunakan Class Object InetAdress, DatagramPacket dan MulticastSocket. Dalam program ini sudah dapat mengirim file *.txt

programnya silakan donlot disini

sedang melakukan chatt


Folder File Kiriman (kiri) - User yang mengirim file (tengah) - User yang menerima file (kanan)

Baca Selengkapnya »»  

Minggu, 17 April 2011

Benerin Flashdisk - "Please Insert ..."


Bermula pada kamis pagi di lab, waktu itu lagi belajar ASP.NET. Karena punya Flashdisk 3 (bukannya sombong tapi kenyataan, wkwkwk) .... dengan bangga gw bilang "Maklum punya flasdisk banyak, jadi susah nyari materinya, hak hak hak.", lanjut "Nih flasdisk dah lama banget ngga rusak-rusak". eeehh disebelah si andi nyeletuk "eehh ntar rusak" diamini pula sama si yudha.. -_-" .

eeehhh bener aje, gw dah pulang lalu ku coloklah (upssss dicolok?????..), flasdisk masutnya. jreeeeenggggggg kedetek dengan label removable, muncul pesan "Please insert media.....". waaaahhh malapetiki neh. bukan masalah isinya tapi Flasdisknya, hahahahaha....
langsung tuh mondar-mandir, dari blog sini, blog sana, tak menghasilkan boy. Saking keselnya mau gw lempar aje tuh flasdisk, tapi sayang-sayang ah.. :) . naaaaahhhh, karena waktu itu dah malam (jam 01:00, pagi ato malam yaa??? :) mending w tidur deh.

ceritanya di pagi hari masih penasaran sama flashdisk gw yang katanya rusak. Tanya deh sama paman google, akhirnya dapet juga pencerahan dengan memprogram ulang(reFlash) flasdisk yang saya punya, naaaah bagaimana caranya???


caranya dengan menggunakan tool formater, gimana cara dapet toolnya ??, saya perrgi ke situs rusia. Disatas tuh ada kotak dan disampingnya ada tombol, pasti itu buat pencariannya (maklum bahasa rusia jadi ngga ngerti/asal tebak aja, hehee). nah buat mencarinya bisa menggunakan idVendor dan idProduct, untuk ini kita dapat menggunakan software USB Monitor Pro. tapi kalo ane cari make nama mikrokontrollernya. naah ane bongkar tuh flasdisk lau ane liat nama mikrocontroller flasdisk ane Phinson PS2232, nah setelah tau tool formaternya, ane cari deh sama paman google, formater untuk flasdisk saya PS2232 Formatter v2.9.0.6 .
jreeeenngggg, akhirnya flasdisk ane ngga berkurang.
semoga membantu, selamat mencobaaaaaa
Baca Selengkapnya »»  

Rabu, 02 Februari 2011

SISTEM ANTRIAN by Achoel Dolie

Inilah dia hasil pertapaan, heheheeh :D. Sitem Antrian menggunakan database MySQL, dengan instalasi yang mudah .. tidak usah membuat ODBC pada server yang lumayan ngerepotin, itu sih menurut ane, hehehehe.. kenapa koq bisa?? *kaget, hak haka hak. Bisa dong, kan seperti yang dulu saya pernah bilang, dengan menggunakan MyVBQL. Dikembangkan dengan menggunakan bahasa pemrograman Visual Basic 6.0. Kita hanya mengatur hak aksesnya saja dalam MySQL. Dalam Sistem Antrian ini terdapat 3 Aplikasi. Yaitu, aplikasi untuk Client Operator, Client Utama dan Server.

A. Server, yaitu aplikasi server yang diinstal ke komputer yang digunakan sebagai server. Dimana dalam komputer itu juga terdapat databasenya. Aplikasi server terdapat 2 layar yaitu:

  1. Layar Utama, dimana di layar ini terdapat keterangan atau petunjuk Nomor Antrian yang terakhir kali dilayani atau yang sedang dilayani. Dan pada Layar Utama ini juga terdapat petunjuk 3 Nomor antrian berikutnya (jika ada antrian yang menunggu)
  2. Control Client, pada layar ini menunjukan Client mana saja yang sedang aktif. Dan kita dapat Mengontrol Client yaitu ,

· Exit Client, Untuk Mengeluarkan Aplikasi Client dari server

· Restart Client, Untuk me-restart komputer client

· Turn Off, Untuk mematikan atau Turn Off Komputer client

· Log Off, Untuk me-Log Off komputer client

B. Client Operator, yaitu aplikasi untuk operator yang akan melayani antrian, dimana maksimal jumlah Client Operator ini maksimal 10. Terdapat menu untuk mengatur koneksi ke aplikasi server dan ke database server.

C. Client Utama yaitu aplikasi yang akan digunakan oleh pengguna sistem antrian untuk mengambil nomor antrian. Terdapat menu untuk mengatur koneksi ke aplikasi server dan database server.

Berikut Screenshootnya... :D


Server Antrian (Layar Utama)


Server Antrian (Control Client)
Client Utama dan Client No. 4 sedang Online


Client Operator
Client No. 4 Sedang dijalankan



Client Utama
Untuk Mengambil No. Antrian



Baca Selengkapnya »»  

Membuat Aplikasi Server dan Client pada Visual Basic 6.0

Aplikasi Server

Untuk membuat aplikasi socket yang sederhana, tidak diperlukan langkah-langkah yang rumit. Kita akan mencoba membuat dua buah aplikasi, yang pertama adalah aplikasi server yang akan menerima data, sedangkan aplikasi kedua adalah aplikasi client yang mengirimkan data pada server. Baik aplikasi server dan aplikasi client mendeļ¬nisikan port yang sama sebagai jalur komunikasi.

Kita akan memulainya dengan aplikasi server, tugas aplikasi server cukup sederhana, yaitu hanya siap sedia menerima data yang masuk pada sebuah port. Control yang Anda perlukan adalah control winsock bernama Winsock1 dan sebuah textbox bernama Text1. Pada event Form_Load, tuliskan kode program di bawah ini:

———————————–

Private Sub Form_Load()
With Winsock1
.LocalPort = 1025
.Listen
End With
End Sub

———————————-

Kode program tersebut melakukan inisialisasi socket, socket memilih port 1025 pada komputer server dan menunggu data yang masuk melalui port tersebut dengan perintah Listen

Selanjutnya pada event Winsock1_ConnectionRequest, ketikkan kode program berikut:

———————————–

Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
If Winsock1.State sckClosed Then Winsock1.Close
Winsock1.Accept requestID
End Sub

———————————–

Kode program di atas berfungsi untuk menerima request koneksi. Selanjutnya pada event Winsock1_DataArrival, ketikkan kode program berikut:

———————————–

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim strData As String

Winsock1.GetData strData
Text1.Text = Text1.Text & strData

End Sub

———————————–

Kode program di atas berfungsi untuk mengambil data yang diterima oleh socket dan menampilkannya pada Text1. Aplikasi server telah selesai!

Aplikasi Client
Seperti aplikasi server, Anda perlu menyiapkan control Winsock dan Text, ditambah sebuah control Command Button yang dapat Anda namakan cmdKirim yang berfungsi untuk mengirimkan data yang diketik pada Text1 ke aplikasi server

Pada event Form_Load, ketikkan kode program di bawah:

———————————–

Private Sub Form_Load()
With Winsock1
.RemoteHost = “127.0.0.1”
.RemotePort = 1025
.Connect
End With
End Sub

———————————–

Kode program di atas berfungsi untuk melakukan inisialisasi, tentukan IP tujuan/server/remote dengan 127.0.0.1 seperti pada contoh jika Anda mencoba aplikasi ini dengan menggunakan satu mesin komputer.

Jika Anda mencobanya dengan menggunakan dua komputer dalam sebuah jaringan, isikan dengan IP komputer yang berfungsi sebagai server.Selanjutnya pada cmdKirim, ketikkan kode program sebagai berikut:

———————————–

Private Sub cmdKirim_Click()
If Winsock1.State = sckConnected Then
Winsock1.SendData Text1.Text
End If
End Sub

———————————–

Kode program di atas akan mengirimkan pesan yang Anda ketik pada textbox Text1 pada aplikasi server.

Sumber : http://blankbrain.wordpress.com/2010/08/28/aplikasi-server-pada-visual-basic-6-0/
Baca Selengkapnya »»  

Sabtu, 29 Januari 2011

Tutorial VB 6.0 : Koneksi Database MySql Tanpa ODBC

Kakek saya bertanya ,, :D .. Apakah membuat koneksi database menggunakan mysql dalam VB 6.0 harus pake ODBC ???. dan saya pun menjawab, owwwhhhhhhh tidak bisa (sule mode on) :P.. tentunya bisa kek, coba deh kakek make API MyVbQL dijamin deh bisa. hehehehehe :D.

MyVbQL adalah application programming interface (API) pada Visual Basic yang dibuat oleh icarz.Inc. MyVbQL merupakan alternatif dari penggunaan driver MS ADO MyODBC yang digunakan oleh pengguna Visual Basic untuk mengakses basis data MySQL. Pembuatan MyVbQL bertujuan untuk mengurangi ukuran setup perangkat lunak. Dan penggunaan MyVbQL.dll dapat mengurangi ukuran setup file sampai 10 MB (megabyte) dibandingkan menggunakan ADO yang standar. (Icarz. Inc, 2002).

Nah sekarang ane buat aje program sederhana dengan menggunakan API MyVBQL, caranya mudah, saudara-saudari add references dulu API nya.

Langkah 1

Buat Form seperti dibawah ini :

Lalu tambahkan kode berikut pada general description di code window
Private connMySQL As New MYSQL_CONNECTION
Private myRS As MYSQL_RS

Langkah 2

Tambahkan event click pada btnOK , btnCancel dan List1

- event click btnOK

Private Sub btnOK_Click()

Dim Sql As String

Dim row As Long

'//error traping

On Error GoTo kesini

List1.Clear

List2.Clear

If connMySQL.State = MY_CONN_OPEN Then connMySQL.CloseConnection

'// buka koneksi

connMySQL.OpenConnection txtDBServer.Text, txtUser.Text, txtPass.Text, "", txtPort.Text

If connMySQL.State = MY_CONN_OPEN Then

Sql = "SHOW DATABASES;"

Set myRS = connMySQL.Execute(Sql, row)

If myRS.RecordCount = 0 Then Exit Sub

myRS.MoveFirst

Do Until myRS.EOF

List1.AddItem myRS.Fields(0).Value

myRS.MoveNext

Loop

myRS.CloseRecordset

Else

MsgBox connMySQL.Error.Description, vbCritical, "Error " & connMySQL.Error.Number

End If

'___________________________________________________________

On Error GoTo 0

Exit Sub

kesini:

MsgBox connMySQL.Error.Description, vbCritical, "Error " & connMySQL.Error.Number

End Sub

- event click btnCancel

Private Sub btnCancel_Click()

txtDBServer.Text = ""

txtPass.Text = ""

txtPort.Text = ""

txtUser.Text = ""

End Sub

- event click List1

Private Sub List1_Click()

Dim Sql As String

Dim row As Long

List2.Clear

On Error Resume Next

If connMySQL.State = MY_CONN_OPEN Then

Sql = "USE " & List1.Text & ";"

connMySQL.Execute Sql

Sql = "SHOW TABLES;"

Set myRS = connMySQL.Execute(Sql, row)

If myRS.RecordCount = 0 Then Exit Sub

myRS.MoveFirst

Do Until myRS.EOF

List2.AddItem myRS.Fields(0).Value

myRS.MoveNext

Loop

myRS.CloseRecordset

End If

End Sub


jreeeenngggg... coba liat hasilnya dibawah ini.. download source codenya disini

Baca Selengkapnya »»  

Senin, 17 Januari 2011

Menangani Single Quote (') Pada SQL

Dalam mengisi data ke dalam database terkadang terdapat karakter quote, terutama single quote. Sebenernya mudah untuk mengatasi masalah ini, yaitu cukup menuliskan dua kali tanda quote tersebut. Artinya setiap ada quote dalam string yang ingin di masukkan ke field dalam database itu harus di gandain, misal kita ingin menginput ta’lim maka kita tulis ta’’lim dalam sqlnya. Ini digunakan jika tanda pengapit untuk valuenya menggunakan single quote. Tetapi bila pengapit value pada sql menggunakan tanda kutipan multi (“) maka inilah yang digandakan.

Contoh :
Misal kita ingin menginput nama sekolah dengan nama : Ta’lim Mubtadi
Maka Sqlnya :
INSERT INTO SEKOLAH(kd_sekolah,nm_sekolah,alamat)
VALUES (’S001’,’Ta’’lim Mubtadi’,’Cipondoh’)

Nah sekarang bagaimana jika dalam pemrograman ???....
Begini, jadi kita hanya menggandakan single quote (’) digandain jadi 2 yaitu (’’), ingat ini 2 single quote bukan multiple quote.

Ini contoh dalam pemrograman Java.
Kita menggunakan string untuk menampung nama sekolah,kode,dan alamat serta menggunakan metod replace Untuk mengganti semua karakter singgle quote (’) menjadi duakali (2 single quote(’’) ).

Sql = ’INSERT INTO SEKOLAH(kd_sekolah,nm_sekolah,alamat)
VALUES (‘+ kode +’,’+ nm_sek.replace(‘\’’,’\’\’’) +’,’ +
alamat_sek.replace(‘\’’,’\’\’’)+’)’;


Jreeennggg… selesai deh, tanda single quote yang mau diinput pun masuk, hehehe
Semoga bermanfaat…
Baca Selengkapnya »»  

Rabu, 12 Januari 2011

ORACLE : MEMBUAT SISTEM AKADEMIK ( ENTRI KELOMPOK DAN NILAI )

Ini yang gw suka kalo UAS Cuma ngumpulin tugas buat system, kalo di f b gw bilang “Like This”, hehehehee. Abis enak sih Cuma buat system, ngga usah belajar dan dengan waktu yang lumayan laaamaaaaaa... hehehe


Di tugas ini ane membuat system akademik untuk entry kelompok dan entri nilai pada Universitas XYZ (XYZ aja deh yang ane pake biar lebih santai.. hehehe)..
ane buat laporannya cetak KRS, KST, Nilai Semester, dan lain-lain. Dan alhamdulillah berhubung dosennya baik hati dan tidak sombong serta menghormati sesama ane diberi nilai yang baaagus dan memuaskan.. hihihihi
Kalo kata sule sih “SEMPOA” .. ahaaaay.

Ini gambar screen shoot entry kelompoknya...Download disini
dokumentasinya



Baca Selengkapnya »»  

Kamis, 06 Januari 2011

PROGRAM J2ME SEDERHANA KRIPTOGRAFI CAESAR CHIPER DAN VIGENERE CHIPER

Di tengah kesibukan UAS lebih baik menyegarkan pikiran dengan ngeblog, hahahaha… sesuai dengan janji saya pada postingan sebelumnya. Ini merupakan pemenuhan janji saya kepada anda, hahahaha *lebaaay*
Oke langsung aja deh mari kita coba mengimplementasikan metode Caesar chipper dan vigenere dalam aplikasi J2ME.
Tapi sebelumnya kita harus memahami bagaimana proses enkripsi maupun deksripsi pada kedua metode ini. Karena metode caesar chiper telah ane jelasin pada postingan sebelumnya jadi disini ane bahas cara vigenere aje ok!!.. hahaha
Satu jam selanjutnya........ begini ceritanya...



Metode ini disebut juga Running Key Chiper tapi lebih di kenal dengan Vigenere Chiper. Karakter ciphertext ditentukan pada pertemuan antara baris dan kolom
Baris. untuk karakter yang akan dienkrip, kolom untuk karakter dari keyword.

Coba lihat contohnya di bawah ini :

Plaintext nya adalah SOUND THE RETREAT dan key(password) adalah DEADFED, dan setelah melakukan enkripsi akan menghasilkan VSUQI XKH VEWWIDW. Coba anda perhatikan kolom untuk plaintext dan baris untuk key. Huruf S pada plaintext bertemu dengan huruf D pada key, maka hasilnya V yang ada pada ciphertext.

Naaaahhh... udah mudengkan, kalo belum, mudeng-mudengin aja deh, hehehehehe

Oke sekarang kita buat programnya.. buka alat perangnya (Netbeans – ane pake Netbean 6.9.1).. hehe

  1. buat tampilan layar :

  1. Tambahkan source code dibawah ini :

String hasil="";

private char [] pass;

private char [] pass2;

private char [] huruf = {'A','B','C','D','E','F','G','H','I','J','K','L','M',

'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',

'a','b','c','d','e','f','g','h','i','j','k','l','m',

'n','o','p','q','r','s','t','u','v','w','x','y','z'};

private char [] rotasi_13={'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',

'A','B','C','D','E','F','G','H','I','J','K','L','M',

'n','o','p','q','r','s','t','u','v','w','x','y','z',

'a','b','c','d','e','f','g','h','i','j','k','l','m'};

  1. Buat method yang digunakan untuk mengenkrip dan mendekrip.


private String kriptografiCaesarChipper(String plainTeks,int panjang,int ambil){

char charEnkrip;

if(ambil

charEnkrip=plainTeks.charAt(ambil);

if (charEnkrip==' '){

hasil=hasil+" ";

}

else{

for(int i=0;i<52;i++){

if(charEnkrip == huruf[i]) {

hasil = hasil + rotasi_13[i];

break;

}

}

}

kriptografiCaesarChipper(plainTeks,panjang,ambil+1);

}

return hasil;

}

private void ConcatPass(String plainTeks,String password){

int jmlSpasi=0;

int indexCurPass2;

pass = new char[password.length()];

int indexPass=0;

for (int x=0;x

if (!(password.charAt(x)==' ')) {

pass[indexPass]=password.charAt(x);

indexPass=indexPass+1;

}

}

int panjang = plainTeks.length();

pass2 = new char[panjang];

int indexCharPass;

for (int i=0;i

if(i

if (plainTeks.charAt(i)==' '){

pass2[i]=' ';

jmlSpasi++;

}

else{

indexCurPass2=i-jmlSpasi;

pass2[i]=pass[indexCurPass2];

}

}

else{

if (plainTeks.charAt(i)==' '){

pass2[i]=' ';

jmlSpasi++;

}

else{

indexCurPass2 = i - jmlSpasi;

indexCharPass = indexCurPass2%password.length();

pass2[i]=pass[indexCharPass];

}

}

}

}

// mengenkrip, jika ada spasi di password maka dianggap A atau index huruf=0;

private String kriptografiEnkripVegenere(String plainTeks,int panjang,int ambil, int jenis){

int indexBaris=0;

int indexKolom=0;

int indexCharHasil=0;

char charEnkrip,passEnkrip;

if(ambil

charEnkrip=plainTeks.charAt(ambil);

passEnkrip = pass2[ambil];

if (charEnkrip==' '){

hasil=hasil+" ";

}

else{

if (jenis == 1 ) {

for(int i=0;i<26;i++){

if(charEnkrip == huruf[i]) {

indexKolom=i;

break;

}

}

for(int i=0;i<26;i++){

if(passEnkrip == huruf[i]) {

indexBaris = i;

break;

}

}

indexCharHasil = indexBaris + indexKolom;

indexCharHasil = indexCharHasil%26;

hasil = hasil + huruf[indexCharHasil];

}

else if(jenis == 2) {

for(int i=26;i<52;i++){

if(charEnkrip == huruf[i]) {

indexKolom=i;

break;

}

}

for(int i=26;i<52;i++){

if(passEnkrip == huruf[i]) {

indexBaris = i;

break;

}

}

indexCharHasil = indexBaris + indexKolom;

indexCharHasil = (indexCharHasil%52);

if (indexCharHasil<26){

indexCharHasil = indexCharHasil+26;

}

hasil = hasil + huruf[indexCharHasil];

}

else if(jenis == 3) {

for(int i=0;i<52;i++){

if(charEnkrip == huruf[i]) {

indexKolom=i;

break;

}

}

for(int i=0;i<52;i++){

if(passEnkrip == huruf[i]) {

indexBaris = i;

break;

}

}

indexCharHasil = indexBaris + indexKolom;

indexCharHasil = indexCharHasil%52;

hasil = hasil + huruf[indexCharHasil];

}

}

kriptografiEnkripVegenere(plainTeks,panjang,ambil+1,jenis);

}

return hasil;

}

// mendekrip, jika ada spasi di password maka di angggap A atau index huruf nya 0

private String kriptografiDekripVegenere(String chiperText,int panjang,int ambil, int jenis){

int indexBaris=0;

int indexChiper=0;

int indexCharHasil=0;

char charDekrip,passEnkrip;

if(ambil

charDekrip=chiperText.charAt(ambil);

passEnkrip = pass2[ambil];

if (charDekrip==' '){

hasil=hasil+" ";

}

else{

if (jenis == 1 ) {

for(int i=0;i<26;i++){

if(charDekrip == huruf[i]) {

indexChiper=i;

break;

}

}

for(int i=0;i<26;i++){

if(passEnkrip == huruf[i]) {

indexBaris = i;

break;

}

}

if (indexChiper

indexCharHasil = 26 + (indexChiper - indexBaris);

}

else {

indexCharHasil = indexChiper - indexBaris;

}

hasil = hasil + huruf[indexCharHasil];

}

else if(jenis == 2) {

for(int i=26;i<52;i++){

if(charDekrip == huruf[i]) {

indexChiper=i;

break;

}

}

for(int i=26;i<52;i++){

if(passEnkrip == huruf[i]) {

indexBaris = i;

break;

}

}

if (indexChiper

indexCharHasil = 52-indexBaris;

indexCharHasil += indexChiper-26;

indexCharHasil +=26;

}

else {

indexCharHasil = (indexChiper - indexBaris);

indexCharHasil %=26;

indexCharHasil +=26;

}

hasil = hasil + huruf[indexCharHasil];

}

else if(jenis == 3) {

for(int i=0;i<52;i++){

if(charDekrip == huruf[i]) {

indexChiper=i;

break;

}

}

for(int i=0;i<52;i++){

if(passEnkrip == huruf[i]) {

indexBaris = i;

break;

}

}

if (indexChiper

indexCharHasil = 26 + (indexChiper - indexBaris);

}

else {

indexCharHasil = indexChiper - indexBaris;

}

hasil = hasil + huruf[indexCharHasil];

}

}

kriptografiDekripVegenere(chiperText,panjang,ambil+1,jenis);

}

return hasil;

}

private void enkrip(int jenis){

if (jenis == 1 ){

hasil="";

txtHasil.setString("");

txtKata.setString(txtKata.getString().toUpperCase());

txtPass.setString(txtPass.getString().toUpperCase());

ConcatPass(txtKata.getString(),txtPass.getString());

}

if (jenis == 2 ){

hasil="";

txtHasil.setString("");

txtKata.setString(txtKata.getString().toLowerCase());

txtPass.setString(txtPass.getString().toLowerCase());

ConcatPass(txtKata.getString(),txtPass.getString());

}

if (jenis == 3 ){

hasil="";

txtHasil.setString("");

ConcatPass(txtKata.getString(),txtPass.getString());

}

txtHasil.setString(kriptografiEnkripVegenere(txtKata.getString(), txtKata.getString().length(), 0,jenis));


}

private void dekrip(int jenis){

if (jenis == 1 ){

hasil="";

txtHasil.setString("");

txtKata.setString(txtKata.getString().toUpperCase());

txtPass.setString(txtPass.getString().toUpperCase());

ConcatPass(txtKata.getString(),txtPass.getString());

}

if (jenis == 2 ){

hasil="";

txtHasil.setString("");

txtKata.setString(txtKata.getString().toLowerCase());

txtPass.setString(txtPass.getString().toLowerCase());

ConcatPass(txtKata.getString(),txtPass.getString());

}

if (jenis == 3 ){

hasil="";

txtHasil.setString("");

ConcatPass(txtKata.getString(),txtPass.getString());

}

txtHasil.setString(kriptografiDekripVegenere(txtKata.getString(), txtKata.getString().length(), 0,jenis));

}


Selanjutnya anda panggil method-method diatas dari command item yang ada pada editor Chaesar Chiper atau Vigenere Chiper yang sesuai. Silahkan download hasil programnya disini






Baca Selengkapnya »»