Perpustakaan widget GWT terbaik? [Tutup]


134

Pertanyaan untuk semua guru GWT di luar sana - mana yang merupakan perpustakaan widget GWT terbaik di luar sana? Dan mengapa?

Daftar berdasarkan jawaban:

И наконец- новое поколение основанное на JsInterop :


Apakah Anda lupa menyertakan gwt-mosaic dalam daftar?
Ashwin Prabhu

2
Pertanyaan ini tidak spesifik tentang persyaratan, jadi dapat diprediksi, yang paling terlihat (inti GWT) dipilih meskipun tidak memenuhi semua persyaratan. Jika Anda memiliki aplikasi perusahaan yang kompleks dengan banyak layar dan volume data tinggi dan Anda membutuhkan kisi dan editor yang kuat, untuk itulah SmartGWT. GWT biasa bagus untuk banyak aplikasi, tetapi banyak perusahaan dengan kumpulan persyaratan khusus ini mengevaluasi GWT dan memutuskan SmartGWT lebih cocok. Untuk mendapatkan gambaran umum dan memutuskan sendiri, baca Panduan Memulai Cepat. smartclient.com/releases/SmartGWT_Quick_Start_Guide.pdf
Charles Kendrick

Anda kehilangan gwt-bootstrap
caarlos0

Saya telah membuat proposal situs untuk memberikan pertanyaan seperti ini kepada pertanyaan resmi yang jauh dari Stack Overflow. Ini disebut Rekomendasi Kode. Bantu wujudkan dengan bergabung dan mengajukan pertanyaan sekarang!
daviewales

Ini juga terlihat menjanjikan: gwt-material-demo.herokuapp.com
kozla13

Jawaban:


52

Jangan mengikat diri Anda ke salah satu perpustakaan ini. Gunakan Vanilla GWT untuk membuat struktur proyek Anda. Secara khusus, gunakan pola MVP dan Event Bus. Silakan, lihat artikel google untuk mengetahui cara terbaik merancang aplikasi klien Anda dengan GWT: Membangun aplikasi MVP

Setelah itu, Anda dapat menggunakan widget apa pun dari pustaka ini (misalnya tabel, atau kotak kombo, pemilih data, dll) dan menggabungkannya ke proyek Anda. Coba gunakan komponen tambahan HANYA jika Anda tidak melihat cara untuk melakukannya dengan vanilla GWT. Dengan cara ini Anda tidak mengikat diri Anda ke pustaka ini yang SELALU merepotkan ketika Anda mencoba melakukan sesuatu yang tidak muncul di aplikasi demo, mengandung banyak bug dan dukungannya sangat buruk.

Cara mencari widget harus mengikuti urutan berikut:

Hati-hati dengan perpustakaan lain, saya telah bekerja dengan mereka (dan masih mengalami mimpi buruk).


1
Ada pengalaman khusus dengan perpustakaan lain yang ingin Anda bagikan?
Adam

6
GXT, saya tidak akan merekomendasikan ini kepada musuh terburuk saya. Jika Anda mempertimbangkannya, silakan, Google dulu dan pastikan Anda tahu di mana Anda akan masuk. SmartGWT, pembungkus JS, sangat jelek. Lari jauh dari itu. Saya memiliki pengalaman dengan keduanya dalam proyek nyata. Pertama saya menggunakan SmartGWT, tetapi keterbatasannya membuat saya pindah ke GXT. Saya segera menemukan kekacauan yang mereka miliki di sana dengan form binding dan java generics (Yesus, setiap kali saya ingat ....) Saya tidak tahu mana yang lebih buruk! Saya menyelesaikannya, ya, tapi saya sangat menderita. Setelah itu saya belajar menggunakan vanilla GWT dan hanya widget yang saya suka dari perpustakaan lain.
monzonj

Posting ini sudah tua dan menurut sifatnya akan tanggal, tetapi saya telah menggunakan GXT secara ekstensif selama 2 tahun terakhir dan meskipun memiliki masalah, ini juga memungkinkan pembuatan aplikasi yang sangat bagus dengan relatif mudah. Ini memiliki grid yang sangat berguna, grid buffer, dan grid langsung. SmartGWT juga memiliki kisi dan komponen berfitur baik. Pertimbangkan juga Vaadin .
Carl Pritchett

43

Tergantung apa yang Anda maksud dengan "terbaik". Penampilan terbaik? API terbaik? Terbaik untuk memperluas kebutuhan khusus Anda sendiri?

Misalnya, saya baru saja mengevaluasi kelas tabel untuk digunakan dalam aplikasi kita. Kami telah menggunakan GWT-Ext, tetapi memiliki banyak masalah kinerja bagi kami, dan sangat sulit untuk mendapatkan ukuran tabel sesuai kebutuhan kami. Saya hampir saja menggunakan GWT-Mosaic , tetapi memutuskan untuk membangun widget di GWT Incubator .

Jadi, mengapa saya membuat pilihan ini? Tampaknya terlalu banyak perpustakaan di luar sana datang dengan milik mereka sendiri, karena kurangnya kata yang lebih baik, bagasi. Entah Anda harus menyelami keseluruhan kerangka kerja MVC (yang mungkin tidak sepenuhnya kompatibel dengan basis kode Anda lainnya), atau Anda harus mengadopsi sistem tata letak model baru seseorang, atau Anda harus hidup dengan fakta bahwa Anda tidak bisa benar-benar men-debug kode (karena ini hanya pembungkus JSNI).

Jangan salah paham, Inkubator GWT tidak sempurna ... widget ada dalam sejumlah fluks. Dalam kasus saya, ini adalah pilihan terbaik. Ini memberi saya kebaikan (tapi jelas tidak sempurna):

  • API
  • Kemungkinan diperpanjang
  • Tampilan dan nuansa (yah, ini agak lemah, tapi itulah kegunaan CSS.)

Jadi ... jawabannya (bagi saya) adalah kombinasi dari:

  • Stok widget GWT (dengan banyak gaya kustom)
  • Tabel Inkubator GWT
  • Beberapa widget buatan sendiri

(Saya harus menambahkan: "bagasi" yang saya maksud tidak selalu berarti buruk. Tetapi, jika Anda hanya menginginkan satu atau dua widget, ini dapat meningkatkan standar tentang apa yang diperlukan untuk menyelesaikan pekerjaan Anda dan bagaimana baik penampilan aplikasi Anda.)


Sebagian besar pustaka widget memerlukan beberapa lisensi karena ketergantungan pada beberapa pustaka AJAX eksternal. Ini, juga, menambah ukuran ekstra pada solusi Anda. Perhatikan juga, bahwa sebagian besar pustaka widget bergantung pada satu atau lebih komponen eksternal tambahan.
IgorM


10

GWT sendiri adalah perpustakaan yang cukup bagus.

Saya tidak menggunakan semua yang disebutkan tetapi dapat merekomendasikan Ext GWT .


2
Saya setuju dengan GWT telanjang. Bersama dengan proyek inkubator ( code.google.com/p/google-web-toolkit-incubator ), pada dasarnya Anda dapat menerapkan apa saja. Saya menggunakan MyGwt tetapi menyebalkan ketika mereka menutup proyek dan mengubah namanya dan semua forum dan dukungan, lisensi diubah
Robert Childan

1
Itu pasti mengerikan. Ini bukanlah cara yang sangat praktis untuk memelihara sebuah perangkat lunak.
DragonBorn

9

Saya lebih suka vanilla GWT. Beberapa API lain terlihat cantik dan tampilan mereka benar-benar memamerkan widget, tetapi saya selalu menemukan bahwa kinerjanya bukan yang terbaik .... ketika saya mengatakan kinerja yang saya maksud lebih seperti waktu respons. Saya benci jika aplikasi terasa lamban.


8

Sebagian besar pustaka yang disebutkan bukan open source dan bahkan lebih buruk lagi: hanya pembungkus di atas pustaka JavaScript. Kekuatan GWT terletak pada kenyataan bahwa aplikasi bekerja pada browser yang berbeda (karena pembuatan kode khusus untuk browser "besar"). Pustaka yang mendasari JavaScript ini dapat menyebabkan banyak masalah.

Saya setuju dengan jgindin GWT Incubator dan GWT Mosaic adalah yang terbaik sejauh ini.


Sangat menyesatkan. Hampir semua pustaka yang terdaftar adalah open source dengan lisensi ramah komersial (Apache, BSD, LGPL) kecuali ExtGWT (GPL). Lebih lanjut, bahkan dalam rangkaian komponen yang sangat terbatas yang saat ini disediakan, GWT memiliki banyak bug lintas-browser - cukup cari database bug mereka untuk memverifikasi ini. Kompiler GWT bukanlah sihir dan tidak secara otomatis mengoreksi bug tata letak browser yang aneh dan spesifik situasi dan sejenisnya - mereka perlu mengatasinya seperti kerangka kerja lainnya. Mereka juga tidak selalu terdepan - mereka belum mengumumkan dukungan resmi iPhone atau Android, SmartGWT.
Charles Kendrick

7

Bukan mengatakan itu "yang terbaik", tapi saya telah menggunakan GWT-Ext di tempat kerja belakangan ini. Ada beberapa pro dan kontra:

Kelebihan:

  • Relatif mudah diatur dan digunakan
  • Komunitas ukuran yang layak di belakangnya
  • BANYAK contoh online, yang semuanya memiliki kode yang menyertai
  • Pilihan widget bagus yang mencakup berbagai fungsi

Kekurangan:

  • Membuat asumsi tentang format dan struktur data Anda yang mungkin tidak dapat Anda tampung
  • Library hanyalah pembungkus JSNI, yang membuatnya lebih sulit untuk di-debug dan diperluas
  • Dukungan dan pengembangan perpustakaan di masa mendatang tidak pasti
  • Beberapa masalah lintas-browser yang mengganggu masih ada (terutama dengan tata letak)
  • Fungsi pencarian di forum mereka pada dasarnya tidak berguna. (Ini menjadi hewan kesayanganku> _ <)

6

JANGAN gunakan salah satu dari mereka! Jika Anda berencana untuk mengembangkan aplikasi skala besar, Anda harus mempertimbangkan untuk menggunakan pola MVP. Implementasi terbaik di sekitar adalah kerangka kerja MVP4G , ini mendukung pemisahan kode GWT di luar kotak. Ada banyak contoh bagus, Anda bisa memulainya. Yang paling berharga adalah Mvp4GModules.


5

Tambahkan yang baru: GWT-Bootstrap :)

Tidak ada rilis stabil saat ini, tetapi akan segera dirilis.


1
GWT-Bootstrap berpotensi menjadi yang terbaik.
Mike

Kecuali untuk pengawasan desain yang sangat mendasar di area seperti tab & modals. Mereka perlu mengurangi ketergantungan mereka pada JQuery dan lebih memikirkan "aplikasi".
Καrτhικ

Patch sangat disambut. Terima kasih atas sarannya
caarlos0

4

Pengalaman saya menunjukkan bahwa selalu ada banyak masalah dengan perpustakaan pihak ketiga. Cara terbaik - adalah dengan menggunakan teknologi terkenal dan buatan itu sendiri ditambah komponen Anda sendiri. Mungkin perlu waktu lebih lama untuk menulis dan memeliharanya, tetapi TCO selalu di level yang lebih rendah.

Perpustakaan pihak ketiga sering kali dapat merusak rencana Anda secara tidak terduga. Dan sulit untuk menemukan dan memperbaiki sumber masalahnya.

Jadi saya sarankan untuk menggunakan GWT biasa.


3

Saya pikir SmartGWT baik-baik saja jika Anda hanya ingin menggunakan Widget sebagaimana adanya, tetapi jika Anda ingin memperluas atau memodifikasi widget seperti yang saya lakukan di Gxt Scheduler, saya pikir Ext-GWT adalah pilihan yang lebih baik.


3

bagi saya EXT-GWT (alias GXT) adalah pustaka terbaik yang tersedia saat ini, saya menggunakannya dalam proyek 6 bulan, dan sangat membantu dengan banyak komponen yang telah ditentukan seperti kisi, pohon .... Juga indah


3
Kamu pasti bercanda! Saya telah menggunakan GXT selama 18 bulan sekarang setiap hari dan saya dapat dengan jujur ​​mengatakan itu adalah mimpi buruk.
Alex Worden


2

Grup pengguna gwt-mosaic tampaknya tidak terlalu aktif dan saya tidak dapat menemukan panduan pengguna selain cuplikan wiki. gwt-mosaic memperkenalkan saya pada dua alat yang menarik.

1) gwt-mosaic menyertakan pembungkus untuk Tibco's PageBus yang merupakan alat publikasi / langganan untuk bagian JS aplikasi Anda (penangan RPC, panggilan balik widget, penyetel widget). Ini adalah alternatif bus acara gwt.

2) gwt-mosaic mendorong penggunaan Beans Binding (http://code.google.com/p/gwt-beans-binding/) untuk mengikat data ke widget dan memvalidasi widget.

smartgwt tidak murah untuk set fitur lengkap dan dukungan. Stoples terlalu besar untuk appengine kecuali Anda menghapus file tema yang tidak Anda gunakan. Mereka juga menginvestasikan teknik di sisi server.

Saya pernah mendengar ext-gwt lamban dan file JS berukuran besar.

Inkubator widget gwt tampak tidak digunakan lagi. Saya yakin grid deluxe akan dirilis dengan gwt baru.

Kurangnya standar tampilan-dan-rasa, pengikatan, dan validasi menghambat interoperabilitas pustaka widget.


Tidak ada masalah SmartGWT GAE dengan .jars besar kecuali Anda mengabaikan petunjuk penginstalan di dokumen. Faktanya, SmartGWT Pro menyertakan proyek contoh yang berjalan pada GAE dan menyediakan CRUD penuh, menggunakan JPA untuk ketekunan. Selain itu, murah itu relatif - opsi lisensi & dukungan paling mahal yang ditawarkan untuk SmartGWT masih merupakan bagian yang dapat diabaikan dari biaya untuk mengirimkan aplikasi / produk secara keseluruhan ketika biaya pengembang, QA, perangkat keras / hosting dll dipertimbangkan. Jika Anda memiliki anggaran yang sedikit, ada versi gratis (LGPL).
Charles Kendrick

2

Jelas bukan SmartGWT. Kerangka mereka membengkak dan memiliki sifat yang sangat setengah matang. Mereka memiliki jutaan widget, tetapi mencoba membuatnya berfungsi untuk proyek Anda tidaklah mudah. Sumber data mempersulit proses pengelolaan data Anda dengan cara yang sangat besar, misalnya, untuk mendapatkan data di sumber data Anda, Anda harus menggunakan fecth dan sering memeriksa. Meskipun Anda dapat menyimpan hasil dalam cache, tidak selalu mudah untuk menginterogasinya.

RPC adalah area lemah dan berbelit-belit lainnya. Ada informasi yang bertentangan dalam dokumentasi dan di forum. Sementara dokumentasi akan mengatakan bahwa Anda sebaiknya jarang menggunakan operasi kustom sebagai bagian dari ds, forum mereka akan memberi tahu Anda bahwa itu baik-baik saja. Belajar menggunakan alat-alat ini secara efektif merupakan pendakian yang menanjak di hari-hari terbaik.

Mereka akan menjual terlalu banyak produk. Misalnya, paket pembuatan bagan / analitik berisi grafik ... Tetapi grafik tersebut tidak akan menampilkan nilai negatif atau membiarkan Anda memanipulasi label sumbu dengan cara yang berarti. Dan mereka secara terbuka menanggapi pertanyaan tentang hal ini di forum dengan sikap "ya jadi apa". "Kami tidak berencana menambahkannya ke 3.0x meskipun itu salah satu nilai jual kami, itu ada di peta jalan kami." Ketika mereka menjual paket itu kepada saya, mereka tidak pernah menyebutkan bahwa saya tidak dapat menunjukkan nilai-nilai negatif. Betulkah? Grafik apa yang tidak perlu menunjukkan nilai negatif? Saya hanya bisa memikirkan satu - yang menggambarkan jumlah pelanggan Isomorfik yang tidak bahagia.

Jauhi orang-orang ini, dan kunjungi situs pesaing mana pun, misalnya ExtJS, JQuery, bahkan quxdoo. Ada beberapa proyek di luar sana yang benar-benar mulai berkembang dan benar-benar menawarkan solusi yang baik.

Berhati-hatilah jika Anda pernah mengevaluasi produk ini. Kelihatannya bagus, tetapi sekitar dua minggu setelah proyek menggunakannya, Anda akan mulai melihat apa yang saya maksud. Widget setengah matang, sumber data sangat rumit, dan hanya karena Anda membayar untuk dukungan forum, tidak berarti Anda benar-benar akan mendapatkan apa pun selain sinis, jawaban merendahkan yang pada awalnya akan membuat Anda mengira Anda melewatkan sesuatu. Anda tidak melakukannya, mereka umumnya sangat sombong.

Semoga sukses, dan jauhi produk ini jika Anda menghargai waktu pengembangan dan pemeliharaan Anda. Oh dan satu hal lagi. Lihat contoh MVC di situs web mereka. Ini benar-benar tidak ada hubungannya dengan MVC selain label bertuliskan "MVC". Mereka akan mencoba meyakinkan Anda bahwa kerangka kerja seperti itu untuk pengembang yang tidak berpengalaman, dan bahwa konsep seperti itu tidak memiliki tempat dalam pemrograman nyata ... Mirip seperti mereka yang mencoba menangkap blok.


Semuanya salah, karena Anda dapat memverifikasi dengan mudah. Berikut adalah contoh MVC ( smartclient.com/smartgwt/showcase/#featured_smartgwt_mvc ) pada dasarnya pengguna ini tidak memahaminya - baca deskripsinya dan Anda akan melihat kekuatan luar biasa yang ditunjukkan. Saya bahkan tidak dapat menebak apa yang dimaksud dengan keharusan "mengambil dan memeriksa" tetapi kemungkinan besar pengguna tidak membaca Panduan Memulai Cepat dan menggunakan sistem secara salah. Cukup baca sendiri ( smartclient.com/releases/SmartGWT_Quick_Start_Guide.pdf ) dan arsitekturnya jelas serta cukup jelas. Selain itu, bagan kami memplot nilai negatif.
Charles Kendrick

Jujur saja di sini. Versi stabil 3.0 saat ini tidak mendukung angka negatif, dan dengan kata-kata mereka sendiri menolak untuk mendukungnya: forums.smartclient.com/showthread.php?t=21219 .
binarygiant


?? Utas tersebut mengarahkan pelanggan untuk menggunakan rilis titik (3.1). Ini gratis, bukan peningkatan, dan sangat stabil. Anda mencoba membuat ini terdengar seperti upaya untuk menjual secara berlebihan atau mengekstrak lebih banyak uang, yang tidak hanya salah, tetapi juga tidak dapat jauh dari kebenaran: lihat saja semua fitur utama baru yang diperoleh orang secara gratis di 3.1 ( blog.isomorphic .com /… ). Anda jelas-jelas sengaja menyesatkan, yang menjelaskan komentar Anda yang lain.
Charles Kendrick

Tentu saja bukan niat saya untuk menyesatkan. Sebagai tanggapan, bagaimanapun, saya akan mengatakan bahwa menyesatkan untuk menyoroti semua fitur hebat dari suatu produk, dalam hal ini paket analitik, tetapi entah bagaimana mengabaikan bahwa itu tidak (sebelum 3.1), pada kenyataannya, merencanakan angka negatif. Lebih lanjut, meningkatkan ke rilis 3 "titik" tidak masalah selama tidak ada implementasi CSS khusus dalam rilis 3.0 yang menyoroti poin lain di mana bekerja dengan SmartGWT itu menyakitkan ...
binarygiant

1

Perpustakaan default Google adalah perpustakaan paling kuat.

Ext GWT menambahkan lonceng dan peluit tetapi selain itu mirip dengan Google.


1

Saat ini kami menyukai widget Mosaik GWT . Kami telah bekerja dengan ext-JS dan sebelumnya kami telah meluncurkan widget kami sendiri. lisensi ext-JS dan massal adalah masalah bagi kami. Menggulung milik kita sendiri bukanlah yang ingin kita lakukan. Mosaic memberi kita jalan tengah yang menyenangkan yang menurut kita akan menjadi jalan tengah yang lebih bahagia saat proyek ini matang.


1

Saya akan mengatakan jika Anda hanya membutuhkan beberapa widget, maka buat sendiri. Anda mungkin menyalin-tempel beberapa konsep dari pustaka yang disebutkan. Tapi mereka semua kekurangan satu atau lain hal. Saya telah bermain dengan sebagian besar dari mereka dan meninggalkan semuanya.


1

Satu hal yang harus diperhatikan adalah dari forum-forum GWT-Ext sepertinya tidak akan banyak dikembangkan / dipelihara lagi (mungkin tidak sama sekali?). Di situs web mereka, mereka merekomendasikan bermigrasi ke SmartGWT .


1

Tidak melihat yang ini disebutkan, Vaadin (sebelumnya dikenal sebagai IT Mill Toolkit), tetapi mungkin itu karena secara teknis tidak persis GWT; seperti yang dikatakan FAQ mereka :

Apa bedanya dengan GWT?

Aplikasi GWT berjalan di browser, sedangkan aplikasi Vaadin berjalan di server. Kami sebenarnya menggunakan GWT sebagai "mesin rendering" di sisi browser, jadi Anda dapat menggabungkan Vaadin dan GWT.


1

smartGWT lambat dan contoh kurang dan sangat sulit untuk menemukan jawaban bahkan untuk pertanyaan dasar, yaitu lihat semua pertanyaan saya yang tidak terjawab di forum ini. Saya membuang smartgwt.


SmartGWT jelas sedang dalam proses tetapi menjadi lebih baik. Pada dua kesempatan terpisah, saya meminta pengembang memperbaiki bug di bagasi dalam beberapa hari setelah saya melaporkannya, yang sangat menggembirakan. Ini adalah API yang besar dan berat, jadi Anda harus bertanya pada diri sendiri apakah itu cocok dengan aplikasi yang Anda tulis.
AndrewR

SmartGWT memiliki lebih banyak sampel daripada perpustakaan mana pun yang dibahas di sini. Ini secara obyektif dapat diverifikasi: ( smartclient.com/smartgwt/showcase/#main ) Kami juga memiliki Panduan Memulai Cepat yang sangat kuat ( smartclient.com/releases/SmartGWT_Quick_Start_Guide.pdf ). Silakan lihat pertanyaan yang diajukan pengguna ini - satu tidak valid, satu lagi saya jawab.
Charles Kendrick


0

Kami telah membangun portal HR yang besar dan beberapa aplikasi yang lebih kecil menggunakan GWT Portlets . Fokus proyek ini tidak terlalu banyak pada membangun kumpulan widget tetapi pada pembuatan model pemrograman sederhana.

Dari situs web:

GWT Portlets adalah kerangka kerja web sumber terbuka gratis untuk membangun aplikasi GWT (Google Web Toolkit). Ini mendefinisikan model pemrograman yang sangat sederhana & produktif, namun kuat untuk membangun aplikasi GWT modular yang bagus.

Model pemrograman agak mirip dengan menulis portlet JSR168 untuk server portal (Liferay, JBoss Portal, dll.). "Portal" adalah aplikasi Anda yang dibuat menggunakan framework GWT Portlets sebagai pustaka. Fungsionalitas aplikasi dikembangkan sebagai Portlet yang digabungkan secara longgar masing-masing dengan DataProvider sisi server opsional.


0

Saya menggunakan GWT selama satu tahun. Setelah banyak penelitian, saya memutuskan GWT Mosaic sebagai pustaka widget .. Mosaic menggunakan beberapa komponen inkubator GWT seperti PagingScrollTable .. Tetapi fitur combobox dan tabel tidak mencukupi untuk kami .. Itulah sebabnya, kami memiliki memperluas komponen ini untuk menambahkan fungsionalitas yang diperlukan.



0

Dua hal penting -dan apa yang terlewatkan oleh sebagian besar perpustakaan- adalah pengujian unit dan debugging. Di sinilah GWT bersinar. Jika Anda menggunakan pustaka yang didasarkan pada vanilla js, Anda memberikan kemampuan untuk menguji unit dan men-debug proyek Anda. Sebagai pengembang GWT, Anda harus mempertimbangkan poin-poin ini dan menggunakan perpustakaan tanpa ketergantungan js atau minimal.


0

Kami telah melakukan proyek gwt selama lebih dari 2 tahun, dan kami tetap menggunakan widget default. Kami membuat perpustakaan sumber terbuka kami sendiri untuk mengisi otomatis yang default atau ekstensi widget kami sendiri. Silakan periksa, namanya gwt-jet . Ini telah diuji dengan sangat baik karena kami menggunakannya di lingkungan produksi yang besar, dan kami berharap ini akan tumbuh dengan aman seiring waktu.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.