A következő címkéjű bejegyzések mutatása: tipp. Összes bejegyzés megjelenítése
A következő címkéjű bejegyzések mutatása: tipp. Összes bejegyzés megjelenítése

2009. szeptember 24., csütörtök

SQL Server 2005 SP3 install hiba elhárítása

Ebbe a problémába én is belefutottam. Nem volt könnyű rájönni a megoldásra.

Én akkor nem írtam le, de más megtette: http://bit.ly/3JF5dp

Még jól jöhet.

2009. április 10., péntek

Postback probléma régebbi IIS (5.x, 6) és/vagy XP Pro és ASP.NET routing esetén

A fejlesztői és a végfelhasználói környezet különbsége sok esetben okozott már fejtörést. Nálunk most éppen a futótérkép fejlesztése körül jelentkezett egy probléma az ASP.NET routing szolgáltatása kapcsán. Konkrétan a fejlesztői gép egy XP míg az alkalmazás valami újabb (esetünkben 2008 server). A routingot pedig használni kell, mert mennyivel jobban néz ki (meg persze SEO frendlibb) egy olyan path, hogy http://www.futoterkep.hu/utvonalak/ mint az, hogy http://www.futoterkep.hu/Modules/TrackList/tr_list.aspx. Igen ám, de az XP Pron az 5.1-es IIS erre az első aszinkron postback után egy 405-ös hibával köp szembe. Ez szerinte annyit jelent, hogy a postot a dev/null-ba küldted és nincs aki válaszoljon túlnan. Hosszas guglizás után sikerült kideríteni (már a hibaüzenet pontos jelentését sem könnyű), hogy a probléma az, hogy a borítékról lemaradt a címzés, így szegény postás vinné, de nem tudja, hogy hová. A HTTP világban ez annyit tesz, hogy a FORM tag action paramétere nem töltődik ki automatikusan és szegény IIS keresné azt a lapot, ahová a kérést küldjük, ami alapértelmezetten a _self vagyis saját maga. Igen ám, de a routinggal megtámogatott oldal esetén ez a lap fizikailag nem létezik, szegény IIS pedig buta és nem tudja megtalálni.

Mi hát a megoldás? Természetesen meg kell címezni a borítékot:

this.form1.Action = this.Request.RawUrl;

Ezután már tudja a postás hová kell vinni és Náncsi néni boldogan nézegeti mekkorát nőttek az unokák.
Persze a dologra rájönni korántsem volt annyira egyszerű, mint ahogy látszik. Remélem van akinek megspóroltam most néhány órányi google túrást…

2009. március 24., kedd

Kép vagy állomány letöltés adott URL mögül

Nemrég szükségem volt a tárgybelire és szokás szerint ismét nem ugrott be elsőre a megoldás.
Gyanítom, hogy más is így lehet ezzel, tehát a magam és minden hozzám hasonlóan feledékeny olvasó számára most lejegyzem a dolgot.
 System.Net.WebClient objWebClient = new System.Net.WebClient();
 objWebClient.DownloadFile(URL, FILENAME);
 System.Drawing.Image imgPhoto = System.Drawing.Image.FromFile(FILENAME);

Esetleg van másféle megoldás is?

2009. március 17., kedd

Firefox és az updatepanel esete deafult buttonnal

Nemrégiben komoly szívások voltak a Futótérkép fejlesztése során az alapértelmezett gombok beállításával azon a néhány helyen, ahol még használunk UpdatePanel kontrolt.
Különböző variációk keletkeztek. Vagy nem is posztolt az alapértelmezett gomb, ha posztolt, akkor nem triggerelte az eseményt és természetesen FF és IE alatt teljesen másképp működött minden megoldás.
Végül ez a blogbejegyzés helyes nyomra vezetett, most már legalább a két mainstream böngésző alatt jól működik. A regisztrációs formon ki lehet próbálni ;)

2009. március 7., szombat

Tartalmazott pont lekérdezése és google maps kinézet egyszerű testreszabása

A google maps újabb verziói ismét szolgálnak néhány hasznos aprósággal.
Ezek közül kettőt emelnék ki, amik nekem igen hiányoztak pl. a futótérkép építése közben.

Az egyik ilyen új függvény arra szolgál, hogy lekérdezhessük egy adott pontról, hogy benne van-e az adott tartományban vagy sem. Természetesen koordináták egyszerű vizsgálatával eddig sem volt ördöngősség kideríteni, de mégiscsak egyszerűbb meghívni a

bounds.containsLatLng(center)

metódust, mint koordinátákat hasonlítgatni. A függvény a 2.88-as verziótól elérhető.
A másik hasznos és egyben csinos újítás a 2.147-ben került be:

map.setUIToDefault();

Igen, ez a pontosan azt csinálja amire a neve utal, vagyis beállítja az alapértelmezett kinézetet egyetlen függvényhívással olyanra, mint a "nagy" Google Maps.
Összeütöttem egy kis példát a két újdonság felhasználásával. A térkép alatti üzenet jelzi, ha mozgatás után a marker kilóg a térképről.


Íme a kód lényeges része:

var map;

var center = new GLatLng(47.173378, 19.539185);

$(document).ready(function()

{

if (GBrowserIsCompatible())

{

map = new GMap2($("#GoogleMap_Div")[0]);

map.setUIToDefault();

map.setCenter(center, 10);

GEvent.addListener(map, "moveend", checkIsInView);

var myMarker = new GMarker(center);

map.addOverlay(myMarker);

checkIsInView();

}

});

function checkIsInView()

{

var bounds = map.getBounds();

var message = ";

if (bounds.containsLatLng(center))

{

message += "green;\">Benne van";

}

else

{

message += "red;\">Nincs benne";

}

message += "";

$("#message")[0].innerHTML = message;

}

2009. február 9., hétfő

.NET optimalizálási tapasztalatok - idegen tollak


Na nem a saját tapasztalataimról van szó, mert hogy jönnék én ahhoz ugye :)
A napokban indult el egy hasznos post sorozat Soci által (http://soci.hu), amiben a saját .NET optimalizálási tapasztalatait írja le nekünk, hogy okuljunk :)

http://soci.hu/blog/index.php/category/szakmai-elet/optimalizalas/

2009. február 8., vasárnap

Geokódolás tipp a Google Maps-hoz

Az itt közzétett - véleményem szerint rendkívül hasznos - frissítés eredményeképpen geokódoláskor (gy.k. címkeresés :)) nem csak a középonti koordinátát kaphatjuk vissza, hanem az ajánlott befoglaló koordinátákat is.
Akkor látjuk hasznát ennek, ha geokódolás után szeretnénk ránagyítani az objektumra vagy már eredendően ezekkel a befoglalókkal szeretnénk inicializálni a térképet és mág ezer más esetben.
Nagyon hasznos lehet clusteringhez is.
Pusztavacs

Kézzelfoghatóan, például az ország közepének keresésekor (http://maps.google.com/maps/geo?output=jsonl&oe=utf-8&q=Pusztavacs,%20Hungary) a visszaadott JSON tartalmaz egy ExtendedData tagot, amelyben megtaláljuk a befoglalót:



{
"name": "Pusztavacs, Hungary",
"Status": {
"code": 200,
"request": "geocode"
},
"Placemark": [ {
"id": "p1",
"address": "Pusztavacs, Hungary",
"AddressDetails": {"Country": {"CountryNameCode": "HU","CountryName": "Hungary","AdministrativeArea": {"AdministrativeAreaName": "Pest","Locality": {"LocalityName": "Pusztavacs"}}},"Accuracy": 4},
"ExtendedData": {
"LatLonBox": {
"north": 47.2079051,
"south": 47.1073380,
"east": 19.6032050,
"west": 19.4464160
}
},
"Point": {
"coordinates": [ 19.5010859, 47.1712960, 0 ]
}
} ]
}

2008. december 9., kedd

Legutolsóként lefutó JS függvény

Nemrég szükségem volt rá, hogy egy bizonyos javascriptet úgy futtassak le egy usercontrolokat bőven tartalmazó MS-AJAXos ASPX oldalon, hogy MINDENKÉPPEN ő legyen a legutolsó.
Teljesen függetlenül attól, hogy esetleg itt-ott RegisterStartupScript metódusok vagy bármi egyéb megoldások az oldal részeiben most vagy később garázdálkodnak-e, én azt szeretném, ha nem borítanák meg a rendet.
Hosszas guglizás és kísérletezés után találtam egy többé-kevésbé kielégítő megoldást.
Azért csak többé-kevésbé, mert IE és FF esetében az elvárt módon működik, de sajnos opera alatt nem (mást meg sem mertem próbálni :)).


A kulcs az alábbi függvény:


function AddOnload(myfunc)
{
    if (window.addEventListener)
        window.addEventListener('load', myfunc, false);
    else if (window.attachEvent)
        window.attachEvent('onload', myfunc);
}


Ami ugye (kompatibilitási okokból kétféleképpen) feliratkozik az oldal onload eseményére.
Ezt próbáltam különböző módokon meghívni, hogy a kívánt eredményt kapjam.


Az első változat így nézett ki:



<html>
<head>
    <script type="text/javascript">
        function mymessage()
        {
            alert("onload event");
        }
 
        ...
        ...
 
        alert('inline');
        AddOnload(function() { alert('TheLastOne'); });
    </script>
</head>
<body onload="mymessage()">
    ... ...
</body>
</html>



IE-re már jó is volt. Először megjelent az inline kód, utána az online attribútumban megadott végül pedig az ominózus utolsó. FF esetében már sajnos nem ez volt a sorrend. Ott gyakorlatilag inline
függvényhívásként működött a dolog, szerintem helytelenül. Azután eltoltam a feliratkozást az oldal végére, ez a FireFoxot is rávezette arra, hogy mit is akarok tulajdonképpen. Mint említettem Operában továbbra sem jó ez a megoldás, de több időt nem szántam rá.
Őszintén szólva az IE és a FF a 99.9%-át lefedi felhasználóknak, tehát ennyiben hagytam a dolgot.



    1 <html>
    2 <head>
    3     <script type="text/javascript">
    4         function mymessage()
    5         {
    6             alert("onload event");
    7         }
    8 
    9         function AddOnload(myfunc)
   10         {
   11             if (window.addEventListener)
   12                 window.addEventListener('load', myfunc, false);
   13             else if (window.attachEvent)
   14                 window.attachEvent('onload', myfunc);
   15         }
   16     </script>
   17 
   18 </head>
   19 <body onload="mymessage()">
   20     ...
   21     ...
   22 </body>
   23 
   24 <script>
   25     alert('inline');
   26     AddOnload(function() { alert('TheLastOne'); });
   27 </script>
   28 </html>


Elég érdekes, hogy melyik böngésző hogyan értelmezte az utasítást.
A fenti kód lett a végső változat, amely FF és IE esetében egyformán utolsónak hívja a kívánt scriptet.

2008. december 2., kedd

WinMerge beállítása merge tool-ként a TotalCommanderben


Ez a tipp hasznos lehet TC és WinMerge fanoknak.

A dolog meglehetősen egyszerű. Fogd a wincmd.ini fájlt és írd be a konfigurációs szekcióba a következőt:

Comparetool=C:\program files\winmerge\WinMerge.exe

A path értelemszerűen behelyettesítendő. Természetesen a dolog nem titkos, benne volt anno a release notes-ban, vélhetően a helpben is meg lehet találni, de hát ki olvassa ezeket? :)

2008. november 29., szombat

A TabContainer és a rejtélyes tábla esete

Jelenleg épp egy olyan ASP.NET alkalmazáson dolgozom, ami használja az AJAX Control Toolkit TabContainer kontrolját.

Tudni kell, hogy az adott alkalmazás esetében eléggé sarkalatos kérdés performancia. Magyarul lassú mint a csiga az akácerdőbe'. Ez részben annak köszönhető, hogy meglehetősen összetett és az összes létező technológiát használja, sőt néhány nem létezőt is :) Ennek megfelelően folyamatosan mérve van és a legkisebb további lassulás is eléggé mély ráncokat vés a homlokokra.

Az előzmények ismeretében érthető, hogy nem volt túl örömteli, mikor egy dizájn csiszolgatás után, ahol is kis kinézetbeli igazgatások történtek, bekerült egyszer csak valahonnan 4 másodperc (!) extra renderelési idő. Igaz, hogy a cucc nagyon lassú, de azért 4 másodperc még így is mintegy 70-80%-os lassulást jelentett. Azonnal elkezdődött a vad nyomozás, majd végül kiderült, hogy nem más tekeri meg ennyire a böngészőt, mint egyetlen egy darab dekorációs célból odabiggyesztett 1 pixeles vonal, ami ezzel a kóddal lett kivitelezve:

<table class="tab_top_decor">

<tbody>

<tr>

<td class="tab_top_decor_selected">

</td>

<td>

</td>

</tr>

</tbody>

</table>


Rendben, elismerem, nem a legjobb erre a célra táblázatot használni, de mivel az oldal teljes egészében old-school (és nem túl okos) módon táblázatokkal van formázva, így azt gondoltam, nem oszt nem szoroz, ráadásul akkor még nem tudtam erről a trükkről, ami a 6os explorernek is megmondja, hogy márpedig mekkora az akkora.
Érthető módon majd megölt a kíváncsiság és szanaszét teszteltük az oldalt, míg végül kiderült, hogy az adott tábla csak a TabContainer belsejébe helyezve okozza ezt a durva lassulást. Idő híján nem nyomoztunk tovább, de valószínűleg a TabContainer javascriptjei között van valami ordenáré módon lebaltázva, aminek ezt a 4 másodpercet köszönhettük.

Miután a korábban említett trükköt kiderítettem átírtam DIV-re a dekorációs csíkot és így már minden rendben volt. Na meg természetesen eldöntöttük, hogy ha egy mód van rá megszabadulunk a tebkonténertől, mielőtt még egy időzítet bomba az arcunkba robban.

2008. november 28., péntek

IE6 és a DIV méretezése

Jelenleg egy olyan projektben dolgozom, ahol az egyetlen és kizárólagos webkliens az Internet Explorer, annak is az öregecske 6-os verziója. Mint tudjuk az IE mindig is arról volt hírhedt, hogy nagyvonalúan kezeli a szabványokat, de különösen hírhedt ez a verzió a DIV elementek érdekes kezeléséről. Nálam ez most éppen azért okozott fejtörést, mert dekorációs célzattal egy 1px-es vonalat kellett elhelyeznem, ami dinamikusan alakulgat. Lényeg az, hogy a leglogikusabb megoldásnak egy 1px magas DIV tűnt. Volna. Ha az IE hajlandó lett volna 10px-nél kisebb elemet megjeleníteni.
Hosszas guglizás után kisült, hogy ez a csacsi IE nem hajlandó az aktuális fontméretnél alacsonyabb lenni, csak, ha ezt külön megmondjuk neki. Hm. Ez vajon kinek a fejéből pattanhatott ki? Vagy csak mellékhatás? Bizonyíték gyanánt nézd meg ezt a kódot IE6 alól:

<div style="background-color: #FF0000; height: 1px"></div>


Ime:

Ha a fentit tudjuk, akkor már könnyen rá lehet jönni, hogy milyen beállításokkal lehet elérni a kíván 1px magasságot.
Logikusnak tűnik a DIV számára az 1px-es fontméret beállítása.

<div style="background-color: #FF0000; height: 1px; font-size: 1px"></div>





Ez a megoldás majdnem jó, de nem teljesen. Így már tudunk egész kicsi magasságot beállítani, de 1px-et mégsem.
Az igazi okosság az overflow tulajdonság beállítása, ami azt jelenti, hogy lekezeljük a kilógó részeket.

<div style="background-color: #FF0000; height: 1px;overflow: hidden"></div>





Így már tökéletes 1px-es csíkunk van. Fentieket teszteléséhez kiválóan lehet alkalmazni az IETester nevű segédprogramot, ami 5.5-től felfelé bármelyik IE verziót tudja nekünk prezentálni.

2008. november 23., vasárnap

Levélküldés tesztelése SMTP nélkül

A legtöbb webes alkalmazásban van egy-két olyan sztori, amikor levelet szándékozunk kiküldeni a rendszerből. A végleges változatban általában SMTP szerver felhasználásával tesszük ezt, de fejlesztés közben meglehetősen kényelmetlen minden tesztfuttatás alkalmával ellenőrizni egy postaládát. Ráadásul korántsem biztos, hogy rendelkezésre áll a megfelelő szerver, a fejlesztői gépre sem feltétlenül tudunk vagy akarunk telepíteni.
Ilyenkor az SmtpClient osztály beállításával megtehetjük, hogy a saját fájlrendszerünkkel "levelezünk".
Fentiekhez a web.config állományban a következő beállítások szükségesek:

<system.net>

<mailSettings>

<smtp deliveryMethod="SpecifiedPickupDirectory">

<specifiedPickupDirectory pickupDirectoryLocation="c:\temp\mailpickup"/>

</smtp>

</mailSettings>

</system.net>


Így azonnal ellenőrizhetjük, hogy az üzenet a megfelelő tartalommal előállt-e.

[Test]

public void SendMailTest()

{

SmtpClient smtpclt = new SmtpClient();

MailMessage message = new MailMessage("from@server.com", "to@server.com");

message.Body = "Body";

message.Subject = "subject";

smtpclt.Send(message);

}


A kliensnek egyébként futás közben is megmondhatjuk, hogy a levelet ebbe a könyvtárba küldje:

smtpclt.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;

smtpclt.PickupDirectoryLocation = "c:\\temp\\mailpickup";

2008. november 13., csütörtök

jQuery intellisense tipp

FRISSÍTÉS:
Tegnap olvastam, hogy a Microsoft a VS2008-hoz megjelentette ezt a frissítést, ami lehetővé teszi, hogy trükközés nélkül használjuk a jQuery intellisense támogatást.

Kettővel ezelőtt írtam, hogy van már VS intellisense részére kommentelt jQuery.
Van egy okos trükk, hogy véletlenül se felejtődhessen benne a végső kódban a kommentekkel tűzdelt js állomány.

<script src="jquery-1.2.6.js" type="text/javascript"/>

<% if (false) { %> <script src="jquery-1.2.6-vsdoc.js" type="text/javascript"/>

<% } %>



A fenti módon inkludálva a scriptet az intellisense látni fogja, viszont rendereléskor nem kerül be az oldalba.
(A tipp az ASP.NET Debugging blogról származik)



2008. október 28., kedd

Intellisense jQuery támogatás a Visual Studiohoz

Nemrégiben röppent fel a hír, hogy a MS letette a voksát a jQuery függvénykönyvtár mellett.
Ennek jegyében a jQuerynél elkészítettek egy a VS számára kommentekkel ellátott verziót, amit az IntelliSense tud kezelni.


Letölthető innen:
1.2.6:
http://code.jquery.com/jquery-1.2.6-vsdoc.js
Latest release (jelenleg ugyanaz)
http://code.jquery.com/jquery-latest-vsdoc.js

Arra azért ügyeljünk, hogy ezek a kommentek nem kicsit hizlalták fel a függvénykönyvtárat. A végső verziókban ne felejtsd el lecserélni a kommentezett verziót a minified vagy a packed verzióra!

2008. szeptember 17., szerda

Lorem ipsum generátor

Gondolom mindenki látott már a „Lorem ipsum" kezdetű latin szöveggel feltöltött oldalakat, adatbázismezőket.

A http://www.lipsum.com/ weboldal egyik oldalról a fenti szöveg különböző fordításait tartalmazza, ha valaki – mint én is – kíváncsi rá, hogy mit is lát tulajdonképpen, amikor ezt a szöveget olvassa. Másik szerepét tekintve az oldal gyakorlatilag BLABLAGYÁR névre hallgathatna magyarul, mert tetszőleges hosszban és/vagy sorszámban tud előállítani kitöltő szöveget, ha akarod "Lorem ipsum"-mal az elején ☺ Készítettek egy remekbeszabott Firefox plugint is, hogy ne kelljen az oldalra elzarándokolni, ha az ember például egy 1000 karakterre korlátozott mező validálását vagy egy karakterszámlálót vagy effélét szeretne tesztelni.

Tud magyarul is:

http://hu.lipsum.com/

2008. szeptember 5., péntek

Hosszú elérést röviden

Ismét sikerült felfedeznem egy hasznos apróságot a C#-ban.
Velem együtt valószínűleg többen dolgoztak már úgy, hogy egyszerre használták pl a

System.Drawing.Drawing2D

és a

System.Web.UI.WebControls

névtereket.

Ilyenkor, ha egyik vagy másik helyről szeretnénk az Image objektumot használni, akkor kénytelenek vagyunk végigkalapálni az objektum teljes nevét névterestül, mindenestül.

Ez intellisense-el nem olyan nehéz, de mégiscsak munkás, meg hát nem is szép. Például:
System.Drawing.Drawing2D.Image im = new System.Drawing.Drawing2D.Image();
Ilyen esetekben hasznos lehet a névterekre illeszthető alias, amit az alábbi módon használhatunk:

using Draw = System.Drawing.Drawing2D;
Draw.Image im = new Draw.Image();

Így azért csak rövidebb :)

2008. augusztus 31., vasárnap

Magyarul is gyalogolhatunk

Nemrégiben írtam róla, hogy a Google térképén lehetőség van az autós (és a világ nyugati felén "békávés") útvonaltervezés mellett, hogy gyalogos sétára kérjünk javaslatot.
Akkor mi még nem használhattunk, de valamikor a közelmúltban suttyomban megjelent ez a feature a magyarországi térképen is.
Sétáljunk át mondjuk a Városligeten az Állatkerthez.

2008. augusztus 17., vasárnap

Hasznos apróságok a Visual Studio 2008 SP1-ben

Ahogy azt korábban írtam nemrégiben megérkezett a VS2008 SP1 végleges változata. Mostanra összegyűlt pár apróság, amit úgy gondoltam érdemes közzétenni.
Előrebocsátanám, miszerint lehet, hogy némelyik itt leírt feature már korábban is megvolt, csak én nem ismertem.

A JavaScript kódok formázásának támogatása az egyik olyan újdonság, amit már réges-rég időszerű lett volna, még akkor, mikor a VS fejlesztői a webes fejlesztés támogatását is bevették a kalapba. A 2008 kiadásával egy egész korrekt intellisense támogatáshoz juthattunk már hozzá, de ez még hiányzott. Igazából még mindig nem lehetünk elégedettek, mert nekem még mindig hiányzik a JS függvények ki-be csukásának lehetősége, ami ugye úgy a HTML, mint a C# vagy VB kódszerkesztőben időtlen idők óta fellelhető.
A szükséges beállítások nem meglepő módon a Tools > Options > Text editor > JScript alól érhetőek el.

Hasonlóan érthetetlen módon eddig a kódkommentekben levő TODO elemeket csak a megnyitott fájlokból volt hajlandó kiolvasni. Én személy szerint szerettem volna együtt látni minden ilyen bejegyzést, ez azonban egy nagyobb projekt esetében meglehetősen problémás lett volna. Az SP1 után nincs ennek akadálya.

Aki szereti pl a Firefox keresési módszerét előnyben részesíteni, annak lehet jó a ctrl+i billentyűkombináció, ami az inkrementális keresést teszi lehetővé az éppen aktuális fájlban. Magyarul, a beírással párhuzamosan keres rá a szövegrészletre.


Egy másik apróság a megnyitott fájlok közötti navigációra ad egy alternatívát. A crtl+tab helyett használhatjuk a ctrl+alt+down (lefelé nyíl) kombót, ami egy kicsi csinos forráslista nézetet ad nekünk.

2008. július 19., szombat

Hogyan látják mások?

Gyakran van, hogy szeretnénk az elkészült weboldalunkat, ha nem is tesztelni, de legalább egy pillantást vetni rá különböző böngészőkön és operációs rendszerek alatt.
Könnyen meg lehet tenni ezt a http://www.browsershots.org címen, ahol minden jelentős (és jelentéktelen) böngésző-oprendszer párosítást megtalálunk. Csak be kell írni a megnézni kívánt oldal címét aztán várni, időnként persze visszanézegetni. A képek egy idő után törlődnek, így egy kis időt rá kell szánni, de esetneként érdemes lehet. Pl. ha épp készülünk kifizetni egy munkát amiről azt mondják, hogy így néz ki linux/konqueror alól is, de aztán meg hátha mégsem ;)

2008. május 27., kedd

Újabb ingyenes e-book .NET témában

Bár inkább cikkgyűjteménynek nevezhető, ami a Simple-Talk közösségi szájt néhány írását fogja egybe. Bár ha jól sejtem elsődlegesen a marketing célokat szolgált a gyűjtemény létrehozása, illetve közzététele, de ettől függetlenül rendkívül hasznos anyagnak tűnik első blikkre. Olyan problémák kerültek be a válogatásba, amik közül jó esélyyel legalább egyeel minden ASP.NET-tel foglalkozó fejlesztő találkozott már.
Letölthető innen.