commit dc84425c0abf1541885e9d0f19335dc7b3431071 Author: pengwenchuan Date: Mon Aug 25 13:55:39 2025 +0800 first init diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..37da2b6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,5 @@ +from nginx:1.29-alpine + +copy html /usr/share/nginx/html + + diff --git a/html/Agreement.html b/html/Agreement.html new file mode 100644 index 0000000..199a96d --- /dev/null +++ b/html/Agreement.html @@ -0,0 +1 @@ +

用户协议

更新日期:2025年8月15日

生效日期:2025年8月15日

目录:

引言

一、帐号管理

二、服务内容

三、用户个人信息保护

四、内容规范

五、使用规则

六、未成年人保护及监护人提示

七、数据储存

八、风险承担

九、知识产权声明

十、法律责任

十一、不可抗力及其他免责事由

十二、服务的变更、中断、终止

十三、其他

十四、如何联系我们

引言

特别提示

智驾定位(以下简称“我们”)在此特别提醒您(用户)在注册成为用户之前,请认真阅读本《用户协议》(以下简称“协议”),确保您充分理解本协议中各条款。请您审慎阅读并选择接受或不接受本协议。除非您接受本协议所有条款,否则您无权注册、登录或使用本协议所涉服务。您的注册、登录、使用等行为将视为对本协议的接受,并同意接受本协议各项条款的约束。

本协议约定我们与用户之间关于“智驾定位”软件服务(以下简称“服务”)的权利义务。“用户”是指注册、登录、使用本服务的个人。

本协议可由我们随时更新,更新后的协议条款一旦公布即代替原来的协议条款,恕不再另行通知,用户可在智驾定位查阅最新版协议条款。在我们修改协议条款后,如果用户不接受修改后的条款,请立即停止使用我们提供的服务,用户继续使用我们提供的服务将被视为接受修改后的协议。

1          帐号管理

1、用户在使用本服务前需要注册一个“智驾定位”帐号。“智驾定位”帐号应当使用手机号或微信、Apple等第三方账号作为登录方式进行绑定注册,请用户使用尚未与“智驾定位”帐号绑定以及未被我们根据本协议封禁的手机号或第三方账号。我们可以根据用户需求或产品需要对帐号注册和绑定的方式进行变更,而无须事先通知用户。

2、在用户注册及使用本服务时,我们可能需要搜集能识别用户身份的个人信息以便我们可以在必要时联系用户,或为用户提供更好的使用体验。我们搜集的信息包括但不限于用户的姓名、性别、年龄、出生日期、身份证号、地址、学校情况、公司情况、所属行业、兴趣爱好、常出没的地方、个人说明等。我们同意对这些信息的使用将受限于用户个人隐私信息保护的约束。用户可以在“智驾定位”查看与编辑个人信息。

3、 “智驾定位”帐号的所有权归我们所有,用户完成申请注册手续后,获得“智驾定位”帐号的使用权,该使用权仅属于初始申请注册人,禁止赠与、借用、租用、转让或售卖。我们因经营需要,有权回收用户的“智驾定位”帐号。

4、用户有责任妥善保管注册帐号信息及密码等帐号登录方式的安全,因用户保管不善可能导致遭受盗号或密码等信息失窃,责任由用户自行承担。用户需要对注册帐号以及帐号下的行为承担法律责任。用户同意在任何情况下不使用其他用户的帐号或密码。在用户怀疑他人使用其帐号或密码时,用户同意立即通知我们。

5、用户应遵守本协议的各项条款,正确、适当地使用本服务,如因用户违反本协议中的任何条款,我们在通知用户后有权依据协议中断或终止对违约用户“智驾定位”帐号提供服务。同时,我们保留在任何时候收回“智驾定位”帐号、用户名的权利。

6、如用户注册“智驾定位”帐号后一年不登录,通知用户后,我们可以收回该帐号,以免造成资源浪费,由此造成的不利后果由用户自行承担。

7、用户可以在“智驾定位”使用进行账号注销服务,用户确认注销账号是不可恢复的操作,用户应自行备份与智驾定位账号相关的信息和数据,用户确认操作之前与智驾定位账号相关的所有服务均已进行妥善处理。用户确认并同意注销账号后并不代表本智驾定位账号注销前的账号行为和相关责任得到豁免或减轻,如在注销期间,用户的账号被他人投诉、被国家机关调查或者正处于诉讼、仲裁程序中,我们有权自行终止用户的账号注销并无需另行得到用户的同意。

2          服务内容

本服务的具体内容由我们根据实际情况提供,可能包括各种工具、内容等。我们可以对其提供的服务予以变更,且我们提供的服务内容可能随时变更。

3          用户个人信息保护

1、填写信息

用户在注册帐号或使用本服务的过程中,可能需要填写或提交一些必要的个人信息,如法律法规、规章规范性文件(以下称“法律法规”)规定的需要填写的身份信息。如用户提交的信息不完整或不符合法律法规的规定,则用户可能无法使用本服务或在使用本服务的过程中受到限制。

2、用户个人信息包括

1)用户自行提供的用户个人信息(如注册时填写的手机号码,昵称,头像等个人信息,使用服务时提供的共享信息等);

2)其他方式分享的用户个人信息;

3)我们为提供服务而合法收集的用户必要个人信息(如使用服务时系统自动采集的设备或软件信息,浏览历史信息,通讯时间信息等技术信息,用户开启定位功能并使用服务时的地理位置信息等)。

其中个人隐私信息是指涉及用户个人身份或个人隐私的信息,比如,用户真实姓名、身份证号、手机号码、手机设备识别码、IP地址、用户聊天记录。非个人隐私信息是指用户对本服务的操作状态以及使用习惯等明确且客观反映在我们服务器端的基本记录信息、个人隐私信息范围外的其它普通信息,以及用户同意公开的上述隐私信息。我们保证在取得用户同意的情况下收集、使用或公开用户的个人隐私信息,用户同意我们无需获得用户的另行确认与授权即可收集、使用或公开用户的非个人隐私信息。

本产品包含基于位置的服务,需要使用用户地理位置信息,用户成功注册帐号视为确认授权我们提取、公开及使用用户的地理位置信息。用户地理位置信息将作为用户公开资料之一,由我们向其他用户公开以便我们向用户提供基于地理位置的产品服务。如用户需要终止向其他用户公开其地理位置信息,可随时自行设置为隐身状态。

3、尊重用户个人信息

尊重用户个人信息的私有性是我们的一贯制度,我们将采取技术措施和其他必要措施,确保用户个人信息安全,防止在本服务中收集的用户个人信息泄露、毁损或丢失。在发生前述情形或者我们发现存在发生前述情形的可能时,我们将及时采取补救措施并告知用户,用户如发现存在前述情形亦需立即与我们联系。

4、我们未经用户同意不向任何第三方公开、 透露用户个人隐私信息

但以下特定情形除外:

(1) 我们根据法律法规规定或有权机关的指示提供用户的个人隐私信息;

(2) 由于用户将其用户密码告知他人或与他人共享注册帐户与密码,由此导致的任何个人信息的泄漏,或其他非因我们原因导致的个人隐私信息的泄露;

(3) 用户自行向第三方公开其个人隐私信息;

(4) 用户与我们及合作单位之间就用户个人隐私信息的使用公开达成约定,我们因此向合作单位公开用户个人隐私信息;

(5) 任何由于黑客攻击、电脑病毒侵入及其他不可抗力事件导致用户个人隐私信息的泄露;

(6) 用户个人信息已经经过处理无法识别特定个人且不能复原。

5、用户同意我们可在以下事项中使用用户的个人隐私信息

(1) 我们向用户及时发送重要通知,如软件更新、本协议条款的变更;

(2) 我们内部进行审计、数据分析和研究等,以改进我们的产品、服务和与用户之间的沟通;

(3) 依本协议约定,我们管理、审查用户信息及进行处理措施;

(4) 适用法律法规规定的其他事项。除上述事项外,如未取得用户事先同意,我们不会将用户个人隐私信息使用于任何其他用途。

6、信息收集

为了改善我们的技术和服务,向用户提供更好的服务体验,我们或可会自行收集使用或向第三方提供用户的非个人隐私信息。

我们保证在合法、正当与必要的原则下收集、使用或者公开用户个人信息且不会收集与提供的服务无关的用户个人信息。

7、注重隐私安全

我们十分注重保护用户的个人隐私,并制定了《智驾定位隐私协议政策》,用户亦可以通过“设置”页面里的“关于”来进行具体查看,用户确认并同意使用我们提供的服务将被视为接受《智驾定位隐私协议政策》。

4          内容规范

1、本条所述内容是指用户使用本服务过程中所制作、上载、复制、发布、传播的任何内容,包括但不限于帐号头像、名称、用户说明等注册信息及认证资料,或文字、语音、图片、视频、图文等发送、回复或自动回复消息和相关链接页面,以及其他使用帐号或本服务所产生的内容。

2、用户不得利用“智驾定位”帐号或本服务制作、上载、复制、发布、传播如下法律、法规和政策禁止的内容:

(1) 反对宪法所确定的基本原则的;

(2) 危害国家安全,泄露国家秘密,颠覆国家政权,破坏国家统一的;

(3) 损害国家荣誉和利益的;

(4) 煽动民族仇恨、民族歧视,破坏民族团结的;

(5) 破坏国家宗教政策,宣扬邪教和封建迷信的;

(6) 散布谣言,扰乱社会秩序,破坏社会稳定的;

(7) 散布淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪的;

(8) 侮辱或者诽谤他人,侵害他人合法权益的;

(9) 不遵守法律法规底线、社会主义制度底线、国家利益底线、公民合法权益底线、社会公共秩序底线、道德风尚底线和信息真实性底线的“七条底线”要求的;

(10) 含有法律、行政法规禁止的其他内容的信息。

3、用户不得利用“智驾定位”帐号或本服务制作、上载、复制、发布、传播如下干扰“智驾定位”正常运营,以及侵犯其他用户或第三方合法权益的内容:

(1) 含有任何性或性暗示的;

(2) 含有辱骂、恐吓、威胁内容的;

(3) 含有骚扰、垃圾广告、恶意信息、诱骗信息的;

(4) 涉及他人隐私、个人信息或资料的;

(5) 侵害他人名誉权、肖像权、知识产权、商业秘密等合法权利的;

(6) 含有其他干扰本服务正常运营和侵犯其他用户或第三方合法权益内容的信息。

5          使用规则

1、用户在本服务中或通过本服务所传送、发布的任何内容并不反映或代表,也不得被视为反映或代表我们的观点、立场或政策,我们对此不承担任何责任。

2、用户不得利用“智驾定位”帐号或本服务进行如下行为:

(1) 提交、发布虚假信息,或盗用他人头像或资料,冒充、利用他人名义的;

(2) 强制、诱导其他用户关注、点击链接页面或分享信息的;

(3) 虚构事实、隐瞒真相以误导、欺骗他人的;

(4) 利用技术手段批量建立虚假帐号的;

(5) 利用“智驾定位”帐号或本服务从事任何违法犯罪活动的;

(6) 制作、发布与以上行为相关的方法、工具,或对此类方法、工具进行运营或传播,无论这些行为是否为商业目的;

(7) 其他违反法律法规规定、侵犯其他用户合法权益、干扰“智驾定位”正常运营或我们未明示授权的行为。

3、用户须对利用“智驾定位”帐号或本服务传送信息的真实性、合法性、无害性、准确性、有效性等全权负责,与用户所传播的信息相关的任何法律责任由用户自行承担,与我们无关。如因此给我们或第三方造成损害的,用户应当依法予以赔偿。

4、我们提供的服务中可能包括广告,用户同意在使用过程中显示我们和第三方供应商、合作伙伴提供的广告。除法律法规明确规定外,用户应自行对依该广告信息进行的交易负责,对用户因依该广告信息进行的交易或前述广告商提供的内容而遭受的损失或损害,我们不承担任何责任。

5、除非我们书面许可,用户不得从事下列任一行为:

(1) 删除软件及其副本上关于著作权的信息;

(2) 对软件进行反向工程、反向汇编、反向编译,或者以其他方式尝试发现软件的源代码;

(3) 对我们拥有知识产权的内容进行使用、出租、出借、复制、修改、链接、转载、汇编、发表、出版、建立镜像站点等;

(4) 对软件或者软件运行过程中释放到任何终端内存中的数据、软件运行过程中客户端与服务器端的交互数据,以及软件运行所必需的系统数据,进行复制、修改、增加、删除、挂接运行或创作任何衍生作品,形式包括但不限于使用插件、外挂或非经我们授权的第三方工具/服务接入软件和相关系统;

(5) 通过修改或伪造软件运行中的指令、数据,增加、删减、变动软件的功能或运行效果,或者将用于上述用途的软件、方法进行运营或向公众传播,无论这些行为是否为商业目的;

(6) 通过非我们开发、授权的第三方软件、插件、外挂、系统,登录或使用我们软件及服务,或制作、发布、传播非我们开发、授权的第三方软件、插件、外挂、系统。

6          未成年人保护及监护人提示

1、 若您是未满18周岁的未成年人,您应在您的监护人同意的情况下,并在监护人的监护、指导下,认真阅读并同意本协议后,方可使用“智驾定位”软件及相关服务。

2、未成年人用户及其监护人理解并确认,如您违反法律法规、本协议内容,则您及您的监护人应依照法律规定承担因此而可能导致的全部法律责任。

3、青少年用户必须遵守《全国青少年网络文明公约》。(1)要善于网上学习,不浏览不良信息;(2)要诚实友好交流,不侮辱欺诈他人;(3)要增强自护意识,不随意约会网友;(4)要维护网络安全,不破坏网络秩序;(5)要有益身心健康,不沉溺虚拟时空。

4、监护人特别提示。如您的被监护人使用“智驾定位”软件及相关服务时,您作为监护人应指导并监督被监护人的使用行为,如您的监护人申请注册使用“智驾定位”帐号,我们有权认为其已取得您的同意。

7          数据储存

1、我们不对用户在本服务中相关数据的删除或储存失败负责。

2、我们可以根据实际情况自行决定用户在本服务中数据的最长储存期限,并在服务器上为其分配数据最大存储空间等。用户可根据自己的需要自行备份本服务中的相关数据。

3、如用户超过1年没有使用本服务或本服务终止,为避免持续占用服务器资源,我们将从服务器上永久地删除用户的数据。本服务停止、终止后,我们没有义务向用户返还任何数据。

8          风险承担

1、用户理解并同意,“智驾定位”仅为用户提供各种服务,用户必须为自己注册帐号下的一切行为负责,包括用户所传送的任何内容以及由此产生的任何后果。用户应对“智驾定位”及本服务中的内容自行加以判断,并承担因使用内容而引起的所有风险,包括因对内容的正确性、完整性或实用性的依赖而产生的风险。我们无法且不会对因用户行为而导致的任何损失或损害承担责任。如果用户发现任何人违反本协议约定或以其他不当的方式使用本服务,请立即向我们举报或投诉,我们将依本协议约定进行处理。

2、用户理解并同意,因业务发展需要,我们保留单方面对本服务的全部或部分服务内容变更、暂停、终止或撤销的权利,用户需承担此风险。

9          知识产权声明

智驾定位尊重和鼓励用户创作的内容,认识到保护知识产权对智驾定位平台生存与发展的重要性,承诺将保护知识产权作为智驾定位平台运营的基本原则之一。

但智驾定位不是知识产权专业机构,不具备审查、判断作品是否侵权的能力,也不具备对用户所发布内容的合法性、真实性及其品质等进行审查的能力。任何用户应当为自己上传文件的行为独立、完全承担法律责任。因您的个人行为所产生的一切争议和纠纷以及诉讼,与智驾定位无关。

1、除本服务中涉及广告的知识产权由相应广告商享有外,我们在本服务中提供的内容(包括但不限于网页、文字、图片、音频、视频、图表等)的知识产权均归我们所有,但用户在使用本服务前对自己发布的内容已合法取得知识产权的除外。

2、除另有特别声明外,我们提供本服务时所依托软件的著作权、专利权及其他知识产权均归我们所有。

3、我们在本服务中所涉及的图形、文字或其组成,以及其他我们标志及产品、服务名称(以下统称“我们标识”),其著作权或商标权归我们所有。未经我们事先书面同意,用户不得将我们标识以任何方式展示或使用或作其他处理,也不得向他人表明用户有权展示、使用、或其他有权处理我们标识的行为。

4、上述及其他任何我们或相关广告商依法拥有的知识产权均受到法律保护,未经我们或相关广告商书面许可,用户不得以任何形式进行使用或创造相关衍生作品。

5、用户在使用智驾定位服务时发表上传的文字、图片、视频、音频、软件以及表演等信息,此部分信息的知识产权归用户,责任由用户承担。但用户的发表、上传行为视为对我们的授权,用户理解并同意授予我们及其关联公司全球范围内完全免费、不可撤销、独家、永久、可转授权和可再许可的权利,包括但不限于:复制权、发行权、出租权、展览权、表演权、放映权、广播权、信息网络传播权、摄制权、改编权、翻译权、汇编权以及《著作权法》规定的由著作权人享有的其他著作财产权利及邻接权利。我们可自行选择是否使用以及使用方式,包括但不限于将前述信息在我们旗下的服务平台上使用与传播,将上述信息再次编辑后使用,以及由我们授权给合作方使用、编辑与传播等。

6、智驾定位有权但无义务对用户发布的内容进行审核,有权根据相关证据结合《中华人民共和国民法典》、《中华人民共和国著作权法》、《信 息网络传播权保护条例》等法律法规对侵权信息进行处理。

7、在智驾定位网站及移动端app中上传或发表的内容,用户应保证其为著作权人或已取得合法授权,并且该内容不会侵犯任何第三方的合法权益。如果第三方提出关于著作权的异议,智驾定位有权根据实际情况删除相关的内容有权追究用户的法律责任,给智驾定位平台或任何第三方造成损失的,用户应负责全额赔偿。

8、智驾定位平台十分重视网络版权及其它知识产权以及用户权益的保护,如果个人或单位发现智驾定位平台上存在侵犯自身合法权益的内容,请与智驾定位平台取得联系(邮箱:zuomeng2@batiao8.com)。为了保证问题能够及时有效地处理,请务必提交真实有效、完整清晰的材料,否则 不予受理。请使用以下格式(包括各条款的序号) :

  1. 权利人对涉嫌侵权内容拥有商标权、著作权或其他依法可以行使权利的权属证明;如果举报人非权利人,请举报人提供代表企业进行举报的书面授权证明。

  2.充分、 明确地描述侵犯了权利人合法权益的内容,提供涉嫌侵权内容在智驾定位上的具体页面地址,指明涉嫌侵权内容中的哪些内容侵犯了上述列明的权利人的合法权益;

  3.权利人具体的联络信息,包括姓名、身份证或护照 复印件(对自然人)、单位登记证明复印件(对单位)、 通信地址、电话号码、传真和电子邮件;

  4.在侵权举报中加入如下关于举报内容真实性的声明:

   a.我本人为所举报内容的合法权利人;

   b.我举报发布在智驾定位平台中的内容侵犯了本人相应的合法权益;

   c. 如果本侵权举报内容不完全属实,本人将承担由此产生的一切法律责任。

智驾定位平台工作人员会在收到相关材料并经相关机构核实后,在10个工作日内处理完毕并给出回复。处理期期间,不提供任何电话、邮件及其他方式的查询服务。若出现智驾定位已经删除或处理的内容,但是百度、谷歌等搜索引擎依然可以搜索到的现象,是因为百度、谷歌等搜索引擎自带缓存,此类问题智驾定位无权也无法处理, 因此相关申请不予受理。用户在智驾定位中的商业行为引发的法律纠纷,由交易双方自行处理,与智驾定位无关。

10     法律责任

1、如果我们发现或收到他人举报或投诉用户违反本协议约定的,我们有权不经通知随时对相关内容,包括但不限于用户资料、聊天记录进行审查、删除,并视情节轻重对违规帐号处以包括但不限于警告、帐号封禁 、设备封禁 、功能封禁 的处罚,且通知用户处理结果。

2、因违反用户协议被封禁的用户,可向我们网站相关页面提交申诉,我们将对申诉进行审查,并自行合理判断决定是否变更处罚措施。

3、用户理解并同意,我们有权依合理判断对违反有关法律法规或本协议规定的行为进行处罚,对违法违规的任何用户采取适当的法律行动,并依据法律法规保存有关信息向有关部门报告等,用户应承担由此而产生的一切法律责任。

4、用户理解并同意,因用户违反本协议约定,导致或产生的任何第三方主张的任何索赔、要求或损失,包括合理的律师费,用户应当赔偿我们与合作公司、关联公司,并使之免受损害。

11     不可抗力及其他免责事由

1、用户理解并确认,在使用本服务的过程中,可能会遇到不可抗力等风险因素,使本服务发生中断。不可抗力是指不能预见、不能克服并不能避免且对一方或双方造成重大影响的客观事件,包括但不限于自然灾害如洪水、地震、瘟疫流行和风暴等以及社会事件如战争、动乱、政府行为等。出现上述情况时,我们将努力在第一时间与相关单位配合,及时进行修复,但是由此给用户或第三方造成的损失,我们及合作单位在法律允许的范围内免责。

2、本服务同大多数互联网服务一样,受包括但不限于用户原因、网络服务质量、社会环境等因素的差异影响,可能受到各种安全问题的侵扰,如他人利用用户的资料,造成现实生活中的骚扰;用户下载安装的其它软件或访问的其他网站中含有“特洛伊木马”等病毒,威胁到用户的计算机信息和数据的安全,继而影响本服务的正常使用等等。用户应加强信息安全及使用者资料的保护意识,要注意加强密码保护,以免遭致损失和骚扰。

3、用户理解并确认,本服务存在因不可抗力、计算机病毒或黑客攻击、系统不稳定、用户所在位置、用户关机以及其他任何技术、互联网络、通信线路原因等造成的服务中断或不能满足用户要求的风险,因此导致的用户或第三方任何损失,我们不承担任何责任。

4、用户理解并确认,在使用本服务过程中存在来自任何他人的包括误导性的、欺骗性的、威胁性的、诽谤性的、令人反感的或非法的信息,或侵犯他人权利的匿名或冒名的信息,以及伴随该等信息的行为,因此导致的用户或第三方的任何损失,我们不承担任何责任。

5、用户理解并确认,我们需要定期或不定期地对“智驾定位”平台或相关的设备进行检修或者维护,如因此类情况而造成服务在合理时间内的中断,我们无需为此承担任何责任,但我们应事先进行通告。

6、我们依据法律法规、本协议约定获得处理违法违规或违约内容的权利,该权利不构成我们的义务或承诺,我们不能保证及时发现违法违规或违约行为或进行相应处理。

7、用户理解并确认,对于我们向用户提供的下列产品或者服务的质量缺陷及其引发的任何损失,我们无需承担任何责任:

(1) 我们向用户免费提供的服务;

(2) 我们向用户赠送的任何产品或者服务;

8、在任何情况下,我们均不对任何间接性、后果性、惩罚性、偶然性、特殊性或刑罚性的损害,包括因用户使用“智驾定位”或本服务而遭受的利润损失,承担责任(即使我们已被告知该等损失的可能性亦然)。尽管本协议中可能含有相悖的规定,我们对用户承担的全部责任,无论因何原因或何种行为方式,始终不超过用户因使用我们提供的服务而支付给我们的费用(如有)。

12     服务的变更、中断、终止

1、鉴于网络服务的特殊性,用户同意我们有权随时变更、中断或终止部分或全部的服务(包括收费服务)。我们变更、中断或终止的服务,我们应当在变更、中断或终止之前通知用户,并应向受影响的用户提供等值的替代性的服务;

2、如发生下列任何一种情形,我们有权变更、中断或终止向用户提供的免费服务或收费服务,而无需对用户或任何第三方承担任何责任:

(1) 根据法律规定用户应提交真实信息,而用户提供的个人资料不真实、或与注册时信息不一致又未能提供合理证明;

(2) 用户违反相关法律法规或本协议的约定;

(3) 按照法律规定或有权机关的要求;

(4) 出于安全的原因或其他必要的情形。

13     其他

1、我们郑重提醒用户注意本协议中免除我们责任和限制用户权利的条款,请用户仔细阅读,自主考虑风险

2、本协议的效力、解释及纠纷的解决,适用于中华人民共和国法律。若用户和我们之间发生任何纠纷或争议,首先应友好协商解决,协商不成的,用户同意将纠纷或争议提交我们住所地有管辖权的人民法院管辖。

3、本协议的任何条款无论因何种原因无效或不具可执行性,其余条款仍有效,对双方具有约束力。

4、由于互联网高速发展,您与我们签署的本协议列明的条款可能并不能完整罗列并覆盖您与智驾定位所有权利与义务,现有的约定也不能保证完全符合未来发展的需求。因此,智驾定位隐私权政策、智驾定位平台行为规范等均为本协议的补充协议,与本协议不可分割且具有同等法律效力。如您使用智驾定位平台服务,视为您同意上述补充协议。

5、本协议中的标题仅为方便阅读而设,并不影响本协议中任何规定的含义或解释。

14     如何联系我们

如果您对本协议有任何疑问、意见或建议,欢迎发送至zuomeng2@batiao8.com与我们进行联系

 

\ No newline at end of file diff --git a/html/Privacy.html b/html/Privacy.html new file mode 100644 index 0000000..124440c --- /dev/null +++ b/html/Privacy.html @@ -0,0 +1 @@ +

隐私政策

更新日期:2025年8月11日

生效日期:2025年8月11日

目录

引言

关于我们

1、我们将收集与您相关的哪些信息

2、我们如何收集您的个人信息

3、我们如何使用您的个人信息

4、我们如何保护您的个人信息

5、我们如何处理儿童信息

6、 您管理个人信息的权利

7、 联系我们

8、 本政策如何更新

引言

1. 智驾定位(以下简称“我们”)深知个人信息对您的重要性,并会尽全力保护您的个人信息安全可靠。请您在使用智驾定位产品和/或服务前,仔细阅读并充分理解本隐私政策的全部内容。一旦您使用或继续使用智驾定位产品/服务,即表示您同意我们按照本隐私政策使用和处理您的相关信息。

2. 我们可能会不时依据法律法规或业务调整对本隐私政策进行修订。当本隐私政策发生变更后,我们会在App内关于-隐私政策中向您展示变更后的内容。

3. 您需理解,只有在您确认并同意变更后的《智驾定位隐私政策》,我们才会依据变更后的隐私政策收集、使用、处理和存储您的个人信息;您有权拒绝同意变更后的隐私政策,但请您知悉,一旦您拒绝同意变更后的隐私政策,可能导致您不能或不能继续完整使用相关服务和功能,或者无法达到我们拟达到的服务效果。

关于我们

智驾定位移动客户端及软件技术服务提供者是重庆做梦科技有限公司。

1         我们将收集与您相关的哪些信息:

我们在提供服务时,会收集、储存和使用下列与您有关的信息。如果您拒绝提供相关信息,可能无法成功注册成为我们的用户或者无法享受相应的服务。

当您在平台创建账户时,您必须提供手机号、姓名才能进行使用,手机号码属于敏感信息,收集手机号为了帮助您完成注册,保护账号的安全,您还可以根据个人需求选择填写头像;

您填写的手机号、姓名、头像等个人信息都将作为便于您的好友识别身份、添加好友和联系您的凭证,您可以在“我的-设置”中修改这些信息。

获取权限为保障为您正常提供相应服务,在您使用产品之前,需要开启以下权限:

1、个人信息类型:设备信息(包括设备型号、设备标识符(如IMEI/ AndroidID/ IDFA/ OPENUDID/ GUID/ OAID)、设备MAC地址、电信运营商等软硬件特征信息)

目的和用途:用于保障用户账号登录和功能实现过程中的安全风控。

2.位置权限(始终允许),您同意开启设备定位服务后,我们会通过GPS或WiFi等方式持续收集您的地理位置信息,将用于为您记录位置信息和为您的好友发送位置信息。您可以通过关闭手机定位服务,停止我们对您的地理位置信息进行收集,同时我们将对您的好友停止更新您的位置。

3.运动和体能记录,您同意开启此权限后,我们将通过获取您设备(iOS)的记录来为您记录运动状态信息,并为您的好友展示运动状态信息;

4.通知权限,您开启此权限后,当您对好友开启守护通知或好友发起求助时,将用于接受手机的通知消息。其他信息除此之外,为保障您能正常使用我们的服务,我们会收集您的设备型号、操作系统、唯一设备标识符、登录IP地址、智驾定位版本号、接入网络方式、类型和状态,这类信息是为提供服务必须收集的基础信息。

5.麦克风权限     

目的:用于实现紧急求助时的伪装语言功能,保障您在特殊场景下的安全求助需求 。

方式:应用通过调用设备麦克风,采集您录入的语音信息,经特定算法转换为伪装语言 。

范围:仅在您主动使用紧急求助伪装语言功能时,采集必要的语音信息,不会在其他场景下获取麦克风数据。

6.通讯录权限     

目的:帮助您无需手动输入手机号,即可快速添加好友,提升社交连接效率 。

方式:应用读取您设备通讯录中的联系人号码信息,与应用内账号匹配,推荐可添加的好友 。

范围:仅读取联系人的手机号码信息,不会获取通讯录中其他非必要的备注、分组等隐私内容。

7. 打电话权限   

目的:方便您在点击好友头像后能快速拨打电话,优化沟通体验 。

方式:应用调用设备的拨号功能,根据您点击的好友关联的电话号码发起呼叫 。

范围:仅在您主动点击好友头像触发拨号操作时,使用相关电话号码信息,不做其他用途。

8. 拍照和相册访问权限,用于选择图片来设置您App中的头像,以及在意见反馈中提交图片反馈。

9. 存储权限,用于存储您想要分享的App界面截图。

 

使用SDK名称:

友盟统计分析SDK

包名:com.umeng.analytics

使用目的:进行APP运营统计与分析

服务类型:统计分析、社会化分享、消息推送;

运营方:友盟同欣(北京)科技有限公司

收集个人信息类型:设备信息(IMEI/MAC/Android ID/IDFA/OAID/OpenUDID/GUID/SIM卡IMSI/ICCID)、地址位置信息、网络信息、获取设备序列号,获取已安装App,获取SN个人信息;

隐私权政策链接:https://www.umeng.com/page/policy

 

阿里云号码认证SDK;

包名:com.mobile.auth

运营方:阿里云计算有限公司

服务类型:本机号码一键登录和认证。

收集信息类型:网络类型、设备信息(IP地址、设备制造商、设备型号、手机操作系统、应用程序供应商标志符(IDFV)、SIM卡或国际移动用户识别码(IMSI)信息、手机号(非必须填写项)等)。

隐私权政策链接:https://terms.aliyun.com/legal-agreement/terms/suit_bu1_ali_cloud/suit_bu1_ali_cloud202112211045_86198.html

 

腾讯开放平台SDK

包名:com.tencent.open/com.tencent.tauth

运营方:深圳市腾讯计算机系统有限公司

服务类型:邀请添加好友,内容分享合作,

收集信息类型:获取已安装APP信息,读写手机外置存储信息  https://docs.qq.com/sheet/DQ2JOU1lUaWVRQU1p?tab=BB08J2

隐私政策链接:https://wiki.connect.qq.com/qq%e4%ba%92%e8%81%94sdk%e9%9a%90%e7%a7%81%e4%bf%9d%e6%8a%a4%e5%a3%b0%e6%98%8e

 

微信SDK

包名:com.tencent.mm

运营方:深圳市腾讯计算机系统有限公司

服务类型:微信分享,微信支付、

收集个人信息类型:获取已安装APP信息、读写手机外置存储信息

隐私权政策链接:https://weixin.qq.com/cgi-bin/readtemplate?lang=zh_CN&t=weixin_agreement&s=privacy

 

BuglySDK

包名:com.tencent.bugly

收集个人信息类型与目的:运行中的进程中信息,为了更真实地为开发者还原Crash场景服务;

Crash环境:Crash信息及线程堆栈,ROM/RAM/SD卡容量、网络/语言等状态

App信息:包名、版本、所属进程名

设备信息:Android id,用于判断Crash设备做统计。

bugly 隐私协议文档下载地址 :https://static.bugly.qq.com/bugly-sdk-privacy-statement.pdf

 

微博SDK;

包名:com.weibo

运营方:深圳市腾讯计算机系统有限公司

服务类型:分享图片和文案

收集个人信息类型:IMEI

隐私链接:https://open.weibo.com/wiki/Sdk/privacy

 

穿山甲(广点通)广告SDK;

包名:com.bykv、com.bytedance.sdk

运营方:北京巨量引擎网络技术有限公司

收集个人信息类型和目的 :读写手机外置存储信息,获取Android_ID,获取设备序列号,获取运行中进程信息,获取软件安装列表,IMEI,获取陀螺仪传感器,加速度传感器,BSSID个人信息、获取IP

隐私链接:https://www.csjplatform.com/privacy

 

优量汇(腾讯)广告SDK;

包名:com.qq.e

深圳市腾讯计算机系统有限公司

收集个人信息类型和目的:读写手机外置存储信息,获取Android_ID,获取设备序列号,获取运行中进程信息,获取软件安装列表,IMEI,获取陀螺仪传感器,加速度传感器,BSSID个人信息、获取IP

隐私链接:https://e.qq.com/dev/help_detail.html?cid=2005&pid=5983

 

华为开放平台定位SDK

包名:com.huawei.hms:maps

第三方名称:华为软件技术有限公司

使用目的:为了向用户提供定位服务

收集个人信息:位置信息(经纬度、精确位置、粗略位置)【通过IP 地址、GNSS信息、WiFi状态、WiFi参数、WiFi列表、SSID、BSSID、基站信息、信号强度的信息、蓝牙信息、传感器信息(矢量、加速度、压力)、设备信号强度信息获取、外部储存目录】、设备标识信息(IMEI、IDFA、IDFV、Android ID、MEID、MAC地址、OAID、IMSI、ICCID、硬件序列号)、当前应用信息(应用名、应用版本号)、设备参数及系统信息(系统属性、设备型号、操作系统、运营商信息)。读取特定类型传感器列表

隐私权政策链接(包含使用方式范围):https://developer.huawei.com/consumer/cn/doc/HMSCore-Guides/personal-data-0000001050158697

 

华为开放平台地图SDK

包名:com.huawei.hms:maps

第三方名称:华为软件技术有限公司

使用目的:为了实现地图展示、定位、搜索等服务(SDK将每30s读取一次位置信息等信息,以保证功能正常运行)

收集个人信息:位置信息(经纬度、精确位置、粗略位置)【通过IP 地址、GNSS信息、WiFi状态、WiFi参数、WiFi列表、SSID、BSSID、基站信息、信号强度的信息、蓝牙信息、传感器信息(矢量、加速度、压力、方向、地磁)、设备信号强度信息获取、外部储存目录】、设备标识信息(IMEI、IDFA、IDFV、Android ID、MEID、MAC地址、OAID、IMSI、ICCID、硬件序列号)、当前应用信息(应用名、应用版本号)、设备参数及系统信息(系统属性、设备型号、操作系统、运营商信息)。读取特定类型传感器列表

隐私权政策链接(包含使用方式范围):https://developer.huawei.com/consumer/cn/doc/HMSCore-Guides/personal-data-0000001050158697

 

百度开放平台定位SDK

包名:com.baidu.location

第三方名称:北京百度网讯科技有限公司

使用目的:为了向用户提供定位服务

收集个人信息:位置信息(经纬度、精确位置、粗略位置)【通过IP 地址、GNSS信息、WiFi状态、WiFi参数、WiFi列表、SSID、BSSID、基站信息、信号强度的信息、蓝牙信息、传感器信息(加速度、陀螺仪、方向、压力、旋转矢量、光照、磁力计)读取特定类型传感器列表、设备信号强度信息获取、外部储存目录】、设备标识信息(IMEI、IDFA、IDFV、Android ID、MEID、MAC地址、OAID、IMSI、ICCID、硬件序列号)、当前应用信息(应用名、应用版本号)、设备参数及系统信息(系统属性、设备型号、操作系统、运营商信息)、AndroidID。

隐私权政策链接(包含使用方式范围):https://lbsyun.baidu.com/index.php?title=openprivacy

 

百度开放平台地图SDK

包名:com.baidu.location

第三方名称:北京百度网讯科技有限公司

使用目的:为了实现地图展示、定位、搜索等服务(SDK将每30s读取一次位置信息等信息,以保证功能正常运行)

收集个人信息:位置信息(经纬度、精确位置、粗略位置)【通过IP 地址、GNSS信息、WiFi状态、WiFi参数、WiFi列表、SSID、BSSID、基站信息、信号强度的信息、蓝牙信息、传感器信息(加速度、陀螺仪、方向、压力、旋转矢量、光照、磁力计)读取特定类型传感器列表、设备信号强度信息获取、外部储存目录】、设备标识信息(IMEI、IDFA、IDFV、Android ID、MEID、MAC地址、OAID、IMSI、ICCID、硬件序列号)、当前应用信息(应用名、应用版本号)、设备参数及系统信息(系统属性、设备型号、操作系统、运营商信息)、AndroidID。

隐私权政策链接(包含使用方式范围):https://lbsyun.baidu.com/index.php?title=openprivacy

 

高德开放平台定位SDK

包名:com.amap.api

第三方名称:高德软件有限公司

使用目的:为了向用户提供定位服务

收集个人信息:位置信息(经纬度、精确位置、粗略位置)【通过IP 地址、GNSS信息、WiFi状态、WiFi参数、WiFi列表、SSID、BSSID、基站信息、信号强度的信息、蓝牙信息、加速度传感器信息、矢量传感器信息、压力传感器信息、设备信号强度信息获取、外部储存目录】、设备标识信息(IMEI、IDFA、IDFV、Android ID、MEID、MAC地址、OAID、IMSI、ICCID、硬件序列号)、当前应用信息(应用名、应用版本号)、设备参数及系统信息(系统属性、设备型号、操作系统、运营商信息)。读取特定类型传感器列表

隐私权政策链接(包含使用方式范围):https://lbs.amap.com/pages/privacy/

 

高德开放平台地图SDK

包名:com.amap.api

第三方名称:高德软件有限公司

使用目的:为了实现地图展示、定位、搜索等服务

收集个人信息:位置信息(经纬度、精确位置、粗略位置)【通过IP 地址、GNSS信息、WiFi状态、WiFi参数、WiFi列表、SSID、BSSID、基站信息、信号强度的信息、蓝牙信息、加速度传感器信息、矢量传感器信息、压力传感器信息、方向传感器信息、地磁传感器信息、设备信号强度信息获取、外部储存目录】、设备标识信息(IMEI、IDFA、IDFV、Android ID、MEID、MAC地址、OAID、IMSI、ICCID、硬件序列号)、当前应用信息(应用名、应用版本号)、设备参数及系统信息(系统属性、设备型号、操作系统、运营商信息)。读取特定类型传感器列表

隐私权政策链接(包含使用方式范围):https://lbs.amap.com/pages/privacy/

 

OPPO;OPush SDK

包名:com.heytap.msp

收集个人信息类型:应用基本信息、应用内设备标识符、设备的硬件信息、系统基本信息和系统设置信息

使用目的:1、提供消息推送服务;2、统计OPPO推送SDK接口调用成功率。

收集数据清单https://open.oppomobile.com/new/developmentDoc/info?id=11229

隐私政策链接:https://open.oppomobile.com/new/developmentDoc/info?id=10288

 

小米;小米推送 SDK

包名:com.xiaomi和com.xiaomi.mipush

收集个人信息类型:应用基本信息、应用内设备标识符、设备的硬件信息、系统基本信息和系统设置信息

使用目的:1、提供消息推送服务;2、统计小米推送SDK接口调用成功率。

隐私政策链接:https://dev.mi.com/distribute/doc/details?pId=1534

 

vivo;vivo推送 SDK

包名:com.vivo和com.vivo.push

收集个人信息类型:应用基本信息、应用内设备标识符、设备的硬件信息、系统基本信息和系统设置信息

使用目的:1、提供消息推送服务;2、统计vivo推送SDK接口调用成功率。

隐私政策链接: https://dev.vivo.com.cn/documentCenter/doc/652https://dev.vivo.com.cn/documentCenter/doc/706

 

华为推送SDK

包名:com.huawei.hms

第三方名称:华为软件技术有限公司

收集个人信息类型:应用基本信息、应用内设备标识符、设备的硬件信息、系统基本信息和系统设置信息

使用目的:1、提供消息推送服务;2、统计华为推送SDK接口调用成功率。

隐私政策链接:https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/sdk-data-security-0000001050042177

 

自启动和关联启动说明

1、为确保本应用处于关闭或后台运行状态下可正常接收到客户端推送的信息,本应用须使用(自启动)能力,将存在一定频率通过系统发送广播唤醒本应用自启动或关联启动行为,是因实现功能及服务所必要的。

2、当您打开内容类推送消息,在征得您的明确同意后,会跳转打开相关内容。在未征得您同意的情况下,则不会有自启动或关联启动。

3、当您打开本 App 内部下载的文件后,会关联启动第三方 App

2         我们如何收集您的个人信息

(一)      Cookie

为确保网站正常运转,我们会在您的移动设备上存储名为 Cookie 的小数据文件。Cookie 通常包含标识符、站点名称以及一些号码和字符。借助于 Cookie,网站能够存储您的偏好或购物篮内的商品等数据。 我们不会将 Cookie 用于本政策所述目的之外的任何用途。您可根据自己的偏好管理或删除 Cookie。您可以清除计算机上保存的所有 Cookie,大部分网络浏览器都设有阻止 Cookie 的功能。但如果您这么做,则需要在每一次访问我们的网站时亲自更改用户设置。

(二)网站信标和像素标签

除 Cookie 外,我们还会在网站上使用网站信标和像素标签等其他同类技术。例如,我们向您发送的电子邮件可能含有链接至我们网站内容的点击 URL。如果您点击该链接,我们则会跟踪此次点击,帮助我们了解您的产品或服务偏好并改善客户服务。网站信标通常是一种嵌入到网站或电子邮件中的透明图像。借助于电子邮件中的像素标签,我们能够获知电子邮件是否被打开。如果您不希望自己的活动以这种方式被追踪,则可以随时从我们的寄信名单中退订。

(二)      Do Not Track(请勿追踪)

很多网络浏览器均设有 Do Not Track 功能,该功能可向网站发布 Do Not Track 请求。目前,主要互联网标准组织尚未设立相关政策来规定网站应如何应对此类请求。但如果您的浏览器启用了Do Not Track,那么我们的所有网站都会尊重您的选择。

3         我们如何使用您的个人信息

(一)共享

  我们不会向其他任何公司、组织和个人分享您的个人信息,但以下情况除外:

  1、在获取明确同意的情况下共享:获得您的明确同意后,我们会与其他方共享您的个人信息。

  2、我们可能会根据法律法规规定,或按政府主管部门的强制性要求,对外共享您的个人信息。

  3、与我们的关联公司共享:您的个人信息可能会与我们关联公司共享。我们只会共享必要的个人信息,且受本隐私政策中所声明目的的约束。关联公司如要改变个人信息的处理目的,将再次征求您的授权同意。 

  4、与授权合作伙伴共享:仅为实现本隐私权政策中声明的目的,我们的某些服务将由授权合作伙伴提供。我们可能会与合作伙伴共享您的某些个人信息,以提供更好的客户服务和用户体验。在这种情况下,这些公司 必须遵守我们的数据隐私和安全要求。我们仅会出于合法、正当、必要、特定、明确的目的共享您的个人信息,并且只会共享提供服务所必要的个人信息。 对我们与之共享个人信息的公司、组织和个人,我们会与其签署严格的保密协定,要求他们按照我们的说明、本隐私政策以及其他任何相关的保密和安全措施来处理个人信息。

(二)转让

  我们不会将您的个人信息转让给任何公司、组织和个人,但以下情况除外:

1、在获取明确同意的情况下转让:获得您的明确同意后,我们会向其他方转让您的个人信息;

2、在涉及合并、收购或破产清算时,如涉及到个人信息转让,我们会在要求新的持有您个人信息的公司、组织继续受此隐私政策的约束,否则我们将要求该公司、组织重新向您征求授权同意。

(三)公开披露

  我们仅会在以下情况下,公开披露您的个人信息:

  1、获得您明确同意后;

  2、基于法律的披露:在法律、法律程序、诉讼或政府主管部门强制性要求的情况下,我们可能会公开披露您的个人信息。

4         我们如何保护您的个人信息

(一)我们已使用符合业界标准的安全防护措施保护您提供的个人信息,防止数据遭到未经授权访问、公开披露、使用、修改、损坏或丢失。我们会采取一切合理可行的措施,保护您的个人信息。例如,在您的浏览器与“服务”之间交换数据(如信用卡信息)时受 SSL 加密保护;我们同时对我们网站提供 https 安全浏览方式;我们会使用加密技术确保数据的保密性;我们会使用受信赖的保护机制防止数据遭到恶意攻击;我们会部署访问控制机制,确保只有授权人员才可访问个人信息;以及我们会举办安全和隐私保护培训课程,加强员工对于保护个人信息重要性的认识。

(二)我们会采取一切合理可行的措施,确保未收集无关的个人信息。我们只会在达成本政策所述目的所需的期限内保留您的个人信息,除非需要延长保留期或受到法律的允许。

(三)互联网并非绝对安全的环境,而且电子邮件、即时通讯、及与其他我们用户的交流方式并未加密,我们强烈建议您不要通过此类方式发送个人信息。请使用复杂密码,协助我们保证您的账号安全。

(四)互联网环境并非百分之百安全,我们将尽力确保或担保您发送给我们的任何信息的安全性。如果我们的物理、技术、或管理防护设施遭到破坏,导致信息被非授权访问、公开披露、篡改、或毁坏,导致您的合法权益受损,我们将承担相应的法律责任。

(五)在不幸发生个人信息安全事件后,我们将按照法律法规的要求,及时向您告知:安全事件的基本情况和可能的影响、我们已采取或将要采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们将及时将事件相关情况以邮件、信函、电话、推送通知等方式告知您,难以逐一告知个人信息主体时,我们会采取合理、有效的方式发布公告。 同时,我们还将按照监管部门要求,主动上报个人信息安全事件的处置情况。

5         我们如何处理儿童的个人信息 

我们的产品、网站和服务主要面向成人。如果没有父母或监护人的同意,儿童不得创建自己的用户账户。

  对于经父母同意而收集儿童个人信息的情况,我们只会在受到法律允许、父母或监护人明确同意或者保护儿童所必要的情况下使用或公开披露此信息。 尽管当地法律和习俗对儿童的定义不同,但我们将不满 14 周岁的任何人均视为儿童。 如果我们发现自己在未事先获得可证实的父母同意的情况下收集了儿童的个人信息,则会设法尽快删除相关数据。

我们非常重视对未成年人个人信息的保护。

若您是18周岁以下的未成年人,在取得您或您的监护人同意之前,我们不会处理您的个人信息。若您是未成年人的监护人,当您对您所监护的未成年人的个人信息有相关疑问时,请通过以下联系方式与我们联系。

若您是14周岁以下的儿童,我们还专门为您制定了《儿童隐私保护声明》,儿童及其监护人在为14周岁以下的儿童使用智驾定位服务前,还应仔细阅读《儿童隐私保护声明》。只有在取得监护人对《儿童隐私保护声明》的同意后,我们才会处理14周岁以下的儿童个人信息。

6         您管理个人信息的权利

我们理解您对个人信息的关注,并尽全力确保您对于自己个人信息访问、更正、删除以及撤回授权的权利,以使您拥有充分的能力保障您的隐私和安全。您的权利包括:

(一)访问您的个人信息

您有权访问您的个人信息,法律法规规定的例外情况除外。

如果您想行使数据访问权,可以通过以下方式自行访问: 账户信息——如果您希望访问或编辑您的账户中的个人资料信息和支付信息、更改您的注册账号、密码、添加安全信息或关闭您的账户等,您可以通过访问“我的-账号设置”执行此类操作。

如果您无法通过上述链接访问这些个人信息,您可以随时使用我们的 Web 表单联系,或发送电子邮件至【zuomeng2@batiao8.com】。我们将在十五天内回复您的访问请求。

对于您在使用我们的产品或服务过程中产生的其他个人信息,只要我们不需要过多投入,我们会向您提供。如果您想行使数据访问权,请发送电子邮件至【 zuomeng2@batiao8.com 】。

(二)更正您的个人信息 

当您发现我们处理的关于您的个人信息有错误时,您有权要求我们做出更正。

您可以通过“(一)访问您的个人信息”中罗列的方式提出更正申请。 如果您无法通过上述链接更正这些个人信息,您可以随时使用我们的 Web 表单联系,或发送电子邮件至【zuomeng2@batiao8.com】我们将在十五天内回复您的更正请求。 

(三)删除您的个人信息 

在以下情形中,您可以向我们提出删除个人信息的请求:

 1、如果我们处理个人信息的行为违反法律法规; 

 2、如果我们收集、使用您的个人信息,却未征得您的同意;

 3、如果我们处理个人信息的行为违反了与您的约定;

 4、如果您不再使用我们的产品或服务,或您注销了账号;

 5、如果我们不再为您提供产品或服务。 若我们决定响应您的删除请求,我们还将同时通知从我们获得您的个人信息的实体,要求其及时删除,除非法律法规另有规定,或这些实体获得您的独立授权。 当您从我们的服务中删除信息后,我们可能不会立即备份系统中删除相应的信息,但会在备份更新时删除这些信息。 

(四)改变您授权同意的范围 

每个业务功能需要一些基本的个人信息才能得以完成(见本策略“第一部分”)。对于额外收集的个人信息的收集和使用,您可以随时给予或撤回您的授权同意,撤回步骤:首页右上角一我的一设置﹣隐私设置﹣系统权限管理。 当您收回同意后,我们将不再处理相应的个人信息。但您收回同意的决定,不会影响此前基于您的授权而开展的个人信息处理。 

(五)个人信息主体注销账户 

您随时可注销此前注册的账户,您可以点击app内“我的”-”设置“-“账号操作”-“注销账号”进行注销操作,在注销账户之后,我们将停止为您提供产品或服务,并依据您的要求,删除您的个人信息,法律法规另有规定的除外。 

(六)个人信息主体获取个人信息副本 

您有权获取您的个人信息副本,您可以通过联系【zuomeng2@batiao8.com】导出至多回复日前30日的位置数据 

(七)约束信息系统自动决策 

在某些业务功能中,我们可能仅依据信息系统、算法等在内的非人工自动决策机制做出决定。如果这些决定显著影响您的合法权益,您有权要求我们做出解释,我们也将提供适当的救济方式。 

(八)响应您的上述请求 

为保障安全,您可能需要提供书面请求,或以其他方式证明您的身份。我们可能会先要求您验证自己的身份,然后再处理您的请求。 我们将在十五天内做出答复。如您不满意,还可以通过以下途径投诉: 对于您合理的请求,我们原则上不收取费用,但对多次重复、超出合理限度的请求,我们将视情收取一定成本费用。对于那些无端重复、需要过多技术手段(例如,需要开发新系统或从根本上改变现行惯例)、给他人合法权益带来风险或者非常不切实际(例如,涉及备份磁带上存放的信息)的请求,我们可能会予以拒绝。

 在以下情形中,按照法律法规要求,我们将无法响应您的请求:

 1、与国家安全、国防安全有关的;

 2、与公共安全、公共卫生、重大公共利益有关的;

 3、与犯罪侦查、起诉和审判等有关的;

 4、有充分证据表明您存在主观恶意或滥用权利的; 

 5、响应您的请求将导致您或其他个人、组织的合法权益受到严重损害的。

7         如何联系我们 

如果您对本隐私政策有任何疑问、意见或建议,欢迎发送至zuomeng2@batiao8.com与我们进行联系

我们将尽快查看邮件,并在十五个工作日内予以回复。

8         本隐私权政策如何更新 

我们可能适时会对本隐私权政策进行调整或变更,本隐私权政策的任何更新将在App内显著位置提示或者以电子邮件或其他方式向您发送通知,除法律法规或监管规定另有强制性规定外,经调整或变更的内容一经通知或公布后的7日后生效。如您在隐私权政策调整或变更后继续使用我们提供的任一服务或访问我们相关网站的,我们相信这代表您已充分阅读、理解并接受修改后的隐私权政策并受其约束。

 

\ No newline at end of file diff --git a/html/dist/css/style.css b/html/dist/css/style.css new file mode 100644 index 0000000..d1af70f --- /dev/null +++ b/html/dist/css/style.css @@ -0,0 +1,3 @@ +html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:0.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace, monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace, monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}body{background:#fff;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}hr{border:0;display:block;height:1px;background:#E4E8EE;margin-top:24px;margin-bottom:24px}ul,ol{margin-top:0;margin-bottom:24px;padding-left:24px}ul{list-style:disc}ol{list-style:decimal}li>ul,li>ol{margin-bottom:0}dl{margin-top:0;margin-bottom:24px}dt{font-weight:600}dd{margin-left:24px;margin-bottom:24px}img{height:auto;max-width:100%;vertical-align:middle}figure{margin:24px 0}figcaption{font-size:16px;line-height:24px;padding:8px 0}img,svg{display:block}table{border-collapse:collapse;margin-bottom:24px;width:100%}tr{border-bottom:1px solid #E4E8EE}th{text-align:left}th,td{padding:10px 16px}th:first-child,td:first-child{padding-left:0}th:last-child,td:last-child{padding-right:0}html{font-size:20px;line-height:30px}body{color:#6B7A90;font-size:1rem}body,button,input,select,textarea{font-family:"Heebo", sans-serif}a{color:#4234F8;text-decoration:none}a:hover,a:active{outline:0;text-decoration:underline}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{clear:both;color:#161E2A;font-family:"Oxygen", sans-serif;font-weight:600}h1,.h1{font-size:38px;line-height:48px;letter-spacing:0px}@media (min-width: 641px){h1,.h1{font-size:44px;line-height:54px;letter-spacing:0px}}h2,.h2{font-size:32px;line-height:42px;letter-spacing:0px}@media (min-width: 641px){h2,.h2{font-size:38px;line-height:48px;letter-spacing:0px}}h3,.h3,blockquote{font-size:28px;line-height:34px;letter-spacing:0px}@media (min-width: 641px){h3,.h3,blockquote{font-size:32px;line-height:42px;letter-spacing:0px}}h4,.h4{font-size:28px;line-height:34px;letter-spacing:0px}h5,.h5,h6,.h6{font-size:20px;line-height:30px;letter-spacing:-0.1px}@media (max-width: 640px){.h1-mobile{font-size:38px;line-height:48px;letter-spacing:0px}.h2-mobile{font-size:32px;line-height:42px;letter-spacing:0px}.h3-mobile{font-size:28px;line-height:34px;letter-spacing:0px}.h4-mobile{font-size:28px;line-height:34px;letter-spacing:0px}.h5-mobile,.h6-mobile{font-size:20px;line-height:30px;letter-spacing:-0.1px}}.text-light{color:#606483}.text-light a{color:#606483}.text-light h1,.text-light h2,.text-light h3,.text-light h4,.text-light h5,.text-light h6,.text-light .h1,.text-light .h2,.text-light .h3,.text-light .h4,.text-light .h5,.text-light .h6{color:#fff !important}.text-sm{font-size:18px;line-height:27px;letter-spacing:-0.1px}.text-xs{font-size:16px;line-height:24px;letter-spacing:-0.1px}h1,h2,.h1,.h2{margin-top:48px;margin-bottom:16px}h3,.h3{margin-top:36px;margin-bottom:12px}h4,h5,h6,.h4,.h5,.h6{margin-top:24px;margin-bottom:4px}p{margin-top:0;margin-bottom:24px}dfn,cite,em,i{font-style:italic}blockquote{color:#6B7A90;font-style:italic;margin-top:24px;margin-bottom:24px;margin-left:24px}blockquote::before{content:"\201C"}blockquote::after{content:"\201D"}blockquote p{display:inline}address{color:#6B7A90;border-width:1px 0;border-style:solid;border-color:#E4E8EE;padding:24px 0;margin:0 0 24px}pre,pre h1,pre h2,pre h3,pre h4,pre h5,pre h6,pre .h1,pre .h2,pre .h3,pre .h4,pre .h5,pre .h6{font-family:"Courier 10 Pitch", Courier, monospace}pre,code,kbd,tt,var{background:#F3F4FF}pre{font-size:16px;line-height:24px;margin-bottom:1.6em;max-width:100%;overflow:auto;padding:24px;margin-top:24px;margin-bottom:24px}code,kbd,tt,var{font-family:Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace;font-size:16px;padding:2px 4px}abbr,acronym{cursor:help}mark,ins{text-decoration:none}small{font-size:18px;line-height:27px;letter-spacing:-0.1px}b,strong{font-weight:600}button,input,select,textarea,label{font-size:20px;line-height:30px}.container,.container-sm{width:100%;margin:0 auto;padding-left:16px;padding-right:16px}@media (min-width: 481px){.container,.container-sm{padding-left:24px;padding-right:24px}}.container{max-width:1128px}.container-sm{max-width:848px}.container .container-sm{max-width:800px;padding-left:0;padding-right:0}.screen-reader-text{clip:rect(1px, 1px, 1px, 1px);position:absolute !important;height:1px;width:1px;overflow:hidden;word-wrap:normal !important}.screen-reader-text:focus{border-radius:2px;box-shadow:0 0 2px 2px rgba(0,0,0,0.6);clip:auto !important;display:block;font-size:14px;letter-spacing:0px;font-weight:600;line-height:16px;text-decoration:none;text-transform:uppercase;background-color:#fff;color:#4234F8 !important;border:none;height:auto;left:8px;padding:16px 40px;top:8px;width:auto;z-index:100000}.list-reset{list-style:none;padding:0}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-primary{color:#4234F8}.text-secondary{color:#FF6C50}.has-top-divider{position:relative}.has-top-divider::before{content:'';position:absolute;top:0;left:0;width:100%;display:block;height:1px;background:#E4E8EE}.has-bottom-divider{position:relative}.has-bottom-divider::after{content:'';position:absolute;bottom:0;left:0;width:100%;display:block;height:1px;background:#E4E8EE}.m-0{margin:0}.mt-0{margin-top:0}.mr-0{margin-right:0}.mb-0{margin-bottom:0}.ml-0{margin-left:0}.m-8{margin:8px}.mt-8{margin-top:8px}.mr-8{margin-right:8px}.mb-8{margin-bottom:8px}.ml-8{margin-left:8px}.m-16{margin:16px}.mt-16{margin-top:16px}.mr-16{margin-right:16px}.mb-16{margin-bottom:16px}.ml-16{margin-left:16px}.m-24{margin:24px}.mt-24{margin-top:24px}.mr-24{margin-right:24px}.mb-24{margin-bottom:24px}.ml-24{margin-left:24px}.m-32{margin:32px}.mt-32{margin-top:32px}.mr-32{margin-right:32px}.mb-32{margin-bottom:32px}.ml-32{margin-left:32px}.m-40{margin:40px}.mt-40{margin-top:40px}.mr-40{margin-right:40px}.mb-40{margin-bottom:40px}.ml-40{margin-left:40px}.m-48{margin:48px}.mt-48{margin-top:48px}.mr-48{margin-right:48px}.mb-48{margin-bottom:48px}.ml-48{margin-left:48px}.m-56{margin:56px}.mt-56{margin-top:56px}.mr-56{margin-right:56px}.mb-56{margin-bottom:56px}.ml-56{margin-left:56px}.m-64{margin:64px}.mt-64{margin-top:64px}.mr-64{margin-right:64px}.mb-64{margin-bottom:64px}.ml-64{margin-left:64px}.p-0{padding:0}.pt-0{padding-top:0}.pr-0{padding-right:0}.pb-0{padding-bottom:0}.pl-0{padding-left:0}.p-8{padding:8px}.pt-8{padding-top:8px}.pr-8{padding-right:8px}.pb-8{padding-bottom:8px}.pl-8{padding-left:8px}.p-16{padding:16px}.pt-16{padding-top:16px}.pr-16{padding-right:16px}.pb-16{padding-bottom:16px}.pl-16{padding-left:16px}.p-24{padding:24px}.pt-24{padding-top:24px}.pr-24{padding-right:24px}.pb-24{padding-bottom:24px}.pl-24{padding-left:24px}.p-32{padding:32px}.pt-32{padding-top:32px}.pr-32{padding-right:32px}.pb-32{padding-bottom:32px}.pl-32{padding-left:32px}.p-40{padding:40px}.pt-40{padding-top:40px}.pr-40{padding-right:40px}.pb-40{padding-bottom:40px}.pl-40{padding-left:40px}.p-48{padding:48px}.pt-48{padding-top:48px}.pr-48{padding-right:48px}.pb-48{padding-bottom:48px}.pl-48{padding-left:48px}.p-56{padding:56px}.pt-56{padding-top:56px}.pr-56{padding-right:56px}.pb-56{padding-bottom:56px}.pl-56{padding-left:56px}.p-64{padding:64px}.pt-64{padding-top:64px}.pr-64{padding-right:64px}.pb-64{padding-bottom:64px}.pl-64{padding-left:64px}.sr .has-animations .is-revealing{visibility:hidden}.button{display:inline-flex;font-size:14px;letter-spacing:0px;font-weight:700;line-height:16px;text-decoration:none !important;text-transform:uppercase;background-color:#fff;background:#fff;color:#4234F8 !important;border:none;border-radius:2px;cursor:pointer;justify-content:center;padding:16px 40px;height:48px;text-align:center;white-space:nowrap}.button:active{outline:0}.button::before{border-radius:2px}.button-shadow{position:relative}.button-shadow::before{content:'';position:absolute;top:0;right:0;bottom:0;left:0;box-shadow:0 8px 16px rgba(22,30,42,0.12);mix-blend-mode:multiply;transition:box-shadow .15s ease}.button-shadow:hover::before{box-shadow:0 8px 16px rgba(22,30,42,0.16)}.button-sm{padding:8px 24px;height:32px}.button-sm.button-shadow::before{box-shadow:0 4px 16px rgba(22,30,42,0.12)}.button-sm.button-shadow:hover::before{box-shadow:0 4px 16px rgba(22,30,42,0.16)}.button-primary,.button-secondary{color:#fff !important;transition:background .15s ease}.button-primary{background:#4234F8}.button-primary:hover{background:#4b3ef8}.button-primary.button-shadow::before{box-shadow:0 8px 16px rgba(66,52,248,0.24)}.button-primary.button-shadow:hover::before{box-shadow:0 8px 16px rgba(66,52,248,0.32)}.button-primary .button-sm.button-shadow::before{box-shadow:0 4px 16px rgba(66,52,248,0.24)}.button-primary .button-sm.button-shadow:hover::before{box-shadow:0 4px 16px rgba(66,52,248,0.32)}.button-secondary{background:#FF6C50}.button-secondary:hover{background:#ff795f}.button-secondary.button-shadow::before{box-shadow:0 8px 16px rgba(255,108,80,0.24)}.button-secondary.button-shadow:hover::before{box-shadow:0 8px 16px rgba(255,108,80,0.32)}.button-secondary .button-sm.button-shadow::before{box-shadow:0 4px 16px rgba(255,108,80,0.24)}.button-secondary .button-sm.button-shadow:hover::before{box-shadow:0 4px 16px rgba(255,108,80,0.32)}.button-block{display:flex;width:100%}@media (max-width: 640px){.button-wide-mobile{width:100%;max-width:280px}}.site-header{padding:24px 0;position:absolute;top:0;left:0;width:100%;z-index:1}.site-header-inner{position:relative;display:flex;justify-content:space-between;align-items:center}.header-links{display:inline-flex}.header-links li{display:inline-flex}.header-links a:not(.button){font-size:16px;line-height:24px;letter-spacing:-0.1px;font-weight:600;color:#606483;text-transform:uppercase;text-decoration:none;line-height:16px;padding:8px 24px}.header-links a:not(.button):hover,.header-links a:not(.button):active{color:#fff}.hero{position:relative;padding-top:128px;padding-bottom:88px;z-index:0}.hero .hero-bg{position:absolute;top:0;bottom:42%;left:0;right:0;background:#0B0D19;z-index:-2}.hero .hero-particles-container{position:absolute;top:0;bottom:42%;left:0;right:0}.hero::before,.hero::after{content:'';position:absolute;left:calc(50% - 360px);width:720px;background-repeat:no-repeat}.hero::before{top:0;height:159px;background-image:url("../images/hero-bg-top.svg");background-size:720px 159px}.hero::after{bottom:42%;height:173px;background-image:url("../images/hero-bg-bottom.svg");background-size:720px 173px}.hero-inner{position:relative;z-index:1}.hero-copy{position:relative;margin-bottom:48px}@media (min-width: 641px){.hero{padding-top:160px;padding-bottom:128px}.hero::before,.hero::after{left:calc(50% - 720px);width:1440px}.hero::before{height:318px;background-size:1440px 318px}.hero::after{height:347px;background-size:1440px 347px}.hero-copy{margin-bottom:88px}.hero-paragraph{padding-left:72px;padding-right:72px}}.has-animations .hero .hero-bg,.has-animations .hero::before,.has-animations .hero::after,.has-animations .hero-particles-container,.has-animations .site-header,.has-animations .hero-title,.has-animations .hero-paragraph,.has-animations .hero-cta,.has-animations .hero .mockup-bg,.has-animations .hero .device-mockup{opacity:0}.has-animations.is-loaded .hero .hero-bg{animation:heroBg 0.6s cubic-bezier(0.215, 0.61, 0.355, 1) forwards}.has-animations.is-loaded .hero::before,.has-animations.is-loaded .hero::after{animation:heroFadeIn .6s ease forwards .45s}.has-animations.is-loaded .site-header,.has-animations.is-loaded .hero-particles-container,.has-animations.is-loaded .hero .mockup-bg{animation:heroFadeIn .6s ease forwards .45s}.has-animations.is-loaded .hero-title{animation:heroContent 0.6s cubic-bezier(0.215, 0.61, 0.355, 1) forwards 0.15s}.has-animations.is-loaded .hero-paragraph{animation:heroContent 0.6s cubic-bezier(0.215, 0.61, 0.355, 1) forwards 0.3s}.has-animations.is-loaded .hero-cta{animation:heroContent 0.6s cubic-bezier(0.215, 0.61, 0.355, 1) forwards 0.45s}.has-animations.is-loaded .hero .device-mockup{animation:heroMockup .6s ease forwards .6s}@keyframes heroBg{from{transform:scaleY(0) scaleX(1.2) skewY(30deg);opacity:1}to{transform:scaleY(1) scaleX(1) skewY(0);opacity:1}}@keyframes heroContent{from{transform:translateY(40px) skewY(2deg);opacity:0}to{transform:translateY(0) skewY(0);opacity:1}}@keyframes heroMockup{from{transform:translateY(80px);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes heroFadeIn{from{opacity:0}to{opacity:1}}.mockup-container{position:relative}.mockup-bg{pointer-events:none}.mockup-bg img,.mockup-bg svg{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);width:auto !important;height:auto;max-width:300% !important}.device-mockup{position:relative;width:350px;height:auto;margin:0 auto;z-index:1}.has-animations .features-extended{opacity:0}.has-animations.is-loaded .features-extended{opacity:1}.features-extended-header{margin-bottom:32px}.features-extended-wrap{display:flex;flex-wrap:wrap;margin-top:-24px}.features-extended-wrap:last-of-type{margin-bottom:-24px}.features-extended-wrap:not(:last-of-type){margin-bottom:24px}.feature-extended{padding:24px 0}.feature-extended-image{position:relative;margin-bottom:32px}.feature-extended-image img,.feature-extended-image svg{width:100%;max-width:296px;height:auto;margin-left:auto;margin-right:auto;overflow:visible}.feature-extended-body{text-align:center}@media (min-width: 641px){.features-extended .container{max-width:912px}.features-extended .section-inner{padding-bottom:128px}.features-extended .section-paragraph{padding-left:72px;padding-right:72px;margin-bottom:0}.features-extended-header{margin-bottom:80px}.features-extended-wrap{margin-top:-64px}.features-extended-wrap:last-of-type{margin-bottom:-64px}.features-extended-wrap:not(:last-of-type){margin-bottom:64px}.feature-extended{display:flex;flex-wrap:nowrap;align-items:stretch;justify-content:flex-end;padding:64px 0}.feature-extended .feature-extended-image{width:440px;margin-right:96px;margin-bottom:0}.feature-extended .feature-extended-image img,.feature-extended .feature-extended-image svg{width:auto}.feature-extended .feature-extended-image img.device-mockup,.feature-extended .feature-extended-image svg.device-mockup{max-width:296px}.feature-extended:nth-child(even){justify-content:flex-start}.feature-extended:nth-child(even) .feature-extended-image{order:1;margin-left:96px;margin-right:0}.feature-extended-body{display:flex;flex-direction:column;justify-content:center;flex-shrink:0;width:360px;text-align:left}}@media (min-width: 1025px){.features-extended .container{max-width:944px}.feature-extended .feature-extended-image{margin-right:64px}.feature-extended:nth-child(even) .feature-extended-image{margin-left:64px}.feature-extended-body{width:392px}}.cta .section-paragraph{margin-bottom:32px}@media (min-width: 641px){.cta .section-paragraph{margin-bottom:32px;padding-left:72px;padding-right:72px}}.is-boxed{background:#fff}.body-wrap{background:#fff;overflow:hidden;display:flex;flex-direction:column;min-height:100vh}.boxed-container{max-width:1440px;margin:0 auto;box-shadow:0 20px 48px rgba(22,30,42,0.16)}main{flex:1 0 auto}.section-inner{position:relative;padding-top:48px;padding-bottom:48px}@media (min-width: 641px){.section-inner{padding-top:88px;padding-bottom:88px}}.site-footer{position:relative;background:#0B0D19}.site-footer::before{content:'';position:absolute;top:-76px;left:calc(50% - 360px);width:720px;height:291px;background-image:url("../images/footer-bg.svg");background-size:720px 291px;background-repeat:no-repeat}.site-footer .footer-particles-container{position:absolute;top:0;bottom:0;left:0;right:0}.site-footer-bottom{font-size:14px;line-height:22px;letter-spacing:0px;z-index:1}.site-footer-bottom a{color:#606483;text-decoration:none}.site-footer-bottom a:hover,.site-footer-bottom a:active{text-decoration:underline}.site-footer-inner{position:relative;display:flex;flex-wrap:wrap;padding-top:48px;padding-bottom:48px;position:relative}.site-footer-inner::before{content:'';position:absolute;top:0;left:0;width:100%;display:block;height:1px;background:#1E233D}.footer-brand,.footer-links,.footer-social-links,.footer-copyright{flex:none;width:100%;display:inline-flex;justify-content:center}.footer-brand,.footer-links,.footer-social-links{margin-bottom:24px}.footer-links li+li,.footer-social-links li+li{margin-left:16px}.footer-social-links li{display:inline-flex}.footer-social-links li a{padding:8px}@media (min-width: 641px){.site-footer::before{top:-152px;left:calc(50% - 720px);width:1440px;height:582px;background-size:1440px 582px}.site-footer-inner{justify-content:space-between;padding-top:64px;padding-bottom:64px}.footer-brand,.footer-links,.footer-social-links,.footer-copyright{flex:50%}.footer-brand,.footer-copyright{justify-content:flex-start}.footer-links,.footer-social-links{justify-content:flex-end}.footer-links{order:1;margin-bottom:0}} + +/*# sourceMappingURL=data:application/json;base64,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LGlCQUFpQixDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsa0JBQWtCLENBQUMsbUVBQW1FLFNBQVMsQ0FBQyxVQUFVLENBQUMsbUJBQW1CLENBQUMsc0JBQXNCLENBQUMsaURBQWlELGtCQUFrQixDQUFDLCtDQUErQyxnQkFBZ0IsQ0FBQyx3QkFBd0IsbUJBQW1CLENBQUMsMEJBQTBCLFdBQVcsQ0FBQywwQkFBMEIscUJBQXFCLFVBQVUsQ0FBQyxzQkFBc0IsQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLDRCQUE0QixDQUFDLG1CQUFtQiw2QkFBNkIsQ0FBQyxnQkFBZ0IsQ0FBQyxtQkFBbUIsQ0FBQyxtRUFBbUUsUUFBUSxDQUFDLGdDQUFnQywwQkFBMEIsQ0FBQyxtQ0FBbUMsd0JBQXdCLENBQUMsY0FBYyxPQUFPLENBQUMsZUFBZSxDQUFDIiwiZmlsZSI6InN0eWxlLmNzcyIsInNvdXJjZXNDb250ZW50IjpbImh0bWx7bGluZS1oZWlnaHQ6MS4xNTstbXMtdGV4dC1zaXplLWFkanVzdDoxMDAlOy13ZWJraXQtdGV4dC1zaXplLWFkanVzdDoxMDAlfWJvZHl7bWFyZ2luOjB9YXJ0aWNsZSxhc2lkZSxmb290ZXIsaGVhZGVyLG5hdixzZWN0aW9ue2Rpc3BsYXk6YmxvY2t9aDF7Zm9udC1zaXplOjJlbTttYXJnaW46MC42N2VtIDB9ZmlnY2FwdGlvbixmaWd1cmUsbWFpbntkaXNwbGF5OmJsb2NrfWZpZ3VyZXttYXJnaW46MWVtIDQwcHh9aHJ7Ym94LXNpemluZzpjb250ZW50LWJveDtoZWlnaHQ6MDtvdmVyZmxvdzp2aXNpYmxlfXByZXtmb250LWZhbWlseTptb25vc3BhY2UsIG1vbm9zcGFjZTtmb250LXNpemU6MWVtfWF7YmFja2dyb3VuZC1jb2xvcjp0cmFuc3BhcmVudDstd2Via2l0LXRleHQtZGVjb3JhdGlvbi1za2lwOm9iamVjdHN9YWJiclt0aXRsZV17Ym9yZGVyLWJvdHRvbTpub25lO3RleHQtZGVjb3JhdGlvbjp1bmRlcmxpbmU7dGV4dC1kZWNvcmF0aW9uOnVuZGVybGluZSBkb3R0ZWR9YixzdHJvbmd7Zm9udC13ZWlnaHQ6aW5oZXJpdH1iLHN0cm9uZ3tmb250LXdlaWdodDpib2xkZXJ9Y29kZSxrYmQsc2FtcHtmb250LWZhbWlseTptb25vc3BhY2UsIG1vbm9zcGFjZTtmb250LXNpemU6MWVtfWRmbntmb250LXN0eWxlOml0YWxpY31tYXJre2JhY2tncm91bmQtY29sb3I6I2ZmMDtjb2xvcjojMDAwfXNtYWxse2ZvbnQtc2l6ZTo4MCV9c3ViLHN1cHtmb250LXNpemU6NzUlO2xpbmUtaGVpZ2h0OjA7cG9zaXRpb246cmVsYXRpdmU7dmVydGljYWwtYWxpZ246YmFzZWxpbmV9c3Vie2JvdHRvbTotMC4yNWVtfXN1cHt0b3A6LTAuNWVtfWF1ZGlvLHZpZGVve2Rpc3BsYXk6aW5saW5lLWJsb2NrfWF1ZGlvOm5vdChbY29udHJvbHNdKXtkaXNwbGF5Om5vbmU7aGVpZ2h0OjB9aW1ne2JvcmRlci1zdHlsZTpub25lfXN2Zzpub3QoOnJvb3Qpe292ZXJmbG93OmhpZGRlbn1idXR0b24saW5wdXQsb3B0Z3JvdXAsc2VsZWN0LHRleHRhcmVhe2ZvbnQtZmFtaWx5OnNhbnMtc2VyaWY7Zm9udC1zaXplOjEwMCU7bGluZS1oZWlnaHQ6MS4xNTttYXJnaW46MH1idXR0b24saW5wdXR7b3ZlcmZsb3c6dmlzaWJsZX1idXR0b24sc2VsZWN0e3RleHQtdHJhbnNmb3JtOm5vbmV9YnV0dG9uLGh0bWwgW3R5cGU9XCJidXR0b25cIl0sW3R5cGU9XCJyZXNldFwiXSxbdHlwZT1cInN1Ym1pdFwiXXstd2Via2l0LWFwcGVhcmFuY2U6YnV0dG9ufWJ1dHRvbjo6LW1vei1mb2N1cy1pbm5lcixbdHlwZT1cImJ1dHRvblwiXTo6LW1vei1mb2N1cy1pbm5lcixbdHlwZT1cInJlc2V0XCJdOjotbW96LWZvY3VzLWlubmVyLFt0eXBlPVwic3VibWl0XCJdOjotbW96LWZvY3VzLWlubmVye2JvcmRlci1zdHlsZTpub25lO3BhZGRpbmc6MH1idXR0b246LW1vei1mb2N1c3JpbmcsW3R5cGU9XCJidXR0b25cIl06LW1vei1mb2N1c3JpbmcsW3R5cGU9XCJyZXNldFwiXTotbW96LWZvY3VzcmluZyxbdHlwZT1cInN1Ym1pdFwiXTotbW96LWZvY3VzcmluZ3tvdXRsaW5lOjFweCBkb3R0ZWQgQnV0dG9uVGV4dH1maWVsZHNldHtwYWRkaW5nOjAuMzVlbSAwLjc1ZW0gMC42MjVlbX1sZWdlbmR7Ym94LXNpemluZzpib3JkZXItYm94O2NvbG9yOmluaGVyaXQ7ZGlzcGxheTp0YWJsZTttYXgtd2lkdGg6MTAwJTtwYWRkaW5nOjA7d2hpdGUtc3BhY2U6bm9ybWFsfXByb2dyZXNze2Rpc3BsYXk6aW5saW5lLWJsb2NrO3ZlcnRpY2FsLWFsaWduOmJhc2VsaW5lfXRleHRhcmVhe292ZXJmbG93OmF1dG99W3R5cGU9XCJjaGVja2JveFwiXSxbdHlwZT1cInJhZGlvXCJde2JveC1zaXppbmc6Ym9yZGVyLWJveDtwYWRkaW5nOjB9W3R5cGU9XCJudW1iZXJcIl06Oi13ZWJraXQtaW5uZXItc3Bpbi1idXR0b24sW3R5cGU9XCJudW1iZXJcIl06Oi13ZWJraXQtb3V0ZXItc3Bpbi1idXR0b257aGVpZ2h0OmF1dG99W3R5cGU9XCJzZWFyY2hcIl17LXdlYmtpdC1hcHBlYXJhbmNlOnRleHRmaWVsZDtvdXRsaW5lLW9mZnNldDotMnB4fVt0eXBlPVwic2VhcmNoXCJdOjotd2Via2l0LXNlYXJjaC1jYW5jZWwtYnV0dG9uLFt0eXBlPVwic2VhcmNoXCJdOjotd2Via2l0LXNlYXJjaC1kZWNvcmF0aW9uey13ZWJraXQtYXBwZWFyYW5jZTpub25lfTo6LXdlYmtpdC1maWxlLXVwbG9hZC1idXR0b257LXdlYmtpdC1hcHBlYXJhbmNlOmJ1dHRvbjtmb250OmluaGVyaXR9ZGV0YWlscyxtZW51e2Rpc3BsYXk6YmxvY2t9c3VtbWFyeXtkaXNwbGF5Omxpc3QtaXRlbX1jYW52YXN7ZGlzcGxheTppbmxpbmUtYmxvY2t9dGVtcGxhdGV7ZGlzcGxheTpub25lfVtoaWRkZW5de2Rpc3BsYXk6bm9uZX1odG1se2JveC1zaXppbmc6Ym9yZGVyLWJveH0qLCo6YmVmb3JlLCo6YWZ0ZXJ7Ym94LXNpemluZzppbmhlcml0fWJvZHl7YmFja2dyb3VuZDojZmZmOy1tb3otb3N4LWZvbnQtc21vb3RoaW5nOmdyYXlzY2FsZTstd2Via2l0LWZvbnQtc21vb3RoaW5nOmFudGlhbGlhc2VkfWhye2JvcmRlcjowO2Rpc3BsYXk6YmxvY2s7aGVpZ2h0OjFweDtiYWNrZ3JvdW5kOiNFNEU4RUU7bWFyZ2luLXRvcDoyNHB4O21hcmdpbi1ib3R0b206MjRweH11bCxvbHttYXJnaW4tdG9wOjA7bWFyZ2luLWJvdHRvbToyNHB4O3BhZGRpbmctbGVmdDoyNHB4fXVse2xpc3Qtc3R5bGU6ZGlzY31vbHtsaXN0LXN0eWxlOmRlY2ltYWx9bGk+dWwsbGk+b2x7bWFyZ2luLWJvdHRvbTowfWRse21hcmdpbi10b3A6MDttYXJnaW4tYm90dG9tOjI0cHh9ZHR7Zm9udC13ZWlnaHQ6NjAwfWRke21hcmdpbi1sZWZ0OjI0cHg7bWFyZ2luLWJvdHRvbToyNHB4fWltZ3toZWlnaHQ6YXV0bzttYXgtd2lkdGg6MTAwJTt2ZXJ0aWNhbC1hbGlnbjptaWRkbGV9ZmlndXJle21hcmdpbjoyNHB4IDB9ZmlnY2FwdGlvbntmb250LXNpemU6MTZweDtsaW5lLWhlaWdodDoyNHB4O3BhZGRpbmc6OHB4IDB9aW1nLHN2Z3tkaXNwbGF5OmJsb2NrfXRhYmxle2JvcmRlci1jb2xsYXBzZTpjb2xsYXBzZTttYXJnaW4tYm90dG9tOjI0cHg7d2lkdGg6MTAwJX10cntib3JkZXItYm90dG9tOjFweCBzb2xpZCAjRTRFOEVFfXRoe3RleHQtYWxpZ246bGVmdH10aCx0ZHtwYWRkaW5nOjEwcHggMTZweH10aDpmaXJzdC1jaGlsZCx0ZDpmaXJzdC1jaGlsZHtwYWRkaW5nLWxlZnQ6MH10aDpsYXN0LWNoaWxkLHRkOmxhc3QtY2hpbGR7cGFkZGluZy1yaWdodDowfWh0bWx7Zm9udC1zaXplOjIwcHg7bGluZS1oZWlnaHQ6MzBweH1ib2R5e2NvbG9yOiM2QjdBOTA7Zm9udC1zaXplOjFyZW19Ym9keSxidXR0b24saW5wdXQsc2VsZWN0LHRleHRhcmVhe2ZvbnQtZmFtaWx5OlwiSGVlYm9cIiwgc2Fucy1zZXJpZn1he2NvbG9yOiM0MjM0Rjg7dGV4dC1kZWNvcmF0aW9uOm5vbmV9YTpob3ZlcixhOmFjdGl2ZXtvdXRsaW5lOjA7dGV4dC1kZWNvcmF0aW9uOnVuZGVybGluZX1oMSxoMixoMyxoNCxoNSxoNiwuaDEsLmgyLC5oMywuaDQsLmg1LC5oNntjbGVhcjpib3RoO2NvbG9yOiMxNjFFMkE7Zm9udC1mYW1pbHk6XCJPeHlnZW5cIiwgc2Fucy1zZXJpZjtmb250LXdlaWdodDo2MDB9aDEsLmgxe2ZvbnQtc2l6ZTozOHB4O2xpbmUtaGVpZ2h0OjQ4cHg7bGV0dGVyLXNwYWNpbmc6MHB4fUBtZWRpYSAobWluLXdpZHRoOiA2NDFweCl7aDEsLmgxe2ZvbnQtc2l6ZTo0NHB4O2xpbmUtaGVpZ2h0OjU0cHg7bGV0dGVyLXNwYWNpbmc6MHB4fX1oMiwuaDJ7Zm9udC1zaXplOjMycHg7bGluZS1oZWlnaHQ6NDJweDtsZXR0ZXItc3BhY2luZzowcHh9QG1lZGlhIChtaW4td2lkdGg6IDY0MXB4KXtoMiwuaDJ7Zm9udC1zaXplOjM4cHg7bGluZS1oZWlnaHQ6NDhweDtsZXR0ZXItc3BhY2luZzowcHh9fWgzLC5oMyxibG9ja3F1b3Rle2ZvbnQtc2l6ZToyOHB4O2xpbmUtaGVpZ2h0OjM0cHg7bGV0dGVyLXNwYWNpbmc6MHB4fUBtZWRpYSAobWluLXdpZHRoOiA2NDFweCl7aDMsLmgzLGJsb2NrcXVvdGV7Zm9udC1zaXplOjMycHg7bGluZS1oZWlnaHQ6NDJweDtsZXR0ZXItc3BhY2luZzowcHh9fWg0LC5oNHtmb250LXNpemU6MjhweDtsaW5lLWhlaWdodDozNHB4O2xldHRlci1zcGFjaW5nOjBweH1oNSwuaDUsaDYsLmg2e2ZvbnQtc2l6ZToyMHB4O2xpbmUtaGVpZ2h0OjMwcHg7bGV0dGVyLXNwYWNpbmc6LTAuMXB4fUBtZWRpYSAobWF4LXdpZHRoOiA2NDBweCl7LmgxLW1vYmlsZXtmb250LXNpemU6MzhweDtsaW5lLWhlaWdodDo0OHB4O2xldHRlci1zcGFjaW5nOjBweH0uaDItbW9iaWxle2ZvbnQtc2l6ZTozMnB4O2xpbmUtaGVpZ2h0OjQycHg7bGV0dGVyLXNwYWNpbmc6MHB4fS5oMy1tb2JpbGV7Zm9udC1zaXplOjI4cHg7bGluZS1oZWlnaHQ6MzRweDtsZXR0ZXItc3BhY2luZzowcHh9Lmg0LW1vYmlsZXtmb250LXNpemU6MjhweDtsaW5lLWhlaWdodDozNHB4O2xldHRlci1zcGFjaW5nOjBweH0uaDUtbW9iaWxlLC5oNi1tb2JpbGV7Zm9udC1zaXplOjIwcHg7bGluZS1oZWlnaHQ6MzBweDtsZXR0ZXItc3BhY2luZzotMC4xcHh9fS50ZXh0LWxpZ2h0e2NvbG9yOiM2MDY0ODN9LnRleHQtbGlnaHQgYXtjb2xvcjojNjA2NDgzfS50ZXh0LWxpZ2h0IGgxLC50ZXh0LWxpZ2h0IGgyLC50ZXh0LWxpZ2h0IGgzLC50ZXh0LWxpZ2h0IGg0LC50ZXh0LWxpZ2h0IGg1LC50ZXh0LWxpZ2h0IGg2LC50ZXh0LWxpZ2h0IC5oMSwudGV4dC1saWdodCAuaDIsLnRleHQtbGlnaHQgLmgzLC50ZXh0LWxpZ2h0IC5oNCwudGV4dC1saWdodCAuaDUsLnRleHQtbGlnaHQgLmg2e2NvbG9yOiNmZmYgIWltcG9ydGFudH0udGV4dC1zbXtmb250LXNpemU6MThweDtsaW5lLWhlaWdodDoyN3B4O2xldHRlci1zcGFjaW5nOi0wLjFweH0udGV4dC14c3tmb250LXNpemU6MTZweDtsaW5lLWhlaWdodDoyNHB4O2xldHRlci1zcGFjaW5nOi0wLjFweH1oMSxoMiwuaDEsLmgye21hcmdpbi10b3A6NDhweDttYXJnaW4tYm90dG9tOjE2cHh9aDMsLmgze21hcmdpbi10b3A6MzZweDttYXJnaW4tYm90dG9tOjEycHh9aDQsaDUsaDYsLmg0LC5oNSwuaDZ7bWFyZ2luLXRvcDoyNHB4O21hcmdpbi1ib3R0b206NHB4fXB7bWFyZ2luLXRvcDowO21hcmdpbi1ib3R0b206MjRweH1kZm4sY2l0ZSxlbSxpe2ZvbnQtc3R5bGU6aXRhbGljfWJsb2NrcXVvdGV7Y29sb3I6IzZCN0E5MDtmb250LXN0eWxlOml0YWxpYzttYXJnaW4tdG9wOjI0cHg7bWFyZ2luLWJvdHRvbToyNHB4O21hcmdpbi1sZWZ0OjI0cHh9YmxvY2txdW90ZTo6YmVmb3Jle2NvbnRlbnQ6XCJcXDIwMUNcIn1ibG9ja3F1b3RlOjphZnRlcntjb250ZW50OlwiXFwyMDFEXCJ9YmxvY2txdW90ZSBwe2Rpc3BsYXk6aW5saW5lfWFkZHJlc3N7Y29sb3I6IzZCN0E5MDtib3JkZXItd2lkdGg6MXB4IDA7Ym9yZGVyLXN0eWxlOnNvbGlkO2JvcmRlci1jb2xvcjojRTRFOEVFO3BhZGRpbmc6MjRweCAwO21hcmdpbjowIDAgMjRweH1wcmUscHJlIGgxLHByZSBoMixwcmUgaDMscHJlIGg0LHByZSBoNSxwcmUgaDYscHJlIC5oMSxwcmUgLmgyLHByZSAuaDMscHJlIC5oNCxwcmUgLmg1LHByZSAuaDZ7Zm9udC1mYW1pbHk6XCJDb3VyaWVyIDEwIFBpdGNoXCIsIENvdXJpZXIsIG1vbm9zcGFjZX1wcmUsY29kZSxrYmQsdHQsdmFye2JhY2tncm91bmQ6I0YzRjRGRn1wcmV7Zm9udC1zaXplOjE2cHg7bGluZS1oZWlnaHQ6MjRweDttYXJnaW4tYm90dG9tOjEuNmVtO21heC13aWR0aDoxMDAlO292ZXJmbG93OmF1dG87cGFkZGluZzoyNHB4O21hcmdpbi10b3A6MjRweDttYXJnaW4tYm90dG9tOjI0cHh9Y29kZSxrYmQsdHQsdmFye2ZvbnQtZmFtaWx5Ok1vbmFjbywgQ29uc29sYXMsIFwiQW5kYWxlIE1vbm9cIiwgXCJEZWphVnUgU2FucyBNb25vXCIsIG1vbm9zcGFjZTtmb250LXNpemU6MTZweDtwYWRkaW5nOjJweCA0cHh9YWJicixhY3Jvbnlte2N1cnNvcjpoZWxwfW1hcmssaW5ze3RleHQtZGVjb3JhdGlvbjpub25lfXNtYWxse2ZvbnQtc2l6ZToxOHB4O2xpbmUtaGVpZ2h0OjI3cHg7bGV0dGVyLXNwYWNpbmc6LTAuMXB4fWIsc3Ryb25ne2ZvbnQtd2VpZ2h0OjYwMH1idXR0b24saW5wdXQsc2VsZWN0LHRleHRhcmVhLGxhYmVse2ZvbnQtc2l6ZToyMHB4O2xpbmUtaGVpZ2h0OjMwcHh9LmNvbnRhaW5lciwuY29udGFpbmVyLXNte3dpZHRoOjEwMCU7bWFyZ2luOjAgYXV0bztwYWRkaW5nLWxlZnQ6MTZweDtwYWRkaW5nLXJpZ2h0OjE2cHh9QG1lZGlhIChtaW4td2lkdGg6IDQ4MXB4KXsuY29udGFpbmVyLC5jb250YWluZXItc217cGFkZGluZy1sZWZ0OjI0cHg7cGFkZGluZy1yaWdodDoyNHB4fX0uY29udGFpbmVye21heC13aWR0aDoxMTI4cHh9LmNvbnRhaW5lci1zbXttYXgtd2lkdGg6ODQ4cHh9LmNvbnRhaW5lciAuY29udGFpbmVyLXNte21heC13aWR0aDo4MDBweDtwYWRkaW5nLWxlZnQ6MDtwYWRkaW5nLXJpZ2h0OjB9LnNjcmVlbi1yZWFkZXItdGV4dHtjbGlwOnJlY3QoMXB4LCAxcHgsIDFweCwgMXB4KTtwb3NpdGlvbjphYnNvbHV0ZSAhaW1wb3J0YW50O2hlaWdodDoxcHg7d2lkdGg6MXB4O292ZXJmbG93OmhpZGRlbjt3b3JkLXdyYXA6bm9ybWFsICFpbXBvcnRhbnR9LnNjcmVlbi1yZWFkZXItdGV4dDpmb2N1c3tib3JkZXItcmFkaXVzOjJweDtib3gtc2hhZG93OjAgMCAycHggMnB4IHJnYmEoMCwwLDAsMC42KTtjbGlwOmF1dG8gIWltcG9ydGFudDtkaXNwbGF5OmJsb2NrO2ZvbnQtc2l6ZToxNHB4O2xldHRlci1zcGFjaW5nOjBweDtmb250LXdlaWdodDo2MDA7bGluZS1oZWlnaHQ6MTZweDt0ZXh0LWRlY29yYXRpb246bm9uZTt0ZXh0LXRyYW5zZm9ybTp1cHBlcmNhc2U7YmFja2dyb3VuZC1jb2xvcjojZmZmO2NvbG9yOiM0MjM0RjggIWltcG9ydGFudDtib3JkZXI6bm9uZTtoZWlnaHQ6YXV0bztsZWZ0OjhweDtwYWRkaW5nOjE2cHggNDBweDt0b3A6OHB4O3dpZHRoOmF1dG87ei1pbmRleDoxMDAwMDB9Lmxpc3QtcmVzZXR7bGlzdC1zdHlsZTpub25lO3BhZGRpbmc6MH0udGV4dC1sZWZ0e3RleHQtYWxpZ246bGVmdH0udGV4dC1jZW50ZXJ7dGV4dC1hbGlnbjpjZW50ZXJ9LnRleHQtcmlnaHR7dGV4dC1hbGlnbjpyaWdodH0udGV4dC1wcmltYXJ5e2NvbG9yOiM0MjM0Rjh9LnRleHQtc2Vjb25kYXJ5e2NvbG9yOiNGRjZDNTB9Lmhhcy10b3AtZGl2aWRlcntwb3NpdGlvbjpyZWxhdGl2ZX0uaGFzLXRvcC1kaXZpZGVyOjpiZWZvcmV7Y29udGVudDonJztwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtsZWZ0OjA7d2lkdGg6MTAwJTtkaXNwbGF5OmJsb2NrO2hlaWdodDoxcHg7YmFja2dyb3VuZDojRTRFOEVFfS5oYXMtYm90dG9tLWRpdmlkZXJ7cG9zaXRpb246cmVsYXRpdmV9Lmhhcy1ib3R0b20tZGl2aWRlcjo6YWZ0ZXJ7Y29udGVudDonJztwb3NpdGlvbjphYnNvbHV0ZTtib3R0b206MDtsZWZ0OjA7d2lkdGg6MTAwJTtkaXNwbGF5OmJsb2NrO2hlaWdodDoxcHg7YmFja2dyb3VuZDojRTRFOEVFfS5tLTB7bWFyZ2luOjB9Lm10LTB7bWFyZ2luLXRvcDowfS5tci0we21hcmdpbi1yaWdodDowfS5tYi0we21hcmdpbi1ib3R0b206MH0ubWwtMHttYXJnaW4tbGVmdDowfS5tLTh7bWFyZ2luOjhweH0ubXQtOHttYXJnaW4tdG9wOjhweH0ubXItOHttYXJnaW4tcmlnaHQ6OHB4fS5tYi04e21hcmdpbi1ib3R0b206OHB4fS5tbC04e21hcmdpbi1sZWZ0OjhweH0ubS0xNnttYXJnaW46MTZweH0ubXQtMTZ7bWFyZ2luLXRvcDoxNnB4fS5tci0xNnttYXJnaW4tcmlnaHQ6MTZweH0ubWItMTZ7bWFyZ2luLWJvdHRvbToxNnB4fS5tbC0xNnttYXJnaW4tbGVmdDoxNnB4fS5tLTI0e21hcmdpbjoyNHB4fS5tdC0yNHttYXJnaW4tdG9wOjI0cHh9Lm1yLTI0e21hcmdpbi1yaWdodDoyNHB4fS5tYi0yNHttYXJnaW4tYm90dG9tOjI0cHh9Lm1sLTI0e21hcmdpbi1sZWZ0OjI0cHh9Lm0tMzJ7bWFyZ2luOjMycHh9Lm10LTMye21hcmdpbi10b3A6MzJweH0ubXItMzJ7bWFyZ2luLXJpZ2h0OjMycHh9Lm1iLTMye21hcmdpbi1ib3R0b206MzJweH0ubWwtMzJ7bWFyZ2luLWxlZnQ6MzJweH0ubS00MHttYXJnaW46NDBweH0ubXQtNDB7bWFyZ2luLXRvcDo0MHB4fS5tci00MHttYXJnaW4tcmlnaHQ6NDBweH0ubWItNDB7bWFyZ2luLWJvdHRvbTo0MHB4fS5tbC00MHttYXJnaW4tbGVmdDo0MHB4fS5tLTQ4e21hcmdpbjo0OHB4fS5tdC00OHttYXJnaW4tdG9wOjQ4cHh9Lm1yLTQ4e21hcmdpbi1yaWdodDo0OHB4fS5tYi00OHttYXJnaW4tYm90dG9tOjQ4cHh9Lm1sLTQ4e21hcmdpbi1sZWZ0OjQ4cHh9Lm0tNTZ7bWFyZ2luOjU2cHh9Lm10LTU2e21hcmdpbi10b3A6NTZweH0ubXItNTZ7bWFyZ2luLXJpZ2h0OjU2cHh9Lm1iLTU2e21hcmdpbi1ib3R0b206NTZweH0ubWwtNTZ7bWFyZ2luLWxlZnQ6NTZweH0ubS02NHttYXJnaW46NjRweH0ubXQtNjR7bWFyZ2luLXRvcDo2NHB4fS5tci02NHttYXJnaW4tcmlnaHQ6NjRweH0ubWItNjR7bWFyZ2luLWJvdHRvbTo2NHB4fS5tbC02NHttYXJnaW4tbGVmdDo2NHB4fS5wLTB7cGFkZGluZzowfS5wdC0we3BhZGRpbmctdG9wOjB9LnByLTB7cGFkZGluZy1yaWdodDowfS5wYi0we3BhZGRpbmctYm90dG9tOjB9LnBsLTB7cGFkZGluZy1sZWZ0OjB9LnAtOHtwYWRkaW5nOjhweH0ucHQtOHtwYWRkaW5nLXRvcDo4cHh9LnByLTh7cGFkZGluZy1yaWdodDo4cHh9LnBiLTh7cGFkZGluZy1ib3R0b206OHB4fS5wbC04e3BhZGRpbmctbGVmdDo4cHh9LnAtMTZ7cGFkZGluZzoxNnB4fS5wdC0xNntwYWRkaW5nLXRvcDoxNnB4fS5wci0xNntwYWRkaW5nLXJpZ2h0OjE2cHh9LnBiLTE2e3BhZGRpbmctYm90dG9tOjE2cHh9LnBsLTE2e3BhZGRpbmctbGVmdDoxNnB4fS5wLTI0e3BhZGRpbmc6MjRweH0ucHQtMjR7cGFkZGluZy10b3A6MjRweH0ucHItMjR7cGFkZGluZy1yaWdodDoyNHB4fS5wYi0yNHtwYWRkaW5nLWJvdHRvbToyNHB4fS5wbC0yNHtwYWRkaW5nLWxlZnQ6MjRweH0ucC0zMntwYWRkaW5nOjMycHh9LnB0LTMye3BhZGRpbmctdG9wOjMycHh9LnByLTMye3BhZGRpbmctcmlnaHQ6MzJweH0ucGItMzJ7cGFkZGluZy1ib3R0b206MzJweH0ucGwtMzJ7cGFkZGluZy1sZWZ0OjMycHh9LnAtNDB7cGFkZGluZzo0MHB4fS5wdC00MHtwYWRkaW5nLXRvcDo0MHB4fS5wci00MHtwYWRkaW5nLXJpZ2h0OjQwcHh9LnBiLTQwe3BhZGRpbmctYm90dG9tOjQwcHh9LnBsLTQwe3BhZGRpbmctbGVmdDo0MHB4fS5wLTQ4e3BhZGRpbmc6NDhweH0ucHQtNDh7cGFkZGluZy10b3A6NDhweH0ucHItNDh7cGFkZGluZy1yaWdodDo0OHB4fS5wYi00OHtwYWRkaW5nLWJvdHRvbTo0OHB4fS5wbC00OHtwYWRkaW5nLWxlZnQ6NDhweH0ucC01NntwYWRkaW5nOjU2cHh9LnB0LTU2e3BhZGRpbmctdG9wOjU2cHh9LnByLTU2e3BhZGRpbmctcmlnaHQ6NTZweH0ucGItNTZ7cGFkZGluZy1ib3R0b206NTZweH0ucGwtNTZ7cGFkZGluZy1sZWZ0OjU2cHh9LnAtNjR7cGFkZGluZzo2NHB4fS5wdC02NHtwYWRkaW5nLXRvcDo2NHB4fS5wci02NHtwYWRkaW5nLXJpZ2h0OjY0cHh9LnBiLTY0e3BhZGRpbmctYm90dG9tOjY0cHh9LnBsLTY0e3BhZGRpbmctbGVmdDo2NHB4fS5zciAuaGFzLWFuaW1hdGlvbnMgLmlzLXJldmVhbGluZ3t2aXNpYmlsaXR5OmhpZGRlbn0uYnV0dG9ue2Rpc3BsYXk6aW5saW5lLWZsZXg7Zm9udC1zaXplOjE0cHg7bGV0dGVyLXNwYWNpbmc6MHB4O2ZvbnQtd2VpZ2h0OjcwMDtsaW5lLWhlaWdodDoxNnB4O3RleHQtZGVjb3JhdGlvbjpub25lICFpbXBvcnRhbnQ7dGV4dC10cmFuc2Zvcm06dXBwZXJjYXNlO2JhY2tncm91bmQtY29sb3I6I2ZmZjtiYWNrZ3JvdW5kOiNmZmY7Y29sb3I6IzQyMzRGOCAhaW1wb3J0YW50O2JvcmRlcjpub25lO2JvcmRlci1yYWRpdXM6MnB4O2N1cnNvcjpwb2ludGVyO2p1c3RpZnktY29udGVudDpjZW50ZXI7cGFkZGluZzoxNnB4IDQwcHg7aGVpZ2h0OjQ4cHg7dGV4dC1hbGlnbjpjZW50ZXI7d2hpdGUtc3BhY2U6bm93cmFwfS5idXR0b246YWN0aXZle291dGxpbmU6MH0uYnV0dG9uOjpiZWZvcmV7Ym9yZGVyLXJhZGl1czoycHh9LmJ1dHRvbi1zaGFkb3d7cG9zaXRpb246cmVsYXRpdmV9LmJ1dHRvbi1zaGFkb3c6OmJlZm9yZXtjb250ZW50OicnO3Bvc2l0aW9uOmFic29sdXRlO3RvcDowO3JpZ2h0OjA7Ym90dG9tOjA7bGVmdDowO2JveC1zaGFkb3c6MCA4cHggMTZweCByZ2JhKDIyLDMwLDQyLDAuMTIpO21peC1ibGVuZC1tb2RlOm11bHRpcGx5O3RyYW5zaXRpb246Ym94LXNoYWRvdyAuMTVzIGVhc2V9LmJ1dHRvbi1zaGFkb3c6aG92ZXI6OmJlZm9yZXtib3gtc2hhZG93OjAgOHB4IDE2cHggcmdiYSgyMiwzMCw0MiwwLjE2KX0uYnV0dG9uLXNte3BhZGRpbmc6OHB4IDI0cHg7aGVpZ2h0OjMycHh9LmJ1dHRvbi1zbS5idXR0b24tc2hhZG93OjpiZWZvcmV7Ym94LXNoYWRvdzowIDRweCAxNnB4IHJnYmEoMjIsMzAsNDIsMC4xMil9LmJ1dHRvbi1zbS5idXR0b24tc2hhZG93OmhvdmVyOjpiZWZvcmV7Ym94LXNoYWRvdzowIDRweCAxNnB4IHJnYmEoMjIsMzAsNDIsMC4xNil9LmJ1dHRvbi1wcmltYXJ5LC5idXR0b24tc2Vjb25kYXJ5e2NvbG9yOiNmZmYgIWltcG9ydGFudDt0cmFuc2l0aW9uOmJhY2tncm91bmQgLjE1cyBlYXNlfS5idXR0b24tcHJpbWFyeXtiYWNrZ3JvdW5kOiM0MjM0Rjh9LmJ1dHRvbi1wcmltYXJ5OmhvdmVye2JhY2tncm91bmQ6IzRiM2VmOH0uYnV0dG9uLXByaW1hcnkuYnV0dG9uLXNoYWRvdzo6YmVmb3Jle2JveC1zaGFkb3c6MCA4cHggMTZweCByZ2JhKDY2LDUyLDI0OCwwLjI0KX0uYnV0dG9uLXByaW1hcnkuYnV0dG9uLXNoYWRvdzpob3Zlcjo6YmVmb3Jle2JveC1zaGFkb3c6MCA4cHggMTZweCByZ2JhKDY2LDUyLDI0OCwwLjMyKX0uYnV0dG9uLXByaW1hcnkgLmJ1dHRvbi1zbS5idXR0b24tc2hhZG93OjpiZWZvcmV7Ym94LXNoYWRvdzowIDRweCAxNnB4IHJnYmEoNjYsNTIsMjQ4LDAuMjQpfS5idXR0b24tcHJpbWFyeSAuYnV0dG9uLXNtLmJ1dHRvbi1zaGFkb3c6aG92ZXI6OmJlZm9yZXtib3gtc2hhZG93OjAgNHB4IDE2cHggcmdiYSg2Niw1MiwyNDgsMC4zMil9LmJ1dHRvbi1zZWNvbmRhcnl7YmFja2dyb3VuZDojRkY2QzUwfS5idXR0b24tc2Vjb25kYXJ5OmhvdmVye2JhY2tncm91bmQ6I2ZmNzk1Zn0uYnV0dG9uLXNlY29uZGFyeS5idXR0b24tc2hhZG93OjpiZWZvcmV7Ym94LXNoYWRvdzowIDhweCAxNnB4IHJnYmEoMjU1LDEwOCw4MCwwLjI0KX0uYnV0dG9uLXNlY29uZGFyeS5idXR0b24tc2hhZG93OmhvdmVyOjpiZWZvcmV7Ym94LXNoYWRvdzowIDhweCAxNnB4IHJnYmEoMjU1LDEwOCw4MCwwLjMyKX0uYnV0dG9uLXNlY29uZGFyeSAuYnV0dG9uLXNtLmJ1dHRvbi1zaGFkb3c6OmJlZm9yZXtib3gtc2hhZG93OjAgNHB4IDE2cHggcmdiYSgyNTUsMTA4LDgwLDAuMjQpfS5idXR0b24tc2Vjb25kYXJ5IC5idXR0b24tc20uYnV0dG9uLXNoYWRvdzpob3Zlcjo6YmVmb3Jle2JveC1zaGFkb3c6MCA0cHggMTZweCByZ2JhKDI1NSwxMDgsODAsMC4zMil9LmJ1dHRvbi1ibG9ja3tkaXNwbGF5OmZsZXg7d2lkdGg6MTAwJX1AbWVkaWEgKG1heC13aWR0aDogNjQwcHgpey5idXR0b24td2lkZS1tb2JpbGV7d2lkdGg6MTAwJTttYXgtd2lkdGg6MjgwcHh9fS5zaXRlLWhlYWRlcntwYWRkaW5nOjI0cHggMDtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtsZWZ0OjA7d2lkdGg6MTAwJTt6LWluZGV4OjF9LnNpdGUtaGVhZGVyLWlubmVye3Bvc2l0aW9uOnJlbGF0aXZlO2Rpc3BsYXk6ZmxleDtqdXN0aWZ5LWNvbnRlbnQ6c3BhY2UtYmV0d2VlbjthbGlnbi1pdGVtczpjZW50ZXJ9LmhlYWRlci1saW5rc3tkaXNwbGF5OmlubGluZS1mbGV4fS5oZWFkZXItbGlua3MgbGl7ZGlzcGxheTppbmxpbmUtZmxleH0uaGVhZGVyLWxpbmtzIGE6bm90KC5idXR0b24pe2ZvbnQtc2l6ZToxNnB4O2xpbmUtaGVpZ2h0OjI0cHg7bGV0dGVyLXNwYWNpbmc6LTAuMXB4O2ZvbnQtd2VpZ2h0OjYwMDtjb2xvcjojNjA2NDgzO3RleHQtdHJhbnNmb3JtOnVwcGVyY2FzZTt0ZXh0LWRlY29yYXRpb246bm9uZTtsaW5lLWhlaWdodDoxNnB4O3BhZGRpbmc6OHB4IDI0cHh9LmhlYWRlci1saW5rcyBhOm5vdCguYnV0dG9uKTpob3ZlciwuaGVhZGVyLWxpbmtzIGE6bm90KC5idXR0b24pOmFjdGl2ZXtjb2xvcjojZmZmfS5oZXJve3Bvc2l0aW9uOnJlbGF0aXZlO3BhZGRpbmctdG9wOjEyOHB4O3BhZGRpbmctYm90dG9tOjg4cHg7ei1pbmRleDowfS5oZXJvIC5oZXJvLWJne3Bvc2l0aW9uOmFic29sdXRlO3RvcDowO2JvdHRvbTo0MiU7bGVmdDowO3JpZ2h0OjA7YmFja2dyb3VuZDojMEIwRDE5O3otaW5kZXg6LTJ9Lmhlcm8gLmhlcm8tcGFydGljbGVzLWNvbnRhaW5lcntwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3R0b206NDIlO2xlZnQ6MDtyaWdodDowfS5oZXJvOjpiZWZvcmUsLmhlcm86OmFmdGVye2NvbnRlbnQ6Jyc7cG9zaXRpb246YWJzb2x1dGU7bGVmdDpjYWxjKDUwJSAtIDM2MHB4KTt3aWR0aDo3MjBweDtiYWNrZ3JvdW5kLXJlcGVhdDpuby1yZXBlYXR9Lmhlcm86OmJlZm9yZXt0b3A6MDtoZWlnaHQ6MTU5cHg7YmFja2dyb3VuZC1pbWFnZTp1cmwoXCIuLi9pbWFnZXMvaGVyby1iZy10b3Auc3ZnXCIpO2JhY2tncm91bmQtc2l6ZTo3MjBweCAxNTlweH0uaGVybzo6YWZ0ZXJ7Ym90dG9tOjQyJTtoZWlnaHQ6MTczcHg7YmFja2dyb3VuZC1pbWFnZTp1cmwoXCIuLi9pbWFnZXMvaGVyby1iZy1ib3R0b20uc3ZnXCIpO2JhY2tncm91bmQtc2l6ZTo3MjBweCAxNzNweH0uaGVyby1pbm5lcntwb3NpdGlvbjpyZWxhdGl2ZTt6LWluZGV4OjF9Lmhlcm8tY29weXtwb3NpdGlvbjpyZWxhdGl2ZTttYXJnaW4tYm90dG9tOjQ4cHh9QG1lZGlhIChtaW4td2lkdGg6IDY0MXB4KXsuaGVyb3twYWRkaW5nLXRvcDoxNjBweDtwYWRkaW5nLWJvdHRvbToxMjhweH0uaGVybzo6YmVmb3JlLC5oZXJvOjphZnRlcntsZWZ0OmNhbGMoNTAlIC0gNzIwcHgpO3dpZHRoOjE0NDBweH0uaGVybzo6YmVmb3Jle2hlaWdodDozMThweDtiYWNrZ3JvdW5kLXNpemU6MTQ0MHB4IDMxOHB4fS5oZXJvOjphZnRlcntoZWlnaHQ6MzQ3cHg7YmFja2dyb3VuZC1zaXplOjE0NDBweCAzNDdweH0uaGVyby1jb3B5e21hcmdpbi1ib3R0b206ODhweH0uaGVyby1wYXJhZ3JhcGh7cGFkZGluZy1sZWZ0OjcycHg7cGFkZGluZy1yaWdodDo3MnB4fX0uaGFzLWFuaW1hdGlvbnMgLmhlcm8gLmhlcm8tYmcsLmhhcy1hbmltYXRpb25zIC5oZXJvOjpiZWZvcmUsLmhhcy1hbmltYXRpb25zIC5oZXJvOjphZnRlciwuaGFzLWFuaW1hdGlvbnMgLmhlcm8tcGFydGljbGVzLWNvbnRhaW5lciwuaGFzLWFuaW1hdGlvbnMgLnNpdGUtaGVhZGVyLC5oYXMtYW5pbWF0aW9ucyAuaGVyby10aXRsZSwuaGFzLWFuaW1hdGlvbnMgLmhlcm8tcGFyYWdyYXBoLC5oYXMtYW5pbWF0aW9ucyAuaGVyby1jdGEsLmhhcy1hbmltYXRpb25zIC5oZXJvIC5tb2NrdXAtYmcsLmhhcy1hbmltYXRpb25zIC5oZXJvIC5kZXZpY2UtbW9ja3Vwe29wYWNpdHk6MH0uaGFzLWFuaW1hdGlvbnMuaXMtbG9hZGVkIC5oZXJvIC5oZXJvLWJne2FuaW1hdGlvbjpoZXJvQmcgMC42cyBjdWJpYy1iZXppZXIoMC4yMTUsIDAuNjEsIDAuMzU1LCAxKSBmb3J3YXJkc30uaGFzLWFuaW1hdGlvbnMuaXMtbG9hZGVkIC5oZXJvOjpiZWZvcmUsLmhhcy1hbmltYXRpb25zLmlzLWxvYWRlZCAuaGVybzo6YWZ0ZXJ7YW5pbWF0aW9uOmhlcm9GYWRlSW4gLjZzIGVhc2UgZm9yd2FyZHMgLjQ1c30uaGFzLWFuaW1hdGlvbnMuaXMtbG9hZGVkIC5zaXRlLWhlYWRlciwuaGFzLWFuaW1hdGlvbnMuaXMtbG9hZGVkIC5oZXJvLXBhcnRpY2xlcy1jb250YWluZXIsLmhhcy1hbmltYXRpb25zLmlzLWxvYWRlZCAuaGVybyAubW9ja3VwLWJne2FuaW1hdGlvbjpoZXJvRmFkZUluIC42cyBlYXNlIGZvcndhcmRzIC40NXN9Lmhhcy1hbmltYXRpb25zLmlzLWxvYWRlZCAuaGVyby10aXRsZXthbmltYXRpb246aGVyb0NvbnRlbnQgMC42cyBjdWJpYy1iZXppZXIoMC4yMTUsIDAuNjEsIDAuMzU1LCAxKSBmb3J3YXJkcyAwLjE1c30uaGFzLWFuaW1hdGlvbnMuaXMtbG9hZGVkIC5oZXJvLXBhcmFncmFwaHthbmltYXRpb246aGVyb0NvbnRlbnQgMC42cyBjdWJpYy1iZXppZXIoMC4yMTUsIDAuNjEsIDAuMzU1LCAxKSBmb3J3YXJkcyAwLjNzfS5oYXMtYW5pbWF0aW9ucy5pcy1sb2FkZWQgLmhlcm8tY3Rhe2FuaW1hdGlvbjpoZXJvQ29udGVudCAwLjZzIGN1YmljLWJlemllcigwLjIxNSwgMC42MSwgMC4zNTUsIDEpIGZvcndhcmRzIDAuNDVzfS5oYXMtYW5pbWF0aW9ucy5pcy1sb2FkZWQgLmhlcm8gLmRldmljZS1tb2NrdXB7YW5pbWF0aW9uOmhlcm9Nb2NrdXAgLjZzIGVhc2UgZm9yd2FyZHMgLjZzfUBrZXlmcmFtZXMgaGVyb0Jne2Zyb217dHJhbnNmb3JtOnNjYWxlWSgwKSBzY2FsZVgoMS4yKSBza2V3WSgzMGRlZyk7b3BhY2l0eToxfXRve3RyYW5zZm9ybTpzY2FsZVkoMSkgc2NhbGVYKDEpIHNrZXdZKDApO29wYWNpdHk6MX19QGtleWZyYW1lcyBoZXJvQ29udGVudHtmcm9te3RyYW5zZm9ybTp0cmFuc2xhdGVZKDQwcHgpIHNrZXdZKDJkZWcpO29wYWNpdHk6MH10b3t0cmFuc2Zvcm06dHJhbnNsYXRlWSgwKSBza2V3WSgwKTtvcGFjaXR5OjF9fUBrZXlmcmFtZXMgaGVyb01vY2t1cHtmcm9te3RyYW5zZm9ybTp0cmFuc2xhdGVZKDgwcHgpO29wYWNpdHk6MH10b3t0cmFuc2Zvcm06dHJhbnNsYXRlWSgwKTtvcGFjaXR5OjF9fUBrZXlmcmFtZXMgaGVyb0ZhZGVJbntmcm9te29wYWNpdHk6MH10b3tvcGFjaXR5OjF9fS5tb2NrdXAtY29udGFpbmVye3Bvc2l0aW9uOnJlbGF0aXZlfS5tb2NrdXAtYmd7cG9pbnRlci1ldmVudHM6bm9uZX0ubW9ja3VwLWJnIGltZywubW9ja3VwLWJnIHN2Z3twb3NpdGlvbjphYnNvbHV0ZTt0b3A6NTAlO2xlZnQ6NTAlO3RyYW5zZm9ybTp0cmFuc2xhdGUoLTUwJSwgLTUwJSk7d2lkdGg6YXV0byAhaW1wb3J0YW50O2hlaWdodDphdXRvO21heC13aWR0aDozMDAlICFpbXBvcnRhbnR9LmRldmljZS1tb2NrdXB7cG9zaXRpb246cmVsYXRpdmU7d2lkdGg6MzUwcHg7aGVpZ2h0OmF1dG87bWFyZ2luOjAgYXV0bzt6LWluZGV4OjF9Lmhhcy1hbmltYXRpb25zIC5mZWF0dXJlcy1leHRlbmRlZHtvcGFjaXR5OjB9Lmhhcy1hbmltYXRpb25zLmlzLWxvYWRlZCAuZmVhdHVyZXMtZXh0ZW5kZWR7b3BhY2l0eToxfS5mZWF0dXJlcy1leHRlbmRlZC1oZWFkZXJ7bWFyZ2luLWJvdHRvbTozMnB4fS5mZWF0dXJlcy1leHRlbmRlZC13cmFwe2Rpc3BsYXk6ZmxleDtmbGV4LXdyYXA6d3JhcDttYXJnaW4tdG9wOi0yNHB4fS5mZWF0dXJlcy1leHRlbmRlZC13cmFwOmxhc3Qtb2YtdHlwZXttYXJnaW4tYm90dG9tOi0yNHB4fS5mZWF0dXJlcy1leHRlbmRlZC13cmFwOm5vdCg6bGFzdC1vZi10eXBlKXttYXJnaW4tYm90dG9tOjI0cHh9LmZlYXR1cmUtZXh0ZW5kZWR7cGFkZGluZzoyNHB4IDB9LmZlYXR1cmUtZXh0ZW5kZWQtaW1hZ2V7cG9zaXRpb246cmVsYXRpdmU7bWFyZ2luLWJvdHRvbTozMnB4fS5mZWF0dXJlLWV4dGVuZGVkLWltYWdlIGltZywuZmVhdHVyZS1leHRlbmRlZC1pbWFnZSBzdmd7d2lkdGg6MTAwJTttYXgtd2lkdGg6Mjk2cHg7aGVpZ2h0OmF1dG87bWFyZ2luLWxlZnQ6YXV0bzttYXJnaW4tcmlnaHQ6YXV0bztvdmVyZmxvdzp2aXNpYmxlfS5mZWF0dXJlLWV4dGVuZGVkLWJvZHl7dGV4dC1hbGlnbjpjZW50ZXJ9QG1lZGlhIChtaW4td2lkdGg6IDY0MXB4KXsuZmVhdHVyZXMtZXh0ZW5kZWQgLmNvbnRhaW5lcnttYXgtd2lkdGg6OTEycHh9LmZlYXR1cmVzLWV4dGVuZGVkIC5zZWN0aW9uLWlubmVye3BhZGRpbmctYm90dG9tOjEyOHB4fS5mZWF0dXJlcy1leHRlbmRlZCAuc2VjdGlvbi1wYXJhZ3JhcGh7cGFkZGluZy1sZWZ0OjcycHg7cGFkZGluZy1yaWdodDo3MnB4O21hcmdpbi1ib3R0b206MH0uZmVhdHVyZXMtZXh0ZW5kZWQtaGVhZGVye21hcmdpbi1ib3R0b206ODBweH0uZmVhdHVyZXMtZXh0ZW5kZWQtd3JhcHttYXJnaW4tdG9wOi02NHB4fS5mZWF0dXJlcy1leHRlbmRlZC13cmFwOmxhc3Qtb2YtdHlwZXttYXJnaW4tYm90dG9tOi02NHB4fS5mZWF0dXJlcy1leHRlbmRlZC13cmFwOm5vdCg6bGFzdC1vZi10eXBlKXttYXJnaW4tYm90dG9tOjY0cHh9LmZlYXR1cmUtZXh0ZW5kZWR7ZGlzcGxheTpmbGV4O2ZsZXgtd3JhcDpub3dyYXA7YWxpZ24taXRlbXM6c3RyZXRjaDtqdXN0aWZ5LWNvbnRlbnQ6ZmxleC1lbmQ7cGFkZGluZzo2NHB4IDB9LmZlYXR1cmUtZXh0ZW5kZWQgLmZlYXR1cmUtZXh0ZW5kZWQtaW1hZ2V7d2lkdGg6NDQwcHg7bWFyZ2luLXJpZ2h0Ojk2cHg7bWFyZ2luLWJvdHRvbTowfS5mZWF0dXJlLWV4dGVuZGVkIC5mZWF0dXJlLWV4dGVuZGVkLWltYWdlIGltZywuZmVhdHVyZS1leHRlbmRlZCAuZmVhdHVyZS1leHRlbmRlZC1pbWFnZSBzdmd7d2lkdGg6YXV0b30uZmVhdHVyZS1leHRlbmRlZCAuZmVhdHVyZS1leHRlbmRlZC1pbWFnZSBpbWcuZGV2aWNlLW1vY2t1cCwuZmVhdHVyZS1leHRlbmRlZCAuZmVhdHVyZS1leHRlbmRlZC1pbWFnZSBzdmcuZGV2aWNlLW1vY2t1cHttYXgtd2lkdGg6Mjk2cHh9LmZlYXR1cmUtZXh0ZW5kZWQ6bnRoLWNoaWxkKGV2ZW4pe2p1c3RpZnktY29udGVudDpmbGV4LXN0YXJ0fS5mZWF0dXJlLWV4dGVuZGVkOm50aC1jaGlsZChldmVuKSAuZmVhdHVyZS1leHRlbmRlZC1pbWFnZXtvcmRlcjoxO21hcmdpbi1sZWZ0Ojk2cHg7bWFyZ2luLXJpZ2h0OjB9LmZlYXR1cmUtZXh0ZW5kZWQtYm9keXtkaXNwbGF5OmZsZXg7ZmxleC1kaXJlY3Rpb246Y29sdW1uO2p1c3RpZnktY29udGVudDpjZW50ZXI7ZmxleC1zaHJpbms6MDt3aWR0aDozNjBweDt0ZXh0LWFsaWduOmxlZnR9fUBtZWRpYSAobWluLXdpZHRoOiAxMDI1cHgpey5mZWF0dXJlcy1leHRlbmRlZCAuY29udGFpbmVye21heC13aWR0aDo5NDRweH0uZmVhdHVyZS1leHRlbmRlZCAuZmVhdHVyZS1leHRlbmRlZC1pbWFnZXttYXJnaW4tcmlnaHQ6NjRweH0uZmVhdHVyZS1leHRlbmRlZDpudGgtY2hpbGQoZXZlbikgLmZlYXR1cmUtZXh0ZW5kZWQtaW1hZ2V7bWFyZ2luLWxlZnQ6NjRweH0uZmVhdHVyZS1leHRlbmRlZC1ib2R5e3dpZHRoOjM5MnB4fX0uY3RhIC5zZWN0aW9uLXBhcmFncmFwaHttYXJnaW4tYm90dG9tOjMycHh9QG1lZGlhIChtaW4td2lkdGg6IDY0MXB4KXsuY3RhIC5zZWN0aW9uLXBhcmFncmFwaHttYXJnaW4tYm90dG9tOjMycHg7cGFkZGluZy1sZWZ0OjcycHg7cGFkZGluZy1yaWdodDo3MnB4fX0uaXMtYm94ZWR7YmFja2dyb3VuZDojZmZmfS5ib2R5LXdyYXB7YmFja2dyb3VuZDojZmZmO292ZXJmbG93OmhpZGRlbjtkaXNwbGF5OmZsZXg7ZmxleC1kaXJlY3Rpb246Y29sdW1uO21pbi1oZWlnaHQ6MTAwdmh9LmJveGVkLWNvbnRhaW5lcnttYXgtd2lkdGg6MTQ0MHB4O21hcmdpbjowIGF1dG87Ym94LXNoYWRvdzowIDIwcHggNDhweCByZ2JhKDIyLDMwLDQyLDAuMTYpfW1haW57ZmxleDoxIDAgYXV0b30uc2VjdGlvbi1pbm5lcntwb3NpdGlvbjpyZWxhdGl2ZTtwYWRkaW5nLXRvcDo0OHB4O3BhZGRpbmctYm90dG9tOjQ4cHh9QG1lZGlhIChtaW4td2lkdGg6IDY0MXB4KXsuc2VjdGlvbi1pbm5lcntwYWRkaW5nLXRvcDo4OHB4O3BhZGRpbmctYm90dG9tOjg4cHh9fS5zaXRlLWZvb3Rlcntwb3NpdGlvbjpyZWxhdGl2ZTtiYWNrZ3JvdW5kOiMwQjBEMTl9LnNpdGUtZm9vdGVyOjpiZWZvcmV7Y29udGVudDonJztwb3NpdGlvbjphYnNvbHV0ZTt0b3A6LTc2cHg7bGVmdDpjYWxjKDUwJSAtIDM2MHB4KTt3aWR0aDo3MjBweDtoZWlnaHQ6MjkxcHg7YmFja2dyb3VuZC1pbWFnZTp1cmwoXCIuLi9pbWFnZXMvZm9vdGVyLWJnLnN2Z1wiKTtiYWNrZ3JvdW5kLXNpemU6NzIwcHggMjkxcHg7YmFja2dyb3VuZC1yZXBlYXQ6bm8tcmVwZWF0fS5zaXRlLWZvb3RlciAuZm9vdGVyLXBhcnRpY2xlcy1jb250YWluZXJ7cG9zaXRpb246YWJzb2x1dGU7dG9wOjA7Ym90dG9tOjA7bGVmdDowO3JpZ2h0OjB9LnNpdGUtZm9vdGVyLWJvdHRvbXtmb250LXNpemU6MTRweDtsaW5lLWhlaWdodDoyMnB4O2xldHRlci1zcGFjaW5nOjBweDt6LWluZGV4OjF9LnNpdGUtZm9vdGVyLWJvdHRvbSBhe2NvbG9yOiM2MDY0ODM7dGV4dC1kZWNvcmF0aW9uOm5vbmV9LnNpdGUtZm9vdGVyLWJvdHRvbSBhOmhvdmVyLC5zaXRlLWZvb3Rlci1ib3R0b20gYTphY3RpdmV7dGV4dC1kZWNvcmF0aW9uOnVuZGVybGluZX0uc2l0ZS1mb290ZXItaW5uZXJ7cG9zaXRpb246cmVsYXRpdmU7ZGlzcGxheTpmbGV4O2ZsZXgtd3JhcDp3cmFwO3BhZGRpbmctdG9wOjQ4cHg7cGFkZGluZy1ib3R0b206NDhweDtwb3NpdGlvbjpyZWxhdGl2ZX0uc2l0ZS1mb290ZXItaW5uZXI6OmJlZm9yZXtjb250ZW50OicnO3Bvc2l0aW9uOmFic29sdXRlO3RvcDowO2xlZnQ6MDt3aWR0aDoxMDAlO2Rpc3BsYXk6YmxvY2s7aGVpZ2h0OjFweDtiYWNrZ3JvdW5kOiMxRTIzM0R9LmZvb3Rlci1icmFuZCwuZm9vdGVyLWxpbmtzLC5mb290ZXItc29jaWFsLWxpbmtzLC5mb290ZXItY29weXJpZ2h0e2ZsZXg6bm9uZTt3aWR0aDoxMDAlO2Rpc3BsYXk6aW5saW5lLWZsZXg7anVzdGlmeS1jb250ZW50OmNlbnRlcn0uZm9vdGVyLWJyYW5kLC5mb290ZXItbGlua3MsLmZvb3Rlci1zb2NpYWwtbGlua3N7bWFyZ2luLWJvdHRvbToyNHB4fS5mb290ZXItbGlua3MgbGkrbGksLmZvb3Rlci1zb2NpYWwtbGlua3MgbGkrbGl7bWFyZ2luLWxlZnQ6MTZweH0uZm9vdGVyLXNvY2lhbC1saW5rcyBsaXtkaXNwbGF5OmlubGluZS1mbGV4fS5mb290ZXItc29jaWFsLWxpbmtzIGxpIGF7cGFkZGluZzo4cHh9QG1lZGlhIChtaW4td2lkdGg6IDY0MXB4KXsuc2l0ZS1mb290ZXI6OmJlZm9yZXt0b3A6LTE1MnB4O2xlZnQ6Y2FsYyg1MCUgLSA3MjBweCk7d2lkdGg6MTQ0MHB4O2hlaWdodDo1ODJweDtiYWNrZ3JvdW5kLXNpemU6MTQ0MHB4IDU4MnB4fS5zaXRlLWZvb3Rlci1pbm5lcntqdXN0aWZ5LWNvbnRlbnQ6c3BhY2UtYmV0d2VlbjtwYWRkaW5nLXRvcDo2NHB4O3BhZGRpbmctYm90dG9tOjY0cHh9LmZvb3Rlci1icmFuZCwuZm9vdGVyLWxpbmtzLC5mb290ZXItc29jaWFsLWxpbmtzLC5mb290ZXItY29weXJpZ2h0e2ZsZXg6NTAlfS5mb290ZXItYnJhbmQsLmZvb3Rlci1jb3B5cmlnaHR7anVzdGlmeS1jb250ZW50OmZsZXgtc3RhcnR9LmZvb3Rlci1saW5rcywuZm9vdGVyLXNvY2lhbC1saW5rc3tqdXN0aWZ5LWNvbnRlbnQ6ZmxleC1lbmR9LmZvb3Rlci1saW5rc3tvcmRlcjoxO21hcmdpbi1ib3R0b206MH19XG4iXX0= */ \ No newline at end of file diff --git a/html/dist/images/footer-bg.svg b/html/dist/images/footer-bg.svg new file mode 100644 index 0000000..a875221 --- /dev/null +++ b/html/dist/images/footer-bg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/dist/images/hero-bg-bottom.svg b/html/dist/images/hero-bg-bottom.svg new file mode 100644 index 0000000..7b905e2 --- /dev/null +++ b/html/dist/images/hero-bg-bottom.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/dist/images/hero-bg-top.svg b/html/dist/images/hero-bg-top.svg new file mode 100644 index 0000000..0065311 --- /dev/null +++ b/html/dist/images/hero-bg-top.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/dist/images/iphone-feature-01.png b/html/dist/images/iphone-feature-01.png new file mode 100644 index 0000000..9134209 Binary files /dev/null and b/html/dist/images/iphone-feature-01.png differ diff --git a/html/dist/images/iphone-feature-02.png b/html/dist/images/iphone-feature-02.png new file mode 100644 index 0000000..3869f99 Binary files /dev/null and b/html/dist/images/iphone-feature-02.png differ diff --git a/html/dist/images/iphone-feature-03.png b/html/dist/images/iphone-feature-03.png new file mode 100644 index 0000000..c64d7b2 Binary files /dev/null and b/html/dist/images/iphone-feature-03.png differ diff --git a/html/dist/images/iphone-feature-04.png b/html/dist/images/iphone-feature-04.png new file mode 100644 index 0000000..bb2ad51 Binary files /dev/null and b/html/dist/images/iphone-feature-04.png differ diff --git a/html/dist/images/iphone-feature-bg-01.svg b/html/dist/images/iphone-feature-bg-01.svg new file mode 100644 index 0000000..f074eea --- /dev/null +++ b/html/dist/images/iphone-feature-bg-01.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/dist/images/iphone-feature-bg-02.svg b/html/dist/images/iphone-feature-bg-02.svg new file mode 100644 index 0000000..dfa9441 --- /dev/null +++ b/html/dist/images/iphone-feature-bg-02.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/dist/images/iphone-feature-bg-03.svg b/html/dist/images/iphone-feature-bg-03.svg new file mode 100644 index 0000000..6880c57 --- /dev/null +++ b/html/dist/images/iphone-feature-bg-03.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/dist/images/iphone-feature-bg-04.svg b/html/dist/images/iphone-feature-bg-04.svg new file mode 100644 index 0000000..ebc0000 --- /dev/null +++ b/html/dist/images/iphone-feature-bg-04.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/dist/images/iphone-hero-bg.svg b/html/dist/images/iphone-hero-bg.svg new file mode 100644 index 0000000..a913ebf --- /dev/null +++ b/html/dist/images/iphone-hero-bg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/dist/images/iphone-hero.png b/html/dist/images/iphone-hero.png new file mode 100644 index 0000000..3ee64ca Binary files /dev/null and b/html/dist/images/iphone-hero.png differ diff --git a/html/dist/images/logo.png b/html/dist/images/logo.png new file mode 100644 index 0000000..017e66b Binary files /dev/null and b/html/dist/images/logo.png differ diff --git a/html/dist/images/logo.svg b/html/dist/images/logo.svg new file mode 100644 index 0000000..fe9cd59 --- /dev/null +++ b/html/dist/images/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/dist/images/logo2.png b/html/dist/images/logo2.png new file mode 100644 index 0000000..2eaa360 Binary files /dev/null and b/html/dist/images/logo2.png differ diff --git a/html/dist/js/main.min.js b/html/dist/js/main.min.js new file mode 100644 index 0000000..3cf3176 --- /dev/null +++ b/html/dist/js/main.min.js @@ -0,0 +1 @@ +!function(){const t=document,e=t.documentElement,i=t.body,n=window.sr=ScrollReveal({mobile:!1});e.classList.remove("no-js"),e.classList.add("js"),window.addEventListener("load",function(){i.classList.add("is-loaded")}),i.classList.contains("has-animations")&&window.addEventListener("load",function(){n.reveal(".feature-extended .device-mockup",{duration:600,distance:"100px",easing:"cubic-bezier(0.215, 0.61, 0.355, 1)",origin:"bottom",viewFactor:.6}),n.reveal(".feature-extended .feature-extended-body",{duration:600,distance:"40px",easing:"cubic-bezier(0.215, 0.61, 0.355, 1)",origin:"top",viewFactor:.6})});let s=function(t){let e=this;e.parentNode=t,e.getCanvasSize(),window.addEventListener("resize",function(){e.getCanvasSize()}),e.mouseX=0,e.mouseY=0,window.addEventListener("mousemove",function(t){e.mouseX=t.clientX,e.mouseY=t.clientY}),e.randomise()};s.prototype.getCanvasSize=function(){this.canvasWidth=this.parentNode.clientWidth,this.canvasHeight=this.parentNode.clientHeight},s.prototype.generateDecimalBetween=function(t,e){return(Math.random()*(t-e)+e).toFixed(2)},s.prototype.update=function(){let t=this;t.translateX=t.translateX-t.movementX,t.translateY=t.translateY-t.movementY,t.posX+=(t.mouseX/(t.staticity/t.magnetism)-t.posX)/t.smoothFactor,t.posY+=(t.mouseY/(t.staticity/t.magnetism)-t.posY)/t.smoothFactor,(t.translateY+t.posY<0||t.translateX+t.posX<0||t.translateX+t.posX>t.canvasWidth)&&(t.randomise(),t.translateY=t.canvasHeight)},s.prototype.randomise=function(){this.colors=["85,107,139","38,141,247","66,52,248","255,108,80","243, 244, 255","96, 100, 131"],this.velocity=30,this.smoothFactor=50,this.staticity=30,this.magnetism=.1+4*Math.random(),this.color=this.colors[Math.floor(Math.random()*this.colors.length)],this.alpha=this.generateDecimalBetween(5,10)/10,this.size=this.generateDecimalBetween(1,4),this.posX=0,this.posY=0,this.movementX=this.generateDecimalBetween(-2,2)/this.velocity,this.movementY=this.generateDecimalBetween(1,20)/this.velocity,this.translateX=this.generateDecimalBetween(0,this.canvasWidth),this.translateY=this.generateDecimalBetween(0,this.canvasHeight)};let a=function(t){this.canvas=document.getElementById(t),this.ctx=this.canvas.getContext("2d"),this.dpr=window.devicePixelRatio};a.prototype.start=function(){let t=this;t.canvasSize(),window.addEventListener("resize",function(){t.canvasSize()}),t.bubblesList=[],t.generateBubbles(),t.animate()},a.prototype.canvasSize=function(){this.container=this.canvas.parentNode,this.w=this.container.offsetWidth,this.h=this.container.offsetHeight,this.wdpi=this.w*this.dpr,this.hdpi=this.h*this.dpr,this.canvas.width=this.wdpi,this.canvas.height=this.hdpi,this.canvas.style.width=this.w+"px",this.canvas.style.height=this.h+"px",this.ctx.scale(this.dpr,this.dpr)},a.prototype.animate=function(){let t=this;t.ctx.clearRect(0,0,t.canvas.clientWidth,t.canvas.clientHeight),t.bubblesList.forEach(function(e){e.update(),t.ctx.translate(e.translateX,e.translateY),t.ctx.beginPath(),t.ctx.arc(e.posX,e.posY,e.size,0,2*Math.PI),t.ctx.fillStyle="rgba("+e.color+","+e.alpha+")",t.ctx.fill(),t.ctx.setTransform(t.dpr,0,0,t.dpr,0,0)}),requestAnimationFrame(this.animate.bind(this))},a.prototype.addBubble=function(t){return this.bubblesList.push(t)},a.prototype.generateBubbles=function(){let t=this;for(let e=0;e + + + + + + 智驾定位 + + + + + +
+ + +
+
+ +
+ +
+
+
+
+

一款面向家庭用户、车队管理者、骑行社群等多种出行场景的精准定位与智能驾驶分析APP。

+

我们致力于通过精准的位置共享、行车轨迹分析和智能出行守护,为每一位用户打造更高效、更安心的出行体验。智能记录、安全前行、分享行程,让关心的人更安心!

+
+ 下载 +
+
+
+
+ iPhone illustration +
+ iPhone Hero +
+
+
+
+ +
+
+
+
+
+
+
+ iPhone Feature 01 illustration +
+ iPhone Feature 01 +
+
+

帮助你查找朋友和车辆的定位

+

数据自动生成,行程随时回顾.

+
+
+
+
+
+ iPhone Feature 02 illustration +
+ iPhone Feature 02 +
+
+

驾驶评分、智驾分析

+

自动计算驾驶行为评分,实时反馈驾驶习惯,包括急刹车、加速、超速等

+

详细分析驾驶行为,展示每次行车的评分细节、改善建议、优化目标

+
+
+
+
+
+ iPhone Feature 03 illustration +
+ iPhone Feature 03 +
+
+

行程回顾、行程分享

+

精准记录每一次行程,回顾路线、时间、里程,支持轨迹回放

+

将实时行程分享给关心你的人

+
+
+
+
+
+ iPhone Feature 04 illustration +
+ iPhone Feature 04 +
+
+

安全省心、隐私保护

+

上车不掉队,圈子一路随行,安心共享每一步

+

圈子虽小,连接无限,定位共享,从亲近的人开始

+
+
+
+
+
+
+
+ + + + +
+ + + diff --git a/html/src/images/footer-bg.svg b/html/src/images/footer-bg.svg new file mode 100644 index 0000000..4d06670 --- /dev/null +++ b/html/src/images/footer-bg.svg @@ -0,0 +1 @@ + diff --git a/html/src/images/hero-bg-bottom.svg b/html/src/images/hero-bg-bottom.svg new file mode 100644 index 0000000..53c0dee --- /dev/null +++ b/html/src/images/hero-bg-bottom.svg @@ -0,0 +1 @@ + diff --git a/html/src/images/hero-bg-top.svg b/html/src/images/hero-bg-top.svg new file mode 100644 index 0000000..0065311 --- /dev/null +++ b/html/src/images/hero-bg-top.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/src/images/iphone-feature-01.png b/html/src/images/iphone-feature-01.png new file mode 100644 index 0000000..bf84d9e Binary files /dev/null and b/html/src/images/iphone-feature-01.png differ diff --git a/html/src/images/iphone-feature-02.png b/html/src/images/iphone-feature-02.png new file mode 100644 index 0000000..086ed12 Binary files /dev/null and b/html/src/images/iphone-feature-02.png differ diff --git a/html/src/images/iphone-feature-03.png b/html/src/images/iphone-feature-03.png new file mode 100644 index 0000000..bf84d9e Binary files /dev/null and b/html/src/images/iphone-feature-03.png differ diff --git a/html/src/images/iphone-feature-04.png b/html/src/images/iphone-feature-04.png new file mode 100644 index 0000000..086ed12 Binary files /dev/null and b/html/src/images/iphone-feature-04.png differ diff --git a/html/src/images/iphone-feature-bg-01.svg b/html/src/images/iphone-feature-bg-01.svg new file mode 100644 index 0000000..f074eea --- /dev/null +++ b/html/src/images/iphone-feature-bg-01.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/src/images/iphone-feature-bg-02.svg b/html/src/images/iphone-feature-bg-02.svg new file mode 100644 index 0000000..dfa9441 --- /dev/null +++ b/html/src/images/iphone-feature-bg-02.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/src/images/iphone-feature-bg-03.svg b/html/src/images/iphone-feature-bg-03.svg new file mode 100644 index 0000000..6880c57 --- /dev/null +++ b/html/src/images/iphone-feature-bg-03.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/src/images/iphone-feature-bg-04.svg b/html/src/images/iphone-feature-bg-04.svg new file mode 100644 index 0000000..ebc0000 --- /dev/null +++ b/html/src/images/iphone-feature-bg-04.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/src/images/iphone-hero-bg.svg b/html/src/images/iphone-hero-bg.svg new file mode 100644 index 0000000..577ec54 --- /dev/null +++ b/html/src/images/iphone-hero-bg.svg @@ -0,0 +1 @@ + diff --git a/html/src/images/iphone-hero.png b/html/src/images/iphone-hero.png new file mode 100644 index 0000000..b58f00f Binary files /dev/null and b/html/src/images/iphone-hero.png differ diff --git a/html/src/images/logo.svg b/html/src/images/logo.svg new file mode 100644 index 0000000..fe9cd59 --- /dev/null +++ b/html/src/images/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/src/js/main.js b/html/src/js/main.js new file mode 100644 index 0000000..e55ee78 --- /dev/null +++ b/html/src/js/main.js @@ -0,0 +1,181 @@ +(function () { + const doc = document + const rootEl = doc.documentElement + const body = doc.body + /* global ScrollReveal */ + const sr = window.sr = ScrollReveal({ mobile: false }) + + rootEl.classList.remove('no-js') + rootEl.classList.add('js') + + window.addEventListener('load', function () { + body.classList.add('is-loaded') + }) + + // Reveal animations + function revealAnimations () { + sr.reveal('.feature-extended .device-mockup', { + duration: 600, + distance: '100px', + easing: 'cubic-bezier(0.215, 0.61, 0.355, 1)', + origin: 'bottom', + viewFactor: 0.6 + }) + sr.reveal('.feature-extended .feature-extended-body', { + duration: 600, + distance: '40px', + easing: 'cubic-bezier(0.215, 0.61, 0.355, 1)', + origin: 'top', + viewFactor: 0.6 + }) + } + + if (body.classList.contains('has-animations')) { + window.addEventListener('load', revealAnimations) + } + + // Particle animation + let Bubble = function (parentNode) { + let self = this + self.parentNode = parentNode + self.getCanvasSize() + window.addEventListener('resize', function () { + self.getCanvasSize() + }) + self.mouseX = 0 + self.mouseY = 0 + window.addEventListener('mousemove', function (e) { + self.mouseX = e.clientX + self.mouseY = e.clientY + }) + self.randomise() + } + + Bubble.prototype.getCanvasSize = function () { + let self = this + self.canvasWidth = self.parentNode.clientWidth + self.canvasHeight = self.parentNode.clientHeight + } + + Bubble.prototype.generateDecimalBetween = function (min, max) { + return (Math.random() * (min - max) + max).toFixed(2) + } + + Bubble.prototype.update = function () { + let self = this + self.translateX = self.translateX - self.movementX + self.translateY = self.translateY - self.movementY + self.posX += ((self.mouseX / (self.staticity / self.magnetism)) - self.posX) / self.smoothFactor + self.posY += ((self.mouseY / (self.staticity / self.magnetism)) - self.posY) / self.smoothFactor + + if (self.translateY + self.posY < 0 || self.translateX + self.posX < 0 || self.translateX + self.posX > self.canvasWidth) { + self.randomise() + self.translateY = self.canvasHeight + } + } + + Bubble.prototype.randomise = function () { + let self = this + self.colors = ['85,107,139', '38,141,247', '66,52,248', '255,108,80', '243, 244, 255', '96, 100, 131'] + self.velocity = 30 // Bubble levitation velocity (the higher the slower) + self.smoothFactor = 50 // The higher, the smoother + self.staticity = 30 // Increase value to make bubbles move slower on mousemove + self.magnetism = 0.1 + Math.random() * 4 + self.color = self.colors[Math.floor(Math.random() * self.colors.length)] + self.alpha = self.generateDecimalBetween(5, 10) / 10 + self.size = self.generateDecimalBetween(1, 4) + self.posX = 0 + self.posY = 0 + self.movementX = self.generateDecimalBetween(-2, 2) / self.velocity + self.movementY = self.generateDecimalBetween(1, 20) / self.velocity + self.translateX = self.generateDecimalBetween(0, self.canvasWidth) + self.translateY = self.generateDecimalBetween(0, self.canvasHeight) + } + + let Background = function (selector) { + let self = this + self.canvas = document.getElementById(selector) + self.ctx = this.canvas.getContext('2d') + self.dpr = window.devicePixelRatio + } + + Background.prototype.start = function () { + let self = this + self.canvasSize() + window.addEventListener('resize', function () { + self.canvasSize() + }) + self.bubblesList = [] + self.generateBubbles() + self.animate() + } + + Background.prototype.canvasSize = function () { + let self = this + self.container = self.canvas.parentNode + // Determine window width and height + self.w = self.container.offsetWidth + self.h = self.container.offsetHeight + self.wdpi = self.w * self.dpr + self.hdpi = self.h * self.dpr + // Set canvas width and height + self.canvas.width = self.wdpi + self.canvas.height = self.hdpi + // Set width and height attributes + self.canvas.style.width = self.w + 'px' + self.canvas.style.height = self.h + 'px' + // Scale down canvas + self.ctx.scale(self.dpr, self.dpr) + } + + Background.prototype.animate = function () { + let self = this + self.ctx.clearRect(0, 0, self.canvas.clientWidth, self.canvas.clientHeight) + self.bubblesList.forEach(function (bubble) { + bubble.update() + self.ctx.translate(bubble.translateX, bubble.translateY) + self.ctx.beginPath() + self.ctx.arc(bubble.posX, bubble.posY, bubble.size, 0, 2 * Math.PI) + self.ctx.fillStyle = 'rgba(' + bubble.color + ',' + bubble.alpha + ')' + self.ctx.fill() + self.ctx.setTransform(self.dpr, 0, 0, self.dpr, 0, 0) + }) + /* global requestAnimationFrame */ + requestAnimationFrame(this.animate.bind(this)) + } + + Background.prototype.addBubble = function (bubble) { + return this.bubblesList.push(bubble) + } + + Background.prototype.generateBubbles = function () { + let self = this + for (let i = 0; i < self.bubbleDensity(); i++) { + self.addBubble(new Bubble(self.canvas.parentNode)) + } + } + + Background.prototype.bubbleDensity = function () { + return 15 + } + + window.addEventListener('load', function () { + const heroParticles = new Background('hero-particles') + const footerParticles = new Background('footer-particles') + heroParticles.start() + footerParticles.start() + }) + + window.requestAnimFrame = (function () { + return ( + window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function (callback) { + window.setTimeout(callback, 1000 / 60) + } + ) + })() +}()) diff --git a/html/src/scss/_normalize.scss b/html/src/scss/_normalize.scss new file mode 100644 index 0000000..8025dce --- /dev/null +++ b/html/src/scss/_normalize.scss @@ -0,0 +1,231 @@ +html { + line-height: 1.15; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; +} + +body { + margin: 0; +} + +article, +aside, +footer, +header, +nav, +section { + display: block; +} + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +figcaption, +figure, +main { + display: block; +} + +figure { + margin: 1em 40px; +} + +hr { + box-sizing: content-box; + height: 0; + overflow: visible; +} + +pre { + font-family: monospace, monospace; + font-size: 1em; +} + +a { + background-color: transparent; + -webkit-text-decoration-skip: objects; +} + +abbr[title] { + border-bottom: none; + text-decoration: underline; + text-decoration: underline dotted; +} + +b, +strong { + font-weight: inherit; +} + +b, +strong { + font-weight: bolder; +} + +code, +kbd, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +dfn { + font-style: italic; +} + +mark { + background-color: #ff0; + color: #000; +} + +small { + font-size: 80%; +} + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +audio, +video { + display: inline-block; +} + +audio:not([controls]) { + display: none; + height: 0; +} + +img { + border-style: none; +} + +svg:not(:root) { + overflow: hidden; +} + +button, +input, +optgroup, +select, +textarea { + font-family: sans-serif; + font-size: 100%; + line-height: 1.15; + margin: 0; +} + +button, +input { + overflow: visible; +} + +button, +select { + text-transform: none; +} + +button, +html [type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +legend { + box-sizing: border-box; + color: inherit; + display: table; + max-width: 100%; + padding: 0; + white-space: normal; +} + +progress { + display: inline-block; + vertical-align: baseline; +} + +textarea { + overflow: auto; +} + +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; + padding: 0; +} + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; +} + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; +} + +details, +menu { + display: block; +} + +summary { + display: list-item; +} + +canvas { + display: inline-block; +} + +template { + display: none; +} + +[hidden] { + display: none; +} \ No newline at end of file diff --git a/html/src/scss/abstracts/_functions.scss b/html/src/scss/abstracts/_functions.scss new file mode 100644 index 0000000..6aa6a1c --- /dev/null +++ b/html/src/scss/abstracts/_functions.scss @@ -0,0 +1,55 @@ +// -------------------------------------------------------------------- +// Retrieve Font Size ------------------------------------------------- +// Used in _mixins.scss [@mixin font-size] ---------------------------- +// -------------------------------------------------------------------- +@function get-font-size($size, $elem) { + @return nth(map-get(map-get($font__scale, $elem), $size), 1); +} + +// -------------------------------------------------------------------- +// Retrieve Line Height ----------------------------------------------- +// Used in _mixins.scss [@mixin font-size] ---------------------------- +// -------------------------------------------------------------------- +@function get-line-height($size, $elem) { + @return nth(map-get(map-get($font__scale, $elem), $size), 2); +} + +// -------------------------------------------------------------------- +// Retrieve Kerning --------------------------------------------------- +// Used in _mixins.scss [@mixin font-size] ---------------------------- +// -------------------------------------------------------------------- +@function get-kerning($size, $elem) { + @return nth(map-get(map-get($font__scale, $elem), $size), 3); +} + +// -------------------------------------------------------------------- +// Retrieve Font Family ----------------------------------------------- +// Used in _mixins.scss [@mixin font-family] -------------------------- +// -------------------------------------------------------------------- +@function get-font-family($elem) { + @return map-get($font__family, $elem); +} + +// -------------------------------------------------------------------- +// Retrieve Font Weight ----------------------------------------------- +// Used in _mixins.scss [@mixin font-weight] -------------------------- +// -------------------------------------------------------------------- +@function get-font-weight($elem) { + @return map-get($font__weight, $elem); +} + +// -------------------------------------------------------------------- +// Retrieve Padding of Content Area Elements -------------------------- +// Used in _mixins.scss [@mixin font-size] ---------------------------- +// -------------------------------------------------------------------- +@function get-content-padding($elem) { + @return map-get($content__padding, $elem); +} + +// -------------------------------------------------------------------- +// Retrieve Colors ---------------------------------------------------- +// Usage: color(typography, 1) ---------------------------------------------- +// -------------------------------------------------------------------- +@function color($elem, $variant) { + @return map-get(map-get($color, $elem), $variant); +} diff --git a/html/src/scss/abstracts/_include-media.scss b/html/src/scss/abstracts/_include-media.scss new file mode 100644 index 0000000..bb5ccd5 --- /dev/null +++ b/html/src/scss/abstracts/_include-media.scss @@ -0,0 +1,567 @@ +@charset "UTF-8"; + +// _ _ _ _ _ +// (_) | | | | | (_) +// _ _ __ ___| |_ _ __| | ___ _ __ ___ ___ __| |_ __ _ +// | | '_ \ / __| | | | |/ _` |/ _ \ | '_ ` _ \ / _ \/ _` | |/ _` | +// | | | | | (__| | |_| | (_| | __/ | | | | | | __/ (_| | | (_| | +// |_|_| |_|\___|_|\__,_|\__,_|\___| |_| |_| |_|\___|\__,_|_|\__,_| +// +// Simple, elegant and maintainable media queries in Sass +// v1.4.9 +// +// http://include-media.com +// +// Authors: Eduardo Boucas (@eduardoboucas) +// Hugo Giraudel (@hugogiraudel) +// +// This project is licensed under the terms of the MIT license + + +//// +/// include-media library public configuration +/// @author Eduardo Boucas +/// @access public +//// + + +/// +/// Creates a list of global breakpoints +/// +/// @example scss - Creates a single breakpoint with the label `phone` +/// $breakpoints: ('phone': 320px); +/// +$breakpoints: ( + 'small': 480px, + 'medium': 640px, + 'large': 1024px, +) !default; + + +/// +/// Creates a list of static expressions or media types +/// +/// @example scss - Creates a single media type (screen) +/// $media-expressions: ('screen': 'screen'); +/// +/// @example scss - Creates a static expression with logical disjunction (OR operator) +/// $media-expressions: ( +/// 'retina2x': '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)' +/// ); +/// +$media-expressions: ( + 'screen': 'screen', + 'print': 'print', + 'handheld': 'handheld', + 'landscape': '(orientation: landscape)', + 'portrait': '(orientation: portrait)', + 'retina2x': '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi), (min-resolution: 2dppx)', + 'retina3x': '(-webkit-min-device-pixel-ratio: 3), (min-resolution: 350dpi), (min-resolution: 3dppx)' +) !default; + + +/// +/// Defines a number to be added or subtracted from each unit when declaring breakpoints with exclusive intervals +/// +/// @example scss - Interval for pixels is defined as `1` by default +/// @include media('>128px') {} +/// +/// /* Generates: */ +/// @media (min-width: 129px) {} +/// +/// @example scss - Interval for ems is defined as `0.01` by default +/// @include media('>20em') {} +/// +/// /* Generates: */ +/// @media (min-width: 20.01em) {} +/// +/// @example scss - Interval for rems is defined as `0.1` by default, to be used with `font-size: 62.5%;` +/// @include media('>2.0rem') {} +/// +/// /* Generates: */ +/// @media (min-width: 2.1rem) {} +/// +$unit-intervals: ( + 'px': 1, + 'em': 0.01, + 'rem': 0.1, + '': 0 +) !default; + +/// +/// Defines whether support for media queries is available, useful for creating separate stylesheets +/// for browsers that don't support media queries. +/// +/// @example scss - Disables support for media queries +/// $im-media-support: false; +/// @include media('>=tablet') { +/// .foo { +/// color: tomato; +/// } +/// } +/// +/// /* Generates: */ +/// .foo { +/// color: tomato; +/// } +/// +$im-media-support: true !default; + +/// +/// Selects which breakpoint to emulate when support for media queries is disabled. Media queries that start at or +/// intercept the breakpoint will be displayed, any others will be ignored. +/// +/// @example scss - This media query will show because it intercepts the static breakpoint +/// $im-media-support: false; +/// $im-no-media-breakpoint: 'desktop'; +/// @include media('>=tablet') { +/// .foo { +/// color: tomato; +/// } +/// } +/// +/// /* Generates: */ +/// .foo { +/// color: tomato; +/// } +/// +/// @example scss - This media query will NOT show because it does not intercept the desktop breakpoint +/// $im-media-support: false; +/// $im-no-media-breakpoint: 'tablet'; +/// @include media('>=desktop') { +/// .foo { +/// color: tomato; +/// } +/// } +/// +/// /* No output */ +/// +$im-no-media-breakpoint: 'desktop' !default; + +/// +/// Selects which media expressions are allowed in an expression for it to be used when media queries +/// are not supported. +/// +/// @example scss - This media query will show because it intercepts the static breakpoint and contains only accepted media expressions +/// $im-media-support: false; +/// $im-no-media-breakpoint: 'desktop'; +/// $im-no-media-expressions: ('screen'); +/// @include media('>=tablet', 'screen') { +/// .foo { +/// color: tomato; +/// } +/// } +/// +/// /* Generates: */ +/// .foo { +/// color: tomato; +/// } +/// +/// @example scss - This media query will NOT show because it intercepts the static breakpoint but contains a media expression that is not accepted +/// $im-media-support: false; +/// $im-no-media-breakpoint: 'desktop'; +/// $im-no-media-expressions: ('screen'); +/// @include media('>=tablet', 'retina2x') { +/// .foo { +/// color: tomato; +/// } +/// } +/// +/// /* No output */ +/// +$im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; + +//// +/// Cross-engine logging engine +/// @author Hugo Giraudel +/// @access private +//// + + +/// +/// Log a message either with `@error` if supported +/// else with `@warn`, using `feature-exists('at-error')` +/// to detect support. +/// +/// @param {String} $message - Message to log +/// +@function im-log($message) { + @if feature-exists('at-error') { + @error $message; + } @else { + @warn $message; + $_: noop(); + } + + @return $message; +} + + +/// +/// Wrapper mixin for the log function so it can be used with a more friendly +/// API than `@if im-log('..') {}` or `$_: im-log('..')`. Basically, use the function +/// within functions because it is not possible to include a mixin in a function +/// and use the mixin everywhere else because it's much more elegant. +/// +/// @param {String} $message - Message to log +/// +@mixin log($message) { + @if im-log($message) {} +} + + +/// +/// Function with no `@return` called next to `@warn` in Sass 3.3 +/// to trigger a compiling error and stop the process. +/// +@function noop() {} + +/// +/// Determines whether a list of conditions is intercepted by the static breakpoint. +/// +/// @param {Arglist} $conditions - Media query conditions +/// +/// @return {Boolean} - Returns true if the conditions are intercepted by the static breakpoint +/// +@function im-intercepts-static-breakpoint($conditions...) { + $no-media-breakpoint-value: map-get($breakpoints, $im-no-media-breakpoint); + + @if not $no-media-breakpoint-value { + @if im-log('`#{$im-no-media-breakpoint}` is not a valid breakpoint.') {} + } + + @each $condition in $conditions { + @if not map-has-key($media-expressions, $condition) { + $operator: get-expression-operator($condition); + $prefix: get-expression-prefix($operator); + $value: get-expression-value($condition, $operator); + + @if ($prefix == 'max' and $value <= $no-media-breakpoint-value) or + ($prefix == 'min' and $value > $no-media-breakpoint-value) { + @return false; + } + } @else if not index($im-no-media-expressions, $condition) { + @return false; + } + } + + @return true; +} + +//// +/// Parsing engine +/// @author Hugo Giraudel +/// @access private +//// + + +/// +/// Get operator of an expression +/// +/// @param {String} $expression - Expression to extract operator from +/// +/// @return {String} - Any of `>=`, `>`, `<=`, `<`, `≥`, `≤` +/// +@function get-expression-operator($expression) { + @each $operator in ('>=', '>', '<=', '<', '≥', '≤') { + @if str-index($expression, $operator) { + @return $operator; + } + } + + // It is not possible to include a mixin inside a function, so we have to + // rely on the `im-log(..)` function rather than the `log(..)` mixin. Because + // functions cannot be called anywhere in Sass, we need to hack the call in + // a dummy variable, such as `$_`. If anybody ever raise a scoping issue with + // Sass 3.3, change this line in `@if im-log(..) {}` instead. + $_: im-log('No operator found in `#{$expression}`.'); +} + + +/// +/// Get dimension of an expression, based on a found operator +/// +/// @param {String} $expression - Expression to extract dimension from +/// @param {String} $operator - Operator from `$expression` +/// +/// @return {String} - `width` or `height` (or potentially anything else) +/// +@function get-expression-dimension($expression, $operator) { + $operator-index: str-index($expression, $operator); + $parsed-dimension: str-slice($expression, 0, $operator-index - 1); + $dimension: 'width'; + + @if str-length($parsed-dimension) > 0 { + $dimension: $parsed-dimension; + } + + @return $dimension; +} + + +/// +/// Get dimension prefix based on an operator +/// +/// @param {String} $operator - Operator +/// +/// @return {String} - `min` or `max` +/// +@function get-expression-prefix($operator) { + @return if(index(('<', '<=', '≤'), $operator), 'max', 'min'); +} + + +/// +/// Get value of an expression, based on a found operator +/// +/// @param {String} $expression - Expression to extract value from +/// @param {String} $operator - Operator from `$expression` +/// +/// @return {Number} - A numeric value +/// +@function get-expression-value($expression, $operator) { + $operator-index: str-index($expression, $operator); + $value: str-slice($expression, $operator-index + str-length($operator)); + + @if map-has-key($breakpoints, $value) { + $value: map-get($breakpoints, $value); + } @else { + $value: to-number($value); + } + + $interval: map-get($unit-intervals, unit($value)); + + @if not $interval { + // It is not possible to include a mixin inside a function, so we have to + // rely on the `im-log(..)` function rather than the `log(..)` mixin. Because + // functions cannot be called anywhere in Sass, we need to hack the call in + // a dummy variable, such as `$_`. If anybody ever raise a scoping issue with + // Sass 3.3, change this line in `@if im-log(..) {}` instead. + $_: im-log('Unknown unit `#{unit($value)}`.'); + } + + @if $operator == '>' { + $value: $value + $interval; + } @else if $operator == '<' { + $value: $value - $interval; + } + + @return $value; +} + + +/// +/// Parse an expression to return a valid media-query expression +/// +/// @param {String} $expression - Expression to parse +/// +/// @return {String} - Valid media query +/// +@function parse-expression($expression) { + // If it is part of $media-expressions, it has no operator + // then there is no need to go any further, just return the value + @if map-has-key($media-expressions, $expression) { + @return map-get($media-expressions, $expression); + } + + $operator: get-expression-operator($expression); + $dimension: get-expression-dimension($expression, $operator); + $prefix: get-expression-prefix($operator); + $value: get-expression-value($expression, $operator); + + @return '(#{$prefix}-#{$dimension}: #{$value})'; +} + +/// +/// Slice `$list` between `$start` and `$end` indexes +/// +/// @access private +/// +/// @param {List} $list - List to slice +/// @param {Number} $start [1] - Start index +/// @param {Number} $end [length($list)] - End index +/// +/// @return {List} Sliced list +/// +@function slice($list, $start: 1, $end: length($list)) { + @if length($list) < 1 or $start > $end { + @return (); + } + + $result: (); + + @for $i from $start through $end { + $result: append($result, nth($list, $i)); + } + + @return $result; +} + +//// +/// String to number converter +/// @author Hugo Giraudel +/// @access private +//// + + +/// +/// Casts a string into a number +/// +/// @param {String | Number} $value - Value to be parsed +/// +/// @return {Number} +/// +@function to-number($value) { + @if type-of($value) == 'number' { + @return $value; + } @else if type-of($value) != 'string' { + $_: im-log('Value for `to-number` should be a number or a string.'); + } + + $first-character: str-slice($value, 1, 1); + $result: 0; + $digits: 0; + $minus: ($first-character == '-'); + $numbers: ('0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9); + + // Remove +/- sign if present at first character + @if ($first-character == '+' or $first-character == '-') { + $value: str-slice($value, 2); + } + + @for $i from 1 through str-length($value) { + $character: str-slice($value, $i, $i); + + @if not (index(map-keys($numbers), $character) or $character == '.') { + @return to-length(if($minus, -$result, $result), str-slice($value, $i)) + } + + @if $character == '.' { + $digits: 1; + } @else if $digits == 0 { + $result: $result * 10 + map-get($numbers, $character); + } @else { + $digits: $digits * 10; + $result: $result + map-get($numbers, $character) / $digits; + } + } + + @return if($minus, -$result, $result); +} + + +/// +/// Add `$unit` to `$value` +/// +/// @param {Number} $value - Value to add unit to +/// @param {String} $unit - String representation of the unit +/// +/// @return {Number} - `$value` expressed in `$unit` +/// +@function to-length($value, $unit) { + $units: ('px': 1px, 'cm': 1cm, 'mm': 1mm, '%': 1%, 'ch': 1ch, 'pc': 1pc, 'in': 1in, 'em': 1em, 'rem': 1rem, 'pt': 1pt, 'ex': 1ex, 'vw': 1vw, 'vh': 1vh, 'vmin': 1vmin, 'vmax': 1vmax); + + @if not index(map-keys($units), $unit) { + $_: im-log('Invalid unit `#{$unit}`.'); + } + + @return $value * map-get($units, $unit); +} + +/// +/// This mixin aims at redefining the configuration just for the scope of +/// the call. It is helpful when having a component needing an extended +/// configuration such as custom breakpoints (referred to as tweakpoints) +/// for instance. +/// +/// @author Hugo Giraudel +/// +/// @param {Map} $tweakpoints [()] - Map of tweakpoints to be merged with `$breakpoints` +/// @param {Map} $tweak-media-expressions [()] - Map of tweaked media expressions to be merged with `$media-expression` +/// +/// @example scss - Extend the global breakpoints with a tweakpoint +/// @include media-context(('custom': 678px)) { +/// .foo { +/// @include media('>phone', '<=custom') { +/// // ... +/// } +/// } +/// } +/// +/// @example scss - Extend the global media expressions with a custom one +/// @include media-context($tweak-media-expressions: ('all': 'all')) { +/// .foo { +/// @include media('all', '>phone') { +/// // ... +/// } +/// } +/// } +/// +/// @example scss - Extend both configuration maps +/// @include media-context(('custom': 678px), ('all': 'all')) { +/// .foo { +/// @include media('all', '>phone', '<=custom') { +/// // ... +/// } +/// } +/// } +/// +@mixin media-context($tweakpoints: (), $tweak-media-expressions: ()) { + // Save global configuration + $global-breakpoints: $breakpoints; + $global-media-expressions: $media-expressions; + + // Update global configuration + $breakpoints: map-merge($breakpoints, $tweakpoints) !global; + $media-expressions: map-merge($media-expressions, $tweak-media-expressions) !global; + + @content; + + // Restore global configuration + $breakpoints: $global-breakpoints !global; + $media-expressions: $global-media-expressions !global; +} + +//// +/// include-media public exposed API +/// @author Eduardo Boucas +/// @access public +//// + + +/// +/// Generates a media query based on a list of conditions +/// +/// @param {Arglist} $conditions - Media query conditions +/// +/// @example scss - With a single set breakpoint +/// @include media('>phone') { } +/// +/// @example scss - With two set breakpoints +/// @include media('>phone', '<=tablet') { } +/// +/// @example scss - With custom values +/// @include media('>=358px', '<850px') { } +/// +/// @example scss - With set breakpoints with custom values +/// @include media('>desktop', '<=1350px') { } +/// +/// @example scss - With a static expression +/// @include media('retina2x') { } +/// +/// @example scss - Mixing everything +/// @include media('>=350px', ' 0) { + @media #{unquote(parse-expression(nth($conditions, 1)))} { + // Recursive call + @include media(slice($conditions, 2)...) { + @content; + } + } + } +} diff --git a/html/src/scss/abstracts/_mixins.scss b/html/src/scss/abstracts/_mixins.scss new file mode 100644 index 0000000..89f5b10 --- /dev/null +++ b/html/src/scss/abstracts/_mixins.scss @@ -0,0 +1,112 @@ +// Font-size + Line-height + Kerning +// Usage: @include font-size(1, mobile) +// Add more true/false args to control what to output: font-size, line-height, kerning +@mixin font-size($size, $elem, $font-size: true, $line-height: false, $kerning: false, $adjust-font-size: 0) { + @if not map-has-key(map-get($font__scale, $elem), $size) { + @warn "'#{$size}' key does not exist in array!"; + } + @if ( $font-size != false ) { + font-size: get-font-size($size, $elem) + $adjust-font-size; + } + @if ( $line-height == true ) { + line-height: get-line-height($size, $elem); + } + @if ( $kerning == true ) { + letter-spacing: get-kerning($size, $elem); + } +} + +// Font Family +@mixin font-family($elem) { + font-family: unquote(get-font-family($elem)); +} + +// Font Weight +@mixin font-weight($elem) { + font-weight: get-font-weight($elem); +} + +// Anchor aspect +@mixin anchor-aspect($type: 'main') { + @if ($type == 'main') { // Base + color: color(primary, 1); + text-decoration: none; + + &:hover, + &:active { + outline: 0; + text-decoration: underline; + } + } @else if ($type == 'header') { + color: color(typography, 2i); + text-transform: uppercase; + text-decoration: none; + + &:hover, + &:active { + color: color(typography, 1i); + } + } @else if ($type == 'footer') { + color: color(typography, 2i); + text-decoration: none; + + &:hover, + &:active { + text-decoration: underline; + } + } +} + +@mixin shadow($layout: false) { + @if ( $layout == 'dark' ) { + box-shadow: 0 20px 48px rgba(darken(color(bg, 1), 35%), .2); + } @else { + box-shadow: 0 20px 48px rgba(color(typography, 1), .16); + } +} + +@mixin shadow-sm($layout: false) { + @if ( $layout == 'dark' ) { + box-shadow: 0 16px 24px rgba(darken(color(bg, 1), 35%), .2); + } @else { + box-shadow: 0 16px 24px rgba(color(typography, 1), .16); + } +} + +@mixin divider-mix($layout: false) { + display: block; + height: 1px; + @if ( $layout == 'dark' ) { + background: color(bg, 2i); + } @else { + background: color(bg, 3); + } +} + +@mixin divider($type: false, $layout: false) { + @if ( $type == 'before' ) { + position: relative; + + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + @include divider-mix($layout); + } + } @else if ($type == 'after') { + position: relative; + + &::after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + width: 100%; + @include divider-mix($layout); + } + } @else { + @include divider-mix($layout); + } +} diff --git a/html/src/scss/abstracts/_variables.scss b/html/src/scss/abstracts/_variables.scss new file mode 100644 index 0000000..8c48715 --- /dev/null +++ b/html/src/scss/abstracts/_variables.scss @@ -0,0 +1,92 @@ +// -------------------------------------------- +// Colors ------------------------------------- +// Usage example: color(primary, main) +// -------------------------------------------- +$color: ( + typography: ( + 1: #161E2A, + 2: #6B7A90, + 1i: #FFF, + 2i: #606483 + ), + bg: ( + 1: #FFFFFF, + 2: #F3F4FF, + 3: #E4E8EE, + 1i: #0B0D19, + 2i: #1E233D + ), + primary: ( + 1: #4234F8, + 2: #7065FA, + 3: #1908F1, + 4: #E2E0FE + ), + secondary: ( + 1: #FF6C50, + 2: #FF816A, + 3: #FF411D, + 4: #FFD8D1 + ) +); + +// -------------------------------------------- +// Typography --------------------------------- +// -------------------------------------------- +$font__family: ( + base: '"Heebo", sans-serif', // font-family(base) + heading: '"Oxygen", sans-serif', // font-family(heading) + code: 'Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace', // font-family(code) + pre: '"Courier 10 Pitch", Courier, monospace' // font-family(pre) +); + +$font__sizes: ( + alpha: ( 44px, 54px, 0px ), // font-size, line-height, kerning (use '0' if don't want to output any kerning) + beta: ( 38px, 48px, 0px ), + gamma: ( 32px, 42px, 0px ), + delta: ( 28px, 34px, 0px ), + epsilon: ( 20px, 30px, -0.1px ), + zeta: ( 18px, 27px, -0.1px ), + eta: ( 16px, 24px, -0.1px ), + theta: ( 14px, 22px, 0px ) +); + +$font__scale: ( + desktop: ( // i.e. $breakpoint__m + $breakpoint__l (600 - 1024) + 1: map-get($font__sizes, alpha), // H1 + 2: map-get($font__sizes, beta), // H2 + 3: map-get($font__sizes, gamma), // H3 + 4: map-get($font__sizes, delta), // H4 + 5: map-get($font__sizes, epsilon), // Body, H5, H6 + 6: map-get($font__sizes, zeta), // Text small + 7: map-get($font__sizes, eta), // Text smaller + 8: map-get($font__sizes, theta) // Footer area + ), + mobile: ( // i.e. $breakpoint__xs + $breakpoint__s (up to 600) + 1: map-get($font__sizes, beta), // H1 + 2: map-get($font__sizes, gamma), // H2 + 3: map-get($font__sizes, delta), // H3 + 4: map-get($font__sizes, delta), // H4 + 5: map-get($font__sizes, epsilon), // Body, H5, H6 + 6: map-get($font__sizes, zeta), // Text small + 7: map-get($font__sizes, eta), // Text smaller + 8: map-get($font__sizes, theta) // Footer area + ) +); + +$font__weight: ( + regular: 400, // font__weight(regular) + medium: 500, // font__weight(medium) + semibold: 600, // font__weight(semibold) + bold: 700 // font__weight(bold) +); + +// -------------------------------------------- +// Structure ---------------------------------- +// -------------------------------------------- +$content__padding: ( + mobile: 16px, + desktop: 24px +); +$container__width: 1080px; +$container__width-sm: 800px; diff --git a/html/src/scss/base/_base.scss b/html/src/scss/base/_base.scss new file mode 100644 index 0000000..9a4da5c --- /dev/null +++ b/html/src/scss/base/_base.scss @@ -0,0 +1,103 @@ +html { + box-sizing: border-box; +} + +*, +*:before, +*:after { /* Inherit box-sizing to make it easier to change the property for components that leverage other behavior; see http://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/ */ + box-sizing: inherit; +} + +body { + background: color(bg, 1); /* Fallback for when there is no custom background color defined. */ + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; +} + +hr { + border: 0; + @include divider(); + margin-top: 24px; + margin-bottom: 24px; +} + +ul, ol { + margin-top: 0; + margin-bottom: 24px; + padding-left: 24px; +} + +ul { + list-style: disc; +} + +ol { + list-style: decimal; +} + +li > ul, +li > ol { + margin-bottom: 0; +} + +dl { + margin-top: 0; + margin-bottom: 24px; +} + +dt { + @include font-weight(semibold); +} + +dd { + margin-left: 24px; + margin-bottom: 24px; +} + +img { + height: auto; /* Make sure images are scaled correctly. */ + max-width: 100%; /* Adhere to container width. */ + vertical-align: middle; +} + +figure { + margin: 24px 0; /* Extra wide images within figure tags don't overflow the content area. */ +} + +figcaption { + @include font-size(7, mobile, true, true); + padding: 8px 0; +} + +img, +svg { + display: block; +} + +// tables +table { + border-collapse: collapse; + margin-bottom: 24px; + width: 100%; +} + +tr { + border-bottom: 1px solid color(bg, 3); +} + +th { + text-align: left; +} + +th, +td { + padding: 10px 16px; + + &:first-child { + padding-left: 0; + } + + &:last-child { + padding-right: 0; + } +} diff --git a/html/src/scss/base/_helpers.scss b/html/src/scss/base/_helpers.scss new file mode 100644 index 0000000..bfb7ab8 --- /dev/null +++ b/html/src/scss/base/_helpers.scss @@ -0,0 +1,469 @@ +.container, +.container-sm { + width: 100%; + margin: 0 auto; + padding-left: get-content-padding(mobile); + padding-right: get-content-padding(mobile); + + @include media( '>small' ) { + padding-left: get-content-padding(desktop); + padding-right: get-content-padding(desktop); + } +} + +.container { + max-width: $container__width + ( get-content-padding(desktop) * 2 ); +} + +.container-sm { + max-width: $container__width-sm + ( get-content-padding(desktop) * 2 ); +} + +.container { + + .container-sm { + max-width: $container__width-sm; + padding-left: 0; + padding-right: 0; + } +} + +/* Text meant only for screen readers. */ +.screen-reader-text { + clip: rect(1px, 1px, 1px, 1px); + position: absolute !important; + height: 1px; + width: 1px; + overflow: hidden; + word-wrap: normal !important; /* Many screen reader and browser combinations announce broken words as they would appear visually. */ + + &:focus { + border-radius: 2px; + box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6); + clip: auto !important; + display: block; + @include font-size(8, mobile, true, false, true); + @if ( get-font-size(8, desktop) != get-font-size(8, mobile) ) { + @include media( '>medium' ) { + @include font-size(8, desktop, true, false, true); + } + } + @include font-weight(semibold); + line-height: 16px; + text-decoration: none; + text-transform: uppercase; + background-color: color(bg, 1); + color: color(primary, 1) !important; + border: none; + height: auto; + left: 8px; + padding: 16px 40px; + top: 8px; + width: auto; + z-index: 100000; + } +} + +.list-reset { + list-style: none; + padding: 0; +} + +.text-left { + text-align: left; +} + +.text-center { + text-align: center; +} + +.text-right { + text-align: right; +} + +.text-primary { + color: color(primary, 1); +} + +.text-secondary { + color: color(secondary, 1); +} + +.has-top-divider { + @include divider(before); +} + +.has-bottom-divider { + @include divider(after); +} + +.m-0 { + margin: 0; +} + +.mt-0 { + margin-top: 0; +} + +.mr-0 { + margin-right: 0; +} + +.mb-0 { + margin-bottom: 0; +} + +.ml-0 { + margin-left: 0; +} + +.m-8 { + margin: 8px; +} + +.mt-8 { + margin-top: 8px; +} + +.mr-8 { + margin-right: 8px; +} + +.mb-8 { + margin-bottom: 8px; +} + +.ml-8 { + margin-left: 8px; +} + +.m-16 { + margin: 16px; +} + +.mt-16 { + margin-top: 16px; +} + +.mr-16 { + margin-right: 16px; +} + +.mb-16 { + margin-bottom: 16px; +} + +.ml-16 { + margin-left: 16px; +} + +.m-24 { + margin: 24px; +} + +.mt-24 { + margin-top: 24px; +} + +.mr-24 { + margin-right: 24px; +} + +.mb-24 { + margin-bottom: 24px; +} + +.ml-24 { + margin-left: 24px; +} + +.m-32 { + margin: 32px; +} + +.mt-32 { + margin-top: 32px; +} + +.mr-32 { + margin-right: 32px; +} + +.mb-32 { + margin-bottom: 32px; +} + +.ml-32 { + margin-left: 32px; +} + +.m-40 { + margin: 40px; +} + +.mt-40 { + margin-top: 40px; +} + +.mr-40 { + margin-right: 40px; +} + +.mb-40 { + margin-bottom: 40px; +} + +.ml-40 { + margin-left: 40px; +} + +.m-48 { + margin: 48px; +} + +.mt-48 { + margin-top: 48px; +} + +.mr-48 { + margin-right: 48px; +} + +.mb-48 { + margin-bottom: 48px; +} + +.ml-48 { + margin-left: 48px; +} + +.m-56 { + margin: 56px; +} + +.mt-56 { + margin-top: 56px; +} + +.mr-56 { + margin-right: 56px; +} + +.mb-56 { + margin-bottom: 56px; +} + +.ml-56 { + margin-left: 56px; +} + +.m-64 { + margin: 64px; +} + +.mt-64 { + margin-top: 64px; +} + +.mr-64 { + margin-right: 64px; +} + +.mb-64 { + margin-bottom: 64px; +} + +.ml-64 { + margin-left: 64px; +} + +.p-0 { + padding: 0; +} + +.pt-0 { + padding-top: 0; +} + +.pr-0 { + padding-right: 0; +} + +.pb-0 { + padding-bottom: 0; +} + +.pl-0 { + padding-left: 0; +} + +.p-8 { + padding: 8px; +} + +.pt-8 { + padding-top: 8px; +} + +.pr-8 { + padding-right: 8px; +} + +.pb-8 { + padding-bottom: 8px; +} + +.pl-8 { + padding-left: 8px; +} + +.p-16 { + padding: 16px; +} + +.pt-16 { + padding-top: 16px; +} + +.pr-16 { + padding-right: 16px; +} + +.pb-16 { + padding-bottom: 16px; +} + +.pl-16 { + padding-left: 16px; +} + +.p-24 { + padding: 24px; +} + +.pt-24 { + padding-top: 24px; +} + +.pr-24 { + padding-right: 24px; +} + +.pb-24 { + padding-bottom: 24px; +} + +.pl-24 { + padding-left: 24px; +} + +.p-32 { + padding: 32px; +} + +.pt-32 { + padding-top: 32px; +} + +.pr-32 { + padding-right: 32px; +} + +.pb-32 { + padding-bottom: 32px; +} + +.pl-32 { + padding-left: 32px; +} + +.p-40 { + padding: 40px; +} + +.pt-40 { + padding-top: 40px; +} + +.pr-40 { + padding-right: 40px; +} + +.pb-40 { + padding-bottom: 40px; +} + +.pl-40 { + padding-left: 40px; +} + +.p-48 { + padding: 48px; +} + +.pt-48 { + padding-top: 48px; +} + +.pr-48 { + padding-right: 48px; +} + +.pb-48 { + padding-bottom: 48px; +} + +.pl-48 { + padding-left: 48px; +} + +.p-56 { + padding: 56px; +} + +.pt-56 { + padding-top: 56px; +} + +.pr-56 { + padding-right: 56px; +} + +.pb-56 { + padding-bottom: 56px; +} + +.pl-56 { + padding-left: 56px; +} + +.p-64 { + padding: 64px; +} + +.pt-64 { + padding-top: 64px; +} + +.pr-64 { + padding-right: 64px; +} + +.pb-64 { + padding-bottom: 64px; +} + +.pl-64 { + padding-left: 64px; +} + +/* Reveal animations */ +.sr { + + .has-animations { + + .is-revealing { + visibility: hidden; + } + } +} diff --git a/html/src/scss/base/_typography.scss b/html/src/scss/base/_typography.scss new file mode 100644 index 0000000..589e40b --- /dev/null +++ b/html/src/scss/base/_typography.scss @@ -0,0 +1,263 @@ +html { + @include font-size(5, mobile, true, true); + @if ( get-font-size(5, desktop) != get-font-size(5, mobile) ) { + @include media( '>medium' ) { + @include font-size(5, desktop, true, true, true); + } + } +} + +body { + color: color(typography, 2); + font-size: 1rem; +} + +body, +button, +input, +select, +textarea { + @include font-family(base); +} + +a { + @include anchor-aspect(main); +} + +h1, h2, h3, h4, h5, h6, +.h1, .h2, .h3, .h4, .h5, .h6 { + clear: both; + color: color(typography, 1); + @if ( get-font-family(heading) != get-font-family(base) ) { + @include font-family(heading); + } + @include font-weight(semibold); +} + +h1, +.h1 { + @include font-size(1, mobile, true, true, true); + @if ( get-font-size(1, desktop) != get-font-size(1, mobile) ) { + @include media( '>medium' ) { + @include font-size(1, desktop, true, true, true); + } + } +} + +h2, +.h2 { + @include font-size(2, mobile, true, true, true); + @if ( get-font-size(2, desktop) != get-font-size(2, mobile) ) { + @include media( '>medium' ) { + @include font-size(2, desktop, true, true, true); + } + } +} + +h3, +.h3, +blockquote { + @include font-size(3, mobile, true, true, true); + @if ( get-font-size(3, desktop) != get-font-size(3, mobile) ) { + @include media( '>medium' ) { + @include font-size(3, desktop, true, true, true); + } + } +} + +h4, +.h4 { + @include font-size(4, mobile, true, true, true); + @if ( get-font-size(4, desktop) != get-font-size(4, mobile) ) { + @include media( '>medium' ) { + @include font-size(4, desktop, true, true, true); + } + } +} + +h5, +.h5, +h6, +.h6 { + @include font-size(5, mobile, true, true, true); + @if ( get-font-size(5, desktop) != get-font-size(5, mobile) ) { + @include media( '>medium' ) { + @include font-size(5, desktop, true, true, true); + } + } +} + +@include media( '<=medium' ) { + + .h1-mobile { + @include font-size(1, mobile, true, true, true); + } + + .h2-mobile { + @include font-size(2, mobile, true, true, true); + } + + .h3-mobile { + @include font-size(3, mobile, true, true, true); + } + + .h4-mobile { + @include font-size(4, mobile, true, true, true); + } + + .h5-mobile, + .h6-mobile { + @include font-size(5, mobile, true, true, true); + } +} + +.text-light { + color: color(typography, 2i); + + a { + color: color(typography, 2i); + } +} + +.text-light { + + h1, h2, h3, h4, h5, h6, + .h1, .h2, .h3, .h4, .h5, .h6 { + color: color(typography, 1i) !important; + } +} + +.text-sm { + @include font-size(6, mobile, true, true, true); + @if ( get-font-size(6, desktop) != get-font-size(6, mobile) ) { + @include media( '>medium' ) { + @include font-size(6, desktop, true, true, true); + } + } +} + +.text-xs { + @include font-size(7, mobile, true, true, true); + @if ( get-font-size(7, desktop) != get-font-size(7, mobile) ) { + @include media( '>medium' ) { + @include font-size(7, desktop, true, true, true); + } + } +} + +h1, h2, +.h1, .h2 { + margin-top: 48px; + margin-bottom: 16px; +} + +h3, +.h3 { + margin-top: 36px; + margin-bottom: 12px; +} + +h4, h5, h6, +.h4, .h5, .h6 { + margin-top: 24px; + margin-bottom: 4px; +} + +p { + margin-top: 0; + margin-bottom: 24px; +} + +dfn, cite, em, i { + font-style: italic; +} + +blockquote { + color: color(typography, 2); + font-style: italic; + margin-top: 24px; + margin-bottom: 24px; + margin-left: 24px; + + &::before { + content: "\201C"; + } + + &::after { + content: "\201D"; + } + + p { + display: inline; + } +} + +address { + color: color(typography, 2); + border-width: 1px 0; + border-style: solid; + border-color: color(bg, 3); + padding: 24px 0; + margin: 0 0 24px; +} + +pre, +pre h1, +pre h2, +pre h3, +pre h4, +pre h5, +pre h6, +pre .h1, +pre .h2, +pre .h3, +pre .h4, +pre .h5, +pre .h6 { + @include font-family(pre); +} + +pre, code, kbd, tt, var { + background: color(bg, 2); +} + +pre { + @include font-size(7, mobile, true, true); + margin-bottom: 1.6em; + max-width: 100%; + overflow: auto; + padding: 24px; + margin-top: 24px; + margin-bottom: 24px; +} + +code, kbd, tt, var { + @include font-family(code); + @include font-size(7, mobile, true); + padding: 2px 4px; +} + +abbr, acronym { + cursor: help; +} + +mark, ins { + text-decoration: none; +} + +small { + @include font-size(6, mobile, true, true, true); +} + +b, +strong { + @include font-weight(semibold); +} + +button, +input, +select, +textarea, +label { + @include font-size(5, mobile, true, true); +} diff --git a/html/src/scss/components/_buttons.scss b/html/src/scss/components/_buttons.scss new file mode 100644 index 0000000..180f084 --- /dev/null +++ b/html/src/scss/components/_buttons.scss @@ -0,0 +1,171 @@ +.button { + display: inline-flex; + @include font-size(8, mobile, true, false, true); + @if ( get-font-size(8, desktop) != get-font-size(8, mobile) ) { + @include media( '>medium' ) { + @include font-size(8, desktop, true, false, true); + } + } + @include font-weight(bold); + line-height: 16px; + text-decoration: none !important; + text-transform: uppercase; + background-color: color(bg, 1); + background: color(bg, 1); + color: color(primary, 1) !important; + border: none; + border-radius: 2px; + cursor: pointer; + justify-content: center; + padding: 16px 40px; + height: 48px; + text-align: center; + white-space: nowrap; + + &:active { + outline: 0; + } + + &::before { + border-radius: 2px; + } +} + +.button-shadow { + position: relative; + + &::before { + content: ''; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + box-shadow: 0 8px 16px rgba(color(typography, 1), .12); + mix-blend-mode: multiply; + transition: box-shadow .15s ease; + } + + &:hover { + + &::before { + box-shadow: 0 8px 16px rgba(color(typography, 1), .16); + } + } +} + +.button-sm { + padding: 8px 24px; + height: 32px; + + &.button-shadow { + + &::before { + box-shadow: 0 4px 16px rgba(color(typography, 1), .12); + } + + &:hover { + + &::before { + box-shadow: 0 4px 16px rgba(color(typography, 1), .16); + } + } + } +} + +.button-primary, +.button-secondary { + color: color(typography, 1i) !important; + transition: background .15s ease; +} + +.button-primary { + background: color(primary, 1); + + &:hover { + background: lighten(color(primary, 1), 2%); + } + + &.button-shadow { + + &::before { + box-shadow: 0 8px 16px rgba(color(primary, 1), .24); + } + + &:hover { + + &::before { + box-shadow: 0 8px 16px rgba(color(primary, 1), .32); + } + } + } + + .button-sm { + + &.button-shadow { + + &::before { + box-shadow: 0 4px 16px rgba(color(primary, 1), .24); + } + + &:hover { + + &::before { + box-shadow: 0 4px 16px rgba(color(primary, 1), .32); + } + } + } + } +} + +.button-secondary { + background: color(secondary, 1); + + &:hover { + background: lighten(color(secondary, 1), 3%); + } + + &.button-shadow { + + &::before { + box-shadow: 0 8px 16px rgba(color(secondary, 1), .24); + } + + &:hover { + + &::before { + box-shadow: 0 8px 16px rgba(color(secondary, 1), .32); + } + } + } + + .button-sm { + + &.button-shadow { + + &::before { + box-shadow: 0 4px 16px rgba(color(secondary, 1), .24); + } + + &:hover { + + &::before { + box-shadow: 0 4px 16px rgba(color(secondary, 1), .32); + } + } + } + } +} + +.button-block { + display: flex; + width: 100%; +} + +@include media( '<=medium' ) { + + .button-wide-mobile { + width: 100%; + max-width: 280px; + } +} diff --git a/html/src/scss/layout/_cta.scss b/html/src/scss/layout/_cta.scss new file mode 100644 index 0000000..3dd0103 --- /dev/null +++ b/html/src/scss/layout/_cta.scss @@ -0,0 +1,18 @@ +.cta { + + .section-paragraph { + margin-bottom: 32px; + } +} + +@include media( '>medium' ) { + + .cta { + + .section-paragraph { + margin-bottom: 32px; + padding-left: 72px; + padding-right: 72px; + } + } +} diff --git a/html/src/scss/layout/_features-extended.scss b/html/src/scss/layout/_features-extended.scss new file mode 100644 index 0000000..32c3b47 --- /dev/null +++ b/html/src/scss/layout/_features-extended.scss @@ -0,0 +1,164 @@ +.has-animations { + + .features-extended { + opacity: 0; + } + + &.is-loaded { + + .features-extended { + opacity: 1; + } + } +} + +.features-extended-header { + margin-bottom: 32px; +} + +.features-extended-wrap { + display: flex; + flex-wrap: wrap; + margin-top: -24px; + + &:last-of-type { + margin-bottom: -24px; + } + + &:not(:last-of-type) { + margin-bottom: 24px; + } +} + +.feature-extended { + padding: 24px 0; +} + +.feature-extended-image { + position: relative; + margin-bottom: 32px; + + img, + svg { + width: 100%; + max-width: 296px; + height: auto; + margin-left: auto; + margin-right: auto; + overflow: visible; + } +} + +.feature-extended-body { + text-align: center; +} + +@include media( '>medium' ) { + + .features-extended { + + .container { + /* image width (440) + padding (96) + text width (360) = 896 */ + max-width: 864px + ( get-content-padding(desktop) * 2 ); + } + + .section-inner { + padding-bottom: 128px; + } + + .section-paragraph { + padding-left: 72px; + padding-right: 72px; + margin-bottom: 0; + } + } + + .features-extended-header { + margin-bottom: 80px; + } + + .features-extended-wrap { + margin-top: -64px; + + &:last-of-type { + margin-bottom: -64px; + } + + &:not(:last-of-type) { + margin-bottom: 64px; + } + } + + .feature-extended { + display: flex; + flex-wrap: nowrap; + align-items: stretch; + justify-content: flex-end; + padding: 64px 0; + + .feature-extended-image { + width: 440px; + margin-right: 96px; + margin-bottom: 0; + + img, + svg { + width: auto; + + &.device-mockup { + max-width: 296px; + } + } + } + + &:nth-child(even) { + justify-content: flex-start; + + .feature-extended-image { + order: 1; + margin-left: 96px; + margin-right: 0; + } + } + } + + .feature-extended-body { + /* Align vertically */ + display: flex; + flex-direction: column; + justify-content: center; + /* Align vertically, end */ + flex-shrink: 0; + width: 360px; + text-align: left; + } +} + +@include media( '>large' ) { + + .features-extended { + + .container { + /* image width (440) + padding (64) + text width (392) = 896 */ + max-width: 896px + ( get-content-padding(desktop) * 2 ); + } + } + + .feature-extended { + + .feature-extended-image { + margin-right: 64px; + } + + &:nth-child(even) { + + .feature-extended-image { + margin-left: 64px; + } + } + } + + .feature-extended-body { + width: 392px; + } +} diff --git a/html/src/scss/layout/_footer.scss b/html/src/scss/layout/_footer.scss new file mode 100644 index 0000000..b1829db --- /dev/null +++ b/html/src/scss/layout/_footer.scss @@ -0,0 +1,128 @@ +.site-footer { + position: relative; + background: color(bg, 1i); + + &::before { + content: ''; + position: absolute; + top: -76px; + left: calc(50% - 360px); + width: 720px; + height: 291px; + background-image: url('../images/footer-bg.svg'); + background-size: 720px 291px; + background-repeat: no-repeat; + } + + .footer-particles-container { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + } +} + +.site-footer-bottom { + @include font-size(8, mobile, true, true, true); + @if ( get-font-size(8, desktop) != get-font-size(8, mobile) ) { + @include media( '>medium' ) { + @include font-size(8, desktop, true, true, true); + } + } + color: color(typography, 3); + z-index: 1; + + a { + @include anchor-aspect(footer); + } +} + +.site-footer-inner { + position: relative; /* To display all elements above the background color */ + display: flex; + flex-wrap: wrap; + padding-top: 48px; + padding-bottom: 48px; + @include divider(before, dark); +} + +.footer-brand, +.footer-links, +.footer-social-links, +.footer-copyright { + flex: none; + width: 100%; + display: inline-flex; + justify-content: center; +} + +.footer-brand, +.footer-links, +.footer-social-links { + margin-bottom: 24px; +} + +.footer-links, +.footer-social-links { + + li { + + + li { + margin-left: 16px; + } + } +} + +.footer-social-links { + + li { + display: inline-flex; + + a { + padding: 8px; + } + } +} + +@include media( '>medium' ) { + + .site-footer { + + &::before { + top: -152px; + left: calc(50% - 720px); + width: 1440px; + height: 582px; + background-size: 1440px 582px; + } + } + + .site-footer-inner { + justify-content: space-between; + padding-top: 64px; + padding-bottom: 64px; + } + + .footer-brand, + .footer-links, + .footer-social-links, + .footer-copyright { + flex: 50%; + } + + .footer-brand, + .footer-copyright { + justify-content: flex-start; + } + + .footer-links, + .footer-social-links { + justify-content: flex-end; + } + + .footer-links { + order: 1; + margin-bottom: 0; + } +} diff --git a/html/src/scss/layout/_header.scss b/html/src/scss/layout/_header.scss new file mode 100644 index 0000000..6667f3e --- /dev/null +++ b/html/src/scss/layout/_header.scss @@ -0,0 +1,36 @@ +.site-header { + padding: 24px 0; + position: absolute; + top: 0; + left: 0; + width: 100%; + z-index: 1; +} + +.site-header-inner { + position: relative; /* To display all elements above the background color */ + display: flex; + justify-content: space-between; + align-items: center; +} + +.header-links { + display: inline-flex; + + li { + display: inline-flex; + } + + a:not(.button) { + @include font-size(7, mobile, true, true, true); + @if ( get-font-size(7, desktop) != get-font-size(7, mobile) ) { + @include media( '>medium' ) { + @include font-size(7, desktop, true, true, true); + } + } + @include font-weight(semibold); + @include anchor-aspect(header); + line-height: 16px; + padding: 8px 24px; + } +} diff --git a/html/src/scss/layout/_hero.scss b/html/src/scss/layout/_hero.scss new file mode 100644 index 0000000..93bbdc5 --- /dev/null +++ b/html/src/scss/layout/_hero.scss @@ -0,0 +1,185 @@ +.hero { + position: relative; + padding-top: 128px; + padding-bottom: 88px; + z-index: 0; + + .hero-bg { + position: absolute; + top: 0; + bottom: 42%; + left: 0; + right: 0; + background: color(bg, 1i); + z-index: -2; + } + + .hero-particles-container { + position: absolute; + top: 0; + bottom: 42%; + left: 0; + right: 0; + } + + &::before, + &::after { + content: ''; + position: absolute; + left: calc(50% - 360px); + width: 720px; + background-repeat: no-repeat; + } + + &::before { + top: 0; + height: 159px; + background-image: url('../images/hero-bg-top.svg'); + background-size: 720px 159px; + } + + &::after { + bottom: 42%; + height: 173px; + background-image: url('../images/hero-bg-bottom.svg'); + background-size: 720px 173px; + } +} + +.hero-inner { + position: relative; + z-index: 1; +} + +.hero-copy { + position: relative; /* To display elements above hero illustrations */ + margin-bottom: 48px; +} + +@include media( '>medium' ) { + + .hero { + padding-top: 160px; + padding-bottom: 128px; + + &::before, + &::after { + left: calc(50% - 720px); + width: 1440px; + } + + &::before { + height: 318px; + background-size: 1440px 318px; + } + + &::after { + height: 347px; + background-size: 1440px 347px; + } + } + + .hero-copy { + margin-bottom: 88px; + } + + .hero-paragraph { + padding-left: 72px; + padding-right: 72px; + } +} + +.has-animations { + + .hero .hero-bg, + .hero::before, + .hero::after, + .hero-particles-container, + .site-header, + .hero-title, + .hero-paragraph, + .hero-cta, + .hero .mockup-bg, + .hero .device-mockup { + opacity: 0; + } + + &.is-loaded { + + .hero { + + .hero-bg { + animation: heroBg .6s cubic-bezier(0.215, 0.61, 0.355, 1) forwards; + } + + &::before, + &::after { + animation: heroFadeIn .6s ease forwards .45s; + } + } + + .site-header, + .hero-particles-container, + .hero .mockup-bg { + animation: heroFadeIn .6s ease forwards .45s; + } + + .hero-title { + animation: heroContent .6s cubic-bezier(0.215, 0.61, 0.355, 1) forwards .15s; + } + + .hero-paragraph { + animation: heroContent .6s cubic-bezier(0.215, 0.61, 0.355, 1) forwards .3s; + } + + .hero-cta { + animation: heroContent .6s cubic-bezier(0.215, 0.61, 0.355, 1) forwards .45s; + } + + .hero .device-mockup { + animation: heroMockup .6s ease forwards .6s; + } + } +} + +@keyframes heroBg { + from { + transform: scaleY(0) scaleX(1.2) skewY(30deg); + opacity: 1; + } + to { + transform: scaleY(1) scaleX(1) skewY(0); + opacity: 1; + } +} + +@keyframes heroContent { + from { + transform: translateY(40px) skewY(2deg); + opacity: 0; + } + to { + transform: translateY(0) skewY(0); + opacity: 1; + } +} + +@keyframes heroMockup { + from { + transform: translateY(80px); + opacity: 0; + } + to { + transform: translateY(0); + opacity: 1; + } +} + +@keyframes heroFadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} diff --git a/html/src/scss/layout/_main.scss b/html/src/scss/layout/_main.scss new file mode 100644 index 0000000..286a05c --- /dev/null +++ b/html/src/scss/layout/_main.scss @@ -0,0 +1,36 @@ +.is-boxed { + background: color(bg, 1); +} + +.body-wrap { + background: color(bg, 1); + overflow: hidden; + /* Sticky footer */ + display: flex; + flex-direction: column; + min-height: 100vh; +} + +.boxed-container { + max-width: 1440px; + margin: 0 auto; + @include shadow; +} + +main { + flex: 1 0 auto; +} + +.section-inner { + position: relative; /* To always display inner elements above pseudo decorative stuff */ + padding-top: 48px; + padding-bottom: 48px; +} + +@include media( '>medium' ) { + + .section-inner { + padding-top: 88px; + padding-bottom: 88px; + } +} diff --git a/html/src/scss/layout/_mockups.scss b/html/src/scss/layout/_mockups.scss new file mode 100644 index 0000000..611646d --- /dev/null +++ b/html/src/scss/layout/_mockups.scss @@ -0,0 +1,26 @@ +.mockup-container { + position: relative; +} + +.mockup-bg { + pointer-events: none; + + img, + svg { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: auto !important; + height: auto; + max-width: 300% !important; + } +} + +.device-mockup { + position: relative; + width: 350px; + height: auto; + margin: 0 auto; + z-index: 1; +} diff --git a/html/src/scss/style.scss b/html/src/scss/style.scss new file mode 100644 index 0000000..7d4e7fc --- /dev/null +++ b/html/src/scss/style.scss @@ -0,0 +1,69 @@ +/*-------------------------------------------------------------- +# Variables, functions and mixins +--------------------------------------------------------------*/ +@import "abstracts/variables", + "abstracts/functions", + "abstracts/mixins", + 'abstracts/include-media'; + +/*-------------------------------------------------------------- +1.0 Normalize + * normalize.css v7.0.0 | MIT License + * github.com/necolas/normalize.css +--------------------------------------------------------------*/ +@import "normalize"; + +/*-------------------------------------------------------------- +# Base +--------------------------------------------------------------*/ +@import "base/base"; + +/*-------------------------------------------------------------- +# Typography +--------------------------------------------------------------*/ +@import "base/typography"; + +/*-------------------------------------------------------------- +# Helpers +--------------------------------------------------------------*/ +@import "base/helpers"; + +/*-------------------------------------------------------------- +# Buttons +--------------------------------------------------------------*/ +@import "components/buttons"; + +/*-------------------------------------------------------------- +# Header +--------------------------------------------------------------*/ +@import "layout/header"; + +/*-------------------------------------------------------------- +# Hero +--------------------------------------------------------------*/ +@import "layout/hero"; + +/*-------------------------------------------------------------- +# Mockup +--------------------------------------------------------------*/ +@import "layout/mockups"; + +/*-------------------------------------------------------------- +# Features extended +--------------------------------------------------------------*/ +@import "layout/features-extended"; + +/*-------------------------------------------------------------- +# CTA +--------------------------------------------------------------*/ +@import "layout/cta"; + +/*-------------------------------------------------------------- +# Site content +--------------------------------------------------------------*/ +@import "layout/main"; + +/*-------------------------------------------------------------- +# Footer +--------------------------------------------------------------*/ +@import "layout/footer";