amir hosein gorji 2 years ago
commit f60b5082b6
  1. 3
      public/ar1.json
  2. 3
      public/en.json
  3. 4
      src/views/AR/BreadCrumb/index.js
  4. 4
      src/views/Auth/Login/Timer/index.js
  5. 4
      src/views/Auth/Profile/Document/index.js
  6. 12
      src/views/Auth/Profile/index.js
  7. 4
      src/views/Blog/BreadCrumb/index.js
  8. 4
      src/views/Blogs/BreadCrumb/index.js
  9. 4
      src/views/Cart/Table/index.js
  10. 6
      src/views/ChatRoom/Header/index.js
  11. 8
      src/views/Checkout/Discount/index.js
  12. 30
      src/views/Checkout/Factor/index.js
  13. 9
      src/views/Checkout/Table/index.js
  14. 4
      src/views/Download/BreadCrumb/index.js
  15. 7
      src/views/Download/index.js
  16. 2
      src/views/Faq/index.js
  17. 5
      src/views/Home/Download/index.js
  18. 4
      src/views/Home/HomeScroll/Product/index.js
  19. 2
      src/views/Home/HomeSearch/index.js
  20. 4
      src/views/Home/HomeSlider/Simple/index.js
  21. 12
      src/views/Home/Navbar/Mobile/NavbarDrawer/NavbarDrawer.js
  22. 2
      src/views/Home/Navbar/Mobile/index.js
  23. 2
      src/views/Home/SingleBlog/index.js
  24. 6
      src/views/NewProfile/index.js
  25. 14
      src/views/Product/AddToCart/index.js
  26. 4
      src/views/Product/BreadCrumb/index.js
  27. 2
      src/views/Product/Comment/Reply/index.js
  28. 2
      src/views/Product/Gallery/Modal/index.js
  29. 4
      src/views/Product/MaterialModal/index.js
  30. 4
      src/views/Products/BreadCrumb/index.js
  31. 2
      src/views/Products/List/index.js
  32. 10
      src/views/Products/Product/index.js
  33. 2
      src/views/Products/index.js
  34. 2
      src/views/QR/Image/index.js
  35. 7
      src/views/Support/index.js

@ -299,5 +299,6 @@
"قبل": "قبل",
"بعد": "التالي",
"متن": "نص",
"شو": "تبين"
"شو": "تبين",
"ذخیره": "متجر"
}

@ -299,5 +299,6 @@
"قبل": "Before",
"بعد": "Next",
"متن": "Text",
"شو": "show"
"شو": "show",
"ذخیره": "save"
}

@ -21,7 +21,7 @@ export default function ActiveLastBreadcrumb(props) {
}}
to={"/"}
>
صفحه اصلی")}{" "}
{window.t("صفحه اصلی")}{" "}
</Link>
<Link
style={{
@ -31,7 +31,7 @@ export default function ActiveLastBreadcrumb(props) {
}}
to={"/ar"}
>
واقعیت افزوده")}{" "}
{window.t("واقعیت افزوده")}{" "}
</Link>
</Breadcrumbs>
);

@ -78,7 +78,7 @@ export default class Timer extends Component {
fontFamily: "numeralLight",
}}
>
زمان باقیمانده تا انقضای کد:
{window.t("زمان باقیمانده تا انقضای کد:")}
</div>
<div style={{ fontSize: fontSize.desktop.div }}>
{this.state.time.s}
@ -98,7 +98,7 @@ export default class Timer extends Component {
fontSize: fontSize.mobile.div,
}}
>
زمان باقیمانده تا انقضای کد")}{" "}
{window.t("زمان باقیمانده تا انقضای کد:")}{" "}
</div>
<div
style={{

@ -30,7 +30,7 @@ export default function Document(props) {
}
/>
<span style={{ fontSize: fontSize.mobile.span }}>
گواهی تدریس خود را آپلود کنید.
{window.t("گواهی تدریس خود را آپلود کنید.")}
</span>
</>
) : (
@ -77,7 +77,7 @@ export default function Document(props) {
margin: "auto",
}}
>
گواهی تدریس خود را آپلود کنید.
{window.t("گواهی تدریس خود را آپلود کنید.")}
</span>
</>
) : (

@ -185,10 +185,10 @@ class Profile extends Component {
<div className="auth-profile d-flex justify-content-center">
<div className="auth-profile__box d-flex flex-column p-4">
<h1 style={{ fontSize: fontSize.desktop.h1 }}>
حساب کاربری")}
{window.t("حساب کاربری")}
</h1>
<p style={{ fontSize: fontSize.desktop.p }}>
لطفا مشخصات خود را به صورت کامل نمایید.
{window.t("لطفا مشخصات خود را به صورت کامل نمایید.")}
</p>
<div
className="auth-profile__box--form d-flex"
@ -383,7 +383,9 @@ class Profile extends Component {
/>
</div>
<div className="auth-profile__box--form__footer d-flex justify-content-center">
<button onClick={() => this.onSubmit()}>ذخیره")}</button>
<button onClick={() => this.onSubmit()}>
{window.t("ذخیره")}
</button>
</div>
</div>
</div>
@ -562,7 +564,9 @@ class Profile extends Component {
defaultValue={profile}
/>
<div className="mobile-auth-profile__footer d-flex justify-content-center">
<button onClick={() => this.onSubmit()}>ذخیره")}</button>{" "}
<button onClick={() => this.onSubmit()}>
{window.t("ذخیره")}
</button>{" "}
</div>
</div>
</>

@ -23,7 +23,7 @@ export default function ActiveLastBreadcrumb(props) {
}}
to={"/"}
>
صفحه اصلی")}{" "}
{window.t("صفحه اصلی")}{" "}
</Link>
{isblog ? (
<Link
@ -33,7 +33,7 @@ export default function ActiveLastBreadcrumb(props) {
}}
to={"/blogs"}
>
وبلاگ")}
{window.t("وبلاگ")}
</Link>
) : null}
<Link

@ -22,7 +22,7 @@ export default function ActiveLastBreadcrumb() {
}}
// onClick={handleClick}
>
صفحه اصلی")}{" "}
{window.t("صفحه اصلی")}{" "}
</Link>
<Link
to={"/blogs"}
@ -33,7 +33,7 @@ export default function ActiveLastBreadcrumb() {
}}
// onClick={handleClick}
>
وبلاگ")}
{window.t("وبلاگ")}
</Link>
</Breadcrumbs>
);

@ -209,7 +209,7 @@ const Item = (props) => {
{`پایه ${grades[data.product.book.gradeId]}`}
</p>
<span style={{ fontSize: 10 }}>
همراه با:
{window.t("همراه با:")}
{data.product.book.items ||
window.t("کد فعالسازی محتوای الکترونیک")}
</span>
@ -335,7 +335,7 @@ const Item = (props) => {
{`پایه ${grades[data.product?.book?.gradeId]}`}
</p>
<span style={{ fontSize: fontSize.desktop.info.span }}>
همراه با:
{window.t("همراه با:")}
{data.product?.book?.items ||
window.t("کد فعالسازی محتوای الکترونیک")}
</span>

@ -83,19 +83,19 @@ class Header extends Component {
className="fontLight menu"
onClick={() => this.handleClose()}
>
پروفایل")}
{window.t("پروفایل")}
</MenuItem>
<MenuItem
className="fontLight menu"
onClick={() => this.handleClose()}
>
حساب کاربری")}{" "}
{window.t("حساب کاربری")}{" "}
</MenuItem>
<MenuItem
className="fontLight menu"
onClick={() => this.handleClose()}
>
خروج")}{" "}
{window.t("خروج")}{" "}
</MenuItem>
</Menu>
</div>

@ -34,7 +34,7 @@ const DiscoutCode = ({ codeId, setCodeId, userId, factorId }) => {
{window.t("کد تخفیف")}
</h2>
<p style={{ fontSize: fontSize.desktop.p }}>
اگر کد تخفیفی دارید آن را در کادر زیر وارد نمائید")}{" "}
{window.t("اگر کد تخفیفی دارید آن را در کادر زیر وارد نمائید")}{" "}
</p>
<div className="discount-code__box d-flex align-items-center">
<input
@ -47,7 +47,7 @@ const DiscoutCode = ({ codeId, setCodeId, userId, factorId }) => {
style={{ fontSize: fontSize.desktop.button }}
onClick={setOff}
>
ثبت کد")}{" "}
{window.t("ثبت کد")}{" "}
</button>
</div>
</div>
@ -58,7 +58,7 @@ const DiscoutCode = ({ codeId, setCodeId, userId, factorId }) => {
{window.t("کد تخفیف")}
</h2>
<p style={{ fontSize: fontSize.mobile.p }}>
اگر کد تخفیفی دارید آن را در کادر زیر وارد نمائید{" "}
{window.t("اگر کد تخفیفی دارید آن را در کادر زیر وارد نمائید")}{" "}
</p>
<div className="mobile-discount-code__box d-flex align-items-center">
<input
@ -70,7 +70,7 @@ const DiscoutCode = ({ codeId, setCodeId, userId, factorId }) => {
style={{ fontSize: fontSize.mobile.button }}
onClick={setOff}
>
ثبت کد")}{" "}
{window.t("ثبت کد")}{" "}
</button>
</div>
</div>

@ -33,22 +33,28 @@ const Factor = (props) => {
<div className="mobile-factor d-flex flex-column">
<div className="d-flex justify-content-between">
<strong>{window.t("مبلغ سبد خرید")}</strong>
<span>{factorInfo.sumPrice} تومان")}</span>
<span>
{factorInfo.sumPrice} {window.t("تومان")}
</span>
</div>
<div className="d-flex justify-content-between">
<strong>{window.t("هزینه ارسال")}</strong>
<span>
{factorInfo.transportPrice}
تومان")}
{window.t("تومان")}
</span>
</div>
<div className="d-flex justify-content-between">
<strong>{window.t("میزان تخفیف")}</strong>
<span>{factorInfo.offPrice} تومان")}</span>
<span>
{factorInfo.offPrice} {window.t("تومان")}
</span>
</div>
<div className="d-flex justify-content-between">
<strong>{window.t("مالیات بر ارزش افزوده")}</strong>
<span>{factorInfo.vatPrice} تومان")}</span>
<span>
{factorInfo.vatPrice} {window.t("تومان")}
</span>
</div>
</div>
) : null}
@ -56,35 +62,35 @@ const Factor = (props) => {
<div className="factor d-flex flex-column">
<div className="d-flex justify-content-between">
<strong style={{ fontSize: fontSize.desktop.strong }}>
مبلغ سبد خرید")}{" "}
{window.t("مبلغ سبد خرید")}{" "}
</strong>
<span style={{ fontSize: fontSize.desktop.span }}>
{factorInfo.sumPrice} تومان")}
{factorInfo.sumPrice} {window.t("تومان")}
</span>
</div>
<div className="d-flex justify-content-between">
<strong style={{ fontSize: fontSize.desktop.strong }}>
هزینه ارسال")}
{window.t("هزینه ارسال")}
</strong>
<span style={{ fontSize: fontSize.desktop.span }}>
{factorInfo.transportPrice}
تومان")}
{window.t("تومان")}
</span>
</div>
<div className="d-flex justify-content-between">
<strong style={{ fontSize: fontSize.desktop.strong }}>
میزان تخفیف")}
{window.t("میزان تخفیف")}
</strong>
<span style={{ fontSize: fontSize.desktop.span }}>
{factorInfo.offPrice} تومان")}
{factorInfo.offPrice} {window.t("تومان")}
</span>
</div>
<div className="d-flex justify-content-between">
<strong style={{ fontSize: fontSize.desktop.strong }}>
مالیات بر ارزش افزوده")}{" "}
{window.t("مالیات بر ارزش افزوده")}{" "}
</strong>
<span style={{ fontSize: fontSize.desktop.span }}>
{factorInfo.vatPrice} تومان")}
{factorInfo.vatPrice} {window.t("تومان")}
</span>
</div>
</div>

@ -178,12 +178,15 @@ const Item = (props) => {
<div className="mobile-cart-table-price d-flex flex-column align-items-center">
<div className="mobile-cart-table-price__price d-flex flex-column justify-content-center align-items-center">
<strong style={{ fontSize: 14 }}>
{data.product.price * data.count || "1000"} تومان")}
{data.product.price * data.count || "1000"}{" "}
{window.t("تومان")}
</strong>
</div>
{route === "cart" ? (
<div className="mobile-cart-table-price__counter d-flex justify-content-around align-items-center">
<span style={{ fontSize: 12 }}>{data.count} عدد")}</span>
<span style={{ fontSize: 12 }}>
{data.count} {window.t("عدد")}
</span>
</div>
) : null}
</div>
@ -191,7 +194,7 @@ const Item = (props) => {
{route === "callback" ? (
<TableCell>
<strong className="d-flex justify-content-center align-items-center">
{data.count} عدد")}{" "}
{data.count} {window.t("عدد")}{" "}
</strong>
</TableCell>
) : null}

@ -21,7 +21,7 @@ export default function ActiveLastBreadcrumb(props) {
}}
to={"/"}
>
صفحه اصلی")}{" "}
{window.t("صفحه اصلی")}{" "}
</Link>
<Link
style={{
@ -31,7 +31,7 @@ export default function ActiveLastBreadcrumb(props) {
}}
to={"/download"}
>
دریافت افزونه واقعیت افزوده")}{" "}
{window.t("دریافت افزونه واقعیت افزوده")}{" "}
</Link>
</Breadcrumbs>
);

@ -59,8 +59,9 @@ class AR extends Component {
: fontSize.mobile.p,
}}
>
برای استفاده از بخش واقعیت افزوده می بایست افزونه آن را نصب
نمایید")}{" "}
{window.t(
"برای استفاده از بخش واقعیت افزوده می بایست افزونه آن را نصب نمایید"
)}{" "}
</p>
<a
href="https://dnvn.ir/ar.apk"
@ -74,7 +75,7 @@ class AR extends Component {
textAlign: "center",
}}
>
دریافت افزونه")}{" "}
{window.t("دریافت افزونه")}{" "}
</a>
</div>
</div>

@ -146,7 +146,7 @@ class Faq extends Component {
<Navbar page={"mobile-faq"} />
<header className="mobile-faq__header d-flex flex-column align-items-center">
<h1 style={{ fontSize: fontSize.mobile.h1 }}>
سلام چطوری میتونم کمکتون کنم؟
{window.t("سلام چطوری میتونم کمکتون کنم؟")}
</h1>
<input
type="search"

@ -9,7 +9,8 @@ const H_DownloadApp = () => {
{window.innerWidth > 1000 ? (
<div className="h-download-app" id="download">
<div className="h-download-app-text">
لذت یادگیری را با")}<span>{window.t("دانوین")}</span> تجربه کنید")}{" "}
{window.t("لذت یادگیری را با")}
<span>{window.t("دانوین")}</span> {window.t("تجربه کنید")}
</div>
<div className="h-download-app-content">
<div className="h-download-app-content-box1"></div>
@ -30,7 +31,7 @@ const H_DownloadApp = () => {
{window.t("دریافت اپلیکیشن اختصاصی دانوین")}
</div>
<div className="h-download-app-content-box2-text-subtitle">
{window.t("به راحتی از همین جا دانلود کنید...")}{" "}
{window.t("به راحتی از همین جا دانلود کنید...")}
</div>
</div>
<img

@ -19,13 +19,13 @@ export default class Product extends Component {
{data.oldPrice ? (
<div>
<div className="scroll-product__price--old d-flex">
{data.oldPrice} تومان")}
{data.oldPrice} {window.t("تومان")}
<span></span>
</div>
</div>
) : null}
<div className="scroll-product__price--price">
{data.price} تومان")}
{data.price} {window.t("تومان")}
</div>
</div>
) : (

@ -78,7 +78,7 @@ class HomeSearch extends Component {
});
}}
>
جستجو")}
{window.t("جستجو")}
</button>
</div>
</>

@ -49,7 +49,7 @@ export default class Simple extends Component {
style={{ fontSize: mobile ? 14 : fontSize.desktop.available }}
className="slider-simple__price--price d-flex"
>
{data.price} تومان")}
{data.price} {window.t("تومان")}
</div>
</div>
) : (
@ -57,7 +57,7 @@ export default class Simple extends Component {
style={{ fontSize: fontSize.desktop.notAvailable }}
className="slider-simple__notAvailabe"
>
ناموجود")}{" "}
{window.t("ناموجود")}
</div>
)}
</Link>

@ -193,7 +193,11 @@ class NavbarDrawer extends Component {
className="navbar-drawer__header--dropdown"
onClick={() => this.setState({ dropdown: false })}
>
{score ? <span>{score} امتیاز</span> : null}
{score ? (
<span>
{score} {window.t("امتیاز")}
</span>
) : null}
<KeyboardArrowUpIcon style={{ color: "grey", fontSize: 30 }} />
</div>
) : (
@ -201,7 +205,11 @@ class NavbarDrawer extends Component {
className="navbar-drawer__header--dropdown"
onClick={() => this.setState({ dropdown: true })}
>
{score ? <span>{score} امتیاز</span> : null}{" "}
{score ? (
<span>
{score} {window.t("امتیاز")}
</span>
) : null}{" "}
<KeyboardArrowDownIcon
style={{ color: "grey", fontSize: 30 }}
/>

@ -94,7 +94,7 @@ export default function MobileNavbar(props) {
to={"/auth"}
className="mobile-navbar__signup"
>
ورود یا ثبتنام")}
{window.t("ورود یا ثبتنام")}
</Link>
{page !== "home" ? <BackButton /> : null}
</div>

@ -32,7 +32,7 @@ export default class SingleBlog extends Component {
style={{ fontSize: fontSize.desktop.a }}
to={"/blogs/" + data.id}
>
ادامه مطلب")}{" "}
{window.t("ادامه مطلب")}
</Link>
</div>
<div

@ -210,7 +210,7 @@ class NewProfile extends Component {
{window.t("حساب کاربری")}
</h1>
<p style={{ fontSize: fontSize.desktop.p }}>
لطفا مشخصات خود را به صورت کامل نمایید.
{window.t("لطفا مشخصات خود را به صورت کامل نمایید.")}
</p>
<form
className="auth-profile__box--form d-flex"
@ -393,7 +393,9 @@ class NewProfile extends Component {
{window.innerWidth < 1000 ? (
<div className="mobile-auth-profile d-flex flex-column">
<img src={logo} alt={window.t("دانوین")} />
<h1 style={{ fontSize: fontSize.mobile.h1 }}>افزودن کاربر جدید</h1>
<h1 style={{ fontSize: fontSize.mobile.h1 }}>
{window.t("افزودن کاربر جدید")}
</h1>
<p style={{ fontSize: fontSize.mobile.p }}>
{window.t("لطفا مشحصات خود را به صورت کامل وارد نمایید")}{" "}
</p>

@ -71,13 +71,13 @@ function AddToCart(props) {
<strong style={{ fontSize: fontSize.desktop.strong }}>
{price}
</strong>{" "}
تومان")}
{window.t("تومان")}
</div>
</div>
{off ? (
<span style={{ fontSize: fontSize.desktop.span }}>
{off} تومان تخفیف")}
{off} {window.t("تومان تخفیف")}
</span>
) : null}
</div>
@ -89,7 +89,7 @@ function AddToCart(props) {
style={{ fontSize: fontSize.desktop.button }}
className="product-addtocart__box--sampleButton"
>
مشاهده نمونه کتاب")} <img src={document_red} alt="" />
{window.t("مشاهده نمونه کتاب")} <img src={document_red} alt="" />
</Link>
<Link
// to={`/products/${
@ -135,7 +135,7 @@ function AddToCart(props) {
}
}}
>
افزودن به سبد خرید")} <img src={basket_white} alt="" />
{window.t("افزودن به سبد خرید")} <img src={basket_white} alt="" />
</button>
<div className="product-addtocart__box--accept d-flex">
<input type="checkbox" checked={true} />
@ -143,7 +143,9 @@ function AddToCart(props) {
to="/page/privacy"
style={{ fontSize: "13px", margin: 0, padding: 0 }}
>
شرایط استفاده از دانوین و حریم خصوصی را مطالعه کرده ام")}
{window.t(
"شرایط استفاده از دانوین و حریم خصوصی را مطالعه کرده ام"
)}
</Link>
</div>
<div className="product-addtocart__box--accept d-flex">
@ -152,7 +154,7 @@ function AddToCart(props) {
to="/page/returning"
style={{ fontSize: "13px", margin: 0, padding: 0 }}
>
شرایط مرجوع کردن کالا در دانوین")}
{window.t("شرایط مرجوع کردن کالا در دانوین")}
</Link>
</div>
</div>

@ -22,7 +22,7 @@ export default function ActiveLastBreadcrumb(props) {
}}
to={"/"}
>
صفحه اصلی")}{" "}
{window.t("صفحه اصلی")}{" "}
</Link>
<Link
style={{
@ -31,7 +31,7 @@ export default function ActiveLastBreadcrumb(props) {
}}
to={"/products"}
>
محصولات")}{" "}
{window.t("محصولات")}{" "}
</Link>
<Link
style={{

@ -16,7 +16,7 @@ const Replay = (props) => {
{window.innerWidth > 1000 ? (
<div className="reply d-flex flex-column justify-content-center">
<strong style={{ fontSize: fontSize.desktop.strong }}>
پاسخ مدیریت سایت")}{" "}
{window.t("پاسخ مدیریت سایت")}{" "}
</strong>
<p style={{ fontSize: fontSize.desktop.p }}>{props.data}</p>
</div>

@ -16,7 +16,7 @@ const Modal = (props) => {
<img
className="modal__exit"
src={exit}
alt="خروح"
alt={window.t("خروج")}
onClick={() => setModal(null)}
/>
<div className="modal__display">

@ -83,13 +83,13 @@ function SimpleModal(props) {
style={{ marginTop: 20, borderRadius: 6, padding: 8 }}
onClick={() => submitComment()}
>
ثبت")}{" "}
{window.t("ثبت")}{" "}
</button>
<button
style={{ marginTop: 20, borderRadius: 6, padding: 8 }}
onClick={() => cancle()}
>
انصراف")}
{window.t("انصراف")}
</button>
</div>
);

@ -22,7 +22,7 @@ export default function ActiveLastBreadcrumb() {
}}
// onClick={handleClick}
>
صفحه اصلی")}{" "}
{window.t("صفحه اصلی")}{" "}
</Link>
<Link
to={"/products"}
@ -33,7 +33,7 @@ export default function ActiveLastBreadcrumb() {
}}
// onClick={handleClick}
>
محصولات")}{" "}
{window.t("محصولات")}{" "}
</Link>
</Breadcrumbs>
);

@ -53,7 +53,7 @@ class List extends React.Component {
align="center"
style={{ margin: "20px auto", color: "gray" }}
>
محصولی با این مشخصات یافت نشد")}{" "}
{window.t("محصولی با این مشخصات یافت نشد")}{" "}
</div>
)
) : (

@ -66,8 +66,10 @@ function Product(props) {
to={`/products/physical/${product.id}`}
className="mobile-products-product__links--physical d-flex justify-content-between align-items-center"
>
<h2> نسخه چاپی")}</h2>
<span>{product.product[0].price} تومان")}</span>
<h2> {window.t("نسخه چاپی")}</h2>
<span>
{product.product[0].price} {window.t("تومان")}
</span>
</Link>
<div
className="mobile-products-product__links--basket d-flex"
@ -132,7 +134,7 @@ function Product(props) {
alt={product.name}
/>
<h1 style={{ fontSize: 15 }}>
{`${product.name} پایه ${grades[product.gradeId]}`}
{`${product.name} ${window.t("پایه")} ${grades[product.gradeId]}`}
</h1>
</Link>
<div className="d-flex" style={{ width: "100%" }}>
@ -143,7 +145,7 @@ function Product(props) {
>
<h2 style={{ fontSize: 12 }}>{window.t("نسخه چاپی")}</h2>
<span style={{ fontSize: 12 }}>
{product.product[0].price} تومان")}
{product.product[0].price} {window.t("تومان")}
</span>
</Link>
<div

@ -131,7 +131,7 @@ class Products extends Component {
textAlign: "center",
}}
>
سبد خرید")}{" "}
{window.t("سبد خرید")}{" "}
</Link>
</div>
</div>

@ -223,7 +223,7 @@ export default function QRImage(props) {
<div className="d-flex flex-column" id="image">
<h3 style={{ fontSize: fontSize.desktop.h3 }}>
<PhotoLibraryRoundedIcon style={{ fontSize: 30 }} />
عکسها")}{" "}
{window.t("عکسها")}{" "}
</h3>
{desktopImages()}
</div>

@ -142,7 +142,12 @@ class Support extends Component {
parent={this}
/>
) : null}
<Input label={"موضوع "} name={"subject"} parent={this} required />
<Input
label={window.t("موضوع")}
name={"subject"}
parent={this}
required
/>
<Input
label={window.t("متن")}
name={"text"}

Loading…
Cancel
Save