diff --git a/.eslintrc.json b/.eslintrc.json index b7bff54145143b..4a87d628a733a9 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -17,6 +17,7 @@ "plugin:jsx-a11y/recommended", "prettier" ], + "plugins": ["no-only-tests"], "globals": { "Promise": true, "window": true, @@ -31,11 +32,12 @@ } }, "rules": { - "import/named": 2, - "import/no-named-as-default": 0, - "import/no-named-as-default-member": 0, - "import/order": 2, - "react/prop-types": "off" + "import/named": "error", + "import/no-named-as-default": "off", + "import/no-named-as-default-member": "off", + "import/order": "error", + "react/prop-types": "off", + "no-only-tests/no-only-tests": "error" }, "overrides": [ { @@ -66,7 +68,20 @@ "leadingUnderscore": "allow", "trailingUnderscore": "allow" }, - + { + "selector": [ + "classProperty", + "objectLiteralProperty", + "typeProperty", + "classMethod", + "objectLiteralMethod", + "typeMethod", + "accessor", + "enumMember" + ], + "format": null, + "modifiers": ["requiresQuotes"] + }, { "selector": "variable", "format": ["camelCase", "UPPER_CASE", "PascalCase"], diff --git a/.github/workflows/autoclose.yml b/.github/workflows/autoclose.yml index 79ce9508339739..68ccb947d14082 100644 --- a/.github/workflows/autoclose.yml +++ b/.github/workflows/autoclose.yml @@ -1,4 +1,4 @@ -name: Autoclose +name: GitHub - Autoclose Invalid PRs on: pull_request_target: branches: @@ -10,7 +10,7 @@ jobs: autoclose: runs-on: ubuntu-20.04 steps: - - uses: actions/github-script@v6 + - uses: actions/github-script@c713e510dbd7d213d92d41b7a7805a986f4c5c66 # tag=v6 with: github-token: ${{secrets.GITHUB_TOKEN}} script: | diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 843e1e1a8e443d..b602ca2bc36038 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,5 +1,4 @@ -name: 'CodeQL' - +name: CI - Run CodeQL Analysis on: push: branches: [main] @@ -31,10 +30,10 @@ jobs: language: ['javascript'] steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Setup CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@d5cec099b513fccc2cfcc9247113ecc9edbdacc5 # tag=v1 with: languages: ${{ matrix.language }} - name: Perform Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@d5cec099b513fccc2cfcc9247113ecc9edbdacc5 # tag=v1 diff --git a/.github/workflows/codesee-diagram.yml b/.github/workflows/codesee-diagram.yml index 5eaa815fd559a1..d5849fd7a6538e 100644 --- a/.github/workflows/codesee-diagram.yml +++ b/.github/workflows/codesee-diagram.yml @@ -1,3 +1,4 @@ +name: CI - Create CodeSee Maps on: workflow_dispatch: schedule: @@ -8,8 +9,6 @@ on: - 'docs/**' types: [opened, synchronize, reopened] -name: CodeSee Map - jobs: test_map_action: runs-on: ubuntu-20.04 @@ -19,7 +18,7 @@ jobs: steps: - name: checkout id: checkout - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 with: repository: ${{ github.event.pull_request.head.repo.full_name }} ref: ${{ github.event.pull_request.head.ref }} @@ -31,7 +30,7 @@ jobs: uses: Codesee-io/codesee-detect-languages-action@latest - name: Configure JDK 16 - uses: actions/setup-java@v3 + uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # tag=v3 if: ${{ fromJSON(steps.detect-languages.outputs.languages).java }} with: java-version: '16' @@ -40,14 +39,13 @@ jobs: # CodeSee Maps Go support uses a static binary so there's no setup step required. - name: Configure Node.js 16 - uses: actions/setup-node@v3 + uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3 if: ${{ fromJSON(steps.detect-languages.outputs.languages).javascript }} with: node-version: '16' - cache: npm - name: Configure Python 3.x - uses: actions/setup-python@v3 + uses: actions/setup-python@b55428b1882923874294fa556849718a1d7f2ca5 # tag=v4 if: ${{ fromJSON(steps.detect-languages.outputs.languages).python }} with: python-version: '3.x' diff --git a/.github/workflows/crowdin-download.client-ui.yml b/.github/workflows/crowdin-download.client-ui.yml index d8205bb2a4d1dc..9e22c07852cd67 100644 --- a/.github/workflows/crowdin-download.client-ui.yml +++ b/.github/workflows/crowdin-download.client-ui.yml @@ -1,4 +1,4 @@ -name: Crowdin Client UI Download +name: i18n - Download Client UI on: workflow_dispatch: schedule: @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout Source Files - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 with: token: ${{ secrets.CROWDIN_CAMPERBOT_PAT }} @@ -209,6 +209,35 @@ jobs: # Uncomment below to debug # dryrun_action: true + ##### Download German ##### + - name: Crowdin Download German Translations + uses: crowdin/github-action@master + # options: https://github.com/crowdin/github-action/blob/master/action.yml + with: + # uploads + upload_sources: false + upload_translations: false + auto_approve_imported: false + import_eq_suggestions: false + + # downloads + download_translations: true + download_language: de + skip_untranslated_files: false + export_only_approved: true + + push_translations: false + + # pull-request + create_pull_request: false + + # global options + config: './crowdin-config.yml' + base_url: ${{ secrets.CROWDIN_BASE_URL_FCC }} + + # Uncomment below to debug + # dryrun_action: true + # Create Commit - name: Commit Changes uses: freecodecamp/crowdin-action@main diff --git a/.github/workflows/crowdin-download.curriculum.yml b/.github/workflows/crowdin-download.curriculum.yml index dfa9883ae9a74d..95a337c7c208f4 100644 --- a/.github/workflows/crowdin-download.curriculum.yml +++ b/.github/workflows/crowdin-download.curriculum.yml @@ -1,4 +1,4 @@ -name: Crowdin Curriculum Download +name: i18n - Download Curriculum on: workflow_dispatch: schedule: @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout Source Files - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 with: token: ${{ secrets.CROWDIN_CAMPERBOT_PAT }} @@ -209,6 +209,35 @@ jobs: # Uncomment below to debug # dryrun_action: true + ##### Download German ##### + - name: Crowdin Download German Translations + uses: crowdin/github-action@master + # options: https://github.com/crowdin/github-action/blob/master/action.yml + with: + # uploads + upload_sources: false + upload_translations: false + auto_approve_imported: false + import_eq_suggestions: false + + # downloads + download_translations: true + download_language: de + skip_untranslated_files: true + export_only_approved: true + + push_translations: false + + # pull-request + create_pull_request: false + + # global options + config: './crowdin-config.yml' + base_url: ${{ secrets.CROWDIN_BASE_URL_FCC }} + + # Uncomment below to debug + # dryrun_action: true + # Create Commit - name: Commit Changes uses: freecodecamp/crowdin-action@main diff --git a/.github/workflows/crowdin-download.docs.yml b/.github/workflows/crowdin-download.docs.yml index 4a14c4c6b20d81..dceeb4c2ebc90c 100644 --- a/.github/workflows/crowdin-download.docs.yml +++ b/.github/workflows/crowdin-download.docs.yml @@ -1,4 +1,4 @@ -name: Crowdin Docs Download +name: i18n - Download Docs on: workflow_dispatch: schedule: @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout Source Files - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 with: token: ${{ secrets.CROWDIN_CAMPERBOT_PAT }} diff --git a/.github/workflows/crowdin-upload.client-ui.yml b/.github/workflows/crowdin-upload.client-ui.yml index dbee7d79a5f573..8aea723250c5b2 100644 --- a/.github/workflows/crowdin-upload.client-ui.yml +++ b/.github/workflows/crowdin-upload.client-ui.yml @@ -1,4 +1,4 @@ -name: Crowdin Client UI Upload +name: i18n - Upload Client UI on: workflow_dispatch: schedule: @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout Source Files - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Generate Crowdin Config uses: freecodecamp/crowdin-action@main diff --git a/.github/workflows/crowdin-upload.curriculum.yml b/.github/workflows/crowdin-upload.curriculum.yml index 314660afb337f1..65aeefdc90927e 100644 --- a/.github/workflows/crowdin-upload.curriculum.yml +++ b/.github/workflows/crowdin-upload.curriculum.yml @@ -1,4 +1,4 @@ -name: Crowdin Curriculum Upload +name: i18n - Upload Curriculum on: workflow_dispatch: schedule: @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout Source Files - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Generate Crowdin Config uses: freecodecamp/crowdin-action@main diff --git a/.github/workflows/crowdin-upload.docs.yml b/.github/workflows/crowdin-upload.docs.yml index 090556b1c13932..61efcd71feb1b8 100644 --- a/.github/workflows/crowdin-upload.docs.yml +++ b/.github/workflows/crowdin-upload.docs.yml @@ -1,4 +1,4 @@ -name: Crowdin Docs Upload +name: i18n - Upload Docs on: workflow_dispatch: schedule: @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout Source Files - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Generate Crowdin Config uses: freecodecamp/crowdin-action@main diff --git a/.github/workflows/cypress-third-party.yml b/.github/workflows/cypress-third-party.yml new file mode 100644 index 00000000000000..f2dc1916374b8d --- /dev/null +++ b/.github/workflows/cypress-third-party.yml @@ -0,0 +1,67 @@ +name: CI - Cypress (e2e) 3rd party donation tests +on: + push: + branches: + - main + +jobs: + do-everything: + name: Build + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + services: + mongodb: + image: mongo:4 + ports: + - 27017:27017 + # We need mailhog to catch any emails the api tries to send. + mailhog: + image: mailhog/mailhog + ports: + - 1025:1025 + + steps: + - name: Checkout Source Files + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 + + - name: Checkout client-config + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 + with: + repository: freeCodeCamp/client-config + path: client-config + + - name: Use Node.js 16.x + uses: actions/setup-node@eeb10cff27034e7acf239c5d29f62154018672fd # tag=v3 + with: + node-version: 16.x + cache: 'npm' + + - name: Set freeCodeCamp Environment Variables + run: | + sed '/STRIPE/d; /PAYPAL/d;' sample.env > .env + echo 'STRIPE_PUBLIC_KEY=${{ secrets.STRIPE_PUBLIC_KEY }}' >> .env + echo 'STRIPE_SECRET_KEY=${{ secrets.STRIPE_SECRET_KEY }}' >> .env + echo 'PAYPAL_CLIENT_ID=${{ secrets.PAYPAL_CLIENT_ID }}' >> .env + echo 'PAYPAL_SECRET=${{ secrets.PAYPAL_SECRET }}' >> .env + + - name: Install and Build + run: | + npm ci + npm run build + - name: Seed Database + run: npm run seed + - name: Move serve.json to Public Folder + run: cp client-config/serve.json client/public/serve.json + + - name: Cypress run + uses: cypress-io/github-action@v2 + with: + record: ${{ env.CYPRESS_RECORD_KEY != 0 }} + start: npm run start-ci + wait-on: http://localhost:8000 + wait-on-timeout: 1200 + config: baseUrl=http://localhost:8000 + browser: chrome + headless: true + spec: cypress/integration/third-party/*.js diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 41baaf1c9435e3..3ba03a196cb86d 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -1,4 +1,4 @@ -name: Cypress +name: CI - Cypress (e2e) tests on: push: paths-ignore: @@ -16,16 +16,16 @@ jobs: steps: - name: Checkout Source Files - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Checkout client-config - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 with: repository: freeCodeCamp/client-config path: client-config - name: Use Node.js 16.x - uses: actions/setup-node@v3 + uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3 with: node-version: 16.x cache: 'npm' @@ -46,13 +46,13 @@ jobs: run: tar -cf client-artifact.tar client/public - name: Upload Client Artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # tag=v3 with: name: client-artifact path: client-artifact.tar - name: Upload Webpack Stats - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # tag=v3 with: name: webpack-stats path: client/public/stats.json @@ -81,18 +81,15 @@ jobs: - 1025:1025 steps: - # We use .npmrc to set the default version to 0, and prevents download during development. - # This installs it specifically in the CI runs. - name: Set Action Environment Variables run: | echo "CYPRESS_RECORD_KEY=${{ secrets.CYPRESS_RECORD_KEY }}" >> $GITHUB_ENV echo "GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> $GITHUB_ENV - echo "CYPRESS_INSTALL_BINARY=7.7.0" >> $GITHUB_ENV - name: Checkout Source Files - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 # tag=v3 with: name: client-artifact @@ -101,8 +98,16 @@ jobs: tar -xf client-artifact.tar rm client-artifact.tar + - name: Downgrade Firefox + run: | + curl https://ftp.mozilla.org/pub/firefox/releases/101.0/linux-x86_64/en-US/firefox-101.0.tar.bz2 --output firefox-101.0.tar.bz2 + tar -xjf firefox-101.0.tar.bz2 + sudo mv firefox /opt/ + sudo mv /usr/bin/firefox /usr/bin/firefox_old + sudo ln -s /opt/firefox/firefox /usr/bin/firefox + - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3 with: node-version: ${{ matrix.node-version }} cache: 'npm' @@ -130,4 +135,6 @@ jobs: config: baseUrl=http://localhost:8000 browser: ${{ matrix.browsers }} headless: true - spec: ${{ matrix.spec }} + spec: | + ${{ matrix.spec }} + cypress/integration/default/**/*.js diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml deleted file mode 100644 index 8966511e0545b1..00000000000000 --- a/.github/workflows/dependency-review.yml +++ /dev/null @@ -1,20 +0,0 @@ -# Dependency Review Action -# -# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging. -# -# Source repository: https://github.com/actions/dependency-review-action -# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement -name: 'Dependency Review' -on: [pull_request] - -permissions: - contents: read - -jobs: - dependency-review: - runs-on: ubuntu-latest - steps: - - name: 'Checkout Repository' - uses: actions/checkout@v3 - - name: 'Dependency Review' - uses: actions/dependency-review-action@v1 diff --git a/.github/workflows/i18n-builds.yml b/.github/workflows/i18n-builds.yml new file mode 100644 index 00000000000000..5027b5664209f6 --- /dev/null +++ b/.github/workflows/i18n-builds.yml @@ -0,0 +1,32 @@ +name: i18n - Build Validation +on: + push: + branches: + - main + +jobs: + ci: + name: Validate i18n Builds + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [16.x] + + steps: + - name: Checkout Source Files + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 + + - name: Use Node.js v${{ matrix.node-version }} + uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3 + with: + node-version: ${{ matrix.node-version }} + + - name: Set freeCodeCamp Environment Variables + run: cp sample.env .env + + - name: Install Dependencies + run: npm ci + + - name: Validate Challenge Files + run: npm run audit-challenges diff --git a/.github/workflows/i18n-prs.yml b/.github/workflows/i18n-prs.yml new file mode 100644 index 00000000000000..8a3fddc0b919be --- /dev/null +++ b/.github/workflows/i18n-prs.yml @@ -0,0 +1,48 @@ +name: i18n - Curriculum PR Validation +on: + pull_request: + branches: + - main + +jobs: + ci: + name: Validate i18n Builds + runs-on: ubuntu-latest + # run only on PRs that camperbot opens with title that matches the curriculum sync + if: ${{ github.event.pull_request.user.login == 'camperbot' && contains(github.event.pull_request.title, 'chore(i18n,learn)') }} + strategy: + matrix: + node-version: [16.x] + + steps: + - name: Checkout Source Files + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 + + - name: Use Node.js v${{ matrix.node-version }} + uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3 + with: + node-version: ${{ matrix.node-version }} + + - name: Set freeCodeCamp Environment Variables + run: cp sample.env .env + + - name: Install Dependencies + run: npm ci + + - name: Validate Challenge Files + id: validate + run: npm run audit-challenges + + - name: Create Comment + # Run if the validate challenge files step fails, specifically. Note that we need the failure() call for this step to trigger if the action fails. + if: ${{ failure() && steps.validate.conclusion == 'failure' }} + uses: actions/github-script@c713e510dbd7d213d92d41b7a7805a986f4c5c66 # tag=v6 + with: + github-token: ${{secrets.CAMPERBOT_NO_TRANSLATE}} + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: "Hey @freecodecamp/i18n, it looks like we have new English curriculum files that need to be translated." + }) diff --git a/.github/workflows/labeler.yaml b/.github/workflows/labeler.yaml index 9d29a16e5aed14..ffe5a5d059db67 100644 --- a/.github/workflows/labeler.yaml +++ b/.github/workflows/labeler.yaml @@ -1,4 +1,4 @@ -name: 'Pull Request Labeler' +name: GitHub - Label PRs on: - pull_request_target @@ -14,7 +14,7 @@ jobs: pull-requests: write runs-on: ubuntu-20.04 steps: - - uses: actions/labeler@v4 + - uses: actions/labeler@9fd24f1f9d6ceb64ba34d181b329ee72f99978a0 # tag=v4 with: repo-token: '${{ secrets.GITHUB_TOKEN }}' sync-labels: true diff --git a/.github/workflows/no-prs-to-translation.yml b/.github/workflows/no-prs-to-translation.yml index 252031ea0c00e8..9b40ba97b00b8b 100644 --- a/.github/workflows/no-prs-to-translation.yml +++ b/.github/workflows/no-prs-to-translation.yml @@ -1,4 +1,4 @@ -name: No translate on GitHub +name: GitHub - No translations via PRs on: pull_request_target: branches: @@ -15,7 +15,7 @@ jobs: has-translation: runs-on: ubuntu-20.04 steps: - - uses: actions/github-script@v6 + - uses: actions/github-script@c713e510dbd7d213d92d41b7a7805a986f4c5c66 # tag=v6 with: github-token: ${{secrets.CAMPERBOT_NO_TRANSLATE}} script: | @@ -30,7 +30,7 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: "Thanks for your pull-request.\n\nWe are no longer accepting changes to the non-English versions of files in parts of this codebase. This pull-request seems to change some of those. Please visit [our contributing guidelines](https://contribute.freecodecamp.org) to learn more about translating freeCodeCamp's resources.\n\nAs always, we value all of your contributions.\n\nHappy contributing!\n\n---\n_**Note:** This message was automatically generated by a bot. If you feel this message is in error or would like help resolving it, feel free to reach us [in our contributor chat](https://chat.freecodecamp.org/channel/contributors)._" + body: "Thanks for your pull-request.\n\nWe are no longer accepting changes to the non-English versions of files in parts of this codebase. This pull-request seems to change some of those. Please visit [our contributing guidelines](https://contribute.freecodecamp.org) to learn more about translating freeCodeCamp's resources.\n\nAs always, we value all of your contributions.\n\nHappy contributing!\n\n---\n_**Note:** This message was automatically generated by a bot. If you feel this message is in error or would like help resolving it, feel free to reach us [in our contributor chat](https://discord.gg/PRyKn3Vbay)._" }) } else if (isDev.status === 200) { core.setFailed('This PR appears to touch translated curriculum files, but since you are on the dev team there is no message.'); diff --git a/.github/workflows/node.js-tests-upcoming.yml b/.github/workflows/node.js-tests-upcoming.yml index 547b70287badab..601db6e258668a 100644 --- a/.github/workflows/node.js-tests-upcoming.yml +++ b/.github/workflows/node.js-tests-upcoming.yml @@ -1,4 +1,4 @@ -name: Node.js CI - Test Upcoming +name: CI - Node.js Test Upcoming on: push: branches: @@ -25,10 +25,10 @@ jobs: steps: - name: Checkout Source Files - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3 with: node-version: ${{ matrix.node-version }} cache: 'npm' @@ -61,13 +61,12 @@ jobs: steps: - name: Checkout Source Files - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3 with: node-version: ${{ matrix.node-version }} - cache: npm - name: Set Environment variables run: | diff --git a/.github/workflows/node.js-tests.yml b/.github/workflows/node.js-tests.yml index 01245394a68a6e..68ca47d176c570 100644 --- a/.github/workflows/node.js-tests.yml +++ b/.github/workflows/node.js-tests.yml @@ -1,4 +1,4 @@ -name: Node.js CI +name: CI - Node.js Test Current on: push: branches-ignore: @@ -20,7 +20,7 @@ jobs: steps: - name: Checkout Source Files - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Check number of lockfiles run: | @@ -31,7 +31,7 @@ jobs: fi - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3 with: node-version: ${{ matrix.node-version }} cache: 'npm' @@ -66,13 +66,12 @@ jobs: steps: - name: Checkout Source Files - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3 with: node-version: ${{ matrix.node-version }} - cache: npm - name: Set Environment variables run: | @@ -101,13 +100,12 @@ jobs: steps: - name: Checkout Source Files - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3 with: node-version: ${{ matrix.node-version }} - cache: npm - name: Set Environment variables run: | @@ -138,13 +136,12 @@ jobs: steps: - name: Checkout Source Files - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3 with: node-version: ${{ matrix.node-version }} - cache: npm - name: Set Environment variables run: | diff --git a/.gitignore b/.gitignore index 286a2e722b191d..63bd214a9e96cb 100644 --- a/.gitignore +++ b/.gitignore @@ -169,6 +169,7 @@ config/certification-settings.js ### Generated utils files ### utils/slugs.js utils/slugs.test.js +utils/index.js ### vim ### # Swap @@ -206,6 +207,7 @@ curriculum/dist curriculum/build client/static/_redirects client/static/mobile +client/static/curriculum-data ### UI Components ### tools/ui-components/dist diff --git a/.gitpod.yml b/.gitpod.yml index 76a4c749236f49..46ccd89059a9b5 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -14,6 +14,10 @@ ports: onOpen: ignore - port: 9230 # client node debug onOpen: ignore + - port: 3200 # challenge editor api + visibility: public + - port: 3300 # challenge editor client + visibility: public tasks: - before: | @@ -22,6 +26,8 @@ tasks: export HOME_LOCATION=$(gp url 8000) export API_LOCATION=$(gp url 3000) export CYPRESS_BASE_URL=$(gp url 8000) + export REACT_APP_CHALLENGE_EDITOR_API_LOCATION=$(gp url 3200) + export CHALLENGE_EDITOR_CLIENT_LOCATION=$(gp url 3300) ' >> ~/.bashrc; exit; diff --git a/.prettierignore b/.prettierignore index 8e56696477f80d..688a16d9c73c85 100644 --- a/.prettierignore +++ b/.prettierignore @@ -11,6 +11,7 @@ client/i18n/**/*.json docs/i18n utils/slugs.js utils/slugs.test.js +utils/index.js **/package-lock.json web/.next -curriculum-server/data/curriculum.json +curriculum-server/data/curriculum.json \ No newline at end of file diff --git a/README.md b/README.md index 42c980c7c08ca0..cba5e2d6053ab1 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![first-timers-only Friendly](https://img.shields.io/badge/first--timers--only-friendly-blue.svg)](http://www.firsttimersonly.com/) [![Open Source Helpers](https://www.codetriage.com/freecodecamp/freecodecamp/badges/users.svg)](https://www.codetriage.com/freecodecamp/freecodecamp) [![Setup Automated](https://img.shields.io/badge/setup-automated-blue?logo=gitpod)](https://gitpod.io/from-referrer/) -[![Rocket.Chat](https://chat.freecodecamp.org/api/v1/shield.svg?type=online&icon=false&name=Chat)](https://chat.freecodecamp.org/) +[![Discord](https://img.shields.io/discord/692816967895220344)](https://discord.gg/PRyKn3Vbay) ## freeCodeCamp.org's open-source codebase and curriculum @@ -36,18 +36,26 @@ The one exception to this is if we discover violations of our [Academic Honesty Here are our ten core certifications: -#### 1. [Responsive Web Design Certification](https://www.freecodecamp.org/learn/responsive-web-design/) +#### 1. [Responsive Web Design Certification](https://www.freecodecamp.org/learn/2022/responsive-web-design/) -- [Basic HTML and HTML5](https://www.freecodecamp.org/learn/responsive-web-design/#basic-html-and-html5) -- [Basic CSS](https://www.freecodecamp.org/learn/responsive-web-design/#basic-css) -- [Applied Visual Design](https://www.freecodecamp.org/learn/responsive-web-design/#applied-visual-design) -- [Applied Accessibility](https://www.freecodecamp.org/learn/responsive-web-design/#applied-accessibility) -- [Responsive Web Design Principles](https://www.freecodecamp.org/learn/responsive-web-design/#responsive-web-design-principles) -- [CSS Flexbox](https://www.freecodecamp.org/learn/responsive-web-design/#css-flexbox) -- [CSS Grid](https://www.freecodecamp.org/learn/responsive-web-design/#css-grid) +- [Learn HTML by Building a Cat Photo App](https://www.freecodecamp.org/learn/2022/responsive-web-design/#learn-html-by-building-a-cat-photo-app) +- [Learn Basic CSS by Building a Cafe Menu](https://www.freecodecamp.org/learn/2022/responsive-web-design/#learn-basic-css-by-building-a-cafe-menu) +- [Learn CSS Colors by Building a Set of Colored Markers](https://www.freecodecamp.org/learn/2022/responsive-web-design/#learn-css-colors-by-building-a-set-of-colored-markers) +- [Learn HTML Forms by Building a Registration Form](https://www.freecodecamp.org/learn/2022/responsive-web-design/#learn-html-forms-by-building-a-registration-form) +- [Learn the CSS Box Model by Building a Rothko Painting](https://www.freecodecamp.org/learn/2022/responsive-web-design/#learn-the-css-box-model-by-building-a-rothko-painting) +- [Learn CSS Flexbox by Building a Photo Gallery](https://www.freecodecamp.org/learn/2022/responsive-web-design/#learn-css-flexbox-by-building-a-photo-gallery) +- [Learn Typography by Building a Nutrition Label](https://www.freecodecamp.org/learn/2022/responsive-web-design/#learn-typography-by-building-a-nutrition-label) +- [Learn Accessibility by Building a Quiz](https://www.freecodecamp.org/learn/2022/responsive-web-design/#learn-accessibility-by-building-a-quiz) +- [Learn More About CSS Pseudo Selectors By Building A Balance Sheet](https://www.freecodecamp.org/learn/2022/responsive-web-design/#learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet) +- [Learn Intermediate CSS by Building a Picasso Painting](https://www.freecodecamp.org/learn/2022/responsive-web-design/#learn-intermediate-css-by-building-a-picasso-painting) +- [Learn Responsive Web Design by Building a Piano](https://www.freecodecamp.org/learn/2022/responsive-web-design/#learn-responsive-web-design-by-building-a-piano) +- [Learn CSS Variables by Building a City Skyline](https://www.freecodecamp.org/learn/2022/responsive-web-design/#learn-css-variables-by-building-a-city-skyline) +- [Learn CSS Grid by Building a Magazine](https://www.freecodecamp.org/learn/2022/responsive-web-design/#learn-css-grid-by-building-a-magazine) +- [Learn CSS Transforms by Building a Penguin](https://www.freecodecamp.org/learn/2022/responsive-web-design/#learn-css-transforms-by-building-a-penguin) +- [Learn CSS Animations by Building a Ferris Wheel](https://www.freecodecamp.org/learn/2022/responsive-web-design/#learn-css-animation-by-building-a-ferris-wheel)

- **Projects**: [Tribute Page](https://www.freecodecamp.org/learn/responsive-web-design/responsive-web-design-projects/build-a-tribute-page), [Survey Form](https://www.freecodecamp.org/learn/responsive-web-design/responsive-web-design-projects/build-a-survey-form), [Product Landing Page](https://www.freecodecamp.org/learn/responsive-web-design/responsive-web-design-projects/build-a-product-landing-page), [Technical Documentation Page](https://www.freecodecamp.org/learn/responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page), [Personal Portfolio Webpage](https://www.freecodecamp.org/learn/responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage) + **Projects**: [Survey Form](https://www.freecodecamp.org/learn/2022/responsive-web-design/build-a-survey-form-project/build-a-survey-form), [Tribute Page](https://www.freecodecamp.org/learn/2022/responsive-web-design/build-a-tribute-page-project/build-a-tribute-page), [Technical Documentation Page](https://www.freecodecamp.org/learn/2022/responsive-web-design/build-a-technical-documentation-page-project/build-a-technical-documentation-page), [Product Landing Page](https://www.freecodecamp.org/learn/2022/responsive-web-design/build-a-product-landing-page-project/build-a-product-landing-page), [Personal Portfolio Webpage](https://www.freecodecamp.org/learn/2022/responsive-web-design/build-a-personal-portfolio-webpage-project/build-a-personal-portfolio-webpage) #### 2. [JavaScript Algorithms and Data Structures Certification](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/) @@ -154,7 +162,7 @@ Our community also has: - A [forum](https://forum.freecodecamp.org) where you can usually get programming help or project feedback within hours. - A [YouTube channel](https://youtube.com/freecodecamp) with free courses on Python, SQL, Android, and a wide variety of other technologies. - A [technical publication](https://www.freecodecamp.org/news) with thousands of programming tutorials and articles about math and computer science. -- A [chat server](https://chat.freecodecamp.org/home) where you can hang out and talk with developers and people who are learning to code. +- A [Discord server](https://discord.gg/Z7Fm39aNtZ) where you can hang out and talk with developers and people who are learning to code. > #### [Join the community here](https://www.freecodecamp.org/signin). diff --git a/api-server/package.json b/api-server/package.json index c80c0e0b1bd689..a234fbda1b02b9 100644 --- a/api-server/package.json +++ b/api-server/package.json @@ -29,14 +29,14 @@ }, "dependencies": { "@freecodecamp/loopback-component-passport": "1.2.0", - "@sentry/node": "6.18.0", + "@sentry/node": "6.19.7", "accepts": "1.3.8", "axios": "0.23.0", "bad-words": "3.0.4", - "body-parser": "1.19.2", + "body-parser": "1.20.0", "compression": "1.7.4", "connect-mongo": "3.2.0", - "cookie-parser": "1.4.5", + "cookie-parser": "1.4.6", "cors": "2.8.5", "cross-env": "7.0.3", "csurf": "1.11.0", @@ -45,8 +45,8 @@ "dedent": "0.7.0", "dotenv": "6.2.0", "express-flash": "0.0.2", - "express-session": "1.17.2", - "express-validator": "6.14.0", + "express-session": "1.17.3", + "express-validator": "6.14.1", "helmet": "3.23.3", "helmet-csp": "2.10.0", "jsonwebtoken": "8.5.1", @@ -55,11 +55,11 @@ "loopback-boot": "2.28.0", "loopback-connector-mongodb": "4.2.0", "method-override": "3.0.0", - "moment": "2.29.1", + "moment": "2.29.3", "moment-timezone": "0.5.33", "mongodb": "3.6.9", "morgan": "1.10.0", - "nanoid": "3.2.0", + "nanoid": "3.3.4", "nodemailer-ses-transport": "1.5.1", "passport": "0.4.1", "passport-auth0": "1.4.2", @@ -69,22 +69,22 @@ "rx": "4.1.0", "stripe": "8.205.0", "uuid": "3.4.0", - "validator": "13.6.0" + "validator": "13.7.0" }, "devDependencies": { - "@babel/cli": "7.17.6", - "@babel/core": "7.15.8", - "@babel/node": "7.16.8", - "@babel/plugin-proposal-class-properties": "7.14.5", - "@babel/plugin-proposal-object-rest-spread": "7.17.3", - "@babel/plugin-proposal-optional-chaining": "7.14.5", - "@babel/preset-env": "7.15.8", - "@babel/register": "7.15.3", + "@babel/cli": "7.17.10", + "@babel/core": "7.18.0", + "@babel/node": "7.17.10", + "@babel/plugin-proposal-class-properties": "7.17.12", + "@babel/plugin-proposal-object-rest-spread": "7.18.0", + "@babel/plugin-proposal-optional-chaining": "7.17.12", + "@babel/preset-env": "7.18.0", + "@babel/register": "7.17.7", "babel-core": "7.0.0-bridge.0", "babel-plugin-transform-function-bind": "6.22.0", "babel-plugin-transform-imports": "1.5.1", "loopback-component-explorer": "6.4.0", - "nodemon": "2.0.14", - "smee-client": "1.2.2" + "nodemon": "2.0.16", + "smee-client": "1.2.3" } } diff --git a/api-server/src/common/models/user.json b/api-server/src/common/models/user.json index 9469518ada7116..9d279d3014c10e 100644 --- a/api-server/src/common/models/user.json +++ b/api-server/src/common/models/user.json @@ -317,6 +317,10 @@ "type": "boolean", "default": false }, + "keyboardShortcuts": { + "type": "boolean", + "default": false + }, "profileUI": { "type": "object", "default": { diff --git a/api-server/src/server/boot/settings.js b/api-server/src/server/boot/settings.js index 8d0bdf44c702c5..d1a4b4006cf6e1 100644 --- a/api-server/src/server/boot/settings.js +++ b/api-server/src/server/boot/settings.js @@ -45,6 +45,11 @@ export default function settingsController(app) { api.put('/update-user-flag', ifNoUser401, updateUserFlag); api.put('/update-my-socials', ifNoUser401, updateMySocials); api.put('/update-my-sound', ifNoUser401, updateMySound); + api.put( + '/update-my-keyboard-shortcuts', + ifNoUser401, + updateMyKeyboardShortcuts + ); api.put('/update-my-honesty', ifNoUser401, updateMyHonesty); api.put('/update-my-quincy-email', ifNoUser401, updateMyQuincyEmail); @@ -234,6 +239,13 @@ function updateMySound(...args) { createUpdateUserProperties(buildUpdate, validate)(...args); } +function updateMyKeyboardShortcuts(...args) { + const buildUpdate = body => _.pick(body, 'keyboardShortcuts'); + const validate = ({ keyboardShortcuts }) => + typeof keyboardShortcuts === 'boolean'; + createUpdateUserProperties(buildUpdate, validate)(...args); +} + function updateMyHonesty(...args) { const buildUpdate = body => _.pick(body, 'isHonest'); const validate = ({ isHonest }) => isHonest === true; @@ -271,6 +283,7 @@ function updateUserFlag(req, res, next) { const allowedKeys = [ 'theme', 'sound', + 'keyboardShortcuts', 'isHonest', 'portfolio', 'sendQuincyEmail', diff --git a/api-server/src/server/middlewares/csurf.js b/api-server/src/server/middlewares/csurf.js index 2d7a70f2483182..4a7b12056ad352 100644 --- a/api-server/src/server/middlewares/csurf.js +++ b/api-server/src/server/middlewares/csurf.js @@ -8,7 +8,7 @@ export const csrfOptions = { export default function getCsurf() { const protection = csurf({ - cookie: csrfOptions + cookie: { ...csrfOptions, httpOnly: true } }); return function csrf(req, res, next) { const { path } = req; diff --git a/api-server/src/server/middlewares/request-authorization.js b/api-server/src/server/middlewares/request-authorization.js index 33d3c0f1f653ab..93d27911884657 100644 --- a/api-server/src/server/middlewares/request-authorization.js +++ b/api-server/src/server/middlewares/request-authorization.js @@ -5,8 +5,7 @@ import { jwtSecret as _jwtSecret } from '../../../../config/secrets'; import { wrapHandledError } from '../utils/create-handled-error'; import { getAccessTokenFromRequest, - errorTypes, - authHeaderNS + errorTypes } from '../utils/getSetAccessToken'; import { getRedirectParams } from '../utils/redirection'; // TOPCODER: we need to use the external ID (i.e. Auth0 ID) @@ -73,10 +72,7 @@ export default function getRequestAuthorisation({ const { origin } = getRedirectParams(req); const { path } = req; if (!isAllowedPath(path)) { - const { accessToken, error, jwt } = getAccessTokenFromRequest( - req, - jwtSecret - ); + const { accessToken, error } = getAccessTokenFromRequest(req, jwtSecret); if (!accessToken && error === errorTypes.noTokenFound) { throw wrapHandledError( new Error('Access token is required for this request'), @@ -104,7 +100,6 @@ export default function getRequestAuthorisation({ status: 403 }); } - res.set(authHeaderNS, jwt); if (isEmpty(req.user)) { // TOPCODER: the accessToken.sub value is the Auth0 ID // (e.g. auth0|12345) that we use to link the diff --git a/api-server/src/server/middlewares/request-authorization.test.js b/api-server/src/server/middlewares/request-authorization.test.js index 593d5930ed9269..3ecfb3ad83287e 100644 --- a/api-server/src/server/middlewares/request-authorization.test.js +++ b/api-server/src/server/middlewares/request-authorization.test.js @@ -168,104 +168,6 @@ describe('request-authorization', () => { expect(req.user).toEqual(users['456def']); }); - it('adds the jwt to the headers', async () => { - const validJWT = jwt.sign({ accessToken }, validJWTSecret); - const req = mockReq({ - path: '/some-path/that-needs/auth', - // eslint-disable-next-line camelcase - cookie: { jwt_access_token: validJWT } - }); - const res = mockRes(); - const next = jest.fn(); - await requestAuthorization(req, res, next); - expect(res.set).toHaveBeenCalledWith('X-fcc-access-token', validJWT); - }); - - it('calls next if request does not require authorization', async () => { - // currently /unsubscribe does not require authorization - const req = mockReq({ path: '/unsubscribe/another/route' }); - const res = mockRes(); - const next = jest.fn(); - await requestAuthorization(req, res, next); - expect(next).toHaveBeenCalled(); - }); - }); - - describe('Auth header', () => { - it('throws when no access token is present', () => { - expect.assertions(2); - const req = mockReq({ path: '/some-path/that-needs/auth' }); - const res = mockRes(); - const next = jest.fn(); - expect(() => requestAuthorization(req, res, next)).toThrowError( - 'Access token is required for this request' - ); - expect(next).not.toHaveBeenCalled(); - }); - - it('throws when the access token is invalid', () => { - expect.assertions(2); - const invalidJWT = jwt.sign({ accessToken }, invalidJWTSecret); - const req = mockReq({ - path: '/some-path/that-needs/auth', - headers: { 'X-fcc-access-token': invalidJWT } - }); - const res = mockRes(); - const next = jest.fn(); - - expect(() => requestAuthorization(req, res, next)).toThrowError( - 'Access token is invalid' - ); - expect(next).not.toHaveBeenCalled(); - }); - - it('throws when the access token has expired', () => { - expect.assertions(2); - const invalidJWT = jwt.sign( - { accessToken: { ...accessToken, created: theBeginningOfTime } }, - validJWTSecret - ); - const req = mockReq({ - path: '/some-path/that-needs/auth', - headers: { 'X-fcc-access-token': invalidJWT } - }); - const res = mockRes(); - const next = jest.fn(); - - expect(() => requestAuthorization(req, res, next)).toThrowError( - 'Access token is no longer valid' - ); - expect(next).not.toHaveBeenCalled(); - }); - - it('adds the user to the request object', async () => { - expect.assertions(3); - const validJWT = jwt.sign({ accessToken }, validJWTSecret); - const req = mockReq({ - path: '/some-path/that-needs/auth', - headers: { 'X-fcc-access-token': validJWT } - }); - const res = mockRes(); - const next = jest.fn(); - await requestAuthorization(req, res, next); - expect(next).toHaveBeenCalled(); - expect(req).toHaveProperty('user'); - expect(req.user).toEqual(users['456def']); - }); - - it('adds the jwt to the headers', async () => { - const validJWT = jwt.sign({ accessToken }, validJWTSecret); - const req = mockReq({ - path: '/some-path/that-needs/auth', - // eslint-disable-next-line camelcase - cookie: { jwt_access_token: validJWT } - }); - const res = mockRes(); - const next = jest.fn(); - await requestAuthorization(req, res, next); - expect(res.set).toHaveBeenCalledWith('X-fcc-access-token', validJWT); - }); - it('calls next if request does not require authorization', async () => { // currently /unsubscribe does not require authorization const req = mockReq({ path: '/unsubscribe/another/route' }); diff --git a/api-server/src/server/utils/getSetAccessToken.js b/api-server/src/server/utils/getSetAccessToken.js index 885ded28fa6283..aad4ec4bb2b585 100644 --- a/api-server/src/server/utils/getSetAccessToken.js +++ b/api-server/src/server/utils/getSetAccessToken.js @@ -3,7 +3,6 @@ import jwt from 'jsonwebtoken'; import { jwtSecret as _jwtSecret } from '../../../../config/secrets'; -export const authHeaderNS = 'X-fcc-access-token'; // TOPCODER: we are using the name of the cookie created // by the TC Auth0 implementation export const jwtCookieNS = 'tcjwt'; @@ -33,7 +32,6 @@ export function setAccessTokenToResponse( export function getAccessTokenFromRequest(req, jwtSecret = _jwtSecret) { const maybeToken = - (req.headers && req.headers[authHeaderNS]) || (req.signedCookies && req.signedCookies[jwtCookieNS]) || (req.cookie && req.cookie[jwtCookieNS]) || // TOPCODER: the jwt cookie is in the cookies var instead @@ -74,10 +72,9 @@ export function getAccessTokenFromRequest(req, jwtSecret = _jwtSecret) { // token, so we just use the token itself. return { accessToken: token, - error: '', - jwt: maybeToken + error: '' }; - // return { accessToken, error: '', jwt: maybeToken }; + // return { accessToken, error: '' }; } export function removeCookies(req, res) { diff --git a/api-server/src/server/utils/getSetAccessToken.test.js b/api-server/src/server/utils/getSetAccessToken.test.js index 768d0ea0d0b6da..2e1aa39980cbad 100644 --- a/api-server/src/server/utils/getSetAccessToken.test.js +++ b/api-server/src/server/utils/getSetAccessToken.test.js @@ -62,61 +62,6 @@ describe('getSetAccessToken', () => { created: accessToken.created.toISOString() }); }); - - it('returns the signed jwt if found', () => { - const validJWT = jwt.sign({ accessToken }, validJWTSecret); - // eslint-disable-next-line camelcase - const req = mockReq({ cookie: { jwt_access_token: validJWT } }); - const result = getAccessTokenFromRequest(req, validJWTSecret); - - expect(result.jwt).toEqual(validJWT); - }); - }); - - describe('Auth headers', () => { - it('returns `invalid token` error for malformed tokens', () => { - const invalidJWT = jwt.sign({ accessToken }, invalidJWTSecret); - // eslint-disable-next-line camelcase - const req = mockReq({ headers: { 'X-fcc-access-token': invalidJWT } }); - const result = getAccessTokenFromRequest(req, validJWTSecret); - - expect(result.error).toEqual(errorTypes.invalidToken); - }); - - it('returns `expired token` error for expired tokens', () => { - const invalidJWT = jwt.sign( - { accessToken: { ...accessToken, created: theBeginningOfTime } }, - validJWTSecret - ); - // eslint-disable-next-line camelcase - const req = mockReq({ headers: { 'X-fcc-access-token': invalidJWT } }); - const result = getAccessTokenFromRequest(req, validJWTSecret); - - expect(result.error).toEqual(errorTypes.expiredToken); - }); - - it('returns a valid access token with no errors ', () => { - expect.assertions(2); - const validJWT = jwt.sign({ accessToken }, validJWTSecret); - // eslint-disable-next-line camelcase - const req = mockReq({ headers: { 'X-fcc-access-token': validJWT } }); - const result = getAccessTokenFromRequest(req, validJWTSecret); - - expect(result.error).toBeFalsy(); - expect(result.accessToken).toEqual({ - ...accessToken, - created: accessToken.created.toISOString() - }); - }); - - it('returns the signed jwt if found', () => { - const validJWT = jwt.sign({ accessToken }, validJWTSecret); - // eslint-disable-next-line camelcase - const req = mockReq({ headers: { 'X-fcc-access-token': validJWT } }); - const result = getAccessTokenFromRequest(req, validJWTSecret); - - expect(result.jwt).toEqual(validJWT); - }); }); }); diff --git a/api-server/src/server/utils/publicUserProps.js b/api-server/src/server/utils/publicUserProps.js index e6b8871e699ba9..e4ff3dc9196205 100644 --- a/api-server/src/server/utils/publicUserProps.js +++ b/api-server/src/server/utils/publicUserProps.js @@ -55,6 +55,7 @@ export const userPropsForSession = [ 'sendQuincyEmail', 'theme', 'sound', + 'keyboardShortcuts', 'completedChallengeCount', 'completedProjectCount', 'completedCertCount', diff --git a/client/gatsby-browser.js b/client/gatsby-browser.js index e2292ec15cc668..11616f7cd30c61 100644 --- a/client/gatsby-browser.js +++ b/client/gatsby-browser.js @@ -30,9 +30,6 @@ export const wrapPageElement = layoutSelector; export const disableCorePrefetching = () => true; export const onClientEntry = () => { - // purge the csrf cookies, rather than relying what the browser decides a - // Session duration is - cookies.erase('_csrf'); // the token must be erased since it is only valid for the old _csrf secret cookies.erase('csrf_token'); }; diff --git a/client/i18n/locales/chinese-traditional/intro.json b/client/i18n/locales/chinese-traditional/intro.json index 5ff0f08db2cca4..e4c0427b59373c 100644 --- a/client/i18n/locales/chinese-traditional/intro.json +++ b/client/i18n/locales/chinese-traditional/intro.json @@ -1,6 +1,6 @@ { "responsive-web-design": { - "title": "Legacy Responsive Web Design", + "title": "(舊版)響應式網頁設計", "intro": [ "在響應式網頁設計認證中,你將學習開發者用來編寫網頁的語言:HTML(超文本標記語言)用於創建內容,CSS(級聯樣式表)用於樣式設計。", "首先,你將通過編寫一個展示貓咪圖片的應用,學習 HTML 和 CSS 的基本知識。 然後,通過畫企鵝來學習像 CSS 變量這樣的現代技術,以及通過構建網頁表單來學習無障礙的最佳實踐。", @@ -67,11 +67,11 @@ } }, "2022/responsive-web-design": { - "title": "(New) Responsive Web Design", + "title": "(新版)響應式網頁設計", "intro": [ "在響應式網頁設計的認證課程中,你將學習用於構建網頁的語言: HTML(超文本標記語言)用於創建內容,CSS(級聯樣式表)用於樣式設計。", - "首先,你將通過編寫一個貓咪相冊應用,學習 HTML 和 CSS 的基本知識。 然後,通過畫企鵝來學習像 CSS 變量這樣的現代技術,並通過編寫網頁表單來學習無障礙的最佳實踐。", - "最後,你將通過編寫一個 Twitter 卡片,學習如何使用 Flexbox 實現能夠適應不同屏幕大小的網頁 ,以及如何使用 CSS Grid 實現一個複雜的博客佈局。" + "首先,你將通過編寫一個展示貓咪圖片的應用來學習 HTML 和 CSS 的基本知識。 然後,通過構建一隻企鵝來學習像 CSS 變量這樣的現代技術,並通過搭建網頁表單來學習無障礙的最佳實踐。", + "最後,你將通過編寫一個 Twitter 卡片,學習如何使用 Flexbox 實現適應不同屏幕大小的網頁 ,以及如何用 CSS Grid 實現一個複雜的博客佈局。" ], "note": "注意:某些瀏覽器擴展程序(例如廣告攔截器和深色模式)可能干擾測試。如果遇到問題,我們建議你在學習課程時禁用那些修改網頁內容或佈局的擴展程序。", "blocks": { @@ -300,64 +300,64 @@ } }, "2022/javascript-algorithms-and-data-structures": { - "title": "JavaScript Algorithms and Data Structures (Beta)", + "title": "JavaScript 算法和數據結構項目(Beta 測試版本)", "intro": [ - "placeholder", - "placeholder" + "佔位符", + "佔位符" ], "note": "", "blocks": { "build-a-caesars-cipher-project": { - "title": "Build a Casears Cipher Project", + "title": "構建一個愷撒密碼項目", "intro": [ "", "" ] }, "build-a-cash-register-project": { - "title": "Build a Cash Register Project", + "title": "構建一個收銀機項目", "intro": [ "", "" ] }, "build-a-palindrome-checker-project": { - "title": "Build a Palindrome Checker Project", + "title": "構建一個迴文檢測器項目", "intro": [ "", "" ] }, "build-a-roman-numeral-converter-project": { - "title": "Build a Roman Numeral Converter Project", + "title": "搭建一個羅馬數字轉換器項目", "intro": [ "", "" ] }, "build-a-telephone-number-validator-project": { - "title": "Build a Telephone Number Validator Project", + "title": "構建一個電話號碼檢驗器項目", "intro": [ "", "" ] }, "learn-basic-javascript-by-building-a-role-playing-game": { - "title": "Learn Basic JavaScript by Building a Role Playing Game", + "title": "通過構建角色扮演遊戲來學習 JavaScript", "intro": [ "", "" ] }, "learn-form-validation-by-building-a-calorie-counter": { - "title": "Learn Form Validation by Building a Calorie Counter", + "title": "通過構建卡路里計數器來學習表單驗證", "intro": [ "", "" ] }, "learn-functional-programming-by-building-a-spreadsheet": { - "title": "Learn Functional Programming by Building a Spreadsheet", + "title": "通過構建電子表格學習函數式編程", "intro": [ "", "" @@ -606,7 +606,7 @@ "mongodb-and-mongoose": { "title": "MongoDB 和 Mongoose", "intro": [ - "MongoDB 是一個存儲你可以在應用程序中使用的 JSON 文件(或記錄)的數據庫應用程序。不同於SQL,另一種類型的數據庫。Mongo 是一個非關係型或 “NoSQL” 數據庫。這意味着 Mongo 將所有相關數據存儲在一個記錄中,而不是像 SQL 數據庫中那樣在許多預設表中存儲數據。", + "MongoDB 是一個存儲 JSON 文件(或記錄)的數據庫程序,你可以在自己的程序中使用這些 JSON 文件。與 SQL——另一種類型的數據庫——所不同的是,MongoDB 是一個非關係型數據庫,也被稱爲 “NoSQL”。這意味着 MongoDB 將所有相關數據都存儲在一個記錄中,而不是像 SQL 數據庫中那樣把數據存儲在許多預設表中。", "Mongoose 是一個廣泛使用的 npm 包,通常和 Mongo 一起安裝。通過 Mongoose,你可以使用 JavaScript 對象而不是 JSON ,這樣就更容易與 Mongo 配合使用。此外,它允許你創建文件架構,即 schema,所以你不會意外地保存錯誤的數據類型並出現 bug。", "在 MongoDB 和 Mongoose 課程中,你將學習處理數據的基本知識,包括如何建立模型,保存、刪除並在數據庫中查找文檔。" ] @@ -804,7 +804,8 @@ "title": "羅塞塔代碼", "intro": [ "通過完成經典的羅塞塔代碼庫中的這些免費編程任務來提升你的創造性問題解決能力。", - "這些挑戰可能很困難,但是它們會將進一步提升你的算法邏輯。" + "這些挑戰可能很困難,但是它們會將進一步提升你的算法邏輯。", + "屬性:Rosetta 代碼" ] }, "project-euler": { @@ -825,9 +826,9 @@ "collapse": "收起課程", "legacy-header": "舊版課程", "legacy-desc": "這些課程不再是認證路徑的一部分,但仍可供你進一步學習。", - "legacy-go-back": "Go to the current version of the curriculum.", - "new-rwd-desc": "We have updated our Responsive Web Design Curriculum. If you were previously working on the RWD curriculum, your progress is still saved! You can find it under the Legacy Responsive Web Design section.", - "new-rwd-article": "We encourage you to read about the changes we made and consider exploring the updated curriculum.", + "legacy-go-back": "進入當前版本的課程。", + "new-rwd-desc": "我們更新了響應式網頁設計課程。 如果你之前正在使用該課程,你的進度仍然可以保存!你可以在舊版響應式網頁設計課程裏找到你的進度。", + "new-rwd-article": "我們希望你閱讀我們所作的修改,並能考慮探索新課程。", "viewing-upcoming-change": "你正在查看Beta頁面。 ", "go-back-to-learn": "回到正式版課程", "read-database-cert-article": "請在繼續之前閱讀這個論壇帖子。", diff --git a/client/i18n/locales/chinese-traditional/links.json b/client/i18n/locales/chinese-traditional/links.json index c77d3408058552..51bec130ca2156 100644 --- a/client/i18n/locales/chinese-traditional/links.json +++ b/client/i18n/locales/chinese-traditional/links.json @@ -1,5 +1,5 @@ { - "help-translate-url": "https://contribute.freecodecamp.org/#/i18n/chinese/how-to-translate-files", + "help-translate-link-url": "https://contribute.freecodecamp.org/#/i18n/chinese/how-to-translate-files", "top-contributors": "https://www.freecodecamp.org/news/freecodecamp-top-contributors/", "footer": { "about-url": "https://chinese.freecodecamp.org/news/about/", @@ -13,16 +13,19 @@ "copyright-url": "https://www.freecodecamp.org/news/copyright-policy/" }, "donate": { - "other-ways-url": "https://chinese.freecodecamp.org/news/how-to-donate-to-free-code-camp/" + "other-ways-url": "https://chinese.freecodecamp.org/news/how-to-donate-to-free-code-camp/", + "download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf", + "download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf", + "one-time-url": "https://paypal.me/freecodecamp" }, "nav": { - "forum": "https://chinese.freecodecamp.org/forum/", + "forum": "https://forum.freecodecamp.org/c/chinese/533", "news": "https://chinese.freecodecamp.org/news/" }, "help": { - "HTML-CSS": "front-end", - "JavaScript": "front-end", - "Python": "curriculum", - "Relational Databases": "curriculum" + "HTML-CSS": "chinese/html-css", + "JavaScript": "chinese/javascript", + "Python": "chinese/python", + "Backend Development": "chinese/programming-help" } } diff --git a/client/i18n/locales/chinese-traditional/translations.json b/client/i18n/locales/chinese-traditional/translations.json index 8c4d57e0b189c0..09f6b06f5652c4 100644 --- a/client/i18n/locales/chinese-traditional/translations.json +++ b/client/i18n/locales/chinese-traditional/translations.json @@ -50,7 +50,8 @@ "reset-lesson": "重置課程", "run": "運行", "run-test": "運行測試(Ctrl + Enter)", - "check-code": "Check Your Code (Ctrl + Enter)", + "check-code": "檢查您的代碼 (Ctrl + Enter)", + "check-code-2": "檢查你的代碼", "reset": "重置", "reset-code": "重置所有代碼", "help": "幫助", @@ -70,7 +71,11 @@ "start-coding": "開始編碼!", "go-to-settings": "轉到設置以申請你的認證", "click-start-course": "開始課程", - "click-start-project": "啓動項目" + "click-start-project": "啓動項目", + "change-language": "修改語言", + "cancel-change": "撤銷修改", + "resume-project": "繼續項目", + "start-project": "開始項目" }, "landing": { "big-heading-1": "免費學習編程", @@ -101,7 +106,7 @@ }, "settings": { "share-projects": "分享你在 freeCodeCamp 之外做的項目,寫的文章或者在 GitHub 上被接受的 pull requests。", - "privacy": "The settings in this section enable you to control what is shown on your freeCodeCamp public portfolio. Press save to save your changes.", + "privacy": "你可以在本節的設置中管理哪些內容可以展示在 freeCodeCamp 公開作品集,點擊“保存”以存儲你的修改。", "data": "請點擊下面的 \"下載你的數據\" 按鈕,查看我們在你的賬號上保存的數據", "disabled": "如果設置爲僅自己可見,其他人將無法訪問你的認證。", "private-name": "如果你將姓名設置爲私密,你的證書上不會顯示你的姓名。", @@ -143,7 +148,8 @@ "my-timeline": "我的時間線", "my-donations": "我的捐款", "night-mode": "夜間模式", - "sound-mode": "篝火模式" + "sound-mode": "篝火模式", + "keyboard-shortcuts": "啓用鍵盤快捷鍵" }, "headings": { "certs": "認證", @@ -269,7 +275,7 @@ "solution-link": "解決方案鏈接", "github-link": "GitHub 鏈接", "submit-and-go": "提交併訪問下一個挑戰", - "congradulations": "Congratulations, your code passes. Submit your code to complete this step and move on to the next one.", + "congratulations": "恭喜,你的代碼已通過。請提交你的代碼以繼續。", "i-completed": "我已經完成這個挑戰", "test-output": "你的測試輸出將在這裏顯示", "running-tests": "// 運行測試", @@ -280,14 +286,14 @@ "percent-complete": "完成 {{percent}}%", "tried-rsa": "如果你已經嘗試了 <0>Read-Search-Ask(閱讀-搜索-提問)方法,那麼你可以在 freeCodeCamp 論壇請求幫助。", "rsa": "閱讀,搜索,提問", + "rsa-forum": "Before making a new post please see if your question has <0>already been answered on the forum.", "reset": "重置這一節課程?", "reset-warn": "你確定要重置這一節課程嗎?編輯器和測試將被重置。", "reset-warn-2": "這個操作不可撤銷", "scrimba-tip": "注意:如果這個小瀏覽器窗口覆蓋了代碼,點擊拖動它。同時,你可以隨時暫停,在視頻中編輯代碼。", "chal-preview": "挑戰預覽", "cert-map-estimates": { - "certs": "{{title}} 認證 (300小時)", - "coding-prep": "{{title}}(數千小時的挑戰)" + "certs": "{{title}} 認證" }, "editor-tabs": { "info": "信息", @@ -296,6 +302,7 @@ "restart": "重啓", "restart-step": "重啓步驟", "console": "控制檯", + "instructions": "說明", "notes": "注意", "preview": "預覽" }, @@ -308,15 +315,16 @@ "submit-public-url": "當你完成項目後,將所有所需文件保存到公共倉庫並將 URL 填寫到下方。", "complete-both-steps": "完成下面的兩個步驟來完成這一挑戰。", "runs-in-vm": "該項目在虛擬機中運行,完成在那裏描述的用戶故事,獲取所有測試並通過它們以完成步驟 1。", - "completed": "Completed", - "not-started": "Not started", - "hint": "Hint", - "test": "Test", - "sorry-try-again": "Sorry, your code does not pass. Try again.", - "sorry-keep-trying": "Sorry, your code does not pass. Keep trying.", - "sorry-getting-there": "Sorry, your code does not pass. You're getting there.", - "sorry-hang-in-there": "Sorry, your code does not pass. Hang in there.", - "sorry-dont-giveup": "Sorry, your code does not pass. Don't give up." + "completed": "已完成", + "not-started": "未開始", + "hint": "提示", + "test": "測試", + "sorry-try-again": "抱歉,你的代碼未通過,再試一次。", + "sorry-keep-trying": "抱歉,你的代碼未通過,再試試看。", + "sorry-getting-there": "抱歉,你的代碼未通過,就快要成功了。", + "sorry-hang-in-there": "抱歉,你的代碼未通過,堅持一下。", + "sorry-dont-giveup": "抱歉,你的代碼未通過,不要放棄。", + "challenges-completed": "已完成 {{completedCount}}/{{totalChallenges}}" }, "donate": { "title": "支持我們的非營利組織", @@ -324,7 +332,6 @@ "redirecting": "重新引導中...", "thanks": "謝謝捐款", "thank-you": "謝謝你成爲我們的支持者。", - "thank-you-2": "謝謝你成爲 freeCodeCamp 的支持者。現在你已設置定期捐款。", "additional": "你可以使用這個鏈接 <0>{{url}} 額外進行一次性捐款:", "help-more": "幫助我們做更多", "error": "你的捐款處理有點問題。", @@ -423,7 +430,7 @@ }, "search": { "label": "搜索", - "placeholder": "搜索 800+ 篇教程", + "placeholder": "搜索 1,000+ 篇教程", "see-results": "查看 {{searchQuery}} 的所有結果", "no-tutorials": "未找到教程", "try": "想要搜索信息?試試使用頁面上的搜索框。", @@ -443,7 +450,9 @@ "and": "和", "change-theme": "登錄以更改主題。", "translation-pending": "幫我們翻譯", - "certification-project": "認證項目" + "certification-project": "認證項目", + "iframe-alert": "通常,此鏈接會將你帶到另一個網站!一切正常,這個鏈接指向:{{externalLink}}。", + "document-notfound": "找不到文件" }, "icons": { "gold-cup": "金獎盃", @@ -452,8 +461,10 @@ "donate": "使用 PayPal 捐款", "fail": "測試失敗", "not-passed": "未通過", + "waiting": "等待中", "passed": "通過", - "hint": "Hint", + "failed": "失敗", + "hint": "提示", "heart": "愛心", "initial": "初始", "info": "介紹信息", @@ -474,8 +485,11 @@ "last-page": "訪問最後一頁", "primary-nav": "主要的", "breadcrumb-nav": "麪包屑導航", - "submit": "Use Ctrl + Enter to submit.", - "running-tests": "Running tests" + "submit": "按下 Ctrl + Enter 鍵提交。", + "running-tests": "正在運行測試", + "step": "步驟", + "steps": "步驟", + "steps-for": "{{blockTitle}} 的步驟" }, "flash": { "honest-first": "申請認證之前,你必須先接受我們的《學術誠信條例》", @@ -681,5 +695,16 @@ "delete-p3": "您需要創建一個新的令牌來保存使用虛擬機的課程部分的未來進度。", "no-thanks": "不,謝謝,我想保留我的令牌", "yes-please": "是的,我想刪除我的令牌" + }, + "shortcuts": { + "title": "鍵盤快捷鍵", + "table-header-action": "行動", + "table-header-key": "關鍵字", + "navigation-mode": "導航模式", + "execute-challenge": "開始挑戰", + "focus-editor": "聚焦編輯器", + "focus-instructions-panel": "聚焦指示面板", + "navigate-previous": "跳轉至上一個練習", + "navigate-next": "跳轉至下一個練習" } } diff --git a/client/i18n/locales/chinese/intro.json b/client/i18n/locales/chinese/intro.json index b70a6b2137dcdf..c4501ae4514988 100644 --- a/client/i18n/locales/chinese/intro.json +++ b/client/i18n/locales/chinese/intro.json @@ -1,6 +1,6 @@ { "responsive-web-design": { - "title": "Legacy Responsive Web Design", + "title": "(旧版)响应式网页设计", "intro": [ "在响应式网页设计认证中,你将学习开发者用来编写网页的语言:HTML(超文本标记语言)用于创建内容,CSS(级联样式表)用于样式设计。", "首先,你将通过编写一个展示猫咪图片的应用,学习 HTML 和 CSS 的基本知识。 然后,通过画企鹅来学习像 CSS 变量这样的现代技术,以及通过构建网页表单来学习无障碍的最佳实践。", @@ -67,11 +67,11 @@ } }, "2022/responsive-web-design": { - "title": "(New) Responsive Web Design", + "title": "(新版)响应式网页设计", "intro": [ "在响应式网页设计的认证课程中,你将学习用于构建网页的语言: HTML(超文本标记语言)用于创建内容,CSS(级联样式表)用于样式设计。", - "首先,你将通过编写一个猫咪相册应用,学习 HTML 和 CSS 的基本知识。 然后,通过画企鹅来学习像 CSS 变量这样的现代技术,并通过编写网页表单来学习无障碍的最佳实践。", - "最后,你将通过编写一个 Twitter 卡片,学习如何使用 Flexbox 实现能够适应不同屏幕大小的网页 ,以及如何使用 CSS Grid 实现一个复杂的博客布局。" + "首先,你将通过编写一个展示猫咪图片的应用来学习 HTML 和 CSS 的基本知识。 然后,通过构建一只企鹅来学习像 CSS 变量这样的现代技术,并通过搭建网页表单来学习无障碍的最佳实践。", + "最后,你将通过编写一个 Twitter 卡片,学习如何使用 Flexbox 实现适应不同屏幕大小的网页 ,以及如何用 CSS Grid 实现一个复杂的博客布局。" ], "note": "注意:某些浏览器扩展程序(例如广告拦截器和深色模式)可能干扰测试。如果遇到问题,我们建议你在学习课程时禁用那些修改网页内容或布局的扩展程序。", "blocks": { @@ -300,64 +300,64 @@ } }, "2022/javascript-algorithms-and-data-structures": { - "title": "JavaScript Algorithms and Data Structures (Beta)", + "title": "JavaScript 算法和数据结构项目(Beta 测试版本)", "intro": [ - "placeholder", - "placeholder" + "占位符", + "占位符" ], "note": "", "blocks": { "build-a-caesars-cipher-project": { - "title": "Build a Casears Cipher Project", + "title": "构建一个恺撒密码项目", "intro": [ "", "" ] }, "build-a-cash-register-project": { - "title": "Build a Cash Register Project", + "title": "构建一个收银机项目", "intro": [ "", "" ] }, "build-a-palindrome-checker-project": { - "title": "Build a Palindrome Checker Project", + "title": "构建一个回文检测器项目", "intro": [ "", "" ] }, "build-a-roman-numeral-converter-project": { - "title": "Build a Roman Numeral Converter Project", + "title": "搭建一个罗马数字转换器项目", "intro": [ "", "" ] }, "build-a-telephone-number-validator-project": { - "title": "Build a Telephone Number Validator Project", + "title": "构建一个电话号码检验器项目", "intro": [ "", "" ] }, "learn-basic-javascript-by-building-a-role-playing-game": { - "title": "Learn Basic JavaScript by Building a Role Playing Game", + "title": "通过构建角色扮演游戏来学习 JavaScript", "intro": [ "", "" ] }, "learn-form-validation-by-building-a-calorie-counter": { - "title": "Learn Form Validation by Building a Calorie Counter", + "title": "通过构建卡路里计数器来学习表单验证", "intro": [ "", "" ] }, "learn-functional-programming-by-building-a-spreadsheet": { - "title": "Learn Functional Programming by Building a Spreadsheet", + "title": "通过构建电子表格学习函数式编程", "intro": [ "", "" @@ -606,7 +606,7 @@ "mongodb-and-mongoose": { "title": "MongoDB 和 Mongoose", "intro": [ - "MongoDB 是一个存储你可以在应用程序中使用的 JSON 文件(或记录)的数据库应用程序。不同于SQL,另一种类型的数据库。Mongo 是一个非关系型或 “NoSQL” 数据库。这意味着 Mongo 将所有相关数据存储在一个记录中,而不是像 SQL 数据库中那样在许多预设表中存储数据。", + "MongoDB 是一个存储 JSON 文件(或记录)的数据库程序,你可以在自己的程序中使用这些 JSON 文件。与 SQL——另一种类型的数据库——所不同的是,MongoDB 是一个非关系型数据库,也被称为 “NoSQL”。这意味着 MongoDB 将所有相关数据都存储在一个记录中,而不是像 SQL 数据库中那样把数据存储在许多预设表中。", "Mongoose 是一个广泛使用的 npm 包,通常和 Mongo 一起安装。通过 Mongoose,你可以使用 JavaScript 对象而不是 JSON ,这样就更容易与 Mongo 配合使用。此外,它允许你创建文件架构,即 schema,所以你不会意外地保存错误的数据类型并出现 bug。", "在 MongoDB 和 Mongoose 课程中,你将学习处理数据的基本知识,包括如何建立模型,保存、删除并在数据库中查找文档。" ] @@ -804,7 +804,8 @@ "title": "罗塞塔代码", "intro": [ "通过完成经典的罗塞塔代码库中的这些免费编程任务来提升你的创造性问题解决能力。", - "这些挑战可能很困难,但是它们会将进一步提升你的算法逻辑。" + "这些挑战可能很困难,但是它们会将进一步提升你的算法逻辑。", + "属性:Rosetta 代码" ] }, "project-euler": { @@ -825,9 +826,9 @@ "collapse": "收起课程", "legacy-header": "旧版课程", "legacy-desc": "这些课程不再是认证路径的一部分,但仍可供你进一步学习。", - "legacy-go-back": "Go to the current version of the curriculum.", - "new-rwd-desc": "We have updated our Responsive Web Design Curriculum. If you were previously working on the RWD curriculum, your progress is still saved! You can find it under the Legacy Responsive Web Design section.", - "new-rwd-article": "We encourage you to read about the changes we made and consider exploring the updated curriculum.", + "legacy-go-back": "进入当前版本的课程。", + "new-rwd-desc": "我们更新了响应式网页设计课程。 如果你之前正在使用该课程,你的进度仍然可以保存!你可以在旧版响应式网页设计课程里找到你的进度。", + "new-rwd-article": "我们希望你阅读我们所作的修改,并能考虑探索新课程。", "viewing-upcoming-change": "你正在查看Beta页面。 ", "go-back-to-learn": "回到正式版课程", "read-database-cert-article": "请在继续之前阅读这个论坛帖子。", diff --git a/client/i18n/locales/chinese/links.json b/client/i18n/locales/chinese/links.json index c77d3408058552..51bec130ca2156 100644 --- a/client/i18n/locales/chinese/links.json +++ b/client/i18n/locales/chinese/links.json @@ -1,5 +1,5 @@ { - "help-translate-url": "https://contribute.freecodecamp.org/#/i18n/chinese/how-to-translate-files", + "help-translate-link-url": "https://contribute.freecodecamp.org/#/i18n/chinese/how-to-translate-files", "top-contributors": "https://www.freecodecamp.org/news/freecodecamp-top-contributors/", "footer": { "about-url": "https://chinese.freecodecamp.org/news/about/", @@ -13,16 +13,19 @@ "copyright-url": "https://www.freecodecamp.org/news/copyright-policy/" }, "donate": { - "other-ways-url": "https://chinese.freecodecamp.org/news/how-to-donate-to-free-code-camp/" + "other-ways-url": "https://chinese.freecodecamp.org/news/how-to-donate-to-free-code-camp/", + "download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf", + "download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf", + "one-time-url": "https://paypal.me/freecodecamp" }, "nav": { - "forum": "https://chinese.freecodecamp.org/forum/", + "forum": "https://forum.freecodecamp.org/c/chinese/533", "news": "https://chinese.freecodecamp.org/news/" }, "help": { - "HTML-CSS": "front-end", - "JavaScript": "front-end", - "Python": "curriculum", - "Relational Databases": "curriculum" + "HTML-CSS": "chinese/html-css", + "JavaScript": "chinese/javascript", + "Python": "chinese/python", + "Backend Development": "chinese/programming-help" } } diff --git a/client/i18n/locales/chinese/translations.json b/client/i18n/locales/chinese/translations.json index c73a719936ed11..ba47cdcbc48775 100644 --- a/client/i18n/locales/chinese/translations.json +++ b/client/i18n/locales/chinese/translations.json @@ -50,7 +50,8 @@ "reset-lesson": "重置课程", "run": "运行", "run-test": "运行测试(Ctrl + Enter)", - "check-code": "Check Your Code (Ctrl + Enter)", + "check-code": "检查您的代码 (Ctrl + Enter)", + "check-code-2": "检查你的代码", "reset": "重置", "reset-code": "重置所有代码", "help": "帮助", @@ -70,7 +71,11 @@ "start-coding": "开始编码!", "go-to-settings": "转到设置以申请你的认证", "click-start-course": "开始课程", - "click-start-project": "启动项目" + "click-start-project": "启动项目", + "change-language": "修改语言", + "cancel-change": "撤销修改", + "resume-project": "继续项目", + "start-project": "开始项目" }, "landing": { "big-heading-1": "免费学习编程", @@ -101,7 +106,7 @@ }, "settings": { "share-projects": "分享你在 freeCodeCamp 之外做的项目,写的文章或者在 GitHub 上被接受的 pull requests。", - "privacy": "The settings in this section enable you to control what is shown on your freeCodeCamp public portfolio. Press save to save your changes.", + "privacy": "你可以在本节的设置中管理哪些内容可以展示在 freeCodeCamp 公开作品集,点击“保存”以存储你的修改。", "data": "请点击下面的 \"下载你的数据\" 按钮,查看我们在你的账号上保存的数据", "disabled": "如果设置为仅自己可见,其他人将无法访问你的认证。", "private-name": "如果你将姓名设置为私密,你的证书上不会显示你的姓名。", @@ -143,7 +148,8 @@ "my-timeline": "我的时间线", "my-donations": "我的捐款", "night-mode": "夜间模式", - "sound-mode": "篝火模式" + "sound-mode": "篝火模式", + "keyboard-shortcuts": "启用键盘快捷键" }, "headings": { "certs": "认证", @@ -269,7 +275,7 @@ "solution-link": "解决方案链接", "github-link": "GitHub 链接", "submit-and-go": "提交并访问下一个挑战", - "congradulations": "Congratulations, your code passes. Submit your code to complete this step and move on to the next one.", + "congratulations": "恭喜,你的代码已通过。请提交你的代码以继续。", "i-completed": "我已经完成这个挑战", "test-output": "你的测试输出将在这里显示", "running-tests": "// 运行测试", @@ -280,14 +286,14 @@ "percent-complete": "完成 {{percent}}%", "tried-rsa": "如果你已经尝试了 <0>Read-Search-Ask(阅读-搜索-提问)方法,那么你可以在 freeCodeCamp 论坛请求帮助。", "rsa": "阅读,搜索,提问", + "rsa-forum": "Before making a new post please see if your question has <0>already been answered on the forum.", "reset": "重置这一节课程?", "reset-warn": "你确定要重置这一节课程吗?编辑器和测试将被重置。", "reset-warn-2": "这个操作不可撤销", "scrimba-tip": "注意:如果这个小浏览器窗口覆盖了代码,点击拖动它。同时,你可以随时暂停,在视频中编辑代码。", "chal-preview": "挑战预览", "cert-map-estimates": { - "certs": "{{title}} 认证 (300小时)", - "coding-prep": "{{title}}(数千小时的挑战)" + "certs": "{{title}} 认证" }, "editor-tabs": { "info": "信息", @@ -296,6 +302,7 @@ "restart": "重启", "restart-step": "重启步骤", "console": "控制台", + "instructions": "说明", "notes": "注意", "preview": "预览" }, @@ -308,15 +315,16 @@ "submit-public-url": "当你完成项目后,将所有所需文件保存到公共仓库并将 URL 填写到下方。", "complete-both-steps": "完成下面的两个步骤来完成这一挑战。", "runs-in-vm": "该项目在虚拟机中运行,完成在那里描述的用户故事,获取所有测试并通过它们以完成步骤 1。", - "completed": "Completed", - "not-started": "Not started", - "hint": "Hint", - "test": "Test", - "sorry-try-again": "Sorry, your code does not pass. Try again.", - "sorry-keep-trying": "Sorry, your code does not pass. Keep trying.", - "sorry-getting-there": "Sorry, your code does not pass. You're getting there.", - "sorry-hang-in-there": "Sorry, your code does not pass. Hang in there.", - "sorry-dont-giveup": "Sorry, your code does not pass. Don't give up." + "completed": "已完成", + "not-started": "未开始", + "hint": "提示", + "test": "测试", + "sorry-try-again": "抱歉,你的代码未通过,再试一次。", + "sorry-keep-trying": "抱歉,你的代码未通过,再试试看。", + "sorry-getting-there": "抱歉,你的代码未通过,就快要成功了。", + "sorry-hang-in-there": "抱歉,你的代码未通过,坚持一下。", + "sorry-dont-giveup": "抱歉,你的代码未通过,不要放弃。", + "challenges-completed": "已完成 {{completedCount}}/{{totalChallenges}}" }, "donate": { "title": "支持我们的非营利组织", @@ -324,7 +332,6 @@ "redirecting": "重新引导中...", "thanks": "谢谢捐款", "thank-you": "谢谢你成为我们的支持者。", - "thank-you-2": "谢谢你成为 freeCodeCamp 的支持者。现在你已设置定期捐款。", "additional": "你可以使用这个链接 <0>{{url}} 额外进行一次性捐款:", "help-more": "帮助我们做更多", "error": "你的捐款处理有点问题。", @@ -423,7 +430,7 @@ }, "search": { "label": "搜索", - "placeholder": "搜索 800+ 篇教程", + "placeholder": "搜索 1,000+ 篇教程", "see-results": "查看 {{searchQuery}} 的所有结果", "no-tutorials": "未找到教程", "try": "想要搜索信息?试试使用页面上的搜索框。", @@ -443,7 +450,9 @@ "and": "和", "change-theme": "登录以更改主题。", "translation-pending": "帮我们翻译", - "certification-project": "认证项目" + "certification-project": "认证项目", + "iframe-alert": "通常,此链接会将你带到另一个网站!一切正常,这个链接指向:{{externalLink}}。", + "document-notfound": "找不到文件" }, "icons": { "gold-cup": "金奖杯", @@ -452,8 +461,10 @@ "donate": "使用 PayPal 捐款", "fail": "测试失败", "not-passed": "未通过", + "waiting": "等待中", "passed": "通过", - "hint": "Hint", + "failed": "失败", + "hint": "提示", "heart": "爱心", "initial": "初始", "info": "介绍信息", @@ -474,8 +485,11 @@ "last-page": "访问最后一页", "primary-nav": "主要的", "breadcrumb-nav": "面包屑导航", - "submit": "Use Ctrl + Enter to submit.", - "running-tests": "Running tests" + "submit": "按下 Ctrl + Enter 键提交。", + "running-tests": "正在运行测试", + "step": "步骤", + "steps": "步骤", + "steps-for": "{{blockTitle}} 的步骤" }, "flash": { "honest-first": "申请认证之前,你必须先接受我们的《学术诚信条例》", @@ -681,5 +695,16 @@ "delete-p3": "您需要创建一个新的令牌来保存使用虚拟机的课程部分的未来进度。", "no-thanks": "不,谢谢,我想保留我的令牌", "yes-please": "是的,我想删除我的令牌" + }, + "shortcuts": { + "title": "键盘快捷键", + "table-header-action": "行动", + "table-header-key": "关键字", + "navigation-mode": "导航模式", + "execute-challenge": "开始挑战", + "focus-editor": "聚焦编辑器", + "focus-instructions-panel": "聚焦指示面板", + "navigate-previous": "跳转至上一个练习", + "navigate-next": "跳转至下一个练习" } } diff --git a/client/i18n/locales/english/intro.json b/client/i18n/locales/english/intro.json index 54380f2e67dc41..0dbf1faf6a1a0b 100644 --- a/client/i18n/locales/english/intro.json +++ b/client/i18n/locales/english/intro.json @@ -70,8 +70,8 @@ "title": "(New) Responsive Web Design", "intro": [ "In this Responsive Web Design Certification, you'll learn the languages that developers use to build webpages: HTML (Hypertext Markup Language) for content, and CSS (Cascading Style Sheets) for design.", - "First, you'll build a cat photo app to learn the basics of HTML and CSS. Later, you'll learn modern techniques like CSS variables by building a penguin, and best practices for accessibility by building a web form.", - "Finally, you'll learn how to make webpages that respond to different screen sizes by building a Twitter card with Flexbox, and a complex blog layout with CSS Grid." + "First, you'll build a cat photo app to learn the basics of HTML and CSS. Later, you'll learn modern techniques like CSS variables by building a penguin, and best practices for accessibility by building a quiz site.", + "Finally, you'll learn how to make webpages that respond to different screen sizes by building a photo gallery with Flexbox, and a magazine article layout with CSS Grid." ], "note": "Note: Some browser extensions, such as ad-blockers and dark mode extensions can interfere with the tests. If you face issues, we recommend disabling extensions that modify the content or layout of pages, while taking the course.", "blocks": { @@ -340,7 +340,7 @@ "note": "", "blocks": { "build-a-caesars-cipher-project": { - "title": "Build a Casears Cipher Project", + "title": "Build a Caesars Cipher Project", "intro": [ "", "" @@ -638,8 +638,8 @@ "mongodb-and-mongoose": { "title": "MongoDB and Mongoose", "intro": [ - "MongoDB is a database application that stores JSON documents (or records) that you can use in your application. Unlike SQL, another type of database, Mongo is a non-relational or \"NoSQL\" database. This means Mongo stores all associated data within one record, instead of storing it across many preset tables as in a SQL database.", - "Mongoose is a popular npm package that is often installed alongside Mongo. With Mongoose, you can use plain JavaScript objects instead of JSON, which makes it easier to work with Mongo. Also, it allows you to create blueprints for your documents called schemas, so you don't accidentally save the wrong type of data and cause bugs later.", + "MongoDB is a database application that stores JSON documents (or records) that you can use in your application. Unlike SQL, another type of database, MongoDB is a non-relational or \"NoSQL\" database. This means MongoDB stores all associated data within one record, instead of storing it across many preset tables as in a SQL database.", + "Mongoose is a popular npm package for interacting with MongoDB. With Mongoose, you can use plain JavaScript objects instead of JSON, which makes it easier to work with MongoDB. Also, it allows you to create blueprints for your documents called schemas, so you don't accidentally save the wrong type of data and cause bugs later.", "In the MongoDB and Mongoose courses, you'll learn the fundamentals of working with persistent data including how to set up a model, and save, delete, and find documents in the database." ] }, @@ -836,7 +836,8 @@ "title": "Rosetta Code", "intro": [ "Level up your creative problem solving skills with these free programming tasks from the classic Rosetta Code library.", - "These challenges can prove to be difficult, but they will push your algorithm logic to new heights." + "These challenges can prove to be difficult, but they will push your algorithm logic to new heights.", + "Attribute: Rosetta Code" ] }, "project-euler": { diff --git a/client/i18n/locales/english/motivation.json b/client/i18n/locales/english/motivation.json index 9b14cef6782c48..cf3924f8add8da 100644 --- a/client/i18n/locales/english/motivation.json +++ b/client/i18n/locales/english/motivation.json @@ -347,6 +347,10 @@ "quote": "Light tomorrow with today.", "author": "Elizabeth Barrett Browning" }, + { + "quote": "If your dreams do not scare you, they are not big enough.", + "author": "Ellen Johnson Sirleaf" + }, { "quote": "Forever is composed of nows.", "author": "Emily Dickinson" diff --git a/client/i18n/locales/english/translations.json b/client/i18n/locales/english/translations.json index 0428211787526d..a1f7df3c8c0e8f 100644 --- a/client/i18n/locales/english/translations.json +++ b/client/i18n/locales/english/translations.json @@ -51,6 +51,7 @@ "run": "Run", "run-test": "Run the Tests (Ctrl + Enter)", "check-code": "Check Your Code (Ctrl + Enter)", + "check-code-2": "Check Your Code", "reset": "Reset", "reset-code": "Reset Code", "help": "Help", @@ -70,7 +71,11 @@ "start-coding": "Start coding!", "go-to-settings": "Go to settings to claim your certification", "click-start-course": "Start the course", - "click-start-project": "Start the project" + "click-start-project": "Start the project", + "change-language": "Change Language", + "cancel-change": "Cancel Change", + "resume-project": "Resume project", + "start-project": "Start project" }, "landing": { "big-heading-1": "Learn to code — for free.", @@ -143,7 +148,8 @@ "my-timeline": "My timeline", "my-donations": "My donations", "night-mode": "Night Mode", - "sound-mode": "Campfire Mode" + "sound-mode": "Campfire Mode", + "keyboard-shortcuts": "Enable Keyboard Shortcuts" }, "headings": { "certs": "Certifications", @@ -269,7 +275,7 @@ "solution-link": "Solution Link", "github-link": "GitHub Link", "submit-and-go": "Submit & go to next step", - "congradulations": "Congratulations, your code passes. Submit your code to complete this step and move on to the next one.", + "congratulations": "Congratulations, your code passes. Submit your code to complete this step and move on to the next one.", "i-completed": "I've completed this challenge", "test-output": "Your test output will go here", "running-tests": "// running tests", @@ -280,14 +286,14 @@ "percent-complete": "{{percent}}% complete", "tried-rsa": "If you've already tried the <0>Read-Search-Ask method, then you can ask for help on the freeCodeCamp forum.", "rsa": "Read, search, ask", + "rsa-forum": "Before making a new post please see if your question has <0>already been answered on the forum.", "reset": "Reset this lesson?", "reset-warn": "Are you sure you wish to reset this lesson? The editors and tests will be reset.", "reset-warn-2": "This cannot be undone", "scrimba-tip": "Tip: If the mini-browser is covering the code, click and drag to move it. Also, feel free to stop and edit the code in the video at any time.", "chal-preview": "Challenge Preview", "cert-map-estimates": { - "certs": "{{title}} Certification (300\u00A0hours)", - "coding-prep": "{{title}} (Thousands of hours of challenges)" + "certs": "{{title}} Certification" }, "editor-tabs": { "info": "Info", @@ -296,6 +302,7 @@ "restart": "Restart", "restart-step": "Restart Step", "console": "Console", + "instructions": "Instructions", "notes": "Notes", "preview": "Preview" }, @@ -316,7 +323,8 @@ "sorry-keep-trying":"Sorry, your code does not pass. Keep trying.", "sorry-getting-there":"Sorry, your code does not pass. You're getting there.", "sorry-hang-in-there":"Sorry, your code does not pass. Hang in there.", - "sorry-dont-giveup":"Sorry, your code does not pass. Don't give up." + "sorry-dont-giveup":"Sorry, your code does not pass. Don't give up.", + "challenges-completed": "{{completedCount}} of {{totalChallenges}} challenges completed" }, "donate": { "title": "Support our nonprofit", @@ -324,7 +332,6 @@ "redirecting": "Redirecting...", "thanks": "Thanks for donating", "thank-you": "Thank you for being a supporter.", - "thank-you-2": "Thank you for being a supporter of freeCodeCamp. You currently have a recurring donation.", "additional": "You can make an additional one-time donation of any amount using this link: <0>{{url}}", "help-more": "Help us do more", "error": "Something went wrong with your donation.", @@ -443,7 +450,10 @@ "and": "and", "change-theme": "Sign in to change theme.", "translation-pending": "Help us translate", - "certification-project": "Certification Project" + "certification-project": "Certification Project", + "iframe-preview": "{{title}} preview", + "iframe-alert": "Normally this link would bring you to another website! It works. This is a link to: {{externalLink}}", + "document-notfound": "document not found" }, "icons": { "gold-cup": "Gold Cup", @@ -452,7 +462,9 @@ "donate": "Donate with PayPal", "fail": "Test Failed", "not-passed": "Not Passed", + "waiting": "Waiting", "passed": "Passed", + "failed": "Failed", "hint": "Hint", "heart": "Heart", "initial": "Initial", @@ -475,7 +487,10 @@ "primary-nav": "primary", "breadcrumb-nav": "breadcrumb", "submit": "Use Ctrl + Enter to submit.", - "running-tests": "Running tests" + "running-tests": "Running tests", + "step": "Step", + "steps": "Steps", + "steps-for": "Steps for {{blockTitle}}" }, "flash": { "honest-first": "To claim a certification, you must first accept our academic honesty policy", @@ -681,5 +696,16 @@ "delete-p3": "You will need to create a new token to save future progress on the curriculum sections that use a virtual machine.", "no-thanks": "No thanks, I would like to keep my token", "yes-please": "Yes please, I would like to delete my token" + }, + "shortcuts": { + "title": "Keyboard shortcuts", + "table-header-action": "Action", + "table-header-key": "Key(s)", + "navigation-mode": "Navigation Mode", + "execute-challenge": "Execute Challenge", + "focus-editor": "Focus Editor", + "focus-instructions-panel": "Focus Instructions Panel", + "navigate-previous": "Navigate Previous Exercise", + "navigate-next": "Navigate Next Exercise" } } diff --git a/client/i18n/locales/english/trending.json b/client/i18n/locales/english/trending.json index 157f74c103bc8c..424577013755a2 100644 --- a/client/i18n/locales/english/trending.json +++ b/client/i18n/locales/english/trending.json @@ -1,62 +1,62 @@ { - "article0title": "Zoom Screen Sharing", - "article0link": "https://www.freecodecamp.org/news/zoom-screen-sharing-how-to-share-my-screen-on-zoom-solved/", - "article1title": "Decimal Place Value", - "article1link": "https://www.freecodecamp.org/news/decimal-place-value-hundreds-thousandths-and-beyond/", - "article2title": "How to Get Into BIOS", - "article2link": "https://www.freecodecamp.org/news/how-to-get-into-bios-in-windows-10-bios-setup-pc-guide/", - "article3title": "String to Int in C++", - "article3link": "https://www.freecodecamp.org/news/string-to-int-in-c-how-to-convert-a-string-to-an-integer-example/", - "article4title": "What is msmpeng.exe", - "article4link": "https://www.freecodecamp.org/news/what-is-msmpeng-exe-why-is-it-of-high-cpu-disk-usage/", - "article5title": "Facetime Not Working", - "article5link": "https://www.freecodecamp.org/news/why-is-my-facetime-not-working/", - "article6title": "Desktop Icons Missing", - "article6link": "https://www.freecodecamp.org/news/desktop-icons-missing-how-to-fix-windows-10-pc-icons-that-have-disappeared/", - "article7title": "How to Copy and Paste", - "article7link": "https://www.freecodecamp.org/news/how-to-copy-and-paste-on-a-computer-windows-pc-keyboard-shortcut-guide/", - "article8title": "Delete a Page in Word", - "article8link": "https://www.freecodecamp.org/news/how-to-delete-a-page-in-word-remove-blank-or-extra-pages/", - "article9title": "vcruntime140.dll Error", - "article9link": "https://www.freecodecamp.org/news/vcruntime140-dll-was-not-found-solved-on-windows-10-pc/", - "article10title": "C++ Vector", - "article10link": "https://www.freecodecamp.org/news/c-vector-std-pattern-vector-in-cpp-with-example-code/", - "article11title": "What is CPU", - "article11link": "https://www.freecodecamp.org/news/what-is-cpu-meaning-definition-and-what-cpu-stands-for/", - "article12title": "IPV4 vs IPV6 ", - "article12link": "https://www.freecodecamp.org/news/ipv4-vs-ipv6-what-is-the-difference-between-ip-addressing-schemes/", - "article13title": "What is IPTV", - "article13link": "https://www.freecodecamp.org/news/what-is-iptv-ip-tv-service-guide/", - "article14title": "HTML Font Size", - "article14link": "https://www.freecodecamp.org/news/html-font-size-how-to-change-text-size-using-inline-css-style/", - "article15title": "Change Mouse DPI", - "article15link": "https://www.freecodecamp.org/news/how-to-change-mouse-dpi-settings-in-windows-10/", - "article16title": "How to Make a GIF", - "article16link": "https://www.freecodecamp.org/news/how-to-make-a-gif-create-animated-gifs-without-downloading-software/", - "article17title": "Git Rename Branch", - "article17link": "https://www.freecodecamp.org/news/git-rename-branch-how-to-change-a-local-branch-name/", - "article18title": "Make a Video Game", - "article18link": "https://www.freecodecamp.org/news/how-to-make-a-video-game-create-your-own-game-from-scratch-tutorial/", - "article19title": "CSS Media Queries", - "article19link": "https://www.freecodecamp.org/news/media-query-css-example-max-and-min-screen-width-for-mobile-responsive-design/", - "article20title": "How to Open .dat Files", - "article20link": "https://www.freecodecamp.org/news/dat-file-how-to-open-the-dat-file-format-extension/", - "article21title": "Record Calls on iPhone", - "article21link": "https://www.freecodecamp.org/news/how-to-record-a-phone-call-on-iphone/", - "article22title": "Ascending vs Descending", - "article22link": "https://www.freecodecamp.org/news/descending-order-vs-ascending-order-what-does-it-mean/", - "article23title": "HTML Email Link Tutorial", - "article23link": "https://www.freecodecamp.org/news/mailto-link-how-to-make-an-html-email-link-example-code/", - "article24title": "Python List Comprehension", - "article24link": "https://www.freecodecamp.org/news/list-comprehension-in-python-with-code-examples/", - "article25title": "Password Protect Zip File", - "article25link": "https://www.freecodecamp.org/news/password-protect-zip-file-windows10/", - "article26title": "Restore Deleted Word File", - "article26link": "https://www.freecodecamp.org/news/how-to-recover-an-unsaved-word-document-restore-a-deleted-word-file/", - "article27title": "Software Engineering Guide", - "article27link": "https://www.freecodecamp.org/news/what-is-software-engineering-how-to-become-a-software-engineer/", - "article28title": "How to Find Your IP Address", - "article28link": "https://www.freecodecamp.org/news/what-is-my-ip-address-for-my-router-how-to-find-your-wifi-address/", - "article29title": "How to Find iPhone Download", - "article29link": "https://www.freecodecamp.org/news/iphone-downloads-folder-where-are-my-downloads-ios-and-ipad/" -} \ No newline at end of file + "article0title": "Discord Won't Open", + "article0link": "https://www.freecodecamp.org/news/discord-wont-open-on-my-pc-solved-in-windows-10/", + "article1title": "Learn Java Courses", + "article1link": "https://www.freecodecamp.org/news/learn-java-free-java-courses-for-beginners/", + "article2title": "SQL Like Statement", + "article2link": "https://www.freecodecamp.org/news/sql-like-statement-how-to-query-sql-with-wildcard/", + "article3title": "File Explorer Error", + "article3link": "https://www.freecodecamp.org/news/file-explorer-not-responding-fixed-on-windows-10-pc/", + "article4title": "Python Find in List", + "article4link": "https://www.freecodecamp.org/news/python-find-in-list-how-to-find-the-index-of-an-item-or-element-in-a-list/", + "article5title": "Functions in Python", + "article5link": "https://www.freecodecamp.org/news/python-functions-define-and-call-a-function/", + "article6title": "Python Reverse List", + "article6link": "https://www.freecodecamp.org/news/python-reverse-list-how-to-reverse-a-range-or-array/", + "article7title": "Create a Table in SQL", + "article7link": "https://www.freecodecamp.org/news/how-to-create-a-table-in-sql-postgres-and-mysql-example-query/", + "article8title": "List Index Out of Range", + "article8link": "https://www.freecodecamp.org/news/list-index-out-of-range-python-error-message-solved/", + "article9title": "Python String.Replace()", + "article9link": "https://www.freecodecamp.org/news/python-string-replace-function-in-python-for-substring-substitution/", + "article10title": "C vs C++", + "article10link": "https://www.freecodecamp.org/news/c-vs-cpp-whats-the-difference/", + "article11title": "Python JSON", + "article11link": "https://www.freecodecamp.org/news/python-json-how-to-convert-a-string-to-json/", + "article12title": "What is a PC?", + "article12link": "https://www.freecodecamp.org/news/what-is-a-pc-computer-definition-and-computer-basics-for-beginners/", + "article13title": "What is Coding?", + "article13link": "https://www.freecodecamp.org/news/computer-coding-computer-program-definition-and-code-meaning/", + "article14title": "Text Box in HTML", + "article14link": "https://www.freecodecamp.org/news/text-box-in-html-the-input-field-html-tag/", + "article15title": "Meta Tag in HTML", + "article15link": "https://www.freecodecamp.org/news/meta-tag-in-html-what-is-metadata-and-meta-description-example/", + "article16title": "Append in Python", + "article16link": "https://www.freecodecamp.org/news/append-in-python-how-to-append-to-a-list-or-an-array/", + "article17title": "Python Not Equal", + "article17link": "https://www.freecodecamp.org/news/python-not-equal-how-to-use-the-does-not-equal-operator/", + "article18title": "Linux awk Command", + "article18link": "https://www.freecodecamp.org/news/the-linux-awk-command-linux-and-unix-usage-syntax-examples/", + "article19title": "JS String Contains", + "article19link": "https://www.freecodecamp.org/news/javascript-string-contains-how-to-use-js-includes/", + "article20title": "How to Open Task Manager", + "article20link": "https://www.freecodecamp.org/news/how-to-open-task-manager-in-windows-10/", + "article21title": "Design Thinking Explained", + "article21link": "https://www.freecodecamp.org/news/the-design-thinking-process-explained/", + "article22title": "Learn Programming Courses", + "article22link": "https://www.freecodecamp.org/news/learn-programming-free-software-development-courses-for-beginners/", + "article23title": "Make a Transparent Taskbar", + "article23link": "https://www.freecodecamp.org/news/transparent-taskbar-how-to-make-a-task-bar-transparent-in-windows-10-pc-2/", + "article24title": "Install Ethernet Driver PC", + "article24link": "https://www.freecodecamp.org/news/windows-10-network-adapter-missing-how-to-install-ethernet-driver-on-pc/", + "article25title": "Default Constructor in Java", + "article25link": "https://www.freecodecamp.org/news/default-constructor-in-java/", + "article26title": "Stuck Win 10 Hard Drive", + "article26link": "https://www.freecodecamp.org/news/scanning-and-repairing-drive-how-to-fix-stuck-windows-10-pc-hard-drive/", + "article27title": "Color Codes for Grey Palette", + "article27link": "https://www.freecodecamp.org/news/color-shades-hex-code-and-rgb-for-gray-color-palette/", + "article28title": "Binary Search Tree Traversal", + "article28link": "https://www.freecodecamp.org/news/binary-search-tree-traversal-inorder-preorder-post-order-for-bst/", + "article29title": "RTC Connecting Discord Fix", + "article29link": "https://www.freecodecamp.org/news/rtc-connecting-discord-how-to-fix-the-server-error/" + } \ No newline at end of file diff --git a/client/i18n/locales/espanol/intro.json b/client/i18n/locales/espanol/intro.json index 0452da462542fa..6ab339f48ed4d8 100644 --- a/client/i18n/locales/espanol/intro.json +++ b/client/i18n/locales/espanol/intro.json @@ -1,6 +1,6 @@ { "responsive-web-design": { - "title": "Legacy Responsive Web Design", + "title": "Diseño Web Responsivo Legado", "intro": [ "En esta Certificación de Diseño Web Responsivo, aprenderás los lenguajes que los desarrolladores utilizan para construir páginas web: HTML (lenguaje de marcado de hipertexto) para el contenido, y CSS (Hojas de estilo en cascada) para el diseño.", "Primero, crearás una aplicación de fotos de gatos para aprender los conceptos básicos de HTML y CSS. Más adelante, aprenderá técnicas modernas como variables CSS mediante la construcción de un pingüino, y las mejores prácticas para la accesibilidad mediante la construcción de un formulario web.", @@ -67,11 +67,11 @@ } }, "2022/responsive-web-design": { - "title": "(New) Responsive Web Design", + "title": "(Nuevo) Diseño Web Responsivo", "intro": [ "En esta certificación de Diseño Web Responsivo, aprenderás los lenguajes que los desarrolladores usan para construir páginas web: HTML (Lenguaje de Marcado de Hipertexto) para el contenido, y CSS (hojas de estilo en cascada) para el diseño.", - "Primero, crearás una aplicación de fotos de gatos para aprender los conceptos básicos de HTML y CSS. Más adelante, aprenderás técnicas modernas como variables CSS mediante la construcción de un pingüino, y las mejores prácticas para la accesibilidad mediante la construcción de un formulario web.", - "Finalmente, aprenderás cómo hacer páginas web que respondan a diferentes tamaños de pantalla construyendo una tarjeta de Twitter con Flexbox, y un diseño complejo de blog con CSS Grid." + "First, you'll build a cat photo app to learn the basics of HTML and CSS. Later, you'll learn modern techniques like CSS variables by building a penguin, and best practices for accessibility by building a quiz site.", + "Finally, you'll learn how to make webpages that respond to different screen sizes by building a photo gallery with Flexbox, and a magazine article layout with CSS Grid." ], "note": "Nota: Algunas extensiones del navegador, como bloqueadores de anuncios o extensiones de modo oscuro pueden interferir con las pruebas. Si tienes algun problema, te recomendamos deshabilitar las extensiones que modifiquen el contenido de la página, mientras tomas el curso.", "blocks": { @@ -300,64 +300,64 @@ } }, "2022/javascript-algorithms-and-data-structures": { - "title": "JavaScript Algorithms and Data Structures (Beta)", + "title": "Algoritmos de JavaScript y estructuras de datos (beta)", "intro": [ - "placeholder", - "placeholder" + "marcador de posición", + "marcador de posición" ], "note": "", "blocks": { "build-a-caesars-cipher-project": { - "title": "Build a Casears Cipher Project", + "title": "Build a Caesars Cipher Project", "intro": [ "", "" ] }, "build-a-cash-register-project": { - "title": "Build a Cash Register Project", + "title": "Construye un proyecto de caja registradora", "intro": [ "", "" ] }, "build-a-palindrome-checker-project": { - "title": "Build a Palindrome Checker Project", + "title": "Construye un proyecto de comprobación de palíndromos", "intro": [ "", "" ] }, "build-a-roman-numeral-converter-project": { - "title": "Build a Roman Numeral Converter Project", + "title": "Construye un proyecto de conversión de números romanos", "intro": [ "", "" ] }, "build-a-telephone-number-validator-project": { - "title": "Build a Telephone Number Validator Project", + "title": "Construye un proyecto validador de números de teléfono", "intro": [ "", "" ] }, "learn-basic-javascript-by-building-a-role-playing-game": { - "title": "Learn Basic JavaScript by Building a Role Playing Game", + "title": "Aprende JavaScript básico construyendo un juego de rol", "intro": [ "", "" ] }, "learn-form-validation-by-building-a-calorie-counter": { - "title": "Learn Form Validation by Building a Calorie Counter", + "title": "Aprende a validar formularios construyendo un contador de calorías", "intro": [ "", "" ] }, "learn-functional-programming-by-building-a-spreadsheet": { - "title": "Learn Functional Programming by Building a Spreadsheet", + "title": "Aprende programación funcional construyendo una hoja de cálculo", "intro": [ "", "" @@ -606,8 +606,8 @@ "mongodb-and-mongoose": { "title": "MongoDB y Mongoose", "intro": [ - "MongoDB es una aplicación de base de datos que almacena documentos (o registros) JSON que puedes utilizar en tu aplicación. A diferencia de SQL, otro tipo de base de datos, Mongo es una base de datos no relacional o \"NoSQL\". Esto significa que Mongo almacena todos los datos asociados dentro de un registro, en lugar de almacenarlos en varias tablas predefinidas como en una base de datos SQL.", - "Mongoose es un popular paquete npm que a menudo se instala junto con Mongo. Con Mongoose, puedes utilizar objetos de JavaScript simples en lugar de JSON, lo que hace más fácil trabajar con Mongo. Además, te permite crear plantillas para tus documentos llamados esquemas, para que no guarde accidentalmente el tipo equivocado de datos y cause errores más tarde.", + "MongoDB is a database application that stores JSON documents (or records) that you can use in your application. Unlike SQL, another type of database, MongoDB is a non-relational or \"NoSQL\" database. This means MongoDB stores all associated data within one record, instead of storing it across many preset tables as in a SQL database.", + "Mongoose is a popular npm package for interacting with MongoDB. With Mongoose, you can use plain JavaScript objects instead of JSON, which makes it easier to work with MongoDB. Also, it allows you to create blueprints for your documents called schemas, so you don't accidentally save the wrong type of data and cause bugs later.", "En los cursos de MongoDB y Mongoose, aprenderás los fundamentos para trabajar con datos persistentes, incluyendo cómo configurar un modelo, guardar, eliminar y encontrar documentos en la base de datos." ] }, @@ -804,7 +804,8 @@ "title": "Rosetta Code", "intro": [ "Sube tu nivel de habilidad de resolución creativa de problemas con estas tareas de programación gratis de la clásica librería de Rosetta Code.", - "Estos desafíos pueden resultar difíciles, pero empujarán tu lógica de algoritmos a nuevas alturas." + "Estos desafíos pueden resultar difíciles, pero empujarán tu lógica de algoritmos a nuevas alturas.", + "Attribute: Rosetta Code" ] }, "project-euler": { @@ -825,9 +826,9 @@ "collapse": "Contraer curso", "legacy-header": "Cursos Antiguos", "legacy-desc": "Estos cursos ya no forman parte de la ruta de certificación, pero todavía están disponibles para tu aprendizaje.", - "legacy-go-back": "Go to the current version of the curriculum.", - "new-rwd-desc": "We have updated our Responsive Web Design Curriculum. If you were previously working on the RWD curriculum, your progress is still saved! You can find it under the Legacy Responsive Web Design section.", - "new-rwd-article": "We encourage you to read about the changes we made and consider exploring the updated curriculum.", + "legacy-go-back": "Ve a la versión actual del plan de estudios.", + "new-rwd-desc": "Hemos actualizado nuestro plan de estudios de diseño web responsivo. Si anteriormente estabas trabajando en el plan de estudios de diseño web responsivo, ¡tu progreso sigue guardado! Puedes encontrarlo en la sección diseño web responsivo legado.", + "new-rwd-article": "Te animamos a leer sobre los cambios que hicimos y considerar explorar el plan de estudios actualizado.", "viewing-upcoming-change": "Estás viendo una página beta. ", "go-back-to-learn": "Volver a la versión estable del currículum.", "read-database-cert-article": "Por favor, lea este post del foro antes de continuar.", diff --git a/client/i18n/locales/espanol/links.json b/client/i18n/locales/espanol/links.json index 6d8a5223ba39f9..cb10cc4354667e 100644 --- a/client/i18n/locales/espanol/links.json +++ b/client/i18n/locales/espanol/links.json @@ -13,7 +13,10 @@ "copyright-url": "https://www.freecodecamp.org/news/copyright-policy/" }, "donate": { - "other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp" + "other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp", + "download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf", + "download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf", + "one-time-url": "https://paypal.me/freecodecamp" }, "nav": { "forum": "https://forum.freecodecamp.org/c/espanol/", @@ -23,6 +26,6 @@ "HTML-CSS": "Espanol/HTML-CSS", "JavaScript": "Espanol/JavaScript", "Python": "Espanol/Python", - "Relational Databases": "Espanol/Relational Databases" + "Backend Development": "espanol/ayuda-de-programacion" } } diff --git a/client/i18n/locales/espanol/translations.json b/client/i18n/locales/espanol/translations.json index 8dc3a37037d484..ce06a9c4ab4ef9 100644 --- a/client/i18n/locales/espanol/translations.json +++ b/client/i18n/locales/espanol/translations.json @@ -50,7 +50,8 @@ "reset-lesson": "Restablecer esta lección", "run": "Ejecutar", "run-test": "Ejecutar las Pruebas (Ctrl + Entrar)", - "check-code": "Check Your Code (Ctrl + Enter)", + "check-code": "Comprueba tu código (Ctrl + Enter)", + "check-code-2": "Check Your Code", "reset": "Restablecer", "reset-code": "Restablecer todo el código", "help": "Ayuda", @@ -70,7 +71,11 @@ "start-coding": "¡Empieza a programar!", "go-to-settings": "Ve a la configuración para reclamar tu certificación", "click-start-course": "Comienza el curso", - "click-start-project": "Comienza el proyecto" + "click-start-project": "Comienza el proyecto", + "change-language": "Cambiar Idioma", + "cancel-change": "Cancelar Cambio", + "resume-project": "Resume project", + "start-project": "Start project" }, "landing": { "big-heading-1": "Aprende a programar gratis.", @@ -101,7 +106,7 @@ }, "settings": { "share-projects": "Comparte tus proyectos, artículos o pull request aceptados que no sean de FreeCodeCamp.", - "privacy": "The settings in this section enable you to control what is shown on your freeCodeCamp public portfolio. Press save to save your changes.", + "privacy": "Los ajustes de esta sección te permiten controlar lo que se muestra en tu cartera pública de freeCodeCamp. Pulsa guardar para guardar tus cambios.", "data": "Para ver qué datos tenemos en tu cuenta, haz clic en el botón \"Descarga tus datos\" a continuación", "disabled": "Tus certificaciones se deshabilitarán si se configuran como privadas.", "private-name": "Tu nombre no aparecerá en tus certificaciones, si está establecido como privado.", @@ -143,7 +148,8 @@ "my-timeline": "Mi cronología", "my-donations": "Mis donaciones", "night-mode": "Modo nocturno", - "sound-mode": "Modo de fogata" + "sound-mode": "Modo de fogata", + "keyboard-shortcuts": "Enable Keyboard Shortcuts" }, "headings": { "certs": "Certificaciones", @@ -269,7 +275,7 @@ "solution-link": "Enlace a la solución", "github-link": "Enlace de GitHub", "submit-and-go": "Enviar y pasar a mi siguiente desafío", - "congradulations": "Congratulations, your code passes. Submit your code to complete this step and move on to the next one.", + "congratulations": "Congratulations, your code passes. Submit your code to continue.", "i-completed": "He completado este desafío", "test-output": "El resultado de tu prueba irá aquí", "running-tests": "// ejecutando pruebas", @@ -280,14 +286,14 @@ "percent-complete": "{{percent}}% completo", "tried-rsa": "Si ya has probado el método <0>Leer-Buscar-Preguntar, entonces puedes pedir ayuda en el foro de freeCodeCamp.", "rsa": "Leer, buscar, preguntar", + "rsa-forum": "Before making a new post please see if your question has <0>already been answered on the forum.", "reset": "¿Restablecer esta lección?", "reset-warn": "¿Estás seguro de que deseas restablecer esta lección? Los editores y las pruebas se restablecerán.", "reset-warn-2": "Esto no se puede deshacer", "scrimba-tip": "Sugerencia: Si el mini-navegador cubre el código, haz clic y arrastra para moverlo. Además, siéntete libre de detener y editar el código en el video en cualquier momento.", "chal-preview": "Vista previa del desafío", "cert-map-estimates": { - "certs": "Certificación {{title}} (300 horas)", - "coding-prep": "{{title}} (Miles de horas de desafíos)" + "certs": "{{title}} Certification" }, "editor-tabs": { "info": "Info", @@ -296,6 +302,7 @@ "restart": "Reiniciar", "restart-step": "Paso de reiniciar", "console": "Consola", + "instructions": "Instrucciones", "notes": "Notas", "preview": "Vista" }, @@ -308,15 +315,16 @@ "submit-public-url": "Cuando haya completado el proyecto, guarde todos los archivos requeridos en un repositorio público y envíe la URL a continuación.", "complete-both-steps": "Completa los dos pasos a continuación para terminar el desafío.", "runs-in-vm": "El proyecto se ejecuta en una máquina virtual, completa las historias de usuario descritas en ella y consigue que todas las pruebas pasen hasta el paso 1.", - "completed": "Completed", - "not-started": "Not started", - "hint": "Hint", - "test": "Test", - "sorry-try-again": "Sorry, your code does not pass. Try again.", - "sorry-keep-trying": "Sorry, your code does not pass. Keep trying.", - "sorry-getting-there": "Sorry, your code does not pass. You're getting there.", - "sorry-hang-in-there": "Sorry, your code does not pass. Hang in there.", - "sorry-dont-giveup": "Sorry, your code does not pass. Don't give up." + "completed": "Completado", + "not-started": "Sin iniciar", + "hint": "Sugerencia", + "test": "Prueba", + "sorry-try-again": "Lo sentimos, tu código no pasa. Inténtalo de nuevo.", + "sorry-keep-trying": "Lo sentimos, tu código no pasa. Continúa intentándolo.", + "sorry-getting-there": "Lo sentimos, tu código no pasa. Casi lo consigues.", + "sorry-hang-in-there": "Lo sentimos, su código no pasa. Aguanta ahí.", + "sorry-dont-giveup": "Lo sentimos, su código no pasa. No te rindas.", + "challenges-completed": "{{completedCount}} of {{totalChallenges}} challenges completed" }, "donate": { "title": "Apoya a nuestra organización sin fines de lucro", @@ -324,7 +332,6 @@ "redirecting": "Redirigiendo...", "thanks": "Gracias por donar", "thank-you": "Gracias por tu apoyo.", - "thank-you-2": "Gracias por apoyar a freeCodeCamp. Actualmente tienes una donación recurrente.", "additional": "Puede hacer una donación adicional única de cualquier monto utilizando este enlace: <0>{{url}}", "help-more": "Ayúdanos a hacer más", "error": "Algo salió mal con tu donación.", @@ -443,7 +450,9 @@ "and": "y", "change-theme": "Entra para cambiar el tema.", "translation-pending": "Ayúdanos a traducir", - "certification-project": "Proyecto de certificación" + "certification-project": "Proyecto de certificación", + "iframe-alert": "Normally this link would bring you to another website! It works. This is a link to: {{externalLink}}", + "document-notfound": "document not found" }, "icons": { "gold-cup": "Copa de Oro", @@ -452,8 +461,10 @@ "donate": "Dona con PayPal", "fail": "Prueba fallida", "not-passed": "Sin aprobar", + "waiting": "Waiting", "passed": "Aprobado", - "hint": "Hint", + "failed": "Failed", + "hint": "Sugerencia", "heart": "Corazón", "initial": "Inicial", "info": "Información de introducción", @@ -474,8 +485,11 @@ "last-page": "Ir a la última página", "primary-nav": "primario", "breadcrumb-nav": "migas de pan", - "submit": "Use Ctrl + Enter to submit.", - "running-tests": "Running tests" + "submit": "Utiliza Ctrl + Enter para enviar.", + "running-tests": "Ejecutando pruebas", + "step": "Step", + "steps": "Steps", + "steps-for": "Steps for {{blockTitle}}" }, "flash": { "honest-first": "Para reclamar una certificación, primero debes aceptar nuestra política de honestidad académica.", @@ -681,5 +695,16 @@ "delete-p3": "Necesitará crear un nuevo token para guardar el progreso futuro en las secciones de currículum que utilizan una máquina virtual.", "no-thanks": "No gracias, me gustaría quedarme con mi token", "yes-please": "Si por favor, deseo borrar mi token" + }, + "shortcuts": { + "title": "Keyboard shortcuts", + "table-header-action": "Action", + "table-header-key": "Key(s)", + "navigation-mode": "Navigation Mode", + "execute-challenge": "Execute Challenge", + "focus-editor": "Focus Editor", + "focus-instructions-panel": "Focus Instructions Panel", + "navigate-previous": "Navigate Previous Exercise", + "navigate-next": "Navigate Next Exercise" } } diff --git a/client/i18n/locales/german/intro.json b/client/i18n/locales/german/intro.json new file mode 100644 index 00000000000000..4a0b4b1cd1df76 --- /dev/null +++ b/client/i18n/locales/german/intro.json @@ -0,0 +1,838 @@ +{ + "responsive-web-design": { + "title": "Altes Responsives Webdesign", + "intro": [ + "In dieser Zertifizierung für \"Responsives Webdesign\" lernst Du die Sprachen, die Entwickler verwenden, um Webseiten zu erstellen: HTML (Hypertext Markup Language) für Inhalte, und CSS (Cascading Style Sheets) für Design.", + "Zuerst erstellst Du eine Katzenfoto-App, um die Grundlagen von HTML und CSS zu erlernen. Später lernst Du moderne Techniken wie CSS-Variablen, indem Du einen Pinguin erstellst und bewährte Abläufe für die Barrierefreiheit beim Erstellen eines Web-Formulars nutzt.", + "Schließlich lernst du, wie du Webseiten erstellst, die auf unterschiedliche Bildschirmgrößen reagieren, indem du eine Twitter-Karte mit Flexbox und ein komplexes Blog-Layout mit CSS Grid erstellst." + ], + "note": "Hinweis: Einige Browser-Erweiterungen, wie z. B. Ad-Blocker und Dark-Mode-Erweiterungen, können die Tests beeinträchtigen. Wenn du Probleme hast, empfehlen wir dir, Erweiterungen, die den Inhalt oder das Layout von Seiten verändern, zu deaktivieren, während du den Kurs machst.", + "blocks": { + "basic-html-and-html5": { + "title": "Grundlegendes HTML und HTML5", + "intro": [ + "HTML ist eine Auszeichnungssprache, die eine spezielle Syntax oder Notation verwendet, um die Struktur einer Webseite für den Browser zu beschreiben. HTML-Elemente haben normalerweise öffnende und schließende Tags, die den Inhalt umgeben und ihm Bedeutung verleihen. Zum Beispiel können verschiedene Elemente Text als Überschrift, Absatz oder Listenelement beschreiben.", + "In diesem Kurs wirst du eine Katzenfoto-App erstellen, um einige der häufigsten HTML-Elemente zu erlernen – das sind die Bausteine jeder Webseite." + ] + }, + "basic-css": { + "title": "Die Grundlagen von CSS", + "intro": [ + "CSS, oder Cascading Style Sheets, teilen dem Browser mit, wie der Text und andere Inhalte, die du in HTML schreibst, dargestellt werden sollen. Mit CSS kannst du die Farbe, die Schriftart, die Größe, die Abstände und viele andere Aspekte von HTML-Elementen steuern.", + "Jetzt, wo du die Struktur deiner Katzenfoto-App definiert hast, kannst du ihr mit CSS etwas Stil verleihen." + ] + }, + "applied-visual-design": { + "title": "Angewandtes visuelles Design", + "intro": [ + "Visuelles Design ist eine Kombination aus Typografie, Farbtheorie, Grafik, Animation, Seitenlayout und mehr, um deine individuelle Botschaft zu vermitteln.", + "In diesem Kurs lernst du, wie du diese verschiedenen Elemente des visuellen Designs auf deine Webseiten anwenden kannst." + ] + }, + "applied-accessibility": { + "title": "Angewandte Barrierefreiheit", + "intro": [ + "In der Webentwicklung bezieht sich Barrierefreiheit auf Webinhalte und eine UI (Benutzeroberfläche), die von einem breiten Publikum verstanden, navigiert und interagiert werden kann. Dies schließt Menschen mit Seh-, Hör-, Mobilitäts- oder kognitiven Behinderungen ein.", + "In diesem Kurs lernst du die besten Vorgehensweisen, um Webseiten zu erstellen, die für jeden zugänglich sind." + ] + }, + "responsive-web-design-principles": { + "title": "Prinzipien des responsiven Webdesigns", + "intro": [ + "Es gibt viele Geräte, die auf das Internet zugreifen können, und sie kommen in allen Formen und Größen vor. Responsives Webdesign ist die Praxis der Gestaltung flexibler Websites, die auf verschiedene Bildschirmgrößen, Ausrichtungen und Auflösungen reagieren können.", + "In diesem Kurs lernst du, wie du CSS benutzt, um deine Webseiten gut aussehen zu lassen, egal auf welchem Gerät sie betrachtet werden." + ] + }, + "css-flexbox": { + "title": "CSS Flexbox", + "intro": [ + "Flexbox ist eine leistungsstarke, gut unterstützte Layout-Methode, die mit der neuesten Version von CSS, CSS3, eingeführt wurde. Mit Flexbox ist es einfach, Elemente auf der Seite zu zentrieren und dynamische Benutzeroberflächen zu erstellen, die sich automatisch verkleinern und vergrößern.", + "In diesem Kurs lernst du die Grundlagen von Flexbox und dynamischen Layouts, indem du eine Twitter-Karte erstellst." + ] + }, + "css-grid": { + "title": "CSS Grid", + "intro": [ + "Das CSS Grid ist ein neuerer Standard, der es einfach macht, komplexe responsive Layouts zu erstellen. Es funktioniert, indem es ein HTML-Element in ein Raster verwandelt und du darin überall Kindelemente platzieren kannst.", + "In diesem Kurs lernst du die Grundlagen des CSS Grid, indem du verschiedene komplexe Layouts erstellst, darunter auch einen Blog." + ] + }, + "responsive-web-design-projects": { + "title": "Responsives Web Design Projekte", + "intro": [ + "Zeit, deine neu erlernten Fähigkeiten in die Tat umzusetzen. Indem du an diesen Projekten arbeitest, bekommst du die Chance, all die Fähigkeiten, Prinzipien und Konzepte anzuwenden, die du bisher gelernt hast: HTML, CSS, Visuelles Design, Barrierefreiheit und mehr.", + "Schließe die folgenden fünf Web-Programmierungsprojekte ab, um Deine Responsive Web Design Zertifizierung zu erhalten." + ] + } + } + }, + "2022/responsive-web-design": { + "title": "(Neu) Responsives Webdesign", + "intro": [ + "In dieser Zertifizierung für responsives Webdesign lernst du die Sprachen, die Entwickler/innen zum Erstellen von Webseiten verwenden: HTML (Hypertext Markup Language) für den Inhalt und CSS (Cascading Style Sheets) für das Design.", + "Zunächst baust du eine Katzenfoto-App, um die Grundlagen von HTML und CSS zu erlernen. Später lernst du moderne Techniken wie CSS-Variablen, indem du einen Pinguin baust, und bewährte Praktiken für Barrierefreiheit, indem du eine Quiz-Site erstellst.", + "Schließlich lernst du, wie du Webseiten erstellst, die auf unterschiedliche Bildschirmgrößen reagieren, indem du eine Fotogalerie mit Flexbox und ein Zeitschriftenartikel-Layout mit CSS Grid erstellst." + ], + "note": "Hinweis: Einige Browser-Erweiterungen, wie z. B. Werbeblocker und Dunkelmodus-Erweiterungen, können die Tests beeinträchtigen. Wenn du Probleme hast, empfehlen wir dir, Erweiterungen, die den Inhalt oder das Layout von Seiten verändern, während der Teilnahme am Kurs zu deaktivieren.", + "blocks": { + "build-a-tribute-page-project": { + "title": "Tribut-Seite", + "intro": [ + "Dies ist eines der Projekte, das du zum Erwerb deines Zertifikats benötigst.", + "In diesem Projekt erstellst du eine Tributseite für ein Thema deiner Wahl, egal ob fiktiv oder real." + ] + }, + "build-a-personal-portfolio-webpage-project": { + "title": "Persönliche Portfolio-Website", + "intro": [ + "Dies ist eines der Projekte, die du für den Erhalt deines Zertifikats benötigst.", + "Für dieses Projekt wirst du deine eigene Portfolioseite erstellen." + ] + }, + "build-a-product-landing-page-project": { + "title": "Produkt Landing Page", + "intro": [ + "Dies ist eines der Projekte, das du zum Erwerb deiner Zertifizierung benötigst.", + "In diesem Projekt wirst du eine Webseite erstellen, um ein Produkt deiner Wahl zu vermarkten." + ] + }, + "build-a-survey-form-project": { + "title": "Umfrageformular", + "intro": [ + "Dies ist eines der Projekte, die du zum Erwerb deines Zertifikats benötigst.", + "In diesem Projekt wirst du ein Umfrageformular erstellen, um Daten von deinen Nutzern zu sammeln." + ] + }, + "build-a-technical-documentation-page-project": { + "title": "Technische Dokumentationsseite", + "intro": [ + "Dies ist eines der Projekte, die du zum Erwerb deines Zertifikats benötigst.", + "In diesem Projekt wirst du eine technische Dokumentationsseite erstellen, die als Anleitung oder Referenz für ein Thema dient." + ] + }, + "learn-html-by-building-a-cat-photo-app": { + "title": "Lerne HTML, indem du eine Katzenfoto-App baust", + "intro": [ + "HTML-Tags geben einer Webseite ihre Struktur. Du kannst HTML-Tags verwenden, um Fotos, Schaltflächen und andere Elemente in deine Webseite einzufügen.", + "In diesem Kurs lernst du die gängigsten HTML-Tags kennen, indem du deine eigene Katzenfoto-App erstellst." + ] + }, + "learn-basic-css-by-building-a-cafe-menu": { + "title": "Lerne CSS-Grundlagen, indem du ein Cafe-Menü erstellst", + "intro": [ + "CSS teilt dem Browser mit, wie deine Webseite angezeigt werden soll. Du kannst mit CSS die Farbe, Schriftart, Größe und andere Aspekte von HTML-Elementen festlegen.", + "In diesem Kurs lernst du CSS, indem du eine Menüseite für eine Café-Webseite entwirfst." + ] + }, + "learn-the-css-box-model-by-building-a-rothko-painting": { + "title": "Lerne das CSS-Box-Modell durch die Erstellung eines Rothko-Gemäldes", + "intro": [ + "Jedes HTML-Element ist eine eigene Box - mit eigenem Abstand und einem Rahmen. Dies wird das Box-Modell genannt.", + "In diesem Kurs verwendest du CSS und das Box-Modell, um deine eigenen rechteckigen Kunstwerke im Rothko-Stil zu erstellen." + ] + }, + "learn-css-variables-by-building-a-city-skyline": { + "title": "Lerne CSS-Variablen, indem du eine Stadtsilhouette baust", + "intro": [ + "CSS-Variablen helfen dir, deine Stile zu organisieren und sie wiederzuverwenden.", + "In diesem Kurs wirst du eine Stadtsilhouette erstellen. Du lernst, wie du CSS-Variablen so konfigurierst, dass du sie jederzeit wiederverwenden kannst." + ] + }, + "learn-html-forms-by-building-a-registration-form": { + "title": "Erlerne HTML-Formulare, indem du ein Registrierungsformular erstellst", + "intro": [ + "Du kannst HTML-Formulare verwenden, um Informationen von Personen zu sammeln, die deine Webseite besuchen.", + "In diesem Kurs lernst du HTML-Formulare kennen, indem du eine Anmeldeseite erstellst. Du lernst, wie du steuern kannst, welche Daten in dein Formular eingegeben werden können, und wie du deine Seite mit neuen CSS-Tools gestalten kannst." + ] + }, + "learn-accessibility-by-building-a-quiz": { + "title": "Erlerne Barrierefreiheit, indem du ein Quiz erstellst", + "intro": [ + "Barrierefreiheit bedeutet, dass deine Webseite für alle Menschen leicht zu bedienen ist - auch für Menschen mit Beeinträchtigungen.", + "In diesem Kurs erstellst du eine Quiz-Webseite. Du lernst Hilfsmittel für die Barrierefreiheit wie Tastenkombinationen, ARIA-Attribute und bewährte Praktiken für das Design kennen." + ] + }, + "learn-intermediate-css-by-building-a-picasso-painting": { + "title": "Erlerne CSS für Fortgeschrittene durch die Erstellung eines Picasso-Gemäldes", + "intro": [ + "In diesem Kurs lernst du einige fortgeschrittene CSS-Techniken kennen, indem du deine eigene Webseite mit Picasso-Gemälden programmierst. Du lernst etwas über SVG-Symbole, CSS-Positionierung und wiederholst andere CSS-Kenntnisse, die du bereits gelernt hast." + ] + }, + "learn-responsive-web-design-by-building-a-piano": { + "title": "Erlerne responsives Webdesign, indem du ein Klavier erstellst", + "intro": [ + "Responsives Design beschreibt, wie deine Webseite auf unterschiedlich großen Bildschirmen aussehen soll.", + "In diesem Kurs wirst du CSS und responsives Design verwenden, um ein Klavier zu programmieren. Außerdem erfährst du mehr über Media-Queries und Pseudoselektoren." + ] + }, + "learn-css-flexbox-by-building-a-photo-gallery": { + "title": "Erlerne CSS Flexbox durch die Erstellung einer Fotogalerie", + "intro": [ + "Flexbox hilft dir, deine Webseite so zu gestalten, dass sie auf jeder Bildschirmgröße gut aussieht.", + "In diesem Kurs verwendest du Flexbox, um eine responsive Fotogalerie-Webseite zu erstellen." + ] + }, + "learn-css-grid-by-building-a-magazine": { + "title": "Erlerne das CSS-Raster (Grid) durch die Erstellung eines Magazins", + "intro": [ + "Mit dem CSS Raster hast du die Kontrolle über die Zeilen und Spalten deines Webseitendesigns.", + "In diesem Kurs wirst du einen Magazinartikel erstellen. Du lernst, wie du CSS Raster verwendest, einschließlich Konzepten wie Rasterzeilen und Rasterspalten." + ] + }, + "learn-typography-by-building-a-nutrition-label": { + "title": "Erlerne Typografie, indem du ein Ernährungsetikett erstellst", + "intro": [ + "Typografie ist die Kunst, deinen Text so zu gestalten, dass er gut lesbar ist und seinem Zweck gerecht wird.", + "In diesem Kurs entwickelst du mithilfe von Typografie eine Webseite mit Nährwertangaben. Du lernst, wie du Text formatieren, die Zeilenhöhe anpassen und deinen Text mit CSS positionieren kannst." + ] + }, + "learn-css-transforms-by-building-a-penguin": { + "title": "Erlerne CSS-Transformationen durch die Erstellung eines Pinguins", + "intro": [ + "Du kannst HTML-Elemente transformieren, um ansprechende Designs zu erstellen, die das Auge des Lesers anziehen. Mit Transformationen kannst du Elemente drehen, skalieren und vieles mehr.", + "In diesem Kurs wirst du einen Pinguin erstellen. Du verwendest CSS-Transformationen, um die Teile deines Pinguins zu positionieren und in der Größe zu verändern, einen Hintergrund zu erstellen und dein Werk zu animieren." + ] + }, + "learn-css-animation-by-building-a-ferris-wheel": { + "title": "Erlerne CSS-Animationen durch die Erstellung eines Riesenrads", + "intro": [ + "Du kannst CSS-Animationen verwenden, um die Aufmerksamkeit auf bestimmte Abschnitte deiner Webseite zu lenken und sie ansprechender zu gestalten.", + "In diesem Kurs wirst du ein Riesenrad erstellen. Du lernst, wie du CSS verwendest, um Elemente zu animieren, sie zu transformieren und ihre Geschwindigkeit anzupassen." + ] + }, + "learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet": { + "title": "Erfahre mehr über CSS-Pseudoselektoren, indem du eine Bilanz erstellst", + "intro": [ + "Du kannst CSS-Pseudoselektoren verwenden, um bestimmte HTML-Elemente zu ändern.", + "In diesem Kurs erstellst du eine Bilanz mit Pseudoselektoren. Du lernst, wie du den Stil eines Elements änderst, wenn du mit der Maus darüber fährst, und wie du andere Ereignisse auf deiner Webseite auslösen kannst." + ] + }, + "learn-css-colors-by-building-a-set-of-colored-markers": { + "title": "Erlerne CSS-Farben, indem du einen Satz farbiger Marker baust", + "intro": [ + "Die Wahl der richtigen Farben für deine Webseite kann die Ästhetik für deine LeserInnen erheblich verbessern.", + "In diesem Kurs erstellst du ein Set aus farbigen Markern. Du lernst verschiedene Möglichkeiten kennen, Farbwerte einzustellen und Farben miteinander zu kombinieren." + ] + } + } + }, + "javascript-algorithms-and-data-structures": { + "title": "JavaScript Algorithmen und Datenstrukturen", + "intro": [ + "Während HTML und CSS den Inhalt und das Styling einer Seite festlegen, wird JavaScript verwendet, um sie interaktiv zu gestalten. In der Zertifizierung \"JavaScript Algorithmen und Datenstrukturen\" lernst du die Grundlagen von JavaScript inklusive Variablen, Arrays, Objekten, Schleifen und Funktionen kennen.", + "Sobald du die Grundlagen beherrschst, wendest du dieses Wissen an, indem du Algorithmen erstellst, um Strings zu manipulieren, Zahlen zu faktorisieren und sogar die Umlaufbahn der Internationalen Raumstation zu berechnen.", + "Auf dem Weg dorthin wirst du auch zwei wichtige Programmierstile oder Paradigmen kennenlernen: Objektorientierte Programmierung (OOP) und funktionale Programmierung (FP)." + ], + "note": "Hinweis: Einige Browser-Erweiterungen, wie z. B. Ad-Blocker und Script-Blocker, können die Tests beeinträchtigen. Wenn du Probleme hast, empfehlen wir, Erweiterungen zu deaktivieren, die den Inhalt von Seiten verändern oder blockieren, während du den Kurs machst.", + "blocks": { + "basic-javascript": { + "title": "Die Grundlangen von JavaScript", + "intro": [ + "JavaScript ist eine Skriptsprache, mit der du Webseiten interaktiv gestalten kannst. Sie ist eine der Kerntechnologien des Webs, zusammen mit HTML und CSS, und wird von allen modernen Browsern unterstützt.", + "In diesem Kurs lernst du fundamentale Programmierkonzepte in JavaScript. Du beginnst mit grundlegenden Datenstrukturen wie Zahlen und Strings. Dann lernst du, mit Arrays, Objekten, Funktionen, Schleifen, if/else-Anweisungen und mehr zu arbeiten." + ] + }, + "es6": { + "title": "ES6", + "intro": [ + "ECMAScript, oder ES, ist eine standardisierte Version von JavaScript. Weil alle großen Browser-Hersteller dieser Spezifikation folgen, sind die Begriffe ECMAScript und JavaScript austauschbar.", + "Das meiste JavaScript, das du bis zu diesem Punkt gelernt hast, war in ES5 (ECMAScript 5), das 2009 fertiggestellt wurde. Du kannst zwar immer noch Programme in ES5 schreiben, aber JavaScript wird ständig weiterentwickelt, und jedes Jahr werden neue Funktionen veröffentlicht.", + "ES6, das 2015 veröffentlicht wurde, hat der Sprache viele leistungsstarke neue Funktionen hinzugefügt. In diesem Kurs lernst du diese neuen Funktionen kennen, darunter Pfeilfunktionen, Destrukturierung, Klassen, Promises und Module." + ] + }, + "regular-expressions": { + "title": "Reguläre Ausdrücke", + "intro": [ + "Reguläre Ausdrücke, oft abgekürzt als \"regex\" oder \"regexp\", sind Pattern (Muster), die Programmierern helfen, Text zu finden, zu suchen und zu ersetzen. Reguläre Ausdrücke sind sehr mächtig, können aber schwer zu lesen sein, weil sie Sonderzeichen verwenden, um komplexere, flexible Übereinstimmungen zu machen.", + "In diesem Kurs lernst du, wie du Sonderzeichen, Capture-Gruppen, positive und negative Lookaheads und andere Techniken verwenden kannst, um jeden beliebigen Text zu finden." + ] + }, + "debugging": { + "title": "Debugging", + "intro": [ + "Debugging ist der Prozess, bei dem du deinen Code durchgehst, Probleme findest und sie behebst.", + "Probleme im Code treten im Allgemeinen in drei Formen auf: Syntaxfehler, die verhindern, dass dein Programm läuft, Laufzeitfehler, bei denen dein Code ein unerwartetes Verhalten zeigt, oder logische Fehler, bei denen dein Code nicht das tut, was du beabsichtigt hast.", + "In diesem Kurs lernst du, wie du die JavaScript-Konsole nutzen kannst, um Programme zu debuggen und häufige Probleme zu vermeiden, bevor sie auftreten." + ] + }, + "basic-data-structures": { + "title": "Grundlegende Datenstrukturen", + "intro": [ + "Daten können auf viele Arten gespeichert und abgerufen werden. Du kennst bereits einige gängige JavaScript Datenstrukturen - Arrays und Objekte.", + "In diesem Kurs über grundlegende Datenstrukturen erfährst du mehr über die Unterschiede zwischen Arrays und Objekten und welche du in verschiedenen Situationen verwenden kannst. Außerdem lernst du, wie du hilfreiche JS-Methoden wie splice() und Object.keys() verwenden kannst, um auf Daten zuzugreifen und sie zu manipulieren." + ] + }, + "basic-algorithm-scripting": { + "title": "Grundlagen des Algorithmus Scripting", + "intro": [ + "Ein Algorithmus ist eine Reihe von Schritt-für-Schritt-Anweisungen, die beschreiben, wie etwas zu tun ist.", + "Um einen effektiven Algorithmus zu schreiben, hilft es, ein Problem in kleinere Teile zu zerlegen und sorgfältig darüber nachzudenken, wie man jeden Teil mit Code löst.", + "In diesem Kurs lernst du die Grundlagen des algorithmischen Denkens, indem du Algorithmen schreibst, die alles von der Umwandlung von Temperaturen bis hin zum Umgang mit komplexen 2D-Arrays tun." + ] + }, + "object-oriented-programming": { + "title": "Objektorientierte Programmierung", + "intro": [ + "OOP, oder objektorientierte Programmierung, ist einer der wichtigsten Ansätze für den Softwareentwicklungsprozess. In OOP organisieren Objekte und Klassen den Code, um Dinge zu beschreiben und was sie tun können.", + "In diesem Kurs lernst du die Grundprinzipien der OOP in JavaScript kennen, einschließlich des this-Schlüsselworts, Prototypenketten, Konstruktoren und Vererbung." + ] + }, + "functional-programming": { + "title": "Funktionale Programmierung", + "intro": [ + "Funktionale Programmierung ist ein weiterer beliebter Ansatz für die Softwareentwicklung. Bei der funktionalen Programmierung wird der Code in kleinere, grundlegende Funktionen unterteilt, die zum Aufbau komplexer Programme kombiniert werden können.", + "In diesem Kurs lernst du die Kernkonzepte der Funktionalen Programmierung, einschließlich reiner Funktionen, wie man Mutationen vermeidet und wie man saubereren Code mit Methoden wie .map() und .filter() schreibt." + ] + }, + "intermediate-algorithm-scripting": { + "title": "Fortgeschrittenes Algorithmus Scripting", + "intro": [ + "Jetzt, wo du die Grundlagen des algorithmischen Denkens, zusammen mit OOP und funktionaler Programmierung kennst, kannst du deine Fähigkeiten mit den fortgeschrittenen Algorithmus-Scripting-Herausforderungen testen." + ] + }, + "javascript-algorithms-and-data-structures-projects": { + "title": "JavaScript Algorithmen- und Datenstrukturprojekte", + "intro": [ + "Geschafft! Zeit, deine neuen JavaScript-Fähigkeiten zum Einsatz zu bringen. Diese Projekte ähneln den Herausforderungen des Algorithmus-Skriptens, die du zuvor durchgeführt hast – nur viel schwieriger.", + "Schließe diese 5 JavaScript Projekte ab, um die JavaScript Algorithmen und Datenstrukturen Zertifizierung zu erhalten." + ] + } + } + }, + "2022/javascript-algorithms-and-data-structures": { + "title": "JavaScript-Algorithmen und Datenstrukturen (Beta)", + "intro": [ + "Platzhalter", + "Platzhalter" + ], + "note": "", + "blocks": { + "build-a-caesars-cipher-project": { + "title": "Erstelle ein Caesar-Verschlüsselung Projekt", + "intro": [ + "", + "" + ] + }, + "build-a-cash-register-project": { + "title": "Erstelle ein Registrierkassenprojekt", + "intro": [ + "", + "" + ] + }, + "build-a-palindrome-checker-project": { + "title": "Erstelle ein Palindromprüfer Projekt", + "intro": [ + "", + "" + ] + }, + "build-a-roman-numeral-converter-project": { + "title": "Erstelle ein Projekt zur Umwandlung römischer Ziffern", + "intro": [ + "", + "" + ] + }, + "build-a-telephone-number-validator-project": { + "title": "Erstelle ein Telefonnummernvalidierungsprojekt", + "intro": [ + "", + "" + ] + }, + "learn-basic-javascript-by-building-a-role-playing-game": { + "title": "Lerne die Grundlagen von JavaScript durch die Entwicklung eines Rollenspiels", + "intro": [ + "", + "" + ] + }, + "learn-form-validation-by-building-a-calorie-counter": { + "title": "Lerne die Formularvalidierung anhand eines Kalorienzählers", + "intro": [ + "", + "" + ] + }, + "learn-functional-programming-by-building-a-spreadsheet": { + "title": "Lerne die funktionale Programmierung durch das Erstellen einer Tabellenkalkulation", + "intro": [ + "", + "" + ] + } + } + }, + "front-end-development-libraries": { + "title": "Front-End-Entwicklungsbibliotheken", + "intro": [ + "Jetzt, wo du mit HTML, CSS und JavaScript vertraut bist, kannst du deine Fähigkeiten verbessern, indem du einige der beliebtesten Front-End-Bibliotheken der Branche lernst.", + "In der Zertifizierung für Front-End-Entwicklungsbibliotheken lernst du, wie du deine Seite mit Bootstrap schnell stylen kannst. Du lernst auch, wie du Logik zu deinen CSS-Styles hinzufügst und sie mit Sass erweiterst.", + "Später baust du einen Warenkorb und andere Anwendungen, um zu lernen, wie du mit React und Redux leistungsstarke Single Page Applications (SPAs) erstellen kannst." + ], + "note": "", + "blocks": { + "bootstrap": { + "title": "Bootstrap", + "intro": [ + "Bootstrap ist ein Front-End-Framework, das für das Design von responsiven Webseiten und Anwendungen verwendet wird. Es verfolgt einen Mobile-First-Ansatz für die Webentwicklung und beinhaltet vorgefertigte CSS-Stile und -Klassen sowie einige JavaScript-Funktionen.", + "In diesem Kurs lernst du, wie du mit Bootstrap responsive Websites erstellst und die enthaltenen Klassen nutzt, um Buttons, Bilder, Formulare, Navigation und andere gängige Elemente zu gestalten." + ] + }, + "jquery": { + "title": "jQuery", + "intro": [ + "jQuery ist eine der am meisten genutzten JavaScript-Bibliotheken der Welt.", + "Im Jahr 2006, als es veröffentlicht wurde, behandelten alle großen Browser JavaScript etwas anders. jQuery vereinfachte den Prozess des Schreibens von clientseitigem JavaScript und stellte außerdem sicher, dass dein Code in allen Browsern auf die gleiche Weise funktioniert.", + "In diesem Kurs lernst du, wie du jQuery verwenden kannst, um verschiedene Elemente auf der Seite auszuwählen, zu entfernen, zu klonen und zu verändern." + ] + }, + "sass": { + "title": "SASS", + "intro": [ + "Sass, oder \"Syntactically Awesome StyleSheets\", ist eine Spracherweiterung von CSS. Es fügt Funktionen hinzu, die im Basis-CSS nicht verfügbar sind, die es dir erleichtern, die Stylesheets für deine Projekte zu vereinfachen und zu pflegen.", + "In diesem Sass Kurs lernst du, wie du Daten in Variablen speicherst, CSS verschachtelst, wiederverwendbare Styles mit Mixins erstellst, Logik und Schleifen zu deinen Styles hinzufügst und vieles mehr." + ] + }, + "react": { + "title": "React", + "intro": [ + "React ist eine beliebte JavaScript-Bibliothek, um wiederverwendbare, komponentengesteuerte Benutzeroberflächen für Webseiten oder Anwendungen zu erstellen.", + "React kombiniert HTML mit JavaScript-Funktionalität in einer eigenen Auszeichnungssprache namens JSX. React macht es auch einfach, den Datenfluss in der gesamten Anwendung zu verwalten.", + "In diesem Kurs lernst du, wie du verschiedene React-Komponenten erstellst, Daten in Form von State Props verwaltest, verschiedene Lifecycle-Methoden wie componentDidMount verwendest und vieles mehr." + ] + }, + "redux": { + "title": "Redux", + "intro": [ + "Wenn Anwendungen größer und umfangreicher werden, wird die Verwaltung von gemeinsam genutzten Daten viel schwieriger. Redux wird als \" vorhersagbarer Zustandscontainer für JavaScript-Apps\" definiert, der dabei hilft, dass deine Apps vorhersagbar funktionieren und einfacher zu testen sind.", + "Obwohl du Redux mit jeder Ansichtsbibliothek verwenden kannst, stellen wir Redux hier vor, bevor wir es in den nächsten Kursen mit React kombinieren.", + "In diesem Kurs lernst du die Grundlagen von Redux stores, actions, reducers und middleware, um Daten in deiner Anwendung zu verwalten." + ] + }, + "react-and-redux": { + "title": "React und Redux", + "intro": [ + "React und Redux werden oft zusammen erwähnt, und das aus gutem Grund. Der Entwickler, der Redux geschaffen hat, war ein React-Entwickler, der es einfacher machen wollte, Daten über verschiedene Komponenten hinweg zu teilen.", + "Jetzt, wo du weißt, wie du den Fluss von geteilten Daten mit Redux verwalten kannst, ist es an der Zeit, dieses Wissen mit React zu kombinieren. In den React- und Redux-Kursen baust du eine React-Komponente und lernst, wie du den Zustand lokal auf der Komponentenebene und in der gesamten Anwendung mit Redux verwalten kannst." + ] + }, + "front-end-development-libraries-projects": { + "title": "Projekte für Front-End-Entwicklung-Bibliotheken", + "intro": [ + "Es ist an der Zeit, deine Fähigkeiten im Bereich der Front-End-Entwicklungs-Bibliotheken auf die Probe zu stellen. Benutze Bootstrap, jQuery, Sass, React und Redux, um 5 Projekte zu bauen, die alles testen, was du bis zu diesem Punkt gelernt hast.", + "Schließe alle 5 Projekte ab und du erhältst die Zertifizierung für Front-End-Entwicklungs-Bibliotheken." + ] + } + } + }, + "data-visualization": { + "title": "Datenvisualisierung", + "intro": [ + "Daten sind überall um uns herum, aber ohne Form und Kontext bedeuten sie nicht viel.", + "In der Datenvisualisierung-Zertifizierung erstellst du Diagramme, Grafiken und Karten, um verschiedene Arten von Daten mit der D3.js Bibliothek zu präsentieren.", + "Du lernst auch etwas über JSON (JavaScript Object Notation) und wie man mit Daten online über eine API (Application Programming Interface) arbeitet." + ], + "note": "", + "blocks": { + "data-visualization-with-d3": { + "title": "Datenvisualisierung mit D3", + "intro": [ + "D3, oder D3.js, steht für Data Driven Documents. Es ist eine JavaScript Bibliothek, um dynamische und interaktive Datenvisualisierungen im Browser zu erstellen.", + "D3 ist so aufgebaut, dass es mit gängigen Webstandards arbeitet - nämlich HTML, CSS und Scalable Vector Graphics (SVG).", + "D3 unterstützt viele verschiedene Arten von Eingangsdatenformaten. Mit den leistungsstarken eingebauten Methoden kannst du diese Daten dann in verschiedene Diagramme, Graphen und Karten umwandeln.", + "In den Kursen zur Datenvisualisierung mit D3 lernst du, wie du mit Daten arbeitest, um verschiedene Diagramme, Graphen, Hover-Elemente und andere Zutaten zu erstellen, um dynamische und attraktive Datenvisualisierungen zu erstellen." + ] + }, + "json-apis-and-ajax": { + "title": "JSON APIs und AJAX", + "intro": [ + "Ähnlich wie Benutzeroberflächen Menschen bei der Verwendung von Programmen helfen, helfen APIs (Application Programming Interfaces) Programmen bei der Interaktion mit anderen Programmen. APIs sind Werkzeuge, die Computer verwenden, um miteinander zu kommunizieren, unter anderem um Daten zu senden und zu empfangen.", + "Programmierer verwenden häufig AJAX (Asynchronous JavaScript and XML), wenn sie mit APIs arbeiten. AJAX bezieht sich auf eine Gruppe von Technologien, die asynchrone Anfragen an einen Server stellen, um Daten zu übertragen, und dann alle zurückgegebenen Daten in die Seite laden. Und die Daten, die zwischen dem Browser und dem Server übertragen werden, liegen oft in einem Format namens JSON (JavaScript Object Notation) vor.", + "In diesem Kurs lernst du die Grundlagen über die Arbeit mit APIs und verschiedenen AJAX Technologien im Browser." + ] + }, + "data-visualization-projects": { + "title": "Datenvisualisierungsprojekte", + "intro": [ + "Jetzt, wo du gelernt hast, wie man mit D3, APIs und AJAX-Technologien arbeitet, kannst du deine Fähigkeiten mit diesen 5 Datenvisualisierungsprojekten auf die Probe stellen.", + "In diesen Projekten musst du Daten abrufen und einen Datensatz parsen und dann D3 verwenden, um verschiedene Datenvisualisierungen zu erstellen. Beende sie alle, um deine Datenvisualisierungs-Zertifizierung zu erhalten." + ] + }, + "d3-dashboard": { + "title": "D3 Dashboard", + "intro": [ + "", + "" + ] + } + } + }, + "relational-database": { + "title": "Relationale Datenbanken (Beta)", + "intro": [ + "In diesen Kursen verwendest du echte Entwickler-Tools und Software wie VS Code, PostgreSQL und die Linux/Unix-Kommandozeile, um interaktive Tutorials zu absolvieren und Projekte zu erstellen.", + "Diese Kurse beginnen mit den grundlegenden Bash-Befehlen. Über das Terminal lernst du alles von der Navigation und dem Umgang mit dem Dateisystem über das Skripting in der Bash bis hin zur fortgeschrittenen Nutzung.", + "Als Nächstes lernst du, wie du eine relationale Datenbank mit PostgreSQL, einem Datenbankmanagementsystem, und SQL, der Sprache dieser Datenbanken, erstellst und verwendest.", + "Schließlich lernst du Git kennen, das Versionskontrollsystem, ein unverzichtbares Werkzeug für jeden Entwickler." + ], + "blocks": { + "build-a-celestial-bodies-database-project": { + "title": "Himmelskörperdatenbank", + "intro": [ + "Dies ist eines der Projekte, das du zum Erwerb deines Zertifikats benötigst.", + "In diesem Projekt wirst du eine Datenbank für Himmelskörper mit PostgreSQL erstellen." + ] + }, + "build-a-number-guessing-game-project": { + "title": "Zahlenratespiel", + "intro": [ + "Dies ist eines der Projekte, das du zum Erwerb deines Zertifikats benötigst.", + "In diesem Projekt verwendest du Bash-Skripte, PostgreSQL und Git, um ein Zahlenratespiel zu erstellen, das im Terminal läuft und Benutzerinformationen speichert." + ] + }, + "build-a-periodic-table-database-project": { + "title": "Periodensystemdatenbank", + "intro": [ + "Dies ist eines der Projekte, das du zum Erwerb deines Zertifikats benötigst.", + "In diesem Projekt erstellst du mit Bash ein Skript, das Informationen über chemische Elemente aus einer Datenbank des Periodensystems abruft." + ] + }, + "build-a-salon-appointment-scheduler-project": { + "title": "Salon-Terminplaner", + "intro": [ + "Dies ist eines der Projekte, das du zum Erwerb deines Zertifikats benötigst.", + "In diesem Projekt erstellst du ein interaktives Bash-Programm, das PostgreSQL nutzt, um die Kunden und Termine deines Salons zu verwalten." + ] + }, + "build-a-world-cup-database-project": { + "title": "WM-Datenbank", + "intro": [ + "Dies ist eines der Projekte, das du zum Erwerb deines Zertifikats benötigst.", + "In diesem Projekt erstellst du ein Bash-Skript, das Informationen von WM-Spielen in PostgreSQL übernimmt und dann die Datenbank nach nützlichen Statistiken abfragt." + ] + }, + "learn-advanced-bash-by-building-a-kitty-ipsum-translator": { + "title": "Lerne Bash für Fortgeschrittene, indem du einen Kitty Ipsum Übersetzer erstellst", + "intro": [ + "Hinter den Bash-Befehlen steckt mehr, als du vielleicht denkst.", + "In diesem Kurs mit 140 Lektionen lernst du einige komplexere Befehle und die Details, wie die Befehle funktionieren." + ] + }, + "learn-bash-and-sql-by-building-a-bike-rental-shop": { + "title": "Lerne Bash und SQL durch den Aufbau eines Fahrradverleihs", + "intro": [ + "In diesem Kurs mit 210 Lektionen erstellst du ein interaktives Bash-Programm, das mit Hilfe von PostgreSQL Mietinformationen für deinen Fahrradverleih speichert." + ] + }, + "learn-bash-by-building-a-boilerplate": { + "title": "Bash lernen durch das Erstellen eines Textbausteines (Boilerplate)", + "intro": [ + "Mit dem Terminal kannst du Textbefehle an deinen Computer senden, mit denen du das Dateisystem manipulieren, Programme ausführen, Aufgaben automatisieren und vieles mehr kannst.", + "In diesem Kurs mit 170 Lektionen lernst du Terminal-Befehle, indem du eine Website-Boilerplate nur über die Kommandozeile erstellst." + ] + }, + "learn-bash-scripting-by-building-five-programs": { + "title": "Lerne Bash-Scripting, indem du fünf Programme erstellst", + "intro": [ + "Bash-Skripte kombinieren Terminalbefehle und Logik zu Programmen, die Aufgaben ausführen oder automatisieren können, und vieles mehr.", + "In diesem Kurs mit 220 Lektionen lernst du weitere Terminalbefehle kennen und wie du sie in Bash-Skripten verwenden kannst, indem du fünf kleine Programme erstellst." + ] + }, + "learn-git-by-building-an-sql-reference-object": { + "title": "Git lernen durch Erstellen eines SQL-Referenzobjekts", + "intro": [ + "Git ist ein Versionskontrollsystem, das alle Änderungen, die du an deiner Codebasis vornimmst, aufzeichnet.", + "In diesem Kurs mit 240 Lektionen lernst du, wie Git den Überblick über deinen Code behält, indem es ein Objekt mit häufig verwendeten SQL-Befehlen erstellt." + ] + }, + "learn-nano-by-building-a-castle": { + "title": "Nano lernen durch den Bau einer Burg", + "intro": [ + "Nano ist ein Programm, mit dem du Dateien direkt im Terminal bearbeiten kannst.", + "In diesem Kurs mit 40 Lektionen lernst du, wie du Dateien im Terminal mit Nano bearbeitest, während du eine Burg baust." + ] + }, + "learn-relational-databases-by-building-a-mario-database": { + "title": "Relationale Datenbanken lernen, indem du eine Mario-Datenbank erstellst", + "intro": [ + "Eine relationale Datenbank organisiert die Daten in Tabellen, die durch Beziehungen miteinander verbunden sind.", + "In diesem Kurs mit 165 Lektionen lernst du die Grundlagen einer relationalen Datenbank kennen, indem du eine PostgreSQL-Datenbank mit Videospielcharakteren erstellst." + ] + }, + "learn-sql-by-building-a-student-database-part-1": { + "title": "Lerne SQL, indem du eine Schülerdatenbank aufbaust: Teil 1", + "intro": [ + "SQL, oder Structured Query Language, ist die Sprache für die Kommunikation mit einer relationalen Datenbank.", + "In diesem Kurs mit 140 Lektionen erstellst du ein Bash-Skript, das SQL verwendet, um Informationen über deine Informatikstudenten in PostgreSQL einzugeben." + ] + }, + "learn-sql-by-building-a-student-database-part-2": { + "title": "Lerne SQL, indem du eine Schülerdatenbank aufbaust: Teil 2", + "intro": [ + "SQL-Join-Befehle werden verwendet, um Informationen aus mehreren Tabellen in einer relationalen Datenbank zu kombinieren", + "In diesem Kurs mit 140 Lektionen wirst du deine Schülerdatenbank vervollständigen und gleichzeitig tiefer in die SQL-Befehle eintauchen." + ] + } + } + }, + "back-end-development-and-apis": { + "title": "Back-End Entwicklung und APIs", + "intro": [ + "Bis zu diesem Punkt hast du JavaScript nur im Front-End verwendet, um einer Seite Interaktivität hinzuzufügen, Aufgaben mit Algorithmen zu lösen oder eine SPA zu bauen. Aber JavaScript kann auch im Back-End, also auf dem Server, verwendet werden, um ganze Webanwendungen zu erstellen.", + "Heutzutage ist eine der beliebtesten Arten, Anwendungen zu erstellen, Microservices. Das sind kleine, modulare Anwendungen, die zusammenarbeiten und ein größeres Ganzes bilden.", + "In der Zertifizierung für Back-End-Entwicklung und APIs lernst du, wie du Back-End-Apps mit Node.js und npm (Node Package Manager) schreibst. Du wirst auch Webanwendungen mit dem Express-Framework erstellen und einen Personensuche-Microservice mit MongoDB und der Mongoose-Bibliothek bauen." + ], + "note": "", + "blocks": { + "managing-packages-with-npm": { + "title": "Pakete mit NPM verwalten", + "intro": [ + "npm (Node Package Manager) ist ein Kommandozeilen-Tool zum Installieren, Erstellen und Teilen von Paketen mit JavaScript-Code, der für Node.js geschrieben wurde. Es gibt viele Open-Source-Pakete, die auf npm verfügbar sind. Bevor du also ein Projekt beginnst, solltest du dir etwas Zeit nehmen, um dich zu informieren, damit du nicht am Ende das Rad neu erfinden musst, wenn du z.B. mit Daten arbeitest oder Daten von einer API abrufst.", + "In diesem Kurs lernst du die Grundlagen der Verwendung von npm. Du erfährst, wie du mit der package.json arbeitest und wie du deine installierten Abhängigkeiten (Dependencies) verwalten kannst." + ] + }, + "basic-node-and-express": { + "title": "Basis Node und Express", + "intro": [ + "Node.js ist eine JavaScript-Laufzeitumgebung, die es Entwicklern ermöglicht, Back-End-Programme (serverseitige Programme) in JavaScript zu schreiben. Node.js kommt mit einer Handvoll eingebauter Module - kleine, unabhängige Programme - die dabei helfen. Einige der Kernmodule sind HTTP, das wie ein Server agiert, und Dateisystem, ein Modul zum Lesen und Ändern von Dateien.", + "In den letzten Kursen hast du gelernt, Pakete von npm zu installieren und zu verwalten, die Sammlungen von kleineren Modulen sind. Diese Pakete können dir helfen, größere, komplexere Anwendungen zu bauen.", + "Express ist ein leichtgewichtiges Framework für Webanwendungen und eines der beliebtesten Pakete auf npm. Mit Express ist es viel einfacher, einen Server zu erstellen und das Routing für deine Anwendung zu verwalten. Damit wird z. B. sichergestellt, dass Besucher auf die richtige Seite geleitet werden, wenn sie einen bestimmten Endpunkt wie
/blog
besuchen.", + "In diesem Kurs lernst du die Grundlagen von Node und Express. Du erfährst, wie du einen Server erstellst, verschiedene Dateien bereitstellst und verschiedene Anfragen des Browsers bearbeitest." + ] + }, + "mongodb-and-mongoose": { + "title": "MongoDB und Mongoose", + "intro": [ + "MongoDB ist eine Datenbankanwendung, die JSON-Dokumente (oder Datensätze) speichert, die du in deiner Anwendung verwenden kannst. Im Gegensatz zu SQL - einer anderen Art von Datenbank - ist MongoDB eine nicht-relationale oder \"NoSQL\"-Datenbank. Das bedeutet, dass MongoDB alle zugehörigen Daten innerhalb eines Datensatzes speichert, anstatt sie über viele voreingestellte Tabellen wie in einer SQL-Datenbank zu speichern.", + "Mongoose ist ein beliebtes npm-Paket für die Interaktion mit MongoDB. Mit Mongoose kannst du einfache JavaScript-Objekte anstelle von JSON verwenden, was die Arbeit mit MongoDB einfacher macht. Außerdem kannst du mit Mongoose Schemas für deine Dokumente erstellen, damit du nicht aus Versehen den falschen Datentyp speicherst und später Fehler verursachst.", + "In den MongoDB- und Mongoose-Kursen lernst du die Grundlagen der Arbeit mit persistenten Daten, einschließlich der Einrichtung eines Modells und dem Speichern, Löschen und Suchen von Dokumenten in der Datenbank." + ] + }, + "back-end-development-and-apis-projects": { + "title": "Projekte für Back-End Entwicklung und APIs", + "intro": [ + "Du hast bereits mit APIs gearbeitet, aber jetzt, wo du npm, Node, Express, MongoDB und Mongoose kennst, ist es an der Zeit, deine eigenen zu bauen. Nutze alles, was du bisher gelernt hast, um 5 verschiedene Microservices zu erstellen, also kleinere Anwendungen, die in ihrem Umfang begrenzt sind.", + "Nachdem du diese erstellt hast, wirst du 5 coole Microservice-APIs haben, mit denen du bei Freunden, Familie und potentiellen Arbeitgebern angeben kannst. Oh, und du wirst auch eine glänzende neue Zertifizierung für Back-End-Entwicklung und APIs haben." + ] + } + } + }, + "quality-assurance": { + "title": "Qualitätssicherung", + "intro": [ + "Wenn deine Programme oder Webanwendungen komplexer werden, solltest du sie testen, um sicherzustellen, dass neue Änderungen nicht die ursprüngliche Funktionalität zerstören.", + "In der Qualitätssicherungs-Zertifizierung lernst du, wie du mit Chai Tests schreibst, um sicherzustellen, dass deine Anwendungen so funktionieren, wie du es von ihnen erwartest.", + "Dann baust du eine Chat-Anwendung, um fortgeschrittene Node- und Express-Konzepte zu lernen. Du wirst auch Pug als Template-Engine, Passport für die Authentifizierung und Socket.io für die Echtzeitkommunikation zwischen dem Server und den verbundenen Clients verwenden." + ], + "note": "", + "blocks": { + "quality-assurance-and-testing-with-chai": { + "title": "Qualitätssicherung und Testen mit Chai", + "intro": [ + "Chai ist eine JavaScript Testbibliothek, die dir hilft zu bestätigen, dass sich dein Programm immer noch so verhält, wie du es erwartest, nachdem du Änderungen an deinem Code vorgenommen hast.", + "Mit Chai kannst du Tests schreiben, die die Anforderungen deines Programms beschreiben und sehen, ob dein Programm sie erfüllt.", + "In diesem Kurs lernst du etwas über Assertions, Deep Equality, Wahrhaftigkeit (\"truthiness\"), das Testen von APIs und andere Grundlagen zum Testen von JavaScript-Anwendungen." + ] + }, + "advanced-node-and-express": { + "title": "Node und Express für Fortgeschrittene", + "intro": [ + "Jetzt ist es an der Zeit, tief in Node.js und Express.js einzutauchen, indem wir eine Chat-Anwendung mit einem Anmeldesystem bauen.", + "Um das Anmeldesystem sicher zu implementieren, musst du etwas über Authentifizierung lernen. Dies ist der Akt der Identitätsprüfung einer Person oder eines Prozesses.", + "In diesem Kurs lernst du, wie du mit Passport die Authentifizierung verwaltest, mit Pug wiederverwendbare Templates für die schnelle Erstellung des Front-Ends erstellst und Websockets für die Echtzeitkommunikation zwischen Clients und Server nutzt." + ] + }, + "quality-assurance-projects": { + "title": "Qualitätssicherungsprojekte", + "intro": [ + "Jetzt, wo du dich sowohl im Front-End als auch im Back-End gut auskennst, ist es an der Zeit, all die Fähigkeiten und Konzepte anzuwenden, die du bis zu diesem Punkt gelernt hast. Du wirst 5 verschiedene Webapplikationen erstellen und für jede einzelne Tests schreiben, um sicherzustellen, dass sie funktionieren und mit verschiedenen Randfällen umgehen können.", + "Nachdem du diese Qualitätssicherungsprojekte abgeschlossen hast, hast du 5 weitere Projekte in der Tasche und eine neue Zertifizierung, die du in deinem Portfolio vorzeigen kannst." + ] + } + } + }, + "scientific-computing-with-python": { + "title": "Wissenschaftliches Rechnen mit Python", + "intro": [ + "Python ist heute eine der beliebtesten und flexibelsten Programmiersprachen. Du kannst sie für alles verwenden, vom einfachen Skripting bis zum maschinellen Lernen.", + "In der Zertifizierung \"Wissenschaftliches Rechnen mit Python\" lernst du die Grundlagen von Python, darunter Variablen, Schleifen, Bedingungen und Funktionen. Dann steigst du schnell zu komplexen Datenstrukturen, Netzwerken, relationalen Datenbanken und Datenvisualisierung auf." + ], + "note": "", + "blocks": { + "python-for-everybody": { + "title": "Python für jedermann", + "intro": [ + "Python für jedermann ist eine kostenlose Videokursreihe, die die Grundlagen der Verwendung von Python 3 vermittelt.", + "Die Kurse wurden von Dr. Charles Severance (auch bekannt als Dr. Chuck) erstellt. Er ist ein klinischer Professor an der University of Michigan School of Information, wo er verschiedene technologieorientierte Kurse unterrichtet, darunter Programmierung, Datenbankdesign und Webentwicklung." + ] + }, + "scientific-computing-with-python-projects": { + "title": "Projekte Wissenschaftliches Rechnen mit Python", + "intro": [ + "Zeit, deine Python-Kenntnisse auf die Probe zu stellen. Indem du diese Projekte abschließt, zeigst du, dass du über gute Grundkenntnisse in Python verfügst und dich für die Zertifizierung \"Wissenschaftliches Rechnen mit Python\" qualifiziert hast." + ] + } + } + }, + "data-analysis-with-python": { + "title": "Datenanalyse mit Python", + "intro": [ + "Datenanalyse gibt es schon seit Langem. Aber bis vor ein paar Jahren haben Entwickler sie mit teuren, proprietären Tools wie Tableau praktiziert. Doch in letzter Zeit haben Python, SQL und andere offene Bibliotheken die Datenanalyse für immer verändert.", + "In der Zertifizierung \"Datenanalyse mit Python\" lernst du die Grundlagen der Datenanalyse mit Python. Am Ende dieser Zertifizierung wirst du wissen, wie man Daten aus Quellen wie CSV und SQL einliest und wie man Bibliotheken wie Numpy, Pandas, Matplotlib und Seaborn verwendet, um Daten zu verarbeiten und zu visualisieren." + ], + "note": "", + "blocks": { + "data-analysis-with-python-course": { + "title": "Datenanalyse mit Python", + "intro": [ + "In diesen umfassenden Videokursen, erstellt von Santiago Basulto, lernst du den gesamten Prozess der Datenanalyse. Du liest Daten aus verschiedenen Quellen (CSV, SQL, Excel), verarbeitest diese Daten mit NumPy und Pandas und visualisierst sie mit Matplotlib und Seaborn,", + "Zusätzlich haben wir einen ausführlichen Jupyter Notebook-Kurs und eine schnelle Python-Referenz zur Auffrischung deiner Programmierkenntnisse integriert." + ] + }, + "numpy": { + "title": "Numpy", + "intro": [ + "Lerne die Grundlagen der NumPy Bibliothek in dem folgenden Videokurs, der von Keith Galli erstellt wurde.", + "In diesem Kurs lernst du, wie NumPy funktioniert und wie es im Vergleich zu Pythons eingebauten Listen funktioniert. Außerdem lernst du, wie man mit NumPy Code schreibt, Indizierung, Reshaping, angewandte Statistik und vieles mehr." + ] + }, + "data-analysis-with-python-projects": { + "title": "Projekte Datenanalyse mit Python", + "intro": [ + "Es gibt viele Möglichkeiten, Daten mit Python zu analysieren. Indem du diese Projekte abschließt, zeigst du, dass du ein gutes Grundwissen über Datenanalyse mit Python hast.", + "Schließe sie alle ab, um deine Zertifizierung \"Datenanalyse mit Python\" zu erhalten." + ] + } + } + }, + "information-security": { + "title": "Informationssicherheit", + "intro": [ + "Bei sämtlichen Online-Aktivitäten ist eine große Menge an sensiblen Daten gefährdet: E-Mail-Adressen, Passwörter, Telefonnummern und vieles mehr.", + "Mit der Zertifizierung für Informationssicherheit baust du eine sichere Web-App mit HelmetJS und lernst die Grundlagen zum Schutz der Daten von Menschen im Internet.", + "Du wirst auch einen TCP-Client und einen Nmap- und Port-Scanner in Python bauen. So lernst du die Grundlagen von Penetrationstests - ein wichtiger Bestandteil guter Informationssicherheit." + ], + "note": "", + "blocks": { + "information-security-with-helmetjs": { + "title": "Informationssicherheit mit HelmetJS", + "intro": [ + "Dieser Programmierkurs konzentriert sich auf HelmetJS, eine Art Middleware für Express-basierte Anwendungen, die automatisch HTTP-Header setzt. Auf diese Weise kann sie verhindern, dass sensible Informationen ungewollt zwischen Server und Client weitergegeben werden.", + "Das Absolvieren der folgenden Kurse wird dir helfen zu verstehen, wie du deine Webseite vor bösartigem Verhalten schützen kannst." + ] + }, + "python-for-penetration-testing": { + "title": "Python für Penetrationstests", + "intro": [ + "Diese Videokurse bringen dir Penetrationstests mit Python bei. Penetrationstests, auch bekannt als Pen-Test, sind simulierte Angriffe auf ein System, um es auf Schwachstellen zu überprüfen.", + "In diesem Kurs lernst du etwas über Sockets, erstellst einen TCP-Server und -Client, baust einen Nmap-Scanner und andere Tools und Techniken, die Pen-Tester täglich verwenden." + ] + }, + "information-security-projects": { + "title": "Projekte Informationssicherheit", + "intro": [ + "Jetzt ist es an der Zeit, deine neuen Fähigkeiten im Bereich der Informationssicherheit in die Tat umzusetzen. Diese Projekte geben dir die Möglichkeit, die erlernten Fähigkeiten, Prinzipien und Konzepte der Informationssicherheit anzuwenden.", + "Wenn du fertig bist, wirst du eine Menge Projekte zur Informationssicherheit in der Tasche haben, zusammen mit einer Zertifizierung, mit der du vor Freunden, Familie und Arbeitgebern angeben kannst." + ] + } + } + }, + "machine-learning-with-python": { + "title": "Maschinelles Lernen mit Python", + "intro": [ + "Maschinelles Lernen hat viele praktische Anwendungen, die du in deinen Projekten oder bei der Arbeit nutzen kannst.", + "In der Zertifizierung \"Maschinelles Lernen mit Python\" verwendest du das TensorFlow-Framework, um verschiedene neuronale Netze zu erstellen und fortgeschrittene Techniken wie natürliche Sprachverarbeitung und Reinforcement Learning (Bestärkendes Lernen) zu erforschen.", + "Du wirst auch in neuronale Netze eintauchen und die Prinzipien hinter der Funktionsweise von tiefen, rekurrenten und konvolutionären neuronalen Netzen lernen." + ], + "note": "", + "blocks": { + "tensorflow": { + "title": "Tensorflow", + "intro": [ + "TensorFlow ist ein Open-Source-Framework, das maschinelles Lernen und neuronale Netzwerke leichter nutzbar macht.", + "Der folgende Videokurs wurde von Tim Ruscica, auch bekannt als \"Tech With Tim\", erstellt. Es wird dir helfen, TensorFlow und einige seiner mächtigen Fähigkeiten zu verstehen." + ] + }, + "how-neural-networks-work": { + "title": "Wie neuronale Netzwerke funktionieren", + "intro": [ + "Neuronale Netzwerke sind der Kern dessen, was wir heute künstliche Intelligenz nennen. Aber in der Vergangenheit waren sie schwer zu verstehen. Vor allem für Anfänger auf dem Gebiet des maschinellen Lernens.", + "Selbst wenn du völlig neu in der Materie der neuronalen Netze bist, werden dich diese Videokurse von Brandon Rohrer mit den Konzepten und der Mathematik dahinter vertraut machen." + ] + }, + "machine-learning-with-python-projects": { + "title": "Projekte Maschinelles Lernen mit Python", + "intro": [ + "Maschinelles Lernen hat viele praktische Anwendungen. Indem du diese kostenlosen und herausfordernden Coding-Projekte absolvierst, zeigst du, dass du ein gutes Grundwissen über maschinelles Lernen hast und qualifizierst dich für deine Zertifizierung \"Machine Learning with Python\"." + ] + } + } + }, + "coding-interview-prep": { + "title": "Vorbereitung auf Bewerbungsgespräche", + "intro": [ + "Wenn du nach kostenlosen Coding-Übungen suchst, um dich auf dein nächstes Vorstellungsgespräch vorzubereiten, haben wir das Richtige für dich.", + "Dieser Bereich enthält hunderte von Coding Challenges, die dein Wissen über Algorithmen, Datenstrukturen und Mathematik testen. Es gibt auch eine Reihe von Projekten, die du mit nach Hause nehmen kannst, um deine Fähigkeiten zu stärken oder dein Portfolio zu erweitern." + ], + "note": "", + "blocks": { + "algorithms": { + "title": "Algorithmen", + "intro": [ + "In diesen kostenlosen Programmierübungen lernst du einige gängige Algorithmen kennen, die dir wahrscheinlich im echten Leben begegnen werden. Sie sind eine großartige Möglichkeit, deine Logik- und Programmierfähigkeiten zu verbessern.", + "Diese Algorithmen werden häufig in Vorstellungsgesprächen verwendet, um die Fähigkeiten eines Bewerbers zu testen. Wir geben dir klare und prägnante Erklärungen, wie diese verschiedenen Algorithmen funktionieren, damit du eine Lösung für jeden einzelnen implementieren kannst." + ] + }, + "data-structures": { + "title": "Datenstrukturen", + "intro": [ + "Diese kostenlosen Programmierkurse sollen dir helfen, mit großen und komplexen Datenstrukturen umzugehen, mit denen du vielleicht noch nicht vertraut bist.", + "In den folgenden Kursen lernst du jede Art von Datenstruktur kennen und implementierst Algorithmen, um dein Verständnis für sie zu vertiefen." + ] + }, + "take-home-projects": { + "title": "Projekte für das Selbststudium", + "intro": [ + "Vorstellungsgespräche waren schon immer stressig. Manchmal wird den Bewerbern ein Projekt mit auf den Weg gegeben, das sie außerhalb des Vorstellungsgesprächs fertigstellen müssen. Diese Art von Vorstellungsgesprächen erfordert in der Regel eine Menge Arbeit, aber sie sind eine großartige Möglichkeit für Arbeitgeber, um zu sehen, wie du dich im Job schlagen könntest.", + "Entwickle die untenstehenden Bonus-Coding-Projekte für zusätzliche Praxis. Nimm dir Zeit, mach sie großartig und füge sie in deinem Lebenslauf oder Portfolio hinzu, um sie potenziellen Arbeitgebern zu zeigen." + ] + }, + "rosetta-code": { + "title": "Rosetta Code", + "intro": [ + "Verbessere deine kreativen Problemlösungsfähigkeiten mit diesen kostenlosen Programmieraufgaben aus der klassischen Rosetta Code Bibliothek.", + "Diese Herausforderungen können sich als schwierig erweisen, aber sie werden deine Algorithmuslogik zu neuen Höhen treiben.", + "Attribut: Rosetta Code" + ] + }, + "project-euler": { + "title": "Projekt Euler", + "intro": [ + "Vervollständige die untenstehenden Programmierherausforderungen aus den umfangreichen Archiven von Projekt Euler. Diese werden dein Algorithmus- und Mathematikwissen festigen.", + "Diese Probleme haben einen unterschiedlichen Schwierigkeitsgrad und für viele ist die Erfahrung ein induktives Kettenlernen. Das bedeutet, dass du durch das Lösen eines Problems ein neues Konzept kennenlernst, das es dir ermöglicht, ein zuvor unzugängliches Problem in Angriff zu nehmen. Kannst du sie alle lösen?" + ] + } + } + }, + "misc-text": { + "certification": "{{cert}} Zertifikat", + "browse-other": "Stöbere in unseren anderen kostenlosen Zertifizierungen\n(Wir empfehlen, diese der Reihe nach zu erledigen)", + "courses": "Kurse", + "steps": "Schritte", + "expand": "Kurs erweitern", + "collapse": "Kurs einklappen", + "legacy-header": "Alte Kurse", + "legacy-desc": "Diese Kurse sind nicht mehr Teil des Zertifizierungsprogramms, stehen dir aber weiterhin zur Verfügung, um dich weiterzubilden.", + "legacy-go-back": "Rufe die aktuelle Version des Lehrplans auf.", + "new-rwd-desc": "Wir haben unseren Responsives Webdesign Studienplan aktualisiert. Wenn du bereits mit dem RWD-Studienplan gearbeitet hast, ist dein Fortschritt noch gespeichert! Du findest ihn unter dem Abschnitt Altes Responsives Webdesign.", + "new-rwd-article": "Wir möchten dich dazu ermutigen, dich über die vorgenommenen Änderungen zu informieren und dich mit dem aktualisierten Studienplan auseinanderzusetzen.", + "viewing-upcoming-change": "Du siehst eine Beta-Seite. ", + "go-back-to-learn": "Gehe zurück zur stabilen Version des Lehrplans.", + "read-database-cert-article": "Bitte lies diesen Forenbeitrag, bevor du fortfährst.", + "enable-cookies": "Bevor du startest, muss du die Cookies von Drittanbietern aktivieren.", + "english-only": "Die Kurse in diesem Bereich sind nur auf Englisch verfügbar. Im Moment können wir nur die Titel und Einführungen übersetzen, nicht aber die Lektionen selbst." + } +} diff --git a/client/i18n/locales/german/links.json b/client/i18n/locales/german/links.json new file mode 100644 index 00000000000000..4ee8c7c50eb704 --- /dev/null +++ b/client/i18n/locales/german/links.json @@ -0,0 +1,31 @@ +{ + "help-translate-link-url": "https://contribute.freecodecamp.org/#/i18n/german/how-to-translate-files", + "top-contributors": "https://www.freecodecamp.org/news/freecodecamp-top-contributors/", + "footer": { + "about-url": "https://www.freecodecamp.org/news/about/", + "shop-url": "https://www.freecodecamp.org/shop/", + "support-url": "https://www.freecodecamp.org/news/support/", + "sponsors-url": "https://www.freecodecamp.org/news/sponsors/", + "honesty-url": "https://www.freecodecamp.org/news/academic-honesty-policy/", + "coc-url": "https://www.freecodecamp.org/news/code-of-conduct/", + "privacy-url": "https://www.freecodecamp.org/news/privacy-policy/", + "tos-url": "https://www.freecodecamp.org/news/terms-of-service/", + "copyright-url": "https://www.freecodecamp.org/news/copyright-policy/" + }, + "donate": { + "other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp", + "download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf", + "download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf", + "one-time-url": "https://paypal.me/freecodecamp" + }, + "nav": { + "forum": "https://forum.freecodecamp.org/", + "news": "https://freecodecamp.org/news/" + }, + "help": { + "HTML-CSS": "HTML-CSS", + "JavaScript": "JavaScript", + "Python": "Python", + "Backend Development": "Backend Development" + } +} diff --git a/client/i18n/locales/german/meta-tags.json b/client/i18n/locales/german/meta-tags.json new file mode 100644 index 00000000000000..1e27c4e817a876 --- /dev/null +++ b/client/i18n/locales/german/meta-tags.json @@ -0,0 +1,32 @@ +{ + "title": "Lerne Programmieren - kostenlos - Programmierkurse für vielbeschäftigte Menschen", + "description": "Lerne Programmieren - kostenlos", + "social-description": "Lerne Programmieren - kostenlos", + "keywords": [ + "python", + "javascript", + "js", + "git", + "github", + "website", + "web", + "entwicklung", + "free", + "code", + "camp", + "kurs", + "kurse", + "html", + "css", + "react", + "redux", + "api", + "front", + "back", + "end", + "lernen", + "tutorial", + "programmierung" + ], + "youre-unsubscribed": "Du wurdest abgemeldet" +} diff --git a/client/i18n/locales/german/motivation.json b/client/i18n/locales/german/motivation.json new file mode 100644 index 00000000000000..a95175b2ddbe54 --- /dev/null +++ b/client/i18n/locales/german/motivation.json @@ -0,0 +1,203 @@ +{ + "compliments": [ + "Ziel erreicht!", + "Du hast Mumm!", + "Bis in die Unendlichkeit und noch weiter!", + "Zugabe!", + "Vorwärts!", + "Es geht ab wie bei Donkey Kong!", + "Code lang und in Frieden.", + "Die Menge tobt!", + "Das ist etwas für das Guinness-Buch!", + "Makelloser Sieg!", + "Sehr effizient!", + "Du hast das richtige Händchen dafür!", + "Zum Batmobil!", + "Zieh alle Register!", + "Du bist ein Zauberer, Harry!", + "Gut gemacht!", + "Du bist der Hammer!", + "Was ist das für eine Zauberei?", + "So wird's gemacht!", + "Du rockst!", + "Woo-hoo!", + "Wir wussten, dass du es schaffst!", + "Boom-shakalaka!", + "Du bist unbesiegbar!", + "Escape velocity reached!", + "Bei dir sieht das ganz einfach aus!", + "Mit Bravour bestanden!", + "Du hast es drauf!", + "Morgen, die ganze Welt!", + "Es lebt. Es lebt!", + "Ich schaue dir in die Augen, Code!", + "Ein Schleife, um sie alle zu knechten!", + "Stürmt die Burg!", + "Gesichtsschmelzendes Gitarrensolo!", + "Bleib ruhig und programmiere weiter!", + "Bullseye!", + "Hasta la vista, Herausforderung!", + "Bingo!", + "Steuermann, Warp Neun. Aktivieren!", + "Pikachu wählt dich!", + + ], + "motivationalQuotes": [ + { + "quote": "Was auch immer du bist, sei ein guter Mensch.", + "author": "Abraham Lincoln" + }, + { + "quote": "Der beste Weg, die Zukunft vorherzusagen, ist, sie zu erfinden.", + "author": "Alan Kay" + }, + { + "quote": "Ein Mensch, der nie einen Fehler gemacht hat, hat nie etwas Neues ausprobiert.", + "author": "Albert Einstein" + }, + { + "quote": "Kreativität ist Intelligenz, die Spaß macht.", + "author": "Albert Einstein" + }, + { + "quote": "Ich habe keine besonderen Talente. Ich bin nur leidenschaftlich neugierig.", + "author": "Albert Einstein" + }, + { + "quote": "Das Leben ist wie Fahrradfahren. Um dein Gleichgewicht zu halten, musst du in Bewegung bleiben.", + "author": "Albert Einstein" + }, + { + "quote": "Mache alles so einfach wie möglich, aber nicht noch einfacher.", + "author": "Albert Einstein" + }, + { + "quote": "Lerne nie etwas auswendig, das du nachschlagen kannst.", + "author": "Albert Einstein" + }, + { + "quote": "Sobald wir unsere Grenzen akzeptieren, gehen wir über sie hinaus.", + "author": "Albert Einstein" + }, + { + "quote": "Spielen ist die höchste Form der Forschung.", + "author": "Albert Einstein" + }, + { + "quote": "Wir können unsere Probleme nicht mit derselben Denkweise lösen, mit der wir sie geschaffen haben.", + "author": "Albert Einstein" + }, + { + "quote": "Weisheit ist kein Produkt der Schulbildung, sondern des lebenslangen Versuchs, sie zu erwerben.", + "author": "Albert Einstein" + }, + { + "quote": "Das Schwierigste ist die Entscheidung zu handeln. Der Rest ist reine Beharrlichkeit.", + "author": "Amelia Earhart" + }, + { + "quote": "Wochenlange Programmierung kann dir Stunden der Planung ersparen.", + "author": "Unbekannt" + }, + { + "quote": "Qualität ist kein Akt, sie ist eine Gewohnheit.", + "author": "Aristoteles" + }, + { + "quote": "Sag es mir und ich vergesse es. Unterrichte mich und ich erinnere mich. Beteilige mich und ich lerne.", + "author": "Benjamin Franklin" + }, + { + "quote": "Gut gemacht ist besser als gut gesagt.", + "author": "Benjamin Franklin" + }, + { + "quote": "Ich fürchte nicht den Mann, der einmal 10.000 Tritte geübt hat, aber ich fürchte den Mann, der einen Tritt 10.000 Mal geübt hat.", + "author": "Bruce Lee" + }, + { + "quote": "Wenn du keine Fehler machst, triffst du auch keine Entscheidungen.", + "author": "Catherine Cook" + }, + { + "quote": "Es ist nicht die stärkste Art, die überlebt, auch nicht die intelligenteste, sondern diejenige, die am schnellsten auf Veränderungen reagiert.", + "author": "Charles Darwin" + }, + { + "quote": "Das Leben besteht zu 10 % aus dem, was dir passiert, und zu 90 % daraus, wie du darauf reagierst.", + "author": "Charles R. Swindoll" + }, + { + "quote": "Es ist egal, wie langsam du gehst, solange du nicht anhältst.", + "author": "Konfuzius" + }, + { + "quote": "Wahres Wissen bedeutet, das Ausmaß der eigenen Unwissenheit zu kennen.", + "author": "Konfuzius" + }, + { + "quote": "Die Vergangenheit kann nicht geändert werden. Die Zukunft liegt noch in deiner Macht.", + "author": "Konfuzius" + }, + { + "quote": "Wir sehen nur, was wir wissen.", + "author": "Johann Wolfgang von Goethe" + }, + { + "quote": "Es ist nicht genug zu wissen; wir müssen es anwenden. Wünschen ist nicht genug; wir müssen tun.", + "author": "Johann Wolfgang von Goethe" + }, + { + "quote": "Tu die schwierigen Dinge, solange sie leicht sind, und tu die großen Dinge, solange sie klein sind. Eine Reise von tausend Meilen muss mit einem einzigen Schritt beginnen.", + "author": "Lao Tzu" + }, + { + "quote": "Mir war schon lange aufgefallen, dass erfolgreiche Menschen sich selten zurücklehnen und die Dinge auf sich zukommen lassen. Sie gingen hinaus und taten etwas.", + "author": "Leonardo da Vinci" + }, + { + "quote": "Lebe so, als würdest du morgen sterben. Lerne, als ob du ewig leben würdest.", + "author": "Mahatma Gandhi" + }, + { + "quote": "Stärke kommt nicht von körperlichen Fähigkeiten. Sie kommt von einem unbezwingbaren Willen.", + "author": "Mahatma Gandhi" + }, + { + "quote": "Nichts im Leben muss man fürchten, man muss es nur verstehen. Jetzt ist es an der Zeit, mehr zu verstehen, damit wir uns weniger fürchten müssen.", + "author": "Marie Curie" + }, + { + "quote": "Das Geheimnis des Weiterkommens liegt darin, anzufangen.", + "author": "Mark Twain" + }, + { + "quote": "Ein Gewinner ist ein Träumer, der niemals aufgibt.", + "author": "Nelson Mandela" + }, + { + "quote": "Es scheint immer unmöglich, bis es geschafft ist.", + "author": "Nelson Mandela" + }, + { + "quote": "Je mehr du weißt, desto mehr erkennst du, dass du nichts weißt.", + "author": "Sokrates" + }, + { + "quote": "Der größte Feind des Wissens ist nicht die Unwissenheit, sondern die Illusion des Wissens.", + "author": "Stephen Hawking" + }, + { + "quote": "Das Universum erlaubt keine Perfektion.", + "author": "Stephen Hawking" + }, + { + "quote": "Egal, ob du die Geheimnisse des Universums lüften willst oder eine Karriere im 21. Jahrhundert anstrebst, grundlegende Computerprogrammierung ist eine wichtige Fähigkeit, die du lernen solltest.", + "author": "Stephen Hawking" + }, + { + "quote": "Ich habe nicht versagt. Ich habe nur 10.000 Wege gefunden, die nicht funktionierten.", + "author": "Thomas A. Edison" + }, + ] +} diff --git a/client/i18n/locales/german/translations.json b/client/i18n/locales/german/translations.json new file mode 100644 index 00000000000000..86efd66099519f --- /dev/null +++ b/client/i18n/locales/german/translations.json @@ -0,0 +1,710 @@ +{ + "buttons": { + "logged-in-cta-btn": "Los geht's! (Es ist 100% kostenlos.)", + "logged-out-cta-btn": "Melde dich an, um deinen Fortschritt zu speichern. (Es ist kostenlos.)", + "view-curriculum": "Curriculum anzeigen", + "first-lesson": "Gehe zur ersten Lektion", + "close": "Schließen", + "edit": "Bearbeiten", + "show-code": "Code anzeigen", + "show-solution": "Lösung anzeigen", + "show-project": "Projekt zeigen", + "frontend": "Front-End", + "backend": "Back-End", + "view": "Anzeigen", + "show-cert": "Zertifikat anzeigen", + "claim-cert": "Zertifizierung anfordern", + "save-progress": "Fortschritt speichern", + "accepted-honesty": "Du hast unsere Akademische Ehrlichkeitsrichtlinie akzeptiert.", + "agree": "Zustimmen", + "save-portfolio": "Dieses Portfolioelement speichern", + "remove-portfolio": "Dieses Portfolioelement entfernen", + "add-portfolio": "Neues Portfolioelement hinzufügen", + "download-data": "Deine Daten herunterladen", + "public": "Öffentlich", + "private": "Privat", + "off": "Aus", + "on": "An", + "sign-in": "Anmeldung", + "sign-up-email-list": "Melde dich für Quincys wöchentliche E-Mails an", + "sign-out": "Abmelden", + "curriculum": "Curriculum", + "forum": "Forum", + "radio": "Radio", + "profile": "Profil", + "news": "News", + "donate": "Spenden", + "update-settings": "Meine Kontoeinstellungen ändern", + "sign-me-out": "Von freeCodeCamp abmelden", + "flag-user": "Dieses Benutzerkonto wegen Missbrauch melden", + "current-challenge": "Zur aktuellen Herausforderung wechseln", + "try-again": "Nochmal versuchen", + "menu": "Menü", + "settings": "Einstellungen", + "take-me": "Bring mich zu den Herausforderungen", + "check-answer": "Überprüfe deine Antwort", + "get-hint": "Erhalte einen Tipp", + "ask-for-help": "Bitte um Hilfe", + "create-post": "Einen Hilfebeitrag im Forum erstellen", + "cancel": "Abbrechen", + "reset-lesson": "Diese Lektion zurücksetzen", + "run": "Ausführen", + "run-test": "Führe die Tests aus (Strg + Enter)", + "check-code": "Überprüfe deinen Code (Strg + Enter)", + "check-code-2": "Prüfe deinen Code", + "reset": "Zurücksetzen", + "reset-code": "Den Quellcode zurücksetzen", + "help": "Hilfe", + "get-help": "Hilfe bekommen", + "watch-video": "Ein Video ansehen", + "resubscribe": "Du kannst hier klicken, um erneut zu abonnieren", + "click-here": "Klicke hier, um dich anzumelden", + "save": "Speichern", + "save-code": "Speichere deinen Code", + "no-thanks": "Nein, danke", + "yes-please": "Ja, bitte", + "update-email": "Meine E-Mail-Adresse aktualisieren", + "verify-email": "E-Mail-Adresse bestätigen", + "submit-and-go": "Absenden und zur nächsten Herausforderung gehen", + "go-to-next": "Gehe zur nächsten Herausforderung", + "ask-later": "Frag später", + "start-coding": "Beginne zu programmieren!", + "go-to-settings": "Gehe zu den Einstellungen, um dein Zertifikat zu beantragen", + "click-start-course": "Start den Kurs", + "click-start-project": "Starte das Projekt", + "change-language": "Sprache wechseln", + "cancel-change": "Änderung abbrechen", + "resume-project": "Projekt fortsetzen", + "start-project": "Projekt starten" + }, + "landing": { + "big-heading-1": "Lerne zu programmieren — kostenlos.", + "big-heading-2": "Projekte entwickeln.", + "big-heading-3": "Zertifizierungen erwerben.", + "h2-heading": "Seit 2014 haben mehr als 40.000 Absolventen von FreeCodeCamp.org Jobs bei Tech-Unternehmen erhalten, unter anderem:", + "hero-img-description": "freeCodeCamp Studenten einer lokalen Lerngruppe in Südkorea.", + "as-seen-in": "Wie gesehen in:", + "testimonials": { + "heading": "Das sagen unsere Absolventen zu freeCodeCamp:", + "shawn": { + "location": "Shawn Wang in Singapur", + "occupation": "Softwareentwickler bei Amazon", + "testimony": "\"Es ist beängstigend, den Beruf zu wechseln. Ich habe erst durch die hunderte Stunden an kostenlosen Lektionen auf freeCodeCamp das Vertrauen gewonnen, dass ich coden kann. Innerhalb eines Jahres hatte ich einen Job mit sechsstelligen Gehalt als Software Entwickler. freeCodeCamp hat mein Leben verändert.\"" + }, + "sarah": { + "location": "Sarah Chima in Nigeria", + "occupation": "Softwareentwicklerin bei ChatDesk", + "testimony": "\"freeCodeCamp war das Tor zu meiner Karriere als Softwareentwickler. Der gut strukturierte Lehrplan brachte meine Programmierkenntnisse von einem totalen Anfängerlevel auf ein sehr sicheres Niveau. Es war alles, was ich brauchte, um meinen ersten Entwicklerjob bei einer großartigen Firma zu bekommen.\"" + }, + "emma": { + "location": "Emma Bostian in Schweden", + "occupation": "Softwareentwicklerin bei Spotify", + "testimony": "\"Ich habe immer damit gekämpft, JavaScript zu lernen. Ich habe viele Kurse belegt, aber der Kurs von freeCodeCamp war derjenige, der am meisten hängen blieb. Das Lernen von JavaScript sowie Datenstrukturen und Algorithmen auf freeCodeCamp gab mir die Fähigkeiten und das Selbstvertrauen, das ich brauchte, um meinen Traumjob als Softwareentwicklerin bei Spotify zu bekommen.\"" + } + }, + "certification-heading": "Erlange kostenlos verifizierte Zertifizierungen in:" + }, + "settings": { + "share-projects": "Teile deine nicht-freeCodeCamp-Projekte, Artikel oder akzeptierte Pull-Requests.", + "privacy": "Die Einstellungen in diesem Abschnitt ermöglichen es dir, zu kontrollieren, was in deinem öffentlichen freeCodeCamp-Portfolio angezeigt wird. Drücke auf Speichern, um deine Änderungen zu speichern.", + "data": "Um zu sehen, welche Daten wir in deinem Konto vorhalten, klicke auf den \"Deine Daten herunterladen\" Button unten", + "disabled": "Deine Zertifizierungen werden deaktiviert, wenn sie auf privat gesetzt sind.", + "private-name": "Dein Name erscheint nicht auf Deinen Zertifizierungen, wenn dieser auf privat eingestellt ist.", + "claim-legacy": "Sobald du die folgenden freeCodeCamp Zertifizierungen erworben hast, kannst du das {{cert}} beanspruchen:", + "for": "Kontoeinstellungen für {{username}}", + "sound-mode": "Das sorgt für den angenehmen Klang der Akustikgitarre auf der gesamten Website. Du bekommst musikalisches Feedback, wenn du im Editor tippst, Aufgaben löst, Zertifizierungen beantragst und vieles mehr.", + "username": { + "contains invalid characters": "Der Benutzername \"{{username}}\" enthält ungültige Zeichen", + "is too short": "Der Benutzername \"{{username}}\" ist zu kurz", + "is a reserved error code": "Der Benutzername \"{{username}}\" ist ein reservierter Fehlercode", + "must be lowercase": "Benutzername \"{{username}}\" muss in Kleinbuchstaben geschrieben sein", + "unavailable": "Benutzername ist nicht verfügbar", + "validating": "Benutzername wird überprüft...", + "available": "Benutzername ist verfügbar", + "change": "Bitte beachte, dass die Änderung deines Benutzernamens auch die URL deines Profils und deiner Zertifikate ändern wird." + }, + "labels": { + "username": "Benutzername", + "name": "Name", + "location": "Standort", + "picture": "Bild", + "about": "Über", + "personal": "Persönliche Website", + "title": "Titel", + "url": "URL", + "image": "Bild", + "description": "Beschreibung", + "project-name": "Name des Projekts", + "solution": "Lösung", + "solution-for": "Lösung für {{projectTitle}}", + "my-profile": "Mein Profil", + "my-name": "Mein Name", + "my-location": "Mein Standort", + "my-about": "Mein \"Über mich\"-Bereich", + "my-points": "Meine Punkte", + "my-heatmap": "Meine Heatmap (Punkte-Historie)", + "my-certs": "Meine Zertifikate", + "my-portfolio": "Mein Portfolio", + "my-timeline": "Meine Zeitleiste", + "my-donations": "Meine Spenden", + "night-mode": "Nacht-Modus", + "sound-mode": "Lagerfeuer-Modus", + "keyboard-shortcuts": "Tastaturkurzbefehle aktivieren" + }, + "headings": { + "certs": "Zertifikate", + "legacy-certs": "Alte Zertifikate", + "honesty": "Akademischer Ehrlichkeitskodex", + "internet": "Dein Internetauftritt", + "portfolio": "Portfolio-Einstellungen", + "privacy": "Privatsphäre-Einstellungen" + }, + "danger": { + "heading": "Gefahrenzone", + "be-careful": "Bitte sei vorsichtig. Änderungen in diesem Bereich sind dauerhaft.", + "reset": "Den ganzen Fortschritt zurücksetzen", + "delete": "Mein Konto löschen", + "delete-title": "Mein Konto löschen", + "delete-p1": "Dadurch werden wirklich alle deine Daten gelöscht, einschließlich aller deiner Fortschritte und Kontoinformationen.", + "delete-p2": "Wir werden später keine dieser Daten für dich wiederherstellen können. Auch dann nicht, wenn du deine Meinung änderst.", + "delete-p3": "Wenn es etwas gibt, was wir besser machen könnten, schick uns stattdessen eine E-Mail und wir werden unser Bestes tun: <0>{{email}}", + "nevermind": "Ich habe es mir anders überlegt und will mein Konto nicht löschen", + "certain": "Ich bin 100%ig sicher. Lösche alles, was mit diesem Konto verbunden ist", + "reset-heading": "Meinen Fortschritt zurücksetzen", + "reset-p1": "Dies wird wirklich alle deine Fortschritte, Punkte, abgeschlossenen Herausforderungen, unsere Aufzeichnungen über deine Projekte, alle Zertifizierungen, die du hast, einfach alles löschen.", + "reset-p2": "Wir werden später keine dieser Daten für dich wiederherstellen können. Auch dann nicht, wenn du deine Meinung änderst.", + "nevermind-2": "Ich habe es mir anders überlegt und will meinen Fortschritt nicht löschen", + "reset-confirm": "Alles zurücksetzen. Ich möchte von Anfang an beginnen" + }, + "email": { + "missing": "Du hast keine E-Mail mit diesem Konto verbunden.", + "heading": "E-Mail-Einstellungen", + "not-verified": "Deine E-Mail wurde noch nicht verifiziert.", + "check": "Bitte überprüfe deine E-Mail, oder <0>fordere eine neue Bestätigungs-E-Mail an.", + "current": "Aktuelle E-Mail", + "new": "Neue E-Mail", + "confirm": "Neue E-Mail bestätigen", + "weekly": "Sende mir die wöchentliche E-Mail von Quincy (Gründer)" + }, + "honesty": { + "p1": "Bevor du ein bestätigtes Zertifikat beanspruchen kannst, musst du unsere akademische Ehrlichkeitserklärung akzeptieren. Sie lautet:", + "p2": "\"Ich verstehe, dass Plagiarismus bedeutet, das Werk eines anderen zu kopieren und das Werk so zu präsentieren, als wäre es mein eigenes, ohne den Originalautor eindeutig anzugeben.\"", + "p3": "\"Ich verstehe, dass Plagiarismus ein Akt der intellektuellen Unehrlichkeit ist und dass Leute normalerweise von der Universität ausgeschlossen oder aus ihrem Job entlassen werden, wenn sie beim Plagiieren erwischt werden.\"", + "p4": "\"Abgesehen von der Verwendung von Open-Source-Bibliotheken wie jQuery und Bootstrap und kurzen Codeschnipseln, die eindeutig ihrem ursprünglichen Autor zugeschrieben werden, wurde 100% des Codes in meinen Projekten von mir oder zusammen mit einer anderen Person geschrieben, die den freeCodeCamp-Lehrplan durchlief und mit der ich in Echtzeit Pair Programming betrieb.\"", + "p5": "\"Ich versichere, dass ich keine meiner Arbeiten auf freeCodeCamp.org plagiiert habe. Ich verstehe, dass das Team von freeCodeCamp.org meine Projekte prüfen wird, um dies zu bestätigen.\"", + "p6": "In den Fällen, in denen wir eindeutige Plagiate entdecken, ersetzen wir die Bescheinigung der betreffenden Person mit der Meldung \"Nach Überprüfung wurde dieses Konto wegen akademischer Unehrlichkeit markiert.\"", + "p7": "Als akademische Institution, die leistungsbasierte Zertifizierungen vergibt, nehmen wir akademische Ehrlichkeit sehr ernst. Wenn du Fragen zu dieser Richtlinie hast oder vermutest, dass jemand dagegen verstoßen hat, kannst du eine E-Mail an <0>{{email}} schicken und wir werden das untersuchen." + } + }, + "profile": { + "you-not-public": "Du hast dein Portfolio nicht öffentlich zugänglich gemacht.", + "username-not-public": "{{username}} hat sein Portfolio nicht öffentlich zugänglich gemacht.", + "you-change-privacy": "Du musst deine Privatsphäre-Einstellung ändern, damit dein Portfolio von anderen gesehen wird. Dies ist eine Vorschau wie dein Portfolio aussehen wird, wenn es veröffentlicht wird.", + "username-change-privacy": "{{username}} muss seine Privatsphäre-Einstellung ändern, damit du sein Portfolio ansehen kannst.", + "supporter": "Unterstützer", + "contributor": "Top Mitwirkender", + "no-certs": "Es wurden keine Zertifizierungen nach dem aktuellen Lehrplan erworben", + "fcc-certs": "freeCodeCamp Zertifikate", + "longest-streak": "Längste Serie:", + "current-streak": "Aktuelle Serie:", + "portfolio": "Portfolio", + "timeline": "Zeitleiste", + "none-completed": "Es wurden noch keine Herausforderungen abgeschlossen.", + "get-started": "Hier geht es los.", + "challenge": "Herausforderung", + "completed": "Abgeschlossen", + "add-linkedin": "Dieses Zertifikat meinem LinkedIn-Profil hinzufügen", + "add-twitter": "Zertifikat auf Twitter teilen", + "tweet": "Ich habe mir gerade die {{certTitle}} -Zertifizierung @freeCodeCamp verdient! Hier kannst du es anschauen: {{certURL}}", + "avatar": "Avatar von {{username}}", + "joined": "{{date}} beigetreten", + "total-points": "{{count}} Gesamtpunkt", + "total-points_plural": "{{count}} Gesamtpunkte", + "points": "{{count}} Punkt am {{date}}", + "points_plural": "{{count}} Punkte am {{date}}", + "screen-shot": "Eine Bildschirmaufnahme von {{title}}", + "page-number": "{{pageNumber}} von {{totalPages}}" + }, + "footer": { + "tax-exempt-status": "freeCodeCamp ist eine von Spendern unterstützte steuerbefreite gemeinnützige Organisation gemäß 501(c)(3) (US-Steueridentifikationsnummer: 82-0779546)", + "mission-statement": "Unsere Mission: Menschen dabei zu helfen, kostenlos zu programmieren. Dies erreichen wir, indem wir Tausende von Videos, Artikeln und interaktiven Programmierstunden erstellen, die der Öffentlichkeit frei zugänglich sind. Wir haben auch Tausende von freeCodeCamp-Lerngruppen auf der ganzen Welt.", + "donation-initiatives": "Spenden an das freeCodeCamp fließen in unsere Bildungsinitiativen und helfen, Server, Dienstleistungen und Mitarbeiter zu bezahlen.", + "donate-text": "Du kannst <1>hier eine steuerlich absetzbare Spende tätigen.", + "trending-guides": "Beliebte Guides", + "our-nonprofit": "Unser Non-Profit", + "links": { + "about": "Über", + "alumni": "Alumni-Netzwerk", + "open-source": "Open Source", + "shop": "Shop", + "support": "Support", + "sponsors": "Sponsoren", + "honesty": "Akademische Ehrlichkeit", + "coc": "Verhaltenskodex", + "privacy": "Datenschutzerklärung", + "tos": "Nutzungsbedingungen", + "copyright": "Urheberrechtsrichtlinie" + }, + "language": "Sprache:" + }, + "learn": { + "heading": "Willkommen zum Studienplan von freeCodeCamp.", + "welcome-1": "Willkommen zurück, {{name}}.", + "welcome-2": "Willkommen auf freeCodeCamp.org", + "start-at-beginning": "Wenn Programmieren ganz neu für dich ist, schlagen wir vor, <0>am Anfang zu beginnen.", + "read-this": { + "heading": "Bitte lies dies sorgfältig durch.", + "p1": "freeCodeCamp ist ein bewährter Weg zu deinem ersten Softwareentwickler-Job.", + "p2": "Mehr als 40.000 Menschen erhielten nach Absolvierung unserer Lehrangebote Arbeit als Entwickler – auch bei großen Unternehmen wie Google und Microsoft.", + "p3": "Wenn du neu in der Programmierung bist, empfehlen wir dir, am Anfang zu beginnen und diese Zertifizierungen der Reihe nach zu erwerben.", + "p4": "Für jede Zertifizierung sind je 5 Projekte zu erstellen, die eine Reihe automatisierter Tests bestehen müssen.", + "p5": "Du kannst diese Zertifizierungen zu deinem Lebenslauf oder LinkedIn hinzufügen. Aber noch wichtiger als die Zertifizierungen ist die Praxis, die du auf deinem Weg bekommst.", + "p6": "Es ist normal, sich zwischendurch überwältigt zu fühlen. Programmieren ist schwierig.", + "p7": "Übung ist der Schlüssel. Üben, üben, üben.", + "p8": "Und dieser Lehrplan wird dir tausende von Stunden praktischer Programmierpraxis geben.", + "p9": "Und wenn du mehr Mathematik und Informatik-Theorie lernen möchtest, haben wir auch Tausende von Stunden an Videokursen auf <0>freeCodeCamps YouTube-Kanal.", + "p10": "Wenn du einen Entwicklerjob oder Freelance-Kunden bekommen möchtest, werden Programmierkenntnisse nur Teil des Puzzles sein. Du musst auch dein persönliches Netzwerk und deinen Ruf als Entwickler aufbauen.", + "p11": "Du kannst dies auf Twitter und GitHub tun, sowie im <0>freeCodeCamp-Forum.", + "p12": "Viel Spaß beim Programmieren!" + }, + "upcoming-lessons": "Bevorstehende Lektionen", + "learn": "Lernen", + "add-subtitles": "Hilf mit Untertitel hinzuzufügen oder zu verbessern", + "wrong-answer": "Sorry, das ist nicht die richtige Antwort. Möchtest du noch einen Anlauf wagen?", + "check-answer": "Klick unten auf den Button, um deine Antwort zu überprüfen.", + "solution-link": "Lösungs-Link", + "github-link": "GitHub Link", + "submit-and-go": "Absenden und zur nächsten Herausforderung gehen", + "congratulations": "Glückwunsch, dein Code hat bestanden. Sende deinen Code ein, um fortzufahren.", + "i-completed": "Ich habe diese Herausforderung abgeschlossen", + "test-output": "Deine Testergebnisse werden hier erscheinen", + "running-tests": "// Tests werden durchgeführt", + "tests-completed": "// Tests abgeschlossen", + "console-output": "// Konsolen-Ausgabe", + "sign-in-save": "Melde dich an, um deinen Fortschritt zu speichern", + "download-solution": "Meine Lösung herunterladen", + "percent-complete": "{{percent}}% abgeschlossen", + "tried-rsa": "Wenn du die <0>Lesen-Suchen-Fragen Methode bereits ausprobiert hast, kannst du im freeCodeCamp-Forum um Hilfe bitten.", + "rsa": "Lesen, suchen, fragen", + "rsa-forum": "Before making a new post please see if your question has <0>already been answered on the forum.", + "reset": "Diese Lektion zurücksetzen?", + "reset-warn": "Bist du dir sicher, dass du diese Lektion zurücksetzen möchtest? Die Editoren und Tests werden zurückgesetzt.", + "reset-warn-2": "Dies kann nicht rückgängig gemacht werden", + "scrimba-tip": "Tipp: Wenn der Mini-Browser den Code verdeckt, kann man ihn mittels Drag-and-drop bewegen. Du kannst jederzeit stoppen und den Code im Video bearbeiten.", + "chal-preview": "Herausforderungs-Vorschau", + "cert-map-estimates": { + "certs": "{{title}} Zertifizierung" + }, + "editor-tabs": { + "info": "Informationen", + "code": "Code", + "tests": "Tests", + "restart": "Neustart", + "restart-step": "Schritt zurücksetzen", + "console": "Konsole", + "instructions": "Anweisungen", + "notes": "Hinweise", + "preview": "Vorschau" + }, + "help-translate": "Wir übersetzen noch die folgenden Zertifikate.", + "help-translate-link": "Hilf uns, zu übersetzen.", + "project-preview-title": "Hier ist eine Vorschau auf das, was du erstellen wirst", + "github-required": "<0>Erstelle ein GitHub-Konto, wenn du noch keines hast. Du benötigst es, wenn du die virtuelle Linux-Server-Maschine erstellst. Dieser Vorgang kann ein paar Minuten dauern.", + "step-1": "Schritt 1: Das Projekt abschließen", + "step-2": "Schritt 2: Übermittle deinen Code", + "submit-public-url": "Wenn du das Projekt fertiggestellt hast, speichere alle benötigten Dateien in einem öffentlichen Repository und gib die URL dazu unten an.", + "complete-both-steps": "Schließe beide Schritte unten ab, um die Aufgabe zu beenden.", + "runs-in-vm": "Das Projekt läuft in einer virtuellen Maschine. Vervollständige die dort beschriebenen User Stories und bestehe alle Tests, um Schritt 1 abzuschließen.", + "completed": "Abgeschlossen", + "not-started": "Nicht gestartet", + "hint": "Hinweis", + "test": "Test", + "sorry-try-again": "Tut mir leid, dein Code funktioniert nicht. Versuche es noch einmal.", + "sorry-keep-trying": "Tut mir leid, dein Code funktioniert nicht. Versuche es weiter.", + "sorry-getting-there": "Tut mir leid, dein Code funktioniert nicht. Du bist auf dem Weg dorthin.", + "sorry-hang-in-there": "Tut mir leid, dein Code funktioniert nicht. Halte durch.", + "sorry-dont-giveup": "Tut mir leid, dein Code funktioniert nicht. Gib nicht auf.", + "challenges-completed": "{{completedCount}} von {{totalChallenges}} Herausforderungen erfüllt" + }, + "donate": { + "title": "Unterstütze unsere Non-Profit-Organisation", + "processing": "Wir bearbeiten deine Spende.", + "redirecting": "Weiterleiten...", + "thanks": "Vielen Dank für die Spende", + "thank-you": "Vielen Dank für deine Unterstützung.", + "additional": "Du kannst eine zusätzliche einmalige Spende in beliebiger Höhe über diesen Link tätigen: <0>{{url}}", + "help-more": "Hilf uns, mehr zu tun", + "error": "Etwas ist mit deiner Spende schiefgelaufen.", + "error-2": "Irgendetwas ist nicht in Ordnung. Bitte kontaktiere donors@freecodecamp.org", + "free-tech": "Deine Spenden unterstützen die kostenlose Technologieausbildung für Menschen auf der ganzen Welt.", + "no-halo": "Wenn dein Profilbild nicht golden scheint, kontaktiere donors@freecodecamp.org.", + "gift-frequency": "Wähle die Schenkungsfrequenz:", + "gift-amount": "Schenkungsbetrag auswählen:", + "confirm": "Bestätige deine Spende", + "confirm-2": "Bestätige deine einmalige Spende von ${{usd}}", + "confirm-3": "Bestätige deine Spende von ${{usd}} / Monat", + "confirm-4": "Bestätige deine Spende von ${{usd}} / Jahr", + "wallet-label": "${{usd}} Spende an freeCodeCamp", + "wallet-label-1": "${{usd}} / monatliche Spende an freeCodeCamp", + "your-donation": "Deine ${{usd}} Spende ermöglicht {{hours}} Stunden des Lernens für Menschen auf der ganzen Welt.", + "your-donation-2": "Deine ${{usd}} Spende wird jeden Monat {{hours}} Stunden des Lernens für Menschen auf der ganzen Welt ermöglichen.", + "your-donation-3": "Deine ${{usd}} Spende wird jedes Jahr {{hours}} Stunden des Lernens für Menschen auf der ganzen Welt ermöglichen.", + "duration": "Werde ein einmaliger Unterstützer für unsere gemeinnützigen Organisation.", + "duration-2": "Werde ein monatlicher Unterstützer für unsere gemeinnützigen Organisation.", + "duration-3": "Werde ein jährlicher Unterstützer für unsere gemeinnützigen Organisation", + "duration-4": "Werde ein Unterstützer für unsere gemeinnützigen Organisation", + "nicely-done": "Großartig. Du hast soeben {{block}} abgeschlossen.", + "credit-card": "Kreditkarte", + "credit-card-2": "Oder spende mit einer Kreditkarte:", + "or-card": "Oder spende mit Karte", + "paypal": "mit PayPal:", + "need-email": "Wir benötigen eine gültige E-Mail-Adresse, an die wir deine Spendenbescheinigung senden können.", + "went-wrong": "Bei der Verarbeitung deiner Spende ist etwas schiefgelaufen. Deine Karte wurde nicht belastet.", + "valid-info": "Bitte gib eine gültige E-Mail-Adresse, Kreditkartennummer und Ablaufdatum ein.", + "valid-email": "Bitte gib eine gültige E-Mail-Adresse ein.", + "valid-card": "Bitte gib eine gültige Kreditkartennummer und das Ablaufdatum ein.", + "email-receipt": "E-Mail (wir schicken dir eine steuerlich absetzbare Spendenquittung):", + "need-help": "Brauchst du Hilfe bei deinen aktuellen oder vergangenen Spenden?", + "forward-receipt": "Sende uns eine Kopie deiner Spendenbescheinigung an donors@freecodecamp.org und lass uns wissen, wie wir dir helfen können.", + "efficiency": "freeCodeCamp ist eine hocheffiziente, gemeinnützige Bildungsorganisation.", + "why-donate-1": "Wenn du für freeCodeCamp spendest, hilfst du Menschen, neue Fähigkeiten zu erlernen und ihre Familien zu versorgen.", + "why-donate-2": "Du hilfst uns auch neue Angebote zu schaffen, die du selbst nutzen kannst, um deine technischen Fähigkeiten zu erweitern.", + "bigger-donation": "Möchtest du eine größere einmalige Spende tätigen, uns einen Scheck schicken oder auf andere Weise spenden?", + "other-ways": "Hier sind viele <0>andere Möglichkeiten, wie du die Mission unserer gemeinnützigen Organisation unterstützen kannst.", + "failed-pay": "Oh - oh. Es sieht so aus, als ob deine Transaktion nicht durchgeführt werden konnte. Kannst du es bitte noch einmal versuchen?", + "try-again": "Bitte versuche es erneut.", + "card-number": "Deine Kartennummer:", + "expiration": "Ablaufdatum:", + "secure-donation": "Sichere Spende", + "faq": "Häufig gestellte Fragen", + "only-you": "Nur du kannst diese Nachricht sehen. Herzlichen Glückwunsch zum Erhalt dieses Zertifikats. Es ist keine leichte Aufgabe. Das freeCodeCamp zu leiten, ist auch nicht einfach. Und billig ist es auch nicht. Hilf uns, dir und vielen anderen Menschen auf der ganzen Welt zu helfen. Sende noch heute eine steuerlich absetzbare Spende an unsere gemeinnützige Organisation.", + "get-help": "Wie kann ich Hilfe für meine Spenden bekommen?", + "how-transparent": "Wie transparent ist freeCodeCamp.org?", + "very-transparent": "Sehr. Wir haben eine Platin-Transparenzbewertung von GuideStar.org.", + "download-irs": "Du kannst <0>unseren Feststellungsbescheid der IRS hier herunterladen.", + "download-990": "Du kannst <0>hier unseren letzten 990 (Jahressteuerbericht) herunterladen.", + "how-efficient": "Wie effizient ist das freeCodeCamp?", + "fcc-budget": "Das Budget von freeCodeCamp ist viel kleiner als das der meisten vergleichbaren gemeinnützigen Organisationen. Wir haben keine professionellen Geldbeschaffer eingestellt. Stattdessen macht Quincy alles selbst.", + "help-millions": "Doch mit einem Budget von nur ein paar hunderttausend Dollar pro Jahr konnten wir Millionen von Menschen helfen.", + "how-one-time": "Wie kann ich eine einmalige Spende leisten?", + "one-time": "Wenn du lieber einmalig spenden möchtest, kannst du die Mission von freeCodeCamp unterstützen, wann immer du Geld übrig hast. Du kannst <0>diesen Link benutzen, um einen beliebigen Betrag über PayPal zu spenden.", + "wire-transfer": "Du kannst auch direkt Geld an das freeCodeCamp überweisen. Wenn du unsere Überweisungsdaten benötigst, schreibe Quincy eine E-Mail an quincy@freecodecamp.org", + "does-crypto": "Akzeptiert das freeCodeCamp Spenden in Bitcoin oder anderen Kryptowährungen?", + "yes-cryptocurrency": "Ja. Bitte sende eine E-Mail an Quincy unter quincy@freecodecamp.org und er kann dir die Informationen zur Wallet von freeCodeCamp schicken. Er kann dir auch eine Spendenbescheinigung ausstellen, falls du eine für deine Steuerklärung benötigst.", + "can-check": "Kann ich einen Scheck per Post schicken?", + "yes-check": "Ja, wir würden uns über einen Scheck freuen. Du kannst ihn per Post an uns schicken:", + "how-matching-gift": "Wie kann ich die gleiche Spende von meinem Arbeitgeber erhalten oder von der Gehaltsabrechnung abziehen lassen?", + "employers-vary": "Das ist von Arbeitgeber zu Arbeitgeber unterschiedlich, und unsere gemeinnützige Organisation ist bereits in vielen der großen Spenden-Datenbanken gelistet.", + "some-volunteer": "Manche Menschen können sich bei freeCodeCamp freiwillig engagieren und ihr Arbeitgeber spendet einen festen Betrag pro Stunde, in der sie sich freiwillig engagieren. Andere Arbeitgeber verdoppeln die Spenden der Spender bis zu einem bestimmten Betrag", + "help-matching-gift": "Wenn du dabei Hilfe brauchst, schreibe Quincy bitte direkt eine E-Mail: quincy@freecodecamp.org", + "how-endowment": "Wie kann ich freeCodeCamp.org eine Spende zukommen lassen?", + "endowment": "Das wäre eine große Hilfe. Da es sich um einen manuellen Prozess handelt, kann Quincy dich persönlich durch den Prozess führen. Bitte schreibe ihm direkt eine E-Mail an quincy@freecodecamp.org.", + "how-legacy": "Wie kann ich ein Vermächtnis für freeCodeCamp.org errichten?", + "we-honored": "Wir würden uns geehrt fühlen, wenn wir mit einer solchen Spende Menschen auf der ganzen Welt helfen könnten, das Programmieren zu lernen. Je nachdem, wo du wohnst, kann dies auch steuerfrei sein.", + "legacy-gift-message": "Ich schenke, vermache und vererbe [den Betrag von _____ USD (oder eine andere Währung) ODER _____ Prozent des Restes und des Nachlasses] an freeCodeCamp.org (Free Code Camp, Inc. Steueridentifikationsnummer 82-0779546), eine gemeinnützige Gesellschaft, die nach den Gesetzen des Staates Delaware, Vereinigte Staaten, gegründet wurde und derzeit ihren Sitz in 3905 Hedgcoxe Rd, PO Box 250352, Plano, Texas, 75025 Vereinigte Staaten, hat, um sie nach eigenem Ermessen für ihre allgemeinen gemeinnützigen Zwecke zu verwenden.", + "thank-wikimedia": "Wir möchten uns bei der Wikimedia Foundation dafür bedanken, dass sie uns diese formelle Formulierung zur Verfügung gestellt hat.", + "legacy-gift-questions": "Wenn du Fragen zu diesem Verfahren hast, schreibe bitte eine E-Mail an Quincy unter quincy@freecodecamp.org.", + "how-stock": "Wie kann ich Aktien für freeCodeCamp.org spenden?", + "welcome-stock": "Wir nehmen deine Aktienspenden gerne entgegen. Schreib Quincy direkt eine E-Mail und er kann dir dabei helfen und dir die Details unseres gemeinnützigen Maklerkontos mitteilen: quincy@freecodecamp.org.", + "how-receipt": "Kann ich eine Spendenbescheinigung bekommen, damit ich meine Spende von der Steuer absetzen kann?", + "just-forward": "Ja, natürlich. Schicke einfach die Quittung deiner Transaktion an donors@freecodecamp.org, sag uns, dass du eine Quittung möchtest und welche besonderen Anweisungen du hast, und wir schicken dir eine Quittung zu.", + "how-update": "Ich habe eine monatliche Spende eingerichtet, aber ich muss die monatliche Zahlung aktualisieren oder aussetzen. Wie kann ich das tun?", + "take-care-of-this": "Schicke einfach eine deiner monatlichen Spendenquittungen an donors@freecodecamp.org und sag uns, was wir für dich tun sollen. Wir erledigen das für dich und schicken dir eine Bestätigung.", + "anything-else": "Gibt es noch etwas, was ich über das Spenden an freeCodeCamp.org erfahren kann?", + "other-support": "Wenn es eine andere Möglichkeit gibt, unsere gemeinnützige Organisation zu unterstützen, die hier nicht aufgeführt ist, oder wenn du Fragen hast, schreibe bitte eine E-Mail an Quincy unter quincy@freecodecamp.org." + }, + "report": { + "sign-in": "Du musst angemeldet sein, um einen Benutzer zu melden", + "details": "Bitte gib so viele Details wie möglich über das Konto oder Verhalten an, das du meldest.", + "portfolio": "Ein Benutzerportfolio melden", + "portfolio-2": "Möchtest du {{username}}'s Portfolio wegen Missbrauch melden?", + "notify-1": "Wir werden das Team der Community-Moderatoren benachrichtigen und eine Kopie dieses Berichts an deine E-Mail senden: {{email}}", + "notify-2": "Wir werden uns bei Bedarf mit dir in Verbindung setzen, um weitere Informationen zu erhalten.", + "what": "Was möchtest du berichten?", + "submit": "Bericht absenden" + }, + "404": { + "page-not-found": "Seite nicht gefunden", + "not-found": "404 nicht gefunden:", + "heres-a-quote": "Wir konnten nicht finden, was du gesucht hast, aber hier ist ein Zitat:" + }, + "search": { + "label": "Suchen", + "placeholder": "Suche in 8.000+ Tutorials", + "see-results": "Alle Ergebnisse für {{searchQuery}} ansehen", + "no-tutorials": "Keine Tutorials gefunden", + "try": "Suchst du nach etwas? Versuche es mit der Suchleiste auf dieser Seite.", + "no-results": "Wir konnten nichts in Verbindung mit <0>{{query}} finden" + }, + "misc": { + "offline": "Du scheinst offline zu sein, dein Fortschritt wird möglicherweise nicht gespeichert", + "server-offline": "Der Server konnte nicht erreicht werden und dein Fortschritt wird möglicherweise nicht gespeichert. Bitte wende dich an den <0>Support, wenn diese Meldung weiterhin erscheint", + "unsubscribed": "Du wurdest erfolgreich abgemeldet", + "keep-coding": "Wie auch immer du weitermachst, programmiere weiter!", + "email-signup": "E-Mail-Registrierung", + "quincy": "- Quincy Larson, der Lehrer, der freeCodeCamp.org gegründet hat", + "email-blast": "Übrigens, jeden Freitag verschicke ich eine E-Mail mit 5 Links über Programmierung und Informatik. Diese schicke ich an etwa 4 Millionen Menschen. Möchtest du, dass ich diese auch an dich sende?", + "update-email-1": "Aktualisiere deine E-Mail-Adresse", + "update-email-2": "Aktualisiere deine E-Mail-Adresse hier:", + "email": "E-Mail", + "and": "und", + "change-theme": "Anmelden, um das Theme zu ändern.", + "translation-pending": "Hilf uns, zu übersetzen", + "certification-project": "Zertifizierungsprojekt", + "iframe-alert": "Normalerweise würde dieser Link dich auf eine andere Website führen! Er funktioniert. Dies ist ein Link zu: {{externalLink}}", + "document-notfound": "Dokument wurde nicht gefunden" + }, + "icons": { + "gold-cup": "Goldpokal", + "avatar": "Standard-Avatar", + "avatar-2": "Ein Avatar, der mit einem Laptop programmiert", + "donate": "Über PayPal spenden", + "fail": "Test fehlgeschlagen", + "not-passed": "Nicht bestanden", + "waiting": "Warten", + "passed": "Bestanden", + "failed": "Fehlgeschlagen", + "hint": "Hinweis", + "heart": "Herz", + "initial": "Initial", + "info": "Einführungsinformationen", + "spacer": "Abstandhalter", + "toggle": "Häkchen umschalten", + "magnifier": "Lupe" + }, + "aria": { + "fcc-curriculum": "freeCodeCamp Studienplan", + "answer": "Antwort", + "linkedin": "Link zu {{username}}'s LinkedIn-Account", + "github": "Link zu {{username}}'s GitHub-Account", + "website": "Link zu {{username}}'s Website", + "twitter": "Link zu {{username}}'s Twitter-Account", + "first-page": "Zur ersten Seite gehen", + "previous-page": "Zur vorherigen Seite gehen", + "next-page": "Zur nächsten Seite gehen", + "last-page": "Zur letzten Seite gehen", + "primary-nav": "primär", + "breadcrumb-nav": "Breadcrumb", + "submit": "Verwende Strg + Enter zum Absenden.", + "running-tests": "Tests werden durchgeführt", + "step": "Schritt", + "steps": "Schritte", + "steps-for": "Schritte für {{blockTitle}}" + }, + "flash": { + "honest-first": "Um eine Zertifizierung zu erlangen, musst du zunächst unsere Richtlinie zur akademischen Ehrlichkeit akzeptieren", + "really-weird": "Etwas wirklich Seltsames ist passiert. Wenn es wieder passiert, erwäge bitte, einen Fehler auf https://github.com/freeCodeCamp/freeCodeCamp/issues/new zu melden.", + "not-right": "Irgendetwas ist nicht in Ordnung. Es wurde ein Bericht erstellt und das freeCodeCamp.org Team wurde benachrichtigt", + "went-wrong": "Etwas ist schief gelaufen, bitte überprüfe und versuche es erneut", + "account-deleted": "Dein Konto wurde erfolgreich gelöscht", + "progress-reset": "Dein Fortschritt wurde zurückgesetzt", + "not-authorized": "Du bist nicht berechtigt, diese Route weiter zu befahren", + "could-not-find": "Wir konnten nicht finden, was du gesucht hast. Bitte überprüfe und versuche es erneut", + "wrong-updating": "Beim Aktualisieren deines Kontos ist etwas schief gelaufen. Bitte überprüfe und versuche es erneut", + "updated-preferences": "Wir haben deine Einstellungen aktualisiert", + "email-invalid": "E-Mail-Format ist ungültig", + "email-valid": "Deine E-Mail wurde erfolgreich geändert. Viel Spaß beim Coding!", + "bad-challengeId": "currentChallengeId ist keine gültige Challenge-ID", + "theme-invalid": "Das Theme ist ungültig", + "theme-set": "Theme bereits festgelegt", + "theme-updated": "Dein Theme wurde aktualisiert!", + "username-used": "Benutzername ist bereits mit diesem Konto verknüpft", + "username-taken": "Benutzername ist bereits mit einem anderen Konto verknüpft", + "username-updated": "Wir haben deinen Benutzernamen auf {{username}} aktualisiert", + "could-not-logout": "Wir konnten dich nicht abmelden, bitte versuche es in einem Moment noch einmal", + "email-encoded-wrong": "Die im Link kodierte E-Mail ist falsch formatiert", + "oops-not-right": "Ups, da stimmt etwas nicht, bitte fordere einen neuen Link zum Anmelden / Registrieren an", + "expired-link": "Es sieht so aus, als ob der Link, den du geklickt hast, abgelaufen wäre. Bitte fordere einen neuen Link an, um dich anzumelden.", + "signin-success": "Geschafft! Du hast dich in deinem Konto angemeldet. Viel Spaß beim Programmieren!", + "social-auth-gone": "Aus Gründen des Datenschutzes verabschieden wir uns von der sozialen Authentifizierung. Beim nächsten Mal empfehlen wir, deine E-Mail-Adresse zu verwenden: {{email}}, um sich stattdessen anzumelden.", + "name-needed": "Wir benötigen deinen Namen, damit wir ihn auf deinem Zertifikat eintragen können. Füge deinen Namen zu deinen Kontoeinstellungen hinzu und klicke auf den Speichern-Button. Dann können wir dein Zertifikat ausstellen.", + "incomplete-steps": "Es sieht so aus, als hättest du die notwendigen Schritte nicht abgeschlossen. Bitte vervollständige die erforderlichen Projekte, um die {{name}} Zertifizierung zu erhalten.", + "already-claimed": "Es sieht so aus, als hättest du bereits die {{name}} Zertifizierung erhalten", + "cert-claim-success": "@{{username}}, du hast erfolgreich die {{name}} Zertifizierung bestanden! Herzlichen Glückwunsch im Namen des freeCodeCamp.org Teams!", + "wrong-name": "Bei der Überprüfung von {{name}} ist etwas schief gelaufen, bitte versuche es erneut. Wenn du weiterhin diesen Fehler erhältst, kannst du eine Nachricht an support@freeCodeCamp.org senden, um Hilfe zu erhalten.", + "error-claiming": "Fehler beim Anfordern von {{certName}}", + "refresh-needed": "Du kannst den Button Zahlungsanforderung nur einmal verwenden. Aktualisiere die Seite, um neu zu beginnen.", + "username-not-found": "Wir konnten keinen Benutzer mit dem Benutzernamen \"{{username}}\" finden", + "add-name": "Dieser Nutzer muss seinen Namen zu seinem Konto hinzufügen, damit andere seine Zertifizierungen sehen können.", + "not-eligible": "Dieser Benutzer ist zu diesem Zeitpunkt nicht für freeCodeCamp.org-Zertifizierungen berechtigt.", + "profile-private": "{{username}} hat sich entschieden, sein Profil privat zu halten. Du musst dein Profil öffentlich machen, damit andere deine Zertifikate sehen können.", + "certs-private": "{{username}} hat sich entschieden, seine Zertifizierungen privat zu lassen. Sie müssen ihre Zertifizierungen öffentlich machen, damit andere sie sehen können.", + "not-honest": "{{username}} hat unserem akademischen Ehrlichkeitsversprechen noch nicht zugestimmt.", + "user-not-certified": "Es sieht so aus, als ob Benutzer {{username}} nicht {{cert}} zertifiziert ist", + "invalid-challenge": "Das scheint keine gültige Einreichung zu sein", + "no-links-provided": "Du hast die gültigen Links nicht angegeben, damit wir deine Arbeit überprüfen können.", + "no-social": "Kein sozialer Account gefunden", + "invalid-social": "Ungültiger sozialer Account", + "no-account": "Kein {{website}}-Account verbunden", + "unlink-success": "Du hast deine {{website}} erfolgreich entfernt", + "provide-username": "Prüfe, ob du einen Benutzernamen und einen Bericht angegeben hast", + "report-sent": "Ein Bericht wurde an das Team mit {{email}} in Kopie gesendet", + "certificate-missing": "Die Zertifizierung, die du einsehen wolltest, existiert nicht", + "create-token-err": "Beim Erstellen deines Benutzer-Tokens ist ein Fehler aufgetreten", + "delete-token-err": "Beim Löschen deines Benutzer-Tokens ist ein Fehler aufgetreten", + "token-created": "Du hast erfolgreich einen neuen Benutzer-Token erstellt.", + "token-deleted": "Dein Benutzer-Token wurde gelöscht.", + "start-project-err": "Beim Versuch, das Projekt zu starten, ist etwas schief gelaufen. Bitte versuche es noch einmal.", + "complete-project-first": "Du musst das Projekt zuerst abschließen.", + "local-code-save-error": "Ups, dein Code wurde nicht gespeichert, der lokale Speicher deines Browsers ist möglicherweise voll.", + "local-code-saved": "Gespeichert! Dein Code wurde im lokalen Speicher deines Browsers gespeichert.", + "code-saved": "Dein Code wurde in der Datenbank gespeichert. Er wird hier sein, wenn du zurückkommst.", + "code-save-error": "Beim Versuch, deinen Code zu speichern, ist ein Fehler aufgetreten.", + "code-save-less": "Mach langsam! Dein Code wurde nicht gespeichert. Versuche es in ein paar Sekunden noch einmal.", + "challenge-save-too-big": "Du kannst deinen Code leider nicht speichern. Dein Code ist {{user-size}} Bytes groß. Wir erlauben ein Maximum von {{max-size}} Bytes. Bitte verkleinere deinen Code und versuche es noch einmal oder bitte um Hilfe auf https://forum.freecodecamp.org", + "challenge-submit-too-big": "Du kannst deinen Code leider nicht einreichen. Dein Code ist {{user-size}} Bytes groß. Wir erlauben ein Maximum von {{max-size}} Bytes. Bitte verkleinere deinen Code und versuche es noch einmal oder bitte um Hilfe auf https://forum.freecodecamp.org", + "invalid-update-flag": "Du versuchst, auf verbotene Ressourcen zuzugreifen. Bitte fordere unter https://forum.freecodecamp.org Unterstützung an, wenn dies eine gültige Anfrage ist." + }, + "validation": { + "max-characters": "Es gibt eine maximale Grenze von 288 Zeichen, du hast noch {{charsLeft}} übrig", + "same-email": "Diese E-Mail ist die gleiche wie deine aktuelle E-Mail", + "invalid-email": "Wir konnten deine E-Mail nicht ordnungsgemäß überprüfen, bitte stelle sicher, dass sie korrekt ist", + "email-mismatch": "Beide neuen E-Mail-Adressen müssen identisch sein", + "title-required": "Ein Titel ist erforderlich", + "title-short": "Titel ist zu kurz", + "title-long": "Titel ist zu lang", + "invalid-url": "Wir konnten deine URL nicht ordnungsgemäß überprüfen, bitte stelle sicher, dass sie korrekt ist", + "invalid-protocol": "URL muss mit http oder https beginnen", + "url-not-image": "URL muss direkt mit einer Bilddatei verknüpft sein", + "use-valid-url": "Bitte verwende eine gültige URL", + "editor-url": "Denke daran, die Live App URL einzureichen.", + "http-url": "Eine unsichere (http) URL kann nicht verwendet werden.", + "own-work-url": "Denke daran, deine eigene Arbeit einzureichen.", + "publicly-visible-url": "Denke daran, eine öffentlich sichtbare App-URL einzureichen." + }, + "certification": { + "executive": "Geschäftsführender Direktor, freeCodeCamp.org", + "verify": "Diese Zertifizierung kann unter {{certURL}} überprüft werden", + "issued": "Ausgestellt", + "fulltext": "<0> Hiermit wird bescheinigt, dass <1>{{user}} <2>die freeCodeCamp.org <3>{{title}} <4>Entwickler-Zertifizierung erfolgreich abgeschlossen hat, was ungefähr {{time}} Stunden an Kursarbeit entspricht.", + "project": { + "heading-legacy-full-stack": "Im Rahmen dieser Legacy-Full-Stack-Zertifizierung hat {{user}} folgende Zertifikate abgeschlossen:", + "heading": "Im Rahmen dieser Zertifizierung hat {{user}} folgende Projekte erstellt und alle automatisierten Testsuiten bestanden:", + "solution": "Lösung", + "no-solution": "Fehler bei der Anzeige der Lösung, schreibe eine E-Mail an support@freeCodeCamp.org, um Hilfe zu erhalten.", + "source": "Quelle", + "footnote": "Wenn du den Verdacht hast, dass eines dieser Projekte gegen die <2>Richtlinie zur akademischen Ehrlichkeit verstößt, <5>melde dies bitte unserem Team.", + "title": { + "Build a Personal Portfolio Webpage": "Erstelle eine persönliche Portfolio-Webseite", + "Build a Random Quote Machine": "Erstelle eine Zufalls-Zitat-Maschine", + "Build a 25 + 5 Clock": "Erstelle eine 25 + 5 Uhr", + "Build a JavaScript Calculator": "Erstelle einen JavaScript-Rechner", + "Show the Local Weather": "Lokales Wetter anzeigen", + "Use the TwitchTV JSON API": "Verwende die TwitchTV JSON API", + "Stylize Stories on Camper News": "Geschichten auf Camper News stilisieren", + "Build a Wikipedia Viewer": "Erstelle einen Wikipedia-Viewer", + "Build a Tic Tac Toe Game": "Erstelle ein Tic Tac Toe Spiel", + "Build a Simon Game": "Erstelle ein Simon-Spiel", + "Timestamp Microservice": "Zeitstempel Microservice", + "Request Header Parser Microservice": "Request-Header-Parser-Mikroservice", + "URL Shortener Microservice": "URL Shortener Microservice", + "Image Search Abstraction Layer": "Bildsuchabstraktionsebene", + "File Metadata Microservice": "Datei-Metadaten-Mikroservice", + "Build a Voting App": "Erstelle eine Abstimmungsapp", + "Build a Nightlife Coordination App": "Erstelle eine App zur Nachtleben-Koordination", + "Chart the Stock Market": "Zeichne den Aktienmarkt auf", + "Manage a Book Trading Club": "Verwalte einen Buchhandelsclub", + "Build a Pinterest Clone": "Erstelle einen Pinterest Klon", + "Build a Markdown Previewer": "Erstelle einen Markdown Vorschau-Viewer", + "Build a Camper Leaderboard": "Erstelle eine Camper-Rangliste", + "Build a Recipe Box": "Erstelle eine Rezeptbox", + "Build the Game of Life": "Erstelle das Spiel des Lebens", + "Build a Roguelike Dungeon Crawler Game": "Erstelle ein schurkenartiges Dungeon Crawler Spiel", + "Visualize Data with a Bar Chart": "Visualisiere Daten mit einem Balkendiagramm", + "Visualize Data with a Scatterplot Graph": "Visualisiere Daten mit einem Scatterplot-Diagramm (Streudiagramm)", + "Visualize Data with a Heat Map": "Visualisiere Daten mit einer Heatmap", + "Show National Contiguity with a Force Directed Graph": "Zeige nationale Kontiguität mit einem kraftgerichteten Graphen", + "Map Data Across the Globe": "Kartendaten rund um den Globus", + "Metric-Imperial Converter": "Metrisch-Imperialer Konverter", + "Issue Tracker": "Issue-Tracker", + "Personal Library": "Persönliche Bibliothek", + "Stock Price Checker": "Aktienpreisprüfer", + "Anonymous Message Board": "Anonymes Nachrichtenbrett", + "Build a Tribute Page": "Erstelle eine Tributeseite", + "Build a Survey Form": "Erstelle ein Umfrageformular", + "Build a Product Landing Page": "Erstelle eine Landing Page für ein Produkt", + "Build a Technical Documentation Page": "Erstelle eine Seite für technische Dokumentation", + "Palindrome Checker": "Palindrom-Checker", + "Roman Numeral Converter": "Konverter für römische Ziffern", + "Caesars Cipher": "Cäsar-Chiffre", + "Telephone Number Validator": "Telefonnummerprüfer", + "Cash Register": "Registrierkasse", + "Build a Drum Machine": "Erstelle eine Schlagzeug-Maschine", + "Visualize Data with a Choropleth Map": "Visualisiere Daten mit einer Choroplethenkarte (Flächenkartogramm)", + "Visualize Data with a Treemap Diagram": "Visualisiere Daten mit einem Treemap-Diagramm", + "Exercise Tracker": "Übungs-Tracker", + "Sudoku Solver": "Sudoku-Löser", + "American British Translator": "Amerikanischer Britischer Übersetzer", + "Arithmetic Formatter": "Arithmetischer Formatierer", + "Time Calculator": "Zeitrechner", + "Budget App": "Budget-App", + "Polygon Area Calculator": "Polygon-Flächenrechner", + "Probability Calculator": "Wahrscheinlichkeitsrechner", + "Mean-Variance-Standard Deviation Calculator": "Berechnungsprogramm für Mittelwert, Varianz, und Standardabweichung", + "Demographic Data Analyzer": "Demografischer Datenanalysator", + "Medical Data Visualizer": "Medizinischer Datenvisualisierer", + "Page View Time Series Visualizer": "Seitenansicht Zeitreihen-Visualisierer", + "Sea Level Predictor": "Meeresspiegelvorhersage", + "Port Scanner": "Port-Scanner", + "SHA-1 Password Cracker": "SHA-1 Passwort-Cracker", + "Secure Real Time Multiplayer Game": "Sicheres Echtzeit-Multiplayer-Spiel", + "Rock Paper Scissors": "Schere Stein Papier", + "Cat and Dog Image Classifier": "Katzen- und Hundebildklassifizierer", + "Book Recommendation Engine using KNN": "Buchempfehlungsmaschine mithilfe von KNN", + "Linear Regression Health Costs Calculator": "Gesundheitskostenrechner mit einer linearen Regression", + "Neural Network SMS Text Classifier": "SMS-Textklassifizierung mittels neuronalem Netzwerk" + } + } + }, + "certification-card": { + "title": "Beantrage dein Zertifikat", + "intro": "Erledige die folgenden Schritte, um deine {{i18nCertText}} zu beanspruchen und anzusehen", + "complete-project": "Schließe {{i18nCertText}} Projekte ab", + "accept-honesty": "Akzeptiere unsere Richtlinie zur akademischen Ehrlichkeit", + "set-name": "Lege deinen Namen fest und mache ihn öffentlich", + "set-certs-public": "Setze deine Zertifizierungseinstellungen auf öffentlich", + "set-profile-public": "Profileinstellungen auf öffentlich setzen", + "set-claim": "Zertifizierung beantragen und anzeigen" + }, + "forum-help": { + "browser-info": "**Deine Browser-Informationen:**", + "user-agent": "User Agent ist: {{userAgent}}", + "challenge": "**Herausforderung:** {{challengeTitle}}", + "challenge-link": "**Link zur Herausforderung: **", + "whats-happening": "**Sag uns, was vor sich geht:**", + "describe": "Beschreibe hier dein Problem im Detail.", + "camper-project": "**Deine Projekt-Link(s)**", + "camper-code": "**Dein Code bisher**", + "warning": "WARNUNG", + "too-long-one": "Der Startcode der Herausforderung und/oder deine Lösung hat die maximale Länge überschritten, die wir von der Herausforderung übernehmen können.", + "too-long-two": "Du musst hier einen zusätzlichen Schritt machen, damit der von dir geschriebene Code in einem einfach zu lesenden Format dargestellt wird.", + "too-long-three": "Bitte kopiere/und füge den gesamten Editor-Code ein, der in der Herausforderung angezeigt wird, von wo aus du gerade verlinkt hast.", + "add-code-one": "Ersetze diese beiden Sätze durch deinen kopierten Code.", + "add-code-two": "Bitte lass die ``` Zeile oben und die ``` Zeile unten stehen,", + "add-code-three": "weil sie die korrekte Formatierung deines Codes im Beitrag ermöglichen." + }, + "user-token": { + "title": "Benutzer-Token", + "create": "Ein neuen Token erstellen", + "create-p1": "Es sieht so aus, als hättest du keinen Benutzer-Token. Erstelle einen, um deinen Fortschritt in diesem Abschnitt zu speichern", + "create-p2": "Erstelle ein Benutzer-Token, um deinen Fortschritt bei den Studienabschnitten zu speichern, die eine virtuelle Maschine verwenden.", + "delete": "Meinen Benutzer-Token löschen", + "delete-title": "Meinen Benutzer-Token löschen", + "delete-p1": "Dein Benutzer-Token wird verwendet, um deinen Fortschritt in den Studienabschnitten zu speichern, die eine virtuelle Maschine verwenden. Wenn du den Verdacht hast, dass er kompromittiert wurde, kannst du ihn löschen, ohne dass der Fortschritt verloren geht. Ein neuer Token wird automatisch erstellt, wenn du das nächste Mal ein Projekt öffnest.", + "delete-p2": "Wenn du vermutest, dass dein Token kompromittiert wurde, kannst du ihn löschen, um ihn unbrauchbar zu machen. Der Fortschritt bei bereits eingereichten Lektionen geht nicht verloren.", + "delete-p3": "Du musst einen neuen Token erstellen, um zukünftige Fortschritte in den Studienplanabschnitten zu speichern, die eine virtuelle Maschine verwenden.", + "no-thanks": "Nein danke, ich möchte meinen Token behalten", + "yes-please": "Ja, ich möchte mein Token löschen" + }, + "shortcuts": { + "title": "Tastaturkurzbefehle", + "table-header-action": "Aktion", + "table-header-key": "Taste(n)", + "navigation-mode": "Navigations-Modus", + "execute-challenge": "Aufgabe ausführen", + "focus-editor": "Fokus Editor", + "focus-instructions-panel": "Fokus-Bedienfeld", + "navigate-previous": "Zur vorherigen Übung navigieren", + "navigate-next": "Zur nächsten Übung navigieren" + } +} diff --git a/client/i18n/locales/german/trending.json b/client/i18n/locales/german/trending.json new file mode 100644 index 00000000000000..424577013755a2 --- /dev/null +++ b/client/i18n/locales/german/trending.json @@ -0,0 +1,62 @@ +{ + "article0title": "Discord Won't Open", + "article0link": "https://www.freecodecamp.org/news/discord-wont-open-on-my-pc-solved-in-windows-10/", + "article1title": "Learn Java Courses", + "article1link": "https://www.freecodecamp.org/news/learn-java-free-java-courses-for-beginners/", + "article2title": "SQL Like Statement", + "article2link": "https://www.freecodecamp.org/news/sql-like-statement-how-to-query-sql-with-wildcard/", + "article3title": "File Explorer Error", + "article3link": "https://www.freecodecamp.org/news/file-explorer-not-responding-fixed-on-windows-10-pc/", + "article4title": "Python Find in List", + "article4link": "https://www.freecodecamp.org/news/python-find-in-list-how-to-find-the-index-of-an-item-or-element-in-a-list/", + "article5title": "Functions in Python", + "article5link": "https://www.freecodecamp.org/news/python-functions-define-and-call-a-function/", + "article6title": "Python Reverse List", + "article6link": "https://www.freecodecamp.org/news/python-reverse-list-how-to-reverse-a-range-or-array/", + "article7title": "Create a Table in SQL", + "article7link": "https://www.freecodecamp.org/news/how-to-create-a-table-in-sql-postgres-and-mysql-example-query/", + "article8title": "List Index Out of Range", + "article8link": "https://www.freecodecamp.org/news/list-index-out-of-range-python-error-message-solved/", + "article9title": "Python String.Replace()", + "article9link": "https://www.freecodecamp.org/news/python-string-replace-function-in-python-for-substring-substitution/", + "article10title": "C vs C++", + "article10link": "https://www.freecodecamp.org/news/c-vs-cpp-whats-the-difference/", + "article11title": "Python JSON", + "article11link": "https://www.freecodecamp.org/news/python-json-how-to-convert-a-string-to-json/", + "article12title": "What is a PC?", + "article12link": "https://www.freecodecamp.org/news/what-is-a-pc-computer-definition-and-computer-basics-for-beginners/", + "article13title": "What is Coding?", + "article13link": "https://www.freecodecamp.org/news/computer-coding-computer-program-definition-and-code-meaning/", + "article14title": "Text Box in HTML", + "article14link": "https://www.freecodecamp.org/news/text-box-in-html-the-input-field-html-tag/", + "article15title": "Meta Tag in HTML", + "article15link": "https://www.freecodecamp.org/news/meta-tag-in-html-what-is-metadata-and-meta-description-example/", + "article16title": "Append in Python", + "article16link": "https://www.freecodecamp.org/news/append-in-python-how-to-append-to-a-list-or-an-array/", + "article17title": "Python Not Equal", + "article17link": "https://www.freecodecamp.org/news/python-not-equal-how-to-use-the-does-not-equal-operator/", + "article18title": "Linux awk Command", + "article18link": "https://www.freecodecamp.org/news/the-linux-awk-command-linux-and-unix-usage-syntax-examples/", + "article19title": "JS String Contains", + "article19link": "https://www.freecodecamp.org/news/javascript-string-contains-how-to-use-js-includes/", + "article20title": "How to Open Task Manager", + "article20link": "https://www.freecodecamp.org/news/how-to-open-task-manager-in-windows-10/", + "article21title": "Design Thinking Explained", + "article21link": "https://www.freecodecamp.org/news/the-design-thinking-process-explained/", + "article22title": "Learn Programming Courses", + "article22link": "https://www.freecodecamp.org/news/learn-programming-free-software-development-courses-for-beginners/", + "article23title": "Make a Transparent Taskbar", + "article23link": "https://www.freecodecamp.org/news/transparent-taskbar-how-to-make-a-task-bar-transparent-in-windows-10-pc-2/", + "article24title": "Install Ethernet Driver PC", + "article24link": "https://www.freecodecamp.org/news/windows-10-network-adapter-missing-how-to-install-ethernet-driver-on-pc/", + "article25title": "Default Constructor in Java", + "article25link": "https://www.freecodecamp.org/news/default-constructor-in-java/", + "article26title": "Stuck Win 10 Hard Drive", + "article26link": "https://www.freecodecamp.org/news/scanning-and-repairing-drive-how-to-fix-stuck-windows-10-pc-hard-drive/", + "article27title": "Color Codes for Grey Palette", + "article27link": "https://www.freecodecamp.org/news/color-shades-hex-code-and-rgb-for-gray-color-palette/", + "article28title": "Binary Search Tree Traversal", + "article28link": "https://www.freecodecamp.org/news/binary-search-tree-traversal-inorder-preorder-post-order-for-bst/", + "article29title": "RTC Connecting Discord Fix", + "article29link": "https://www.freecodecamp.org/news/rtc-connecting-discord-how-to-fix-the-server-error/" + } \ No newline at end of file diff --git a/client/i18n/locales/italian/intro.json b/client/i18n/locales/italian/intro.json index 6828908cfd2a38..fead2731369f51 100644 --- a/client/i18n/locales/italian/intro.json +++ b/client/i18n/locales/italian/intro.json @@ -67,11 +67,11 @@ } }, "2022/responsive-web-design": { - "title": "(New) Responsive Web Design", + "title": "(Nuovo) Web Design Responsivo", "intro": [ "In questo corso certificato di Web Design Responsivo imparerai i linguaggi che gli sviluppatori utilizzano per creare le pagine web. HTML (Hypertext Markup Language) per i contenuti e CSS (Cascading Style Sheets) per il design.", - "Innanzitutto, creerai un'app di foto per gatti per imparare le basi dell'HTML e dei CSS. Più avanti, imparerai le moderne tecniche come le variabili CSS disegnando un pinguino, e le migliori pratiche di accessibilità creando un form web.", - "Infine imparerai a fare pagine web adattabili a diverse misure di schermo creando una Twitter Card con Flexbox, e un complesso layout per un blog con una griglia CSS." + "Per prima cosa, costruirai un'app con foto di gatti per imparare le basi di HTML e CSS. Poi apprenderai tecniche più moderne come le variabili in CSS costruendo un pinguino, e le migliori pratiche per l'accessibilità costruendo un quiz.", + "Infine, imparerai come fare pagine web che rispondono a diverse dimensioni dello schermo costruendo una galleria di foto con Flexbox e il layout di un articolo di rivista con CSS Grid." ], "note": "Nota: Alcune estensioni del browser, come ad esempio gli ad-blocker e le estensioni per la modalità scura, possono interferire con i test. In caso di problemi, ti consigliamo di disabilitare le estensioni che modificano il contenuto o il layout delle pagine durante il corso.", "blocks": { @@ -300,64 +300,64 @@ } }, "2022/javascript-algorithms-and-data-structures": { - "title": "JavaScript Algorithms and Data Structures (Beta)", + "title": "Algoritmi e Strutture Dati JavaScript (Beta)", "intro": [ - "placeholder", - "placeholder" + "segnaposto", + "segnaposto" ], "note": "", "blocks": { "build-a-caesars-cipher-project": { - "title": "Build a Casears Cipher Project", + "title": "Crea un cifrario di Cesare", "intro": [ "", "" ] }, "build-a-cash-register-project": { - "title": "Build a Cash Register Project", + "title": "Crea un registro di cassa", "intro": [ "", "" ] }, "build-a-palindrome-checker-project": { - "title": "Build a Palindrome Checker Project", + "title": "Crea un verificatore di palindromi", "intro": [ "", "" ] }, "build-a-roman-numeral-converter-project": { - "title": "Build a Roman Numeral Converter Project", + "title": "Crea un convertitore di numeri romani", "intro": [ "", "" ] }, "build-a-telephone-number-validator-project": { - "title": "Build a Telephone Number Validator Project", + "title": "Crea un validatore di numeri telefonici", "intro": [ "", "" ] }, "learn-basic-javascript-by-building-a-role-playing-game": { - "title": "Learn Basic JavaScript by Building a Role Playing Game", + "title": "Impara JavaScript Base creando un gioco di ruolo", "intro": [ "", "" ] }, "learn-form-validation-by-building-a-calorie-counter": { - "title": "Learn Form Validation by Building a Calorie Counter", + "title": "Impara la validazione dei moduli creando un contatore di calorie", "intro": [ "", "" ] }, "learn-functional-programming-by-building-a-spreadsheet": { - "title": "Learn Functional Programming by Building a Spreadsheet", + "title": "Impara programmazione funzionale creando un foglio di calcolo", "intro": [ "", "" @@ -606,8 +606,8 @@ "mongodb-and-mongoose": { "title": "MongoDB e Mongoose", "intro": [ - "MongoDB è un'applicazione di database che memorizza documenti JSON (o record) che è possibile utilizzare nella propria applicazione. A differenza di SQL, un altro tipo di database, Mongo è un database non relazionale o \"NoSQL\". Questo significa che Mongo memorizza tutti i dati associati in un record, invece di memorizzarli in molte tabelle preimpostate come in un database SQL.", - "Mongoose è un popolare pacchetto npm che è spesso installato insieme a Mongo. Con Mongoose, è possibile utilizzare semplici oggetti JavaScript invece di JSON, il che rende più facile lavorare con Mongo. Inoltre, ti permette di creare progetti per i tuoi documenti chiamati schemas, in modo da non salvare accidentalmente il tipo sbagliato di dati e causare bug in seguito.", + "MongoDB è un'applicazione di databse che memorizza documenti JSON (o record) che puoi usare nella tua applicazione. A differenza di SQL, un altro tipo di database, MongoDB è un database non relazionale o un database \"NoSQL\". Questo significa che MongoDB memorizza tutti i dati associati in un record al posto di memorizzarli in varie tabelle preimpostate come in un database SQL.", + "Mongoose è un popolare pacchetto npm che interagisce con MongoDB. Con Mongoose puoi utilizzare dei semplici oggetti JavaScript al posto di JSON, ciò rende più facile lavorare con MongoDB. Inoltre, ti permette di creare schemi per i tuoi documenti chiamati schemas, così da non salvare il tipo di dato sbagliato e causare bug in seguito.", "Nei corsi di MongoDB e Mongoose, imparerai i fondamenti di come si lavora con dati persistenti, incluso come impostare un modello, e salvare, cancellare e trovare documenti nel database." ] }, @@ -804,7 +804,8 @@ "title": "Codice Rosetta", "intro": [ "Fai salire di livello le tue capacità creative di problem solving con queste attività di programmazione gratuite dalla libreria classica Rosetta Code.", - "Queste sfide possono rivelarsi difficili, ma spingeranno la tua logica algoritmica a nuove vette." + "Queste sfide possono rivelarsi difficili, ma spingeranno la tua logica algoritmica a nuove vette.", + "Fonte: Codice Rosetta" ] }, "project-euler": { diff --git a/client/i18n/locales/italian/links.json b/client/i18n/locales/italian/links.json index 171469390073b7..eb29b9968e040c 100644 --- a/client/i18n/locales/italian/links.json +++ b/client/i18n/locales/italian/links.json @@ -13,7 +13,10 @@ "copyright-url": "https://www.freecodecamp.org/news/copyright-policy/" }, "donate": { - "other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp" + "other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp", + "download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf", + "download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf", + "one-time-url": "https://paypal.me/freecodecamp" }, "nav": { "forum": "https://forum.freecodecamp.org/c/italiano/", @@ -23,6 +26,6 @@ "HTML-CSS": "Italiano/HTML-CSS", "JavaScript": "Italiano/JavaScript", "Python": "Italiano/Python", - "Relational Databases": "Italiano/Relational Databases" + "Backend Development": "italiano/aiuto-programmazione" } } diff --git a/client/i18n/locales/italian/meta-tags.json b/client/i18n/locales/italian/meta-tags.json index cf2020dbfb80e6..558473305e141c 100644 --- a/client/i18n/locales/italian/meta-tags.json +++ b/client/i18n/locales/italian/meta-tags.json @@ -1,21 +1,21 @@ { - "title": "Learn to Code — For Free — Coding Courses for Busy People", - "description": "Learn to Code — For Free", - "social-description": "Learn to Code — For Free", + "title": "Impara a programmare — Gratis — Corsi di programmazione per persone impegnate", + "description": "Impara a programmare — Gratis", + "social-description": "Impara a programmare — Gratis", "keywords": [ "python", "javascript", "js", "git", "github", - "website", + "sito web", "web", - "development", + "sviluppo", "free", "code", "camp", - "course", - "courses", + "corso", + "corsi", "html", "css", "react", @@ -24,9 +24,12 @@ "front", "back", "end", - "learn", + "imparare", "tutorial", - "programming" + "programmazione", + "gratis", + "gratuitamente", + "programmare" ], - "youre-unsubscribed": "You have been unsubscribed" + "youre-unsubscribed": "La tua iscrizione è stata cancellata" } diff --git a/client/i18n/locales/italian/translations.json b/client/i18n/locales/italian/translations.json index 5a629f4f1f9bc7..4d237c3605a86c 100644 --- a/client/i18n/locales/italian/translations.json +++ b/client/i18n/locales/italian/translations.json @@ -50,7 +50,8 @@ "reset-lesson": "Resetta questa lezione", "run": "Avvia", "run-test": "Esegui i test (Ctrl + Invio)", - "check-code": "Check Your Code (Ctrl + Enter)", + "check-code": "Verifica il tuo codice (Ctrl + Invio)", + "check-code-2": "Verifica il tuo codice", "reset": "Resetta", "reset-code": "Resetta tutto il codice", "help": "Guida", @@ -70,7 +71,11 @@ "start-coding": "Inizia a programmare!", "go-to-settings": "Vai alle impostazioni per richiedere la tua certificazione", "click-start-course": "Inizia il corso", - "click-start-project": "Inizia il progetto" + "click-start-project": "Inizia il progetto", + "change-language": "Cambia lingua", + "cancel-change": "Annulla modifica", + "resume-project": "Riprendi progetto", + "start-project": "Avvia il progetto" }, "landing": { "big-heading-1": "Impara a programmare — gratis.", @@ -101,7 +106,7 @@ }, "settings": { "share-projects": "Condividi i tuoi progetti non-freeCodeCamp, articoli o pull request accettate.", - "privacy": "The settings in this section enable you to control what is shown on your freeCodeCamp public portfolio. Press save to save your changes.", + "privacy": "Le impostazioni di questa sezione ti permettono di controllare quello che viene mostrato sul tuo portfolio pubblico di freeCodeCamp. Premi salva per salvare le tue modifiche.", "data": "Per vedere quali dati teniamo nel tuo account, clicca sul pulsante \"Scarica i tuoi dati\" qui sotto", "disabled": "Le tue certificazioni saranno disabilitate, se impostato su privato.", "private-name": "Il tuo nome non apparirà sulle certificazioni, se impostato su privato.", @@ -143,7 +148,8 @@ "my-timeline": "La mia cronologia", "my-donations": "Le mie donazioni", "night-mode": "Modalità Notturna", - "sound-mode": "Modalità Campfire" + "sound-mode": "Modalità Campfire", + "keyboard-shortcuts": "Abilita le scorciatoie da tastiera" }, "headings": { "certs": "Certificazioni", @@ -269,7 +275,7 @@ "solution-link": "Link alla soluzione", "github-link": "Link GitHub", "submit-and-go": "Invia e vai alla prossima sfida", - "congradulations": "Congratulations, your code passes. Submit your code to complete this step and move on to the next one.", + "congratulations": "Congratulazioni, hai superato i test. Invia in tuo codice per continuare.", "i-completed": "Ho completato questa sfida", "test-output": "Il risultato del tuo test andrà qui", "running-tests": "// test in corso", @@ -280,14 +286,14 @@ "percent-complete": "{{percent}}% completato", "tried-rsa": "Se hai già provato il metodo <0>Leggi-Cerca-Chiedi, allora puoi chiedere aiuto sul forum freeCodeCamp.", "rsa": "Leggi, cerca, chiedi", + "rsa-forum": "Before making a new post please see if your question has <0>already been answered on the forum.", "reset": "Vuoi resettare questa lezione?", "reset-warn": "Sei sicuro di voler resettare questa lezione? Gli editor e i test saranno resettati.", "reset-warn-2": "Questa operazione non potrà essere annullata", "scrimba-tip": "Suggerimento: Se il mini-browser copre il codice, fare clic e trascinalo per spostarlo. Inoltre, sentiti libero di fermare e modificare il codice nel video in qualsiasi momento.", "chal-preview": "Anteprima della sfida", "cert-map-estimates": { - "certs": "Certificazione {{title}} (300 ore)", - "coding-prep": "{{title}} (migliaia di ore di sfide)" + "certs": "Certificazione {{title}}" }, "editor-tabs": { "info": "Informazioni", @@ -296,6 +302,7 @@ "restart": "Inizia da capo", "restart-step": "Ricomincia step", "console": "Console", + "instructions": "Istruzioni", "notes": "Note", "preview": "Anteprima" }, @@ -310,13 +317,14 @@ "runs-in-vm": "Il progetto esegue in una macchina virtuale, completa le user story descritte lì dentro e fai passare tutti i test per finire lo step 1.", "completed": "Completato", "not-started": "Non iniziato", - "hint": "Hint", + "hint": "Suggerimento", "test": "Test", - "sorry-try-again": "Sorry, your code does not pass. Try again.", - "sorry-keep-trying": "Sorry, your code does not pass. Keep trying.", - "sorry-getting-there": "Sorry, your code does not pass. You're getting there.", - "sorry-hang-in-there": "Sorry, your code does not pass. Hang in there.", - "sorry-dont-giveup": "Sorry, your code does not pass. Don't give up." + "sorry-try-again": "Il tuo codice non è corretto. Riprova.", + "sorry-keep-trying": "Il tuo codice non è corretto. Continua a provare.", + "sorry-getting-there": "Il tuo codice non è corretto. Ci sei quasi.", + "sorry-hang-in-there": "Il tuo codice non è corretto. Tieni duro.", + "sorry-dont-giveup": "Il tuo codice non è corretto. Non arrenderti.", + "challenges-completed": "{{completedCount}} di {{totalChallenges}} sfide completate" }, "donate": { "title": "Supporta il nostro no profit", @@ -324,7 +332,6 @@ "redirecting": "Reindirizzamento...", "thanks": "Grazie per la donazione", "thank-you": "Grazie per essere un sostenitore.", - "thank-you-2": "Grazie per essere un sostenitore di freeCodeCamp. Al momento hai una donazione ricorrente.", "additional": "Puoi effettuare una donazione una tantum aggiuntiva di qualsiasi importo utilizzando questo link: <0>{{url}}", "help-more": "Aiutaci a fare di più", "error": "Qualcosa è andato storto con la tua donazione.", @@ -443,7 +450,9 @@ "and": "e", "change-theme": "Accedi per modificare il tema.", "translation-pending": "Aiutaci a tradurlo", - "certification-project": "Progetto della certificazione" + "certification-project": "Progetto della certificazione", + "iframe-alert": "Solitamente questo link ti porterebbe su un altro sito web! Funziona. Questo è un link per {{externalLink}}", + "document-notfound": "documento non trovato" }, "icons": { "gold-cup": "Coppa d'Oro", @@ -452,8 +461,10 @@ "donate": "Dona con PayPal", "fail": "Test Fallito", "not-passed": "Non Superato", + "waiting": "Attendi", "passed": "Superato", - "hint": "Hint", + "failed": "Non corretto", + "hint": "Suggerimento", "heart": "Cuore", "initial": "Iniziale", "info": "Informazioni introduttive", @@ -474,8 +485,11 @@ "last-page": "Va all'ultima pagina", "primary-nav": "primario", "breadcrumb-nav": "percorso", - "submit": "Use Ctrl + Enter to submit.", - "running-tests": "Running tests" + "submit": "Usa Ctrl + Invio per inviare.", + "running-tests": "Test in corso", + "step": "Step", + "steps": "Step", + "steps-for": "Step per {{blockTitle}}" }, "flash": { "honest-first": "Per richiedere una certificazione, è necessario prima accettare la nostra politica di onestà accademica", @@ -681,5 +695,16 @@ "delete-p3": "Avrai bisogno di creare un nuovo token per salvare progressi futuri nelle sezioni del curriculum che usano una macchina virtuale.", "no-thanks": "No grazie, vorrei tenere il mio token", "yes-please": "Sì per favore, vorrei eliminare il mio token" + }, + "shortcuts": { + "title": "Scorciatoie da tastiera", + "table-header-action": "Azione", + "table-header-key": "Tasti", + "navigation-mode": "Modalità Di Navigazione", + "execute-challenge": "Esegui Sfida", + "focus-editor": "Focus Editor", + "focus-instructions-panel": "Focus sul pannello delle istruzioni", + "navigate-previous": "Passa all'esercizio precedente", + "navigate-next": "Passa all'esercizio successivo" } } diff --git a/client/i18n/locales/italian/trending.json b/client/i18n/locales/italian/trending.json index a74ab81bcdeb6a..68cf97c66c734d 100644 --- a/client/i18n/locales/italian/trending.json +++ b/client/i18n/locales/italian/trending.json @@ -1,62 +1,62 @@ { - "article0title": "Array di oggetti JS", - "article0link": "https://www.freecodecamp.org/italian/news/tutorial-sugli-array-di-oggetti-in-javascript/", - "article1title": "Operatore ? in JS", - "article1link": "https://www.freecodecamp.org/italian/news/operatore-punto-interrogativo-in-javascript/", - "article2title": "z-index non funziona CSS", - "article2link": "https://www.freecodecamp.org/italian/news/4-ragioni-z-index/", - "article3title": "Calcolatrice in JS", - "article3link": "https://www.freecodecamp.org/italian/news/creare-calcolatrice-con-js/", - "article4title": "Comandi SQL base", - "article4link": "https://www.freecodecamp.org/italian/news/comandi-sql-di-base-la-lista-di-query-e-istruzioni-per-database-che-dovresti-conoscere/", - "article5title": "Comandi Git base", - "article5link": "https://www.freecodecamp.org/italian/news/ecco-tutti-i-comandi-di-git-che-ho-usato-nellultima-settimana-e-cosa-fanno/", - "article6title": "Modulo % in Python", - "article6link": "https://www.freecodecamp.org/italian/news/loperatore-modulo-in-python-cosa-significa-il-simbolo/", - "article7title": "Un milione di dollari a FCC", - "article7link": "https://www.freecodecamp.org/italian/news/ffreecodecamp-ha-appena-ricevuto-una-donazione-da-un-milione-di-dollari-da-un-allunno-per-costruire-un-curriculum-web3-a-emissioni-zero/", - "article8title": "Clonare array in JS", - "article8link": "https://www.freecodecamp.org/italian/news/come-clonare-un-array-in-javascript/", - "article9title": "Sottostringhe in Python", - "article9link": "https://www.freecodecamp.org/italian/news/sottostringhe-in-python/", - "article10title": "for loop in Python", - "article10link": "https://www.freecodecamp.org/italian/news/loop-for-in-python-esempi-con-for-i-in-range/", - "article11title": "Append in Python", - "article11link": "https://www.freecodecamp.org/italian/news/append-in-python-aggiungere-elemento-a-lista/", - "article12title": "forEach in JavaScript", - "article12link": "https://www.freecodecamp.org/italian/news/foreach-in-javascript-come-iterare-su-un-array-in-js/", - "article13title": "Replace con Regex JS", - "article13link": "https://www.freecodecamp.org/italian/news/javascript-string-replace-esempio-con-regex/", - "article14title": "Esempi console.log JS", - "article14link": "https://www.freecodecamp.org/italian/news/esempio-javascript-console-log-come-stampare-sulla-console-in-js-3/", - "article15title": "Tipi di dati in statistica", - "article15link": "https://www.freecodecamp.org/italian/news/tipi-di-dati-in-statistica-dati-nominali-ordinali-di-intervallo-di-rapporto-spiegati-con-esempi/", - "article16title": "Metodo reduce JS", - "article16link": "https://www.freecodecamp.org/italian/news/una-guida-al-metodo-reduce-in-javascript//", - "article17title": "Hash Table in JS", - "article17link": "https://www.freecodecamp.org/italian/news/tabella-hash-di-javascript-hashing-di-array-associativo-in-js/", - "article18title": "map vs forEach in JS", - "article18link": "https://www.freecodecamp.org/italian/news/le-differenze-tra-map-e-foreach-che-ogni-sviluppatore-dovrebbe-conoscere/", - "article19title": "Sottostringa in Python", - "article19link": "https://www.freecodecamp.org/italian/news/come-ottenere-una-sottostringa-in-python/", - "article20title": "Conversione da 12 a 24h", - "article20link": "https://www.freecodecamp.org/italian/news/convertire-le-ore-am-pm-al-formato-24-ore/", - "article21title": "Usare API con Fetch in JS", - "article21link": "https://www.freecodecamp.org/italian/news/fetch-api-come-effettuare-una-richiesta-get-e-una-richiesta-post-in-javascript/", - "article22title": "Git Checkout branch remoto", - "article22link": "https://www.freecodecamp.org/italian/news/tutorial-su-git-checkout-di-un-branch-remoto/", - "article23title": "Guida con esempi in Python", - "article23link": "https://www.freecodecamp.org/italian/news/guida-al-codice-python-tutorial-per-principianti-con-esempi/", - "article24title": "Invertire un numero con JS", - "article24link": "https://www.freecodecamp.org/italian/news/come-invertire-un-numero-in-javascript/", - "article25title": "Crea lista vuota in Python", - "article25link": "https://www.freecodecamp.org/italian/news/tutorial-liste-vuote-in-python/", - "article26title": "Dinosauro di Google Chrome", - "article26link": "https://www.freecodecamp.org/italian/news/come-giocare-a-dinosaur-game/", - "article27title": "\"Hello, World!\" in Python", - "article27link": "https://www.freecodecamp.org/italian/news/tutorial-programma-hello-world-per-python/", - "article28title": "Andare a capo Python", - "article28link": "https://www.freecodecamp.org/italian/news/andare-a-capo-con-python/", - "article29title": "Invertire una stringa JS", - "article29link": "https://www.freecodecamp.org/italian/news/tre-modi-per-invertire-una-stringa-in-javascript/" + "article0title": "Unire CSV con Python", + "article0link": "https://www.freecodecamp.org/italian/news/come-combinare-file-multipli-in-formato-csv-con-8-righe-di-codice/", + "article1title": "Il comando Git push", + "article1link": "https://www.freecodecamp.org/italian/news/il-comando-git-push-spiegato/", + "article2title": "Centrare immagini in CSS", + "article2link": "https://www.freecodecamp.org/italian/news/come-centrare-un-immagine-usando/", + "article3title": "I codici Alt", + "article3link": "https://www.freecodecamp.org/italian/news/codici-alt/", + "article4title": "Tenere a bada il footer", + "article4link": "https://www.freecodecamp.org/italian/news/come-mantenere-il-footer-al-suo-posto/", + "article5title": "Cosa è un'API?", + "article5link": "https://www.freecodecamp.org/italian/news/cose-un-api-in-italiano-per-favore/", + "article6title": "Chiave licenza Windows10", + "article6link": "https://www.freecodecamp.org/italian/news/come-trovare-la-tua-chiave-di-licenza-di-windows-10/", + "article7title": "Live Server non funziona", + "article7link": "https://www.freecodecamp.org/italian/news/live-server-di-visual-studio-code-non-funzionante-2/", + "article8title": "Formattare in Markdown", + "article8link": "https://www.freecodecamp.org/italian/news/come-formattare-il-codice-in-markdown/", + "article9title": "Guida allo stile di fCC", + "article9link": "https://www.freecodecamp.org/italian/news/la-guida-allo-stile-di-pubblicazione-di-freecodecamp/", + "article10title": "Valori unici Python", + "article10link": "https://www.freecodecamp.org/italian/news/lista-con-valori-unici-come-ottenere-una-lista-di-valori-unici-in-python/", + "article11title": "Array.find() in JS", + "article11link": "https://www.freecodecamp.org/italian/news/tutorial-array-find-in-javascript/", + "article12title": "position in CSS", + "article12link": "https://www.freecodecamp.org/italian/news/come-usare-la-proprieta-position-in-css-per-allineare-elementi/", + "article13title": "Destrutturazione in JS", + "article13link": "https://www.freecodecamp.org/italian/news/destrutturazione-in-javascript-come-destrutturare-array-e-oggetti/", + "article14title": ".length in JS", + "article14link": "https://www.freecodecamp.org/italian/news/verificare-se-un-array-javascrit-e-vuoto/", + "article15title": "Boilerplate HTML5", + "article15link": "https://www.freecodecamp.org/italian/news/template-base-html5/", + "article16title": "Manuale JS", + "article16link": "https://www.freecodecamp.org/italian/news/manuale-javascript-per-principianti-edizione-2020/", + "article17title": "Git e GitHub", + "article17link": "https://www.freecodecamp.org/italian/news/come-usare-git-e-github-in-un-team-come-un-professionista-con-la-partecipazione-di-harry-e-hermione/", + "article18title": "Cos'è about:blank", + "article18link": "https://www.freecodecamp.org/italian/news/cosa-e-about-blank-e-come-liberartene/", + "article19title": "LS in Linux", + "article19link": "https://www.freecodecamp.org/italian/news/il-comando-ls-in-linux-come-elencare-file-e-cartelle-le-flag-di-opzione/", + "article20title": "Immagine di sfondo REACT", + "article20link": "https://www.freecodecamp.org/italian/news/come-impostare-una-immagine-di-background-in-react-usando-il-css-in-linea/", + "article21title": "Vim su Windows in PowerShell", + "article21link": "https://www.freecodecamp.org/italian/news/vim-guida-di-installazione-su-windows-come-eseguire-leditor-di-testo-vim-in-powershell-sul-tuo-pc/", + "article22title": "Processi Child di Node.js", + "article22link": "https://www.freecodecamp.org/italian/news/processi-child-di-node-js-tutto-cio-che-devi-sapere/", + "article23title": "Algoritmi di forza bruta", + "article23link": "https://www.freecodecamp.org/italian/news/algoritmi-di-forza-bruta/", + "article24title": "@property in Python", + "article24link": "https://www.freecodecamp.org/italian/news/il-decoratore-property-in-python-utilizzo-vantaggi-e-sintassi/", + "article25title": "L'algoritmo di Dijkstra", + "article25link": "https://www.freecodecamp.org/italian/news/lalgoritmo-dei-cammini-minimi-di-dijkstra-una-dettagliata-introduzione-grafica/", + "article26title": "Come annullare un Git Add", + "article26link": "https://www.freecodecamp.org/italian/news/come-annullare-un-git-add/", + "article27title": "Ripristinare schede su Chrome", + "article27link": "https://www.freecodecamp.org/italian/news/come-ripristinare-schede-su-chrome/", + "article28title": "Link nuova scheda in HTML", + "article28link": "https://www.freecodecamp.org/italian/news/html-per-aprire-un-link-in-una-nuova-scheda/", + "article29title": "Eliminare un branch di Git", + "article29link": "https://www.freecodecamp.org/italian/news/eliminare-branch-git-locale-e-remoto/" } diff --git a/client/i18n/locales/japanese/intro.json b/client/i18n/locales/japanese/intro.json index 2a93080edb3694..208bbab8acd585 100644 --- a/client/i18n/locales/japanese/intro.json +++ b/client/i18n/locales/japanese/intro.json @@ -1,6 +1,6 @@ { "responsive-web-design": { - "title": "レスポンシブウェブデザイン (レガシー)", + "title": "(レガシー) レスポンシブウェブデザイン", "intro": [ "このレスポンシブウェブデザイン認定講座では、開発者がウェブページを構築するために使用する言語について学びます。コンテンツには HTML (Hypertext Markup Language)、デザインには CSS (Cascading Style Sheets) を使用します。", "初めに、HTML と CSS の基礎を学ぶために、猫の写真アプリを作ります。その後、ペンギンの絵を作りながら CSS 変数等のモダンなテクニックを学びます。そしてウェブフォームを作りながらアクセシビリティのベストプラクティスを学びます。", @@ -32,7 +32,7 @@ "applied-accessibility": { "title": "応用アクセシビリティ", "intro": [ - "ウェブ開発におけるアクセシビリティとは、幅広いユーザーが理解し、移動し、対話できるコンテンツやUI (ユーザーインターフェース) のことを指します。これには視覚、聴覚、運動、認知に障害がある人も含みます。", + "ウェブ開発におけるアクセシビリティとは、幅広いユーザーが理解し、移動し、対話できるコンテンツや UI (ユーザーインターフェース) のことを指します。これには視覚、聴覚、運動、認知に障害がある人も含みます。", "このコースでは、誰もがアクセス可能な Web ページを構築するためのベストプラクティスを学びます。" ] }, @@ -67,11 +67,11 @@ } }, "2022/responsive-web-design": { - "title": "(New) Responsive Web Design", + "title": "(新) レスポンシブウェブデザイン", "intro": [ "このレスポンシブウェブデザイン認定講座では、開発者がウェブページを構築するために使用する言語について学びます。コンテンツには HTML (Hypertext Markup Language)、デザインには CSS (Cascading Style Sheets) を使用します。", - "初めに、HTML と CSS の基礎を学ぶために、猫の写真アプリを作ります。その後、ペンギンの絵を作りながら CSS 変数等のモダンなテクニックを学びます。そしてウェブフォームを作りながらアクセシビリティのベストプラクティスを学びます。", - "最後に、Flexbox を使った Twitter カードや CSS グリッドを使った複雑なブログレイアウトの作成を通じて、さまざまな画面サイズに応答するウェブページを作成する方法を学びます。" + "初めに、HTML と CSS の基礎を学ぶために、猫の写真アプリを作ります。その後、ペンギンの絵を作りながら CSS 変数等のモダンなテクニックを学びます。そしてクイズサイトを作りながらアクセシビリティのベストプラクティスを学びます。", + "最後に、フレックスボックスを使ったフォトギャラリーや、CSS グリッドを使った雑誌記事のレイアウトの作成を通じて、さまざまな画面サイズに応じて表示されるウェブページの作成方法を学びます。" ], "note": "注意: 広告ブロッカーやダークモード拡張などの、一部のブラウザ拡張機能がテストに干渉する可能性があります。問題が発生した場合、コース受講中はページのコンテンツやレイアウトを変更する拡張機能を無効にすることをお勧めします。", "blocks": { @@ -128,14 +128,14 @@ "title": "CSS ボックスモデルの学習: ロスコの絵画を作成する", "intro": [ "すべての HTML 要素は間隔と境界を伴ったボックスそのものです。これはボックスモデルと呼ばれています。", - "このコースでは、CSS とボックスモデルを使ってロスコ風の長方形アート作品を作成します。" + "このコースでは、CSS とボックスモデルを使ってマーク・ロスコ風の長方形アート作品を作成します。" ] }, "learn-css-variables-by-building-a-city-skyline": { "title": "CSS 変数の学習: 都市のスカイラインを作成する", "intro": [ - "CSS の変数はスタイルを体系づけたり、それらを再利用するのに役立ちます。", - "このコースでは、都市のスカイラインを作成します。CSS の変数の設定方法を学習して、使いたい時にいつでもそれらを再利用できるようにします。" + "CSS の変数はスタイルを体系づけたり、再利用するのに役立ちます。", + "このコースでは、都市のスカイラインの風景を作成します。CSS 変数の設定方法を学習して、必要に応じて再利用できるようにします。" ] }, "learn-html-forms-by-building-a-registration-form": { @@ -149,7 +149,7 @@ "title": "アクセシビリティの学習: クイズを作成する", "intro": [ "アクセシビリティとは、障害のある人を含むすべての人々にとって、ウェブページを利用しやすくすることです。", - "このコースでは、クイズのウェブページを作成します。キーボードショートカット、ARIA 属性、デザインのベストプラクティスなど、アクセシビリティのツールについて学習します。" + "このコースでは、クイズ (小テスト) のウェブページを作成します。キーボードショートカット、ARIA 属性、デザインのベストプラクティスなど、アクセシビリティのツールについて学習します。" ] }, "learn-intermediate-css-by-building-a-picasso-painting": { @@ -180,10 +180,10 @@ ] }, "learn-typography-by-building-a-nutrition-label": { - "title": "タイポグラフィの学習: 栄養ラベルを作成する", + "title": "タイポグラフィの学習: 栄養成分表示ラベルを作成する", "intro": [ - "タイポグラフィはテキストを読み易く、また目的に合うようにスタイリングする技術です。", - "このコースでは、タイポグラフィを用いて栄養ラベルのウェブページを作成します。CSS を用いてテキストを整え、行の高さを調節し、テキストを配置することを学習します。" + "タイポグラフィとは、テキストを読み易く、また目的に合うようにスタイリングする技術です。", + "このコースでは、タイポグラフィを用いて栄養成分表示ラベルのウェブページを作成します。CSS を用いてテキストを整え、行の高さを調節し、テキストを配置することを学習します。" ] }, "learn-css-transforms-by-building-a-penguin": { @@ -201,10 +201,10 @@ ] }, "learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet": { - "title": "CSS 疑似セレクターの学習: 貸借対照表を作成する", + "title": "CSS 疑似セレクターの学習: バランスシートを作成する", "intro": [ "CSS の疑似セレクターを用いて、特定の HTML 要素を変化させることができます。", - "このコースでは、疑似セレクターを用いて貸借対照表を作成します。ウェブページ上でマウスポインタを要素の上に合わせた時に要素のスタイルを変更する方法や、他のイベントを起こす方法を学習します。" + "このコースでは、疑似セレクターを用いてバランスシート (貸借対照表) を作成します。ウェブページ上でマウスポインタを要素の上に合わせた時に要素のスタイルを変更する方法や、他のイベントを起こす方法を学習します。" ] }, "learn-css-colors-by-building-a-set-of-colored-markers": { @@ -300,64 +300,64 @@ } }, "2022/javascript-algorithms-and-data-structures": { - "title": "JavaScript Algorithms and Data Structures (Beta)", + "title": "JavaScript アルゴリズムとデータ構造 (ベータ版)", "intro": [ - "placeholder", - "placeholder" + "プレイスホルダー", + "プレイスホルダー" ], "note": "", "blocks": { "build-a-caesars-cipher-project": { - "title": "Build a Casears Cipher Project", + "title": "シーザー暗号解析器作成プロジェクト", "intro": [ "", "" ] }, "build-a-cash-register-project": { - "title": "Build a Cash Register Project", + "title": "キャッシュレジスター作成プロジェクト", "intro": [ "", "" ] }, "build-a-palindrome-checker-project": { - "title": "Build a Palindrome Checker Project", + "title": "回文チェッカー作成プロジェクト", "intro": [ "", "" ] }, "build-a-roman-numeral-converter-project": { - "title": "Build a Roman Numeral Converter Project", + "title": "ローマ数字コンバーター作成プロジェクト", "intro": [ "", "" ] }, "build-a-telephone-number-validator-project": { - "title": "Build a Telephone Number Validator Project", + "title": "電話番号バリデーター作成プロジェクト", "intro": [ "", "" ] }, "learn-basic-javascript-by-building-a-role-playing-game": { - "title": "Learn Basic JavaScript by Building a Role Playing Game", + "title": "JavaScript の基礎の学習: ロールプレイングゲームを作る", "intro": [ "", "" ] }, "learn-form-validation-by-building-a-calorie-counter": { - "title": "Learn Form Validation by Building a Calorie Counter", + "title": "フォームの検証の学習: カロリー計算機を作る", "intro": [ "", "" ] }, "learn-functional-programming-by-building-a-spreadsheet": { - "title": "Learn Functional Programming by Building a Spreadsheet", + "title": "関数型プログラミングの学習: スプレッドシートを作る", "intro": [ "", "" @@ -606,8 +606,8 @@ "mongodb-and-mongoose": { "title": "MongoDB と Mongoose", "intro": [ - "MongoDB はアプリケーションで使用できる JSON ドキュメント (またはレコード) を保管するデータベースアプリケーションです。別の種類のデータベースである SQL とは異なり、Mongo は非リレーショナル、または \"NoSQL\" データベースです。これは、SQL データベースがあらかじめ定義した多くのテーブルにデータを保管するのと異なり、Mongo はすべての関連データを一つのレコードの中に保管することを意味します。", - "Mongoose は、よく Mongo と一緒にインストールされる一般的な npm パッケージです。Mongoose を使用することで、JSON ではなく素の JavaScript オブジェクトを使用することができるようになり、Mongo が使いやすくなります。また、スキーマと呼ばれるドキュメントの設計図を作成することを可能にし、間違った型のデータを保存してしまい後にバグを発生させることを防ぎます。", + "MongoDB はアプリケーションで使用できる JSON ドキュメント (またはレコード) を保管するデータベースアプリケーションです。別の種類のデータベースである SQL とは異なり、MongoDB は非リレーショナル、または \"NoSQL\" データベースです。これは、SQL データベースがあらかじめ定義した多くのテーブルにデータを保管するのと異なり、MongoDB はすべての関連データを一つのレコードの中に保管することを意味します。", + "Mongoose は MongoDB とやり取りするためによく使われる npm パッケージです。Mongoose を利用することで、JSON ではなく素の JavaScript オブジェクトを使用できるようになり、MongoDB が使いやすくなります。また、スキーマと呼ばれるドキュメントの設計図を作成することを可能にし、間違った型のデータを保存してしまい後にバグを発生させることを防ぎます。", "MongoDB と Mongoose コースでは、モデルを設定する方法や、データベース内のドキュメントを保存、削除、検索する方法など、永続的なデータを扱うことの基本を学習します。" ] }, @@ -804,7 +804,8 @@ "title": "ロゼッタコード", "intro": [ "由緒あるロゼッタコードライブラリから取られた以下の無料のプログラミングタスクで、クリエイティブな課題解決技能を向上させましょう。", - "これらの課題は困難かもしれませんが、あなたのアルゴリズムのロジックを新たな高みに押し上げます。" + "これらの課題は困難かもしれませんが、あなたのアルゴリズムのロジックを新たな高みに押し上げます。", + "作: Rosetta Code" ] }, "project-euler": { diff --git a/client/i18n/locales/japanese/links.json b/client/i18n/locales/japanese/links.json index b48130a30582a9..653e921affb71f 100644 --- a/client/i18n/locales/japanese/links.json +++ b/client/i18n/locales/japanese/links.json @@ -26,6 +26,6 @@ "HTML-CSS": "Japanese/HTML-CSS", "JavaScript": "Japanese/JavaScript", "Python": "Japanese/Python", - "Relational Databases": "Japanese/Relational Databases" + "Backend Development": "Japanese/programming-help" } } diff --git a/client/i18n/locales/japanese/meta-tags.json b/client/i18n/locales/japanese/meta-tags.json index 281848e60e959c..b96a2590d23234 100644 --- a/client/i18n/locales/japanese/meta-tags.json +++ b/client/i18n/locales/japanese/meta-tags.json @@ -1,5 +1,5 @@ { - "title": "プログラミングを無料で学ぶ: 多忙な人々のためのプログラミング講座", + "title": "プログラミングを無料で学ぶ: 働きながら学べるプログラミング講座", "description": "プログラミングを無料で学ぶ", "social-description": "プログラミングを無料で学ぶ", "keywords": [ @@ -37,5 +37,5 @@ "プログラミング", "学習" ], - "youre-unsubscribed": "You have been unsubscribed" + "youre-unsubscribed": "購読を解除しました" } diff --git a/client/i18n/locales/japanese/translations.json b/client/i18n/locales/japanese/translations.json index aeb6e96c3bd39b..e881cc4814090c 100644 --- a/client/i18n/locales/japanese/translations.json +++ b/client/i18n/locales/japanese/translations.json @@ -50,7 +50,8 @@ "reset-lesson": "レッスンをリセット", "run": "実行", "run-test": "テスト実行 (Ctrl + Enter)", - "check-code": "Check Your Code (Ctrl + Enter)", + "check-code": "コードをチェック (Ctrl + Enter)", + "check-code-2": "コードをチェック", "reset": "リセット", "reset-code": "全てのコードをリセット", "help": "ヘルプ", @@ -70,7 +71,11 @@ "start-coding": "コーディングを始めましょう!", "go-to-settings": "設定へ移動して認定証を取得", "click-start-course": "コースを開始", - "click-start-project": "プロジェクトを開始" + "click-start-project": "プロジェクトを開始", + "change-language": "言語変更", + "cancel-change": "変更キャンセル", + "resume-project": "プロジェクト再開", + "start-project": "プロジェクト開始" }, "landing": { "big-heading-1": "プログラミングを無料で学ぶ。", @@ -101,9 +106,9 @@ }, "settings": { "share-projects": "あなたの freeCodeCamp 以外のプロジェクトや記事、承認されたプルリクエストをシェアしましょう。", - "privacy": "The settings in this section enable you to control what is shown on your freeCodeCamp public portfolio. Press save to save your changes.", + "privacy": "この設定セクションでは、あなたの freeCodeCamp 公開ポートフォリオに表示する項目を制御できます。変更を保存するには「保存」をクリックしてください。", "data": "アカウントに保存されているデータを確認するには、下の「データをダウンロード」ボタンをクリックしてください", - "disabled": "プライベートに設定されている場合、認定証は無効化されます。", + "disabled": "非公開に設定されている場合、認定証は無効化されます。", "private-name": "非公開に設定されている場合、あなたの名前は認定証に表示されません。", "claim-legacy": "以下の freeCodeCamp 認定証を取得すると、 {{cert}} を受け取ることができます。", "for": "{{username}} さんのアカウント設定", @@ -143,7 +148,8 @@ "my-timeline": "自分のタイムライン", "my-donations": "自分の寄付", "night-mode": "ナイトモード", - "sound-mode": "キャンプファイアモード" + "sound-mode": "キャンプファイアモード", + "keyboard-shortcuts": "キーボードショートカットを有効にする" }, "headings": { "certs": "認定証", @@ -269,7 +275,7 @@ "solution-link": "回答のリンク", "github-link": "GitHub のリンク", "submit-and-go": "提出して次のチャレンジに進む", - "congradulations": "Congratulations, your code passes. Submit your code to complete this step and move on to the next one.", + "congratulations": "おめでとうございます、合格です。次に進むにはコードを提出してください。", "i-completed": "このチャレンジを完了しました", "test-output": "テストの結果はこちらに表示されます", "running-tests": "// テストを実行中です", @@ -280,14 +286,14 @@ "percent-complete": "{{percent}}% 完了", "tried-rsa": "すでに <0>Read-Search-Ask (読む - 検索する - 質問する) メソッドを試したなら、freeCodeCamp フォーラムで助けを求めることができます。", "rsa": "読む (Read)、検索する (Search)、質問する (Ask)", + "rsa-forum": "Before making a new post please see if your question has <0>already been answered on the forum.", "reset": "このレッスンをリセットしますか?", "reset-warn": "本当にこのレッスンをリセットしてもよろしいですか?エディターとテストがリセットされます。", "reset-warn-2": "この操作は取り消すことが出来ません", "scrimba-tip": "ヒント: ミニブラウザがコードを覆ってしまう場合は、クリックとドラッグで移動させてください。また、いつでも遠慮なくビデオを停止させてコードを編集してください。", "chal-preview": "チャレンジのプレビュー", "cert-map-estimates": { - "certs": "{{title}} 認定講座 (300 時間)", - "coding-prep": "{{title}} (数千時間のチャレンジ)" + "certs": "{{title}} 認定講座" }, "editor-tabs": { "info": "詳細", @@ -296,49 +302,50 @@ "restart": "リスタート", "restart-step": "ステップをリスタート", "console": "コンソール", + "instructions": "手順書", "notes": "ノート", "preview": "プレビュー" }, "help-translate": "以下の認定講座は現在翻訳中です。", "help-translate-link": "翻訳にご協力ください。", - "project-preview-title": "これがあなたが作成するもののプレビューです。", + "project-preview-title": "これが今から作る物のプレビューです。", "github-required": "<0>GitHub アカウントをお持ちでない場合は作成してください。 仮想 Linux サーバーマシンを作成する際に必要です。この処理には数分かかることがあります。", "step-1": "ステップ 1: プロジェクトを完成させる", "step-2": "ステップ 2: コードを提出する", "submit-public-url": "プロジェクトが完成したら、必須のファイルをすべてパブリックリポジトリに保存し、リポジトリの URL を以下に提出してください。", "complete-both-steps": "チャレンジを終えるには、以下 2 つのステップを完了させてください。", "runs-in-vm": "このプロジェクトは仮想マシン内で動作します。ステップ 1 を完了するには、そこで述べられたユーザーストーリーを実装し、すべてのテストに合格してください。", - "completed": "Completed", + "completed": "完了", "not-started": "未着手", - "hint": "Hint", - "test": "Test", - "sorry-try-again": "Sorry, your code does not pass. Try again.", - "sorry-keep-trying": "Sorry, your code does not pass. Keep trying.", - "sorry-getting-there": "Sorry, your code does not pass. You're getting there.", - "sorry-hang-in-there": "Sorry, your code does not pass. Hang in there.", - "sorry-dont-giveup": "Sorry, your code does not pass. Don't give up." + "hint": "ヒント", + "test": "テスト", + "sorry-try-again": "残念ながら、テストが通りませんでした。もう一度挑戦しましょう。", + "sorry-keep-trying": "残念ながら、テストが通りませんでした。続けて挑戦しましょう。", + "sorry-getting-there": "残念ながら、テストが通りませんでした。もう一息です。", + "sorry-hang-in-there": "残念ながら、テストが通りませんでした。がんばりましょう。", + "sorry-dont-giveup": "残念ながら、テストが通りませんでした。諦めないでください。", + "challenges-completed": "{{totalChallenges}} 件中 {{completedCount}} 件完了" }, "donate": { "title": "非営利団体を支援する", - "processing": "いただいたご寄付を処理中です。", + "processing": "いただいた寄付を処理中です。", "redirecting": "リダイレクト中...", - "thanks": "ご寄付ありがとうございます", + "thanks": "寄付ありがとうございます", "thank-you": "サポーターとなっていただき、ありがとうございます。", - "thank-you-2": "freeCodeCamp のサポーターとなっていただき、ありがとうございます。現在定期的なご寄付をいただいております。", "additional": "任意の金額を、追加で 1 回ずつご寄付いただけるリンクはこちら: <0>{{url}}", "help-more": "私たちのさらなる活動をご支援ください", - "error": "ご寄付の処理に問題が発生しました。", + "error": "寄付の処理に問題が発生しました。", "error-2": "問題が発生しました。donors@freecodecamp.org までお問い合わせください。", "free-tech": "いただいたご寄付は世界中の人々への無料の技術教育を支援します。", "no-halo": "プロフィール画像の周りに金色の枠が表示されない場合は、donors@freecodecamp.org までご連絡ください。", "gift-frequency": "ギフトの頻度を選択する:", "gift-amount": "ギフトの金額を選択する:", - "confirm": "ご寄付の確認", - "confirm-2": "${{usd}} の一回のご寄付を確認する", - "confirm-3": "毎月${{usd}} のご寄付を確認する", - "confirm-4": "毎年${{usd}} のご寄付を確認する", - "wallet-label": "freeCodeCamp へ${{usd}} を寄付する", - "wallet-label-1": "freeCodeCamp へ毎月${{usd}} を寄付する", + "confirm": "寄付の申込み", + "confirm-2": "{{usd}} ドルの一回の寄付の申込み", + "confirm-3": "毎月 {{usd}} ドルの寄付の申込み", + "confirm-4": "毎年 {{usd}} ドルの寄付の申込み", + "wallet-label": "freeCodeCamp への ${{usd}} の寄付", + "wallet-label-1": "freeCodeCamp への ${{usd}} / 月の寄付", "your-donation": "あなたの {{usd}} ドルのご寄付が、世界中の人々に {{hours}} 時間の学びを提供します。", "your-donation-2": "あなたの {{usd}} ドルのご寄付が、世界中の人々に {{hours}} 時間の学びを毎月提供します。", "your-donation-3": "あなたの {{usd}} ドルのご寄付が、世界中の人々に {{hours}} 時間の学びを毎年提供します。", @@ -352,17 +359,17 @@ "or-card": "またはカードで寄付する", "paypal": "PayPalで寄付する:", "need-email": "贈与税の領収書をお送りできる有効なメールアドレスが必要です。", - "went-wrong": "ご寄付の処理中に問題が発生しました。カードへの請求は行われておりません。", + "went-wrong": "寄付の処理中に問題が発生しました。カードへの請求は行われておりません。", "valid-info": "有効なメールアドレス、クレジットカード番号、有効期限を入力してください。", "valid-email": "有効なメールアドレスを入力してください。", "valid-card": "有効なクレジットカード番号、有効期限を入力してください。", - "email-receipt": "Eメール (税控除可能な場合があるご寄付の領収書をお送りいたします):", - "need-help": "現在または過去のご寄付についてお困りでしょうか?", - "forward-receipt": "ご寄付の領収書のコピーを添えて、お問い合わせ内容を donors@freecodecamp.org までお送りください。", + "email-receipt": "Eメール (寄付の領収書をお送りいたします。税控除可能な場合がございます。):", + "need-help": "現在または過去の寄付についてお困りでしょうか?", + "forward-receipt": "寄付の領収書のコピーを添えて、お問い合わせ内容を donors@freecodecamp.org までお送りください。", "efficiency": "freeCodeCamp は非常に効率的な、教育分野の非営利団体です。", "why-donate-1": "freeCodeCamp にご寄付いただくことにより、新しい技能を学習して家族を支えようとしている人々を助けることに繋がります。", "why-donate-2": "また、あなた自身の技術スキルを高めるための、学習リソースの作成を支援することにもなります。", - "bigger-donation": "より多くの金額による一回のご寄付や、小切手の送付、または他の方法をお考えでしょうか?", + "bigger-donation": "より多くの金額による一回の寄付や、小切手の送付、または他の方法をお考えでしょうか?", "other-ways": "<0>当非営利団体の使命をご支援いただける方法 は他にも多数ございます。", "failed-pay": "処理が完了しませんでした。再度お試しください。", "try-again": "再試行してください。", @@ -370,7 +377,7 @@ "expiration": "有効期限:", "secure-donation": "セキュアな寄付", "faq": "よくある質問", - "only-you": "このメッセージはあなただけに表示されています。認定証の獲得おめでとうございます。簡単な課題ではなかったことと思います。freeCodeCamp を運営することもまた、簡単ではありません。費用のかからないことでもありません。ぜひ、私たちがあなたを含む世界中の人々のお役に立てるようご支援ください。当非営利団体へのご寄付をお願い申し上げます。(ご寄付は税控除可能な場合がございます。)", + "only-you": "このメッセージはあなただけに表示されています。認定証の獲得おめでとうございます。簡単な課題ではなかったことと思います。freeCodeCamp を運営することもまた、簡単ではありません。費用のかからないことでもありません。ぜひ、私たちがあなたを含む世界中の人々のお役に立てるようご支援ください。当非営利団体へのご寄付をお願い申し上げます。(場合により税控除可能)", "get-help": "寄付に関してサポートが必要な場合はどうしたらいいですか?", "how-transparent": "freeCodeCamp.org の透明性はどのような状態ですか?", "very-transparent": "極めて高いと評価されています。私たちは GuideStar.org より、プラチナグレードの透明性評価を受けています。", @@ -380,7 +387,7 @@ "fcc-budget": "freeCodeCamp の予算は、ほとんどの同規模の非営利団体と比べ非常に少ないです。私たちはプロの資金調達者に参加を依頼していません。代わりに、Quincy が自分自身ですべてを行っています。", "help-millions": "しかしながら、私たちは年間わずか数十万ドルの予算で、数百万の人々を支援することができています。", "how-one-time": "一回ごとの寄付を行うにはどうしたらいいですか?", - "one-time": "一回ごとのご寄付をご希望の場合、いつでも経済的なゆとりがある時に、freeCodeCamp のミッションをご支援いただくことができます。<0>こちらのリンクから、PayPal を通して任意の金額を寄付することができます。", + "one-time": "一回ごとの寄付をご希望の場合、いつでも経済的なゆとりがある時に、freeCodeCamp のミッションをご支援いただくことができます。<0>こちらのリンクから、PayPal を通して任意の金額を寄付することができます。", "wire-transfer": "電信送金で直接 freeCodeCamp へ送金することも可能です。電信送金の詳細が必要な場合、Quincy (quincy@freecodecamp.org) までメールにてご連絡ください。", "does-crypto": "freeCodeCamp では Bitcoin などの暗号通貨での寄付を受け付けていますか?", "yes-cryptocurrency": "はい。Quincy 宛てに quincy@freecodecamp.org までメールでお問い合わせいただければ、freeCodeCamp のウォレット情報をお知らせいたします。税金の手続きのため寄付金の領収書をご希望の場合も、Quincy にて対応いたします。", @@ -393,12 +400,12 @@ "how-endowment": "freeCodeCamp.org のために基金を設立するにはどうしたらいいですか?", "endowment": "これは大変心強い支援となります。多くの手作業による処理が必要になりますので、Quincy から個人的にご説明いたします。quincy@freecodecamp.org まで直接メールにてご連絡ください。", "how-legacy": "freeCodeCamp.org へ遺贈寄付するにはどうしたらいいですか?", - "we-honored": "世界中の人々のコード学習支援のために、そのようなご寄付を活用させていただけることを光栄に思います。 また、お住まいの場所によっては非課税となる場合もございます。", + "we-honored": "世界中の人々のコード学習支援のために、そのような寄付を活用させていただけることを光栄に思います。また、お住まいの場所によっては非課税となる場合もございます。", "legacy-gift-message": "私は [合計 _____ USD (または他の通貨) または私の残余財産の _____ パーセント] を、現所在地が 3905 Hedgcoxe Rd, PO Box 250352, Plano, Texas, 75025 United States である、アメリカ合衆国デラウェア州の法律に基づき組織された公益法人 freeCodeCamp.org (Free Code Camp, Inc. 納税者番号 82-0779546) へ、法人自身の裁量による一般的な慈善目的の使用の為に、寄付、遺贈します。", "thank-wikimedia": "この正式な文面を私たちに提供して下さったウィキメディア財団に感謝申し上げます。", "legacy-gift-questions": "この手順に関するお問い合わせにつきましては、Quincy 宛てに quincy@freecodecamp.org までメールにてご連絡ください。", "how-stock": "株式を freeCodeCamp.org に寄付するにはどうしたらいいですか?", - "welcome-stock": "株式による寄付も歓迎しております。Quincy 宛てに quincy@freecodecamp.org まで直接メールにてご連絡いただければ、当非営利団体の証券口座の詳細も含めご説明させていただきます。", + "welcome-stock": "株式による寄付も歓迎しております。Quincy 宛てに quincy@freecodecamp.org まで直接メールにてご連絡いただければ、当非営利団体の証券口座の詳細も含めご説明いたします。", "how-receipt": "税金から寄付金を控除するために、寄付金の領収書を受け取ることはできますか?", "just-forward": "もちろんです。取引時の領収書を donors@freecodecamp.org まで転送し、領収書を必要とされている旨と、その他特別なご指示がございましたらその点も併せてご連絡ください。領収書を添えて返信いたします。", "how-update": "毎月の寄付を設定しましたが、月次の処理を変更または停止したいです。どうしたらいいですか?", @@ -423,7 +430,7 @@ }, "search": { "label": "検索", - "placeholder": "8,000 以上のチュートリアルを検索", + "placeholder": "チュートリアルを検索", "see-results": "{{searchQuery}} のすべての結果を見る", "no-tutorials": "チュートリアルは見つかりませんでした", "try": "何かお探しですか?このページの検索バーを試してみてください。", @@ -443,7 +450,9 @@ "and": "および", "change-theme": "テーマを変更するにはサインインしてください。", "translation-pending": "翻訳にご協力ください。", - "certification-project": "認定プロジェクト" + "certification-project": "認定プロジェクト", + "iframe-alert": "このリンクは通常の環境では他のウェブサイトを開きます。正しく動作しています。これは {{externalLink}} へのリンクです。", + "document-notfound": "ドキュメントが見つかりませんでした" }, "icons": { "gold-cup": "ゴールドカップ", @@ -452,8 +461,10 @@ "donate": "PayPal で寄付する", "fail": "テスト失敗", "not-passed": "未完了", - "passed": "合格済み", - "hint": "Hint", + "waiting": "待機中", + "passed": "完了", + "failed": "失敗", + "hint": "ヒント", "heart": "ハート", "initial": "初期状態", "info": "導入情報", @@ -474,8 +485,11 @@ "last-page": "最後のページへ移動", "primary-nav": "プライマリー", "breadcrumb-nav": "パンくずリスト", - "submit": "Use Ctrl + Enter to submit.", - "running-tests": "Running tests" + "submit": "提出するには Ctrl + Enter を押してください。", + "running-tests": "テスト実行中", + "step": "ステップ", + "steps": "ステップ一覧", + "steps-for": "「{{blockTitle}}」のステップ一覧" }, "flash": { "honest-first": "認定証を請求するには、まず学問的誠実性ポリシーに同意する必要があります。", @@ -681,5 +695,16 @@ "delete-p3": "仮想マシンを使用するカリキュラムセクションでこの先の進行状況を保存するには、新しいトークンを作成する必要があります。", "no-thanks": "いいえ、トークンを維持したいです", "yes-please": "はい、トークンを削除します" + }, + "shortcuts": { + "title": "キーボードショートカット", + "table-header-action": "操作", + "table-header-key": "キー", + "navigation-mode": "ナビゲーションモード", + "execute-challenge": "チャレンジを実行", + "focus-editor": "エディターにフォーカス", + "focus-instructions-panel": "手順書パネルにフォーカス", + "navigate-previous": "前の課題へ移動", + "navigate-next": "次の課題へ移動" } } diff --git a/client/i18n/locales/portuguese/intro.json b/client/i18n/locales/portuguese/intro.json index 5a945f67162273..f1e1d78f8f7666 100644 --- a/client/i18n/locales/portuguese/intro.json +++ b/client/i18n/locales/portuguese/intro.json @@ -70,8 +70,8 @@ "title": "Design responsivo para a web (novo)", "intro": [ "Nessa certificação de Design responsivo para a web, você aprenderá as linguagens que os desenvolvedores usam para construir sites: HTML (Linguagem de Marcação de Hipertexto) para o conteúdo e CSS (Folha de Estilo em Cascata) para o design.", - "Primeiro, você vai construir um aplicativo de fotos de gato para aprender o básico de HTML e CSS. Mais tarde, você aprenderá técnicas modernas como variáveis CSS construindo um pinguim, e melhores práticas de acessibilidade criando um formulário web.", - "Finalmente, você vai aprender a fazer páginas web que respondem a diferentes tamanhos de telas construindo um card do Twitter com Flexbox, e um layout complexo de blog com o CSS Grid." + "Primeiro, você vai construir um aplicativo de fotos de gato para aprender o básico de HTML e CSS. Mais tarde, você aprenderá técnicas modernas como variáveis CSS construindo um pinguim, e melhores práticas de acessibilidade criando um site de questionário.", + "Finalmente, você vai aprender a fazer páginas web que respondem a diferentes tamanhos de telas construindo uma galeria de fotos com o Flexbox, e um layout de artigo de revista com o CSS Grid." ], "note": "Observação: algumas extensões de navegador, como bloqueadores de anúncios e extensões de modo escuro podem interferir nos testes. Se você tiver problemas, recomendamos desabilitar extensões que modifiquem o conteúdo ou o layout das páginas durante o curso.", "blocks": { @@ -606,8 +606,8 @@ "mongodb-and-mongoose": { "title": "MongoDB e Mongoose", "intro": [ - "O MongoDB é uma aplicação de banco de dados que armazena documentos JSON (ou registros) que podem ser usados em sua aplicação. Ao contrário do SQL, outro tipo de banco de dados, o Mongo é um banco de dados não relacional ou \"NoSQL\". Isto significa que o Mongo armazena todos os dados associados dentro de um registro, em vez de armazená-los em muitas tabelas predefinidas, como em um banco de dados SQL.", - "O Mongoose é um pacote popular do npm que é frequentemente instalado junto com MongoDB. Com o Mongoose, você pode usar objetos JavaScript simples em vez de JSON, o que torna mais fácil trabalhar com o Mongo. Além disso, ele permite que você crie projetos para seus documentos, chamados schemas, para que você não salve acidentalmente o tipo errado de dados e cause bugs mais tarde.", + "O MongoDB é uma aplicação de banco de dados que armazena documentos JSON (ou registros) que podem ser usados em sua aplicação. Ao contrário do SQL, outro tipo de banco de dados, o MongoDB é um banco de dados não relacional ou \"NoSQL\". Isto significa que o MongoDB armazena todos os dados associados dentro de um registro, em vez de armazená-los em muitas tabelas predefinidas, como em um banco de dados SQL.", + "O Mongoose é um pacote popular do npm para a interação com o MongoDB. Com o Mongoose, você pode usar objetos JavaScript simples em vez de JSON, o que torna mais fácil trabalhar com o MongoDB. Além disso, ele permite que você crie projetos para seus documentos, chamados schemas, para que você não salve acidentalmente o tipo errado de dados e cause bugs mais tarde.", "Nos cursos de MongoDB e Mongoose, você aprenderá os fundamentos de trabalhar com dados persistentes, incluindo como configurar um modelo, salvar, excluir e buscar documentos no banco de dados." ] }, @@ -804,7 +804,8 @@ "title": "Rosetta Code", "intro": [ "Aumente o nível de suas habilidades criativas de resolução de problemas com essas tarefas de programação gratuitas da biblioteca clássica do Rosetta Code.", - "Esses desafios podem ser difíceis, mas levarão sua lógica de algoritmos a novos patamares." + "Esses desafios podem ser difíceis, mas levarão sua lógica de algoritmos a novos patamares.", + "Attribute: Rosetta Code" ] }, "project-euler": { diff --git a/client/i18n/locales/portuguese/links.json b/client/i18n/locales/portuguese/links.json index 8672bd3bca512c..4fe3a2f5b325cc 100644 --- a/client/i18n/locales/portuguese/links.json +++ b/client/i18n/locales/portuguese/links.json @@ -13,7 +13,10 @@ "copyright-url": "https://www.freecodecamp.org/news/copyright-policy/" }, "donate": { - "other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp" + "other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp", + "download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf", + "download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf", + "one-time-url": "https://paypal.me/freecodecamp" }, "nav": { "forum": "https://forum.freecodecamp.org/c/portugues/", @@ -23,6 +26,6 @@ "HTML-CSS": "Portugues/HTML-CSS", "JavaScript": "Portugues/JavaScript", "Python": "Portugues/Python", - "Relational Databases": "Portugues/Relational Databases" + "Backend Development": "Portugues/ajuda-em-programacao" } } diff --git a/client/i18n/locales/portuguese/meta-tags.json b/client/i18n/locales/portuguese/meta-tags.json index cf2020dbfb80e6..667f8c71f84da9 100644 --- a/client/i18n/locales/portuguese/meta-tags.json +++ b/client/i18n/locales/portuguese/meta-tags.json @@ -1,21 +1,21 @@ { - "title": "Learn to Code — For Free — Coding Courses for Busy People", - "description": "Learn to Code — For Free", - "social-description": "Learn to Code — For Free", + "title": "Aprenda a programar — de graça — Cursos de programação para pessoas ocupadas", + "description": "Aprenda a programar — de graça", + "social-description": "Aprenda a programar — de graça", "keywords": [ "python", "javascript", "js", "git", "github", - "website", + "site", "web", - "development", - "free", - "code", - "camp", - "course", - "courses", + "desenvolvimento", + "gratuito", + "programar", + "freecodecamp", + "curso", + "cursos", "html", "css", "react", @@ -24,9 +24,9 @@ "front", "back", "end", - "learn", + "aprender", "tutorial", - "programming" + "programação" ], - "youre-unsubscribed": "You have been unsubscribed" + "youre-unsubscribed": "Você não está mais inscrito" } diff --git a/client/i18n/locales/portuguese/translations.json b/client/i18n/locales/portuguese/translations.json index af8eb9f4be2bfb..70a6c82803eebd 100644 --- a/client/i18n/locales/portuguese/translations.json +++ b/client/i18n/locales/portuguese/translations.json @@ -50,7 +50,8 @@ "reset-lesson": "Reiniciar esta aula", "run": "Executar", "run-test": "Execute os testes (Ctrl + Enter)", - "check-code": "Check Your Code (Ctrl + Enter)", + "check-code": "Verifique seu código (Ctrl + Enter)", + "check-code-2": "Verifique seu código", "reset": "Redefinir", "reset-code": "Redefinir todo o código", "help": "Ajuda", @@ -70,7 +71,11 @@ "start-coding": "Comece a programar!", "go-to-settings": "Vá para as configurações para solicitar sua certificação", "click-start-course": "Iniciar o curso", - "click-start-project": "Iniciar o projeto" + "click-start-project": "Iniciar o projeto", + "change-language": "Alterar idioma", + "cancel-change": "Cancelar alteração", + "resume-project": "Retomar projeto", + "start-project": "Iniciar o projeto" }, "landing": { "big-heading-1": "Aprenda a programar — de graça.", @@ -101,7 +106,7 @@ }, "settings": { "share-projects": "Compartilhe seus projetos que não sejam do freeCodeCamp, artigos ou pull requests aceitas.", - "privacy": "The settings in this section enable you to control what is shown on your freeCodeCamp public portfolio. Press save to save your changes.", + "privacy": "As configurações nesta seção permitem que você controle o que é mostrado no seu portfólio público do freeCodeCamp. Pressione Save para salvar suas alterações.", "data": "Para ver quais dados mantemos sobre sua conta, clique no botão \"Baixar seus dados\" abaixo", "disabled": "Suas certificações serão desabilitadas ao configurar como privado.", "private-name": "Seu nome não aparecerá nas certificações, se isto estiver definido como privado.", @@ -143,7 +148,8 @@ "my-timeline": "Minha linha do tempo", "my-donations": "Minhas doações", "night-mode": "Modo noturno", - "sound-mode": "Modo fogueira" + "sound-mode": "Modo fogueira", + "keyboard-shortcuts": "Habilitar teclas de atalho" }, "headings": { "certs": "Certificações", @@ -269,7 +275,7 @@ "solution-link": "Link da solução", "github-link": "Link do GitHub", "submit-and-go": "Enviar e ir para o meu próximo desafio", - "congradulations": "Congratulations, your code passes. Submit your code to complete this step and move on to the next one.", + "congratulations": "Parabéns, o código passou. Envie o código para continuar.", "i-completed": "Já completei este desafio", "test-output": "O resultado do seu código vai aparecer aqui", "running-tests": "// executando testes", @@ -280,14 +286,14 @@ "percent-complete": "{{percent}}% completo", "tried-rsa": "Se você já tentou usar o método de <0>ler, pesquisar e perguntar, então pode pedir ajuda no fórum freeCodeCamp.", "rsa": "Leia, pesquise, pergunte", + "rsa-forum": "Before making a new post please see if your question has <0>already been answered on the forum.", "reset": "Reiniciar esta aula?", "reset-warn": "Tem certeza de que deseja reiniciar esta lição? Os editores e testes serão reiniciados.", "reset-warn-2": "Isto não pode ser desfeito", "scrimba-tip": "Dica: se o minibrowser estiver cobrindo o código, clique e arraste para movê-lo. Além disso, sinta-se à vontade para parar e editar o código no vídeo a qualquer momento.", "chal-preview": "Pré-visualização do desafio", "cert-map-estimates": { - "certs": "Certificação {{title}} (300 horas)", - "coding-prep": "{{title}} (milhares de horas de desafios)" + "certs": "Certificação {{title}}" }, "editor-tabs": { "info": "Informações", @@ -296,6 +302,7 @@ "restart": "Reiniciar", "restart-step": "Reiniciar etapa", "console": "Console", + "instructions": "Instruções", "notes": "Observações", "preview": "Pré-visualizar" }, @@ -310,13 +317,14 @@ "runs-in-vm": "O projeto é executado em uma máquina virtual. Complete as histórias de usuários descritas lá e passe em todos os testes para concluir a etapa 1.", "completed": "Concluído", "not-started": "Não iniciado", - "hint": "Hint", - "test": "Test", - "sorry-try-again": "Sorry, your code does not pass. Try again.", - "sorry-keep-trying": "Sorry, your code does not pass. Keep trying.", - "sorry-getting-there": "Sorry, your code does not pass. You're getting there.", - "sorry-hang-in-there": "Sorry, your code does not pass. Hang in there.", - "sorry-dont-giveup": "Sorry, your code does not pass. Don't give up." + "hint": "Dica", + "test": "Teste", + "sorry-try-again": "Desculpe, seu código não passou nos testes. Tente novamente.", + "sorry-keep-trying": "Desculpe, seu código não passou nos testes. Continue tentando.", + "sorry-getting-there": "Desculpe, seu código não passou nos testes. Você está chegando lá.", + "sorry-hang-in-there": "Desculpe, seu código não passou nos testes. Você está chegando lá.", + "sorry-dont-giveup": "Desculpe, seu código não passou nos testes. Não desista.", + "challenges-completed": "{{completedCount}} de {{totalChallenges}} desafios concluídos" }, "donate": { "title": "Dê seu apoio à nossa organização sem fins lucrativos", @@ -324,7 +332,6 @@ "redirecting": "Redirecionando...", "thanks": "Agradecemos por sua doação", "thank-you": "Obrigado pelo seu apoio.", - "thank-you-2": "Obrigado por apoiar o freeCodeCamp. Você tem uma doação recorrente registrada.", "additional": "Você pode fazer uma doação adicional de qualquer valor usando este link: <0>{{url}}", "help-more": "Ajude-nos a fazer mais", "error": "Algo deu errado com a sua doação.", @@ -443,7 +450,9 @@ "and": "e", "change-theme": "Faça login para mudar o tema.", "translation-pending": "Ajude-nos a traduzir", - "certification-project": "Projeto de certificação" + "certification-project": "Projeto de certificação", + "iframe-alert": "Normalmente, este link levaria você para outro site da web! Funciona. Esse é um link para: {{externalLink}}", + "document-notfound": "documento não encontrado" }, "icons": { "gold-cup": "Taça de ouro", @@ -452,8 +461,10 @@ "donate": "Doar com PayPal", "fail": "Exame não concluído com sucesso", "not-passed": "Não aprovado", + "waiting": "Aguardando", "passed": "Aprovado", - "hint": "Hint", + "failed": "Falhou", + "hint": "Dica", "heart": "Coração", "initial": "Inicial", "info": "Informações introdutórias", @@ -474,8 +485,11 @@ "last-page": "Ir para a última página", "primary-nav": "primário", "breadcrumb-nav": "breadcrumb", - "submit": "Use Ctrl + Enter to submit.", - "running-tests": "Running tests" + "submit": "Use Ctrl + Enter para enviar.", + "running-tests": "Executando testes", + "step": "Passo", + "steps": "Passos", + "steps-for": "Passos para {{blockTitle}}" }, "flash": { "honest-first": "Para solicitar uma certificação, você precisa primeiro aceitar nossa política de honestidade acadêmica", @@ -681,5 +695,16 @@ "delete-p3": "Você precisa criar um novo token para salvar seu progresso futuro nas seções de currículo que usam uma máquina virtual.", "no-thanks": "Não, obrigado. Eu gostaria de manter meu token", "yes-please": "Sim, eu gostaria de excluir meu token" + }, + "shortcuts": { + "title": "Atalhos do teclado", + "table-header-action": "Ação", + "table-header-key": "Tecla(s)", + "navigation-mode": "Modo de navegação", + "execute-challenge": "Executar desafio", + "focus-editor": "Foco no editor", + "focus-instructions-panel": "Foco no painel de instruções", + "navigate-previous": "Navegar para o exercício anterior", + "navigate-next": "Navegar para o próximo exercício" } } diff --git a/client/i18n/locales/ukrainian/intro.json b/client/i18n/locales/ukrainian/intro.json index d27266803f4724..dd0838e270186f 100644 --- a/client/i18n/locales/ukrainian/intro.json +++ b/client/i18n/locales/ukrainian/intro.json @@ -1,256 +1,256 @@ { "responsive-web-design": { - "title": "Legacy Responsive Web Design", + "title": "Застарілий адаптивний вебдизайн", "intro": [ - "У цьому сертифікаті \"Адаптивний вебдизайн\" ви вивчите мови, які розробники використовують для створення вебсторінок: HTML (мова розмітки гіпертексту) для змісту, і CSS (Каскадні таблиці стилів) для дизайну.", + "В сертифікації «Адаптивний вебдизайн» ви вивчите мови, які розробники використовують для створення вебсторінок: HTML (мова розмітки гіпертексту) для вмісту та CSS (каскадні таблиці стилів) для дизайну.", "Спочатку ви створите застосунок із фотографіями котів, аби вивчити основи HTML та CSS. Пізніше ви опануєте сучасні методи, такі як змінні CSS, завдяки створенню пінгвіна, а також створите вебформу, щоб опанувати практики покращення доступності.", - "Ви також дізнаєтеся, як конструювати вебсайти, які відповідають різним розмірам екранів створивши Twitter Card за допомогою Flexbox, а ще складний макет блогу з CSS Grid." + "Ви також дізнаєтеся, як конструювати вебсайти, які відповідають різним розмірам екранів, створивши Twitter Card за допомогою Flexbox, а ще складний макет блогу з CSS Grid." ], "note": "Примітка: деякі розширення браузера (як блокувальники реклами та темні режими) можуть втручатися в тести. Якщо ви зіткнулися з подібними проблемами, ми рекомендуємо вимкнути розширення, які змінюють вміст або макет сторінок під час виконання курсу.", "blocks": { "basic-html-and-html5": { "title": "Основи HTML та HTML5", "intro": [ - "HTML — це мова розмітки, яка використовує спеціальний синтаксис або примітки, для опису структури вебсторінки чи браузера. Елементи HTML зазвичай відкривають та закривають теги, що охоплюють вміст та надають йому значення. Наприклад, різні елементи можуть описати текст як заголовок, абзац або елемент списку.", + "HTML – це мова розмітки, яка використовує спеціальний синтаксис або примітки для опису структури вебсторінки чи браузера. Елементи HTML зазвичай мають початковий та кінцевий теґи, які оточують вміст та надають йому значення. Наприклад, різні елементи можуть описати текст як заголовок, абзац або елемент списку.", "У цьому курсі ви створите застосунок із фотографіями котів, щоб опанувати застосування деяких з найпоширеніших елементів HTML (головних блоків будь-якої вебсторінки)." ] }, "basic-css": { "title": "Основи CSS", "intro": [ - "CSS, або Каскадні таблиці стилів, повідомляють браузеру як показати текст та інший вміст, який ви написали в HTML. За допомогою CSS ви можете регулювати колір, шрифт, розмір, відстань і багато інших аспектів елементів HTML.", - "І зараз, коли ви описали структуру вашого фото-додатка, стилізуйте його за допомогою CSS." + "CSS, або каскадні таблиці стилів, повідомляють браузеру як показати текст та інший вміст, який ви написали в HTML. За допомогою CSS ви можете регулювати колір, шрифт, розмір, відстань і багато інших аспектів елементів HTML.", + "І зараз, коли ви описали структуру свого застосунку, стилізуйте його за допомогою CSS." ] }, "applied-visual-design": { "title": "Прикладний візуальний дизайн", "intro": [ - "Візуальний дизайн - це поєднання типографії, кольорознавства, графіки, анімації, макетів сторінок і багато чого іншого, аби допомогти вам передати ваше унікальне повідомлення.", + "Візуальний дизайн – це поєднання типографії, кольорознавства, графіки, анімації, макетів сторінок і багато чого іншого, аби допомогти вам передати своє унікальне повідомлення.", "У цьому курсі ви навчитеся застосовувати усі ці елементи візуального дизайну для своїх вебсайтів." ] }, "applied-accessibility": { - "title": "Доступність для людей з обмеженими можливостями", + "title": "Прикладна доступність", "intro": [ - "У процесі розробки вебсайтів, спеціальні можливості посилаються на вміст сайту та ІК (інтерфейс користувача), який широка аудиторія зможе розпізнати, з яким зможе взаємодіяти та за допомогою якого зможе зорієнтуватися на сайті. У цю аудиторія також входять люди із зоровими, слуховими, руховими та когнітивними розладами.", + "У процесі веброзробки спеціальні можливості посилаються на вміст сайту та інтерфейс користувача, який широка аудиторія зможе розпізнати, з яким зможе взаємодіяти та за допомогою якого зможе зорієнтуватися на сайті. У цю аудиторію також входять люди із зоровими, слуховими, руховими та когнітивними розладами.", "У цьому курсі ви дізнаєтеся найкращі практики для створення вебсайтів, які доступні кожному." ] }, "responsive-web-design-principles": { - "title": "Принципи Адаптивного вебдизайну", + "title": "Принципи адаптивного вебдизайну", "intro": [ - "Підключитися до мережі можна з багатьох пристроїв усіх форм і розмірів. Адаптивний вебдизайн - це проєктування гнучких вебсайтів, які пристосовуються до різних розмірів, орієнтацій та розширення екранів.", + "Підключитися до мережі можна з багатьох пристроїв різних форм і розмірів. Адаптивний вебдизайн – це проєктування гнучких вебсайтів, які пристосовуються до різних розмірів, орієнтацій та розширення екранів.", "У цьому курсі ви дізнаєтеся як використовувати CSS, аби ваші вебсайти мали гарний вигляд, незалежно від того, на якому пристрої вони відтворені." ] }, "css-flexbox": { "title": "CSS Flexbox", "intro": [ - "Flexbox - це потужний режим розмітки, який підтримується практично на всіх пристроях і який було введено з останньою версією CSS, CSS3. За допомогою flexbox набагато легше відцентровувати елементи сторінки та створювати функціональні інтерфейси користувачів, які автоматично зменшуються та розширяються.", + "Flexbox – це потужний режим розмітки, який підтримується практично на всіх пристроях і який було введено з останньою версією CSS, CSS3. За допомогою flexbox набагато легше відцентровувати елементи сторінки та створювати функціональні інтерфейси користувачів, які автоматично зменшуються та розширяються.", "У цьому курсі ви дізнаєтеся про складові flexbox та функціональної розмітки, коли створюватимете Twitter card." ] }, "css-grid": { "title": "CSS Grid", "intro": [ - "CSS grid - це новіший режим розмітки, за допомогою якого можна легко створювати складну адаптивну композицію. Він перетворює елемент HTML у сітку і допомагає розмістити дочірні елементи будь-де на екрані.", + "CSS grid – це новіший режим розмітки, за допомогою якого можна легко створювати складну адаптивну композицію. Він перетворює елемент HTML у сітку і допомагає розмістити дочірні елементи будь-де на екрані.", "У цьому курсі ви вивчите основи CSS Grid, створюючи різні складні композиції, в тому числі макет блогу." ] }, "responsive-web-design-projects": { - "title": "Проєкти Адаптивного вебдизайну", + "title": "Проєкти «Адаптивний вебдизайн»", "intro": [ - "Настав час скористатися отриманими навичками на практиці. Під час роботи над проєктами, ви зможете застосувати всі навички, правила і поняття, які ви нещодавно вивчили, такі як: HTML, CSS, Візуальний дизайн, Застосування для людей з обеженими можливостями та інше.", - "Завершіть 5 проєктів з вебпрограмування, що розташовані нижче, аби отримати свій сертифікат з адаптивного вебдизайну." + "Настав час скористатися отриманими навичками на практиці. Під час роботи над проєктами ви зможете застосувати всі навички, правила і поняття, які ви нещодавно вивчили, такі як: HTML, CSS, візуальний дизайн, доступність та інше.", + "Завершіть п'ять проєктів з вебпрограмування, що розташовані нижче, аби отримати сертифікацію «Адаптивний вебдизайн»." ] } } }, "2022/responsive-web-design": { - "title": "(New) Responsive Web Design", + "title": "(Новий) адаптивний вебдизайн", "intro": [ - "In this Responsive Web Design Certification, you'll learn the languages that developers use to build webpages: HTML (Hypertext Markup Language) for content, and CSS (Cascading Style Sheets) for design.", - "First, you'll build a cat photo app to learn the basics of HTML and CSS. Later, you'll learn modern techniques like CSS variables by building a penguin, and best practices for accessibility by building a web form.", - "Finally, you'll learn how to make webpages that respond to different screen sizes by building a Twitter card with Flexbox, and a complex blog layout with CSS Grid." + "В сертифікації «Адаптивний вебдизайн» ви вивчите мови, які розробники використовують для створення вебсторінок: HTML (мова розмітки гіпертексту) для вмісту та CSS (каскадні таблиці стилів) для дизайну.", + "Спочатку ви створите застосунок із фотографіями котів, аби вивчити основи HTML та CSS. Пізніше ви опануєте сучасні методи, такі як змінні CSS, завдяки створенню пінгвіна, а також створите вікторину, щоб опанувати доступність.", + "Наостанок ви дізнаєтеся, як створити вебсторінки, які реагують на зміну розміру екрану, створивши фотогалерею за допомогою Flexbox і макет журналу з CSS Grid." ], - "note": "Note: Some browser extensions, such as ad-blockers and dark mode extensions can interfere with the tests. If you face issues, we recommend disabling extensions that modify the content or layout of pages, while taking the course.", + "note": "Примітка: деякі розширення браузера (як блокувальники реклами та темні режими) можуть втручатися в тести. Якщо ви зіткнулися з подібними проблемами, ми рекомендуємо вимкнути розширення, які змінюють вміст або макет сторінок під час виконання курсу.", "blocks": { "build-a-tribute-page-project": { - "title": "Tribute Page", + "title": "Пам'ятна сторінка", "intro": [ - "This is one of the required projects to earn your certification.", - "For this project, you will build a tribute page for a subject of your choosing, fictional or real." + "Це один з обов'язкових до виконання проєктів для отримання сертифікації.", + "В цьому проєкті ви створите пам'ятку сторінку на тему за власним вибором." ] }, "build-a-personal-portfolio-webpage-project": { - "title": "Personal Portfolio Webpage", + "title": "Вебсторінка персонального портфоліо", "intro": [ - "This is one of the required projects to earn your certification.", - "For this project, you will build your own personal portfolio page." + "Це один з обов'язкових до виконання проєктів для отримання сертифікації.", + "В цьому проєкті ви створите вебсторінку персонального портфоліо." ] }, "build-a-product-landing-page-project": { - "title": "Product Landing Page", + "title": "Посадкова сторінка продукту", "intro": [ - "This is one of the required projects to earn your certification.", - "For this project, you will build a product landing page to market a product of your choice." + "Це один з обов'язкових до виконання проєктів для отримання сертифікації.", + "В цьому проєкті ви створите посадкову сторінку продукту, щоб збути продукт за власним вибором." ] }, "build-a-survey-form-project": { - "title": "Survey Form", + "title": "Форма для опитування", "intro": [ - "This is one of the required projects to earn your certification.", - "For this project, you will build a survey form to collect data from your users." + "Це один з обов'язкових до виконання проєктів для отримання сертифікації.", + "В цьому проєкті ви створите форму для опитування, щоб зібрати дані своїх користувачів." ] }, "build-a-technical-documentation-page-project": { - "title": "Technical Documentation Page", + "title": "Сторінка технічної документації", "intro": [ - "This is one of the required projects to earn your certification.", - "For this project, you will build a technical documentation page to serve as instruction or reference for a topic." + "Це один з обов'язкових до виконання проєктів для отримання сертифікації.", + "В цьому проєкті ви створите сторінку технічної документації, яка служитиме інструкцією або довідником." ] }, "learn-html-by-building-a-cat-photo-app": { - "title": "Learn HTML by Building a Cat Photo App", + "title": "Вивчіть HTML, створивши застосунок з котами", "intro": [ - "HTML tags give a webpage its structure. You can use HTML tags to add photos, buttons, and other elements to your webpage.", - "In this course, you'll learn the most common HTML tags by building your own cat photo app." + "Теґи HTML надають вебсторінці структуру. Ви можете використовувати теґи HTML, щоб додати фотографії, кнопки та інші елементи до своєї вебсторінки.", + "У цьому курсі ви вивчите найпоширеніші теґи HTML, створивши власний застосунок з фотографіями котів." ] }, "learn-basic-css-by-building-a-cafe-menu": { - "title": "Learn Basic CSS by Building a Cafe Menu", + "title": "Вивчіть основи CSS, створивши меню для кафе", "intro": [ - "CSS tells the browser how to display your webpage. You can use CSS to set the color, font, size, and other aspects of HTML elements.", - "In this course, you'll learn CSS by designing a menu page for a cafe webpage." + "CSS повідомляє браузеру, як зображати вашу вебсторінку. Ви можете використовувати CSS, щоб встановити колір, шрифт, розмір та інші властивості елементів HTML.", + "У цьому курсі ви вивчите CSS, розробивши дизайн меню для веб-сторінки кафе." ] }, "learn-the-css-box-model-by-building-a-rothko-painting": { - "title": "Learn the CSS Box Model by Building a Rothko Painting", + "title": "Вивчіть блокову модель CSS, створивши картину Ротко", "intro": [ - "Every HTML element is its own box – with its own spacing and a border. This is called the Box Model.", - "In this course, you'll use CSS and the Box Model to create your own Rothko-style rectangular art pieces." + "Кожен елемент HTML є своїм власним блоком із власним простором та краєм. Це називається блоковою моделлю.", + "У цьому курсі ви використовуватимете CSS та блокову модель, щоб створити власну картину в стилі Ротко." ] }, "learn-css-variables-by-building-a-city-skyline": { - "title": "Learn CSS Variables by Building a City Skyline", + "title": "Вивчіть змінні CSS, створивши панораму міста", "intro": [ - "CSS variables help you organize your styles and reuse them.", - "In this course, you'll build a city skyline. You'll learn how to configure CSS variables so you can reuse them whenever you want." + "Змінні CSS допомагають організувати стилі та повторно використовувати їх.", + "У цьому курсі ви побудуєте панораму міста. Ви дізнаєтеся, як налаштувати змінні CSS для того, щоб повторно використовувати їх, коли забажаєте." ] }, "learn-html-forms-by-building-a-registration-form": { - "title": "Learn HTML Forms by Building a Registration Form", + "title": "Вивчіть форми HTML, створивши реєстраційну форму", "intro": [ - "You can use HTML forms to collect information from people who visit your webpage.", - "In this course, you'll learn HTML forms by building a signup page. You'll learn how to control what types of data people can type into your form, and some new CSS tools for styling your page." + "Ви можете використовувати форми HTML для збору інформації від людей, які відвідують вашу вебсторінку.", + "У цьому курсі ви вивчите форми HTML, створивши реєстраційну форму. Ви дізнаєтеся, як керувати типами даних, які люди можуть вводити у вашу форму, і деякі нові інструменти CSS для стилізації своєї сторінки." ] }, "learn-accessibility-by-building-a-quiz": { - "title": "Learn Accessibility by Building a Quiz", + "title": "Вивчіть доступність, створивши вікторину", "intro": [ - "Accessibility is making your webpage easy for all people to use – even people with disabilities.", - "In this course, you'll build a quiz webpage. You'll learn accessibility tools such as keyboard shortcuts, ARIA attributes, and design best practices." + "Доступність полегшує користування вашою вебсторінкою для всіх людей, навіть для людей з порушеннями.", + "У цьому курсі ви створите вебсторінку вікторини. Ви дізнаєтеся про інструменти доступності, такі як комбінації клавіш, атрибути ARIA та найкращі поради щодо дизайну." ] }, "learn-intermediate-css-by-building-a-picasso-painting": { - "title": "Learn Intermediate CSS by Building a Picasso Painting", + "title": "Вивчіть перехідний CSS, створивши картину Пікассо", "intro": [ - "In this course, you'll learn how to use some intermediate CSS techniques by coding your own Picasso painting webpage. You'll learn about SVG icons, CSS positioning, and review other CSS skills you've learned." + "У цьому курсі ви дізнаєтеся, як використовувати деякі техніки перехідного CSS, кодуючи власну вебсторінку з картиною Пікассо. Ви дізнаєтеся про іконки SVG, позиціювання CSS та пригадаєте інші навички CSS, яких ви навчилися." ] }, "learn-responsive-web-design-by-building-a-piano": { - "title": "Learn Responsive Web Design by Building a Piano", + "title": "Вивчіть адаптивний вебдизайн, створивши піаніно", "intro": [ - "Responsive Design tells your webpage how it should look on different-sized screens.", - "In this course, you'll use CSS and Responsive Design to code a piano. You'll also learn more about media queries and pseudo selectors." + "Адаптивний дизайн каже вашій вебсторінці, як вона має виглядати на екранах різного розміру.", + "У цьому курсі ви використовуватимете CSS та адаптивний дизайн для кодування піаніно. До того ж, ви більше дізнаєтесь про медіазапити та псевдоселектори." ] }, "learn-css-flexbox-by-building-a-photo-gallery": { - "title": "Learn CSS Flexbox by Building a Photo Gallery", + "title": "Вивчіть CSS Flexbox, створивши фотогалерею", "intro": [ - "Flexbox helps you design your webpage so that it looks good on any screen size.", - "In this course, you'll use Flexbox to build a responsive photo gallery webpage." + "Flexbox допомагає створити вебсторінку, яка матиме хороший вигляд на екрані будь-якого розміру.", + "У цьому курсі ви використовуватимете Flexbox для створення адаптивної вебсторінки фотогалереї." ] }, "learn-css-grid-by-building-a-magazine": { - "title": "Learn CSS Grid by Building a Magazine", + "title": "Вивчіть CSS Grid, створивши журнал", "intro": [ - "CSS Grid gives you control over the rows and columns of your webpage design.", - "In this course, you'll build a magazine article. You'll learn how to use CSS Grid, including concepts like grid rows and grid columns." + "CSS Grid дає вам можливість керувати рядками та стовпчиками своєї вебсторінки.", + "У цьому курсі ви створите журнальну статтю. Ви дізнаєтеся, як використовувати CSS Grid, включно з рядками та стовпчиками сітки." ] }, "learn-typography-by-building-a-nutrition-label": { - "title": "Learn Typography by Building a Nutrition Label", + "title": "Вивчіть типографію, створивши етикетку", "intro": [ - "Typography is the art of styling your text to be easily readable and suit its purpose.", - "In this course, you'll use typography to build a nutrition label webpage. You'll learn how to style text, adjust line height, and position your text using CSS." + "Типографія – це мистецтво стилізації тексту, щоб його було легко читати та він відповідав своєму призначенню.", + "У цьому курсі ви використовуватимете типографію, щоб створити вебсторінку з харчовою етикеткою. Ви дізнаєтеся, як стилізувати текст, регулювати висоту рядка та позиціювати текст за допомогою CSS." ] }, "learn-css-transforms-by-building-a-penguin": { - "title": "Learn CSS Transforms by Building a Penguin", + "title": "Вивчіть трансформації CSS, створивши пінгвіна", "intro": [ - "You can transform HTML elements to create appealing designs that draw your reader's eye. You can use transforms to rotate elements, scale them, and more.", - "In this course, you'll build a penguin. You'll use CSS transforms to position and resize the parts of your penguin, create a background, and animate your work." + "Ви можете трансформувати елементи HTML, щоб створити привабливий дизайн, який привертає увагу читача. Ви можете використовувати трансформації, щоб обертати елементи, масштабувати їх тощо.", + "У цьому курсі ви побудуєте пінгвіна. Ви будете використовувати трансформації CSS, щоб позиціювати та змінювати розмір частин свого пінгвіна, створювати фон та анімувати роботу." ] }, "learn-css-animation-by-building-a-ferris-wheel": { - "title": "Learn CSS Animation by Building a Ferris Wheel", + "title": "Вивчіть анімацію CSS, створивши оглядове колесо", "intro": [ - "You can use CSS animation to draw attention to specific sections of your webpage and make it more engaging.", - "In this course, you'll build a Ferris wheel. You'll learn how to use CSS to animate elements, transform them, and adjust their speed." + "Ви можете використовувати анімацію CSS, щоб привернути увагу до певних розділів вебсторінки та зробити її більш привабливою.", + "У цьому курсі ви побудуєте оглядове колесо. Ви дізнаєтеся, як використовувати CSS для анімації елементів, трансформації та регулювання швидкості." ] }, "learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet": { - "title": "Learn More About CSS Pseudo Selectors By Building A Balance Sheet", + "title": "Вивчіть більше про псевдоселектори CSS, створивши бухгалтерський баланс", "intro": [ - "You can use CSS pseudo selectors to change specific HTML elements.", - "In this course, you'll build a balance sheet using pseudo selectors. You'll learn how to change the style of an element when you hover over it with your mouse, and trigger other events on your webpage." + "Ви можете використовувати псевдоселектори CSS, щоб змінити певні елементи HTML.", + "У цьому курсі ви побудуєте бухгалтерський баланс за допомогою псевдоселекторів. Ви дізнаєтеся як змінити стиль елемента, коли ви наводите на нього курсор, та запускати інші події на своїй вебсторінці." ] }, "learn-css-colors-by-building-a-set-of-colored-markers": { - "title": "Learn CSS Colors by Building a Set of Colored Markers", + "title": "Вивчіть кольори CSS, створивши набір кольорових маркерів", "intro": [ - "Selecting the correct colors for your webpage can greatly improve the aesthetic appeal to your readers.", - "In this course, you'll build a set of colored markers. You'll learn different ways to set color values and how to pair colors with each other." + "Вибір правильних кольорів для вебсторінки може значно покращити естетичне вподобання читачів.", + "У цьому курсі ви створите набір кольорових маркерів. Ви дізнаєтесь про різні способи встановлення значень кольорів та як поєднувати кольори між собою." ] } } }, "javascript-algorithms-and-data-structures": { - "title": "Алгоритми JavaScript та Структури даних", + "title": "Алгоритми JavaScript та структури даних", "intro": [ - "Якщо HTML і CSS відповідають за вміст і стилізацію сторінки, то JavaScript робить її інтерактивно. У довідці \"Алгоритм JavaScript та Структури Даних\" ви вивчите основи JavaScript, включно зі змінними, масивами, об'єктами, циклами та функціями.", - "Як тільки ви вивчите основи, ви почнете застосовувати ці знання, створюючи алгоритми, щоб уміло маніпулювати рядками, факторизувати числа, і навіть зможете обчислити орбіту Міжнародної Космічної Станції.", - "Крім того, ви також вивчите два важливих стилі або парадигми в програмуванні: Об'єктозорієнтоване програмування (ООП) і Функційне програмування (ФП)." + "Якщо HTML та CSS відповідають за вміст і стилізацію сторінки, то JavaScript робить її інтерактивною. У сертифікації «Алгоритми JavaScript та структури даних» ви вивчите основи JavaScript, включно зі змінними, масивами, об'єктами, циклами та функціями.", + "Як тільки ви вивчите основи, ви почнете застосовувати ці знання, створюючи алгоритми, щоб уміло маніпулювати рядками, факторизувати числа, і навіть зможете обчислити орбіту міжнародної космічної станції.", + "Крім того, ви також вивчите два важливих стилі або парадигми в програмуванні: об'єктноорієнтоване програмування (ООП) та функційне програмування (ФП)." ], - "note": "Примітка: Деякі розширення браузера, такі як блокувальники реклами та скриптів можуть заважати тестам. Якщо ж ви зіштовхнулися з проблемами, ми рекомендуємо вимкнути розширення, які змінюють або блокують вміст сторінок під час проходження курсу.", + "note": "Примітка: деякі розширення браузера (як блокувальники реклами та скриптів) можуть втручатися в тести. Якщо ви зіткнулися з подібними проблемами, ми рекомендуємо вимкнути розширення, які змінюють або блокують вміст сторінок під час виконання курсу.", "blocks": { "basic-javascript": { "title": "Основи JavaScript", "intro": [ "JavaScript — це скриптова мова, яка використовується для того, аби зробити вебсайти інтерактивними. Це одна з основних технологій в мережі (разом з HTML та CSS), яка підтримується всіма сучасними браузерами.", - "У цьому курсі ви вивчите головні поняття програмування в JavaScript. Ви почнете з простих структур даних, таких як числа та рядки. Далі ви почнете роботу з масивами, об'єктами, функціями, циклами, умовними конструкціями (if/else) тощо." + "У цьому курсі ви вивчите головні поняття програмування в JavaScript. Ви почнете з простих структур даних, таких як числа та рядки. Далі ви почнете роботу з масивами, об'єктами, функціями, циклами, умовними конструкціями тощо." ] }, "es6": { "title": "ES6", "intro": [ - "ECMAScript, або ES — це стандартизована версія JavaScript. Оскільки більшість браузерів дотримуються цих стандартів, умови ECMAScript і JavaScript є взаємозамінними.", + "ECMAScript, або ES – це стандартизована версія JavaScript. Оскільки більшість браузерів дотримуються цих стандартів, ECMAScript та JavaScript є взаємозамінними.", "Більша частина JavaScript (про яку ви вже дізналися) була в ES5 (ECMAScript 5), який утвердили у 2009 році. Поки ви все ще маєте можливість писати програми в ES5, JavaScript постійно розвивається і там щорічно вводяться нові функції.", - "У ES6, який випустили у 2015 році, додали багато нових потужних функцій до цієї мови. У курсі ви вивчите ці нові особливості, такі як функції arrow (стрілки), деструкція, класи, проміси та модулі." + "ES6, який випустили у 2015 році, додав багато нових потужних функцій до цієї мови. У курсі ви вивчите нові особливості, такі як стрілочні функції, деструкція, класи, проміси та модулі." ] }, "regular-expressions": { "title": "Регулярні вирази", "intro": [ - "Регулярні вирази (відомі як \"regex\" або \"regexp\") — шаблони, які допомагають програмістам поєднувати, шукати та замінювати текст. Регулярні вирази дуже важливі, але їх важко читати, оскільки у них використовуються спеціальні символи для створення складніших, гнучкіших поєднань.", + "Регулярні вирази (відомі як «regex» або «regexp») – шаблони, які допомагають програмістам поєднувати, шукати та замінювати текст. Регулярні вирази дуже важливі, але їх важко читати, оскільки у них використовуються спеціальні символи для створення складніших, гнучкіших поєднань.", "У цьому курсі ви дізнаєтеся як використовувати спеціальні символи, групи захоплення, позитивний та негативний огляди та інші техніки, аби текст відповідав бажаному." ] }, "debugging": { "title": "Налагодження програм", "intro": [ - "Налагодження програм — це процес перевірки коду на наявність помилок та їх виправлення.", + "Налагодження програм – це процес перевірки коду на наявність помилок та їх виправлення.", "Помилки в коді, як правило, розподіляють на три категорії: синтаксичні, які заважають вашій програмі працювати; помилки середовища виконання, коли ваш код поводиться непередбачувано; або логічні, коли ваш код не виконує свою функцію.", "У цьому курсі ви дізнаєтеся як використовувати консоль JavaScript, аби налагодити програми та уникнути розповсюджених помилок." ] @@ -258,30 +258,30 @@ "basic-data-structures": { "title": "Основи структур даних", "intro": [ - "Багатьома способами можна зберегти дані та отримати до них доступ. Ви вже знаєте деякі загальні структури даних JavaScript - масиви та об'єкти.", - "У цьому курсі Основ структур даних ви дізнаєтеся більше про різницю між масивами та об'єктами, та в яких ситуаціях вони використовуються. Ви також дізнаєтеся як використовувати корисні JS методи, такі як splice() і Object.keys() аби отримати доступ до даних та маніпулювати ними." + "Багатьома способами можна зберегти дані та отримати до них доступ. Ви вже знаєте деякі загальні структури даних JavaScript – масиви та об'єкти.", + "У курсі «Основи структур даних» ви дізнаєтеся більше про різницю між масивами та об'єктами, та в яких ситуаціях вони використовуються. Ви також дізнаєтеся як використовувати корисні методи JS, такі як splice() та Object.keys(), аби отримати доступ до даних та маніпулювати ними." ] }, "basic-algorithm-scripting": { "title": "Основи написання алгоритмів", "intro": [ - "Алгоритм — це ряд покрокових інструкцій, які описують як щось робити.", + "Алгоритм – це ряд покрокових інструкцій, які описують як щось робити.", "Написання успішного алгоритму допомагає розбити задачу на менші частини та гарно подумати над тим, як вирішити кожну частину за допомогою коду.", - "У цьому курсі ви вивчите основи алгоритмічного мислення, пишучи алгоритми, які роблять усе - від перетворення температур до користування складними 2D масивами." + "У цьому курсі ви вивчите основи алгоритмічного мислення, пишучи алгоритми, які роблять усе: від перетворення температур до користування складними 2D масивами." ] }, "object-oriented-programming": { - "title": "Об'єктозорієнтоване програмування", + "title": "Об'єктноорієнтоване програмування", "intro": [ - "ООП, або Об'єктозорієнтоване програмування - це один з основних підходів до процесу розробки програмного забезпечення. В ООП об'єкти й класи впорядковують код для опису речей і того, що вони роблять.", - "У цьому курсі ви вивчите основні принципи ООП в JavaScript, включаючи this ключове слово, прототипи ланцюгів, конструктори та наслідування." + "ООП, або об'єктноорієнтоване програмування – це один з основних підходів до процесу розробки програмного забезпечення. В ООП об'єкти та класи впорядковують код для опису речей і того, що вони роблять.", + "У цьому курсі ви вивчите основні принципи ООП в JavaScript, включно з ключовим словом this, прототипи ланцюгів, конструктори та наслідування." ] }, "functional-programming": { "title": "Функційне програмування", "intro": [ - "Функційне програмування це ще один популярний підхід до розробки програмного забезпечення. У функційному програмуванні код впорядкований у менші, прості функції, які можна об'єднувати для створення складних програм.", - "У цьому курсі ви вивчите основні поняття функційного програмування, включаючи чисті функції, як уникнути мутацій і як писати чистіший код за допомогою методів, таких як .map() і .filter()." + "Функційне програмування – це ще один популярний підхід до розробки програмного забезпечення. У функційному програмуванні код впорядкований у менші, прості функції, які можна об'єднувати для створення складних програм.", + "У цьому курсі ви вивчите основні поняття функційного програмування, включно з чистими функціями, як уникнути мутацій і як писати чистіший код за допомогою методів, таких як .map() і .filter()." ] }, "intermediate-algorithm-scripting": { @@ -291,73 +291,73 @@ ] }, "javascript-algorithms-and-data-structures-projects": { - "title": "Проєкти з Алгоритмами JavaScript та Структурами даних", + "title": "Проєкти «Алгоритми JavaScript та структури даних»", "intro": [ "Тепер настав час випробувати свої навички роботи з JavaScript на практиці. Ці проєкти подібні до тестів з написання алгоритмів, які ви вже робили, але складніші.", - "Виконайте ці 5 проєктів JavaScript, аби отримати сертифікат \"Алгоритми JavaScript та Структури даних\"." + "Виконайте п'ять проєктів JavaScript, аби отримати сертифікацію «Алгоритми JavaScript та структури даних»." ] } } }, "2022/javascript-algorithms-and-data-structures": { - "title": "JavaScript Algorithms and Data Structures (Beta)", + "title": "Алгоритми JavaScript та структури даних (бета-версія)", "intro": [ - "placeholder", - "placeholder" + "заповнювач", + "заповнювач" ], "note": "", "blocks": { "build-a-caesars-cipher-project": { - "title": "Build a Casears Cipher Project", + "title": "Проєкт «Створіть шифр Цезаря»", "intro": [ "", "" ] }, "build-a-cash-register-project": { - "title": "Build a Cash Register Project", + "title": "Проєкт «Створіть касовий апарат»", "intro": [ "", "" ] }, "build-a-palindrome-checker-project": { - "title": "Build a Palindrome Checker Project", + "title": "Проєкт «Створіть перевірку паліндрома»", "intro": [ "", "" ] }, "build-a-roman-numeral-converter-project": { - "title": "Build a Roman Numeral Converter Project", + "title": "Проєкт «Створіть конвертер римських чисел»", "intro": [ "", "" ] }, "build-a-telephone-number-validator-project": { - "title": "Build a Telephone Number Validator Project", + "title": "Проєкт «Створіть валідатор мобільного номера»", "intro": [ "", "" ] }, "learn-basic-javascript-by-building-a-role-playing-game": { - "title": "Learn Basic JavaScript by Building a Role Playing Game", + "title": "Вивчіть основи JavaScript, створивши рольову гру", "intro": [ "", "" ] }, "learn-form-validation-by-building-a-calorie-counter": { - "title": "Learn Form Validation by Building a Calorie Counter", + "title": "Вивчіть валідацію форм, створивши лічильник калорій", "intro": [ "", "" ] }, "learn-functional-programming-by-building-a-spreadsheet": { - "title": "Learn Functional Programming by Building a Spreadsheet", + "title": "Вивчіть функційне програмування, створивши електронну таблицю", "intro": [ "", "" @@ -366,10 +366,10 @@ } }, "front-end-development-libraries": { - "title": "Бібліотеки фронтенд (Front End)", + "title": "Бібліотеки Front End", "intro": [ "Тепер, коли ви вже знайомі з HTML, CSS та JavaScript, піднімімо ваш рівень навичок, вивчаючи декілька найбільш популярних бібліотек верстки в галузі.", - "У курсі \"Бібліотеки фронтенд\" ви навчитеся швидко стилізувати ваш сайт за допомогою Bootstrap. Також ви навчитеся покращувати ваші CSS стилі та розширювати їх за допомогою Sass.", + "У курсі «Бібліотеки Front End» ви навчитеся швидко стилізувати свій сайт за допомогою Bootstrap. Також ви навчитеся покращувати свої стилі CSS та розширювати їх за допомогою Sass.", "Згодом ви розробите кошик для покупок та інші застосунки, щоб навчитися створювати потужні односторінкові застосунки (SPAs) з React та Redux." ], "note": "", @@ -377,53 +377,53 @@ "bootstrap": { "title": "Bootstrap", "intro": [ - "Bootstrap — це фронтенд каркас створений для проєктування адаптивних вебсторінок та застосунків. Для веброзробки цей фреймворк використовує принцип Mobile First, включає попередньо інтегровані стилі та класи CSS і деякі розширення JavaScript.", + "Bootstrap – це фронтенд каркас, створений для проєктування адаптивних вебсторінок та застосунків. Для веброзробки цей фреймворк використовує принцип Mobile First, включає попередньо інтегровані стилі та класи CSS і деякі розширення JavaScript.", "Під час цього курсу ви навчитеся створювати адаптивні вебсайти за допомогою Bootstrap та використовувати готові шаблони для стилізації кнопок, зображень, форм, навігації та інших поширених елементів." ] }, "jquery": { "title": "jQuery", "intro": [ - "jQuery — одна з найпопулярніших у світі бібліотек JavaScript.", - "До її запуску у 2006 році, кожний браузер використовував JavaScript по своєму. jQuery спростила роботу з JavaScript для користувачів, а також забезпечила кросбраузерність створених кодів.", + "jQuery – одна з найпопулярніших у світі бібліотек JavaScript.", + "До її запуску у 2006 році, кожний браузер використовував JavaScript по-своєму. jQuery спростила роботу з JavaScript для користувачів, а також забезпечила кросбраузерність створених кодів.", "Під час цього курсу ви навчитеся використовувати jQuery для виділення, вилучення, копіювання та редагування різних елементів на сторінці." ] }, "sass": { "title": "SASS", "intro": [ - "Sass, або \"Syntactically Awesome StyleSheets\" — це мовне розширення CSS, що містить функції, яких немає у базовому CSS, і тим самим допомагає спростити створення таблиць стилів для ваших проєктів.", - "У цьому курсі ви навчитеся зберігати дані у змінних, вкладати CSS, створювати багаторазові стилі за допомогою міксин (Mixins), додавати умовні конструкції та цикли до ваших стилів тощо." + "Sass, або «Syntactically Awesome StyleSheets» – це мовне розширення CSS, що містить функції, яких немає у базовому CSS, і тим самим допомагає спростити створення таблиць стилів для ваших проєктів.", + "У цьому курсі ви навчитеся зберігати дані у змінних, вкладати CSS, створювати багаторазові стилі за допомогою міксин, додавати умовні конструкції та цикли до своїх стилів тощо." ] }, "react": { "title": "React", "intro": [ - "React — це популярна бібліотека JavaScript для створення багаторазових компонентних користувацьких інтерфейсів для вебсторінок або додатків.", + "React – це популярна бібліотека JavaScript для створення багаторазових компонентних користувацьких інтерфейсів для вебсторінок або додатків.", "React поєднує HTML з функціями JavaScript, формуючи власну мову розмітки під назвою JSX. React також дозволяє легко керувати потоком даних у всьому додатку.", - "Під час цього курсу ви навчитеся створювати різні компоненти React, керувати даними за допомогою пропсів (props), а також застосовувати різні методи життєвого циклу, такі як componentDidMount тощо." + "У цьому курсі ви навчитеся створювати різні компоненти React, керувати даними за допомогою пропсів, а також застосовувати різні методи життєвого циклу, такі як componentDidMount тощо." ] }, "redux": { "title": "Redux", "intro": [ - "Зі збільшенням розмірів та кількості додатків, керувати спільними даними стає все складніше. Redux називають \"відкритою JS бібліотекою призначеною для управління станом програм JavaScript\", яка забезпечує належну роботу ваших програм і спрощує їхнє тестування.", + "Зі збільшенням розмірів та кількості додатків, керувати спільними даними стає все складніше. Redux називають «відкритою JS бібліотекою призначеною для управління станом програм JavaScript», яка забезпечує належну роботу ваших програм і спрощує тестування.", "Хоча ви можете використовувати його з будь-якою іншою бібліотекою, ми лише коротко розповімо про Redux, а тоді об'єднаємо його з React у наступному наборі курсів.", - "Під час цього курсу ви вивчите базову інформацію про сховища, дії, редуктори та проміжне програмне забезпечення Redux для керування даними у вашому додатку." + "Під час цього курсу ви вивчите базову інформацію про сховища, дії, редуктори та проміжне програмне забезпечення Redux для керування даними у своєму додатку." ] }, "react-and-redux": { - "title": "React і Redux", + "title": "React та Redux", "intro": [ "React часто використовують разом із Redux, і не дарма. Redux і React створив один програміст, який хотів зробити процес передачі даних між компонентами простішим.", - "Тепер коли ви вже навчились керувати загальними даними за допомогою Redux, ви можете виконувати дії й в React. На курсах React і Redux, ви навчитесь будувати компонент React і дізнаєтесь, як локально керувати станом на рівні компонента та й у цілому додатку за допомогою Redux." + "Тепер коли ви вже навчились керувати загальними даними за допомогою Redux, ви можете виконувати дії в React. На курсах React і Redux, ви навчитесь будувати компонент React і дізнаєтесь, як локально керувати станом на рівні компонента, та й у цілому додатку, за допомогою Redux." ] }, "front-end-development-libraries-projects": { - "title": "Проєкти по бібліотеках фронтенд розробки", + "title": "Проєкти «Бібліотеки Front End»", "intro": [ - "Прийшов час протестувати ваші навички роботи з бібліотеками фронтенд розробки. Використовуйте Bootstrap, jQuery, Sass, React та Redux, аби створити 5 проєктів, що перевірять ваші знання з усього, що ви вивчили дотепер.", - "Завершіть всі 5 проєктів і отримайте сертифікат по бібліотеках фронтенд розробки." + "Прийшов час протестувати ваші навички роботи з бібліотеками фронтенд розробки. Використайте Bootstrap, jQuery, Sass, React та Redux, аби створити 5 проєктів, що перевірять ваші знання з усього, що ви вивчили дотепер.", + "Виконайте п'ять проєктів та отримайте сертифікацію «Бібліотеки Front End»." ] } } @@ -432,33 +432,33 @@ "title": "Візуалізація даних", "intro": [ "Дані повсюди, але це не означає, що більшість з них без форми чи контексту.", - "У сертифікаті \"Візуалізація даних\" ви створите діаграми, графіки та карти, що показують різні типи даних, за допомогою бібліотеки D3.js.", - "Ви також дізнаєтесь про JSON (JavaScript Object Notation), і як працювати з даними онлайн користуючись API (Application Programing Interface)." + "У сертифікації «Візуалізація даних» ви створите діаграми, графіки та карти, що показують різні типи даних, за допомогою бібліотеки D3.js.", + "Ви також дізнаєтесь про JSON (JavaScript Object Notation) та як працювати з даними онлайн, користуючись API (Application Programing Interface)." ], "note": "", "blocks": { "data-visualization-with-d3": { - "title": "Візуалізація даних за допомогою D3", + "title": "Візуалізація даних з D3", "intro": [ - "D3, або D3.js — розшифровується як \"Data Driven Documents\", а українською — \"Документи, керовані даними\". Це бібліотека JavaScript для створення функціональної та інтерактивної візуалізації даних у браузері.", + "D3, або D3.js, розшифровується як «Data Driven Documents». Це бібліотека JavaScript для створення функціональної та інтерактивної візуалізації даних у браузері.", "D3 створено для роботи з поширеними вебстандартами, а саме: HTML, CSS і SVG (масштабована векторна графіка).", "D3 підтримує багато різних форматів даних. Тому, використовуючи її потужні вбудовані методи, ви можете перетворити ці дані у різні діаграми, графіки та карти.", - "У курсі \"Візуалізація даних за допомогою D3\" ви навчитеся працювати з даними, аби створювати різні діаграми, графіки, hover елементи, та інші складові частини, аби створити динамічну та принадну візуалізацію даних." + "У курсі «Візуалізація даних з D3» ви навчитеся працювати з даними, аби створювати різні діаграми, графіки, елементи наведення та інші складові частини, аби створити динамічну та принадну візуалізацію даних." ] }, "json-apis-and-ajax": { "title": "JSON API та AJAX", "intro": [ - "Так само як інтерфейс користувача (UIs) допомагає людям користуватися програмами, так само й APIs (Application Programming Interfaces) допомагає програмам взаємодіяти між собою. APIs — це інструменти, які використовуються комп'ютерами для комунікування один з одним, і, частково, для надсилання та отримання даних.", + "Так само як інтерфейс користувача (UIs) допомагає людям користуватися програмами, так само й APIs (Application Programming Interfaces) допомагає програмам взаємодіяти між собою. APIs – це інструменти, які використовуються комп'ютерами для комунікування один з одним, і, частково, для надсилання та отримання даних.", "Програмісти часто використовують AJAX (Asynchronous JavaScript and XML) при роботі з APIs. AJAX належить до групи технологій, які роблять асинхронні запити до сервера для передачі даних, а потім завантажують будь-які отримані дані до сторінки. І дані, що були передані між браузером і сервером, часто мають формат JSON (JavaScript Object Notation).", - "Цей курс навчить вас основ роботи з APIs та різними AJAX технологіями в браузері." + "Цей курс навчить вас основ роботи з APIs та різними технологіями AJAX в браузері." ] }, "data-visualization-projects": { - "title": "Проєкти візуалізації даних", + "title": "Проєкти «Візуалізація даних»", "intro": [ "Тепер, коли ви дізналися як працювати з D3, APIs та AJAX технологіями, перевірте свої навички за допомогою цього тесту з 5-ма проєктами візуалізації даних.", - "У цих проєктах вам потрібно буде отримати й проаналізувати набір даних, тоді використати D3 для створення різної візуалізації даних. Завершіть усі проєкти, аби отримати сертифікат з візуалізації даних." + "У цих проєктах вам потрібно буде отримати й проаналізувати набір даних, тоді використати D3 для створення різної візуалізації даних. Завершіть усі проєкти, аби отримати сертифікацію «Візуалізація даних»." ] }, "d3-dashboard": { @@ -471,151 +471,151 @@ } }, "relational-database": { - "title": "Relational Database (Beta)", + "title": "Реляційна база даних (бета-версія)", "intro": [ - "For these courses, you will use real developer tools and software including VS Code, PostgreSQL, and the Linux / Unix command line to complete interactive tutorials and build projects.", - "These courses start off with basic Bash commands. Using the terminal, you will learn everything from navigating and manipulating a file system, scripting in Bash, all the way to advanced usage.", - "Next, you will learn how to create and use a relational database with PostgreSQL, a database management system, and SQL, the language of these databases.", - "Finally, you will learn Git, the version control system, an essential tool of every developer." + "У цих курсах ви використовуватимете реальні інструменти розробника та програмне забезпечення, включно з VS Code, PostgreSQL та командним рядком Linux / Unix для завершення інтерактивних уроків і створення проєктів.", + "Ці курси починаються з основних команд Bash. За допомогою терміналу ви навчитеся усього необхідного (від навігації та маніпуляції файловою системою, написання скрипту в Bash до просунутого використання).", + "Далі ви навчитеся створювати та використовувати реляційну базу даних з PostgreSQL (система керування базами даних) та SQL (мова баз даних).", + "Зрештою, ви дізнаєтеся про Git, систему контролю версій, важливий інструмент кожного розробника." ], "blocks": { "build-a-celestial-bodies-database-project": { - "title": "Celestial Bodies Database", + "title": "База даних «Небесні тіла»", "intro": [ - "This is one of the required projects to earn your certification.", - "For this project, you will build a database of celestial bodies using PostgreSQL." + "Це один з обов'язкових до виконання проєктів для отримання сертифікації.", + "У цьому проєкті ви побудуєте базу даних небесних тіл, використовуючи PostgreSQL." ] }, "build-a-number-guessing-game-project": { - "title": "Number Guessing Game", + "title": "Гра «Вгадай число»", "intro": [ - "This is one of the required projects to earn your certification.", - "For this project, you will use Bash scripting, PostgreSQL, and Git to create a number guessing game that runs in the terminal and saves user information." + "Це один з обов'язкових до виконання проєктів для отримання сертифікації.", + "У цьому проєкті ви використовуватимете сценарії Bash, PostgreSQL та Git, щоб створити гру з вгадуванням чисел, яка запускається в терміналі та зберігає інформацію користувача." ] }, "build-a-periodic-table-database-project": { - "title": "Periodic Table Database", + "title": "База даних «Періодична таблиця»", "intro": [ - "This is one of the required projects to earn your certification.", - "For this project, you will create Bash a script to get information about chemical elements from a periodic table database." + "Це один з обов'язкових до виконання проєктів для отримання сертифікації.", + "У цьому проєкті ви створите скрипт Bash для отримання інформації про хімічні елементи з бази даних періодичної таблиці." ] }, "build-a-salon-appointment-scheduler-project": { - "title": "Salon Appointment Scheduler", + "title": "Планувальник «Записи в салоні»", "intro": [ - "This is one of the required projects to earn your certification.", - "For this project, you will create an interactive Bash program that uses PostgreSQL to track the customers and appointments for your salon." + "Це один з обов'язкових до виконання проєктів для отримання сертифікації.", + "У цьому проєкті ви створите інтерактивну програму Bash, яка використовує PostgreSQL для відстеження клієнтів і зустрічей у вашому салоні." ] }, "build-a-world-cup-database-project": { - "title": "World Cup Database", + "title": "База даних «Чемпіонат світу»", "intro": [ - "This is one of the required projects to earn your certification.", - "For this project, you will create a Bash script that enters information from World Cup games into PostgreSQL, then query the database for useful statistics." + "Це один з обов'язкових до виконання проєктів для отримання сертифікації.", + "У цьому проєкті ви створите скрипт Bash, який вводить інформацію з ігор чемпіонату світу в PostgreSQL, а потім запитує базу даних для отримання статистики." ] }, "learn-advanced-bash-by-building-a-kitty-ipsum-translator": { - "title": "Learn Advanced Bash by Building a Kitty Ipsum Translator", + "title": "Вивчіть прогресивний Bash, створивши перекладач Kitty Ipsum", "intro": [ - "There's more to Bash commands than you might think.", - "In this 140-lesson course, you will learn some more complex commands, and the details of how commands work." + "У командах Bash більше, ніж ви могли собі уявити.", + "У цьому курсі з 140 уроків ви дізнаєтеся про деякі складніші команди, а також детально дізнаєтеся як вони працюють." ] }, "learn-bash-and-sql-by-building-a-bike-rental-shop": { - "title": "Learn Bash and SQL by Building a Bike Rental Shop", + "title": "Вивчіть Bash та SQL, створивши магазин прокату велосипедів", "intro": [ - "In this 210-lesson course, you will build an interactive Bash program that stores rental information for your bike rental shop using PostgreSQL." + "У цьому курсі з 210 уроків ви створите інтерактивну програму Bash, яка зберігатиме інформацію про оренду для вашого магазину прокату велосипедів, використовуючи PostgreSQL." ] }, "learn-bash-by-building-a-boilerplate": { - "title": "Learn Bash by Building a Boilerplate", + "title": "Вивчіть Bash, створивши шаблонний код", "intro": [ - "The terminal allows you to send text commands to your computer that can manipulate the file system, run programs, automate tasks, and much more.", - "In this 170-lesson course, you will learn terminal commands by creating a website boilerplate using only the command line." + "Термінал дозволяє відправляти текстові команди на ваш комп’ютер, які можуть маніпулювати файловою системою, запускати програми, автоматизувати завдання та багато іншого.", + "У цьому курсі з 170 уроків ви вивчите команди терміналу, створивши шаблонний код вебсайту, використовуючи лише командний рядок." ] }, "learn-bash-scripting-by-building-five-programs": { - "title": "Learn Bash Scripting by Building Five Programs", + "title": "Вивчіть скрипт Bash, створивши п’ять програм", "intro": [ - "Bash scripts combine terminal commands and logic into programs that can execute or automate tasks, and much more.", - "In this 220-lesson course, you will learn more terminal commands and how to use them within Bash scripts by creating five small programs." + "Скрипти Bash поєднують команди терміналу та логіку в програми, які можуть виконувати або автоматизувати завдання та багато іншого.", + "У цьому курсі з 220 уроків ви вивчите більше про команди терміналу та як їх використовувати в скриптах Bash, створивши п’ять невеликих програм." ] }, "learn-git-by-building-an-sql-reference-object": { - "title": "Learn Git by Building an SQL Reference Object", + "title": "Вивчіть Git, створивши об'єкт SQL", "intro": [ - "Git is a version control system that keeps track of all the changes you make to your codebase.", - "In this 240-lesson course, you will learn how Git keeps track of your code by creating an object containing commonly used SQL commands." + "Git – це система контролю версій, яка відстежує усі зміни, внесені вами до свого коду.", + "У цьому курсі з 240 уроків ви вивчите як Git відстежує ваш код, створюючи об’єкт, що містить часто використовувані команди SQL." ] }, "learn-nano-by-building-a-castle": { - "title": "Learn Nano by Building a Castle", + "title": "Вивчіть Nano, створивши замок", "intro": [ - "Nano is a program that allows you to edit files right in the terminal.", - "In this 40-lesson course, you will learn how to edit files in the terminal with Nano while building a castle." + "Nano – це програма, яка дозволяє редагувати файли прямо в терміналі.", + "У цьому курсі з 40 уроків ви вивчите як редагувати файли в терміналі за допомогою Nano під час будівництва замку." ] }, "learn-relational-databases-by-building-a-mario-database": { - "title": "Learn Relational Databases by Building a Mario Database", + "title": "Вивчіть реляційні бази даних, створивши базу даних «Mario»", "intro": [ - "A relational database organizes data into tables that are linked together through relationships.", - "In this 165-lesson course, you will learn the basics of a relational database by creating a PostgreSQL database filled with video game characters." + "Реляційна база даних організовує дані в таблиці, які пов’язані між собою через спорідненість.", + "В цьому курсі з 165 уроків ви вивчите основи реляційної бази даних, створивши базу даних PostgreSQL, наповнену персонажами з відеоігор." ] }, "learn-sql-by-building-a-student-database-part-1": { - "title": "Learn SQL by Building a Student Database: Part 1", + "title": "Вивчіть SQL, створивши студентську базу даних (частина 1)", "intro": [ - "SQL, or Structured Query Language, is the language for communicating with a relational database.", - "In this 140-lesson course, you will create a Bash script that uses SQL to enter information about your computer science students into PostgreSQL." + "SQL, або Structured Query Language (мова структурованих запитів) – це мова для спілкування з реляційною базою даних.", + "В цьому курсі з 140 уроків ви створите скрипт Bash, який використовує SQL для введення інформації про ваших студентів з інформатики в PostgreSQL." ] }, "learn-sql-by-building-a-student-database-part-2": { - "title": "Learn SQL by Building a Student Database: Part 2", + "title": "Вивчіть SQL, створивши студентську базу даних (частина 2)", "intro": [ - "SQL join commands are used to combine information from multiple tables in a relational database", - "In this 140-lesson course, you will complete your student database while diving deeper into SQL commands." + "Команди об’єднання SQL використовуються, щоб поєднати інформацію з кількох таблиць у реляційній базі даних", + "У цьому курсі з 140 уроків ви завершите свою базу даних студентів, глибше занурившись в команди SQL." ] } } }, "back-end-development-and-apis": { - "title": "Бекенд розробка та API", + "title": "Розробка Back End та API", "intro": [ - "До цього моменту ви використовували JavaScript тільки для фронтенду, аби зробити вебсторінку інтерактивнішою, чи розв'язати завдання з алгоритмами, або створити односторінкові застосунки (SPA). Але JavaScript можна використовувати й в бекенд, або на сервері, для створення цілих вебзастосунків.", - "Сьогодні один із найпопулярніших способів створення застосунків — це за допомогою мікросервісів, маленьких модульних застосунків, які разом формують єдине ціле.", - "У курсі \"Бекенд розробка та API\" ви навчитеся писати бекенд програми за допомогою Node.js і npm (Node Package Manager). Також, ви створите вебзастосунок за допомогою фреймворку Express та мікросервіс для пошуку людей (People Finder) за допомогою MongoDB і Mongoose library." + "До цього моменту ви використовували JavaScript тільки для фронтенду, аби зробити вебсторінку інтерактивнішою, розв'язати завдання з алгоритмами, або створити SPA. Але JavaScript можна використовувати й в бекенд, або на сервері, для створення цілих вебзастосунків.", + "Сьогодні один із найпопулярніших способів створення застосунків – за допомогою мікросервісів, маленьких модульних застосунків, які разом формують єдине ціле.", + "У сертифікації «Розробка Back End та API» ви навчитеся писати бекенд програми за допомогою Node.js та npm (Node Package Manager). Також, ви створите вебзастосунок за допомогою фреймворку Express та мікросервіс для пошуку людей за допомогою MongoDB і Mongoose library." ], "note": "", "blocks": { "managing-packages-with-npm": { - "title": "Керування пакетами NPM", + "title": "Керування пакетами з NPM", "intro": [ - "npm (Node Package Manager) — це інструмент командного рядка для встановлення, створення та поширення пакетів JavaScript-коду написаного для Node.js. На npm знаходяться багато пакетів з відкритим вихідним кодом, тому спершу ретельно їх вивчіть, щоб вам не довелося виправляти помилки під час роботи з даними чи отримання даних з API.", - "У цьому курсі ви вивчите основи використання npm, включаючи роботу із package.json та керування вашими встановленими залежностями." + "npm (Node Package Manager) – це інструмент командного рядка для встановлення, створення та поширення пакетів коду JavaScript, написаного для Node.js. На npm знаходиться багато пакетів з відкритим вихідним кодом, тому спершу ретельно їх вивчіть, щоб вам не довелося виправляти помилки під час роботи з даними чи отримання даних з API.", + "У цьому курсі ви вивчите основи використання npm, включно з тим як працювати із package.json та як керувати встановленими залежностями." ] }, "basic-node-and-express": { "title": "Основи Node та Express", "intro": [ - "Node.js — це середовище виконання JavaScript, що дозволяє розробникам писати бекенд (серверні) програми в JavaScript. Node.js має кілька вбудованих модулів, — маленьких, незалежних програм — які допомагають з цим. Деякі з основних модулів містять HTTP, який працює на зразок сервера, і файлову систему — модуль для читання і редагування файлів.", + "Node.js – це середовище виконання JavaScript, що дозволяє розробникам писати бекенд (серверні) програми в JavaScript. Node.js має кілька вбудованих модулів, – маленьких, незалежних програм – які допомагають з цим. Деякі з основних модулів містять HTTP, який працює на зразок сервера, і файлову систему – модуль для читання і редагування файлів.", "В останній групі курсів ви навчилися встановлювати та керувати пакетами npm, які є скупченнями менших модулів. Ці пакети можуть допомогти вам створити більші, складніші застосунки.", - "Express is a lightweight web application framework, and is one of the most popular packages on npm. Express makes it much easier to create a server and handle routing for your application, which handles things like directing people to the correct page when they visit a certain endpoint like
/blog
.", - "У цьому курсі ви дізнаєтесь основи Node та Express, включаючи те, як створювати сервер, обслуговувати різні файли та обробляти різні запити з браузера." + "Express – це спрощений фреймворк вебзастосунків та один з найбільш популярних пакетів на npm. Express значно полегшує створення сервера та керування маршрутизацією вашого застосунку, що відповідає за такі речі як перенаправлення людей до потрібної сторінки, коли вони відвідують певну кінцеву точку, наприклад
/blog
.", + "У цьому курсі ви дізнаєтесь основи Node та Express, включно з тим, як створювати сервер, обслуговувати різні файли та обробляти різні запити з браузера." ] }, "mongodb-and-mongoose": { - "title": "MongoDB і Mongoose", + "title": "MongoDB та Mongoose", "intro": [ - "MongoDB це програма бази даних, яка зберігає JSON документи(чи записи), які ви можете використати у своєму застосунку. На відміну від SQL, іншого типу бази даних, Mongo це нереляційна, або \"NoSQL\" база даних. Це означає, що Mongo зберігає усі збірні дані в межах одного запису, замість того, щоб тримати їх у багатьох попередньо налаштованих таблицях, як у базі даних SQL.", - "Moongoose це популярний пакет npm, який часто встановлюють разом із Mongo. З Moongoose ви можете використовувати прості об'єкти JavaScript замість JSON, що полегшує роботу із Mongo. Він також дозволяє створити нарис документів під назвою \"схеми\", щоб ви ненароком не зберегли хибний тип даних та потім не спричинили помилок.", - "На курсах MongoDB та Mongoose, ви вивчите основи роботи із постійними даними, враховуючи налаштування моделі, збереження, видалення та пошук документів у базі даних." + "MongoDB – це програма бази даних, яка зберігає JSON документи (чи записи), які ви можете використати у своєму застосунку. На відміну від SQL, іншого типу бази даних, MongoDB – це нереляційна, або «NoSQL» база даних. Це означає, що MongoDB зберігає усі збірні дані в межах одного запису, замість того, щоб тримати їх у багатьох попередньо налаштованих таблицях, як у базі даних SQL.", + "Moongoose – це популярний пакет npm для взаємодії з MongoDB. З Moongoose ви можете використовувати прості об'єкти JavaScript замість JSON, що полегшує роботу із MongoDB. Він також дозволяє створити нарис документів під назвою «схеми», щоб ви ненароком не зберегли хибний тип даних та не спричинили помилок.", + "На курсах MongoDB та Mongoose ви вивчите основи роботи із постійними даними, враховуючи налаштування моделі, збереження, видалення та пошук документів у базі даних." ] }, "back-end-development-and-apis-projects": { - "title": "Бекенд розробка та проєкти API", + "title": "Проєкти «Розробка Back End та API»", "intro": [ "Раніше ви уже мали справу з API, але тепер, коли ви знайомі із nmp, Node, Express, Mongo DB та Mongoose, прийшов час створити щось власне. Застосуйте усі отримані знання, щоб створити 5 окремих мікросерверів, які є меншими застосунками з обмеженими можливостями.", - "Створивши їх, ви матимете 5 крутих API мікросерверів, якими можна похвалитися перед друзями, рідними чи потенційними роботодавцями. О, а ще новенька бекенд розробка та сертифікати API." + "Створивши їх, ви матимете 5 крутих API мікросерверів, якими можна похвалитися перед друзями, рідними чи потенційними роботодавцями. О, а ще новеньку сертифікацію «Розробка Back End та APIs»." ] } } @@ -623,8 +623,8 @@ "quality-assurance": { "title": "Забезпечення якості", "intro": [ - "Оскільки ваші програми чи вебзастосунки стають складнішими, ви захочете протестувати їх, щоб переконатися, що нові зміни не порушують їх початкових функцій.", - "У межах сертифікації \"Забезпечення якості\" ви дізнаєтесь, як писати тести з Chai, щоб переконатись, що ваші застосунки працюють так, як ви очікуєте.", + "Оскільки ваші програми чи вебзастосунки стають складнішими, ви захочете протестувати їх, щоб переконатися, що нові зміни не порушують початкові функції.", + "У сертифікації «Забезпечення якості» ви дізнаєтесь як писати тести з Chai, щоб переконатись, що ваші застосунки працюють так, як ви очікуєте.", "Потім ви створите застосунок чату, щоб вивчити розширені концепції Node та Express. Ви також будете використовувати Pug як шаблонізатор, Passport для автентифікації та Socket.io для комунікування в режимі реального часу між сервером та підключеними клієнтами." ], "note": "", @@ -632,7 +632,7 @@ "quality-assurance-and-testing-with-chai": { "title": "Забезпечення якості та тестування з Chai", "intro": [ - "Chai - це бібліотека тестування JavaScript, яка допомагає вам переконатись, що ваша програма все ще поводиться так, як ви очікуєте, після внесення змін до коду.", + "Chai – це бібліотека тестування JavaScript, яка допомагає вам переконатись, що ваша програма все ще поводиться так, як ви очікуєте, після внесення змін до коду.", "Використовуючи Chai, ви зможете писати тести, які описують ваші програмні вимоги, та бачити чи ваш застосунок відповідає їм.", "У цьому курсі ви дізнаєтесь про припущення, глибоку рівність, правдивість, тестування API та інші основи тестування програм JavaScript." ] @@ -642,51 +642,51 @@ "intro": [ "Настав час глибоко зануритися у Node.js та Express.js, створивши застосунок чату із системою входу.", "Щоб безпечно впровадити систему входу, вам потрібно буде дізнатися про автентифікацію. Це акт перевірки особи або процесу.", - "У цьому курсі ви дізнаєтесь, як використовувати Passport для управління автентифікацією, Pug для створення шаблонів багаторазового використання для швидкого створення інтерфейсу та веб-сокети для комунікування в реальному часі між клієнтами та сервером." + "У цьому курсі ви дізнаєтесь, як використовувати Passport для управління автентифікацією, Pug для створення шаблонів багаторазового використання для швидкого створення інтерфейсу та вебсокети для комунікування в реальному часі між клієнтами та сервером." ] }, "quality-assurance-projects": { - "title": "Проєкти забезпечення якості", + "title": "Проєкти «Забезпечення якості»", "intro": [ - "Тепер, коли ви добре розбираєтесь у фронт енд та бек енд, настав час застосувати всі навички та концепції, які ви вивчили до цього моменту. Ви створите 5 різних веб-застосунків і напишете тести для кожного, щоб переконатися чи вони працюють і обробляють всі можливі сценарії (edge cases).", + "Тепер, коли ви добре розбираєтесь у фронт енд та бек енд, настав час застосувати всі навички та концепції, які ви вивчили до цього моменту. Ви створите 5 різних вебзастосунків і напишете тести для кожного, щоб переконатися чи вони працюють і обробляють всі можливі сценарії.", "Після завершення цих проєктів із забезпечення якості у вас буде ще 5 проєктів, а також нова сертифікація, якою можна похвалитись у портфоліо." ] } } }, "scientific-computing-with-python": { - "title": "Наукові обчислення за допомогою Python", + "title": "Наукові обчислення з Python", "intro": [ - "Python - одна з найпопулярніших, гнучких мов програмування на сьогодні. Ви можете використовувати її для всього - від базових скриптів до машинного навчання.", - "У сертифікації про наукові обчислення з Python ви дізнаєтесь основи Python, такі як змінні, цикли, умовні переходи та функції. Тоді ви швидко перейдете до складних структур даних, роботи з мережами, реляційних баз даних та візуалізації даних." + "Python – одна з найпопулярніших, гнучких мов програмування на сьогодні. Ви можете використовувати її для всього: від базових скриптів до машинного навчання.", + "У сертифікації «Наукові обчислення з Python» ви дізнаєтесь основи Python, такі як змінні, цикли, умовні переходи та функції. Тоді ви швидко перейдете до складних структур даних, роботи з мережами, реляційних баз даних та візуалізації даних." ], "note": "", "blocks": { "python-for-everybody": { "title": "Python для всіх", "intro": [ - "Python для всіх - це безкоштовна серія відеокурсів, яка вчить основам використання Python 3.", - "Курси були створені доктором Чарльзом Северансом (також відомим як Dr. Chuck). Він є професором школи інформації університету Мічигану, де викладає різні технологічні курси, включаючи програмування, дизайн баз даних та веброзробку." + "Python для всіх – це безоплатна серія відеокурсів, яка вчить основам використання Python 3.", + "Курси були створені Чарльзом Северансом (також відомим як Dr. Chuck). Він є професором школи інформації університету Мічигану, де викладає різні технологічні курси, включно з програмуванням, дизайном баз даних та веброзробкою." ] }, "scientific-computing-with-python-projects": { - "title": "Наукові обчислення за допомогою Python проєктів", + "title": "Проєкти «Наукові обчислення з Python»", "intro": [ - "Час перевірити свої навички роботи з Python. Завершивши ці проєкти, ви продемонструєте, що володієте хорошими фундаментальними знаннями Python і маєте право на сертифікацію з наукових обчислень з Python." + "Час перевірити свої навички роботи з Python. Завершивши ці проєкти, ви продемонструєте, що володієте хорошими фундаментальними знаннями Python і маєте право на сертифікацію «Наукові обчислення з Python»." ] } } }, "data-analysis-with-python": { - "title": "Аналіз даних за допомогою Python", + "title": "Аналіз даних з Python", "intro": [ "Аналіз даних існує вже давно. Але ще кілька років тому розробники практикували його за допомогою дорогих інструментів із закритим кодом, таких як Tableau. Але нещодавно Python, SQL та інші відкриті бібліотеки назавжди змінили аналіз даних.", - "У сертифікації \"Аналіз даних за допомогою Python\" ви дізнаєтесь про основи аналізу даних за допомогою Python. Наприкінці цієї сертифікації ви будете знати, як читати дані з таких джерел, як CSV та SQL, і як використовувати бібліотеки, такі як Numpy, Pandas, Matplotlib та Seaborn для обробки та візуалізації даних." + "У сертифікації «Аналіз даних з Python» ви дізнаєтесь про основи аналізу даних за допомогою Python. Наприкінці цієї сертифікації ви будете знати, як читати дані з таких джерел, як CSV та SQL, і як використовувати бібліотеки, такі як Numpy, Pandas, Matplotlib та Seaborn для обробки та візуалізації даних." ], "note": "", "blocks": { "data-analysis-with-python-course": { - "title": "Аналіз даних за допомогою Python", + "title": "Аналіз даних з Python", "intro": [ "У цих комплексних відеокурсах, створених Сантьяго Басульто, ви дізнаєтесь про весь процес аналізу даних. Ви будете зчитувати дані з різних джерел (CSV, SQL, Excel), обробляти ці дані за допомогою NumPy та Pandas і візуалізувати їх за допомогою Matplotlib та Seaborn,", "Крім того, ми включили детальний курс по Jupyter Notebook та короткий довідник з Python, щоб оновити ваші навички програмування." @@ -700,10 +700,10 @@ ] }, "data-analysis-with-python-projects": { - "title": "Проєкт Аналіз даних за допомогою Python", + "title": "Проєкти «Аналіз даних з Python»", "intro": [ "Існує багато способів аналізу даних за допомогою Python. Завершивши ці проєкти, ви продемонструєте, що володієте хорошими фундаментальними знаннями аналізу даних, використовуючи Python.", - "Завершіть всі проєкти, щоб отримати сертифікат з аналізу даних, використовуючи Python." + "Завершіть всі проєкти, щоб отримати сертифікацію «Аналіз даних з Python»." ] } } @@ -712,30 +712,30 @@ "title": "Інформаційна безпека", "intro": [ "Завдяки всьому, що ми робимо в Інтернеті, величезна кількість конфіденційної інформації знаходиться в зоні ризику: електронні адреси, паролі, номери телефонів тощо.", - "Завдяки сертифікації із інформаційної безпеки ви створите безпечний веб-застосунок за допомогою HelmetJS, щоб вивчити основи захисту інформації людей в Інтернеті.", - "Ви також створите TCP-клієнт, а також Nmap і сканер портів у Python. Це допоможе вам вивчити основи тесту на проникнення — важливого компоненту надійної інформаційної безпеки." + "Завдяки сертифікації «Інформаційна безпека» ви створите безпечний вебзастосунок за допомогою HelmetJS, щоб вивчити основи захисту інформації людей в Інтернеті.", + "Ви також створите TCP client, а ще Nmap і сканер портів у Python. Це допоможе вам вивчити основи тесту на проникнення – важливого компоненту надійної інформаційної безпеки." ], "note": "", "blocks": { "information-security-with-helmetjs": { - "title": "Інформаційна безпека за допомогою HelmetJS", + "title": "Інформаційна безпека з HelmetJS", "intro": [ "Цей курс програмування зосереджений на HelmetJS, типі проміжного програмного забезпечення для застосунків на основі Express, яке автоматично встановлює заголовки HTTP. Таким чином, він може запобігти випадковому передаванню конфіденційної інформації між сервером та клієнтом.", - "Завершення цих курсів допоможе вам зрозуміти, як захистити свій сайт від зловмисної поведінки." + "Завершення курсів допоможе вам зрозуміти, як захистити свій сайт від зловмисної поведінки." ] }, "python-for-penetration-testing": { - "title": "Python для тесту на проникнення (penetration testing)", + "title": "Python для тесту на проникнення", "intro": [ - "Ці відеокурси навчать вас тесту на проникнення за допомогою Python. Також відомий як пен тест (pen test), тест на проникнення — це змодельована атака на систему, задля перевірки її на вразливі місця.", + "Ці відеокурси навчать вас тесту на проникнення за допомогою Python. Також відомий як пен тест (pen test), тест на проникнення – це змодельована атака на систему задля перевірки на вразливі місця.", "У цьому курсі ви дізнаєтеся про сокети, створите TCP сервер та клієнт, створите Nmap сканер і інші інструменти та техніки, які пен тестувальники використовують щоденно." ] }, "information-security-projects": { - "title": "Проєкти інформаційної безпеки", + "title": "Проєкти «Інформаційна безпека»", "intro": [ "Настав час перевірити ваші навички з інформаційної безпеки на практиці. Ці проєкти дадуть вам шанс застосувати всі набуті вміння, вивчені правила та поняття з інформаційної безпеки.", - "Коли ви закінчите, у вас буде достатньо проєктів з інформаційної безпеки за плечима, разом з сертифікатом, який ви зможете показати вашим друзям, сім'ї та роботодавцям." + "Коли ви закінчите, у вас буде достатньо проєктів з інформаційної безпеки за плечима, разом з сертифікацією, якою ви можете похизуватись перед друзям, сім'єю та роботодавцями." ] } } @@ -744,7 +744,7 @@ "title": "Машинне навчання з Python", "intro": [ "Машинне навчання має багато практичних застосунків, які ви можете використовувати у своїх проєктах чи роботі.", - "У сертифікаті \"Машинне навчання з Python\" ви використовуватимете фреймворк TensorFlow, аби створити декілька нейронних мереж і вивчити складніші техніки, такі як обробка природної мови й навчання з підкріпленням.", + "У сертифікації «Машинне навчання з Python» ви використовуватимете фреймворк TensorFlow, аби створити декілька нейронних мереж і вивчити складніші техніки, такі як обробка природної мови й навчання з підкріпленням.", "Також ви зануритеся у нейронні мережі та вивчите правила, за якими працюють глибокі, рекурентні та згорткові нейронні мережі." ], "note": "", @@ -752,8 +752,8 @@ "tensorflow": { "title": "Tensorflow", "intro": [ - "Tensorflow — це фреймворк з відкритим вихідним кодом, що полегшує використання машинного навчання та нейронних мереж.", - "Наступний відеокурс був створений Тімом Рущіцею, який має сайт \"Tech With Tim\". Він допоможе вам зрозуміти TensorFlow і деякі з його потужних можливостей." + "Tensorflow – це фреймворк з відкритим вихідним кодом, що полегшує використання машинного навчання та нейронних мереж.", + "Наступний відеокурс був створений Тімом Рущіцею, також відомим як «Tech With Tim». Він допоможе зрозуміти TensorFlow і деякі з його потужних можливостей." ] }, "how-neural-networks-work": { @@ -764,9 +764,9 @@ ] }, "machine-learning-with-python-projects": { - "title": "Проєкти машинного навчання з Python", + "title": "Проєкти «Машинне навчання з Python»", "intro": [ - "Машинне навчання може бути дуже корисним. Завершивши ці безплатні складні проєкти з програмування, ви покажете, що маєте базові знання з машинного навчання й отримаєте сертифікат \"Машинне навчання з Python\"." + "Машинне навчання може бути дуже корисним. Завершивши ці безоплатні складні проєкти з програмування, ви покажете, що маєте базові знання з машинного навчання й отримаєте сертифікацію «Машинне навчання з Python»." ] } } @@ -774,7 +774,7 @@ "coding-interview-prep": { "title": "Підготовка до співбесіди по кодуванню", "intro": [ - "Шукаєте безплатні вправи з кодування, щоб підготуватися до наступної співбесіди? Ми уже про це подбали.", + "Шукаєте безоплатні вправи з кодування, щоб підготуватися до наступної співбесіди? Ми уже про це подбали.", "Цей розділ містить сотні завдань з програмування, які перевіряють ваші знання алгоритмів, структур даних і математики. Тут також є декілька проєктів, які ви можете використати для зміцнення своїх навичок або просто додати до свого портфоліо." ], "note": "", @@ -782,7 +782,7 @@ "algorithms": { "title": "Алгоритми", "intro": [ - "Ці вправи з безоплатного програмування навчать вас загальних алгоритмів, з якими ви скоріш за все зіткнетеся в житті. Це чудова можливість вдосконалити як логіку, так і програмувальні навички.", + "Ці безоплатні вправи з програмування навчать вас загальних алгоритмів, з якими ви скоріш за все зіткнетеся в житті. Це чудова можливість вдосконалити як логіку, так і програмувальні навички.", "Подібні алгоритми часто використовують на співбесідах, щоб перевірити навички кандидатів. Ми чітко пояснимо, як саме функціонують різноманітні алгоритми, щоб ви могли підібрати рішення до кожного." ] }, @@ -804,34 +804,35 @@ "title": "Rosetta Code", "intro": [ "Розвиньте свої навички творчого підходу до розв'язання проблем за допомогою завдань з базової бібліотеки Rosetta Code.", - "Ці завдання можуть виявитися важкими, але вони підштовхнуть ваше логічне мислення до нових висот." + "Ці завдання можуть виявитися важкими, але вони підштовхнуть ваше логічне мислення до нових висот.", + "Атрибут: Rosetta Code" ] }, "project-euler": { - "title": "Проєкт Ейлер", + "title": "Проєкт «Ейлер»", "intro": [ - "Зробіть ці завдання з програмування з архівів проєкту Ейлер. Вони удосконалять ваші алгоритмічні та математичні знання.", + "Виконайте завдання з програмування з архівів проєкту «Ейлер». Вони удосконалять ваші алгоритмічні та математичні знання.", "Тут є завдання різної складності, а для багатьох здобуття досвіду полягає в індуктивному методі навчання. Тобто, вирішення одного завдання прояснить нову концепцію та дозволить вирішити раніше незрозумілу задачу. Чи під силу вам вирішити кожну?" ] } } }, "misc-text": { - "certification": "{{cert}} сертифікат", - "browse-other": "Перегляньте інші безплатні сертифікати\n(ми рекомендуємо робити це послідовно)", + "certification": "Сертифікація {{cert}}", + "browse-other": "Перегляньте інші безоплатні сертифікації\n(ми рекомендуємо робити це послідовно)", "courses": "Курси", "steps": "Кроки", - "expand": "Expand course", - "collapse": "Collapse course", - "legacy-header": "Legacy Courses", - "legacy-desc": "These courses are no longer part of the certification path, but are still available for you to further your learning.", - "legacy-go-back": "Go to the current version of the curriculum.", - "new-rwd-desc": "We have updated our Responsive Web Design Curriculum. If you were previously working on the RWD curriculum, your progress is still saved! You can find it under the Legacy Responsive Web Design section.", - "new-rwd-article": "We encourage you to read about the changes we made and consider exploring the updated curriculum.", - "viewing-upcoming-change": "You are looking at a beta page. ", - "go-back-to-learn": "Go back to the stable version of the curriculum.", - "read-database-cert-article": "Please read this forum post before proceeding.", - "enable-cookies": "You must enable third-party cookies before starting.", - "english-only": "The courses in this section are only available in English. We are only able to translate the titles and introductions at the moment, not the lessons themselves." + "expand": "Розгорнути курс", + "collapse": "Згорнути курс", + "legacy-header": "Застарілі курси", + "legacy-desc": "Ці курси більше не входять до сертифікацій, але вони все ще доступні для навчання.", + "legacy-go-back": "Перейти до поточної версії навчальної програми.", + "new-rwd-desc": "Ми оновили нашу навчальну програму «Адаптивний вебдизайн». Якщо ви раніше працювали з навчальною програмою, ваш прогрес досі збережено! Ви можете знайти його в секції «Застарілий адаптивний вебдизайн».", + "new-rwd-article": "Ми радимо прочитати про внесені зміни та розглянути можливість вивчення оновленої навчальної програми.", + "viewing-upcoming-change": "Ви дивитесь на бета-версію сторінки. ", + "go-back-to-learn": "Поверніться до стабільної версії навчальної програми.", + "read-database-cert-article": "Будь ласка, прочитайте повідомлення на форумі, перш ніж продовжити.", + "enable-cookies": "Ви повинні ввімкнути сторонні файли cookie перед початком роботи.", + "english-only": "Курси в цьому розділі доступні лише англійською мовою. Наразі ми можемо перекладати лише заголовки й вступи, а не самі уроки." } } diff --git a/client/i18n/locales/ukrainian/links.json b/client/i18n/locales/ukrainian/links.json index 65f62b29c19ce1..d94c781872c64a 100644 --- a/client/i18n/locales/ukrainian/links.json +++ b/client/i18n/locales/ukrainian/links.json @@ -13,7 +13,10 @@ "copyright-url": "https://www.freecodecamp.org/news/copyright-policy/" }, "donate": { - "other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp" + "other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp", + "download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf", + "download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf", + "one-time-url": "https://paypal.me/freecodecamp" }, "nav": { "forum": "https://forum.freecodecamp.org/", @@ -23,6 +26,6 @@ "HTML-CSS": "HTML-CSS", "JavaScript": "JavaScript", "Python": "Python", - "Relational Databases": "Relational Databases" + "Backend Development": "Backend Development" } } diff --git a/client/i18n/locales/ukrainian/meta-tags.json b/client/i18n/locales/ukrainian/meta-tags.json index cf2020dbfb80e6..f3280cca892f9c 100644 --- a/client/i18n/locales/ukrainian/meta-tags.json +++ b/client/i18n/locales/ukrainian/meta-tags.json @@ -1,21 +1,21 @@ { - "title": "Learn to Code — For Free — Coding Courses for Busy People", - "description": "Learn to Code — For Free", - "social-description": "Learn to Code — For Free", + "title": "Навчіться кодувати безкоштовно: курси кодування для зайнятих людей", + "description": "Навчіться кодувати безкоштовно. Створюйте проєкти. Отримуйте сертифікати. З 2014 року, понад 40 000 випускників freeCodeCamp.org отримали роботу в найбільших технологічних компаніях, як-от Apple, Google та Amazon.", + "social-description": "Навчіться кодувати БЕЗКОШТОВНО", "keywords": [ "python", "javascript", "js", "git", "github", - "website", - "web", - "development", + "вебсайт", + "веб", + "розробка", "free", "code", "camp", - "course", - "courses", + "курс", + "курси", "html", "css", "react", @@ -24,9 +24,10 @@ "front", "back", "end", - "learn", - "tutorial", - "programming" + "навчитись", + "вивчити", + "туторіал", + "програмування" ], - "youre-unsubscribed": "You have been unsubscribed" + "youre-unsubscribed": "Вашу підписку скасовано" } diff --git a/client/i18n/locales/ukrainian/translations.json b/client/i18n/locales/ukrainian/translations.json index d494917a2b5d34..a17a6ff8bc40ce 100644 --- a/client/i18n/locales/ukrainian/translations.json +++ b/client/i18n/locales/ukrainian/translations.json @@ -1,19 +1,19 @@ { "buttons": { - "logged-in-cta-btn": "Почніть (це безкоштовно)", - "logged-out-cta-btn": "Увійдіть, щоб зберегти ваш прогрес (це безкоштовно)", + "logged-in-cta-btn": "Розпочати (безоплатно)", + "logged-out-cta-btn": "Увійдіть, щоб зберегти прогрес (безоплатно)", "view-curriculum": "Переглянути навчальну програму", "first-lesson": "Перейти до першого уроку", "close": "Закрити", "edit": "Редагувати", "show-code": "Показати код", "show-solution": "Показати рішення", - "show-project": "Show Project", - "frontend": "Фронтенд (Front End)", - "backend": "Бекенд (Back End)", + "show-project": "Показати проєкт", + "frontend": "Front End", + "backend": "Back End", "view": "Перегляд", - "show-cert": "Показати сертифікат", - "claim-cert": "Отримати сертифікат", + "show-cert": "Показати сертифікацію", + "claim-cert": "Отримати сертифікацію", "save-progress": "Зберегти прогрес", "accepted-honesty": "Ви прийняли нашу Політику академічної доброчесності.", "agree": "Прийняти", @@ -26,7 +26,7 @@ "off": "Вимкнути", "on": "Увімкнути", "sign-in": "Увійти", - "sign-up-email-list": "Sign up for Quincy's weekly emails", + "sign-up-email-list": "Підписатись на щотижневу розсилку від Квінсі", "sign-out": "Вийти", "curriculum": "Навчальна програма", "forum": "Форум", @@ -49,8 +49,9 @@ "cancel": "Скасувати", "reset-lesson": "Скинути цей урок", "run": "Запустити", - "run-test": "Run the Tests (Ctrl + Enter)", - "check-code": "Check Your Code (Ctrl + Enter)", + "run-test": "Протестувати (Ctrl + Enter)", + "check-code": "Перевірити код (Ctrl + Enter)", + "check-code-2": "Перевірити код", "reset": "Скинути", "reset-code": "Скинути весь код", "help": "Допомога", @@ -59,7 +60,7 @@ "resubscribe": "Натисніть тут для повторної підписки", "click-here": "Натисніть тут, щоб увійти", "save": "Зберегти", - "save-code": "Save your Code", + "save-code": "Збережіть свій код", "no-thanks": "Ні, дякую", "yes-please": "Так, будь ласка", "update-email": "Оновити мою адресу електронної пошти", @@ -67,56 +68,60 @@ "submit-and-go": "Відправити та перейти до наступного завдання", "go-to-next": "Перейти до наступного завдання", "ask-later": "Запитати пізніше", - "start-coding": "Start coding!", - "go-to-settings": "Go to settings to claim your certification", - "click-start-course": "Start the course", - "click-start-project": "Start the project" + "start-coding": "Почніть кодувати!", + "go-to-settings": "Перейдіть до налаштувань, щоб отримати сертифікацію", + "click-start-course": "Розпочати курс", + "click-start-project": "Розпочати проєкт", + "change-language": "Змінити мову", + "cancel-change": "Скасувати зміни", + "resume-project": "Відновити проєкт", + "start-project": "Розпочати проєкт" }, "landing": { - "big-heading-1": "Вчіться програмувати — це безкоштовно.", - "big-heading-2": "Створюйте проекти.", - "big-heading-3": "Отримуйте сертифікати.", + "big-heading-1": "Вчіться програмувати безоплатно.", + "big-heading-2": "Створюйте проєкти.", + "big-heading-3": "Отримуйте сертифікації.", "h2-heading": "З 2014 року, понад 40 000 випускників freeCodeCamp.org отримали роботу в технологічних компаніях, таких як:", "hero-img-description": "Cтуденти місцевої навчальної групи freeCodeCamp в Південній Кореї.", "as-seen-in": "Про нас пишуть:", "testimonials": { "heading": "Ось що наші випускники говорять про freeCodeCamp:", "shawn": { - "location": "Шон Ванг з Сінгапуру", + "location": "Шон Вонг з Сінгапуру", "occupation": "Інженер програмного забезпечення в Amazon", - "testimony": "\"Змінювати професію — страшно. Я набув впевненості в програмуванні лише після того, як пройшов сотні годин безкоштовних занять на freeCodeCamp. І вже за рік я отримав роботу інженера програмного забезпечення з шестизначною заплатою. freeCodeCamp змінив моє життя.\"" + "testimony": "«Змінювати професію – страшно. Я набув впевненості в програмуванні лише після того, як пройшов сотні годин безоплатних занять на freeCodeCamp. І вже за рік я отримав роботу інженера програмного забезпечення з шестизначною заплатою. freeCodeCamp змінив моє життя.»" }, "sarah": { "location": "Сара Чіма з Нігерії", "occupation": "Інженерка програмного забезпечення в ChatDesk", - "testimony": "\"freeCodeCamp став для мене пропуском у професію інженерки програмного забезпечення. Гарно структурована навчальна програма дозволила покращити свої знання з програмування з початкового рівня до дуже впевненого. Це все що було потрібно, щоб знайти свою першу роботу розробниці програмного забезпечення у чудовій компанії.\"" + "testimony": "«freeCodeCamp став для мене пропуском у професію інженерки програмного забезпечення. Гарно структурована навчальна програма дозволила покращити мої знання з програмування з початкового рівня до дуже впевненого. Це все що було потрібно, щоб знайти свою першу роботу розробниці програмного забезпечення у чудовій компанії.»" }, "emma": { "location": "Емма Бостіан зі Швеції", "occupation": "Інженерка програмного забезпечення в Spotify", - "testimony": "\"У мене завжди виникали труднощі при вивченні JavaScript. Я проходила багато курсів, але з курсом freeCodeCamp я залишилася надовго. Вивчення JavaScript, а також структур даних та алгоритмів у freeCodeCamp дало мені необхідні навички та впевненість, щоб знайти роботу моєї мрії — інженерка програмного забезпечення у Spotify.\"" + "testimony": "«У мене завжди виникали труднощі при вивченні JavaScript. Я проходила багато курсів, але з курсом freeCodeCamp я залишилася надовго. Вивчення JavaScript, а також структур даних та алгоритмів у freeCodeCamp дало мені необхідні навички та впевненість, щоб знайти роботу моєї мрії: інженерка програмного забезпечення у Spotify.»" } }, - "certification-heading": "Отримайте безкоштовні підтверджені сертифікати в таких сферах:" + "certification-heading": "Отримайте безоплатні підтверджені сертифікації в:" }, "settings": { "share-projects": "Діліться своїми проєктами, статтями або прийнятими пул реквестами, які не відносяться до freeCodeCamp.", - "privacy": "The settings in this section enable you to control what is shown on your freeCodeCamp public portfolio. Press save to save your changes.", - "data": "Щоб побачити, які дані ми зберігаємо на вашому обліковому записі, натисніть кнопку \"Завантажити дані\" нижче", - "disabled": "Ваші сертифікати будуть відключені, коли ввімкнено режим приватного перегляду.", - "private-name": "Ваше ім'я не буде показуватися на ваших сертифікатах, коли ввімкнено режим приватного перегляду.", - "claim-legacy": "Як тільки ви виконаєте завдання таких сертифікатів freeCodeCamp, ви зможете отримати {{cert}}:", + "privacy": "Налаштування в цьому розділі дозволяють керувати тим, що зображається на публічному портфоліо freeCodeCamp. Натисніть «Зберегти», щоб зберегти свої зміни.", + "data": "Щоб побачити, які дані ми зберігаємо на вашому обліковому записі, натисніть кнопку «Завантажити свої дані» нижче", + "disabled": "Ваші сертифікації будуть відключені, коли ввімкнено режим приватного перегляду.", + "private-name": "Ваше ім'я не буде показуватися на ваших сертифікаціях, коли ввімкнено режим приватного перегляду.", + "claim-legacy": "Як тільки ви виконаєте завдання наступних сертифікацій freeCodeCamp, ви зможете отримати {{cert}}:", "for": "Налаштування облікового запису для {{username}}", - "sound-mode": "This adds the pleasant sound of acoustic guitar throughout the website. You'll get musical feedback as you type in the editor, complete challenges, claim certifications, and more.", + "sound-mode": "Це додає приємне звучання акустичної гітари на всьому вебсайті. Ви почуєте музичний супровід, коли будете писати у редакторі, при завершенні випробувань, при затвердженні сертифікацій та інше.", "username": { - "contains invalid characters": "Ім'я користувача \"{{username}}\" містить неприпустимі символи", - "is too short": "Ім'я користувача \"{{username}}\" занадто коротке", - "is a reserved error code": "Ім'я користувача \"{{username}}\" є зарезервованим кодом помилки", - "must be lowercase": "Ім'я користувача \"{{username}}\" має бути написано в нижньому регістрі", + "contains invalid characters": "Ім'я користувача «{{username}}» містить неприпустимі символи", + "is too short": "Ім'я користувача «{{username}}» занадто коротке", + "is a reserved error code": "Ім'я користувача «{{username}}» є зарезервованим кодом помилки", + "must be lowercase": "Ім'я користувача «{{username}}» має бути маленькими буквами", "unavailable": "Ім'я користувача недоступне", "validating": "Перевірка імені користувача...", "available": "Ім'я користувача доступне", - "change": "Будь ласка, зверніть увагу, що зміна імені користувача також змінить URL-адресу вашого профілю та ваших сертифікатів." + "change": "Будь ласка, зверніть увагу, що зміна імені користувача також змінить URL-адресу вашого профілю та сертифікацій." }, "labels": { "username": "Ім'я користувача", @@ -124,7 +129,7 @@ "location": "Місцеперебування", "picture": "Фото", "about": "Про", - "personal": "Особиста веб-сторінка", + "personal": "Особиста вебсторінка", "title": "Заголовок", "url": "URL-адреса", "image": "Зображення", @@ -138,16 +143,17 @@ "my-about": "Про мене", "my-points": "Мої бали", "my-heatmap": "Моя теплокарта", - "my-certs": "Мої сертифікати", + "my-certs": "Мої сертифікації", "my-portfolio": "Моє портфоліо", "my-timeline": "Моя хронологія", "my-donations": "Мої внески", "night-mode": "Нічний режим", - "sound-mode": "Режим багаття" + "sound-mode": "Режим багаття", + "keyboard-shortcuts": "Увімкнути клавіатурні скорочення" }, "headings": { - "certs": "Сертифікати", - "legacy-certs": "Застарілі сертифікати", + "certs": "Сертифікації", + "legacy-certs": "Застарілі сертифікації", "honesty": "Політика академічної доброчесності", "internet": "Ваша присутність в інтернеті", "portfolio": "Налаштування портфоліо", @@ -161,11 +167,11 @@ "delete-title": "Видалити мій обліковий запис", "delete-p1": "Це дійсно видалить усі ваші дані (весь ваш прогрес та дані облікового запису також).", "delete-p2": "Ми не зможемо відновити ці дані для вас пізніше, навіть якщо ви передумаєте.", - "delete-p3": "Якщо у вас є пропозиція щодо покращення проекту, надішліть нам електронний лист, і ми зробимо все можливе: <0>{{email}}", + "delete-p3": "Якщо у вас є пропозиція щодо покращення проєкту, надішліть нам електронний лист, і ми зробимо все можливе: <0>{{email}}", "nevermind": "Я не хочу видаляти свій обліковий запис.", - "certain": "Я впевнений на 100%. Видаліть все, що пов'язане з цим обліковим записом.", + "certain": "Я впевнений(-а) на 100%. Видаліть все, що пов'язане з цим обліковим записом.", "reset-heading": "Скинути мій прогрес", - "reset-p1": "Це дійсно видалить весь ваш прогрес (бали, завершені завдання, наші записи ваших проєктів, будь-які отримані сертифікати) та всі дані.", + "reset-p1": "Це дійсно видалить весь ваш прогрес (бали, завершені завдання, наші записи ваших проєктів, будь-які отримані сертифікації) та всі дані.", "reset-p2": "Ми не зможемо відновити ці дані для вас пізніше, навіть якщо ви передумаєте.", "nevermind-2": "Я не хочу видаляти весь мій прогрес.", "reset-confirm": "Скинути все. Я хочу почати з початку." @@ -174,31 +180,31 @@ "missing": "У вас немає електронної пошти, пов'язаної з цим обліковим записом.", "heading": "Налаштування електронної пошти", "not-verified": "Вашу електронну пошту не підтверджено.", - "check": "Будь ласка, перевірте вашу електронну пошту, або <0>надішліть запит на новий лист для підтвердження.", + "check": "Будь ласка, перевірте свою електронну пошту, або <0>надішліть запит на новий лист для підтвердження.", "current": "Поточна адреса електронної пошти", "new": "Нова адреса електронної пошти", "confirm": "Підтвердити нову адресу електронної пошти", "weekly": "Надсилати мені щотижневу розсилку від Квінсі" }, "honesty": { - "p1": "Перш ніж ви зможете претендувати на підтверджений сертифікат, ви повинні прийняти Обітницю академічної доброчесності, яка свідчить про те, що:", - "p2": "\"Я розумію, що плагіат означає копіювання чужої роботи та оприлюднення її під своїм іменем без належного посилання на оригінального автора.\"", - "p3": "\"Я розумію, що плагіат є актом інтелектуальної нечесності, і те, що людей зазвичай виганяють з університету чи звільняють з роботи, якщо їх спіймають на плагіаті.\"", - "p4": "\"Окрім використання бібліотек з відкритим вихідним кодом, таких як jQuery і Bootstrap, а також коротких фрагментів коду, де є посилання на оригінального автора, 100% коду в моїх проектах написано мною, або разом з іншим студентом, який проходив навчальну програму freeCodeCamp, з яким я займався парним програмуванням в режимі реального часу.\"", - "p5": "\"Я зобов'язуюсь, що жоден з моїх проєктів freeCodeCamp.org не буде плагіатом. Я розумію, що команда freeCodeCamp.org буде перевіряти мої проєкти, щоб підтвердити це.\"", - "p6": "У ситуаціях, коли ми виявляємо випадки однозначного плагіату, ми замінюємо сертифікат цієї людини повідомленням про те, що \"Після перевірки, цей обліковий запис був позначено як той, що порушує академічну доброчесність.\"", - "p7": "Як академічна установа, яка надає сертифікати на основі досягнень, ми дуже серйозно ставимося до академічної доброчесності. Якщо у вас є будь-які запитання щодо цієї політики, або ви підозрюєте, що хтось порушив її, можете написати нам <0>{{email}} і ми розглянемо це питання." + "p1": "Перш ніж ви зможете претендувати на підтверджену сертифікацію, ви повинні прийняти Обітницю академічної доброчесності, яка свідчить про те, що:", + "p2": "«Я розумію, що плагіат означає копіювання чужої роботи та оприлюднення її під своїм іменем без належного посилання на оригінального автора.»", + "p3": "«Я розумію, що плагіат є актом інтелектуальної нечесності, і те, що людей зазвичай виганяють з університету чи звільняють з роботи, якщо їх спіймають на плагіаті.»", + "p4": "«Окрім використання бібліотек з відкритим вихідним кодом, таких як jQuery і Bootstrap, а також коротких фрагментів коду, де є посилання на оригінального автора, 100% коду в моїх проєктах написано мною, або разом з іншим студентом, який проходив навчальну програму freeCodeCamp, з яким я займався(-лась) парним програмуванням в режимі реального часу.»", + "p5": "«Я зобов'язуюсь, що жоден з моїх проєктів freeCodeCamp.org не буде плагіатом. Я розумію, що команда freeCodeCamp.org буде перевіряти мої проєкти, щоб підтвердити це.»", + "p6": "У ситуаціях, коли ми виявляємо випадки однозначного плагіату, ми замінюємо сертифікацію цієї людини повідомленням про те, що «Після перевірки, цей обліковий запис був позначено як той, що порушує академічну доброчесність.»", + "p7": "Як академічна установа, яка надає сертифікації на основі досягнень, ми дуже серйозно ставимося до академічної доброчесності. Якщо у вас є будь-які запитання щодо цієї політики, або ви підозрюєте, що хтось порушив її, можете написати нам <0>{{email}} і ми розглянемо це питання." } }, "profile": { "you-not-public": "Ви не зробили портфоліо загальнодоступним.", - "username-not-public": "{{username}} не зробив своє портфоліо загальнодоступним.", + "username-not-public": "{{username}} не зробив(-ла) своє портфоліо загальнодоступним.", "you-change-privacy": "Вам потрібно змінити налаштування конфіденційності для того, щоб інші могли побачити ваше портфоліо. Це попередній перегляд того, як ваше портфоліо буде виглядати при відкритому доступі.", "username-change-privacy": "{{username}} має змінити налаштування конфіденційності для того, щоб ви могли переглянути портфоліо.", "supporter": "Прихильник", "contributor": "Найактивніший користувач", - "no-certs": "Не було отримано сертифікатів у цій навчальній програмі", - "fcc-certs": "freeCodeCamp сертифікати", + "no-certs": "Не було отримано сертифікацій у цій навчальній програмі", + "fcc-certs": "Сертифікації freeCodeCamp", "longest-streak": "Найбільша кількість днів без перерви:", "current-streak": "Поточна кількість днів без перерви:", "portfolio": "Портфоліо", @@ -207,11 +213,11 @@ "get-started": "Почніть тут.", "challenge": "Завдання", "completed": "Виконано", - "add-linkedin": "Додати цей сертифікат до мого профілю LinkedIn", - "add-twitter": "Поділитися цим сертифікатом у Twitter", - "tweet": "Я щойно отримав {{certTitle}} сертифікат @freeCodeCamp! Перегляньте його тут: {{certURL}}", + "add-linkedin": "Додати цю сертифікацію до мого профілю LinkedIn", + "add-twitter": "Поділитися цією сертифікацією у Twitter", + "tweet": "Я щойно отримав(-ла) сертифікацію {{certTitle}} від @freeCodeCamp! Перегляньте її тут: {{certURL}}", "avatar": "Аватар {{username}}", - "joined": "Приєднався {{date}}", + "joined": "Приєднався(-лась) {{date}}", "total-points": "{{count}} загальний бал", "total-points_plural": "{{count}} всього балів", "points": "{{count}} бал станом на {{date}}", @@ -220,12 +226,12 @@ "page-number": "{{pageNumber}} з {{totalPages}}" }, "footer": { - "tax-exempt-status": "freeCodeCamp — це некомерційна організація, яка підтримується спонсорськими внесками та звільнена від сплати податків 501(c)(3) (Федеральний ідентифікаційний номер платника податків США: 82-0779546)", - "mission-statement": "Ми хочемо допомогти людям безкоштовно навчитися програмувати. Ми досягаємо цього, створюючи тисячі відео, статей та інтерактивних уроків з програмування — вони усі доступні для широкого загалу. Також ми маємо тисячі безплатний навчальних груп freeCodeCamp у всьому світі.", + "tax-exempt-status": "freeCodeCamp – це некомерційна організація, яка підтримується спонсорськими внесками та звільнена від сплати податків 501(c)(3) (Федеральний ідентифікаційний номер платника податків США: 82-0779546)", + "mission-statement": "Ми хочемо допомогти людям безкоштовно навчитися програмувати. Ми досягаємо цього, створюючи тисячі відео, статей та інтерактивних уроків з програмування – вони усі доступні для широкого загалу. Також ми маємо тисячі безоплатних навчальних груп freeCodeCamp у всьому світі.", "donation-initiatives": "Внески до freeCodeCamp йдуть на наші освітні програми та допомагають оплачувати сервери, послуги та персонал.", - "donate-text": "You can <1>make a tax-deductible donation here.", + "donate-text": "Ви можете <1>зробити неоподаткований внесок тут.", "trending-guides": "Популярні статті", - "our-nonprofit": "Наша неприбуткова організація", + "our-nonprofit": "Наша некомерційна організація", "links": { "about": "Про нас", "alumni": "Спільнота випускників", @@ -247,21 +253,21 @@ "welcome-2": "Ласкаво просимо до freeCodeCamp.org", "start-at-beginning": "Якщо ви новачок у програмуванні, ми рекомендуємо <0>почати з самого початку.", "read-this": { - "heading": "Будь ласка, зупиніться і прочитайте це.", - "p1": "freeCodeCamp - це перевірений шлях до вашої першої роботи розробника програмного забезпечення.", + "heading": "Будь ласка, прочитайте це.", + "p1": "freeCodeCamp – це перевірений шлях до вашої першої роботи розробника програмного забезпечення.", "p2": "Після завершення курсу понад 40 000 людей отримали роботу у сфері розробки програмного забезпечення (в тому числі у великих компаніях, таких як Google і Microsoft).", - "p3": "Якщо ви новачок в програмуванні, ми радимо вам розпочати з самого початку та отримувати ці сертифікати послідовно.", - "p4": "Щоб отримати кожен сертифікат, створіть 5 необхідних проєктів і успішно пройдіть усі тести.", - "p5": "Ви можете додати ці сертифікати до свого резюме або LinkedIn. Але важливішим за сертифікати є практика, яку ви отримаєте під час навчання.", - "p6": "Якщо ви почуваєтесь перевантаженим, це нормально. Програмувати — важко.", - "p7": "Практика — це найголовніше. Практика, практика, практика.", + "p3": "Якщо ви новачок в програмуванні, ми радимо вам розпочати з самого початку та отримувати сертифікації послідовно.", + "p4": "Щоб отримати кожну сертифікацію, створіть 5 необхідних проєктів і успішно пройдіть усі тести.", + "p5": "Ви можете додати сертифікації до свого резюме або LinkedIn. Але важливішою за сертифікацію є практика, яку ви отримаєте під час навчання.", + "p6": "Якщо ви відчуваєте перевантаження, це нормально. Програмувати – важко.", + "p7": "Практика – це найголовніше. Практика, практика, практика.", "p8": "Ця навчальна програма дасть вам тисячі годин практики в програмуванні.", "p9": "А якщо ви бажаєте дізнатися більше про математику та теорію комп'ютерних наук, то у нас також є тисячі годин відеокурсів на <0>YouTube-каналі freeCodeCamp.", "p10": "Якщо ви хочете отримати роботу розробника або знайти клієнтів онлайн, навички програмування будуть лише частиною завдання. Вам також потрібно створити свою мережу контактів і сформувати репутацію розробника.", "p11": "Ви можете зробити це в Twitter і GitHub, а також на <0>форумі freeCodeCamp.", - "p12": "Вдалого програмування!" + "p12": "Щасливого кодування!" }, - "upcoming-lessons": "Наступні уроки", + "upcoming-lessons": "Майбутні уроки", "learn": "Навчання", "add-subtitles": "Допомогти покращити або додати субтитри", "wrong-answer": "Вибачте, але це неправильна відповідь. Спробуєте ще раз?", @@ -269,54 +275,56 @@ "solution-link": "Посилання на рішення", "github-link": "Посилання на GitHub", "submit-and-go": "Відправити та перейти до мого наступного завдання", - "congradulations": "Congratulations, your code passes. Submit your code to complete this step and move on to the next one.", - "i-completed": "Я виконав це завдання", + "congratulations": "Вітаємо, ваш код проходить. Відправте свій код, щоб продовжити.", + "i-completed": "Я виконав(-ла) це завдання", "test-output": "Результат вашого тесту буде доступний тут", - "running-tests": "// запуск тестів", - "tests-completed": "// тести виконано", + "running-tests": "// запущені тести", + "tests-completed": "// виконані тести", "console-output": "// вивід консолі", - "sign-in-save": "Увійдіть, щоб зберегти ваш прогрес", + "sign-in-save": "Увійдіть, щоб зберегти свій прогрес", "download-solution": "Завантажити моє рішення", "percent-complete": "{{percent}}% виконано", - "tried-rsa": "Якщо ви вже спробували метод <0>Читати-Шукати-Питати, то ви можете звернутися за допомогою на форумі freeCodeCamp.", - "rsa": "Читати, шукати, запитувати", + "tried-rsa": "Якщо ви вже спробували метод <0>читати-шукати-питати, то ви можете звернутися за допомогою на форум freeCodeCamp.", + "rsa": "Читати, шукати, питати", + "rsa-forum": "Before making a new post please see if your question has <0>already been answered on the forum.", "reset": "Скинути цей урок?", "reset-warn": "Ви впевнені, що хочете скинути цей урок? Редактори та тести будуть скинуті.", "reset-warn-2": "Цю дію неможливо відмінити", "scrimba-tip": "Порада: якщо мінібраузер закриває код, то натисніть та перетягніть його у сторону. Також не соромтеся зупинятися та редагувати код у відео у будь-який час.", "chal-preview": "Попередній перегляд завдання", "cert-map-estimates": { - "certs": "{{title}} Сертифікат (300 годин)", - "coding-prep": "{{title}} (Тисячі годин практики)" + "certs": "Сертифікація {{title}}" }, "editor-tabs": { "info": "Інформація", "code": "Код", "tests": "Тести", - "restart": "Restart", - "restart-step": "Restart Step", - "console": "Console", - "notes": "Notes", + "restart": "Перезапустити", + "restart-step": "Перезапустити крок", + "console": "Консоль", + "instructions": "Інструкції", + "notes": "Примітки", "preview": "Попередній перегляд" }, - "help-translate": "Ми все ще перекладаємо такі сертифікати.", + "help-translate": "Ми досі перекладаємо наступні сертифікації.", "help-translate-link": "Допоможіть нам з перекладом.", - "project-preview-title": "Here's a preview of what you will build", - "github-required": "<0>Create a GitHub account if you don't have one. You'll need it when you create the virtual Linux server machine. This process may take a few minutes.", - "step-1": "Step 1: Complete the project", - "step-2": "Step 2: Submit your code", - "submit-public-url": "When you have completed the project, save all the required files into a public repository and submit the URL to it below.", - "complete-both-steps": "Complete both steps below to finish the challenge.", - "runs-in-vm": "The project runs in a virtual machine, complete the user stories described in there and get all the tests to pass to finish step 1.", - "completed": "Completed", - "not-started": "Not started", - "hint": "Hint", - "test": "Test", - "sorry-try-again": "Sorry, your code does not pass. Try again.", - "sorry-keep-trying": "Sorry, your code does not pass. Keep trying.", - "sorry-getting-there": "Sorry, your code does not pass. You're getting there.", - "sorry-hang-in-there": "Sorry, your code does not pass. Hang in there.", - "sorry-dont-giveup": "Sorry, your code does not pass. Don't give up." + "project-preview-title": "Попередній перегляд того, що ви будете створювати", + "github-required": "<0>Створіть обліковий запис GitHub, якщо у вас його немає. Він вам знадобиться під час створення віртуальної серверної машини Linux. Цей процес може зайняти кілька хвилин.", + "step-1": "Крок 1: Завершіть проєкт", + "step-2": "Крок 2: Відправте код", + "submit-public-url": "Коли ви завершите проєкт, збережіть усі необхідні файли в загальнодоступному репозиторію та вкажіть URL-адресу на нього нижче.", + "complete-both-steps": "Виконайте обидва кроки, щоб закінчити завдання.", + "runs-in-vm": "Проєкт виконується в віртуальній машині; виконайте описані там історії користувачів та пройдіть всі тести, щоб завершити крок 1.", + "completed": "Виконано", + "not-started": "Не розпочато", + "hint": "Підказка", + "test": "Тест", + "sorry-try-again": "На жаль, ваш код не пройшов. Спробуйте ще раз.", + "sorry-keep-trying": "На жаль, ваш код не пройшов. Продовжуйте спроби.", + "sorry-getting-there": "На жаль, ваш код не пройшов. Ви йдете у правильному напрямку.", + "sorry-hang-in-there": "На жаль, ваш код не пройшов. Тримайтеся.", + "sorry-dont-giveup": "На жаль, ваш код не пройшов. Не здавайтеся.", + "challenges-completed": "{{completedCount}} з {{totalChallenges}} завдань виконано" }, "donate": { "title": "Підтримати нашу некомерційну організацію", @@ -324,22 +332,21 @@ "redirecting": "Переадресація...", "thanks": "Дякуємо за внесок", "thank-you": "Дякуємо за вашу підтримку.", - "thank-you-2": "Дякуємо вам за підтримку freeCodeCamp. У вас є регулярні внески.", "additional": "Ви можете зробити додатковий одноразовий внесок на будь-яку суму за цим посиланням: <0>{{url}}", "help-more": "Допоможіть нам розвиватися", "error": "Щось не так з вашим внеском.", - "error-2": "Something is not right. Please contact donors@freecodecamp.org", + "error-2": "Щось пішло не так. Будь ласка, зв'яжіться з donors@freecodecamp.org", "free-tech": "Ваші внески підтримуватимуть безкоштовну технологічну освіту для людей у всьому світі.", - "no-halo": "Якщо ви не бачите золотий ореол навколо фотографії вашого профілю, повідомте в donors@freecodecamp.org.", - "gift-frequency": "Оберіть частоту сплачення внесків:", + "no-halo": "Якщо ви не бачите золотий ореол навколо фотографії свого профілю, повідомте в donors@freecodecamp.org.", + "gift-frequency": "Оберіть частоту сплати внесків:", "gift-amount": "Оберіть розмір внеску:", - "confirm": "Підтвердьте ваш внесок", - "confirm-2": "Підтвердьте ваш одноразовий внесок у розмірі ${{usd}}", - "confirm-3": "Підтвердьте ваш внесок у розмірі ${{usd}} / на місяць", - "confirm-4": "Підтвердьте ваш внесок у розмірі ${{usd}} / на рік", - "wallet-label": "${{usd}} пожертвування для FreeCodeCamp", - "wallet-label-1": "${{usd}} / місячне пожертвування для FreeCodeCamp", - "your-donation": "Ваш внесок у розмірі ${{usd}} надасть {{hours}} годин навчання людям у всьому світі.", + "confirm": "Підтвердьте свій внесок", + "confirm-2": "Підтвердьте свій одноразовий внесок у розмірі ${{usd}}", + "confirm-3": "Підтвердьте свій внесок у розмірі ${{usd}} на місяць", + "confirm-4": "Підтвердьте свій внесок у розмірі ${{usd}} на рік", + "wallet-label": "Внесок ${{usd}} для FreeCodeCamp", + "wallet-label-1": "Внесок ${{usd}} на місяць для FreeCodeCamp", + "your-donation": "Ваш внесок у розмірі ${{usd}} надаватиме {{hours}} годин навчання людям у всьому світі.", "your-donation-2": "Ваш внесок у розмірі ${{usd}} щомісяця надаватиме {{hours}} годин навчання людям у всьому світі.", "your-donation-3": "Ваш внесок у розмірі ${{usd}} щороку надаватиме {{hours}} годин навчання людям у всьому світі.", "duration": "Станьте одноразовим спонсором нашої некомерційної організації.", @@ -359,8 +366,8 @@ "email-receipt": "Електронна пошта (ми надішлемо вам квитанцію про оплату внеску, що не підлягає оподаткуванню):", "need-help": "Потрібна допомога з поточними або попередніми внесками?", "forward-receipt": "Надішліть копію квитанції про оплату внеску на donors@freecodecamp.org і напишіть, як ми можемо вам допомогти.", - "efficiency": "freeCodeCamp — це високоефективна некомерційна освітня організація.", - "why-donate-1": "Коли ви робите внесок на freeCodeCamp, ви допомагаєте людям опанувати нові навички та забезпечувати їхні сім'ї.", + "efficiency": "freeCodeCamp – це високоефективна некомерційна освітня організація.", + "why-donate-1": "Коли ви робите внесок для freeCodeCamp, ви допомагаєте людям опанувати нові навички та забезпечувати їхні сім'ї.", "why-donate-2": "Ви також допомагаєте нам створювати нові ресурси для вас, щоб ви використовували їх для розширення власних технологічних навичок.", "bigger-donation": "Бажаєте зробити більший одноразовий внесок, відправити нам чек на електронну пошту або в інший спосіб?", "other-ways": "Існує багато <0>інших способів підтримати місію нашої некомерційної організації.", @@ -368,43 +375,43 @@ "try-again": "Будь ласка, повторіть спробу.", "card-number": "Номер вашої картки:", "expiration": "Дата закінчення терміну дії:", - "secure-donation": "Secure donation", - "faq": "Frequently asked questions", - "only-you": "Only you can see this message. Congratulations on earning this certification. It's no easy task. Running freeCodeCamp isn't easy either. Nor is it cheap. Help us help you and many other people around the world. Make a tax-deductible supporting donation to our nonprofit today.", - "get-help": "How can I get help with my donations?", - "how-transparent": "How transparent is freeCodeCamp.org?", - "very-transparent": "Very. We have a Platinum transparency rating from GuideStar.org.", - "download-irs": "You can <0>download our IRS Determination Letter here.", - "download-990": "You can <0>download our most recent 990 (annual tax report) here.", - "how-efficient": "How efficient is freeCodeCamp?", - "fcc-budget": "freeCodeCamp's budget is much smaller than most comparable nonprofits. We haven't brought in professional fundraisers. Instead, Quincy does everything himself.", - "help-millions": "However, on a budget of only a few hundred thousand dollars per year, we have been able to help millions of people.", - "how-one-time": "How can I make a one-time donation?", - "one-time": "If you'd prefer to make one-time donations, you can support freeCodeCamp's mission whenever you have cash to spare. You can use <0>this link to donate whatever amount feels right through PayPal.", - "wire-transfer": "You can also send money to freeCodeCamp directly through a wire transfer. If you need our wire details, email Quincy at quincy@freecodecamp.org", - "does-crypto": "Does freeCodeCamp accept donations in Bitcoin or other cryptocurrencies?", - "yes-cryptocurrency": "Yes. Please email Quincy at quincy@freecodecamp.org and he can send you freeCodeCamp's wallet information. He can also provide you with a donation receipt if you need one for your taxes.", - "can-check": "Can I mail a physical check?", - "yes-check": "Yes, we would welcome a check. You can mail it to us at:", - "how-matching-gift": "How can I set up matching gifts from my employer, or payroll deductions?", - "employers-vary": "This varies from employer to employer, and our nonprofit is already listed in many of the big donation-matching databases.", - "some-volunteer": "Some people are able to volunteer for freeCodeCamp and their employer matches by donating a fixed amount per hour they volunteer. Other employers will match any donations the donors make up to a certain amount", - "help-matching-gift": "If you need help with this, please email Quincy directly: quincy@freecodecamp.org", - "how-endowment": "How can I set up an Endowment Gift to freeCodeCamp.org?", - "endowment": "This would be a huge help. Since this is a more manual process, Quincy can help walk you through it personally. Please email him directly at quincy@freecodecamp.org.", - "how-legacy": "How can I set up a Legacy gift to freeCodeCamp.org?", - "we-honored": "We would be honored to put such a gift to good use helping people around the world learn to code. Depending on where you live, this may also be tax exempt.", - "legacy-gift-message": "I give, devise, and bequeath [the sum of _____ USD (or other currency) OR _____ percent of the rest and residue of my estate] to freeCodeCamp.org (Free Code Camp, Inc. tax identification number 82-0779546), a charitable corporation organized under the laws of the State of Delaware, United States, currently located at 3905 Hedgcoxe Rd, PO Box 250352, Plano, Texas, 75025 United States, to be used for its general charitable purposes at its discretion.", - "thank-wikimedia": "We would like to thank the Wikimedia Foundation for providing this formal language for us to use.", - "legacy-gift-questions": "If you have any questions about this process, please email Quincy at quincy@freecodecamp.org.", - "how-stock": "How can I donate stock to freeCodeCamp.org?", - "welcome-stock": "We would welcome your stock donations. Please email Quincy directly and he can help you with this, and share our nonprofit's brokerage account details: quincy@freecodecamp.org.", - "how-receipt": "Can I get a donation receipt so that I can deduct my donation from my taxes?", - "just-forward": "Absolutely. Just forward the receipt from your transaction to donors@freecodecamp.org, tell us you'd like a receipt and any special instructions you may have, and we'll reply with a receipt for you.", - "how-update": "I set up a monthly donation, but I need to update or pause the monthly recurrence. How can I do this?", - "take-care-of-this": "Just forward one of your monthly donation receipts to donors@freecodecamp.org and tell us what you'd like us to do. We'll take care of this for you and send you confirmation.", - "anything-else": "Is there anything else I can learn about donating to freeCodeCamp.org?", - "other-support": "If there is some other way you'd like to support our nonprofit and its mission that isn't listed here, or if you have any questions at all, please email Quincy at quincy@freecodecamp.org." + "secure-donation": "Безпечний внесок", + "faq": "Поширені питання", + "only-you": "Лише ви можете бачити це повідомлення. Вітаємо з отриманням сертифікації. Це було нелегко. Піклуватись про freeCodeCamp також нелегко. І недешево. Допоможіть нам допомогти вам та іншим людям з усього світу. Зробіть внесок, що не підлягає оподаткуванню, для нашої некомерційної організації сьогодні.", + "get-help": "Як отримати допомогу з внесками?", + "how-transparent": "Наскільки прозорий freeCodeCamp.org?", + "very-transparent": "Дуже прозорий. Ми отримали платиновий рейтинг від GuideStar.org.", + "download-irs": "Ви можете <0>завантажити наш детермінаційний лист, виданий Службою внутрішніх доходів (IRS), тут.", + "download-990": "Ви можете <0>завантажити наш останній 990 (річний податковий звіт) тут.", + "how-efficient": "Наскільки ефективний freeCodeCamp?", + "fcc-budget": "Бюджет freeCodeCamp набагато менший за більшість некомерційних організацій. Ми не залучали професійний збір коштів. Натомість Квінсі робить все сам.", + "help-millions": "Однак з бюджетом лише на кілька сотень тисяч доларів на рік, ми змогли допомогти мільйонам людей.", + "how-one-time": "Як зробити одноразовий внесок?", + "one-time": "Якщо ви хочете робити одноразові внески, то можете підтримати місію freeCodeCamp кожен раз, коли маєте лишні гроші. Можете використати <0>це посилання, щоб зробити внесок будь-якої суми через PayPal.", + "wire-transfer": "Ви також можете надіслати кошти напряму до freeCodeCamp через грошовий переказ. Якщо вам потрібно більше деталей про це, напишіть Квінсі на quincy@freecodecamp.org", + "does-crypto": "Чи приймає freeCodeCamp внески в біткоїнах чи інших криптовалютах?", + "yes-cryptocurrency": "Так. Будь ласка, напишіть Квінсі на quincy@freecodecamp.org і він зможе надіслати вам інформацію про гаманець freeCodeCamp. Він також може надати квитанцію про внесок, якщо вам потрібно.", + "can-check": "Чи можу я відправити фіскальний чек?", + "yes-check": "Так, ми б були раді. Ви можете відправити його сюди:", + "how-matching-gift": "Як налаштувати подарунки від мого роботодавця, або нарахування на заробітну плату?", + "employers-vary": "Це залежить від роботодавця, і наша некомерційна організація вже зазначена у багатьох великих базах.", + "some-volunteer": "Деякі люди можуть волонтерити для freeCodeCamp і їхні роботодавці дарують фіксовану суму за кожну годину волонтерства. Інші роботодавці дарують будь-який внесок, який компенсують дарувальники на певну суму", + "help-matching-gift": "Якщо вам потрібна допомога – напишіть напряму до Квінсі: quincy@freecodecamp.org", + "how-endowment": "Як оформити постійне дарування для freeCodeCamp.org?", + "endowment": "Це була б величезна допомога. Оскільки це більш ручний процес, Квінсі особисто може допомогти вам. Будь ласка, напишіть йому на quincy@freecodecamp.org.", + "how-legacy": "Як оформити дарування для freeCodeCamp.org?", + "we-honored": "Для нас велика честь використати такий дарунок з користю, щоб допомогти людям у всьому світі навчитися кодувати. Залежно від того, де ви проживаєте, це також може бути податковою пільгою.", + "legacy-gift-message": "Я передаю, відписую та заповідаю [суму _____ доларів США (або іншої валюти) АБО _____ відсотків від залишку свого майна] freeCodeCamp.org (Free Code Camp, Inc. ідентифікаційний податковий номер 82-0779546), благодійній корпорації, організованій відповідно до законів штату Делавер, Сполучені Штати, наразі розташованій за адресою 3905 Hedgcoxe Rd, PO Box 250352, Plano, Texas, 75025 United States, для використання в загальних благодійних цілях на власний розсуд.", + "thank-wikimedia": "Ми б хотіли подякувати фонду «Вікімедіа» за надання офіційного стилю.", + "legacy-gift-questions": "Якщо у вас виникли будь-які питання щодо цього процесу, будь ласка, напишіть Квінсі на quincy@freecodecamp.org.", + "how-stock": "Як пожертвувати акції для freeCodeCamp.org?", + "welcome-stock": "Ми будемо раді вашим акціям. Будь ласка, напишіть Квінсі та він допоможе вам з цим, зокрема поділиться деталями нашого брокерського рахунку: quincy@freecodecamp.org.", + "how-receipt": "Чи можу я отримати квитанцію про внесок, щоб відраховувати його від податків?", + "just-forward": "Абсолютно. Просто надішліть квитанцію своєї транзакції на адресу donors@freecodecamp.сом, скажіть нам, що ви хотіли б отримати квитанцію, та зазначте, якщо у вас є особисті побажання, і ми відповімо вам з квитанцією.", + "how-update": "Я налаштував(-ла) щомісячний внесок, але мені потрібно оновити або призупинити повторюваність. Як це зробити?", + "take-care-of-this": "Просто перешліть одну із щомісячних квитанцій на donors@freecodecamp.org та повідомте, чим ми можемо допомогти. Ми подбаємо про це та надішлемо вам підтвердження.", + "anything-else": "Чи можу я дізнатись ще щось про внески до freeCodeCamp.org?", + "other-support": "Якщо ви хочете підтримати нашу некомерційну організацію іншим шляхом, або ж маєте будь-які інші питання – напишіть Квінсі на quincy@freecodecamp.org." }, "report": { "sign-in": "Щоб повідомити про порушення користувача, ви повинні ввійти в систему", @@ -423,19 +430,19 @@ }, "search": { "label": "Пошук", - "placeholder": "Search 8,000+ tutorials", + "placeholder": "Шукати серед 8000+ уроків", "see-results": "Переглянути всі результати для {{searchQuery}}", "no-tutorials": "Не знайдено жодного уроку", "try": "Шукаєте щось? Спробуйте пошуковий рядок на цій сторінці.", "no-results": "Ми не змогли знайти нічого, що стосується <0>{{query}}" }, "misc": { - "offline": "Схоже, що ви не підключені до мережі, тому не зможете зберегти ваш прогрес.", - "server-offline": "Сервер не відповідає, ваш прогрес не збережеться. Будь ласка, зв'яжіться з <0>підтримкою, якщо це помилка не зникне.", + "offline": "Схоже, що ви не підключені до мережі, тому не зможете зберегти свій прогрес", + "server-offline": "Сервер не відповідає, ваш прогрес може не зберегтись. Будь ласка, зв'яжіться з <0>підтримкою, якщо ця помилка не зникне", "unsubscribed": "Підписку успішно скасовано", "keep-coding": "Що б не сталося, продовжуйте програмувати!", "email-signup": "Реєстрація через електронну пошту", - "quincy": "- Квінсі Ларсон, вчитель, який заснував freeCodeCamp.org", + "quincy": "– Квінсі Ларсон, вчитель, який заснував freeCodeCamp.org", "email-blast": "До речі, щоп'ятниці я надсилаю електронний лист із 5 посиланнями про програмування та інформатику. Я відправляю їх приблизно 4 мільйонам людей. Чи хотіли б ви, щоб я відправляв ці листи ще й вам?", "update-email-1": "Оновити свою адресу електронної пошти", "update-email-2": "Оновіть свою адресу електронної пошти тут:", @@ -443,7 +450,9 @@ "and": "і", "change-theme": "Увійдіть, щоб змінити тему.", "translation-pending": "Допоможіть нам з перекладом", - "certification-project": "Certification Project" + "certification-project": "Сертифікаційний проєкт", + "iframe-alert": "Зазвичай це посилання перенесло б вас на інший вебсайт! Воно працює. Це посилання на: {{externalLink}}", + "document-notfound": "документ не знайдено" }, "icons": { "gold-cup": "Золотий кубок", @@ -452,8 +461,10 @@ "donate": "Зробити внесок через PayPal", "fail": "Тест не пройдений", "not-passed": "Не пройдено", + "waiting": "В очікуванні", "passed": "Пройдено", - "hint": "Hint", + "failed": "Не вдалося", + "hint": "Підказка", "heart": "Серце", "initial": "Початковий", "info": "Інформація", @@ -462,7 +473,7 @@ "magnifier": "лупа" }, "aria": { - "fcc-curriculum": "freeCodeCamp Curriculum", + "fcc-curriculum": "Навчальний план freeCodeCamp", "answer": "Відповідь", "linkedin": "Посилання на сторінку LinkedIn {{username}}", "github": "Посилання на сторінку GitHub {{username}}", @@ -472,13 +483,16 @@ "previous-page": "Перейти на попередню сторінку", "next-page": "Перейти на наступну сторінку", "last-page": "Перейти на останню сторінку", - "primary-nav": "primary", - "breadcrumb-nav": "breadcrumb", - "submit": "Use Ctrl + Enter to submit.", - "running-tests": "Running tests" + "primary-nav": "первинний", + "breadcrumb-nav": "навігаційна стежка", + "submit": "Використайте Ctrl + Enter, щоб відправити.", + "running-tests": "Запущені тести", + "step": "Крок", + "steps": "Кроки", + "steps-for": "Кроки для {{blockTitle}}" }, "flash": { - "honest-first": "Щоб отримати сертифікат, ви повинні спочатку прийняти нашу політику академічної доброчесності", + "honest-first": "Щоб отримати сертифікацію, ви повинні спочатку прийняти нашу політику академічної доброчесності", "really-weird": "Щось пішло не так. Якщо це повториться, будь ласка, повідомте про це за посиланням: https://github.com/freeCodeCamp/freeCodeCamp/issues/new", "not-right": "Щось пішло не так. Звіт було сформовано і команду freeCodeCamp.org вже сповістили.", "went-wrong": "Щось пішло не так. Будь ласка, перевірте та повторіть спробу.", @@ -489,7 +503,7 @@ "wrong-updating": "Щось пішло не так під час оновлення вашого облікового запису. Будь ласка, перевірте і повторіть спробу", "updated-preferences": "Ми оновили ваші налаштування", "email-invalid": "Неприпустимий формат адреси електронної пошти", - "email-valid": "Вашу електронну пошту змінено. Вдалого кодування!", + "email-valid": "Вашу електронну пошту змінено. Щасливого кодування!", "bad-challengeId": "currentChallengeId не є дійсним ідентифікатором завдання", "theme-invalid": "Недійсна тема", "theme-set": "Тема вже встановлена", @@ -502,53 +516,53 @@ "oops-not-right": "Щось пішло не так, будь ласка, створіть запит на нове посилання для входу/реєстрації", "expired-link": "Схоже, посилання, на яке ви натиснули, застаріло. Будь ласка, створіть запит на нове посилання, щоб увійти", "signin-success": "Ви успішно ввійшли у свій обліковий запис. Вдалого програмування!", - "social-auth-gone": "Ми відходимо від автентифікації з соцмереж через конфіденційність. Наступного разу ми рекомендуємо використовувати вашу адресу електронної пошти: {{email}} для входу в систему.", - "name-needed": "Нам потрібне ваше ім'я, щоб ми могли вказати його в вашому сертифікаті. Додайте своє ім'я до налаштувань облікового запису і натисніть кнопку \"Зберегти\". Після цього ми зможемо видати вам ваш сертифікат.", - "incomplete-steps": "Схоже, ви не завершили необхідні кроки. Будь ласка, виконайте необхідні проекти, щоб отримати сертифікат {{name}}.", - "already-claimed": "Схоже, ви вже отримали сертифікат {{name}}", - "cert-claim-success": "@{{username}}, ви успішно отримали сертифікат {{name}}! Вітаємо від імені команди freeCodeCamp.org!", + "social-auth-gone": "Ми відходимо від автентифікації з соцмереж через конфіденційність. Наступного разу ми рекомендуємо використовувати свою адресу електронної пошти: {{email}} для входу в систему.", + "name-needed": "Нам потрібне ваше ім'я, щоб ми могли вказати його в сертифікаті. Додайте своє ім'я до налаштувань облікового запису і натисніть кнопку «Зберегти». Після цього ми зможемо видати вам сертифікат.", + "incomplete-steps": "Схоже, ви не завершили необхідні кроки. Будь ласка, виконайте необхідні проєкти, щоб отримати сертифікацію {{name}}.", + "already-claimed": "Схоже, ви вже отримали сертифікацію {{name}}", + "cert-claim-success": "@{{username}}, ви успішно отримали сертифікацію {{name}}! Вітаємо від імені команди freeCodeCamp.org!", "wrong-name": "Щось пішло не так під час перевірки {{name}}, будь ласка, спробуйте ще раз. Якщо ви продовжуєте отримувати цю помилку, ви можете надіслати повідомлення на support@freeCodeCamp.org, щоб отримати допомогу.", "error-claiming": "Під час отримання {{certName}} сталася помилка", "refresh-needed": "Ви можете використовувати кнопку PaymentRequest тільки один раз. Оновіть сторінку, щоб почати знову.", - "username-not-found": "Ми не змогли знайти користувача з ім'ям \"{{username}}\"", - "add-name": "Цей користувач повинен додати своє ім'я до свого облікового запису, щоб інші могли переглянути його сертифікат.", - "not-eligible": "Наразі цей користувач не має права отримати безкоштовний сертифікат freeCodeCamp.org.", - "profile-private": "{{username}} has chosen to make their profile private. They will need to make their profile public in order for others to be able to view their certification.", - "certs-private": "{{username}} вирішив зробити свої сертифікати конфіденційними. Йому потрібно надати спільний доступ до своїх сертифікатів, щоб інші могли їх переглянути.", - "not-honest": "{{username}} ще не прийняв нашу Обітницю академічної доброчесності.", + "username-not-found": "Ми не змогли знайти користувача з ім'ям «{{username}}»", + "add-name": "Цей користувач повинен додати своє ім'я до свого облікового запису, щоб інші могли переглянути його сертифікацію.", + "not-eligible": "Наразі цей користувач не має права отримати безоплатну сертифікацію freeCodeCamp.org.", + "profile-private": "{{username}} вирішив(-ла) зробити свій профіль конфіденційним. Йому/їй потрібно надати спільний доступ до свого профілю, щоб інші мали змогу переглянути сертифікацію.", + "certs-private": "{{username}} вирішив(-ла) зробити свої сертифікації конфіденційними. Йому/їй потрібно надати спільний доступ до своїх сертифікацій, щоб інші могли їх переглянути.", + "not-honest": "{{username}} ще не прийняв(-ла) нашу Обітницю академічної доброчесності.", "user-not-certified": "Схоже, що користувач {{username}} не є сертифікованим {{cert}}", "invalid-challenge": "Не вдалося підтвердити завдання", - "no-links-provided": "Ви не надали нам дійсні посилання для перевірки вашої роботи.", + "no-links-provided": "Ви не надали нам дійсні посилання для перевірки своєї роботи.", "no-social": "Обліковий запис соціальної мережі не знайдено", "invalid-social": "Неправильний обліковий запис соціальної мережі", "no-account": "Немає облікового запису, пов'язаного з {{website}}", "unlink-success": "Ви успішно від'єдналися від {{website}}", "provide-username": "Перевірте, чи ви вказали ім'я користувача та звіт", "report-sent": "Звіт був відправлений команді з {{email}} в копії", - "certificate-missing": "Такий сертифікат не існує.", - "create-token-err": "An error occurred while creating your user token", - "delete-token-err": "An error occurred while deleting your user token", - "token-created": "You have successfully created a new user token.", - "token-deleted": "Your user token has been deleted.", - "start-project-err": "Something went wrong trying to start the project. Please try again.", - "complete-project-first": "You must complete the project first.", - "local-code-save-error": "Oops, your code did not save, your browser's local storage may be full.", - "local-code-saved": "Saved! Your code was saved to your browser's local storage.", - "code-saved": "Your code was saved to the database. It will be here when you return.", - "code-save-error": "An error occurred trying to save your code.", - "code-save-less": "Slow Down! Your code was not saved. Try again in a few seconds.", - "challenge-save-too-big": "Sorry, you cannot save your code. Your code is {{user-size}} bytes. We allow a maximum of {{max-size}} bytes. Please make your code smaller and try again or request assistance on https://forum.freecodecamp.org", - "challenge-submit-too-big": "Sorry, you cannot submit your code. Your code is {{user-size}} bytes. We allow a maximum of {{max-size}} bytes. Please make your code smaller and try again or request assistance on https://forum.freecodecamp.org", - "invalid-update-flag": "You are attempting to access forbidden resources. Please request assistance on https://forum.freecodecamp.org if this is a valid request." + "certificate-missing": "Такої сертифікації не існує", + "create-token-err": "Під час створення маркера користувача сталася помилка", + "delete-token-err": "Під час видалення маркера користувача сталася помилка", + "token-created": "Ви успішно створили новий маркер користувача.", + "token-deleted": "Ваш маркер користувача видалено.", + "start-project-err": "Під час запуску проєкту сталася помилка. Будь ласка, спробуйте ще раз.", + "complete-project-first": "Спочатку ви повинні завершити проєкт.", + "local-code-save-error": "Упс, ваш код не збережено. Можливо, локальне сховище вашого браузера заповнене.", + "local-code-saved": "Збережено! Код було збережено в локальному сховищі вашого браузера.", + "code-saved": "Ваш код збережено в базі даних. Він буде тут, коли ви повернетесь.", + "code-save-error": "Під час спроби зберегти ваш код сталася помилка.", + "code-save-less": "Зачекайте! Ваш код не було збережено. Спробуйте ще раз через кілька секунд.", + "challenge-save-too-big": "На жаль, ви не можете зберегти свій код. Ваш код займає {{user-size}} байт. Максимальна кількість байтів: {{max-size}}. Будь ласка, зменште свій код і повторіть спробу або попросіть допомоги на https://forum.freecodecamp.org", + "challenge-submit-too-big": "На жаль, ви не можете надіслати свій код. Ваш код займає {{user-size}} байт. Максимальна кількість байтів: {{max-size}}. Будь ласка, зменште свій код і повторіть спробу або попросіть допомоги на https://forum.freecodecamp.org", + "invalid-update-flag": "Ви намагаєтеся отримати доступ до заборонених ресурсів. Зверніться по допомогу на https://forum.freecodecamp.org, якщо це є дійсним запитом." }, "validation": { - "max-characters": "Максимальний розмір — 288 символів, у вас залишилося {{charsLeft}}", + "max-characters": "Максимальний розмір – 288 символів, у вас залишилося {{charsLeft}}", "same-email": "Ця адреса електронної пошти збігається з вашою поточною адресою", "invalid-email": "Ми не змогли перевірити вашу адресу електронної пошти. Будь ласка, переконайтеся, що вона правильна.", "email-mismatch": "Обидві нові адреси електронної пошти повинні збігатися", "title-required": "Необхідно вказати заголовок", - "title-short": "Заголовок занадто короткий", - "title-long": "Заголовок занадто довгий", + "title-short": "Закороткий заголовок", + "title-long": "Задовгий заголовок", "invalid-url": "Ми не змогли перевірити вашу URL-адресу. Будь ласка, переконайтеся, що вона правильна.", "invalid-protocol": "URL-адреса має починатися з http або https", "url-not-image": "URL-адреса повинна посилатись на файл зображення безпосередньо", @@ -560,27 +574,27 @@ }, "certification": { "executive": "Виконавчий директор, freeCodeCamp.org", - "verify": "Перевірити цей сертифікат за посиланням {{certURL}}", + "verify": "Перевірити сертифікацію за посиланням {{certURL}}", "issued": "Виданий", - "fulltext": "<0>Цей сертифікат засвідчує, що <1>{{user}} <2>успішно закінчив курс freeCodeCamp.org <3>{{title}} <4>Сертифікат розробника, що підтверджує приблизно {{time}} годин навчання на курсі.", + "fulltext": "<0>Цей сертифікат засвідчує, що <1>{{user}} <2>успішно закінчив(-ла) сертифікацію <3>{{title}} <4>від freeCodeCamp.org, виконавши приблизно {{time}} годин навчання на курсі.", "project": { - "heading-legacy-full-stack": "В рамках сертифікації програмного забезпечення повного циклу {{user}} отримав такі сертифікати:", - "heading": "У рамках цієї сертифікації, {{user}} створив такі проекти і успішно пройшов усі автоматизовані тестування:", + "heading-legacy-full-stack": "В рамках сертифікації програмного забезпечення повного циклу {{user}} отримав(-ла) такі сертифікації:", + "heading": "У рамках цієї сертифікації {{user}} створив(-ла) такі проєкти і успішно пройшов(-ла) усі автоматизовані тестування:", "solution": "рішення", - "no-solution": "error displaying solution, email support@freeCodeCamp.org to get help.", + "no-solution": "помилка відображення рішення, напишіть на support@freeCodeCamp.org, щоб отримати допомогу.", "source": "джерело", - "footnote": "Якщо ви підозрюєте, що будь-який з цих проектів порушує <2>політику академічної доброчесності, будь ласка, <5>повідомте про це нашій команді.", + "footnote": "Якщо ви підозрюєте, що будь-який з цих проєктів порушує <2>політику академічної доброчесності, будь ласка, <5>повідомте про це нашій команді.", "title": { "Build a Personal Portfolio Webpage": "Створіть вебсторінку персонального портфоліо", "Build a Random Quote Machine": "Створіть генератор випадкових цитат", "Build a 25 + 5 Clock": "Створіть таймер 25 + 5", - "Build a JavaScript Calculator": "Створіть JavaScript калькулятор", + "Build a JavaScript Calculator": "Створіть калькулятор JavaScript", "Show the Local Weather": "Покажіть місцеву погоду", "Use the TwitchTV JSON API": "Використайте TwitchTV JSON API", "Stylize Stories on Camper News": "Стилізуйте стрічку новин на Camper News", - "Build a Wikipedia Viewer": "Створіть переглядач Вікіпедії", - "Build a Tic Tac Toe Game": "Створіть гру хрестики-нулики", - "Build a Simon Game": "Створіть гру Simon", + "Build a Wikipedia Viewer": "Створіть переглядача вікіпедії", + "Build a Tic Tac Toe Game": "Створіть гру «Хрестики-нулики»", + "Build a Simon Game": "Створіть гру «Simon»", "Timestamp Microservice": "Мікросервіс позначок часу", "Request Header Parser Microservice": "Мікросервіс парсингу заголовків запиту", "URL Shortener Microservice": "Мікросервіс скорочування URL-адрес", @@ -591,14 +605,14 @@ "Chart the Stock Market": "Діаграма фондової біржі", "Manage a Book Trading Club": "Керуйте клубом книготоргівлі", "Build a Pinterest Clone": "Створіть копію Pinterest", - "Build a Markdown Previewer": "Створіть Markdown-програму попереднього перегляду", + "Build a Markdown Previewer": "Створіть попередній перегляд Markdown", "Build a Camper Leaderboard": "Створіть таблицю лідерів-кемперів", "Build a Recipe Box": "Створіть збірник рецептів", - "Build the Game of Life": "Створіть гру \"Життя\"", - "Build a Roguelike Dungeon Crawler Game": "Створіть гру Roguelike Dungeon Crawler", - "Visualize Data with a Bar Chart": "Візуалізуйте дані за допомогою гістограми", - "Visualize Data with a Scatterplot Graph": "Візуалізуйте дані за допомогою точкової діаграми", - "Visualize Data with a Heat Map": "Візуалізуйте дані за допомогою теплокарти", + "Build the Game of Life": "Створіть гру «Життя»", + "Build a Roguelike Dungeon Crawler Game": "Створіть гру «Roguelike Dungeon Crawler»", + "Visualize Data with a Bar Chart": "Візуалізуйте дані з допомогою стовпчикової діаграми", + "Visualize Data with a Scatterplot Graph": "Візуалізуйте дані з допомогою точкової діаграми", + "Visualize Data with a Heat Map": "Візуалізуйте дані з допомогою теплокарти", "Show National Contiguity with a Force Directed Graph": "Покажіть національну спільність за допомогою орієнтованого графу", "Map Data Across the Globe": "Картографічні дані з усього світу", "Metric-Imperial Converter": "Конвертер метрично-британських величин", @@ -608,16 +622,16 @@ "Anonymous Message Board": "Анонімна панель повідомлень", "Build a Tribute Page": "Створіть пам'ятну сторінку", "Build a Survey Form": "Створіть форму для опитування", - "Build a Product Landing Page": "Створіть цільову сторінку продукту", + "Build a Product Landing Page": "Створіть посадкову сторінку продукту", "Build a Technical Documentation Page": "Створіть сторінку технічної документації", "Palindrome Checker": "Перевірка паліндромів", "Roman Numeral Converter": "Конвертер римських цифр", "Caesars Cipher": "Шифр Цезаря", - "Telephone Number Validator": "Перевірка телефонного номера", + "Telephone Number Validator": "Валідатор мобільного номера", "Cash Register": "Касовий апарат", "Build a Drum Machine": "Створіть драм-машину", - "Visualize Data with a Choropleth Map": "Візуалізуйте дані за допомогою фонової картограми", - "Visualize Data with a Treemap Diagram": "Візуалізуйте дані за допомогою діаграми Treemap", + "Visualize Data with a Choropleth Map": "Візуалізуйте дані з допомогою хороплета", + "Visualize Data with a Treemap Diagram": "Візуалізуйте дані з допомогою деревової діаграми", "Exercise Tracker": "Трекер вправ", "Sudoku Solver": "Програма для розв'язування судоку", "American British Translator": "Американо-британський перекладач", @@ -632,7 +646,7 @@ "Page View Time Series Visualizer": "Візуалізатор часового ряду перегляду сторінки", "Sea Level Predictor": "Прогнозування змін рівня моря", "Port Scanner": "Сканер портів", - "SHA-1 Password Cracker": "SHA-1 Програма для злому паролів", + "SHA-1 Password Cracker": "Програма для злому паролів SHA-1", "Secure Real Time Multiplayer Game": "Безпечна багатокористувацька гра в режимі реального часу", "Rock Paper Scissors": "Камінь-ножиці-папір", "Cat and Dog Image Classifier": "Класифікатор зображень котів і собак", @@ -643,14 +657,14 @@ } }, "certification-card": { - "title": "Отримайте свій сертифікат", - "intro": "Завершіть наступні кроки, щоб мати змогу отримати та переглянути ваші {{i18nCertText}}", + "title": "Отримайте свою сертифікацію", + "intro": "Завершіть наступні кроки, щоб мати змогу отримати та переглянути свої {{i18nCertText}}", "complete-project": "Завершено {{i18nCertText}} проєкт", "accept-honesty": "Прийняти нашу Політику академічної доброчесності", "set-name": "Введіть своє ім'я та зробіть його загальнодоступним", - "set-certs-public": "Відкрити загальний доступ до сертифікатів", - "set-profile-public": "Відкрити загальний доступ до вашого профілю", - "set-claim": "Отримайте та перегляньте свої сертифікати" + "set-certs-public": "Відкрити загальний доступ до сертифікацій", + "set-profile-public": "Відкрити загальний доступ до профілю", + "set-claim": "Отримайте та перегляньте свої сертифікації" }, "forum-help": { "browser-info": "**Інформація про ваш браузер:**", @@ -658,7 +672,7 @@ "challenge": "**Завдання:** {{challengeTitle}}", "challenge-link": "**Посилання на завдання:**", "whats-happening": "**Розкажіть нам, що сталося:**", - "describe": "Детально опишіть вашу проблему тут.", + "describe": "Детально опишіть свою проблему тут.", "camper-project": "**Посилання на ваші проєкти**", "camper-code": "**Ваш код**", "warning": "УВАГА", @@ -670,16 +684,27 @@ "add-code-three": "тому що вони дозволяють вашому коду бути правильно відформатованим у повідомленні." }, "user-token": { - "title": "User Token", - "create": "Create a new token", - "create-p1": "It looks like you don't have a user token. Create one to save your progress on this section", - "create-p2": "Create a user token to save your progress on the curriculum sections that use a virtual machine.", - "delete": "Delete my user token", - "delete-title": "Delete My User Token", - "delete-p1": "Your user token is used to save your progress on curriculum sections that use a virtual machine. If you suspect it has been compromised, you can delete it without losing any progress. A new one will be created automatically the next time you open a project.", - "delete-p2": "If you suspect your token has been compromised, you can delete it to make it unusable. Progress on previously submitted lessons will not be lost.", - "delete-p3": "You will need to create a new token to save future progress on the curriculum sections that use a virtual machine.", - "no-thanks": "No thanks, I would like to keep my token", - "yes-please": "Yes please, I would like to delete my token" + "title": "Токен користувача", + "create": "Створити новий токен", + "create-p1": "Схоже, у вас немає токена користувача. Створіть його, щоб зберегти свій прогрес в цьому розділі", + "create-p2": "Створіть токен користувача, щоб зберегти свій прогрес у розділах навчальної програми, які використовують віртуальну машину.", + "delete": "Видалити мій токен", + "delete-title": "Видалити мій токен", + "delete-p1": "Ваш токен користувача використовується для збереження вашого прогресу в розділах навчальної програми, які використовують віртуальну машину. Якщо ви підозрюєте, що його було зламано, ви можете видалити його, не втрачаючи прогресу. Новий буде створено автоматично, коли ви відкриєте проєкт.", + "delete-p2": "Якщо ви підозрюєте, що ваш токен зламано, ви можете видалити його, щоб зробити його непридатним для використання. Прогрес на раніше поданих уроках не буде втрачено.", + "delete-p3": "Вам потрібно буде створити новий токен, щоб зберегти майбутній прогрес у розділах навчальної програми, які використовують віртуальну машину.", + "no-thanks": "Ні, дякую, я хотів(-ла) би зберегти свій токен", + "yes-please": "Так, я хотів(-ла) би видалити свій токен" + }, + "shortcuts": { + "title": "Гарячі клавіші", + "table-header-action": "Дія", + "table-header-key": "Ключ(і)", + "navigation-mode": "Режим навігації", + "execute-challenge": "Виконати завдання", + "focus-editor": "Редактор фокусу", + "focus-instructions-panel": "Панель інструкцій щодо фокусування", + "navigate-previous": "Перейти до попередньої вправи", + "navigate-next": "Перейти до наступної вправи" } } diff --git a/client/i18n/schema-validation.js b/client/i18n/schema-validation.js deleted file mode 100644 index 187ed2ed18e52c..00000000000000 --- a/client/i18n/schema-validation.js +++ /dev/null @@ -1,287 +0,0 @@ -const path = require('path'); -const { availableLangs } = require('../../config/i18n/all-langs'); -const introSchema = require('./locales/english/intro.json'); -const linksSchema = require('./locales/english/links.json'); -const metaTagsSchema = require('./locales/english/meta-tags.json'); -const motivationSchema = require('./locales/english/motivation.json'); -const translationsSchema = require('./locales/english/translations.json'); -const trendingSchema = require('./locales/english/trending.json'); - -/** - * Flattens a nested object structure into a single - * object with property chains as keys. - * @param {Object} obj Object to flatten - * @param {String} namespace Used for property chaining - */ -const flattenAnObject = (obj, namespace = '') => { - const flattened = {}; - Object.keys(obj).forEach(key => { - if (Array.isArray(obj[key])) { - flattened[namespace ? `${namespace}.${key}` : key] = obj[key]; - } else if (typeof obj[key] === 'object') { - Object.assign( - flattened, - flattenAnObject(obj[key], namespace ? `${namespace}.${key}` : key) - ); - } else { - flattened[namespace ? `${namespace}.${key}` : key] = obj[key]; - } - }); - return flattened; -}; - -/** - * Checks if a translation object is missing keys - * that are present in the schema. - * @param {String[]} file Array of translation object's keys - * @param {String[]} schema Array of matching schema's keys - * @param {String} path string path to file - */ -const findMissingKeys = (file, schema, path) => { - const missingKeys = []; - for (const key of schema) { - if (!file.includes(key)) { - missingKeys.push(key); - } - } - if (missingKeys.length) { - console.warn( - `${path} is missing these required keys: ${missingKeys.join(', ')}` - ); - } -}; - -/** - * Checks if a translation object has extra - * keys which are NOT present in the schema. - * @param {String[]} file Array of translation object's keys - * @param {String[]} schema Array of matching schema's keys - * @param {String} path string path to file - */ -const findExtraneousKeys = (file, schema, path) => { - const extraKeys = []; - for (const key of file) { - if (!schema.includes(key)) { - extraKeys.push(key); - } - } - if (extraKeys.length) { - console.warn( - `${path} has these keys that are not in the schema: ${extraKeys.join( - ', ' - )}` - ); - } -}; - -/** - * Validates that all values in the object are non-empty. Includes - * validation of nested objects. - * @param {Object} obj The object to check the values of - * @param {String} namespace String for tracking nested properties - */ -const noEmptyObjectValues = (obj, namespace = '') => { - const emptyKeys = []; - for (const key of Object.keys(obj)) { - if (Array.isArray(obj[key])) { - if (!obj[key].length) { - emptyKeys.push(namespace ? `${namespace}.${key}` : key); - } - } else if (typeof obj[key] === 'object') { - emptyKeys.push( - noEmptyObjectValues(obj[key], namespace ? `${namespace}.${key}` : key) - ); - } else if (!obj[key]) { - emptyKeys.push(namespace ? `${namespace}.${key}` : key); - } - } - return emptyKeys.flat(); -}; - -/** - * Grab the schema keys once, to avoid overhead of - * fetching within iterative function. - */ -const translationSchemaKeys = Object.keys(flattenAnObject(translationsSchema)); -const trendingSchemaKeys = Object.keys(flattenAnObject(trendingSchema)); -const motivationSchemaKeys = Object.keys(flattenAnObject(motivationSchema)); -const introSchemaKeys = Object.keys(flattenAnObject(introSchema)); -const metaTagsSchemaKeys = Object.keys(flattenAnObject(metaTagsSchema)); -const linksSchemaKeys = Object.keys(flattenAnObject(linksSchema)); - -/** - * Function that checks the translations.json file - * for each available client language. - * @param {String[]} languages List of languages to test - */ -const translationSchemaValidation = languages => { - languages.forEach(language => { - const filePath = path.join( - __dirname, - `/locales/${language}/translations.json` - ); - const fileJson = require(filePath); - const fileKeys = Object.keys(flattenAnObject(fileJson)); - findMissingKeys( - fileKeys, - translationSchemaKeys, - `${language}/translations.json` - ); - findExtraneousKeys( - fileKeys, - translationSchemaKeys, - `${language}/translations.json` - ); - const emptyKeys = noEmptyObjectValues(fileJson); - if (emptyKeys.length) { - console.warn( - `${language}/translation.json has these empty keys: ${emptyKeys.join( - ', ' - )}` - ); - } - console.info(`${language} translation.json validation complete.`); - }); -}; - -/** - * Function that checks the trending.json file - * for each available client language. - * @param {String[]} languages List of languages to test - */ -const trendingSchemaValidation = languages => { - languages.forEach(language => { - const filePath = path.join(__dirname, `/locales/${language}/trending.json`); - const fileJson = require(filePath); - const fileKeys = Object.keys(flattenAnObject(fileJson)); - findMissingKeys(fileKeys, trendingSchemaKeys, `${language}/trending.json`); - findExtraneousKeys( - fileKeys, - trendingSchemaKeys, - `${language}/trending.json` - ); - const emptyKeys = noEmptyObjectValues(fileJson); - if (emptyKeys.length) { - console.warn( - `${language}/trending.json has these empty keys: ${emptyKeys.join( - ', ' - )}` - ); - } - console.info(`${language} trending.json validation complete`); - }); -}; - -const motivationSchemaValidation = languages => { - languages.forEach(language => { - const filePath = path.join( - __dirname, - `/locales/${language}/motivation.json` - ); - const fileJson = require(filePath); - const fileKeys = Object.keys(flattenAnObject(fileJson)); - findMissingKeys( - fileKeys, - motivationSchemaKeys, - `${language}/motivation.json` - ); - findExtraneousKeys( - fileKeys, - motivationSchemaKeys, - `${language}/motivation.json` - ); - const emptyKeys = noEmptyObjectValues(fileJson); - if (emptyKeys.length) { - console.warn( - `${language}/motivation.json has these empty keys: ${emptyKeys.join( - ', ' - )}` - ); - } - // Special line to assert that objects in motivational quote are correct - if ( - !fileJson.motivationalQuotes.every( - object => - Object.prototype.hasOwnProperty.call(object, 'quote') && - Object.prototype.hasOwnProperty.call(object, 'author') - ) - ) { - console.warn(`${language}/motivation.json has malformed quote objects.`); - } - console.info(`${language} motivation.json validation complete`); - }); -}; - -/** - * Function that checks the intro.json file - * for each available client language. - * @param {String[]} languages List of languages to test - */ -const introSchemaValidation = languages => { - languages.forEach(language => { - const filePath = path.join(__dirname, `/locales/${language}/intro.json`); - const fileJson = require(filePath); - const fileKeys = Object.keys(flattenAnObject(fileJson)); - findMissingKeys(fileKeys, introSchemaKeys, `${language}/intro.json`); - findExtraneousKeys(fileKeys, introSchemaKeys, `${language}/intro.json`); - const emptyKeys = noEmptyObjectValues(fileJson); - if (emptyKeys.length) { - console.warn( - `${language}/intro.json has these empty keys: ${emptyKeys.join(', ')}` - ); - } - console.info(`${language} intro.json validation complete`); - }); -}; - -const metaTagsSchemaValidation = languages => { - languages.forEach(language => { - const filePath = path.join( - __dirname, - `/locales/${language}/meta-tags.json` - ); - const fileJson = require(filePath); - const fileKeys = Object.keys(flattenAnObject(fileJson)); - findMissingKeys(fileKeys, metaTagsSchemaKeys, `${language}/meta-tags.json`); - findExtraneousKeys( - fileKeys, - metaTagsSchemaKeys, - `${language}/metaTags.json` - ); - const emptyKeys = noEmptyObjectValues(fileJson); - if (emptyKeys.length) { - console.warn( - `${language}/metaTags.json has these empty keys: ${emptyKeys.join( - ', ' - )}` - ); - } - console.info(`${language} metaTags.json validation complete`); - }); -}; - -const linksSchemaValidation = languages => { - languages.forEach(language => { - const filePath = path.join(__dirname, `/locales/${language}/links.json`); - const fileJson = require(filePath); - const fileKeys = Object.keys(flattenAnObject(fileJson)); - findMissingKeys(fileKeys, linksSchemaKeys, `${language}/links.json`); - findExtraneousKeys(fileKeys, linksSchemaKeys, `${language}/links.json`); - const emptyKeys = noEmptyObjectValues(fileJson); - if (emptyKeys.length) { - console.warn( - `${language}/links.json has these empty keys: ${emptyKeys.join(', ')}` - ); - } - console.info(`${language} links.json validation complete`); - }); -}; - -const translatedLangs = availableLangs.client.filter(x => x !== 'english'); - -translationSchemaValidation(translatedLangs); -trendingSchemaValidation(translatedLangs); -motivationSchemaValidation(translatedLangs); -introSchemaValidation(translatedLangs); -metaTagsSchemaValidation(translatedLangs); -linksSchemaValidation(translatedLangs); diff --git a/client/i18n/schema-validation.ts b/client/i18n/schema-validation.ts new file mode 100644 index 00000000000000..c066cdc1fe07db --- /dev/null +++ b/client/i18n/schema-validation.ts @@ -0,0 +1,260 @@ +import path from 'path'; +import { readFile } from 'fs/promises'; +import { availableLangs } from '../../config/i18n/all-langs'; +import introSchema from './locales/english/intro.json'; +import linksSchema from './locales/english/links.json'; +import metaTagsSchema from './locales/english/meta-tags.json'; +import motivationSchema from './locales/english/motivation.json'; +import translationsSchema from './locales/english/translations.json'; +import trendingSchema from './locales/english/trending.json'; + +type MotivationalQuotes = { quote: string; author: string }[]; + +/** + * Flattens a nested object structure into a single + * object with property chains as keys. + * @param {Object} obj Object to flatten + * @param {String} namespace Used for property chaining + */ +const flattenAnObject = (obj: Record, namespace = '') => { + const flattened: Record = {}; + Object.keys(obj).forEach(key => { + const value = obj[key]; + const field = namespace ? `${namespace}.${key}` : key; + if (Array.isArray(value)) { + flattened[field] = value; + } else if (typeof value === 'object') { + Object.assign( + flattened, + flattenAnObject(value as Record, field) + ); + } else { + flattened[field] = value; + } + }); + return flattened; +}; + +/** + * Checks if a translation object is missing keys + * that are present in the schema. + * @param {String[]} file Array of translation object's keys + * @param {String[]} schema Array of matching schema's keys + * @param {String} path string path to file + */ +const findMissingKeys = (file: string[], schema: string[], path: string) => { + const missingKeys = []; + for (const key of schema) { + if (!file.includes(key)) { + missingKeys.push(key); + } + } + if (missingKeys.length) { + console.warn( + `${path} is missing these required keys: ${missingKeys.join(', ')}` + ); + } +}; + +/** + * Checks if a translation object has extra + * keys which are NOT present in the schema. + * @param {String[]} file Array of translation object's keys + * @param {String[]} schema Array of matching schema's keys + * @param {String} path string path to file + */ +const findExtraneousKeys = (file: string[], schema: string[], path: string) => { + const extraKeys = []; + for (const key of file) { + if (!schema.includes(key)) { + extraKeys.push(key); + } + } + if (extraKeys.length) { + console.warn( + `${path} has these keys that are not in the schema: ${extraKeys.join( + ', ' + )}` + ); + } +}; + +/** + * Validates that all values in the object are non-empty. Includes + * validation of nested objects. + * @param {Object} obj The object to check the values of + * @param {String} namespace String for tracking nested properties + */ +const noEmptyObjectValues = ( + obj: Record, + namespace = '' +): string[] => { + const emptyKeys = []; + for (const key of Object.keys(obj)) { + const value = obj[key]; + const field = namespace ? `${namespace}.${key}` : key; + if (Array.isArray(value)) { + if (!value.length) { + emptyKeys.push(field); + } + } else if (typeof value === 'object') { + emptyKeys.push( + noEmptyObjectValues(value as Record, field) + ); + } else if (!value) { + emptyKeys.push(field); + } + } + return emptyKeys.flat(); +}; + +/** + * Grab the schema keys once, to avoid overhead of + * fetching within iterative function. + */ +const translationSchemaKeys = Object.keys(flattenAnObject(translationsSchema)); +const trendingSchemaKeys = Object.keys(flattenAnObject(trendingSchema)); +const motivationSchemaKeys = Object.keys(flattenAnObject(motivationSchema)); +const introSchemaKeys = Object.keys(flattenAnObject(introSchema)); +const metaTagsSchemaKeys = Object.keys(flattenAnObject(metaTagsSchema)); +const linksSchemaKeys = Object.keys(flattenAnObject(linksSchema)); + +/** + * Function that checks the translations.json file + * for each available client language. + * @param {String[]} languages List of languages to test + */ +const translationSchemaValidation = (languages: string[]) => { + languages.forEach(language => { + void readJsonFile(language, 'translations').then(fileJson => { + schemaValidation( + language, + 'translations', + fileJson, + translationSchemaKeys + ); + }); + }); +}; + +/** + * Function that checks the trending.json file + * for each available client language. + * @param {String[]} languages List of languages to test + */ +const trendingSchemaValidation = (languages: string[]) => { + languages.forEach(language => { + void readJsonFile(language, 'trending').then(fileJson => { + schemaValidation(language, 'trending', fileJson, trendingSchemaKeys); + }); + }); +}; + +/** + * Function that checks the motivation.json file + * for each available client language. + * @param {String[]} languages List of languages to test + */ +const motivationSchemaValidation = (languages: string[]) => { + languages.forEach(language => { + void readJsonFile(language, 'motivation').then(fileJson => { + schemaValidation(language, 'motivation', fileJson, motivationSchemaKeys); + }); + }); +}; + +/** + * Function that checks the intro.json file + * for each available client language. + * @param {String[]} languages List of languages to test + */ +const introSchemaValidation = (languages: string[]) => { + languages.forEach(language => { + void readJsonFile(language, 'intro').then(fileJson => { + schemaValidation(language, 'intro', fileJson, introSchemaKeys); + }); + }); +}; + +/** + * Function that checks the meta-tags.json file + * for each available client language. + * @param {String[]} languages List of languages to test + */ +const metaTagsSchemaValidation = (languages: string[]) => { + languages.forEach(language => { + void readJsonFile(language, 'meta-tags').then(fileJson => { + schemaValidation(language, 'meta-tags', fileJson, metaTagsSchemaKeys); + }); + }); +}; + +/** + * Function that checks the links.json file + * for each available client language. + * @param {String[]} languages List of languages to test + */ +const linksSchemaValidation = (languages: string[]) => { + languages.forEach(language => { + void readJsonFile(language, 'links').then(fileJson => { + schemaValidation(language, 'links', fileJson, linksSchemaKeys); + }); + }); +}; + +/** + * Common Function that checks the json file + * @param {String} language the language to test + * @param {String} fileName the fileName of json file to test + * @param {Object} fileJson the fileJson got by readJsonFile + * @param {String[]} schemaKeys Array of matching schema's keys + */ +const schemaValidation = ( + language: string, + fileName: string, + fileJson: Record, + schemaKeys: string[] +) => { + const fileKeys = Object.keys(flattenAnObject(fileJson)); + findMissingKeys(fileKeys, schemaKeys, `${language}/${fileName}.json`); + findExtraneousKeys(fileKeys, schemaKeys, `${language}/${fileName}.json`); + const emptyKeys = noEmptyObjectValues(fileJson); + if (emptyKeys.length) { + console.warn( + `${language}/${fileName}.json has these empty keys: ${emptyKeys.join( + ', ' + )}` + ); + } + // Special line to assert that objects in motivational quote are correct + if ( + fileName === 'motivation' && + !(fileJson.motivationalQuotes as MotivationalQuotes).every( + (object: object) => + Object.prototype.hasOwnProperty.call(object, 'quote') && + Object.prototype.hasOwnProperty.call(object, 'author') + ) + ) { + console.warn(`${language}/${fileName}.json has malformed quote objects.`); + } + console.info(`${language} ${fileName}.json validation complete`); +}; + +const readJsonFile = async (language: string, fileName: string) => { + const filePath = path.join( + __dirname, + `/locales/${language}/${fileName}.json` + ); + const file = await readFile(filePath, 'utf8'); + const fileJson = JSON.parse(file) as Record; + return fileJson; +}; + +const translatedLangs = availableLangs.client.filter(x => x !== 'english'); + +translationSchemaValidation(translatedLangs); +trendingSchemaValidation(translatedLangs); +motivationSchemaValidation(translatedLangs); +introSchemaValidation(translatedLangs); +metaTagsSchemaValidation(translatedLangs); +linksSchemaValidation(translatedLangs); diff --git a/client/package.json b/client/package.json index 8b6dff4e94ea00..3c18ca5c6525d2 100644 --- a/client/package.json +++ b/client/package.json @@ -25,35 +25,36 @@ "clean": "gatsby clean", "predevelop": "npm --prefix ../ run create:config && npm run build:workers -- --env development", "develop": "cross-env NODE_OPTIONS=\"--max-old-space-size=5000\" gatsby develop --inspect=9230", - "lint": "node ./i18n/schema-validation.js", + "lint": "ts-node ./i18n/schema-validation.ts", "serve": "gatsby serve -p 8000", - "serve-ci": "serve -l 8000 -c ../serve.json public", + "serve-ci": "serve -l 8000 -c serve.json public", "prestand-alone": "npm run prebuild", "stand-alone": "gatsby develop", "validate-keys": "ts-node --project ../tsconfig.json ../tools/scripts/lint/validate-keys" }, "dependencies": { - "@babel/plugin-proposal-export-default-from": "7.16.7", - "@babel/plugin-proposal-function-bind": "7.16.7", + "@babel/plugin-proposal-export-default-from": "7.18.10", + "@babel/plugin-proposal-function-bind": "7.18.9", "@babel/polyfill": "7.12.1", - "@babel/preset-env": "7.17.10", - "@babel/preset-react": "7.16.7", - "@babel/standalone": "7.17.11", - "@fortawesome/fontawesome-svg-core": "6.1.1", - "@fortawesome/free-brands-svg-icons": "6.1.1", - "@fortawesome/free-solid-svg-icons": "6.1.1", - "@fortawesome/react-fontawesome": "0.1.18", - "@freecodecamp/loop-protect": "2.2.1", + "@babel/preset-env": "7.18.10", + "@babel/preset-react": "7.18.6", + "@babel/standalone": "7.18.13", + "@fortawesome/fontawesome-svg-core": "6.1.2", + "@fortawesome/free-brands-svg-icons": "6.1.2", + "@fortawesome/free-solid-svg-icons": "6.1.2", + "@fortawesome/react-fontawesome": "0.2.0", + "@freecodecamp/curriculum-helpers": "1.0.5", + "@freecodecamp/loop-protect": "3.0.0", "@freecodecamp/react-bootstrap": "0.32.3", "@freecodecamp/react-calendar-heatmap": "1.0.0", "@freecodecamp/strip-comments": "3.0.1", "@loadable/component": "5.15.2", "@reach/router": "1.3.4", "@sentry/gatsby": "6.19.7", - "@stripe/react-stripe-js": "1.7.2", - "@stripe/stripe-js": "1.29.0", + "@stripe/react-stripe-js": "1.10.0", + "@stripe/stripe-js": "1.35.0", "@types/react-scrollable-anchor": "0.6.1", - "algoliasearch": "4.13.0", + "algoliasearch": "4.14.2", "assert": "2.0.0", "babel-plugin-preval": "5.1.0", "babel-plugin-prismjs": "2.1.0", @@ -79,62 +80,62 @@ "gatsby-source-filesystem": "3.14.0", "gatsby-transformer-remark": "4.11.0", "i18next": "20.6.1", - "jquery": "3.6.0", + "jquery": "3.6.1", "lodash": "4.17.21", "lodash-es": "4.17.21", "monaco-editor": "0.28.1", "nanoid": "3.3.4", "normalize-url": "4.5.1", "path-browserify": "1.0.1", - "postcss": "8.4.13", - "prismjs": "1.28.0", + "postcss": "8.4.16", + "prismjs": "1.29.0", "process": "0.11.10", "prop-types": "15.8.1", - "psl": "1.8.0", + "psl": "1.9.0", "query-string": "7.0.1", "react": "16.14.0", "react-dom": "16.14.0", "react-final-form": "6.5.9", - "react-ga": "3.3.0", + "react-ga": "3.3.1", "react-helmet": "6.1.0", "react-hotkeys": "2.0.0", - "react-i18next": "11.16.9", - "react-instantsearch-dom": "6.24.3", - "react-lazy-load": "3.1.13", + "react-i18next": "11.18.5", + "react-instantsearch-dom": "6.32.0", + "react-lazy-load": "3.1.14", "react-monaco-editor": "0.40.0", "react-redux": "5.1.2", - "react-reflex": "4.0.8", + "react-reflex": "4.0.9", "react-responsive": "6.1.2", "react-scrollable-anchor": "0.6.1", "react-spinkit": "3.0.0", "react-tooltip": "4.2.21", - "react-transition-group": "4.4.2", + "react-transition-group": "4.4.5", "react-youtube": "7.14.0", "redux": "4.2.0", "redux-actions": "2.6.5", "redux-devtools-extension": "2.13.9", "redux-observable": "1.2.0", - "redux-saga": "1.1.3", - "reselect": "4.1.5", + "redux-saga": "1.2.1", + "reselect": "4.1.6", "rxjs": "6.6.7", - "sanitize-html": "2.7.0", + "sanitize-html": "2.7.1", "sass.js": "0.11.1", "sha-1": "1.0.0", "store": "2.0.12", "stream-browserify": "3.0.0", "tone": "14.7.77", - "typescript": "4.6.4", + "typescript": "4.8.2", "util": "0.12.4", "uuid": "8.3.2", "validator": "13.7.0" }, "devDependencies": { - "@babel/types": "7.17.10", - "@codesee/babel-plugin-instrument": "0.259.0", - "@codesee/tracker": "0.259.0", - "@testing-library/jest-dom": "5.16.4", + "@babel/types": "7.18.13", + "@codesee/babel-plugin-instrument": "0.359.0", + "@codesee/tracker": "0.359.0", + "@testing-library/jest-dom": "5.16.5", "@testing-library/react": "12.1.5", - "autoprefixer": "10.4.7", + "autoprefixer": "10.4.8", "babel-plugin-transform-imports": "2.0.0", "chokidar": "3.5.3", "copy-webpack-plugin": "9.1.0", @@ -145,9 +146,9 @@ "react-test-renderer": "16.14.0", "redux-mock-store": "1.5.4", "redux-saga-test-plan": "4.0.5", - "serve": "13.0.2", - "ts-node": "10.7.0", - "webpack": "5.72.1", - "webpack-cli": "4.9.2" + "serve": "13.0.4", + "ts-node": "10.9.1", + "webpack": "5.74.0", + "webpack-cli": "4.10.0" } } diff --git a/client/src/__mocks__/challenge-nodes.ts b/client/src/__mocks__/challenge-nodes.ts index 7824cdb4778dde..6f5bf58eb26efe 100644 --- a/client/src/__mocks__/challenge-nodes.ts +++ b/client/src/__mocks__/challenge-nodes.ts @@ -182,6 +182,20 @@ const mockChallengeNodes: MockChallengeNodes[] = [ superBlock: 'super-block-three', dashedName: 'challenge-three' } + }, + { + challenge: { + fields: { + slug: '/super-block-four/block-a/challenge-one', + blockName: 'Block A' + }, + id: 'm', + block: 'block-a', + title: 'Challenge One', + isPrivate: false, + superBlock: 'super-block-four', + dashedName: 'challenge-one' + } } ]; diff --git a/client/src/__mocks__/gatsby.js b/client/src/__mocks__/gatsby.js deleted file mode 100644 index 86532bb220c72d..00000000000000 --- a/client/src/__mocks__/gatsby.js +++ /dev/null @@ -1,41 +0,0 @@ -/* eslint-disable no-unused-vars */ -const React = require('react'); - -const gatsby = jest.requireActual('gatsby'); - -const envData = require('../../../config/env.json'); - -const { clientLocale } = envData; - -module.exports = { - ...gatsby, - navigate: jest.fn(), - graphql: jest.fn(), - Link: jest.fn().mockImplementation( - // these props are invalid for an `a` tag - ({ - activeClassName, - activeStyle, - getProps, - innerRef, - partiallyActive, - ref, - replace, - to, - ...rest - }) => - React.createElement('a', { - ...rest, - href: to - }) - ), - withPrefix: jest.fn().mockImplementation(path => { - const pathPrefix = - clientLocale === 'english' || clientLocale === 'chinese' - ? '' - : '/' + clientLocale; - return pathPrefix + path; - }), - StaticQuery: jest.fn(), - useStaticQuery: jest.fn() -}; diff --git a/client/src/__mocks__/gatsby.ts b/client/src/__mocks__/gatsby.ts new file mode 100644 index 00000000000000..7eee88b22ff6cb --- /dev/null +++ b/client/src/__mocks__/gatsby.ts @@ -0,0 +1,31 @@ +/* eslint-disable no-unused-vars */ +import React from 'react'; +import { GatsbyLinkProps } from 'gatsby'; +const gatsby: NodeModule = jest.requireActual('gatsby'); + +import envData from '../../../config/env.json'; + +const { clientLocale } = envData; + +module.exports = { + ...gatsby, + navigate: jest.fn(), + graphql: jest.fn(), + Link: jest.fn().mockImplementation( + // these props are invalid for an `a` tag + ({ to, ...rest }: GatsbyLinkProps) => + React.createElement('a', { + ...rest, + href: to + }) + ), + withPrefix: jest.fn().mockImplementation((path: string) => { + const pathPrefix = + clientLocale === 'english' || clientLocale === 'chinese' + ? '' + : '/' + clientLocale; + return pathPrefix + path; + }), + StaticQuery: jest.fn(), + useStaticQuery: jest.fn() +}; diff --git a/client/src/assets/icons/language-globe.tsx b/client/src/assets/icons/language-globe.tsx new file mode 100644 index 00000000000000..af82eabc374632 --- /dev/null +++ b/client/src/assets/icons/language-globe.tsx @@ -0,0 +1,58 @@ +import React from 'react'; + +function LanguageGlobe( + props: JSX.IntrinsicAttributes & React.SVGProps +): JSX.Element { + return ( + <> + + + + + + + + + ); +} + +LanguageGlobe.displayName = 'LanguageGlobe'; + +export default LanguageGlobe; diff --git a/client/src/client-only-routes/show-certification.tsx b/client/src/client-only-routes/show-certification.tsx index 9d96d7c917294d..a398f5be85cd53 100644 --- a/client/src/client-only-routes/show-certification.tsx +++ b/client/src/client-only-routes/show-certification.tsx @@ -257,6 +257,7 @@ const ShowCertification = (props: ShowCertificationProps): JSX.Element => { const donationSection = (
+ {!isDonationSubmitted && ( @@ -316,7 +317,6 @@ const ShowCertification = (props: ShowCertificationProps): JSX.Element => { return ( - {isDonationDisplayed && !isDonationClosed ? donationSection : ''}
@@ -375,11 +375,13 @@ const ShowCertification = (props: ShowCertificationProps): JSX.Element => { - - {signedInUserName === username ? shareCertBtns : ''} - - - +
+ + {signedInUserName === username ? shareCertBtns : ''} + + + +
); }; diff --git a/client/src/client-only-routes/show-settings.tsx b/client/src/client-only-routes/show-settings.tsx index 415d7e0dae22bd..0e4872e5884db6 100644 --- a/client/src/client-only-routes/show-settings.tsx +++ b/client/src/client-only-routes/show-settings.tsx @@ -1,5 +1,5 @@ import { Grid } from '@freecodecamp/react-bootstrap'; -import React from 'react'; +import React, { useRef } from 'react'; import Helmet from 'react-helmet'; import { useTranslation } from 'react-i18next'; import { connect } from 'react-redux'; @@ -33,6 +33,7 @@ import { updateMyQuincyEmail, updateMySound, updateMyTheme, + updateMyKeyboardShortcuts, updateUserFlag, verifyCert } from '../redux/settings'; @@ -48,6 +49,7 @@ interface ShowSettingsProps { submitNewAbout: () => void; toggleNightMode: (theme: Themes) => void; toggleSoundMode: (sound: boolean) => void; + toggleKeyboardShortcuts: (keyboardShortcuts: boolean) => void; updateInternetSettings: () => void; updateIsHonest: () => void; updatePortfolio: () => void; @@ -77,6 +79,8 @@ const mapDispatchToProps = { submitNewAbout, toggleNightMode: (theme: Themes) => updateMyTheme({ theme }), toggleSoundMode: (sound: boolean) => updateMySound({ sound }), + toggleKeyboardShortcuts: (keyboardShortcuts: boolean) => + updateMyKeyboardShortcuts({ keyboardShortcuts }), updateInternetSettings: updateUserFlag, updateIsHonest: updateMyHonesty, updatePortfolio: updateMyPortfolio, @@ -93,6 +97,7 @@ export function ShowSettings(props: ShowSettingsProps): JSX.Element { submitNewAbout, toggleNightMode, toggleSoundMode, + toggleKeyboardShortcuts, user: { completedChallenges, email, @@ -121,6 +126,7 @@ export function ShowSettings(props: ShowSettingsProps): JSX.Element { points, theme, sound, + keyboardShortcuts, location, name, githubProfile, @@ -138,12 +144,13 @@ export function ShowSettings(props: ShowSettingsProps): JSX.Element { verifyCert, userToken } = props; + const isSignedInRef = useRef(isSignedIn); if (showLoading) { return ; } - if (!isSignedIn) { + if (!isSignedInRef.current) { navigate(`${apiLocation}/signin`); return ; } @@ -165,9 +172,11 @@ export function ShowSettings(props: ShowSettingsProps): JSX.Element { picture={picture} points={points} sound={sound} + keyboardShortcuts={keyboardShortcuts} submitNewAbout={submitNewAbout} toggleNightMode={toggleNightMode} toggleSoundMode={toggleSoundMode} + toggleKeyboardShortcuts={toggleKeyboardShortcuts} username={username} /> diff --git a/client/src/client/frame-runner.ts b/client/src/client/frame-runner.ts index d950edc631af9b..4a749625bea8e8 100644 --- a/client/src/client/frame-runner.ts +++ b/client/src/client/frame-runner.ts @@ -1,6 +1,6 @@ import '@babel/polyfill'; import jQuery from 'jquery'; -import curriculumHelpers from '../utils/curriculum-helpers'; +import * as helpers from '@freecodecamp/curriculum-helpers'; declare global { interface Window { @@ -83,17 +83,15 @@ async function initTestFrame(e: InitTestFrameArg = { code: {} }) { return o; }; - // eslint-disable-next-line no-inline-comments const { default: chai } = await import(/* webpackChunkName: "chai" */ 'chai'); const assert = chai.assert; - const __helpers = curriculumHelpers; + const __helpers = helpers; /* eslint-enable @typescript-eslint/no-unused-vars */ let Enzyme; if (e.loadEnzyme) { /* eslint-disable prefer-const */ let Adapter16; - /* eslint-disable no-inline-comments */ [{ default: Enzyme }, { default: Adapter16 }] = await Promise.all([ import(/* webpackChunkName: "enzyme" */ 'enzyme'), @@ -119,7 +117,6 @@ async function initTestFrame(e: InitTestFrameArg = { code: {} }) { // document ready: $(() => { try { - // eslint-disable-next-line no-eval const test: unknown = eval(testString); resolve(test); } catch (err) { diff --git a/client/src/client/workers/test-evaluator.ts b/client/src/client/workers/test-evaluator.ts index 589292d02d885e..38fb0841c455db 100644 --- a/client/src/client/workers/test-evaluator.ts +++ b/client/src/client/workers/test-evaluator.ts @@ -1,9 +1,7 @@ import chai from 'chai'; import '@babel/polyfill'; import { toString as __toString } from 'lodash-es'; -import curriculumHelpers, { - removeJSComments -} from '../../utils/curriculum-helpers'; +import * as helpers from '@freecodecamp/curriculum-helpers'; import { format as __format } from '../../utils/format'; const ctx: Worker & typeof globalThis = self as unknown as Worker & @@ -80,14 +78,14 @@ interface TestEvaluatorEvent extends MessageEvent { ctx.onmessage = async (e: TestEvaluatorEvent) => { /* eslint-disable @typescript-eslint/no-unused-vars */ let code = (e.data?.code?.contents || '').slice(); - code = e.data?.removeComments ? removeJSComments(code) : code; + code = e.data?.removeComments ? helpers.removeJSComments(code) : code; let editableContents = (e.data?.code?.editableContents || '').slice(); editableContents = e.data?.removeComments - ? removeJSComments(editableContents) + ? helpers.removeJSComments(editableContents) : editableContents; const assert = chai.assert; - const __helpers = curriculumHelpers; + const __helpers = helpers; // Fake Deep Equal dependency const DeepEqual = (a: unknown, b: unknown) => JSON.stringify(a) === JSON.stringify(b); @@ -104,13 +102,15 @@ ctx.onmessage = async (e: TestEvaluatorEvent) => { try { // Logging is proxyed after the build to catch console.log messages // generated during testing. - testResult = eval(`${ - e.data?.removeComments ? removeJSComments(e.data.build) : e.data.build + testResult = (await eval(`${ + e.data?.removeComments + ? helpers.removeJSComments(e.data.build) + : e.data.build } __utils.flushLogs(); __userCodeWasExecuted = true; __utils.toggleProxyLogger(true); -${e.data.testString}`) as unknown; +${e.data.testString}`)) as unknown; } catch (err) { if (__userCodeWasExecuted) { // rethrow error, since test failed. diff --git a/client/src/components/Donation/donation-text-components.tsx b/client/src/components/Donation/donation-text-components.tsx index 85e996c8d236e5..fe454c8a6e37b7 100644 --- a/client/src/components/Donation/donation-text-components.tsx +++ b/client/src/components/Donation/donation-text-components.tsx @@ -58,10 +58,12 @@ export const DonationOptionsText = (): JSX.Element => { export const DonationOptionsAlertText = (): JSX.Element => { const { t } = useTranslation(); return ( -

+

donate.bigger-donation{' '} - placeholder + + placeholder +

); diff --git a/client/src/components/Footer/__snapshots__/footer.test.tsx.snap b/client/src/components/Footer/__snapshots__/footer.test.tsx.snap index 526ecff41949ef..cc98c5b98af472 100644 --- a/client/src/components/Footer/__snapshots__/footer.test.tsx.snap +++ b/client/src/components/Footer/__snapshots__/footer.test.tsx.snap @@ -38,11 +38,11 @@ exports[`
matches snapshot 1`] = `
-
footer.trending-guides -
+
@@ -282,11 +282,11 @@ exports[`
matches snapshot 1`] = `
-
footer.our-nonprofit -
+
diff --git a/client/src/components/Footer/footer.css b/client/src/components/Footer/footer.css index 14c274c8be6f21..69748558984d31 100644 --- a/client/src/components/Footer/footer.css +++ b/client/src/components/Footer/footer.css @@ -42,6 +42,8 @@ font-size: 16px; text-align: center; padding: 0 15px 15px; + margin-bottom: 0; + font-family: Lato, sans-serif; } .footer-row { diff --git a/client/src/components/Footer/index.tsx b/client/src/components/Footer/index.tsx index fed253ccbd0762..5bb1c61aefba6f 100644 --- a/client/src/components/Footer/index.tsx +++ b/client/src/components/Footer/index.tsx @@ -25,7 +25,7 @@ function Footer(): JSX.Element {

-
{t('footer.trending-guides')}
+

{t('footer.trending-guides')}

@@ -132,7 +132,7 @@ function Footer(): JSX.Element {
-
{t('footer.our-nonprofit')}
+

{t('footer.our-nonprofit')}

diff --git a/client/src/components/FourOhFour/index.tsx b/client/src/components/FourOhFour/index.tsx index 34a8abc9a115a6..7f392cf48cbc43 100644 --- a/client/src/components/FourOhFour/index.tsx +++ b/client/src/components/FourOhFour/index.tsx @@ -11,8 +11,7 @@ import './404.css'; const FourOhFour = (): JSX.Element => { const { t } = useTranslation(); - // TODO: Remove this type coercion when get-words.js is migrated - const quote = randomQuote() as { quote: string; author: string }; + const quote = randomQuote(); return (
diff --git a/client/src/components/Header/components/Login.tsx b/client/src/components/Header/components/Login.tsx index 2bf96c08e23e7e..83c162bd1597e7 100644 --- a/client/src/components/Header/components/Login.tsx +++ b/client/src/components/Header/components/Login.tsx @@ -1,5 +1,7 @@ import { Button } from '@freecodecamp/react-bootstrap'; -import React from 'react'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faRightToBracket } from '@fortawesome/free-solid-svg-icons'; +import React, { ReactNode } from 'react'; import { useTranslation } from 'react-i18next'; import { connect } from 'react-redux'; import { createSelector } from 'reselect'; @@ -7,8 +9,6 @@ import { createSelector } from 'reselect'; import envData from '../../../../../config/env.json'; import { isSignedInSelector } from '../../../redux'; -import './login.css'; - const { apiLocation, homeLocation } = envData; const mapStateToProps = createSelector(isSignedInSelector, isSignedIn => ({ @@ -17,7 +17,7 @@ const mapStateToProps = createSelector(isSignedInSelector, isSignedIn => ({ export interface LoginProps { block?: boolean; - children?: unknown; + children?: ReactNode; 'data-test-label'?: string; isSignedIn?: boolean; } @@ -38,7 +38,11 @@ const Login = ({ data-test-label={dataTestLabel} href={href} > - {children || t('buttons.sign-in')} + + + {t('buttons.sign-in')} + + {children || t('buttons.sign-in')} ); }; diff --git a/client/src/components/Header/components/login.css b/client/src/components/Header/components/login.css deleted file mode 100644 index e49325e8313ab6..00000000000000 --- a/client/src/components/Header/components/login.css +++ /dev/null @@ -1,3 +0,0 @@ -.signup-btn { - padding: 4px 12px; -} diff --git a/client/src/components/Header/components/menu-button.tsx b/client/src/components/Header/components/menu-button.tsx index 71992801059db6..d5c600edda0d0b 100644 --- a/client/src/components/Header/components/menu-button.tsx +++ b/client/src/components/Header/components/menu-button.tsx @@ -1,39 +1,59 @@ import React, { RefObject } from 'react'; import { useTranslation } from 'react-i18next'; -import AuthOrProfile from './auth-or-profile'; - +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faBars } from '@fortawesome/free-solid-svg-icons'; export interface MenuButtonProps { className?: string; displayMenu?: boolean; innerRef?: RefObject; - onClick?: React.MouseEventHandler | undefined; - user?: Record; + showMenu: () => void; + hideMenu: () => void; } const MenuButton = ({ displayMenu, innerRef, - onClick, - user + showMenu, + hideMenu }: MenuButtonProps): JSX.Element => { const { t } = useTranslation(); + // Will close the menu if the user Shift+Tabs from the menu button. + const handleBlur = (event: React.FocusEvent): void => { + if ( + event.relatedTarget && + !event.relatedTarget.closest('.universal-nav-right') && + displayMenu + ) { + hideMenu(); + } + }; + + const handleClick = (): void => { + if (displayMenu) { + hideMenu(); + return; + } + showMenu(); + }; + return ( - <> - - - + ); }; diff --git a/client/src/components/Header/components/nav-links.tsx b/client/src/components/Header/components/nav-links.tsx index e84e25b8f1c6e6..3f23162748639d 100644 --- a/client/src/components/Header/components/nav-links.tsx +++ b/client/src/components/Header/components/nav-links.tsx @@ -16,19 +16,22 @@ import { faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import React, { Component, Fragment } from 'react'; +import React, { Component, Fragment, createRef, Ref } from 'react'; import { TFunction, withTranslation } from 'react-i18next'; import { connect } from 'react-redux'; import envData from '../../../../../config/env.json'; import { availableLangs, - getLangName + LangNames, + LangCodes, + hiddenLangs } from '../../../../../config/i18n/all-langs'; import { hardGoTo as navigate } from '../../../redux'; import { updateUserFlag } from '../../../redux/settings'; import createLanguageRedirect from '../../create-language-redirect'; import { Link } from '../../helpers'; import { Themes } from '../../settings/theme'; +import LanguageGlobe from '../../../assets/icons/language-globe'; const { clientLocale, radioLocation, apiLocation } = envData; @@ -36,13 +39,17 @@ const locales = availableLangs.client; export interface NavLinksProps { displayMenu?: boolean; + isLanguageMenuDisplayed?: boolean; fetchState?: { pending: boolean }; i18n: Object; t: TFunction; - toggleDisplayMenu?: React.MouseEventHandler; + hideMenu: () => void; toggleNightMode: (x: any) => any; user?: Record; navigate?: (location: string) => void; + showLanguageMenu?: (elementToFocus: HTMLButtonElement) => void; + hideLanguageMenu?: () => void; + menuButtonRef: Ref; } const mapDispatchToProps = { @@ -52,10 +59,22 @@ const mapDispatchToProps = { export class NavLinks extends Component { static displayName: string; + langButtonRef: React.RefObject; + firstLangOptionRef: React.RefObject; + lastLangOptionRef: React.RefObject; constructor(props: NavLinksProps) { super(props); + this.langButtonRef = createRef(); + this.firstLangOptionRef = createRef(); + this.lastLangOptionRef = createRef(); this.handleLanguageChange = this.handleLanguageChange.bind(this); + this.handleLanguageMenuKeyDown = this.handleLanguageMenuKeyDown.bind(this); + this.handleLanguageButtonClick = this.handleLanguageButtonClick.bind(this); + this.handleLanguageButtonKeyDown = + this.handleLanguageButtonKeyDown.bind(this); + this.handleMenuKeyDown = this.handleMenuKeyDown.bind(this); + this.handleBlur = this.handleBlur.bind(this); } toggleTheme(currentTheme = Themes.Default, toggleNightMode: any) { @@ -64,23 +83,171 @@ export class NavLinks extends Component { ); } - handleLanguageChange = ( - event: React.ChangeEvent - ): void => { - const { toggleDisplayMenu, navigate } = this.props; - toggleDisplayMenu(); + getPreviousMenuItem(target: HTMLElement): HTMLElement { + const { menuButtonRef } = this.props; + const previousSibling = + target.closest('.nav-list > li')?.previousElementSibling; + return previousSibling?.querySelector('a, button') ?? menuButtonRef.current; + } + handleLanguageChange = (event: React.MouseEvent): void => { + event.preventDefault(); + const { hideMenu, hideLanguageMenu, menuButtonRef, navigate } = this.props; + const newLanguage = event.target.dataset.value as string; + // If user selected cancel then close menu and put focus on button + if (newLanguage === 'exit-lang-menu') { + // Set focus to language button first so we don't lose focus + // for screen readers. + this.langButtonRef.current.focus(); + hideLanguageMenu(); + return; + } + // Put focus on menu button first so we don't lose focus + // for screen readers. + menuButtonRef.current.focus(); + hideMenu(); + // If user selected the current language then we just close the menu + if (newLanguage === clientLocale) { + return; + } const path = createLanguageRedirect({ clientLocale, - lang: event.target.value + lang: newLanguage }); return navigate(path); }; + handleMenuKeyDown = (event: React.KeyboardEvent): void => { + const { menuButtonRef, hideMenu } = this.props; + if (event.key === 'Escape') { + menuButtonRef.current.focus(); + hideMenu(); + event.preventDefault(); + } + }; + + handleLanguageButtonClick = (): void => { + const { isLanguageMenuDisplayed, hideLanguageMenu, showLanguageMenu } = + this.props; + if (isLanguageMenuDisplayed) { + hideLanguageMenu(); + } else { + showLanguageMenu(this.firstLangOptionRef.current); + } + }; + + handleLanguageButtonKeyDown = ( + event: React.KeyboardEvent + ): void => { + const { menuButtonRef, showLanguageMenu, hideMenu } = this.props; + /* eslint-disable @typescript-eslint/naming-convention */ + const doKeyPress = { + Escape: () => { + menuButtonRef.current.focus(); + hideMenu(); + event.preventDefault(); + }, + ArrowDown: () => { + showLanguageMenu(this.firstLangOptionRef.current); + event.preventDefault(); + }, + ArrowUp: () => { + showLanguageMenu(this.lastLangOptionRef.current); + event.preventDefault(); + } + }; + /* eslint-enable @typescript-eslint/naming-convention */ + doKeyPress[event.key]?.(); + }; + + handleLanguageMenuKeyDown = ( + event: React.KeyboardEvent + ): void => { + const { hideLanguageMenu, hideMenu } = this.props; + const focusFirstLanguageMenuItem = () => { + this.firstLangOptionRef.current.focus(); + event.preventDefault(); + }; + const focusLastLanguageMenuItem = () => { + this.lastLangOptionRef.current.focus(); + event.preventDefault(); + }; + /* eslint-disable @typescript-eslint/naming-convention */ + const doKeyPress = { + Tab: () => { + if (!event.shiftKey) { + // Let the Tab work as normal. + hideLanguageMenu(); + // Close the menu if focus is now outside of the menu. This will + // happen when there is no Sign Out menu item. + setTimeout(() => { + const currentlyFocusedElement = document.activeElement; + if ( + currentlyFocusedElement && + !currentlyFocusedElement.closest('.nav-list') + ) { + hideMenu(); + } + }, 200); + return; + } + // Because FF adds an extra tab stop to the lang menu (because it + // is scrollable) we need to manually focus the previous menu item. + this.getPreviousMenuItem(this.langButtonRef.current).focus(); + hideLanguageMenu(); + event.preventDefault(); + }, + ArrowUp: () => { + const arrowUpItemToFocus = + event.target === this.firstLangOptionRef.current + ? this.lastLangOptionRef.current + : (event.target.parentNode.previousSibling + .firstChild as HTMLElement); + arrowUpItemToFocus.focus(); + event.preventDefault(); + }, + ArrowDown: () => { + const arrowDownItemToFocus = + event.target === this.lastLangOptionRef.current + ? this.firstLangOptionRef.current + : (event.target.parentNode.nextSibling.firstChild as HTMLElement); + arrowDownItemToFocus.focus(); + event.preventDefault(); + }, + Escape: () => { + // Set focus to language button first so we don't lose focus + // for screen readers. + this.langButtonRef.current.focus(); + hideLanguageMenu(); + event.preventDefault(); + }, + Home: focusFirstLanguageMenuItem, + PageUp: focusFirstLanguageMenuItem, + End: focusLastLanguageMenuItem, + PageDown: focusLastLanguageMenuItem + }; + /* eslint-enable @typescript-eslint/naming-convention */ + doKeyPress[event.key]?.(); + }; + + // Added to the last item in the nav menu. Will close the menu if + // the user Tabs out of the menu. + handleBlur = (event: React.FocusEvent): void => { + const { hideMenu, menuButtonRef } = this.props; + if ( + event.relatedTarget && + !event.relatedTarget.closest('.nav-list') && + event.relatedTarget !== menuButtonRef.current + ) { + hideMenu(); + } + }; + render() { const { displayMenu, + isLanguageMenuDisplayed, fetchState, t, toggleNightMode, @@ -92,132 +259,216 @@ export class NavLinks extends Component { return pending ? (
) : ( -
+
    {isDonating ? ( -
    - {t('donate.thanks')} - -
    +
  • +
    + {t('donate.thanks')} + +
    +
  • ) : ( - - {t('buttons.donate')} - - )} - {!username && ( - - {t('buttons.sign-in')} - - )} - - {t('buttons.curriculum')} - - {username && ( - +
  • - {t('buttons.profile')} - - - {t('buttons.settings')} + {t('buttons.donate')} +
  • + )} +
  • + + {t('buttons.curriculum')} + +
  • + {username && ( + +
  • + + {t('buttons.profile')} + +
  • +
  • + + {t('buttons.settings')} + +
  • )} -
    - - {t('buttons.forum')} - - - - {t('buttons.news')} - - - - {t('buttons.radio')} - - -
    - -
    - {t('footer.language')} -
    - -
    - -
    + {t('buttons.forum')} + + + +
  • + + {t('buttons.news')} + + +
  • +
  • + + {t('buttons.radio')} + + +
  • +
  • + +
  • +
  • +
    + + +
    +
  • {username && ( -
    - - {t('buttons.sign-out')} - +
  • + + {t('buttons.sign-out')} + +
  • )} -
+ ); } } diff --git a/client/src/components/Header/components/universal-nav.css b/client/src/components/Header/components/universal-nav.css index e28881984b1c67..40947e38215db9 100644 --- a/client/src/components/Header/components/universal-nav.css +++ b/client/src/components/Header/components/universal-nav.css @@ -3,7 +3,7 @@ justify-content: space-between; align-items: flex-start; font-size: 18px; - font-family: 'Roboto-Mono', sans-serif; + font-family: 'Lato', sans-serif; height: var(--header-height); background: var(--theme-color); position: fixed; @@ -18,10 +18,6 @@ text-decoration: none; } -.universal-nav .universal-nav-right a { - font-family: 'Roboto Mono', monospace; -} - .universal-nav-left { display: flex; flex: 1 0 33%; @@ -89,7 +85,12 @@ margin: 0 0 0 -12px; padding: 0; list-style: none; - max-width: 250px; + max-width: 15rem; +} + +.nav-list li { + width: 100%; + height: 2.2rem; } .nav-link { @@ -104,28 +105,35 @@ min-height: var(--header-height); width: 100%; border: none; + height: 100%; } -.dropdown-nav-link { - padding-left: 0; - padding-right: 0; +.nav-lang { + padding: 0; + width: 100%; + height: 100%; } -.dropdown-nav-link:hover .nav-link-lang-dropdown, -.dropdown-nav-link:active .nav-link-lang-dropdown { - background-image: url('data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2212%22%20height%3D%2212%22%20viewBox%3D%220%200%2012%2012%22%3E%3Ctitle%3Edown-arrow%3C%2Ftitle%3E%3Cg%20fill%3D%22%23000000%22%3E%3Cpath%20d%3D%22M10.293%2C3.293%2C6%2C7.586%2C1.707%2C3.293A1%2C1%2C0%2C0%2C0%2C.293%2C4.707l5%2C5a1%2C1%2C0%2C0%2C0%2C1.414%2C0l5-5a1%2C1%2C0%2C1%2C0-1.414-1.414Z%22%20fill%3D%22%23000000%22%3E%3C%2Fpath%3E%3C%2Fg%3E%3C%2Fsvg%3E'); +.nav-link:focus { + outline: 3px solid var(--blue-mid); + outline-offset: -4px; } -.nav-link:hover, -.nav-link:active { - color: var(--theme-color); +.nav-link:focus:not(:focus-visible) { + background-color: inherit; + color: inherit; +} + +.nav-link:not([aria-disabled='true']):hover { + color: var(--theme-color) !important; text-decoration: none; - background: white; + background-color: var(--gray-10) !important; cursor: pointer; + outline: none !important; } .nav-link-header, -.nav-link-header:hover, +.nav-link-header:not([aria-disabled='true']):hover, .nav-link-header:active { color: var(--gray-00); background-color: var(--gray-90); @@ -142,33 +150,148 @@ height: auto !important; } -.nav-link:hover .nav-link-lang-dropdown, -.nav-link:active .nav-link-lang-dropdown { +.nav-link:hover .nav-lang-menu, +.nav-link:active .nav-lang-menu { background-color: var(--gray-00); color: var(--gray-90); cursor: pointer; } -.nav-link-lang-dropdown { - padding: 0 15px; - color: var(--gray-00); - background-color: var(--gray-90); +button.nav-link:focus { + color: var(--tertiary-color); + background-color: var(--tertiary-background); + outline: 3px solid var(--blue-mid); + outline-offset: -4px; +} + +button.nav-link:focus:not(:focus-visible) { + background-color: inherit; + color: #fff; + outline: none; +} + +button.nav-link:not([aria-disabled='true']):hover { + background-color: var(--gray-10); + color: var(--theme-color); +} + +button.nav-link[aria-disabled='true'] { + cursor: default; + background-color: inherit; +} + +.display-menu .theme-disabled { + height: 4.2rem; +} + +.nav-link-header label { + font-weight: normal; + margin-bottom: 0; +} + +.nav-lang-menu { + display: none; + padding: 0; + color: var(--gray-90); + background-color: var(--gray-80); width: 100%; - border: none; - position: relative; + position: absolute; -webkit-appearance: none; -moz-appearance: none; appearance: none; - background-image: url('data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2212%22%20height%3D%2212%22%20viewBox%3D%220%200%2012%2012%22%3E%3Ctitle%3Edown-arrow%3C%2Ftitle%3E%3Cg%20fill%3D%22%23ffffff%22%3E%3Cpath%20d%3D%22M10.293%2C3.293%2C6%2C7.586%2C1.707%2C3.293A1%2C1%2C0%2C0%2C0%2C.293%2C4.707l5%2C5a1%2C1%2C0%2C0%2C0%2C1.414%2C0l5-5a1%2C1%2C0%2C1%2C0-1.414-1.414Z%22%20fill%3D%22%23ffffff%22%3E%3C%2Fpath%3E%3C%2Fg%3E%3C%2Fsvg%3E'); - background-size: 10px; - background-position: calc(100% - 15px) center; - background-repeat: no-repeat; + list-style-type: none; + margin: 0; + border: 2px solid var(--gray-90); + border-top: 0; + border-bottom: 0; + top: 0; + overflow-y: auto; + scrollbar-width: auto; + /* lang menu should always be full height */ + height: 19.9rem; +} + +/* main menu must be at least as tall as lang menu (when displayed) + unless there isn't enough view port height */ +.nav-list.display-lang-menu { + min-height: min(19.9rem, calc(100vh - var(--header-height))); +} + +.nav-lang-menu > button:hover { + background-image: none !important; } -.nav-link-lang-dropdown:focus { +.nav-lang-menu .nav-link { + color: #fff; + background-color: inherit; + padding-top: 0; +} + +.nav-lang-menu .nav-link:focus { + color: #000; + background-color: var(--gray-10); outline: none; } +.nav-lang-menu .nav-link:focus:not(:focus-visible) { + background-color: inherit; +} + +.nav-lang-menu .nav-link:hover { + background-color: var(--gray-10) !important; +} + +.nav-lang-button { + display: flex; + justify-content: space-between; + background-image: none; +} + +.nav-lang-button:hover svg, +.nav-lang-button:focus { + fill: var(--gray-10); +} + +.nav-lang-button:focus:not(:focus-visible) { + fill: revert; +} + +.nav-lang-button[aria-expanded='true'] + .nav-lang-menu { + display: block; +} + +.nav-lang-button svg { + height: 1rem; + width: 1rem; +} + +.dark-palette .nav-lang-button:focus { + fill: revert; +} + +.nav-lang-menu-option[aria-current='true'] { + /* check mark for current language */ + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='32' height='32' preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16'%3E%3Cg fill='white'%3E%3Cpath d='M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06a.733.733 0 0 1 1.047 0l3.052 3.093l5.4-6.425a.247.247 0 0 1 .02-.022z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E"); + background-size: 1.2rem; + background-position: calc(100% - 10px) center; + background-repeat: no-repeat; +} + +.nav-lang-menu-option[aria-current='true']:focus { + /* check mark for current language */ + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='32' height='32' preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16'%3E%3Cg fill='currentColor'%3E%3Cpath d='M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06a.733.733 0 0 1 1.047 0l3.052 3.093l5.4-6.425a.247.247 0 0 1 .02-.022z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E"); +} + +.nav-lang-menu-option[aria-current='true']:focus:not(:focus-visible) { + /* check mark for current language */ + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='32' height='32' preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16'%3E%3Cg fill='white'%3E%3Cpath d='M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06a.733.733 0 0 1 1.047 0l3.052 3.093l5.4-6.425a.247.247 0 0 1 .02-.022z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E"); +} + +.nav-lang-menu-option[aria-current='true']:hover { + /* check mark for current language */ + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='32' height='32' preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16'%3E%3Cg fill='currentColor'%3E%3Cpath d='M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06a.733.733 0 0 1 1.047 0l3.052 3.093l5.4-6.425a.247.247 0 0 1 .02-.022z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E") !important; +} + .nav-link-flex { display: flex; justify-content: space-between; @@ -202,8 +325,10 @@ color: var(--gray-00); background-color: var(--theme-color); cursor: pointer; - max-height: calc(var(--header-height) - 6px); + max-height: calc(var(--header-height) - 8px); margin-right: 10px; + display: flex; + align-items: center; } .toggle-button-nav:hover { @@ -213,8 +338,12 @@ } .toggle-button-nav:focus { - outline: 5px auto -webkit-focus-ring-color !important; - outline-offset: -3px; + outline: 3px solid var(--blue-mid); + outline-offset: 0; +} + +.toggle-button-nav:focus:not(:focus-visible) { + outline: none; } .avatar-nav-link { @@ -269,12 +398,12 @@ scrollbar-width: none; } -.display-menu::-webkit-scrollbar { - display: none; +.expand-lang-menu .display-menu { + overflow-y: unset; } -.toggle-button-nav { - display: flex; +.display-menu::-webkit-scrollbar { + display: none; } .reverse-toggle-color { @@ -287,28 +416,97 @@ color: var(--theme-color); } -.nav-line, +.nav-line { + border-top: 0.1rem solid var(--gray-45); +} + .nav-line-2 { border-color: var(--gray-45); width: 100%; margin: 0; -} - -.nav-line-2 { border-top-width: 2px; } .signup-btn { max-height: calc(var(--header-height) - 6px); - padding: 0 8px; + padding: 4px 12px; margin-left: 2px; + font-family: 'Roboto Mono', monospace !important; + display: flex; + align-items: center; + justify-content: center; } -@media (max-width: 980px) { - .universal-nav-left { - display: none; - } +.universal-nav-right .fcc_searchBar { + position: absolute; + top: 0; + left: 0; +} + +.universal-nav-right .fcc_searchBar .ais-SearchBox-form { + width: 100vw; + height: 38px; + max-width: unset; + padding: 0 15px; + left: 0; +} + +/* In mobile layout, prevent search input from hanging around if the + menu is collapsed. */ +.universal-nav-right + #toggle-button-nav[aria-expanded='false'] + + .fcc_searchBar + .ais-SearchBox-form { + display: none; +} + +/* In mobile layout, prevent search results from hanging around if the + menu is collapsed. */ +.universal-nav-right + #toggle-button-nav[aria-expanded='false'] + + .fcc_searchBar + .ais-Hits { + display: none; +} + +.universal-nav-right .ais-SearchBox-input { + width: calc(100vw - 17rem); + padding-left: 27px; +} + +.universal-nav-right .fcc_searchBar .ais-Hits { + width: calc(100vw - 17rem); +} + +.universal-nav-right .fcc_searchBar .ais-SearchBox-submit { + top: unset; + margin-top: 19px; + left: 18px; +} +.ais-SearchBox-input:focus { + outline: 3px solid var(--blue-mid); +} + +.ais-SearchBox-submit:focus { + outline: 3px solid var(--blue-mid); +} + +.ais-SearchBox-submit:focus:not(:focus-visible) { + outline: none; +} + +#toggle-button-nav .menu-btn-text, +#universal-nav .login-btn-text { + display: inline-block; +} + +#toggle-button-nav .menu-btn-icon, +.login-btn-icon { + display: none; +} + +@media (max-width: 980px) { .universal-nav-middle { flex: none; } @@ -318,7 +516,7 @@ } .universal-nav-right { - flex: 1 0 50%; + flex: 1 0 auto; display: flex; justify-content: flex-end; } @@ -350,46 +548,61 @@ margin-top: 0; } - .fcc_searchBar .ais-SearchBox-form { - max-width: 100%; - } - - .ais-SearchBox-input { - min-width: 100%; + .fcc_searchBar, + .fcc_searchBar div { + width: 100%; } - .ais-Hits { - min-width: calc(100% - 30px); + .universal-nav-right .fcc_searchBar .ais-SearchBox-form { + width: 100%; } .display-menu { max-height: calc(100vh - var(--header-height) * 2); } + + .universal-nav-right .ais-SearchBox-input { + width: calc(100vw - 30px); + } + + .universal-nav-right .fcc_searchBar .ais-Hits { + width: calc(100% - 30px); + } + #universal-nav .signup-btn { + padding: 4px 6px; + } + #toggle-button-nav .menu-btn-text, + #universal-nav .login-btn-text { + display: none; + } + + #toggle-button-nav .menu-btn-icon, + #universal-nav .login-btn-icon { + display: inline-block; + } + .toggle-button-nav { + padding: 2px 8px; + } + #universal-nav-logo svg { + display: block; + width: auto; + height: 18px; + margin: 10px 0; + } } -@media (max-width: 455px) { +@media (max-width: 450px) { .universal-nav { padding: 0 5px; } - .universal-nav { padding: 0 5px; } - .nav-link-sign-in { display: flex; } - - .navatar .signup-btn { - display: none; - } - - .navatar { - display: none; - } - #universal-nav-logo { - max-width: 60%; + left: 8px; } } @@ -398,4 +611,10 @@ max-width: none; left: -170px; } + #universal-nav-logo svg { + display: block; + width: auto; + height: 24px; + margin: 7px 0; + } } diff --git a/client/src/components/Header/components/universal-nav.tsx b/client/src/components/Header/components/universal-nav.tsx index 8603b62f25a39d..a11e008f8d4357 100644 --- a/client/src/components/Header/components/universal-nav.tsx +++ b/client/src/components/Header/components/universal-nav.tsx @@ -6,29 +6,41 @@ import Loadable from '@loadable/component'; import React, { Ref } from 'react'; import { useTranslation } from 'react-i18next'; +import Media from 'react-responsive'; import { isLanding } from '../../../utils/path-parsers'; import { Link, SkeletonSprite } from '../../helpers'; import MenuButton from './menu-button'; import NavLinks from './nav-links'; import NavLogo from './nav-logo'; import './universal-nav.css'; +import AuthOrProfile from './auth-or-profile'; const SearchBar = Loadable(() => import('../../search/searchBar/search-bar')); const SearchBarOptimized = Loadable( () => import('../../search/searchBar/search-bar-optimized') ); +const MAX_MOBILE_WIDTH = 980; + export interface UniversalNavProps { displayMenu?: boolean; + isLanguageMenuDisplayed?: boolean; fetchState?: { pending: boolean }; menuButtonRef?: Ref | undefined; searchBarRef?: unknown; - toggleDisplayMenu?: React.MouseEventHandler | undefined; + showMenu?: () => void; + hideMenu?: () => void; + showLanguageMenu?: (elementToFocus: HTMLButtonElement) => void; + hideLanguageMenu?: () => void; user?: Record; } export const UniversalNav = ({ displayMenu, - toggleDisplayMenu, + isLanguageMenuDisplayed, + showMenu, + hideMenu, + showLanguageMenu, + hideLanguageMenu, menuButtonRef, searchBarRef, user, @@ -47,15 +59,13 @@ export const UniversalNav = ({ return (
- - ); }; diff --git a/client/src/components/Header/header.test.tsx b/client/src/components/Header/header.test.tsx index 9fb4be3ff9facc..d6ff706876120a 100644 --- a/client/src/components/Header/header.test.tsx +++ b/client/src/components/Header/header.test.tsx @@ -2,191 +2,12 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-return */ -import React, { Ref } from 'react'; -import { useTranslation } from 'react-i18next'; +import React from 'react'; import { create, ReactTestRendererJSON } from 'react-test-renderer'; -import ShallowRenderer from 'react-test-renderer/shallow'; - -import envData from '../../../../config/env.json'; -import { availableLangs, getLangName } from '../../../../config/i18n/all-langs'; -import { Themes } from '../settings/theme'; import AuthOrProfile from './components/auth-or-profile'; -import { NavLinks } from './components/nav-links'; -import { UniversalNav } from './components/universal-nav'; - -const { apiLocation, clientLocale } = envData; jest.mock('../../analytics'); -describe('', () => { - const UniversalNavProps = { - displayMenu: false, - menuButtonRef: {} as Ref | undefined, - searchBarRef: {}, - // eslint-disable-next-line @typescript-eslint/no-empty-function - toggleDisplayMenu: function () {}, - pathName: '/', - fetchState: { - pending: false - } - }; - it('renders to the DOM', () => { - const utils = ShallowRenderer.createRenderer(); - utils.render(); - const view = utils.getRenderOutput(); - expect(view).toBeTruthy(); - }); -}); - -describe('', () => { - const { t } = useTranslation(); - it('has expected navigation links when not signed in', () => { - const landingPageProps = { - fetchState: { - pending: false - }, - user: { - isDonating: false, - username: null, - theme: Themes.Default - }, - i18n: { - language: 'en' - }, - toggleNightMode: (theme: Themes) => theme, - t: t - }; - const utils = ShallowRenderer.createRenderer(); - utils.render(); - const view = utils.getRenderOutput(); - expect( - hasDonateNavItem(view) && - hasSignInNavItem(view) && - hasCurriculumNavItem(view) && - hasForumNavItem(view) && - hasNewsNavItem(view) && - hasRadioNavItem(view) && - hasLanguageHeader(view) && - hasLanguageDropdown(view) - ).toBeTruthy(); - }); - - it('has expected navigation links when signed in', () => { - const landingPageProps = { - fetchState: { - pending: false - }, - user: { - isDonating: false, - username: 'nhcarrigan', - theme: Themes.Default - }, - i18n: { - language: 'en' - }, - t: t, - toggleNightMode: (theme: Themes) => theme - }; - const utils = ShallowRenderer.createRenderer(); - utils.render(); - const view = utils.getRenderOutput(); - expect( - hasDonateNavItem(view) && - hasCurriculumNavItem(view) && - hasProfileAndSettingsNavItems(view, landingPageProps.user.username) && - hasForumNavItem(view) && - hasNewsNavItem(view) && - hasRadioNavItem(view) && - hasSignOutNavItem(view) - ).toBeTruthy(); - }); - - it('has expected navigation links when signed in and donating', () => { - const landingPageProps = { - fetchState: { - pending: false - }, - user: { - isDonating: true, - username: 'moT01', - theme: Themes.Default - }, - i18n: { - language: 'en' - }, - t: t, - toggleNightMode: (theme: Themes) => theme - }; - const utils = ShallowRenderer.createRenderer(); - utils.render(); - const view = utils.getRenderOutput(); - expect( - hasThanksForDonating(view) && - hasCurriculumNavItem(view) && - hasProfileAndSettingsNavItems(view, landingPageProps.user.username) && - hasForumNavItem(view) && - hasNewsNavItem(view) && - hasRadioNavItem(view) && - hasSignOutNavItem(view) && - hasLanguageHeader(view) && - hasLanguageDropdown(view) - ).toBeTruthy(); - }); - - it('has expected available languages in the language dropdown', () => { - const landingPageProps = { - fetchState: { - pending: false - }, - user: { - isDonating: true, - username: 'moT01', - theme: Themes.Default - }, - i18n: { - language: 'en' - }, - t: t, - toggleNightMode: (theme: Themes) => theme - }; - const utils = ShallowRenderer.createRenderer(); - utils.render(); - const view = utils.getRenderOutput(); - expect( - hasLanguageHeader(view) && - hasLanguageDropdown(view) && - hasAllAvailableLanguagesInDropdown(view) - ).toBeTruthy(); - }); - - it('has default language selected in language dropdown based on client config', () => { - const landingPageProps = { - fetchState: { - pending: false - }, - user: { - isDonating: true, - username: 'moT01', - theme: Themes.Default - }, - i18n: { - language: 'en' - }, - t: t, - toggleNightMode: (theme: Themes) => theme - }; - const utils = ShallowRenderer.createRenderer(); - utils.render(); - const view = utils.getRenderOutput(); - expect( - hasLanguageHeader(view) && - hasLanguageDropdown(view) && - hasAllAvailableLanguagesInDropdown(view) && - hasDefaultLanguageInLanguageDropdown(view, clientLocale) - ).toBeTruthy(); - }); -}); - describe('', () => { it('has avatar with default border for default users', () => { const defaultUserProps = { @@ -257,123 +78,9 @@ describe('', () => { }); }); -const navigationLinks = (component: JSX.Element, key: string) => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-call - const target = component.props.children.find( - (child: { key?: string }) => child && child.key === key - ); - return target.props; -}; - // eslint-disable-next-line @typescript-eslint/no-explicit-any const profileNavItem = (component: any) => component.children[0]; -const hasDonateNavItem = (component: JSX.Element) => { - const { children, to } = navigationLinks(component, 'donate'); - return children === 'buttons.donate' && to === '/donate'; -}; - -const hasThanksForDonating = (component: JSX.Element) => { - const { children } = navigationLinks(component, 'donate'); - return children ? children[0].props.children === 'donate.thanks' : null; -}; - -const hasSignInNavItem = (component: JSX.Element) => { - const { children } = navigationLinks(component, 'signin'); - return children === 'buttons.sign-in'; -}; - -const hasCurriculumNavItem = (component: JSX.Element) => { - const { children, to } = navigationLinks(component, 'learn'); - return children === 'buttons.curriculum' && to === '/learn'; -}; - -const hasProfileAndSettingsNavItems = ( - component: JSX.Element, - username: string -) => { - const fragment = navigationLinks(component, 'profile-settings'); - - const profile = fragment ? fragment.children[0].props : null; - const settings = fragment.children[1].props; - - const hasProfile = - profile.children === 'buttons.profile' && profile.to === `/${username}`; - const hasSettings = - settings.children === 'buttons.settings' && settings.to === '/settings'; - - return hasProfile && hasSettings; -}; - -const hasForumNavItem = (component: JSX.Element) => { - const { children, to } = navigationLinks(component, 'forum'); - // TODO: test compiled TFunction value - return ( - children[0].props.children === 'buttons.forum' && to === 'links:nav.forum' - ); -}; - -const hasNewsNavItem = (component: JSX.Element) => { - const { children, to } = navigationLinks(component, 'news'); - return ( - children[0].props.children === 'buttons.news' && to === 'links:nav.news' - ); -}; - -const hasRadioNavItem = (component: JSX.Element) => { - const { children, to } = navigationLinks(component, 'radio'); - return ( - children[0].props.children === 'buttons.radio' && - to === 'https://coderadio.freecodecamp.org' - ); -}; - -const hasLanguageHeader = (component: JSX.Element) => { - const { children } = navigationLinks(component, 'lang-header'); - return children === 'footer.language'; -}; - -const hasLanguageDropdown = (component: JSX.Element) => { - const { children } = navigationLinks(component, 'language-dropdown'); - return children.type === 'select'; -}; - -const hasDefaultLanguageInLanguageDropdown = ( - component: JSX.Element, - defaultLanguage: string -) => { - const { children } = navigationLinks(component, 'language-dropdown'); - return children.props.value === defaultLanguage; -}; - -const hasAllAvailableLanguagesInDropdown = (component: JSX.Element) => { - const { children }: { children: JSX.Element } = navigationLinks( - component, - 'language-dropdown' - ); - // eslint-disable-next-line @typescript-eslint/no-unsafe-call - return children.props.children.every( - ({ props }: { props: { value: string; children: string } }) => - availableLangs.client.includes(props.value) && - getLangName(props.value) === props.children - ); -}; - -const hasSignOutNavItem = (component: JSX.Element) => { - const { children } = navigationLinks(component, 'signout-frag'); - const signOutProps = children[1].props; - - return ( - signOutProps.children === 'buttons.sign-out' && - signOutProps.href === `${apiLocation}/signout` - ); -}; - -/* TODO: Apply this to Universalnav component -const hasSignInButton = component => - component.props.children[1].props.children === 'buttons.sign-in'; -*/ - const avatarHasClass = ( componentTree: ReactTestRendererJSON | ReactTestRendererJSON[] | null, classes: string diff --git a/client/src/components/Header/index.tsx b/client/src/components/Header/index.tsx index 0c904b6b33c341..e165e80e0dcdf1 100644 --- a/client/src/components/Header/index.tsx +++ b/client/src/components/Header/index.tsx @@ -15,52 +15,71 @@ export interface HeaderProps { } export class Header extends React.Component< HeaderProps, - { displayMenu: boolean } + { displayMenu: boolean; isLanguageMenuDisplayed: boolean } > { - menuButtonRef: React.RefObject; + menuButtonRef: React.RefObject; searchBarRef: React.RefObject; static displayName: string; constructor(props: HeaderProps) { super(props); this.state = { - displayMenu: false + displayMenu: false, + isLanguageMenuDisplayed: false }; this.menuButtonRef = React.createRef(); this.searchBarRef = React.createRef(); this.handleClickOutside = this.handleClickOutside.bind(this); - this.toggleDisplayMenu = this.toggleDisplayMenu.bind(this); - } - - componentDidMount(): void { - document.addEventListener('click', this.handleClickOutside); - } - - componentWillUnmount(): void { - document.removeEventListener('click', this.handleClickOutside); + this.showMenu = this.showMenu.bind(this); + this.hideMenu = this.hideMenu.bind(this); + this.showLanguageMenu = this.showLanguageMenu.bind(this); + this.hideLanguageMenu = this.hideLanguageMenu.bind(this); } handleClickOutside(event: globalThis.MouseEvent): void { + const eventTarget = event.target as HTMLElement; if ( this.state.displayMenu && this.menuButtonRef.current && - !this.menuButtonRef.current.contains(event.target) && + !this.menuButtonRef.current.contains(eventTarget) && // since the search bar is part of the menu on small screens, clicks on // the search bar should not toggle the menu this.searchBarRef.current && - !this.searchBarRef.current.contains(event.target) && - !(event.target instanceof HTMLSelectElement) + !this.searchBarRef.current.contains(eventTarget) && + // don't count clicks on language button/menu + !eventTarget.closest('.nav-lang') && + // don't count clicks on disabled elements + !eventTarget.closest('[aria-disabled="true"]') ) { - this.toggleDisplayMenu(); + this.hideMenu(); } } - toggleDisplayMenu(): void { - this.setState(({ displayMenu }: { displayMenu: boolean }) => ({ - displayMenu: !displayMenu - })); + showMenu(): void { + this.setState({ displayMenu: true }, () => { + document.addEventListener('click', this.handleClickOutside); + }); + } + + hideMenu(): void { + this.setState({ displayMenu: false }, () => { + document.removeEventListener('click', this.handleClickOutside); + this.hideLanguageMenu(); + }); } + + // elementToFocus must be a link in the language menu + showLanguageMenu(elementToFocus: HTMLButtonElement): void { + this.setState({ isLanguageMenuDisplayed: true }, () => + elementToFocus.focus() + ); + } + + hideLanguageMenu(): void { + this.setState({ isLanguageMenuDisplayed: false }); + } + render(): JSX.Element { - const { displayMenu } = this.state; + const { displayMenu, isLanguageMenuDisplayed } = this.state; const { fetchState, user } = this.props; return ( <> @@ -71,9 +90,13 @@ export class Header extends React.Component<
diff --git a/client/src/components/Map/__snapshots__/map.test.tsx.snap b/client/src/components/Map/__snapshots__/map.test.tsx.snap index b1365622b20404..078190f95fa774 100644 --- a/client/src/components/Map/__snapshots__/map.test.tsx.snap +++ b/client/src/components/Map/__snapshots__/map.test.tsx.snap @@ -52,7 +52,7 @@ exports[` snapshot: Map 1`] = `
  • +
  • + +
    + +
    + +
    +
  • diff --git a/client/src/components/Map/index.tsx b/client/src/components/Map/index.tsx index ec9f45b9f8665a..01ea334f727106 100644 --- a/client/src/components/Map/index.tsx +++ b/client/src/components/Map/index.tsx @@ -28,10 +28,10 @@ interface MapData { function createSuperBlockTitle(superBlock: SuperBlocks) { const superBlockTitle = i18next.t(`intro:${superBlock}.title`); return superBlock === 'coding-interview-prep' - ? i18next.t('learn.cert-map-estimates.coding-prep', { + ? superBlockTitle + : i18next.t('learn.cert-map-estimates.certs', { title: superBlockTitle - }) - : i18next.t('learn.cert-map-estimates.certs', { title: superBlockTitle }); + }); } const linkSpacingStyle = { @@ -168,8 +168,8 @@ export function Map({ const nodes = data.allChallengeNode.nodes; const temp = [ nodes[0], - nodes[11], - ...nodes.filter((_, i) => i !== 0 && i !== 11) + nodes[12], + ...nodes.filter((_, i) => i !== 0 && i !== 12) ]; return ( diff --git a/client/src/components/create-redirect.ts b/client/src/components/create-redirect.ts index 250f1b8d02cd7f..41d3cfc564c1ba 100644 --- a/client/src/components/create-redirect.ts +++ b/client/src/components/create-redirect.ts @@ -1,3 +1,4 @@ +/* eslint-disable react/display-name */ import { navigate } from 'gatsby'; const createRedirect = diff --git a/client/src/components/profile/components/certifications.tsx b/client/src/components/profile/components/certifications.tsx index 88f98d7f1770c4..0350bf390fd37f 100644 --- a/client/src/components/profile/components/certifications.tsx +++ b/client/src/components/profile/components/certifications.tsx @@ -15,7 +15,7 @@ const mapStateToProps = ( props: CertificationProps ) => createSelector( - certificatesByNameSelector(props.username), + certificatesByNameSelector(props.username.toLowerCase()), ({ hasModernCert, hasLegacyCert, @@ -48,6 +48,7 @@ function renderCertShow(username: string, cert: CurrentCert): React.ReactNode { View {cert.title} diff --git a/client/src/components/profile/components/time-line.tsx b/client/src/components/profile/components/time-line.tsx index d1ac3063453f61..f8eb48335767ef 100644 --- a/client/src/components/profile/components/time-line.tsx +++ b/client/src/components/profile/components/time-line.tsx @@ -243,6 +243,7 @@ function useIdToNameMap(): Map { challenge { fields { slug + blockName } id title @@ -268,11 +269,16 @@ function useIdToNameMap(): Map { // @ts-expect-error Graphql needs typing title, // @ts-expect-error Graphql needs typing - fields: { slug } + fields: { slug, blockName } } } }) => { - idToNameMap.set(id, { challengeTitle: title, challengePath: slug }); + idToNameMap.set(id, { + challengeTitle: `${ + title.includes('Step') ? `${blockName} - ` : '' + }${title}`, + challengePath: slug + }); } ); return idToNameMap; diff --git a/client/src/components/profile/profile.test.tsx b/client/src/components/profile/profile.test.tsx index 0e4172f84d04bb..8255e1e691d31b 100644 --- a/client/src/components/profile/profile.test.tsx +++ b/client/src/components/profile/profile.test.tsx @@ -50,6 +50,7 @@ const userProps = { savedChallenges: [], sendQuincyEmail: true, sound: true, + keyboardShortcuts: false, theme: Themes.Default, twitter: 'string', username: 'string', diff --git a/client/src/components/settings/about.tsx b/client/src/components/settings/about.tsx index a5ceb119e7de49..61f5ff7d96cc7f 100644 --- a/client/src/components/settings/about.tsx +++ b/client/src/components/settings/about.tsx @@ -14,6 +14,7 @@ import BlockSaveButton from '../helpers/form/block-save-button'; import SoundSettings from './sound'; import ThemeSettings, { Themes } from './theme'; import UsernameSettings from './username'; +import KeyboardShortcutsSettings from './keyboard-shortcuts'; type FormValues = { name: string; @@ -30,10 +31,12 @@ type AboutProps = { picture: string; points: number; sound: boolean; + keyboardShortcuts: boolean; submitNewAbout: (formValues: FormValues) => void; t: TFunction; toggleNightMode: (theme: Themes) => void; toggleSoundMode: (sound: boolean) => void; + toggleKeyboardShortcuts: (keyboardShortcuts: boolean) => void; username: string; }; @@ -198,10 +201,12 @@ class AboutSettings extends Component { const { currentTheme, sound, + keyboardShortcuts, username, t, toggleNightMode, - toggleSoundMode + toggleSoundMode, + toggleKeyboardShortcuts } = this.props; return (
    @@ -260,6 +265,10 @@ class AboutSettings extends Component { toggleNightMode={toggleNightMode} /> +
    ); diff --git a/client/src/components/settings/certification.js b/client/src/components/settings/certification.js index 60db0661773f57..54027261b95b81 100644 --- a/client/src/components/settings/certification.js +++ b/client/src/components/settings/certification.js @@ -264,10 +264,10 @@ export class CertificationSettings extends Component { return projectsMap[certName] .map(({ link, title, id }) => ( - + {title} - + {this.getProjectSolution(id, title)} @@ -278,6 +278,7 @@ export class CertificationSettings extends Component { ); const ShowMultifileProjectSolution = ( - - - {t('buttons.show-code')} - - - {t('buttons.show-project')} - - +
    + + + {t('buttons.show-code')} + + + {t('buttons.show-project')} + + +
    ); const ShowProjectAndGithubLinks = ( diff --git a/client/src/pages/certification.css b/client/src/pages/certification.css index 98c8bd8de35147..086c5001ae1c07 100644 --- a/client/src/pages/certification.css +++ b/client/src/pages/certification.css @@ -159,6 +159,10 @@ background-color: var(--gray-05); } +.certificate-outer-wrapper { + margin-top: calc(-1 * var(--header-height)); +} + /*mobile media queries*/ @media screen and (max-width: 675px) { .certification-namespaces.issue-date { @@ -257,6 +261,55 @@ } } -.certificate-outer-wrapper { - margin-top: calc(-1 * var(--header-height)); +/* print media queries */ +@media print { + body { + height: 210mm; + width: 297mm; + } + + .certificate-outer-wrapper { + width: 100%; + margin: 0; + justify-content: center; + } + + .certification-namespace { + border-color: var(--theme-color) !important; + } + + .certificate-outer-wrapper header { + -webkit-print-color-adjust: exact !important; + color-adjust: exact !important; + background-color: var(--theme-color) !important; + display: flex; + align-items: center; + justify-content: space-around; + } + + .certification-namespace h3 { + font-size: 25px; + } + + .certification-namespace h1 { + font-size: 28px; + } + + .certification-namespace .issue-date, + .certification-namespace .issue-date strong { + color: var(--gray-00) !important; + } + + .certification-namespace .information { + height: 300px; + } + + .certification-namespace .signatures img { + max-width: 300px !important; + } + + .row.certificate-links, + .donation-section { + display: none; + } } diff --git a/client/src/pages/donate.tsx b/client/src/pages/donate.tsx index ea871feb4cd5ca..211ebbbf7fb10b 100644 --- a/client/src/pages/donate.tsx +++ b/client/src/pages/donate.tsx @@ -100,8 +100,8 @@ function DonatePage({ {isDonating ? ( - -

    {t('donate.thank-you-2')}

    + +

    {t('donate.thank-you')}


    diff --git a/client/src/pages/learn.tsx b/client/src/pages/learn.tsx index 6cc089fc38fac7..16e3bea6ff8a22 100644 --- a/client/src/pages/learn.tsx +++ b/client/src/pages/learn.tsx @@ -100,7 +100,13 @@ export default connect(mapStateToProps, null)(LearnPage); export const query = graphql` query FirstChallenge { - challengeNode(challenge: { order: { eq: 0 }, challengeOrder: { eq: 0 } }) { + challengeNode( + challenge: { + superOrder: { eq: 0 } + order: { eq: 0 } + challengeOrder: { eq: 0 } + } + ) { challenge { fields { slug diff --git a/client/src/redux/accept-terms-saga.js b/client/src/redux/accept-terms-saga.js index b97bf59a601fae..0c8092efec0537 100644 --- a/client/src/redux/accept-terms-saga.js +++ b/client/src/redux/accept-terms-saga.js @@ -8,10 +8,10 @@ import { acceptTermsComplete, acceptTermsError } from './'; function* acceptTermsSaga({ payload: quincyEmails }) { try { - const response = yield call(putUserAcceptsTerms, quincyEmails); + const { data } = yield call(putUserAcceptsTerms, quincyEmails); yield put(acceptTermsComplete(quincyEmails)); - yield put(createFlashMessage(response)); + yield put(createFlashMessage(data)); } catch (e) { yield put(acceptTermsError(e)); } diff --git a/client/src/redux/codeally-saga.js b/client/src/redux/codeally-saga.js index cc5c6a09221d67..820e6600410163 100644 --- a/client/src/redux/codeally-saga.js +++ b/client/src/redux/codeally-saga.js @@ -22,10 +22,10 @@ function* tryToShowCodeAllySaga() { yield put(showCodeAlly()); } else { try { - const response = yield call(postUserToken); + const { data } = yield call(postUserToken); - if (response?.userToken) { - yield put(updateUserToken(response.userToken)); + if (data?.userToken) { + yield put(updateUserToken(data.userToken)); yield put(showCodeAlly()); } else { yield put(createFlashMessage(startProjectErrMessage)); diff --git a/client/src/redux/donation-saga.js b/client/src/redux/donation-saga.js index 79860f4a2c2ef1..8ec0ca55f9576c 100644 --- a/client/src/redux/donation-saga.js +++ b/client/src/redux/donation-saga.js @@ -103,7 +103,9 @@ function* postChargeStripeCardSaga({ }) { try { const optimizedPayload = { paymentMethodId, amount, duration }; - const { error } = yield call(postChargeStripeCard, optimizedPayload); + const { + data: { error } + } = yield call(postChargeStripeCard, optimizedPayload); if (error) { yield stripeCardErrorHandler( error, diff --git a/client/src/redux/failed-updates-epic.js b/client/src/redux/failed-updates-epic.js index 0aad82e75cd6f0..f8f78feee1a1fc 100644 --- a/client/src/redux/failed-updates-epic.js +++ b/client/src/redux/failed-updates-epic.js @@ -1,4 +1,3 @@ -/* eslint-disable no-unused-vars */ import { ofType } from 'redux-observable'; import { merge, empty } from 'rxjs'; import { @@ -51,15 +50,14 @@ function failedUpdateEpic(action$, state$) { filter(() => store.get(key)), filter(() => isServerOnlineSelector(state$.value)), tap(() => { - let failures = store.get(key) || []; + let failures = store.get(key); + failures = Array.isArray(failures) ? failures : []; let submitableFailures = failures.filter(isSubmitable); // delete unsubmitable failed challenges - if (submitableFailures.length !== failures.length) { - store.set(key, submitableFailures); - failures = submitableFailures; - } + store.set(key, submitableFailures); + failures = submitableFailures; let delayTime = 100; const batch = failures.map((update, i) => { @@ -77,11 +75,8 @@ function failedUpdateEpic(action$, state$) { return delay(delayTime, () => postUpdate$(update) .pipe( - switchMap(response => { - if ( - response && - (response.message || isGoodXHRStatus(response.status)) - ) { + switchMap(({ response, data }) => { + if (data?.message || isGoodXHRStatus(response?.status)) { console.info(`${update.id} succeeded`); // the request completed successfully const failures = store.get(key) || []; @@ -104,8 +99,7 @@ function failedUpdateEpic(action$, state$) { ignoreElements() ); - return storeUpdates; - // return merge(storeUpdates, flushUpdates); + return merge(storeUpdates, flushUpdates); } export default failedUpdateEpic; diff --git a/client/src/redux/failed-updates-epic.test.js b/client/src/redux/failed-updates-epic.test.js index c7eb49d76c525c..f677d5f290f971 100644 --- a/client/src/redux/failed-updates-epic.test.js +++ b/client/src/redux/failed-updates-epic.test.js @@ -8,8 +8,7 @@ jest.mock('../analytics'); const key = 'fcc-failed-updates'; -// TODO: re-enable once we start flushing failed updates again -describe.skip('failed-updates-epic', () => { +describe('failed-updates-epic', () => { it('should remove faulty backend challenges from localStorage', async () => { store.set(key, failedSubmissions); diff --git a/client/src/redux/fetch-user-saga.js b/client/src/redux/fetch-user-saga.js index 5d60b990b8b2ab..a77a72a74d23e5 100644 --- a/client/src/redux/fetch-user-saga.js +++ b/client/src/redux/fetch-user-saga.js @@ -16,15 +16,14 @@ function* fetchSessionUser() { } try { const { - user = {}, - result = '', - sessionMeta = {} + data: { user = {}, result = '', sessionMeta = {} } } = yield call(getSessionUser); const appUser = user[result] || {}; yield put( fetchUserComplete({ user: appUser, username: result, sessionMeta }) ); } catch (e) { + console.log('failed to fetch user', e); yield put(fetchUserError(e)); } } @@ -33,10 +32,9 @@ function* fetchOtherUser({ payload: maybeUser = '' }) { try { const maybeUserLC = maybeUser.toLowerCase(); - const { entities: { user = {} } = {}, result = '' } = yield call( - getUserProfile, - maybeUserLC - ); + const { + data: { entities: { user = {} } = {}, result = '' } + } = yield call(getUserProfile, maybeUserLC); const otherUser = user[result] || {}; yield put( fetchProfileForUserComplete({ user: otherUser, username: result }) diff --git a/client/src/redux/index.js b/client/src/redux/index.js index 2ef07d287b4982..916becc024dc61 100644 --- a/client/src/redux/index.js +++ b/client/src/redux/index.js @@ -735,6 +735,8 @@ export const reducer = handleActions( payload ? spreadThePayloadOnUser(state, payload) : state, [settingsTypes.updateMyThemeComplete]: (state, { payload }) => payload ? spreadThePayloadOnUser(state, payload) : state, + [settingsTypes.updateMyKeyboardShortcutsComplete]: (state, { payload }) => + payload ? spreadThePayloadOnUser(state, payload) : state, [settingsTypes.updateMyHonestyComplete]: (state, { payload }) => payload ? spreadThePayloadOnUser(state, payload) : state, [settingsTypes.updateMyQuincyEmailComplete]: (state, { payload }) => diff --git a/client/src/redux/prop-types.ts b/client/src/redux/prop-types.ts index f45f5ff31c1298..1a2947a392588a 100644 --- a/client/src/redux/prop-types.ts +++ b/client/src/redux/prop-types.ts @@ -59,6 +59,7 @@ export const UserPropType = PropTypes.shape({ sendQuincyEmail: PropTypes.bool, sound: PropTypes.bool, theme: PropTypes.string, + keyboardShortcuts: PropTypes.bool, twitter: PropTypes.string, username: PropTypes.string, website: PropTypes.string @@ -277,6 +278,7 @@ export type User = { sendQuincyEmail: boolean; sound: boolean; theme: Themes; + keyboardShortcuts: boolean; twitter: string; username: string; website: string; @@ -385,7 +387,7 @@ export type ChallengeFile = { name: string; editableRegionBoundaries?: number[]; usesMultifileEditor?: boolean; - error: null | string; + error: null | string | unknown; head: string; tail: string; seed: string; diff --git a/client/src/redux/report-user-saga.js b/client/src/redux/report-user-saga.js index 34906e11151215..f3c89c91a02e7d 100644 --- a/client/src/redux/report-user-saga.js +++ b/client/src/redux/report-user-saga.js @@ -8,10 +8,10 @@ import { reportUserComplete, reportUserError } from './'; function* reportUserSaga({ payload }) { try { - const response = yield call(postReportUser, payload); + const { data } = yield call(postReportUser, payload); yield put(reportUserComplete()); - yield put(createFlashMessage(response)); + yield put(createFlashMessage(data)); } catch (e) { yield put(reportUserError(e)); } diff --git a/client/src/redux/save-challenge-saga.js b/client/src/redux/save-challenge-saga.js index 0c87196bb2669d..02d938fe2f2cdb 100644 --- a/client/src/redux/save-challenge-saga.js +++ b/client/src/redux/save-challenge-saga.js @@ -46,14 +46,14 @@ export function* saveChallengeSaga() { ); } else { try { - const response = yield call(postSaveChallenge, body); + const { data } = yield call(postSaveChallenge, body); - if (response?.message) { - yield put(createFlashMessage(response)); - } else if (response?.savedChallenges) { + if (data?.message) { + yield put(createFlashMessage(data)); + } else if (data?.savedChallenges) { yield put( saveChallengeComplete( - mapFilesToChallengeFiles(response.savedChallenges) + mapFilesToChallengeFiles(data.savedChallenges) ) ); yield put( diff --git a/client/src/redux/settings/action-types.js b/client/src/redux/settings/action-types.js index ed770cf795212d..22957c0614da19 100644 --- a/client/src/redux/settings/action-types.js +++ b/client/src/redux/settings/action-types.js @@ -12,6 +12,7 @@ export const actionTypes = createTypes( ...createAsyncTypes('updateMySocials'), ...createAsyncTypes('updateMySound'), ...createAsyncTypes('updateMyTheme'), + ...createAsyncTypes('updateMyKeyboardShortcuts'), ...createAsyncTypes('updateMyHonesty'), ...createAsyncTypes('updateMyQuincyEmail'), ...createAsyncTypes('updateMyPortfolio'), diff --git a/client/src/redux/settings/danger-zone-saga.js b/client/src/redux/settings/danger-zone-saga.js index 10d41d4d39d21f..d9d4e6741ffff7 100644 --- a/client/src/redux/settings/danger-zone-saga.js +++ b/client/src/redux/settings/danger-zone-saga.js @@ -19,7 +19,7 @@ function* deleteAccountSaga() { ); // remove current user information from application state yield put(resetUserData()); - yield call(navigate, '/'); + yield call(navigate, '/learn'); } catch (e) { yield put(deleteAccountError(e)); } diff --git a/client/src/redux/settings/index.js b/client/src/redux/settings/index.js index 984a2354dee61f..bff8e41af6a1d1 100644 --- a/client/src/redux/settings/index.js +++ b/client/src/redux/settings/index.js @@ -84,6 +84,17 @@ export const updateMyThemeComplete = createAction( ); export const updateMyThemeError = createAction(types.updateMyThemeError); +export const updateMyKeyboardShortcuts = createAction( + types.updateMyKeyboardShortcuts +); +export const updateMyKeyboardShortcutsComplete = createAction( + types.updateMyKeyboardShortcutsComplete, + checkForSuccessPayload +); +export const updateMyKeyboardShortcutsError = createAction( + types.updateMyKeyboardShortcutsError +); + export const updateMyHonesty = createAction(types.updateMyHonesty); export const updateMyHonestyComplete = createAction( types.updateMyHonestyComplete, diff --git a/client/src/redux/settings/settings-sagas.js b/client/src/redux/settings/settings-sagas.js index 9559e6c282e3c2..358f6b68a7217a 100644 --- a/client/src/redux/settings/settings-sagas.js +++ b/client/src/redux/settings/settings-sagas.js @@ -7,6 +7,7 @@ import { takeEvery, debounce } from 'redux-saga/effects'; +import store from 'store'; import { createFlashMessage } from '../../components/Flash/redux'; import { @@ -21,10 +22,15 @@ import { putVerifyCert, putUpdateMyPortfolio, putUpdateMyTheme, - putUpdateMySound + putUpdateMySound, + putUpdateMyKeyboardShortcuts } from '../../utils/ajax'; import { certMap } from '../../resources/cert-and-project-map'; import { completedChallengesSelector } from '..'; +import { + certTypes, + certTypeIdMap +} from '../../../../config/certification-settings'; import { updateUserFlagComplete, updateUserFlagError, @@ -49,14 +55,16 @@ import { updateMyThemeComplete, updateMyThemeError, updateMySoundComplete, - updateMySoundError + updateMySoundError, + updateMyKeyboardShortcutsComplete, + updateMyKeyboardShortcutsError } from './'; function* submitNewAboutSaga({ payload }) { try { - const response = yield call(putUpdateMyAbout, payload); - yield put(submitNewAboutComplete({ ...response, payload })); - yield put(createFlashMessage(response)); + const { data } = yield call(putUpdateMyAbout, payload); + yield put(submitNewAboutComplete({ ...data, payload })); + yield put(createFlashMessage(data)); } catch (e) { yield put(submitNewAboutError(e)); } @@ -64,9 +72,9 @@ function* submitNewAboutSaga({ payload }) { function* submitNewUsernameSaga({ payload: username }) { try { - const response = yield call(putUpdateMyUsername, username); - yield put(submitNewUsernameComplete({ ...response, username })); - yield put(createFlashMessage(response)); + const { data } = yield call(putUpdateMyUsername, username); + yield put(submitNewUsernameComplete({ ...data, username })); + yield put(createFlashMessage(data)); } catch (e) { yield put(submitNewUsernameError(e)); } @@ -74,9 +82,9 @@ function* submitNewUsernameSaga({ payload: username }) { function* submitProfileUISaga({ payload }) { try { - const response = yield call(putUpdateMyProfileUI, payload); - yield put(submitProfileUIComplete({ ...response, payload })); - yield put(createFlashMessage(response)); + const { data } = yield call(putUpdateMyProfileUI, payload); + yield put(submitProfileUIComplete({ ...data, payload })); + yield put(createFlashMessage(data)); } catch (e) { yield put(submitProfileUIError); } @@ -84,10 +92,10 @@ function* submitProfileUISaga({ payload }) { function* updateUserFlagSaga({ payload: update }) { try { - const response = yield call(putUpdateUserFlag, update); - yield put(updateUserFlagComplete({ ...response, payload: update })); + const { data } = yield call(putUpdateUserFlag, update); + yield put(updateUserFlagComplete({ ...data, payload: update })); yield put( - createFlashMessage({ ...response, variables: { theme: update.theme } }) + createFlashMessage({ ...data, variables: { theme: update.theme } }) ); } catch (e) { yield put(updateUserFlagError(e)); @@ -96,9 +104,9 @@ function* updateUserFlagSaga({ payload: update }) { function* updateMySocialsSaga({ payload: update }) { try { - const response = yield call(putUpdateMySocials, update); - yield put(updateMySocialsComplete({ ...response, payload: update })); - yield put(createFlashMessage({ ...response })); + const { data } = yield call(putUpdateMySocials, update); + yield put(updateMySocialsComplete({ ...data, payload: update })); + yield put(createFlashMessage({ ...data })); } catch (e) { yield put(updateMySocialsError); } @@ -106,9 +114,10 @@ function* updateMySocialsSaga({ payload: update }) { function* updateMySoundSaga({ payload: update }) { try { - const response = yield call(putUpdateMySound, update); - yield put(updateMySoundComplete({ ...response, payload: update })); - yield put(createFlashMessage({ ...response })); + store.set('fcc-sound', !!update.sound); + const { data } = yield call(putUpdateMySound, update); + yield put(updateMySoundComplete({ ...data, payload: update })); + yield put(createFlashMessage({ ...data })); } catch (e) { yield put(updateMySoundError); } @@ -116,19 +125,29 @@ function* updateMySoundSaga({ payload: update }) { function* updateMyThemeSaga({ payload: update }) { try { - const response = yield call(putUpdateMyTheme, update); - yield put(updateMyThemeComplete({ ...response, payload: update })); - yield put(createFlashMessage({ ...response })); + const { data } = yield call(putUpdateMyTheme, update); + yield put(updateMyThemeComplete({ ...data, payload: update })); + yield put(createFlashMessage({ ...data })); } catch (e) { yield put(updateMyThemeError); } } +function* updateMyKeyboardShortcutsSaga({ payload: update }) { + try { + const { data } = yield call(putUpdateMyKeyboardShortcuts, update); + yield put(updateMyKeyboardShortcutsComplete({ ...data, payload: update })); + yield put(createFlashMessage({ ...data })); + } catch (e) { + yield put(updateMyKeyboardShortcutsError); + } +} + function* updateMyHonestySaga({ payload: update }) { try { - const response = yield call(putUpdateMyHonesty, update); - yield put(updateMyHonestyComplete({ ...response, payload: update })); - yield put(createFlashMessage({ ...response })); + const { data } = yield call(putUpdateMyHonesty, update); + yield put(updateMyHonestyComplete({ ...data, payload: update })); + yield put(createFlashMessage({ ...data })); } catch (e) { yield put(updateMyHonestyError); } @@ -136,9 +155,9 @@ function* updateMyHonestySaga({ payload: update }) { function* updateMyQuincyEmailSaga({ payload: update }) { try { - const response = yield call(putUpdateMyQuincyEmail, update); - yield put(updateMyQuincyEmailComplete({ ...response, payload: update })); - yield put(createFlashMessage({ ...response })); + const { data } = yield call(putUpdateMyQuincyEmail, update); + yield put(updateMyQuincyEmailComplete({ ...data, payload: update })); + yield put(createFlashMessage({ ...data })); } catch (e) { yield put(updateMyQuincyEmailError); } @@ -146,9 +165,9 @@ function* updateMyQuincyEmailSaga({ payload: update }) { function* updateMyPortfolioSaga({ payload: update }) { try { - const response = yield call(putUpdateMyPortfolio, update); - yield put(updateMyPortfolioComplete({ ...response, payload: update })); - yield put(createFlashMessage({ ...response })); + const { data } = yield call(putUpdateMyPortfolio, update); + yield put(updateMyPortfolioComplete({ ...data, payload: update })); + yield put(createFlashMessage({ ...data })); } catch (e) { yield put(updateMyPortfolioError); } @@ -156,7 +175,9 @@ function* updateMyPortfolioSaga({ payload: update }) { function* validateUsernameSaga({ payload }) { try { - const { exists } = yield call(getUsernameExists, payload); + const { + data: { exists } + } = yield call(getUsernameExists, payload); yield put(validateUsernameComplete(exists)); } catch (e) { yield put(validateUsernameError(e)); @@ -165,32 +186,35 @@ function* validateUsernameSaga({ payload }) { function* verifyCertificationSaga({ payload }) { // check redux if can claim cert before calling backend - const completedChallenges = yield select(completedChallengesSelector); const currentCert = certMap.find(cert => cert.certSlug === payload); - const currentCertIds = currentCert?.projects.map(project => project.id); + const completedChallenges = yield select(completedChallengesSelector); const certTitle = currentCert?.title || payload; - const flash = { - type: 'info', - message: 'flash.incomplete-steps', - variables: { name: certTitle } - }; - - const canClaimCert = currentCertIds.every(id => - completedChallenges.find(challenge => challenge.id === id) - ); + // (20/06/2022) Full Stack client-side validation is already done here: + // https://github.com/freeCodeCamp/freeCodeCamp/blob/main/client/src/components/settings/certification.js#L309 + if (currentCert?.id !== certTypeIdMap[certTypes.fullStack]) { + const flash = { + type: 'info', + message: 'flash.incomplete-steps', + variables: { name: certTitle } + }; + + const currentCertIds = currentCert?.projects?.map(project => project.id); + const canClaimCert = currentCertIds.every(id => + completedChallenges.find(challenge => challenge.id === id) + ); - if (!canClaimCert) { - yield put(createFlashMessage(flash)); - return; + if (!canClaimCert) { + yield put(createFlashMessage(flash)); + return; + } } // redux says challenges are complete, call back end try { - const { response, isCertMap, completedChallenges } = yield call( - putVerifyCert, - payload - ); + const { + data: { response, isCertMap, completedChallenges } + } = yield call(putVerifyCert, payload); yield put( verifyCertComplete({ ...response, @@ -216,6 +240,7 @@ export function createSettingsSagas(types) { takeEvery(types.updateMyHonesty, updateMyHonestySaga), takeEvery(types.updateMySound, updateMySoundSaga), takeEvery(types.updateMyTheme, updateMyThemeSaga), + takeEvery(types.updateMyKeyboardShortcuts, updateMyKeyboardShortcutsSaga), takeEvery(types.updateMyQuincyEmail, updateMyQuincyEmailSaga), takeEvery(types.updateMyPortfolio, updateMyPortfolioSaga), takeLatest(types.submitNewAbout, submitNewAboutSaga), diff --git a/client/src/redux/settings/update-email-saga.js b/client/src/redux/settings/update-email-saga.js index a1dce59b0ca2d5..9108d8c5f9ea05 100644 --- a/client/src/redux/settings/update-email-saga.js +++ b/client/src/redux/settings/update-email-saga.js @@ -13,14 +13,14 @@ function* updateMyEmailSaga({ payload: email = '' }) { return; } try { - const response = yield call(putUserUpdateEmail, email); + const { data } = yield call(putUserUpdateEmail, email); yield put( updateMyEmailComplete({ - ...response, + ...data, payload: { email, isEmailVerified: false } }) ); - yield put(createFlashMessage(response)); + yield put(createFlashMessage(data)); } catch (e) { yield put(updateMyEmailError(e)); } diff --git a/client/src/redux/show-cert-saga.js b/client/src/redux/show-cert-saga.js index 682aafe20d2c92..2cb1a4be3c698c 100644 --- a/client/src/redux/show-cert-saga.js +++ b/client/src/redux/show-cert-saga.js @@ -7,8 +7,8 @@ import { showCertComplete, showCertError } from '.'; function* getShowCertSaga({ payload: { username, certSlug } }) { try { - const response = yield call(getShowCert, username, certSlug); - const { messages } = response; + const { data } = yield call(getShowCert, username, certSlug); + const { messages } = data; if (messages && messages.length) { for (let i = 0; i < messages.length; i++) { yield put(createFlashMessage(messages[i])); @@ -16,7 +16,7 @@ function* getShowCertSaga({ payload: { username, certSlug } }) { yield call(navigate, '/'); return; } - yield put(showCertComplete(response)); + yield put(showCertComplete(data)); } catch (e) { yield put(showCertError(e)); } diff --git a/client/src/redux/user-token-saga.js b/client/src/redux/user-token-saga.js index e99f9f0694bff2..0928aff1b242e8 100644 --- a/client/src/redux/user-token-saga.js +++ b/client/src/redux/user-token-saga.js @@ -17,12 +17,9 @@ const message = { function* deleteUserTokenSaga() { try { - const response = yield call(deleteUserToken); + const { data } = yield call(deleteUserToken); - if ( - response && - Object.prototype.hasOwnProperty.call(response, 'userToken') - ) { + if (data && Object.prototype.hasOwnProperty.call(data, 'userToken')) { yield put(deleteUserTokenComplete()); yield put(createFlashMessage(message.deleted)); } else { diff --git a/client/src/resources/cert-and-project-map.ts b/client/src/resources/cert-and-project-map.ts index 3a0f3a090e920c..198d658fa35d6e 100644 --- a/client/src/resources/cert-and-project-map.ts +++ b/client/src/resources/cert-and-project-map.ts @@ -463,6 +463,44 @@ const certMap = [ } ] }, + { + id: '606243f50267e718b1e755f4', + title: 'Relational Database', + certSlug: 'relational-database-v8', + flag: 'isRelationalDatabaseCertV8', + projects: [ + { + id: '5f1a4ef5d5d6b5ab580fc6ae', + title: 'Celestial Bodies Database', + link: `${relationalDatabaseBase}/build-a-celestial-bodies-database-project/build-a-celestial-bodies-database`, + certSlug: 'relational-database-v8' + }, + { + id: '5f9771307d4d22b9d2b75a94', + title: 'World Cup Database', + link: `${relationalDatabaseBase}/build-a-world-cup-database-project/build-a-world-cup-database`, + certSlug: 'relational-database-v8' + }, + { + id: '5f87ac112ae598023a42df1a', + title: 'Salon Appointment Scheduler', + link: `${relationalDatabaseBase}/build-a-salon-appointment-scheduler-project/build-a-salon-appointment-scheduler`, + certSlug: 'relational-database-v8' + }, + { + id: '602d9ff222201c65d2a019f2', + title: 'Periodic Table Database', + link: `${relationalDatabaseBase}/build-a-periodic-table-database-project/build-a-periodic-table-database`, + certSlug: 'relational-database-v8' + }, + { + id: '602da04c22201c65d2a019f4', + title: 'Number Guessing Game', + link: `${relationalDatabaseBase}/build-a-number-guessing-game-project/build-a-number-guessing-game`, + certSlug: 'relational-database-v8' + } + ] + }, { id: '561add10cb82ac38a17523bc', title: 'Back End Development and APIs', @@ -691,44 +729,6 @@ const certMap = [ certSlug: 'machine-learning-with-python-v7' } ] - }, - { - id: '606243f50267e718b1e755f4', - title: 'Relational Database', - certSlug: 'relational-database-v8', - flag: 'isRelationalDatabaseCertV8', - projects: [ - { - id: '5f1a4ef5d5d6b5ab580fc6ae', - title: 'Celestial Bodies Database', - link: `${relationalDatabaseBase}/build-a-celestial-bodies-database-project/build-a-celestial-bodies-database`, - certSlug: 'relational-database-v8' - }, - { - id: '5f9771307d4d22b9d2b75a94', - title: 'World Cup Database', - link: `${relationalDatabaseBase}/build-a-world-cup-database-project/build-a-world-cup-database`, - certSlug: 'relational-database-v8' - }, - { - id: '5f87ac112ae598023a42df1a', - title: 'Salon Appointment Scheduler', - link: `${relationalDatabaseBase}/build-a-salon-appointment-scheduler-project/build-a-salon-appointment-scheduler`, - certSlug: 'relational-database-v8' - }, - { - id: '602d9ff222201c65d2a019f2', - title: 'Periodic Table Database', - link: `${relationalDatabaseBase}/build-a-periodic-table-database-project/build-a-periodic-table-database`, - certSlug: 'relational-database-v8' - }, - { - id: '602da04c22201c65d2a019f4', - title: 'Number Guessing Game', - link: `${relationalDatabaseBase}/build-a-number-guessing-game-project/build-a-number-guessing-game`, - certSlug: 'relational-database-v8' - } - ] } ] as const; diff --git a/client/src/templates/Challenges/classic/action-row.tsx b/client/src/templates/Challenges/classic/action-row.tsx index 8daaaefa04778f..8d41e8222512c1 100644 --- a/client/src/templates/Challenges/classic/action-row.tsx +++ b/client/src/templates/Challenges/classic/action-row.tsx @@ -1,36 +1,30 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; -import { connect } from 'react-redux'; + import BreadCrumb from '../components/bread-crumb'; -import { resetChallenge } from '../redux'; import EditorTabs from './editor-tabs'; interface ActionRowProps { block: string; hasNotes: boolean; - isMultifileCertProject: boolean; - showInstructions: boolean; + isProjectBasedChallenge: boolean; showConsole: boolean; showNotes: boolean; + showInstructions: boolean; showPreview: boolean; superBlock: string; togglePane: (pane: string) => void; - resetChallenge: () => void; showBreadcrumbs?: boolean; } -const mapDispatchToProps = { - resetChallenge -}; - const ActionRow = ({ hasNotes, togglePane, showNotes, showPreview, - isMultifileCertProject, - showInstructions, showConsole, + showInstructions, + isProjectBasedChallenge, superBlock, showBreadcrumbs = true, block @@ -44,7 +38,7 @@ const ActionRow = ({ )}
    - {isMultifileCertProject && ( + {!isProjectBasedChallenge && ( )} @@ -92,4 +86,4 @@ const ActionRow = ({ ActionRow.displayName = 'ActionRow'; -export default connect(null, mapDispatchToProps)(ActionRow); +export default ActionRow; diff --git a/client/src/templates/Challenges/classic/classic.css b/client/src/templates/Challenges/classic/classic.css index 516f1ee27c99ee..7148b987c767a8 100644 --- a/client/src/templates/Challenges/classic/classic.css +++ b/client/src/templates/Challenges/classic/classic.css @@ -11,24 +11,19 @@ top: -999em; } -#challenge-page-tabs .nav-tabs { - margin-left: 2px; - display: flex; -} - -#challenge-page-tabs .nav-tabs > li { - flex: 1; - text-align: center; +.monaco-editor .editor-widget { + display: none !important; } -#challenge-page-tabs .nav-tabs > li > a { - padding: 5px 10px; - text-decoration: none; - font-size: 0.8em; +.monaco-menu .monaco-action-bar.vertical .action-item:nth-last-child(n + 5), +.monaco-menu .monaco-action-bar.vertical .action-item:last-child, +.monaco-menu .monaco-action-bar.vertical .action-label.separator { + display: none !important; } -#challenge-page-tabs .nav-tabs > li > a:hover { - color: var(--gray-85); +.action-row { + padding: 10px; + border-bottom: 1px solid var(--quaternary-background); } #challenge-page-tabs .tab-content { @@ -47,20 +42,6 @@ ); } -#challenge-page-tabs .tab-pane { - height: 100%; - overflow: hidden; -} - -#challenge-page-tabs .nav-tabs > li.active > a { - color: var(--quaternary-color); - background-color: var(--quaternary-background); -} - -.monaco-editor .editor-widget { - display: none !important; -} - .monaco-editor, .monaco-editor .margin, .monaco-editor-background, @@ -79,40 +60,35 @@ display: none !important; } -.monaco-editor-tabs { - display: flex; - padding: 0px 10px; - background-color: var(--primary-background); - border-bottom: 2px solid var(--primary-color); +.restart-step-tab { + margin: 0 auto; } -.monaco-editor-tab { - position: relative; - top: 2px; - padding: 4px 16px; - border: 2px solid var(--primary-color); - border-left: none; - background-color: var(--secondary-background); +#mobile-layout .nav-tabs { + margin-left: 2px; + display: flex; } -button.monaco-editor-tab:hover { - color: var(--quaternary-color); - background-color: var(--quaternary-background); +#mobile-layout .nav-tabs > li { + flex: 1; + text-align: center; } -.monaco-editor-tab:first-child { - border-left: 2px solid var(--primary-color); +#mobile-layout .nav-tabs > li > a { + padding: 5px 10px; + text-decoration: none; + font-size: 0.8em; } -.monaco-editor-tab-selected { - background-color: var(--primary-background); - border-bottom: 2px solid var(--primary-background); +#mobile-layout .nav-tabs > li > a:hover { + color: var(--gray-85); } -.monaco-editor-tab[aria-expanded='true'] { - border-color: var(--secondary-color); - background-color: var(--secondary-color); - color: var(--secondary-background); +#mobile-layout .tab-content { + height: calc( + 100vh - var(--header-height, 0px) - var(--flash-message-height, 0px) - 69px + ); + overflow-y: auto; } .action-row { @@ -125,12 +101,15 @@ button.monaco-editor-tab:hover { border-bottom: none; background-color: var(--secondary-background); gap: 8px; + display: flex; } -.action-row .monaco-editor-tabs .monaco-editor-tab { - top: 0; +#mobile-layout .monaco-editor-tabs { + padding: 10px; + width: 100%; } -.monaco-editor .squiggly-hint { - background: none !important; +#mobile-layout .monaco-editor-tabs button { + flex: 1; + max-width: 50%; } diff --git a/client/src/templates/Challenges/classic/desktop-layout.tsx b/client/src/templates/Challenges/classic/desktop-layout.tsx index 6fc608c72d7ee3..4d875322c88804 100644 --- a/client/src/templates/Challenges/classic/desktop-layout.tsx +++ b/client/src/templates/Challenges/classic/desktop-layout.tsx @@ -61,6 +61,7 @@ const DesktopLayout = (props: DesktopLayoutProps): JSX.Element => { setShowNotes(!showNotes); break; default: + setShowInstructions(false); setShowConsole(false); setShowPreview(false); setShowNotes(false); @@ -110,20 +111,18 @@ const DesktopLayout = (props: DesktopLayoutProps): JSX.Element => { return (
    - {(projectBasedChallenge || isMultifileCertProject) && ( - - )} +
    {!projectBasedChallenge && showInstructions && ( diff --git a/client/src/templates/Challenges/classic/editor-tabs.tsx b/client/src/templates/Challenges/classic/editor-tabs.tsx index f2861c3bb3e56b..b855bc0364b7b5 100644 --- a/client/src/templates/Challenges/classic/editor-tabs.tsx +++ b/client/src/templates/Challenges/classic/editor-tabs.tsx @@ -49,6 +49,7 @@ class EditorTabs extends Component { : 'btn-tab-primary--outline' } key={challengeFile.fileKey} + data-cy={`editor-tab-${challengeFile.fileKey}`} onClick={() => toggleVisibleEditor(challengeFile.fileKey)} > {`${challengeFile.name}.${challengeFile.ext}`}{' '} diff --git a/client/src/templates/Challenges/classic/editor.css b/client/src/templates/Challenges/classic/editor.css index 325dd91c5678de..560c0c399c867a 100644 --- a/client/src/templates/Challenges/classic/editor.css +++ b/client/src/templates/Challenges/classic/editor.css @@ -3,6 +3,15 @@ color: var(--primary-color); } +.monaco-scrollable-element { + overflow: visible !important; +} + +.monaco-editor-background { + overflow: visible !important; + contain: none !important; +} + .vs .monaco-scrollable-element > .scrollbar > .slider { z-index: 11; } diff --git a/client/src/templates/Challenges/classic/editor.tsx b/client/src/templates/Challenges/classic/editor.tsx index be63d9783a9381..bac527d68d21da 100644 --- a/client/src/templates/Challenges/classic/editor.tsx +++ b/client/src/templates/Challenges/classic/editor.tsx @@ -21,6 +21,7 @@ import { createSelector } from 'reselect'; import store from 'store'; import { debounce } from 'lodash-es'; +import { useTranslation } from 'react-i18next'; import { Loader } from '../../../components/helpers'; import { Themes } from '../../../components/settings/theme'; import { @@ -39,7 +40,10 @@ import { } from '../../../redux/prop-types'; import { editorToneOptions } from '../../../utils/tone/editor-config'; import { editorNotes } from '../../../utils/tone/editor-notes'; -import { challengeTypes } from '../../../../utils/challenge-types'; +import { + challengeTypes, + isFinalProject +} from '../../../../utils/challenge-types'; import { canFocusEditorSelector, challengeMetaSelector, @@ -89,6 +93,7 @@ interface EditorProps { isResetting: boolean; isSignedIn: boolean; openHelpModal: () => void; + openResetModal: () => void; output: string[]; resizeProps: ResizeProps; saveChallenge: () => void; @@ -177,7 +182,8 @@ const mapDispatchToProps = { submitChallenge, initTests, stopResetting, - openHelpModal: () => openModal('help') + openHelpModal: () => openModal('help'), + openResetModal: () => openModal('reset') }; const modeMap = { @@ -234,6 +240,7 @@ const initialData: EditorProperties = { }; const Editor = (props: EditorProps): JSX.Element => { + const { t } = useTranslation(); const { editorRef, initTests } = props; // These refs are used during initialisation of the editor as well as by // callbacks. Since they have to be initialised before editorWillMount and @@ -244,6 +251,11 @@ const Editor = (props: EditorProps): JSX.Element => { const monacoRef: MutableRefObject = useRef(null); const dataRef = useRef({ ...initialData }); + + const submitChallengeDebounceRef = useRef( + debounce(props.submitChallenge, 1000, { leading: true, trailing: false }) + ); + const player = useRef<{ // eslint-disable-next-line @typescript-eslint/no-explicit-any sampler: any; @@ -299,7 +311,8 @@ const Editor = (props: EditorProps): JSX.Element => { enabled: false }, quickSuggestions: false, - suggestOnTriggerCharacters: false + suggestOnTriggerCharacters: false, + lineNumbersMinChars: 2 }; const getEditableRegionFromRedux = () => { @@ -427,9 +440,12 @@ const Editor = (props: EditorProps): JSX.Element => { id: 'execute-challenge', label: 'Run tests', /* eslint-disable no-bitwise */ - keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter], + keybindings: [ + monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, + monaco.KeyMod.WinCtrl | monaco.KeyCode.Enter + ], run: () => { - if (props.usesMultifileEditor) { + if (props.usesMultifileEditor && !isFinalProject(props.challengeType)) { if (challengeIsComplete()) { tryToSubmitChallenge(); } else { @@ -452,7 +468,10 @@ const Editor = (props: EditorProps): JSX.Element => { editor.addAction({ id: 'save-editor-content', label: 'Save editor content', - keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_S], + keybindings: [ + monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_S, + monaco.KeyMod.WinCtrl | monaco.KeyCode.KEY_S + ], run: props.challengeType === challengeTypes.multifileCertProject && props.isSignedIn @@ -464,7 +483,10 @@ const Editor = (props: EditorProps): JSX.Element => { editor.addAction({ id: 'toggle-accessibility', label: 'Toggle Accessibility Mode', - keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_E], + keybindings: [ + monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_E, + monaco.KeyMod.WinCtrl | monaco.KeyCode.KEY_E + ], run: () => { const currentAccessibility = storedAccessibilityMode(); @@ -492,6 +514,16 @@ const Editor = (props: EditorProps): JSX.Element => { if (!getStoredAriaRoledescription()) { setAriaRoledescription(false); } + + // Add invisible content widget over line numbers so touch users will + // always have a place to vertically scroll the editor. + const scrollGutterNode = createScrollGutterNode(editor); + const scrollGutterWidget = createWidget( + editor, + 'scrollgutter.widget', + scrollGutterNode + ); + editor.addContentWidget(scrollGutterWidget); }; const toggleAriaRoledescription = () => { @@ -573,7 +605,7 @@ const Editor = (props: EditorProps): JSX.Element => { attemptRef.current.attempts++; } - const tryToSubmitChallenge = debounce(props.submitChallenge, 2000); + const tryToSubmitChallenge = submitChallengeDebounceRef.current; function createLowerJaw(outputNode: HTMLElement, callback?: () => void) { const { output } = props; @@ -646,10 +678,13 @@ const Editor = (props: EditorProps): JSX.Element => { if (isChallengeCompleted) { jawHeading.classList.add('challenge-description-header'); const challengeTitle = document.createElement('h1'); - challengeTitle.innerText = title; + challengeTitle.innerHTML = `${title} ${t( + 'icons.passed' + )}`; jawHeading.appendChild(challengeTitle); const checkmark = ReactDOMServer.renderToStaticMarkup( { return outputNode; } + function createScrollGutterNode( + editor: editor.IStandaloneCodeEditor + ): HTMLDivElement { + const scrollGutterNode = document.createElement('div'); + const lineGutterWidth = editor.getLayoutInfo().contentLeft; + scrollGutterNode.style.width = `${lineGutterWidth}px`; + scrollGutterNode.style.left = `-${lineGutterWidth}px`; + scrollGutterNode.style.top = '0'; + scrollGutterNode.style.height = '10000px'; + scrollGutterNode.style.background = 'transparent'; + return scrollGutterNode; + } + function resetMarginDecorations() { const { model, insideEditDecId } = dataRef.current; const range = model?.getDecorationRange(insideEditDecId); @@ -885,42 +933,49 @@ const Editor = (props: EditorProps): JSX.Element => { })[0]; } - function addWidgetsToRegions(editor: editor.IStandaloneCodeEditor) { - const createWidget = ( - id: string, - domNode: HTMLDivElement, - getTop: () => string - ) => { - const getId = () => id; - const getDomNode = () => domNode; - const getPosition = () => { + const createWidget = ( + editor: editor.IStandaloneCodeEditor, + id: string, + domNode: HTMLDivElement, + // If getTop function is not provided then no positioning will be done here. + // This allows scroll gutter to do its positioning elsewhere. + getTop?: () => string + ) => { + const getId = () => id; + const getDomNode = () => domNode; + const getPosition = () => { + if (getTop) { domNode.style.width = `${editor.getLayoutInfo().contentWidth}px`; domNode.style.top = getTop(); - - // must return null, so that Monaco knows the widget will position - // itself. - return null; - }; - // Only the description content widget uses this method but it - // is harmless to pass it to the overlay widget. - const afterRender = () => { + } + // must return null, so that Monaco knows the widget will position + // itself. + return null; + }; + // Only the description content widget uses this method but it + // is harmless to pass it to the overlay widget. + const afterRender = () => { + if (getTop) { domNode.style.left = '0'; - domNode.style.visibility = 'visible'; - }; - return { - getId, - getDomNode, - getPosition, - afterRender - }; + } + domNode.style.visibility = 'visible'; }; + return { + getId, + getDomNode, + getPosition, + afterRender + }; + }; + function addWidgetsToRegions(editor: editor.IStandaloneCodeEditor) { const descriptionNode = createDescription(editor); const outputNode = createOutputNode(editor); if (!dataRef.current.descriptionWidget) { dataRef.current.descriptionWidget = createWidget( + editor, 'description.widget', descriptionNode, getDescriptionZoneTop @@ -940,6 +995,7 @@ const Editor = (props: EditorProps): JSX.Element => { } if (!dataRef.current.outputWidget) { dataRef.current.outputWidget = createWidget( + editor, 'output.widget', outputNode, getOutputZoneTop diff --git a/client/src/templates/Challenges/classic/lower-jaw.tsx b/client/src/templates/Challenges/classic/lower-jaw.tsx index d59aa450da2779..b6627d305080fe 100644 --- a/client/src/templates/Challenges/classic/lower-jaw.tsx +++ b/client/src/templates/Challenges/classic/lower-jaw.tsx @@ -10,10 +10,11 @@ import { useTranslation } from 'react-i18next'; import TestFail from '../../../assets/icons/test-fail'; import TestHint from '../../../assets/icons/test-hint'; import TestPass from '../../../assets/icons/test-pass'; +import { MAX_MOBILE_WIDTH } from '../../../../../config/misc'; interface LowerJawProps { hint?: string; - challengeIsCompleted?: boolean; + challengeIsCompleted: boolean; openHelpModal: () => void; tryToExecuteChallenge: () => void; tryToSubmitChallenge: () => void; @@ -54,7 +55,7 @@ const LowerJaw = ({ useEffect(() => { if (attemptsNumber && attemptsNumber > 0) { - //hide the feedback from SR untill the "Running tests" are displayed and removed. + //hide the feedback from SR until the "Running tests" are displayed and removed. setIsFeedbackHidden(true); //allow the lower jaw height to be picked up by the editor. @@ -88,6 +89,8 @@ const LowerJaw = ({ }, 500); } + setTestBtnariaHidden(challengeIsCompleted); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [challengeHasBeenCompleted]); @@ -98,6 +101,14 @@ const LowerJaw = ({ } }); + /* + Return early in lifecycle based on the earliest available conditions to help the editor + calculate the correct editor gap for the lower jaw. + + For consistency, use the persisted version if the conditions has been met before. + */ + const earliestAvailableHint = hint || previousHint; + const sentencePicker = useCallback(() => { const sentenceArray = [ 'learn.sorry-try-again', @@ -129,18 +140,16 @@ const LowerJaw = ({

    - {t('learn.congradulations')} + {t('learn.congratulations')} {submitKeyboardInstructions}

    ); - - // show the hint if the previousHint is not set - } else if (hint || previousHint) { - const hintDiscription = `

    ${t('learn.hint')}

    ${ - hint || previousHint - }`; + } else if (earliestAvailableHint) { + const hintDescription = `

    ${t( + 'learn.hint' + )}

    ${earliestAvailableHint}`; return ( <>
    @@ -161,7 +170,7 @@ const LowerJaw = ({
    @@ -170,14 +179,15 @@ const LowerJaw = ({ }, [ attemptsNumber, challengeHasBeenCompleted, - hint, + earliestAvailableHint, isEditorInFocus, isFeedbackHidden, - previousHint, sentencePicker, t ]); + const showDesktopButton = window.innerWidth > MAX_MOBILE_WIDTH; + const renderButtons = () => { return ( <> @@ -189,20 +199,20 @@ const LowerJaw = ({ aria-hidden={testBtnariaHidden} onClick={tryToExecuteChallenge} > - {t('buttons.check-code')} + {showDesktopButton + ? t('buttons.check-code') + : t('buttons.check-code-2')} {isRunningTests && '...'} -
    - -
    + ); }; diff --git a/client/src/templates/Challenges/classic/multifile-editor.tsx b/client/src/templates/Challenges/classic/multifile-editor.tsx index 22f1d7290397bc..34cac67c66a355 100644 --- a/client/src/templates/Challenges/classic/multifile-editor.tsx +++ b/client/src/templates/Challenges/classic/multifile-editor.tsx @@ -130,7 +130,12 @@ const MultifileEditor = (props: MultifileEditorProps) => { ); } else { return ( - + { + const target = e.target as HTMLElement; + if (target?.closest('.editor-upper-jaw')) { + e.stopPropagation(); + } +}; + // Component class ShowClassic extends Component { static displayName: string; @@ -189,7 +198,6 @@ class ShowClassic extends Component { } onStopResize(event: HandlerProps) { - // @ts-expect-error TODO: Apparently, name does not exist on type const { name, flex } = event.component.props; // Only interested in tracking layout updates for ReflexElement's @@ -225,6 +233,13 @@ class ShowClassic extends Component { } } = this.props; this.initializeComponent(title); + // Bug fix for the monaco content widget and touch devices/right mouse + // click. (Issue #46166) + document.addEventListener('mousedown', handleContentWidgetEvents, true); + document.addEventListener('contextmenu', handleContentWidgetEvents, true); + document.addEventListener('touchstart', handleContentWidgetEvents, true); + document.addEventListener('touchmove', handleContentWidgetEvents, true); + document.addEventListener('touchend', handleContentWidgetEvents, true); } componentDidUpdate(prevProps: ShowClassicProps) { @@ -302,6 +317,15 @@ class ShowClassic extends Component { const { createFiles, cancelTests } = this.props; createFiles([]); cancelTests(); + document.removeEventListener('mousedown', handleContentWidgetEvents, true); + document.removeEventListener( + 'contextmenu', + handleContentWidgetEvents, + true + ); + document.removeEventListener('touchstart', handleContentWidgetEvents, true); + document.removeEventListener('touchmove', handleContentWidgetEvents, true); + document.removeEventListener('touchend', handleContentWidgetEvents, true); } getChallenge = () => this.props.data.challengeNode.challenge; @@ -434,6 +458,7 @@ class ShowClassic extends Component { return ( } executeChallenge={executeChallenge} innerRef={this.containerRef} @@ -488,7 +513,7 @@ class ShowClassic extends Component { certification={certification} superBlock={superBlock} /> - + {/* TODO: Decide if this is still needed */} diff --git a/client/src/templates/Challenges/codeally/show.tsx b/client/src/templates/Challenges/codeally/show.tsx index 6fd66637a15a8b..e4e0f33ed27dba 100644 --- a/client/src/templates/Challenges/codeally/show.tsx +++ b/client/src/templates/Challenges/codeally/show.tsx @@ -207,10 +207,22 @@ class ShowCodeAlly extends Component { userToken = null } = this.props; + // Initial CodeAlly login includes a tempToken in redirect URL + const queryParams = new URLSearchParams(window.location.search); + const codeAllyTempToken: string | null = queryParams.get('tempToken'); + + const tempToken = codeAllyTempToken ? `tempToken=${codeAllyTempToken}` : ''; + + // Include a unique param to avoid CodeAlly caching issues + const date = `date=${Date.now()}`; + + // User token for submitting CodeRoad tutorials const envVariables = userToken - ? `&envVariables=CODEROAD_WEBHOOK_TOKEN=${userToken}` + ? `envVariables=CODEROAD_WEBHOOK_TOKEN=${userToken}` : ''; + const goBackTo = `goBackTo=${window.location.href}`; + const isPartiallyCompleted = partiallyCompletedChallenges.some( challenge => challenge.id === challengeId ); @@ -224,9 +236,11 @@ class ShowCodeAlly extends Component { + + + +


    +
    +

    Contact me!

    +

    Use the links below to get in touch.

    +

    FreeCodeCamp.org | GitHub | Facebook | LinkedIn +

    + + + +``` + +```css +nav{ + position: fixed; + width: 100%; + text-align: right; + font-size: 24pt; + top: 0%; + right: 5px; + background-color: #000000; + color: #ffffff; +} +@media (max-width: 500px){ + nav{ + display: none; + } +} +a{ + color: #ffffff; +} +main{ + text-align: center; + background-color: black; + font-family:Pacifico +} +h1{ + font-size: 48pt; +} +h2{ + font-size: 24pt; +} +p{ + font-size: 12pt; +} +#welcome-section{ + background-color:#251a4a; + color: #FFFFFF; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} +#projects{ + background-color: #060a9c; + color: #ffffff; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} +#contact{ + background-color: #03300b; + color: #ffffff; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/build-a-product-landing-page-project/build-a-product-landing-page.md b/curriculum/challenges/espanol/14-responsive-web-design-22/build-a-product-landing-page-project/build-a-product-landing-page.md new file mode 100644 index 00000000000000..6e6c8dba4eae26 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/build-a-product-landing-page-project/build-a-product-landing-page.md @@ -0,0 +1,467 @@ +--- +id: 587d78af367417b2b2512b04 +title: Construye una página de inicio de producto +challengeType: 14 +forumTopicId: 301144 +dashedName: build-a-product-landing-page +--- + +# --description-- + +**Objetivo:** Crea una aplicación que sea funcionalmente similar a https://product-landing-page.freecodecamp.rocks + +**Historias de usuario:** + +1. Tu página de inicio de producto debe tener un elemento `header` con un correspondiente `id="header"` +1. Puedes ver una imagen dentro del elemento `header` con un correspondiente `id="header-img"` (Un logotipo sería una buena imagen aquí) +1. Dentro el elemento `#header`, puedes ver un elemento `nav` con su correspondiente `id="nav-bar"` +1. Puedes ver al menos tres elementos cliqueables dentro del elemento `nav`, cafda una con la clase `nav-link` +1. Cuando hagas click en un botón `.nav-link` en el elemento `nav`, serás redireccionado a la sección correspondiente de la página de inicio +1. Puedes ver un vídeo del producto incrustado con `id="video"` +1. Tu página de inicio tiene un elemento `form` con un correspondiente `id="form"` +1. Dentro del formulario, hay un campo `input` con `id="email"`, donde puedes ingresar tu dirección de email +1. El campo de entrada `#email` debe tener un marcador de texto para que los usuarios sepan para que sirve este campo +1. El campo de entrada `#email` usa validación HTML5 para confirmar que el texto ingresado es una dirección de email +1. Dentro del formulario, hay un `input` de tipo submit (enviar) con su correspondiente `id="submit"` +1. Cuendo haces click en el elemento `#submit`, el email es enviado a una página web (Utiliza esta URL de pruebas: `https://www.freecodecamp.com/email-submit`) +1. La barra de navegación siempre debe estar en la parte superior de la vista +1. La página de inicio de tu producto debe tener al menos una consulta de medios +1. Tu página de inicio del producto debe utillizar el flexbox CSS al menos una vez + +Completa las instrucciones y pasa todas las pruebas a continuación para completar este proyecto. Dale tu propio estilo estilo personal. ¡Feliz día programando! + +**Nota:** Asegúrate de agregar `` en tu HTML para enlazar tu hoja de estilos y aplicar tu CSS + +# --hints-- + +Debes tener un elemento `header` con un `id` de `header`. + +```js +const el = document.getElementById('header') +assert(!!el && el.tagName === 'HEADER') +``` + +Debes tener un elemento `img` con un `id` de `header-img`. + +```js +const el = document.getElementById('header-img') +assert(!!el && el.tagName === 'IMG') +``` + +Tu `#header-img` debe ser descendiente de `#header`. + +```js +const els = document.querySelectorAll('#header #header-img') +assert(els.length > 0) +``` + +Tu `#header-img` debe tener un atributo `src`. + +```js +const el = document.getElementById('header-img') +assert(!!el && !!el.src) +``` + +El valor del `src` de `#header-img` debe ser una URL válida (inicia con `http`). + +```js +const el = document.getElementById('header-img') +assert(!!el && /^http/.test(el.src)) +``` + +Debes tener un elemento `nav` con un `id` de `nav-bar`. + +```js +const el = document.getElementById('nav-bar') +assert(!!el && el.tagName === 'NAV') +``` + +Tu `#nav-bar` debe ser descendiente de `#header`. + +```js +const els = document.querySelectorAll('#header #nav-bar') +assert(els.length > 0) +``` + +Debes tener al menos 3 elementos `.nav-link` dentro del `#nav-bar`. + +```js +const els = document.querySelectorAll('#nav-bar .nav-link') +assert(els.length >= 3) +``` + +Cada elemento `.nav-link` debe tener un atributo `href`. + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + if (!el.href) assert(false) +}) +assert(els.length > 0) +``` + +Cada elemento `.nav-link` debe estar enlazado a su elemento correspondiente en la página de aterrizaje (el valor que tiene el `href` es el id de otro elemento, por ejemplo, `#footer`). + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + const linkDestination = el.getAttribute('href').slice(1) + if (!document.getElementById(linkDestination)) assert(false) +}) +assert(els.length > 0) +``` + +Debes tener un elemento `video` o `iframe` con un `id` de `video`. + +```js +const el = document.getElementById('video') +assert(!!el && (el.tagName === 'VIDEO' || el.tagName === 'IFRAME')) +``` + +Tu `#video` debe tener un atributo `src`. + +```js +let el = document.getElementById('video') +const sourceNode = el.children; +let sourceElement = null; +if (sourceNode.length) { + sourceElement = [...video.children].filter(el => el.localName === 'source')[0]; +} +if (sourceElement) { + el = sourceElement; +} +assert(el.hasAttribute('src')); +``` + +Debes tener un elemento `form` con un `id` de `form`. + +```js +const el = document.getElementById('form') +assert(!!el && el.tagName === 'FORM') +``` + +Debes tener un elemento `input` con un `id` de `email`. + +```js +const el = document.getElementById('email') +assert(!!el && el.tagName === 'INPUT') +``` + +Tu `#email` debe ser descendiente de `#form`. + +```js +const els = document.querySelectorAll('#form #email') +assert(els.length > 0) +``` + +Tu `#email` debe tener el atributo `placeholder` con un texto marcador de posición. + +```js +const el = document.getElementById('email') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Tu `#email` debe usar la validación HTML5 estableciendo su `type` a `email`. + +```js +const el = document.getElementById('email') +assert(!!el && el.type === 'email') +``` + +Debes tener un elemento `input` con un `id` de `submit`. + +```js +const el = document.getElementById('submit') +assert(!!el && el.tagName === 'INPUT') +``` + +Tu `#submit` debe ser descendiente de `#form`. + +```js +const els = document.querySelectorAll('#form #submit') +assert(els.length > 0) +``` + +Tu `#submit` debe tener un `type` de `submit`. + +```js +const el = document.getElementById('submit') +assert(!!el && el.type === 'submit') +``` + +Tu `#form` debe tener un atributo `action` de `https://www.freecodecamp.com/email-submit`. + +```js +const el = document.getElementById('form') +assert(!!el && el.action === 'https://www.freecodecamp.com/email-submit') +``` + +Tu `#email` debe tener un atributo `name` de `email`. + +```js +const el = document.getElementById('email') +assert(!!el && el.name === 'email') +``` + +Tu `#nav-bar` siempre debe estar en la parte superior de la ventana gráfica. + +```js +(async () => { + const timeout = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)); + + const header = document.getElementById('header'); + const headerChildren = header.children; + const navbarCandidates = [header, ...headerChildren]; + + // Return smallest top position of all navbar candidates + const getNavbarPosition = (candidates = []) => { + return candidates.reduce( + (min, candidate) => + Math.min(min, Math.abs(candidate?.getBoundingClientRect().top)), + Infinity + ); + }; + assert.approximately( + getNavbarPosition(navbarCandidates), + 0, + 15, + '#header or one of its children should be at the top of the viewport ' + ); + + window.scroll(0, 500); + await timeout(1); + + assert.approximately( + getNavbarPosition(navbarCandidates), + 0, + 15, + '#header or one of its children should be at the top of the ' + + 'viewport even after scrolling ' + ); + + window.scroll(0, 0); +})(); +``` + +Tu página de aterrizaje de un producto debe usar por lo menos una consulta de medios. + +```js +const htmlSourceAttr = Array.from(document.querySelectorAll('source')).map(el => el.getAttribute('media')) +const cssCheck = new __helpers.CSSHelp(document).getCSSRules('media') +assert(cssCheck.length > 0 || htmlSourceAttr.length > 0); +``` + +Tu página de aterrizaje de un producto debe usar CSS Flexbox por lo menos una vez. + +```js +const stylesheet = new __helpers.CSSHelp(document).getStyleSheet() +const cssRules = new __helpers.CSSHelp(document).styleSheetToCssRulesArray(stylesheet) +const usesFlex = cssRules.find(rule => { + return rule.style?.display === 'flex' || rule.style?.display === 'inline-flex' +}) +assert(usesFlex) +``` + +# --seed-- + +## --seed-contents-- + +```html + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Product Landing Page + + + +
    +

    + Pokemon Daycare Service +

    +
    +

    What we offer

    +
    +
    + +
    +
    Guaranteed friendly and loving staff!
    +
    +
    +
    + +
    +
    + Comfortable environment for Pokemon to explore and play! +
    +
    +
    +
    + +
    +
    + Multiple membership plans to fit your lifestyle! +
    +
    +
    +
    +

    Check us out!

    + A sneak peek into our facility: +
    + +
    +
    +

    Membership Plans

    +
    +
    + Basic Membership
    +
      +
    • One Pokemon
    • +
    • Food and berries provided
    • +
    + $9.99/month +
    +
    + Silver Membership
    +
      +
    • Up to Three Pokemon
    • +
    • Food and berries provided
    • +
    • Grooming and accessories included
    • +
    + $19.99/month +
    +
    + Gold Membership
    +
      +
    • Up to six Pokemon!
    • +
    • Food and berries provided
    • +
    • Grooming and accessories included
    • +
    • Personal training for each Pokemon
    • +
    • Breeding and egg hatching
    • +
    + $29.99/month +
    +
    +
    + +

    Sign up for our newsletter!

    + + + + +
    + + +``` + +```css +body { + background-color: #3a3240; + color: white; +} +main { + max-width: 750px; + margin: 50px auto; +} +input { + background-color: #92869c; +} +a:not(.nav-link) { + color: white; +} +#header-img { + max-height: 25px; +} +#nav-bar { + position: fixed; + width: 100%; + text-align: center; + top: 0%; + background-color: #92869c; +} +h1 { + text-align: center; +} +body { + text-align: center; +} +footer { + text-align: center; +} +#bullet { + max-height: 25px; +} +.flex-here { + display: flex; + justify-content: center; +} +.flex-left { + height: 25px; +} +.flex-mem { + display: flex; + justify-content: center; +} +.flex-mem-box { + background-color: #92869c; + border-color: black; + border-width: 5px; + border-style: solid; + margin: 10px; + padding: 10px; + color: black; +} +@media (max-width: 350px) { + #video { + width: 300; + height: 200; + } +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/build-a-technical-documentation-page-project/build-a-technical-documentation-page.md b/curriculum/challenges/espanol/14-responsive-web-design-22/build-a-technical-documentation-page-project/build-a-technical-documentation-page.md new file mode 100644 index 00000000000000..5c2fd8307c6293 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/build-a-technical-documentation-page-project/build-a-technical-documentation-page.md @@ -0,0 +1,529 @@ +--- +id: 587d78b0367417b2b2512b05 +title: Construye una página de documentación técnica +challengeType: 14 +forumTopicId: 301146 +dashedName: build-a-technical-documentation-page +--- + +# --description-- + +**Objetivo:** Crea una aplicación que sea funcionalmente similar a https://technical-documentation-page.freecodecamp.rocks + +**Historias de Usuario:** + +1. Puedes ver un elemento `main` con su correspondiente `id="main-doc"`, el cual abarcará el contenido principal de la página (documentación técnica) +1. Dentro del elemento `#main-doc`, se pueden ver varios elementos `section`, cada uno con la clase `main-section`. Debe haber un mínimo de cinco +1. El primer elemento dentro de cada `.main-section` debería ser un elemento `header`, el cual contendrá texto que describa el tema de esa sección. +1. Cada elemento `section` con la clase `main-section` debería tener también un `id` que corresponda al texto de cada `header` contenido dentro de él. Cualquier espacio debe ser reemplazado por guiones bajos ( Ejemplo: La sección que contiene el encabezado "JavaScript and Java" debe tener un `id="JavaScript_and_Java"`) +1. Los elementos `.main-section` deberán tener al menos diez elementos `p` en total (no cada uno) +1. Los elementos `.main-section` deberán tener al menos cinco elementos `code` en total (no cada uno) +1. Los elementos `.main-section` deberán tener al menos cinco items `li` en total (no cada uno) +1. Puedes ver un elemento `nav` con su correspondiente `id="navbar"` +1. La barra de navegación deberá contener un elemento `header`, el cual contendrá texto que describa el tema de la documentación técnica +1. Además, la barra de navegación deberá contener elementos de enlace (`a`) con la clase `nav-link`. Debe haber uno para cada elemento con la clase `main-section` +1. El elemento `header` dentro de la `#navbar` debería ir antes que los elementos (`a`) de la barra de navegación +1. Cada elemento con la clase `nav-link` debería tener texto que corresponda al texto del `header` de cada `section` (Ejemplo: Si tienes una seccion/encabezado "Hello world", tu barra de navegación debería tener un elemento que contenga el texto "Hello world") +1. Al hacer click en un elemento de tu barra de navegación, la página debería dirigirse a la sección correspondiente del elemento `#main-doc` (Ejemplo: Si haces click en el elemento `.nav-link` que contiene el texto "Hello world", la página debería dirigirse al elemento `section` que tenga ese id y contenga el encabezado correspondiente) +1. En dispositivos de tamaño normal (portatiles, computadoras de escritorio), el elemento con `id="navbar"` debe mostrarse en el lado izquierdo de la pantalla y siempre ser visible para el usuario +1. Tu documentación técnica debe usar al menos una media query + +Completa las historias de usuario y pasa todas las pruebas a continuación para completar este proyecto. Dale tu propio estilo personal. ¡Feliz día programando! + +**Nota:** Asegúrate de agregar `` en tu HTML para enlazar tu hoja de estilos y aplicar tu CSS + +# --hints-- + +Debes tener un elemento `main` con un `id` de `main-doc`. + +```js +const el = document.getElementById('main-doc') +assert(!!el) +``` + +Debes tener al menos cinco elementos `section` con la clase `main-section`. + +```js +const els = document.querySelectorAll('#main-doc section') +assert(els.length >= 5) +``` + +Todos tus elementos `.main-section` deben ser elementos `section`. + +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if (el.tagName !== 'SECTION') assert(false) +}) +assert(els.length > 0) +``` + +Debes tener al menos cinco elementos `.main-section` que sean descendientes de `#main-doc`. + +```js +const els = document.querySelectorAll('#main-doc .main-section') +assert(els.length >= 5) +``` + +El primer hijo de cada `.main-section` debe ser un elemento `header`. + +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if(el.firstElementChild?.tagName !== 'HEADER') assert(false) +}) +assert(els.length > 0) +``` + +Ninguno de tus elementos `header` debe estar vacío. + +```js +const els = document.querySelectorAll('header') +els.forEach(el => { + if (el.innerText?.length <= 0) assert(false) +}) +assert(els.length > 0) +``` + +Todos tus elementos `.main-section` deben tener un `id`. + +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if (!el.id || el.id === '') assert(false) +}) +assert(els.length > 0) +``` + +Cada `.main-section` debe tener un `id` que coincida con el texto de su primer hijo, para tener espacios en el texto de su hijo reemplace los espacios por (`_`) para los id. + +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + const text = el.firstElementChild?.innerText?.replaceAll(' ', '_') + if (el.id?.toUpperCase() !== text?.toUpperCase()) assert(false) +}) +assert(els.length > 0) +``` + +Debes tener al menos 10 elementos (en total) `p` dentro de tus elementos `.main-section`. + +```js +const els = document.querySelectorAll('.main-section p') +assert(els.length >= 10) +``` + +Debes tener al menos cinco elementos `code` que sean descendientes de los elementos `.main-section`. + +```js +const els = document.querySelectorAll('.main-section code') +assert(els.length >= 5) +``` + +Debes tener al menos cinco elementos `li` que sean descendientes de los elementos `.main-section`. + +```js +const els = document.querySelectorAll('.main-section li') +assert(els.length >= 5) +``` + +Debes tener un elemento `nav` con un `id` de `navbar`. + +```js +const el = document.getElementById('navbar') +assert(!!el && el.tagName === 'NAV') +``` + +Tu `#navbar` debe tener exactamente un elemento `header` dentro de él. + +```js +const els = document.querySelectorAll('#navbar header') +assert(els.length === 1) +``` + +Debes tener al menos un elemento `a` con la clase `nav-link`. + +```js +const els = document.querySelectorAll('a.nav-link') +assert(els.length >= 1) +``` + +Todos tus elementos `.nav-link` deben ser elementos de anclaje (`a`). + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + if (el.tagName !== 'A') assert(false) +}) +assert(els.length > 0) +``` + +Todos tus elementos `.nav-link` deben estar en el `#navbar`. + +```js +const els1 = document.querySelectorAll('.nav-link') +const els2 = document.querySelectorAll('#navbar .nav-link') +assert(els2.length > 0 && els1.length === els2.length) +``` + +Debes tener el mismo número de elementos `.nav-link` y `.main-section`. + +```js +const els1 = document.querySelectorAll('.main-section') +const els2 = document.querySelectorAll('.nav-link') +assert(els1.length > 0 && els2.length > 0 && els1.length === els2.length) +``` + +El elemento `header` en el `#navbar` debe estar antes que cualquier enlace (`a`) en el `#navbar`. + +```js +const navLinks = document.querySelectorAll('#navbar a.nav-link'); +const header = document.querySelector('#navbar header'); +navLinks.forEach((navLink) => { + if ( + ( + header.compareDocumentPosition(navLink) & + Node.DOCUMENT_POSITION_PRECEDING + ) + ) assert(false) +}); +assert(!!header) +``` + +Cada `.nav-link` debe tener un texto que corresponda con el texto del `header` de su `section` relacionado (por ejemplo, si tienes un section/header "Hello world", tu `#navbar` debe tener un `.nav-link` que tenga el texto "Hello world"). + +```js +const headerText = Array.from(document.querySelectorAll('.main-section')).map(el => + el.firstElementChild?.innerText?.trim().toUpperCase() +) +const linkText = Array.from(document.querySelectorAll('.nav-link')).map(el => + el.innerText?.trim().toUpperCase() +) +const remainder = headerText.filter(str => linkText.indexOf(str) === -1) +assert(headerText.length > 0 && headerText.length > 0 && remainder.length === 0) +``` + +Cada `.nav-link` debe tener un atributo `href` que enlace a su correspondiente `.main-section` (por ejemplo, si haces clic en un elemento `.nav-link` que contenga el texto "Hello world", la pagina navega al elemento `section` con ese id). + +```js +const hrefValues = Array.from(document.querySelectorAll('.nav-link')).map(el => el.getAttribute('href')) +const mainSectionIDs = Array.from(document.querySelectorAll('.main-section')).map(el => el.id) +const missingHrefValues = mainSectionIDs.filter(str => hrefValues.indexOf('#' + str) === -1) +assert(hrefValues.length > 0 && mainSectionIDs.length > 0 && missingHrefValues.length === 0) +``` + +Tu `#navbar` siempre debe estar en el borde izquierdo de la ventana. + +```js +const el = document.getElementById('navbar') +const left1 = el?.offsetLeft +const left2 = el?.offsetLeft +assert(!!el && left1 >= -15 && left1 <= 15 && left2 >= -15 && left2 <= 15) +``` + +Tu proyecto de documentación técnica debe usar al menos una media query. + +```js +const htmlSourceAttr = Array.from(document.querySelectorAll('source')).map(el => el.getAttribute('media')) +const cssCheck = new __helpers.CSSHelp(document).getCSSRules('media') +assert(cssCheck.length > 0 || htmlSourceAttr.length > 0); +``` + +# --seed-- + +## --seed-contents-- + +```html + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Technical Documentation Page + + + +
    +
    +
    Introduction
    +

    + Welcome to a basic introduction of algebra. In this tutorial, we will + review some of the more common algebraic concepts. +

    +
    +
    +
    Definitions
    +

    + To start with, let's define some of the more common terms used in + algebra: +

    +
      +
    • + Variable: A variable is an unknown value, usually represented + by a letter. +
    • +
    • + Expression: Essentially a mathematical object. For the + purpose of this tutorial, an expression is one part of an equation. +
    • +
    • + Equation: An equation is a mathematical argument in which two + expressions result in the same value. +
    • +
    +
    +
    +
    Examples
    +

    + Sometimes it is easier to understand the definitions when you have a + physical example to look at. Here is an example of the above terms.

    + x + 5 = 12

    + In this above example, we have: +

    +
      +
    • Variable: The variable in the example is "x".
    • +
    • + Expression: There are two expressions in this example. They + are "x+5" and "12". +
    • +
    • + Equation: The entire example, "x+5=12", is an equation. +
    • +
    +
    +
    +
    Solving Equations
    +

    + The primary use for algebra is to determine an unknown value, the + "variable", with the information provided. Continuing to use our + example from above, we can find the value of the variable "x".

    + x + 5 = 12

    + In an equation, both sides result in the same value. So you can + manipulate the two expressions however you need, as long as you + perform the same operation (or change) to each side. You do this + because the goal when solving an equation is to + get the variable into its own expression, or by itself on one side + of the = sign.
    For this example, we want to remove the "+5" so the "x" is + alone. To do this, we can subtract 5, because subtraction is + the opposite operation to addition. But remember, we have to perform + the same operation to both sides of the equation. Now our equation + looks like this.

    + x + 5 - 5 = 12 - 5

    + The equation looks like a mess right now, because we haven't completed + the operations. We can simplify this equation to make it easier + to read by performing the operations "5-5" and "12-5". The result + is:

    + x = 7

    + We now have our solution to this equation! +

    +
    +
    +
    Solving Equations II
    +

    + Let us look at a slightly more challenging equation.

    + 3x + 4 = 13

    + Again we can start with subtraction. In this case, we want to subtract + 4 from each side of the equation. We will also go ahead and simplify + with each step. So now we have:

    + 3x = 9

    + "3x" translates to "3*x", where the "*" symbol indicates + multiplication. We use the "*" to avoid confusion, as the "x" is now a + variable instead of a multiplication symbol. The opposite operation + for multiplication is division, so we need to + divide each expression by 3.

    + x = 3

    + And now we have our solution! +

    +
    +
    +
    Solving Equations III
    +

    + Now we are getting in to more complex operations. Here is another + equation for us to look at:

    + x^2 - 8 = 8

    + Our very first step will be to add 8 to each side. This is + different from our previous examples, where we had to subtract. But + remember, our goal is to get the variable alone by performing opposite + operations.

    + x^2 = 16

    + But what does the "^2" mean? The "^" symbol is used to denote + exponents in situations where superscript is not available. When + superscript is available, you would see it as x2. + For the sake of this project, however, we will use the "^" symbol.
    + An exponent tells you how many times the base (in our case, "x") is + multiplied by itself. So, "x^2" would be the same as "x*x". Now the + opposite function of multiplication is division, but we would have to + divide both sides by "x". We do not want to do this, as that + would put an "x" on the other side of the equation. So instead, we + need to use the root operation! For an exponent of "2", we call this + the "square root" and denote it with "√". Our equation is now: +

    + x = √9

    + Performing a root operation by hand can be a tedious process, so we + recommend using a calculator when necessary. However, we are lucky in + that "9" is a + perfect square, so we do not need to calculate anything. Instead, we find our + answer to be:

    + x = 3 +

    +
    +
    +
    System of Equations
    +

    + As you explore your algebra studies further, you may start to run + across equations with more than one variable. The first such equations + will likely look like:

    + y = 3x

    + An equation like this does not have one single solution. + Rather, there are a series of values for which the equation is true. + For example, if "x=3" and "y=9", the equation is true. These equations + are usually used to plot a graph.
    + Getting more complicated, though, you may be given a pair of + equations. This is called a "system of equations", and CAN be solved. + Let's look at how we do this! Consider the following system of + equations:

    + y = 3x | y - 6 = x + A system of equations IS solvable, but it is a multi-step process. To + get started, we need to chose a variable we are solving for. Let's + solve for "x" first. From the second equation, we know that "x" equals + "y - 6", but we cannot simplify that further because we do not have a + value for "y". Except, thanks to the system of equations, we DO have a + value for "y". We know that "y" equals "3x". So, looking at our second + equation, we can replace "y" with "3x" because they have the same + value. We then get:

    + 3x - 6 = x

    + Now we can solve for "x"! We start by adding 6 to each side.

    + 3x = x + 6

    + We still need to get "x" by itself, so we subtract "x" from both sides + and get:

    + 2x = 6

    + If this confuses you, remember that "3x" is the same as "x+x+x". + Subtract an "x" from that and you get "x+x", or "2x". Now we divide + both sides by 2 and have our value for x!

    + x = 3

    + However, our work is not done yet. We still need to find the value for + "y". Let's go back to our first equation:

    + y = 3x

    + We have a value for "x" now, so let's see what happens if we put that + value in.

    + y = 3*3

    + We perform the multiplication and discover that "y=9"! Our solution to + this system of equations then is:

    + x = 3 and y = 9

    +

    +
    +
    +
    Try it Yourself!
    +

    Coming Soon!

    +

    Keep an eye out for new additions!

    +
    +
    +
    More Information
    +

    Check out the following links for more information!

    + +
    +
    + + + +``` + +```css +* { + background-color: #3a3240; +} +a { + color: #92869c; +} +a:hover { + background-color: #92869c; + color: #3a3240; +} +#navbar { + border-style: solid; + border-width: 5px; + border-color: #92869c; + height: 100%; + top: -5px; + left: -5px; + padding: 5px; + text-align: center; + color: #92869c +} +@media (min-width: 480px) { + #navbar { + position: fixed; + } +} +main { + margin-left: 220px; + color: #92869c +} +header { + font-size: 20pt; +} +code { + background-color: #92869c; + border-style: dashed; + border-width: 2px; + border-color: #92869c; + padding: 5px; + color: black; +} +footer { + text-align: center; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613297a923965e0703b64796.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613297a923965e0703b64796.md new file mode 100644 index 00000000000000..042f8b444072bd --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613297a923965e0703b64796.md @@ -0,0 +1,56 @@ +--- +id: 613297a923965e0703b64796 +title: Paso 2 +challengeType: 0 +dashedName: step-2 +--- + +# --description-- + +Puede que ya estés familiarizado con el elemento `meta`; es usado para especificar información sobre la página, como el título, descripción, palabras clave y el autor. + +Dale a tu página un elemento `meta` con un valor `charset` apropiado. + +El atributo `charset` especifica la codificación de los caracteres de la página, y actualmente `UTF-8` es la única codificación soportada por la mayoría de navegadores. + +# --hints-- + +Debes crear un elemento `meta` dentro del elemento `head`. + +```js +assert.exists(document.querySelector('head > meta')); +``` + +Debes dar a la etiqueta `meta` un `charset` de `UTF-8`. + +```js +assert.equal(document.querySelector('head > meta')?.getAttribute('charset')?.toLowerCase(), 'utf-8'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +--fcc-editable-region-- + + + +--fcc-editable-region-- + + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61329b210dac0b08047fd6ab.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61329b210dac0b08047fd6ab.md new file mode 100644 index 00000000000000..105c06ce8df9a0 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61329b210dac0b08047fd6ab.md @@ -0,0 +1,61 @@ +--- +id: 61329b210dac0b08047fd6ab +title: Paso 3 +challengeType: 0 +dashedName: step-3 +--- + +# --description-- + +Continuando con los elementos `meta`, una definición de `viewport` le dice al navegador cómo renderizar la página. Incluyendo una mejor accesibilidad visual en móvil, y mejora _SEO_ (optimización del motor de búsqueda). + +Agrega una definición de `viewport` con un atributo `content` que detalla el `width` y `initial-scale` de la página. + +# --hints-- + +Debes crear un elemento `meta` dentro del elemento `head`. + +```js +assert.equal(document.querySelectorAll('head > meta')?.length, 2); +``` + +Debes dar al `meta` un atributo `name` de `viewport`. + +```js +assert.equal(document.querySelectorAll('head > meta[name="viewport"]')?.length, 1); +``` + +Debes dar al `meta` un atributo `content` de `width=device-width, initial-scale=1`. + +```js +assert.equal(document.querySelectorAll('head > meta[content="width=device-width, initial-scale=1.0"]')?.length || document.querySelectorAll('head > meta[content="width=device-width, initial-scale=1"]')?.length, 1); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +--fcc-editable-region-- + + + + +--fcc-editable-region-- + + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61329d52e5010e08d9b9d66b.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61329d52e5010e08d9b9d66b.md new file mode 100644 index 00000000000000..68e7ea4e60e14f --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61329d52e5010e08d9b9d66b.md @@ -0,0 +1,68 @@ +--- +id: 61329d52e5010e08d9b9d66b +title: Paso 4 +challengeType: 0 +dashedName: step-4 +--- + +# --description-- + +Otro elemento `meta` importante para la accesibilidad y SEO es la definición de `description`. El valor del atributo `content` es usado por los motores de búsqueda para proporcionar una descripción de tu página. + +Agrega un elemento `meta` con el atributo `name` establecido a `description`, y dale un útil atributo `content`. + +# --hints-- + +Debes agregar un nuevo elemento `meta` al `head`. + +```js +assert.equal(document.querySelectorAll('meta').length, 3); +``` + +Debes dar al `meta` un atributo `name` de `description`. + +```js +assert.exists(document.querySelector('meta[name="description"]')); +``` + +Debes darle al `meta` un atributo `content`. + +```js +assert.notEmpty(document.querySelector('meta[name="description"]')?.content); +``` + +El valor del atributo `content` no debe tener más de 165 caracteres. _Esta es la longitud máxima de la descripción de Google._ + +```js +assert.isAtMost(document.querySelector('meta[name="description"]')?.content?.length, 165); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +--fcc-editable-region-- + + + + + +--fcc-editable-region-- + + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6133acc353338c0bba9cb553.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6133acc353338c0bba9cb553.md new file mode 100644 index 00000000000000..f520a24c0f26b8 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6133acc353338c0bba9cb553.md @@ -0,0 +1,63 @@ +--- +id: 6133acc353338c0bba9cb553 +title: Paso 5 +challengeType: 0 +dashedName: step-5 +--- + +# --description-- + +Finalmente, en el `head`, el elemento `title` es útil para que los lectores de pantalla entiendan el contenido de la página. Además, es una parte importante del _SEO_. + +Dale a tu página un `title` que sea descriptivo y conciso. + +# --hints-- + +Debes agregar un elemento `title` al `head`. + +```js +assert.exists(document.querySelector('head > title')); +``` + +No debes hacer que el `title` sea más largo que 60 caracteres. + +```js +assert.isAtMost(document.querySelector('head > title')?.textContent?.length, 60); +``` + +Intenta ser más descriptivo con tu elemento `title`. _Pista: Por lo menos 15 caracteres_ + +```js +assert.isAtLeast(document.querySelector('head > title')?.textContent?.length, 15); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +--fcc-editable-region-- + + + + + + +--fcc-editable-region-- + + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6133d11ef548f51f876149e3.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6133d11ef548f51f876149e3.md new file mode 100644 index 00000000000000..a591d0e407b2e1 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6133d11ef548f51f876149e3.md @@ -0,0 +1,68 @@ +--- +id: 6133d11ef548f51f876149e3 +title: Paso 6 +challengeType: 0 +dashedName: step-6 +--- + +# --description-- + +La navegación es una parte fundamental de la accesibilidad, y los lectores de pantalla confían en que proporciones la estructura de tu página. Esto se consigue con elementos HTML semánticos. + +Agrega un elemento `header` y un elemento `main` a tu página. + +El elemento `header` se utilizará para introducir la página, así como para proporcionar un menú de navegación. + +El elemento `main` contendrá el contenido principal de tu página. + +# --hints-- + +Debes agregar un elemento `header` al `body`. + +```js +assert.exists(document.querySelector('body > header')); +``` + +Debes agregar un elemento `main` al `body`. + +```js +assert.exists(document.querySelector('body > main')); +``` + +El elemento `header` debe ir antes del elemento `main`. + +```js +assert.exists(document.querySelector('header + main')); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + +--fcc-editable-region-- + + + +--fcc-editable-region-- + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613e2546d0594208229ada50.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613e2546d0594208229ada50.md new file mode 100644 index 00000000000000..624a8b2a05ee24 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613e2546d0594208229ada50.md @@ -0,0 +1,93 @@ +--- +id: 613e2546d0594208229ada50 +title: Paso 7 +challengeType: 0 +dashedName: step-7 +--- + +# --description-- + +Dentro del `header`, proporciona contexto sobre la página anidando un elemento `img`, `h1` y `nav`. + +El `img` debe apuntar a `https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg`, y tener un `id` de `logo`. + +El `h1` debe contener el texto `HTML/CSS Quiz`. + +# --hints-- + +Debes agregar un elemento `img` al elemento `header`. + +```js +assert.exists(document.querySelector('header > img')); +``` + +Debes agregar un elemento `h1` al elemento `header`. + +```js +assert.exists(document.querySelector('header > h1')); +``` + +Debes agregar un elemento `nav` al elemento `header`. + +```js +assert.exists(document.querySelector('header > nav')); +``` + +Debes colocar los elementos `img`, `h1` y `nav` en ese orden. + +```js +assert.exists(document.querySelector('img + h1 + nav')); +``` + +Debes dar al elemento `img` un atributo `src` de `https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg`. + +```js +assert.equal(document.querySelector('img')?.src, 'https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg'); +``` + +Debes dar al elemento `img` un atributo `id` de `logo`. + +```js +assert.equal(document.querySelector('img')?.id, 'logo'); +``` + +Debes dar al elemento `h1` el texto `HTML/CSS Quiz`. + +```js +assert.include(document.querySelector('h1')?.innerText?.toLowerCase(), 'html/css quiz'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +--fcc-editable-region-- +
    + +
    +--fcc-editable-region-- +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613e275749ebd008e74bb62e.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613e275749ebd008e74bb62e.md new file mode 100644 index 00000000000000..4431fd22e34df4 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613e275749ebd008e74bb62e.md @@ -0,0 +1,66 @@ +--- +id: 613e275749ebd008e74bb62e +title: Paso 8 +challengeType: 0 +dashedName: step-8 +--- + +# --description-- + +Una propiedad útil de un _SVG_ (gráficos vectoriales escalables) es que contiene un atributo `path` que permite escalar la imagen sin afectar la resolución de la imagen resultante. + +Actualmente, el `img` está asumiendo el tamaño predeterminado, que es demasiado grande. De manera adecuada, escala la imagen usando el `id` como selector y establece el `width` a `max(100px, 18vw)`. + +# --hints-- + +Debes usar el selector `#logo` para apuntar al elemento `img`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('#logo')); +``` + +Debes dar al `img` un `width` de `max(100px, 18vw)`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('#logo')?.width, 'max(100px, 18vw)'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6140827cff96e906bd38fc2b.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6140827cff96e906bd38fc2b.md new file mode 100644 index 00000000000000..33f159859b665a --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6140827cff96e906bd38fc2b.md @@ -0,0 +1,93 @@ +--- +id: 6140827cff96e906bd38fc2b +title: Paso 9 +challengeType: 0 +dashedName: step-9 +--- + +# --description-- + +Como se describe en la [Guia de Estilo de freeCodeCamp](https://design-style-guide.freecodecamp.org/), el logo debe mantener una relación de aspecto de `35 / 4`, y tener un relleno alrededor del texto. + +En primer lugar, cambia el `background-color` a `#0a0a23` para que pueda ver el logo. Luego, usa la propiedad `aspect-ratio` para establecer la relación de aspecto a `35 / 4`. Finalmente, agrega alrededor un `padding` de `0.4rem`. + +# --hints-- + +Debes dar al `#logo` un `background-color` de `#0a0a23`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('#logo')?.backgroundColor, 'rgb(10, 10, 35)'); +``` + +Debes usar una propiedad `aspect-ratio`. + +```js +assert.notEmpty(new __helpers.CSSHelp(document).getStyle('#logo')?.aspectRatio); +``` + +No debes usar la propiedad `height`. + +```js +assert.isEmpty(new __helpers.CSSHelp(document).getStyle('#logo')?.height); +``` + +No debes cambiar la propiedad `width`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('#logo')?.width, 'max(100px, 18vw)'); +``` + +Debes dar al `img` un `aspect-ratio` de `35 / 4`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('#logo')?.aspectRatio, '35 / 4'); +``` + +Debes dar al `img` un `padding` de `0.4rem`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('#logo')?.padding, '0.4rem'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +--fcc-editable-region-- +#logo { + width: max(100px, 18vw); + +} +--fcc-editable-region-- + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6140883f74224508174794c0.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6140883f74224508174794c0.md new file mode 100644 index 00000000000000..774de7e62d04a2 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6140883f74224508174794c0.md @@ -0,0 +1,89 @@ +--- +id: 6140883f74224508174794c0 +title: Paso 10 +challengeType: 0 +dashedName: step-10 +--- + +# --description-- + +Haz que el `header` ocupe todo el ancho de su contenedor padre, establece su `height` a `50px` y establece el `background-color` a `#1b1b32`. Luego, establece el `display` para usar _Flexbox_. + +# --hints-- + +Debes usar el selector del elemento `header`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('header')); +``` + +Debes dar al `header` un `width` de `100%`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('header')?.width, '100%'); +``` + +Debes dar al `header` un `height` de `50px`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('header')?.height, '50px'); +``` + +Debes dar al `header` un `background-color` de `#1b1b32`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('header')?.backgroundColor, 'rgb(27, 27, 50)'); +``` + +Debes dar al `header` un `display` de `flex`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('header')?.display, 'flex'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61408e4ae3e35d08feb260eb.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61408e4ae3e35d08feb260eb.md new file mode 100644 index 00000000000000..4891d3fb690b7d --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61408e4ae3e35d08feb260eb.md @@ -0,0 +1,83 @@ +--- +id: 61408e4ae3e35d08feb260eb +title: Paso 11 +challengeType: 0 +dashedName: step-11 +--- + +# --description-- + +Cambia el color de fuente del `h1` a `#f1be32`, y establece el tamaño de la fuente a `min(5vw, 1.2em)`. + +# --hints-- + +Debes usar el selector del elemento `h1`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('h1')); +``` + +Debes dar al `h1` un `color` de `#f1be32`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('h1')?.color, 'rgb(241, 190, 50)'); +``` + +Debes dar al `h1` un `font-size` de `min(5vw, 1.2em)`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('h1')?.fontSize, 'min(5vw, 1.2em)'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61408f155e798909b6908712.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61408f155e798909b6908712.md new file mode 100644 index 00000000000000..c12f83a091c01e --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61408f155e798909b6908712.md @@ -0,0 +1,112 @@ +--- +id: 61408f155e798909b6908712 +title: Paso 12 +challengeType: 0 +dashedName: step-12 +--- + +# --description-- + +Para habilitar la navegación en la página, agrega una lista desordenada con los tres elementos de la lista siguientes: + +- `INFO` +- `HTML` +- `CSS` + +El texto de los elementos de la lista debe estar envuelto en etiquetas de anclaje. + +# --hints-- + +Debes anidar un elemento `ul` dentro del `nav`. + +```js +assert.equal(document.querySelectorAll('nav > ul')?.length, 1); +``` + +Debes anidar tres elementos `li` dentro del elemento `ul`. + +```js +assert.equal(document.querySelectorAll('nav > ul > li')?.length, 3); +``` + +Debes anidar un elemento `a` dentro de cada elemento `li`. + +```js +assert.equal(document.querySelectorAll('nav > ul > li > a')?.length, 3); +``` + +Debes dar al primer elemento `a` el texto `INFO`. + +```js +assert.equal(document.querySelectorAll('nav > ul > li > a')?.[0]?.textContent, 'INFO'); +``` + +Debes dar al segundo elemento `a` el texto `HTML`. + +```js +assert.equal(document.querySelectorAll('nav > ul > li > a')?.[1]?.textContent, 'HTML'); +``` + +Debes dar al tercer elemento `a` el texto `CSS`. + +```js +assert.equal(document.querySelectorAll('nav > ul > li > a')?.[2]?.textContent, 'CSS'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    +--fcc-editable-region-- + +--fcc-editable-region-- +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614090d5a22b6f0a5a6b464c.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614090d5a22b6f0a5a6b464c.md new file mode 100644 index 00000000000000..75cc7a84919cbb --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614090d5a22b6f0a5a6b464c.md @@ -0,0 +1,102 @@ +--- +id: 614090d5a22b6f0a5a6b464c +title: Paso 13 +challengeType: 0 +dashedName: step-13 +--- + + + +# --description-- + +Apunta a los elementos de lista desordenada dentro de los elementos `nav`, y usa _Flexbox_ para espaciar de manera uniforme a los hijos. + +# --hints-- + +Debes usar el selector `nav > ul`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('nav > ul')); +``` + +Debes dar a los elementos `nav > ul` un `display` de `flex`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('nav > ul')?.display, 'flex'); +``` + +Debes dar a los elementos `nav > ul` un `justify-content` de `space-evenly`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('nav > ul')?.justifyContent, 'space-evenly'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6141fabd6f75610664e908fd.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6141fabd6f75610664e908fd.md new file mode 100644 index 00000000000000..722463c8e6894d --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6141fabd6f75610664e908fd.md @@ -0,0 +1,125 @@ +--- +id: 6141fabd6f75610664e908fd +title: Paso 14 +challengeType: 0 +dashedName: step-14 +--- + +# --description-- + +Como este es un cuestionario, necesitaras un formulario para que los usuarios envíen sus respuestas. Puedes separar semánticamente el contenido dentro del formulario usando elementos `section`. + +Dentro del elemento `main`, crea un formulario con tres elementos `section` anidados. Luego, haga que el formulario se envíe a `https://freecodecamp.org/practice-project/accessibility-quiz`, usando el método correcto. + +# --hints-- + +Debes anidar un elemento `form` dentro de tu elemento `main`. + +```js +assert.exists(document.querySelector('main > form')); +``` + +Debes anidar tres elementos `section` dentro de tu elemento `form`. + +```js +assert.equal(document.querySelectorAll('main > form > section')?.length, 3); +``` + +Debes dar al elemento `form` un atributo `action`. + +```js +assert.notEmpty(document.querySelector('main > form')?.action); +``` + +Debes dar al atributo `action` el valor `https://freecodecamp.org/practice-project/accessibility-quiz`. + +```js +assert.equal(document.querySelector('main > form')?.action, 'https://freecodecamp.org/practice-project/accessibility-quiz'); +``` + +Debes dar al elemento `form` un atributo `method`. + +```js +assert.notEmpty(document.querySelector('main > form')?.method); +``` + +Debes dar al elemento `form` un atributo `method` con el valor `post`. + +```js +assert.equal(document.querySelector('main > form')?.method?.toLowerCase(), 'post'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +--fcc-editable-region-- +
    + +
    +--fcc-editable-region-- + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6141fed65b61320743da5894.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6141fed65b61320743da5894.md new file mode 100644 index 00000000000000..bc661db584b0d9 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6141fed65b61320743da5894.md @@ -0,0 +1,111 @@ +--- +id: 6141fed65b61320743da5894 +title: Paso 15 +challengeType: 0 +dashedName: step-15 +--- + +# --description-- + +Para aumentar la accesibilidad de la página, el atributo `role` puede ser usado para indicar el propósito detrás de un elemento en la página para las tecnologías de asistencia. El atributo `role` es una parte de la _Iniciativa de Accesibilidad Web_ (WAI, por sus siglas en inglés), y acepta valores predefinidos. + +Dale a cada elemento `section` el rol `region`. + +# --hints-- + +Debes dar al primer elemento `section` el rol `region`. + +```js +assert.equal(document.querySelectorAll('section')?.[0]?.getAttribute('role'), 'region'); +``` + +Debes dar al segundo elemento `section` el rol `region`. + +```js +assert.equal(document.querySelectorAll('section')?.[1]?.getAttribute('role'), 'region'); +``` + +Debes dar al tercer elemento `section` el rol `region`. + +```js +assert.equal(document.querySelectorAll('section')?.[2]?.getAttribute('role'), 'region'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +--fcc-editable-region-- +
    +
    +
    +
    +
    +--fcc-editable-region-- +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614202874ca576084fca625f.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614202874ca576084fca625f.md new file mode 100644 index 00000000000000..8224314de98714 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614202874ca576084fca625f.md @@ -0,0 +1,171 @@ +--- +id: 614202874ca576084fca625f +title: Paso 16 +challengeType: 0 +dashedName: step-16 +--- + +# --description-- + +Cada rol `region` requiere una etiqueta visible, que debe ser referenciado por el atributo `aria-labelledby`. + +A los elementos `section`, dale los siguientes atributos `aria-labelledby`: + +- `student-info` +- `html-questions` +- `css-questions` + +Luego, dentro de cada elemento `section`, anida un elemento `h2` con un `id` que coincida con su atributo `aria-labelledby` correspondiente. Da a cada `h2` un contenido de texto adecuado. + +# --hints-- + +Debes dar al primer elemento `section` un atributo `aria-labelledby` de `student-info`. + +```js +assert.equal(document.querySelectorAll('section')?.[0]?.getAttribute('aria-labelledby'), 'student-info'); +``` + +Debes dar al segundo elemento `section` un atributo `aria-labelledby` de `html-questions`. + +```js +assert.equal(document.querySelectorAll('section')?.[1]?.getAttribute('aria-labelledby'), 'html-questions'); +``` + +Debes dar al tercer elemento `section` un atributo `aria-labelledby` de `css-questions`. + +```js +assert.equal(document.querySelectorAll('section')?.[2]?.getAttribute('aria-labelledby'), 'css-questions'); +``` + +Debes anidar un elemento `h2` dentro del primer elemento `section`. + +```js +assert.equal(document.querySelectorAll('section')?.[0]?.querySelectorAll('h2')?.length, 1); +``` + +Debes anidar un elemento `h2` dentro del segundo elemento `section`. + +```js +assert.equal(document.querySelectorAll('section')?.[1]?.querySelectorAll('h2')?.length, 1); +``` + +Debes anidar un elemento `h2` dentro del tercer elemento `section`. + +```js +assert.equal(document.querySelectorAll('section')?.[2]?.querySelectorAll('h2')?.length, 1); +``` + +Debes dar al primer elemento `h2` un atributo `id` de `student-info`. + +```js +assert.equal(document.querySelectorAll('h2')?.[0]?.id, 'student-info'); +``` + +Debes dar al segundo elemento `h2` un atributo `id` de `html-questions`. + +```js +assert.equal(document.querySelectorAll('h2')?.[1]?.id, 'html-questions'); +``` + +Debes dar al tercer elemento `h2` un atributo `id` de `css-questions`. + +```js +assert.equal(document.querySelectorAll('h2')?.[2]?.id, 'css-questions'); +``` + +Debes dar al primer elemento `h2` un contenido de texto adecuado. _Pista: Yo hubiera elegido `Student Info`_ + +```js +assert.isAtLeast(document.querySelectorAll('h2')?.[0]?.textContent?.length, 1); +``` + +Debes dar al segundo elemento `h2` un contenido de texto adecuado. _Pista: Yo hubiera elegido `HTML`_ + +```js +assert.isAtLeast(document.querySelectorAll('h2')?.[1]?.textContent?.length, 1); +``` + +Debes dar al tercer elemento `h2` un contenido de texto adecuado. _Pista: Yo hubiera elegido `CSS`_ + +```js +assert.isAtLeast(document.querySelectorAll('h2')?.[2]?.textContent?.length, 1); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +--fcc-editable-region-- +
    +
    +
    +
    +
    +--fcc-editable-region-- +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614206033d366c090ca7dd42.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614206033d366c090ca7dd42.md new file mode 100644 index 00000000000000..301d9e689f6cb7 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614206033d366c090ca7dd42.md @@ -0,0 +1,140 @@ +--- +id: 614206033d366c090ca7dd42 +title: Paso 17 +challengeType: 0 +dashedName: step-17 +--- + +# --description-- + +El tipo de letra juega un rol importante en la accesibilidad de una página. Algunas fuentes son más fáciles de leer que otras, y esto es especialmente cierto en pantallas de resolución baja. + +Cambia la fuente para ambos elementos `h1` y `h2` a `Verdana`, y usa otra fuente web segura de la familia sans-serif como un respaldo. + +Además, agrega un `border-bottom` de `4px solid #dfdfe2` a los elementos `h2` para distinguir las secciones. + +# --hints-- + +Debes usar un selector de elementos múltiples que apunte a los elementos `h1` y `h2`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s); +assert.exists(gs('h1, h2') || gs('h2, h1')); +``` + +Debes establecer el primer valor de la propiedad `font-family` a `Verdana`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s); +const style = gs('h1, h2') || gs('h2, h1'); +assert.include(style?.fontFamily, 'Verdana'); +``` + +Debes establecer el segundo valor de la propiedad `font-family` a otra fuente sans-serif, segura para la web. _Pista: Yo elegiría Tahoma_. + +```js +// Acceptable fonts: Arial, sans-serif, Helvetica, Tahoma, Trebuchet MS. +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s); +const style = gs('h1, h2') || gs('h2, h1'); +assert.match(style?.fontFamily, /(Tahoma)|(Arial)|(sans-serif)|(Helvetica)|(Trebuchet MS)/); +``` + +Debes usar un selector del elemento `h2` para apuntar a los elementos `h2`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('h2')); +``` + +Debes dar al `h2` una propiedad `border-bottom` de `4px solid #dfdfe2`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('h2')?.borderBottom, '4px solid rgb(223, 223, 226)'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    +
    +

    HTML

    +
    +
    +

    CSS

    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61435e3c0679a306c20f1acc.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61435e3c0679a306c20f1acc.md new file mode 100644 index 00000000000000..883b807026543a --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61435e3c0679a306c20f1acc.md @@ -0,0 +1,125 @@ +--- +id: 61435e3c0679a306c20f1acc +title: Paso 18 +challengeType: 0 +dashedName: step-18 +--- + +# --description-- + +Para poder navegar dentro de la página, dale a cada elemento ancla un `href` correspondiente al `id` de los elementos `h2`. + +# --hints-- + +Debes dar al primer elemento `a` un `href` de `#student-info`. + +```js +assert.equal(document.querySelectorAll('a')?.[0]?.getAttribute('href'), '#student-info'); +``` + +Debes dar al segundo elemento `a` un `href` de `#html-questions`. + +```js +assert.equal(document.querySelectorAll('a')?.[1]?.getAttribute('href'), '#html-questions'); +``` + +Debes dar al tercer elemento `a` un `href` de `#css-questions`. + +```js +assert.equal(document.querySelectorAll('a')?.[2]?.getAttribute('href'), '#css-questions'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    +
    +

    HTML

    +
    +
    +

    CSS

    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143610161323a081b249c19.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143610161323a081b249c19.md new file mode 100644 index 00000000000000..250f060cb948a3 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143610161323a081b249c19.md @@ -0,0 +1,173 @@ +--- +id: 6143610161323a081b249c19 +title: Paso 19 +challengeType: 0 +dashedName: step-19 +--- + +# --description-- + +Rellenando el contenido del cuestionario, debajo de `#student-info`, agrega tres elementos `div` con un `class` de `info`. + +Luego, dentro de cada `div` anida un elmento `label` y un elemento `input`. + +# --hints-- + +Debes anidar tres elementos `div` debajo del elemento `h2#student-info`. + +```js +assert.equal(document.querySelectorAll('h2#student-info ~ div')?.length, 3); +``` + +Debes dar al primer `div` un `class` de `info`. + +```js +assert.equal(document.querySelectorAll('h2#student-info ~ div')?.[0]?.className, 'info'); +``` + +Debes dar al segundo `div` un `class` de `info`. + +```js +assert.equal(document.querySelectorAll('h2#student-info ~ div')?.[1]?.className, 'info'); +``` + +Debes dar al tercer `div` un `class` de `info`. + +```js +assert.equal(document.querySelectorAll('h2#student-info ~ div')?.[2]?.className, 'info'); +``` + +Debes anidar un elemento `label` dentro del primer `div`. + +```js +assert.equal(document.querySelectorAll('h2#student-info ~ div')?.[0]?.querySelectorAll('label')?.length, 1); +``` + +Debes anidar un elemento `input` dentro del primer `div`, después del `label`. + +```js +assert.equal(document.querySelectorAll('h2#student-info ~ div')?.[0]?.querySelectorAll('input')?.length, 1); +assert.exists(document.querySelectorAll('h2#student-info ~ div')?.[0]?.querySelector('label + input')); +``` + +Debes anidar un elemento `label` dentro del segundo `div`. + +```js +assert.equal(document.querySelectorAll('h2#student-info ~ div')?.[1]?.querySelectorAll('label')?.length, 1); +``` + +Debes anidar un elemento `input` dentro del segundo `div`, después del `label`. + +```js +assert.equal(document.querySelectorAll('h2#student-info ~ div')?.[1]?.querySelectorAll('input')?.length, 1); +assert.exists(document.querySelectorAll('h2#student-info ~ div')?.[1]?.querySelector('label + input')); +``` + +Debes anidar un elemento `label` dentro del tercer `div`. + +```js +assert.equal(document.querySelectorAll('h2#student-info ~ div')?.[2]?.querySelectorAll('label')?.length, 1); +``` + +Debes anidar un elemento `input` dentro del tercer `div`, después del `label`. + +```js +assert.equal(document.querySelectorAll('h2#student-info ~ div')?.[2]?.querySelectorAll('input')?.length, 1); +assert.exists(document.querySelectorAll('h2#student-info ~ div')?.[2]?.querySelector('label + input')); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +--fcc-editable-region-- +
    +

    Student Info

    + +
    +--fcc-editable-region-- +
    +

    HTML

    +
    +
    +

    CSS

    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143639d5eddc7094161648c.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143639d5eddc7094161648c.md new file mode 100644 index 00000000000000..e922095984e022 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143639d5eddc7094161648c.md @@ -0,0 +1,195 @@ +--- +id: 6143639d5eddc7094161648c +title: Paso 20 +challengeType: 0 +dashedName: step-20 +--- + +# --description-- + +Es importante vincular cada `input` con su elemento `label` correspondiente. Esto proporciona a los usuarios de tecnologías de asistencia una referencia visual del input. + +Esto se hace dando al `label` un atributo `for`, que contiene el `id` del `input`. + +Esta sección tomará el nombre del estudiante, correo electrónico y la fecha de nacimiento. Da a los elementos `label` un atributo `for` apropiado, así como contenido de texto. Luego, vincula los elemento `input` con sus elementos `label` correspondientes. + +# --hints-- + +Debes dar al primer elemento `label` un atributo `for` apropiado. + +```js +assert.isAtLeast(document.querySelectorAll('label')?.[0]?.htmlFor?.length, 1); +``` + +Debes dar al segundo elemento `label` un atributo `for` apropiado. + +```js +assert.isAtLeast(document.querySelectorAll('label')?.[1]?.htmlFor?.length, 1); +``` + +Debes dar al tercer elemento `label` un atributo `for` apropiado. + +```js +assert.isAtLeast(document.querySelectorAll('label')?.[2]?.htmlFor?.length, 1); +``` + +Debes dar al primer elemento `label` un contenido de texto apropiado. + +```js +assert.isAtLeast(document.querySelectorAll('label')?.[0]?.textContent?.length, 1); +``` + +Debes dar al segundo elemento `label` un contenido de texto apropiado. + +```js +assert.isAtLeast(document.querySelectorAll('label')?.[1]?.textContent?.length, 1); +``` + +Debes dar al tercer elemento `label` un contenido de texto apropiado. + +```js +assert.isAtLeast(document.querySelectorAll('label')?.[2]?.textContent?.length, 1); +``` + +Debes dar al primer elemento `input` un atributo `id` que coincida con el atributo `for` del primer `label`. + +```js +assert.equal(document.querySelectorAll('input')?.[0]?.id, document.querySelectorAll('label')?.[0]?.htmlFor); +``` + +Debes dar al segundo elemento `input` un atributo `id` que coincida con el atributo `for` del segundo `label`. + +```js +assert.equal(document.querySelectorAll('input')?.[1]?.id, document.querySelectorAll('label')?.[1]?.htmlFor); +``` + +Debes dar al tercer elemento `input` un atributo `id` que coincida con el atributo `for` del tercer `label`. + +```js +assert.equal(document.querySelectorAll('input')?.[2]?.id, document.querySelectorAll('label')?.[2]?.htmlFor); +``` + +No debes usar el mismo atributo `id` para más de un elemento `input`. + +```js +const id = (n) => document.querySelectorAll('input')?.[n]?.id; +assert.notEqual(id(0), id(1)); +assert.notEqual(id(0), id(2)); +assert.notEqual(id(1), id(2)); +``` + +No debes usar el mismo atributo `for` para más de un elemento `label`. + +```js +const htmlFor = (n) => document.querySelectorAll('label')?.[n]?.htmlFor; +assert.notEqual(htmlFor(0), htmlFor(1)); +assert.notEqual(htmlFor(0), htmlFor(2)); +assert.notEqual(htmlFor(1), htmlFor(2)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +--fcc-editable-region-- +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +--fcc-editable-region-- +
    +

    HTML

    +
    +
    +

    CSS

    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143908b6aafb00a659ca189.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143908b6aafb00a659ca189.md new file mode 100644 index 00000000000000..58a93ea7a87764 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143908b6aafb00a659ca189.md @@ -0,0 +1,161 @@ +--- +id: 6143908b6aafb00a659ca189 +title: Paso 21 +challengeType: 0 +dashedName: step-21 +--- + +# --description-- + +Teniendo en cuenta las mejores prácticas para las entradas de formularios, da a cada `input` un atributo `type` y `name` apropiados. Luego, da al primer `input` un atributo `placeholder`. + +# --hints-- + +Debes dar al primer `input` un `type` de `text`. + +```js +assert.equal(document.querySelectorAll('input')?.[0]?.type, 'text'); +``` + +Debes dar al segundo `input` un `type` de `email`. + +```js +assert.equal(document.querySelectorAll('input')?.[1]?.type, 'email'); +``` + +Debes dar al tercer `input` un `type` de `date`. + +```js +assert.equal(document.querySelectorAll('input')?.[2]?.type, 'date'); +``` + +Debes dar al primer `input` un atributo `name` apropiado. + +```js +assert.isAtLeast(document.querySelectorAll('input')?.[0]?.name?.length, 1); +``` + +Debes dar al segundo `input` un atributo `name` apropiado. + +```js +assert.isAtLeast(document.querySelectorAll('input')?.[1]?.name?.length, 1); +``` + +Debes dar al tercer `input` un atributo `name` apropiado. + +```js +assert.isAtLeast(document.querySelectorAll('input')?.[2]?.name?.length, 1); +``` + +Debes dar al primer `input` un atributo `placeholder`. + +```js +assert.notEmpty(document.querySelectorAll('input')?.[0]?.placeholder); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +--fcc-editable-region-- +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +--fcc-editable-region-- +
    +

    HTML

    +
    +
    +

    CSS

    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143920c8eafb00b735746ce.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143920c8eafb00b735746ce.md new file mode 100644 index 00000000000000..ec4f7470b84f77 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143920c8eafb00b735746ce.md @@ -0,0 +1,127 @@ +--- +id: 6143920c8eafb00b735746ce +title: Paso 22 +challengeType: 0 +dashedName: step-22 +--- + +# --description-- + +A pesar de que agregaste un `placeholder` al primer elemento `input` en la lección anterior, actualmente no es la mejor práctica para la accesibilidad; muy a menudo, los usuarios confunden el texto del marcador de posición con un valor de entrada real - creen que ya hay un valor en la entrada. + +Elimina el texto del marcador de posición del primer elemento `input`, confiando en que el `label` es la mejor práctica. + +# --hints-- + +Debes eliminar el atributo `placeholder` del primer elemento `input`. + +```js +assert.isEmpty(document.querySelectorAll('input')?.[0]?.placeholder); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +--fcc-editable-region-- +
    + + +
    +--fcc-editable-region-- +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +
    +

    CSS

    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143931a113bb80c45546287.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143931a113bb80c45546287.md new file mode 100644 index 00000000000000..0bb448144f78a1 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143931a113bb80c45546287.md @@ -0,0 +1,139 @@ +--- +id: 6143931a113bb80c45546287 +title: Paso 23 +challengeType: 0 +dashedName: step-23 +--- + +# --description-- + +Probablemente, `D.O.B.` no es lo suficientemente descriptivo. Esto es especialmente cierto para los usuarios con discapacidad visual. Una forma de evitar este problema, sin tener que agregar texto visible a la etiqueta, es agregando texto que solo pueda leer un lector de pantalla. + +Agrega un elemento `span` con la clase `sr-only` al contenido de texto actual del tercer elemento `label`. + +# --hints-- + +Debes agregar un elemento `span` dentro del tercer elemento `label`. + +```js +assert.exists(document.querySelector('.info:nth-of-type(3) > label > span')); +``` + +Debes dar al elemento `span` una clase `sr-only`. + +```js +assert.equal(document.querySelector('.info:nth-of-type(3) > label > span')?.className, 'sr-only'); +``` + +Debes colocar el `span` después del contenido de texto `D.O.B.`. + +```js +assert.match(document.querySelector('.info:nth-of-type(3) > label')?.innerHTML, /D\.O\.B\. + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +--fcc-editable-region-- +
    + + +
    +--fcc-editable-region-- +
    +
    +

    HTML

    +
    +
    +

    CSS

    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614394fb41985e0d2012a93e.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614394fb41985e0d2012a93e.md new file mode 100644 index 00000000000000..ebb3eeabbe0d1d --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614394fb41985e0d2012a93e.md @@ -0,0 +1,125 @@ +--- +id: 614394fb41985e0d2012a93e +title: Paso 24 +challengeType: 0 +dashedName: step-24 +--- + +# --description-- + +Dentro del elemento `span`, agrega el texto `(Date of Birth)`. + +# --hints-- + +Debes dar al elemento `span` el texto `(Date of Birth)`. + +```js +assert.equal(document.querySelector('.info:nth-of-type(3) > label > span')?.textContent, '(Date of Birth)'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +--fcc-editable-region-- +
    + + +
    +--fcc-editable-region-- +
    +
    +

    HTML

    +
    +
    +

    CSS

    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143956ed76ed60e012faa51.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143956ed76ed60e012faa51.md new file mode 100644 index 00000000000000..52131d6d4952d8 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143956ed76ed60e012faa51.md @@ -0,0 +1,197 @@ +--- +id: 6143956ed76ed60e012faa51 +title: Paso 25 +challengeType: 0 +dashedName: step-25 +--- + +# --description-- + +El texto `.sr-only` todavía es visible. Hay un patrón común para ocultar texto visualmente para que sólo los lectores de pantalla lean. + +Este patrón es establecer las siguientes propiedades de CSS: + +```css +position: absolute; +width: 1px; +height: 1px; +padding: 0; +margin: -1px; +overflow: hidden; +clip: rect(0, 0, 0, 0); +white-space: nowrap; +border: 0; +``` + +Utilice lo anterior para definir la clase `sr-only`. + +# --hints-- + +Tu código debe usar el selector `.sr-only`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('.sr-only')); +``` + +Debes dar al `.sr-only` un `position` de `absolute`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.sr-only')?.position, 'absolute'); +``` + +Debes dar al `.sr-only` un `width` de `1px`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.sr-only')?.width, '1px'); +``` + +Debes dar al `.sr-only` un `height` de `1px`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.sr-only')?.height, '1px'); +``` + +Debes dar al `.sr-only` un `padding` de `0`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.sr-only')?.padding, '0px'); +``` + +Debes dar al `.sr-only` un `margin` de `-1px`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.sr-only')?.margin, '-1px'); +``` + +Debes dar al `.sr-only` un `overflow` de `hidden`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.sr-only')?.overflow, 'hidden'); +``` + +Debes dar al `.sr-only` un `clip` de `rect(0, 0, 0, 0)`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.sr-only')?.clip, 'rect(0px, 0px, 0px, 0px)'); +``` + +Debes dar al `.sr-only` un `white-space` de `nowrap`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.sr-only')?.whiteSpace, 'nowrap'); +``` + +Debes dar al `.sr-only` un `border` de `0`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.sr-only')?.borderWidth, '0px'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +
    +

    CSS

    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614396f7ae83f20ea6f9f4b3.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614396f7ae83f20ea6f9f4b3.md new file mode 100644 index 00000000000000..6a8b2979080229 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614396f7ae83f20ea6f9f4b3.md @@ -0,0 +1,200 @@ +--- +id: 614396f7ae83f20ea6f9f4b3 +title: Paso 26 +challengeType: 0 +dashedName: step-26 +--- + +# --description-- + +Dentro del segundo elemento `section`, agrega dos elementos `div` con la clase `question-block`. + +Luego, dentro de cada elemento `div.question-block`, agrega un elemento `p` con un texto de números incrementales, empezando en `1`, y un elemento `fieldset` con la clase `question`. + +# --hints-- + +Debes anidar dos elementos `div` dentro del segundo elemento `section`. + +```js +assert.equal(document.querySelectorAll('section:nth-of-type(2) > div')?.length, 2); +``` + +Debes dar al primer elemento `div` nuevo una clase `question-block`. + +```js +assert.equal(document.querySelectorAll('section:nth-of-type(2) > div')?.[0]?.className, 'question-block'); +``` + +Debes dar al segundo elemento `div` nuevo una clase `question-block`. + +```js +assert.equal(document.querySelectorAll('section:nth-of-type(2) > div')?.[1]?.className, 'question-block'); +``` + +Debes anidar un elemento `p` dentro de cada elemento `div.question-block`. + +```js +assert.equal(document.querySelectorAll('section:nth-of-type(2) > div.question-block > p')?.length, 2); +``` + +Debes dar al primer elemento `p` un texto de `1`. + +```js +assert.equal(document.querySelectorAll('section:nth-of-type(2) > div.question-block > p')?.[0]?.textContent, '1'); +``` + +Debes dar al segundo elemento `p` un texto de `2`. + +```js +assert.equal(document.querySelectorAll('section:nth-of-type(2) > div.question-block > p')?.[1]?.textContent, '2'); +``` + +Debes anidar un elemento `fieldset` dentro de cada elemento `div.question-block`. + +```js +assert.equal(document.querySelectorAll('section:nth-of-type(2) > div.question-block > fieldset')?.length, 2); +``` + +Debes colocar el primer elemento `fieldset` después del primer elemento `p`. + +```js +assert.exists(document.querySelector('section:nth-of-type(2) > div.question-block > p + fieldset')); +``` + +Debes colocar el segundo elemento `fieldset` después del segundo elemento `p`. + +```js +assert.exists(document.querySelector('section:nth-of-type(2) > div.question-block:nth-of-type(2) > p + fieldset')); +``` + +Debes dar al primer elemento `fieldset` una clase `question`. + +```js +assert.equal(document.querySelectorAll('section:nth-of-type(2) > div.question-block > fieldset')?.[0]?.className, 'question'); +``` + +Debes dar al segundo elemento `fieldset` una clase `question`. + +```js +assert.equal(document.querySelectorAll('section:nth-of-type(2) > div.question-block > fieldset')?.[1]?.className, 'question'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +--fcc-editable-region-- +
    +

    HTML

    + +
    +--fcc-editable-region-- +
    +

    CSS

    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143cb26f7edff2dc28f7da5.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143cb26f7edff2dc28f7da5.md new file mode 100644 index 00000000000000..143c1702a9b560 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143cb26f7edff2dc28f7da5.md @@ -0,0 +1,177 @@ +--- +id: 6143cb26f7edff2dc28f7da5 +title: Paso 27 +challengeType: 0 +dashedName: step-27 +--- + +# --description-- + +Cada `fieldset` contendrá una pregunta true/false. + +Dentro de cada `fieldset`, anida un elemento `legend` y un elemento `ul` con dos opciones. + +# --hints-- + +Anida un elemento `legend` dentro del primer elemento `fieldset`. + +```js +assert.equal(document.querySelectorAll('.question-block:nth-of-type(1) > fieldset > legend')?.length, 1); +``` + +Debes anidar un elemento `ul` dentro del primer elemento `fieldset`. + +```js +assert.equal(document.querySelectorAll('.question-block:nth-of-type(1) > fieldset > ul')?.length, 1); +``` + +Debes anidar dos elementos `li` dentro del primer elemento `ul`. + +```js +assert.equal(document.querySelectorAll('fieldset > ul')?.[0]?.querySelectorAll('li')?.length, 2); +``` + +Debes anidar un elemento `legend` dentro del segundo elemento `fieldset`. + +```js +assert.equal(document.querySelectorAll('.question-block:nth-of-type(2) > fieldset > legend')?.length, 1); +``` + +Debes anidar un elemento `ul` dentro del segundo elemento `fieldset`. + +```js +assert.equal(document.querySelectorAll('.question-block:nth-of-type(2) > fieldset > ul')?.length, 1); +``` + +Anida dos elementos `li` dentro del segundo elemento `ul`. + +```js +assert.equal(document.querySelectorAll('fieldset > ul')?.[1]?.querySelectorAll('li')?.length, 2); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +--fcc-editable-region-- +
    +

    HTML

    +
    +

    1

    +
    +
    +
    +

    2

    +
    +
    +
    +--fcc-editable-region-- +
    +

    CSS

    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6144e818fd5ea704fe56081d.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6144e818fd5ea704fe56081d.md new file mode 100644 index 00000000000000..d2c03862f7baa8 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6144e818fd5ea704fe56081d.md @@ -0,0 +1,195 @@ +--- +id: 6144e818fd5ea704fe56081d +title: Paso 28 +challengeType: 0 +dashedName: step-28 +--- + +# --description-- + +Dale a cada `fieldset` un atributo `name` adecuado. Luego, dale a ambas listas desordenadas un `class` de `answers-list`. + +Por último, usa el `legend` para titular el contenido del `fieldset`, colocando una pregunta de true/false como contenido de texto. + +# --hints-- + +Debes dar al primer `fieldset` un atributo `name` adecuado. _Pista: Yo usaría `html-question-one`_ + +```js +assert.notEmpty(document.querySelectorAll('fieldset')?.[0]?.name); +``` + +Debes dar al segundo `fieldset` un atributo `name` adecuado. _Pista: Yo usaría `html-question-two`_ + +```js +assert.notEmpty(document.querySelectorAll('fieldset')?.[1]?.name); +``` + +Debes dar al primer elemento `ul` un `class` de `answers-list`. + +```js +assert.equal(document.querySelectorAll('fieldset > ul')?.[0]?.className, 'answers-list'); +``` + +Debes dar al segundo elemento `ul` un `class` de `answers-list`. + +```js +assert.equal(document.querySelectorAll('fieldset > ul')?.[1]?.className, 'answers-list'); +``` + +Debes dar al primer elemento `legend` contenido de texto. + +```js +assert.notEmpty(document.querySelectorAll('legend')?.[0]?.textContent); +``` + +Debes dar a segundo elemento `legend` contenido de texto. + +```js +assert.notEmpty(document.querySelectorAll('legend')?.[1]?.textContent); +``` + +No debes usar el mismo contenido de texto para ambos elementos `legend`. + +```js +assert.notEqual(document.querySelectorAll('legend')?.[0]?.textContent, document.querySelectorAll('legend')?.[1]?.textContent); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +--fcc-editable-region-- +
    +

    HTML

    +
    +

    1

    +
    + +
      +
    • +
    • +
    +
    +
    +
    +

    2

    +
    + +
      +
    • +
    • +
    +
    +
    +
    +--fcc-editable-region-- +
    +

    CSS

    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6144f8dc6849e405dd8bb829.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6144f8dc6849e405dd8bb829.md new file mode 100644 index 00000000000000..5eb3587bfefb09 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6144f8dc6849e405dd8bb829.md @@ -0,0 +1,231 @@ +--- +id: 6144f8dc6849e405dd8bb829 +title: Paso 29 +challengeType: 0 +dashedName: step-29 +--- + +# --description-- + +Para proporcionar funcionalidad a las preguntas de true/false, necesitamos un conjunto de entradas que no permitan ser seleccionadas al mimo tiempo. + +Dentro de cada elemento de lista, anida un elemento `label`, y dentro de cada elemento `label`, anida un elemento `input` con un `type` apropiado. + +# --hints-- + +Debes anidar un elemento `label` dentro del primer elemento `li`. + +```js +assert.exists(document.querySelectorAll('ul.answers-list > li')?.[0]?.querySelector('label')); +``` + +Debes anidar un elemento `label` dentro del segundo elemento `li`. + +```js +assert.exists(document.querySelectorAll('ul.answers-list > li')?.[1]?.querySelector('label')); +``` + +Debes anidar un elemento `label` dentro del tercer elemento `li`. + +```js +assert.exists(document.querySelectorAll('ul.answers-list > li')?.[2]?.querySelector('label')); +``` + +Debes anidar un elemento `label` dentro del cuarto elemento `li`. + +```js +assert.exists(document.querySelectorAll('ul.answers-list > li')?.[3]?.querySelector('label')); +``` + +Debes anidar un elemento `input` dentro del primer elemento `label`. + +```js +assert.exists(document.querySelectorAll('ul.answers-list > li')?.[0]?.querySelector('label')?.querySelector('input')); +``` + +Debes anidar un elemento `input` dentro del segundo elemento `label`. + +```js +assert.exists(document.querySelectorAll('ul.answers-list > li')?.[1]?.querySelector('label')?.querySelector('input')); +``` + +Debes anidar un elemento `input` dentro del tercer elemento `label`. + +```js +assert.exists(document.querySelectorAll('ul.answers-list > li')?.[2]?.querySelector('label')?.querySelector('input')); +``` + +Debes anidar un elemenot `input` dentro del cuarto elemento `label`. + +```js +assert.exists(document.querySelectorAll('ul.answers-list > li')?.[3]?.querySelector('label')?.querySelector('input')); +``` + +Debes dar al primer `input` un `type` de `radio`. + +```js +assert.equal(document.querySelectorAll('ul.answers-list > li > label > input')?.[0]?.type, 'radio'); +``` + +Debes dar al segundo `input` un `type` de `radio`. + +```js +assert.equal(document.querySelectorAll('ul.answers-list > li > label > input')?.[1]?.type, 'radio'); +``` + +Debes dar al tercer `input` un `type` de `radio`. + +```js +assert.equal(document.querySelectorAll('ul.answers-list > li > label > input')?.[2]?.type, 'radio'); +``` + +Debes dar al cuarto `input` un `type` de `radio`. + +```js +assert.equal(document.querySelectorAll('ul.answers-list > li > label > input')?.[3]?.type, 'radio'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +--fcc-editable-region-- +
      +
    • +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • +
    • +
    +--fcc-editable-region-- +
    +
    +
    +
    +

    CSS

    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145e6eeaa66c605eb087fe9.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145e6eeaa66c605eb087fe9.md new file mode 100644 index 00000000000000..6a813c33fe1b23 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145e6eeaa66c605eb087fe9.md @@ -0,0 +1,207 @@ +--- +id: 6145e6eeaa66c605eb087fe9 +title: Paso 30 +challengeType: 0 +dashedName: step-30 +--- + +# --description-- + +Aunque no es necesario para elementos `label` con un `input` anidado, sigue siendo una buena práctica vincular explícitamente un `label` con su elemento `input` correspondiente. + +Vincula los elementos `label` con sus elementos `input` correspondientes. + +# --hints-- + +Debes dar al primer `label` un atributo `for` que coincida con el `id` de su elemento `input`. + +```js +const htmlFor = document.querySelectorAll('ul.answers-list > li > label')?.[0]?.htmlFor; +assert.notEmpty(htmlFor); +assert.equal(htmlFor, document.querySelectorAll('ul.answers-list > li > label > input')?.[0]?.id); +``` + +Debes dar al segundo `label` un atributo `for` que coincida con el `id` de su elemento `input`. + +```js +const htmlFor = document.querySelectorAll('ul.answers-list > li > label')?.[1]?.htmlFor; +assert.notEmpty(htmlFor); +assert.equal(htmlFor, document.querySelectorAll('ul.answers-list > li > label > input')?.[1]?.id); +``` + +Debes dar al tercer `label` un atributo `for` que coincida con el `id` de su elemento `input`. + +```js +const htmlFor = document.querySelectorAll('ul.answers-list > li > label')?.[2]?.htmlFor; +assert.notEmpty(htmlFor); +assert.equal(htmlFor, document.querySelectorAll('ul.answers-list > li > label > input')?.[2]?.id); +``` + +Debes dar al cuarto `label` un atributo `for` que coincida con el `id` de su elemento `input`. + +```js +const htmlFor = document.querySelectorAll('ul.answers-list > li > label')?.[3]?.htmlFor; +assert.notEmpty(htmlFor); +assert.equal(htmlFor, document.querySelectorAll('ul.answers-list > li > label > input')?.[3]?.id); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +--fcc-editable-region-- +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +--fcc-editable-region-- +
    +
    +
    +
    +

    CSS

    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145e8b5080a5f06bb0223d0.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145e8b5080a5f06bb0223d0.md new file mode 100644 index 00000000000000..1922c1d297ceea --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145e8b5080a5f06bb0223d0.md @@ -0,0 +1,287 @@ +--- +id: 6145e8b5080a5f06bb0223d0 +title: Paso 31 +challengeType: 0 +dashedName: step-31 +--- + +# --description-- + +Provee a los elementos `label` texto de tal manera que el `input` este antes del texto. A continuación, dale a los elementos `input` un `value` que coincida con el texto. + +El texto debe ser `True` o `False`. + +# --hints-- + +Debes dar al primer elemento `label` contenido de texto. + +```js +assert.notEmpty(document.querySelectorAll('ul.answers-list > li > label')?.[0]?.textContent?.trim()); +``` + +Debes dar al segundo elemento `label` contenido de texto. + +```js +assert.notEmpty(document.querySelectorAll('ul.answers-list > li > label')?.[1]?.textContent?.trim()); +``` + +Debes dar al tercer elemento `label` contenido de texto. + +```js +assert.notEmpty(document.querySelectorAll('ul.answers-list > li > label')?.[2]?.textContent?.trim()); +``` + +Debes dar al cuarto elemento `label` contenido de texto. + +```js +assert.notEmpty(document.querySelectorAll('ul.answers-list > li > label')?.[3]?.textContent?.trim()); +``` + +Debes colocar el contenido de texto del primer `label` después del elemento `input`. + +```js +assert.match(document.querySelectorAll('ul.answers-list > li > label')?.[0]?.innerHTML, />[\s\S]+[a-zA-Z]/); +``` + +Debes colocar el contenido de texto del segundo `label` después del elemento `input`. + +```js +assert.match(document.querySelectorAll('ul.answers-list > li > label')?.[1]?.innerHTML, />[\s\S]+[a-zA-Z]/); +``` + +Debes colocar el contenido de texto del tercer `label` después del elemento `input`. + +```js +assert.match(document.querySelectorAll('ul.answers-list > li > label')?.[2]?.innerHTML, />[\s\S]+[a-zA-Z]/); +``` + +Debes colocar el contenido de texto del cuarto `label` después del elemento `input`. + +```js +assert.match(document.querySelectorAll('ul.answers-list > li > label')?.[3]?.innerHTML, />[\s\S]+[a-zA-Z]/); +``` + +Debes dar al primer `label` el texto `True` o `False`. + +```js +assert.include(['True', 'False'], document.querySelectorAll('ul.answers-list > li > label')?.[0]?.textContent?.trim()); +``` + +Debes dar al segundo `label` el texto `True`. + +```js +const l = (n) => document.querySelectorAll('ul.answers-list > li > label')?.[n]?.textContent?.trim(); +assert(l(0) === 'False' ? l(1) === 'True' : true); +``` + +Debes dar al segundo `label` el texto `False`. + +```js +const l = (n) => document.querySelectorAll('ul.answers-list > li > label')?.[n]?.textContent?.trim(); +assert(l(0) === 'True' ? l(1) === 'False' : true); +``` + +Debes dar al tercer `label` el texto `True` o `False`. + +```js +assert.include(['True', 'False'], document.querySelectorAll('ul.answers-list > li > label')?.[2]?.textContent?.trim()); +``` + +Debes dar al cuarto `label` el texto `True`. + +```js +const l = (n) => document.querySelectorAll('ul.answers-list > li > label')?.[n]?.textContent?.trim(); +assert(l(2) === 'False' ? l(3) === 'True' : true); +``` + +Debes dar al cuarto `label` el texto`False`. + +```js +const l = (n) => document.querySelectorAll('ul.answers-list > li > label')?.[n]?.textContent?.trim(); +assert(l(2) === 'True' ? l(3) === 'False' : true); +``` + +Debes dar al primer `input` un `value` que coincida con el contenido de texto del `label`. + +```js +assert.equal(document.querySelectorAll('ul.answers-list > li > label')?.[0]?.textContent?.trim()?.toLowerCase(), document.querySelectorAll('ul.answers-list > li > label > input')?.[0]?.value?.toLowerCase()); +``` + +Debes dar al segundo `input` un `value` que coincida con el contenido de texto del `label`. + +```js +assert.equal(document.querySelectorAll('ul.answers-list > li > label')?.[1]?.textContent?.trim()?.toLowerCase(), document.querySelectorAll('ul.answers-list > li > label > input')?.[1]?.value?.toLowerCase()); +``` + +Debes dar al tercer `input` un `value` que coincida con el contenido de texto del `label`. + +```js +assert.equal(document.querySelectorAll('ul.answers-list > li > label')?.[2]?.textContent?.trim()?.toLowerCase(), document.querySelectorAll('ul.answers-list > li > label > input')?.[2]?.value?.toLowerCase()); +``` + +Debes dar al cuarto `input` un `value` que coincida con el contenido de texto del `label`. + +```js +assert.equal(document.querySelectorAll('ul.answers-list > li > label')?.[3]?.textContent?.trim()?.toLowerCase(), document.querySelectorAll('ul.answers-list > li > label > input')?.[3]?.value?.toLowerCase()); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +--fcc-editable-region-- +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +--fcc-editable-region-- +
    +
    +
    +
    +

    CSS

    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145eb5f08a38a0786c7a80c.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145eb5f08a38a0786c7a80c.md new file mode 100644 index 00000000000000..1d5412f116e2d5 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145eb5f08a38a0786c7a80c.md @@ -0,0 +1,224 @@ +--- +id: 6145eb5f08a38a0786c7a80c +title: Paso 32 +challengeType: 0 +dashedName: step-32 +--- + +# --description-- + +Si hace clic en las entradas de radio, notara que ambas entradas dentro del mismo grupo de campos true/false pueden seleccionarse al mismo tiempo. + +Agrupe las entradas relevantes de tal forma que solo se pueda seleccionar una entrada de un par a la vez. + +# --hints-- + +Debes dar al primer `input` un atributo `name`. + +```js +assert.notEmpty(document.querySelectorAll('ul.answers-list > li > label > input')?.[0]?.name); +``` + +Debes dar al segundo `input` un atributo `name`. + +```js +assert.notEmpty(document.querySelectorAll('ul.answers-list > li > label > input')?.[1]?.name); +``` + +Debes dar al tercer `input` un atributo `name`. + +```js +assert.notEmpty(document.querySelectorAll('ul.answers-list > li > label > input')?.[2]?.name); +``` + +Debes dar al cuarto `input` un atributo `name`. + +```js +assert.notEmpty(document.querySelectorAll('ul.answers-list > li > label > input')?.[3]?.name); +``` + +Debes dar al segundo `input` un atributo `name` que coincida con el atributo `name` del primer `input`. + +```js +const i = (n) => document.querySelectorAll('ul.answers-list > li > label > input')?.[n]?.name; +assert.equal(i(1), i(0)); +``` + +Debes dar al cuarto `input` un atributo `name` que coincida con el atributo `name` del tercer `input`. + +```js +const i = (n) => document.querySelectorAll('ul.answers-list > li > label > input')?.[n]?.name; +assert.equal(i(3), i(2)); +``` + +Debes dar diferentes atributos `name` al primer `input` y tercer `input`. + +```js +const i = (n) => document.querySelectorAll('ul.answers-list > li > label > input')?.[n]?.name; +assert.notEqual(i(0), i(2)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +--fcc-editable-region-- +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +--fcc-editable-region-- +
    +
    +
    +
    +

    CSS

    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145ed1f22caab087630aaad.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145ed1f22caab087630aaad.md new file mode 100644 index 00000000000000..3d80a02c192669 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145ed1f22caab087630aaad.md @@ -0,0 +1,191 @@ +--- +id: 6145ed1f22caab087630aaad +title: Paso 33 +challengeType: 0 +dashedName: step-33 +--- + +# --description-- + +Para prevenir la repetición innecesaria, apunta al pseudoelemento `before` del elemento `p`, y dale una propiedad `content` de `"Question #"`. + +# --hints-- + +Debes usar el selector `p::before`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('p::before')); +``` + +Debes dar al pseudoelemento `p::before` una propiedad `content` de `"Question #"`. + +```js +assert.include(new __helpers.CSSHelp(document).getStyle('p::before')?.content, 'Question #'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145ee65e2e1530938cb594d.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145ee65e2e1530938cb594d.md new file mode 100644 index 00000000000000..9be5a0396e4567 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145ee65e2e1530938cb594d.md @@ -0,0 +1,232 @@ +--- +id: 6145ee65e2e1530938cb594d +title: Paso 34 +challengeType: 0 +dashedName: step-34 +--- + +# --description-- + +La sección final de este cuestionario contendrá un desplegable y un cuadro de texto. + +Empieza anidando un `div` con un `class` de `formrow`, y anida cuatro elementos `div` dentro, alternando sus atributos `class` con `question-block` y `answer`. + +# --hints-- + +Debes agregar un elemento `div` dentro del último `section`. + +```js +assert.exists(document.querySelector('section:nth-of-type(3) > div')); +``` + +Debes dar al primer `div` un `class` de `formrow`. + +```js +assert.equal(document.querySelector('section:nth-of-type(3) > div')?.className, 'formrow'); +``` + +Debes colocar el `div.formrow` después del elemento `h2`. + +```js +assert.exists(document.querySelector('section:nth-of-type(3) > h2 + div.formrow')); +``` + +Debes anidar cuatro elementos `div` dentro del `div.formrow`. + +```js +assert.equal(document.querySelectorAll('section:nth-of-type(3) > div.formrow > div')?.length, 4); +``` + +Debes dar al primer `div` anidado un `class` de `question-block`. + +```js +assert.equal(document.querySelector('section:nth-of-type(3) > div.formrow > div:nth-of-type(1)')?.className, 'question-block'); +``` + +Debes dar al segundo `div` anidado un `class` de `answer`. + +```js +assert.equal(document.querySelector('section:nth-of-type(3) > div.formrow > div:nth-of-type(2)')?.className, 'answer'); +``` + +Debes dar al tercer `div` anidado un `class` de `question-block`. + +```js +assert.equal(document.querySelector('section:nth-of-type(3) > div.formrow > div:nth-of-type(3)')?.className, 'question-block'); +``` + +Debes dar al cuarto `div` anidado un `class` de `answer`. + +```js +assert.equal(document.querySelector('section:nth-of-type(3) > div.formrow > div:nth-of-type(4)')?.className, 'answer'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +--fcc-editable-region-- +
    +

    CSS

    + +
    +--fcc-editable-region-- +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f02240ff8f09f7ec913c.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f02240ff8f09f7ec913c.md new file mode 100644 index 00000000000000..a0dc151d3b669a --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f02240ff8f09f7ec913c.md @@ -0,0 +1,215 @@ +--- +id: 6145f02240ff8f09f7ec913c +title: Paso 35 +challengeType: 0 +dashedName: step-35 +--- + +# --description-- + +Dentro de los elementos `div.question-block`, anide un elemento `label` y dele contenido de texto. + +# --hints-- + +Debes anidar un elemento `label` dentro del primer elemento `div.question-block`. + +```js +assert.exists(document.querySelectorAll('.formrow > .question-block')?.[0]?.querySelector('label')); +``` + +Debes anidar un elemento `label` dentro del segundo elemento `div.question-block`. + +```js +assert.exists(document.querySelectorAll('.formrow > .question-block')?.[1]?.querySelector('label')); +``` + +Debes dar al primer elemento `label` contenido de texto. + +```js +assert.isAtLeast(document.querySelectorAll('.formrow > .question-block')?.[0]?.querySelector('label')?.textContent?.length, 1); +``` + +Debes dar al segundo elemento `label` contenido de texto. + +```js +assert.isAtLeast(document.querySelectorAll('.formrow > .question-block')?.[1]?.querySelector('label')?.textContent?.length, 1); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +--fcc-editable-region-- +
    +

    CSS

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +--fcc-editable-region-- +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f14f019a4b0adb94b051.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f14f019a4b0adb94b051.md new file mode 100644 index 00000000000000..f074c99c0e5dce --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f14f019a4b0adb94b051.md @@ -0,0 +1,250 @@ +--- +id: 6145f14f019a4b0adb94b051 +title: Paso 36 +challengeType: 0 +dashedName: step-36 +--- + +# --description-- + +Dentro del primer elemento `div.answer`, anida un elemento `select` requerido con tres elementos `option`. + +Dale al elemento `option` un `value` de `""` y el texto `Select an option`. Dale al segundo elemento `option` un `value` de `yes` y el texto `Yes`. Dale al tercer elemento `option` un elemento `value` de `no` y el texto `No`. + +# --hints-- + +Debes anidar un elemento `select` dentro del primer elemento `div.answer`. + +```js +assert.exists(document.querySelector('div.answer > select')); +``` + +Debes anidar tres elementos `option` dentro del elemento `select`. + +```js +assert.equal(document.querySelectorAll('div.answer > select > option')?.length, 3); +``` + +Debes dar al primer elemento `option` un `value` de `""`. + +```js +assert.equal(document.querySelector('div.answer > select > option:nth-child(1)')?.value, ''); +``` + +Debes dar al primer elemento `option` un contenido de texto de `Select an option`. + +```js +assert.equal(document.querySelector('div.answer > select > option:nth-child(1)')?.textContent, 'Select an option'); +``` + +Debes dar al segundo elemento `option` un `value` de `yes`. + +```js +assert.equal(document.querySelector('div.answer > select > option:nth-child(2)')?.value, 'yes'); +``` + +Debes dar al segundo elemento `option` un contenido de texto de `Yes`. + +```js +assert.equal(document.querySelector('div.answer > select > option:nth-child(2)')?.textContent, 'Yes'); +``` + +Debes dar al tercer elemento `option` un `value` de `no`. + +```js +assert.equal(document.querySelector('div.answer > select > option:nth-child(3)')?.value, 'no'); +``` + +Debes dar al tercer elemento `option` un contenido de texto de `No`. + +```js +assert.equal(document.querySelector('div.answer > select > option:nth-child(3)')?.textContent, 'No'); +``` + +Debes dar al `select` un atributo `required`. + +```js +assert.isTrue(document.querySelector('div.answer > select')?.required); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +--fcc-editable-region-- +
    + +
    +--fcc-editable-region-- +
    + +
    +
    +
    +
    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f3a5cd9be60b9459cdd6.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f3a5cd9be60b9459cdd6.md new file mode 100644 index 00000000000000..2d61a60c036cc2 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f3a5cd9be60b9459cdd6.md @@ -0,0 +1,222 @@ +--- +id: 6145f3a5cd9be60b9459cdd6 +title: Paso 37 +challengeType: 0 +dashedName: step-37 +--- + +# --description-- + +Enlace el primer elemento `label` al elemento `select`, y dale al elemento `select` un atributo `name`. + +# --hints-- + +Dale al elemento `label` un atributo `for`. + +```js +assert.notEmpty(document.querySelector('.question-block > label')?.htmlFor); +``` + +Dale al elemento `select` un atributo `id`. + +```js +assert.notEmpty(document.querySelector('.answer > select')?.id); +``` + +Debes dar al elemento `select` un `id` que coincida con el atributo `for` del elemento `label`. + +```js +assert.equal(document.querySelector('.answer > select')?.id, document.querySelector('.question-block > label')?.htmlFor); +``` + +Debes dar al elemento `select` un atributo `name`. + +```js +assert.notEmpty(document.querySelector('.answer > select')?.name); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +--fcc-editable-region-- +
    + +
    +
    + +
    +--fcc-editable-region-- +
    + +
    +
    +
    +
    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f47393fbe70c4d885f9c.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f47393fbe70c4d885f9c.md new file mode 100644 index 00000000000000..1d4d62068df676 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f47393fbe70c4d885f9c.md @@ -0,0 +1,229 @@ +--- +id: 6145f47393fbe70c4d885f9c +title: Paso 38 +challengeType: 0 +dashedName: step-38 +--- + +# --description-- + +Anida un elemento `textarea` dentro del segundo elemento `div.answer`, y establece el número de filas y columnas que tiene. + +Luego, dale al `textarea` un texto de marcador de posición que describa un ejemplo de respuesta. + +# --hints-- + +Debes anidar un elemento `textarea` dentro del segundo elemento `div.answer`. + +```js +assert.exists(document.querySelectorAll('div.answer')?.[1]?.querySelector('textarea')); +``` + +Debes dar al `textarea` un atributo `rows` con un número. + +```js +const rows = document.querySelectorAll('div.answer')?.[1]?.querySelector('textarea')?.getAttribute('rows'); +assert.notEmpty(rows); +assert.isNotNaN(Number(rows)); +``` + +Debes dar al `textarea` un atributo `cols` con un número. + +```js +const cols = document.querySelectorAll('div.answer')?.[1]?.querySelector('textarea')?.getAttribute('cols'); +assert.notEmpty(cols); +assert.isNotNaN(Number(cols)); +``` + +Debes dar al `textarea` un atributo `placeholder` con un texto que describa un ejemplo de respuesta. + +```js +assert.notEmpty(document.querySelectorAll('div.answer')?.[1]?.querySelector('textarea')?.getAttribute('placeholder')); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +--fcc-editable-region-- +
    + +
    +--fcc-editable-region-- +
    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f59029474c0d3dc1c8b8.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f59029474c0d3dc1c8b8.md new file mode 100644 index 00000000000000..8fa2d1328a9e5e --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f59029474c0d3dc1c8b8.md @@ -0,0 +1,217 @@ +--- +id: 6145f59029474c0d3dc1c8b8 +title: Paso 39 +challengeType: 0 +dashedName: step-39 +--- + +# --description-- + +Al igual que los otros elementos `input` y `label`, enlace el `textarea` con su elemento `label` correspondiente, y dale un atributo `name`. + +# --hints-- + +Debes dar al elemento `label` un atributo `for`. + +```js +assert.notEmpty(document.querySelectorAll('.formrow > .question-block')?.[1]?.querySelector('label')?.htmlFor); +``` + +Debes dar al elemento `textarea` un atributo `id` que coincida con el atributo `for` del elemento `label`. + +```js +assert.equal(document.querySelectorAll('.formrow > .question-block')?.[1]?.querySelector('label')?.htmlFor, document.querySelectorAll('.answer')?.[1]?.querySelector('textarea')?.id); +``` + +Debes dar al elemento `textarea` un atributo `name`. + +```js +assert.notEmpty(document.querySelectorAll('.answer')?.[1]?.querySelector('textarea')?.name); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +--fcc-editable-region-- +
    + +
    +
    + +
    +--fcc-editable-region-- +
    +
    +
    +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f685797bd30df9784e8c.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f685797bd30df9784e8c.md new file mode 100644 index 00000000000000..8098f049eb0f3a --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f685797bd30df9784e8c.md @@ -0,0 +1,230 @@ +--- +id: 6145f685797bd30df9784e8c +title: Paso 40 +challengeType: 0 +dashedName: step-40 +--- + +# --description-- + +No olvide dar a su `form` un botón de envió. + +# --hints-- + +Debes agregar un elemento `button` o `input`. + +```js +assert.exists(document.querySelector('button') || document.querySelector('main > input') || document.querySelector('form > input')); +``` + +Debes colocar el botón de envío dentro del elemento `form`. + +```js +assert.exists(document.querySelector('form > button') || document.querySelector('form > input')); +``` + +Debes colocar el botón de envío después del último elemento `section`. + +```js +assert.exists(document.querySelector('section:last-of-type + button') || document.querySelector('section:last-of-type + input')); +``` + +Debes dar al botón de envío un `type` de `submit`. + +```js +assert.exists(document.querySelector('button[type="submit"]') || document.querySelector('form > input[type="submit"]')); +``` + +El botón de envío debe mostrar el texto `Submit`. + +```js +assert.equal(document.querySelector('button[type="submit"]')?.textContent ?? document.querySelector('input[type="submit"]')?.value, 'Submit'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +--fcc-editable-region-- +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +--fcc-editable-region-- +
    + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f829ac6a920ebf5797d7.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f829ac6a920ebf5797d7.md new file mode 100644 index 00000000000000..5f24c358f1656e --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f829ac6a920ebf5797d7.md @@ -0,0 +1,215 @@ +--- +id: 6145f829ac6a920ebf5797d7 +title: Paso 41 +challengeType: 0 +dashedName: step-41 +--- + +# --description-- + +Los dos últimos elementos HTML semánticos para este proyecto son `footer` y `address`. El elemento `footer` es un contenedor para una colección de contenidos relacionados de la página, y el elemento `address` es un contenedor para la información de contacto del autor de página. + +Después del elemento `main`, agrega un elemento `footer`, y anida un elemento `address` dentro de él. + +# --hints-- + +Debes agregar un elemento `footer` después del elemento `main`. + +```js +assert.exists(document.querySelector('main + footer')); +``` + +Debes anidar un elemento `address` dentro del elemento `footer`. + +```js +assert.exists(document.querySelector('footer > address')); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +--fcc-editable-region-- + +--fcc-editable-region-- + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f8f8bcd4370f6509078e.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f8f8bcd4370f6509078e.md new file mode 100644 index 00000000000000..d8ceac3517743b --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f8f8bcd4370f6509078e.md @@ -0,0 +1,220 @@ +--- +id: 6145f8f8bcd4370f6509078e +title: Paso 42 +challengeType: 0 +dashedName: step-42 +--- + +# --description-- + +Dentro del elemento `address`, agrega lo siguiente: + +```html +freeCodeCamp
    +San Francisco
    +California
    +USA +``` + +Puedes visitarlo, pero puede que no encuentres nada... + +# --hints-- + +Debes agregar el texto de arriba incluyendo las etiquetas `
    ` en el elemento `address`. + +```js +assert.equal(document.querySelector('address')?.innerText, 'freeCodeCamp\nSan Francisco\nCalifornia\nUSA'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +--fcc-editable-region-- +
    +
    + +
    +
    +--fcc-editable-region-- + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145fb5018cb5b100cb2a88c.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145fb5018cb5b100cb2a88c.md new file mode 100644 index 00000000000000..75d555b6778c75 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145fb5018cb5b100cb2a88c.md @@ -0,0 +1,229 @@ +--- +id: 6145fb5018cb5b100cb2a88c +title: Paso 43 +challengeType: 0 +dashedName: step-43 +--- + +# --description-- + +El elemento `address` no tiene por qué contener una ubicación geográfica física. Puede usarse para proporcionar un enlace hacia el tema. + +Envuelve un enlace alrededor del texto `freeCodeCamp`, y establece su ubicación hacia `https://freecodecamp.org`. + +# --hints-- + +Debes agregar un elemento `a`. + +```js +assert.exists(document.querySelector('address > a')); +``` + +Debes dar al elemento `a` un atributo `href` de `https://freecodecamp.org`. + +```js +assert.equal(document.querySelector('address > a')?.getAttribute('href'), 'https://freecodecamp.org'); +``` + +Debes envolver el elemento `a` alrededor del texto existente `freeCodeCamp`. + +```js +assert.equal(document.querySelector('address > a')?.innerHTML, 'freeCodeCamp'); +assert.equal(document.querySelector('address')?.innerHTML?.match(/freeCodeCamp/g)?.length, 1); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +--fcc-editable-region-- +
    +
    + freeCodeCamp
    + San Francisco
    + California
    + USA +
    +
    +--fcc-editable-region-- + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145fc3707fc3310c277f5c8.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145fc3707fc3310c277f5c8.md new file mode 100644 index 00000000000000..e2f0565b086a46 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145fc3707fc3310c277f5c8.md @@ -0,0 +1,256 @@ +--- +id: 6145fc3707fc3310c277f5c8 +title: Paso 44 +challengeType: 0 +dashedName: step-44 +--- + +# --description-- + +Volvemos a estilizar la página. Selecciona los elementos de lista dentro de la barra de navegación, y dales los siguientes estilos: + +```css +color: #dfdfe2; +margin: 0 0.2rem; +padding: 0.2rem; +display: block; +``` + +# --hints-- + +Debes usar el selector `nav li` o el `nav > ul > li`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s); +assert.exists(gs('nav li') || gs('nav > ul > li')); +``` + +Debes dar a los elementos `li` un `color` de `#dfdfe2`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s); +const color = gs('nav li')?.color ?? gs('nav > ul > li')?.color; +assert.equal(color, 'rgb(223, 223, 226)'); +``` + +Debes dar a los elementos `li` un `margin` de `0 0.2rem`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s); +const margin = gs('nav li')?.margin ?? gs('nav > ul > li')?.margin; +assert.equal(margin, '0px 0.2rem'); +``` + +Debes dar a los elementos `li` un `padding` de `0.2rem`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s); +const padding = gs('nav li')?.padding ?? gs('nav > ul > li')?.padding; +assert.equal(padding, '0.2rem'); +``` + +Debes dar a los elementos `li` un `display` de `block`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s); +const display = gs('nav li')?.display ?? gs('nav > ul > li')?.display; +assert.equal(display, 'block'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614796cb8086be482d60e0ac.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614796cb8086be482d60e0ac.md new file mode 100644 index 00000000000000..7f7a7af4ef89d2 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614796cb8086be482d60e0ac.md @@ -0,0 +1,260 @@ +--- +id: 614796cb8086be482d60e0ac +title: Paso 45 +challengeType: 0 +dashedName: step-45 +--- + +# --description-- + +En el tema de la accesibilidad visual, el contraste entre elementos es un factor clave. Por ejemplo, el contraste entre el texto y el fondo de un encabezado debe ser de al menos 4.5:1. + +Cambia el color de la fuente de todos los elementos de anclaje dentro de los elementos de lista, a algo con una relación de contraste de al menos 7:1. + +# --hints-- + +Debes usar el selector `li > a`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('li > a')); +``` + +Debes dar al elemento `a` una propiedad `color`. + +```js +assert.notEmpty(new __helpers.CSSHelp(document).getStyle('li > a')?.color); +``` + +Debes dar a la propiedad `color` un contraste con el fondo de al menos 7:1. _Pista: Yo usaría `#dfdfe2`_ + +```js +function luminance(r, g, b) { + const a = [r, g, b].map((v) => { + v /= 255; + return v <= 0.03928 ? v / 12.92 : Math.pow( (v + 0.055) / 1.055, 2.4 ); + }); + return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722; +} +function contrast(rgb1, rgb2) { + const lum1 = luminance(rgb1[0], rgb1[1], rgb1[2]); + const lum2 = luminance(rgb2[0], rgb2[1], rgb2[2]); + const brightest = Math.max(lum1, lum2); + const darkest = Math.min(lum1, lum2); + return (brightest + 0.05) + / (darkest + 0.05); +} +const backgroundColour = [27, 27, 50]; + +for (let elem of document.querySelectorAll('li > a')) { + const a = getComputedStyle(elem)?.color; + const rgbA = a?.match(/(\d+),\s(\d+),\s(\d+)/); + const aColour = [rgbA[1], rgbA[2], rgbA[3]]; + assert.isAtLeast(contrast(backgroundColour, aColour), 7); +} +``` + + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6147a14ef5668b5881ef2297.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6147a14ef5668b5881ef2297.md new file mode 100644 index 00000000000000..ae759ca65f6e40 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6147a14ef5668b5881ef2297.md @@ -0,0 +1,260 @@ +--- +id: 6147a14ef5668b5881ef2297 +title: Paso 46 +challengeType: 0 +dashedName: step-46 +--- + +# --description-- + +Para hacer que los botones de navegación se parezcan más a los botones típicos, elimine el subrayado de las etiquetas de anclaje. + +Luego, cree un selector que apunte a los elementos de lista de navegación para que cuando el cursor pase sobre ellos, el color de fondo y el color del texto son cambiados, y el cursor se convierte en un puntero. + +# --hints-- + +Debes usar el selector `li > a` existente para establecer `text-decoration` a `none`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('li > a')?.textDecoration, 'none'); +``` + +Debes usar el selector `nav > ul > li:hover` o el `nav li:hover` para estilizar los elementos al pasar por encima de ellos. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s); +assert.exists(gs('nav > ul > li:hover') || gs('nav li:hover')); +``` + +Debes dar a los elementos `li` que son sobrevolados un `background-color` de `#dfdfe2`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s); +const bgColor = gs('nav > ul > li:hover')?.backgroundColor ?? gs('nav li:hover')?.backgroundColor; +assert.equal(bgColor, 'rgb(223, 223, 226)'); +``` + +Debes dar a los elementos `li` que son sobrevolados un `color` de `#1b1b32`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s); +const color = gs('nav > ul > li:hover')?.color ?? gs('nav li:hover')?.color; +assert.equal(color, 'rgb(27, 27, 50)'); +``` + +Debes dar a los elementos `li` que son sobrevolados un `cursor` de `pointer`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s); +const cursor = gs('nav > ul > li:hover')?.cursor ?? gs('nav li:hover')?.cursor; +assert.equal(cursor, 'pointer'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +--fcc-editable-region-- + + +li > a { + color: inherit; +} +--fcc-editable-region-- + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614878f7a412310647873015.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614878f7a412310647873015.md new file mode 100644 index 00000000000000..45bb5e35123b37 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614878f7a412310647873015.md @@ -0,0 +1,253 @@ +--- +id: 614878f7a412310647873015 +title: Paso 47 +challengeType: 0 +dashedName: step-47 +--- + +# --description-- + +Ordena el `header`, usando _Flexbox_ para colocar espacio entre los hijos y centrarlos verticalmente. + +Luego, fija el `header` en la parte superior de la ventana gráfica. + +# --hints-- + +Debes dar al `header` un `justify-content` de `space-between`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('header')?.justifyContent, 'space-between'); +``` + +Debes dar al `header` un `align-items` de `center`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('header')?.alignItems, 'center'); +``` + +Debes dar al `header` un `position` de `fixed`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('header')?.position, 'fixed'); +``` + +Debes dar al `header` un `top` de `0`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('header')?.top, '0px'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +--fcc-editable-region-- +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + +} +--fcc-editable-region-- + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61487b77d4a37707073a64e5.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61487b77d4a37707073a64e5.md new file mode 100644 index 00000000000000..6be6e7ddf250a6 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61487b77d4a37707073a64e5.md @@ -0,0 +1,261 @@ +--- +id: 61487b77d4a37707073a64e5 +title: Paso 48 +challengeType: 0 +dashedName: step-48 +--- + +# --description-- + +Cuando el ancho de la pantalla es pequeño, el `h1` no envuelve su contenido de texto como debería. Alinee el texto del elemento `h1` en el centro. + +Luego, da al `main` un relleno de tal manera que el encabezado de la sección `Student Info` pueda ser completamente visto. + +# --hints-- + +Debes dar al `h1` un `text-align` de `center`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('h1')?.textAlign, 'center'); +``` + +Debes agregar un selector `main` que apunte al elemento `main`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('main')); +``` + +Debes dar al `main` un `padding-top` de al menos `25px`. + +```js +assert.isAtLeast(Number(new __helpers.CSSHelp(document).getStyle('main')?.paddingTop?.replace(/\D+/, '')), 25); +``` + +Solo debes cambiar el valor del `padding-top`. + +```js +assert.isEmpty(new __helpers.CSSHelp(document).getStyle('main')?.paddingBottom); +assert.isEmpty(new __helpers.CSSHelp(document).getStyle('main')?.paddingLeft); +assert.isEmpty(new __helpers.CSSHelp(document).getStyle('main')?.paddingRight); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +--fcc-editable-region-- +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + +} + + +--fcc-editable-region-- + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61487da611a65307e78d2c20.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61487da611a65307e78d2c20.md new file mode 100644 index 00000000000000..23ded356cd49d8 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61487da611a65307e78d2c20.md @@ -0,0 +1,275 @@ +--- +id: 61487da611a65307e78d2c20 +title: Paso 49 +challengeType: 0 +dashedName: step-49 +--- + +# --description-- + +En pantallas pequeñas, la lista desordenada en la barra de navegación desborda el lado derecho de la pantalla. + +Soluciona esto usando _Flexbox_ para envolver el contenido de `ul`. Luego, establezca las siguientes propiedades CSS para alinear correctamente el texto: + +```css +align-items: center; +padding-inline-start: 0; +margin-block: 0; +height: 100%; +``` + +# --hints-- + +Debes dar al `ul` un `flex-wrap` de `wrap`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('nav > ul')?.flexWrap, 'wrap'); +``` + +Debes dar al `ul` un `align-items` de `center`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('nav > ul')?.alignItems, 'center'); +``` + +Debes dar al `ul` un `padding-inline-start` de `0`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('nav > ul')?.paddingInlineStart, '0px'); +``` + +Debes dar al `ul` un `margin-block` de `0`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('nav > ul')?.marginBlock, '0px'); +``` + +Debes dar al `ul` un `height` de `100%`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('nav > ul')?.height, '100%'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +--fcc-editable-region-- +nav > ul { + display: flex; + justify-content: space-evenly; + +} +--fcc-editable-region-- + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61487f703571b60899055cf9.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61487f703571b60899055cf9.md new file mode 100644 index 00000000000000..b04638483f7aee --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61487f703571b60899055cf9.md @@ -0,0 +1,287 @@ +--- +id: 61487f703571b60899055cf9 +title: Paso 50 +challengeType: 0 +dashedName: step-50 +--- + +# --description-- + +Establece el ancho de los elementos `section` al `80%` de su contenedor padre. Luego, utilice los margenes para centar los elementos `section`, agregando `10px` al margen inferior. + +Además, asegúrese de que los elementos `section` no puedan tener más de `600px` de ancho. + +# --hints-- + +Debes usar un selector `section`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('section')); +``` + +Debes dar al `section` un `width` de `80%`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('section')?.width, '80%'); +``` + +Debes dar al `section` un `margin-top` de `0`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('section')?.marginTop, '0px'); +``` + +Debes dar al `section` un `margin-right` de `auto`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('section')?.marginRight, 'auto'); +``` + +Debes dar al `section` un `margin-bottom` de `10px`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('section')?.marginBottom, '10px'); +``` + +Debes dar al `section` un `margin-left` de `auto`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('section')?.marginLeft, 'auto'); +``` + +Debes dar al `section` un `max-width` de `600px`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('section')?.maxWidth, '600px'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +--fcc-editable-region-- + + +--fcc-editable-region-- + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; +} + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614880dc16070e093e29bc56.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614880dc16070e093e29bc56.md new file mode 100644 index 00000000000000..0c0a041ceecea7 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614880dc16070e093e29bc56.md @@ -0,0 +1,259 @@ +--- +id: 614880dc16070e093e29bc56 +title: Paso 51 +challengeType: 0 +dashedName: step-51 +--- + +# --description-- + +Reemplaza el margen superior del elemento `h2` con `60px` de relleno superior. + +# --hints-- + +Debes dar al `h2` un `margin-top` de `0`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('h2')?.marginTop, '0px'); +``` + +Debes dar al `h2` un `padding-top` de `60px`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('h2')?.paddingTop, '60px'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +--fcc-editable-region-- +h2 { + border-bottom: 4px solid #dfdfe2; + +} +--fcc-editable-region-- + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614883b6fa720e09fb167de9.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614883b6fa720e09fb167de9.md new file mode 100644 index 00000000000000..1e74224ec216cf --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614883b6fa720e09fb167de9.md @@ -0,0 +1,280 @@ +--- +id: 614883b6fa720e09fb167de9 +title: Paso 52 +challengeType: 0 +dashedName: step-52 +--- + +# --description-- + +Agrega relleno a la parte superior y a la parte izquierda de los elementos `.info`, y establece los demás valores a `0`. + +# --hints-- + +Debes usar el selector `.info`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('.info')); +``` + +Debes dar al `.info` un `padding-top` de al menos `1px`. + +```js +assert.isAtLeast(Number(new __helpers.CSSHelp(document).getStyle('.info')?.paddingTop?.replace(/\D+/, '')), 1); +``` + +Debes dar al `.info` un `padding-right` de `0`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.info')?.paddingRight, '0px'); +``` + +Debes dar al `.info` un `padding-bottom` de `0`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.info')?.paddingBottom, '0px'); +``` + +Debes dar al `.info` un `padding-left` de al menos `1px`. + +```js +assert.isAtLeast(Number(new __helpers.CSSHelp(document).getStyle('.info')?.paddingLeft?.replace(/\D+/, '')), 1); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614884c1f5d6f30ab3d78cde.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614884c1f5d6f30ab3d78cde.md new file mode 100644 index 00000000000000..47b671796c24c3 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614884c1f5d6f30ab3d78cde.md @@ -0,0 +1,364 @@ +--- +id: 614884c1f5d6f30ab3d78cde +title: Paso 53 +challengeType: 0 +dashedName: step-53 +--- + +# --description-- + +Da a los elementos `.formrow` margen superior y relleno izquierdo y derecho. Los demás valores de relleno deben ser `0`. + +Luego, incremente el tamaño de fuente para todos los elementos `input`. + +# --hints-- + +Debe usar un selector `.formrow` para apuntar a los elementos `.formrow`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('.formrow')); +``` + +Debe dar al `.formrow` un `margin-top` de al menos `1px`. + +```js +const val = new __helpers.CSSHelp(document).getStyle('.formrow')?.marginTop; +let valInPx = 0; +if (/^\d+rem$/.test(val)) { + valInPx = remToPx(Number(val.replace('rem', ''))); +} else if (/^\d+em$/.test(val)) { + valInPx = emToPx(Number(val.replace('em', ''))); +} else { + valInPx = Number(val?.replace('px', '')); +} +function emToPx(em) { + return em * parseFloat(getComputedStyle(document.querySelector('.formrow'))?.fontSize); +} +function remToPx(rem) { + return rem * parseFloat(getComputedStyle(document.documentElement)?.fontSize); +} +assert.isAtLeast(valInPx, 1); +``` + +Debe dar al `.formrow` un `padding-top` de `0`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.formrow')?.paddingTop, '0px'); +``` + +Debe dar al `.formrow` un `padding-right` de al menos `1px`. + +```js +const val = new __helpers.CSSHelp(document).getStyle('.formrow')?.paddingRight; +let valInPx = 0; +if (/^\d+rem$/.test(val)) { + valInPx = remToPx(Number(val.replace('rem', ''))); +} else if (/^\d+em$/.test(val)) { + valInPx = emToPx(Number(val.replace('em', ''))); +} else { + valInPx = Number(val?.replace('px', '')); +} +function emToPx(em) { + return em * parseFloat(getComputedStyle(document.querySelector('.formrow'))?.fontSize); +} +function remToPx(rem) { + return rem * parseFloat(getComputedStyle(document.documentElement)?.fontSize); +} +assert.isAtLeast(valInPx, 1); +``` + +Debe dar al `.formrow` un `padding-bottom` de `0`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.formrow')?.paddingBottom, '0px'); +``` + +Debe dar al `.formrow` un `padding-left` de al menos `1px`. + +```js +const val = new __helpers.CSSHelp(document).getStyle('.formrow')?.paddingLeft; +let valInPx = 0; +if (/^\d+rem$/.test(val)) { + valInPx = remToPx(Number(val.replace('rem', ''))); +} else if (/^\d+em$/.test(val)) { + valInPx = emToPx(Number(val.replace('em', ''))); +} else { + valInPx = Number(val?.replace('px', '')); +} +function emToPx(em) { + return em * parseFloat(getComputedStyle(document.querySelector('.formrow'))?.fontSize); +} +function remToPx(rem) { + return rem * parseFloat(getComputedStyle(document.documentElement)?.fontSize); +} +assert.isAtLeast(valInPx, 1); +``` + +Debe usar un selector `input` para apuntar a los elementos `input`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('input')); +``` + +Debe dar al `input` un `font-size` mayor que `13px`. + +```js +const val = new __helpers.CSSHelp(document).getStyle('input')?.fontSize; +let valInPx = 0; +if (/^\d+rem$/.test(val)) { + valInPx = remToPx(Number(val.replace('rem', ''))); +} else if (/^\d+em$/.test(val)) { + valInPx = emToPx(Number(val.replace('em', ''))); +} else { + valInPx = Number(val?.replace('px', '')); +} +function emToPx(em) { + return em * parseFloat(getComputedStyle(document.querySelector('.formrow'))?.fontSize); +} +function remToPx(rem) { + return rem * parseFloat(getComputedStyle(document.documentElement)?.fontSize); +} +assert.isAtLeast(valInPx, 13); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61488ecfd05e290b5712e6da.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61488ecfd05e290b5712e6da.md new file mode 100644 index 00000000000000..7f581073684d13 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61488ecfd05e290b5712e6da.md @@ -0,0 +1,286 @@ +--- +id: 61488ecfd05e290b5712e6da +title: Paso 54 +challengeType: 0 +dashedName: step-54 +--- + +# --description-- + +Para hacer que la primera sección se vea más en línea, apunte solo a los elementos `input` dentro de los elementos `.info`, y establezca su `width` a `50%`, y alinee su texto a la izquierda. + +# --hints-- + +Debes usar el selector `.info input` o `.info > input`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s); +assert.exists(gs('.info input') || gs('.info > input')); +``` + +Debes dar a los elementos `input` un `width` de `50%`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s)?.width; +const width = gs('.info input') ?? gs('.info > input'); +assert.equal(width, '50%'); +``` + +Debes dar a los elementos `input` un `text-align` de `left`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s)?.textAlign; +const textAlign = gs('.info input') ?? gs('.info > input'); +assert.equal(textAlign, 'left'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148d99cdc7acd0c519862cb.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148d99cdc7acd0c519862cb.md new file mode 100644 index 00000000000000..8297e8f4d28c4f --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148d99cdc7acd0c519862cb.md @@ -0,0 +1,291 @@ +--- +id: 6148d99cdc7acd0c519862cb +title: Paso 55 +challengeType: 0 +dashedName: step-55 +--- + +# --description-- + +Apunta a todos los elementos `label` dentro de los elementos `.info`, y establece su `width` a `10%`, y haga que no ocupen menos de `55px`. + +# --hints-- + +Debes usar el selector `.info label` o el `.info > label`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s); +assert.exists(gs('.info label') || gs('.info > label')); +``` + +Debes dar a los elementos `label` un `width` de `10%`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s)?.width; +const width = gs('.info label') || gs('.info > label'); +assert.equal(width, '10%'); +``` + +Debes dar a los elementos `label` un `min-width` de `55px`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s)?.minWidth; +const minWidth = gs('.info label') || gs('.info > label'); +assert.equal(minWidth, '55px'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +--fcc-editable-region-- +.info input { + width: 50%; + text-align: left; +} + + +--fcc-editable-region-- + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148da157cc0bd0d06df5c0a.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148da157cc0bd0d06df5c0a.md new file mode 100644 index 00000000000000..e4a1c6bfd87521 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148da157cc0bd0d06df5c0a.md @@ -0,0 +1,306 @@ +--- +id: 6148da157cc0bd0d06df5c0a +title: Paso 56 +challengeType: 0 +dashedName: step-56 +--- + +# --description-- + +Para alinear las cajas `input` entre sí, establece la propiedad `display` a `inline-block` para todos los elementos `input` y `label` dentro de los elementos `.info`. + +Además, alinee el texto a la derecha. + +# --hints-- + +Debes usar el selector `.info > label, .info > input` o el `.info label, .info input`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s); +assert.exists(gs('.info > label, .info > input') || gs('.info label, .info input') || gs('.info > input, .info > label') || gs('.info input, .info label')); +``` + +Debes dar a los elementos `input` y `label` un `display` de `inline-block`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s)?.display; +const display = gs('.info > label, .info > input') ?? gs('.info label, .info input') ?? gs('.info > input, .info > label') ?? gs('.info input, .info label'); +assert.equal(display, 'inline-block'); +``` + +Debes dar a los elementos `input` y `label` un `text-align` de `right`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s)?.textAlign; +const textAlign = gs('.info > label, .info > input') ?? gs('.info label, .info input') ?? gs('.info > input, .info > label') ?? gs('.info input, .info label'); +assert.equal(textAlign, 'right'); +``` + +Debes establecer la propiedad `text-align: right` antes de la regla `.info input`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyleRule(s); +assert(gs('.info input').isDeclaredAfter('.info label, .info input') || gs('.info input').isDeclaredAfter('.info > label, .info > input') || gs('.info input').isDeclaredAfter('.info > input, .info > label') || gs('.info input').isDeclaredAfter('.info input, .info label')); + +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +--fcc-editable-region-- + + +.info input { + width: 50%; + text-align: left; +} + +.info label { + width: 10%; + min-width: 55px; +} +--fcc-editable-region-- + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148dc095264000dce348bf5.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148dc095264000dce348bf5.md new file mode 100644 index 00000000000000..3d7c82477f0e5e --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148dc095264000dce348bf5.md @@ -0,0 +1,323 @@ +--- +id: 6148dc095264000dce348bf5 +title: Paso 57 +challengeType: 0 +dashedName: step-57 +--- + +# --description-- + +Para ordenar los elementos `.question-block`, establece las siguientes propiedades CSS: + +```css +text-align: left; +display: block; +width: 100%; +margin-top: 20px; +padding-top: 5px; +``` + +# --hints-- + +Debes usar el selector `.question-block`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('.question-block')); +``` + +Debes dar al elemento `.question-block` un `display` de `block`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.question-block')?.display, 'block'); +``` + +Debes dar al elemento `.question-block` un `width` de `100%`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.question-block')?.width, '100%'); +``` + +Debes dar al elemento `.question-block` un `margin-top` de `20px`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.question-block')?.marginTop, '20px'); +``` + +Debes dar al elemento `.question-block` un `padding-top` de `5px`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.question-block')?.paddingTop, '5px'); +``` + +Debes dar al elemento `.question-block` un `text-align` de `left`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.question-block')?.textAlign, 'left'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +.info label, .info input { + display: inline-block; + text-align: right; +} + +.info input { + width: 50%; + text-align: left; +} + +.info label { + width: 10%; + min-width: 55px; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148dcaaf2e8750e6cb4501a.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148dcaaf2e8750e6cb4501a.md new file mode 100644 index 00000000000000..a39f63d3bac49f --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148dcaaf2e8750e6cb4501a.md @@ -0,0 +1,316 @@ +--- +id: 6148dcaaf2e8750e6cb4501a +title: Paso 58 +challengeType: 0 +dashedName: step-58 +--- + +# --description-- + +Haz que los elementos de párrafo aparezcan como una prioridad más alta, con las siguientes propiedades CSS: + +```css +margin-top: 5px; +padding-left: 15px; +font-size: 20px; +``` + +# --hints-- + +Debes usar el selector del elemento `p`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('p')); +``` + +Debes dar al elemento `p` un `margin-top` de `5px`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('p')?.marginTop, '5px'); +``` + +Debes dar al elemento `p` un `padding-left` de `15px`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('p')?.paddingLeft, '15px'); +``` + +Debes dar al elemento `p` un `font-size` de `20px`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('p')?.fontSize, '20px'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +.info label, .info input { + display: inline-block; + text-align: right; +} + +.info input { + width: 50%; + text-align: left; +} + +.info label { + width: 10%; + min-width: 55px; +} + +.question-block { + text-align: left; + display: block; + width: 100%; + margin-top: 20px; + padding-top: 5px; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148dd31d210990f0fb140f8.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148dd31d210990f0fb140f8.md new file mode 100644 index 00000000000000..c3a10371319995 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148dd31d210990f0fb140f8.md @@ -0,0 +1,312 @@ +--- +id: 6148dd31d210990f0fb140f8 +title: Paso 59 +challengeType: 0 +dashedName: step-59 +--- + +# --description-- + +Es útil ver el borde por defecto alrededor de los elementos `fieldset`, durante el desarrollo. Sin embargo, puede que no sea el estilo que quieras. + +Elimina el borde y el relleno inferior de los elementos `.question`. + +# --hints-- + +Debes usar el selector `.question`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('.question')); +``` + +Debes dar al `.question` un `border` de `none`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.question')?.borderStyle, 'none'); +``` + +Debes dar al `.question` un `padding-bottom` de `0`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.question')?.paddingBottom, '0px'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +.info label, .info input { + display: inline-block; + text-align: right; +} + +.info input { + width: 50%; + text-align: left; +} + +.info label { + width: 10%; + min-width: 55px; +} + +.question-block { + text-align: left; + display: block; + width: 100%; + margin-top: 20px; + padding-top: 5px; +} + +p { + margin-top: 5px; + padding-left: 15px; + font-size: 20px; +} + +p::before { + content: "Question #"; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148defa9c01520fb9d178a0.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148defa9c01520fb9d178a0.md new file mode 100644 index 00000000000000..2951464acb9e31 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148defa9c01520fb9d178a0.md @@ -0,0 +1,315 @@ +--- +id: 6148defa9c01520fb9d178a0 +title: Paso 60 +challengeType: 0 +dashedName: step-60 +--- + +# --description-- + +Elimina el estilo predeterminado para los elementos de la lista `.answers-list`, y elimina el relleno de la lista desordenada. + +# --hints-- + +Debes usar el selector `.answers-list`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('.answers-list')); +``` + +Debes dar al `.answers-list` un `list-style` de `none`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.answers-list')?.listStyle, 'none'); +``` + +Debes dar al `.answers-list` un `padding` de `0`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('.answers-list')?.padding, '0px'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +.info label, .info input { + display: inline-block; + text-align: right; +} + +.info input { + width: 50%; + text-align: left; +} + +.info label { + width: 10%; + min-width: 55px; +} + +.question-block { + text-align: left; + display: block; + width: 100%; + margin-top: 20px; + padding-top: 5px; +} + +p { + margin-top: 5px; + padding-left: 15px; + font-size: 20px; +} + +p::before { + content: "Question #"; +} + +.question { + border: none; + padding-bottom: 0; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148dfab9b54c110577de165.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148dfab9b54c110577de165.md new file mode 100644 index 00000000000000..9a06dba964ab74 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148dfab9b54c110577de165.md @@ -0,0 +1,360 @@ +--- +id: 6148dfab9b54c110577de165 +title: Paso 61 +challengeType: 0 +dashedName: step-61 +--- + +# --description-- + +Dale al botón de envío un diseño al estilo freeCodeCamp, con las siguientes propiedades CSS: + +```css +display: block; +margin: 40px auto; +width: 40%; +padding: 15px; +font-size: 23px; +background: #d0d0d5; +border: 3px solid #3b3b4f; +``` + +# --hints-- + +Debes usar el selector del elemento `button`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('button')); +``` + +Debes dar al `button` un `display` de `block`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('button')?.display, 'block'); +``` + +Debes dar al `button` un `margin` de `40px auto`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('button')?.margin, '40px auto'); +``` + +Debes dar al `button` un `width` de `40%`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('button')?.width, '40%'); +``` + +Debes dar al `button` un `padding` de `15px`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('button')?.padding, '15px'); +``` + +Debes dar al `button` un `font-size` de `23px`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('button')?.fontSize, '23px'); +``` + +Debes dar al `button` un `background` de `#d0d0d5`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('button')?.backgroundColor, 'rgb(208, 208, 213)'); +``` + +Debes dar al `button` un `border` de `3px solid #3b3b4f`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('button')?.border, '3px solid rgb(59, 59, 79)'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +.info label, .info input { + display: inline-block; + text-align: right; +} + +.info input { + width: 50%; + text-align: left; +} + +.info label { + width: 10%; + min-width: 55px; +} + +.question-block { + text-align: left; + display: block; + width: 100%; + margin-top: 20px; + padding-top: 5px; +} + +p { + margin-top: 5px; + padding-left: 15px; + font-size: 20px; +} + +p::before { + content: "Question #"; +} + +.question { + border: none; + padding-bottom: 0; +} + +.answers-list { + list-style: none; + padding: 0; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e0bcc13efd10f7d7a6a9.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e0bcc13efd10f7d7a6a9.md new file mode 100644 index 00000000000000..c58911e760705b --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e0bcc13efd10f7d7a6a9.md @@ -0,0 +1,336 @@ +--- +id: 6148e0bcc13efd10f7d7a6a9 +title: Paso 62 +challengeType: 0 +dashedName: step-62 +--- + +# --description-- + +Establece el color de fondo del `footer` a `#2a2a40`, y usa _Flexbox_ para centrar horizontalmente el texto. + +# --hints-- + +Debes usar el selector del elemento `footer`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('footer')); +``` + +Debes dar al `footer` un `background-color` de `#2a2a40`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('footer')?.backgroundColor, 'rgb(42, 42, 64)'); +``` + +Debes dar al `footer` un `display` de `flex`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('footer')?.display, 'flex'); +``` + +Debes dar al `footer` un `justify-content` de `center`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('footer')?.justifyContent, 'center'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +.info label, .info input { + display: inline-block; + text-align: right; +} + +.info input { + width: 50%; + text-align: left; +} + +.info label { + width: 10%; + min-width: 55px; +} + +.question-block { + text-align: left; + display: block; + width: 100%; + margin-top: 20px; + padding-top: 5px; +} + +p { + margin-top: 5px; + padding-left: 15px; + font-size: 20px; +} + +p::before { + content: "Question #"; +} + +.question { + border: none; + padding-bottom: 0; +} + +.answers-list { + list-style: none; + padding: 0; +} + +button { + display: block; + margin: 40px auto; + width: 40%; + padding: 15px; + font-size: 23px; + background: #d0d0d5; + border: 3px solid #3b3b4f; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e161ecec9511941f8833.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e161ecec9511941f8833.md new file mode 100644 index 00000000000000..6721601a53c4e3 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e161ecec9511941f8833.md @@ -0,0 +1,356 @@ +--- +id: 6148e161ecec9511941f8833 +title: Paso 63 +challengeType: 0 +dashedName: step-63 +--- + +# --description-- + +Ahora, no podemos leer el texto. Apunta al `footer` y al elemento ancla dentro para establecer el color de la fuente a un color de relación de contraste adecuado. + +# --hints-- + +Debes usar el selector `footer, footer a`. + +```js +const gs = (s) => new __helpers.CSSHelp(document).getStyle(s); +assert.exists(gs('footer, footer a') || gs('footer a, footer')); +``` + +Debes establecer el `color` a un valor con una relación de contraste de al menos `7:1`. _Pista: Yo sugiero `#dfdfe2`_ + +```js +function luminance(r, g, b) { + const a = [r, g, b].map((v) => { + v /= 255; + return v <= 0.03928 ? v / 12.92 : Math.pow( (v + 0.055) / 1.055, 2.4 ); + }); + return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722; +} +function contrast(rgb1, rgb2) { + const lum1 = luminance(rgb1[0], rgb1[1], rgb1[2]); + const lum2 = luminance(rgb2[0], rgb2[1], rgb2[2]); + const brightest = Math.max(lum1, lum2); + const darkest = Math.min(lum1, lum2); + return (brightest + 0.05) + / (darkest + 0.05); +} +const backgroundColour = [42, 42, 64]; + +const foot = getComputedStyle(document.querySelector('footer'))?.color; +const a = getComputedStyle(document.querySelector('footer a'))?.color; + +const rgbFoot = foot?.match(/(\d+),\s(\d+),\s(\d+)/); +const rgbA = a?.match(/(\d+),\s(\d+),\s(\d+)/); +const footColour = [rgbFoot[1], rgbFoot[2], rgbFoot[3]]; +const aColour = [rgbA[1], rgbA[2], rgbA[3]]; +assert.isAtLeast(contrast(backgroundColour, footColour), 7); +assert.isAtLeast(contrast(backgroundColour, aColour), 7); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +.info label, .info input { + display: inline-block; + text-align: right; +} + +.info input { + width: 50%; + text-align: left; +} + +.info label { + width: 10%; + min-width: 55px; +} + +.question-block { + text-align: left; + display: block; + width: 100%; + margin-top: 20px; + padding-top: 5px; +} + +p { + margin-top: 5px; + padding-left: 15px; + font-size: 20px; +} + +p::before { + content: "Question #"; +} + +.question { + border: none; + padding-bottom: 0; +} + +.answers-list { + list-style: none; + padding: 0; +} + +button { + display: block; + margin: 40px auto; + width: 40%; + padding: 15px; + font-size: 23px; + background: #d0d0d5; + border: 3px solid #3b3b4f; +} + +footer { + background-color: #2a2a40; + display: flex; + justify-content: center; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e28706b34912340fd042.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e28706b34912340fd042.md new file mode 100644 index 00000000000000..7279836593d171 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e28706b34912340fd042.md @@ -0,0 +1,359 @@ +--- +id: 6148e28706b34912340fd042 +title: Paso 64 +challengeType: 0 +dashedName: step-64 +--- + +# --description-- + +Centra horizontalmente todo el texto dentro del elemento `address` y agrega un poco de relleno. + +# --hints-- + +Debes usar el selector del elemento `address`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('address')); +``` + +Debes dar al `address` un `text-align` de `center`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('address')?.textAlign, 'center'); +``` + +Debes dar al `address` un `padding-top` de al menos `1px`. + +```js +assert.isAtLeast(Number(window.getComputedStyle(document.querySelector('address'), null)?.getPropertyValue('padding-top')?.replace(/\D\D+/, '')), 1); +``` + +Debes dar al `address` un `padding-right` de al menos `1px`. + +```js +assert.isAtLeast(Number(window.getComputedStyle(document.querySelector('address'), null)?.getPropertyValue('padding-right')?.replace(/\D\D+/, '')), 1); +``` + +Debes dar al `address` un `padding-bottom` de al menos `1px`. + +```js +assert.isAtLeast(Number(window.getComputedStyle(document.querySelector('address'), null)?.getPropertyValue('padding-bottom')?.replace(/\D\D+/, '')), 1); +``` + +Debes dar al `address` un `padding-left` de al menos `1px`. + +```js +assert.isAtLeast(Number(window.getComputedStyle(document.querySelector('address'), null)?.getPropertyValue('padding-left')?.replace(/\D\D+/, '')), 1); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +.info label, .info input { + display: inline-block; + text-align: right; +} + +.info input { + width: 50%; + text-align: left; +} + +.info label { + width: 10%; + min-width: 55px; +} + +.question-block { + text-align: left; + display: block; + width: 100%; + margin-top: 20px; + padding-top: 5px; +} + +p { + margin-top: 5px; + padding-left: 15px; + font-size: 20px; +} + +p::before { + content: "Question #"; +} + +.question { + border: none; + padding-bottom: 0; +} + +.answers-list { + list-style: none; + padding: 0; +} + +button { + display: block; + margin: 40px auto; + width: 40%; + padding: 15px; + font-size: 23px; + background: #d0d0d5; + border: 3px solid #3b3b4f; +} + +footer { + background-color: #2a2a40; + display: flex; + justify-content: center; +} + +footer, +footer a { + color: #dfdfe2; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e335c1edd512d00e4691.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e335c1edd512d00e4691.md new file mode 100644 index 00000000000000..bcc08f7bfdc935 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e335c1edd512d00e4691.md @@ -0,0 +1,342 @@ +--- +id: 6148e335c1edd512d00e4691 +title: Paso 65 +challengeType: 0 +dashedName: step-65 +--- + +# --description-- + +Al hacer clic en los enlaces de navegación, la ventana gráfica debería saltar a la sección correspondiente. Sin embargo, este salto puede desorientar a algunos usuarios. + +Selecciona todos los elementos y establece el `scroll-behavior` a `smooth`. + +# --hints-- + +Debes usar el selector `*`. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('*')); +``` + +Debes dar al `*` un `scroll-behavior` de `smooth`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('*')?.scrollBehavior, 'smooth'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +--fcc-editable-region-- + +--fcc-editable-region-- + +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +.info label, .info input { + display: inline-block; + text-align: right; +} + +.info input { + width: 50%; + text-align: left; +} + +.info label { + width: 10%; + min-width: 55px; +} + +.question-block { + text-align: left; + display: block; + width: 100%; + margin-top: 20px; + padding-top: 5px; +} + +p { + margin-top: 5px; + padding-left: 15px; + font-size: 20px; +} + +p::before { + content: "Question #"; +} + +.question { + border: none; + padding-bottom: 0; +} + +.answers-list { + list-style: none; + padding: 0; +} + +button { + display: block; + margin: 40px auto; + width: 40%; + padding: 15px; + font-size: 23px; + background: #d0d0d5; + border: 3px solid #3b3b4f; +} + +footer { + background-color: #2a2a40; + display: flex; + justify-content: center; +} + +footer, +footer a { + color: #dfdfe2; +} + +address { + text-align: center; + padding: 0.3em; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e5aeb102e3142de026a2.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e5aeb102e3142de026a2.md new file mode 100644 index 00000000000000..07ff181bda0c59 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e5aeb102e3142de026a2.md @@ -0,0 +1,685 @@ +--- +id: 6148e5aeb102e3142de026a2 +title: Paso 67 +challengeType: 0 +dashedName: step-67 +--- + +# --description-- + +Finalmente, la accesibilidad de la navegación puede mejorarse proporcionando atajos de teclado. + +El atributo `accesskey` acepta una lista de teclas de acceso separadas por espacios. Por ejemplo: + +```html + +``` + +Dale a cada uno de los enlaces de navegación una tecla de acceso. + +_Nota: No siempre se aconseja utilizar las claves de acceso, pero pueden ser útiles_ + +Bien hecho. Has completado el proyecto de práctica del _cuestionario accesible_. + +# --hints-- + +Debes dar al primer elemento `a` un `accesskey` de una letra. + +```js +assert.equal(document.querySelectorAll('a')?.[0]?.getAttribute('accesskey')?.length, 1); +``` + +Debes dar al segundo elemento `a` un `accesskey` de una letra. + +```js +assert.equal(document.querySelectorAll('a')?.[1]?.getAttribute('accesskey')?.length, 1); +``` + +Debes dar al tercer elemento `a` un `accesskey` de una letra. + +```js +assert.equal(document.querySelectorAll('a')?.[2]?.getAttribute('accesskey')?.length, 1); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +@media (prefers-reduced-motion: no-preference) { + * { + scroll-behavior: smooth; + } +} + +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +.info label, .info input { + display: inline-block; + text-align: right; +} + +.info input { + width: 50%; + text-align: left; +} + +.info label { + width: 10%; + min-width: 55px; +} + +.question-block { + text-align: left; + display: block; + width: 100%; + margin-top: 20px; + padding-top: 5px; +} + +p { + margin-top: 5px; + padding-left: 15px; + font-size: 20px; +} + +p::before { + content: "Question #"; +} + +.question { + border: none; + padding-bottom: 0; +} + +.answers-list { + list-style: none; + padding: 0; +} + +button { + display: block; + margin: 40px auto; + width: 40%; + padding: 15px; + font-size: 23px; + background: #d0d0d5; + border: 3px solid #3b3b4f; +} + +footer { + background-color: #2a2a40; + display: flex; + justify-content: center; +} + +footer, +footer a { + color: #dfdfe2; +} + +address { + text-align: center; + padding: 0.3em; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` + +## --solutions-- + +```html + + + + + + + + Accessibility Quiz + + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    + +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +@media (prefers-reduced-motion: no-preference) { + * { + scroll-behavior: smooth; + } +} + +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + position: fixed; + background-color: #1b1b32; + top: 0; +} + +#logo { + width: max(100px, 18vw); + aspect-ratio: 35 / 4; + max-height: 100%; + background-color: #0a0a23; + padding: 0.4rem; +} + +h1 { + text-align: center; + font-size: min(5vw, 1.2em); + color: #f1be32; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + flex-wrap: wrap; + justify-content: space-evenly; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + display: block; + margin: 0 0.2rem; + color: #dfdfe2; + padding: 0.2rem; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0px auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + + +.info { + margin: 0 auto; + padding: 10px 0 0 5px; +} +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +.info label, +.info input { + display: inline-block; + text-align: right; +} + +.info label { + width: 10%; + min-width: 55px; +} + +.info input { + width: 50%; + text-align: left; +} + +.question-block { + text-align: left; + display: block; + width: 100%; + margin-top: 20px; + padding-top: 5px; +} + +p { + margin-top: 5px; + padding-left: 15px; + font-size: 20px; +} + +p::before { + content: "Question #"; +} + +.question { + border: none; + padding-bottom: 0; +} + +.answers-list { + list-style: none; + padding: 0; +} + +button { + display: block; + margin: 40px auto; + width: 40%; + padding: 15px; + font-size: 23px; + background: #d0d0d5; + border: 3px solid #3b3b4f; +} + +footer { + background-color: #2a2a40; + display: flex; + justify-content: center; +} + +footer, +footer a { + color: #dfdfe2; +} + +address { + text-align: center; + padding: 0.3em; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614ccc21ea91ef1736b9b578.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614ccc21ea91ef1736b9b578.md new file mode 100644 index 00000000000000..f3ba7c692b238b --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614ccc21ea91ef1736b9b578.md @@ -0,0 +1,50 @@ +--- +id: 614ccc21ea91ef1736b9b578 +title: Paso 1 +challengeType: 0 +dashedName: step-1 +--- + +# --description-- + +Bienvenido a la primera parte del cuestionario accesible. Como te estás convirtiendo en un desarrollador experimentado de HTML y CSS, empezamos con la plantilla básica. + +Empieza este viaje por la accesibilidad proporcionando un atributo `lang` a tu elemento `html`. Esto ayudará a los lectores de pantalla a identificar el idioma de la página. + +# --hints-- + +Debes dar al elemento `html` un atributo `lang`. _Pista: Puedes usar el valor `en` para inglés_ + +```js +assert.match(code, //i); +// TODO: This should/could be fixed in the builder.js +// assert.notThrow(Intl.getCanonicalLocales(document.querySelector('html').lang)); +``` + +# --seed-- + +## --seed-contents-- + +```html + +--fcc-editable-region-- + + + + + + + + +--fcc-editable-region-- + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f33071498eb2472b87ddee4.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f33071498eb2472b87ddee4.md new file mode 100644 index 00000000000000..6de9cb5881dbb7 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f33071498eb2472b87ddee4.md @@ -0,0 +1,43 @@ +--- +id: 5f33071498eb2472b87ddee4 +title: Paso 1 +challengeType: 0 +dashedName: step-1 +--- + +# --description-- + +Como has aprendido en los pasos anteriores del proyecto Cat Photo App, hay una estructura básica necesaria para comenzar a construir tu página web. + +Añade la etiqueta `` y un elemento `html`. + +# --hints-- + +Debes tener la declaración `DOCTYPE`. + +```js +assert(code.match(//i)); +``` + +Debes tener una etiqueta `` de apertura. + +```js +assert(code.match(//i)); +``` + +Debes tener una etiqueta `` de cierre. Recuerda que las etiquetas de cierre tienen una `/` después del corchete `<` de apertura. + +```js +assert(code.match(/<\/html>/i)); +``` + +# --seed-- + +## --seed-contents-- + +```html +--fcc-editable-region-- + +--fcc-editable-region-- + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3313e74582ad9d063e3a38.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3313e74582ad9d063e3a38.md new file mode 100644 index 00000000000000..de7099fdad5840 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3313e74582ad9d063e3a38.md @@ -0,0 +1,61 @@ +--- +id: 5f3313e74582ad9d063e3a38 +title: Paso 2 +challengeType: 0 +dashedName: step-2 +--- + +# --description-- + +Añade un elemento `head` dentro del elemento `html`, para que puedas añadir un elemento `title`. El texto del elemento `title` deber ser `Cafe Menu`. + +# --hints-- + +Debes tener una etiqueta `` de apertura. + +```js +assert(code.match(//i)); +``` + +Debes tener una etiqueta `` de cierre. + +```js +assert(code.match(//i)); +``` + +Debes tener una etiqueta `` de apertura. + +```js +assert(code.match(/<title>/i)); +``` + +Debes tener una etiqueta `` de cierre. + +```js +assert(code.match(/<\/title>/i)); +``` + +Tu elemento `title` debe estar anidado dentro del elemento `head`. + +```js +assert(code.match(/\s*.*<\/title>\s*<\/head>/si)); +``` + +Tu elemento `title` debe tener el texto `Cafe Menu`. Talvez debas revisar tu ortografía. + +```js +assert.match(document.querySelector('title')?.innerText, /Cafe Menu/i); +``` + +# --seed-- + +## --seed-contents-- + +```html +<!DOCTYPE html> +<html lang="en"> +--fcc-editable-region-- + +--fcc-editable-region-- +</html> +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f331e55dfab7a896e53c3a1.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f331e55dfab7a896e53c3a1.md new file mode 100644 index 00000000000000..e711daa06cbdba --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f331e55dfab7a896e53c3a1.md @@ -0,0 +1,47 @@ +--- +id: 5f331e55dfab7a896e53c3a1 +title: Paso 3 +challengeType: 0 +dashedName: step-3 +--- + +# --description-- + +El elemento `title` es uno de los varios elementos que proporcionan información adicional no visible en la página web, pero que es útil para los motores de búsqueda o en cómo es mostrada la página. + +Dentro del elemento `head`, anida un elemento `meta` con un atributo `charset` con el valor `utf-8` para decirle al navegador cómo se codificarán los caracteres para la página. Ten en cuenta que los elementos `meta` se cierran automáticamente. + +# --hints-- + +Debes tener una etiqueta `meta`. + +```js +assert(code.match(/<meta.*?\/?>/is)); +``` + +Tu etiqueta `meta` debe tener un atributo `charset`. + +```js +assert(code.match(/<meta charset=/i)); +``` + +Tu atributo `charset` debe tener el valor `utf-8`. + +```js +assert(code.match(/charset=('|")utf-8\1/i)); +``` + +# --seed-- + +## --seed-contents-- + +```html +<!DOCTYPE html> +<html lang="en"> +--fcc-editable-region-- + <head> + <title>Cafe Menu + +--fcc-editable-region-- + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3326b143638ee1a09ff1e3.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3326b143638ee1a09ff1e3.md new file mode 100644 index 00000000000000..747ef660a494d2 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3326b143638ee1a09ff1e3.md @@ -0,0 +1,54 @@ +--- +id: 5f3326b143638ee1a09ff1e3 +title: Paso 4 +challengeType: 0 +dashedName: step-4 +--- + +# --description-- + +Para comenzar a crear contenido real, añade un elemento `body` debajo del elemento `head`. + +# --hints-- + +Debes tener una etiqueta `` de apertura. + +```js +assert(code.match(//i)); +``` + +Debes tener una etiqueta `` de cierre. + +```js +assert(code.match(/<\/body>/i)); +``` + +No debes modificar el elemento `head`. Asegúrese de que no eliminaste tu etiqueta de cierre. + +```js +assert(code.match(//i)); +assert(code.match(/<\/head>/i)); +``` + +Tu elemento `body` debe estar después del elemento `head`. + +```js +assert(code.match(/<\/head>[.\n\s]*/im)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +--fcc-editable-region-- + + + Cafe Menu + +--fcc-editable-region-- + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f33294a6af5e9188dbdb8f3.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f33294a6af5e9188dbdb8f3.md new file mode 100644 index 00000000000000..0874534f73dce2 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f33294a6af5e9188dbdb8f3.md @@ -0,0 +1,60 @@ +--- +id: 5f33294a6af5e9188dbdb8f3 +title: Paso 5 +challengeType: 0 +dashedName: step-5 +--- + +# --description-- + +El nombre de la cafetería es `CAMPER CAFE`. Añade un elemento `h1` dentro tu elemento `body`. Dale el nombre de la cafetería en mayúsculas para hacer que resalte. + +# --hints-- + +Debes tener una etiqueta `

    ` de apertura. + +```js +assert(code.match(/

    /i)); +``` + +Debes tener una etiqueta `

    ` de cierre. + +```js +assert(code.match(/<\/h1>/i)); +``` + +No debes modificar el elemento `body` existente. + +```js +assert($('body').length === 1); +``` + +Tu elemento `h1` debe estar anidado dentro del elemento `body`. + +```js +assert($('h1')[0].parentElement.tagName === "BODY"); +``` + +Tu elemento `h1` debe tener el texto `CAMPER CAFE`. + +```js +assert(code.match(/

    CAMPER CAFE<\/h1>/)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + Cafe Menu + +--fcc-editable-region-- + + +--fcc-editable-region-- + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f332a88dc25a0fd25c7687a.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f332a88dc25a0fd25c7687a.md new file mode 100644 index 00000000000000..0941dfc4276885 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f332a88dc25a0fd25c7687a.md @@ -0,0 +1,62 @@ +--- +id: 5f332a88dc25a0fd25c7687a +title: Paso 6 +challengeType: 0 +dashedName: step-6 +--- + +# --description-- + +Para que los visitantes sepan que la cafetería fue fundada en el 2020, añade un elemento `p` debajo del elemento `h1` con el texto `Est. 2020`. + +# --hints-- + +Debes tener una etiqueta `

    ` de apertura. + +```js +assert(code.match(/

    /i)); +``` + +Debes tener una etiqueta `

    ` de cierre. + +```js +assert(code.match(/<\/p>/i)); +``` + +No debes modificar el elemento `h1` existente. Asegúrese de que no eliminaste tu etiqueta de cierre. + +```js +assert($('h1').length === 1); +``` + +Tu elemento `p` debe estar debajo del elemento `h1`. + +```js +assert($('p')[0].previousElementSibling.tagName === 'H1'); +``` + +Tu elemento `p` debe tener el texto `Est. 2020`. + +```js +assert(document.querySelector("p").innerText === "Est. 2020"); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + Cafe Menu + + +--fcc-editable-region-- +

    CAMPER CAFE

    +--fcc-editable-region-- + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f332b23c2045fb843337579.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f332b23c2045fb843337579.md new file mode 100644 index 00000000000000..65815622261f44 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f332b23c2045fb843337579.md @@ -0,0 +1,59 @@ +--- +id: 5f332b23c2045fb843337579 +title: Paso 7 +challengeType: 0 +dashedName: step-7 +--- + +# --description-- + +Ya que el elemento `p` añadido en el paso anterior, provee información extra sobre la cafetería, anida el elemento `h1` y el elemento `p` dentro de un elemento `header`. + +# --hints-- + +Debes tener una etiqueta `
    ` de apertura. + +```js +assert(code.match(/
    /i)); +``` + +Debes tener una etiqueta `
    ` de cierre. + +```js +assert(code.match(/<\/header>/i)); +``` + +Tu elemento `h1` debe estar anidado dentro del elemento `header`. + +```js +const header = document.querySelectorAll('header')[0]; +assert(header.children[0].tagName === 'H1'); +``` + +Tu elemento `p` debe estar anidado dentro del elemento `header`. + +```js +const header = document.querySelectorAll('header')[0]; +assert(header.children[1].tagName === "P"); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + Cafe Menu + + +--fcc-editable-region-- +

    CAMPER CAFE

    +

    Est. 2020

    +--fcc-editable-region-- + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f33310c1851c6c4da013250.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f33310c1851c6c4da013250.md new file mode 100644 index 00000000000000..17fcabd6af43ff --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f33310c1851c6c4da013250.md @@ -0,0 +1,59 @@ +--- +id: 5f33310c1851c6c4da013250 +title: Paso 8 +challengeType: 0 +dashedName: step-8 +--- + +# --description-- + +Es hora de añadir contenido al menú. Añade un elemento `main` debajo del elemento `header` existente. Eventualmente, contendrá información sobre los precios del café y postres ofrecidos por la cafetería. + +# --hints-- + +Debes tener una etiqueta `
    ` de apertura. + +```js +assert(code.match(/
    /i)); +``` + +Debes tener una etiqueta `
    ` de cierre. + +```js +assert(code.match(/<\/main>/i)); +``` + +No debes modificar el elemento `header`. Asegúrate de no eliminar accidentalmente tu etiqueta de cierre. + +```js +assert($('header').length === 1); +``` + +Tu etiqueta `main` debe estar después de la etiqueta `header`. + +```js +const main = document.querySelectorAll('main')[0]; +assert(main.previousElementSibling.tagName === 'HEADER'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + Cafe Menu + + +--fcc-editable-region-- +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +--fcc-editable-region-- + + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f344f9c805cd193c33d829c.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f344f9c805cd193c33d829c.md new file mode 100644 index 00000000000000..a39ef2e5585d60 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f344f9c805cd193c33d829c.md @@ -0,0 +1,71 @@ +--- +id: 5f344f9c805cd193c33d829c +title: Paso 12 +challengeType: 0 +dashedName: step-12 +--- + +# --description-- + +Puedes darle estilo a un elemento, especificándolo en el elemento `style` y añadiendo una propiedad para el elemento, de esta forma: + +```css +element { + property: value; +} +``` + +Centra tu elemento `h1` dándole a su propiedad `text-align` al valor `center`. + +# --hints-- + +Debes tener un selector `h1` en el elemento `style`. + +```js +const hasSelector = new __helpers.CSSHelp(document).getStyle('h1'); +assert(hasSelector); +``` + +Tu propiedad `text-align` debe tener el valor `center`. + +```js +const hasTextAlign = new __helpers.CSSHelp(document).getCSSRules().some(x => x.style['text-align'] === 'center'); +assert(hasTextAlign); +``` + +El selector `h1` debe darle a la propiedad `text-align` el valor `center`. + +```js +const h1TextAlign = new __helpers.CSSHelp(document).getStyle('h1')?.getPropertyValue('text-align'); +assert(h1TextAlign === 'center'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + Cafe Menu +--fcc-editable-region-- + +--fcc-editable-region-- + + +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f344fad8bf01691e71a30eb.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f344fad8bf01691e71a30eb.md new file mode 100644 index 00000000000000..0e575b95232495 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f344fad8bf01691e71a30eb.md @@ -0,0 +1,57 @@ +--- +id: 5f344fad8bf01691e71a30eb +title: Paso 11 +challengeType: 0 +dashedName: step-11 +--- + +# --description-- + +Hasta ahora, has estado limitado en cuanto a la presentación y apariencia del contenido que creas. Para empezar a tomar control, añade un elemento `style` dentro del elemento `head`. + +# --hints-- + +Tu código debe tener una etiqueta `` de cierre. + +```js +assert(code.match(/<\/style\s*>/)); +``` + +Tu elemento `style` debe estar anidado dentro del elemento `head`. + +```js +assert(code.match(/[\w\W\s]*[\w\W\s]*<\/style\s*>[\w\W\s]*<\/head\s*>/i)) +``` + +# --seed-- + +## --seed-contents-- + +```html + + +--fcc-editable-region-- + + + Cafe Menu + + +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    + +--fcc-editable-region-- + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f344fbc22624a2976425065.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f344fbc22624a2976425065.md new file mode 100644 index 00000000000000..8877540f986880 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f344fbc22624a2976425065.md @@ -0,0 +1,70 @@ +--- +id: 5f344fbc22624a2976425065 +title: Paso 10 +challengeType: 0 +dashedName: step-10 +--- + +# --description-- + +Crea un elemento `h2` en el elemento `section` y dale el texto `Coffee`. + +# --hints-- + +Debes tener una etiqueta `

    ` de apertura. + +```js +assert(code.match(//i)); +``` + +Debes tener una etiqueta `

    ` de cierre. + +```js +assert(code.match(/<\/h2\s*>/i)); +``` + +No debes modificar el elemento `section` existente. Asegúrate de que no eliminaste tu etiqueta de cierre. + +```js +assert($('section').length === 1); +``` + +Tu elemento `h2` debe estar anidado dentro de tu elemento `section`. + +```js +const h2 = document.querySelector('h2'); +assert(h2.parentElement.tagName === 'SECTION'); +``` + +Tu elemento `h2` debe tener el texto `Coffee`. + +```js +const h2 = document.querySelector('h2'); +assert(h2.innerText === 'Coffee'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + Cafe Menu + + +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +--fcc-editable-region-- +
    +
    +--fcc-editable-region-- +
    + + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f344fc1520b6719f2e35605.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f344fc1520b6719f2e35605.md new file mode 100644 index 00000000000000..38dee0448dbfd2 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f344fc1520b6719f2e35605.md @@ -0,0 +1,61 @@ +--- +id: 5f344fc1520b6719f2e35605 +title: Paso 9 +challengeType: 0 +dashedName: step-9 +--- + +# --description-- + +Habrá dos secciones en el menú, una para cafés (coffes) y otra para postres (desserts). Añade un elemento `section` dentro del elemento `main` para que tengas un lugar donde poner todos los cafés disponibles. + +# --hints-- + +Debes tener una etiqueta `
    ` de apertura. + +```js +assert(code.match(//i)); +``` + +Debes tener una etiqueta `
    ` de cierre. + +```js +assert(code.match(/<\/section\s*>/i)); +``` + +No debes modificar el elemento `main` existente. Asegúrate de que no eliminaste la etiqueta de cierre. + +```js +assert($('main').length === 1); +``` + +Tu elemento `section` debe estar anidado dentro de tu elemento `main`. + +```js +const main = document.querySelectorAll('main')?.[0]; +assert(main.children[0].tagName === 'SECTION'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + Cafe Menu + + +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +--fcc-editable-region-- +
    +
    +--fcc-editable-region-- + + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477ae34c1239cafe128be.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477ae34c1239cafe128be.md new file mode 100644 index 00000000000000..32dd008fd2fbd9 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477ae34c1239cafe128be.md @@ -0,0 +1,73 @@ +--- +id: 5f3477ae34c1239cafe128be +title: Paso 14 +challengeType: 0 +dashedName: step-14 +--- + +# --description-- + +Ahora tienes tres selectores de tipo con exactamente el mismo estilo. Puede añadir el mismo grupo de estilos a varios elementos creando una lista de selectores. Cada selector se separa con comas, de esta forma: + +```css +selector1, selector2 { + property: value; +} +``` + +Usa una lista de selectores para centrar los elementos `h1`, `h2` y `p` al mismo tiempo. + +# --hints-- + +Debes usar un solo selector de tipo para los tres elementos, `h1, h2, p`. Asegúrate de usar ese orden. + +```js +const hasSelector = new __helpers.CSSHelp(document).getStyle('h1, h2, p'); +assert(hasSelector); +``` + +Debes tener un solo selector en el elemento `style`. + +```js +const selectors = new __helpers.CSSHelp(document).getCSSRules().filter(x => x.selectorText) +assert(selectors.length === 1); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + Cafe Menu +--fcc-editable-region-- + +--fcc-editable-region-- + + +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477ae8466a9a3d2cc953c.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477ae8466a9a3d2cc953c.md new file mode 100644 index 00000000000000..e1de33b5132473 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477ae8466a9a3d2cc953c.md @@ -0,0 +1,67 @@ +--- +id: 5f3477ae8466a9a3d2cc953c +title: Paso 16 +challengeType: 0 +dashedName: step-16 +--- + +# --description-- + +Ahora que tienes el código CSS en el archivo `styles.css`, puedes proseguir a eliminar el elemento `style` y todo su contenido. Una vez eliminado, el texto que estaba centrado regresara hacia la izquierda. + +# --hints-- + +No debe tener ninguna etiqueta `style` en tu código. + +```js +assert(!code.match(/style/i)); +``` + +No debes tener ningún selector CSS en tu archivo HTML. + +```js +(getUserInput) => { + const html = getUserInput('editableContents'); + assert(!html.includes('style')); + assert(!html.includes('text-align')); +} +``` + +# --seed-- + +## --seed-contents-- + +```html + + +--fcc-editable-region-- + + + Cafe Menu + + +--fcc-editable-region-- + +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    + + +``` + +```css +h1, h2, p { + text-align: center; +} +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477ae9675db8bb7655b30.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477ae9675db8bb7655b30.md new file mode 100644 index 00000000000000..3c8b796fdcd7fd --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477ae9675db8bb7655b30.md @@ -0,0 +1,87 @@ +--- +id: 5f3477ae9675db8bb7655b30 +title: Paso 13 +challengeType: 0 +dashedName: step-13 +--- + +# --description-- + +En el paso anterior, utilizaste un selector de tipo para darle estilo al elemento `h1`. Ahora centra los elementos `h2` y `p` añadiendo un selector de tipo para cada elemento. + +# --hints-- + +No debes modificar el elemento `h1` existente. + +```js +const hasH1 = new __helpers.CSSHelp(document).getStyle('h1'); +assert(hasH1); +``` + +Debes agregar un nuevo selector `h2`. + +```js +const hasH2 = new __helpers.CSSHelp(document).getStyle('h2'); +assert(hasH2); +``` + +Debes agregar un nuevo selector `p`. + +```js +const hasP = new __helpers.CSSHelp(document).getStyle('p'); +assert(hasP); +``` + +Tu elemento `h1` debe tener una propiedad, `text-align` el valor `center`. + +```js +const h1TextAlign = new __helpers.CSSHelp(document).getStyle('h1')?.getPropertyValue('text-align'); +assert(h1TextAlign === 'center'); +``` + +Tu elemento `h2` deben una propiedad `text-align` con el valor `center`. + +```js +const h2TextAlign = new __helpers.CSSHelp(document).getStyle('h2')?.getPropertyValue('text-align'); +assert(h2TextAlign === 'center'); +``` + +Tu elemento `p` debe tener una propiedad `text-align` con el valor `center`. + +```js +const pTextAlign = new __helpers.CSSHelp(document).getStyle('p')?.getPropertyValue('text-align'); +assert(pTextAlign === 'center'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + Cafe Menu +--fcc-editable-region-- + +--fcc-editable-region-- + + +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477aefa51bfc29327200b.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477aefa51bfc29327200b.md new file mode 100644 index 00000000000000..e339bd686a7d4a --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477aefa51bfc29327200b.md @@ -0,0 +1,77 @@ +--- +id: 5f3477aefa51bfc29327200b +title: Paso 15 +challengeType: 0 +dashedName: step-15 +--- + +# --description-- + +Has dado estilo a tres elementos escribiendo CSS dentro de la etiqueta `style`. Esto funciona, pero dado que habrá muchos más estilos, es mejor poner todos los estilos dentro de un archivo separado y enlazarlo. + +Hemos creado un archivo separado `styles.css` por ti y cambiamos la vista del editor a ese archivo. Puedes moverte entre los archivos mediante las pestañas en la parte superior del editor. + +Comienza reescribiendo, los estilos que ya has creado, en el archivo `styles.css`. Asegúrate de excluir las etiquetas `style` de apertura y cierre. + +# --hints-- + +Tu archivo `styles.css` debe tener los selectores de tipo `h1, h2, p`. + +```js +(getUserInput) => { + assert(getUserInput('editableContents').replace(/[\s\n]*/g, "").match(/(h1|h2|p),(h1|h2|p),(h1|h2|p){/)); +} +``` + +Tu selector debe establecer la propiedad `text-align` al valor `center`. + +```js +(getUserInput) => { + assert(getUserInput('editableContents').match(/text-align:\s*center;?/)); +} +``` + +Debes tener un solo selector. + +```js +(getUserInput) => { + assert(getUserInput('editableContents').match(/text-align:\s*center;?/)?.length === 1); +} +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + Cafe Menu + + + +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    + + +``` + +```css +--fcc-editable-region-- + +--fcc-editable-region-- + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477cb2e27333b1ab2b955.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477cb2e27333b1ab2b955.md new file mode 100644 index 00000000000000..fe58661dadaf7e --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477cb2e27333b1ab2b955.md @@ -0,0 +1,87 @@ +--- +id: 5f3477cb2e27333b1ab2b955 +title: Paso 17 +challengeType: 0 +dashedName: step-17 +--- + +# --description-- + +Ahora tienes que vincular el archivo `styles.css` para que los estilos se apliquen de nuevo. Anida el elemento de cierre automático `link` dentro del elemento `head`. Dale un atributo `rel` con el valor `stylesheet` y un atributo `href` con el valor `styles.css`. + +# --hints-- + +Tu código debe tener un elemento `link`. + +```js +const link = document.querySelector('link'); +assert(link); +``` + +No debes modificar el elemento `head` existente. Asegúrate de no haber eliminado la etiqueta de cierre. + +```js +assert($('head').length === 1); +``` + +Tu elemento `link` debe ser un elemento de cierre automático. + +```js +assert(code.match(//i)); +``` + +Tu elemento `link` debe estar dentro del elemento `head`. + +```js +const link = document.querySelector('head > link'); +assert(link); +``` + +Tu elemento `link` debe tener un atributo `rel` con el valor `stylesheet`. + +```js +const link = document.querySelector('link') +const rel = link.getAttribute('rel') +assert(rel == `stylesheet`) +``` + +Tu elemento `link` debe tener un atributo `href` con el valor `styles.css`. + +```js +const link = document.querySelector('link') +assert(link.dataset.href == 'styles.css') + +``` + +# --seed-- + +## --seed-contents-- + +```html + + +--fcc-editable-region-- + + + Cafe Menu + +--fcc-editable-region-- + +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    + + +``` + +```css +h1, h2, p { + text-align: center; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477cb303c5cb61b43aa9b.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477cb303c5cb61b43aa9b.md new file mode 100644 index 00000000000000..57189fd687c52f --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477cb303c5cb61b43aa9b.md @@ -0,0 +1,70 @@ +--- +id: 5f3477cb303c5cb61b43aa9b +title: Paso 19 +challengeType: 0 +dashedName: step-19 +--- + +# --description-- + +El texto está centrado nuevamente, por lo tanto el vínculo al archivo CSS está funcionando. Añade otro estilo al archivo que cambie la propiedad `background-color` a `brown` para el elemento `body`. + +# --hints-- + +Debes usar un selector `body`. + +```js +const hasBody = new __helpers.CSSHelp(document).getStyle('body'); +assert(hasBody); +``` + +Debes establecer la propiedad `background-color` como `brown`. + +```js +const hasBackground = new __helpers.CSSHelp(document).getCSSRules().some(x => x.style['background-color'] === 'brown'); +assert(hasBackground); +``` + +Tu elemento `body` debe tener un color de fondo (background color) con el valor `brown` (café). + +```js +const bodyBackground = new __helpers.CSSHelp(document).getStyle('body')?.getPropertyValue('background-color'); +assert(bodyBackground === 'brown'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    + + +``` + +```css +--fcc-editable-region-- +h1, h2, p { + text-align: center; +} +--fcc-editable-region-- + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477cbcb6ba47918c1da92.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477cbcb6ba47918c1da92.md new file mode 100644 index 00000000000000..549c4e930bdac6 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477cbcb6ba47918c1da92.md @@ -0,0 +1,72 @@ +--- +id: 5f3477cbcb6ba47918c1da92 +title: Paso 18 +challengeType: 0 +dashedName: step-18 +--- + +# --description-- + +Para que el estilo de la página se vea similar tanto en móvil como en ordenador de escritorio o portátil, necesitas añadir un elemento `meta` con un atributo especial `content`. + +Añade lo siguiente dentro del elemento `head`: + +```html + +``` + +# --hints-- + +Tu código debe tener dos elementos `meta`. + +```js +assert(code.match(//g).length === 2); +``` + +Tu elemento `meta` debe tener un atributo `name` con un valor de `viewport`. + +```js +const meta = $('meta'); +assert(meta[0].outerHTML.match(/name=('|")viewport\1/) || meta[1].outerHTML.match(/name=('|")viewport\1/)); +``` + +Tu elemento `meta` debe tener un atributo `content` con un valor de `width=device-width, initial-scale=1.0`. + +```js +const meta = $('meta'); +assert(meta[0].outerHTML.match(/content=('|")width=device-width, initial-scale=1.0\1/) || meta[1].outerHTML.match(/content=('|")width=device-width, initial-scale=1.0\1/)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +--fcc-editable-region-- + + + Cafe Menu + + +--fcc-editable-region-- + +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    + + +``` + +```css +h1, h2, p { + text-align: center; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f34a1fd611d003edeafd681.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f34a1fd611d003edeafd681.md new file mode 100644 index 00000000000000..7870161253e4c0 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f34a1fd611d003edeafd681.md @@ -0,0 +1,64 @@ +--- +id: 5f34a1fd611d003edeafd681 +title: Paso 20 +challengeType: 0 +dashedName: step-20 +--- + +# --description-- + +Ese fondo color café hace difícil leer el texto. Cambia el color de fondo (background color) del elemento `body` para que sea `burlywood` para que tenga algo de color, pero se pueda leer el texto. + +# --hints-- + +Debes darle el valor `burlywood` a la propiedad `background-color`. + +```js +const hasBackground = new __helpers.CSSHelp(document).getCSSRules().some(x => x.style['background-color'] === 'burlywood'); +assert(hasBackground); +``` + +Tu elemento `body` debe tener un color de fondo `burlywood`. + +```js +const bodyBackground = new __helpers.CSSHelp(document).getStyle('body')?.getPropertyValue('background-color'); +assert(bodyBackground === 'burlywood'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    + + +``` + +```css +--fcc-editable-region-- +body { + background-color: brown; +} +--fcc-editable-region-- +h1, h2, p { + text-align: center; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed60785e1f3e9850b6e.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed60785e1f3e9850b6e.md new file mode 100644 index 00000000000000..f77436629470b8 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed60785e1f3e9850b6e.md @@ -0,0 +1,74 @@ +--- +id: 5f356ed60785e1f3e9850b6e +title: Paso 25 +challengeType: 0 +dashedName: step-25 +--- + +# --description-- + +Ahora es fácil ver que el texto está centrado dentro del elemento `div`. Por ahora, el ancho (width) del elemento `div` está en píxeles (`px`). Cambia el valor de la propiedad `width` a `80%`, para que tenga el 80% del ancho de su elemento padre (`body`). + +# --hints-- + +La propiedad `width` debe tener el valor `80%`. + +```js +const hasWidth = new __helpers.CSSHelp(document).getCSSRules().some(x => x.style.width === '80%'); +assert(hasWidth); +``` + +No debes tener ni una propiedad `width` con el valor `300px`. + +```js +const hasWidth = new __helpers.CSSHelp(document).getCSSRules().some(x => x.style.width === '300px'); +assert(!hasWidth); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + +
    +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    +
    + + +``` + +```css +body { + /* + background-color: burlywood; + */ +} + +h1, h2, p { + text-align: center; +} +--fcc-editable-region-- +div { + width: 300px; + background-color: burlywood; +} +--fcc-editable-region-- +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed60a5decd94ab66986.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed60a5decd94ab66986.md new file mode 100644 index 00000000000000..dd157ec575fad7 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed60a5decd94ab66986.md @@ -0,0 +1,79 @@ +--- +id: 5f356ed60a5decd94ab66986 +title: Paso 23 +challengeType: 0 +removeComments: false +dashedName: step-23 +--- + +# --description-- + +Los comentarios en CSS se ven así: + +```css +/* comment here */ +``` + +En tu hoja de estilos, convierte a un comentario la línea con el valor y la propiedad `background-color`, así podrás ver el efecto de solo darle estilo al elemento `div`. Esto hará que el fondo vuelva a ser blanco. + +# --hints-- + +Debes convertir a un comentario la línea `background-color: burlywood;` de tu código CSS. + +```js +assert(code.match(/\/\*\s*background-color:\s*burlywood;?\s*\*\//i)); +``` + + +Tu elemento `body` debe tener un color de fondo blanco. + +```js +const bodyCSS = $('body').css('background-color'); +assert(bodyCSS === "rgba(0, 0, 0, 0)") +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + +
    +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    +
    + + +``` + +```css +body { +--fcc-editable-region-- + background-color: burlywood; +--fcc-editable-region-- +} + +h1, h2, p { + text-align: center; +} + +div { + width: 300px; +} +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed6199b0cdef1d2be8f.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed6199b0cdef1d2be8f.md new file mode 100644 index 00000000000000..1a0f4599a650d0 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed6199b0cdef1d2be8f.md @@ -0,0 +1,85 @@ +--- +id: 5f356ed6199b0cdef1d2be8f +title: Paso 27 +challengeType: 0 +dashedName: step-27 +--- + +# --description-- + +Hasta ahora has estado usando selectores de tipo para darle estilo a los elementos. Un selector de clase (class selector) se define con un punto e inmediatamente después un nombre, de esta forma: + +```css +.class-name { + styles +} +``` + +Cambia el selector `div` existente a un selector de clase, reemplazando `div` por una clase llamada `menu`. + +# --hints-- + +Debes tener un selector de clase `.menu`. + +```js +const hasMenu = new __helpers.CSSHelp(document).getStyle('.menu'); +assert(hasMenu); +``` + +No debes tener un selector `div`. + +```js +const hasDiv = new __helpers.CSSHelp(document).getStyle('div'); +assert(!hasDiv); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + +
    +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    +
    + + +``` + +```css +body { + /* + background-color: burlywood; + */ +} + +h1, h2, p { + text-align: center; +} + +--fcc-editable-region-- +div { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} +--fcc-editable-region-- +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed63c7807a4f1e6d054.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed63c7807a4f1e6d054.md new file mode 100644 index 00000000000000..73fe86d39855b5 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed63c7807a4f1e6d054.md @@ -0,0 +1,76 @@ +--- +id: 5f356ed63c7807a4f1e6d054 +title: Paso 22 +challengeType: 0 +dashedName: step-22 +--- + +# --description-- + +El objetivo ahora, es hacer que él `div` no ocupe todo el ancho de la página. La propiedad CSS `width`, es perfecta para esto. Crea un nuevo selector de tipo en la hoja de estilos que le dé a tu elemento `div` un ancho dé `300px` utilizando la propiedad width. + +# --hints-- + +Debes tener un selector de tipo `div`. + +```js +const hasDiv = new __helpers.CSSHelp(document).getStyle('div'); +assert(hasDiv); +``` + +La propiedad `width` debe tener el valor `300px`. + +```js +const hasWidth = new __helpers.CSSHelp(document).getCSSRules().some(x => x.style.width === '300px'); +assert(hasWidth); +``` + +Tu elemento `div` debe tener un ancho de 300px. + +```js +const divWidth = new __helpers.CSSHelp(document).getStyle('div')?.getPropertyValue('width'); +assert(divWidth === '300px'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + +
    +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    +
    + + +``` + +```css +--fcc-editable-region-- +body { + background-color: burlywood; +} + +h1, h2, p { + text-align: center; +} +--fcc-editable-region-- + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed63e0fa262326eef05.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed63e0fa262326eef05.md new file mode 100644 index 00000000000000..ff3d6277e514f8 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed63e0fa262326eef05.md @@ -0,0 +1,74 @@ +--- +id: 5f356ed63e0fa262326eef05 +title: Paso 24 +challengeType: 0 +dashedName: step-24 +--- + +# --description-- + +Ahora utiliza el selector `div` existente, para darle un color de fondo `burlywood` al elemento `div`. + +# --hints-- + +Debes darle el valor `burlywood` a la propiedad `background-color`. + +```js +const hasBackgroundColor = new __helpers.CSSHelp(document).getCSSRules().some(x => x.style['background-color'] === 'burlywood'); +assert(hasBackgroundColor); +``` + +Tu elemento `div` debe tener un color de fondo burlywood. + +```js +const divBackground = new __helpers.CSSHelp(document).getStyle('div')?.getPropertyValue('background-color'); +assert(divBackground === 'burlywood'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + +
    +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    +
    + + +``` + +```css +body { + /* + background-color: burlywood; + */ +} + +h1, h2, p { + text-align: center; +} + +--fcc-editable-region-- +div { + width: 300px; +} +--fcc-editable-region-- +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed656a336993abd9f7c.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed656a336993abd9f7c.md new file mode 100644 index 00000000000000..fa0e1129ce6c2a --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed656a336993abd9f7c.md @@ -0,0 +1,83 @@ +--- +id: 5f356ed656a336993abd9f7c +title: Paso 26 +challengeType: 0 +dashedName: step-26 +--- + +# --description-- + +Ahora centraremos horizontalmente él `div`. Puedes hacer esto, dándole el valor `auto` a las propiedades `margin-left` y `margin-right` (margen-izquierdo y margen-derecho). Piensa en el margen como un espacio invisible alrededor de un elemento. Usando estas dos propiedades de margen, centra el elemento `div` dentro del elemento `body`. + +# --hints-- + +La propiedad `margin-left` debe tener el valor `auto`. + +```js +const hasMargin = new __helpers.CSSHelp(document).getCSSRules().some(x => x.style['margin-left'] === 'auto'); +assert(hasMargin); +``` + +La propiedad `margin-right` debe tener el valor `auto`. + +```js +const hasMargin = new __helpers.CSSHelp(document).getCSSRules().some(x => x.style['margin-right'] === 'auto'); +assert(hasMargin); +``` + +Debes darle el valor `auto` a las propiedades `margin-left` y `margin-right` del elemento `div`. + +```js +const divMarginRight = new __helpers.CSSHelp(document).getStyle('div')?.getPropertyValue('margin-right'); +const divMarginLeft = new __helpers.CSSHelp(document).getStyle('div')?.getPropertyValue('margin-left'); +assert(divMarginRight === 'auto'); +assert(divMarginLeft === 'auto'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + +
    +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    +
    + + +``` + +```css +body { + /* + background-color: burlywood; + */ +} + +h1, h2, p { + text-align: center; +} + +--fcc-editable-region-- +div { + width: 80%; + background-color: burlywood; +} +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed69db0a491745e2bb6.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed69db0a491745e2bb6.md new file mode 100644 index 00000000000000..3a0a57829d205a --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed69db0a491745e2bb6.md @@ -0,0 +1,75 @@ +--- +id: 5f356ed69db0a491745e2bb6 +title: Paso 28 +challengeType: 0 +dashedName: step-28 +--- + +# --description-- + +Para aplicar el estilo al elemento `div`, añade un atributo `class` al elemento `div` con el valor `menu`. + +# --hints-- + +El elemento `div` aún debería ser visible. Asegúrate de que no has modificado incorrectamente la etiqueta `
    `. + +```js +assert($('div').length === 1); +``` + +Tu elemento `div` debe tener un atributo class (clase) con el valor `menu`. + +```js +assert($('div').attr('class').includes('menu')); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + +--fcc-editable-region-- +
    +--fcc-editable-region-- +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    +
    + + +``` + +```css +body { + /* + background-color: burlywood; + */ +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed6cf6eab5f15f5cfe6.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed6cf6eab5f15f5cfe6.md new file mode 100644 index 00000000000000..92ec125bf89fd9 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f356ed6cf6eab5f15f5cfe6.md @@ -0,0 +1,77 @@ +--- +id: 5f356ed6cf6eab5f15f5cfe6 +title: Paso 21 +challengeType: 0 +dashedName: step-21 +--- + +# --description-- + +El elemento `div` se utiliza principalmente para própositos de diseño a diferencia de los otros elementos de contenido que has usado hasta ahora. Añade un elemento `div` dentro del elemento `body` y luego mueve todos los demás elementos dentro del nuevo `div`. + +# --hints-- + +Debes tener una etiqueta `
    ` de apertura. + +```js +assert(code.match(/
    /i)); +``` + +Debes tener una etiqueta `
    ` de cierre. + +```js +assert(code.match(/<\/div>/i)); +``` + +No debes modificar el elemento `body` existente. Asegúrate de que no eliminaste la etiqueta de cierre. + +```js +assert($('body').length === 1); +``` + +Tu etiqueta `div` debe estar anidada dentro del elemento `body`. + +```js +const div = $('div')[0]; +assert(div.parentElement.tagName === 'BODY'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + +--fcc-editable-region-- + +
    +

    CAMPER CAFE

    +

    Est. 2020

    +
    +
    +
    +

    Coffee

    +
    +
    + +--fcc-editable-region-- + +``` + +```css +body { + background-color: burlywood; +} + +h1, h2, p { + text-align: center; +} +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f35e5c4321f818cdc4bed30.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f35e5c4321f818cdc4bed30.md new file mode 100644 index 00000000000000..dabed358e01134 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f35e5c4321f818cdc4bed30.md @@ -0,0 +1,86 @@ +--- +id: 5f35e5c4321f818cdc4bed30 +title: Paso 30 +challengeType: 0 +dashedName: step-30 +--- + +# --description-- + +Se ve bien. Es hora de empezar a añadir algunos elementos al menú. Añade un elemento `article` vacío debajo del encabezado `Coffee`. Contendrá el sabor y precio de cada café que estás ofreciendo. + +# --hints-- + +Debes tener una etiqueta `
    ` de apertura. + +```js +assert(code.match(/
    /i)); +``` + +Debes tener una etiqueta `
    ` de cierre. + +```js +assert(code.match(/<\/article>/i)); +``` + +No debes modificar el elemento `h2` existente. + +```js +assert($('h2').length === 1); +``` + +Tu elemento `article` debe estar después del elemento `h2`. + +```js +const article = $('article')[0]; +assert(article.previousElementSibling.tagName === 'H2'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f35e5c44359872a137bd98f.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f35e5c44359872a137bd98f.md new file mode 100644 index 00000000000000..6a8b0bc053c312 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f35e5c44359872a137bd98f.md @@ -0,0 +1,92 @@ +--- +id: 5f35e5c44359872a137bd98f +title: Paso 29 +challengeType: 0 +dashedName: step-29 +--- + +# --description-- + +Ya que el producto principal a la venta en la cafetería es el café, podrías utilizar una imagen de granos de café como imagen de fondo. + +Elimina el comentario y su contenido dentro del selector de tipo `body`. Ahora añade una propiedad `background-image` y dale el valor `url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg)`. + +# --hints-- + +Debes eliminar el comentario con la propiedad `background-color`. + +```js +assert(!code.match(/\/\*\s*background-color:\s*burlywood;?\s*\*\//i)) +``` + +Tu selector `body` no debe tener ningún comentario. + +```js +assert(!code.match(/body\s*{\s*\/\*/i)); +``` + +La propiedad `background-image` debe tener el valor `url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg)`. + +```js +const hasBackground = new __helpers.CSSHelp(document).getCSSRules().some(x => x.style['background-image'] === `url("https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg")`) +assert(hasBackground) +``` + +Tu elemento `body` debe tener una imagen de granos de café como imagen de fondo. + +```js +const bodyBackground = new __helpers.CSSHelp(document).getStyle('body')?.getPropertyValue('background-image'); +console.log(bodyBackground); +assert(bodyBackground === `url("https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg")`); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +--fcc-editable-region-- +body { + /* + background-color: burlywood; + */ +} +--fcc-editable-region-- + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3c866d0fc037f7311b4ac8.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3c866d0fc037f7311b4ac8.md new file mode 100644 index 00000000000000..08ab5b8d8fcea2 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3c866d0fc037f7311b4ac8.md @@ -0,0 +1,107 @@ +--- +id: 5f3c866d0fc037f7311b4ac8 +title: Paso 39 +challengeType: 0 +dashedName: step-39 +--- + +# --description-- + +Así está mejor, pero el precio no se quedó en la derecha. Esto se debe a que los elementos de `inline-block` solo ocupan el ancho de su contenido. Para extenderlos, añade una propiedad `width` a los selectores de clase `flavor` y `price` dándoles un valor de `50%` a cada uno. + +# --hints-- + +La propiedad `width` del selector de clase `.flavor` debe tener un valor de `50%`. + +```js +const flavorWidth = new __helpers.CSSHelp(document).getStyle('.flavor')?.getPropertyValue('width'); +assert(flavorWidth === '50%'); +``` + +La propiedad `width` del selector de clase `.price` debe tener un valor de `50%`. + +```js +const priceWidth = new __helpers.CSSHelp(document).getStyle('.price')?.getPropertyValue('width'); +assert(priceWidth === '50%'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} + +.item p { + display: inline-block; +} + +--fcc-editable-region-- +.flavor { + text-align: left; +} + +.price { + text-align: right; +} +--fcc-editable-region-- +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3c866d28d7ad0de6470505.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3c866d28d7ad0de6470505.md new file mode 100644 index 00000000000000..57e0a9d571e7fb --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3c866d28d7ad0de6470505.md @@ -0,0 +1,100 @@ +--- +id: 5f3c866d28d7ad0de6470505 +title: Paso 33 +challengeType: 0 +dashedName: step-33 +--- + +# --description-- + +Por ahora, los sabores y precios están uno encima del otro y se centran con su respectivo elemento `p`. Sería mejor si el sabor estuviera en la izquierda y el precio estuviera en la derecha. + +Al elemento `p` con el texto `French Vanilla` agrégale un atributo class con el valor `flavor`. + +# --hints-- + +Debes agregar un atributo class con el valor `flavor` a tu elemento `p`. + +```js +assert(code.match(//i)); +``` + +Solo debes tener un elemento con el atributo class y el valor `flavor`. + +```js +assert($('.flavor').length === 1); +``` + +El atributo class con el valor `flavor` debe estar en el elemento `p` con el texto `French Vanilla`. + +```js +assert($('.flavor')[0].innerText.match(/French Vanilla/i)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3c866d5414453fc2d7b480.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3c866d5414453fc2d7b480.md new file mode 100644 index 00000000000000..712a0633479cc3 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3c866d5414453fc2d7b480.md @@ -0,0 +1,128 @@ +--- +id: 5f3c866d5414453fc2d7b480 +title: Paso 32 +challengeType: 0 +dashedName: step-32 +--- + +# --description-- + +Empezando debajo del par café/precio existente, añade los siguientes cafés y precios, utilizando elementos `article` con dos elementos `p` anidados dentro de cada uno. Al igual que antes, el texto del primer elemento `p` debe ser el sabor al café y el texto del segundo elemento `p` debe ser el precio. + +```bash +Caramel Macchiato 3.75 +Pumpkin Spice 3.50 +Hazelnut 4.00 +Mocha 4.50 +``` + +# --hints-- + +Debes tener cinco elementos `article`. + +```js +assert($('article').length === 5); +``` + +Cada elemento `article` debe tener dos elementos `p`. + +```js +const articles = $('article'); +assert(articles[0].children.length === 2); +assert(articles[1].children.length === 2); +assert(articles[2].children.length === 2); +assert(articles[3].children.length === 2); +assert(articles[4].children.length === 2); +``` + +Tu primer elemento `article` debe tener elementos `p` con los textos `French Vanilla` y `3.00`. + +```js +const children = $('article')[0].children; +assert(children[0].innerText.match(/French Vanilla/i)); +assert(children[1].innerText.match(/3\.00/i)); +``` + +Tu segundo elemento `article` debe tener elementos `p` con los textos `Caramel Macchiato` y `3.75`. + +```js +const children = $('article')[1].children; +assert(children[0].innerText.match(/Caramel Macchiato/i)); +assert(children[1].innerText.match(/3\.75/i)); +``` + +Tu tercer elemento `article` debe tener elementos `p` con los textos `Pumpkin Spice` y `3.50`. + +```js +const children = $('article')[2].children; +assert(children[0].innerText.match(/Pumpkin Spice/i)); +assert(children[1].innerText.match(/3\.50/i)); +``` + +Tu cuarto elemento `article` debe tener elementos `p` con los textos `Hazelnut` y `4.00`. + +```js +const children = $('article')[3].children; +assert(children[0].innerText.match(/Hazelnut/i)); +assert(children[1].innerText.match(/4\.00/i)); +``` + +Tu quinto elemento `article` debe tener elementos `p` con los textos `Mocha` y `4.50`. + +```js +const children = $('article')[4].children; +assert(children[0].innerText.match(/Mocha/i)); +assert(children[1].innerText.match(/4\.50/i)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3c866daec9a49519871816.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3c866daec9a49519871816.md new file mode 100644 index 00000000000000..1567372af94718 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3c866daec9a49519871816.md @@ -0,0 +1,88 @@ +--- +id: 5f3c866daec9a49519871816 +title: Paso 31 +challengeType: 0 +dashedName: step-31 +--- + +# --description-- + +Los elementos `article` comúnmente contienen múltiples elementos que tienen información relacionada. En este caso, contendrá un sabor de café y un precio para ese sabor. Anida dos elementos `p` dentro de tu elemento `article`. El texto del primero será `French Vanilla`, y el texto del segundo será `3.00`. + +# --hints-- + +No debes modificar el elemento `article` existente. + +```js +assert($('article').length === 1); +``` + +Tu elemento `article` debe tener dos elementos `p`. + +```js +assert($('article').children('p').length === 2); +``` + +Tu primer elemento `p` debe tener el texto `French Vanilla`. + +```js +const firstP = $('article').children('p')[0]; +assert(firstP.innerText.match(/French Vanilla/i)); +``` + +Tu segundo elemento `p` debe tener el texto `3.00`. + +```js +const secondP = $('article').children('p')[1]; +assert(secondP.innerText.match(/3\.00/i)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3c866dd0d0275f01d4d847.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3c866dd0d0275f01d4d847.md new file mode 100644 index 00000000000000..4f495b30673cfa --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3c866dd0d0275f01d4d847.md @@ -0,0 +1,111 @@ +--- +id: 5f3c866dd0d0275f01d4d847 +title: Paso 40 +challengeType: 0 +dashedName: step-40 +--- + +# --description-- + +Bueno, eso no funcionó. Cambiar los elementos `p` a `inline-block` y colocarlos en líneas diferentes crea un espacio extra a la derecha del primer elemento `p`, haciendo que el segundo se mueva a la siguiente línea. Una forma de arreglar esto, es hacer que el ancho (width) de cada elemento `p` sea un poco menor que `50%`. + +Cambia el valor de la propiedad `width` a `49%` en cada clase para ver qué sucede. + +# --hints-- + +Debes darle un valor de `49%` a la propiedad `width` en tu selector de clase `.flavor`. + +```js +const flavorWidth = new __helpers.CSSHelp(document).getStyle('.flavor')?.getPropertyValue('width'); +assert(flavorWidth === '49%'); +``` + +Debes darle un valor de `49%` a la propiedad `width` en tu selector de clase `.price`. + +```js +const priceWidth = new __helpers.CSSHelp(document).getStyle('.price')?.getPropertyValue('width'); +assert(priceWidth === '49%'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} + +.item p { + display: inline-block; +} + +--fcc-editable-region-- +.flavor { + text-align: left; + width: 50%; +} + +.price { + text-align: right; + width: 50%; +} +--fcc-editable-region-- +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3cade94c6576e7f7b7953f.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3cade94c6576e7f7b7953f.md new file mode 100644 index 00000000000000..79e1b552d82c59 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3cade94c6576e7f7b7953f.md @@ -0,0 +1,108 @@ +--- +id: 5f3cade94c6576e7f7b7953f +title: Paso 42 +challengeType: 0 +dashedName: step-42 +--- + +# --description-- + +Ahora, sigue adelante y cambia la anchura de las clases `flavor` y `price` de nuevo a `50%`. + +# --hints-- + +Debes establecer la propiedad `width` a `50%` en tu selector `.flavor`. + +```js +const flavorWidth = new __helpers.CSSHelp(document).getStyle('.flavor')?.getPropertyValue('width'); +assert(flavorWidth === '50%'); +``` + +Debes establecer la propiedad `width` a `50%` en tu selector `.price`. + +```js +const priceWidth = new __helpers.CSSHelp(document).getStyle('.price')?.getPropertyValue('width'); +assert(priceWidth === '50%'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} + +.item p { + display: inline-block; +} + +--fcc-editable-region-- +.flavor { + text-align: left; + width: 49%; +} + +.price { + text-align: right; + width: 49%; +} +--fcc-editable-region-- +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3cade9993019e26313fa8e.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3cade9993019e26313fa8e.md new file mode 100644 index 00000000000000..c2005a7d2c7d7b --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3cade9993019e26313fa8e.md @@ -0,0 +1,119 @@ +--- +id: 5f3cade9993019e26313fa8e +title: Paso 43 +challengeType: 0 +dashedName: step-43 +--- + +# --description-- + +Ahora que sabes que funciona, puedes modificar los elementos `article` y `p` restantes para que coincidan con el primer conjunto. Empieza añadiendo la clase `item` a los demás elementos `article`. + +# --hints-- + +Debes tener solamente cinco elementos `article`. + +```js +assert($('article').length === 5); +``` + +Debes tener solamente cinco elementos `.item`. + +```js +assert($('.item').length === 5); +``` + +Tus elementos `.item` y tus elementos `article` deben ser los mismos. + + +```js +const articles = $('article'); +const items = $('.item'); +assert(articles[0] === items[0]); +assert(articles[1] === items[1]); +assert(articles[2] === items[2]); +assert(articles[3] === items[3]); +assert(articles[4] === items[4]); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} + +.item p { + display: inline-block; +} + +.flavor { + text-align: left; + width: 50%; +} + +.price { + text-align: right; + width: 50%; +} +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3cade99dda4e6071a85dfd.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3cade99dda4e6071a85dfd.md new file mode 100644 index 00000000000000..76eb20848f55fa --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3cade99dda4e6071a85dfd.md @@ -0,0 +1,114 @@ +--- +id: 5f3cade99dda4e6071a85dfd +title: Paso 47 +challengeType: 0 +dashedName: step-47 +--- + +# --description-- + +En los siguientes pasos volverás a darle estilo al menú, pero por ahora; debajo del primer elemento section, añade un nuevo elemento `section` para mostrar los postres que ofrece la cafetería. + +# --hints-- + +Debes tener una etiqueta `section` de apertura. + +```js +assert(code.match(/
    /ig).length === 2); +``` + +Debes tener una etiqueta `section` de cierre. + +```js +assert(code.match(/<\/section>/ig).length === 2); +``` + +No debes modificar el elemento `main` existente. + +```js +assert($('main').length === 1); +``` + +Tu nuevo elemento `section` debe estar anidado dentro del elemento `main`. + +```js +assert($('main').children('section').length === 2); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} + +.item p { + display: inline-block; +} + +.flavor { + text-align: left; + width: 75%; +} + +.price { + text-align: right; + width: 25% +} +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3cade9fa77275d9f4efe62.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3cade9fa77275d9f4efe62.md new file mode 100644 index 00000000000000..281db7166e9f10 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3cade9fa77275d9f4efe62.md @@ -0,0 +1,103 @@ +--- +id: 5f3cade9fa77275d9f4efe62 +title: Paso 41 +challengeType: 0 +dashedName: step-41 +--- + +# --description-- + +Eso funcionó, pero todavía hay un poco de espacio a la derecha del precio. + +Podrías seguir probando diferentes porcentajes para la propiedad width (ancho). En su lugar, simplemente mueve el elemento `p` con el precio, para que los elementos p estén en la misma línea y sin espacios entre ellos. + +# --hints-- + +No debe haber ningún espacio entre tus elementos `p`. + +```js +assert(code.match(/Vanilla<\/p>

    + + + + + Cafe Menu + + + +

    + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} + +.item p { + display: inline-block; +} + +.flavor { + text-align: left; + width: 49%; +} + +.price { + text-align: right; + width: 49%; +} +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e05473f91f948724ab.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e05473f91f948724ab.md new file mode 100644 index 00000000000000..e4f78d46d3f563 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e05473f91f948724ab.md @@ -0,0 +1,121 @@ +--- +id: 5f3ef6e05473f91f948724ab +title: Paso 58 +challengeType: 0 +dashedName: step-58 +--- + +# --description-- + +Puedes cambiar la fuente (`font-family`) del texto, para que luzca diferente de la fuente predeterminada de tu navegador. Cada navegador cuenta con algunas fuentes comunes disponibles. + +Cambia todo el texto de tu elemento `body`, añadiendo una propiedad `font-family` con el valor `sans-serif`. Esta es una fuente común, la cual es bastante legible. + +# --hints-- + +La propiedad `font-family` debe tener el valor `sans-serif`. + +```js +const hasFontFamily = new __helpers.CSSHelp(document).getCSSRules().some(x => x.style['font-family'] === 'sans-serif'); +``` + +La propiedad `font-family` debe de darle a tu elemento `body` la fuente `sans-serif`. + +```js +const bodyFontFamily = new __helpers.CSSHelp(document).getStyle('body')?.getPropertyValue('font-family'); +assert(bodyFontFamily === 'sans-serif'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +--fcc-editable-region-- +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} +--fcc-editable-region-- + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; + padding: 20px; + max-width: 500px; +} + +.item p { + display: inline-block; +} + +.flavor, .dessert { + text-align: left; + width: 75%; +} + +.price { + text-align: right; + width: 25% +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e0819d4f23ca7285e6.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e0819d4f23ca7285e6.md new file mode 100644 index 00000000000000..7c86a906db240b --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e0819d4f23ca7285e6.md @@ -0,0 +1,111 @@ +--- +id: 5f3ef6e0819d4f23ca7285e6 +title: Paso 49 +challengeType: 0 +dashedName: step-49 +--- + +# --description-- + +Añade un elemento `article` vacío debajo del título `Desserts`. Dale un atributo `class` con el valor `item`. + +# --hints-- + +No debes modificar el elemento `h2` existente. + +```js +assert($('h2').length === 2); +``` + +Tu elemento `article` debe estar debajo del elemento `h2`. + +```js +assert($('section')[1].children[1].tagName === 'ARTICLE'); +``` + +Tu nuevo elemento, `article` una clase (class) `item`. + +```js +assert($('section')[1].children[1].className === 'item'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} + +.item p { + display: inline-block; +} + +.flavor { + text-align: left; + width: 75%; +} + +.price { + text-align: right; + width: 25% +} +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e0a81099d9a697b550.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e0a81099d9a697b550.md new file mode 100644 index 00000000000000..74f66b2b2b6e57 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e0a81099d9a697b550.md @@ -0,0 +1,156 @@ +--- +id: 5f3ef6e0a81099d9a697b550 +title: Paso 65 +challengeType: 0 +dashedName: step-65 +--- + +# --description-- + +Dentro del elemento `footer`, añade un elemento `p`. Después, anida un elemento anchor (`a`) en el elemento `p` que enlace a `https://www.freecodecamp.org` y tenga el texto `Visit our website`. + +# --hints-- + +No debes modificar el elemento `footer` existente. + +```js +assert($('footer').length === 1); +``` + +Tu elemento nuevo elemento `p` debe estar anidado dentro de tu elemento `footer`. + +```js +assert($('footer').children('p').length === 1); +``` + +Tu nuevo elemento `a` debe ser anidado dentro de tu nuevo elemento `p`. + +```js +assert($('footer').children('p').children('a').length === 1); +``` + +Tu nuevo elemento `a` debe tener el texto `Visit our website`. + +```js +assert($('footer').find('a')[0].innerText.match(/Visit our website/i)); +``` + +Tu nuevo elemento `a` te debe enlazar a `https://www.freecodecamp.org`. Recuerda que los elementos `a` utilizan el atributo `href` para crear un enlace. + +```js +assert($('footer').find('a').attr('href') === 'https://www.freecodecamp.org'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); + font-family: sans-serif; +} + +h1 { + font-size: 40px; +} + +h2 { + font-size: 30px; +} + +.established { + font-style: italic; +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; + padding: 20px; + max-width: 500px; +} + +h1, h2 { + font-family: Impact, serif; +} + +.item p { + display: inline-block; +} + +.flavor, .dessert { + text-align: left; + width: 75%; +} + +.price { + text-align: right; + width: 25% +} +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e0e0c3feaebcf647ad.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e0e0c3feaebcf647ad.md new file mode 100644 index 00000000000000..e51fdca288effd --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e0e0c3feaebcf647ad.md @@ -0,0 +1,110 @@ +--- +id: 5f3ef6e0e0c3feaebcf647ad +title: Paso 48 +challengeType: 0 +dashedName: step-48 +--- + +# --description-- + +Añade un elemento `h2` con el texto `Desserts` dentro del nuevo elemento section. + +# --hints-- + +No debes modificar el elemento `section` existente. + +```js +assert($('section').length === 2); +``` + +Debes anidar un elemento `h2` dentro del segundo elemento `section`. + +```js +assert($('section')[1].children[0].tagName === 'H2'); +``` + +Tu nuevo elemento `h2` debe tener el texto `Desserts`. + +```js +assert($('h2')[1].innerText.match(/Desserts/i)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} + +.item p { + display: inline-block; +} + +.flavor { + text-align: left; + width: 75%; +} + +.price { + text-align: right; + width: 25% +} +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f4701b942c824109626c3d8.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f4701b942c824109626c3d8.md new file mode 100644 index 00000000000000..e9f151fc1d3e96 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f4701b942c824109626c3d8.md @@ -0,0 +1,157 @@ +--- +id: 5f4701b942c824109626c3d8 +title: Paso 77 +challengeType: 0 +dashedName: step-77 +--- + +# --description-- + +Ahora añade la clase `bottom-line` al segundo elemento `hr` para que se aplique el estilo. + +# --hints-- + +Debes aplicar la propiedad `class="bottom-line"`. + +```js +assert(code.match(/class=('|")bottom-line\1/i)); +``` + +Tu clase `bottom-line` debe aplicarse al segundo elemento `hr`. + +```js +assert($('hr')[1].className === 'bottom-line'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); + font-family: sans-serif; + padding: 20px; +} + +h1 { + font-size: 40px; +} + +h2 { + font-size: 30px; +} + +.established { + font-style: italic; +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; + padding: 20px; + max-width: 500px; +} + +hr { + height: 2px; + background-color: brown; + border-color: brown; +} + +.bottom-line { + margin-top: 25px; +} + +h1, h2 { + font-family: Impact, serif; +} + +.item p { + display: inline-block; + margin-top: 5px; + margin-bottom: 5px; + font-size: 18px; +} + +.flavor, .dessert { + text-align: left; + width: 75%; +} + +.price { + text-align: right; + width: 25% +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f47633757ae3469f2d33d2e.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f47633757ae3469f2d33d2e.md new file mode 100644 index 00000000000000..2fa32f10bd5fd5 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f47633757ae3469f2d33d2e.md @@ -0,0 +1,106 @@ +--- +id: 5f47633757ae3469f2d33d2e +title: Paso 46 +challengeType: 0 +dashedName: step-46 +--- + +# --description-- + +Si reduces el ancho de la ventana donde se muestra la vista previa, llegara un punto donde parte del texto de la izquierda saltará a la siguiente línea. Esto se debe a que el ancho de los elementos `p` del lado izquierdo solo pueden tomar `50%` del espacio. + +Como sabemos que los precios de la derecha tienen menos caracteres, cambia el valor de la propiedad `width` del selector de clase `flavor` a `75%` y el valor de la propiedad `width` del selector de clase `price` a `25%`. + +# --hints-- + +La propiedad `width` del selector de clase `.flavor` debe tener un valor dé `75%`. + +```js +const flavorWidth = new __helpers.CSSHelp(document).getStyle('.flavor')?.getPropertyValue('width'); +assert(flavorWidth === '75%'); +``` + +Debes darle un valor de `25%` a la propiedad `width` de tu selector de clase `.price`. + +```js +const priceWidth = new __helpers.CSSHelp(document).getStyle('.price')?.getPropertyValue('width'); +assert(priceWidth === '25%'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} + +.item p { + display: inline-block; +} + +--fcc-editable-region-- +.flavor { + text-align: left; + width: 50%; +} + +.price { + text-align: right; + width: 50%; +} +--fcc-editable-region-- +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f716ad029ee4053c7027a7a.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f716ad029ee4053c7027a7a.md new file mode 100644 index 00000000000000..14859abcd69a1a --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f716ad029ee4053c7027a7a.md @@ -0,0 +1,119 @@ +--- +id: 5f716ad029ee4053c7027a7a +title: Paso 50 +challengeType: 0 +dashedName: step-50 +--- + +# --description-- + +Anida dos elementos `p` dentro de tu elemento `article`. El texto del primero será `Donut`, y el texto del segundo será `1.50`. Coloca ambos elementos p en la misma línea, asegurándote de que no haya ningún espacio entre ellos. + +# --hints-- + +No debes modificar el elemento `article` existente. + +```js +assert($('article').length === 6); +``` + +Tu elemento `article` debe tener dos elementos `p`. + +```js +assert($('article').last().children('p').length === 2); +``` + +Tu primer elemento `p` debe tener el texto `Donut`. + +```js +assert($('article').last().children('p')[0].innerText.match(/Donut/i)); +``` + +Tu segundo elemento `p` debe tener el texto `1.50`. + +```js +assert($('article').last().children('p')[1].innerText.match(/1\.50/i)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} + +.item p { + display: inline-block; +} + +.flavor { + text-align: left; + width: 75%; +} + +.price { + text-align: right; + width: 25% +} +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f7691dafd882520797cd2f0.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f7691dafd882520797cd2f0.md new file mode 100644 index 00000000000000..7e5814b6bdb9cc --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f7691dafd882520797cd2f0.md @@ -0,0 +1,100 @@ +--- +id: 5f7691dafd882520797cd2f0 +title: Paso 44 +challengeType: 0 +dashedName: step-44 +--- + +# --description-- + +A continuación, mueve los otros elementos `p` para que estén en la misma línea sin espacios entre ellos. + +# --hints-- + +No debe haber ningún espacio entre sus elementos `p`. + +```js +assert(!code.match(/<\/p>\s+

    + + + + + Cafe Menu + + + +

    + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} + +.item p { + display: inline-block; +} + +.flavor { + text-align: left; + width: 50%; +} + +.price { + text-align: right; + width: 50%; +} +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f7692f7c5b3ce22a57788b6.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f7692f7c5b3ce22a57788b6.md new file mode 100644 index 00000000000000..7d5bb02ef0a2e8 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f7692f7c5b3ce22a57788b6.md @@ -0,0 +1,126 @@ +--- +id: 5f7692f7c5b3ce22a57788b6 +title: Paso 45 +challengeType: 0 +dashedName: step-45 +--- + +# --description-- + +Para terminar de agregar estilos, agrega las clases `flavor` y `price` a todos los elementos `p` restantes. + +# --hints-- + +Debes tener cinco elementos `.flavor`. + +```js +assert($('.flavor').length === 5); +``` + +Debes tener cinco elementos `.price`. + +```js +assert($('.price').length === 5); +``` + +Tus elementos `.flavor` deben ser los mismos elementos `p` con los textos `French Vanilla`, `Caramel Macchiato`, `Pumpkin Spice`, `Hazelnut` y `Mocha`. + +```js +const p = $('p'); +const flavor = $('.flavor'); +assert(p[1] === flavor[0]); +assert(p[3] === flavor[1]); +assert(p[5] === flavor[2]); +assert(p[7] === flavor[3]); +assert(p[9] === flavor[4]); +``` + +Tus elementos `.price` deben ser los mismos elementos `p` con los textos `3.00`, `3.75`, `3.50`, `4.00` y `4.50`. + +```js +const p = $('p'); +const price = $('.price'); +assert(p[2] === price[0]); +assert(p[4] === price[1]); +assert(p[6] === price[2]); +assert(p[8] === price[3]); +assert(p[10] === price[4]); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} + +.item p { + display: inline-block; +} + +.flavor { + text-align: left; + width: 50%; +} + +.price { + text-align: right; + width: 50%; +} +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f769541be494f25449b292f.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f769541be494f25449b292f.md new file mode 100644 index 00000000000000..186677bcfbf1c4 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f769541be494f25449b292f.md @@ -0,0 +1,105 @@ +--- +id: 5f769541be494f25449b292f +title: Paso 34 +challengeType: 0 +dashedName: step-34 +--- + +# --description-- + +Utilizando la nueva clase (class) `flavor` como un selector de clase, a la propiedad `text-align` dale el valor `left`. + +# --hints-- + +Debes tener un selector de clase `flavor`. + +```js +const hasFlavor = new __helpers.CSSHelp(document).getStyle('.flavor'); +assert(hasFlavor); +``` + +La propiedad `text-align` Debe tener el valor `left`. + +```js +const hasTextAlign = new __helpers.CSSHelp(document).getCSSRules().some(x => x.style['text-align'] === 'left'); +assert(hasTextAlign); +``` + +El selector de clase `flavor` debe de darle a la propiedad `text-align` el valor `left`. + +```js +const flavorTextAlign = new __helpers.CSSHelp(document).getStyle('.flavor')?.getPropertyValue('text-align'); +assert(flavorTextAlign === 'left'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f769702e6e33127d14aa120.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f769702e6e33127d14aa120.md new file mode 100644 index 00000000000000..c3099796f76820 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f769702e6e33127d14aa120.md @@ -0,0 +1,106 @@ +--- +id: 5f769702e6e33127d14aa120 +title: Paso 36 +challengeType: 0 +dashedName: step-36 +--- + +# --description-- + +Ahora alinea a la derecha los elementos con la clase `price` utilizando la propiedad text-align y el valor `right`. + +# --hints-- + +Debes tener un selector de clase `price`. + +```js +assert(code.match(/\.price\s*{/i)); +``` + +El selector de clase `price` debe tener una propiedad `text-align` con el valor `right`. + +```js +assert(code.match(/\.price\s*{\s*text-align:\s*right;?/i)); +``` + +Tu elemento `.price` debe estar alineado a la derecha. + +```js +assert($('.price').css('text-align') === 'right'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} + +.flavor { + text-align: left; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f7b87422a560036fd03ccff.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f7b87422a560036fd03ccff.md new file mode 100644 index 00000000000000..91bab8f340cef6 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f7b87422a560036fd03ccff.md @@ -0,0 +1,120 @@ +--- +id: 5f7b87422a560036fd03ccff +title: Paso 51 +challengeType: 0 +dashedName: step-51 +--- + +# --description-- + +A los dos elementos `p` que acabas de añadir, añade un atributo `class` con el valor `dessert` al primer elemento `p` y un atributo `class` con el valor `price` al segundo elemento `p`. + +# --hints-- + +Debes tener un elemento `p` con la clase `dessert`. + +```js +assert($('.dessert').length === 1); +``` + +Tu elemento `p` con el texto `Donut` debe tener una clase `dessert`. + +```js +assert($('.dessert')[0].innerText.match(/donut/i)); +``` + +Tu elemento `p` con el texto `1.50` debe tener una clase `price`. + +```js +assert($('.price').last().text().match(/1\.50/)); +``` + +No debe haber ningún espacio entre tus elementos `p`. + +```js +assert(!code.match(/<\/p>\s+

    + + + + + Cafe Menu + + + +

    + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} + +.item p { + display: inline-block; +} + +.flavor { + text-align: left; + width: 75%; +} + +.price { + text-align: right; + width: 25% +} +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f7b88d37b1f98386f04edc0.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f7b88d37b1f98386f04edc0.md new file mode 100644 index 00000000000000..bf9ca77c4c9a8c --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f7b88d37b1f98386f04edc0.md @@ -0,0 +1,104 @@ +--- +id: 5f7b88d37b1f98386f04edc0 +title: Paso 52 +challengeType: 0 +dashedName: step-52 +--- + +# --description-- + +Algo no se ve bien. Añadiste un atributo `class` con el valor correcto al elemento `p` con el texto `Donut`, pero aún no has definido un selector. + +Ya que el selector de clase `flavor` ya tiene las propiedades que necesitas, solo añádele la clase `dessert`. + +# --hints-- + +Debes añadir un selector de clase `.dessert` al selector de clase `.flavor`. + +```js +const selector = new __helpers.CSSHelp(document).getStyle('.flavor, .dessert') || new __helpers.CSSHelp(document).getStyle('.dessert, .flavor'); +assert(selector) +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); +} + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; +} + +.item p { + display: inline-block; +} + +--fcc-editable-region-- +.flavor { + text-align: left; + width: 75%; +} +--fcc-editable-region-- + +.price { + text-align: right; + width: 25% +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc174fcf86c76b9248c6eb2.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc174fcf86c76b9248c6eb2.md new file mode 100644 index 00000000000000..5d1ad914d65be3 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc174fcf86c76b9248c6eb2.md @@ -0,0 +1,63 @@ +--- +id: 5dc174fcf86c76b9248c6eb2 +title: Paso 1 +challengeType: 0 +dashedName: step-1 +--- + +# --description-- + +Los elementos HTML tienen etiquetas de apertura como `

    ` y etiquetas de cierre como `

    `. + +Encuentra el elemento `h1` y cambia su texto a: + + `CatPhotoApp` + +Asegúrate de que el texto esté entre las etiquetas de apertura y cierre. + +# --hints-- + +El texto `CatPhotoApp` debe estar presente en el código. Tal vez deberías revisar tu ortografía. + +```js +assert(code.match(/catphotoapp/i)); +``` + +Tu elemento `h1` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('h1')); +``` + +Tu elemento `h1` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/h1\>/)); +``` + +Tienes más de un elemento `h1`. Elimina el elemento `h1` extra. + +```js +assert(document.querySelectorAll('h1').length === 1); +``` + +El texto de tu elemento `h1` deber ser `CatPhotoApp`. Probablemente olvidaste añadir el texto, tienes un error tipográfico o no está entre las etiquetas de apertura y cierre del elemento `h1`. + +```js +assert(document.querySelector('h1').innerText.toLowerCase() === 'catphotoapp'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +--fcc-editable-region-- +

    Hello World

    +--fcc-editable-region-- + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc1798ff86c76b9248c6eb3.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc1798ff86c76b9248c6eb3.md new file mode 100644 index 00000000000000..a1b9cdacc2ede5 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc1798ff86c76b9248c6eb3.md @@ -0,0 +1,84 @@ +--- +id: 5dc1798ff86c76b9248c6eb3 +title: Paso 2 +challengeType: 0 +dashedName: step-2 +--- + +# --description-- + +Los elementos de título de `h1` a `h6` se utilizan para indicar la importancia del contenido debajo de ellos. Entre menor sea el número, el contenido será más importante, por lo tanto, el elemento `h2` es menos importante que el elemento `h1`. Solo utiliza un elemento `h1` por página y coloca encabezados de menor importancia debajo de encabezados de mayor importacion. + +Debajo del elemento `h1`, añade un elemento `h2` con este texto: + +`Cat Photos` + +# --hints-- + +Tu elemento `h1` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('h1')); +``` + +Tu elemento `h1` debe tener una etiqueta de cierre. Las etiquetas de cierre tienen una `/` inmediatamente después del carácter `<`. + +```js +assert(code.match(/<\/h1\>/)); +``` + +Solo deberías tener un elemento `h1`. Elimina el que está de más. + +```js +assert( + document.querySelector('h1') && document.querySelectorAll('h1').length === 1 +); +``` + +El texto de tu elemento `h1` debe ser 'CatPhotoApp'. Probablemente no has añadido el texto o tienes un error tipográfico. + +```js +assert(document.querySelector('h1').innerText.toLowerCase() === 'catphotoapp'); +``` + +Tu elemento `h2` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('h2')); +``` + +Tu elemento `h2` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/h2\>/)); +``` + +El texto de tu elemento `h2` debe ser 'Cat Photos'. El texto `Cat Photos` debe estar entre las etiquetas de apertura y cierre del elemento `h2`. + +```js +assert(document.querySelector('h2').innerText.toLowerCase() === 'cat photos'); +``` + +Tu elemento `h2` debe estar debajo del elemento `h1`. El elemento `h1` tiene mayor importancia, por lo tanto, debe estar encima del elemento `h2`. + +```js +const collection = [...document.querySelectorAll('h1,h2')].map( + (node) => node.nodeName +); +assert(collection.indexOf('H1') < collection.indexOf('H2')); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +--fcc-editable-region-- +

    CatPhotoApp

    +--fcc-editable-region-- + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc17d3bf86c76b9248c6eb4.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc17d3bf86c76b9248c6eb4.md new file mode 100644 index 00000000000000..72f08ac0ebb178 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc17d3bf86c76b9248c6eb4.md @@ -0,0 +1,60 @@ +--- +id: 5dc17d3bf86c76b9248c6eb4 +title: Paso 3 +challengeType: 0 +dashedName: step-3 +--- + +# --description-- + +El elemento `p` es usado para crear un párrafo de texto en sitios webs. Crea un elemento `p` debajo de tu elemento `h2` y dale el siguiente texto: + +`Click here to view more cat photos` + +# --hints-- + +El elemento `p` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('p')); +``` + +El elemento `p` debe tener una etiqueta de cierre. Las etiquetas de cierre tienen una `/` después del carácter `<`. + +```js +assert(code.match(/<\/p\>/)); +``` + +El texto de tu elemento `p` debe ser `Click here to view more cat photos.` olvidaste añadirlo o tienes un error tipográfico. + +```js +const extraSpacesRemoved = document + .querySelector('p') + .innerText.replace(/\s+/g, ' '); +assert(extraSpacesRemoved.match(/click here to view more cat photos\.?$/i)); +``` + +El elemento `p` debe estar debajo del elemento `h2`. Los tienes en el orden incorrecto. + +```js +const collection = [...document.querySelectorAll('h2,p')].map( + (node) => node.nodeName +); +assert(collection.indexOf('H2') < collection.indexOf('P')); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +--fcc-editable-region-- +

    Cat Photos

    +--fcc-editable-region-- + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc17dc8f86c76b9248c6eb5.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc17dc8f86c76b9248c6eb5.md new file mode 100644 index 00000000000000..f75d8c52977fc4 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc17dc8f86c76b9248c6eb5.md @@ -0,0 +1,70 @@ +--- +id: 5dc17dc8f86c76b9248c6eb5 +title: Paso 4 +challengeType: 0 +dashedName: step-4 +--- + +# --description-- + +Los comentarios te permiten dejar mensajes sin afectar lo que se muestra en el navegador. Te permite crear código que no se ejecutará. Un comentario en HTML comienza con ``. Por ejemplo, el comentario`` contiene el texto `TODO: Remove h1`. + +Añade un comentario sobre el elemento `p` con este texto: + +`TODO: Add link to cat photos` + +# --hints-- + +Tu comentario debe iniciar con ``. Faltan uno o más de los caracteres que definen el final de un comentario. + +```js +assert(code.match(/-->/)); +``` + +Tu código no debe tener caracteres extra de apertura/cierre para crear comentarios. Tienes los caracteres `` extra mostrándose en el navegador. + +```js +const noSpaces = code.replace(/\s/g, ''); +assert(noSpaces.match(//g).length < 2); +``` + +Tu comentario debe contener el texto `TODO: Add link to cat photos`. + +```js +assert(code.match(//i)); +``` + +Tu comentario debe estar sobre el elemento `p`. Los tienes en el orden incorrecto. + +```js +assert( + code + .replace(/\s/g, '') + .match( + /

    clickheretoviewmorecatphotos\.?<\/p>/i + ) +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +

    Cat Photos

    +--fcc-editable-region-- +

    Click here to view more cat photos.

    +--fcc-editable-region-- + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc2385ff86c76b9248c6eb7.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc2385ff86c76b9248c6eb7.md new file mode 100644 index 00000000000000..d65a8e1cf813ba --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc2385ff86c76b9248c6eb7.md @@ -0,0 +1,73 @@ +--- +id: 5dc2385ff86c76b9248c6eb7 +title: Paso 5 +challengeType: 0 +dashedName: step-5 +--- + +# --description-- + +HTML5 tiene diferentes elementos que ayudan a diferenciar diferentes tipos de contenido. Estos elementos hacen tu código HTML más fácil de leer y ayudan con el Posicionamiento en buscadores (Search Engine Optimization - SEO) y accesibilidad. + +Identifica la sección principal de esta página añadiendo la etiqueta de apertura `
    ` después del elemento `h1` y una etiqueta de cierre `
    ` después del elemento `p`. + +# --hints-- + +Tu elemento `main` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('main')); +``` + +Tu elemento `main` debe tener una etiqueta de cierre. Las etiquetas de cierre tienen una `/` después del carácter `<`. + +```js +assert(code.match(/<\/main\>/)); +``` + +La etiqueta de apertura del elemento `main` debe estar debajo del elemento `h1`. Los tienes en el orden incorrecto. + +```js +const collection = [...document.querySelectorAll('main,h1')].map( + (node) => node.nodeName +); +assert(collection.indexOf('H1') < collection.indexOf('MAIN')); +``` + +La etiqueta de apertura del elemento `main` debe estar encima del elemento `h2`. Los tienes en el orden incorrecto. + +```js +const collection = [...document.querySelectorAll('main,h2')].map( + (node) => node.nodeName +); +assert(collection.indexOf('MAIN') < collection.indexOf('H2')); +``` + +La etiqueta de cierre del elemento `main` debe estar debajo del elemento `p`. Los tienes en el orden incorrecto. + +```js +const mainNode = document.querySelector('main'); +const pNode = document.querySelector('p'); +assert( + mainNode.contains(pNode) && + pNode.textContent.toLowerCase().match(/click here to view more cat photos/) +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +--fcc-editable-region-- +

    CatPhotoApp

    +

    Cat Photos

    + +

    Click here to view more cat photos.

    +--fcc-editable-region-- + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc23991f86c76b9248c6eb8.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc23991f86c76b9248c6eb8.md new file mode 100644 index 00000000000000..99568a19319298 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc23991f86c76b9248c6eb8.md @@ -0,0 +1,102 @@ +--- +id: 5dc23991f86c76b9248c6eb8 +title: Paso 6 +challengeType: 0 +dashedName: step-6 +--- + +# --description-- + +En el paso anterior, anidaste un elemento `h2`, un comentario y un elemento `p` dentro de un elemento `main`. Un elemento anidado es hijo de su elemento padre. Debe tener una indentación o sangría de dos espacios más que su elemento padre para mejorar la legibilidad, de esta forma: + +```html +
      +
    • Child Element 1
    • +
    • Child Element 2
    • +
    +``` + +Añade dos espacios delante de los tres elementos hijos del elemento `main` para que tu código HTML sea más legible. + +# --hints-- + +Tu código debe tener un elemento `h2` con el texto `Cat Photos`. Puede que lo hayas eliminado accidentalmente, faltan las etiquetas de apertura y de cierre o el texto ha sido modificado. + +```js +assert( + document.querySelector('h2') && + code.match(/<\/h2\>/) && + document.querySelector('h2').innerText.toLowerCase() === 'cat photos' +); +``` + +Tu elemento `h2` debe estar debajo de la etiqueta de apertura del elemento `main` y la etiqueta de apertura debe tener 6 espacios de separación desde inicio de la línea. + +```js +assert(code.toLowerCase().match(/\s*\n\s{6}

    /)); +``` + +Tu código debe tener un comentario. Eliminaste el comentario de un paso anterior. + +```js +assert(code.match(//)); +``` + +El texto del comentario debe ser `TODO: Add link to cat photos`. No cambies el texto o los espacios del comentario. + +```js +assert(code.match(//i)); +``` + +Tu comentario debe estar debajo del elemento `h2` y tener 6 espacios desde el inicio de la línea. + +```js +assert( + code + .toLowerCase() + .match(/<\/h2>\n\s{6}/) +); +``` + +Tu código debe tener un elemento `p`. Eliminaste el elemento `p` de un paso anterior. + +```js +assert(document.querySelector('p')); +``` + +El texto del elemento `p` debe ser `Click here to view more cat photos.` No cambies el texto, el espaciado, o la puntuación del elemento `p`. + +```js +assert( + document + .querySelector('p') + .innerText.toLowerCase() + .match(/click\s+here\s+to\s+view\s+more\s+cat\s+photos\.?$/) +); +``` + +Tu elemento `p` debe estar debajo del comentario y su etiqueta de apertura debe tener 6 espacios desde el inicio de la línea. + +```js +assert(code.toLowerCase().match(/-->\n\s{6}

    /)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +--fcc-editable-region-- +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    +
    +--fcc-editable-region-- + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc23f9bf86c76b9248c6eba.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc23f9bf86c76b9248c6eba.md new file mode 100644 index 00000000000000..a24b20b79d0173 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc23f9bf86c76b9248c6eba.md @@ -0,0 +1,61 @@ +--- +id: 5dc23f9bf86c76b9248c6eba +title: Paso 7 +challengeType: 0 +dashedName: step-7 +--- + +# --description-- + +Puedes añadir imágenes a tu sitio web utilizando el elemento `img`. Los elementos `img` tienen una etiqueta de apertura sin una etiqueta de cierre. La etiqueta de un elemento que no necesita etiqueta de cierre se conoce como etiqueta de autocierre (self-closing tag). + +Añade un elemento `img` debajo del elemento `p`. Por ahora no se mostrará ninguna imagen en el navegador. + +# --hints-- + +Tu elemento `img` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('img')); +``` + +Tu elemento `img` no debe tener una etiqueta de cierre. Una etiqueta de cierre tiene una `/` después del carácter `<`. + +```js +assert(!code.match(/<\/img\>/)); +``` + +Solo debes tener un elemento `img`. Elimina los que estén de más. + +```js +assert(document.querySelectorAll('img').length === 1); +``` + +Tu elemento `img` debe estar debajo del elemento `p`. Los tienes en el orden incorrecto. + +```js +const collection = [...document.querySelectorAll('p,img')].map( + (node) => node.nodeName +); +assert(collection.indexOf('P') < collection.indexOf('IMG')); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +

    Cat Photos

    + +--fcc-editable-region-- +

    Click here to view more cat photos.

    +--fcc-editable-region-- +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc24073f86c76b9248c6ebb.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc24073f86c76b9248c6ebb.md new file mode 100644 index 00000000000000..98c04c8bd66966 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc24073f86c76b9248c6ebb.md @@ -0,0 +1,61 @@ +--- +id: 5dc24073f86c76b9248c6ebb +title: Paso 8 +challengeType: 0 +dashedName: step-8 +--- + +# --description-- + +Los atributos HTML son palabras especiales usadas dentro de la etiqueta de apertura de un elemento para controlar el comportamiento del elemento. El atributo `src` en un elemento `img` especifica la URL (donde se localiza la imagen). Un ejemplo de un elemento `img` usando el atributo `src`: ``. + +Dentro del elemento `img` existente, añade un atributo `src` con esta URL: + +`https://cdn.freecodecamp.org/curriculum/cat-photo-app/relaxing-cat.jpg` + +# --hints-- + +Tu código debe tener un elemento `img`. Pudiste haber borrado el elemento `img` o no pusiste entre comillas el valor del atributo `src`. + +```js +assert(document.querySelector('img')); +``` + +Tu elemento `img` debe tener un atributo `src`. Probablemente no has añadido el atributo o tienes un error tipográfico. Asegúrate e de que hay un espacio entre el nombre del elemento y el nombre del atributo. + +```js +assert(document.querySelector('img').src); +``` + +El atributo `src` del elemento `img` debe tener el valor '`https://cdn.freecodecamp.org/curriculum/cat-photo-app/relaxing-cat.jpg`'. Probablemente no has añadido la URL o tienes un error tipográfico. La URL debe ser exactamente igual, cuidando mayúsculas y minúsculas. + +```js +assert(document.querySelector('img').src === 'https://cdn.freecodecamp.org/curriculum/cat-photo-app/relaxing-cat.jpg'); +``` + +Aunque le has dado la URL correcta al atributo `src` del elemento `img`, se recomienda siempre poner el valor de un atributo entre comillas. + +```js +assert(!/\ + +

    CatPhotoApp

    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    +--fcc-editable-region-- + +--fcc-editable-region-- +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc24165f86c76b9248c6ebc.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc24165f86c76b9248c6ebc.md new file mode 100644 index 00000000000000..63112c82ef2a65 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc24165f86c76b9248c6ebc.md @@ -0,0 +1,59 @@ +--- +id: 5dc24165f86c76b9248c6ebc +title: Paso 9 +challengeType: 0 +dashedName: step-9 +--- + +# --description-- + +Todos los elementos `img` deben tener un atributo `alt`. El texto del atributo `alt` es utilizado por lectores de pantalla para mejora la accesibilidad y es mostrado en caso de que la imagen falle en cargar. Por ejemplo, `A cat` tiene un atributo `alt` con el texto `A cat`. + +Dentro del elemento `img`, añade un atributo `alt` con este texto: + +`A cute orange cat lying on its back` + +# --hints-- + +Tu código debe tener un elemento `img`. Eliminaste el elemento `img` de uno de los pasos anteriores. + +```js +assert(document.querySelector('img')); +``` + +Tu elemento `img` no tiene un atributo `alt`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +assert(document.querySelector('img').hasAttribute('alt')); +``` + +El atributo `alt` del elemento `img` tiene un valor diferente a 'A cute orange cat lying on its back'. Asegúrate de que el valor del atributo `alt` esté entre comillas. + +```js +const altText = document + .querySelector('img') + .alt.toLowerCase() + .replace(/\s+/g, ' '); +assert(altText.match(/A cute orange cat lying on its back\.?$/i)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    +--fcc-editable-region-- + +--fcc-editable-region-- +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc24614f86c76b9248c6ebd.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc24614f86c76b9248c6ebd.md new file mode 100644 index 00000000000000..e749963bc64a5d --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dc24614f86c76b9248c6ebd.md @@ -0,0 +1,79 @@ +--- +id: 5dc24614f86c76b9248c6ebd +title: Paso 10 +challengeType: 0 +dashedName: step-10 +--- + +# --description-- + +Puedes hacer un enlace que te llevará a otra página con el elemento anchor (`a`). Por ejemplo, `` te llevará a `freecodecamp.org`. + +Agrega un elemento anchor después del párrafo que te lleve a `https://freecatphotoapp.com`. Por ahora, el enlace no aparecerá en la vista previa. + +# --hints-- + +El elemento (`a`) debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('a')); +``` + +El elemento anchor (`a`) debe tener una etiqueta de cierre. Una etiqueta de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/a\>/)); +``` + +Tu elemento anchor (`a`) debe estar debajo del elemento `p`. Los tienes en el orden incorrecto. + +```js +const collection = [...document.querySelectorAll('a, p')].map( + (node) => node.nodeName +); +assert(collection.indexOf('P') < collection.indexOf('A')); +``` + +Tu elemento anchor (`a`) no tiene un atributo `href`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +assert(document.querySelector('a').hasAttribute('href')); +``` + +Tu elemento anchor (`a`) te debe de llevar a `https://freecatphotoapp.com`. Probablemente no has añadido la URL o tienes un error tipográfico. + +```js +assert( + document.querySelector('a').getAttribute('href') === + 'https://freecatphotoapp.com' +); +``` + +Aunque le has dado el enlace correcto al parámetro `href` del elemento anchor ('a'), se recomienda siempre poner el valor de un atributo entre comillas. + +```js +assert( + !/\ + +

    CatPhotoApp

    +
    +

    Cat Photos

    + +--fcc-editable-region-- +

    Click here to view more cat photos.

    +--fcc-editable-region-- + A cute orange cat lying on its back. +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ddbd81294d8ddc1510a8e56.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ddbd81294d8ddc1510a8e56.md new file mode 100644 index 00000000000000..671025d349f463 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ddbd81294d8ddc1510a8e56.md @@ -0,0 +1,57 @@ +--- +id: 5ddbd81294d8ddc1510a8e56 +title: Paso 11 +challengeType: 0 +dashedName: step-11 +--- + +# --description-- + +El texto de un enlace debe colocarse entre la etiqueta de apertura y la etiqueta de cierre de un elemento anchor (`a`). Por ejemplo, `click here to go to freeCodeCamp.org` es un enlace con el texto `click here to go to freeCodeCamp.org`. + +Añade el texto `cat photos` al elemento anchor. Esto se convertirá en el texto del enlace. + +# --hints-- + +Tu elemento (`a`) debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('a')); +``` + +Tu elemento anchor (`a`) debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/a\>/)); +``` + +El texto de tu elemento anchor (`a`) debería ser `cat photos`. Asegúrate de poner el texto del enlace entre la etiqueta de apertura y etiqueta de cierre del elemento (`a`). + +```js +assert( + document.querySelector('a').innerText.toLowerCase().replace(/\s+/g, ' ') === + 'cat photos' +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    +--fcc-editable-region-- + +--fcc-editable-region-- + A cute orange cat lying on its back. +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa22d1b521be39a3de7be0.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa22d1b521be39a3de7be0.md new file mode 100644 index 00000000000000..3b4f3bd55737e7 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa22d1b521be39a3de7be0.md @@ -0,0 +1,66 @@ +--- +id: 5dfa22d1b521be39a3de7be0 +title: Paso 12 +challengeType: 0 +dashedName: step-12 +--- + +# --description-- + +Convierte las palabras `cat photos` ubicadas dentro del elemento `p` en un enlace usando el mismo valor para el atributo `href` que el enlace debajo del elemento `p`. El elemento `p` debe seguir mostrando el mismo texto en el navegador, pero las palabras `cat photos` ahora deben ser un enlace. Asegúrate de eliminar el elemento `a` con el texto `cat photos` en la linea debajo del elemento `p`. + +# --hints-- + +Tu código solo debe contener un elemento anchor (`a`). Elimina cualquier elemento anchor extra. + +```js +assert(document.querySelectorAll('a').length === 1); +``` + +Tu elemento anchor (`a`) debe estar anidado dentro del elemento `p`. + +```js +assert($('p > a').length); +``` + +El texto del enlace debe ser `cat photos`. Probablemente no has añadido el texto o tienes un error tipográfico. + +```js +const nestedAnchor = $('p > a')[0]; +assert( + nestedAnchor.getAttribute('href') === 'https://freecatphotoapp.com' && + nestedAnchor.innerText.toLowerCase().replace(/\s+/g, ' ') === 'cat photos' +); +``` + +Después de anidar el elemento achor (`a`), el único contenido visible en el navegador del elemento `p` debe ser `Click here to view more cat photos.` Comprueba el texto, el espaciado y la puntuación del elemento `p` y del elemento anchor anidado. + +```js +const pText = document + .querySelector('p') + .innerText.toLowerCase() + .replace(/\s+/g, ' '); +assert(pText.match(/click here to view more cat photos\.?$/)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +

    Cat Photos

    + +--fcc-editable-region-- +

    Click here to view more cat photos.

    + cat photos +--fcc-editable-region-- + A cute orange cat lying on its back. +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa2407b521be39a3de7be1.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa2407b521be39a3de7be1.md new file mode 100644 index 00000000000000..9517903b59dbc6 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa2407b521be39a3de7be1.md @@ -0,0 +1,55 @@ +--- +id: 5dfa2407b521be39a3de7be1 +title: Paso 13 +challengeType: 0 +dashedName: step-13 +--- + +# --description-- + +Añade un atributo `target` con el valor `_blank` en la etiqueta de apertura, del elemento anchor (`a`) para que el enlace abra en una nueva pestaña. + +# --hints-- + +Tu elemento `p` debe tener un elemento anchor (`a`) anidado, con el texto `cat photos`. Es posible que lo hayas eliminado o que tengas un error tipográfico. + +```js +const anchor = $('p > a'); +assert( + anchor.length && + anchor[0].innerText.toLowerCase().replace(/\s+/g, ' ') === 'cat photos' +); +``` + +Tu elemento anchor (`a`) no tiene un atributo `target`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +assert(document.querySelector('a').hasAttribute('target')); +``` + +El valor del atributo `target` debe ser `_blank`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +assert(document.querySelector('a').getAttribute('target') === '_blank'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +

    Cat Photos

    + +--fcc-editable-region-- +

    Click here to view more cat photos.

    +--fcc-editable-region-- + A cute orange cat lying on its back. +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa30b9eacea3f48c6300ad.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa30b9eacea3f48c6300ad.md new file mode 100644 index 00000000000000..a9cdfbbd49fce5 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa30b9eacea3f48c6300ad.md @@ -0,0 +1,88 @@ +--- +id: 5dfa30b9eacea3f48c6300ad +title: Paso 14 +challengeType: 0 +dashedName: step-14 +--- + +# --description-- + +Convierte la imagen en un enlace rodeándola con las etiquetas correctas. Utiliza `https://freecatphotoapp.com` como valor del atributo `href` del elemento archor. + +# --hints-- + +Debes tener un elemento `img` cuyo valor del atributo `src` debe ser `https://cdn.freecodecamp.org/curriculum/cat-photo-app/relaxing-cat.jpg`. Puede que lo hayas borrado accidentalmente. + +```js +assert( + document.querySelector('img') && + document.querySelector('img').getAttribute('src') === + 'https://cdn.freecodecamp.org/curriculum/cat-photo-app/relaxing-cat.jpg' +); +``` + +Tu elemento (`a`) debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelectorAll('a').length >= 2); +``` + +Solo debes añadir una etiqueta de apertura del elemento anchor (`a`). Elimina cualquier extra. + +```js +assert(document.querySelectorAll('a').length === 2); +``` + +Tu elemento anchor (`a`) debe tener una etiqueta de cierre. Las etiquetas de cierre tienen una `/` inmediatamente después del carácter `<`. + +```js +assert(code.match(/<\/a>/g).length >= 2); +``` + +Solo debes añadir una etiqueta de cierre del elemento anchor (`a`). Elimina cualquier extra. + +```js +assert(code.match(/<\/a>/g).length === 2); +``` + +Tu elemento anchor (`a`) no tiene un atributo `href`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +assert(document.querySelector('a').hasAttribute('href')); +``` + +Tu elemento anchor (`a`) te debe de llevar a `https://freecatphotoapp.com`. Probablemente no has añadido la URL o tienes un error tipográfico. + +```js +assert( + document.querySelectorAll('a')[1].getAttribute('href') === + 'https://freecatphotoapp.com' +); +``` + +Tu elemento `img` debe estar anidado dentro del elemento anchor (`a`). Todo el elemento `img` debe estar entre las etiquetas de apertura y cierre del elemento anchor (`a`). + +```js +assert(document.querySelector('img').parentNode.nodeName === 'A'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    +--fcc-editable-region-- + A cute orange cat lying on its back. +--fcc-editable-region-- +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa3589eacea3f48c6300ae.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa3589eacea3f48c6300ae.md new file mode 100644 index 00000000000000..0f5eaa4d7570d8 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa3589eacea3f48c6300ae.md @@ -0,0 +1,75 @@ +--- +id: 5dfa3589eacea3f48c6300ae +title: Paso 17 +challengeType: 0 +dashedName: step-17 +--- + +# --description-- + +Dentro del segundo elemento `section`, añade un nuevo elemento `h2` con el texto `Cat Lists`. + +# --hints-- + +Tu elemento `section` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert( + document.querySelectorAll('section').length === 2 && + code.match(/<\/section>/g).length === 2 +); +``` + +Tu elemento `h2` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelectorAll('h2').length === 2); +``` + +Tu elemento `h2` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/h2\>/g).length === 2); +``` + +Tu segundo elemento `h2` debe estar arriba de la etiqueta de cierre del segundo elemento `section`. No está en la posición correcta. + +```js +const secondSection = document.querySelectorAll('section')[1]; +assert(secondSection.lastElementChild.nodeName === 'H2'); +``` + +El segundo `h2` debe tener el texto `Cat Lists`. Probablemente no has añadido el texto o tienes un error tipográfico. + +```js +assert( + document + .querySelectorAll('main > section')[1] + .lastElementChild.innerText.toLowerCase() === 'cat lists' +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +--fcc-editable-region-- +
    +
    +--fcc-editable-region-- +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa371beacea3f48c6300af.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa371beacea3f48c6300af.md new file mode 100644 index 00000000000000..843d35d5be04be --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa371beacea3f48c6300af.md @@ -0,0 +1,84 @@ +--- +id: 5dfa371beacea3f48c6300af +title: Paso 18 +challengeType: 0 +dashedName: step-18 +--- + +# --description-- + +Cuando añades un elemento de título de menor rango a la página, se da a entender que estás iniciando una nueva sub-sección. + +Después del elemento `h2` del segundo elemento `section`, añade un elemento `h3` con este texto: + +`Things cats love:` + +# --hints-- + +Al segundo elemento `section` parece faltarle las etiquetas de apertura y cierre. + +```js +assert( + document.querySelectorAll('main > section')[1] && + code.match(/\<\/section>/g).length == 2 +); +``` + +Debe haber un elemento `h3` arriba de la etiqueta de cierre del segundo elemento `section`. + +```js +assert( + document.querySelectorAll('main > section')[1].lastElementChild.nodeName === + 'H3' +); +``` + +El elemento `h3` que está arriba de la etiqueta de cierre del segundo elemento `section` debe tener el texto `Things cats love:`. Asegúrate de incluir los dos puntos al final del texto. + +```js +assert( + document + .querySelectorAll('main > section')[1] + .lastElementChild.innerText.toLowerCase() + .replace(/\s+/g, ' ') === 'things cats love:' +); +``` + +Debe haber un elemento `h2` con el texto `Cat Lists` arriba del elemento `h3` que está anidado en el último elemento `section`. Probablemente eliminaste el elemento `h2`. + +```js +const secondSectionLastElemNode = document.querySelectorAll('main > section')[1] + .lastElementChild; +assert( + secondSectionLastElemNode.nodeName === 'H3' && + secondSectionLastElemNode.previousElementSibling.innerText + .toLowerCase() + .replace(/\s+/g, ' ') === 'cat lists' +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +--fcc-editable-region-- +
    +

    Cat Lists

    +
    +--fcc-editable-region-- +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa37b9eacea3f48c6300b0.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa37b9eacea3f48c6300b0.md new file mode 100644 index 00000000000000..b3d5dc26b6d9e7 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa37b9eacea3f48c6300b0.md @@ -0,0 +1,58 @@ +--- +id: 5dfa37b9eacea3f48c6300b0 +title: Paso 19 +challengeType: 0 +dashedName: step-19 +--- + +# --description-- + +Después del elemento `h3` con el texto `Things cats love:`, añade una lista desordenada, unordered list - (`ul`). Ten en cuenta que nada será mostrado aún. + +# --hints-- + +Tu elemento `ul` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('ul')); +``` + +Tu elemento `ul` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/ul>/)); +``` + +El elemento `ul` debe ir arriba de la etiqueta de cierre del segundo elemento `section`. + +```js +const secondSectionLastElemNode = $('main > section')[1].lastElementChild; +assert(secondSectionLastElemNode.nodeName === 'UL'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +--fcc-editable-region-- +

    Cat Lists

    +

    Things cats love:

    +--fcc-editable-region-- +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfb5ecbeacea3f48c6300b1.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfb5ecbeacea3f48c6300b1.md new file mode 100644 index 00000000000000..a9b1ff85a136b1 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfb5ecbeacea3f48c6300b1.md @@ -0,0 +1,79 @@ +--- +id: 5dfb5ecbeacea3f48c6300b1 +title: Paso 20 +challengeType: 0 +dashedName: step-20 +--- + +# --description-- + +Utiliza la etiqueta (`li` - list item) para agregar elementos a una lista. Aquí hay un ejemplo de una lista de objetos en una lista desordenada: + +```html +
      +
    • milk
    • +
    • cheese
    • +
    +``` + +Dentro del elemento `ul` anida tres elementos li para mostrar tres cosas que aman los gatos: + +`cat nip` `laser pointers` `lasagna` + +# --hints-- + +Debes tener tres elementos `li`. Cada elemento `li` debe tener su propia etiqueta de apertura y cierre. + +```js +assert($('li').length === 3 && code.match(/<\/li\>/g).length === 3); +``` + +Debes tener tres elementos `li` con los textos `cat nip`, `laser pointers` y `lasagna` en cualquier orden. Probablemente no has añadido el texto o tienes un error tipográfico. + +```js +assert.deepStrictEqual( + [...document.querySelectorAll('li')] + .map((item) => item.innerText.toLowerCase()) + .sort((a, b) => a.localeCompare(b)), + ['cat nip', 'lasagna', 'laser pointers'] +); +``` + +Los tres elementos `li` deben estar entre las etiquetas de apertura y cierre del elemento `ul`. + +```js +assert( + [...document.querySelectorAll('li')].filter( + (item) => item.parentNode.nodeName === 'UL' + ).length === 3 +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +--fcc-editable-region-- +
      +
    +--fcc-editable-region-- +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfb6250eacea3f48c6300b2.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfb6250eacea3f48c6300b2.md new file mode 100644 index 00000000000000..0f7bc823c1c751 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfb6250eacea3f48c6300b2.md @@ -0,0 +1,94 @@ +--- +id: 5dfb6250eacea3f48c6300b2 +title: Paso 21 +challengeType: 0 +dashedName: step-21 +--- + +# --description-- + +Después de la lista desordenada - ul, añade una nueva imagen con un atributo `src` con el valor: + +`https://cdn.freecodecamp.org/curriculum/cat-photo-app/lasagna.jpg` + +Y un atributo `alt` con el valor: + +`A slice of lasagna on a plate.` + +# --hints-- + +Debe haber un elemento `img` después de la etiqueta de cierre del elemento ``. + +```js +assert($('section')[1].lastElementChild.nodeName === 'IMG'); +``` + +La nueva imagen no tiene un atributo `alt`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +assert($('section')[1].lastElementChild.hasAttribute('alt')); +``` + +La nueva imagen debe tener un atributo `alt` con el valor `A slice of lasagna on a plate.` Asegurate de que el valor del atributo `alt` está entre comillas. + +```js +assert( + $('section')[1] + .lastElementChild.getAttribute('alt') + .replace(/\s+/g, ' ') + .match(/^A slice of lasagna on a plate\.?$/i) +); +``` + +La nueva imagen no tiene un atributo `src`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +assert($('section')[1].lastElementChild.hasAttribute('src')); +``` + +La nueva imagen debe tener un atributo `src` con el valor `https://cdn.freecodecamp.org/curriculum/cat-photo-app/lasagna.jpg`. Asegúrate de que el valor del atributo `src` esté entre comillas. + +```js +assert( + $('section')[1].lastElementChild.getAttribute('src') === + 'https://cdn.freecodecamp.org/curriculum/cat-photo-app/lasagna.jpg' +); +``` + +Aunque el atributo `src` de la nueva imagen tenga la URL correcta, se recomienda siempre poner entre comillas el valor de un atributo. + +```js +assert(!/\ + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +--fcc-editable-region-- +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +--fcc-editable-region-- +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfb655eeacea3f48c6300b3.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfb655eeacea3f48c6300b3.md new file mode 100644 index 00000000000000..403f640f2114d5 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfb655eeacea3f48c6300b3.md @@ -0,0 +1,76 @@ +--- +id: 5dfb655eeacea3f48c6300b3 +title: Paso 22 +challengeType: 0 +dashedName: step-22 +--- + +# --description-- + +El elemento `figure` representa contenido independiente y te permitirá asociar una imagen a una descripción. + +Anida la imagen que acabas de añadir dentro de un elemento `figure`. + +# --hints-- + +Tu elemento `figure` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('figure')); +``` + +Tu elemento `figure` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/figure\>/)); +``` + +Debe haber un elemento `figure` arriba de la etiqueta de cierre del segundo elemento `section`. + +```js +assert($('section')[1].lastElementChild.nodeName === 'FIGURE'); +``` + +El elemento, `img` lasagna, debe estar anidado en el elemento `figure`. + +```js +assert( + document.querySelector('figure > img') && + document.querySelector('figure > img').getAttribute('src').toLowerCase() === + 'https://cdn.freecodecamp.org/curriculum/cat-photo-app/lasagna.jpg' +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +--fcc-editable-region-- + A slice of lasagna on a plate. +--fcc-editable-region-- +
    +
    + + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfb6a35eacea3f48c6300b4.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfb6a35eacea3f48c6300b4.md new file mode 100644 index 00000000000000..87e0fa5ba38db3 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfb6a35eacea3f48c6300b4.md @@ -0,0 +1,108 @@ +--- +id: 5dfb6a35eacea3f48c6300b4 +title: Paso 23 +challengeType: 0 +dashedName: step-23 +--- + +# --description-- + +Un elemento (`figcaption`), se utiliza para añadir una descripción o leyenda para describir una imagen anidada en un elemento `figure`. Por ejemplo, `
    A cute cat
    ` añade la leyenda `A cute cat`. + +Después de anidar la imagen en el elemento `figure`, añade un elemento `figcaption` con el texto: + +`Cats love lasagna.` + +# --hints-- + +El elemento, `img` de una lasaña (lasagna), debe estar anidado en el elemento `figure`. + +```js +assert( + document.querySelector('figure > img') && + document.querySelector('figure > img').getAttribute('src').toLowerCase() === + 'https://cdn.freecodecamp.org/curriculum/cat-photo-app/lasagna.jpg' +); +``` + +Tu elemento `figcaption` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('figcaption')); +``` + +Tu elemento `figcaption` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/figcaption\>/)); +``` + +El elemento `figcaption` debe estar anidado en el elemento `figure`. + +```js +assert( + document.querySelector('figure > figcaption') && + document.querySelector('figure > figcaption') +); +``` + +El elemento, `img` de una lasaña (lasagna), debe estar anidado en el elemento `figure`. + +```js +assert( + document.querySelector('figure > img') && + document.querySelector('figure > img').getAttribute('src').toLowerCase() === + 'https://cdn.freecodecamp.org/curriculum/cat-photo-app/lasagna.jpg' +); +``` + +El elemento `figcaption` anidado en el elemento `figure` debe estar debajo del elemento `img`. Los tienes en el orden incorrecto. + +```js +assert( + document.querySelector('figcaption').previousElementSibling.nodeName === 'IMG' +); +``` + +El texto de tu elemento `figcaption` debe ser `Cats love lasagna.` olvidaste añadirlo o tienes un error tipográfico. + +```js +assert( + document.querySelector('figcaption').innerText.match(/Cats love lasagna.?$/i) +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +--fcc-editable-region-- +
    + A slice of lasagna on a plate. +
    +--fcc-editable-region-- +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d0.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d0.md new file mode 100644 index 00000000000000..fb3bfb67868a79 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d0.md @@ -0,0 +1,85 @@ +--- +id: 5ef9b03c81a63668521804d0 +title: Paso 24 +challengeType: 0 +dashedName: step-24 +--- + +# --description-- + +Enfatiza la palabra `love` en el elemento `figcaption` envolviendola en un elemento énfasis `em`. + +# --hints-- + +Tu elemento énfasis `em` debería tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('em')); +``` + +Tu elemento énfasis `em` debería tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/em\>/)); +``` + +Has eliminado el elemento `figcaption` o le falta una etiqueta de apertura o de cierre. + +```js +assert(document.querySelector('figcaption') && code.match(/<\/figcaption\>/)); +``` + +Tu elemento énfasis `em` debería rodear el texto `love`. Probablemente no has añadido el texto o tienes un error tipográfico. + +```js +assert( + document.querySelector('figcaption > em').innerText.toLowerCase() === 'love' +); +``` + +El texto del elemento `figcaption` debe ser `Cats love lasagna`. Comprueba que no haya errores tipográficos y que los espacios entre las etiquetas del elemento `em` son los correctos. + +```js +assert( + document + .querySelector('figcaption') + .innerText.replace(/\s+/gi, ' ') + .match(/cats love lasagna\.?/i) +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +--fcc-editable-region-- +
    Cats love lasagna.
    +--fcc-editable-region-- +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d1.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d1.md new file mode 100644 index 00000000000000..6c5e8720fea38e --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d1.md @@ -0,0 +1,81 @@ +--- +id: 5ef9b03c81a63668521804d1 +title: Paso 25 +challengeType: 0 +dashedName: step-25 +--- + +# --description-- + +Después del elemento `figure`, añade un elemento `h3` con el texto: + +`Top 3 things cats hate:` + +# --hints-- + +Debe haber un elemento `h3` arriba de la etiqueta de cierre del segundo elemento `section`. No olvides su etiqueta de apertura y cierre. + +```js +assert( + document.querySelectorAll('main > section')[1].lastElementChild.nodeName === + 'H3' && code.match(/<\/h3\>/g).length === 2 +); +``` + +El nuevo elemento `h3` debe tener el texto `Top 3 things cats hate:`. Asegúrate de incluir los dos puntos al final del texto. + +```js +assert( + document + .querySelectorAll('main > section')[1] + .lastElementChild.innerText.toLowerCase() + .replace(/\s+/g, ' ') === 'top 3 things cats hate:' +); +``` + +Debe haber un elemento `figure` arriba del nuevo elemento `h3`. Es probable que hayas eliminado el elemento `figure`. + +```js +const secondSectionLastElemNode = document.querySelectorAll('main > section')[1] + .lastElementChild; +assert( + secondSectionLastElemNode.nodeName === 'H3' && + secondSectionLastElemNode.previousElementSibling.nodeName === 'FIGURE' +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +--fcc-editable-region-- +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +--fcc-editable-region-- +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d2.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d2.md new file mode 100644 index 00000000000000..49a6b2a03071a3 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d2.md @@ -0,0 +1,94 @@ +--- +id: 5ef9b03c81a63668521804d2 +title: Paso 26 +challengeType: 0 +dashedName: step-26 +--- + +# --description-- + +El código de una lista ordenada, ordered list (`ol`), es similar al de una lista no ordenada, unordered list (ul), pero los elemento de una lista ordenada aparecen enumerados. + +En el segundo elemento `section`, después del último elemento `h3`, añade una lista ordenada con estos tres elementos: + +`flea treatment` `thunder` `other cats` + +# --hints-- + +Tu elemento `ol` (lista ordenada) debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('ol')); +``` + +Tu elemento `ol` debe tener una etiqueta de cierre. Las etiquetas de cierre tienen una `/` inmediatamente después del carácter `<`. + +```js +assert(code.match(/<\/ol>/)); +``` + +El elemento `ol` debe estar arriba de la etiqueta de cierre del segundo elemento `section`. Los tienes en el orden incorrecto. + +```js +assert($('main > section')[1].lastElementChild.nodeName === 'OL'); +``` + +Los tres elementos `li` deben estar anidados dentro del elemento `ol`. + +```js +assert( + [...document.querySelectorAll('li')].filter( + (item) => item.parentNode.nodeName === 'OL' + ).length === 3 +); +``` + +Debes tener tres elementos `li` con los textos `flea treatment`, `thunder` y `other cats` en cualquier orden. + +```js +assert.deepStrictEqual( + [...document.querySelectorAll('li')] + .filter((item) => item.parentNode.nodeName === 'OL') + .map((item) => item.innerText.toLowerCase()) + .sort((a, b) => a.localeCompare(b)), + ['flea treatment', 'other cats', 'thunder'] +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +--fcc-editable-region-- +

    Top 3 things cats hate:

    +--fcc-editable-region-- +
    +
    + + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d3.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d3.md new file mode 100644 index 00000000000000..2f0e3990b6122d --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d3.md @@ -0,0 +1,72 @@ +--- +id: 5ef9b03c81a63668521804d3 +title: Paso 27 +challengeType: 0 +dashedName: step-27 +--- + +# --description-- + +Después de la lista ordenada (ol), añade otro elemento `figure`. + +# --hints-- + +Tu elemento `figure` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelectorAll('figure').length === 2); +``` + +Tu elemento `figure` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/figure>/g).length === 2); +``` + +Debe haber un elemento `figure` arriba de la etiqueta de cierre del segundo elemento `section`. + +```js +assert($('main > section')[1].lastElementChild.nodeName === 'FIGURE'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +--fcc-editable-region-- +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +--fcc-editable-region-- +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d4.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d4.md new file mode 100644 index 00000000000000..181aed0ea284bd --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d4.md @@ -0,0 +1,96 @@ +--- +id: 5ef9b03c81a63668521804d4 +title: Paso 31 +challengeType: 0 +dashedName: step-31 +--- + +# --description-- + +El elemento `strong` se utiliza para indicar que una parte de un texto es importante o urgente. + +En el elemento `figcaption` que acabas de añadir, indica que la palabra `hate` tiene mayor importancia, envolviéndola con un elemento `strong`. + +# --hints-- + +Tu elemento `strong` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('strong')); +``` + +Tu elemento `strong` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/strong\>/)); +``` + +Tu elemento `strong` debe rodear la palabra `hate` en el texto `Cats hate other cats.` Has omitido el texto o tienes un error tipográfico. + +```js +assert( + document + .querySelectorAll('figcaption')[1] + .querySelector('strong') + .innerText.toLowerCase() === 'hate' +); +``` + +El texto del elemento `figcaption` debe ser `Cats hate other cats.` Comprueba que no hay errores tipográficos y que los espacios alrededor de las etiquetas de cierre y apertura del elemento `strong` son los correctos. + +```js +const secondFigCaption = document.querySelectorAll('figcaption')[1]; +assert( + secondFigCaption && + secondFigCaption.innerText + .replace(/\s+/gi, ' ') + .trim() + .match(/cats hate other cats\.?/i) +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +--fcc-editable-region-- +
    Cats hate other cats.
    +--fcc-editable-region-- +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d5.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d5.md new file mode 100644 index 00000000000000..2fd8a8d30a9858 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d5.md @@ -0,0 +1,105 @@ +--- +id: 5ef9b03c81a63668521804d5 +title: Paso 33 +challengeType: 0 +dashedName: step-33 +--- + +# --description-- + +Dentro del tercer elemento `section` añade un elemento `h2` con el texto: + +`Cat Form` + +# --hints-- + +No se ha podido encontrar el tercer elemento `section`. Es posible que hayas eliminado el elemento o alguna de las etiquetas de apertura o de cierre. + +```js +assert( + document.querySelectorAll('section').length === 3 && + code.match(/<\/section>/g).length === 3 +); +``` + +Tu elemento `h2` debe tener una etiqueta de apertura y una etiqueta de cierre. Puede que te falte una o ambas etiquetas. + +```js +assert( + document.querySelectorAll('h2').length >= 3 && + code.match(/<\/h2>/g).length >= 3 +); +``` + +Solo debes añadir un elemento `h2`. Elimina cualquier extra. + +```js +assert(document.querySelectorAll('h2').length === 3); +``` + +El nuevo elemento `h2` debe estar arriba de la etiqueta de cierre del tercer elemento `section`. + +```js +const thirdSection = document.querySelectorAll('section')[2]; +assert(thirdSection.lastElementChild.nodeName === 'H2'); +``` + +El texto de tu elemento `h2` deber ser `Cat Form`. + +```js +const thirdSection = document.querySelectorAll('section')[2]; +assert( + thirdSection + .querySelector('h2') + .innerText.toLowerCase() + .replace(/\s+/g, ' ') === 'cat form' +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +--fcc-editable-region-- +
    +
    +--fcc-editable-region-- +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d6.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d6.md new file mode 100644 index 00000000000000..575c1718f2b58f --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d6.md @@ -0,0 +1,88 @@ +--- +id: 5ef9b03c81a63668521804d6 +title: Paso 34 +challengeType: 0 +dashedName: step-34 +--- + +# --description-- + +Ahora añadirás un formulario web para recolectar información de los usuarios. + +Después del título `Cat Form`, añade un elemento `form`. + +# --hints-- + +Tu elemento `form` debe tener una etiqueta de apertura y una etiqueta de cierre. Puede que te falte una o dos de las etiquetas requeridas o las tienes en el orden incorrecto. + +```js +assert(document.querySelector('form') && code.match(/<\/form>/g)); +``` + +Las etiquetas del elemento `form` no están en el orden correcto. + +```js +const noSpaces = code.replace(/\s/g, ''); +assert(noSpaces.indexOf('
    ') < noSpaces.indexOf('
    ')); +``` + +El elemento `form` anidado en el último elemento `section` debe estar debajo del elemento `h2`. Tienes el elemento `h2` y el elemento `form` en el orden incorrecto. + +```js +assert(document.querySelector('form').previousElementSibling.nodeName === 'H2'); +``` + +Tu elemento `form` no debe tener contenido. Elimina cualquier elemento HTML o texto que tengas entre las etiquetas del elemento `form`. + +```js +assert($('form')[0].innerHTML.trim().length === 0); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +--fcc-editable-region-- +

    Cat Form

    +--fcc-editable-region-- +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d7.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d7.md new file mode 100644 index 00000000000000..6f5a3d4d6475c7 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d7.md @@ -0,0 +1,116 @@ +--- +id: 5ef9b03c81a63668521804d7 +title: Paso 35 +challengeType: 0 +dashedName: step-35 +--- + +# --description-- + +El atributo `action` indica, dónde deben enviarse los datos del formulario. Por ejemplo, `
    ` le dice al navegador que los datos del formulario deben ser enviados a la ruta `/submit-url`. + +Al elemento `form`, añádele un atributo `action` con el valor `https://freecatphotoapp.com/submit-cat-photo`. + +# --hints-- + +Tu elemento `form` debe tener una etiqueta de apertura y una etiqueta de cierre. Puede que te falte una o dos de las etiquetas requeridas o las tienes en el orden incorrecto. + +```js +const noSpaces = code.replace(/\s/g, ''); +assert( + document.querySelector('form') && + code.match(/<\/form>/g) && + noSpaces.indexOf('') +); +``` + +Tu elemento `form` anidado en el último elemento `section` debe estar debajo del elemento `h2`. Tienes el elemento `h2` y el elemento `form` en el orden incorrecto. + +```js +assert(document.querySelector('form').previousElementSibling.nodeName === 'H2'); +``` + +Tu elemento `form` no debe tener contenido. Elimina cualquier elemento HTML o texto que tengas entre las etiquetas del elemento `form`. + +```js +assert($('form')[0].innerHTML.trim().length === 0); +``` + +Tu elemento `form` no tiene un atributo `action`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +const form = document.querySelector('form'); +assert(form.hasAttribute('action')); +``` + +Tu formulario `form` debe tener un atributo `action` con el valor `https://freecatphotoapp.com/submit-cat-photo`. + +```js +const form = document.querySelector('form'); +assert( + form + .getAttribute('action') + .match(/^https:\/\/freecatphotoapp\.com\/submit-cat-photo$/) +); +``` + +Aunque el atributo `action` tenga la URL correcta, se recomienda siempre poner entre comillas el valor de un atributo. + +```js +assert( + !/\ + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +--fcc-editable-region-- +
    +
    +--fcc-editable-region-- +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d8.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d8.md new file mode 100644 index 00000000000000..a19065348cecf2 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d8.md @@ -0,0 +1,109 @@ +--- +id: 5ef9b03c81a63668521804d8 +title: Paso 36 +challengeType: 0 +dashedName: step-36 +--- + +# --description-- + +El elemento `input` te permite recolectar datos desde un formulario web de diferentes formas. Al igual que los elementos `img`, los elementos `input` son de auto-cierre y no necesitan etiquetas de cierre. + +Anida un elemento `input` dentro del elemento `form`. + +# --hints-- + +Tu elemento `form` debe tener una etiqueta de apertura y una etiqueta de cierre en el orden correcto. Puede que te falte una o dos de las etiquetas requeridas o las tienes en el orden incorrecto. + +```js +const noSpaces = code.replace(/\s/g, ''); +assert( + document.querySelector('form') && + code.match(/<\/form>/g) && + noSpaces.indexOf('') +); +``` + +La etiqueta de apertura de tu elemento `form` solo debe tener un atributo `action`. Elimina cualquier otra cosa que hayas escrito en ella. + +```js +assert([...document.querySelector('form').attributes].length < 2); +``` + +Debes crear un elemento input. Revisa la sintaxis. + +```js +assert(document.querySelector('input')); +``` + +Tu elemento `input` debe tener una etiqueta de apertura, pero no una etiquete de cierre. + +```js +assert(document.querySelector('input') && !code.match(/<\/input\>/g)); +``` + +Tu elemento `input` debe estar anidado dentro del elemento `form`. + +```js +assert(document.querySelector('form > input')); +``` + +Tu elemento `form` solo debe contener el elemento `input`. Elimina cualquier elemento HTML o texto que tengas entre las etiquetas del elemento `form`. + +```js +assert( + $('form')[0].children.length === 1 && + $('form')[0].innerText.trim().length === 0 +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +--fcc-editable-region-- +
    +
    +--fcc-editable-region-- +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d9.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d9.md new file mode 100644 index 00000000000000..ead83fea544f0f --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d9.md @@ -0,0 +1,104 @@ +--- +id: 5ef9b03c81a63668521804d9 +title: Paso 39 +challengeType: 0 +dashedName: step-39 +--- + +# --description-- + +Un texto provisional (placeholder) nos da una idea de que tipo de información debemos escribir en un elemento input. Por ejemplo, ``. + +Añade el texto provisional `cat photo URL` a tu elemento `input`. + +# --hints-- + +Has eliminado el elemento `input` o tiene sintaxis inválida. Todos los valores de los atributos deben estar entre comillas. + +```js +assert($('input').length); +``` + +Tu elemento `form` solo debe contener el elemento `input`. Elimina cualquier elemento HTML o texto que tengas entre las etiquetas del elemento `form`. + +```js +assert( + $('form')[0].children.length === 1 && + $('form')[0].innerText.trim().length === 0 +); +``` + +Tu elemento `input` no tiene un atributo `placeholder`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +assert($('input')[0].hasAttribute('placeholder')); +``` + +Tu elemento `input` debe tener un atributo `placeholder` con el valor `cat photo URL`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +assert( + $('input')[0] + .getAttribute('placeholder') + .replace(/\s+/g, ' ') + .match(/^cat photo URL$/i) +); +``` + +Aunque al atributo `placeholder` del elemento `input` le hayas dado el valor `cat photo URL`, se recomienda siempre poner el valor de un atributo entre comillas. + +```js +assert(!/\<\s*input\s+placeholder\s*=\s*cat\s+photo\s+url/i.test(code)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +--fcc-editable-region-- + +--fcc-editable-region-- +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804da.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804da.md new file mode 100644 index 00000000000000..5fcff4721658ea --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804da.md @@ -0,0 +1,93 @@ +--- +id: 5ef9b03c81a63668521804da +title: Paso 41 +challengeType: 0 +dashedName: step-41 +--- + +# --description-- + +Utiliza el elemento `button` para crear un botón cliqueable. Por ejemplo, `` crea un botón con el texto `Click Here`. + +Añade un elemento `button` con el texto `Submit` debajo del elemento `input`. El comportamiento predeterminado de un botón sin atributos en un formulario es enviar la información a la ubicación especificada en el atributo `action` del formulario. + +# --hints-- + +Tu elemento `button` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('button')); +``` + +Tu elemento `button` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/button\>/)); +``` + +El texto de tu elemento `button` debe ser `Submit`. Probablemente no has añadido el texto o tienes un error tipográfico. + +```js +assert(document.querySelector('button').innerText.toLowerCase() === 'submit'); +``` + +Tu elemento `button` debe estar debajo del elemento `input`. Los tienes en el orden incorrecto. + +```js +const collection = [...document.querySelectorAll('input, button')].map( + (node) => node.nodeName +); +assert(collection.indexOf('INPUT') < collection.indexOf('BUTTON')); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +--fcc-editable-region-- + +--fcc-editable-region-- +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804db.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804db.md new file mode 100644 index 00000000000000..4e33170896f7bb --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804db.md @@ -0,0 +1,91 @@ +--- +id: 5ef9b03c81a63668521804db +title: Paso 40 +challengeType: 0 +dashedName: step-40 +--- + +# --description-- + +Para evitar que un usuario entregue su formulario incompleto, necesitas añadir el atributo `required` al elemento `input`. El atributo `required` no necesita ningún valor. Simplemente necesitas añadir la palabra `required` al elemento `input`, asegurándote de que hay espacios entre ella y los otros atributos. + +# --hints-- + +Has eliminado el elemento `input` o la sintaxis es incorrecta. Todos los valores de los atributos deben estar entre comillas. + +```js +assert($('input').length); +``` + +Tu elemento `form` solo debe contener el elemento `input`. Elimina cualquier elemento HTML o texto que tengas entre las etiquetas del elemento `form`. + +```js +assert( + $('form')[0].children.length === 1 && + $('form')[0].innerText.trim().length === 0 +); +``` + +Tu elemento `input` debe tener el atributo `required`. Recuerda, simplemente añade la palabra `required` a la etiqueta del elemento `input`. + +```js +assert($('input')[0].hasAttribute('required')); +``` + +No debes añadir ningún valor al atributo `required`. + +```js +assert($('input')[0].getAttribute('required') === ''); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +--fcc-editable-region-- + +--fcc-editable-region-- +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804dc.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804dc.md new file mode 100644 index 00000000000000..da092ad64147b4 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804dc.md @@ -0,0 +1,137 @@ +--- +id: 5ef9b03c81a63668521804dc +title: Paso 43 +challengeType: 0 +dashedName: step-43 +--- + +# --description-- + +Puedes usar botones de radio (radio button) para preguntas en las que quieres que el usuario solo te dé una respuesta a partir de múltiples opciones. + +Aquí hay un ejemplo de un radio button con la opción `cat`: ` cat`. Recuerda que los elementos `input` son de auto-cierre, no necesitan etiqueta de cierre. + +Antes de la casilla de entrada de texto (text input), añade un radio button con la opción: + +`Indoor` + +# --hints-- + +Debes crear un elemento input para tu radio button. Revisa la sintaxis. + +```js +assert($('form > input').length >= 2); +``` + +Tu elemento `input` debe tener una etiqueta de apertura, pero no una etiquete de cierre. + +```js +assert($('form > input') && !code.match(/<\/input\>/g)); +``` + +Solo debiste de haber añadido un elemento input para tu radio button. Elimina los que estén de más. + +```js +assert($('form > input').length === 2); +``` + +Tu nuevo elemento `input` debe estar arriba del elemento `input` ya existente que tiene un atributo `type` con el valor `text`. Los tienes en el orden incorrecto. + +```js +const existingInputElem = document.querySelector('form > input[type="text"]'); +assert( + existingInputElem && + existingInputElem.previousElementSibling.nodeName === 'INPUT' +); +``` + +Tu nuevo elemento `input` no tiene un atributo `type`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura. + +```js +assert($('input')[0].hasAttribute('type')); +``` + +Tu nuevo elemento `input` debe tener un atributo `type` con el valor `radio`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +assert( + $('input')[0] + .getAttribute('type') + .match(/^radio$/i) +); +``` + +Aunque al atributo `type` del elemento `input` le hayas dado el valor `radio`, se recomienda siempre poner el valor de un atributo entre comillas. + +```js +assert(!/\<\s*input\s+type\s*=\s*radio/i.test(code)); +``` + +El texto `Indoor` debe estar después del `radio` button no antes. + +```js +const radioInputElem = $('input')[0]; +assert(!radioInputElem.previousSibling.nodeValue.match(/Indoor/i)); +``` + +El texto `Indoor` debe estar inmediatamente a la derecha del `radio` button ningún espacio. Probablemente no has añadido el texto o tienes un error tipográfico. + +```js +const radioInputElem = $('input')[0]; +assert( + radioInputElem.nextSibling.nodeValue.replace(/\s+/g, ' ').match(/Indoor/i) +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +--fcc-editable-region-- + +--fcc-editable-region-- + +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804dd.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804dd.md new file mode 100644 index 00000000000000..8cfe2ae1736044 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804dd.md @@ -0,0 +1,104 @@ +--- +id: 5ef9b03c81a63668521804dd +title: Paso 44 +challengeType: 0 +dashedName: step-44 +--- + +# --description-- + +Un elemento `label` es como una etiqueta que ayuda a asociar un texto a un elemento `input` (Especialmente para tecnologías de asistencia como lectores de pantalla). Por ejemplo, `` hace que al hacer click en la palabra `cat` se seleccione el radio button correspondiente. + +Anida tu `radio` button dentro de un elemento `label`. + +# --hints-- + +Asegúrate de que el radio button aún está presente. + +```js +assert($('input[type="radio"]')[0]); +``` + +El texto `Indoor` debe estar inmediatamente a la derecha del `radio` button. Asegúrate de que hay un espacio entre el elemento y el texto. Probablemente no has añadido el texto o tienes un error tipográfico. + +```js +const radioInputElem = $('input')[0]; +assert( + radioInputElem.nextSibling.nodeValue.replace(/\s+/g, ' ').match(/ Indoor/i) +); +``` + +Tu elemento `label` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('label')); +``` + +Tu elemento `label` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/label\>/)); +``` + +El botón de radio y su texto deben ubicarse entre las etiquetas de apertura y cierre del elemento `label`. + +```js +const labelChildNodes = [...$('form > label')[0].childNodes]; +assert( + labelChildNodes.filter((childNode) => childNode.nodeName === 'INPUT').length +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +--fcc-editable-region-- + Indoor +--fcc-editable-region-- + + +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804de.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804de.md new file mode 100644 index 00000000000000..78b0d88b3a81c8 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804de.md @@ -0,0 +1,98 @@ +--- +id: 5ef9b03c81a63668521804de +title: Paso 47 +challengeType: 0 +dashedName: step-47 +--- + +# --description-- + +Puedes observar que ambos elementos radio button pueden ser seleccionados al mismo tiempo. Para hacer que al seleccionar un radio button, el otro sé deseleccione automáticamente, ambos botones deben tener un atributo `name` con el mismo valor. + +Añade el atributo `name` con el valor `indoor-outdoor` a ambos radio button. + +# --hints-- + +Ambosradio button aún deben estar ubicados entre las etiquetas de apertura y cierre del elemento `label`. + +```js +const labelChildNodes = [...document.querySelectorAll('form > label')].map( + (node) => node.childNodes +); +assert( + labelChildNodes.filter((childNode) => childNode[0].nodeName === 'INPUT') + .length === 2 +); +``` + +Ambos radio button deben tener un atributo `name`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +const radioButtons = [...document.querySelectorAll('input[type="radio"]')]; +assert(radioButtons.every((btn) => btn.hasAttribute('name'))); +``` + +Ambos radio button deben tener un atributo `name` con el valor `indoor-outdoor`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +const radioButtons = [...$('input[type="radio"]')]; +assert( + radioButtons.every((btn) => + btn.getAttribute('name').match(/^indoor-outdoor$/) + ) +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +--fcc-editable-region-- + + +--fcc-editable-region-- + + +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804df.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804df.md new file mode 100644 index 00000000000000..6a7f4e1a515a00 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804df.md @@ -0,0 +1,89 @@ +--- +id: 5ef9b03c81a63668521804df +title: Paso 45 +challengeType: 0 +dashedName: step-45 +--- + +# --description-- + +El atributo `id` se utiliza para identificar elementos HTML específicos. Cada atributo `id` debe tener un valor único, diferente a los demás valores `id` de la página. + +Añade un atributo `id` con el valor `indoor` al radio button. Cuando los elementos tienen múltiples atributos, el orden de los atributos no es importante. + +# --hints-- + +Tu radio button debe ubicarse entre las etiquetas de apertura y cierre del elemento `label`. + +```js +const labelChildNodes = [...$('form > label')[0].childNodes]; +assert( + labelChildNodes.filter((childNode) => childNode.nodeName === 'INPUT').length +); +``` + +Tu radio button debe tener un atributo `id`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +assert($('input')[0].hasAttribute('id')); +``` + +Tu elemento radio button debe tener un atributo `id` con el valor `indoor`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +assert($('input')[0].id.match(/^indoor$/)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +--fcc-editable-region-- + +--fcc-editable-region-- + + +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e1.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e1.md new file mode 100644 index 00000000000000..dce69d29bb9996 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e1.md @@ -0,0 +1,102 @@ +--- +id: 5ef9b03c81a63668521804e1 +title: Paso 49 +challengeType: 0 +dashedName: step-49 +--- + +# --description-- + +El elemento `fieldset` se utiliza para agrupar elementos input y label relacionados dentro de un formulario web. Los elementos `fieldset` son elementos de nivel de bloque, lo que significa que aparecen en una nueva línea. + +Anida los radio button `Indoor` y `Outdoor` dentro de un elemento `fieldset`, y no olvides la indentación de los botones. + +# --hints-- + +Ambos radio button aún deben estar ubicados entre las etiquetas de apertura y cierre del elemento `label`. + +```js +const labelChildNodes = [...$('label')].map((node) => [...node.childNodes]); +assert( + labelChildNodes.filter( + childNodes => + childNodes.filter(node => node.nodeName === 'INPUT').length === 1 + ).length === 2 +); +``` + +Tu elemento `fieldset` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('fieldset')); +``` + +Tu elemento `fieldset` debe tener una etiqueta de cierre. Las etiquetas de cierre tienen una `/` inmediatamente después del carácter `<`. + +```js +assert(code.match(/<\/fieldset\>/)); +``` + +Ambos radio button y sus respectivos elementos label deben estar entre las etiquetas de apretura y cierre del elemento `fieldset`. + +```js +const radioButtons = [...$('input[type="radio"]')]; +assert( + radioButtons.every((btn) => btn.parentNode.parentNode.nodeName === 'FIELDSET') +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +--fcc-editable-region-- + + +--fcc-editable-region-- + + +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e2.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e2.md new file mode 100644 index 00000000000000..85ba3b8c46efc9 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e2.md @@ -0,0 +1,130 @@ +--- +id: 5ef9b03c81a63668521804e2 +title: Paso 53 +challengeType: 0 +dashedName: step-53 +--- + +# --description-- + +Los formularios Usualmente usan casillas de verificación (checkboxes-checkbox) para preguntas que puedan tener más de una respuesta. Por ejemplo, aquí hay un checkbox (casilla de verificación) con la opción `tacos`: ` tacos`. + +Bajo el elemento `legend` que acabas de añadir, agrega un elemento `input` con un atributo `type` con el valor `checkbox` y dale la opción: + +`Loving` + +# --hints-- + +Tu elemento `input` de tu checkbox debe tener una etiqueta de apertura, pero no una etiquete de cierre. + +```js +assert($('fieldset > input') && !code.match(/<\/input\>/g)); +``` + +Solo debiste de haber añadido un elemento input para tu checkbox. Elimina los que estén de más. + +```js +assert($('fieldset > input').length === 1); +``` + +Tu nuevo elemento `input` debe estar debajo del elemento `legend` que tiene el texto `What's your cat's personality?`. Los tienes en el orden incorrecto. + +```js +const existingLegendElem = $('fieldset > legend')[1]; +assert( + existingLegendElem && + existingLegendElem.nextElementSibling.nodeName === 'INPUT' +); +``` + +Tu nuevo elemento `input` no tiene un atributo `type`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura. + +```js +assert($('fieldset > input')[0].hasAttribute('type')); +``` + +Tu nuevo elemento `input` debe tener un atributo `type` con el valor `checkbox`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +assert( + $('fieldset > input')[0] + .getAttribute('type') + .match(/^checkbox$/i) +); +``` + +Aunque al atributo `type` del elemento `input` le hayas dado el valor `checkbox`, se recomienda siempre poner el valor de un atributo entre comillas. + +```js +assert(!/\<\s*input\s+type\s*=\s*checkbox/i.test(code)); +``` + +El texto `Loving` debe estar inmediatamente a la derecha de tu checkbox. Asegúrate de que hay un espacio entre el elemento y el texto. Probablemente no has añadido el texto o tienes un error tipográfico. + +```js +const checkboxInputElem = $('input[type="checkbox"]')[0]; +assert( + checkboxInputElem.nextSibling.nodeValue.replace(/\s+/g, ' ').match(/ Loving/i) +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +
    + Is your cat an indoor or outdoor cat? + + +
    +
    +--fcc-editable-region-- + What's your cat's personality? +--fcc-editable-region-- +
    + + +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e3.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e3.md new file mode 100644 index 00000000000000..fc62a80890a8b9 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e3.md @@ -0,0 +1,122 @@ +--- +id: 5ef9b03c81a63668521804e3 +title: Paso 57 +challengeType: 0 +dashedName: step-57 +--- + +# --description-- + +Añade otro checkbox después del que acabas de añadir. El valor de atributo `id` debe ser `lazy` y el valor de atributo `name` debe ser el mismo que el del último checkbox. + +También añade un elemento `label` a la derecha del nuevo elemento checkbox con el texto `Lazy`. Asegúrate de asociar el elemento `label` con el nuevo checkbox utilizando el atributo `for`. + +# --hints-- + +Necesitas añadir un nuevo checkbox. + +```js +assert($('input[type="checkbox"]').length === 2); +``` + +Su nuevo checkbox debe tener un atributo `id` con el valor `lazy` y un atributo `name` con el valor `personality`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +const checkboxes = [...$('input[type="checkbox"]')]; +assert( + checkboxes.some( + (checkbox) => + checkbox.id === 'lazy' && checkbox.getAttribute('name') === 'personality' + ) +); +``` + +Tu nuevo checkbox debe estar después del primero. Los tienes en el orden incorrecto. + +```js +const checkboxes = [...$('input[type="checkbox"]')].map( + (checkbox) => checkbox.id +); +assert(checkboxes.indexOf('loving') < checkboxes.indexOf('lazy')); +``` + +A la derecha de tu nuevo checkbox, debe haber un elemento `label` con el texto `Lazy`. + +```js +const nextElementSibling = $('input[type="checkbox"]')[1].nextElementSibling; +assert( + nextElementSibling.nodeName === 'LABEL' && + nextElementSibling.innerText.replace(/\s+/g, '').match(/^Lazy$/i) +); +``` + +El nuevo elemento `label` debe tener un atributo `for` con el mismo valor del atributo `id` del checkbox. Probablemente no has añadido el valor o tienes un error tipográfico. + +```js +assert( + $('input[type="checkbox"]')[1].nextElementSibling.getAttribute('for') === + 'lazy' +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +
    + Is your cat an indoor or outdoor cat? + + +
    +
    + What's your cat's personality? +--fcc-editable-region-- + +--fcc-editable-region-- +
    + + +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e5.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e5.md new file mode 100644 index 00000000000000..5f922afe5dacd0 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e5.md @@ -0,0 +1,117 @@ +--- +id: 5ef9b03c81a63668521804e5 +title: Paso 60 +challengeType: 0 +dashedName: step-60 +--- + +# --description-- + +Para hacer que un checkbox o un radio button este seleccionado por defecto, necesitas añadir el atributo `checked`. No hay necesidad de agregarle un valor al atributo `checked`. Simplemente necesitas añadir la palabra `checked` al elemento `input`, asegurándote de que hay espacios entre ella y los otros atributos. + +Haz que el primer radio button y el primer checkbox estén seleccionados por defecto. + +# --hints-- + +Asegúrate de que todavía hay dos radio button y tres checkbox anidados en sus respectivos elementos `fieldset`. + +```js +assert( + $('input[type="radio"]').length === 2 && + $('fieldset > input[type="checkbox"]').length === 3 +); +``` + +Al primer radio button le falta el atributo `checked`. + +```js +assert($('input[type="radio"]')[0].hasAttribute('checked')); +``` + +El segundo radio button no debe tener el atributo `checked`. + +```js +assert(!$('input[type="radio"]')[1].hasAttribute('checked')); +``` + +Al primer checkbox le falta el atributo `checked`. + +```js +assert($('input[type="checkbox"]')[0].hasAttribute('checked')); +``` + +El segundo checkbox no debe tener el atributo `checked`. + +```js +assert(!$('input[type="checkbox"]')[1].hasAttribute('checked')); +``` + +El tercer checkbox no debe tener el atributo `checked`. + +```js +assert(!$('input[type="checkbox"]')[2].hasAttribute('checked')); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +--fcc-editable-region-- +
    + Is your cat an indoor or outdoor cat? + + +
    +
    + What's your cat's personality? + + + +
    +--fcc-editable-region-- + + +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e7.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e7.md new file mode 100644 index 00000000000000..336e15c7b8c375 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e7.md @@ -0,0 +1,102 @@ +--- +id: 5ef9b03c81a63668521804e7 +title: Paso 61 +challengeType: 0 +dashedName: step-61 +--- + +# --description-- + +Ahora añadirás un pie de página con el elemento footer. + +Después del elemento `main` añade un elemento `footer`. + +# --hints-- + +Has eliminado el elemento `main` o le falta una etiqueta de apertura o de cierre. + +```js +assert(document.querySelector('main') && code.match(/<\/main>/)); +``` + +Tu elemento `footer` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('footer')); +``` + +Tu elemento `footer` debe tener una etiqueta de cierre. Las etiquetas de cierre tienen una `/` inmediatamente después del carácter `<`. + +```js +assert(code.match(/<\/footer\>/)); +``` + +Tu elemento `footer` debe ir debajo de la etiqueta de cierre del elemento `main`. Lo has puesto en un lugar diferente. + +```js +assert(document.querySelector('main').nextElementSibling.nodeName === 'FOOTER'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +
    + Is your cat an indoor or outdoor cat? + + +
    +
    + What's your cat's personality? + + + +
    + + +
    +
    +--fcc-editable-region-- +
    + + +--fcc-editable-region-- +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e8.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e8.md new file mode 100644 index 00000000000000..949658ca1dfeef --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e8.md @@ -0,0 +1,104 @@ +--- +id: 5ef9b03c81a63668521804e8 +title: Paso 62 +challengeType: 0 +dashedName: step-62 +--- + +# --description-- + +Anida un elemento `p` con el texto `No Copyright - freeCodeCamp.org` dentro del elemento `footer`. + +# --hints-- + +Has eliminado el elemento `footer` o le falta una etiqueta de apertura o de cierre. + +```js +assert(document.querySelector('footer') && code.match(/<\/footer>/)); +``` + +Tu elemento `footer` debe tener un elemento `p`. Asegúrate de añadir una etiqueta de apertura y de cierre al elemento `p`. + +```js +assert(document.querySelector('footer > p')); +``` + +Tu elemento `footer` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +const pElemClosingTags = code.match(/<\/p\>/g); +assert(pElemClosingTags && pElemClosingTags.length === 2); +``` + +El texto de tu elemento `p` debe ser `No Copyright - freeCodeCamp.org`. Probablemente olvidaste añadir el texto, tienes un error tipográfico o no está entre las etiquetas de apertura y cierre del elemento `p`. + +```js +const extraSpacesRemoved = $('footer > p')[0].innerText.replace(/\s+/g, ' '); +assert(extraSpacesRemoved.match(/No Copyright - freeCodeCamp\.org$/i)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +
    + Is your cat an indoor or outdoor cat? + + +
    +
    + What's your cat's personality? + + + +
    + + +
    +
    +
    +--fcc-editable-region-- +
    +
    +--fcc-editable-region-- + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e9.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e9.md new file mode 100644 index 00000000000000..7903e637a95e0e --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e9.md @@ -0,0 +1,118 @@ +--- +id: 5ef9b03c81a63668521804e9 +title: Paso 63 +challengeType: 0 +dashedName: step-63 +--- + +# --description-- + +Convierte el texto `freeCodeCamp.org` a un link, poniendo dentro de un elemento anchor (`a`). El valor del atributo `href` debe ser `https://www.freecodecamp.org`. + +# --hints-- + +Tu elemento anchor (`a`) debe estar anidado dentro del elemento `footer`. Asegúrate de añadir una etiqueta de apertura y de cierre al elemento anchor (`a`). + +```js +assert($('footer > p > a').length); +``` + +Tu elemento anchor (`a`) debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +const aElemClosingTags = code.match(/<\/a\>/g); +assert(aElemClosingTags && aElemClosingTags.length === 3); +``` + +Tu elemento anchor (`a`) debe tener un atributo `href` con el valor `https://www.freecodecamp.org`. Probablemente no has añadido el atributo/valor o tienes un error tipográfico. + +```js +const nestedAnchor = $('footer > p > a')[0]; +assert(nestedAnchor.getAttribute('href').toLowerCase() === 'https://www.freecodecamp.org'); +``` + +El texto del enlace debe ser `freeCodeCamp.org`. Probablemente no has añadido el texto o tienes un error tipográfico. + +```js +const nestedAnchor = $('footer > p > a')[0]; +assert( + nestedAnchor.innerText.toLowerCase().replace(/\s+/g, ' ') === + 'freecodecamp.org' +); +``` + +Después de anidar el elemento anchor (`a`), el único texto de un elemento `p`, visible en el navegador, debe ser, `No Copyright - freeCodeCamp.org`. Comprueba que el texto, el espaciado o la puntuación del elemento `p` y del elemento anchor anidado son correctos. + +```js +const pText = $('footer > p')[0].innerText.toLowerCase().replace(/\s+/g, ' '); +assert(pText.match(/^no copyright - freecodecamp.org$/)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +
    + Is your cat an indoor or outdoor cat? + + +
    +
    + What's your cat's personality? + + + +
    + + +
    +
    +
    +
    +

    +--fcc-editable-region-- + No Copyright - freeCodeCamp.org +--fcc-editable-region-- +

    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804ea.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804ea.md new file mode 100644 index 00000000000000..4437208d643b20 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804ea.md @@ -0,0 +1,108 @@ +--- +id: 5ef9b03c81a63668521804ea +title: Paso 64 +challengeType: 0 +dashedName: step-64 +--- + +# --description-- + +Puedes notar que todo lo que has añadido hasta ahora, está dentro del elemento `body`. Todos los elementos que deben ser renderizados o mostrados en la página, deben ir dentro del elemento `body`. Sin embargo, otro tipo información que también es importante va dentro del elemento `head`. + +Añade un elemento `head` justo arriba del elemento `body`. + +# --hints-- + +Has eliminado el elemento `body` o le falta una etiqueta de apertura o de cierre. + +```js +assert(document.querySelector('body') && code.match(/<\/body>/)); +``` + +Tu elemento `head` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(code.match(/\/)); +``` + +Tu elemento `head` debe tener una etiqueta de cierre. Las etiquetas de cierre tienen una `/` inmediatamente después del carácter `<`. + +```js +assert(code.match(/\<\/head\>/)); +``` + +Tu elemento `head` debe ir arriba de la etiqueta de apertura del elemento `body`. Lo has puesto en un lugar diferente. + +```js +const noSpaces = code.replace(/\s/g, ''); +assert(noSpaces.match(/\<\/head\>\/)); +``` + +# --seed-- + +## --seed-contents-- + +```html + +--fcc-editable-region-- + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +
    + Is your cat an indoor or outdoor cat? + + +
    +
    + What's your cat's personality? + + + +
    + + +
    +
    +
    + + +--fcc-editable-region-- + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804eb.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804eb.md new file mode 100644 index 00000000000000..f2b0ab30f3dd53 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804eb.md @@ -0,0 +1,112 @@ +--- +id: 5ef9b03c81a63668521804eb +title: Paso 65 +challengeType: 0 +dashedName: step-65 +--- + +# --description-- + +El elemento `title` (título) determina lo que los navegadores muestran en la barra de título o en las pestañas del navegador. + +Dentro del elemento `head` añade un elemento `title` con el siguiente texto: + +`CatPhotoApp` + +# --hints-- + +Has eliminado el elemento `head` o le falta una etiqueta de apertura o de cierre. + +```js +assert(code.match(/\/) && code.match(/\<\/head\>/)); +``` + +Tu elemento `title` debe estar anidado dentro del elemento `head`. Asegúrate de añadir una etiqueta de apertura y de cierre al elemento `title`. + +```js +const noSpaces = code.replace(/\s/g, ''); +assert(noSpaces.match(/\\.*\<\/title\>\<\/head\>/)); +``` + +Tu elemento `title` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/\<\/title\>/)); +``` + +El texto de tu elemento `title` deber ser `CatPhotoApp`. Probablemente no has añadido el texto o tienes un error tipográfico. + +```js +assert(document.title && document.title.toLowerCase() === 'catphotoapp'); +``` + +# --seed-- + +## --seed-contents-- + +```html + +--fcc-editable-region-- + + +--fcc-editable-region-- + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +
    + Is your cat an indoor or outdoor cat? + + +
    +
    + What's your cat's personality? + + + +
    + + +
    +
    +
    + + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804ec.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804ec.md new file mode 100644 index 00000000000000..5dedca8cfbdab7 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804ec.md @@ -0,0 +1,105 @@ +--- +id: 5ef9b03c81a63668521804ec +title: Paso 66 +challengeType: 0 +dashedName: step-66 +--- + +# --description-- + +Puedes ver que todo el contenido de la página está anidado dentro de un elemento `html`. Podemos deducir que todos los elementos son descendientes de este elemento `html`. + +Añade un atributo `lang` con el valor `en` a la etiqueta de apertura del elemento `html` para especificar que el lenguaje de la página es el inglés. + +# --hints-- + +Has eliminado el elemento `html` o le falta una etiqueta de apertura o de cierre. + +```js +assert(code.match(/\/) && code.match(/\<\/html\>/)); +``` + +Tu elemento `html` debe tener un atributo `lang` con el valor `en`. Probablemente no has añadido el atributo/valor o tienes un error tipográfico. + +```js +const extraSpacesRemoved = code.replace(/\s+/g, ' '); +assert(extraSpacesRemoved.match(/\/)); +``` + +Aunque al atributo `lang` del elemento `html` le hayas dado el valor `en`, se recomienda siempre poner el valor de un atributo entre comillas. + +```js +assert(code.match(//gi)); +``` + +# --seed-- + +## --seed-contents-- + +```html +--fcc-editable-region-- + +--fcc-editable-region-- + + CatPhotoApp + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +
    + Is your cat an indoor or outdoor cat? + + +
    +
    + What's your cat's personality? + + + +
    + + +
    +
    +
    + + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804ee.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804ee.md new file mode 100644 index 00000000000000..ac81a72135e679 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804ee.md @@ -0,0 +1,166 @@ +--- +id: 5ef9b03c81a63668521804ee +title: Paso 67 +challengeType: 0 +dashedName: step-67 +--- + +# --description-- + +Todas las páginas deben comenzar con ``. Esta cadena especial es conocida como una declaración y se asegura de que el navegador intente cumplir las especificaciones de la industria. + +Para completar este proyecto, añade esta declaración como la primera línea del código. + +# --hints-- + +Tu código debe comenzar con la declaración ``. Probablemente omitiste la declaración, tienes un error tipográfico, o no es la primera línea de código. + +```js +assert(code.match(/\<\s*!DOCTYPE\s+html\s*\>/)); +``` + +La declaración `` debe estar ubicada hasta arriba del documento. + +```js +const noSpaces = code.replace(/\s/g, ''); +assert(noSpaces.match(/^\<\!DOCTYPEhtml\>\ + + CatPhotoApp + +--fcc-editable-region-- + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +
    + Is your cat an indoor or outdoor cat? + + +
    +
    + What's your cat's personality? + + + +
    + + +
    +
    +
    + + + +``` + +# --solutions-- + +```html + + + + CatPhotoApp + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +
    + Is your cat an indoor or outdoor cat? + + +
    +
    + What's your cat's personality? + + + +
    + + +
    +
    +
    + + + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efada803cbd2bbdab94e332.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efada803cbd2bbdab94e332.md new file mode 100644 index 00000000000000..80cbf1335bb885 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efada803cbd2bbdab94e332.md @@ -0,0 +1,99 @@ +--- +id: 5efada803cbd2bbdab94e332 +title: Paso 28 +challengeType: 0 +dashedName: step-28 +--- + +# --description-- + +Dentro del elemento `figure` que acabas de añadir, anida un elemento `img` con un atributo `src` con el valor `https://cdn.freecodecamp.org/curriculum/cat-photo-app/cats.jpg`. + +# --hints-- + +Tu segundo elemento `figure` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelectorAll('figure').length >= 2); +``` + +Tu segundo elemento `figure` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/figure>/g).length >= 2); +``` + +Debe haber un segundo elemento `figure` justo arriba de la etiqueta de cierre del segundo elemento `section`. Los tienes en el orden incorrecto. + +```js +assert($('main > section')[1].lastElementChild.nodeName === 'FIGURE'); +``` + +Debes tener tercer elemento `img` anidado en el elemento `figure`. + +```js +const catsImg = document.querySelectorAll('figure > img')[1]; +assert( + catsImg +); +``` + +La tercer imagen, debe tener un atributo `src` con el valor `https://cdn.freecodecamp.org/curriculum/cat-photo-app/cats.jpg`. + +```js +const catsImg = document.querySelectorAll('figure > img')[1]; +assert( + catsImg && + catsImg.getAttribute('src').toLowerCase() === 'https://cdn.freecodecamp.org/curriculum/cat-photo-app/cats.jpg' +); +``` + +Aunque el atributo `src` de la nueva imagen tenga la URL correcta, se recomienda siempre poner entre comillas el valor de un atributo. + +```js +assert(!/\ + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +--fcc-editable-region-- +
    +
    +--fcc-editable-region-- +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efae0543cbd2bbdab94e333.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efae0543cbd2bbdab94e333.md new file mode 100644 index 00000000000000..5f01b3b0afdbec --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efae0543cbd2bbdab94e333.md @@ -0,0 +1,99 @@ +--- +id: 5efae0543cbd2bbdab94e333 +title: Paso 29 +challengeType: 0 +dashedName: step-29 +--- + +# --description-- + +Para mejorar la accesibilidad de la imagen que acabas de añadir, añade un atributo `alt` con el texto: + +`Five cats looking around a field.` + +# --hints-- + +Tu elemento `figure` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelectorAll('figure').length === 2); +``` + +Tu elemento `ol` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/figure>/g).length === 2); +``` + +Debe haber un elemento `figure` justo arriba de la etiqueta de cierre del último elemento `section`. + +```js +assert($('main > section')[1].lastElementChild.nodeName === 'FIGURE'); +``` + +El elemento `img` con imagen de unos gatos debe estar anidado en el elemento `figure`. + +```js +const catsImg = document.querySelectorAll('figure > img')[1]; +assert( + catsImg && + catsImg.getAttribute('src').toLowerCase() === 'https://cdn.freecodecamp.org/curriculum/cat-photo-app/cats.jpg' +); +``` + +El elemento `img` debe tener un atributo `alt` con el valor `Five cats looking around a field.` + +```js +const catsImg = document.querySelectorAll('figure > img')[1]; +assert( + catsImg + .getAttribute('alt') + .replace(/\s+/g, ' ') + .match(/^Five cats looking around a field\.?$/i) +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    +--fcc-editable-region-- + +--fcc-editable-region-- +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efae16e3cbd2bbdab94e334.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efae16e3cbd2bbdab94e334.md new file mode 100644 index 00000000000000..f65a0c8eee3692 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efae16e3cbd2bbdab94e334.md @@ -0,0 +1,123 @@ +--- +id: 5efae16e3cbd2bbdab94e334 +title: Paso 30 +challengeType: 0 +dashedName: step-30 +--- + +# --description-- + +Después del último elemento `img` añade un elemento `figcaption` con el texto `Cats hate other cats.` + +# --hints-- + +Tu elemento `figcaption` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelectorAll('figcaption').length === 2); +``` + +Tu elemento `figcaption` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/figcaption\>/g).length === 2); +``` + +Debe haber un elemento `figure` justo arriba de la etiqueta de cierre del segundo elemento `section`. + +```js +assert($('main > section')[1].lastElementChild.nodeName === 'FIGURE'); +``` + +El último elemento `img` debe estar anidado en el elemento `figure`. + +```js +const catsImg = document.querySelectorAll('figure > img')[1]; +assert( + catsImg && + catsImg.getAttribute('src').toLowerCase() === 'https://cdn.freecodecamp.org/curriculum/cat-photo-app/cats.jpg' +); +``` + +Tu elemento `figure` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelectorAll('figure').length === 2); +``` + +Tu elemento `figure` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/figure\>/g).length === 2); +``` + +El elemento `figcaption` debe estar anidado en el elemento `figure`. + +```js +assert(document.querySelectorAll('figure > figcaption').length === 2); +``` + +El elemento `figcaption` anidado en el elemento `figure` debe estar debajo del elemento `img`. Tienes el elemento `img` y el elemento `figcaption` en el orden incorrecto. + +```js +assert( + document.querySelectorAll('figcaption')[1].previousElementSibling.nodeName === + 'IMG' +); +``` + +El elemento `figcaption` debe tener el texto `Cats hate other cats.` Has omitido una palabra o tienes un error tipográfico. + +```js +assert( + document + .querySelectorAll('figcaption')[1] + .innerText.toLowerCase() + .match(/Cats hate other cats\.?$/i) +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    +--fcc-editable-region-- + Five cats looking around a field. +--fcc-editable-region-- +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efb23e70dc218d6c85f89b1.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efb23e70dc218d6c85f89b1.md new file mode 100644 index 00000000000000..24d3915a008f15 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efb23e70dc218d6c85f89b1.md @@ -0,0 +1,104 @@ +--- +id: 5efb23e70dc218d6c85f89b1 +title: Paso 37 +challengeType: 0 +dashedName: step-37 +--- + +# --description-- + +Hay diferentes tipos de elementos input, los cuales los puedes crear con el atributo `type`. Puedes crear fácilmente un campo de contraseña (password), un botón de reinicio (reset) o un control para permitir a los usuarios seleccionar un archivo desde su computadora. + +Crea un campo de texto, para permitir la entrada de texto de un usuario, añadiendo el atributo `type` con el valor `text` al elemento `input`. + +# --hints-- + +Has eliminado el elemento `input` o tiene una sintaxis inválida. Si has añadido los atributos, asegúrate de que sus valores están entre comillas. + +```js +assert($('input').length); +``` + +Tu elemento `form` solo debe contener el elemento `input`. Elimina cualquier elemento HTML o texto extra que tengas entre las etiquetas del elemento `form`. + +```js +assert( + $('form')[0].children.length === 1 && + $('form')[0].innerText.trim().length === 0 +); +``` + +Tu elemento `input` no tiene un atributo `type` con el valor `text`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +assert($('input')[0].hasAttribute('type')); +``` + +Tu elemento `input` debe tener un atributo `type` con el valor `text`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +assert( + $('input')[0] + .getAttribute('type') + .replace(/\s+/g, ' ') + .match(/^text$/i) +); +``` + +Aunque al atributo `type` del elemento `input` le hayas dado el valor `text`, se recomienda siempre poner el valor de un atributo entre comillas. + +```js +assert(!/\ + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +--fcc-editable-region-- + +--fcc-editable-region-- +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efb2c990dc218d6c85f89b2.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efb2c990dc218d6c85f89b2.md new file mode 100644 index 00000000000000..51418efc41809d --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efb2c990dc218d6c85f89b2.md @@ -0,0 +1,101 @@ +--- +id: 5efb2c990dc218d6c85f89b2 +title: Paso 42 +challengeType: 0 +dashedName: step-42 +--- + +# --description-- + +A pesar de que hayas añadido tu botón debajo del elemento input de tipo texto, estos aparecen juntos en la página. Esto se debe a que los elementos `input` y `button` son elementos inline, los cuales no aparecen en una nueva línea. + +Anteriormente, aprendiste que el botón envía el formulario por defecto, pero puedes añadir el atributo `type` con el valor `submit` para hacerlo más claro. Adelante, hazlo para especificar dónde se debe enviar el formulario al hacer clic en el botón. + +# --hints-- + +Tu elemento `button` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('button')); +``` + +Tu elemento `button` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/button\>/)); +``` + +Tu elemento `button` no tiene un atributo `type`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura. + +```js +assert($('button')[0].hasAttribute('type')); +``` + +Tu elemento `button` debe tener un atributo `type` con el valor `submit`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +assert( + $('button')[0] + .getAttribute('type') + .match(/^submit$/i) +); +``` + +Aunque al atributo `type` del elemento `button` le hayas dado el valor `submit`, se recomienda siempre poner el valor de un atributo entre comillas. + +```js +assert(!/\<\s*button\s+type\s*=\s*submit/i.test(code)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    + +--fcc-editable-region-- + +--fcc-editable-region-- +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc4f528d6a74d05e68af74.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc4f528d6a74d05e68af74.md new file mode 100644 index 00000000000000..e8b22c5e0f0e77 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc4f528d6a74d05e68af74.md @@ -0,0 +1,136 @@ +--- +id: 5efc4f528d6a74d05e68af74 +title: Paso 55 +challengeType: 0 +dashedName: step-55 +--- + +# --description-- + +Hay otra manera de asociar un texto con el elemento `input`. Puedes anidar un texto dentro de un elemento `label` y añadirle un atributo `for` con el mismo valor del atributo `id` del elemento `input`. + +Asocia el texto `Loving` con el checkbox, anidando el texto `Loving` en un elemento `label` y colócalo a la derecha del elemento `input` de tipo checkbox. + +# --hints-- + +Asegúrate de que el checkbox aún está presente. + +```js +assert($('input[type="checkbox"]')[0]); +``` + +Tu checkbox, aún debe tener un atributo `id` con el valor `loving`. Talvez eliminaste el atributo o cambiaste su valor. + +```js +assert($('input[type="checkbox"]')[0].id === 'loving'); +``` + +El texto `Loving` ya no debe estar inmediatamente a la derecha de tu checkbox. Debe estar anidado dentro de un elemento `label`. Asegúrate de que hay un espacio entre los dos elementos. + +```js +const checkboxInputElem = $('input[type="checkbox"]')[0]; +assert( + !checkboxInputElem.nextSibling.nodeValue + .replace(/\s+/g, ' ') + .match(/ Loving/i) +); +``` + +Necesitas añadir un nuevo elemento `label` en el cual anidar el texto `Loving`. No olvides su etiqueta de apertura y cierre. + +```js +assert( + document.querySelectorAll('label').length === 3 && + code.match(/<\/label\>/g).length === 3 +); +``` + +El nuevo elemento `label` debe estar inmediatamente a la derecha de tu checkbox. Asegúrate de que hay un espacio entre los dos elementos. + +```js +const checkboxInputElem = $('input[type="checkbox"]')[0]; +assert(checkboxInputElem.nextElementSibling.nodeName === 'LABEL'); +``` + +El nuevo elemento `label` no tiene un atributo `for`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura. + +```js +const labelElem = $('input[type="checkbox"]')[0].nextElementSibling; +assert(labelElem.hasAttribute('for')); +``` + +El nuevo elemento `label` debe tener un atributo `for` con el valor `loving`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +const labelElem = $('input[type="checkbox"]')[0].nextElementSibling; +assert(labelElem.getAttribute('for').match(/^loving$/)); +``` + +El texto `Loving` debe estar anidado dentro del nuevo elemento `label`. Probablemente no has añadido el texto o tienes un error tipográfico. + +```js +const labelElem = document.querySelector('label[for="loving"]'); +assert(labelElem.textContent.replace(/\s/g, '').match(/Loving/i)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +
    + Is your cat an indoor or outdoor cat? + + +
    +
    + What's your cat's personality? +--fcc-editable-region-- + Loving +--fcc-editable-region-- +
    + + +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc518e8d6a74d05e68af75.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc518e8d6a74d05e68af75.md new file mode 100644 index 00000000000000..691db4dcce5513 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc518e8d6a74d05e68af75.md @@ -0,0 +1,98 @@ +--- +id: 5efc518e8d6a74d05e68af75 +title: Paso 56 +challengeType: 0 +dashedName: step-56 +--- + +# --description-- + +Añade el atributo `name` con el valor `personality` al elemento `input` de tipo checkbox. + +Aunque no notarás cambios en el navegador, hacer esto hará más fácil que un servidor procese tu formulario web, especialmente cuando hay múltiples checkbox. + +# --hints-- + +Asegúrate de que el checkbox aún está presente. + +```js +assert($('input[type="checkbox"]')[0]); +``` + +El elemento `input` de tipo checkbox no tiene un atributo `name`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura. + +```js +assert($('input[type="checkbox"]')[0].hasAttribute('name')); +``` + +El elemento `input` de tipo checkbox, debe tener un atributo `name` con el valor `personality`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +assert( + $('input[type="checkbox"]')[0] + .getAttribute('name') + .match(/^personality$/) +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +
    + Is your cat an indoor or outdoor cat? + + +
    +
    + What's your cat's personality? +--fcc-editable-region-- + +--fcc-editable-region-- +
    + + +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc54138d6a74d05e68af76.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc54138d6a74d05e68af76.md new file mode 100644 index 00000000000000..72fd8b5c9131e0 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc54138d6a74d05e68af76.md @@ -0,0 +1,86 @@ +--- +id: 5efc54138d6a74d05e68af76 +title: Paso 54 +challengeType: 0 +dashedName: step-54 +--- + +# --description-- + +Añade un atributo `id` con el valor `loving` al elemento input de tipo checkbox. + +# --hints-- + +Tu checkbox debe tener un atributo `id`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +assert($('input[type="checkbox"]')[0].hasAttribute('id')); +``` + +Tu checkbox debe tener un atributo `id` con el valor `loving`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +assert($('input[type="checkbox"]')[0].id.match(/^loving$/)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +
    + Is your cat an indoor or outdoor cat? + + +
    +
    + What's your cat's personality? +--fcc-editable-region-- + Loving +--fcc-editable-region-- +
    + + +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc575c8d6a74d05e68af77.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc575c8d6a74d05e68af77.md new file mode 100644 index 00000000000000..8517b85502c4d0 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc575c8d6a74d05e68af77.md @@ -0,0 +1,124 @@ +--- +id: 5efc575c8d6a74d05e68af77 +title: Paso 58 +challengeType: 0 +dashedName: step-58 +--- + +# --description-- + +Añade un último checkbox, después del anterior, con un atributo `id` con el valor `energetic`. El atributo `name` debe ser igual que el del checkbox anterior. + +También añade un elemento `label` a la derecha del nuevo elemento checkbox con el texto `Energetic`. Asegúrese de asociar el elemento `label` con el nuevo checkbox. + +# --hints-- + +Necesitas añadir un nuevo checkbox. + +```js +assert($('input[type="checkbox"]').length === 3); +``` + +Tu nuevo checkbox debe tener un atributo `id` con el valor `energetic` y un atributo `name` con el valor `personality`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +const checkboxes = [...$('input[type="checkbox"]')]; +assert( + checkboxes.some( + (checkbox) => + checkbox.id === 'energetic' && + checkbox.getAttribute('name') === 'personality' + ) +); +``` + +Tu nuevo checkbox debe estar después del segundo. Los tienes en el orden incorrecto. + +```js +const checkboxes = [...$('input[type="checkbox"]')].map( + (checkbox) => checkbox.id +); +assert(checkboxes.indexOf('lazy') < checkboxes.indexOf('energetic')); +``` + +A la derecha de tu nuevo checkbox, debe haber un elemento `label` con el texto `Energetic`. + +```js +const nextElementSibling = $('input[type="checkbox"]')[2].nextElementSibling; +assert( + nextElementSibling.nodeName === 'LABEL' && + nextElementSibling.innerText.replace(/\s+/g, '').match(/^Energetic$/i) +); +``` + +El nuevo elemento `label` debe tener un atributo `for` con el mismo valor del atributo `id` del nuevo checkbox. Probablemente no has añadido el valor o tienes un error tipográfico. + +```js +assert( + $('input[type="checkbox"]')[2].nextElementSibling.getAttribute('for') === + 'energetic' +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +
    + Is your cat an indoor or outdoor cat? + + +
    +
    + What's your cat's personality? +--fcc-editable-region-- + + +--fcc-editable-region-- +
    + + +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f05a1d8e233dff4a68508d8.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f05a1d8e233dff4a68508d8.md new file mode 100644 index 00000000000000..c70e3d1285a4a1 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f05a1d8e233dff4a68508d8.md @@ -0,0 +1,109 @@ +--- +id: 5f05a1d8e233dff4a68508d8 +title: Paso 46 +challengeType: 0 +dashedName: step-46 +--- + +# --description-- + +Anida otro radio button, con la opción `Outdoor` dentro de un nuevo elemento `label`. El nuevo radio button debe colocarse después del primero. Después, a su atributo `id` dale el valor: + +`outdoor` + +# --hints-- + +Necesitarás añadir un nuevo elemento `label` en el cual anidaras tu nuevo radio button. No olvides su etiqueta de apertura y cierre. + +```js +assert( + document.querySelectorAll('label').length === 2 && + code.match(/<\/label\>/g).length === 2 +); +``` + +El texto `Outdoor` debe estar inmediatamente a la derecha del `radio` button. Asegúrate de que hay un espacio entre el elemento y el texto. Probablemente no has añadido el texto o tienes un error tipográfico. + +```js +const radioButtons = [...$('input')]; +assert( + radioButtons.filter((btn) => + btn.nextSibling.nodeValue.replace(/\s+/g, ' ').match(/ Outdoor/i) + ).length +); +``` + +Tu nuevo radio button y su respectivo elemento label deben estar debajo del primero. Los tienes en el orden incorrecto. + +```js +const collection = [ + ...document.querySelectorAll('input[type="radio"]') +].map((node) => node.nextSibling.nodeValue.replace(/\s+/g, '')); +assert(collection.indexOf('Indoor') < collection.indexOf('Outdoor')); +``` + +Tu nuevo radio button debe tener un atributo `id`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +assert($('input')[1].hasAttribute('id')); +``` + +Tu nuevo radio button debe tener un atributo `id` con el valor `outdoor`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +assert($('input')[1].id.match(/^outdoor$/)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +--fcc-editable-region-- + +--fcc-editable-region-- + + +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f07be6ef7412fbad0c5626b.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f07be6ef7412fbad0c5626b.md new file mode 100644 index 00000000000000..38f9edc0702152 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f07be6ef7412fbad0c5626b.md @@ -0,0 +1,63 @@ +--- +id: 5f07be6ef7412fbad0c5626b +title: Paso 15 +challengeType: 0 +dashedName: step-15 +--- + +# --description-- + +Antes de añadir nuevo contenido, deberías utilizar un elemento `section`, para separar el contenido de cat photos, del contenido que añadiremos después. + +Toma todos los elementos actualmente ubicados dentro del elemento `main` y anidarlos dentro de un elemento `section`. + +# --hints-- + +Tu elemento `section` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('section')); +``` + +Tu elemento `section` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/section\>/)); +``` + +El elemento `section` debe estar entre las etiquetas de apertura y cierre del elemento `main`. + +```js +assert(document.querySelector('section').parentNode.nodeName === 'MAIN'); +``` + +Los elementos `h2`, comentario, `p` y anchor (`a`) deben estar entre las etiquetas de apertura y cierre del elemento `section`. + +```js +const childrenOfSection = [...document.querySelector('section').childNodes]; +const foundElems = childrenOfSection.filter((child) => { + return ['H2', 'A', 'P'].includes(child.nodeName); +}); +assert(foundElems.length === 3); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +--fcc-editable-region-- +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +--fcc-editable-region-- + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f07c98cdb9413cbd4b16750.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f07c98cdb9413cbd4b16750.md new file mode 100644 index 00000000000000..121e2bf37b6f45 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f07c98cdb9413cbd4b16750.md @@ -0,0 +1,81 @@ +--- +id: 5f07c98cdb9413cbd4b16750 +title: Paso 16 +challengeType: 0 +dashedName: step-16 +--- + +# --description-- + +Es hora de añadir una nueva sección con un elemento section. Añade un segundo elemento `section` debajo del elemento `section` existente. + +# --hints-- + +Tu elemento `section` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelectorAll('section').length >= 2); +``` + +Solo debes añadir una etiqueta de apertura al elemento `section`. Elimina cualquier extra. + +```js +assert(document.querySelectorAll('section').length === 2); +``` + +Tu elemento `section` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/section>/g).length >= 2); +``` + +Solo debes añadir una etiqueta de cierre al elemento `section`. Elimina cualquier extra. + +```js +assert(code.match(/<\/section>/g).length === 2); +``` + +El segundo elemento `section` no debe estar anidado dentro del primer elemento `section`. + +```js +const childrenOf1stSection = [ + ...document.querySelector('main > section').children +]; +const foundElems = childrenOf1stSection.filter((child) => { + return child.nodeName === 'SECTION'; +}); +assert(foundElems.length === 0); +``` + +Ambos elementos `section` deben estar entre las etiquetas de apertura y cierre del elemento `main`. + +```js +const childrenOfMain = [...document.querySelector('main').children]; +const foundElems = childrenOfMain.filter((child) => { + return child.nodeName === 'SECTION'; +}); +assert(foundElems.length === 2); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +--fcc-editable-region-- +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +--fcc-editable-region-- +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f07fb1579dc934717801375.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f07fb1579dc934717801375.md new file mode 100644 index 00000000000000..5f0b15caa591fd --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f07fb1579dc934717801375.md @@ -0,0 +1,98 @@ +--- +id: 5f07fb1579dc934717801375 +title: Paso 32 +challengeType: 0 +dashedName: step-32 +--- + +# --description-- + +Es hora de añadir una nueva sección con un elemento section. Añade un segundo elemento `section` debajo del segundo elemento `section` existente. + +# --hints-- + +Tu elemento `section` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelectorAll('section').length >= 3); +``` + +Solo debes añadir una etiqueta de apertura al elemento `section`. Elimina cualquier extra. + +```js +assert(document.querySelectorAll('section').length === 3); +``` + +Tu elemento `section` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/section>/g).length >= 3); +``` + +Solo debes añadir una etiqueta de cierre al elemento `section`. Elimina cualquier extra. + +```js +assert(code.match(/<\/section>/g).length === 3); +``` + +Todos los elementos `section` deben estar entre las etiquetas de apertura y cierre del elemento `main`. + +```js +const childrenOfMain = [...document.querySelector('main').children]; +const sectionElemsFound = childrenOfMain.filter((child) => { + return child.nodeName === 'SECTION'; +}); +assert(sectionElemsFound.length === 3); +``` + +El último elemento `section` no debe tener contenido. Elimina cualquier elemento HTML o texto que tengas entre las etiquetas del elemento `section`. + +```js +assert($('main > section')[2].children.length === 0); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +--fcc-editable-region-- +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +--fcc-editable-region-- +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f0d48e7b435f13ab6550051.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f0d48e7b435f13ab6550051.md new file mode 100644 index 00000000000000..2c18cc296de0b1 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f0d48e7b435f13ab6550051.md @@ -0,0 +1,105 @@ +--- +id: 5f0d48e7b435f13ab6550051 +title: Paso 50 +challengeType: 0 +dashedName: step-50 +--- + +# --description-- + +El elemento `legend` actúa como una leyenda/descripción, para el contenido del elemento `fieldset`. Le da a los usuarios un contexto sobre lo que deben ingresar en esa parte del formulario. + +Añade un elemento `legend` con el texto `Is your cat an indoor or outdoor cat?` sobre ambos botones de radio (radio button). + +# --hints-- + +Tu elemento `legend` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelector('legend')); +``` + +Tu elemento `legend` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/legend\>/)); +``` + +Tu elemento `legend` debe estar inmediatamente debajo de la etiqueta de apertura del elemento `fieldset` y arriba de la etiqueta de apertura del elemento `label` del primer botón de radio (radio button). No está en la posición correcta. + +```js +const fieldsetElem = document.querySelector('fieldset'); +const fieldsetElemChildren = fieldsetElem.children; +assert( + fieldsetElem.firstElementChild.nodeName === 'LEGEND' && + fieldsetElemChildren[1].nodeName === 'LABEL' && + fieldsetElemChildren[1].children[0].nodeName === 'INPUT' && + fieldsetElemChildren[1].children[0].id === 'indoor' +); +``` + +El texto de tu elemento `legend` debe ser `Is your cat an indoor or outdoor cat?`. Probablemente olvidaste añadir el texto, tienes un error tipográfico o no está entre las etiquetas de apertura y cierre del elemento `legend`. + +```js +const extraSpacesRemoved = document + .querySelector('legend') + .innerText.replace(/\s+/g, ' '); +assert(extraSpacesRemoved.match(/Is your cat an indoor or outdoor cat\??$/i)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +--fcc-editable-region-- +
    + + +
    +--fcc-editable-region-- + + +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f0d4ab1b435f13ab6550052.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f0d4ab1b435f13ab6550052.md new file mode 100644 index 00000000000000..ba5e8b806281dd --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f0d4ab1b435f13ab6550052.md @@ -0,0 +1,128 @@ +--- +id: 5f0d4ab1b435f13ab6550052 +title: Paso 51 +challengeType: 0 +dashedName: step-51 +--- + +# --description-- + +A continuación, añadirás nuevos elementos `input` al formulario, añade otro elemento `fieldset`, directamente debajo del elemento `fieldset` existente. + +# --hints-- + +Tu nuevo elemento `fieldset` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +assert(document.querySelectorAll('fieldset').length >= 2); +``` + +Solo debes añadir una etiqueta de apertura al elemento `fieldset`. Elimina cualquier extra. + +```js +assert(document.querySelectorAll('fieldset').length === 2); +``` + +Tu elemento `fieldset` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/fieldset>/g).length >= 2); +``` + +Solo debes añadir una etiqueta de cierre al elemento `fieldset`. Elimina cualquier extra. + +```js +assert(code.match(/<\/fieldset>/g).length === 2); +``` + +El segundo elemento `fieldset` no debe estar anidado dentro del primer elemento `fieldset`. + +```js +const childrenOf1stFieldset = [ + ...document.querySelector('form > fieldset').children +]; +const foundElems = childrenOf1stFieldset.filter((child) => { + return child.nodeName === 'FIELDSET'; +}); +assert(foundElems.length === 0); +``` + +Ambos elementos `fieldset` deben estar encima del campo de texto y su respectivo elemento `label`. No están en orden. + +```js +const formChildren = $('form')[0].children; +assert( + formChildren[0].nodeName === 'FIELDSET' && + formChildren[1].nodeName === 'FIELDSET' && + formChildren[2] && + formChildren[2].nodeName === 'INPUT' && + formChildren[2].getAttribute('type') === 'text' +); +``` + +Tu nuevo elemento `fieldset` debe estar debajo del elemento `fieldset` existente. Los tienes en el orden incorrecto. + +```js +const fieldsetChildren = [...document.querySelectorAll('fieldset')].map( + (elem) => elem.children +); +assert(fieldsetChildren[0].length > fieldsetChildren[1].length); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +--fcc-editable-region-- +
    + Is your cat an indoor or outdoor cat? + + +
    + + +--fcc-editable-region-- +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f0d4d04b435f13ab6550053.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f0d4d04b435f13ab6550053.md new file mode 100644 index 00000000000000..48867ee1f84317 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f0d4d04b435f13ab6550053.md @@ -0,0 +1,114 @@ +--- +id: 5f0d4d04b435f13ab6550053 +title: Paso 52 +challengeType: 0 +dashedName: step-52 +--- + +# --description-- + +Añade un elemento `legend` con el texto `What's your cat's personality?` dentro del segundo elemento `fieldset`. + +# --hints-- + +Has eliminado el elemento `fieldset` o le falta una etiqueta de apertura o de cierre. + +```js +assert( + document.querySelectorAll('fieldset').length === 2 && + code.match(/<\/fieldset>/g).length === 2 +); +``` + +Tu elemento `legend` debe tener una etiqueta de apertura. Las etiquetas de apertura tienen esta sintaxis: ``. + +```js +const secondFieldset = $('fieldset')[1]; +assert( + secondFieldset && + [...secondFieldset.children].filter((child) => child.nodeName === 'LEGEND') + .length +); +``` + +Tu elemento `legend` debe tener una etiqueta de cierre. Las etiquetas de cierre tiene una `/` después del carácter `<`. + +```js +assert(code.match(/<\/legend\>/g).length === 2); +``` + +El elemento `legend` debe tener el texto `What's your cat's personality?`. Probablemente no has añadido el texto o tienes un error tipográfico. + +```js +const secondFieldset = $('fieldset')[1]; +assert( + secondFieldset && + [...secondFieldset.children].filter((child) => { + const extraSpacesRemoved = child.innerText.replace(/\s+/g, ' '); + return ( + child.nodeName === 'LEGEND' && + extraSpacesRemoved.match(/What's your cat's personality\??$/i) + ); + }).length +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +
    + Is your cat an indoor or outdoor cat? + + +
    +--fcc-editable-region-- +
    +
    +--fcc-editable-region-- + + +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f1a80975fc4bcae0edb3497.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f1a80975fc4bcae0edb3497.md new file mode 100644 index 00000000000000..b564bf7bfe9792 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f1a80975fc4bcae0edb3497.md @@ -0,0 +1,101 @@ +--- +id: 5f1a80975fc4bcae0edb3497 +title: Paso 48 +challengeType: 0 +dashedName: step-48 +--- + +# --description-- + +Si seleccionas el radio button `Indoor` y envías el formulario, los datos del radio button se basarán en sus atributos `name` y `value`. Ya que tus elementos radio button no tienen el atributo `value`, los datos del formulario se verán así `indoor-outdoor=on`, lo cual no es útil cuando tienes múltiples radio button. + +Añade un atributo `value` a ambos radio button. Por conveniencia, a los atributos `value` dales el mismo valor del atributo `id` de cada radio button. + +# --hints-- + +Ambos radio button aún deben estar ubicados entre las etiquetas de apertura y cierre del elemento `label`. + +```js +const labelChildNodes = [...document.querySelectorAll('form > label')].map( + (node) => node.childNodes +); +assert( + labelChildNodes.filter((childNode) => childNode[0].nodeName === 'INPUT') + .length === 2 +); +``` + +Ambos radio button deben tener un atributo `value`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +const radioButtons = [...document.querySelectorAll('input[type="radio"]')]; +assert(radioButtons.every((btn) => btn.hasAttribute('value'))); +``` + +El radio button `Indoor` debe tener un atributo `value` con el valor `indoor`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +const indoorRadioButton = document.querySelector('#indoor'); +assert(indoorRadioButton.getAttribute('value').match(/^indoor$/)); +``` + +El radio button `Outdoor` debe tener un atributo `value` con el valor `outdoor`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +const outdoorRadioButton = document.querySelector('#outdoor'); +assert(outdoorRadioButton.getAttribute('value').match(/^outdoor$/)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +--fcc-editable-region-- + + +--fcc-editable-region-- + + +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f1a89f1190aff21ae42105a.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f1a89f1190aff21ae42105a.md new file mode 100644 index 00000000000000..a56432c43e6a46 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5f1a89f1190aff21ae42105a.md @@ -0,0 +1,106 @@ +--- +id: 5f1a89f1190aff21ae42105a +title: Paso 59 +challengeType: 0 +dashedName: step-59 +--- + +# --description-- + +Al igual que los radio button, los datos de formulario de un checkbox se basan en los atributos `name` / `value`. Mientras que el atributo `value` es opcional, es una buena práctica incluirlo en cualquier checkbox o radio button de una página. + +Añade un atributo `value` a los dos checkbox. Por conveniencia, a los atributos `value` dales el mismo valor del atributo `id` de cada checkbox. + +# --hints-- + +Los tres checkbox deben tener un atributo `value`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +const checkboxes = [...document.querySelectorAll('input[type="checkbox"]')]; +assert(checkboxes.every((checkbox) => checkbox.hasAttribute('value'))); +``` + +El atributo `value` del checkbox `Loving` debería tener el valor `loving`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +const lovingCheckbox = document.querySelector('#loving'); +assert(lovingCheckbox.getAttribute('value').match(/^loving$/)); +``` + +El atributo `value` del checkbox `Lazy` debería tener el valor `lazy`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +const lazyCheckbox = document.querySelector('#lazy'); +assert(lazyCheckbox.getAttribute('value').match(/^lazy$/)); +``` + +El atributo `value` del checkbox `Energetic` debería tener el valor `energetic`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +const energeticCheckbox = document.querySelector('#energetic'); +assert(energeticCheckbox.getAttribute('value').match(/^energetic$/)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +--fcc-editable-region-- +
    + Is your cat an indoor or outdoor cat? + + +
    +
    + What's your cat's personality? + + + +
    +--fcc-editable-region-- + + +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/7cf9b03d81a65668421804c3.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/7cf9b03d81a65668421804c3.md new file mode 100644 index 00000000000000..1bfdd10fb5091d --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/7cf9b03d81a65668421804c3.md @@ -0,0 +1,103 @@ +--- +id: 7cf9b03d81a65668421804c3 +title: Paso 38 +challengeType: 0 +dashedName: step-38 +--- + +# --description-- + +Para que los datos de un formulario puedan acceder al destino especificado en el atributo `action`, debes darle al campo de texto un atributo `name` y darle un valor que represente a los datos que están siendo enviados. Por ejemplo, puede utilizar la siguiente sintaxis para un campo de texto de dirección de correo electrónico: ``. + +Añade el atributo `name` con el valor `catphotourl` a tu campo de texto. + +# --hints-- + +Has eliminado tu elemento `input` o tiene una sintaxis inválida. Todos los valores de los atributos deben estar entre comillas. + +```js +assert($('input').length); +``` + +Tu elemento `form` solo debe contener el elemento `input`. Elimina cualquier elemento HTML o texto que tengas entre las etiquetas del elemento `form`. + +```js +assert( + $('form')[0].children.length === 1 && + $('form')[0].innerText.trim().length === 0 +); +``` + +Tu elemento `input` no tiene un atributo `name`. Comprueba que hay un espacio después del nombre de la etiqueta de apertura y/o que hay espacios antes de todos los nombres de los atributos. + +```js +assert($('input')[0].hasAttribute('name')); +``` + +Tu elemento `input` debe tener un atributo `name` con el valor `catphotourl`. Probablemente no has añadido el valor o tienes un error tipográfico. Recuerda que los valores de los atributos deben estar entre comillas. + +```js +assert( + $('input')[0] + .getAttribute('name') + .match(/^catphotourl$/i) +); +``` + +Aunque al atributo `name` del elemento `input` le hayas dado el valor `catphotourl`, se recomienda siempre poner el valor de un atributo entre comillas. + +```js +assert(!/\<\s*input\s+.*\s*=\s*catphotourl/.test(code)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +

    CatPhotoApp

    +
    +
    +

    Cat Photos

    + +

    Click here to view more cat photos.

    + A cute orange cat lying on its back. +
    +
    +

    Cat Lists

    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +
    + A slice of lasagna on a plate. +
    Cats love lasagna.
    +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + Five cats looking around a field. +
    Cats hate other cats.
    +
    +
    +
    +

    Cat Form

    +
    +--fcc-editable-region-- + +--fcc-editable-region-- +
    +
    +
    + + +``` + diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f027099a15b00485563dd2.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f027099a15b00485563dd2.md new file mode 100644 index 00000000000000..cd1b02e4643966 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f027099a15b00485563dd2.md @@ -0,0 +1,54 @@ +--- +id: 60f027099a15b00485563dd2 +title: Paso 2 +challengeType: 0 +dashedName: step-2 +--- + +# --description-- + +Añade una etiqueta de apertura y cierre `html` abajo de `DOCTYPE`para que tengas espacio para comenzar a poner código. + +# --hints-- + +Tu declaración `DOCTYPE` debe estar al principio de tu HTML. + +```js +assert(__helpers.removeHtmlComments(code).match(/^\s*/i)); +``` + +Tu `html` debe tener una etiqueta de apertura. + +```js +assert(code.match(//gi)); +``` + +Tu etiqueta `html` debe tener una etiqueta de cierre. + +```js +assert(code.match(/<\/html\s*>/)); +``` + +Tu etiqueta `html` debe estar en el orden correcto. + +```js +assert(code.match(/\s*<\/html\s*>/)); +``` + +Solamente debes de tener una etiqueta `html`. + +```js +// Possibly a redundant test, as browser fixes this +assert(document.querySelectorAll('html').length === 1); +``` + +# --seed-- + +## --seed-contents-- + +```html +--fcc-editable-region-- + + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f02e7361b68405e27b62a5.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f02e7361b68405e27b62a5.md new file mode 100644 index 00000000000000..37f33230d26efb --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f02e7361b68405e27b62a5.md @@ -0,0 +1,43 @@ +--- +id: 60f02e7361b68405e27b62a5 +title: Paso 5 +challengeType: 0 +dashedName: step-5 +--- + +# --description-- + +Dentro del `body`, proporciona un título, añadiendo un `h1` con el texto `Registration Form`. + +# --hints-- + +Debes añadir el `h1` dentro del `body`. + +```js +assert.exists(document.querySelector('body > h1')); +``` + +Debes añadir al `h1` el texto de `Registration Form`. + +```js +assert.equal(document.querySelector('body > h1')?.textContent, 'Registration Form'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + Registration Form + + +--fcc-editable-region-- + + + +--fcc-editable-region-- + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f1a5e2d2c23707a4f9a660.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f1a5e2d2c23707a4f9a660.md new file mode 100644 index 00000000000000..5141dbac05381f --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f1a5e2d2c23707a4f9a660.md @@ -0,0 +1,51 @@ +--- +id: 60f1a5e2d2c23707a4f9a660 +title: Paso 8 +challengeType: 0 +dashedName: step-8 +--- + +# --description-- + +Ahora, deshacerte de la barra de desplazamiento horizontal, al establecer el `body` `margin` por defecto añadido por algunos navegadores a `0`. + +# --hints-- + +Deberías añadir `margin` dentro del `body` selector de elementos. + +```js +assert.isNotEmpty(new __helpers.CSSHelp(document).getStyle('body')?.margin); +``` + +Debes dar a `margin` un valor de `0`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('body')?.margin, '0px'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + Registration Form + + + +

    Registration Form

    +

    Please fill out this form with the required information

    + + +``` + +```css +--fcc-editable-region-- +body { + width: 100%; + height: 100vh; +} +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f1a9cbd23023082e149fee.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f1a9cbd23023082e149fee.md new file mode 100644 index 00000000000000..938fb1eb3ebb78 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f1a9cbd23023082e149fee.md @@ -0,0 +1,64 @@ +--- +id: 60f1a9cbd23023082e149fee +title: Paso 9 +challengeType: 0 +dashedName: step-9 +--- + +# --description-- + +Eso es mejor. Ahora haz el fondo fácil para los ojos, cambia el `body` `background-color` a `#1b1b32`. Ahora, para ver el texto cambia el `color`a `#f5f6f7`. + +# --hints-- + +Deberás añadir `background-color`dentro del `body` selector de elementos. + +```js +assert.isNotEmpty(new __helpers.CSSHelp(document).getStyle('body')?.backgroundColor); +``` + +Deberás dar al `background-color` un valor de `#1b1b32`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('body')?.backgroundColor, 'rgb(27, 27, 50)'); +``` + +Deberás añadir el `color` dentro del `body` selector de elementos. + +```js +assert.isNotEmpty(new __helpers.CSSHelp(document).getStyle('body')?.color); +``` + +Deberás dar al `color` un valor de `#f5f6f7`. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('body')?.color, 'rgb(245, 246, 247)'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + Registration Form + + + +

    Registration Form

    +

    Please fill out this form with the required information

    + + +``` + +```css +--fcc-editable-region-- +body { + width: 100%; + height: 100vh; + margin: 0; +} +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f5c3e399ff1a05629964e4.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f5c3e399ff1a05629964e4.md new file mode 100644 index 00000000000000..48b238e5e5776e --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f5c3e399ff1a05629964e4.md @@ -0,0 +1,62 @@ +--- +id: 60f5c3e399ff1a05629964e4 +title: Paso 10 +challengeType: 0 +dashedName: step-10 +--- + +# --description-- + +Como sugiere el título, está creando un formulario. Así que después del elemento `p` inserta un `form` con un atributo de `action` "tageting" `https://register-demo.freecodecamp.org`. + +# --hints-- + +Tebes añadir un `form` después de el elemento `p`. + +```js +assert.exists(document.querySelector('p + form')); +``` + +Debes añadir el `form`un attributo de `action`. + +```js +// Default action points to window location +assert.notEqual(document.querySelector('form')?.action, window?.location?.href); +``` + +Debes dar a la `action` un valor de `https://register-demo.freecodecamp.org`. + +```js +assert.equal(document.querySelector('form')?.action, 'https://register-demo.freecodecamp.org/'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + Registration Form + + +--fcc-editable-region-- + +

    Registration Form

    +

    Please fill out this form with the required information

    + + +--fcc-editable-region-- + +``` + +```css +body { + width: 100%; + height: 100vh; + margin: 0; + background-color: #1b1b32; + color: #f5f6f7; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f5cb8875ab6a0610f05071.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f5cb8875ab6a0610f05071.md new file mode 100644 index 00000000000000..d3ef77b5a50066 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f5cb8875ab6a0610f05071.md @@ -0,0 +1,63 @@ +--- +id: 60f5cb8875ab6a0610f05071 +title: Paso 11 +challengeType: 0 +dashedName: step-11 +--- + +# --description-- + +Como pensamos tener tres secciones distintas en el formulario, añade tres elementos `fieldset` dentro del `form`. + +# --hints-- + +Deberás añadir tres `fieldset`. + +```js +assert.equal(document.querySelectorAll('fieldset')?.length, 3); +``` + +Los tres elementos `fieldset` deben estar dentro del `form`. + +```js +assert.equal(document.querySelectorAll('form > fieldset')?.length, 3); +``` + +Los tres elementos `fieldset` deben ser hermanos. + +```js +assert.exists(document.querySelector('fieldset + fieldset + fieldset')); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + Registration Form + + +--fcc-editable-region-- + +

    Registration Form

    +

    Please fill out this form with the required information

    +
    + +
    + +--fcc-editable-region-- + +``` + +```css +body { + width: 100%; + height: 100vh; + margin: 0; + background-color: #1b1b32; + color: #f5f6f7; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f5d2776c854e069560fbe6.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f5d2776c854e069560fbe6.md new file mode 100644 index 00000000000000..35643999ac7590 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f5d2776c854e069560fbe6.md @@ -0,0 +1,61 @@ +--- +id: 60f5d2776c854e069560fbe6 +title: Paso 12 +challengeType: 0 +dashedName: step-12 +--- + +# --description-- + +Al primer `fieldset`deberá tener los campos de nombre, email y contraseña. Comienza añadiendo cuetro elementos `label`al primer `fieldset`. + +# --hints-- + +Debes añadir cuatro elementos `label`. + +```js +assert.equal(document.querySelectorAll('label')?.length, 4); +``` + +Debes aladir los elementos `label` al primer `fieldset`. + +```js +assert.equal(document.querySelector('fieldset')?.querySelectorAll('label')?.length, 4); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + Registration Form + + + +

    Registration Form

    +

    Please fill out this form with the required information

    +--fcc-editable-region-- +
    +
    + +
    +
    +
    +
    +--fcc-editable-region-- + + +``` + +```css +body { + width: 100%; + height: 100vh; + margin: 0; + background-color: #1b1b32; + color: #f5f6f7; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f5dc35c07ac1078f140916.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f5dc35c07ac1078f140916.md new file mode 100644 index 00000000000000..58b361aa2e0fb2 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60f5dc35c07ac1078f140916.md @@ -0,0 +1,81 @@ +--- +id: 60f5dc35c07ac1078f140916 +title: Paso 13 +challengeType: 0 +dashedName: step-13 +--- + +# --description-- + +Agrega el siguiente texto a los elementos `label`: + +- `Enter Your First Name:` +- `Enter Your Last Name:` +- `Enter Your Email:` +- `Create a New Password:` + +# --hints-- + +El primer `label` debe tener el texto `Enter Your First Name:`. + +```js +assert.match(document.querySelector('label')?.innerHTML, /Enter Your First Name:/i); +``` + +El segundo `label` debe tener el texto `Enter Your Last Name:`. + +```js +assert.match(document.querySelector('fieldset > label:nth-child(2)')?.innerHTML, /Enter Your Last Name:/i); +``` + +El tercer `label` debe tener el texto `Enter Your Email:`. + +```js +assert.match(document.querySelector('fieldset > label:nth-child(3)')?.innerHTML, /Enter Your Email:/i); +``` + +El cuatro `label` debe tener el texto `Create a New Password:`. + +```js +assert.match(document.querySelector('fieldset > label:nth-child(4)')?.innerHTML, /Create a New Password:/i); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + Registration Form + + + +

    Registration Form

    +

    Please fill out this form with the required information

    +
    +--fcc-editable-region-- +
    + + + + +
    +--fcc-editable-region-- +
    +
    +
    + + +``` + +```css +body { + width: 100%; + height: 100vh; + margin: 0; + background-color: #1b1b32; + color: #f5f6f7; +} +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet/61fd5a93fd62bb35968adeab.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet/61fd5a93fd62bb35968adeab.md new file mode 100644 index 00000000000000..ac16de44b6e122 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet/61fd5a93fd62bb35968adeab.md @@ -0,0 +1,117 @@ +--- +id: 61fd5a93fd62bb35968adeab +title: Paso 1 +challengeType: 0 +dashedName: step-1 +--- + +# --description-- + +Configura tu HTML con los elementos `DOCTYPE`, `html`, `head` y `body`. Dale a tu elemento `head` los elementos `meta` apropiados para el `charset` y el `viewport`, un elemento `title` con un titulo apropiado y un elemento `link` para tu hoja de estilos. + +# --hints-- + +Tu código debe tener una declaración ``. + +```js +assert(code.match(//i)); +``` + +Tu código debe tener un elemento `html`. + +```js +assert.equal(document.querySelectorAll('html')?.length, 1); +``` + +Tu código debe tener un elemento `head` dentro del elemento `html`. + +```js +assert.equal(document.querySelectorAll('head')?.length, 1); +``` + +Tu código debe tener un elemento `body` dentro del elemento `html`. + +```js +assert.equal(document.querySelectorAll('body')?.length, 1); +``` + +Tu elemento `head` debe ir antes de tu elemento `body`. + +```js +assert.equal(document.querySelector('body')?.previousElementSibling?.tagName, 'HEAD'); +``` + +Debes tener dos elementos `meta`. + +```js +const meta = document.querySelectorAll('meta'); +assert.equal(meta?.length, 2); +``` + +Un elemento `meta` debe tener un `name` establecido en `viewport` y un `content` establecido en `width=device-width, initial-scale=1.0`. + +```js +const meta = [...document.querySelectorAll('meta')]; +const target = meta?.find(m => m?.getAttribute('name') === 'viewport' && m?.getAttribute('content') === 'width=device-width, initial-scale=1.0' && !m?.getAttribute('charset')); +assert.exists(target); +``` + +El otro elemento `meta` debe tener un atributo `charset` establecido en `UTF-8`. + +```js +const meta = [...document.querySelectorAll('meta')]; +const target = meta?.find(m => !m?.getAttribute('name') && !m?.getAttribute('content') && m?.getAttribute('charset')?.toLowerCase() === 'utf-8'); +assert.exists(target); +``` + +Tu código debe tener un elemento `title`. + +```js +const title = document.querySelector('title'); +assert.exists(title); +``` + +Tu `title` debe tener un poco de texto. + +```js +const title = document.querySelector('title'); +assert.isAtLeast(title?.textContent?.length, 1); +``` + +Tu código debe tener un elemento `link`. + +```js +assert(/[\w\W\s]*[\w\W\s]*<\/head>/i)) +``` + +Tu elemento `link` debe tener un atributo `rel` con el valor `stylesheet`. + +```js +assert.match(code, / + + + + + Balance Sheet + + + +
    +
    +

    + + AcmeWidgetCorp + Balance Sheet + +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Assets
    201920202021
    Cash This is the cash we currently have on hand.$25$30$28
    Checking Our primary transactional account.$54$56$53
    Savings Funds set aside for emergencies.$500$650$728
    Total Assets$579$736$809
    +--fcc-editable-region-- + +
    +--fcc-editable-region-- + +
    +
    +
    +
    + + +``` + +```css + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet/61fd8e491324ce717da97ffe.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet/61fd8e491324ce717da97ffe.md new file mode 100644 index 00000000000000..60c9792a1b1955 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet/61fd8e491324ce717da97ffe.md @@ -0,0 +1,119 @@ +--- +id: 61fd8e491324ce717da97ffe +title: Paso 18 +challengeType: 0 +dashedName: step-18 +--- + +# --description-- + +Dentro de tu `thead`, agrega un `tr`. Dentro de eso, agrega un elemento `td` y tres elementos `th`. + +# --hints-- + +Tu elemento `thead` debe tener un elemento `tr`. + +```js +assert(document.querySelectorAll('table')?.[1]?.querySelector('thead')?.children?.[0]?.localName === 'tr'); +``` + +Tu elemento `tr` debe tener un elemento `td` como primer hijo. + +```js +assert(document.querySelectorAll('table')?.[1]?.querySelector('tr')?.children?.[0]?.localName === 'td'); +``` + +Tu elemento `tr` debe tener tres elementos `th`, después del elemento `td`. + +```js +assert(document.querySelectorAll('table')?.[1]?.querySelector('tr')?.children?.[1]?.localName === 'th'); +assert(document.querySelectorAll('table')?.[1]?.querySelector('tr')?.children?.[2]?.localName === 'th'); +assert(document.querySelectorAll('table')?.[1]?.querySelector('tr')?.children?.[3]?.localName === 'th'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Balance Sheet + + + +
    +
    +

    + + AcmeWidgetCorp + Balance Sheet + +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Assets
    201920202021
    Cash This is the cash we currently have on hand.$25$30$28
    Checking Our primary transactional account.$54$56$53
    Savings Funds set aside for emergencies.$500$650$728
    Total Assets$579$736$809
    +--fcc-editable-region-- + + + + + + +
    Liabilities
    +--fcc-editable-region-- + +
    +
    +
    +
    + + +``` + +```css + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet/61fd8fd08af43372f02952d0.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet/61fd8fd08af43372f02952d0.md new file mode 100644 index 00000000000000..bd7da3df5bd2fa --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet/61fd8fd08af43372f02952d0.md @@ -0,0 +1,149 @@ +--- +id: 61fd8fd08af43372f02952d0 +title: Paso 19 +challengeType: 0 +dashedName: step-19 +--- + +# --description-- + +Dale a cada elemento `th` un elemento `span` con la clase establecida en `sr-only` y el siguiente texto, en ese orden: `2019`, `2020` y `2021`. + +# --hints-- + +Cada uno de tus elementos `th` debe tener un elemento `span`. + +```js +const ths = [...document.querySelectorAll('table')?.[1]?.querySelectorAll('th')]; +ths?.forEach(th => { + assert(th?.children?.length === 1); + assert(th?.children?.[0]?.localName === 'span'); +}); +``` + +Cada uno de tus nuevos elementos `span` debe tener el atributo `class` establecido en `sr-only`. + +```js +const ths = [...document.querySelectorAll('table')?.[1]?.querySelectorAll('th')]; +ths?.forEach(th => { + assert(th?.children?.[0]?.classList?.contains('sr-only')); +}); +``` + +Tu primer elemento `span` debe tener el texto `2019`. + +```js +assert(document.querySelectorAll('table')?.[1]?.querySelectorAll('th')?.[0]?.children?.[0]?.textContent === '2019'); +``` + +Tu segundo elemento `span` debe tener el texto `2020`. + +```js +assert(document.querySelectorAll('table')?.[1]?.querySelectorAll('th')?.[1]?.children?.[0]?.textContent === '2020'); +``` + +Tu tercer elemento `span` debe tener el texto `2021`. + +```js +assert(document.querySelectorAll('table')?.[1]?.querySelectorAll('th')?.[2]?.children?.[0]?.textContent === '2021'); +``` + +Tu elemento `td` debe estar vacío. + +```js +assert(document.querySelectorAll('table')?.[1]?.querySelectorAll('td')?.[0]?.textContent === ''); +assert(document.querySelectorAll('table')?.[1]?.querySelectorAll('td')?.[0]?.children?.length === 0); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Balance Sheet + + + +
    +
    +

    + + AcmeWidgetCorp + Balance Sheet + +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Assets
    201920202021
    Cash This is the cash we currently have on hand.$25$30$28
    Checking Our primary transactional account.$54$56$53
    Savings Funds set aside for emergencies.$500$650$728
    Total Assets$579$736$809
    +--fcc-editable-region-- + + + + + + + + + + + + +
    Liabilities
    +--fcc-editable-region-- + +
    +
    +
    +
    + + +``` + +```css + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet/61fd9a4ff2fc4481b9157bd7.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet/61fd9a4ff2fc4481b9157bd7.md new file mode 100644 index 00000000000000..ca6146efacc703 --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet/61fd9a4ff2fc4481b9157bd7.md @@ -0,0 +1,165 @@ +--- +id: 61fd9a4ff2fc4481b9157bd7 +title: Paso 25 +challengeType: 0 +dashedName: step-25 +--- + +# --description-- + +Para tu tercera tabla, agrega un `caption` con el texto `Net Worth` y configura la cabecera y el cuerpo de la tabla. + +# --hints-- + +Tu tercer elemento `table` debe tener un elemento `caption`. + +```js +assert(document.querySelectorAll('table')?.[2]?.children?.[0]?.localName === 'caption'); +``` + +Tu elemento `caption` debe tener el texto `Net Worth`. + +```js +assert(document.querySelectorAll('table')?.[2]?.querySelector('caption')?.textContent === 'Net Worth'); +``` + +Tu tercer elemento `table` debe tener un elemento `thead`. + +```js +assert(document.querySelectorAll('table')?.[2]?.querySelector('thead')); +``` + +Tu tercer elemento `table` debe tener un elemento `tbody`. + +```js +assert(document.querySelectorAll('table')?.[2]?.querySelector('tbody')); +``` + +Tu elemento `thead` debe estar inmediatamente debajo de tu elemento `caption`. + +```js +assert(document.querySelectorAll('table')?.[2]?.querySelector('caption')?.nextElementSibling?.localName === 'thead'); +``` + +Tu elemento `tbody` debe estar inmediatamente debajo de tu elemento `thead`. + +```js +assert(document.querySelectorAll('table')?.[2]?.querySelector('thead')?.nextElementSibling?.localName === 'tbody'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Balance Sheet + + + +
    +
    +

    + + AcmeWidgetCorp + Balance Sheet + +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Assets
    201920202021
    Cash This is the cash we currently have on hand.$25$30$28
    Checking Our primary transactional account.$54$56$53
    Savings Funds set aside for emergencies.$500$650$728
    Total Assets$579$736$809
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Liabilities
    201920202021
    Loans The outstanding balance on our startup loan.$500$250$0
    Expenses Annual anticipated expenses, such as payroll.$200$300$400
    Credit The outstanding balance on our credit card.$50$50$75
    Total Liabilities$750$600$475
    +--fcc-editable-region-- + +
    +--fcc-editable-region-- +
    +
    +
    + + +``` + +```css + +``` diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet/61fd9b7285bde783ad5b8aac.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet/61fd9b7285bde783ad5b8aac.md new file mode 100644 index 00000000000000..4c8d53a8805c1e --- /dev/null +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-more-about-css-pseudo-selectors-by-building-a-balance-sheet/61fd9b7285bde783ad5b8aac.md @@ -0,0 +1,208 @@ +--- +id: 61fd9b7285bde783ad5b8aac +title: Paso 27 +challengeType: 0 +dashedName: step-27 +--- + +# --description-- + +Dentro del `tbody`, agrega un `tr` con el `class` establecido en `total`. Dentro de eso, agrega un `th` con el texto `Total Net Worth`, y envuelve `Net Worth` en un `span` con el `class` establecido en `sr-only`. + +Luego agrega tres elementos `td`, dando al tercero un `class` establecido en `current`, y dando a cada uno el siguiente texto: `$-171`, `$136`, `$334`. + +# --hints-- + +Tu elemento `tbody` debe tener un elemento `tr`. + +```js +assert(document.querySelectorAll('table')?.[2]?.querySelector('tbody')?.querySelectorAll('tr')?.length === 1); +``` + +Tu elemento `tr` debe tener el `class` establecido en `total`. + +```js +assert(document.querySelectorAll('table')?.[2]?.querySelector('tbody')?.querySelector('tr')?.classList?.contains('total')); +``` + +Tu `tr` debe tener un elemento `th`. + +```js +assert(document.querySelectorAll('table')?.[2]?.querySelector('tbody')?.querySelectorAll('tr')?.[0]?.querySelector('th')); +``` + +Tu elemento `th` debe tener el texto `Total Net Worth`. + +```js +assert(document.querySelectorAll('table')?.[2]?.querySelector('tbody')?.querySelectorAll('tr')?.[0]?.querySelector('th')?.innerText === 'Total Net Worth'); +``` + +Debes envolver el texto `Net Worth` en un elemento `span`. + +```js +assert(document.querySelectorAll('table')?.[2]?.querySelector('tbody')?.querySelectorAll('tr')?.[0]?.querySelector('th > span')?.textContent === 'Net Worth'); +``` + +Tu elemento `span` debe tener un atributo `class` establecido en `sr-only`. + +```js +assert(document.querySelectorAll('table')?.[2]?.querySelector('tbody')?.querySelectorAll('tr')?.[0]?.querySelector('th > span')?.classList?.contains('sr-only')); +``` + +Debes tener tres elementos `td`. + +```js +assert(document.querySelectorAll('table')?.[2]?.querySelector('tbody')?.querySelectorAll('tr')?.[0]?.querySelectorAll('td').length === 3); +``` + +Tu primer elemento `td` debe tener el texto `$-171`. + +```js +assert(document.querySelectorAll('table')?.[2]?.querySelector('tbody')?.querySelectorAll('tr')?.[0]?.querySelectorAll('td')?.[0]?.textContent === '$-171'); +``` + +Tu segundo elemento `td` debe tener el texto `$136`. + +```js +assert(document.querySelectorAll('table')?.[2]?.querySelector('tbody')?.querySelectorAll('tr')?.[0]?.querySelectorAll('td')?.[1]?.textContent === '$136'); +``` + +Tu tercer elemento `td` debe tener el texto `$334`. + +```js +assert(document.querySelectorAll('table')?.[2]?.querySelector('tbody')?.querySelectorAll('tr')?.[0]?.querySelectorAll('td')?.[2]?.textContent === '$334'); +``` + +Tu tercer elemento `td` debe tener el `class` establecido en `current`. + +```js +assert(document.querySelectorAll('table')?.[2]?.querySelector('tbody')?.querySelectorAll('tr')?.[0]?.querySelectorAll('td')?.[2]?.classList?.contains('current')); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Balance Sheet + + + +
    +
    +

    + + AcmeWidgetCorp + Balance Sheet + +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Assets
    201920202021
    Cash This is the cash we currently have on hand.$25$30$28
    Checking Our primary transactional account.$54$56$53
    Savings Funds set aside for emergencies.$500$650$728
    Total Assets$579$736$809
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Liabilities
    201920202021
    Loans The outstanding balance on our startup loan.$500$250$0
    Expenses Annual anticipated expenses, such as payroll.$200$300$400
    Credit The outstanding balance on our credit card.$50$50$75
    Total Liabilities$750$600$475
    +--fcc-editable-region-- + + + + + + + + + + + + +
    Net Worth
    201920202021
    +--fcc-editable-region-- +
    +
    +
    + + +``` + +```css + +``` diff --git a/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/build-a-caesars-cipher-project/caesars-cipher.md b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/build-a-caesars-cipher-project/caesars-cipher.md new file mode 100644 index 00000000000000..f89be515412eb1 --- /dev/null +++ b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/build-a-caesars-cipher-project/caesars-cipher.md @@ -0,0 +1,88 @@ +--- +id: 56533eb9ac21ba0edf2244e2 +title: Construye un cifrado César +challengeType: 5 +forumTopicId: 16003 +dashedName: build-a-caesars-cipher +--- + +# --description-- + +Uno de los cifrados más simples y conocidos es el cifrado César, también conocido como cifrado por desplazamiento. En un cifrado por desplazamiento los significados de las letras se desplazan por una cantidad determinada de letras. + +Un uso moderno común es el cifrado ROT13, donde los valores de las letras son desplazados por 13 lugares. Así `A ↔ N`, `B ↔ O` y así sucesivamente. + +Escriba una función que reciba una cadena codificada en ROT13 como entrada y devuelva una cadena decodificada. + +Todas las letras estarán en mayúsculas. No transforme ningún carácter no alfabético (espacios, puntuación, por ejemplo), pero si aplíquele el desplazamiento. + +# --hints-- + +`rot13("SERR PBQR PNZC")` debe decodificarse en la cadena `FREE CODE CAMP` + +```js +assert(rot13('SERR PBQR PNZC') === 'FREE CODE CAMP'); +``` + +`rot13("SERR CVMMN!")` debe decodificarse en la cadena `FREE PIZZA!` + +```js +assert(rot13('SERR CVMMN!') === 'FREE PIZZA!'); +``` + +`rot13("SERR YBIR?")` debe decodificarse en la cadena `FREE LOVE?` + +```js +assert(rot13('SERR YBIR?') === 'FREE LOVE?'); +``` + +`rot13("GUR DHVPX OEBJA SBK WHZCF BIRE GUR YNML QBT.")` debe decodificarse en la cadena `THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.` + +```js +assert( + rot13('GUR DHVPX OEBJA SBK WHZCF BIRE GUR YNML QBT.') === + 'THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.' +); +``` + +# --seed-- + +## --seed-contents-- + +```js +function rot13(str) { + return str; +} + +rot13("SERR PBQR PNZC"); +``` + +# --solutions-- + +```js +var lookup = { + 'A': 'N','B': 'O','C': 'P','D': 'Q', + 'E': 'R','F': 'S','G': 'T','H': 'U', + 'I': 'V','J': 'W','K': 'X','L': 'Y', + 'M': 'Z','N': 'A','O': 'B','P': 'C', + 'Q': 'D','R': 'E','S': 'F','T': 'G', + 'U': 'H','V': 'I','W': 'J','X': 'K', + 'Y': 'L','Z': 'M' +}; + +function rot13(encodedStr) { + var codeArr = encodedStr.split(""); // String to Array + var decodedArr = []; // Your Result goes here + // Only change code below this line + + decodedArr = codeArr.map(function(letter) { + if(lookup.hasOwnProperty(letter)) { + letter = lookup[letter]; + } + return letter; + }); + + // Only change code above this line + return decodedArr.join(""); // Array to String +} +``` diff --git a/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/build-a-cash-register-project/cash-register.md b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/build-a-cash-register-project/cash-register.md new file mode 100644 index 00000000000000..20d96f7a4b4c38 --- /dev/null +++ b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/build-a-cash-register-project/cash-register.md @@ -0,0 +1,252 @@ +--- +id: aa2e6f85cab2ab736c9a9b24 +title: Construye una caja registradora +challengeType: 5 +forumTopicId: 16012 +dashedName: build-a-cash-register +--- + +# --description-- + +Diseña una función `checkCashRegister()` que acepte el precio de compra como primer argumento (`price`), la cantidad pagada como segundo argumento (`cash`), y el dinero en efectivo que tiene la caja (`cid`) como tercer argumento. + +`cid` es un arreglo 2D que enumera las monedas disponibles. + +La función `checkCashRegister()` siempre debe devolver un objeto con una clave `status` y una clave `change`. + +Devuelve `{status: "INSUFFICIENT_FUNDS", change: []}` si el efectivo en caja es menor que el cambio necesario, o si no puedes devolver el cambio exacto. + +Devuelve `{status: "CLOSED", change: [...]}` si el efectivo en caja como valor de la clave `change` es igual al cambio que se debe entregar. + +En cualquier otro caso, devuelve `{status: "OPEN", change: [...]}`, con el cambio a entregar en monedas y billetes, ordenados de mayor a menor, como valor de la clave `change`. + +
    Unidad MonetariaImporte
    Centavo$0.01 (CENTAVO)
    Níquel$0.05 (NÍQUEL)
    Díez Centavos$0.1 (DÍEZ CENTAVOS)
    25 centavos$0.25 (QUARTER)
    Dólar$1 (UNO)
    Cinco dólares$5 (CINCO)
    Diez dólares$10 (DÍEZ)
    Veinte dólares$20 (VEINTE)
    Cien dólares$100 (CIEN)
    + +Vea a continuación un ejemplo de un arreglo de efectivo en caja: + +```js +[ + ["PENNY", 1.01], + ["NICKEL", 2.05], + ["DIME", 3.1], + ["QUARTER", 4.25], + ["ONE", 90], + ["FIVE", 55], + ["TEN", 20], + ["TWENTY", 60], + ["ONE HUNDRED", 100] +] +``` + +# --hints-- + +`checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]])` debe devolver un objeto. + +```js +assert.deepEqual( + Object.prototype.toString.call( + checkCashRegister(19.5, 20, [ + ['PENNY', 1.01], + ['NICKEL', 2.05], + ['DIME', 3.1], + ['QUARTER', 4.25], + ['ONE', 90], + ['FIVE', 55], + ['TEN', 20], + ['TWENTY', 60], + ['ONE HUNDRED', 100] + ]) + ), + '[object Object]' +); +``` + +`checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]])` debe devolver `{status: "OPEN", change: [["QUARTER", 0.5]]}`. + +```js +assert.deepEqual( + checkCashRegister(19.5, 20, [ + ['PENNY', 1.01], + ['NICKEL', 2.05], + ['DIME', 3.1], + ['QUARTER', 4.25], + ['ONE', 90], + ['FIVE', 55], + ['TEN', 20], + ['TWENTY', 60], + ['ONE HUNDRED', 100] + ]), + { status: 'OPEN', change: [['QUARTER', 0.5]] } +); +``` + +`checkCashRegister(3.26, 100, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]])` debe devolver `{status: "OPEN", change: [["TWENTY", 60], ["TEN", 20], ["FIVE", 15], ["ONE", 1], ["QUARTER", 0.5], ["DIME", 0.2], ["PENNY", 0.04]]}`. + +```js +assert.deepEqual( + checkCashRegister(3.26, 100, [ + ['PENNY', 1.01], + ['NICKEL', 2.05], + ['DIME', 3.1], + ['QUARTER', 4.25], + ['ONE', 90], + ['FIVE', 55], + ['TEN', 20], + ['TWENTY', 60], + ['ONE HUNDRED', 100] + ]), + { + status: 'OPEN', + change: [ + ['TWENTY', 60], + ['TEN', 20], + ['FIVE', 15], + ['ONE', 1], + ['QUARTER', 0.5], + ['DIME', 0.2], + ['PENNY', 0.04] + ] + } +); +``` + +`checkCashRegister(19.5, 20, [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]])` debe devolver `{status: "INSUFFICIENT_FUNDS", change: []}`. + +```js +assert.deepEqual( + checkCashRegister(19.5, 20, [ + ['PENNY', 0.01], + ['NICKEL', 0], + ['DIME', 0], + ['QUARTER', 0], + ['ONE', 0], + ['FIVE', 0], + ['TEN', 0], + ['TWENTY', 0], + ['ONE HUNDRED', 0] + ]), + { status: 'INSUFFICIENT_FUNDS', change: [] } +); +``` + +`checkCashRegister(19.5, 20, [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 1], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]])` debe devolver `{status: "INSUFFICIENT_FUNDS", change: []}`. + +```js +assert.deepEqual( + checkCashRegister(19.5, 20, [ + ['PENNY', 0.01], + ['NICKEL', 0], + ['DIME', 0], + ['QUARTER', 0], + ['ONE', 1], + ['FIVE', 0], + ['TEN', 0], + ['TWENTY', 0], + ['ONE HUNDRED', 0] + ]), + { status: 'INSUFFICIENT_FUNDS', change: [] } +); +``` + +`checkCashRegister(19.5, 20, [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]])` debe devolver `{status: "CLOSED", change: [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]}`. + +```js +assert.deepEqual( + checkCashRegister(19.5, 20, [ + ['PENNY', 0.5], + ['NICKEL', 0], + ['DIME', 0], + ['QUARTER', 0], + ['ONE', 0], + ['FIVE', 0], + ['TEN', 0], + ['TWENTY', 0], + ['ONE HUNDRED', 0] + ]), + { + status: 'CLOSED', + change: [ + ['PENNY', 0.5], + ['NICKEL', 0], + ['DIME', 0], + ['QUARTER', 0], + ['ONE', 0], + ['FIVE', 0], + ['TEN', 0], + ['TWENTY', 0], + ['ONE HUNDRED', 0] + ] + } +); +``` + +# --seed-- + +## --seed-contents-- + +```js +function checkCashRegister(price, cash, cid) { + let change; + return change; +} + +checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]); +``` + +# --solutions-- + +```js +const denom = [ + { name: "ONE HUNDRED", val: 100 }, + { name: "TWENTY", val: 20 }, + { name: "TEN", val: 10 }, + { name: "FIVE", val: 5 }, + { name: "ONE", val: 1 }, + { name: "QUARTER", val: 0.25 }, + { name: "DIME", val: 0.1 }, + { name: "NICKEL", val: 0.05 }, + { name: "PENNY", val: 0.01 }, +]; + +function checkCashRegister(price, cash, cid) { + const output = { status: null, change: [] }; + let change = cash - price; + const register = cid.reduce( + function (acc, curr) { + acc.total += curr[1]; + acc[curr[0]] = curr[1]; + return acc; + }, + { total: 0 } + ); + if (register.total === change) { + output.status = "CLOSED"; + output.change = cid; + return output; + } + if (register.total < change) { + output.status = "INSUFFICIENT_FUNDS"; + return output; + } + const change_arr = denom.reduce(function (acc, curr) { + let value = 0; + while (register[curr.name] > 0 && change >= curr.val) { + change -= curr.val; + register[curr.name] -= curr.val; + value += curr.val; + change = Math.round(change * 100) / 100; + } + if (value > 0) { + acc.push([curr.name, value]); + } + return acc; + }, []); + if (change_arr.length < 1 || change > 0) { + output.status = "INSUFFICIENT_FUNDS"; + return output; + } + output.status = "OPEN"; + output.change = change_arr; + return output; +} +``` diff --git a/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/build-a-palindrome-checker-project/palindrome-checker.md b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/build-a-palindrome-checker-project/palindrome-checker.md new file mode 100644 index 00000000000000..d28e91621ed41e --- /dev/null +++ b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/build-a-palindrome-checker-project/palindrome-checker.md @@ -0,0 +1,125 @@ +--- +id: aaa48de84e1ecc7c742e1124 +title: Construye un proyecto de comprobación de palíndromos +challengeType: 5 +forumTopicId: 16004 +dashedName: build-a-palindrome-checker +--- + +# --description-- + +Devuelve `true` si la cadena proporcionada es un palíndromo. De lo contrario, devuelve `false`. + +Un palíndromo es una palabra o frase que se escribe de la misma manera hacia adelante y hacia atrás, ignorando la puntuación, mayúsculas, minúsculas y espaciado. + +**Nota:** Tendrás que eliminar **todos los caracteres no alfanuméricos** (puntuación, espacios y símbolos) y convertir todo en mayúsculas o minúsculas para comprobar si hay palíndromos. + +Pasaremos cadenas con formatos variables, como `racecar`, `RaceCar` y `race CAR` entre otros. + +También pasaremos cadenas con símbolos especiales, como `2A3*3a2`, `2A3 3a2` y `2_A3*3#A2`. + +# --hints-- + +`palindrome("eye")` debe devolver un booleano. + +```js +assert(typeof palindrome('eye') === 'boolean'); +``` + +`palindrome("eye")` debe devolver `true`. + +```js +assert(palindrome('eye') === true); +``` + +`palindrome("_eye")` debe devolver `true`. + +```js +assert(palindrome('_eye') === true); +``` + +`palindrome("race car")` debe devolver `true`. + +```js +assert(palindrome('race car') === true); +``` + +`palindrome("not a palindrome")` debe devolver `false`. + +```js +assert(palindrome('not a palindrome') === false); +``` + +`palindrome("A man, a plan, a canal. Panama")` debe devolver `true`. + +```js +assert(palindrome('A man, a plan, a canal. Panama') === true); +``` + +`palindrome("never odd or even")` debe devolver `true`. + +```js +assert(palindrome('never odd or even') === true); +``` + +`palindrome("nope")` debe devolver `false`. + +```js +assert(palindrome('nope') === false); +``` + +`palindrome("almostomla")` debe devolver `false`. + +```js +assert(palindrome('almostomla') === false); +``` + +`palindrome("My age is 0, 0 si ega ym.")` debe devolver `true`. + +```js +assert(palindrome('My age is 0, 0 si ega ym.') === true); +``` + +`palindrome("1 eye for of 1 eye.")` debe devolver `false`. + +```js +assert(palindrome('1 eye for of 1 eye.') === false); +``` + +`palindrome("0_0 (: /-\ :) 0-0")` debe devolver `true`. + +```js +assert(palindrome('0_0 (: /- :) 0-0') === true); +``` + +`palindrome("five|\_/|four")` debe devolver `false`. + +```js +assert(palindrome('five|_/|four') === false); +``` + +# --seed-- + +## --seed-contents-- + +```js +function palindrome(str) { + return true; +} + +palindrome("eye"); +``` + +# --solutions-- + +```js +function palindrome(str) { + var string = str.toLowerCase().split(/[^A-Za-z0-9]/gi).join(''); + var aux = string.split(''); + if (aux.join('') === aux.reverse().join('')){ + return true; + } + + return false; +} +``` diff --git a/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/build-a-roman-numeral-converter-project/roman-numeral-converter.md b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/build-a-roman-numeral-converter-project/roman-numeral-converter.md new file mode 100644 index 00000000000000..61fde50ea64834 --- /dev/null +++ b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/build-a-roman-numeral-converter-project/roman-numeral-converter.md @@ -0,0 +1,215 @@ +--- +id: a7f4d8f2483413a6ce226cac +title: Construya un convertidor de números romanos +challengeType: 5 +forumTopicId: 16044 +dashedName: build-a-roman-numeral-converter +--- + +# --description-- + +Convierte el número dado en un número romano. + +| Números romanos | Números arábigos | +| --------------- | ---------------- | +| M | 1000 | +| CM | 900 | +| D | 500 | +| CD | 400 | +| C | 100 | +| XC | 90 | +| L | 50 | +| XL | 40 | +| X | 10 | +| IX | 9 | +| V | 5 | +| IV | 4 | +| I | 1 | + +Todas las respuestas de los números romanos deben ser proporcionadas en mayúsculas. + +# --hints-- + +`convertToRoman(2)` debe devolver la cadena `II`. + +```js +assert.deepEqual(convertToRoman(2), 'II'); +``` + +`convertToRoman(3)` debe devolver la cadena `III`. + +```js +assert.deepEqual(convertToRoman(3), 'III'); +``` + +`convertToRoman(4)` debe devolver la cadena `IV`. + +```js +assert.deepEqual(convertToRoman(4), 'IV'); +``` + +`convertToRoman(5)` debe devolver la cadena `V`. + +```js +assert.deepEqual(convertToRoman(5), 'V'); +``` + +`convertToRoman(9)` debe devolver la cadena `IX`. + +```js +assert.deepEqual(convertToRoman(9), 'IX'); +``` + +`convertToRoman(12)` debe devolver la cadena `XII`. + +```js +assert.deepEqual(convertToRoman(12), 'XII'); +``` + +`convertToRoman(16)` debe devolver la cadena `XVI`. + +```js +assert.deepEqual(convertToRoman(16), 'XVI'); +``` + +`convertToRoman(29)` debe devolver la cadena `XXIX`. + +```js +assert.deepEqual(convertToRoman(29), 'XXIX'); +``` + +`convertToRoman(44)` debe devolver la cadena `XLIV`. + +```js +assert.deepEqual(convertToRoman(44), 'XLIV'); +``` + +`convertToRoman(45)` debe devolver la cadena `XLV`. + +```js +assert.deepEqual(convertToRoman(45), 'XLV'); +``` + +`convertToRoman(68)` debe devolver la cadena `LXVIII` + +```js +assert.deepEqual(convertToRoman(68), 'LXVIII'); +``` + +`convertToRoman(83)` debe devolver la cadena `LXXXIII` + +```js +assert.deepEqual(convertToRoman(83), 'LXXXIII'); +``` + +`convertToRoman(97)` debe devolver la cadena `XCVII` + +```js +assert.deepEqual(convertToRoman(97), 'XCVII'); +``` + +`convertToRoman(99)` debe devolver la cadena `XCIX` + +```js +assert.deepEqual(convertToRoman(99), 'XCIX'); +``` + +`convertToRoman(400)` debe devolver la cadena `CD` + +```js +assert.deepEqual(convertToRoman(400), 'CD'); +``` + +`convertToRoman(500)` debe devolver la cadena `D` + +```js +assert.deepEqual(convertToRoman(500), 'D'); +``` + +`convertToRoman(501)` debe devolver la cadena `DI` + +```js +assert.deepEqual(convertToRoman(501), 'DI'); +``` + +`convertToRoman(649)` debe devolver la cadena `DCXLIX` + +```js +assert.deepEqual(convertToRoman(649), 'DCXLIX'); +``` + +`convertToRoman(798)` debe devolver la cadena `DCCXCVIII` + +```js +assert.deepEqual(convertToRoman(798), 'DCCXCVIII'); +``` + +`convertToRoman(891)` debe devolver la cadena `DCCCXCI` + +```js +assert.deepEqual(convertToRoman(891), 'DCCCXCI'); +``` + +`convertToRoman(1000)` debe devolver la cadena `M` + +```js +assert.deepEqual(convertToRoman(1000), 'M'); +``` + +`convertToRoman(1004)` debe devolver la cadena `MIV` + +```js +assert.deepEqual(convertToRoman(1004), 'MIV'); +``` + +`convertToRoman(1006)` debe devolver la cadena `MVI` + +```js +assert.deepEqual(convertToRoman(1006), 'MVI'); +``` + +`convertToRoman(1023)` debe devolver la cadena `MXXIII` + +```js +assert.deepEqual(convertToRoman(1023), 'MXXIII'); +``` + +`convertToRoman(2014)` debe devolver la cadena `MMXIV` + +```js +assert.deepEqual(convertToRoman(2014), 'MMXIV'); +``` + +`convertToRoman(3999)` debe devolver la cadena `MMMCMXCIX` + +```js +assert.deepEqual(convertToRoman(3999), 'MMMCMXCIX'); +``` + +# --seed-- + +## --seed-contents-- + +```js +function convertToRoman(num) { + return num; +} + +convertToRoman(36); +``` + +# --solutions-- + +```js +function convertToRoman(num) { + var ref = [['M', 1000], ['CM', 900], ['D', 500], ['CD', 400], ['C', 100], ['XC', 90], ['L', 50], ['XL', 40], ['X', 10], ['IX', 9], ['V', 5], ['IV', 4], ['I', 1]]; + var res = []; + ref.forEach(function(p) { + while (num >= p[1]) { + res.push(p[0]); + num -= p[1]; + } + }); + return res.join(''); +} +``` diff --git a/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/build-a-telephone-number-validator-project/telephone-number-validator.md b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/build-a-telephone-number-validator-project/telephone-number-validator.md new file mode 100644 index 00000000000000..66d1de9e59b6cd --- /dev/null +++ b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/build-a-telephone-number-validator-project/telephone-number-validator.md @@ -0,0 +1,217 @@ +--- +id: aff0395860f5d3034dc0bfc9 +title: Crear un validador de números de teléfono +challengeType: 5 +forumTopicId: 16090 +dashedName: build-a-telephone-number-validator +--- + +# --description-- + +Devuelve `true` si la cadena pasada concuerda con un número de teléfono válido en Estados Unidos. + +El usuario puede completar el campo del formulario de la forma de números de teléfono que elija, siempre que tenga el formato de un número válido de EE. UU. Los siguientes son ejemplos de formatos válidos para números de EE. UU. (consulte las pruebas a continuación para conocer otras variantes): + +
    555-555-5555
    (555)555-5555
    (555) 555-5555
    555 555 5555
    5555555555
    1 555 555 5555
    + +Para este desafío, se le presentará una cadena como: `800-692-7753` o `8oo-six427676;laskdjf`. Tu trabajo serávalidar o rechazar el número de teléfono de EE. UU. en función de cualquier combinación de los formatos proporcionados anteriormente. El código de área es requerido. Si se proporciona el código de país, debe confirmar que el código de país es `1`. Devolverá `true` (verdadero) si la cadena es un número de teléfono de EE. UU. válido; de lo contrario, devolverá `false` (falso). + +# --hints-- + +`telephoneCheck("555-555-5555")` debería devolver un booleano. + +```js +assert(typeof telephoneCheck('555-555-5555') === 'boolean'); +``` + +`telephoneCheck("1 555-555-5555")` debería devolver `true`. + +```js +assert(telephoneCheck('1 555-555-5555') === true); +``` + +`telephoneCheck("1 (555) 555-5555")` debería devolver `true`. + +```js +assert(telephoneCheck('1 (555) 555-5555') === true); +``` + +`telephoneCheck("5555555555")` debería devolver `true`. + +```js +assert(telephoneCheck('5555555555') === true); +``` + +`telephoneCheck("555-555-5555")` debería devolver `true`. + +```js +assert(telephoneCheck('555-555-5555') === true); +``` + +`telephoneCheck("(555)555-5555")` debería devolver `true`. + +```js +assert(telephoneCheck('(555)555-5555') === true); +``` + +`telephoneCheck("1(555)555-5555")` debería devolver `true`. + +```js +assert(telephoneCheck('1(555)555-5555') === true); +``` + +`telephoneCheck("555-5555")` debería devolver `false`. + +```js +assert(telephoneCheck('555-5555') === false); +``` + +`telephoneCheck("5555555")` debería devolver `false`. + +```js +assert(telephoneCheck('5555555') === false); +``` + +`telephoneCheck("1 555)555-5555")` debería devolver `false`. + +```js +assert(telephoneCheck('1 555)555-5555') === false); +``` + +`telephoneCheck("1 555 555 5555")` debería devolver `true`. + +```js +assert(telephoneCheck('1 555 555 5555') === true); +``` + +`telephoneCheck("1 456 789 4444")` debería devolver `true`. + +```js +assert(telephoneCheck('1 456 789 4444') === true); +``` + +`telephoneCheck("123**&!!asdf#")` debería devolver `false`. + +```js +assert(telephoneCheck('123**&!!asdf#') === false); +``` + +`telephoneCheck("55555555")` debería devolver `false`. + +```js +assert(telephoneCheck('55555555') === false); +``` + +`telephoneCheck("(6054756961)")` debería devolver `false`. + +```js +assert(telephoneCheck('(6054756961)') === false); +``` + +`telephoneCheck("2 (757) 622-7382")` debería devolver `false`. + +```js +assert(telephoneCheck('2 (757) 622-7382') === false); +``` + +`telephoneCheck("0 (757) 622-7382")` debería devolver `false`. + +```js +assert(telephoneCheck('0 (757) 622-7382') === false); +``` + +`telephoneCheck("-1 (757) 622-7382")` debería devolver `false`. + +```js +assert(telephoneCheck('-1 (757) 622-7382') === false); +``` + +`telephoneCheck("2 757 622-7382")` debería devolver `false`. + +```js +assert(telephoneCheck('2 757 622-7382') === false); +``` + +`telephoneCheck("10 (757) 622-7382")` debería devolver `false`. + +```js +assert(telephoneCheck('10 (757) 622-7382') === false); +``` + +`telephoneCheck("27576227382")` debería devolver `false`. + +```js +assert(telephoneCheck('27576227382') === false); +``` + +`telephoneCheck("(275)76227382")` debería devolver `false`. + +```js +assert(telephoneCheck('(275)76227382') === false); +``` + +`telephoneCheck("2(757)6227382")` debería devolver `false`. + +```js +assert(telephoneCheck('2(757)6227382') === false); +``` + +`telephoneCheck("2(757)622-7382")` debería devolver `false`. + +```js +assert(telephoneCheck('2(757)622-7382') === false); +``` + +`telephoneCheck("555)-555-5555")` debería devolver `false`. + +```js +assert(telephoneCheck('555)-555-5555') === false); +``` + +`telephoneCheck("(555-555-5555")` debería devolver `false`. + +```js +assert(telephoneCheck('(555-555-5555') === false); +``` + +`telephoneCheck("(555)5(55?)-5555")` debería devolver `false`. + +```js +assert(telephoneCheck('(555)5(55?)-5555') === false); +``` + +`telephoneCheck("55 55-55-555-5")` debería devolver `false`. + +```js +assert(telephoneCheck('55 55-55-555-5') === false); +``` + +`telephoneCheck("11 555-555-5555")` debería devolver `false`. + +```js +assert(telephoneCheck('11 555-555-5555') === false); +``` + +# --seed-- + +## --seed-contents-- + +```js +function telephoneCheck(str) { + return true; +} + +telephoneCheck("555-555-5555"); +``` + +# --solutions-- + +```js +var re = /^([+]?1[\s]?)?((?:[(](?:[2-9]1[02-9]|[2-9][02-8][0-9])[)][\s]?)|(?:(?:[2-9]1[02-9]|[2-9][02-8][0-9])[\s.-]?)){1}([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2}[\s.-]?){1}([0-9]{4}){1}$/; + +function telephoneCheck(str) { + return re.test(str); +} + +telephoneCheck("555-555-5555"); +``` diff --git a/curriculum/challenges/german/00-certifications/back-end-development-and-apis-certification/back-end-development-and-apis-certification.yml b/curriculum/challenges/german/00-certifications/back-end-development-and-apis-certification/back-end-development-and-apis-certification.yml new file mode 100644 index 00000000000000..1592b68b7b36cf --- /dev/null +++ b/curriculum/challenges/german/00-certifications/back-end-development-and-apis-certification/back-end-development-and-apis-certification.yml @@ -0,0 +1,22 @@ +--- +id: 561add10cb82ac38a17523bc +title: Zertifizierung von Backend-Entwicklung und APIs +certification: back-end-development-and-apis +challengeType: 7 +isPrivate: true +tests: + - + id: bd7158d8c443edefaeb5bdef + title: Zeitstempel Microservice + - + id: bd7158d8c443edefaeb5bdff + title: Microservice zum Parsen von Anfrage-Headern + - + id: bd7158d8c443edefaeb5bd0e + title: URL-Verkürzungs-Microservice + - + id: 5a8b073d06fa14fcfde687aa + title: Übungs-Tracker + - + id: bd7158d8c443edefaeb5bd0f + title: Datei-Metadaten-Mikroservice diff --git a/curriculum/challenges/german/00-certifications/data-analysis-with-python-certification/data-analysis-with-python-certification.yml b/curriculum/challenges/german/00-certifications/data-analysis-with-python-certification/data-analysis-with-python-certification.yml new file mode 100644 index 00000000000000..b1e71765f45ab1 --- /dev/null +++ b/curriculum/challenges/german/00-certifications/data-analysis-with-python-certification/data-analysis-with-python-certification.yml @@ -0,0 +1,23 @@ +--- +id: 5e46fc95ac417301a38fb934 +title: Zertifizierung für Datenanalyse mit Python +certification: data-analysis-with-python +challengeType: 7 +isPrivate: true +tests: + - + id: 5e46f7e5ac417301a38fb928 + title: Rechner für Mittelwert-Varianz-Standardabweichung + - + id: 5e46f7e5ac417301a38fb929 + title: Demografischer Datenanalysator + - + id: 5e46f7f8ac417301a38fb92a + title: Medizinischer Datenvisualisierer + - + id: 5e46f802ac417301a38fb92b + title: Seitenansicht Zeitreihenvisualisierer + - + id: 5e4f5c4b570f7e3a4949899f + title: Meeresspiegelvorhersage + diff --git a/curriculum/challenges/german/00-certifications/data-visualization-certification/data-visualization-certification.yml b/curriculum/challenges/german/00-certifications/data-visualization-certification/data-visualization-certification.yml new file mode 100644 index 00000000000000..221b00fce00662 --- /dev/null +++ b/curriculum/challenges/german/00-certifications/data-visualization-certification/data-visualization-certification.yml @@ -0,0 +1,22 @@ +--- +id: 5a553ca864b52e1d8bceea14 +title: Zertifizierung für Datenvisualisierung +certification: data-visualization +challengeType: 7 +isPrivate: true +tests: + - + id: bd7168d8c242eddfaeb5bd13 + title: Visualisieren von Daten mithilfe eines Balkendiagramms + - + id: bd7178d8c242eddfaeb5bd13 + title: Visualisierung von Daten mithilfe eines Streudiagramms + - + id: bd7188d8c242eddfaeb5bd13 + title: Visualisieren von Daten mithilfe einer Heatmap + - + id: 587d7fa6367417b2b2512bbf + title: Visualisierung von Daten mithilfe einer Choropleth-Karte + - + id: 587d7fa6367417b2b2512bc0 + title: Visualisierung von Daten mithilfe eines Treemap-Diagramms diff --git a/curriculum/challenges/german/00-certifications/front-end-development-libraries-certification/front-end-development-libraries-certification.yml b/curriculum/challenges/german/00-certifications/front-end-development-libraries-certification/front-end-development-libraries-certification.yml new file mode 100644 index 00000000000000..977c8c835fdc33 --- /dev/null +++ b/curriculum/challenges/german/00-certifications/front-end-development-libraries-certification/front-end-development-libraries-certification.yml @@ -0,0 +1,22 @@ +--- +id: 561acd10cb82ac38a17513bc +title: Zertifizierung von Front-End-Entwicklungsbibliotheken +certification: front-end-development-libraries +challengeType: 7 +isPrivate: true +tests: + - + id: bd7158d8c442eddfaeb5bd13 + title: Erstelle eine Zufalls-Zitat-Maschine + - + id: bd7157d8c242eddfaeb5bd13 + title: Erstelle einen Markdown Vorschau-Viewer + - + id: 587d7dbc367417b2b2512bae + title: Erstelle eine Schlagzeug-Maschine + - + id: bd7158d8c442eddfaeb5bd17 + title: Erstelle einen JavaScript-Rechner + - + id: bd7158d8c442eddfaeb5bd0f + title: Erstelle eine 25 + 5 Uhr diff --git a/curriculum/challenges/german/00-certifications/information-security-certification/information-security-certification.yml b/curriculum/challenges/german/00-certifications/information-security-certification/information-security-certification.yml new file mode 100644 index 00000000000000..8997e87b86b0b4 --- /dev/null +++ b/curriculum/challenges/german/00-certifications/information-security-certification/information-security-certification.yml @@ -0,0 +1,22 @@ +--- +id: 5e6021435ac9d0ecd8b94b00 +title: Zertifizierung für Informationssicherheit +certification: information-security +challengeType: 7 +isPrivate: true +tests: + - + id: 587d824a367417b2b2512c44 + title: Aktienpreisprüfer + - + id: 587d824a367417b2b2512c45 + title: Anonymes Nachrichtenbrett + - + id: 5e46f979ac417301a38fb932 + title: Port-Scanner + - + id: 5e46f983ac417301a38fb933 + title: SHA-1 Passwort-Cracker + - + id: 5e601c775ac9d0ecd8b94aff + title: Sicheres Echtzeit-Multiplayer-Spiel diff --git a/curriculum/challenges/german/00-certifications/javascript-algorithms-and-data-structures-certification/javascript-algorithms-and-data-structures-certification.yml b/curriculum/challenges/german/00-certifications/javascript-algorithms-and-data-structures-certification/javascript-algorithms-and-data-structures-certification.yml new file mode 100644 index 00000000000000..f45647dd82b6fb --- /dev/null +++ b/curriculum/challenges/german/00-certifications/javascript-algorithms-and-data-structures-certification/javascript-algorithms-and-data-structures-certification.yml @@ -0,0 +1,22 @@ +--- +id: 561abd10cb81ac38a17513bc +title: Zertifizierung für JavaScript-Algorithmen und Datenstrukturen +certification: javascript-algorithms-and-data-structures +challengeType: 7 +isPrivate: true +tests: + - + id: aaa48de84e1ecc7c742e1124 + title: Palindrom-Prüfer + - + id: a7f4d8f2483413a6ce226cac + title: Konverter für römische Zahlen + - + id: 56533eb9ac21ba0edf2244e2 + title: Cäsar-Chiffrierung + - + id: aff0395860f5d3034dc0bfc9 + title: Telefonnummern-Prüfer + - + id: aa2e6f85cab2ab736c9a9b24 + title: Registrierkasse diff --git a/curriculum/challenges/german/00-certifications/legacy-back-end-certification/legacy-back-end-certification.yml b/curriculum/challenges/german/00-certifications/legacy-back-end-certification/legacy-back-end-certification.yml new file mode 100644 index 00000000000000..439c65ca26b69d --- /dev/null +++ b/curriculum/challenges/german/00-certifications/legacy-back-end-certification/legacy-back-end-certification.yml @@ -0,0 +1,37 @@ +--- +id: 660add10cb82ac38a17513be +title: Zertifizierung für "Legacy" Front End +certification: legacy-back-end +challengeType: 7 +isPrivate: true +tests: + - + id: bd7158d8c443edefaeb5bdef + title: Zeitstempel Microservice + - + id: bd7158d8c443edefaeb5bdff + title: Request-Header-Parser-Mikroservice + - + id: bd7158d8c443edefaeb5bd0e + title: URL-Verkürzungs-Microservice + - + id: bd7158d8c443edefaeb5bdee + title: Bildsuchabstraktionsebene + - + id: bd7158d8c443edefaeb5bd0f + title: Datei-Metadaten-Mikroservice + - + id: bd7158d8c443eddfaeb5bdef + title: Erstelle eine Abstimmungsapp + - + id: bd7158d8c443eddfaeb5bdff + title: Erstelle eine App zur Koordination des Nachtlebens + - + id: bd7158d8c443eddfaeb5bd0e + title: Chart der Börse + - + id: bd7158d8c443eddfaeb5bd0f + title: Verwalte einen Buchhandelsclub + - + id: bd7158d8c443eddfaeb5bdee + title: Erstelle einen Pinterest Klon diff --git a/curriculum/challenges/german/00-certifications/legacy-data-visualization-certification/legacy-data-visualization-certification.yml b/curriculum/challenges/german/00-certifications/legacy-data-visualization-certification/legacy-data-visualization-certification.yml new file mode 100644 index 00000000000000..b388d7d5e110e9 --- /dev/null +++ b/curriculum/challenges/german/00-certifications/legacy-data-visualization-certification/legacy-data-visualization-certification.yml @@ -0,0 +1,37 @@ +--- +id: 561add10cb82ac39a17513bc +title: Zertifizierung für "Legacy" Datenvisualisierung +certification: legacy-data-visualization +challengeType: 7 +isPrivate: true +tests: + - + id: bd7157d8c242eddfaeb5bd13 + title: Erstelle einen Markdown Vorschau-Viewer + - + id: bd7156d8c242eddfaeb5bd13 + title: Erstelle eine Teilnehmer-Rangliste + - + id: bd7155d8c242eddfaeb5bd13 + title: Erstelle eine Rezeptbox + - + id: bd7154d8c242eddfaeb5bd13 + title: Erstelle das Spiel des Lebens + - + id: bd7153d8c242eddfaeb5bd13 + title: Erstelle ein schurkenartiges Dungeon Crawler Spiel + - + id: bd7168d8c242eddfaeb5bd13 + title: Visualisiere Daten mit einem Balkendiagramm + - + id: bd7178d8c242eddfaeb5bd13 + title: Visualisiere Daten mit einem Scatterplot-Diagramm (Streudiagramm) + - + id: bd7188d8c242eddfaeb5bd13 + title: Visualisiere Daten mit einer Heatmap + - + id: bd7198d8c242eddfaeb5bd13 + title: Nationale Kontiguität mit einem Force Directed Graph zeigen + - + id: bd7108d8c242eddfaeb5bd13 + title: Kartendaten rund um den Globus diff --git a/curriculum/challenges/german/00-certifications/legacy-front-end-certification/legacy-front-end-certification.yml b/curriculum/challenges/german/00-certifications/legacy-front-end-certification/legacy-front-end-certification.yml new file mode 100644 index 00000000000000..21e2de43682523 --- /dev/null +++ b/curriculum/challenges/german/00-certifications/legacy-front-end-certification/legacy-front-end-certification.yml @@ -0,0 +1,37 @@ +--- +id: 561add10cb82ac38a17513be +title: Zertifizierung für "Legacy" Front End +certification: legacy-front-end +challengeType: 7 +isPrivate: true +tests: + - + id: bd7158d8c242eddfaeb5bd13 + title: Erstellung einer persönlichen Portfolio-Webseite + - + id: bd7158d8c442eddfaeb5bd13 + title: Erstelle eine Zufalls-Zitat-Maschine + - + id: bd7158d8c442eddfaeb5bd0f + title: Erstelle eine 25 + 5 Uhr + - + id: bd7158d8c442eddfaeb5bd17 + title: Erstelle einen JavaScript-Rechner + - + id: bd7158d8c442eddfaeb5bd10 + title: Lokales Wetter anzeigen + - + id: bd7158d8c442eddfaeb5bd1f + title: Verwenden der Twitch JSON API + - + id: bd7158d8c442eddfaeb5bd18 + title: Style Camper News Geschichten + - + id: bd7158d8c442eddfaeb5bd19 + title: Erstelle einen Wikipedia-Viewer + - + id: bd7158d8c442eedfaeb5bd1c + title: Erstelle ein Tic Tac Toe Spiel + - + id: bd7158d8c442eddfaeb5bd1c + title: Erstelle ein Simon-Spiel diff --git a/curriculum/challenges/german/00-certifications/legacy-full-stack-certification/legacy-full-stack-certification.yml b/curriculum/challenges/german/00-certifications/legacy-full-stack-certification/legacy-full-stack-certification.yml new file mode 100644 index 00000000000000..c0f7baf0e5671c --- /dev/null +++ b/curriculum/challenges/german/00-certifications/legacy-full-stack-certification/legacy-full-stack-certification.yml @@ -0,0 +1,25 @@ +--- +id: 561add10cb82ac38a17213bd +title: Legacy Zertifizierung für Full Stack +certification: legacy-full-stack +challengeType: 7 +isPrivate: true +tests: + - + id: 561add10cb82ac38a17513bc + title: Zertifizierung für Responsive Web Design + - + id: 561abd10cb81ac38a17513bc + title: Zertifizierung für JavaScript-Algorithmen und Datenstrukturen + - + id: 561acd10cb82ac38a17513bc + title: Zertifizierung für Front-End Bibliotheken + - + id: 5a553ca864b52e1d8bceea14 + title: Zertifizierung für Datenvisualisierung + - + id: 561add10cb82ac38a17523bc + title: Zertifizierung für API's und Microservices + - + id: 561add10cb82ac38a17213bc + title: Legacy Zertifizierung für Sicherheit und Qualitätssicherung diff --git a/curriculum/challenges/german/00-certifications/legacy-information-security-and-quality-assurance-certification/legacy-information-security-and-quality-assurance-certification.yml b/curriculum/challenges/german/00-certifications/legacy-information-security-and-quality-assurance-certification/legacy-information-security-and-quality-assurance-certification.yml new file mode 100644 index 00000000000000..3ba934933ba54e --- /dev/null +++ b/curriculum/challenges/german/00-certifications/legacy-information-security-and-quality-assurance-certification/legacy-information-security-and-quality-assurance-certification.yml @@ -0,0 +1,22 @@ +--- +id: 561add10cb82ac38a17213bc +title: Legacy Zertifizierung für Informationssicherheit und Qualitätssicherung +certification: legacy-information-security-and-quality-assurance +challengeType: 7 +isPrivate: true +tests: + - + id: 587d8249367417b2b2512c41 + title: Metrisch-Imperialer Konverter + - + id: 587d8249367417b2b2512c42 + title: Issue-Tracker + - + id: 587d824a367417b2b2512c43 + title: Persönliche Bibliothek + - + id: 587d824a367417b2b2512c44 + title: Aktienpreisprüfer + - + id: 587d824a367417b2b2512c45 + title: Anonymes Nachrichtenbrett diff --git a/curriculum/challenges/german/00-certifications/machine-learning-with-python-certification/machine-learning-with-python-certification.yml b/curriculum/challenges/german/00-certifications/machine-learning-with-python-certification/machine-learning-with-python-certification.yml new file mode 100644 index 00000000000000..e5ece5b06d8c57 --- /dev/null +++ b/curriculum/challenges/german/00-certifications/machine-learning-with-python-certification/machine-learning-with-python-certification.yml @@ -0,0 +1,23 @@ +--- +id: 5e46fc95ac417301a38fb935 +title: Zertifizierung für Machine Learning mit Python +certification: machine-learning-with-python +challengeType: 7 +isPrivate: true +tests: + - + id: 5e46f8d6ac417301a38fb92d + title: Schere Stein Papier + - + id: 5e46f8dcac417301a38fb92e + title: Katzen- und Hundebildklassifizierer + - + id: 5e46f8e3ac417301a38fb92f + title: Buchempfehlungsprogramm mit KNN + - + id: 5e46f8edac417301a38fb930 + title: Gesundheitskostenrechner mit einer linearen Regression + - + id: 5e46f8edac417301a38fb931 + title: SMS-Textklassifizierung mittels neuronalem Netzwerk + diff --git a/curriculum/challenges/german/00-certifications/quality-assurance-certification/quality-assurance-certification.yml b/curriculum/challenges/german/00-certifications/quality-assurance-certification/quality-assurance-certification.yml new file mode 100644 index 00000000000000..28d527fbacc2d4 --- /dev/null +++ b/curriculum/challenges/german/00-certifications/quality-assurance-certification/quality-assurance-certification.yml @@ -0,0 +1,23 @@ +--- +id: 5e611829481575a52dc59c0e +title: Zertifizierung für Qualitätssicherung +certification: quality-assurance +challengeType: 7 +isPrivate: true +tests: + - + id: 587d8249367417b2b2512c41 + title: Metrisch-Imperialer Konverter + - + id: 587d8249367417b2b2512c42 + title: Issue-Tracker + - + id: 587d824a367417b2b2512c43 + title: Persönliche Bibliothek + - + id: 5e601bf95ac9d0ecd8b94afd + title: Sudoku-Löser + - + id: 5e601c0d5ac9d0ecd8b94afe + title: Übersetzer Amerikanisch-Britisch + diff --git a/curriculum/challenges/german/00-certifications/relational-database-certification/relational-database-certification.yml b/curriculum/challenges/german/00-certifications/relational-database-certification/relational-database-certification.yml new file mode 100644 index 00000000000000..111f74565f1cbd --- /dev/null +++ b/curriculum/challenges/german/00-certifications/relational-database-certification/relational-database-certification.yml @@ -0,0 +1,22 @@ +--- +id: 606243f50267e718b1e755f4 +title: Zertifizierung für relationale Datenbanken +certification: relational-database +challengeType: 7 +isPrivate: true +tests: + - + id: 5f1a4ef5d5d6b5ab580fc6ae + title: Himmelskörperdatenbank + - + id: 5f9771307d4d22b9d2b75a94 + title: Weltmeisterschafts-Datenbank + - + id: 5f87ac112ae598023a42df1a + title: Salon-Terminplaner + - + id: 602d9ff222201c65d2a019f2 + title: Periodensystemdatenbank + - + id: 602da04c22201c65d2a019f4 + title: Zahlenratespiel diff --git a/curriculum/challenges/german/00-certifications/responsive-web-design-certification/responsive-web-design-certification.yml b/curriculum/challenges/german/00-certifications/responsive-web-design-certification/responsive-web-design-certification.yml new file mode 100644 index 00000000000000..27093b61d7b897 --- /dev/null +++ b/curriculum/challenges/german/00-certifications/responsive-web-design-certification/responsive-web-design-certification.yml @@ -0,0 +1,22 @@ +--- +id: 561add10cb82ac38a17513bc +title: Zertifizierung für Responsive Web Design +certification: responsive-web-design +challengeType: 7 +isPrivate: true +tests: + - + id: bd7158d8c442eddfaeb5bd18 + title: Erstelle einer Tributseite + - + id: 587d78af367417b2b2512b03 + title: Erstellung eines Umfrageformulars + - + id: 587d78af367417b2b2512b04 + title: Erstellung einer Produkt-Landing-Page + - + id: 587d78b0367417b2b2512b05 + title: Erstellung einer technischen Dokumentationsseite + - + id: bd7158d8c242eddfaeb5bd13 + title: Erstellung einer persönlichen Portfolio-Webseite diff --git a/curriculum/challenges/german/00-certifications/scientific-computing-with-python-certification/scientific-computing-with-python-certification.yml b/curriculum/challenges/german/00-certifications/scientific-computing-with-python-certification/scientific-computing-with-python-certification.yml new file mode 100644 index 00000000000000..629c41b106a5ed --- /dev/null +++ b/curriculum/challenges/german/00-certifications/scientific-computing-with-python-certification/scientific-computing-with-python-certification.yml @@ -0,0 +1,22 @@ +--- +id: 5e44431b903586ffb414c951 +title: Zertifizierung für Wissenschaftliches Rechnen mit Python +certification: scientific-computing-with-python +challengeType: 7 +isPrivate: true +tests: + - + id: 5e44412c903586ffb414c94c + title: Arithmetischer Formatierer + - + id: 5e444136903586ffb414c94d + title: Zeitrechner + - + id: 5e44413e903586ffb414c94e + title: Budget-App + - + id: 5e444147903586ffb414c94f + title: Polygon-Flächenrechner + - + id: 5e44414f903586ffb414c950 + title: Wahrscheinlichkeitsrechner diff --git a/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/add-a-text-alternative-to-images-for-visually-impaired-accessibility.md b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/add-a-text-alternative-to-images-for-visually-impaired-accessibility.md new file mode 100644 index 00000000000000..237616ef837211 --- /dev/null +++ b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/add-a-text-alternative-to-images-for-visually-impaired-accessibility.md @@ -0,0 +1,46 @@ +--- +id: 587d774c367417b2b2512a9c +title: Füge einen alternativen Text zu einem Bild für Sehbehinderte hinzu +challengeType: 0 +videoUrl: 'https://scrimba.com/c/cPp7VfD' +forumTopicId: 16628 +dashedName: add-a-text-alternative-to-images-for-visually-impaired-accessibility +--- + +# --description-- + +Du hast wahrscheinlich ein `alt`-Attribut an einem `img`-Tag in anderen Aufgaben gesehen. `alt`-Text beschreibt den Inhalt des Bildes und bietet eine Textalternative für das Bild. Ein `alt`-Attribut hilft in Fällen, in denen das Bild nicht geladen wird oder von einem Benutzer nicht betrachtet werden kann. Suchmaschinen verwenden es auch, um zu verstehen, was ein Bild enthält, um es in die Suchergebnisse aufzunehmen. Hier ist ein Beispiel: + +```html +Company logo +``` + +Menschen mit Sehbehinderungen sind auf Screenreader angewiesen, um Webinhalte in eine Sprachausgabe umzuwandeln. Sie erhalten keine Informationen, wenn sie nur visuell dargestellt werden. Bei Bildern können Screenreader auf das `alt`-Attribut zugreifen und dessen Inhalt lesen, um wichtige Informationen zu liefern. + +Ein guter `alt` Text liefert dem Leser eine kurze Beschreibung des Bildes. Du solltest immer ein `alt`-Attribut in dein Bild einfügen. Gemäß der HTML5-Spezifikation wird dies nun als verbindlich angesehen. + +# --instructions-- + +Camper Cat ist zufällig sowohl ein Coding Ninja als auch ein tatsächlicher Ninja, der eine Website aufbaut um sein Wissen zu teilen. Das Profilbild, das er verwenden möchte, zeigt seine Fähigkeiten und sollte von allen Besuchern der Website wahrgenommen werden. Füge ein `alt`-Attribut in den `img`-Tag ein, das erklärt, dass Camper Cat Karate praktiziert. (Das Bild `src` verweist nicht auf eine tatsächliche Datei, du solltest also den `alt`-Text in der Anzeige sehen.) + +# --hints-- + +Dein `img`-Tag sollte ein `alt`-Attribut besitzen und dieses sollte nicht leer sein. + +```js +assert($('img').attr('alt')); +``` + +# --seed-- + +## --seed-contents-- + +```html + +``` + +# --solutions-- + +```html +Someone doing karate +``` diff --git a/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/add-an-accessible-date-picker.md b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/add-an-accessible-date-picker.md new file mode 100644 index 00000000000000..86f0086277ae9e --- /dev/null +++ b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/add-an-accessible-date-picker.md @@ -0,0 +1,105 @@ +--- +id: 587d778b367417b2b2512aa8 +title: Füge eine barrierefreie Datumsauswahl hinzu +challengeType: 0 +videoUrl: 'https://scrimba.com/c/cR3bRbCV' +forumTopicId: 301008 +dashedName: add-an-accessible-date-picker +--- + +# --description-- + +Formulare enthalten oft das `input`-Feld mit dem verschiedene Formularsteuerelemente erstellt werden können. Das `type`-Attribut dieses Elements gibt an, welche Art von `input`-Element erstellt wird. + +Möglicherweise hast Du den `text`- und `submit`-Tag in vorherigen Aufgaben schon gesehen. Und mit HTML5 wurde eine Option eingeführt, um ein `date`-Feld für Datumsangaben zu nutzen. Abhängig von der Browserunterstützung wird eine Datumsauswahl im `input`-Feld angezeigt, wenn es im Fokus ist, was das Ausfüllen eines Formulars für alle Benutzer erleichtert. + +Bei älteren Browsern wird der Typ standardmäßig auf `text` gesetzt, so dass es hilfreich ist, dem Benutzer das erwartete Datumsformat im `label`- oder `placeholder`-Text anzuzeigen, nur für den Fall. + +Hier ist ein Beispiel: + +```html + + +``` + +# --instructions-- + +Camper Cat stellt ein Mortal Kombat-Turnier auf die Beine und möchte seine Teilnehmer fragen, welches Datum dafür in Frage kommt. Füge ein `input`-Tag mit dem Attribut `type` `date`, dem Attribut `id` `pickdate` und dem Attribut `name` `date` ein. + +# --hints-- + +Dein Code sollte einen `input` Tag für das Datumsauswahlfeld hinzufügen. + +```js +assert($('input').length == 2); +``` + +Dein `input`-Tag sollte ein `type`-Attribut mit einem Wert `date` enthalten. + +```js +assert($('input').attr('type') == 'date'); +``` + +Dein `input`-Tag sollte ein `id`-Attribut mit einem Wert `pickdate` enthalten. + +```js +assert($('input').attr('id') == 'pickdate'); +``` + +Dein `input`-Tag sollte ein `name`-Attribut mit einem Wert `date` enthalten. + +```js +assert($('input').attr('name') == 'date'); +``` + +# --seed-- + +## --seed-contents-- + +```html + +
    +

    Tournaments

    +
    +
    +
    +

    Mortal Kombat Tournament Survey

    +
    +

    Tell us the best date for the competition

    + + + + + + + + + +
    +
    +
    +
    © 2018 Camper Cat
    + +``` + +# --solutions-- + +```html + +
    +

    Tournaments

    +
    +
    +
    +

    Mortal Kombat Tournament Survey

    +
    +

    Tell us the best date for the competition

    + + + +
    +
    +
    +
    © 2018 Camper Cat
    + +``` diff --git a/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/avoid-colorblindness-issues-by-carefully-choosing-colors-that-convey-information.md b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/avoid-colorblindness-issues-by-carefully-choosing-colors-that-convey-information.md new file mode 100644 index 00000000000000..8ea62298f8a7da --- /dev/null +++ b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/avoid-colorblindness-issues-by-carefully-choosing-colors-that-convey-information.md @@ -0,0 +1,74 @@ +--- +id: 587d778f367417b2b2512aad +title: >- + Vermeidung von Problemen mit Farbenblindheit durch sorgfältige Auswahl von Farben, die Informationen vermitteln +challengeType: 0 +videoUrl: 'https://scrimba.com/c/c437as3' +forumTopicId: 301011 +dashedName: >- + avoid-colorblindness-issues-by-carefully-choosing-colors-that-convey-information +--- + +# --description-- + +Es gibt verschiedene Formen der Farbblindheit. Diese können von einer reduzierten Empfindlichkeit für eine bestimmte Wellenlänge des Lichts bis hin zur Unfähigkeit, überhaupt Farben zu sehen, reichen. Die häufigste Form ist eine reduzierte Empfindlichkeit zur Erkennung von Grüntönen. + +Zum Beispiel, wenn zwei ähnliche grüne Farben die Vorder- und Hintergrundfarbe deines Inhaltes sind, kann ein farbenblinder Benutzer diese möglicherweise nicht unterscheiden. Ähnliche Farben können auf dem Farbkreis als Nachbarn betrachtet werden, jedoch sollte diese Kombination bei der Übermittlung wichtiger Informationen vermieden werden. + +**Hinweis:** Einige Online-Farbauswahlwerkzeuge enthalten visuelle Simulationen, wie Farben für unterschiedliche Farbblindheiten angezeigt werden. Neben der Online-Kontrastprüfung, sind diese großartige Ressourcen. + +# --instructions-- + +Camper Cat testet verschiedene Stile für eine wichtige Schaltfläche, aber die gelbe (`#FFFF33`) Hintergrundfarbe `background-color` und die grüne (`#33FF33`) Textfarbe `color` sind benachbarte Farbtöne auf dem Farbkreis und für einige farbenblinde Benutzer praktisch nicht unterscheidbar. (Ihre ähnliche Helligkeit versagt auch bei der Prüfung des Kontrastverhältnisses). Ändere die Textfarbe `color` in dunkelblau (`#003366`), um beide Probleme zu lösen. + +# --hints-- + +Dein Code sollte die Textfarbe `color` für die Schaltfläche `button` in dunkelblau ändern. + +```js +assert($('button').css('color') == 'rgb(0, 51, 102)'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + +
    +

    Danger!

    +
    + + +``` + +# --solutions-- + +```html + + + + +
    +

    Danger!

    +
    + + +``` diff --git a/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/avoid-colorblindness-issues-by-using-sufficient-contrast.md b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/avoid-colorblindness-issues-by-using-sufficient-contrast.md new file mode 100644 index 00000000000000..035abbf460887d --- /dev/null +++ b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/avoid-colorblindness-issues-by-using-sufficient-contrast.md @@ -0,0 +1,84 @@ +--- +id: 587d778f367417b2b2512aac +title: Vermeide Probleme bei Farbenblindheit durch ausreichenden Kontrast +challengeType: 0 +videoUrl: 'https://scrimba.com/c/cmzMEUw' +forumTopicId: 301012 +dashedName: avoid-colorblindness-issues-by-using-sufficient-contrast +--- + +# --description-- + +Farbe ist ein großer Teil des visuellen Designs, dessen Verwendung allerdings zu zwei Problemen der Barrierefreiheit führt. Zuerst einmal sollte Farbe allein nicht als einzige Möglichkeit verwendet werden, um wichtige Informationen zu vermitteln, da Benutzer von Screenreadern diese nicht sehen werden. Zweitens müssen Vorder- und Hintergrundfarben einen ausreichenden Kontrast aufweisen, damit farbenblinde Benutzer sie unterscheiden können. + +Frühere Aufgaben behandelten Alternativtexte, um das erste Problem zu lösen. Die letzte Aufgabe führte Werkzeuge für die Kontrastprüfung ein, um gegen das zweite Problem vorzugehen. Das von den WCAG empfohlene Kontrastverhältnis von 4.5:1 gilt sowohl für die Verwendung von Farben als auch für Graustufenkombinationen. + +Farbenblinde Benutzer haben Schwierigkeiten, einige Farben von anderen zu unterscheiden, meistens geht es um Farbtöne aber manchmal auch um die Helligkeit. Du erinnerst dich vielleicht daran, dass das Kontrastverhältnis anhand der relativen Luminanz- (oder Helligkeits-) Werte der Vorder- und Hintergrundfarben berechnet wird. + +In der Praxis kann das Kontrastverhältnis von 4.5:1 durch Schattieren (Hinzufügen von Schwarz) der dunkleren Farbe und Abtönen (Hinzufügen von Weiß) der helleren Farbe erreicht werden. Dunklere Farbtöne auf dem Farbkreis gelten als Blautöne, Violett, Magenta und Rot, während hellere Farbtöne Orangen, Gelb, Grün und Blau-Grün sind. + +# --instructions-- + +Camper Cat experimentiert mit der Verwendung von Farbe für seinen Blogtext und -hintergrund, aber seine aktuelle Kombination aus einer grünlichen Hintergrundfarbe `background-color` mit kastanienbrauner Textfarbe `color` hat ein Kontrastverhältnis von 2.5:1. Da er die Farben mit der CSS-Eigenschaft `hsl()` (was für Farbton, Sättigung, Helligkeit steht) deklariert hat, kannst du die Helligkeit der Farben leicht anpassen, indem du das dritte Argument änderst. Erhöhe den Helligkeitswert der Hintergrundfarbe `background-color` von 35 % auf 55 % und verringere den Helligkeitswert der Farbe `color` von 20 % auf 15 %. Dadurch wird der Kontrast auf 5.9:1 verbessert. + +# --hints-- + +Dein Code sollte nur den Helligkeitswert für die Textfarbe `color` auf einen Wert von 15 % ändern. + +```js +assert(code.match(/color:\s*?hsl\(0,\s*?55%,\s*?15%\)/gi)); +``` + +Dein Code sollte nur den Helligkeitswert für die Hintergrundfarbe `background-color` auf einen Wert von 55% ändern. + +```js +assert(code.match(/background-color:\s*?hsl\(120,\s*?25%,\s*?55%\)/gi)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + +
    +

    Deep Thoughts with Master Camper Cat

    +
    +
    +

    A Word on the Recent Catnip Doping Scandal

    +

    The influence that catnip has on feline behavior is well-documented, and its use as an herbal supplement in competitive ninja circles remains controversial. Once again, the debate to ban the substance is brought to the public's attention after the high-profile win of Kittytron, a long-time proponent and user of the green stuff, at the Claw of Fury tournament.

    +

    As I've stated in the past, I firmly believe a true ninja's skills must come from within, with no external influences. My own catnip use shall continue as purely recreational.

    +
    + +``` + +# --solutions-- + +```html + + + + +
    +

    Deep Thoughts with Master Camper Cat

    +
    +
    +

    A Word on the Recent Catnip Doping Scandal

    +

    The influence that catnip has on feline behavior is well-documented, and its use as an herbal supplement in competitive ninja circles remains controversial. Once again, the debate to ban the substance is brought to the public's attention after the high-profile win of Kittytron, a long-time proponent and user of the green stuff, at the Claw of Fury tournament.

    +

    As I've stated in the past, I firmly believe a true ninja's skills must come from within, with no external influences. My own catnip use shall continue as purely recreational.

    +
    + +``` diff --git a/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/give-links-meaning-by-using-descriptive-link-text.md b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/give-links-meaning-by-using-descriptive-link-text.md new file mode 100644 index 00000000000000..af7364f66d4dc1 --- /dev/null +++ b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/give-links-meaning-by-using-descriptive-link-text.md @@ -0,0 +1,75 @@ +--- +id: 587d778f367417b2b2512aae +title: Gib Links eine Bedeutung durch die Verwendung von aussagekräftigem Linktext +challengeType: 0 +videoUrl: 'https://scrimba.com/c/c437DcV' +forumTopicId: 301013 +dashedName: give-links-meaning-by-using-descriptive-link-text +--- + +# --description-- + +Benutzer von Screenreadern haben verschiedene Möglichkeiten, welche Art von Inhalten ihr Gerät liest. Zu diesen Optionen gehören das Springen zu (oder über) markante Elemente, das Springen zum Hauptinhalt oder das Abrufen einer Seitenübersicht aus den Überschriften. Eine andere Option ist es, nur die verfügbaren Links einer Seite zu hören. + +Screenreader tun dies, indem sie den Linktext lesen, oder das, was zwischen den Anchor-Tags (`a`) steht. Eine Liste mit "Hier klicken"- oder "Mehr lesen"-Links ist nicht hilfreich. Verwende stattdessen kurzen, aber beschreibenden Text innerhalb der `a`-Tags, um diesen Benutzern mehr zu vermitteln. + +# --instructions-- + +Der Linktext, den Camper Cat benutzt ist nicht sehr aussagekräftig ohne den ihn umgebenden Kontext. Verschiebe die Anchor-Tags (`a`) so, dass sie den Text `information about batteries` umschließen, anstatt `Click here`. + +# --hints-- + +Dein Code sollte die Anchor-Tags `a` um die Wörter `Click here` versetzen, so dass sie die Wörter `information about batteries` umschliessen. + +```js +assert( + $('a') + .text() + .match(/^(information about batteries)$/g) +); +``` + +Das `a` Element sollte ein `href` Attribut mit dem Wert eines leeren Strings `""` haben. + +```js +assert($('a').attr('href') === ''); +``` + +Das `a` Element sollte ein schliessendes Tag haben. + +```js +assert( + code.match(/<\/a>/g) && + code.match(/<\/a>/g).length === code.match(//g).length +); +``` + +# --seed-- + +## --seed-contents-- + +```html + +
    +

    Deep Thoughts with Master Camper Cat

    +
    +
    + +``` + +# --solutions-- + +```html + +
    +

    Deep Thoughts with Master Camper Cat

    +
    +
    +

    Defeating your Foe: the Red Dot is Ours!

    +

    Felines the world over have been waging war on the most persistent of foes. This red nemesis combines both cunning stealth and lightning speed. But chin up, fellow fighters, our time for victory may soon be near. Click here for information about batteries

    +
    + +``` diff --git a/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/improve-accessibility-of-audio-content-with-the-audio-element.md b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/improve-accessibility-of-audio-content-with-the-audio-element.md new file mode 100644 index 00000000000000..0705b16d038b1b --- /dev/null +++ b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/improve-accessibility-of-audio-content-with-the-audio-element.md @@ -0,0 +1,115 @@ +--- +id: 587d7789367417b2b2512aa4 +title: Verbessere den Zugriff auf Audio-Inhalte mit dem Audio-Element +challengeType: 0 +videoUrl: 'https://scrimba.com/c/cVJVkcZ' +forumTopicId: 301014 +dashedName: improve-accessibility-of-audio-content-with-the-audio-element +--- + +# --description-- + +Das `audio`-Element von HTML5 sorgt für eine semantische Bedeutung, wenn es Sound- oder Audio-Stream-Inhalte in dein Markup einbettet. Audioinhalte benötigen auch eine Textalternative, um für gehörlose oder schwerhörige Menschen zugänglich zu sein. Dies kann mit nahegelegenem Text auf der Seite oder einem Link zu einem Transkript geschehen. + +Das `audio`-Tag unterstützt das `controls`-Attribut. Dies zeigt die Standard-Wiedergabe-, Pause- und andere Steuerelemente des Browsers an und unterstützt die Tastaturfunktionalität. Dies ist ein boolesches Attribut, d. h. es benötigt keinen Wert, sein Vorhandensein im Tag schaltet die Einstellung ein. + +Hier ist ein Beispiel: + +```html + +``` + +**Hinweis:** Multimediainhalte haben in der Regel sowohl visuelle als auch auditive Komponenten. Sie benötigt synchronisierte Untertitel und ein Transkript, damit Benutzer mit Seh- und/oder Hörbehinderungen darauf zugreifen können. Im Allgemeinen ist ein Webentwickler nicht für die Erstellung der Untertitel oder des Transkripts verantwortlich, muss aber wissen, wie er sie einfügen kann. + +# --instructions-- + +Zeit, eine Pause von Camper Cat zu machen und seinen Kollegen Zersiax (@zersiax) zu treffen, einen Meister der Barrierefreiheit und einen Screenreader-Nutzer. Um einen Clip seines Screenreaders in Aktion zu hören, füge ein `audio`-Element nach dem `p`-Tag ein. Füge das `controls`-Attribut hinzu. Dann platziere einen `source`-Tag innerhalb der `audio`-Tags, wobei das `src`-Attribut auf `https://s3.amazonaws.com/freecodecamp/screen-reader.mp3` und das `type`-Attribut auf `"audio/mpeg"` gesetzt ist. + +**Hinweis:** Der Audioclip klingt vielleicht schnell und ist schwer verständlich, aber das ist eine normale Geschwindigkeit für Benutzer von Screenreadern. + +# --hints-- + +Dein Code sollte ein `audio`-Tag haben. + +```js +assert($('audio').length === 1); +``` + +Dein `audio`-Element sollte einen schließenden Tag haben. + +```js +assert( + code.match(/<\/audio>/g).length === 1 && + code.match(/[\s\S]*<\/audio>/g) +); +``` + +Das `audio`-Tag sollte das `controls`-Attribut haben. + +```js +assert($('audio').attr('controls')); +``` + +Dein Code sollte ein `source`-Tag haben. + +```js +assert($('source').length === 1); +``` + +Dein `source`-Tag sollte sich innerhalb der `audio`-Tags befinden. + +```js +assert($('audio').children('source').length === 1); +``` + +Der Wert für das `src`-Attribut im `source`-Tag sollte genau mit dem Link in der Anleitung übereinstimmen. + +```js +assert( + $('source').attr('src') === + 'https://s3.amazonaws.com/freecodecamp/screen-reader.mp3' +); +``` + +Dein Code sollte ein `type`-Attribut im `source`-Tag mit einem Wert von audio/mpeg enthalten. + +```js +assert($('source').attr('type') === 'audio/mpeg'); +``` + +# --seed-- + +## --seed-contents-- + +```html + +
    +

    Real Coding Ninjas

    +
    +
    +

    A sound clip of Zersiax's screen reader in action.

    + + + +
    + +``` + +# --solutions-- + +```html + +
    +

    Real Coding Ninjas

    +
    +
    +

    A sound clip of Zersiax's screen reader in action.

    + +
    + +``` diff --git a/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/improve-chart-accessibility-with-the-figure-element.md b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/improve-chart-accessibility-with-the-figure-element.md new file mode 100644 index 00000000000000..3e5977952ffeb7 --- /dev/null +++ b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/improve-chart-accessibility-with-the-figure-element.md @@ -0,0 +1,161 @@ +--- +id: 587d778a367417b2b2512aa5 +title: Verbessere den Zugriff auf Diagramme mit dem Figure-Element +challengeType: 0 +videoUrl: 'https://scrimba.com/c/cGJMqtE' +forumTopicId: 301015 +dashedName: improve-chart-accessibility-with-the-figure-element +--- + +# --description-- + +Mit HTML5 wurde das `figure`-Element und das zugehörige `figcaption` eingeführt. Zusammen verwendet, umschließen diese Elemente eine visuelle Darstellung (wie ein Bild, ein Diagramm oder eine Tabelle) zusammen mit ihrer Beschriftung. Durch das Zusammenfassen dieser Elemente wird der Zugriff auf den Inhalt in zweifacher Hinsicht verbessert, da zusammengehörige Inhalte semantisch gruppiert werden und eine Textalternative zur Erläuterung der Abbildung `figure` bereitgestellt wird. + +Bei Visualisierungen von Daten, wie z. B. Diagrammen, kann die Beschriftung verwendet werden, um die Trends oder Schlussfolgerungen für Benutzer mit Sehbehinderungen kurz zu erwähnen. Eine weitere Herausforderung besteht darin, wie man eine tabellarische Version der Daten des Diagramms für Screenreader-Benutzer außerhalb des Bildschirms darstellen kann (mit CSS). + +Hier ist ein Beispiel - beachte, dass das `figcaption`-Element innerhalb des `figure`-Tags steht und mit anderen Elementen kombiniert werden kann: + +```html +
    + Photo of Camper Cat executing a roundhouse kick +
    +
    + Master Camper Cat demonstrates proper form of a roundhouse kick. +
    +
    +``` + +# --instructions-- + +Camper Cat arbeitet hart daran, ein gestapeltes Säulendiagramm zu erstellen, das zeigt, wie viel Zeit pro Woche für das Training in Tarnung, Kampf und Waffen aufgewendet werden muss. Hilf ihm, seine Seite besser zu strukturieren, indem du das `div`-Tag, das er verwendet hat, in ein `figure`-Tag und das `p`-Tag, das die Überschrift umgibt, in ein `figcaption`-Tag änderst. + +# --hints-- + +Dein Code sollte ein `figure` Tag haben. + +```js +assert($('figure').length == 1); +``` + +Dein Code sollte ein `figcaption` Tag haben. + +```js +assert($('figcaption').length == 1); +``` + +Dein Code sollte keine `div` Tags haben. + +```js +assert($('div').length == 0); +``` + +Dein Code sollte keine `p` Tags haben. + +```js +assert($('p').length == 0); +``` + +Die `figcaption`-Element sollte ein Kindelement des `figure`-Tags sein. + +```js +assert($('figure').children('figcaption').length == 1); +``` + +Dein `figure`-Element sollte ein schließendes Tag haben. + +```js +assert( + code.match(/<\/figure>/g) && + code.match(/<\/figure>/g).length === code.match(/
    /g).length +); +``` + +# --seed-- + +## --seed-contents-- + +```html + +
    +

    Training

    + +
    +
    +
    + + +
    + +
    +

    Breakdown per week of time to spend training in stealth, combat, and weapons.

    +
    + + +
    +
    +

    Stealth & Agility Training

    +

    Climb foliage quickly using a minimum spanning tree approach

    +

    No training is NP-complete without parkour

    +
    +
    +

    Combat Training

    +

    Dispatch multiple enemies with multithreaded tactics

    +

    Goodbye world: 5 proven ways to knock out an opponent

    +
    +
    +

    Weapons Training

    +

    Swords: the best tool to literally divide and conquer

    +

    Breadth-first or depth-first in multi-weapon training?

    +
    +
    +
    © 2018 Camper Cat
    + +``` + +# --solutions-- + +```html + +
    +

    Training

    + +
    +
    +
    +
    + +
    +
    Breakdown per week of time to spend training in stealth, combat, and weapons.
    +
    +
    +
    +

    Stealth & Agility Training

    +

    Climb foliage quickly using a minimum spanning tree approach

    +

    No training is NP-complete without parkour

    +
    +
    +

    Combat Training

    +

    Dispatch multiple enemies with multithreaded tactics

    +

    Goodbye world: 5 proven ways to knock out an opponent

    +
    +
    +

    Weapons Training

    +

    Swords: the best tool to literally divide and conquer

    +

    Breadth-first or depth-first in multi-weapon training?

    +
    +
    +
    © 2018 Camper Cat
    + +``` diff --git a/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/improve-form-field-accessibility-with-the-label-element.md b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/improve-form-field-accessibility-with-the-label-element.md new file mode 100644 index 00000000000000..59529f6d198ecd --- /dev/null +++ b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/improve-form-field-accessibility-with-the-label-element.md @@ -0,0 +1,119 @@ +--- +id: 587d778a367417b2b2512aa6 +title: Verbessere die Zugänglichkeit von Formularfeldern mit der Bezeichnung Element +challengeType: 0 +videoUrl: 'https://scrimba.com/c/cGJMMAN' +forumTopicId: 301016 +dashedName: improve-form-field-accessibility-with-the-label-element +--- + +# --description-- + +Die Verbesserung der Barrierefreiheit mit semantischem HTML-Markup bezieht sich sowohl auf die Verwendung geeigneter Tag-Namen als auch Attribute. Die nächsten Aufgaben decken einige wichtige Szenarien mithilfe von Attributen in Formularen ab. + +Das `label`-Tag umschließt den Text für ein bestimmtes Formularsteuerelement, normalerweise den Namen oder die Bezeichnung für eine Auswahl. Dies bindet die Bedeutung an das Element und macht das Formular lesbarer. Das `for`-Attribut auf einem `label`-Tag verknüpft dieses `label` explizit mit dem Formularsteuerelement und wird von Screenreadern verwendet. + +In einer Lektion im Bereich Basic HTML hast du etwas über Optionsfelder und deren Labels gelernt. In der Lektion haben wir die Optionsfelder in ein `label` Element mit einem Lable Text gesetzt um diesen Text anklickbar zu machen. Eine andere Möglichkeit, dies zu erreichen, ist die Verwendung des `for`-Attributs, wie es in dieser Lektion erklärt wird. + +Der Wert des `for`-Attributs muss mit dem Wert des `id`-Attributs des Formularsteuerelements übereinstimmen. Hier ist ein Beispiel: + +```html +
    + + +
    +``` + +# --instructions-- + +Camper Cat erwartet ein großes Interesse an seinen durchdachten Blogbeiträgen und möchte ein E-Mail-Anmeldeformular einbauen. Füge ein `for`-Attribut auf dem E-Mail-`label` hinzu, das mit der `id` auf seinem `input`-Feld übereinstimmt. + +# --hints-- + +Dein Code sollte ein `for` Attribut am `label` Tag haben, das nicht leer ist. + +```js +assert($('label').attr('for')); +``` + +Dein `for` Attributwert sollte mit dem `id` Wert in der E-mail `input` übereinstimmen. + +```js +assert($('label').attr('for') == 'email'); +``` + +# --seed-- + +## --seed-contents-- + +```html + +
    +

    Deep Thoughts with Master Camper Cat

    +
    +
    +
    +

    Sign up to receive Camper Cat's blog posts by email here!

    + + + + + + + +
    +
    +
    +

    The Garfield Files: Lasagna as Training Fuel?

    +

    The internet is littered with varying opinions on nutritional paradigms, from catnip paleo to hairball cleanses. But let's turn our attention to an often overlooked fitness fuel, and examine the protein-carb-NOM trifecta that is lasagna...

    +
    + +
    +

    Defeating your Foe: the Red Dot is Ours!

    +

    Felines the world over have been waging war on the most persistent of foes. This red nemesis combines both cunning stealth and lightning speed. But chin up, fellow fighters, our time for victory may soon be near...

    +
    + +
    +

    Is Chuck Norris a Cat Person?

    +

    Chuck Norris is widely regarded as the premier martial artist on the planet, and it's a complete coincidence that anyone who disagrees with this fact mysteriously disappears soon after. But the real question is, is he a cat person?...

    +
    +
    © 2018 Camper Cat
    + +``` + +# --solutions-- + +```html + +
    +

    Deep Thoughts with Master Camper Cat

    +
    +
    +
    +

    Sign up to receive Camper Cat's blog posts by email here!

    + + + + + + + +
    +
    +
    +

    The Garfield Files: Lasagna as Training Fuel?

    +

    The internet is littered with varying opinions on nutritional paradigms, from catnip paleo to hairball cleanses. But let's turn our attention to an often overlooked fitness fuel, and examine the protein-carb-NOM trifecta that is lasagna...

    +
    + +
    +

    Defeating your Foe: the Red Dot is Ours!

    +

    Felines the world over have been waging war on the most persistent of foes. This red nemesis combines both cunning stealth and lightning speed. But chin up, fellow fighters, our time for victory may soon be near...

    +
    + +
    +

    Is Chuck Norris a Cat Person?

    +

    Chuck Norris is widely regarded as the premier martial artist on the planet, and it's a complete coincidence that anyone who disagrees with this fact mysteriously disappears soon after. But the real question is, is he a cat person?...

    +
    +
    © 2018 Camper Cat
    + +``` diff --git a/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/improve-readability-with-high-contrast-text.md b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/improve-readability-with-high-contrast-text.md new file mode 100644 index 00000000000000..232a1733798d28 --- /dev/null +++ b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/improve-readability-with-high-contrast-text.md @@ -0,0 +1,80 @@ +--- +id: 587d778e367417b2b2512aab +title: Verbessere Lesbarkeit mit kontrastreichem Text +challengeType: 0 +videoUrl: 'https://scrimba.com/c/cKb3nCq' +forumTopicId: 301017 +dashedName: improve-readability-with-high-contrast-text +--- + +# --description-- + +Ein geringer Kontrast zwischen der Vorder- und Hintergrundfarbe kann die Lesbarkeit von Text erschweren. Ein ausreichender Kontrast verbessert die Lesbarkeit deiner Inhalte, aber was genau bedeutet "ausreichend"? + +Die Web Content Accessibility Guidelines (WCAG) empfehlen mindestens ein Kontrastverhältnis von 4,5 zu 1 für einen normalen Text. Das Verhältnis wird durch den Vergleich der relativen Leuchtdichtewerte zweier Farben berechnet. Dieser reicht von 1:1 für die gleiche Farbe, also kein Kontrast, bis zu 21:1 für Weiß gegen Schwarz, dem stärksten Kontrast. Im Internet kannst du viele Rechner zum Bestimmen deiner Kontrastverhältnisse finden. + +# --instructions-- + +Camper Cat benutzt eine hellgraue Farbe für seinen Text auf weißem Hintergrund, was zu einem 1,5:1 Kontrastverhältnis führt, wodurch das Lesen erschwert ist. Ändere die Textfarbe `color` von dem aktuellen Grau (`#D3D3D3`) in ein dunkleres Grau (`#636363`), um das Kontrastverhältnis auf 6:1 zu verbessern. + +# --hints-- + +Dein Code sollte die Textfarbe `color` für den `body` auf das dunklere Grau ändern. + +```js +assert($('body').css('color') == 'rgb(99, 99, 99)'); +``` + +Dein Code sollte die Hintergrundfarbe `background-color` für den `body` nicht ändern. + +```js +assert($('body').css('background-color') == 'rgb(255, 255, 255)'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + +
    +

    Deep Thoughts with Master Camper Cat

    +
    +
    +

    A Word on the Recent Catnip Doping Scandal

    +

    The influence that catnip has on feline behavior is well-documented, and its use as an herbal supplement in competitive ninja circles remains controversial. Once again, the debate to ban the substance is brought to the public's attention after the high-profile win of Kittytron, a long-time proponent and user of the green stuff, at the Claw of Fury tournament.

    +

    As I've stated in the past, I firmly believe a true ninja's skills must come from within, with no external influences. My own catnip use shall continue as purely recreational.

    +
    + +``` + +# --solutions-- + +```html + + + + +
    +

    Deep Thoughts with Master Camper Cat

    +
    +
    +

    A Word on the Recent Catnip Doping Scandal

    +

    The influence that catnip has on feline behavior is well-documented, and its use as an herbal supplement in competitive ninja circles remains controversial. Once again, the debate to ban the substance is brought to the public's attention after the high-profile win of Kittytron, a long-time proponent and user of the green stuff, at the Claw of Fury tournament.

    +

    As I've stated in the past, I firmly believe a true ninja's skills must come from within, with no external influences. My own catnip use shall continue as purely recreational.

    +
    + +``` diff --git a/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/jump-straight-to-the-content-using-the-main-element.md b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/jump-straight-to-the-content-using-the-main-element.md new file mode 100644 index 00000000000000..23c995a49daf5b --- /dev/null +++ b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/jump-straight-to-the-content-using-the-main-element.md @@ -0,0 +1,62 @@ +--- +id: 587d774e367417b2b2512a9f +title: Springe mit Hilfe des main Elements direkt zum Inhalt +challengeType: 0 +videoUrl: 'https://scrimba.com/c/cPp7zuE' +forumTopicId: 301018 +dashedName: jump-straight-to-the-content-using-the-main-element +--- + +# --description-- + +Mit HTML5 wurden mehrere neue Elemente eingeführt, die Entwicklern mehr Möglichkeiten bieten und gleichzeitig Funktionen zur Barrierefreiheit enthalten. Zu diesen Tags gehören unter anderem `main`, `header`, `footer`, `nav`, `article` und `section`. + +Standardmäßig rendert ein Browser diese Elemente ähnlich wie das einfache `div`. Wenn du sie jedoch an geeigneter Stelle verwendest, verleiht das deinem Markup zusätzliche Bedeutung. Der Tag-Name allein kann schon auf die Art der darin enthaltenen Informationen hinweisen, was dem Inhalt eine semantische Bedeutung verleiht. Unterstützende Technologien können auf diese Informationen zugreifen, um ihren Benutzern eine bessere Seitenübersicht oder Navigationsoptionen zu bieten. + +Das `main`-Element wird verwendet, um (du hast es erraten) den Hauptinhalt zu umschließen, und es sollte nur eines pro Seite geben. Es soll die Informationen umfassen, die sich auf das zentrale Thema deiner Seite beziehen. Es soll keine Elemente enthalten, die sich über Seiten hinweg wiederholen, wie Navigationslinks oder Banner. + +Der `main`-Tag hat auch eine eingebettete Landmark-Funktion, die unterstützende Technologien verwenden können, um schnell zum Hauptinhalt zu navigieren. Wenn du jemals einen Link "Zum Hauptinhalt springen" am Anfang einer Seite gesehen hast, gibt die Verwendung des `main`-Tags unterstützenden Hilfsmitteln automatisch diese Funktionalität. + +# --instructions-- + +Camper Cat hat ein paar große Ideen für seine Seite über Ninjawaffen. Hilf ihm, sein Markup einzurichten, indem du öffnende und schließende `main`-Tags zwischen dem `header` und dem `footer` einfügst (Wird in anderen Herausforderungen behandelt). Lass die `main` Tags vorerst leer. + +# --hints-- + +Dein Code sollte ein `main` Tag haben. + +```js +assert($('main').length == 1); +``` + +Die `main` Tags sollten zwischen dem schließenden `header` Tag und dem öffnendem `footer` Tag sein. + +```js +assert(code.match(/<\/header>\s*?
    \s*?<\/main>/gi)); +``` + +# --seed-- + +## --seed-contents-- + +```html +
    +

    Weapons of the Ninja

    +
    + + + +
    +``` + +# --solutions-- + +```html +
    +

    Weapons of the Ninja

    +
    +
    + +
    +
    +``` diff --git a/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/know-when-alt-text-should-be-left-blank.md b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/know-when-alt-text-should-be-left-blank.md new file mode 100644 index 00000000000000..4e354847d59a53 --- /dev/null +++ b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/know-when-alt-text-should-be-left-blank.md @@ -0,0 +1,76 @@ +--- +id: 587d774c367417b2b2512a9d +title: Wissen, wann Alt-Text leer bleiben sollte +challengeType: 0 +videoUrl: 'https://scrimba.com/c/cM9P4t2' +forumTopicId: 301019 +dashedName: know-when-alt-text-should-be-left-blank +--- + +# --description-- + +In der letzten Herausforderung hast du gelernt, dass das Einfügen eines `alt`-Attributs bei der Verwendung von `img`-Tags obligatorisch ist. Manchmal werden Bilder jedoch mit einer Beschriftung gruppiert, die sie bereits beschreibt, oder sie werden nur zur Dekoration verwendet. In diesen Fällen kann der `alt`-Text redundant oder unnötig erscheinen. + +Wenn ein Bild bereits mit Textinhalt erklärt wird oder keine Bedeutung zu einer Seite hinzufügt, benötigt das `img` immer noch ein `alt`-Attribut, aber es kann auf einen leeren String gesetzt werden. Hier ist ein Beispiel: + +```html + +``` + +Auch Hintergrundbilder fallen in der Regel unter das Stichwort "dekorativ". Allerdings werden sie in der Regel mit CSS-Regeln angewendet und sind daher nicht Teil des Markup-Screenreader-Prozesses. + +**Hinweis:** Bei Bildern mit einer Bildunterschrift solltest du trotzdem `alt`-Text einfügen, da er Suchmaschinen hilft, den Inhalt des Bildes zu katalogisieren. + +# --instructions-- + +Camper Cat hat ein Seitengerüst für den Blog-Teil seiner Website codiert. Er plant, seine beiden Artikel mit einem dekorativen Bild eines Samuraischwertes optisch zu trennen. Füge ein `alt`-Attribut zum `img`-Tag hinzu und setze es auf einen leeren String. (Beachte, dass das Bild `src` nicht auf eine tatsächliche Datei verlinkt - mache dir keine Sorgen, dass in der Anzeige keine Schwerter zu sehen sind.) + +# --hints-- + +Dein `img`-Tag sollte ein `alt`-Attribut haben. + +```js +assert(!($('img').attr('alt') == undefined)); +``` + +Das `alt`-Attribut sollte auf einen leeren String gesetzt werden. + +```js +assert($('img').attr('alt') == ''); +``` + +# --seed-- + +## --seed-contents-- + +```html +

    Deep Thoughts with Master Camper Cat

    +
    +

    Defeating your Foe: the Red Dot is Ours!

    +

    To Come...

    +
    + + + +
    +

    Is Chuck Norris a Cat Person?

    +

    To Come...

    +
    +``` + +# --solutions-- + +```html +

    Deep Thoughts with Master Camper Cat

    +
    +

    Defeating your Foe: the Red Dot is Ours!

    +

    To Come...

    +
    + + + +
    +

    Is Chuck Norris a Cat Person?

    +

    To Come...

    +
    +``` diff --git a/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/make-elements-only-visible-to-a-screen-reader-by-using-custom-css.md b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/make-elements-only-visible-to-a-screen-reader-by-using-custom-css.md new file mode 100644 index 00000000000000..79c989fd2bf468 --- /dev/null +++ b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/make-elements-only-visible-to-a-screen-reader-by-using-custom-css.md @@ -0,0 +1,244 @@ +--- +id: 587d778d367417b2b2512aaa +title: Mache Elemente nur für einen Screenreader sichtbar, indem du selbsterstelltes CSS nutzt +challengeType: 0 +videoUrl: 'https://scrimba.com/c/cJ8QGkhJ' +forumTopicId: 301020 +dashedName: make-elements-only-visible-to-a-screen-reader-by-using-custom-css +--- + +# --description-- + +Hast du bemerkt, dass bei allen Aufgaben zur Barrierefreiheit bis jetzt kein CSS verwendet wurde? Dies zeigt, wie wichtig es ist, mit einer logischen Gliederung des Dokuments und semantisch sinnvollen, den Inhalt umfassenden Tags zu beginnen, bevor man sich um den visuellen Gestaltungsaspekt kümmert. + +Allerdings kannst du mit der Magie von CSS auch die Barrierefreiheit deiner Seite verbessern, wenn du Inhalte visuell verbergen willst, die nur für Screenreader gedacht sind. Dies ist der Fall, wenn sich Informationen in einem visuellen Format befinden (wie einem Diagramm), wohingegen Screenreader eine alternative Präsentation benötigen (wie eine Tabelle), um auf die Daten zuzugreifen. CSS wird verwendet, um die ausschließlich für Screenreader bestimmten Elemente außerhalb des sichtbaren Bereichs des Browserfensters zu positionieren. + +Hier ist ein Beispiel für die CSS-Regeln, mit denen dies erreicht wird: + +```css +.sr-only { + position: absolute; + left: -10000px; + width: 1px; + height: 1px; + top: auto; + overflow: hidden; +} +``` + +**Hinweis:** Die folgenden CSS-Ansätze werden NICHT dasselbe tun: + +
      +
    • display: none; oder visibility: hidden; verbergen Inhalte für jeden, einschließlich den Nutzern von Bildschirmleseprogrammen
    • +
    • Nullwerte für Pixelgrößen; z. B. width: 0px; height: 0px; entfernt dieses Element aus dem Fluss deines Dokuments, d. h. Screenreader werden es ignorieren
    • +
    + +# --instructions-- + +Camper Cat hat für seine Trainingsseite ein wirklich cooles gestapeltes Balkendiagramm kreiert und eine Tabelle der Daten für Sehbehinderte bereitgestellt. Die Tabelle hat bereits eine `sr-only` ("nur Screenreader") Klasse, aber die CSS-Regeln sind noch nicht ausgefüllt. Gib der `position` einen `absolute` Wert. Setze den Wert für `left` auf `-10000px` und für `width` und `height` je auf `1px`. + +# --hints-- + +Dein Code sollte die Eigenschaft `position` der `sr-only` Klasse auf einen Wert von `absolute` setzen. + +```js +assert($('.sr-only').css('position') == 'absolute'); +``` + +Dein Code sollte die Eigenschaft `left` der `sr-only` Klasse auf einen Wert von `-10000px` setzen. + +```js +assert($('.sr-only').css('left') == '-10000px'); +``` + +Dein Code sollte die Eigenschaft `width` der `sr-only` Klasse auf einen Wert von `1` Pixel setzen. + +```js +assert(code.match(/width:\s*?1px/gi)); +``` + +Dein Code sollte die Eigenschaft `height` der `sr-only` Klasse auf einen Wert von `1` Pixel setzen. + +```js +assert(code.match(/height:\s*?1px/gi)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + +
    +

    Training

    + +
    +
    +

    Master Camper Cat's Beginner Three Week Training Program

    +
    + +

    [Stacked bar chart]

    +
    +
    Breakdown per week of time to spend training in stealth, combat, and weapons.
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Hours of Weekly Training in Stealth, Combat, and Weapons
    Stealth & AgilityCombatWeaponsTotal
    Week One35210
    Week Two45312
    Week Three46313
    +
    +
    +

    Stealth & Agility Training

    +

    Climb foliage quickly using a minimum spanning tree approach

    +

    No training is NP-complete without parkour

    +
    +
    +

    Combat Training

    +

    Dispatch multiple enemies with multithreaded tactics

    +

    Goodbye, world: 5 proven ways to knock out an opponent

    +
    +
    +

    Weapons Training

    +

    Swords: the best tool to literally divide and conquer

    +

    Breadth-first or depth-first in multi-weapon training?

    +
    +
    © 2018 Camper Cat
    + +``` + +# --solutions-- + +```html + + + + +
    +

    Training

    + +
    +
    +

    Master Camper Cat's Beginner Three Week Training Program

    +
    + +

    [Stacked bar chart]

    +
    +
    Breakdown per week of time to spend training in stealth, combat, and weapons.
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Hours of Weekly Training in Stealth, Combat, and Weapons
    Stealth & AgilityCombatWeaponsTotal
    Week One35210
    Week Two45312
    Week Three46313
    +
    +
    +

    Stealth & Agility Training

    +

    Climb foliage quickly using a minimum spanning tree approach

    +

    No training is NP-complete without parkour

    +
    +
    +

    Combat Training

    +

    Dispatch multiple enemies with multithreaded tactics

    +

    Goodbye, world: 5 proven ways to knock out an opponent

    +
    +
    +

    Weapons Training

    +

    Swords: the best tool to literally divide and conquer

    +

    Breadth-first or depth-first in multi-weapon training?

    +
    +
    © 2018 Camper Cat
    + +``` diff --git a/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/make-links-navigable-with-html-access-keys.md b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/make-links-navigable-with-html-access-keys.md new file mode 100644 index 00000000000000..038de4a56f7046 --- /dev/null +++ b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/make-links-navigable-with-html-access-keys.md @@ -0,0 +1,106 @@ +--- +id: 587d7790367417b2b2512aaf +title: Links mit HTML-Tastaturkürzel navigierbar machen +challengeType: 0 +videoUrl: 'https://scrimba.com/c/cQvmaTp' +forumTopicId: 301021 +dashedName: make-links-navigable-with-html-access-keys +--- + +# --description-- + +HTML bietet die `accesskey`-Eigenschaft, um eine Shortcut-Taste zu bestimmen, die ein Element aktiviert oder in den Fokus bringt. Das Hinzufügen eines `accesskey`-Attributs kann die Navigation für Benutzer, die nur die Tastatur verwenden, effizienter machen. + +HTML5 lässt diese Eigenschaft für jedes Element zu, aber sie ist insbesondere dann nützlich, wenn man sie mit interaktiven Elementen benutzt. Dazu zählen Links, Buttons und Formularsteuerelemente. + +Hier ist ein Beispiel: + +```html + +``` + +# --instructions-- + +Camper Cat möchte, dass die Links rund um die beiden Blog-Artikel-Titel mit Tastaturkürzeln versehen werden, damit die Benutzer seiner Website schnell zur vollständigen Geschichte navigieren können. Füge ein `accesskey`-Attribut zu beiden Links hinzu und setze den ersten auf `g` (für Garfield) und den zweiten auf `c` (für Chuck Norris). + +# --hints-- + +Dein Code sollte ein `accesskey`-Attribut zum `a`-Tag mit der `id` von `first` hinzufügen. + +```js +assert($('#first').attr('accesskey')); +``` + +Dein Code sollte ein `accesskey`-Attribut zum `a`-Tag mit der `id` von `second` hinzufügen. + +```js +assert($('#second').attr('accesskey')); +``` + +Dein Code sollte das `accesskey`-Attribut auf dem `a`-Tag mit der `id` von `first` auf `g` setzen. Beachte, dass die Groß-/Kleinschreibung eine Rolle spielt. + +```js +assert($('#first').attr('accesskey') == 'g'); +``` + +Dein Code sollte das `accesskey`-Attribut auf dem `a`-Tag mit der `id` von `second` auf `c` setzen. Beachte, dass die Groß-/Kleinschreibung eine Rolle spielt. + +```js +assert($('#second').attr('accesskey') == 'c'); +``` + +# --seed-- + +## --seed-contents-- + +```html + +
    +

    Deep Thoughts with Master Camper Cat

    +
    +
    + + +

    The Garfield Files: Lasagna as Training Fuel?

    + + +

    The internet is littered with varying opinions on nutritional paradigms, from catnip paleo to hairball cleanses. But let's turn our attention to an often overlooked fitness fuel, and examine the protein-carb-NOM trifecta that is lasagna...

    +
    +
    + + +

    Is Chuck Norris a Cat Person?

    + + +

    Chuck Norris is widely regarded as the premier martial artist on the planet, and it's a complete coincidence that anyone who disagrees with this fact mysteriously disappears soon after. But the real question is, is he a cat person?...

    +
    +
    © 2018 Camper Cat
    + +``` + +# --solutions-- + +```html + +
    +

    Deep Thoughts with Master Camper Cat

    +
    +
    + + +

    The Garfield Files: Lasagna as Training Fuel?

    + + +

    The internet is littered with varying opinions on nutritional paradigms, from catnip paleo to hairball cleanses. But let's turn our attention to an often overlooked fitness fuel, and examine the protein-carb-NOM trifecta that is lasagna...

    +
    +
    + + +

    Is Chuck Norris a Cat Person?

    + + +

    Chuck Norris is widely regarded as the premier martial artist on the planet, and it's a complete coincidence that anyone who disagrees with this fact mysteriously disappears soon after. But the real question is, is he a cat person?...

    +
    +
    © 2018 Camper Cat
    + +``` diff --git a/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-footer-landmark.md b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-footer-landmark.md new file mode 100644 index 00000000000000..4a8774f0d33c0c --- /dev/null +++ b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-footer-landmark.md @@ -0,0 +1,116 @@ +--- +id: 587d7788367417b2b2512aa3 +title: Vereinfache Screenreader-Navigation mit der Grenzrolle eines Footer-Elements +challengeType: 0 +videoUrl: 'https://scrimba.com/c/crVrDh8' +forumTopicId: 301022 +dashedName: make-screen-reader-navigation-easier-with-the-footer-landmark +--- + +# --description-- + +Ähnlich wie `header` und `nav`, verfügt das Element `footer` über eine Grenzrolle, mit der Hilfsmittel schnell dorthin navigieren können. In erster Linie wird das Footer-Tag für urheberrechtliche Informationen oder weiterführende Links verwendet, die normalerweise am Ende einer Seite zu finden sind. + +# --instructions-- + +Die Übungsseite von Camper Cat macht gute Fortschritte. Ändere das `div`-Element, mit dem er seine Copyright-Information am Ende der Seite einbindet, in das neue `footer`-Element. + +# --hints-- + +Dein Code sollte ein `footer`-Tag enthalten. + +```js +assert($('footer').length == 1); +``` + +Dein Code sollte keine `div`-Tags enthalten. + +```js +assert($('div').length == 0); +``` + +Dein Code sollte ein öffnendes und schließendes `footer`-Tag enthalten. + +```js +assert(code.match(/
    \s*© 2018 Camper Cat\s*<\/footer>/g)); +``` + +# --seed-- + +## --seed-contents-- + +```html + +
    +

    Training

    + +
    +
    +
    +

    Stealth & Agility Training

    +

    Climb foliage quickly using a minimum spanning tree approach

    +

    No training is NP-complete without parkour

    +
    +
    +

    Combat Training

    +

    Dispatch multiple enemies with multithreaded tactics

    +

    Goodbye world: 5 proven ways to knock out an opponent

    +
    +
    +

    Weapons Training

    +

    Swords: the best tool to literally divide and conquer

    +

    Breadth-first or depth-first in multi-weapon training?

    +
    +
    + + +
    © 2018 Camper Cat
    + + + +``` + +# --solutions-- + +```html + +
    +

    Training

    + +
    +
    +
    +

    Stealth & Agility Training

    +

    Climb foliage quickly using a minimum spanning tree approach

    +

    No training is NP-complete without parkour

    +
    +
    +

    Combat Training

    +

    Dispatch multiple enemies with multithreaded tactics

    +

    Goodbye world: 5 proven ways to knock out an opponent

    +
    +
    +

    Weapons Training

    +

    Swords: the best tool to literally divide and conquer

    +

    Breadth-first or depth-first in multi-weapon training?

    +
    +
    + + +
    © 2018 Camper Cat
    + + + +``` diff --git a/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-header-landmark.md b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-header-landmark.md new file mode 100644 index 00000000000000..8fcc4f857640e8 --- /dev/null +++ b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-header-landmark.md @@ -0,0 +1,111 @@ +--- +id: 587d7787367417b2b2512aa1 +title: Vereinfache Screenreader-Navigation mit der Grenzrolle eines Header-Elements +challengeType: 0 +videoUrl: 'https://scrimba.com/c/cB76vtv' +forumTopicId: 301023 +dashedName: make-screen-reader-navigation-easier-with-the-header-landmark +--- + +# --description-- + +Das nächste HTML5-Element das semantische Aussagekraft verleiht und der Barrierefreiheit dient, ist das `header`-Tag (engl. "Kopfzeile"). Es wird verwendet, um einleitende Informationen oder Navigationslinks für sein übergeordnetes Tag zusammenzufassen und eignet sich gut für Inhalte, die auf mehreren Seiten oben wiederholt werden. + +`header` hat ebenfalls eine inhärente Grenzrolle, wie du das bereits von `main` kennst und erlaubt assistiven Technologien schnell zu diesem Inhalt zu navigieren. + +**Hinweis:** Der `header` ist für den `body` des HTML-Dokuments vorgesehen. Er unterscheidet sich vom `head`-Element, welches den Seitentitel, Metainformationen, etc. beinhaltet. + +# --instructions-- + +Camper Cat schreibt einige großartige Artikel über Ninja-Training und möchte eine Seite für sie zu seiner Website hinzufügen. Ändere das obere `div`, welches im Moment das `h1`-Element beinhaltet, in ein `header`-Tag. + +# --hints-- + +Dein Code sollte ein `header`-Tag beinhalten. + +```js +assert($('header').length == 1); +``` + +Dein `header`-Tag sollte das `h1`-Element umfassen. + +```js +assert($('header').children('h1').length == 1); +``` + +Dein Code sollte keine `div`-Tags enthalten. + +```js +assert($('div').length == 0); +``` + +Dein `header`-Element sollte ein schließendes Tag haben. + +```js +assert( + code.match(/<\/header>/g) && + code.match(/<\/header>/g).length === code.match(/
    /g).length +); +``` + +# --seed-- + +## --seed-contents-- + +```html + + +
    +

    Training with Camper Cat

    +
    + + +
    +
    +

    Stealth & Agility Training

    +

    Climb foliage quickly using a minimum spanning tree approach

    +

    No training is NP-complete without parkour

    +
    +
    +

    Combat Training

    +

    Dispatch multiple enemies with multithreaded tactics

    +

    Goodbye world: 5 proven ways to knock out an opponent

    +
    +
    +

    Weapons Training

    +

    Swords: the best tool to literally divide and conquer

    +

    Breadth-first or depth-first in multi-weapon training?

    +
    +
    + +``` + +# --solutions-- + +```html + + +
    +

    Training with Camper Cat

    +
    + + +
    +
    +

    Stealth & Agility Training

    +

    Climb foliage quickly using a minimum spanning tree approach

    +

    No training is NP-complete without parkour

    +
    +
    +

    Combat Training

    +

    Dispatch multiple enemies with multithreaded tactics

    +

    Goodbye world: 5 proven ways to knock out an opponent

    +
    +
    +

    Weapons Training

    +

    Swords: the best tool to literally divide and conquer

    +

    Breadth-first or depth-first in multi-weapon training?

    +
    +
    + +``` diff --git a/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-nav-landmark.md b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-nav-landmark.md new file mode 100644 index 00000000000000..cf130ee275eb80 --- /dev/null +++ b/curriculum/challenges/german/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-nav-landmark.md @@ -0,0 +1,121 @@ +--- +id: 587d7788367417b2b2512aa2 +title: Vereinfache Screenreader-Navigation mit der Grenzrolle eines Nav-Elements +challengeType: 0 +videoUrl: 'https://scrimba.com/c/czVwWSv' +forumTopicId: 301024 +dashedName: make-screen-reader-navigation-easier-with-the-nav-landmark +--- + +# --description-- + +Das `nav`-Element ist ein weiteres HTML5-Element mit inhärenter Grenzrolle zur einfacheren Navigation per Screenreader. Dieses Tag soll die wichtigsten Navigationslinks auf deiner Seite umfassen. + +Wenn Links sich am Ende der Seite wiederholen, ist es unnötig, diese auch mit einem `nav`-Tag zu markieren. Die Verwendung eines `footer` (wird in der nächsten Aufgabe behandelt) genügt. + +# --instructions-- + +Camper Cat fügte Navigationslinks oben auf seiner Trainingsseite hinzu, umgab sie aber mit einem `div`. Ändere das `div` in ein `nav`-Tag, um die Barrierefreiheit auf seiner Seite zu verbessern. + +# --hints-- + +Dein Code sollte ein `nav`-Tag enthalten. + +```js +assert($('nav').length == 1); +``` + +Deine `nav`-Tags sollten die `ul` und deren Listenelemente umhüllen. + +```js +assert($('nav').children('ul').length == 1); +``` + +Dein Code sollte keine `div`-Tags mehr enthalten. + +```js +assert($('div').length == 0); +``` + +Dein `nav`-Element sollte ein schließendes Tag haben. + +```js +assert( + code.match(/<\/nav>/g) && + code.match(/<\/nav>/g).length === code.match(/
    +``` + +# --solutions-- + +```html + + + + + + + +
    +

    CatPhotoApp

    + +

    Click here for cat photos.

    + + A cute orange cat lying on its back. + + Three kittens running towards the camera. + + + + +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + + + + + + + +
    +
    + +``` diff --git a/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/create-a-bootstrap-headline.md b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/create-a-bootstrap-headline.md new file mode 100644 index 00000000000000..88d19a7dcb6b3f --- /dev/null +++ b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/create-a-bootstrap-headline.md @@ -0,0 +1,67 @@ +--- +id: bad87fee1348bd9aec908846 +title: Erstelle eine Bootstrap-Überschrift +challengeType: 0 +forumTopicId: 16812 +dashedName: create-a-bootstrap-headline +--- + +# --description-- + +Lasst uns jetzt etwas von Grund auf neu bauen, um unsere HTML-, CSS- und Bootstrap-Kenntnisse zu verbessern. + +Wir werden einen jQuery-Playground bauen, den wir dann in unseren jQuery-Aufgaben verwenden werden. + +Erstelle für den Anfang ein `h3`-Element mit dem Text `jQuery Playground`. + +Gib deinem `h3`-Element mit der `text-primary` Bootstrap-Klasse eine Farbe und zentriere es mit der `text-center` Bootstrap-Klasse. + +# --hints-- + +Du solltest deiner Seite ein `h3`-Element hinzufügen. + +```js +assert($('h3') && $('h3').length > 0); +``` + +Dein `h3`-Element sollte ein abschließendes Tag enthalten. + +```js +assert( + code.match(/<\/h3>/g) && + code.match(/

    /g).length === code.match(/

    jQuery Playground

    +``` diff --git a/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/create-a-bootstrap-row.md b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/create-a-bootstrap-row.md new file mode 100644 index 00000000000000..04109735935990 --- /dev/null +++ b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/create-a-bootstrap-row.md @@ -0,0 +1,68 @@ +--- +id: bad87fee1348bd9bec908846 +title: Erstelle eine Bootstrap Zeile +challengeType: 0 +forumTopicId: 16813 +dashedName: create-a-bootstrap-row +--- + +# --description-- + +Jetzt erstellen wir eine Bootstrap Zeile für unsere Inline-Elemente. + +Erstelle ein `div` Element unter dem `h3` Tag mit der Klasse `row`. + +# --hints-- + +Du solltest ein `div` Element unter deinem `h3` Element hinzufügen. + +```js +assert( + $('div').length > 1 && + $('div.row h3.text-primary').length == 0 && + $('div.row + h3.text-primary').length == 0 && + $('h3.text-primary + div.row').length > 0 +); +``` + +Dein `div` Element soll die Klasse `row` haben + +```js +assert($('div').hasClass('row')); +``` + +Dein `row div` soll innerhalb des `container-fluid div` verschachtelt sein + +```js +assert($('div.container-fluid div.row').length > 0); +``` + +Dein `div` Element sollte einen abschließenden Tag haben. + +```js +assert( + code.match(/<\/div>/g) && + code.match(/
    /g).length === code.match(/
    +

    jQuery Playground

    + +
    +``` + +# --solutions-- + +```html +
    +

    jQuery Playground

    +
    +
    +``` diff --git a/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/create-a-class-to-target-with-jquery-selectors.md b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/create-a-class-to-target-with-jquery-selectors.md new file mode 100644 index 00000000000000..9668a8513f4721 --- /dev/null +++ b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/create-a-class-to-target-with-jquery-selectors.md @@ -0,0 +1,71 @@ +--- +id: bad87fee1348bd9aec908852 +title: Erstellen Sie eine Zielklasse mit jQuery-Selektoren +challengeType: 0 +forumTopicId: 16815 +dashedName: create-a-class-to-target-with-jquery-selectors +--- + +# --description-- + +Nicht jede Klasse muss ein entsprechendes CSS haben. Manchmal erstellen wir Klassen, damit wir diese Elemente mit jQuery einfacher auswählen können. + +Gib jedem deiner `button` Elemente die Klasse `target`. + +# --hints-- + +Du sollst die Klasse `target` zu jedem deiner `button` Elemente zuweisen. + +```js +assert($('.target').length > 5); +``` + +# --seed-- + +## --seed-contents-- + +```html +
    +

    jQuery Playground

    +
    +
    +
    + + + +
    +
    +
    +
    + + + +
    +
    +
    +
    +``` + +# --solutions-- + +```html +
    +

    jQuery Playground

    +
    +
    +
    + + + +
    +
    +
    +
    + + + +
    +
    +
    +
    +``` diff --git a/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/create-a-custom-heading.md b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/create-a-custom-heading.md new file mode 100644 index 00000000000000..8dc4300fff3c10 --- /dev/null +++ b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/create-a-custom-heading.md @@ -0,0 +1,177 @@ +--- +id: bad87fee1348bd9aede08845 +title: Erstelle eine eigene Überschrift +challengeType: 0 +forumTopicId: 16816 +dashedName: create-a-custom-heading +--- + +# --description-- + +Wir werden eine einfache Überschrift für unsere Katzenfoto-App erstellen, indem wir den Titel und das Bild einer entspannten Katze in derselben Reihe platzieren. + +Denk daran, dass Bootstrap ein Gestaltungsraster (Grid) mit responsivem Design verwendet, das es einfach macht, Elemente in Zeilen anzuordnen und die relative Breite der einzelnen Elemente festzulegen. Die meisten Bootstrap-Klassen können auf ein `div`-Element angewendet werden. + +Verschachtel dein erstes Bild und dein `h2`-Element in ein einziges `
    `-Element. Verschachtel dein `h2`-Element in einem `
    ` und dein Bild in einem `
    `, damit sie sich auf der gleichen Zeile befinden. + +Hast du bemerkt, dass das Bild jetzt genau die richtige Größe hat, um neben den Text zu passen? + +# --hints-- + +Dein `h2`-Element und das oberste `img`-Element sollten beide in einem `div`-Element der Klasse `row` verschachtelt werden. + +```js +assert($('div.row:has(h2)').length > 0 && $('div.row:has(img)').length > 0); +``` + +Dein oberstes `img`-Element sollte in einem `div` der Klasse `col-xs-4` verschachtelt sein. + +```js +assert( + $('div.col-xs-4:has(img)').length > 0 && + $('div.col-xs-4:has(div)').length === 0 +); +``` + +Dein `h2`-Element sollte in einem `div` der Klasse `col-xs-8` verschachtelt sein. + +```js +assert( + $('div.col-xs-8:has(h2)').length > 0 && + $('div.col-xs-8:has(div)').length === 0 +); +``` + +All deine `div` Elemente sollten abschließende Tags haben. + +```js +assert( + code.match(/<\/div>/g) && + code.match(/
    /g).length === code.match(/
    + + + +
    +

    CatPhotoApp

    + + A cute orange cat lying on its back. + + Three kittens running towards the camera. +
    +
    + +
    +
    + +
    +
    + +
    +
    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + + + + + + + +
    +
    +``` + +# --solutions-- + +```html + + + + +
    +
    +
    +

    CatPhotoApp

    +
    +
    + A cute orange cat lying on its back. +
    +
    + Three kittens running towards the camera. +
    +
    + +
    +
    + +
    +
    + +
    +
    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + + + + + + + +
    +
    +``` diff --git a/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/create-bootstrap-wells.md b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/create-bootstrap-wells.md new file mode 100644 index 00000000000000..0ba270cb287143 --- /dev/null +++ b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/create-bootstrap-wells.md @@ -0,0 +1,71 @@ +--- +id: bad87fee1348bd9aec908848 +title: Erstelle Bootstrap Wells +challengeType: 0 +forumTopicId: 16825 +dashedName: create-bootstrap-wells +--- + +# --description-- + +Bootstrap hat eine Klasse namens `well`, die deinen Spalten visuelle Tiefe verleihen kann. + +Verschachtle ein `div`-Element mit der Klasse `well` in jedem deiner `col-xs-6` `div`-Elemente. + +# --hints-- + +Du solltest ein `div` Element mit der Klasse `well` in jedem deiner `div` Elemente mit der Klasse `col-xs-6` hinzufügen + +```js +assert($('div.col-xs-6').not(':has(>div.well)').length < 1); +``` + +Deine beiden `div`-Elemente der Klasse `col-xs-6` sollten in deinem `div`-Element der Klasse `row` eingebettet sein. + +```js +assert($('div.row > div.col-xs-6').length > 1); +``` + +All deine `div`-Elemente sollen abschließende Tags enthalten. + +```js +assert( + code.match(/<\/div>/g) && + code.match(/
    /g).length === code.match(/
    +

    jQuery Playground

    +
    +
    + +
    +
    + +
    +
    +
    +``` + +# --solutions-- + +```html +
    +

    jQuery Playground

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +``` diff --git a/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/ditch-custom-css-for-bootstrap.md b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/ditch-custom-css-for-bootstrap.md new file mode 100644 index 00000000000000..51f4ccf78df8f1 --- /dev/null +++ b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/ditch-custom-css-for-bootstrap.md @@ -0,0 +1,188 @@ +--- +id: bad87fee1347bd9aedf08845 +title: Verwende Bootstrap statt eigenem CSS +challengeType: 0 +forumTopicId: 17565 +dashedName: ditch-custom-css-for-bootstrap +--- + +# --description-- + +Wir können unseren Code aufräumen und unsere Katzenfoto-App konventioneller aussehen lassen, indem wir die in Bootstrap integrierten Formate anstelle der benutzerdefinierten Formate verwenden, die wir zuvor erstellt haben. + +Keine Sorge - wir werden später noch viel Zeit haben, um unser CSS anzupassen. + +Lösche die `.red-text`, `p`, und `.smaller-image` CSS Deklarationen von deinem `style`-Element, damit die einzigen Deklarationen, die in deinem `style`-Element vorhanden sind, `h2` und`thick-green-border` sind. + +Lösche dann das `p`-Element, das einen toten Link enthält. Entferne dann die `red-text` Klasse aus deinem `h2` Element und ersetze diese durch die `text-primary` Bootstrap Klasse. + +Entferne schließlich die `smaller-image`-Klasse von deinem ersten `img` Element und ersetze es mit der `img-responsive`- Klasse. + +# --hints-- + +Dein `h2`-Element sollte nicht mehr die Klasse `red-text` haben. + +```js +assert(!$('h2').hasClass('red-text')); +``` + +Dein `h2`-Element sollte jetzt die Klasse `text-primary` haben. + +```js +assert($('h2').hasClass('text-primary')); +``` + +Deine Absatzelemente sollten nicht mehr die Schriftart `Monospace` verwenden. + +```js +assert( + !$('p') + .css('font-family') + .match(/monospace/i) +); +``` + +Die `smaller-image`-Klasse sollte aus dem oberen Bild entfernt werden. + +```js +assert(!$('img').hasClass('smaller-image')); +``` + +Du solltest die `img-responsive`-Klasse zu deinem oberen Bild hinzufügen. + +```js +assert($('.img-responsive').length > 1); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + +
    +

    CatPhotoApp

    + +

    Click here for cat photos.

    + + A cute orange cat lying on its back. + + Three kittens running towards the camera. +
    +
    + +
    +
    + +
    +
    + +
    +
    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + + + + + + + +
    +
    +``` + +# --solutions-- + +```html + + + +
    +

    CatPhotoApp

    + + A cute orange cat lying on its back. + + Three kittens running towards the camera. +
    +
    + +
    +
    + +
    +
    + +
    +
    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + + + + + + + +
    +
    +``` diff --git a/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/give-each-element-a-unique-id.md b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/give-each-element-a-unique-id.md new file mode 100644 index 00000000000000..b7df8e8ec20c04 --- /dev/null +++ b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/give-each-element-a-unique-id.md @@ -0,0 +1,125 @@ +--- +id: bad87fee1348bd9aec908855 +title: Gib jedem Element eine eindeutige ID +challengeType: 0 +forumTopicId: 18191 +dashedName: give-each-element-a-unique-id +--- + +# --description-- + +Wir werden jQuery auch verwenden wollen, um einzelne Buttons durch deren eindeutige ID anzuwählen. + +Gib jedem Button eine eindeutige ID, angefangen mit `target1` und endend mit `target6`. + +Stelle sicher, dass `target1` bis `target3` in `#left-well` und `target4` bis `target6` in `#right-well` untergeordnet sind. + +# --hints-- + +Es sollte ein `button`-Element mit der ID `target1` geben. + +```js +assert( + $('#left-well').children('#target1') && + $('#left-well').children('#target1').length > 0 +); +``` + +Es sollte ein `button`-Element mit der ID `target2` geben. + +```js +assert( + $('#left-well').children('#target2') && + $('#left-well').children('#target2').length > 0 +); +``` + +Es sollte ein `button`-Element mit der ID `target3` geben. + +```js +assert( + $('#left-well').children('#target3') && + $('#left-well').children('#target3').length > 0 +); +``` + +Es sollte ein `button`-Element mit der ID `target4` geben. + +```js +assert( + $('#right-well').children('#target4') && + $('#right-well').children('#target4').length > 0 +); +``` + +Es sollte ein `button`-Element mit der ID `target5` geben. + +```js +assert( + $('#right-well').children('#target5') && + $('#right-well').children('#target5').length > 0 +); +``` + +Es sollte ein `button`-Element mit der ID `target6` geben. + +```js +assert( + $('#right-well').children('#target6') && + $('#right-well').children('#target6').length > 0 +); +``` + +# --seed-- + +## --seed-contents-- + +```html +
    +

    jQuery Playground

    +
    +
    +

    #left-well

    +
    + + + +
    +
    +
    +

    #right-well

    +
    + + + +
    +
    +
    +
    +``` + +# --solutions-- + +```html +
    +

    jQuery Playground

    +
    +
    +

    #left-well

    +
    + + + +
    +
    +
    +

    #right-well

    +
    + + + +
    +
    +
    +
    +``` diff --git a/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/house-our-page-within-a-bootstrap-container-fluid-div.md b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/house-our-page-within-a-bootstrap-container-fluid-div.md new file mode 100644 index 00000000000000..2308e5e68bff03 --- /dev/null +++ b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/house-our-page-within-a-bootstrap-container-fluid-div.md @@ -0,0 +1,53 @@ +--- +id: bad87fee1348bd9aec908746 +title: Platziere unserer Seite in einem Bootstrap Container-Fluid-Div +challengeType: 0 +forumTopicId: 18198 +dashedName: house-our-page-within-a-bootstrap-container-fluid-div +--- + +# --description-- + +Nun müssen wir sicherstellen, dass alle Inhalte auf deiner Seite für Mobilgeräte geeignet sind. + +Lass uns dein `h3` Element innerhalb eines `div` Elements mit der Klasse `container-fluid` einbetten. + +# --hints-- + +Dein `div` Element sollte die Klasse `container-fluid` haben. + +```js +assert($('div').hasClass('container-fluid')); +``` + +Jedes deiner `div` Elemente sollte geschlossene Tags haben. + +```js +assert( + code.match(/<\/div>/g) && + code.match(/
    /g).length === code.match(/
    0); +``` + +# --seed-- + +## --seed-contents-- + +```html +

    jQuery Playground

    +``` + +# --solutions-- + +```html +
    +

    jQuery Playground

    +
    +``` diff --git a/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/label-bootstrap-buttons.md b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/label-bootstrap-buttons.md new file mode 100644 index 00000000000000..ef7a47c607d17f --- /dev/null +++ b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/label-bootstrap-buttons.md @@ -0,0 +1,105 @@ +--- +id: bad87fee1348bd9aec908856 +title: Bootstrap-Buttons beschriften +challengeType: 0 +forumTopicId: 18222 +dashedName: label-bootstrap-buttons +--- + +# --description-- + +So wie wir unsere Wells beschriftet haben, soltlen wir auch unsere Buttons beschriften. + +Gib jedem deiner `button`-Elemente den Text, der seinem Id-Selektor entspricht. + +# --hints-- + +Dein `button`-Element mit der Id `target1` sollte den Text `#target1` beinhalten. + +```js +assert(new RegExp('#target1', 'gi').test($('#target1').text())); +``` + +Dein `button`-Element mit der Id `target2` sollte den Text `#target2` beinhalten. + +```js +assert(new RegExp('#target2', 'gi').test($('#target2').text())); +``` + +Dein `button`-Element mit der Id `target3` sollte den Text `#target3` beinhalten. + +```js +assert(new RegExp('#target3', 'gi').test($('#target3').text())); +``` + +Dein `button`-Element mit der Id `target4` sollte den Text `#target4` beinhalten. + +```js +assert(new RegExp('#target4', 'gi').test($('#target4').text())); +``` + +Dein `button`-Element mit der Id `target5` sollte den Text `#target5` beinhalten. + +```js +assert(new RegExp('#target5', 'gi').test($('#target5').text())); +``` + +Dein `button`-Element mit der Id `target6` sollte den Text `#target6` beinhalten. + +```js +assert(new RegExp('#target6', 'gi').test($('#target6').text())); +``` + +# --seed-- + +## --seed-contents-- + +```html +
    +

    jQuery Playground

    +
    +
    +

    #left-well

    +
    + + + +
    +
    +
    +

    #right-well

    +
    + + + +
    +
    +
    +
    +``` + +# --solutions-- + +```html +
    +

    jQuery Playground

    +
    +
    +

    #left-well

    +
    + + + +
    +
    +
    +

    #right-well

    +
    + + + +
    +
    +
    +
    +``` diff --git a/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/label-bootstrap-wells.md b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/label-bootstrap-wells.md new file mode 100644 index 00000000000000..4f2612d951e22e --- /dev/null +++ b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/label-bootstrap-wells.md @@ -0,0 +1,101 @@ +--- +id: bad87fee1348bd9aec908854 +title: Beschrifte Bootstrap Wells +challengeType: 0 +forumTopicId: 18223 +dashedName: label-bootstrap-wells +--- + +# --description-- + +Um der Klarheit willen, werden wir unsere beiden Wells mit ihren Ids beschriften. + +Füge über deinem left-well, innerhalb des `col-xs-6` `div`-Elements, ein `h4`-Element mit dem Text `#left-well` hinzu. + +Füge über deinem right-well, innerhalb des `col-xs-6` `div`- Elements, ein `h4`-Element mit dem Text `#right-well` hinzu. + +# --hints-- + +Du solltest ein `h4`-Element zu jedem deiner `
    `-Elemente hinzufügen. + +```js +assert( + $('.col-xs-6').children('h4') && $('.col-xs-6').children('h4').length > 1 +); +``` + +Dein `h4`-Element sollte den Text `#left-well` beinhalten. + +```js +assert(new RegExp('#left-well', 'gi').test($('h4').text())); +``` + +Ein `h4`-Element sollte den Text `#right-well` beinhalten. + +```js +assert(new RegExp('#right-well', 'gi').test($('h4').text())); +``` + +Alle deine `h4`-Elemente sollten abschließende Tags haben. + +```js +assert( + code.match(/<\/h4>/g) && + code.match(/

    /g).length === code.match(/

    +

    jQuery Playground

    +
    +
    + +
    + + + +
    +
    +
    + +
    + + + +
    +
    +
    +
    +``` + +# --solutions-- + +```html +
    +

    jQuery Playground

    +
    +
    +

    #left-well

    +
    + + + +
    +
    +
    +

    #right-well

    +
    + + + +
    +
    +
    +
    +``` diff --git a/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/line-up-form-elements-responsively-with-bootstrap.md b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/line-up-form-elements-responsively-with-bootstrap.md new file mode 100644 index 00000000000000..dca63299b90f9a --- /dev/null +++ b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/line-up-form-elements-responsively-with-bootstrap.md @@ -0,0 +1,215 @@ +--- +id: bad87fee1348bd9aec908845 +title: Ordne die Formular-Elemente responsiv mit Bootstrap an +challengeType: 0 +forumTopicId: 18225 +required: + - + link: >- + https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.css + raw: true +dashedName: line-up-form-elements-responsively-with-bootstrap +--- + +# --description-- + +Jetzt lass uns dein Formular-`input` und dein Übermittlungs-`button` in die selbe Zeile bringen. Wir machen das auf die gleiche Art und Weise wie davor: Indem wir ein `div`-Element mit der Klasse `row`, und andere `div`-Elemente innerhalb dieser mittels der `col-xs-*` Klasse verwenden. + +Verschachtel beide deiner Text-`input` Felder des Formulars sowie den Übermittlungs-`button` innerhalb eines `div` mit der Klasse `row`. Veschachtel den Text `input` im Formular innerhalb einer div mit der Klasse `col-xs-7`. Verschachtel deinen Bestätigungs- `button` des Formulars in ein `div` mit der Klasse `col-xs-5`. + +Das ist die letzte Aufgabe, die wir fürs Erste für unsere Katzenfoto-App machen. Wir hoffen, dass dir das Lernen von Font Awesome, Bootstrap und responsivem Design gefallen hat! + +# --hints-- + +Der Button für die Übermittlung des Formulars und die Texteingabe sollten in einem div mit der Klasse `row` verschachtelt sein. + +```js +assert( + $('div.row:has(input[type="text"])').length > 0 && + $('div.row:has(button[type="submit"])').length > 0 +); +``` + +Die Texteingabe in deinem Formular sollte in einem div mit der Klasse `col-xs-7` verschachtelt sein. + +```js +assert($('div.col-xs-7:has(input[type="text"])').length > 0); +``` + +Der Button zur Übermittlung des Formulars sollte in einem div mit der Klasse `col-xs-5` verschachelt sein. + +```js +assert($('div.col-xs-5:has(button[type="submit"])').length > 0); +``` + +All deine `div`-Elemente sollten abschließende Tags haben. + +```js +assert( + code.match(/<\/div>/g) && + code.match(/
    /g).length === code.match(/
    + + +
    +
    +
    +

    CatPhotoApp

    +
    +
    + A cute orange cat lying on its back. +
    +
    + Three kittens running towards the camera. +
    +
    + +
    +
    + +
    +
    + +
    +
    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    + + +
    +
    +``` + +# --solutions-- + +```html + + + +
    +
    +
    +

    CatPhotoApp

    +
    +
    + A cute orange cat lying on its back. +
    +
    + Three kittens running towards the camera. +
    +
    + +
    +
    + +
    +
    + +
    +
    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +``` diff --git a/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/make-images-mobile-responsive.md b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/make-images-mobile-responsive.md new file mode 100644 index 00000000000000..a7ee307d5cb6c3 --- /dev/null +++ b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/make-images-mobile-responsive.md @@ -0,0 +1,176 @@ +--- +id: bad87fee1348bd9acde08812 +title: Gestalte die Bilder mobilfähig +challengeType: 0 +forumTopicId: 18232 +dashedName: make-images-mobile-responsive +--- + +# --description-- + +Füge zunächst ein neues Bild unter dem bestehenden Bild ein. Setze das `src`-Attribut auf `https://cdn.freecodecamp.org/curriculum/cat-photo-app/running-cats.jpg`. + +Es wäre großartig, wenn dieses Bild genau die Breite des Bildschirms unseres Telefons haben könnte. + +Zum Glück müssen wir mit Bootstrap nur die Klasse `img-responsive` zu deinem Bild hinzufügen. Wenn du das machst, sollte das Bild genau auf die Breite deiner Seite passen. + +# --hints-- + +Du solltest insgesamt zwei Bilder haben. + +```js +assert($('img').length === 2); +``` + +Dein neues Bild sollte unter dem alten stehen und die Klasse `img-responsive` haben. + +```js +assert($('img:eq(1)').hasClass('img-responsive')); +``` + +Dein neues Bild sollte nicht die Klasse `smaller-image` haben. + +```js +assert(!$('img:eq(1)').hasClass('smaller-image')); +``` + +Dein neues Bild sollte einen `src` von `https://cdn.freecodecamp.org/curriculum/cat-photo-app/running-cats.jpg` haben. + +```js +assert($('img:eq(1)').attr('src') === 'https://cdn.freecodecamp.org/curriculum/cat-photo-app/running-cats.jpg'); +``` + +Dein neues `img`-Element sollte eine abschließende spitze Klammer haben. + +```js +assert( + code.match(//g).length === 2 && + code.match(/ + + +
    +

    CatPhotoApp

    + +

    Click here for cat photos.

    + + A cute orange cat lying on its back. + +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + + + + + + + +
    +
    +``` + +# --solutions-- + +```html + + + +
    +

    CatPhotoApp

    + +

    Click here for cat photos.

    + + A cute orange cat lying on its back. + + +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + + + + + + + +
    +
    +``` diff --git a/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/responsively-style-checkboxes.md b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/responsively-style-checkboxes.md new file mode 100644 index 00000000000000..d014d01f542647 --- /dev/null +++ b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/responsively-style-checkboxes.md @@ -0,0 +1,192 @@ +--- +id: bad87fee1348bd9aeda08845 +title: Kontrollkästchen ansprechend gestalten +challengeType: 0 +forumTopicId: 18269 +required: + - + link: >- + https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.css + raw: true +dashedName: responsively-style-checkboxes +--- + +# --description-- + +Da die `col-xs-*`-Klassen von Bootstrap auf alle `form`-Elemente anwendbar sind, kannst du sie auch für deine Kontrollkästchen verwenden! Auf diese Weise werden die Kontrollkästchen gleichmäßig auf der Seite verteilt, unabhängig davon, wie breit die Bildschirmauflösung ist. + +# --instructions-- + +Verschachtel alle drei Kontrollkästchen in einem `
    `-Element. Verschachtel dann jedes in einem `
    `-Element. + +# --hints-- + +All deine Kontrollkästchen sollten innerhalb eines `div` mit der Klasse `row` verschachtelt sein. + +```js +assert($('div.row:has(input[type="checkbox"])').length > 0); +``` + +Jedes deiner Kontrollkästchen sollte in einem eigenen `div` mit der Klasse `col-xs-4` verschachtelt sein. + +```js +assert($('div.col-xs-4:has(input[type="checkbox"])').length > 2); +``` + +All deine `div`-Elemente sollten abschließende Tags haben. + +```js +assert( + code.match(/<\/div>/g) && + code.match(/
    /g).length === code.match(/
    + + +
    +
    +
    +

    CatPhotoApp

    +
    +
    + A cute orange cat lying on its back. +
    +
    + Three kittens running towards the camera. +
    +
    + +
    +
    + +
    +
    + +
    +
    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    +
    +``` + +# --solutions-- + +```html + + + +
    +
    +
    +

    CatPhotoApp

    +
    +
    + A cute orange cat lying on its back. +
    +
    + Three kittens running towards the camera. +
    +
    + +
    +
    + +
    +
    + +
    +
    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    + + +
    +
    +``` diff --git a/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/responsively-style-radio-buttons.md b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/responsively-style-radio-buttons.md new file mode 100644 index 00000000000000..665638029c3ba9 --- /dev/null +++ b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/responsively-style-radio-buttons.md @@ -0,0 +1,176 @@ +--- +id: bad87fee1348bd9aedb08845 +title: Ansprechende Gestaltung von Radio-Buttons +challengeType: 0 +forumTopicId: 18270 +required: + - + link: >- + https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.css + raw: true +dashedName: responsively-style-radio-buttons +--- + +# --description-- + +Du kannst die `col-xs-*`-Klassen von Bootstrap auch auf `form`-Elemente anwenden! Auf diese Weise werden unsere Radio-Buttons gleichmäßig über die Seite verteilt, unabhängig davon, wie breit die Bildschirmauflösung ist. + +Verschachtel deine beiden Optionsfelder in einem `
    `-Element. Verschachtel dann jedes in einem `
    `-Element. + +**Hinweis:** Zur Erinnerung, Radio-Buttons sind `input`-Elemente des Typs `radio`. + +# --hints-- + +All deine Radio-Buttons sollten innerhalb eines `div` mit der Klasse `row` verschachtelt sein. + +```js +assert($('div.row:has(input[type="radio"])').length > 0); +``` + +Jeder deiner Radio-Buttons sollte in einem eigenen `div` mit der Klasse `col-xs-6` verschachtelt sein. + +```js +assert($('div.col-xs-6:has(input[type="radio"])').length > 1); +``` + +All deine `div`-Elemente sollten abschließende Tags haben. + +```js +assert( + code.match(/<\/div>/g) && + code.match(/
    /g).length === code.match(/
    + + +
    +
    +
    +

    CatPhotoApp

    +
    +
    + A cute orange cat lying on its back. +
    +
    + Three kittens running towards the camera. +
    +
    + +
    +
    + +
    +
    + +
    +
    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    + + + + + + + +
    +
    +``` + +# --solutions-- + +```html + + + +
    +
    +
    +

    CatPhotoApp

    +
    +
    + A cute orange cat lying on its back. +
    +
    + Three kittens running towards the camera. +
    +
    + +
    +
    + +
    +
    + +
    +
    +

    Things cats love:

    +
      +
    • cat nip
    • +
    • laser pointers
    • +
    • lasagna
    • +
    +

    Top 3 things cats hate:

    +
      +
    1. flea treatment
    2. +
    3. thunder
    4. +
    5. other cats
    6. +
    +
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    +
    +``` diff --git a/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/split-your-bootstrap-row.md b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/split-your-bootstrap-row.md new file mode 100644 index 00000000000000..2b6e369236b127 --- /dev/null +++ b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/split-your-bootstrap-row.md @@ -0,0 +1,57 @@ +--- +id: bad87fee1348bd9aec908847 +title: Teile dein Bootstrap-Zeile +challengeType: 0 +forumTopicId: 18306 +dashedName: split-your-bootstrap-row +--- + +# --description-- + +Da wir nun eine Bootstrap-Zeile haben, können wir sie in zwei Spalten aufteilen, um unsere Elemente unterzubringen. + +Erstelle innerhalb deiner Zeile zwei `div`-Elemente, beide mit der Klasse `col-xs-6`. + +# --hints-- + +Zwei `div class="col-xs-6"`-Elemente sollten in deinem `div class="row"`-Element verschachtelt sein. + +```js +assert($('div.row > div.col-xs-6').length > 1); +``` + +All deine `div`-Elemente sollten abschließende Tags haben. + +```js +assert( + code.match(/<\/div>/g) && + code.match(/
    /g).length === code.match(/
    +

    jQuery Playground

    +
    + + +
    +
    +``` + +# --solutions-- + +```html +
    +

    jQuery Playground

    +
    +
    +
    +
    +
    +``` diff --git a/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/style-text-inputs-as-form-controls.md b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/style-text-inputs-as-form-controls.md new file mode 100644 index 00000000000000..d1036d4a2bf529 --- /dev/null +++ b/curriculum/challenges/german/03-front-end-development-libraries/bootstrap/style-text-inputs-as-form-controls.md @@ -0,0 +1,202 @@ +--- +id: bad87fee1348bd9aed908845 +title: Gestalte Texteingaben als Formular-Elemente +challengeType: 0 +forumTopicId: 18312 +required: + - + link: >- + https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.css + raw: true +dashedName: style-text-inputs-as-form-controls +--- + +# --description-- + +Du kannst das `fa-paper-plane` Font Awesome-Symbol hinzufügen, indem du `` innerhalb deines Bestätigungs-`button`-Elements einfügst. + +Gib dem Texteingabefeld deines Formulars die Klasse `form-control`. Gib dem Bestätigungsbutton deines Formulars die Klassen `btn btn-primary`. Gib dem Button das Font Awesome-Symbol `fa-paper-plane`. + +Alle textuellen ``-, ` +
    +
    + + + +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +--fcc-editable-region-- +h2 { + border-bottom: 4px solid #dfdfe2; + +} +--fcc-editable-region-- + +p::before { + content: "Question #"; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/german/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e0bcc13efd10f7d7a6a9.md b/curriculum/challenges/german/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e0bcc13efd10f7d7a6a9.md new file mode 100644 index 00000000000000..e22f6d07981a7d --- /dev/null +++ b/curriculum/challenges/german/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e0bcc13efd10f7d7a6a9.md @@ -0,0 +1,336 @@ +--- +id: 6148e0bcc13efd10f7d7a6a9 +title: Schritt 62 +challengeType: 0 +dashedName: step-62 +--- + +# --description-- + +Setze die `footer` Hintergrundfarbe auf `#2a2a40` und verwende _Flexbox_, um den Text horizontal zu zentrieren. + +# --hints-- + +Du solltest den `footer` Element-Selektor verwenden. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('footer')); +``` + +Du solltest dem `footer` eine `background-color` von `#2a2a40` geben. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('footer')?.backgroundColor, 'rgb(42, 42, 64)'); +``` + +Du solltest dem `footer` ein `display` von `flex` geben. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('footer')?.display, 'flex'); +``` + +Du solltest dem `footer` ein `justify-content` von `center` geben. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('footer')?.justifyContent, 'center'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +.info label, .info input { + display: inline-block; + text-align: right; +} + +.info input { + width: 50%; + text-align: left; +} + +.info label { + width: 10%; + min-width: 55px; +} + +.question-block { + text-align: left; + display: block; + width: 100%; + margin-top: 20px; + padding-top: 5px; +} + +p { + margin-top: 5px; + padding-left: 15px; + font-size: 20px; +} + +p::before { + content: "Question #"; +} + +.question { + border: none; + padding-bottom: 0; +} + +.answers-list { + list-style: none; + padding: 0; +} + +button { + display: block; + margin: 40px auto; + width: 40%; + padding: 15px; + font-size: 23px; + background: #d0d0d5; + border: 3px solid #3b3b4f; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/german/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e28706b34912340fd042.md b/curriculum/challenges/german/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e28706b34912340fd042.md new file mode 100644 index 00000000000000..47a984abb3f6a7 --- /dev/null +++ b/curriculum/challenges/german/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e28706b34912340fd042.md @@ -0,0 +1,359 @@ +--- +id: 6148e28706b34912340fd042 +title: Schritt 64 +challengeType: 0 +dashedName: step-64 +--- + +# --description-- + +Zentriere den gesamten Text horizontal innerhalb des `address`-Elements und füge einige Padding-Einheiten hinzu. + +# --hints-- + +Du solltest den `address` Element-Selektor verwenden. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('address')); +``` + +Du solltest `address` ein `text-align` von `center` geben. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('address')?.textAlign, 'center'); +``` + +Du solltest `address` ein `padding-top` von mindestens `1px` geben. + +```js +assert.isAtLeast(Number(window.getComputedStyle(document.querySelector('address'), null)?.getPropertyValue('padding-top')?.replace(/\D\D+/, '')), 1); +``` + +Du solltest `address` ein `padding-right` von mindestens `1px` geben. + +```js +assert.isAtLeast(Number(window.getComputedStyle(document.querySelector('address'), null)?.getPropertyValue('padding-right')?.replace(/\D\D+/, '')), 1); +``` + +Du solltest `address` ein `padding-bottom` von mindestens `1px` geben. + +```js +assert.isAtLeast(Number(window.getComputedStyle(document.querySelector('address'), null)?.getPropertyValue('padding-bottom')?.replace(/\D\D+/, '')), 1); +``` + +Du solltest `address` ein `padding-left` von mindestens `1px` geben. + +```js +assert.isAtLeast(Number(window.getComputedStyle(document.querySelector('address'), null)?.getPropertyValue('padding-left')?.replace(/\D\D+/, '')), 1); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +.info label, .info input { + display: inline-block; + text-align: right; +} + +.info input { + width: 50%; + text-align: left; +} + +.info label { + width: 10%; + min-width: 55px; +} + +.question-block { + text-align: left; + display: block; + width: 100%; + margin-top: 20px; + padding-top: 5px; +} + +p { + margin-top: 5px; + padding-left: 15px; + font-size: 20px; +} + +p::before { + content: "Question #"; +} + +.question { + border: none; + padding-bottom: 0; +} + +.answers-list { + list-style: none; + padding: 0; +} + +button { + display: block; + margin: 40px auto; + width: 40%; + padding: 15px; + font-size: 23px; + background: #d0d0d5; + border: 3px solid #3b3b4f; +} + +footer { + background-color: #2a2a40; + display: flex; + justify-content: center; +} + +footer, +footer a { + color: #dfdfe2; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/german/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e335c1edd512d00e4691.md b/curriculum/challenges/german/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e335c1edd512d00e4691.md new file mode 100644 index 00000000000000..2152a6882a5a0d --- /dev/null +++ b/curriculum/challenges/german/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e335c1edd512d00e4691.md @@ -0,0 +1,342 @@ +--- +id: 6148e335c1edd512d00e4691 +title: Schritt 65 +challengeType: 0 +dashedName: step-65 +--- + +# --description-- + +Wenn du auf die Navigationslinks klickst, sollte das Ansichtsfenster zu dem entsprechenden Abschnitt springen. Dieses Springen kann jedoch für manche Benutzer verwirrend sein. + +Wähle alle Elemente aus und setze das `scroll-behavior` auf `smooth`. + +# --hints-- + +Du solltest den Selektor `*` verwenden. + +```js +assert.exists(new __helpers.CSSHelp(document).getStyle('*')); +``` + +Du solltest `*` ein `scroll-behavior` von `smooth` geben. + +```js +assert.equal(new __helpers.CSSHelp(document).getStyle('*')?.scrollBehavior, 'smooth'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +--fcc-editable-region-- + +--fcc-editable-region-- + +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +.info label, .info input { + display: inline-block; + text-align: right; +} + +.info input { + width: 50%; + text-align: left; +} + +.info label { + width: 10%; + min-width: 55px; +} + +.question-block { + text-align: left; + display: block; + width: 100%; + margin-top: 20px; + padding-top: 5px; +} + +p { + margin-top: 5px; + padding-left: 15px; + font-size: 20px; +} + +p::before { + content: "Question #"; +} + +.question { + border: none; + padding-bottom: 0; +} + +.answers-list { + list-style: none; + padding: 0; +} + +button { + display: block; + margin: 40px auto; + width: 40%; + padding: 15px; + font-size: 23px; + background: #d0d0d5; + border: 3px solid #3b3b4f; +} + +footer { + background-color: #2a2a40; + display: flex; + justify-content: center; +} + +footer, +footer a { + color: #dfdfe2; +} + +address { + text-align: center; + padding: 0.3em; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/german/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e5aeb102e3142de026a2.md b/curriculum/challenges/german/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e5aeb102e3142de026a2.md new file mode 100644 index 00000000000000..3cc7276c981a53 --- /dev/null +++ b/curriculum/challenges/german/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148e5aeb102e3142de026a2.md @@ -0,0 +1,685 @@ +--- +id: 6148e5aeb102e3142de026a2 +title: Schritt 67 +challengeType: 0 +dashedName: step-67 +--- + +# --description-- + +Endlich kann die Verfügbarkeit der Navigation durch die Bereitstellung von Tastaturkürzeln verbessert werden. + +Das Attribut `accesskey` akzeptiert eine durch Leerzeichen getrennte Liste von Zugangsschlüsseln. Zum Beispiel: + +```html + +``` + +Gib jedem der Navigationslinks einen Zugangsschlüssel mit einem Buchstaben. + +_Hinweis: Es ist nicht immer ratsam, Zugangsschlüsseln zu verwenden, aber sie können nützlich sein_ + +Gut gemacht. Du hast das Übungsprojekt _Barrierefreiheit-Quiz_ abgeschlossen. + +# --hints-- + +Du solltest dem ersten `a`-Element einen aus einem einzigen Buchstaben bestehenden `accesskey` geben. + +```js +assert.equal(document.querySelectorAll('a')?.[0]?.getAttribute('accesskey')?.length, 1); +``` + +Du solltest dem zweiten `a`-Element einen aus einem einzigen Buchstaben bestehenden `accesskey` geben. + +```js +assert.equal(document.querySelectorAll('a')?.[1]?.getAttribute('accesskey')?.length, 1); +``` + +Du solltest dem dritten `a`-Element einen aus einem einzigen Buchstaben bestehenden `accesskey` geben. + +```js +assert.equal(document.querySelectorAll('a')?.[2]?.getAttribute('accesskey')?.length, 1); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Accessibility Quiz + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +@media (prefers-reduced-motion: no-preference) { + * { + scroll-behavior: smooth; + } +} + +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + background-color: #1b1b32; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; +} + +#logo { + width: max(100px, 18vw); + background-color: #0a0a23; + aspect-ratio: 35 / 4; + padding: 0.4rem; +} + +h1 { + color: #f1be32; + font-size: min(5vw, 1.2em); + text-align: center; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + color: #dfdfe2; + margin: 0 0.2rem; + padding: 0.2rem; + display: block; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0 auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + +.info { + padding: 10px 0 0 5px; +} + +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +.info label, .info input { + display: inline-block; + text-align: right; +} + +.info input { + width: 50%; + text-align: left; +} + +.info label { + width: 10%; + min-width: 55px; +} + +.question-block { + text-align: left; + display: block; + width: 100%; + margin-top: 20px; + padding-top: 5px; +} + +p { + margin-top: 5px; + padding-left: 15px; + font-size: 20px; +} + +p::before { + content: "Question #"; +} + +.question { + border: none; + padding-bottom: 0; +} + +.answers-list { + list-style: none; + padding: 0; +} + +button { + display: block; + margin: 40px auto; + width: 40%; + padding: 15px; + font-size: 23px; + background: #d0d0d5; + border: 3px solid #3b3b4f; +} + +footer { + background-color: #2a2a40; + display: flex; + justify-content: center; +} + +footer, +footer a { + color: #dfdfe2; +} + +address { + text-align: center; + padding: 0.3em; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` + +## --solutions-- + +```html + + + + + + + + Accessibility Quiz + + + + +
    + +

    HTML/CSS Quiz

    + +
    +
    +
    +
    +

    Student Info

    + +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    HTML

    +
    +

    1

    +
    + + The legend element represents a caption for the content of its + parent fieldset element + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +

    2

    +
    + + A label element nesting an input element is required to have a + for attribute with the same value as the input's id + +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +

    CSS

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + + + + +``` + +```css +@media (prefers-reduced-motion: no-preference) { + * { + scroll-behavior: smooth; + } +} + +body { + background: #f5f6f7; + color: #1b1b32; + font-family: Helvetica; + margin: 0; +} + +header { + width: 100%; + height: 50px; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + position: fixed; + background-color: #1b1b32; + top: 0; +} + +#logo { + width: max(100px, 18vw); + aspect-ratio: 35 / 4; + max-height: 100%; + background-color: #0a0a23; + padding: 0.4rem; +} + +h1 { + text-align: center; + font-size: min(5vw, 1.2em); + color: #f1be32; +} + +nav { + width: 50%; + max-width: 300px; + height: 50px; +} + +nav > ul { + display: flex; + flex-wrap: wrap; + justify-content: space-evenly; + align-items: center; + padding-inline-start: 0; + margin-block: 0; + height: 100%; +} + +nav > ul > li { + display: block; + margin: 0 0.2rem; + color: #dfdfe2; + padding: 0.2rem; +} + +nav > ul > li:hover { + background-color: #dfdfe2; + color: #1b1b32; + cursor: pointer; +} + +li > a { + color: inherit; + text-decoration: none; +} + +main { + padding-top: 50px; +} + +section { + width: 80%; + margin: 0px auto 10px auto; + max-width: 600px; +} + +h1, +h2 { + font-family: Verdana, Tahoma; +} + +h2 { + border-bottom: 4px solid #dfdfe2; + margin-top: 0px; + padding-top: 60px; +} + + +.info { + margin: 0 auto; + padding: 10px 0 0 5px; +} +.formrow { + margin-top: 30px; + padding: 0px 15px; +} + +input { + font-size: 16px; +} + +.info label, +.info input { + display: inline-block; + text-align: right; +} + +.info label { + width: 10%; + min-width: 55px; +} + +.info input { + width: 50%; + text-align: left; +} + +.question-block { + text-align: left; + display: block; + width: 100%; + margin-top: 20px; + padding-top: 5px; +} + +p { + margin-top: 5px; + padding-left: 15px; + font-size: 20px; +} + +p::before { + content: "Question #"; +} + +.question { + border: none; + padding-bottom: 0; +} + +.answers-list { + list-style: none; + padding: 0; +} + +button { + display: block; + margin: 40px auto; + width: 40%; + padding: 15px; + font-size: 23px; + background: #d0d0d5; + border: 3px solid #3b3b4f; +} + +footer { + background-color: #2a2a40; + display: flex; + justify-content: center; +} + +footer, +footer a { + color: #dfdfe2; +} + +address { + text-align: center; + padding: 0.3em; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +``` diff --git a/curriculum/challenges/german/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e06d34faac0447fc44.md b/curriculum/challenges/german/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e06d34faac0447fc44.md new file mode 100644 index 00000000000000..aa23aabc917c48 --- /dev/null +++ b/curriculum/challenges/german/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e06d34faac0447fc44.md @@ -0,0 +1,135 @@ +--- +id: 5f3ef6e06d34faac0447fc44 +title: Schritt 61 +challengeType: 0 +dashedName: step-61 +--- + +# --description-- + +Mache den `Est. 2020`-Text kursiv, indem du einen `established`-Klassenselektor erstellst und ihm die `font-style`-Eigenschaft mit dem Wert `italic` gibst. + +# --hints-- + +Du solltest einen `.established`-Selektor haben. + +```js +const hasEstablished = new __helpers.CSSHelp(document).getStyle('.established'); +assert(hasEstablished); +``` + +Du solltest die `font-style`-Eigenschaft auf `italic` setzen. + +```js +const hasFontStyle = new __helpers.CSSHelp(document).getCSSRules().some(x => x.style['font-style'] === 'italic'); +assert(hasFontStyle); +``` + +Dein `.established`-Selektor sollte die `font-style`-Eigenschaft auf `italic` setzen. + +```js +const establishedFontStyle = new __helpers.CSSHelp(document).getStyle('.established')?.getPropertyValue('font-style'); +assert(establishedFontStyle === 'italic'); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + Cafe Menu + + + + + + +``` + +```css +body { + background-image: url(https://cdn.freecodecamp.org/curriculum/css-cafe/beans.jpg); + font-family: sans-serif; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +h1, h2, p { + text-align: center; +} + +.menu { + width: 80%; + background-color: burlywood; + margin-left: auto; + margin-right: auto; + padding: 20px; + max-width: 500px; +} + +h1, h2 { + font-family: Impact, serif; +} + +.item p { + display: inline-block; +} + +.flavor, .dessert { + text-align: left; + width: 75%; +} + +.price { + text-align: right; + width: 25% +} +``` + diff --git a/curriculum/challenges/italian/01-responsive-web-design/applied-visual-design/adjust-the-hue-of-a-color.md b/curriculum/challenges/italian/01-responsive-web-design/applied-visual-design/adjust-the-hue-of-a-color.md index 28f42534f820c2..f34228af9cd102 100644 --- a/curriculum/challenges/italian/01-responsive-web-design/applied-visual-design/adjust-the-hue-of-a-color.md +++ b/curriculum/challenges/italian/01-responsive-web-design/applied-visual-design/adjust-the-hue-of-a-color.md @@ -27,19 +27,19 @@ Cambia il `background-color` di ogni elemento `div` basandoti sui nomi delle cla # --hints-- -Il tuo codice dovrebbe usare le funzioni `hsl()` per dichiarare il colore verde. +Il codice dovrebbe avere la funzione `hsl()` per dichiarare il colore verde. ```js assert(code.match(/\.green\s*?{\s*?background-color\s*:\s*?hsl/gi)); ``` -Il tuo codice dovrebbe utilizzare le funzioni `hsl()` per dichiarare il colore ciano. +Il codice dovrebbe avere la funzione `hsl()` per dichiarare il colore ciano. ```js assert(code.match(/\.cyan\s*?{\s*?background-color\s*:\s*?hsl/gi)); ``` -Il tuo codice dovrebbe utilizzare le funzioni `hsl()` per dichiarare il colore blu. +Il codice dovrebbe avere la funzione `hsl()` per dichiarare il colore blu. ```js assert(code.match(/\.blue\s*?{\s*?background-color\s*:\s*?hsl/gi)); diff --git a/curriculum/challenges/italian/01-responsive-web-design/applied-visual-design/adjust-the-tone-of-a-color.md b/curriculum/challenges/italian/01-responsive-web-design/applied-visual-design/adjust-the-tone-of-a-color.md index bc7483e99b8a05..4668bf038fdcff 100644 --- a/curriculum/challenges/italian/01-responsive-web-design/applied-visual-design/adjust-the-tone-of-a-color.md +++ b/curriculum/challenges/italian/01-responsive-web-design/applied-visual-design/adjust-the-tone-of-a-color.md @@ -20,9 +20,11 @@ Tutti gli elementi hanno un `background-color` predefinito `transparent`. Il nos L'elemento `nav` dovrebbe avere un `background-color` del colore ciano regolato utilizzando la proprietà `hsl()`. ```js -assert( - code.match(/nav\s*?{\s*?background-color:\s*?hsl\(180,\s*?80%,\s*?25%\)/gi) -); +// Computed style of hsl(180, 80%, 25%) results in rgb(13,115,115) +assert.equal( + new __helpers.CSSHelp(document).getStyle('nav').getPropVal('background-color', true), + 'rgb(13,115,115)' +) ``` # --seed-- diff --git a/curriculum/challenges/italian/01-responsive-web-design/applied-visual-design/learn-about-complementary-colors.md b/curriculum/challenges/italian/01-responsive-web-design/applied-visual-design/learn-about-complementary-colors.md index c020fc0a550b20..0e289305dcbd6d 100644 --- a/curriculum/challenges/italian/01-responsive-web-design/applied-visual-design/learn-about-complementary-colors.md +++ b/curriculum/challenges/italian/01-responsive-web-design/applied-visual-design/learn-about-complementary-colors.md @@ -17,7 +17,7 @@ Alcuni esempi di colori complementari con i loro codici esadecimali sono:
    rosso (#FF0000) e ciano (#00FFFF)
    verde (#00FF00) e magenta (#FF00FF)
    blu (#0000FF) e giallo (#FFFF00)
    -Questo è diverso dal modello di colore superato RYB (Rosso Giallo Blu) che hanno insegnato a molti di noi a scuola, che ha diversi colori primari e complementari. La teoria dei colori moderna utilizza il modello RGB additivo (come su uno schermo del computer) e il modello CMY(K) sottrattivo (come nella stampa). Leggi [qui](https://it.wikipedia.org/wiki/Modello_di_colore) per maggiori informazioni su questo argomento complesso. +Questo è diverso dal modello di colore superato RYB (Rosso Giallo Blu) che hanno insegnato a molti di noi a scuola, che ha diversi colori primari e complementari. La teoria dei colori moderna utilizza il modello RGB additivo (come su uno schermo del computer) e il modello CMY(K) sottrattivo (come nella stampa). Ci sono molti strumenti di selezione del colore disponibili online che hanno un'opzione per trovare il complementare di un colore. diff --git a/curriculum/challenges/italian/01-responsive-web-design/applied-visual-design/use-a-bezier-curve-to-move-a-graphic.md b/curriculum/challenges/italian/01-responsive-web-design/applied-visual-design/use-a-bezier-curve-to-move-a-graphic.md index d6707780107116..f4d88dd5070008 100644 --- a/curriculum/challenges/italian/01-responsive-web-design/applied-visual-design/use-a-bezier-curve-to-move-a-graphic.md +++ b/curriculum/challenges/italian/01-responsive-web-design/applied-visual-design/use-a-bezier-curve-to-move-a-graphic.md @@ -21,7 +21,7 @@ Ricorda che tutte le funzioni `cubic-bezier` iniziano con `p0` a (0, 0) e termin # --instructions-- -Per vedere l'effetto di questa curva di Bezier in azione, cambia la `animation-timing-function` dell'elemento con id `red` in una funzione `cubic-bezier` con valori x1, y1, x2, y2 fissati rispettivamente a 0, 0, 0.58, 1. Questo farà progredire entrambi gli elementi attraverso l'animazione in modo simile. +Per vedere l'effetto di questa curva di Bezier in azione, cambia la `animation-timing-function` dell'elemento con id `red` in una funzione `cubic-bezier` con valori x1, y1, x2, y2 fissati rispettivamente a `0, 0, 0.58, 1`. Questo farà progredire entrambi gli elementi attraverso l'animazione in modo simile. # --hints-- diff --git a/curriculum/challenges/italian/01-responsive-web-design/basic-css/import-a-google-font.md b/curriculum/challenges/italian/01-responsive-web-design/basic-css/import-a-google-font.md index ecc7c165bb6931..c384980f11ed68 100644 --- a/curriculum/challenges/italian/01-responsive-web-design/basic-css/import-a-google-font.md +++ b/curriculum/challenges/italian/01-responsive-web-design/basic-css/import-a-google-font.md @@ -11,7 +11,7 @@ dashedName: import-a-google-font Oltre a specificare i caratteri comuni che si trovano nella maggior parte dei sistemi operativi, possiamo anche specificare font web personalizzati non standard per l'uso nel nostro sito web. Ci sono molte fonti dove reperire i web fonts su Internet. Per questo esempio ci concentreremo sulla libreria Google Fonts. -[Google Fonts](https://fonts.google.com/) è una libreria gratuita di web fonts che puoi usare nel tuo CSS facendo riferimento all'URL del font. +Google Fonts è una libreria gratuita di font che puoi utilizzare in CSS facendo riferimento all'URL del font. Quindi, andiamo avanti e importiamo e applichiamo un carattere di Google (nota che se Google è bloccato nel vostro paese, dovrai saltare questa fase). diff --git a/curriculum/challenges/italian/01-responsive-web-design/basic-css/use-hex-code-for-specific-colors.md b/curriculum/challenges/italian/01-responsive-web-design/basic-css/use-hex-code-for-specific-colors.md index 882db8c71ac345..6540044928ffd1 100644 --- a/curriculum/challenges/italian/01-responsive-web-design/basic-css/use-hex-code-for-specific-colors.md +++ b/curriculum/challenges/italian/01-responsive-web-design/basic-css/use-hex-code-for-specific-colors.md @@ -11,9 +11,9 @@ dashedName: use-hex-code-for-specific-colors Lo sapevi che ci sono altri modi per rappresentare i colori in CSS? Uno di questi modi è chiamato codice esadecimale, o codice hex per brevità. -Di solito usiamo i numeri decimali (o numeri in base 10), che usano i simboli da 0 a 9 per ogni cifra. Gli esadecimali (o hex) sono numeri in base 16. Ciò significa che utilizzano sedici simboli distinti. Come per i i decimali, i simboli 0-9 rappresentano i valori da zero a nove. I successivi simboli A,B,C,D,E,F rappresentano i valori da dieci a quindici. Complessivamente, una cifra esadecimale può andare da 0 a F, dandoci 16 valori totali possibili. Qui puoi trovare ulteriori informazioni sul [sistema numerico esadecimale](https://it.wikipedia.org/wiki/Sistema_numerico_esadecimale). +Di solito usiamo i numeri decimali (o numeri in base 10), che usano i simboli da 0 a 9 per ogni cifra. Gli esadecimali (o hex) sono numeri in base 16. Ciò significa che utilizzano sedici simboli distinti. Come per i i decimali, i simboli 0-9 rappresentano i valori da zero a nove. I successivi simboli A,B,C,D,E,F rappresentano i valori da dieci a quindici. Complessivamente, una cifra esadecimale può andare da 0 a F, dandoci 16 valori totali possibili. Qui puoi trovare ulteriori informazioni sul sistema numerico esadecimale. -In CSS, possiamo usare 6 cifre esadecimali per rappresentare i colori, due ciascuna per le componenti rossa (R), verde (G) e blu (B). Ad esempio, `#000000` è nero ed è anche il valore più basso possibile. You can find more information about the [RGB color system here](https://www.freecodecamp.org/news/rgb-color-html-and-css-guide/#whatisthergbcolormodel). +In CSS, possiamo usare 6 cifre esadecimali per rappresentare i colori, due ciascuna per le componenti rossa (R), verde (G) e blu (B). Ad esempio, `#000000` è nero ed è anche il valore più basso possibile. Qui puoi trovare più informazioni sul sistema di colori RGB. ```css body { diff --git a/curriculum/challenges/italian/01-responsive-web-design/basic-html-and-html5/add-images-to-your-website.md b/curriculum/challenges/italian/01-responsive-web-design/basic-html-and-html5/add-images-to-your-website.md index 80189c6d8edd70..2033b2a278dde8 100644 --- a/curriculum/challenges/italian/01-responsive-web-design/basic-html-and-html5/add-images-to-your-website.md +++ b/curriculum/challenges/italian/01-responsive-web-design/basic-html-and-html5/add-images-to-your-website.md @@ -60,7 +60,7 @@ L'elemento `alt` della tua immagine non dovrebbe essere vuoto. assert( $('img').attr('alt') && $('img').attr('alt').length && - /)\S+\1\S*\/?>/.test( + /<(?:img|IMG)\S*alt=(['"])(?!\1|>)\S+\1\S*\/?>/.test( __helpers.removeWhiteSpace(code) ) ); diff --git a/curriculum/challenges/italian/01-responsive-web-design/css-flexbox/align-elements-using-the-justify-content-property.md b/curriculum/challenges/italian/01-responsive-web-design/css-flexbox/align-elements-using-the-justify-content-property.md index 0c317e43024403..326ef042816fcf 100644 --- a/curriculum/challenges/italian/01-responsive-web-design/css-flexbox/align-elements-using-the-justify-content-property.md +++ b/curriculum/challenges/italian/01-responsive-web-design/css-flexbox/align-elements-using-the-justify-content-property.md @@ -11,11 +11,11 @@ dashedName: align-elements-using-the-justify-content-property Certe volte gli oggetti flex all'interno di un contenitore flex non riempiono tutto lo spazio del contenitore. È comune voler dire a CSS di allineare e spaziare gli elementi flex in una certa maniera. Fortunatamente, la proprietà `justify-content` ha diverse opzioni per farlo. Ma prima, c'è un po' di terminologia importante da capire prima di rivedere queste opzioni. -[Ecco una immagine utile da W3C che illustra i concetti sotto per un contenitore 'row' (riga) flex.](https://www.w3.org/TR/css-flexbox-1/images/flex-direction-terms.svg) +Per maggiori informazioni sulle proprietà flex-box, leggi qui -Ricorda che l'impostazione di un contenitore flex come riga posiziona gli elementi flex fianco a fianco da sinistra a destra. Un contenitore flex impostato come colonna piazza gli oggetti flex in una pila verticale dall'alto verso il basso. Per ognuno, la direzione in cui sono disposti gli elementi flex è chiamata **asse principale**. Per una riga, si tratta di una linea orizzontale che taglia ogni elemento. E per una colonna, l'asse principale è una linea verticale attraverso gli elementi. +Ricorda che l'impostazione di un contenitore flex come riga posiziona gli elementi flex fianco a fianco da sinistra a destra. Un contenitore flex impostato come colonna piazza gli oggetti flex in una pila verticale dall'alto verso il basso. Per ognuno, la direzione in cui sono disposti gli elementi flex è chiamata **asse principale**. Per una riga, si tratta di una linea orizzontale che taglia ogni elemento. E per una colonna, l'asse principale è una linea verticale che attraversa gli elementi. -Ci sono diverse opzioni per come spaziare gli elementi flex lungo la linea che è l'asse principale. Uno dei più comunemente usati è `justify-content: center;`, che allinea tutti gli elementi flex al centro del contenitore flex. Altre opzioni includono: +Ci sono diverse opzioni per spaziare gli elementi flex lungo la linea corrispondente all'asse principale. Una delle più usate è `justify-content: center;`, che allinea tutti gli elementi flex al centro del contenitore flex. Altre opzioni includono:
    • flex-start: allinea gli elementi all'inizio del contenitore flex. Per una riga, questo spinge gli oggetti alla sinistra del contenitore. Per una colonna, questo spinge gli oggetti verso l'alto del contenitore. Questo è l'allineamento predefinito se non viene specificato alcun justify-content.
    • flex-end: allinea gli elementi alla fine del contenitore flex. Per una riga, questo spinge gli oggetti alla destra del contenitore. Per una colonna, questo spinge gli oggetti verso il fondo del contenitore.
    • space-between: allinea gli oggetti al centro dell'asse principale, con spazio aggiuntivo tra gli elementi. Il primo e l'ultimo elemento vengono spinti fino all'estremità del contenitore flex. Ad esempio, in una riga il primo elemento è contro il lato sinistro del contenitore, l'ultimo elemento è contro il lato destro del contenitore, quindi lo spazio rimanente è distribuito uniformemente tra gli altri elementi.
    • space-around: simile a space-between ma il primo e l'ultimo elemento non sono vincolati ai bordi del contenitore, lo spazio è distribuito intorno a tutti gli elementi con metà dello spazio su entrambe le estremità del contenitore flex.
    • space-evenly: distribuisce lo spazio uniformemente tra gli elementi flex con uno spazio pieno a entrambe le estremità del contrainer flex.
    @@ -24,11 +24,11 @@ Ci sono diverse opzioni per come spaziare gli elementi flex lungo la linea che Un esempio aiuta a mostrare questa proprietà in azione. Aggiungi la proprietà CSS `justify-content` all'elemento `#box-container` e dagli un valore di `center`. **Bonus** -Prova le altre opzioni per la proprietà `justify-content` nell'editor di codice per vedere le loro differenze. Nota però che un valore di `center` è l'unico che supererà questa sfida. +Prova le altre opzioni per la proprietà `justify-content` nell'editor di codice per vedere le loro differenze. Nota però che il valore `center` è l'unico che ti farà superare questa sfida. # --hints-- -L'elemento `#box-container` dovrebbe avere una proprietà `justify-content` impostata su un valore di `center`. +L'elemento `#box-container` dovrebbe avere una proprietà `justify-content` impostata sul valore `center`. ```js assert($('#box-container').css('justify-content') == 'center'); diff --git a/curriculum/challenges/italian/01-responsive-web-design/css-grid/divide-the-grid-into-an-area-template.md b/curriculum/challenges/italian/01-responsive-web-design/css-grid/divide-the-grid-into-an-area-template.md index 196254d58ed273..350d52e738bc82 100644 --- a/curriculum/challenges/italian/01-responsive-web-design/css-grid/divide-the-grid-into-an-area-template.md +++ b/curriculum/challenges/italian/01-responsive-web-design/css-grid/divide-the-grid-into-an-area-template.md @@ -17,7 +17,7 @@ grid-template-areas: "advert footer footer"; ``` -Questo codice raggruppa le celle della griglia in quattro aree; `header`, `advert`, `content` e `footer`. Ogni parola rappresenta una cella e ogni coppia di virgolette rappresenta una riga. +Il codice qui sopra raggruppa le celle della griglia in quattro aree: `header`, `advert`, `content` e `footer`. Ogni parola rappresenta una cella e ogni coppia di virgolette rappresenta una riga. # --instructions-- diff --git a/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md b/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md index 0226992eec9a74..065a31797fbe57 100644 --- a/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md +++ b/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md @@ -1,6 +1,6 @@ --- id: bd7158d8c242eddfaeb5bd13 -title: Build a Personal Portfolio Webpage +title: Creare una pagina Web per il Portfolio Personale challengeType: 14 forumTopicId: 301143 dashedName: build-a-personal-portfolio-webpage @@ -8,34 +8,36 @@ dashedName: build-a-personal-portfolio-webpage # --description-- -**Objective:** Build an app that is functionally similar to https://personal-portfolio.freecodecamp.rocks +**Obiettivo:** crea un'app funzionalmente simile a https://personal-portfolio.freecodecamp.rocks -**User Stories:** +**User story:** -1. Your portfolio should have a welcome section with an `id` of `welcome-section` -1. The welcome section should have an `h1` element that contains text -1. Your portfolio should have a projects section with an `id` of `projects` -1. The projects section should contain at least one element with a `class` of `project-tile` to hold a project -1. The projects section should contain at least one link to a project -1. Your portfolio should have a navbar with an id of `navbar` -1. The navbar should contain at least one link that you can click on to navigate to different sections of the page -1. Your portfolio should have a link with an id of `profile-link`, which opens your GitHub or freeCodeCamp profile in a new tab -1. Your portfolio should have at least one media query -1. The height of the welcome section should be equal to the height of the viewport -1. The navbar should always be at the top of the viewport +1. Il portfolio dovrebbe avere una sezione di benvenuto con un `id` di `welcome-section` +1. La sezione di benvenuto dovrebbe avere un elemento `h1` che contiene del testo +1. Il tuo portfolio dovrebbe avere una sezione progetti con un attributo `id` di `projects` +1. La sezione progetti dovrebbe contenere almeno un elemento con un attributo `class` di `project-tile` per contenere un progetto +1. La sezione progetti dovrebbe contenere almeno un link ad un progetto +1. Il tuo portfolio dovrebbe avere una barra di navigazione con un id di `navbar` +1. La barra di navigazione dovrebbe contenere almeno un link che puoi cliccare per navigare ad una sezione diversa della pagina +1. Il portfolio dovrebbe avere un link con un id di `profile-link` che apre il tuo profilo GitHub o freeCodeCamp in una nuova scheda +1. Il portfolio dovrebbe avere almeno una media query +1. L'altezza della sezione di benvenuto dovrebbe essere uguale all'altezza della porta di visualizzazione +1. La barra di navigazione dovrebbe sempre essere in cima alla porta di visualizzazione -Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! +Soddisfa le user story e passa tutti i test qua sotto per complerare questo progetto. Usa il tuo stile personale. Buon divertimento! + +**Nota:** Assicurati di aggiungere `` nel tuo HTML per linkare il tuo foglio di stile e applicare il tuo CSS # --hints-- -Your portfolio should have a "Welcome" section with an `id` of `welcome-section`. +Il portfolio dovrebbe avere una sezione "Benvenuto" con un `id` di `welcome-section`. ```js const el = document.getElementById('welcome-section') assert(!!el); ``` -Your `#welcom-section` element should contain an `h1` element. +L'elemento `#welcome-section` dovrebbe contenere un elemento `h1`. ```js assert.isAbove( @@ -45,7 +47,7 @@ assert.isAbove( ); ``` -You should not have any empty `h1` elements within `#welcome-section` element. +Non dovrebbe esserci alcun elemento `h1` dentro l'elemento `#welcome-section`. ```js assert.isAbove( @@ -56,14 +58,14 @@ assert.isAbove( ); ``` -You should have a "Projects" section with an `id` of `projects`. +Dovresti avere una sezione "Progetti" con un `id` di `projects`. ```js const el = document.getElementById('projects') assert(!!el); ``` -Your portfolio should contain at least one elment with a class of `project-tile`. +Il portfolio dovrebbe contenere almeno un elemento con una classe di `project-tile`. ```js assert.isAbove( @@ -72,20 +74,20 @@ assert.isAbove( ); ``` -Your `#projects` element should contain at least one `a` element. +L'elemento `#projects` dovrebbe contenere almeno un elemento `a`. ```js assert.isAbove(document.querySelectorAll('#projects a').length, 0); ``` -Your portfolio should have a navbar with an `id` of `navbar`. +Il portfolio dovrebbe avere una barra di navigazione con un attributo `id` di `navbar`. ```js const el = document.getElementById('navbar'); assert(!!el); ``` -Your `#navbar` element should contain at least one `a` element whose `href` attribute starts with `#`. +L'elemento `#navbar` dovrebbe contenere almeno un elemento `a` il cui attributo `href` inizia con `#`. ```js const links = [...document.querySelectorAll('#navbar a')].filter( @@ -99,27 +101,29 @@ assert.isAbove( ); ``` -Your portfolio should have an `a` element with an `id` of `profile-link`. +Il portfolio dovrebbe avere almeno un elemento `a` con un attributo `id` di `profile-link`. ```js const el = document.getElementById('profile-link'); assert(!!el && el.tagName === 'A') ``` -Your `#profile-link` element should have a `target` attribute of `_blank`. +L'elemento `#profile-link` dovrebbe avere un attributo `target` di `_blank`. ```js const el = document.getElementById('profile-link'); assert(!!el && el.target === '_blank') ``` -Your portfolio should use at least one media query. +Il portfolio dovrebbe usare almeno una media query. ```js -assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +const htmlSourceAttr = Array.from(document.querySelectorAll('source')).map(el => el.getAttribute('media')) +const cssCheck = new __helpers.CSSHelp(document).getCSSRules('media') +assert(cssCheck.length > 0 || htmlSourceAttr.length > 0); ``` -Your `#navbar` element should always be at the top of the viewport. +L'elemento `#navbar` dovrebbe sempre essere in cima al viewport. ```js (async () => { @@ -168,11 +172,11 @@ Your `#navbar` element should always be at the top of the viewport. - + Personal Portfolio - +