28 Ocak 2018 Pazar

javascript fonksiyon defination varyasyonları

javascriptte fonksiyonlar otomatik olarak window nesnesine bağlanır. window nesnesinde ki fonksiyonlar global dır ve heryerden erişilebilir.

Heryerden erişilmesine gerek olmayan fonksiyonlar ise object içinede tanımlanır ve sadece o object ismi ile invoke edilebilir.  Bu yöntem programcılar tarafından tercih edilen bir yöntemdir.

Bir fonksiyonda return olması zorunlu değildir. Return olmayan fonksiyonlar geriye undefined döndürür.


Bir fonksiyonda belli bir koşula göre erken çıkmak için de return ifadesi kullanılır.
.


1. function bildirimi (defination)
function functionName(parameters) {
// body goes here
}

Bu şekilde tanımlamanın avantajı invoke edildiği yerin üstünde de olsa çalışır altında da olsa çalışır.
Örnek

var circleArea = computeArea(3);
console.log("Area of circle with radius 3: " + circleArea);
circleArea = computeArea(5);
console.log("Area of circle with radius 5: " + circleArea);
circleArea = computeArea(7);
console.log("Area of circle with radius 7: " + circleArea);

function computeArea(radius) {
var area = radius * radius * Math.PI;
return area;
}
2. function ifadeleri (expressions)
 
function computeArea(radius) {
var area = radius * radius * Math.PI;
return area;
}
var computeArea = function(radius) {
var area = radius * radius * Math.PI;
return area;
};

Bu şekilde tanımlamada fonksiyon bir değişken gibi tanımlanıyor. Bir değer barındıran değişken bu sefer bir fonksiyon barındırıyor. 
Bu şekilde tanımlamada fonksyion bir değişkene atandığı için kesinlikle invoke edilmeden önce tanımlanmalıdır. Aksi halde hata oluşur.
Örnek
var computeArea = function(radius) {
var area = radius * radius * Math.PI;
return area;
};
var circleArea = computeArea(3);
console.log("Area of circle with radius 3: " + circleArea);
circleArea = computeArea(5);
console.log("Area of circle with radius 5: " + circleArea);
circleArea = computeArea(7);
console.log("Area of circle with radius 7: " + circleArea);
var computeArea = function(radius) {
var area = radius * radius * Math.PI;
return area;
};

3. İsimsiz Functions (Anonymous)

Bir fonksiyon sadece 1 kez kullanılacak başka yerde kullanılmayacaksa isimsiz fonksiyon olarak tanımlanır.

Bu şekilde tanımlamanın avantajı gereksiz foksiyon tanımlamalarını önlemektir. Dolayısıyla site kod okunurluğunu artırır ve tarayıcı performansını olumlu yönde etkiler.
Örnek
var myArray = [1, 2, 3];
var newArray = myArray.map(function(x) { return x+1; });
console.log(newArray);
function map(a, f) {
var newArray = [];
for (var i = 0; i < a.length; i++) {
newArray.push(f(a[i]));
}
return newArray;
}
function addOne(x) {
return x+1;
}
var newArray2 = map(myArray, addOne);//bu kısımda fonksiyona parametre olarak fonksiyon gönderilmektedir
var newArray2 = map(myArray, function(x) { return x+1; });
console.log(newArray2);


4.fonksiyon dan fonksiyon döndürme (Returning a Function from a Function

)
Fonksiyona parametre olarak fonksiyon gönderilebileceği gibi (yukarıdaki örneği incele), fonksiyon geri dönüş değeri olarak bir fonksiyon döndürebilir. 
Aşağıdaki örneği dikkatlice inceleyin.
Örnek
function makeConverterFunction(multiplier, term) {
      return function(input) {
          var convertedValue = input * multiplier;
          convertedValue = convertedValue.toFixed(2);
          return convertedValue + " " + term;
     };
}
var 
kilometersToMiles = makeConverterFunction(0.6214, "miles");
console.log("10 km is " + kilometersToMiles(10));
var milesToKilometers = makeConverterFunction(1.62, "km");
console.log("10 miles is " + milesToKilometers(10));

5. Functions as Callbacks
Javascriptin kalbi olaylardır (events). Javascripte olayları işlemek için fonksiyonlar kullanılır.
Genellikle olay işleyicilerine callback denir çünkü olay olduğunda, o olayı işlemek için bir fonksiyonu "geri çağırırız". Geri bildirimler her zaman olaylarla ilgili değildir. Ama çoğunluk itibariyle olaylarla ilgilidir.


Callbackler genellikle asenkron işlemlerde kullanılır. aşağıdaki örnekte konumunuz tespit edilmeye çalışılacaktır. Konumun ne zaman tespit edileceği belli değildir. Tespit edildiği anda getLocation fonksiyonu çalıştırılacaktır

(function() {//bu fonksiyon iife fonksiyondur, otomatik olarak çalışır
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(getLocation);
}
else {
console.log("Sorry, no Geolocation support!");
return;
}
})();

function getLocation(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;

console.log( "You are at lat: " + latitude + ", long: " + longitude);
}

24 Ocak 2018 Çarşamba

e ticaret notları

/*-- Product Quantity --*/
$('.product-quantity').append('<span class="dec qtybtn"><i class="fa fa-angle-left"></i></span><span class="inc qtybtn"><i class="fa fa-angle-right"></i></span>');
$('.qtybtn').on('click', function() {
var $button = $(this);
var oldValue = $button.parent().find('input').val();
if ($button.hasClass('inc')) {
var newVal = parseFloat(oldValue) + 1;
} else {
// Don't allow decrementing below zero
if (oldValue > 0) {
var newVal = parseFloat(oldValue) - 1;
} else {
newVal = 0;
}
}
$button.parent().find('input').val(newVal);
});
/*-- Product Quantity --*/ 

Spiffy.onError(XMLHttpRequest, textStatus)

Spiffy.onCartUpdate(cart)

Spiffy.onItemAdded(line_item)

Spiffy.onProduct(product)

Spiffy.resizeImage(image, size)



Ajax Calls

Spiffy.addItem(variant_id, quantity, callback)

Spiffy.addItemFromForm(form_id, callback)

Spiffy.getCart(callback)

Spiffy.getProduct(handle, callback)

Spiffy.changeItem(variant_id, quantity, callback)

Spiffy.changeItemIndex(cart_index, quantity, callback)

Spiffy.removeItem(variant_id, callback)

Spiffy.removeItemIndex(cart_index, callback)

Spiffy.clear(callback)

Spiffy.updateCart(updates, callback)

Spiffy.updateCartFromForm(form_id, callback)

Spiffy.updateCartAttributes(attributes, callback)

Spiffy.updateCartNote(note, callback)





function floatToString(t, r) {
    var e = t.toFixed(r).toString();
    return e.match(/^\.\d+/) ? "0" + e :
        e
}

function attributeToString(t) {
    return "string" != typeof t &&
        "undefined" === (t += "") && (t =
            ""), jQuery.trim(t)
}
"undefined" == typeof window.Shopify &&
    (window.Shopify = {}), Shopify.money_format =
    "${{amount}}", Shopify.onError =
    function(t, r) {
        var e = eval("(" + t.responseText +
            ")");
        e.message ? alert(e.message +
            "(" + e.status + "): " +
            e.description) : alert(
            "Error : " + Shopify.fullMessagesFromErrors(
                e).join("; ") + "."
        )
    }, Shopify.fullMessagesFromErrors =
    function(t) {
        var r = [];
        return jQuery.each(t, function(
            t, e) {
            jQuery.each(e,
                function(e,
                    a) {
                    r.push(
                        t +
                        " " +
                        a
                    )
                })
        }), r
    }, Shopify.onCartUpdate = function(
        t) {
        alert("There are now " + t.item_count +
            " items in the cart.")
    }, Shopify.onCartShippingRatesUpdate =
    function(t, r) {
        var e = "";
        r.zip && (e += r.zip + ", "), r
            .province && (e += r.province +
                ", "), e += r.country,
            alert("There are " + t.length +
                " shipping rates available for " +
                e + ", starting at " +
                Shopify.formatMoney(t[0]
                    .price) + ".")
    }, Shopify.onItemAdded = function(t) {
        alert(t.title +
            " was added to your shopping cart."
        )
    }, Shopify.onProduct = function(t) {
        alert(
            "Received everything we ever wanted to know about " +
            t.title)
    }, Shopify.formatMoney = function(t,
        r) {
        function e(t, r) {
            return void 0 === t ? r : t
        }

        function a(t, r, a, o) {
            if (r = e(r, 2), a = e(a,
                    ","), o = e(o, "."),
                isNaN(t) || null == t)
                return 0;
            t = (t / 100).toFixed(r);
            var n = t.split(".");
            return n[0].replace(
                /(\d)(?=(\d\d\d)+(?!\d))/g,
                "$1" + a) + (n[1] ?
                o + n[1] : "")
        }
        "string" == typeof t && (t = t.replace(
            ".", ""));
        var o = "",
            n = /\{\{\s*(\w+)\s*\}\}/,
            i = r || this.money_format;
        switch (i.match(n)[1]) {
            case "amount":
                o = a(t, 2);
                break;
            case "amount_no_decimals":
                o = a(t, 0);
                break;
            case "amount_with_comma_separator":
                o = a(t, 2, ".", ",");
                break;
            case "amount_with_space_separator":
                o = a(t, 2, " ", ",");
                break;
            case "amount_with_period_and_space_separator":
                o = a(t, 2, " ", ".");
                break;
            case "amount_no_decimals_with_comma_separator":
                o = a(t, 0, ".", ",");
                break;
            case "amount_no_decimals_with_space_separator":
                o = a(t, 0, ".", "");
                break;
            case "amount_with_space_separator":
                o = a(t, 2, ",", "");
                break;
            case "amount_with_apostrophe_separator":
                o = a(t, 2, "'", ".")
        }
        return i.replace(n, o)
    }, Shopify.resizeImage = function(t,
        r) {
        try {
            if ("original" == r) return t;
            var e = t.match(
                /(.*\/[\w\-\_\.]+)\.(\w{2,4})/
            );
            return e[1] + "_" + r + "." +
                e[2]
        } catch (r) {
            return t
        }
    }, Shopify.addItem = function(t, r,
        e) {
        var r = r || 1,
            a = {
                type: "POST",
                url: "/cart/add.js",
                data: "quantity=" + r +
                    "&id=" + t,
                dataType: "json",
                success: function(t) {
                    "function" ==
                    typeof e ? e(t) :
                        Shopify.onItemAdded(
                            t)
                },
                error: function(t, r) {
                    Shopify.onError(
                        t, r)
                }
            };
        jQuery.ajax(a)
    }, Shopify.addItemFromForm =
    function(t, r) {
        var e = {
            type: "POST",
            url: "/cart/add.js",
            data: jQuery("#" + t).serialize(),
            dataType: "json",
            success: function(t) {
                "function" ==
                typeof r ? r(t) :
                    Shopify.onItemAdded(
                        t)
            },
            error: function(t, r) {
                Shopify.onError(
                    t, r)
            }
        };
        jQuery.ajax(e)
    }, Shopify.getCart = function(t) {
        jQuery.getJSON("/cart.js",
            function(r) {
                "function" ==
                typeof t ? t(r) :
                    Shopify.onCartUpdate(
                        r)
            })
    }, Shopify.pollForCartShippingRatesForDestination =
    function(t, r, e) {
        e = e || Shopify.onError;
        var a = function() {
            jQuery.ajax(
                "/cart/async_shipping_rates", {
                    dataType: "json",
                    success: function(
                        e,
                        o,
                        n) {
                        200
                            ===
                            n
                            .status ?
                            "function" ==
                            typeof r ?
                            r(
                                e
                                .shipping_rates,
                                t
                            ) :
                            Shopify
                            .onCartShippingRatesUpdate(
                                e
                                .shipping_rates,
                                t
                            ) :
                            setTimeout(
                                a,
                                500
                            )
                    },
                    error: e
                })
        };
        return a
    }, Shopify.getCartShippingRatesForDestination =
    function(t, r, e) {
        e = e || Shopify.onError;
        var a = {
            type: "POST",
            url: "/cart/prepare_shipping_rates",
            data: Shopify.param({
                shipping_address: t
            }),
            success: Shopify.pollForCartShippingRatesForDestination(
                t, r, e),
            error: e
        };
        jQuery.ajax(a)
    }, Shopify.getProduct = function(t,
        r) {
        jQuery.getJSON("/products/" + t +
            ".js",
            function(t) {
                "function" ==
                typeof r ? r(t) :
                    Shopify.onProduct(
                        t)
            })
    }, Shopify.changeItem = function(t,
        r, e) {
        var a = {
            type: "POST",
            url: "/cart/change.js",
            data: "quantity=" + r +
                "&id=" + t,
            dataType: "json",
            success: function(t) {
                "function" ==
                typeof e ? e(t) :
                    Shopify.onCartUpdate(
                        t)
            },
            error: function(t, r) {
                Shopify.onError(
                    t, r)
            }
        };
        jQuery.ajax(a)
    }, Shopify.removeItem = function(t,
        r) {
        var e = {
            type: "POST",
            url: "/cart/change.js",
            data: "quantity=0&id=" +
                t,
            dataType: "json",
            success: function(t) {
                "function" ==
                typeof r ? r(t) :
                    Shopify.onCartUpdate(
                        t)
            },
            error: function(t, r) {
                Shopify.onError(
                    t, r)
            }
        };
        jQuery.ajax(e)
    }, Shopify.clear = function(t) {
        var r = {
            type: "POST",
            url: "/cart/clear.js",
            data: "",
            dataType: "json",
            success: function(r) {
                "function" ==
                typeof t ? t(r) :
                    Shopify.onCartUpdate(
                        r)
            },
            error: function(t, r) {
                Shopify.onError(
                    t, r)
            }
        };
        jQuery.ajax(r)
    }, Shopify.updateCartFromForm =
    function(t, r) {
        var e = {
            type: "POST",
            url: "/cart/update.js",
            data: jQuery("#" + t).serialize(),
            dataType: "json",
            success: function(t) {
                "function" ==
                typeof r ? r(t) :
                    Shopify.onCartUpdate(
                        t)
            },
            error: function(t, r) {
                Shopify.onError(
                    t, r)
            }
        };
        jQuery.ajax(e)
    }, Shopify.updateCartAttributes =
    function(t, r) {
        var e = "";
        jQuery.isArray(t) ? jQuery.each(
                t,
                function(t, r) {
                    var a =
                        attributeToString(
                            r.key);
                    "" !== a && (e +=
                        "attributes[" +
                        a + "]=" +
                        attributeToString(
                            r.value
                        ) + "&")
                }) : "object" == typeof t &&
            null !== t && jQuery.each(t,
                function(t, r) {
                    e += "attributes[" +
                        attributeToString(
                            t) + "]=" +
                        attributeToString(
                            r) + "&"
                });
        var a = {
            type: "POST",
            url: "/cart/update.js",
            data: e,
            dataType: "json",
            success: function(t) {
                "function" ==
                typeof r ? r(t) :
                    Shopify.onCartUpdate(
                        t)
            },
            error: function(t, r) {
                Shopify.onError(
                    t, r)
            }
        };
        jQuery.ajax(a)
    }, Shopify.updateCartNote =
    function(t, r) {
        var e = {
            type: "POST",
            url: "/cart/update.js",
            data: "note=" +
                attributeToString(t),
            dataType: "json",
            success: function(t) {
                "function" ==
                typeof r ? r(t) :
                    Shopify.onCartUpdate(
                        t)
            },
            error: function(t, r) {
                Shopify.onError(
                    t, r)
            }
        };
        jQuery.ajax(e)
    }, jQuery.fn.jquery >= "1.4" ?
    Shopify.param = jQuery.param : (
        Shopify.param = function(t) {
            var r = [],
                e = function(t, e) {
                    e = jQuery.isFunction(
                            e) ? e() :
                        e, r[r.length] =
                        encodeURIComponent(
                            t) + "=" +
                        encodeURIComponent(
                            e)
                };
            if (jQuery.isArray(t) || t.jquery)
                jQuery.each(t, function() {
                    e(this.name,
                        this.value
                    )
                });
            else
                for (var a in t) Shopify
                    .buildParams(a, t[a],
                        e);
            return r.join("&").replace(
                /%20/g, "+")
        }, Shopify.buildParams =
        function(t, r, e) {
            jQuery.isArray(r) && r.length ?
                jQuery.each(r, function(
                    r, a) {
                    rbracket.test(t) ?
                        e(t, a) :
                        Shopify.buildParams(
                            t + "[" +
                            (
                                "object" ==
                                typeof a ||
                                jQuery
                                .isArray(
                                    a
                                ) ?
                                r :
                                "") +
                            "]", a,
                            e)
                }) : null != r &&
                "object" == typeof r ?
                Shopify.isEmptyObject(r) ?
                e(t, "") : jQuery.each(
                    r,
                    function(r, a) {
                        Shopify.buildParams(
                            t + "[" +
                            r + "]",
                            a, e)
                    }) : e(t, r)
        }, Shopify.isEmptyObject =
        function(t) {
            for (var r in t) return !1;
            return !0
        });

20 Ocak 2018 Cumartesi

State saving Datatable

local storage de saklar

filtreleme yapılmış datatable sayfasına tekrar dönüldüğünde filtrenin otomatik olarak uygulanmasını sağlar.

link

https://datatables.net/examples/basic_init/state_save.html

26 Aralık 2017 Salı

Wordpress Developer Beginners Yeni Tema


header.php

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Awesome Theme</title>
</head>

<body>


footer.php
<footer>
<p>This is my footer</p>
</footer>

</body>
</html>


index.php

<?php get_header(); ?>

<h1>This is my index</h1>

<?php get_footer(); ?>



style.css

/*
Theme Name: Awesome Theme
Theme URI: http://alecaddd.com/awesometheme
Author: Alecaddd
Author URI: http://alecaddd.com
Description: This is an awesome theme
Version: 0.1 alpha
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: black, white, responsive, one-column, two-columns, featured-images, custom-menu, custom-header, post-formats
*/

------------------------------

// Header Çağırma: <?php get_header(); ?> // Footer Çağırma: <?php get_footer(); ?> // Karakter Kodlaması <?php bloginfo( 'charset' ); ?> //Blog Adı <?php bloginfo('name'); ?> //Blog Adresi: <?php bloginfo('url'); ?> //Title <?php wp_title('&laquo;', true, 'right'); ?> <?php bloginfo('name'); ?> //Tema Yolu <?php bloginfo('template_url'); ?> //Stil Dosyası <?php bloginfo('stylesheet_url'); ?> //Menü Oluşturma <?php wp_nav_menu( array( 'theme_location' => 'menu' ) ); ?> //Menü Oluşturma Functions.php add_theme_support('menus'); register_nav_menus(array( 'menu' => 'Header Menü' ));


---------------------------------------------------------


//While Döngüsü Başlangıç
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

//While Döngüsü Bitiş
<?php endwhile; else: ?>
<?php _e('Sonuç Bulunamadı.'); ?>
<?php endif; ?>

//Yazı Kategorisi
<?php the_category(', ,') ?>

//Yazı Başlığı
<?php the_title(); ?>

//Yazı Adresi
<?php the_permalink(); ?>

//Thumbnail
<?php if (has_post_thumbnail()) { the_post_thumbnail('anasayfa',array('class'=>'makale-resim'));
 }
 else{
 ?>
 <img src="<?php bloginfo("template_url"); ?>/img/yoksa.jpg" alt="Yazı Resmi" height="155" width="265">
 <?php } ?>

//Thumbnail Funtions (functions.php yazılacak)
add_theme_support( 'post-thumbnails' );
add_image_size( 'anasayfa', 155, 265, true );

//The Excerpt
<?php the_excerpt(); ?>

//The Exceprt Functions (functions.php yazılacak)
function new_excerpt_length($length) {
return 12;
}
add_filter('excerpt_length', 'new_excerpt_length');

//Yazı Tarihi
<?php the_time('d F Y'); ?>


-------------------------------------------------------------------



7 Aralık 2017 Perşembe

Muhasebe faydali linkler

Incelemeye değer

https://www.ofisassist.com/muhasebe-programi


Güzel blog yazısı
https://www.parasut.com/blog/girisimcinin-on-muhasebe-kilavuzu


muhasebede barkod sistemi aşağıdaki gibi olmalıdır.
barkod unique olmalıdır


id urunid birimid barkod

24 Kasım 2017 Cuma

Javascript Pattern

JavaScript'te üç
yeni nesneler oluşturmak için yaygın yollar şunlardır:

// Aşağıdaki seçeneklerin her biri boş bir nesne yaratacaktır:

var newObject = {}; // or
var newObject = Object.create(null); // or

var newObject = new Object();



Singleton Pattern

Java veya C # gibi diğer dillerde yerleşik ad alanları bulunurken, JavaScript bunları basit nesneler kullanarak taklit etmek zorundadır.

Şu senaryoyu inceleyin: Programınızda sıkça kullandığınız sayfada bir dizi işlevin asılı kalması.
function login() {  
    // do some login shtuffs
}

function logout() {  
    // do some logout shtuffs
}

function addToCart() {  
    // blah, blah blah...
}
Bir kaç şey burada devam ediyor ...
1. İşlevlerimiz küresel alanı kirletiyor. Sayfada dolaşırken bir şeyler eklemek zorunda kalacaklar. Açıkça beyan edilen ana nesne olmadan, küresel olarak mevcut olan windownesneye bağlanırlar.
2. Yanlışlıkla başka bir küresel addToCartişlev tanımlayacak olsaydık veya yazar aynı şeyi yapan bir kütüphaneyi getirseydik orijinalin üzerine yazar ve gerçekten de karmakarışık bir hata ayıklama durumuna gelebiliriz.
Bunu, kodumuzun yapabileceği bir tane (ve sadece bir tane) global nesne oluşturarak gözden geçirelim.
var NAMESPACE = {};

NAMESPACE.login = function() {  
    // do some login shtuffs
}

NAMESPACE.logout = function() {  
    // do some logout shtuffs
}

NAMESPACE.addToCart = function() {  
    // blah, blah blah...
}
Artık kimse, adı da olan bir nesne oluşturmadığı sürece NAMESPACEkodumuzun güvende olması gerekir. Buradan her türlü şeyi yapabiliriz. Nesne değişkenlerini daha yuvalayabiliriz veya yapıcı işlevler oluşturabiliriz:
var NAMESPACE = {};

NAMESPACE.Widget = function(foo, bar) {  
    // Some awesome widget code
}

NAMESPACE.Widget.prototype.doSomethingAwesome = function() {  
    // do something awesome!!!
}

var myWidget = new NAMESPACE.Widget('hello', 'world'); 

12 Kasım 2017 Pazar

analytics a few simple info

Boyutlar verilere ilişkin özelliklerdir. Örneğin, Şehirboyutu oturumun açıldığı şehri (ör. "Ankara" veya "İstanbul"), Sayfa boyutu ise görüntülenen bir sayfanın URL'sini belirtir.
Metrikler nicel ölçümlerdirOturum sayısı metriği toplam oturum sayısını gösterir. Sayfa/Oturummetriği oturum başına görüntülenen ortalama sayfa sayısıdır.
Çoğu Analytics raporundaki tablolarda boyut değerleri satırlar ve metrikler sütunlar halinde düzenlenmiştir.



Şimdi birkaç önemli metriğin nasıl hesaplandığını inceleyelim:
  • Analytics, bir sayfa görüntüleme isabetinin zaman damgasını alıp bunu bir sonraki sayfa görüntüleme isabetinin zaman damgasından çıkararak "Sayfada Geçirilen Süre"yi elde edebilir.
  • "Oturum başına sayfa sayısı", kullanıcının oturumunda oluşturduğu benzersiz sayfa görüntüleme isabetlerinin ortalama sayısıdır.
  • Ortalama oturum süresi, birinci isabetten itibaren kullanıcı siteden ayrılmadan veya oturum zaman aşımına uğramadan önce son isabete kadar geçirilen ortalama süredir.
  • Hemen çıkma oranı, oturum süresi veya sayfada geçirilen süreyi hesaplamak için, sitenizde ikinci bir etkileşimi olmayıp yalnızca bir etkileşimde bulunan kullanıcılara bakarak hesaplanır. Bu durumda, hemen çıkılan bir ziyaretin sayfa görüntülemesine oturum süresi veya sayfada geçirilen süre olarak sıfır değeri atanır.

Kayseri Invisalign Tedavisi

Herkes harika bir gülümseme ister ama çoğumuzun buna ulaşmak için yardıma ihtiyacı vardır. Giderek daha fazla insan, hizalayıcı adı verilen ...